• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • KDE Home
  • Contact Us
 

Kontact Plugin Interface Library

plugin.cpp
00001 /*
00002   This file is part of the KDE Kontact Plugin Interface Library.
00003 
00004   Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
00005   Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org>
00006 
00007   This library is free software; you can redistribute it and/or
00008   modify it under the terms of the GNU Library General Public
00009   License as published by the Free Software Foundation; either
00010   version 2 of the License, or (at your option) any later version.
00011 
00012   This library is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015   Library General Public License for more details.
00016 
00017   You should have received a copy of the GNU Library General Public License
00018   along with this library; see the file COPYING.LIB.  If not, write to
00019   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020   Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "plugin.h"
00024 #include <QFile>
00025 #include "core.h"
00026 
00027 #include <kpimutils/processes.h>
00028 
00029 #include <kparts/componentfactory.h>
00030 #include <kxmlguifactory.h>
00031 #include <kaboutdata.h>
00032 #include <kglobal.h>
00033 #include <kdebug.h>
00034 #include <kcomponentdata.h>
00035 #include <kstandarddirs.h>
00036 #include <krun.h>
00037 
00038 #include <QObject>
00039 #include <QDBusConnection>
00040 
00041 #include <unistd.h>
00042 
00043 using namespace KontactInterface;
00044 
00049 //@cond PRIVATE
00050 class Plugin::Private
00051 {
00052   public:
00053 
00054     void partDestroyed();
00055     void setXmlFiles();
00056     void removeInvisibleToolbarActions( Plugin *plugin );
00057 
00058     Core *core;
00059     QList<KAction*> newActions;
00060     QList<KAction*> syncActions;
00061     QString identifier;
00062     QString title;
00063     QString icon;
00064     QString executableName;
00065     QString serviceName;
00066     QByteArray partLibraryName;
00067     QByteArray pluginName;
00068     bool hasPart;
00069     KParts::ReadOnlyPart *part;
00070     bool disabled;
00071 };
00072 //@endcond
00073 
00074 Plugin::Plugin( Core *core, QObject *parent, const char *appName, const char *pluginName )
00075   : KXMLGUIClient( core ), QObject( parent ), d( new Private )
00076 {
00077   setObjectName( appName );
00078   core->factory()->addClient( this );
00079   KGlobal::locale()->insertCatalog( appName );
00080 
00081   d->pluginName = pluginName ? pluginName : appName;
00082   d->core = core;
00083   d->hasPart = true;
00084   d->part = 0;
00085   d->disabled = false;
00086 }
00087 
00088 Plugin::~Plugin()
00089 {
00090   delete d->part;
00091   delete d;
00092 }
00093 
00094 void Plugin::setIdentifier( const QString &identifier )
00095 {
00096   d->identifier = identifier;
00097 }
00098 
00099 QString Plugin::identifier() const
00100 {
00101   return d->identifier;
00102 }
00103 
00104 void Plugin::setTitle( const QString &title )
00105 {
00106   d->title = title;
00107 }
00108 
00109 QString Plugin::title() const
00110 {
00111   return d->title;
00112 }
00113 
00114 void Plugin::setIcon( const QString &icon )
00115 {
00116   d->icon = icon;
00117 }
00118 
00119 QString Plugin::icon() const
00120 {
00121   return d->icon;
00122 }
00123 
00124 void Plugin::setExecutableName( const QString &bin )
00125 {
00126   d->executableName = bin;
00127 }
00128 
00129 QString Plugin::executableName() const
00130 {
00131   return d->executableName;
00132 }
00133 
00134 void Plugin::setPartLibraryName( const QByteArray &libName )
00135 {
00136   d->partLibraryName = libName;
00137 }
00138 
00139 bool Plugin::createDBUSInterface( const QString &serviceType )
00140 {
00141   Q_UNUSED( serviceType );
00142   return false;
00143 }
00144 
00145 bool Plugin::isRunningStandalone() const
00146 {
00147   return false;
00148 }
00149 
00150 KParts::ReadOnlyPart *Plugin::loadPart()
00151 {
00152   return core()->createPart( d->partLibraryName );
00153 }
00154 
00155 const KAboutData *Plugin::aboutData() const
00156 {
00157   KPluginLoader loader( d->partLibraryName );
00158   KPluginFactory *factory = loader.factory();
00159   kDebug() << "filename:" << loader.fileName();
00160   kDebug() << "libname:" << d->partLibraryName;
00161 
00162   if ( factory ) {
00163     if ( factory->componentData().isValid() ) {
00164       kDebug() << "returning factory component aboutdata";
00165       return factory->componentData().aboutData();
00166     } else {
00167       // If the componentData of the factory is invalid, the likely cause is that
00168       // the part has not been ported to use K_PLUGIN_FACTORY/K_EXPORT_PLUGIN yet.
00169       // In that case, fallback to the old method of loading component data, which
00170       // does only work for old-style parts.
00171 
00172       kDebug() << "Unable to load component data for" << loader.fileName()
00173                << "trying to use the old style plugin system now.";
00174       const KComponentData instance =
00175         KParts::Factory::partComponentDataFromLibrary( d->partLibraryName );
00176       if ( instance.isValid() ) {
00177         return instance.aboutData();
00178       } else {
00179         kDebug() << "Invalid instance, unable to get about information!";
00180       }
00181     }
00182   }
00183 
00184   kError() << "Cannot load instance for" << title();
00185   return 0;
00186 }
00187 
00188 KParts::ReadOnlyPart *Plugin::part()
00189 {
00190   if ( !d->part ) {
00191     d->part = createPart();
00192     if ( d->part ) {
00193       connect( d->part, SIGNAL(destroyed()), SLOT(partDestroyed()) );
00194       d->removeInvisibleToolbarActions(this);
00195       core()->partLoaded( this, d->part );
00196     }
00197   }
00198   return d->part;
00199 }
00200 
00201 QString Plugin::tipFile() const
00202 {
00203   return QString();
00204 }
00205 
00206 QString Plugin::registerClient()
00207 {
00208   if ( d->serviceName.isEmpty() ) {
00209     d->serviceName = "org.kde." + objectName().toLatin1();
00210 #ifdef Q_WS_WIN
00211     const QString pid = QString::number( getpid() );
00212     d->serviceName.append( ".unique-" + pid );
00213 #endif
00214     QDBusConnection::sessionBus().registerService( d->serviceName );
00215   }
00216   return d->serviceName;
00217 }
00218 
00219 int Plugin::weight() const
00220 {
00221   return 0;
00222 }
00223 
00224 void Plugin::insertNewAction( KAction *action )
00225 {
00226   d->newActions.append( action );
00227 }
00228 
00229 void Plugin::insertSyncAction( KAction *action )
00230 {
00231   d->syncActions.append( action );
00232 }
00233 
00234 QList<KAction*> Plugin::newActions() const
00235 {
00236   return d->newActions;
00237 }
00238 
00239 QList<KAction*> Plugin::syncActions() const
00240 {
00241   return d->syncActions;
00242 }
00243 
00244 QStringList Plugin::invisibleToolbarActions() const
00245 {
00246   return QStringList();
00247 }
00248 
00249 bool Plugin::canDecodeMimeData( const QMimeData *data ) const
00250 {
00251   Q_UNUSED( data );
00252   return false;
00253 }
00254 
00255 void Plugin::processDropEvent( QDropEvent * )
00256 {
00257 }
00258 
00259 void Plugin::readProperties( const KConfigGroup & )
00260 {
00261 }
00262 
00263 void Plugin::saveProperties( KConfigGroup & )
00264 {
00265 }
00266 
00267 Core *Plugin::core() const
00268 {
00269   return d->core;
00270 }
00271 
00272 void Plugin::aboutToSelect()
00273 {
00274   // Because the 3 korganizer plugins share the same part, we need to switch
00275   // that part's XML files every time we are about to show its GUI...
00276   d->setXmlFiles();
00277 
00278   select();
00279 }
00280 
00281 void Plugin::select()
00282 {
00283 }
00284 
00285 void Plugin::configUpdated()
00286 {
00287 }
00288 
00289 //@cond PRIVATE
00290 void Plugin::Private::partDestroyed()
00291 {
00292   part = 0;
00293 }
00294 
00295 void Plugin::Private::removeInvisibleToolbarActions( Plugin *plugin )
00296 {
00297   if ( pluginName.isEmpty() ) {
00298     return;
00299   }
00300 
00301   // Hide unwanted toolbar action by modifying the XML before createGUI, rather
00302   // than doing it by calling removeAction on the toolbar after createGUI. Both
00303   // solutions work visually, but only modifying the XML ensures that the
00304   // actions don't appear in "edit toolbars". #207296
00305   const QStringList hideActions = plugin->invisibleToolbarActions();
00306   //kDebug() << "Hiding actions" << hideActions << "from" << pluginName << part;
00307   QDomDocument doc = part->domDocument();
00308   QDomElement docElem = doc.documentElement();
00309   // 1. Iterate over containers
00310   for ( QDomElement containerElem = docElem.firstChildElement();
00311         !containerElem.isNull(); containerElem = containerElem.nextSiblingElement() ) {
00312     if ( QString::compare( containerElem.tagName(), "ToolBar", Qt::CaseInsensitive ) == 0 ) {
00313       // 2. Iterate over actions in toolbars
00314       QDomElement actionElem = containerElem.firstChildElement();
00315       while ( !actionElem.isNull() ) {
00316         QDomElement nextActionElem = actionElem.nextSiblingElement();
00317         if ( QString::compare( actionElem.tagName(), "Action", Qt::CaseInsensitive ) == 0 ) {
00318           //kDebug() << "Looking at action" << actionElem.attribute("name");
00319           if ( hideActions.contains( actionElem.attribute( "name" ) ) ) {
00320             //kDebug() << "REMOVING";
00321             containerElem.removeChild( actionElem );
00322           }
00323         }
00324         actionElem = nextActionElem;
00325       }
00326     }
00327   }
00328 
00329   // Possible optimization: we could do all the above and the writing below
00330   // only when (newAppFile does not exist) or (version of domDocument > version of newAppFile)  (*)
00331   // This requires parsing newAppFile when it exists, though, and better use
00332   // the fast kdeui code for that rather than a full QDomDocument.
00333   // (*) or when invisibleToolbarActions() changes :)
00334 
00335   const QString newAppFile =
00336     KStandardDirs::locateLocal( "data", "kontact/default-" + pluginName + ".rc" );
00337   QFile file( newAppFile );
00338   if ( !file.open( QFile::WriteOnly ) ) {
00339     kWarning() << "error writing to" << newAppFile;
00340     return;
00341   }
00342   file.write( doc.toString().toUtf8() );
00343   file.flush();
00344 
00345   setXmlFiles();
00346 }
00347 
00348 void Plugin::Private::setXmlFiles()
00349 {
00350   const QString newAppFile =
00351     KStandardDirs::locateLocal( "data", "kontact/default-" + pluginName + ".rc" );
00352   const QString localFile =
00353     KStandardDirs::locateLocal( "data", "kontact/local-" + pluginName + ".rc" );
00354   if ( part->xmlFile() != newAppFile || part->localXMLFile() != localFile ) {
00355     part->replaceXMLFile( newAppFile, localFile );
00356   }
00357 }
00358 //@endcond
00359 
00360 void Plugin::slotConfigUpdated()
00361 {
00362   configUpdated();
00363 }
00364 
00365 void Plugin::bringToForeground()
00366 {
00367   if ( d->executableName.isEmpty() ) {
00368     return;
00369   }
00370 #ifdef Q_WS_WIN
00371   KPIMUtils::activateWindowForProcess( d->executableName );
00372 #else
00373   KRun::runCommand( d->executableName, 0 );
00374 #endif
00375 }
00376 
00377 Summary *Plugin::createSummaryWidget( QWidget *parent )
00378 {
00379   Q_UNUSED( parent );
00380   return 0;
00381 }
00382 
00383 bool Plugin::showInSideBar() const
00384 {
00385   return d->hasPart;
00386 }
00387 
00388 void Plugin::setShowInSideBar( bool hasPart )
00389 {
00390   d->hasPart = hasPart;
00391 }
00392 
00393 bool Plugin::queryClose() const
00394 {
00395   return true;
00396 }
00397 
00398 void Plugin::setDisabled( bool disabled )
00399 {
00400   d->disabled = disabled;
00401 }
00402 
00403 bool Plugin::disabled() const
00404 {
00405   return d->disabled;
00406 }
00407 
00408 void Plugin::virtual_hook( int, void * )
00409 {
00410   //BASE::virtual_hook( id, data );
00411 }
00412 
00413 #include "plugin.moc"
00414 
00415 // vim: sw=2 et sts=2 tw=80
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 14 2012 04:51:33 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Kontact Plugin Interface Library

Skip menu "Kontact Plugin Interface Library"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal