TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

plugin.cpp 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /* This file is part of the KDE project
  2. Copyright (C) 1999 Simon Hausmann <hausmann@kde.org>
  3. (C) 1999 David Faure <faure@kde.org>
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public License
  13. along with this library; see the file COPYING.LIB. If not, write to
  14. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. #include <config.h>
  18. #include <tdeparts/plugin.h>
  19. #include <tdeparts/part.h>
  20. #include <tdeparts/componentfactory.h>
  21. #include <assert.h>
  22. #include <tqfile.h>
  23. #include <tqobjectlist.h>
  24. #include <tqfileinfo.h>
  25. #include <klibloader.h>
  26. #include <kinstance.h>
  27. #include <kstandarddirs.h>
  28. #include <kdebug.h>
  29. #include <kxmlguifactory.h>
  30. #include <tdelocale.h>
  31. #include <tdeconfig.h>
  32. #include <ksimpleconfig.h>
  33. using namespace KParts;
  34. class Plugin::PluginPrivate
  35. {
  36. public:
  37. PluginPrivate() : m_parentInstance( 0 ) {}
  38. const TDEInstance *m_parentInstance;
  39. TQString m_library; // filename of the library
  40. };
  41. Plugin::Plugin( TQObject* parent, const char* name )
  42. : TQObject( parent, name )
  43. {
  44. //kdDebug() << className() << endl;
  45. d = new PluginPrivate();
  46. }
  47. Plugin::~Plugin()
  48. {
  49. delete d;
  50. }
  51. TQString Plugin::xmlFile() const
  52. {
  53. TQString path = KXMLGUIClient::xmlFile();
  54. if ( !d->m_parentInstance || ( path.length() > 0 && path[ 0 ] == '/' ) )
  55. return path;
  56. TQString absPath = locate( "data", TQString::fromLatin1( d->m_parentInstance->instanceName() ) + '/' + path );
  57. assert( !absPath.isEmpty() );
  58. return absPath;
  59. }
  60. TQString Plugin::localXMLFile() const
  61. {
  62. TQString path = KXMLGUIClient::xmlFile();
  63. if ( !d->m_parentInstance || ( path.length() > 0 && path[ 0 ] == '/' ) )
  64. return path;
  65. TQString absPath = locateLocal( "data", TQString::fromLatin1( d->m_parentInstance->instanceName() ) + '/' + path );
  66. assert( !absPath.isEmpty() );
  67. return absPath;
  68. }
  69. //static
  70. TQValueList<Plugin::PluginInfo> Plugin::pluginInfos( const TDEInstance * instance )
  71. {
  72. if ( !instance )
  73. kdError(1000) << "No instance ???" << endl;
  74. TQValueList<PluginInfo> plugins;
  75. // KDE4: change * into *.rc and remove test for .desktop from the for loop below.
  76. const TQStringList pluginDocs = instance->dirs()->findAllResources(
  77. "data", instance->instanceName()+"/kpartplugins/*", true, false );
  78. TQMap<TQString,TQStringList> sortedPlugins;
  79. TQStringList::ConstIterator pIt = pluginDocs.begin();
  80. TQStringList::ConstIterator pEnd = pluginDocs.end();
  81. for (; pIt != pEnd; ++pIt )
  82. {
  83. TQFileInfo fInfo( *pIt );
  84. if ( fInfo.extension() == TQString::fromLatin1( "desktop" ) )
  85. continue;
  86. TQMap<TQString,TQStringList>::Iterator mapIt = sortedPlugins.find( fInfo.fileName() );
  87. if ( mapIt == sortedPlugins.end() )
  88. mapIt = sortedPlugins.insert( fInfo.fileName(), TQStringList() );
  89. mapIt.data().append( *pIt );
  90. }
  91. TQMap<TQString,TQStringList>::ConstIterator mapIt = sortedPlugins.begin();
  92. TQMap<TQString,TQStringList>::ConstIterator mapEnd = sortedPlugins.end();
  93. for (; mapIt != mapEnd; ++mapIt )
  94. {
  95. PluginInfo info;
  96. TQString doc;
  97. info.m_absXMLFileName = KXMLGUIClient::findMostRecentXMLFile( mapIt.data(), doc );
  98. if ( info.m_absXMLFileName.isEmpty() )
  99. continue;
  100. kdDebug( 1000 ) << "found KParts Plugin : " << info.m_absXMLFileName << endl;
  101. info.m_relXMLFileName = "kpartplugins/";
  102. info.m_relXMLFileName += mapIt.key();
  103. info.m_document.setContent( doc );
  104. if ( info.m_document.documentElement().isNull() )
  105. continue;
  106. plugins.append( info );
  107. }
  108. return plugins;
  109. }
  110. void Plugin::loadPlugins( TQObject *parent, const TDEInstance *instance )
  111. {
  112. loadPlugins( parent, pluginInfos( instance ), instance );
  113. }
  114. void Plugin::loadPlugins( TQObject *parent, const TQValueList<PluginInfo> &pluginInfos, const TDEInstance *instance )
  115. {
  116. TQValueList<PluginInfo>::ConstIterator pIt = pluginInfos.begin();
  117. TQValueList<PluginInfo>::ConstIterator pEnd = pluginInfos.end();
  118. for (; pIt != pEnd; ++pIt )
  119. {
  120. TQString library = (*pIt).m_document.documentElement().attribute( "library" );
  121. if ( library.isEmpty() || hasPlugin( parent, library ) )
  122. continue;
  123. Plugin *plugin = loadPlugin( parent, TQFile::encodeName(library) );
  124. if ( plugin )
  125. {
  126. plugin->d->m_parentInstance = instance;
  127. plugin->setXMLFile( (*pIt).m_relXMLFileName, false, false );
  128. plugin->setDOMDocument( (*pIt).m_document );
  129. }
  130. }
  131. }
  132. void Plugin::loadPlugins( TQObject *parent, const TQValueList<PluginInfo> &pluginInfos )
  133. {
  134. loadPlugins(parent, pluginInfos, 0);
  135. }
  136. // static
  137. Plugin* Plugin::loadPlugin( TQObject * parent, const char* libname )
  138. {
  139. Plugin* plugin = ComponentFactory::createInstanceFromLibrary<Plugin>( libname, parent, libname );
  140. if ( !plugin )
  141. return 0L;
  142. plugin->d->m_library = libname;
  143. return plugin;
  144. }
  145. TQPtrList<KParts::Plugin> Plugin::pluginObjects( TQObject *parent )
  146. {
  147. TQPtrList<KParts::Plugin> objects;
  148. if (!parent )
  149. return objects;
  150. TQObjectList *plugins = parent->queryList( "KParts::Plugin", 0, false, false );
  151. TQObjectListIt it( *plugins );
  152. for ( ; it.current() ; ++it )
  153. {
  154. objects.append( static_cast<Plugin *>( it.current() ) );
  155. }
  156. delete plugins;
  157. return objects;
  158. }
  159. bool Plugin::hasPlugin( TQObject* parent, const TQString& library )
  160. {
  161. TQObjectList *plugins = parent->queryList( "KParts::Plugin", 0, false, false );
  162. TQObjectListIt it( *plugins );
  163. for ( ; it.current() ; ++it )
  164. {
  165. if ( static_cast<Plugin *>( it.current() )->d->m_library == library )
  166. {
  167. delete plugins;
  168. return true;
  169. }
  170. }
  171. delete plugins;
  172. return false;
  173. }
  174. void Plugin::setInstance( TDEInstance *instance )
  175. {
  176. TDEGlobal::locale()->insertCatalogue( instance->instanceName() );
  177. KXMLGUIClient::setInstance( instance );
  178. }
  179. void Plugin::loadPlugins( TQObject *parent, KXMLGUIClient* parentGUIClient, TDEInstance* instance, bool enableNewPluginsByDefault )
  180. {
  181. TDEConfigGroup cfgGroup( instance->config(), "KParts Plugins" );
  182. TQValueList<PluginInfo> plugins = pluginInfos( instance );
  183. TQValueList<PluginInfo>::ConstIterator pIt = plugins.begin();
  184. TQValueList<PluginInfo>::ConstIterator pEnd = plugins.end();
  185. for (; pIt != pEnd; ++pIt )
  186. {
  187. TQDomElement docElem = (*pIt).m_document.documentElement();
  188. TQString library = docElem.attribute( "library" );
  189. if ( library.isEmpty() )
  190. continue;
  191. // Check configuration
  192. const TQString name = docElem.attribute( "name" );
  193. bool pluginEnabled = enableNewPluginsByDefault;
  194. if ( cfgGroup.hasKey( name + "Enabled" ) )
  195. {
  196. pluginEnabled = cfgGroup.readBoolEntry( name + "Enabled" );
  197. }
  198. else
  199. { // no user-setting, load plugin default setting
  200. TQString relPath = TQString( instance->instanceName() ) + "/" + (*pIt).m_relXMLFileName;
  201. relPath.truncate( relPath.findRev( '.' ) ); // remove extension
  202. relPath += ".desktop";
  203. //kdDebug(1000) << "looking for " << relPath << endl;
  204. const TQString desktopfile = instance->dirs()->findResource( "data", relPath );
  205. if( !desktopfile.isEmpty() )
  206. {
  207. //kdDebug(1000) << "loadPlugins found desktop file for " << name << ": " << desktopfile << endl;
  208. KSimpleConfig desktop( desktopfile, true );
  209. desktop.setDesktopGroup();
  210. pluginEnabled = desktop.readBoolEntry(
  211. "X-TDE-PluginInfo-EnabledByDefault", enableNewPluginsByDefault );
  212. }
  213. else
  214. {
  215. //kdDebug(1000) << "loadPlugins no desktop file found in " << relPath << endl;
  216. }
  217. }
  218. // search through already present plugins
  219. TQObjectList *pluginList = parent->queryList( "KParts::Plugin", 0, false, false );
  220. TQObjectListIt it( *pluginList );
  221. bool pluginFound = false;
  222. for ( ; it.current() ; ++it )
  223. {
  224. Plugin * plugin = static_cast<Plugin *>( it.current() );
  225. if( plugin->d->m_library == library )
  226. {
  227. // delete and unload disabled plugins
  228. if( !pluginEnabled )
  229. {
  230. kdDebug( 1000 ) << "remove plugin " << name << endl;
  231. KXMLGUIFactory * factory = plugin->factory();
  232. if( factory )
  233. factory->removeClient( plugin );
  234. delete plugin;
  235. }
  236. pluginFound = true;
  237. break;
  238. }
  239. }
  240. delete pluginList;
  241. // if the plugin is already loaded or if it's disabled in the
  242. // configuration do nothing
  243. if( pluginFound || !pluginEnabled )
  244. continue;
  245. kdDebug( 1000 ) << "load plugin " << name << endl;
  246. Plugin *plugin = loadPlugin( parent, TQFile::encodeName(library) );
  247. if ( plugin )
  248. {
  249. plugin->d->m_parentInstance = instance;
  250. plugin->setXMLFile( (*pIt).m_relXMLFileName, false, false );
  251. plugin->setDOMDocument( (*pIt).m_document );
  252. parentGUIClient->insertChildClient( plugin );
  253. }
  254. }
  255. }
  256. // vim:sw=4:et:sts=4
  257. #include "plugin.moc"