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

Kontact Plugin Interface Library

  • kontactinterface
plugin.cpp
1 /*
2  This file is part of the KDE Kontact Plugin Interface Library.
3 
4  Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
5  Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include "plugin.h"
24 #include <QFile>
25 #include "core.h"
26 
27 #include <kpimutils/processes.h>
28 
29 #include <kparts/componentfactory.h>
30 #include <kxmlguifactory.h>
31 #include <kaboutdata.h>
32 #include <kglobal.h>
33 #include <kdebug.h>
34 #include <kcomponentdata.h>
35 #include <kstandarddirs.h>
36 #include <krun.h>
37 
38 #include <QObject>
39 #include <QDBusConnection>
40 
41 #include <unistd.h>
42 
43 using namespace KontactInterface;
44 
49 //@cond PRIVATE
50 class Plugin::Private
51 {
52  public:
53 
54  void partDestroyed();
55  void setXmlFiles();
56  void removeInvisibleToolbarActions( Plugin *plugin );
57 
58  Core *core;
59  QList<KAction*> newActions;
60  QList<KAction*> syncActions;
61  QString identifier;
62  QString title;
63  QString icon;
64  QString executableName;
65  QString serviceName;
66  QByteArray partLibraryName;
67  QByteArray pluginName;
68  bool hasPart;
69  KParts::ReadOnlyPart *part;
70  bool disabled;
71 };
72 //@endcond
73 
74 Plugin::Plugin( Core *core, QObject *parent, const char *appName, const char *pluginName )
75  : KXMLGUIClient( core ), QObject( parent ), d( new Private )
76 {
77  setObjectName( appName );
78  core->factory()->addClient( this );
79  KGlobal::locale()->insertCatalog( appName );
80 
81  d->pluginName = pluginName ? pluginName : appName;
82  d->core = core;
83  d->hasPart = true;
84  d->part = 0;
85  d->disabled = false;
86 }
87 
88 Plugin::~Plugin()
89 {
90  delete d->part;
91  delete d;
92 }
93 
94 void Plugin::setIdentifier( const QString &identifier )
95 {
96  d->identifier = identifier;
97 }
98 
99 QString Plugin::identifier() const
100 {
101  return d->identifier;
102 }
103 
104 void Plugin::setTitle( const QString &title )
105 {
106  d->title = title;
107 }
108 
109 QString Plugin::title() const
110 {
111  return d->title;
112 }
113 
114 void Plugin::setIcon( const QString &icon )
115 {
116  d->icon = icon;
117 }
118 
119 QString Plugin::icon() const
120 {
121  return d->icon;
122 }
123 
124 void Plugin::setExecutableName( const QString &bin )
125 {
126  d->executableName = bin;
127 }
128 
129 QString Plugin::executableName() const
130 {
131  return d->executableName;
132 }
133 
134 void Plugin::setPartLibraryName( const QByteArray &libName )
135 {
136  d->partLibraryName = libName;
137 }
138 
139 bool Plugin::createDBUSInterface( const QString &serviceType )
140 {
141  Q_UNUSED( serviceType );
142  return false;
143 }
144 
145 bool Plugin::isRunningStandalone() const
146 {
147  return false;
148 }
149 
150 KParts::ReadOnlyPart *Plugin::loadPart()
151 {
152  return core()->createPart( d->partLibraryName );
153 }
154 
155 const KAboutData *Plugin::aboutData() const
156 {
157  KPluginLoader loader( d->partLibraryName );
158  KPluginFactory *factory = loader.factory();
159  kDebug() << "filename:" << loader.fileName();
160  kDebug() << "libname:" << d->partLibraryName;
161 
162  if ( factory ) {
163  if ( factory->componentData().isValid() ) {
164  kDebug() << "returning factory component aboutdata";
165  return factory->componentData().aboutData();
166  } else {
167  // If the componentData of the factory is invalid, the likely cause is that
168  // the part has not been ported to use K_PLUGIN_FACTORY/K_EXPORT_PLUGIN yet.
169  // In that case, fallback to the old method of loading component data, which
170  // does only work for old-style parts.
171 
172  kDebug() << "Unable to load component data for" << loader.fileName()
173  << "trying to use the old style plugin system now.";
174  const KComponentData instance =
175  KParts::Factory::partComponentDataFromLibrary( d->partLibraryName );
176  if ( instance.isValid() ) {
177  return instance.aboutData();
178  } else {
179  kDebug() << "Invalid instance, unable to get about information!";
180  }
181  }
182  }
183 
184  kError() << "Cannot load instance for" << title();
185  return 0;
186 }
187 
188 KParts::ReadOnlyPart *Plugin::part()
189 {
190  if ( !d->part ) {
191  d->part = createPart();
192  if ( d->part ) {
193  connect( d->part, SIGNAL(destroyed()), SLOT(partDestroyed()) );
194  d->removeInvisibleToolbarActions(this);
195  core()->partLoaded( this, d->part );
196  }
197  }
198  return d->part;
199 }
200 
201 QString Plugin::tipFile() const
202 {
203  return QString();
204 }
205 
206 QString Plugin::registerClient()
207 {
208  if ( d->serviceName.isEmpty() ) {
209  d->serviceName = "org.kde." + objectName().toLatin1();
210 #ifdef Q_WS_WIN
211  const QString pid = QString::number( getpid() );
212  d->serviceName.append( ".unique-" + pid );
213 #endif
214  QDBusConnection::sessionBus().registerService( d->serviceName );
215  }
216  return d->serviceName;
217 }
218 
219 int Plugin::weight() const
220 {
221  return 0;
222 }
223 
224 void Plugin::insertNewAction( KAction *action )
225 {
226  d->newActions.append( action );
227 }
228 
229 void Plugin::insertSyncAction( KAction *action )
230 {
231  d->syncActions.append( action );
232 }
233 
234 QList<KAction*> Plugin::newActions() const
235 {
236  return d->newActions;
237 }
238 
239 QList<KAction*> Plugin::syncActions() const
240 {
241  return d->syncActions;
242 }
243 
244 QStringList Plugin::invisibleToolbarActions() const
245 {
246  return QStringList();
247 }
248 
249 bool Plugin::canDecodeMimeData( const QMimeData *data ) const
250 {
251  Q_UNUSED( data );
252  return false;
253 }
254 
255 void Plugin::processDropEvent( QDropEvent * )
256 {
257 }
258 
259 void Plugin::readProperties( const KConfigGroup & )
260 {
261 }
262 
263 void Plugin::saveProperties( KConfigGroup & )
264 {
265 }
266 
267 Core *Plugin::core() const
268 {
269  return d->core;
270 }
271 
272 void Plugin::aboutToSelect()
273 {
274  // Because the 3 korganizer plugins share the same part, we need to switch
275  // that part's XML files every time we are about to show its GUI...
276  d->setXmlFiles();
277 
278  select();
279 }
280 
281 void Plugin::select()
282 {
283 }
284 
285 void Plugin::configUpdated()
286 {
287 }
288 
289 //@cond PRIVATE
290 void Plugin::Private::partDestroyed()
291 {
292  part = 0;
293 }
294 
295 void Plugin::Private::removeInvisibleToolbarActions( Plugin *plugin )
296 {
297  if ( pluginName.isEmpty() ) {
298  return;
299  }
300 
301  // Hide unwanted toolbar action by modifying the XML before createGUI, rather
302  // than doing it by calling removeAction on the toolbar after createGUI. Both
303  // solutions work visually, but only modifying the XML ensures that the
304  // actions don't appear in "edit toolbars". #207296
305  const QStringList hideActions = plugin->invisibleToolbarActions();
306  //kDebug() << "Hiding actions" << hideActions << "from" << pluginName << part;
307  QDomDocument doc = part->domDocument();
308  QDomElement docElem = doc.documentElement();
309  // 1. Iterate over containers
310  for ( QDomElement containerElem = docElem.firstChildElement();
311  !containerElem.isNull(); containerElem = containerElem.nextSiblingElement() ) {
312  if ( QString::compare( containerElem.tagName(), "ToolBar", Qt::CaseInsensitive ) == 0 ) {
313  // 2. Iterate over actions in toolbars
314  QDomElement actionElem = containerElem.firstChildElement();
315  while ( !actionElem.isNull() ) {
316  QDomElement nextActionElem = actionElem.nextSiblingElement();
317  if ( QString::compare( actionElem.tagName(), "Action", Qt::CaseInsensitive ) == 0 ) {
318  //kDebug() << "Looking at action" << actionElem.attribute("name");
319  if ( hideActions.contains( actionElem.attribute( "name" ) ) ) {
320  //kDebug() << "REMOVING";
321  containerElem.removeChild( actionElem );
322  }
323  }
324  actionElem = nextActionElem;
325  }
326  }
327  }
328 
329  // Possible optimization: we could do all the above and the writing below
330  // only when (newAppFile does not exist) or (version of domDocument > version of newAppFile) (*)
331  // This requires parsing newAppFile when it exists, though, and better use
332  // the fast kdeui code for that rather than a full QDomDocument.
333  // (*) or when invisibleToolbarActions() changes :)
334 
335  const QString newAppFile =
336  KStandardDirs::locateLocal( "data", "kontact/default-" + pluginName + ".rc" );
337  QFile file( newAppFile );
338  if ( !file.open( QFile::WriteOnly ) ) {
339  kWarning() << "error writing to" << newAppFile;
340  return;
341  }
342  file.write( doc.toString().toUtf8() );
343  file.flush();
344 
345  setXmlFiles();
346 }
347 
348 void Plugin::Private::setXmlFiles()
349 {
350  const QString newAppFile =
351  KStandardDirs::locateLocal( "data", "kontact/default-" + pluginName + ".rc" );
352  const QString localFile =
353  KStandardDirs::locateLocal( "data", "kontact/local-" + pluginName + ".rc" );
354  if ( part->xmlFile() != newAppFile || part->localXMLFile() != localFile ) {
355  part->replaceXMLFile( newAppFile, localFile );
356  }
357 }
358 //@endcond
359 
360 void Plugin::slotConfigUpdated()
361 {
362  configUpdated();
363 }
364 
365 void Plugin::bringToForeground()
366 {
367  if ( d->executableName.isEmpty() ) {
368  return;
369  }
370 #ifdef Q_WS_WIN
371  KPIMUtils::activateWindowForProcess( d->executableName );
372 #else
373  KRun::runCommand( d->executableName, 0 );
374 #endif
375 }
376 
377 Summary *Plugin::createSummaryWidget( QWidget *parent )
378 {
379  Q_UNUSED( parent );
380  return 0;
381 }
382 
383 bool Plugin::showInSideBar() const
384 {
385  return d->hasPart;
386 }
387 
388 void Plugin::setShowInSideBar( bool hasPart )
389 {
390  d->hasPart = hasPart;
391 }
392 
393 bool Plugin::queryClose() const
394 {
395  return true;
396 }
397 
398 void Plugin::setDisabled( bool disabled )
399 {
400  d->disabled = disabled;
401 }
402 
403 bool Plugin::disabled() const
404 {
405  return d->disabled;
406 }
407 
408 void Plugin::virtual_hook( int, void * )
409 {
410  //BASE::virtual_hook( id, data );
411 }
412 
413 #include "plugin.moc"
414 
415 // 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 Tue Dec 4 2012 14:35:56 by doxygen 1.8.1.2 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.9.4 API Reference

Skip menu "kdepimlibs-4.9.4 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