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

kontact

  • sources
  • kde-4.12
  • 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/progressdialog.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  /* Create a progress dialog and hide it. */
373  KPIM::ProgressDialog *progressDialog = new KPIM::ProgressDialog( statusBar(), this );
374  progressDialog->hide();
375 
376  mLittleProgress = new KPIM::StatusbarProgressWidget( progressDialog, statusBar() );
377 
378  mStatusMsgLabel =
379  new KSqueezedTextLabel( i18nc( "@info:status", " Initializing..." ), statusBar() );
380  mStatusMsgLabel->setTextElideMode( Qt::ElideRight );
381  mStatusMsgLabel->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
382 
383  statusBar()->addWidget( mStatusMsgLabel, 10 );
384  statusBar()->addPermanentWidget( mLittleProgress, 0 );
385  mLittleProgress->show();
386 
387  mSplitter->setCollapsible( 1, false );
388 }
389 
390 void MainWindow::paintAboutScreen( const QString &msg )
391 {
392  QString location = KStandardDirs::locate( "data", QLatin1String("kontact/about/main.html") );
393  QString content = QLatin1String(KPIMUtils::kFileToByteArray( location ));
394  content = content.arg( QLatin1String("file:") + KStandardDirs::locate(
395  "data", QLatin1String("kdeui/about/kde_infopage.css") ) );
396  if ( QApplication::isRightToLeft() ) {
397  content =
398  content.arg( QLatin1String("@import \"%1\";") ).
399  arg( QLatin1String("file:") + KStandardDirs::locate(
400  "data", QLatin1String("kdeui/about/kde_infopage_rtl.css") ) );
401  } else {
402  content = content.arg( QString() );
403  }
404 
405  mIntroPart->setHtml(
406  content.arg( QFont().pointSize() + 2 ).
407  arg( i18nc( "@item:intext", "KDE Kontact" ) ).
408  arg( i18nc( "@item:intext", "Get Organized!" ) ).
409  arg( i18nc( "@item:intext", "The KDE Personal Information Management Suite" ) ).
410  arg( msg ) );
411 }
412 
413 void MainWindow::initAboutScreen()
414 {
415  KHBox *introbox = new KHBox( mPartsStack );
416  mPartsStack->addWidget( introbox );
417  mPartsStack->setCurrentWidget( introbox );
418  mIntroPart = new KWebView( introbox );
419  mIntroPart->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
420  mIntroPart->setFocusPolicy( Qt::WheelFocus );
421  // Let's better be paranoid and disable plugins (it defaults to enabled):
422  mIntroPart->settings()->setAttribute( QWebSettings::JavascriptEnabled, false );
423  mIntroPart->settings()->setAttribute( QWebSettings::JavaEnabled, false );
424  mIntroPart->settings()->setAttribute( QWebSettings::PluginsEnabled, false );
425 
426  connect( mIntroPart->page(), SIGNAL(linkClicked(QUrl)), this,
427  SLOT(slotOpenUrl(QUrl)), Qt::QueuedConnection );
428 }
429 
430 void MainWindow::setupActions()
431 {
432  actionCollection()->addAction( KStandardAction::Quit, this, SLOT(slotQuit()) );
433 
434  mNewActions = new KActionMenu(
435  i18nc( "@title:menu create new pim items (message,calendar,to-do,etc.)", "New" ), this );
436  actionCollection()->addAction( QLatin1String("action_new"), mNewActions );
437  mNewActions->setShortcut( KStandardShortcut::openNew() );
438  connect( mNewActions, SIGNAL(triggered(bool)), this, SLOT(slotNewClicked()) );
439 
440  // If the user is using disconnected imap mail folders as groupware, we add
441  // plugins' Synchronize actions to the toolbar which trigger an imap sync.
442  // Otherwise it's redundant and misleading.
443  KConfig _config( QLatin1String("kmail2rc") );
444  KConfigGroup config( &_config, "Groupware" );
445 #if defined(KDEPIM_ENTERPRISE_BUILD)
446  bool defGW = config.readEntry( "Enabled", true );
447 #else
448  bool defGW = config.readEntry( "Enabled", false );
449 #endif
450  KConfig *_cfg = Prefs::self()->config();
451  KConfigGroup cfg( _cfg, "Kontact Groupware Settings" );
452  mSyncActionsEnabled = cfg.readEntry( "GroupwareMailFoldersEnabled", defGW );
453 
454  if ( mSyncActionsEnabled ) {
455  mSyncActions = new KActionMenu(
456  KIcon( QLatin1String("view-refresh") ),
457  i18nc( "@title:menu synchronize pim items (message,calendar,to-do,etc.)", "Sync" ), this );
458  actionCollection()->addAction( QLatin1String("action_sync"), mSyncActions );
459  mSyncActions->setShortcut( KStandardShortcut::reload() );
460  connect( mSyncActions, SIGNAL(triggered(bool)), this, SLOT(slotSyncClicked()) );
461  }
462 
463  KAction *action =
464  new KAction( KIcon( QLatin1String("configure") ),
465  i18nc( "@action:inmenu", "Configure Kontact..." ), this );
466  action->setHelpText(
467  i18nc( "@info:status", "Configure Kontact" ) );
468  action->setWhatsThis(
469  i18nc( "@info:whatsthis",
470  "You will be presented with a dialog where you can configure Kontact." ) );
471  actionCollection()->addAction( QLatin1String("settings_configure_kontact"), action );
472  connect( action, SIGNAL(triggered(bool)), SLOT(slotPreferences()) );
473 
474  action =
475  new KAction( KIcon( QLatin1String("kontact") ),
476  i18nc( "@action:inmenu", "&Kontact Introduction" ), this );
477  action->setHelpText(
478  i18nc( "@info:status", "Show the Kontact Introduction page" ) );
479  action->setWhatsThis(
480  i18nc( "@info:whatsthis",
481  "Choose this option to see the Kontact Introduction page." ) );
482  actionCollection()->addAction( QLatin1String("help_introduction"), action );
483  connect( action, SIGNAL(triggered(bool)), SLOT(slotShowIntroduction()) );
484 
485  action =
486  new KAction( KIcon( QLatin1String("ktip") ),
487  i18nc( "@action:inmenu", "&Tip of the Day" ), this );
488  action->setHelpText(
489  i18nc( "@info:status", "Show the Tip-of-the-Day dialog" ) );
490  action->setWhatsThis(
491  i18nc( "@info:whatsthis",
492  "You will be presented with a dialog showing small tips to help "
493  "you use this program more effectively." ) );
494  actionCollection()->addAction( QLatin1String("help_tipofday"), action );
495  connect( action, SIGNAL(triggered(bool)), SLOT(slotShowTip()) );
496  //TODO 4.12: add description
497  QShortcut *shortcut = new QShortcut( QKeySequence(Qt::Key_F9), this );
498  connect(shortcut, SIGNAL(activated()), this, SLOT(slotShowHideSideBar()));
499 }
500 
501 bool MainWindow::isPluginLoaded( const KPluginInfo &info )
502 {
503  return ( pluginFromInfo( info ) != 0 );
504 }
505 
506 KontactInterface::Plugin *MainWindow::pluginFromInfo( const KPluginInfo &info )
507 {
508  PluginList::ConstIterator end = mPlugins.constEnd();
509  for ( PluginList::ConstIterator it = mPlugins.constBegin(); it != end; ++it ) {
510  if ( (*it)->identifier() == info.pluginName() ) {
511  return *it;
512  }
513  }
514  return 0;
515 }
516 
517 void MainWindow::loadPlugins()
518 {
519  QList<KontactInterface::Plugin *> plugins;
520 
521  int i;
522  KPluginInfo::List::ConstIterator it;
523  KPluginInfo::List::ConstIterator end( mPluginInfos.constEnd() );
524  for ( it = mPluginInfos.constBegin(); it != end; ++it ) {
525  if ( !it->isPluginEnabled() ) {
526  continue;
527  }
528 
529  KontactInterface::Plugin *plugin = 0;
530  if ( isPluginLoaded( *it ) ) {
531  plugin = pluginFromInfo( *it );
532  if ( plugin ) {
533  plugin->configUpdated();
534  }
535  continue;
536  }
537 
538  kDebug() << "Loading Plugin:" << it->name();
539  QString error;
540  plugin =
541  it->service()->createInstance<KontactInterface::Plugin>( this, QVariantList(), &error );
542 
543  if ( !plugin ) {
544  kDebug() << "Unable to create plugin for" << it->name() << error;
545  continue;
546  }
547 
548  plugin->setIdentifier( it->pluginName() );
549  plugin->setTitle( it->name() );
550  plugin->setIcon( it->icon() );
551 
552  QVariant libNameProp = it->property( QLatin1String("X-KDE-KontactPartLibraryName") );
553  QVariant exeNameProp = it->property( QLatin1String("X-KDE-KontactPartExecutableName") );
554  QVariant loadOnStart = it->property( QLatin1String("X-KDE-KontactPartLoadOnStart") );
555  QVariant hasPartProp = it->property( QLatin1String("X-KDE-KontactPluginHasPart") );
556 
557  if ( !loadOnStart.isNull() && loadOnStart.toBool() ) {
558  mDelayedPreload.append( plugin );
559  }
560 
561  kDebug() << "LIBNAMEPART:" << libNameProp.toString();
562 
563  plugin->setPartLibraryName( libNameProp.toString().toUtf8() );
564  plugin->setExecutableName( exeNameProp.toString() );
565  if ( hasPartProp.isValid() ) {
566  plugin->setShowInSideBar( hasPartProp.toBool() );
567  }
568 
569  for ( i = 0; i < plugins.count(); ++i ) {
570  KontactInterface::Plugin *p = plugins.at( i );
571  if ( plugin->weight() < p->weight() ) {
572  break;
573  }
574  }
575  plugins.insert( i, plugin );
576 
577  }
578 
579  const int numberOfPlugins( plugins.count() );
580  for ( i = 0; i < numberOfPlugins; ++i ) {
581  KontactInterface::Plugin *plugin = plugins.at( i );
582 
583  const QList<KAction*> actionList = plugin->newActions();
584  QList<KAction*>::const_iterator listIt;
585  QList<KAction*>::const_iterator end( actionList.end() );
586 
587  for ( listIt = actionList.begin(); listIt != end; ++listIt ) {
588  kDebug() << QLatin1String("Plugging New actions") << (*listIt)->objectName();
589  mNewActions->addAction( (*listIt) );
590  }
591 
592  if ( mSyncActionsEnabled ) {
593  Q_FOREACH ( KAction *listIt, plugin->syncActions() ) {
594  kDebug() << QLatin1String("Plugging Sync actions") << listIt->objectName();
595  mSyncActions->addAction( listIt );
596  }
597  }
598  addPlugin( plugin );
599  }
600 
601  const bool state = ( !mPlugins.isEmpty() );
602  mNewActions->setEnabled( state );
603  if ( mSyncActionsEnabled ) {
604  mSyncActions->setEnabled( state );
605  }
606 }
607 
608 void MainWindow::unloadPlugins()
609 {
610  KPluginInfo::List::ConstIterator end = mPluginInfos.constEnd();
611  KPluginInfo::List::ConstIterator it;
612  for ( it = mPluginInfos.constBegin(); it != end; ++it ) {
613  if ( !it->isPluginEnabled() ) {
614  removePlugin( *it );
615  }
616  }
617 }
618 
619 void MainWindow::updateShortcuts()
620 {
621  ActionPluginList::ConstIterator end = mActionPlugins.constEnd();
622  ActionPluginList::ConstIterator it;
623  int i = 0;
624  for ( it = mActionPlugins.constBegin(); it != end; ++it ) {
625  KAction *action = static_cast<KAction*>( *it );
626  const QString shortcut = QString::fromLatin1( "Ctrl+%1" ).arg( mActionPlugins.count() - i );
627  action->setShortcut( KShortcut( shortcut ) );
628  ++i;
629  }
630  factory()->plugActionList( this, QLatin1String( "navigator_actionlist" ), mActionPlugins );
631 }
632 
633 bool MainWindow::removePlugin( const KPluginInfo &info )
634 {
635  PluginList::Iterator end = mPlugins.end();
636  for ( PluginList::Iterator it = mPlugins.begin(); it != end; ++it ) {
637  KontactInterface::Plugin *plugin = *it;
638  if ( ( *it )->identifier() == info.pluginName() ) {
639  QList<KAction*> actionList = plugin->newActions();
640  QList<KAction*>::const_iterator listIt;
641  QList<KAction*>::const_iterator listEnd( actionList.constEnd() );
642  for ( listIt = actionList.constBegin(); listIt != listEnd; ++listIt ) {
643  kDebug() << QLatin1String("Unplugging New actions") << (*listIt)->objectName();
644  mNewActions->removeAction( *listIt );
645  }
646 
647  if ( mSyncActionsEnabled ) {
648  actionList = plugin->syncActions();
649  for ( listIt = actionList.constBegin(); listIt != actionList.constEnd(); ++listIt ) {
650  kDebug() << QLatin1String("Unplugging Sync actions") << (*listIt)->objectName();
651  mSyncActions->removeAction( *listIt );
652  }
653  }
654  removeChildClient( plugin );
655 
656  if ( mCurrentPlugin == plugin ) {
657  mCurrentPlugin = 0;
658  createGUI( 0 );
659  }
660 
661  plugin->deleteLater(); // removes the part automatically
662  mPlugins.erase( it );
663  if ( plugin->showInSideBar() ) {
664  QAction *q = mPluginAction[plugin]; // remove KAction, to free the shortcut for later use
665  mActionPlugins.removeAll( q );
666  mPluginAction.remove(plugin);
667  delete q;
668  }
669 
670  if ( mCurrentPlugin == 0 ) {
671  PluginList::Iterator it;
672  PluginList::Iterator pluginEnd( mPlugins.end() );
673  for ( it = mPlugins.begin(); it != pluginEnd; ++it ) {
674  if ( (*it)->showInSideBar() ) {
675  selectPlugin( *it );
676  return true;
677  }
678  }
679  }
680  return true;
681  }
682 
683  }
684 
685  return false;
686 }
687 
688 void MainWindow::addPlugin( KontactInterface::Plugin *plugin )
689 {
690  kDebug();
691 
692  mPlugins.append( plugin );
693 
694  if ( plugin->showInSideBar() ) {
695  KAction *action = new KAction( KIcon( plugin->icon() ), plugin->title(), this );
696  action->setHelpText(
697  i18nc( "@info:status", "Plugin %1", plugin->title() ) );
698  action->setWhatsThis(
699  i18nc( "@info:whatsthis",
700  "Switch to plugin %1", plugin->title() ) );
701  action->setCheckable( true );
702  action->setData( QVariant::fromValue( plugin ) ); // on the slot we can decode
703  // which action was triggered
704  connect( action, SIGNAL(triggered(bool)), SLOT(slotActionTriggered()) );
705  actionCollection()->addAction( plugin->title(), action );
706  mActionPlugins.append( action );
707  mPluginAction.insert( plugin, action );
708  }
709 
710  // merge the plugins GUI into the main window
711  insertChildClient( plugin );
712 
713  // sort the action plugins again and reset shortcuts. If we removed and then readded some plugins
714  // we need to take in count their weights for setting shortcuts again
715  qSort( mActionPlugins.begin(), mActionPlugins.end(), pluginActionWeightLessThan );
716  qSort( mPlugins.begin(), mPlugins.end(), pluginWeightLessThan );
717  int i = 0;
718  foreach ( QAction *qaction, mActionPlugins ) {
719  KAction *action = static_cast<KAction*>( qaction );
720  QString shortcut = QString::fromLatin1( "Ctrl+%1" ).arg( mActionPlugins.count() - i );
721  action->setShortcut( KShortcut( shortcut ) );
722  ++i;
723  }
724 }
725 
726 void MainWindow::partLoaded( KontactInterface::Plugin *plugin, KParts::ReadOnlyPart *part )
727 {
728  Q_UNUSED( plugin );
729 
730  // See if we have this part already (e.g. due to two plugins sharing it)
731  if ( mPartsStack->indexOf( part->widget() ) != -1 ) {
732  return;
733  }
734 
735  mPartsStack->addWidget( part->widget() );
736 
737  mPartManager->addPart( part, false );
738  // Workaround for KParts misbehavior: addPart calls show!
739  part->widget()->hide();
740 }
741 
742 void MainWindow::slotActivePartChanged( KParts::Part *part )
743 {
744  if ( !part ) {
745  createGUI( 0 );
746  return;
747  }
748 
749  kDebug() << QLatin1String("Part activated:") << part
750  << QLatin1String("with stack id.")<< mPartsStack->indexOf( part->widget() );
751 
752  statusBar()->clearMessage();
753 }
754 
755 void MainWindow::slotNewClicked()
756 {
757  if ( !mCurrentPlugin->newActions().isEmpty() ) {
758  mCurrentPlugin->newActions().first()->trigger();
759  } else {
760  PluginList::Iterator it;
761  PluginList::Iterator end( mPlugins.end() );
762  for ( it = mPlugins.begin(); it != end; ++it ) {
763  if ( !(*it)->newActions().isEmpty() ) {
764  (*it)->newActions().first()->trigger();
765  return;
766  }
767  }
768  }
769 }
770 
771 void MainWindow::slotSyncClicked()
772 {
773  if ( !mCurrentPlugin->syncActions().isEmpty() ) {
774  mCurrentPlugin->syncActions().first()->trigger();
775  } else {
776  PluginList::Iterator it;
777  PluginList::Iterator end( mPlugins.end() );
778  for ( it = mPlugins.begin(); it != end; ++it ) {
779  if ( !(*it)->syncActions().isEmpty() ) {
780  (*it)->syncActions().first()->trigger();
781  return;
782  }
783  }
784  }
785 }
786 
787 KToolBar *MainWindow::findToolBar( const char *name )
788 {
789  // like KMainWindow::toolBar, but which doesn't create the toolbar if not found
790  return findChild<KToolBar *>( QLatin1String(name) );
791 }
792 
793 void MainWindow::selectPlugin( KontactInterface::Plugin *plugin )
794 {
795  if ( !plugin ) {
796  return;
797  }
798 
799  if ( plugin->isRunningStandalone() ) {
800  statusBar()->showMessage(
801  i18nc( "@info:status",
802  "Application is running standalone. Foregrounding..." ), 1000 );
803  plugin->bringToForeground();
804  return;
805  }
806 
807  QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
808 
809  if ( mCurrentPlugin ) {
810  saveMainWindowSettings(
811  KGlobal::config()->group(
812  QString::fromLatin1( "MainWindow%1" ).arg( mCurrentPlugin->identifier() ) ) );
813  }
814 
815  KParts::Part *part = plugin->part();
816 
817  if ( !part ) {
818  QApplication::restoreOverrideCursor();
819  KMessageBox::error(
820  this,
821  i18nc( "@info",
822  "Cannot load part for %1.",
823  plugin->title() ) + QLatin1Char('\n') + lastErrorMessage() );
824  plugin->setDisabled( true );
825  mSidePane->updatePlugins();
826  return;
827  }
828 
829  if ( mCurrentPlugin ) {
830  KAction *action = mPluginAction[ mCurrentPlugin ];
831  if ( action ) {
832  action->setChecked( false );
833  }
834  }
835  KAction *selectedPluginAction = mPluginAction[ plugin ];
836  if ( selectedPluginAction ) {
837  selectedPluginAction->setChecked( true );
838  }
839 
840  // store old focus widget
841  QWidget *focusWidget = kapp->focusWidget();
842  if ( mCurrentPlugin && focusWidget ) {
843  // save the focus widget only when it belongs to the activated part
844  QWidget *parent = focusWidget->parentWidget();
845  while ( parent ) {
846  if ( parent == mCurrentPlugin->part()->widget() ) {
847  mFocusWidgets.insert( mCurrentPlugin->identifier(), QPointer<QWidget>( focusWidget ) );
848  }
849  parent = parent->parentWidget();
850  }
851  }
852 
853  if ( mSidePane ) {
854  mSidePane->setCurrentPlugin( plugin->identifier() );
855  }
856 
857  plugin->aboutToSelect();
858 
859  mPartManager->setActivePart( part );
860  QWidget *view = part->widget();
861  Q_ASSERT( view );
862 
863  if ( view ) {
864  mPartsStack->setCurrentWidget( view );
865  view->show();
866 
867  if ( !mFocusWidgets.isEmpty() && mFocusWidgets.contains( plugin->identifier() ) ) {
868  focusWidget = mFocusWidgets[ plugin->identifier() ];
869  if ( focusWidget ) {
870  focusWidget->setFocus();
871  }
872  } else {
873  view->setFocus();
874  }
875 
876  mCurrentPlugin = plugin;
877 
878  QAction *newAction = 0;
879  if ( !plugin->newActions().isEmpty() ) {
880  newAction = plugin->newActions().first();
881  }
882 
883  QAction *syncAction = 0;
884  if ( !plugin->syncActions().isEmpty() ) {
885  syncAction = plugin->syncActions().first();
886  }
887 
888  createGUI( plugin->part() );
889 
890  setCaption( i18nc( "@title:window Plugin dependent window title",
891  "%1 - Kontact", plugin->title() ) );
892 
893  if ( newAction ) {
894  mNewActions->setIcon( newAction->icon() );
895  static_cast<QAction*>( mNewActions )->setText( newAction->text() );
896  mNewActions->setWhatsThis( newAction->whatsThis() );
897  } else { // we'll use the action of the first plugin which offers one
898  PluginList::Iterator it;
899  PluginList::Iterator end(mPlugins.end());
900  for ( it = mPlugins.begin(); it != end; ++it ) {
901  if ( !(*it)->newActions().isEmpty() ) {
902  newAction = (*it)->newActions().first();
903  }
904  if ( newAction ) {
905  static_cast<QAction*>( mNewActions )->setIcon( newAction->icon() );
906  mNewActions->setText( newAction->text() );
907  mNewActions->setWhatsThis( newAction->whatsThis() );
908  break;
909  }
910  }
911  }
912 
913  if ( mSyncActionsEnabled ) {
914  if ( syncAction ) {
915  mSyncActions->setIcon( syncAction->icon() );
916  static_cast<QAction*>( mSyncActions )->setText( syncAction->text() );
917  } else { // we'll use the action of the first plugin which offers one
918  PluginList::Iterator it;
919  PluginList::Iterator end(mPlugins.end());
920  for ( it = mPlugins.begin(); it != end; ++it ) {
921  if ( !(*it)->syncActions().isEmpty() ) {
922  syncAction = (*it)->syncActions().first();
923  }
924  if ( syncAction ) {
925  static_cast<QAction*>( mSyncActions )->setIcon( syncAction->icon() );
926  mSyncActions->setText( syncAction->text() );
927  break;
928  }
929  }
930  }
931  }
932  }
933 
934  KToolBar *navigatorToolBar = findToolBar( "navigatorToolBar" );
935  if ( navigatorToolBar && !navigatorToolBar->isHidden() &&
936  ( toolBarArea( navigatorToolBar ) == Qt::TopToolBarArea ||
937  toolBarArea( navigatorToolBar ) == Qt::BottomToolBarArea ) ) {
938  addToolBar( toolBarArea( navigatorToolBar ), navigatorToolBar );
939  }
940 
941  applyMainWindowSettings( KGlobal::config()->group(
942  QString::fromLatin1( "MainWindow%1" ).arg( plugin->identifier() ) ) );
943 
944  QApplication::restoreOverrideCursor();
945 }
946 
947 void MainWindow::slotActionTriggered()
948 {
949  KAction *actionSender = static_cast<KAction*>( sender() );
950  actionSender->setChecked( true );
951  KontactInterface::Plugin *plugin = actionSender->data().value<KontactInterface::Plugin*>();
952  if ( !plugin ) {
953  return;
954  }
955  mSidePane->setCurrentPlugin( plugin->identifier() );
956 }
957 
958 void MainWindow::selectPlugin( const QString &pluginName )
959 {
960  PluginList::ConstIterator end = mPlugins.constEnd();
961  for ( PluginList::ConstIterator it = mPlugins.constBegin(); it != end; ++it ) {
962  if ( ( *it )->identifier() == pluginName ) {
963  selectPlugin( *it );
964  return;
965  }
966  }
967 }
968 
969 void MainWindow::loadSettings()
970 {
971  if ( mSplitter ) {
972  // if the preferences do not contain useful values, the side pane part of the splitter
973  // takes up the full width of the window, so leave the splitter sizing at the widget defaults
974  QList<int> sizes = Prefs::self()->sidePaneSplitter();
975  if ( sizes.count() == mSplitter->count() ) {
976  mSplitter->setSizes( sizes );
977  }
978  }
979 
980  // Preload Plugins. This _must_ happen before the default part is loaded
981  PluginList::ConstIterator it;
982  PluginList::ConstIterator end( mDelayedPreload.constEnd() );
983  for ( it = mDelayedPreload.constBegin(); it != end; ++it ) {
984  selectPlugin( *it );
985  }
986  selectPlugin( Prefs::self()->mActivePlugin );
987 }
988 
989 void MainWindow::saveSettings()
990 {
991  if ( mSplitter ) {
992  Prefs::self()->mSidePaneSplitter = mSplitter->sizes();
993  }
994 
995  if ( mCurrentPlugin ) {
996  Prefs::self()->mActivePlugin = mCurrentPlugin->identifier();
997  }
998 }
999 
1000 void MainWindow::slotShowTip()
1001 {
1002  showTip( true );
1003 }
1004 
1005 void MainWindow::slotShowTipOnStart()
1006 {
1007  showTip( false );
1008 }
1009 
1010 void MainWindow::slotShowIntroduction()
1011 {
1012  mPartsStack->setCurrentIndex( 0 );
1013 }
1014 
1015 void MainWindow::showTip( bool force )
1016 {
1017  QStringList tips;
1018  PluginList::ConstIterator end = mPlugins.constEnd();
1019  for ( PluginList::ConstIterator it = mPlugins.constBegin(); it != end; ++it ) {
1020  const QString file = (*it)->tipFile();
1021  if ( !file.isEmpty() ) {
1022  tips.append( file );
1023  }
1024  }
1025 
1026  KTipDialog::showMultiTip( this, tips, force );
1027 }
1028 
1029 void MainWindow::slotQuit()
1030 {
1031  mReallyClose = true;
1032  close();
1033 }
1034 
1035 void MainWindow::slotPreferences()
1036 {
1037  static Kontact::KontactConfigureDialog *dlg = 0;
1038  if ( !dlg ) {
1039  dlg = new Kontact::KontactConfigureDialog( this );
1040  dlg->setAllowComponentSelection( true );
1041 
1042  // do not show settings of components running standalone
1043  KPluginInfo::List filteredPlugins = mPluginInfos;
1044  PluginList::ConstIterator it;
1045  PluginList::ConstIterator end(mPlugins.constEnd());
1046  for ( it = mPlugins.constBegin(); it != end; ++it ) {
1047  if ( (*it)->isRunningStandalone() ) {
1048  KPluginInfo::List::ConstIterator infoIt;
1049  KPluginInfo::List::ConstIterator infoEnd(filteredPlugins.constEnd());
1050  for ( infoIt = filteredPlugins.constBegin();
1051  infoIt != infoEnd; ++infoIt ) {
1052  if ( infoIt->pluginName() == (*it)->identifier() ) {
1053  filteredPlugins.removeAll( *infoIt );
1054  break;
1055  }
1056  }
1057  }
1058  }
1059 
1060  dlg->setHelp( QLatin1String("main-config"), QLatin1String("kontact") );
1061  dlg->addPluginInfos( filteredPlugins );
1062  connect( dlg, SIGNAL(pluginSelectionChanged()), SLOT(pluginsChanged()) );
1063  }
1064 
1065  dlg->show();
1066 }
1067 
1068 void MainWindow::pluginsChanged()
1069 {
1070  unplugActionList( QLatin1String("navigator_actionlist") );
1071  unloadPlugins();
1072  loadPlugins();
1073  mSidePane->updatePlugins();
1074  updateShortcuts();
1075 }
1076 
1077 void MainWindow::updateConfig()
1078 {
1079  kDebug();
1080 
1081  saveSettings();
1082  loadSettings();
1083 }
1084 
1085 void MainWindow::showAboutDialog()
1086 {
1087  QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
1088 
1089  if ( !mAboutDialog ) {
1090  mAboutDialog = new AboutDialog( this );
1091  }
1092 
1093  mAboutDialog->show();
1094  mAboutDialog->raise();
1095  QApplication::restoreOverrideCursor();
1096 }
1097 
1098 void MainWindow::configureShortcuts()
1099 {
1100  KShortcutsDialog dialog(
1101  KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this );
1102  dialog.addCollection( actionCollection() );
1103 
1104  if ( mCurrentPlugin && mCurrentPlugin->part() ) {
1105  dialog.addCollection( mCurrentPlugin->part()->actionCollection() );
1106  }
1107 
1108  dialog.configure();
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 
1292 #include "mainwindow.moc"
Kontact::MainWindow::pluginActionWeightLessThan
static bool pluginActionWeightLessThan(const QAction *left, const QAction *right)
Definition: mainwindow.cpp:309
Kontact::MainWindow::slotOpenUrl
void slotOpenUrl(const KUrl &url)
Definition: mainwindow.cpp:1142
Kontact::MainWindow::initGUI
void initGUI()
Definition: mainwindow.cpp:165
Kontact::SidePaneBase::setCurrentPlugin
virtual void setCurrentPlugin(const QString &)=0
KPIM::BroadcastStatus::instance
static BroadcastStatus * instance()
Kontact::MainWindow::slotActivePartChanged
void slotActivePartChanged(KParts::Part *part)
Definition: mainwindow.cpp:742
Kontact::MainWindow::initObject
void initObject()
Definition: mainwindow.cpp:216
QWidget
Kontact::MainWindow::slotPreferences
void slotPreferences()
Definition: mainwindow.cpp:1035
Kontact::IconSidePane
Definition: iconsidepane.h:99
prefs.h
statusbarprogresswidget.h
Kontact::MainWindow::slotShowStatusMsg
void slotShowStatusMsg(const QString &)
Definition: mainwindow.cpp:1218
Kontact::MainWindow::setInitialActivePluginModule
void setInitialActivePluginModule(const QString &)
Definition: mainwindow.cpp:301
Kontact::MainWindow::slotNewToolbarConfig
void slotNewToolbarConfig()
Definition: mainwindow.cpp:1124
Kontact::Prefs::mSidePaneSplitter
QList< int > mSidePaneSplitter
Definition: prefs.h:246
Kontact::Prefs::mActivePlugin
QString mActivePlugin
Definition: prefs.h:243
Kontact::Prefs::setLastVersionSeen
static void setLastVersionSeen(const QString &v)
Set LastVersionSeen.
Definition: prefs.h:213
Kontact::MainWindow::slotShowTipOnStart
void slotShowTipOnStart()
Definition: mainwindow.cpp:1005
KSYCOCA_WAIT_TIMEOUT
static const int KSYCOCA_WAIT_TIMEOUT
Definition: mainwindow.cpp:80
aboutdialog.h
Kontact::MainWindow::slotNewClicked
void slotNewClicked()
Definition: mainwindow.cpp:755
mainwindow.h
kontactconfiguredialog.h
Kontact::MainWindow::~MainWindow
~MainWindow()
Definition: mainwindow.cpp:270
KPIM::StatusbarProgressWidget
KPIM::ProgressDialog
Kontact::MainWindow::selectPlugin
virtual void selectPlugin(KontactInterface::Plugin *plugin)
Definition: mainwindow.cpp:793
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
Kontact::Prefs::lastVersionSeen
static QString lastVersionSeen()
Get LastVersionSeen.
Definition: prefs.h:223
Kontact::MainWindow::updateConfig
void updateConfig()
Definition: mainwindow.cpp:1077
Kontact::MainWindow::showAboutDialog
void showAboutDialog()
Definition: mainwindow.cpp:1085
Kontact::SidePaneBase::updatePlugins
virtual void updatePlugins()=0
This method is called by the core whenever the count of plugins has changed.
Kontact::MainWindow::slotQuit
void slotQuit()
Definition: mainwindow.cpp:1029
Kontact::MainWindow::MainWindow
MainWindow()
Definition: mainwindow.cpp:138
Kontact::MainWindow::slotShowIntroduction
void slotShowIntroduction()
Definition: mainwindow.cpp:1010
Kontact::Prefs::self
static Prefs * self()
Definition: prefs.cpp:25
KHBox
iconsidepane.h
Kontact::MainWindow::slotShowTip
void slotShowTip()
Definition: mainwindow.cpp:1000
progressdialog.h
broadcaststatus.h
Kontact::MainWindow::slotActionTriggered
void slotActionTriggered()
Definition: mainwindow.cpp:947
Kontact::KontactConfigureDialog
Definition: kontactconfiguredialog.h:25
Kontact::AboutDialog
Definition: aboutdialog.h:39
Kontact::MainWindow::slotSyncClicked
void slotSyncClicked()
Definition: mainwindow.cpp:771
QList
version
static const char version[]
Definition: main.cpp:50
Kontact::Prefs::sidePaneSplitter
static QList< int > sidePaneSplitter()
Get SidePaneSplitter.
Definition: prefs.h:115
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:58:30 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

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