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
00037
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
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
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
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
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
00159
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
00168
if(
m_globalParts[ name ] != 0 )
00169
continue;
00170
00171 assert( !( *it )->hasServiceType(
"KDevelop/Part" ) );
00172
00173
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
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
00207
if(
m_globalParts[ name ] != 0 )
00208
continue;
00209
00210 assert( !( *it )->hasServiceType(
"KDevelop/Part" ) );
00211
00212
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
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 }