#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "core.h" #include "api.h" #include "toplevel.h" #include "projectmanager.h" //#include "partselectwidget.h" #include "domutil.h" #include "plugincontroller.h" #include "pluginselectdialog.h" #include "shellextension.h" // a separate method in this anonymous namespace to avoid having it all // inline in plugincontroller.h namespace { template ComponentType *loadDefaultPart( const TQString &serviceType ) { KTrader::OfferList offers = KTrader::self()->query(serviceType, TQString("[X-KDevelop-Version] == %1").tqarg(KDEVELOP_PLUGIN_VERSION)); KTrader::OfferList::ConstIterator serviceIt = offers.begin(); for ( ; serviceIt != offers.end(); ++serviceIt ) { KService::Ptr service = *serviceIt; ComponentType *part = KParts::ComponentFactory ::createInstanceFromService< ComponentType >( service, API::getInstance(), 0, PluginController::argumentsFromService( service ) ); if ( part ) return part; } return 0; } } PluginController *PluginController::s_instance = 0; PluginController *PluginController::getInstance() { if (!s_instance) s_instance = new PluginController(); return s_instance; } PluginController::PluginController() : KDevPluginController() { /* m_defaultProfile = TQString::tqfromLatin1( "FullIDE" ); m_defaultProfilePath = kapp->dirs()->localkdedir() + "/" + KStandardDirs::kde_default( "data" ) + TQString::tqfromLatin1("/tdevelop/profiles/FullIDE");*/ KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); if( args->isSet("profile") ){ m_profile = TQString::fromLocal8Bit( args->getOption("profile") ); } else { m_profile = ShellExtension::getInstance()->defaultProfile(); } } void PluginController::loadInitialPlugins() { loadCorePlugins(); TQStringList disableList; Profile * profile = engine().findProfile( currentProfile() ); if( profile ) { Profile::EntryList disableEntryList = profile->list( Profile::ExplicitDisable ); for ( Profile::EntryList::const_iterator it = disableEntryList.constBegin(); it != disableEntryList.constEnd(); ++it ) { disableList << (*it).name; } } loadGlobalPlugins( disableList ); } PluginController::~PluginController() { unloadPlugins(); } void PluginController::loadCorePlugins() { KTrader::OfferList coreOffers = m_engine.offers(m_profile, ProfileEngine::Core); loadPlugins( coreOffers ); } void PluginController::loadGlobalPlugins( const TQStringList & ignorePlugins ) { KTrader::OfferList globalOffers = m_engine.offers(m_profile, ProfileEngine::Global); loadPlugins( globalOffers, ignorePlugins ); } void PluginController::loadProjectPlugins( const TQStringList & ignorePlugins ) { KTrader::OfferList projectOffers = m_engine.offers(m_profile, ProfileEngine::Project); loadPlugins( projectOffers, ignorePlugins ); } void PluginController::loadPlugins( KTrader::OfferList offers, const TQStringList & ignorePlugins ) { TopLevel::getInstance()->main()->setFocus(); for (KTrader::OfferList::ConstIterator it = offers.begin(); it != offers.end(); ++it) { TQString name = (*it)->desktopEntryName(); // Check if it is already loaded or shouldn't be if( m_parts[ name ] != 0 || ignorePlugins.contains( name ) ) continue; emit loadingPlugin(i18n("Loading: %1").tqarg((*it)->genericName())); KDevPlugin *plugin = loadPlugin( *it ); if ( plugin ) { m_parts.insert( name, plugin ); integratePart( plugin ); } } } void PluginController::unloadPlugins() { for( TQDictIterator it( m_parts ); !it.isEmpty(); ) { KDevPlugin* part = it.current(); removePart( part ); m_parts.remove( it.currentKey() ); delete part; } } void PluginController::unloadProjectPlugins( ) { // this is nasty, but we need to unload the version control plugin too, and the // right moment to do this is here KTrader::OfferList offers = KTrader::self()->query("KDevelop/VersionControl", ""); offers += m_engine.offers(m_profile, ProfileEngine::Project); for (KTrader::OfferList::ConstIterator it = offers.begin(); it != offers.end(); ++it) { TQString name = (*it)->desktopEntryName(); if ( KDevPlugin * plugin = m_parts[ name ] ) { kdDebug(9000) << " *** Removing: " << name << endl; removeAndForgetPart( name, plugin ); delete plugin; } } } void PluginController::unloadPlugins( TQStringList const & unloadParts ) { TQStringList::ConstIterator it = unloadParts.begin(); while ( it != unloadParts.end() ) { KDevPlugin* part = m_parts[ *it ]; if( part ) { kdDebug(9000) << " *** Removing: " << *it << endl; removePart( part ); m_parts.remove( *it ); delete part; } ++it; } } KDevPlugin *PluginController::loadPlugin( const KService::Ptr &service ) { int err = 0; KDevPlugin * pl = KParts::ComponentFactory ::createInstanceFromService( service, API::getInstance(), 0, argumentsFromService( service ), &err ); if (!pl) { KMessageBox::error( 0, i18n("Could not load plugin
" "Plugin %1 could not be loaded
" "Library loader error: %2").tqarg(service->name()). arg(KLibLoader::self()->lastErrorMessage()), i18n("Could not load plugin")); } // kdDebug() << "ERR: " << err << endl; return pl; } TQStringList PluginController::argumentsFromService( const KService::Ptr &service ) { TQStringList args; if ( !service ) // service is a reference to a pointer, so a check whether it is 0 is still required return args; TQVariant prop = service->property( "X-KDevelop-Args" ); if ( prop.isValid() ) args = TQStringList::split( " ", prop.toString() ); return args; } void PluginController::integratePart(KXMLGUIClient *part) { if ( ! part ) return; Core::setupShourtcutTips(part); TopLevel::getInstance()->main()->guiFactory()->addClient(part); connect( part->actionCollection(), TQT_SIGNAL( actionStatusText( const TQString & ) ), TopLevel::getInstance()->main()->actionCollection(), TQT_SIGNAL( actionStatusText( const TQString & ) ) ); } void PluginController::integrateAndRememberPart(const TQString &name, KDevPlugin *part) { m_parts.insert(name, part); integratePart(part); } void PluginController::removePart(KXMLGUIClient *part) { if (TopLevel::mainWindowValid()) // is 0 when window was already closed TopLevel::getInstance()->main()->guiFactory()->removeClient(part); } void PluginController::removeAndForgetPart(const TQString &name, KDevPlugin *part) { kdDebug() << "removing: " << name << endl; m_parts.remove(name); removePart(part); } const TQValueList PluginController::loadedPlugins() { TQValueList plugins; TQDictIterator itt(m_parts); while( itt.current() ) { plugins.append( itt.current() ); ++itt; } return plugins; } KDevPlugin * PluginController::extension( const TQString & serviceType, const TQString & constraint ) { KTrader::OfferList offers = KDevPluginController::query(serviceType, constraint); for (KTrader::OfferList::const_iterator it = offers.constBegin(); it != offers.end(); ++it) { KDevPlugin *ext = m_parts[(*it)->desktopEntryName()]; if (ext) return ext; } return 0; } KDevPlugin * PluginController::loadPlugin( const TQString & serviceType, const TQString & constraint ) { KTrader::OfferList offers = KDevPluginController::query( serviceType, constraint ); if ( !offers.size() == 1 ) return 0; KTrader::OfferList::const_iterator it = offers.constBegin(); TQString name = (*it)->desktopEntryName(); KDevPlugin * plugin = 0; if ( plugin = m_parts[ name ] ) { return plugin; } if ( plugin = loadPlugin( *it ) ) { m_parts.insert( name, plugin ); integratePart( plugin ); } return plugin; } void PluginController::unloadPlugin( const TQString & plugin ) { TQStringList pluginList; pluginList << plugin; unloadPlugins( pluginList ); } KURL::List PluginController::profileResources(const TQString &nameFilter) { return m_engine.resources(currentProfile(), nameFilter); } KURL::List PluginController::profileResourcesRecursive(const TQString &nameFilter) { return m_engine.resourcesRecursive(currentProfile(), nameFilter); } TQString PluginController::changeProfile(const TQString &newProfile) { kdDebug() << "CHANGING PROFILE: from " << currentProfile() << " to " << newProfile << endl; TQStringList unload; KTrader::OfferList coreLoad; KTrader::OfferList globalLoad; m_engine.diffProfiles(ProfileEngine::Core, currentProfile(), newProfile, unload, coreLoad); m_engine.diffProfiles(ProfileEngine::Global, currentProfile(), newProfile, unload, globalLoad); TQString oldProfile = m_profile; m_profile = newProfile; unloadPlugins(unload); loadPlugins( coreLoad ); loadPlugins( globalLoad ); return oldProfile; } void PluginController::selectPlugins( ) { kdDebug(9000) << k_funcinfo << endl; PluginSelectDialog dlg; if ( dlg.exec() == TQDialog::Accepted ) { TQStringList unselectedPlugins = dlg.unselectedPluginNames(); kdDebug(9000) << unselectedPlugins << endl; unloadPlugins( unselectedPlugins ); loadGlobalPlugins( unselectedPlugins ); if ( ProjectManager::getInstance()->projectLoaded() ) { loadProjectPlugins( unselectedPlugins ); DomUtil::writeListEntry( *API::getInstance()->projectDom(), "/general/ignoreparts", "part", unselectedPlugins ); } } } /* KDevPlugin * PluginController::getPlugin( const KService::Ptr & service ) { KDevPlugin * plugin = m_parts[ (*it)->name() ]; if ( !plugin ) { KDevPlugin * plugin = loadPlugin( *it ); if ( plugin ) { integratePart( plugin ); m_parts.insert( (*it)->name(), plugin ); } } return plugin; } */ #include "plugincontroller.moc"