• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kontact

  • sources
  • kde-4.14
  • kdepim
  • kontact
  • src
mainwindow.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KDE Kontact.
3 
4  Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
5  Copyright (c) 2002-2005 Daniel Molkentin <molkentin@kde.org>
6  Copyright (c) 2003-2005 Cornelius Schumacher <schumacher@kde.org>
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License along
19  with this program; if not, write to the Free Software Foundation, Inc.,
20  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22 
23 #include <config-enterprise.h>
24 
25 #include "mainwindow.h"
26 #include "aboutdialog.h"
27 #include "prefs.h"
28 #include "iconsidepane.h"
29 #include "kontactconfiguredialog.h"
30 using namespace Kontact;
31 
32 #include <unistd.h>
33 
34 #include <libkdepim/misc/broadcaststatus.h>
35 #include <libkdepim/progresswidget/progressstatusbarwidget.h>
36 #include <libkdepim/progresswidget/statusbarprogresswidget.h>
37 
38 #include <KontactInterface/Core>
39 #include <KontactInterface/Plugin>
40 
41 #include <KPIMUtils/KFileIO>
42 
43 #include <KActionCollection>
44 #include <KActionMenu>
45 #include <KApplication>
46 #include <KComponentData>
47 #include <KConfigGroup>
48 #include <KDBusServiceStarter>
49 #include <KDebug>
50 #include <KEditToolBar>
51 #include <KHelpMenu>
52 #include <KWebView>
53 #include <KMessageBox>
54 #include <KPluginInfo>
55 #include <KRun>
56 #include <KServiceTypeTrader>
57 #include <KShortcutsDialog>
58 #include <KSqueezedTextLabel>
59 #include <KStandardAction>
60 #include <KStandardDirs>
61 #include <KStatusBar>
62 #include <KTipDialog>
63 #include <KToolBar>
64 #include <KToolInvocation>
65 #include <KXMLGUIFactory>
66 #include <KParts/PartManager>
67 #include <KSettings/Dispatcher>
68 #include <KSettings/Dialog>
69 #include <KSycoca>
70 
71 #include <QDBusConnection>
72 #include <QSplitter>
73 #include <QStackedWidget>
74 #include <QTimer>
75 #include <QVBoxLayout>
76 #include <QWebSettings>
77 #include <QShortcut>
78 
79 // Define the maximum time Kontact waits for KSycoca to become available.
80 static const int KSYCOCA_WAIT_TIMEOUT = 10;
81 
82 // This class extends the normal KDBusServiceStarter.
83 //
84 // When a service start is requested, it asks all plugins
85 // to create their dbus interfaces in addition to the normal
86 // way of starting a service.
87 class ServiceStarter : public KDBusServiceStarter
88 {
89 public:
90 
91  virtual int startServiceFor( const QString &serviceType,
92  const QString &constraint = QString(),
93  QString *error = 0, QString *dbusService = 0,
94  int flags = 0 );
95 
96  // We need to keep track of the plugins which are loaded, so pass a pointer
97  // to the plugin list here. Be sure to reset it back to 0 with
98  // setPluginList() as soon as the list gets destroyed.
99  ServiceStarter( PluginList *pluginList ) {
100  mPlugins = pluginList;
101  }
102 
103  static void setPluginList( PluginList *pluginList ) {
104  mPlugins = pluginList;
105  }
106 
107 protected:
108 
109  virtual ~ServiceStarter() {}
110  static PluginList *mPlugins;
111 };
112 
113 PluginList *ServiceStarter::mPlugins = 0;
114 
115 int ServiceStarter::startServiceFor( const QString &serviceType,
116  const QString &constraint,
117  QString *error, QString *dbusService,
118  int flags )
119 {
120  if ( mPlugins ) {
121  PluginList::ConstIterator end = mPlugins->constEnd();
122  for ( PluginList::ConstIterator it = mPlugins->constBegin(); it != end; ++it ) {
123  if ( (*it)->createDBUSInterface( serviceType ) ) {
124  kDebug() << "found interface for" << serviceType;
125  if ( dbusService ) {
126  *dbusService = (*it)->registerClient();
127  }
128  return 0;
129  }
130  }
131  }
132 
133  kDebug() << "Didn't find dbus interface, falling back to external process";
134  return KDBusServiceStarter::startServiceFor( serviceType, constraint,
135  error, dbusService, flags );
136 }
137 
138 MainWindow::MainWindow()
139  : KontactInterface::Core(), mSplitter( 0 ), mCurrentPlugin( 0 ), mAboutDialog( 0 ),
140  mReallyClose( false ), mSyncActionsEnabled( true )
141 {
142  // The ServiceStarter created here will be deleted by the KDbusServiceStarter
143  // base class, which is a global static.
144  new ServiceStarter( &mPlugins );
145 
146  QDBusConnection::sessionBus().registerObject(
147  QLatin1String("/KontactInterface"), this, QDBusConnection::ExportScriptableSlots );
148 
149  // Set this to be the group leader for all subdialogs - this means
150  // modal subdialogs will only affect this dialog, not the other windows
151  setAttribute( Qt::WA_GroupLeader );
152 
153  initGUI();
154  initObject();
155 
156  mSidePane->setMaximumWidth( mSidePane->sizeHint().width() );
157  mSidePane->setMinimumWidth( mSidePane->sizeHint().width() );
158 
159  factory()->plugActionList( this, QLatin1String( "navigator_actionlist" ), mActionPlugins );
160 
161  restoreWindowSize( KConfigGroup( KGlobal::config(), "MainWindow" ) );
162  setAutoSaveSettings();
163 }
164 
165 void MainWindow::initGUI()
166 {
167  initWidgets();
168  setupActions();
169  setHelpMenuEnabled( false );
170  KHelpMenu *helpMenu = new KHelpMenu( this, 0, true, actionCollection() );
171  connect( helpMenu, SIGNAL(showAboutApplication()), SLOT(showAboutDialog()) );
172 
173  KStandardAction::keyBindings( this, SLOT(configureShortcuts()), actionCollection() );
174  KStandardAction::configureToolbars( this, SLOT(configureToolbars()), actionCollection() );
175  setXMLFile( QLatin1String("kontactui.rc") );
176 
177  setStandardToolBarMenuEnabled( true );
178 
179  createGUI( 0 );
180 
181  KToolBar *navigatorToolBar = findToolBar( "navigatorToolBar" );
182  if ( navigatorToolBar ) {
183  if ( layoutDirection() == Qt::LeftToRight ) {
184  navigatorToolBar->setLayoutDirection( Qt::RightToLeft );
185  } else {
186  navigatorToolBar->setLayoutDirection( Qt::LeftToRight );
187  }
188  Q_ASSERT( navigatorToolBar->sizeHint().isValid() );
189  navigatorToolBar->setMinimumWidth( navigatorToolBar->sizeHint().width() );
190  } else {
191  kError() << "Unable to find navigatorToolBar, probably kontactui.rc is missing";
192  }
193 }
194 
195 void MainWindow::waitForKSycoca()
196 {
197  int i = 0;
198  while ( i < KSYCOCA_WAIT_TIMEOUT ) {
199  if ( KSycoca::isAvailable() ) {
200  return;
201  }
202  // When KSycoca is not availabe that usually means Kontact
203  // was started before kded is done with it's first run
204  // we want to block Kontact execution to
205  // give Kded time to initialize and create the
206  // System Configuration database necessary for further
207  // Kontact startup
208  kDebug() << "Waiting for KSycoca";
209  sleep(1);
210  ++i;
211  }
212  // This should only happen if the distribution is broken
213  kFatal() << "KSycoca unavailable. Kontact will be unable to find plugins.";
214 }
215 
216 void MainWindow::initObject()
217 {
218  if ( !KSycoca::isAvailable() ) {
219  waitForKSycoca();
220  }
221  KService::List offers = KServiceTypeTrader::self()->query(
222  QString::fromLatin1( "Kontact/Plugin" ),
223  QString::fromLatin1( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );
224  mPluginInfos = KPluginInfo::fromServices(
225  offers, KConfigGroup( Prefs::self()->config(), "Plugins" ) );
226 
227  KPluginInfo::List::Iterator it;
228  KPluginInfo::List::Iterator end( mPluginInfos.end() );
229 
230  for ( it = mPluginInfos.begin(); it != end; ++it ) {
231  it->load();
232  }
233 
234  // prepare the part manager
235  mPartManager = new KParts::PartManager( this );
236  connect( mPartManager, SIGNAL(activePartChanged(KParts::Part*)),
237  this, SLOT(slotActivePartChanged(KParts::Part*)) );
238 
239  loadPlugins();
240 
241  if ( mSidePane ) {
242  mSidePane->updatePlugins();
243  }
244 
245  KSettings::Dispatcher::registerComponent( componentData(), this, "updateConfig" );
246 
247  loadSettings();
248 
249  statusBar()->show();
250 
251  QTimer::singleShot( 200, this, SLOT(slotShowTipOnStart()) );
252 
253  // done initializing
254  slotShowStatusMsg( QString::null ); //krazy:exclude=nullstrassign for old broken gcc
255 
256  connect( KPIM::BroadcastStatus::instance(), SIGNAL(statusMsg(QString)),
257  this, SLOT(slotShowStatusMsg(QString)) );
258 
259  // launch commandline specified module if any
260  activateInitialPluginModule();
261 
262  if ( Prefs::lastVersionSeen() == KGlobal::mainComponent().aboutData()->version() ) {
263  selectPlugin( mCurrentPlugin );
264  }
265 
266  paintAboutScreen( introductionString() );
267  Prefs::setLastVersionSeen( KGlobal::mainComponent().aboutData()->version() );
268 }
269 
270 MainWindow::~MainWindow()
271 {
272  if ( mCurrentPlugin ) {
273  saveMainWindowSettings(
274  KGlobal::config()->group(
275  QString::fromLatin1( "MainWindow%1" ).arg( mCurrentPlugin->identifier() ) ) );
276  }
277 
278  createGUI( 0 );
279  ServiceStarter::setPluginList( 0 );
280  saveSettings();
281 
282  //QList<KParts::Part*> parts = mPartManager->parts();
283 
284  // Q_FOREACH( KParts::Part *p, parts ) {
285  // delete p;
286  // p = 0;
287  // }
288 
289  Prefs::self()->writeConfig();
290 
291  // During deletion of plugins, we should not access the plugin list (bug #182176)
292  delete mSidePane;
293 
294  PluginList::ConstIterator end = mPlugins.constEnd();
295  for ( PluginList::ConstIterator it = mPlugins.constBegin(); it != end; ++it ) {
296  delete *it;
297  }
298 }
299 
300 // Called by main().
301 void MainWindow::setInitialActivePluginModule( const QString &module )
302 {
303  if (mInitialActiveModule != module) {
304  mInitialActiveModule = module;
305  activateInitialPluginModule();
306  }
307 }
308 
309 bool MainWindow::pluginActionWeightLessThan( const QAction *left, const QAction *right )
310 {
311  // Since this lessThan method is used only for the toolbar (which is on
312  // the inverse layout direction than the rest of the system), we add the
313  // elements on the exactly inverse order. (ereslibre)
314  return !pluginWeightLessThan( left->data().value<KontactInterface::Plugin*>(),
315  right->data().value<KontactInterface::Plugin*>() );
316 }
317 
318 bool MainWindow::pluginWeightLessThan( const KontactInterface::Plugin *left,
319  const KontactInterface::Plugin *right )
320 {
321  return left->weight() < right->weight();
322 }
323 
324 void MainWindow::activateInitialPluginModule()
325 {
326  if ( !mInitialActiveModule.isEmpty() && !mPlugins.isEmpty() ) {
327  PluginList::ConstIterator end = mPlugins.constEnd();
328  for ( PluginList::ConstIterator it = mPlugins.constBegin(); it != end; ++it ) {
329  if ( !(*it)->identifier().isEmpty() &&
330  (*it)->identifier().contains( mInitialActiveModule ) ) {
331  selectPlugin( *it );
332  return;
333  }
334  }
335  }
336 }
337 
338 void MainWindow::initWidgets()
339 {
340  QWidget *mTopWidget = new QWidget( this );
341  QVBoxLayout *layout = new QVBoxLayout;
342  layout->setMargin(0);
343  layout->setSpacing(0);
344  mTopWidget->setLayout( layout );
345  setCentralWidget( mTopWidget );
346 
347  mSplitter = new QSplitter( mTopWidget );
348  layout->addWidget( mSplitter );
349  mSidePane = new IconSidePane( this, mSplitter );
350  /*
351  // don't occupy screen estate on load
352 
353  QList<int> sizes;
354  sizes << 0;
355  mSplitter->setSizes(sizes);
356 */
357  connect( mSidePane, SIGNAL(pluginSelected(KontactInterface::Plugin*)),
358  SLOT(selectPlugin(KontactInterface::Plugin*)) );
359 
360  mPartsStack = new QStackedWidget( mSplitter );
361  mPartsStack->layout()->setSpacing( 0 );
362 
363  initAboutScreen();
364 
365  const QString loading =
366  i18nc( "@item",
367  "<h2 style='text-align:center; margin-top: 0px; margin-bottom: 0px'>%1</h2>",
368  i18nc( "@item:intext", "Loading Kontact..." ) );
369 
370  paintAboutScreen( loading );
371 
372  KPIM::ProgressStatusBarWidget * progressStatusBarWidget = new KPIM::ProgressStatusBarWidget(statusBar(), this);
373 
374  mStatusMsgLabel =
375  new KSqueezedTextLabel( i18nc( "@info:status", " Initializing..." ), statusBar() );
376  mStatusMsgLabel->setTextElideMode( Qt::ElideRight );
377  mStatusMsgLabel->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
378 
379  statusBar()->addWidget( mStatusMsgLabel, 10 );
380  statusBar()->addPermanentWidget( progressStatusBarWidget->littleProgress(), 0 );
381 
382  mSplitter->setCollapsible( 1, false );
383 }
384 
385 void MainWindow::paintAboutScreen( const QString &msg )
386 {
387  QString location = KStandardDirs::locate( "data", QLatin1String("kontact/about/main.html") );
388  QString content = QLatin1String(KPIMUtils::kFileToByteArray( location ));
389  content = content.arg( QLatin1String("file:") + KStandardDirs::locate(
390  "data", QLatin1String("kdeui/about/kde_infopage.css") ) );
391  if ( QApplication::isRightToLeft() ) {
392  content =
393  content.arg( QLatin1String("@import \"%1\";") ).
394  arg( QLatin1String("file:") + KStandardDirs::locate(
395  "data", QLatin1String("kdeui/about/kde_infopage_rtl.css") ) );
396  } else {
397  content = content.arg( QString() );
398  }
399 
400  mIntroPart->setHtml(
401  content.arg( QFont().pointSize() + 2 ).
402  arg( i18nc( "@item:intext", "KDE Kontact" ) ).
403  arg( i18nc( "@item:intext", "Get Organized!" ) ).
404  arg( i18nc( "@item:intext", "The KDE Personal Information Management Suite" ) ).
405  arg( msg ) );
406 }
407 
408 void MainWindow::initAboutScreen()
409 {
410  KHBox *introbox = new KHBox( mPartsStack );
411  mPartsStack->addWidget( introbox );
412  mPartsStack->setCurrentWidget( introbox );
413  mIntroPart = new KWebView( introbox );
414  mIntroPart->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
415  mIntroPart->setFocusPolicy( Qt::WheelFocus );
416  // Let's better be paranoid and disable plugins (it defaults to enabled):
417  mIntroPart->settings()->setAttribute( QWebSettings::JavascriptEnabled, false );
418  mIntroPart->settings()->setAttribute( QWebSettings::JavaEnabled, false );
419  mIntroPart->settings()->setAttribute( QWebSettings::PluginsEnabled, false );
420 
421  connect( mIntroPart->page(), SIGNAL(linkClicked(QUrl)), this,
422  SLOT(slotOpenUrl(QUrl)), Qt::QueuedConnection );
423 }
424 
425 void MainWindow::setupActions()
426 {
427  actionCollection()->addAction( KStandardAction::Quit, this, SLOT(slotQuit()) );
428 
429  mNewActions = new KActionMenu(
430  i18nc( "@title:menu create new pim items (message,calendar,to-do,etc.)", "New" ), this );
431  actionCollection()->addAction( QLatin1String("action_new"), mNewActions );
432  mNewActions->setShortcut( KStandardShortcut::openNew() );
433  connect( mNewActions, SIGNAL(triggered(bool)), this, SLOT(slotNewClicked()) );
434 
435  // If the user is using disconnected imap mail folders as groupware, we add
436  // plugins' Synchronize actions to the toolbar which trigger an imap sync.
437  // Otherwise it's redundant and misleading.
438  KConfig _config( QLatin1String("kmail2rc") );
439  KConfigGroup config( &_config, "Groupware" );
440 #if defined(KDEPIM_ENTERPRISE_BUILD)
441  bool defGW = config.readEntry( "Enabled", true );
442 #else
443  bool defGW = config.readEntry( "Enabled", false );
444 #endif
445  KConfig *_cfg = Prefs::self()->config();
446  KConfigGroup cfg( _cfg, "Kontact Groupware Settings" );
447  mSyncActionsEnabled = cfg.readEntry( "GroupwareMailFoldersEnabled", defGW );
448 
449  if ( mSyncActionsEnabled ) {
450  mSyncActions = new KActionMenu(
451  KIcon( QLatin1String("view-refresh") ),
452  i18nc( "@title:menu synchronize pim items (message,calendar,to-do,etc.)", "Sync" ), this );
453  actionCollection()->addAction( QLatin1String("action_sync"), mSyncActions );
454  mSyncActions->setShortcut( KStandardShortcut::reload() );
455  connect( mSyncActions, SIGNAL(triggered(bool)), this, SLOT(slotSyncClicked()) );
456  }
457 
458  KAction *action =
459  new KAction( KIcon( QLatin1String("configure") ),
460  i18nc( "@action:inmenu", "Configure Kontact..." ), this );
461  action->setHelpText(
462  i18nc( "@info:status", "Configure Kontact" ) );
463  action->setWhatsThis(
464  i18nc( "@info:whatsthis",
465  "You will be presented with a dialog where you can configure Kontact." ) );
466  actionCollection()->addAction( QLatin1String("settings_configure_kontact"), action );
467  connect( action, SIGNAL(triggered(bool)), SLOT(slotPreferences()) );
468 
469  action =
470  new KAction( KIcon( QLatin1String("kontact") ),
471  i18nc( "@action:inmenu", "&Kontact Introduction" ), this );
472  action->setHelpText(
473  i18nc( "@info:status", "Show the Kontact Introduction page" ) );
474  action->setWhatsThis(
475  i18nc( "@info:whatsthis",
476  "Choose this option to see the Kontact Introduction page." ) );
477  actionCollection()->addAction( QLatin1String("help_introduction"), action );
478  connect( action, SIGNAL(triggered(bool)), SLOT(slotShowIntroduction()) );
479 
480  action =
481  new KAction( KIcon( QLatin1String("ktip") ),
482  i18nc( "@action:inmenu", "&Tip of the Day" ), this );
483  action->setHelpText(
484  i18nc( "@info:status", "Show the Tip-of-the-Day dialog" ) );
485  action->setWhatsThis(
486  i18nc( "@info:whatsthis",
487  "You will be presented with a dialog showing small tips to help "
488  "you use this program more effectively." ) );
489  actionCollection()->addAction( QLatin1String("help_tipofday"), action );
490  connect( action, SIGNAL(triggered(bool)), SLOT(slotShowTip()) );
491  //TODO 4.12: add description
492  QShortcut *shortcut = new QShortcut( QKeySequence(Qt::Key_F9), this );
493  connect(shortcut, SIGNAL(activated()), this, SLOT(slotShowHideSideBar()));
494 }
495 
496 bool MainWindow::isPluginLoaded( const KPluginInfo &info )
497 {
498  return ( pluginFromInfo( info ) != 0 );
499 }
500 
501 KontactInterface::Plugin *MainWindow::pluginFromInfo( const KPluginInfo &info )
502 {
503  PluginList::ConstIterator end = mPlugins.constEnd();
504  for ( PluginList::ConstIterator it = mPlugins.constBegin(); it != end; ++it ) {
505  if ( (*it)->identifier() == info.pluginName() ) {
506  return *it;
507  }
508  }
509  return 0;
510 }
511 
512 void MainWindow::loadPlugins()
513 {
514  QList<KontactInterface::Plugin *> plugins;
515 
516  int i;
517  KPluginInfo::List::ConstIterator it;
518  KPluginInfo::List::ConstIterator end( mPluginInfos.constEnd() );
519  for ( it = mPluginInfos.constBegin(); it != end; ++it ) {
520  if ( !it->isPluginEnabled() ) {
521  continue;
522  }
523 
524  KontactInterface::Plugin *plugin = 0;
525  if ( isPluginLoaded( *it ) ) {
526  plugin = pluginFromInfo( *it );
527  if ( plugin ) {
528  plugin->configUpdated();
529  }
530  continue;
531  }
532 
533  kDebug() << "Loading Plugin:" << it->name();
534  QString error;
535  plugin =
536  it->service()->createInstance<KontactInterface::Plugin>( this, QVariantList(), &error );
537 
538  if ( !plugin ) {
539  kDebug() << "Unable to create plugin for" << it->name() << error;
540  continue;
541  }
542 
543  plugin->setIdentifier( it->pluginName() );
544  plugin->setTitle( it->name() );
545  plugin->setIcon( it->icon() );
546 
547  QVariant libNameProp = it->property( QLatin1String("X-KDE-KontactPartLibraryName") );
548  QVariant exeNameProp = it->property( QLatin1String("X-KDE-KontactPartExecutableName") );
549  QVariant loadOnStart = it->property( QLatin1String("X-KDE-KontactPartLoadOnStart") );
550  QVariant hasPartProp = it->property( QLatin1String("X-KDE-KontactPluginHasPart") );
551 
552  if ( !loadOnStart.isNull() && loadOnStart.toBool() ) {
553  mDelayedPreload.append( plugin );
554  }
555 
556  kDebug() << "LIBNAMEPART:" << libNameProp.toString();
557 
558  plugin->setPartLibraryName( libNameProp.toString().toUtf8() );
559  plugin->setExecutableName( exeNameProp.toString() );
560  if ( hasPartProp.isValid() ) {
561  plugin->setShowInSideBar( hasPartProp.toBool() );
562  }
563 
564  for ( i = 0; i < plugins.count(); ++i ) {
565  KontactInterface::Plugin *p = plugins.at( i );
566  if ( plugin->weight() < p->weight() ) {
567  break;
568  }
569  }
570  plugins.insert( i, plugin );
571 
572  }
573 
574  const int numberOfPlugins( plugins.count() );
575  for ( i = 0; i < numberOfPlugins; ++i ) {
576  KontactInterface::Plugin *plugin = plugins.at( i );
577 
578  const QList<KAction*> actionList = plugin->newActions();
579  QList<KAction*>::const_iterator listIt;
580  QList<KAction*>::const_iterator end( actionList.end() );
581 
582  for ( listIt = actionList.begin(); listIt != end; ++listIt ) {
583  kDebug() << QLatin1String("Plugging New actions") << (*listIt)->objectName();
584  mNewActions->addAction( (*listIt) );
585  }
586 
587  if ( mSyncActionsEnabled ) {
588  Q_FOREACH ( KAction *listIt, plugin->syncActions() ) {
589  kDebug() << QLatin1String("Plugging Sync actions") << listIt->objectName();
590  mSyncActions->addAction( listIt );
591  }
592  }
593  addPlugin( plugin );
594  }
595 
596  const bool state = ( !mPlugins.isEmpty() );
597  mNewActions->setEnabled( state );
598  if ( mSyncActionsEnabled ) {
599  mSyncActions->setEnabled( state );
600  }
601 }
602 
603 void MainWindow::unloadPlugins()
604 {
605  KPluginInfo::List::ConstIterator end = mPluginInfos.constEnd();
606  KPluginInfo::List::ConstIterator it;
607  for ( it = mPluginInfos.constBegin(); it != end; ++it ) {
608  if ( !it->isPluginEnabled() ) {
609  removePlugin( *it );
610  }
611  }
612 }
613 
614 void MainWindow::updateShortcuts()
615 {
616  ActionPluginList::ConstIterator end = mActionPlugins.constEnd();
617  ActionPluginList::ConstIterator it;
618  int i = 0;
619  for ( it = mActionPlugins.constBegin(); it != end; ++it ) {
620  KAction *action = static_cast<KAction*>( *it );
621  const QString shortcut = QString::fromLatin1( "Ctrl+%1" ).arg( mActionPlugins.count() - i );
622  action->setShortcut( KShortcut( shortcut ) );
623  ++i;
624  }
625  factory()->plugActionList( this, QLatin1String( "navigator_actionlist" ), mActionPlugins );
626 }
627 
628 bool MainWindow::removePlugin( const KPluginInfo &info )
629 {
630  PluginList::Iterator end = mPlugins.end();
631  for ( PluginList::Iterator it = mPlugins.begin(); it != end; ++it ) {
632  KontactInterface::Plugin *plugin = *it;
633  if ( ( *it )->identifier() == info.pluginName() ) {
634  QList<KAction*> actionList = plugin->newActions();
635  QList<KAction*>::const_iterator listIt;
636  QList<KAction*>::const_iterator listEnd( actionList.constEnd() );
637  for ( listIt = actionList.constBegin(); listIt != listEnd; ++listIt ) {
638  kDebug() << QLatin1String("Unplugging New actions") << (*listIt)->objectName();
639  mNewActions->removeAction( *listIt );
640  }
641 
642  if ( mSyncActionsEnabled ) {
643  actionList = plugin->syncActions();
644  for ( listIt = actionList.constBegin(); listIt != actionList.constEnd(); ++listIt ) {
645  kDebug() << QLatin1String("Unplugging Sync actions") << (*listIt)->objectName();
646  mSyncActions->removeAction( *listIt );
647  }
648  }
649  removeChildClient( plugin );
650 
651  if ( mCurrentPlugin == plugin ) {
652  mCurrentPlugin = 0;
653  createGUI( 0 );
654  }
655 
656  plugin->deleteLater(); // removes the part automatically
657  mPlugins.erase( it );
658  if ( plugin->showInSideBar() ) {
659  QAction *q = mPluginAction[plugin]; // remove KAction, to free the shortcut for later use
660  mActionPlugins.removeAll( q );
661  mPluginAction.remove(plugin);
662  delete q;
663  }
664 
665  if ( mCurrentPlugin == 0 ) {
666  PluginList::Iterator it;
667  PluginList::Iterator pluginEnd( mPlugins.end() );
668  for ( it = mPlugins.begin(); it != pluginEnd; ++it ) {
669  if ( (*it)->showInSideBar() ) {
670  selectPlugin( *it );
671  return true;
672  }
673  }
674  }
675  return true;
676  }
677 
678  }
679 
680  return false;
681 }
682 
683 void MainWindow::addPlugin( KontactInterface::Plugin *plugin )
684 {
685  kDebug();
686 
687  mPlugins.append( plugin );
688 
689  if ( plugin->showInSideBar() ) {
690  KAction *action = new KAction( KIcon( plugin->icon() ), plugin->title(), this );
691  action->setHelpText(
692  i18nc( "@info:status", "Plugin %1", plugin->title() ) );
693  action->setWhatsThis(
694  i18nc( "@info:whatsthis",
695  "Switch to plugin %1", plugin->title() ) );
696  action->setCheckable( true );
697  action->setData( QVariant::fromValue( plugin ) ); // on the slot we can decode
698  // which action was triggered
699  connect( action, SIGNAL(triggered(bool)), SLOT(slotActionTriggered()) );
700  actionCollection()->addAction( plugin->title(), action );
701  mActionPlugins.append( action );
702  mPluginAction.insert( plugin, action );
703  }
704 
705  // merge the plugins GUI into the main window
706  insertChildClient( plugin );
707 
708  // sort the action plugins again and reset shortcuts. If we removed and then readded some plugins
709  // we need to take in count their weights for setting shortcuts again
710  qSort( mActionPlugins.begin(), mActionPlugins.end(), pluginActionWeightLessThan );
711  qSort( mPlugins.begin(), mPlugins.end(), pluginWeightLessThan );
712  int i = 0;
713  foreach ( QAction *qaction, mActionPlugins ) {
714  KAction *action = static_cast<KAction*>( qaction );
715  QString shortcut = QString::fromLatin1( "Ctrl+%1" ).arg( mActionPlugins.count() - i );
716  action->setShortcut( KShortcut( shortcut ) );
717  ++i;
718  }
719 }
720 
721 void MainWindow::partLoaded( KontactInterface::Plugin *plugin, KParts::ReadOnlyPart *part )
722 {
723  Q_UNUSED( plugin );
724 
725  // See if we have this part already (e.g. due to two plugins sharing it)
726  if ( mPartsStack->indexOf( part->widget() ) != -1 ) {
727  return;
728  }
729 
730  mPartsStack->addWidget( part->widget() );
731 
732  mPartManager->addPart( part, false );
733  // Workaround for KParts misbehavior: addPart calls show!
734  part->widget()->hide();
735 }
736 
737 void MainWindow::slotActivePartChanged( KParts::Part *part )
738 {
739  if ( !part ) {
740  createGUI( 0 );
741  return;
742  }
743 
744  kDebug() << QLatin1String("Part activated:") << part
745  << QLatin1String("with stack id.")<< mPartsStack->indexOf( part->widget() );
746 
747  statusBar()->clearMessage();
748 }
749 
750 void MainWindow::slotNewClicked()
751 {
752  if ( !mCurrentPlugin->newActions().isEmpty() ) {
753  mCurrentPlugin->newActions().first()->trigger();
754  } else {
755  PluginList::Iterator it;
756  PluginList::Iterator end( mPlugins.end() );
757  for ( it = mPlugins.begin(); it != end; ++it ) {
758  if ( !(*it)->newActions().isEmpty() ) {
759  (*it)->newActions().first()->trigger();
760  return;
761  }
762  }
763  }
764 }
765 
766 void MainWindow::slotSyncClicked()
767 {
768  if ( !mCurrentPlugin->syncActions().isEmpty() ) {
769  mCurrentPlugin->syncActions().first()->trigger();
770  } else {
771  PluginList::Iterator it;
772  PluginList::Iterator end( mPlugins.end() );
773  for ( it = mPlugins.begin(); it != end; ++it ) {
774  if ( !(*it)->syncActions().isEmpty() ) {
775  (*it)->syncActions().first()->trigger();
776  return;
777  }
778  }
779  }
780 }
781 
782 KToolBar *MainWindow::findToolBar( const char *name )
783 {
784  // like KMainWindow::toolBar, but which doesn't create the toolbar if not found
785  return findChild<KToolBar *>( QLatin1String(name) );
786 }
787 
788 void MainWindow::selectPlugin( KontactInterface::Plugin *plugin )
789 {
790  if ( !plugin ) {
791  return;
792  }
793 
794  if ( plugin->isRunningStandalone() ) {
795  statusBar()->showMessage(
796  i18nc( "@info:status",
797  "Application is running standalone. Foregrounding..." ), 1000 );
798  plugin->bringToForeground();
799  return;
800  }
801 
802  QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
803 
804  if ( mCurrentPlugin ) {
805  saveMainWindowSettings(
806  KGlobal::config()->group(
807  QString::fromLatin1( "MainWindow%1" ).arg( mCurrentPlugin->identifier() ) ) );
808  }
809 
810  KParts::Part *part = plugin->part();
811 
812  if ( !part ) {
813  QApplication::restoreOverrideCursor();
814  KMessageBox::error(
815  this,
816  i18nc( "@info",
817  "Cannot load part for %1.",
818  plugin->title() ) + QLatin1Char('\n') + lastErrorMessage() );
819  plugin->setDisabled( true );
820  mSidePane->updatePlugins();
821  return;
822  }
823 
824  if ( mCurrentPlugin ) {
825  KAction *action = mPluginAction[ mCurrentPlugin ];
826  if ( action ) {
827  action->setChecked( false );
828  }
829  }
830  KAction *selectedPluginAction = mPluginAction[ plugin ];
831  if ( selectedPluginAction ) {
832  selectedPluginAction->setChecked( true );
833  }
834 
835  // store old focus widget
836  QWidget *focusWidget = kapp->focusWidget();
837  if ( mCurrentPlugin && focusWidget ) {
838  // save the focus widget only when it belongs to the activated part
839  QWidget *parent = focusWidget->parentWidget();
840  while ( parent ) {
841  if ( parent == mCurrentPlugin->part()->widget() ) {
842  mFocusWidgets.insert( mCurrentPlugin->identifier(), QPointer<QWidget>( focusWidget ) );
843  }
844  parent = parent->parentWidget();
845  }
846  }
847 
848  if ( mSidePane ) {
849  mSidePane->setCurrentPlugin( plugin->identifier() );
850  }
851 
852  plugin->aboutToSelect();
853 
854  mPartManager->setActivePart( part );
855  QWidget *view = part->widget();
856  Q_ASSERT( view );
857 
858  if ( view ) {
859  mPartsStack->setCurrentWidget( view );
860  view->show();
861 
862  if ( !mFocusWidgets.isEmpty() && mFocusWidgets.contains( plugin->identifier() ) ) {
863  focusWidget = mFocusWidgets[ plugin->identifier() ];
864  if ( focusWidget ) {
865  focusWidget->setFocus();
866  }
867  } else {
868  view->setFocus();
869  }
870 
871  mCurrentPlugin = plugin;
872 
873  QAction *newAction = 0;
874  if ( !plugin->newActions().isEmpty() ) {
875  newAction = plugin->newActions().first();
876  }
877 
878  QAction *syncAction = 0;
879  if ( !plugin->syncActions().isEmpty() ) {
880  syncAction = plugin->syncActions().first();
881  }
882 
883  createGUI( plugin->part() );
884  plugin->shortcutChanged();
885 
886 
887  setCaption( i18nc( "@title:window Plugin dependent window title",
888  "%1 - Kontact", plugin->title() ) );
889 
890  if ( newAction ) {
891  mNewActions->setIcon( newAction->icon() );
892  static_cast<QAction*>( mNewActions )->setText( newAction->text() );
893  mNewActions->setWhatsThis( newAction->whatsThis() );
894  } else { // we'll use the action of the first plugin which offers one
895  PluginList::Iterator it;
896  PluginList::Iterator end(mPlugins.end());
897  for ( it = mPlugins.begin(); it != end; ++it ) {
898  if ( !(*it)->newActions().isEmpty() ) {
899  newAction = (*it)->newActions().first();
900  }
901  if ( newAction ) {
902  static_cast<QAction*>( mNewActions )->setIcon( newAction->icon() );
903  mNewActions->setText( newAction->text() );
904  mNewActions->setWhatsThis( newAction->whatsThis() );
905  break;
906  }
907  }
908  }
909 
910  if ( mSyncActionsEnabled ) {
911  if ( syncAction ) {
912  mSyncActions->setIcon( syncAction->icon() );
913  static_cast<QAction*>( mSyncActions )->setText( syncAction->text() );
914  } else { // we'll use the action of the first plugin which offers one
915  PluginList::Iterator it;
916  PluginList::Iterator end(mPlugins.end());
917  for ( it = mPlugins.begin(); it != end; ++it ) {
918  if ( !(*it)->syncActions().isEmpty() ) {
919  syncAction = (*it)->syncActions().first();
920  }
921  if ( syncAction ) {
922  static_cast<QAction*>( mSyncActions )->setIcon( syncAction->icon() );
923  mSyncActions->setText( syncAction->text() );
924  break;
925  }
926  }
927  }
928  }
929  }
930 
931  KToolBar *navigatorToolBar = findToolBar( "navigatorToolBar" );
932  if ( navigatorToolBar && !navigatorToolBar->isHidden() &&
933  ( toolBarArea( navigatorToolBar ) == Qt::TopToolBarArea ||
934  toolBarArea( navigatorToolBar ) == Qt::BottomToolBarArea ) ) {
935  addToolBar( toolBarArea( navigatorToolBar ), navigatorToolBar );
936  }
937 
938  applyMainWindowSettings( KGlobal::config()->group(
939  QString::fromLatin1( "MainWindow%1" ).arg( plugin->identifier() ) ) );
940 
941  QApplication::restoreOverrideCursor();
942 }
943 
944 void MainWindow::slotActionTriggered()
945 {
946  KAction *actionSender = static_cast<KAction*>( sender() );
947  actionSender->setChecked( true );
948  KontactInterface::Plugin *plugin = actionSender->data().value<KontactInterface::Plugin*>();
949  if ( !plugin ) {
950  return;
951  }
952  mSidePane->setCurrentPlugin( plugin->identifier() );
953 }
954 
955 void MainWindow::selectPlugin( const QString &pluginName )
956 {
957  PluginList::ConstIterator end = mPlugins.constEnd();
958  for ( PluginList::ConstIterator it = mPlugins.constBegin(); it != end; ++it ) {
959  if ( ( *it )->identifier() == pluginName ) {
960  selectPlugin( *it );
961  return;
962  }
963  }
964 }
965 
966 void MainWindow::loadSettings()
967 {
968  if ( mSplitter ) {
969  // if the preferences do not contain useful values, the side pane part of the splitter
970  // takes up the full width of the window, so leave the splitter sizing at the widget defaults
971  QList<int> sizes = Prefs::self()->sidePaneSplitter();
972  if ( sizes.count() == mSplitter->count() ) {
973  mSplitter->setSizes( sizes );
974  }
975  }
976 
977  // Preload Plugins. This _must_ happen before the default part is loaded
978  PluginList::ConstIterator it;
979  PluginList::ConstIterator end( mDelayedPreload.constEnd() );
980  for ( it = mDelayedPreload.constBegin(); it != end; ++it ) {
981  selectPlugin( *it );
982  }
983  selectPlugin( Prefs::self()->mActivePlugin );
984 }
985 
986 void MainWindow::saveSettings()
987 {
988  if ( mSplitter ) {
989  Prefs::self()->mSidePaneSplitter = mSplitter->sizes();
990  }
991 
992  if ( mCurrentPlugin ) {
993  Prefs::self()->mActivePlugin = mCurrentPlugin->identifier();
994  }
995 }
996 
997 void MainWindow::slotShowTip()
998 {
999  showTip( true );
1000 }
1001 
1002 void MainWindow::slotShowTipOnStart()
1003 {
1004  showTip( false );
1005 }
1006 
1007 void MainWindow::slotShowIntroduction()
1008 {
1009  mPartsStack->setCurrentIndex( 0 );
1010 }
1011 
1012 void MainWindow::showTip( bool force )
1013 {
1014  QStringList tips;
1015  PluginList::ConstIterator end = mPlugins.constEnd();
1016  for ( PluginList::ConstIterator it = mPlugins.constBegin(); it != end; ++it ) {
1017  const QString file = (*it)->tipFile();
1018  if ( !file.isEmpty() ) {
1019  tips.append( file );
1020  }
1021  }
1022 
1023  KTipDialog::showMultiTip( this, tips, force );
1024 }
1025 
1026 void MainWindow::slotQuit()
1027 {
1028  mReallyClose = true;
1029  close();
1030 }
1031 
1032 void MainWindow::slotPreferences()
1033 {
1034  static Kontact::KontactConfigureDialog *dlg = 0;
1035  if ( !dlg ) {
1036  dlg = new Kontact::KontactConfigureDialog( this );
1037  dlg->setAllowComponentSelection( true );
1038 
1039  // do not show settings of components running standalone
1040  KPluginInfo::List filteredPlugins = mPluginInfos;
1041  PluginList::ConstIterator it;
1042  PluginList::ConstIterator end(mPlugins.constEnd());
1043  for ( it = mPlugins.constBegin(); it != end; ++it ) {
1044  if ( (*it)->isRunningStandalone() ) {
1045  KPluginInfo::List::ConstIterator infoIt;
1046  KPluginInfo::List::ConstIterator infoEnd(filteredPlugins.constEnd());
1047  for ( infoIt = filteredPlugins.constBegin();
1048  infoIt != infoEnd; ++infoIt ) {
1049  if ( infoIt->pluginName() == (*it)->identifier() ) {
1050  filteredPlugins.removeAll( *infoIt );
1051  break;
1052  }
1053  }
1054  }
1055  }
1056 
1057  dlg->setHelp( QLatin1String("main-config"), QLatin1String("kontact") );
1058  dlg->addPluginInfos( filteredPlugins );
1059  connect( dlg, SIGNAL(pluginSelectionChanged()), SLOT(pluginsChanged()) );
1060  }
1061 
1062  dlg->show();
1063 }
1064 
1065 void MainWindow::pluginsChanged()
1066 {
1067  unplugActionList( QLatin1String("navigator_actionlist") );
1068  unloadPlugins();
1069  loadPlugins();
1070  mSidePane->updatePlugins();
1071  updateShortcuts();
1072 }
1073 
1074 void MainWindow::updateConfig()
1075 {
1076  kDebug();
1077 
1078  saveSettings();
1079  loadSettings();
1080 }
1081 
1082 void MainWindow::showAboutDialog()
1083 {
1084  QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
1085 
1086  if ( !mAboutDialog ) {
1087  mAboutDialog = new AboutDialog( this );
1088  }
1089 
1090  mAboutDialog->show();
1091  mAboutDialog->raise();
1092  QApplication::restoreOverrideCursor();
1093 }
1094 
1095 void MainWindow::configureShortcuts()
1096 {
1097  KShortcutsDialog dialog(
1098  KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this );
1099  dialog.addCollection( actionCollection() );
1100 
1101  if ( mCurrentPlugin && mCurrentPlugin->part() ) {
1102  dialog.addCollection( mCurrentPlugin->part()->actionCollection() );
1103  }
1104 
1105  dialog.configure();
1106  if ( mCurrentPlugin && mCurrentPlugin->part() ) {
1107  mCurrentPlugin->shortcutChanged();
1108  }
1109 }
1110 
1111 void MainWindow::configureToolbars()
1112 {
1113  if ( mCurrentPlugin ) {
1114  saveMainWindowSettings(
1115  KGlobal::config()->group(
1116  QString::fromLatin1( "MainWindow%1" ).arg( mCurrentPlugin->identifier() ) ) );
1117  }
1118  QPointer<KEditToolBar> edit = new KEditToolBar( factory() );
1119  connect( edit, SIGNAL(newToolBarConfig()), this, SLOT(slotNewToolbarConfig()) );
1120  edit->exec();
1121  delete edit;
1122 }
1123 
1124 void MainWindow::slotNewToolbarConfig()
1125 {
1126  if ( mCurrentPlugin && mCurrentPlugin->part() ) {
1127  createGUI( mCurrentPlugin->part() );
1128  }
1129  if ( mCurrentPlugin ) {
1130  applyMainWindowSettings(
1131  KGlobal::config()->group(
1132  QString::fromLatin1( "MainWindow%1" ).arg( mCurrentPlugin->identifier() ) ) );
1133  }
1134  updateShortcuts(); // for the plugActionList call
1135 }
1136 
1137 void MainWindow::slotOpenUrl( const QUrl &url )
1138 {
1139  slotOpenUrl( KUrl( url ) );
1140 }
1141 
1142 void MainWindow::slotOpenUrl( const KUrl &url )
1143 {
1144  if ( url.protocol() == QLatin1String( "exec" ) ) {
1145  const QString path( url.path() );
1146  if ( path == QLatin1String( "/switch" ) ) {
1147  if ( mCurrentPlugin ) {
1148  mPartsStack->setCurrentIndex( mPartsStack->indexOf( mCurrentPlugin->part()->widget() ) );
1149  }
1150  }
1151  else if ( path == QLatin1String( "/accountwizard" ) ) {
1152  KRun::runCommand( QLatin1String( "accountwizard" ), this );
1153  slotQuit();
1154  }
1155  else if ( path.startsWith( QLatin1String( "/help" ) ) ) {
1156  QString app( QLatin1String("kontact") );
1157  if ( !url.query().isEmpty() ) {
1158  app = url.query().mid( 1 );
1159  }
1160  KToolInvocation::invokeHelp( QString(), app );
1161  }
1162  } else {
1163  new KRun( url, this );
1164  }
1165 }
1166 
1167 void MainWindow::readProperties( const KConfigGroup &config )
1168 {
1169  Core::readProperties( config );
1170 
1171  QSet<QString> activePlugins =
1172  QSet<QString>::fromList( config.readEntry( "ActivePlugins", QStringList() ) );
1173 
1174  if ( !activePlugins.isEmpty() ) {
1175  foreach ( KontactInterface::Plugin *plugin, mPlugins ) {
1176  if ( !plugin->isRunningStandalone() && activePlugins.contains( plugin->identifier() ) ) {
1177  plugin->readProperties( config );
1178  }
1179  }
1180  }
1181 }
1182 
1183 void MainWindow::saveProperties( KConfigGroup &config )
1184 {
1185  Core::saveProperties( config );
1186 
1187  QStringList activePlugins;
1188 
1189  foreach ( const KPluginInfo &pluginInfo, mPluginInfos ) {
1190  if ( pluginInfo.isPluginEnabled() ) {
1191  KontactInterface::Plugin *plugin = pluginFromInfo( pluginInfo );
1192  if ( plugin ) {
1193  activePlugins.append( plugin->identifier() );
1194  plugin->saveProperties( config );
1195  }
1196  }
1197  }
1198 
1199  config.writeEntry( "ActivePlugins", activePlugins );
1200 }
1201 
1202 bool MainWindow::queryClose()
1203 {
1204  if ( kapp->sessionSaving() || mReallyClose ) {
1205  return true;
1206  }
1207 
1208  foreach ( KontactInterface::Plugin *plugin, mPlugins ) {
1209  if ( !plugin->isRunningStandalone() ) {
1210  if ( !plugin->queryClose() ) {
1211  return false;
1212  }
1213  }
1214  }
1215  return true;
1216 }
1217 
1218 void MainWindow::slotShowStatusMsg( const QString &msg )
1219 {
1220  if ( !statusBar() || !mStatusMsgLabel ) {
1221  return;
1222  }
1223 
1224  mStatusMsgLabel->setText( msg );
1225 }
1226 
1227 QString MainWindow::introductionString()
1228 {
1229  KIconLoader *iconloader = KIconLoader::global();
1230  const int iconSize = iconloader->currentSize( KIconLoader::Desktop );
1231 
1232  const QString handbook_icon_path = iconloader->iconPath( QLatin1String("help-contents"), KIconLoader::Desktop );
1233  const QString html_icon_path = iconloader->iconPath( QLatin1String("kontact"), KIconLoader::Desktop );
1234  const QString wizard_icon_path = iconloader->iconPath( QLatin1String("tools-wizard"), KIconLoader::Desktop );
1235 
1236  QString info =
1237  ki18nc(
1238  "@info",
1239  "<h2 style='text-align:center; margin-top: 0px;'>Welcome to Kontact %1</h2>"
1240  "<p align=\"center\">%2</p>"
1241  "<table align=\"center\">"
1242  "<tr><td><a href=\"%3\"><img width=\"%4\" height=\"%5\" src=\"%6\" /></a></td>"
1243  "<td><a href=\"%7\">%8</a><br /><span id=\"subtext\"><nobr>%9</nobr></span></td></tr>"
1244  "<tr><td><a href=\"%10\"><img width=\"%11\" height=\"%12\" src=\"%13\" /></a></td>"
1245  "<td><a href=\"%14\">%15</a><br /><span id=\"subtext\"><nobr>%16</nobr></span></td></tr>"
1246  "<tr><td><a href=\"%17\"><img width=\"%18\" height=\"%19\" src=\"%20\" /></a></td>"
1247  "<td><a href=\"%21\">%22</a><br /><span id=\"subtext\"><nobr>%23</nobr></span></td></tr>"
1248  "</table>"
1249  "<p style=\"margin-bottom: 0px\"> <a href=\"%24\">Skip this introduction</a></p>" ).
1250  subs( KGlobal::mainComponent().aboutData()->version() ).
1251  subs( i18nc( "@item:intext",
1252  "Kontact handles your e-mail, address book, calendar, to-do list and more." ) ).
1253  subs( QLatin1String("exec:/help?kontact") ).
1254  subs( iconSize ).
1255  subs( iconSize ).
1256  subs( QLatin1String("file:") + handbook_icon_path ).
1257  subs( QLatin1String("exec:/help?kontact") ).
1258  subs( i18nc( "@item:intext", "Read Manual" ) ).
1259  subs( i18nc( "@item:intext", "Learn more about Kontact and its components" ) ).
1260  subs( QLatin1String("http://kontact.org") ).
1261  subs( iconSize ).
1262  subs( iconSize ).
1263  subs( QLatin1String("file:") + html_icon_path ).
1264  subs( QLatin1String("http://kontact.org") ).
1265  subs( i18nc( "@item:intext", "Visit Kontact Website" ) ).
1266  subs( i18nc( "@item:intext", "Access online resources and tutorials" ) ).
1267  subs( QLatin1String("exec:/accountwizard") ).
1268  subs( iconSize ).
1269  subs( iconSize ).
1270  subs( QLatin1String("file:") + wizard_icon_path ).
1271  subs( QLatin1String("exec:/accountwizard") ).
1272  subs( i18nc( "@item:intext", "Setup your Accounts" ) ).
1273  subs( i18nc( "@item:intext", "Prepare Kontact for use" ) ).
1274  subs( QLatin1String("exec:/switch") ).
1275  toString();
1276  return info;
1277 }
1278 
1279 void MainWindow::slotShowHideSideBar()
1280 {
1281  QList<int> sizes = mSplitter->sizes();
1282  if (!sizes.isEmpty()) {
1283  if (sizes.at(0) != 0) {
1284  sizes[0] = 0;
1285  } else {
1286  sizes[0] = 10;
1287  }
1288  mSplitter->setSizes(sizes);
1289  }
1290 }
1291 
QWidget::layout
QLayout * layout() const
QAction::text
text
Kontact::MainWindow::pluginActionWeightLessThan
static bool pluginActionWeightLessThan(const QAction *left, const QAction *right)
Definition: mainwindow.cpp:309
QWidget
QApplication::isRightToLeft
bool isRightToLeft()
Kontact::MainWindow::slotOpenUrl
void slotOpenUrl(const KUrl &url)
Definition: mainwindow.cpp:1142
QSplitter::setSizes
void setSizes(const QList< int > &list)
QMap::contains
bool contains(const Key &key) const
Kontact::MainWindow::initGUI
void initGUI()
Definition: mainwindow.cpp:165
Kontact::SidePaneBase::setCurrentPlugin
virtual void setCurrentPlugin(const QString &)=0
KPIM::BroadcastStatus::instance
static BroadcastStatus * instance()
QAction::data
QVariant data() const
QFont
Kontact::MainWindow::slotActivePartChanged
void slotActivePartChanged(KParts::Part *part)
Definition: mainwindow.cpp:737
Kontact::MainWindow::initObject
void initObject()
Definition: mainwindow.cpp:216
QAction::icon
icon
QList::at
const T & at(int i) const
QPointer
QDBusConnection::registerObject
bool registerObject(const QString &path, QObject *object, QFlags< QDBusConnection::RegisterOption > options)
QVariant::value
T value() const
Kontact::MainWindow::slotPreferences
void slotPreferences()
Definition: mainwindow.cpp:1032
QList::erase
iterator erase(iterator pos)
QDBusConnection::sessionBus
QDBusConnection sessionBus()
Kontact::IconSidePane
Definition: iconsidepane.h:99
statusbarprogresswidget.h
Kontact::MainWindow::slotShowStatusMsg
void slotShowStatusMsg(const QString &)
Definition: mainwindow.cpp:1218
Kontact::MainWindow::setInitialActivePluginModule
void setInitialActivePluginModule(const QString &)
Definition: mainwindow.cpp:301
QWidget::focusWidget
QWidget * focusWidget() const
QList::const_iterator
Kontact::MainWindow::slotNewToolbarConfig
void slotNewToolbarConfig()
Definition: mainwindow.cpp:1124
QSplitter::count
int count() const
Kontact::MainWindow::slotShowTipOnStart
void slotShowTipOnStart()
Definition: mainwindow.cpp:1002
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
QStackedWidget::setCurrentWidget
void setCurrentWidget(QWidget *widget)
QSplitter::sizes
QList< int > sizes() const
QWidget::setLayout
void setLayout(QLayout *layout)
QVariant::isNull
bool isNull() const
QWidget::setFocus
void setFocus()
KSYCOCA_WAIT_TIMEOUT
static const int KSYCOCA_WAIT_TIMEOUT
Definition: mainwindow.cpp:80
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
aboutdialog.h
QList::removeAll
int removeAll(const T &value)
Kontact::MainWindow::slotNewClicked
void slotNewClicked()
Definition: mainwindow.cpp:750
mainwindow.h
QStackedWidget::setCurrentIndex
void setCurrentIndex(int index)
QApplication::setOverrideCursor
void setOverrideCursor(const QCursor &cursor)
QVBoxLayout
QApplication::restoreOverrideCursor
void restoreOverrideCursor()
QList::Iterator
typedef Iterator
QSet
QStackedWidget
QShortcut
QString
QList
QLayout::setMargin
void setMargin(int margin)
QStringList
kontactconfiguredialog.h
QAction::whatsThis
whatsThis
QList::end
iterator end()
Kontact::MainWindow::~MainWindow
~MainWindow()
Definition: mainwindow.cpp:270
QUrl
QLatin1Char
Kontact::MainWindow::selectPlugin
virtual void selectPlugin(KontactInterface::Plugin *plugin)
Definition: mainwindow.cpp:788
QVariant::fromValue
QVariant fromValue(const T &value)
QSet::contains
bool contains(const T &value) const
Kontact::MainWindow::activateInitialPluginModule
void activateInitialPluginModule()
Definition: mainwindow.cpp:324
Kontact::MainWindow::pluginWeightLessThan
static bool pluginWeightLessThan(const KontactInterface::Plugin *left, const KontactInterface::Plugin *right)
Definition: mainwindow.cpp:318
progressstatusbarwidget.h
QSplitter
Kontact::MainWindow::updateConfig
void updateConfig()
Definition: mainwindow.cpp:1074
KPIM::ProgressStatusBarWidget::littleProgress
KPIM::StatusbarProgressWidget * littleProgress() const
QString::mid
QString mid(int position, int n) const
Kontact::MainWindow::showAboutDialog
void showAboutDialog()
Definition: mainwindow.cpp:1082
Kontact::SidePaneBase::updatePlugins
virtual void updatePlugins()=0
This method is called by the core whenever the count of plugins has changed.
QLatin1String
QKeySequence
QStackedWidget::indexOf
int indexOf(QWidget *widget) const
Kontact::MainWindow::slotQuit
void slotQuit()
Definition: mainwindow.cpp:1026
QList::insert
void insert(int i, const T &value)
QWidget::parentWidget
QWidget * parentWidget() const
Kontact::MainWindow::MainWindow
MainWindow()
Definition: mainwindow.cpp:138
QAction
QList::ConstIterator
typedef ConstIterator
QSet::fromList
QSet< T > fromList(const QList< T > &list)
Kontact::MainWindow::slotShowIntroduction
void slotShowIntroduction()
Definition: mainwindow.cpp:1007
QVariant::toBool
bool toBool() const
QSet::isEmpty
bool isEmpty() const
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QVariant::isValid
bool isValid() const
QLayout::setSpacing
void setSpacing(int)
QMap::insert
iterator insert(const Key &key, const T &value)
KHBox
QWidget::show
void show()
QMap::isEmpty
bool isEmpty() const
KPIM::ProgressStatusBarWidget
QSplitter::setCollapsible
void setCollapsible(int index, bool collapse)
iconsidepane.h
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
Kontact::MainWindow::slotShowTip
void slotShowTip()
Definition: mainwindow.cpp:997
QStackedWidget::addWidget
int addWidget(QWidget *widget)
broadcaststatus.h
QCursor
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QVariant::toString
QString toString() const
Kontact::MainWindow::slotActionTriggered
void slotActionTriggered()
Definition: mainwindow.cpp:944
QList::begin
iterator begin()
QBoxLayout::setSpacing
void setSpacing(int spacing)
Kontact::KontactConfigureDialog
Definition: kontactconfiguredialog.h:25
Kontact::AboutDialog
Definition: aboutdialog.h:39
Kontact::MainWindow::slotSyncClicked
void slotSyncClicked()
Definition: mainwindow.cpp:766
version
static const char version[]
Definition: main.cpp:50
QMap::remove
int remove(const Key &key)
QTimer::singleShot
singleShot
QVariant
QString::toUtf8
QByteArray toUtf8() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:11 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kontact

Skip menu "kontact"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



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