KDevelop API Documentation

src/plugincontroller.cpp

Go to the documentation of this file.
00001 #include <qfile.h> 00002 #include <qvbox.h> 00003 00004 #include <kcmdlineargs.h> 00005 #include <kapplication.h> 00006 #include <klibloader.h> 00007 #include <kservice.h> 00008 #include <ktrader.h> 00009 #include <kmessagebox.h> 00010 #include <kconfig.h> 00011 #include <klocale.h> 00012 #include <kmainwindow.h> 00013 #include <kparts/componentfactory.h> 00014 #include <assert.h> 00015 #include <kdebug.h> 00016 #include <kdialogbase.h> 00017 #include <kcmdlineargs.h> 00018 #include <kstandarddirs.h> 00019 00020 #include <kdevapi.h> 00021 #include <kdevplugin.h> 00022 #include <kdevmakefrontend.h> 00023 #include <kdevappfrontend.h> 00024 #include <kdevdifffrontend.h> 00025 #include <kdevsourceformatter.h> 00026 #include <kaction.h> 00027 00028 #include "core.h" 00029 #include "api.h" 00030 #include "toplevel.h" 00031 #include "partselectwidget.h" 00032 00033 #include "plugincontroller.h" 00034 #include "plugincontroller.moc" 00035 00036 // a separate method in this anonymous namespace to avoid having it all 00037 // inline in plugincontroller.h 00038 namespace 00039 { 00040 template <class ComponentType> 00041 ComponentType *loadDefaultPart( const QString &serviceType ) 00042 { 00043 KTrader::OfferList offers = KTrader::self()->query(serviceType, QString("[X-KDevelop-Version] == %1").arg(KDEVELOP_PLUGIN_VERSION)); 00044 KTrader::OfferList::ConstIterator serviceIt = offers.begin(); 00045 for ( ; serviceIt != offers.end(); ++serviceIt ) { 00046 KService::Ptr service = *serviceIt; 00047 00048 ComponentType *part = KParts::ComponentFactory 00049 ::createInstanceFromService< ComponentType >( service, API::getInstance(), 0, 00050 PluginController::argumentsFromService( service ) ); 00051 00052 if ( part ) 00053 return part; 00054 } 00055 return 0; 00056 } 00057 } 00058 00059 PluginController *PluginController::s_instance = 0; 00060 00061 00062 PluginController *PluginController::getInstance() 00063 { 00064 if (!s_instance) 00065 s_instance = new PluginController(); 00066 return s_instance; 00067 } 00068 00069 00070 PluginController::PluginController() 00071 : QObject() 00072 { 00073 connect( Core::getInstance(), SIGNAL(configWidget(KDialogBase*)), 00074 this, SLOT(slotConfigWidget(KDialogBase*)) ); 00075 00076 m_defaultProfile = QString::fromLatin1( "FullIDE" ); 00077 m_defaultProfilePath = kapp->dirs()->localkdedir() + "/" + 00078 KStandardDirs::kde_default( "data" ) + 00079 QString::fromLatin1("/kdevelop/profiles/FullIDE"); 00080 } 00081 00082 00083 void PluginController::loadInitialPlugins() 00084 { 00085 KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); 00086 00087 loadDefaultParts(); 00088 loadCorePlugins(); 00089 00090 m_profile = QString::null; 00091 if( args->isSet("profile") ){ 00092 m_profile = QString::fromLocal8Bit( args->getOption("profile") ); 00093 m_profilePath = m_profile; 00094 00095 if( m_profile[0] != '/' ) 00096 m_profilePath = locate( "data", QString::fromLatin1("kdevelop/profiles/") + m_profile ); 00097 00098 if( m_profilePath.isEmpty() ) 00099 m_profilePath = kapp->dirs()->localkdedir() + 00100 KStandardDirs::kde_default( "data" ) + 00101 QString::fromLatin1("/kdevelop/profiles/") + m_profile; 00102 } 00103 00104 if( m_profile.isEmpty() || m_profilePath.isEmpty() ){ 00105 m_profile = m_defaultProfile; 00106 m_profilePath = m_defaultProfilePath; 00107 } 00108 00109 loadGlobalPlugins(); 00110 } 00111 00112 00113 PluginController::~PluginController() 00114 { 00115 unloadGlobalPlugins(); 00116 } 00117 00118 00119 void PluginController::loadDefaultParts() 00120 { 00121 // Make frontend 00122 emit loadingPlugin(i18n("Loading plugin: Make frontend")); 00123 KDevMakeFrontend *makeFrontend = loadDefaultPart< KDevMakeFrontend >( "KDevelop/MakeFrontend" ); 00124 if ( makeFrontend ) { 00125 API::getInstance()->setMakeFrontend( makeFrontend ); 00126 integratePart( makeFrontend ); 00127 } 00128 00129 // App frontend 00130 emit loadingPlugin(i18n("Loading plugin: Application frontend")); 00131 KDevAppFrontend *appFrontend = loadDefaultPart< KDevAppFrontend >( "KDevelop/AppFrontend" ); 00132 if ( appFrontend ) { 00133 API::getInstance()->setAppFrontend( appFrontend ); 00134 integratePart( appFrontend ); 00135 } 00136 00137 // Diff frontend 00138 emit loadingPlugin(i18n("Loading plugin: Diff frontend")); 00139 KDevDiffFrontend *diffFrontend = loadDefaultPart< KDevDiffFrontend >( "KDevelop/DiffFrontend" ); 00140 if ( diffFrontend ) { 00141 API::getInstance()->setDiffFrontend( diffFrontend ); 00142 integratePart( diffFrontend ); 00143 } else { 00144 kdDebug( 9000 ) << "could not load Diff frontend" << endl; 00145 } 00146 00147 // Source formatter 00148 emit loadingPlugin(i18n("Loading plugin: Source formatter")); 00149 KDevSourceFormatter *sourceFormatter = loadDefaultPart< KDevSourceFormatter >( "KDevelop/SourceFormatter" ); 00150 if ( sourceFormatter ) { 00151 API::getInstance()->setSourceFormatter( sourceFormatter ); 00152 integratePart( sourceFormatter ); 00153 } else { 00154 kdDebug( 9000 ) << "could not load Source formatter" << endl; 00155 } 00156 } 00157 00158 // a Core plugin is implicitly global, so it makes 00159 // sense to put them in the global plugin container 00160 void PluginController::loadCorePlugins() 00161 { 00162 KTrader::OfferList coreOffers = pluginServices( "Core" ); 00163 for (KTrader::OfferList::ConstIterator it = coreOffers.begin(); it != coreOffers.end(); ++it) 00164 { 00165 QString name = (*it)->name(); 00166 00167 // Check if it is already loaded 00168 if( m_globalParts[ name ] != 0 ) 00169 continue; 00170 00171 assert( !( *it )->hasServiceType( "KDevelop/Part" ) ); 00172 00173 // emit loadingPlugin(i18n("Loading plugin: %1").arg((*it)->comment())); 00174 emit loadingPlugin(i18n("Loading plugin: %1").arg((*it)->genericName())); 00175 00176 KDevPlugin *plugin = loadPlugin( *it ); 00177 if ( plugin ) 00178 { 00179 m_globalParts.insert( name, plugin ); 00180 integratePart( plugin ); 00181 } 00182 } 00183 } 00184 00185 void PluginController::loadGlobalPlugins() 00186 { 00187 KTrader::OfferList globalOffers = pluginServices( "Global" ); 00188 KConfig config( m_profilePath ); 00189 for (KTrader::OfferList::ConstIterator it = globalOffers.begin(); it != globalOffers.end(); ++it) 00190 { 00191 config.setGroup( "Plugins" ); 00192 00193 QString name = (*it)->name(); 00194 00195 // Unload it it is marked as ignored and loaded 00196 if (!config.readBoolEntry( name, true)) { 00197 KDevPlugin* part = m_globalParts[name]; 00198 if( part ) { 00199 removePart( part ); 00200 m_globalParts.remove( name ); 00201 part->deleteLater(); 00202 } 00203 continue; 00204 } 00205 00206 // Check if it is already loaded 00207 if( m_globalParts[ name ] != 0 ) 00208 continue; 00209 00210 assert( !( *it )->hasServiceType( "KDevelop/Part" ) ); 00211 00212 // emit loadingPlugin(i18n("Loading plugin: %1").arg((*it)->comment())); 00213 emit loadingPlugin(i18n("Loading plugin: %1").arg((*it)->genericName())); 00214 00215 KDevPlugin *plugin = loadPlugin( *it ); 00216 if ( plugin ) { 00217 m_globalParts.insert( name, plugin ); 00218 integratePart( plugin ); 00219 } 00220 } 00221 } 00222 00223 void PluginController::unloadGlobalPlugins() 00224 { 00225 for( QDictIterator<KDevPlugin> it( m_globalParts ); !it.isEmpty(); ) 00226 { 00227 KDevPlugin* part = it.current(); 00228 removePart( part ); 00229 m_globalParts.remove( it.currentKey() ); 00230 delete part; 00231 } 00232 } 00233 00234 KService::List PluginController::pluginServices( const QString &scope ) 00235 { 00236 QString constraint = QString::fromLatin1("[X-KDevelop-Version] == %1").arg(KDEVELOP_PLUGIN_VERSION); 00237 00238 if ( !scope.isEmpty() ) 00239 constraint += QString::fromLatin1( " and [X-KDevelop-Scope] == '%1'").arg( scope ); 00240 return KTrader::self()->query( QString::fromLatin1( "KDevelop/Plugin" ), 00241 constraint ); 00242 } 00243 00244 KDevPlugin *PluginController::loadPlugin( const KService::Ptr &service ) 00245 { 00246 return KParts::ComponentFactory 00247 ::createInstanceFromService<KDevPlugin>( service, API::getInstance(), 0, 00248 argumentsFromService( service ) ); 00249 } 00250 00251 QStringList PluginController::argumentsFromService( const KService::Ptr &service ) 00252 { 00253 QStringList args; 00254 if ( !service ) 00255 // service is a reference to a pointer, so a check whether it is 0 is still required 00256 return args; 00257 QVariant prop = service->property( "X-KDevelop-Args" ); 00258 if ( prop.isValid() ) 00259 args = QStringList::split( " ", prop.toString() ); 00260 return args; 00261 } 00262 00263 void PluginController::slotConfigWidget( KDialogBase* dlg ) 00264 { 00265 QVBox *vbox = dlg->addVBoxPage(i18n("Plugins")); 00266 PartSelectWidget *w = new PartSelectWidget(vbox, "part selection widget"); 00267 connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); 00268 connect( w, SIGNAL(accepted()), this, SLOT(loadGlobalPlugins()) ); 00269 } 00270 00271 void PluginController::integratePart(KXMLGUIClient *part) 00272 { 00273 if ( ! part ) return; 00274 00275 TopLevel::getInstance()->main()->guiFactory()->addClient(part); 00276 00277 connect( part->actionCollection(), SIGNAL( actionStatusText( const QString & ) ), 00278 TopLevel::getInstance()->main()->actionCollection(), SIGNAL( actionStatusText( const QString & ) ) ); 00279 } 00280 00281 void PluginController::removePart(KXMLGUIClient *part) 00282 { 00283 TopLevel::getInstance()->main()->guiFactory()->removeClient(part); 00284 }
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:53 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003