00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qcombobox.h>
00024 #include <qdockarea.h>
00025 #include <qguardedptr.h>
00026 #include <qhbox.h>
00027 #include <qimage.h>
00028 #include <qobjectlist.h>
00029 #include <qprogressbar.h>
00030 #include <qpushbutton.h>
00031 #include <qsplitter.h>
00032 #include <qtimer.h>
00033 #include <qwhatsthis.h>
00034
00035 #include <dcopclient.h>
00036 #include <kapplication.h>
00037 #include <kconfig.h>
00038 #include <kdebug.h>
00039 #include <kedittoolbar.h>
00040 #include <kguiitem.h>
00041 #include <khelpmenu.h>
00042 #include <kiconloader.h>
00043 #include <kkeydialog.h>
00044 #include <klibloader.h>
00045 #include <klistbox.h>
00046 #include <klocale.h>
00047 #include <kmessagebox.h>
00048 #include <kparts/componentfactory.h>
00049 #include <kplugininfo.h>
00050 #include <kpopupmenu.h>
00051 #include <ksettings/dialog.h>
00052 #include <ksettings/dispatcher.h>
00053 #include <kshortcut.h>
00054 #include <kstandarddirs.h>
00055 #include <kstatusbar.h>
00056 #include <kstdaction.h>
00057 #include <ktip.h>
00058 #include <ktrader.h>
00059 #include <ksettings/componentsdialog.h>
00060 #include <kstringhandler.h>
00061 #include <krsqueezedtextlabel.h>
00062 #include <khtml_part.h>
00063 #include <khtmlview.h>
00064 #include <libkdepim/kfileio.h>
00065 #include <kcursor.h>
00066 #include <krun.h>
00067 #include <kaboutdata.h>
00068 #include <kmenubar.h>
00069 #include <kstdaccel.h>
00070 #include <kcmultidialog.h>
00071 #include <kipc.h>
00072
00073 #include "aboutdialog.h"
00074 #include "iconsidepane.h"
00075 #include "mainwindow.h"
00076 #include "plugin.h"
00077 #include "prefs.h"
00078 #include "profiledialog.h"
00079 #include "profilemanager.h"
00080 #include "progressdialog.h"
00081 #include "statusbarprogresswidget.h"
00082 #include "broadcaststatus.h"
00083
00084 using namespace Kontact;
00085
00086 class SettingsDialogWrapper : public KSettings::Dialog
00087 {
00088 public:
00089 SettingsDialogWrapper( ContentInListView content, QWidget * parent = 0 )
00090 : KSettings::Dialog( content, parent, 0 )
00091 {
00092 }
00093
00094
00095 void fixButtonLabel( QWidget *widget )
00096 {
00097 QObject *object = widget->child( "KJanusWidget::buttonBelowList" );
00098 QPushButton *button = static_cast<QPushButton*>( object );
00099 if ( button )
00100 button->setText( i18n( "Select Components ..." ) );
00101 }
00102 };
00103
00104 MainWindow::MainWindow()
00105 : Kontact::Core(), mTopWidget( 0 ), mSplitter( 0 ),
00106 mCurrentPlugin( 0 ), mAboutDialog( 0 ), mReallyClose( false ), mSyncActionsEnabled( true )
00107 {
00108
00109
00110 setWFlags( getWFlags() | WGroupLeader );
00111
00112 initGUI();
00113 initObject();
00114 }
00115
00116 void MainWindow::initGUI()
00117 {
00118 initWidgets();
00119 setupActions();
00120 setHelpMenuEnabled( false );
00121 KHelpMenu *helpMenu = new KHelpMenu( this, 0, true, actionCollection() );
00122 connect( helpMenu, SIGNAL( showAboutApplication() ),
00123 SLOT( showAboutDialog() ) );
00124
00125 KStdAction::keyBindings( this, SLOT( configureShortcuts() ), actionCollection() );
00126 KStdAction::configureToolbars( this, SLOT( configureToolbars() ), actionCollection() );
00127 setXMLFile( "kontactui.rc" );
00128
00129 setStandardToolBarMenuEnabled( true );
00130
00131 createGUI( 0 );
00132
00133 resize( 700, 520 );
00134 setAutoSaveSettings();
00135
00136 connect( Kontact::ProfileManager::self(), SIGNAL( profileLoaded( const QString& ) ),
00137 this, SLOT( slotLoadProfile( const QString& ) ) );
00138 connect( Kontact::ProfileManager::self(), SIGNAL( saveToProfileRequested( const QString& ) ),
00139 this, SLOT( slotSaveToProfile( const QString& ) ) );
00140 }
00141
00142
00143 void MainWindow::initObject()
00144 {
00145 KTrader::OfferList offers = KTrader::self()->query(
00146 QString::fromLatin1( "Kontact/Plugin" ),
00147 QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );
00148 mPluginInfos = KPluginInfo::fromServices( offers, Prefs::self()->config(), "Plugins" );
00149
00150 KPluginInfo::List::Iterator it;
00151 for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) {
00152 ( *it )->load();
00153 }
00154
00155
00156 mPartManager = new KParts::PartManager( this );
00157 connect( mPartManager, SIGNAL( activePartChanged( KParts::Part* ) ),
00158 this, SLOT( slotActivePartChanged( KParts::Part* ) ) );
00159
00160 loadPlugins();
00161
00162 if ( mSidePane ) {
00163 mSidePane->updatePlugins();
00164 plugActionList( "navigator_actionlist", mSidePane->actions() );
00165 }
00166
00167 KSettings::Dispatcher::self()->registerInstance( instance(), this,
00168 SLOT( updateConfig() ) );
00169
00170 loadSettings();
00171
00172 statusBar()->show();
00173
00174 showTip( false );
00175
00176
00177 slotShowStatusMsg( QString::null );
00178
00179 connect( KPIM::BroadcastStatus::instance(), SIGNAL( statusMsg( const QString& ) ),
00180 this, SLOT( slotShowStatusMsg( const QString& ) ) );
00181
00182
00183 activatePluginModule();
00184
00185 if ( Prefs::lastVersionSeen() == kapp->aboutData()->version() ) {
00186 selectPlugin( mCurrentPlugin );
00187 }
00188
00189 paintAboutScreen( introductionString() );
00190 Prefs::setLastVersionSeen( kapp->aboutData()->version() );
00191 }
00192
00193 MainWindow::~MainWindow()
00194 {
00195 saveSettings();
00196
00197 QPtrList<KParts::Part> parts = *mPartManager->parts();
00198
00199 for ( KParts::Part *p = parts.last(); p; p = parts.prev() ) {
00200 delete p;
00201 p = 0;
00202 }
00203
00204 Prefs::self()->writeConfig();
00205 }
00206
00207 void MainWindow::setActivePluginModule( const QString &module )
00208 {
00209 mActiveModule = module;
00210 activatePluginModule();
00211 }
00212
00213 void MainWindow::activatePluginModule()
00214 {
00215 if ( !mActiveModule.isEmpty() ) {
00216 PluginList::ConstIterator end = mPlugins.end();
00217 for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
00218 if ( ( *it )->identifier().contains( mActiveModule ) ) {
00219 selectPlugin( *it );
00220 return;
00221 }
00222 }
00223 }
00224
00225 void MainWindow::initWidgets()
00226 {
00227
00228 mTopWidget = new QHBox( this );
00229 mTopWidget->setFrameStyle( QFrame::Panel | QFrame::Sunken );
00230 setCentralWidget( mTopWidget );
00231
00232 QHBox *mBox = 0;
00233 mSplitter = new QSplitter( mTopWidget );
00234 mBox = new QHBox( mTopWidget );
00235 mSidePane = new IconSidePane( this, mSplitter );
00236 mSidePane->setSizePolicy( QSizePolicy( QSizePolicy::Maximum,
00237 QSizePolicy::Preferred ) );
00238
00239 QValueList<int> sizes;
00240 sizes << 0;
00241 mSplitter->setSizes(sizes);
00242
00243 mSidePane->setActionCollection( actionCollection() );
00244
00245 connect( mSidePane, SIGNAL( pluginSelected( Kontact::Plugin * ) ),
00246 SLOT( selectPlugin( Kontact::Plugin * ) ) );
00247
00248 QVBox *vBox;
00249 if ( mSplitter ) {
00250 vBox = new QVBox( mSplitter );
00251 } else {
00252 vBox = new QVBox( mBox );
00253 }
00254
00255 vBox->setSpacing( 0 );
00256
00257 mPartsStack = new QWidgetStack( vBox );
00258 initAboutScreen();
00259
00260 QString loading = i18n( "<h2 style='text-align:center; margin-top: 0px; margin-bottom: 0px'>%1</h2>" )
00261 .arg( i18n("Loading Kontact...") );
00262
00263 paintAboutScreen( loading );
00264
00265
00266 KPIM::ProgressDialog *progressDialog = new KPIM::ProgressDialog( statusBar(), this );
00267 progressDialog->hide();
00268
00269 mLittleProgress = new KPIM::StatusbarProgressWidget( progressDialog, statusBar() );
00270
00271 mStatusMsgLabel = new KRSqueezedTextLabel( i18n( " Initializing..." ), statusBar() );
00272 mStatusMsgLabel->setAlignment( AlignLeft | AlignVCenter );
00273
00274 statusBar()->addWidget( mStatusMsgLabel, 10 , false );
00275 statusBar()->addWidget( mLittleProgress, 0 , true );
00276 mLittleProgress->show();
00277 }
00278
00279
00280 void MainWindow::paintAboutScreen( const QString& msg )
00281 {
00282 QString location = locate( "data", "kontact/about/main.html" );
00283 QString content = KPIM::kFileToString( location );
00284 content = content.arg( locate( "data", "libkdepim/about/kde_infopage.css" ) );
00285 if ( kapp->reverseLayout() )
00286 content = content.arg( "@import \"%1\";" ).arg( locate( "data", "libkdepim/about/kde_infopage_rtl.css" ) );
00287 else
00288 content = content.arg( "" );
00289
00290 mIntroPart->begin( KURL( location ) );
00291
00292 QString appName( i18n( "KDE Kontact" ) );
00293 QString catchPhrase( i18n( "Get Organized!" ) );
00294 QString quickDescription( i18n( "The KDE Personal Information Management Suite" ) );
00295
00296 mIntroPart->write( content.arg( QFont().pointSize() + 2 ).arg( appName )
00297 .arg( catchPhrase ).arg( quickDescription ).arg( msg ) );
00298 mIntroPart->end();
00299 }
00300
00301 void MainWindow::initAboutScreen()
00302 {
00303 QHBox *introbox = new QHBox( mPartsStack );
00304 mPartsStack->addWidget( introbox );
00305 mPartsStack->raiseWidget( introbox );
00306 mIntroPart = new KHTMLPart( introbox );
00307 mIntroPart->widget()->setFocusPolicy( WheelFocus );
00308
00309 mIntroPart->setPluginsEnabled( false );
00310 mIntroPart->setJScriptEnabled( false );
00311 mIntroPart->setJavaEnabled( false );
00312 mIntroPart->setMetaRefreshEnabled( false );
00313 mIntroPart->setURLCursor( KCursor::handCursor() );
00314 mIntroPart->view()->setLineWidth( 0 );
00315
00316 connect( mIntroPart->browserExtension(),
00317 SIGNAL( openURLRequest( const KURL&, const KParts::URLArgs& ) ),
00318 SLOT( slotOpenUrl( const KURL& ) ) );
00319
00320 connect( mIntroPart->browserExtension(),
00321 SIGNAL( createNewWindow( const KURL&, const KParts::URLArgs& ) ),
00322 SLOT( slotOpenUrl( const KURL& ) ) );
00323 }
00324
00325 void MainWindow::setupActions()
00326 {
00327 KStdAction::quit( this, SLOT( slotQuit() ), actionCollection() );
00328 mNewActions = new KToolBarPopupAction( KGuiItem( i18n( "New" ), "" ),
00329 KStdAccel::shortcut(KStdAccel::New), this, SLOT( slotNewClicked() ),
00330 actionCollection(), "action_new" );
00331
00332 KConfig* const cfg = Prefs::self()->config();
00333 cfg->setGroup( "Kontact Groupware Settings" );
00334 mSyncActionsEnabled = cfg->readBoolEntry( "GroupwareMailFoldersEnabled", true );
00335
00336 if ( mSyncActionsEnabled ) {
00337 mSyncActions = new KToolBarPopupAction( KGuiItem( i18n( "Synchronize" ), "kitchensync" ),
00338 KStdAccel::shortcut(KStdAccel::Reload), this, SLOT( slotSyncClicked() ),
00339 actionCollection(), "action_sync" );
00340 }
00341 new KAction( i18n( "Configure Kontact..." ), "configure", 0, this, SLOT( slotPreferences() ),
00342 actionCollection(), "settings_configure_kontact" );
00343
00344 new KAction( i18n( "Configure &Profiles..." ), 0, this, SLOT( slotConfigureProfiles() ),
00345 actionCollection(), "settings_configure_kontact_profiles" );
00346
00347 new KAction( i18n( "&Kontact Introduction" ), 0, this, SLOT( slotShowIntroduction() ),
00348 actionCollection(), "help_introduction" );
00349 new KAction( i18n( "&Tip of the Day" ), 0, this, SLOT( slotShowTip() ),
00350 actionCollection(), "help_tipofday" );
00351 new KAction( i18n( "&Request Feature..." ), 0, this, SLOT( slotRequestFeature() ),
00352 actionCollection(), "help_requestfeature" );
00353
00354 KWidgetAction* spacerAction = new KWidgetAction( new QWidget( this ), "SpacerAction", "", 0, 0, actionCollection(), "navigator_spacer_item" );
00355 spacerAction->setAutoSized( true );
00356 }
00357
00358 void MainWindow::slotConfigureProfiles()
00359 {
00360 QGuardedPtr<Kontact::ProfileDialog> dlg = new Kontact::ProfileDialog( this );
00361 dlg->setModal( true );
00362 dlg->exec();
00363 delete dlg;
00364 }
00365
00366 namespace {
00367 void copyConfigEntry( KConfig* source, KConfig* dest, const QString& group, const QString& key, const QString& defaultValue=QString() )
00368 {
00369 source->setGroup( group );
00370 dest->setGroup( group );
00371 dest->writeEntry( key, source->readEntry( key, defaultValue ) );
00372 }
00373 }
00374
00375 void MainWindow::slotSaveToProfile( const QString& id )
00376 {
00377 const QString path = Kontact::ProfileManager::self()->profileById( id ).saveLocation();
00378 if ( path.isNull() )
00379 return;
00380
00381 KConfig* const cfg = Prefs::self()->config();
00382 Prefs::self()->writeConfig();
00383 saveMainWindowSettings( cfg );
00384 saveSettings();
00385
00386 KConfig profile( path+"/kontactrc", false, false );
00387 ::copyConfigEntry( cfg, &profile, "MainWindow Toolbar navigatorToolBar", "Hidden", "true" );
00388 ::copyConfigEntry( cfg, &profile, "View", "SidePaneSplitter" );
00389 ::copyConfigEntry( cfg, &profile, "Icons", "Theme" );
00390
00391 for ( PluginList::Iterator it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00392 if ( !(*it)->isRunningStandalone() ) {
00393 (*it)->part();
00394 }
00395 (*it)->saveToProfile( path );
00396 }
00397 }
00398
00399 void MainWindow::slotLoadProfile( const QString& id )
00400 {
00401 const QString path = Kontact::ProfileManager::self()->profileById( id ).saveLocation();
00402 if ( path.isNull() )
00403 return;
00404
00405 KConfig* const cfg = Prefs::self()->config();
00406 Prefs::self()->writeConfig();
00407 saveMainWindowSettings( cfg );
00408 saveSettings();
00409
00410 const KConfig profile( path+"/kontactrc", false, false );
00411 const QStringList groups = profile.groupList();
00412 for ( QStringList::ConstIterator it = groups.begin(), end = groups.end(); it != end; ++it )
00413 {
00414 cfg->setGroup( *it );
00415 typedef QMap<QString, QString> StringMap;
00416 const StringMap entries = profile.entryMap( *it );
00417 for ( StringMap::ConstIterator it2 = entries.begin(), end = entries.end(); it2 != end; ++it2 )
00418 {
00419 if ( it2.data() == "KONTACT_PROFILE_DELETE_KEY" )
00420 cfg->deleteEntry( it2.key() );
00421 else
00422 cfg->writeEntry( it2.key(), it2.data() );
00423 }
00424 }
00425
00426 cfg->sync();
00427 Prefs::self()->readConfig();
00428 applyMainWindowSettings( cfg );
00429 KIconTheme::reconfigure();
00430 const WId wid = winId();
00431 KIPC::sendMessage( KIPC::PaletteChanged, wid );
00432 KIPC::sendMessage( KIPC::FontChanged, wid );
00433 KIPC::sendMessage( KIPC::StyleChanged, wid );
00434 KIPC::sendMessage( KIPC::SettingsChanged, wid );
00435 for ( int i = 0; i < KIcon::LastGroup; ++i )
00436 KIPC::sendMessage( KIPC::IconChanged, wid, i );
00437
00438 loadSettings();
00439
00440 for ( PluginList::Iterator it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00441 if ( !(*it)->isRunningStandalone() ) {
00442 kdDebug() << "Ensure loaded: " << (*it)->identifier() << endl;
00443 (*it)->part();
00444 }
00445 (*it)->loadProfile( path );
00446 }
00447 }
00448
00449 bool MainWindow::isPluginLoaded( const KPluginInfo *info )
00450 {
00451 return (pluginFromInfo( info ) != 0);
00452 }
00453
00454 Plugin *MainWindow::pluginFromInfo( const KPluginInfo *info )
00455 {
00456 PluginList::ConstIterator end = mPlugins.end();
00457 for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
00458 if ( (*it)->identifier() == info->pluginName() )
00459 return *it;
00460
00461 return 0;
00462 }
00463
00464 void MainWindow::loadPlugins()
00465 {
00466 QPtrList<Plugin> plugins;
00467 QPtrList<KParts::Part> loadDelayed;
00468
00469 uint i;
00470 KPluginInfo::List::ConstIterator it;
00471 for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) {
00472 if ( !(*it)->isPluginEnabled() )
00473 continue;
00474 if ( isPluginLoaded( *it ) ) {
00475 Plugin *plugin = pluginFromInfo( *it );
00476 if ( plugin )
00477 plugin->configUpdated();
00478 continue;
00479 }
00480
00481 kdDebug(5600) << "Loading Plugin: " << (*it)->name() << endl;
00482 Kontact::Plugin *plugin =
00483 KParts::ComponentFactory::createInstanceFromService<Kontact::Plugin>(
00484 (*it)->service(), this );
00485
00486 if ( !plugin )
00487 continue;
00488
00489 plugin->setIdentifier( (*it)->pluginName() );
00490 plugin->setTitle( (*it)->name() );
00491 plugin->setIcon( (*it)->icon() );
00492
00493 QVariant libNameProp = (*it)->property( "X-KDE-KontactPartLibraryName" );
00494 QVariant exeNameProp = (*it)->property( "X-KDE-KontactPartExecutableName" );
00495 QVariant loadOnStart = (*it)->property( "X-KDE-KontactPartLoadOnStart" );
00496 QVariant hasPartProp = (*it)->property( "X-KDE-KontactPluginHasPart" );
00497
00498 if ( !loadOnStart.isNull() && loadOnStart.toBool() )
00499 mDelayedPreload.append( plugin );
00500
00501 kdDebug(5600) << "LIBNAMEPART: " << libNameProp.toString() << endl;
00502
00503 plugin->setPartLibraryName( libNameProp.toString().utf8() );
00504 plugin->setExecutableName( exeNameProp.toString() );
00505 if ( hasPartProp.isValid() )
00506 plugin->setShowInSideBar( hasPartProp.toBool() );
00507
00508 for ( i = 0; i < plugins.count(); ++i ) {
00509 Plugin *p = plugins.at( i );
00510 if ( plugin->weight() < p->weight() )
00511 break;
00512 }
00513
00514 plugins.insert( i, plugin );
00515 }
00516
00517 for ( i = 0; i < plugins.count(); ++ i ) {
00518 Plugin *plugin = plugins.at( i );
00519
00520 KAction *action;
00521 QPtrList<KAction> *actionList = plugin->newActions();
00522
00523 for ( action = actionList->first(); action; action = actionList->next() ) {
00524 kdDebug(5600) << "Plugging " << action->name() << endl;
00525 action->plug( mNewActions->popupMenu() );
00526 }
00527
00528 if ( mSyncActionsEnabled ) {
00529 actionList = plugin->syncActions();
00530 for ( action = actionList->first(); action; action = actionList->next() ) {
00531 kdDebug(5600) << "Plugging " << action->name() << endl;
00532 action->plug( mSyncActions->popupMenu() );
00533 }
00534 }
00535 addPlugin( plugin );
00536 }
00537
00538 mNewActions->setEnabled( mPlugins.size() != 0 );
00539 if ( mSyncActionsEnabled )
00540 mSyncActions->setEnabled( mPlugins.size() != 0 );
00541 }
00542
00543 void MainWindow::unloadPlugins()
00544 {
00545 KPluginInfo::List::ConstIterator end = mPluginInfos.end();
00546 KPluginInfo::List::ConstIterator it;
00547 for ( it = mPluginInfos.begin(); it != end; ++it ) {
00548 if ( !(*it)->isPluginEnabled() )
00549 removePlugin( *it );
00550 }
00551 }
00552
00553 bool MainWindow::removePlugin( const KPluginInfo *info )
00554 {
00555 PluginList::Iterator end = mPlugins.end();
00556 for ( PluginList::Iterator it = mPlugins.begin(); it != end; ++it )
00557 if ( ( *it )->identifier() == info->pluginName() ) {
00558 Plugin *plugin = *it;
00559
00560 KAction *action;
00561 QPtrList<KAction> *actionList = plugin->newActions();
00562
00563 for ( action = actionList->first(); action; action = actionList->next() ) {
00564 kdDebug(5600) << "Unplugging " << action->name() << endl;
00565 action->unplug( mNewActions->popupMenu() );
00566 }
00567
00568 if ( mSyncActionsEnabled ) {
00569 actionList = plugin->syncActions();
00570 for ( action = actionList->first(); action; action = actionList->next() ) {
00571 kdDebug(5600) << "Unplugging " << action->name() << endl;
00572 action->unplug( mSyncActions->popupMenu() );
00573 }
00574 }
00575 removeChildClient( plugin );
00576
00577 if ( mCurrentPlugin == plugin )
00578 mCurrentPlugin = 0;
00579
00580 delete plugin;
00581 mPlugins.remove( it );
00582
00583 if ( mCurrentPlugin == 0 ) {
00584 PluginList::Iterator it;
00585 for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00586 if ( (*it)->showInSideBar() ) {
00587 selectPlugin( *it );
00588 return true;
00589 }
00590 }
00591 }
00592
00593 return true;
00594 }
00595
00596 return false;
00597 }
00598
00599 void MainWindow::addPlugin( Kontact::Plugin *plugin )
00600 {
00601 kdDebug(5600) << "Added plugin" << endl;
00602
00603 mPlugins.append( plugin );
00604
00605
00606 insertChildClient( plugin );
00607 }
00608
00609 void MainWindow::partLoaded( Kontact::Plugin*, KParts::ReadOnlyPart *part )
00610 {
00611
00612 if ( mPartsStack->id( part->widget() ) != -1 )
00613 return;
00614
00615 mPartsStack->addWidget( part->widget() );
00616
00617 mPartManager->addPart( part, false );
00618
00619 part->widget()->hide();
00620 }
00621
00622 void MainWindow::slotActivePartChanged( KParts::Part *part )
00623 {
00624 if ( !part ) {
00625 createGUI( 0 );
00626 return;
00627 }
00628
00629 kdDebug(5600) << "Part activated: " << part << " with stack id. "
00630 << mPartsStack->id( part->widget() )<< endl;
00631
00632
00633
00634 statusBar()->clear();
00635 }
00636
00637 void MainWindow::slotNewClicked()
00638 {
00639 KAction *action = mCurrentPlugin->newActions()->first();
00640 if ( action ) {
00641 action->activate();
00642 } else {
00643 PluginList::Iterator it;
00644 for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00645 action = (*it)->newActions()->first();
00646 if ( action ) {
00647 action->activate();
00648 return;
00649 }
00650 }
00651 }
00652 }
00653
00654 void MainWindow::slotSyncClicked()
00655 {
00656 KAction *action = mCurrentPlugin->syncActions()->first();
00657 if ( action ) {
00658 action->activate();
00659 } else {
00660 PluginList::Iterator it;
00661 for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00662 action = (*it)->syncActions()->first();
00663 if ( action ) {
00664 action->activate();
00665 return;
00666 }
00667 }
00668 }
00669 }
00670
00671 KToolBar* Kontact::MainWindow::findToolBar(const char* name)
00672 {
00673
00674 return static_cast<KToolBar *>(child(name, "KToolBar"));
00675 }
00676
00677 void MainWindow::selectPlugin( Kontact::Plugin *plugin )
00678 {
00679 if ( !plugin )
00680 return;
00681
00682 if ( plugin->isRunningStandalone() ) {
00683 statusBar()->message( i18n( "Application is running standalone. Foregrounding..." ), 1000 );
00684 mSidePane->indicateForegrunding( plugin );
00685 plugin->bringToForeground();
00686 return;
00687 }
00688
00689 KApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
00690
00691 KParts::Part *part = plugin->part();
00692
00693 if ( !part ) {
00694 KApplication::restoreOverrideCursor();
00695 KMessageBox::error( this, i18n( "Cannot load part for %1." )
00696 .arg( plugin->title() )
00697 + "\n" + lastErrorMessage() );
00698 plugin->setDisabled( true );
00699 mSidePane->updatePlugins();
00700 return;
00701 }
00702
00703
00704 QWidget *focusWidget = kapp->focusWidget();
00705 if ( mCurrentPlugin && focusWidget ) {
00706
00707 QWidget *parent = focusWidget->parentWidget();
00708 while ( parent ) {
00709 if ( parent == mCurrentPlugin->part()->widget() )
00710 mFocusWidgets.insert( mCurrentPlugin->identifier(), QGuardedPtr<QWidget>( focusWidget ) );
00711
00712 parent = parent->parentWidget();
00713 }
00714 }
00715
00716 if ( mSidePane )
00717 mSidePane->selectPlugin( plugin );
00718
00719 plugin->select();
00720
00721 mPartManager->setActivePart( part );
00722 QWidget *view = part->widget();
00723 Q_ASSERT( view );
00724
00725 if ( view ) {
00726 mPartsStack->raiseWidget( view );
00727 view->show();
00728
00729 if ( mFocusWidgets.contains( plugin->identifier() ) ) {
00730 focusWidget = mFocusWidgets[ plugin->identifier() ];
00731 if ( focusWidget )
00732 focusWidget->setFocus();
00733 } else
00734 view->setFocus();
00735
00736 mCurrentPlugin = plugin;
00737 KAction *newAction = plugin->newActions()->first();
00738 KAction *syncAction = plugin->syncActions()->first();
00739
00740 createGUI( plugin->part() );
00741
00742 KToolBar* navigatorToolBar = findToolBar( "navigatorToolBar" );
00743
00744 if ( navigatorToolBar && !navigatorToolBar->isHidden() &&
00745 navigatorToolBar->barPos() == KToolBar::Top ) {
00746 topDock()->moveDockWindow( navigatorToolBar, -1 );
00747 }
00748
00749 setCaption( i18n( "Plugin dependent window title" ,"%1 - Kontact" ).arg( plugin->title() ) );
00750
00751 if ( newAction ) {
00752 mNewActions->setIcon( newAction->icon() );
00753 mNewActions->setText( newAction->text() );
00754 } else {
00755 PluginList::Iterator it;
00756 for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00757 newAction = (*it)->newActions()->first();
00758 if ( newAction ) {
00759 mNewActions->setIcon( newAction->icon() );
00760 mNewActions->setText( newAction->text() );
00761 break;
00762 }
00763 }
00764 }
00765 if ( mSyncActionsEnabled ) {
00766 if ( syncAction ) {
00767 mSyncActions->setIcon( syncAction->icon() );
00768 mSyncActions->setText( syncAction->text() );
00769 } else {
00770 PluginList::Iterator it;
00771 for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00772 syncAction = (*it)->syncActions()->first();
00773 if ( syncAction ) {
00774 mSyncActions->setIcon( syncAction->icon() );
00775 mSyncActions->setText( syncAction->text() );
00776 break;
00777 }
00778 }
00779 }
00780 }
00781 }
00782 QStringList invisibleActions = plugin->invisibleToolbarActions();
00783
00784 QStringList::ConstIterator it;
00785 for ( it = invisibleActions.begin(); it != invisibleActions.end(); ++it ) {
00786 KAction *action = part->actionCollection()->action( (*it).latin1() );
00787 if ( action ) {
00788 QPtrListIterator<KToolBar> it( toolBarIterator() );
00789 for ( ; it.current() ; ++it ) {
00790 action->unplug( it.current() );
00791 }
00792 }
00793 }
00794
00795 KApplication::restoreOverrideCursor();
00796 }
00797
00798 void MainWindow::selectPlugin( const QString &pluginName )
00799 {
00800 PluginList::ConstIterator end = mPlugins.end();
00801 for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
00802 if ( ( *it )->identifier() == pluginName ) {
00803 selectPlugin( *it );
00804 return;
00805 }
00806 }
00807
00808 void MainWindow::loadSettings()
00809 {
00810 if ( mSplitter )
00811 mSplitter->setSizes( Prefs::self()->mSidePaneSplitter );
00812
00813
00814 PluginList::ConstIterator it;
00815 for ( it = mDelayedPreload.begin(); it != mDelayedPreload.end(); ++it )
00816 selectPlugin( *it );
00817
00818 selectPlugin( Prefs::self()->mActivePlugin );
00819 }
00820
00821 void MainWindow::saveSettings()
00822 {
00823 if ( mSplitter )
00824 Prefs::self()->mSidePaneSplitter = mSplitter->sizes();
00825
00826 if ( mCurrentPlugin )
00827 Prefs::self()->mActivePlugin = mCurrentPlugin->identifier();
00828 }
00829
00830 void MainWindow::slotShowTip()
00831 {
00832 showTip( true );
00833 }
00834
00835 void MainWindow::slotRequestFeature()
00836 {
00837 if ( kapp )
00838 kapp->invokeBrowser( "http://kontact.org/shopping" );
00839 }
00840
00841 void MainWindow::slotShowIntroduction()
00842 {
00843 mPartsStack->raiseWidget( 0 );
00844 }
00845
00846 void MainWindow::showTip( bool force )
00847 {
00848 QStringList tips;
00849 PluginList::ConstIterator end = mPlugins.end();
00850 for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) {
00851 QString file = (*it)->tipFile();
00852 if ( !file.isEmpty() )
00853 tips.append( file );
00854 }
00855
00856 KTipDialog::showMultiTip( this, tips, force );
00857 }
00858
00859 void MainWindow::slotQuit()
00860 {
00861 mReallyClose = true;
00862 close();
00863 }
00864
00865 void MainWindow::slotPreferences()
00866 {
00867 static SettingsDialogWrapper *dlg = 0;
00868 if ( !dlg ) {
00869
00870 QValueList<KPluginInfo*> filteredPlugins = mPluginInfos;
00871 PluginList::ConstIterator it;
00872 for ( it = mPlugins.begin(); it != mPlugins.end(); ++it )
00873 if ( (*it)->isRunningStandalone() ) {
00874 QValueList<KPluginInfo*>::ConstIterator infoIt;
00875 for ( infoIt = filteredPlugins.begin(); infoIt != filteredPlugins.end(); ++infoIt ) {
00876 if ( (*infoIt)->pluginName() == (*it)->identifier() ) {
00877 filteredPlugins.remove( *infoIt );
00878 break;
00879 }
00880 }
00881 }
00882 dlg = new SettingsDialogWrapper( KSettings::Dialog::Configurable, this );
00883 dlg->addPluginInfos( filteredPlugins );
00884 connect( dlg, SIGNAL( pluginSelectionChanged() ),
00885 SLOT( pluginsChanged() ) );
00886 }
00887
00888 dlg->show();
00889 dlg->fixButtonLabel( this );
00890 }
00891
00892 int MainWindow::startServiceFor( const QString& serviceType,
00893 const QString& constraint,
00894 const QString& preferences,
00895 QString *error, QCString* dcopService,
00896 int flags )
00897 {
00898 PluginList::ConstIterator end = mPlugins.end();
00899 for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) {
00900 if ( (*it)->createDCOPInterface( serviceType ) ) {
00901 kdDebug(5600) << "found interface for " << serviceType << endl;
00902 if ( dcopService )
00903 *dcopService = (*it)->dcopClient()->appId();
00904 kdDebug(5600) << "appId=" << (*it)->dcopClient()->appId() << endl;
00905 return 0;
00906 }
00907 }
00908
00909 kdDebug(5600) <<
00910 "Didn't find dcop interface, falling back to external process" << endl;
00911
00912 return KDCOPServiceStarter::startServiceFor( serviceType, constraint,
00913 preferences, error, dcopService, flags );
00914 }
00915
00916 void MainWindow::pluginsChanged()
00917 {
00918 unplugActionList( "navigator_actionlist" );
00919 unloadPlugins();
00920 loadPlugins();
00921 mSidePane->updatePlugins();
00922 plugActionList( "navigator_actionlist", mSidePane->actions() );
00923 }
00924
00925 void MainWindow::updateConfig()
00926 {
00927 kdDebug( 5600 ) << k_funcinfo << endl;
00928
00929 saveSettings();
00930 loadSettings();
00931 }
00932
00933 void MainWindow::showAboutDialog()
00934 {
00935 KApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
00936
00937 if ( !mAboutDialog )
00938 mAboutDialog = new AboutDialog( this );
00939
00940 mAboutDialog->show();
00941 mAboutDialog->raise();
00942 KApplication::restoreOverrideCursor();
00943 }
00944
00945 void MainWindow::configureShortcuts()
00946 {
00947 KKeyDialog dialog( true, this );
00948 dialog.insert( actionCollection() );
00949
00950 if ( mCurrentPlugin && mCurrentPlugin->part() )
00951 dialog.insert( mCurrentPlugin->part()->actionCollection() );
00952
00953 dialog.configure();
00954 }
00955
00956 void MainWindow::configureToolbars()
00957 {
00958 saveMainWindowSettings( KGlobal::config(), "MainWindow" );
00959
00960 KEditToolbar edit( factory() );
00961 connect( &edit, SIGNAL( newToolbarConfig() ),
00962 this, SLOT( slotNewToolbarConfig() ) );
00963 edit.exec();
00964 }
00965
00966 void MainWindow::slotNewToolbarConfig()
00967 {
00968 if ( mCurrentPlugin && mCurrentPlugin->part() )
00969 createGUI( mCurrentPlugin->part() );
00970 applyMainWindowSettings( KGlobal::config(), "MainWindow" );
00971 }
00972
00973 void MainWindow::slotOpenUrl( const KURL &url )
00974 {
00975 if ( url.protocol() == "exec" ) {
00976 if ( url.path() == "/switch" ) {
00977 selectPlugin( mCurrentPlugin );
00978 }
00979 if ( url.path() == "/gwwizard" ) {
00980 KRun::runCommand( "groupwarewizard" );
00981 slotQuit();
00982 }
00983 } else
00984 new KRun( url, this );
00985 }
00986
00987 void MainWindow::readProperties( KConfig *config )
00988 {
00989 Core::readProperties( config );
00990
00991 QStringList activePlugins = config->readListEntry( "ActivePlugins" );
00992 QValueList<Plugin*>::ConstIterator it = mPlugins.begin();
00993 QValueList<Plugin*>::ConstIterator end = mPlugins.end();
00994 for ( ; it != end; ++it ) {
00995 Plugin *plugin = *it;
00996 if ( !plugin->isRunningStandalone() ) {
00997 QStringList::ConstIterator activePlugin = activePlugins.find( plugin->identifier() );
00998 if ( activePlugin != activePlugins.end() ) {
00999 plugin->readProperties( config );
01000 }
01001 }
01002 }
01003 }
01004
01005 void MainWindow::saveProperties( KConfig *config )
01006 {
01007 Core::saveProperties( config );
01008
01009 QStringList activePlugins;
01010
01011 KPluginInfo::List::Iterator it = mPluginInfos.begin();
01012 KPluginInfo::List::Iterator end = mPluginInfos.end();
01013 for ( ; it != end; ++it ) {
01014 KPluginInfo *info = *it;
01015 if ( info->isPluginEnabled() ) {
01016 Plugin *plugin = pluginFromInfo( info );
01017 if ( plugin ) {
01018 activePlugins.append( plugin->identifier() );
01019 plugin->saveProperties( config );
01020 }
01021 }
01022 }
01023
01024 config->writeEntry( "ActivePlugins", activePlugins );
01025 }
01026
01027 bool MainWindow::queryClose()
01028 {
01029 if ( kapp->sessionSaving() || mReallyClose )
01030 return true;
01031
01032 bool localClose = true;
01033 QValueList<Plugin*>::ConstIterator end = mPlugins.end();
01034 QValueList<Plugin*>::ConstIterator it = mPlugins.begin();
01035 for ( ; it != end; ++it ) {
01036 Plugin *plugin = *it;
01037 if ( !plugin->isRunningStandalone() )
01038 if ( !plugin->queryClose() )
01039 localClose = false;
01040 }
01041
01042 return localClose;
01043 }
01044
01045 void MainWindow::slotShowStatusMsg( const QString &msg )
01046 {
01047 if ( !statusBar() || !mStatusMsgLabel )
01048 return;
01049
01050 mStatusMsgLabel->setText( msg );
01051 }
01052
01053 QString MainWindow::introductionString()
01054 {
01055 KIconLoader *iconloader = KGlobal::iconLoader();
01056 int iconSize = iconloader->currentSize( KIcon::Desktop );
01057
01058 QString handbook_icon_path = iconloader->iconPath( "contents2", KIcon::Desktop );
01059 QString html_icon_path = iconloader->iconPath( "html", KIcon::Desktop );
01060 QString wizard_icon_path = iconloader->iconPath( "wizard", KIcon::Desktop );
01061
01062 QString info = i18n( "<h2 style='text-align:center; margin-top: 0px;'>Welcome to Kontact %1</h2>"
01063 "<p>%1</p>"
01064 "<table align=\"center\">"
01065 "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
01066 "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
01067 "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
01068 "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
01069 "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
01070 "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
01071 "</table>"
01072 "<p style=\"margin-bottom: 0px\"> <a href=\"%1\">Skip this introduction</a></p>" )
01073 .arg( kapp->aboutData()->version() )
01074 .arg( i18n( "Kontact handles your e-mail, addressbook, calendar, to-do list and more." ) )
01075 .arg( "help:/kontact" )
01076 .arg( iconSize )
01077 .arg( iconSize )
01078 .arg( handbook_icon_path )
01079 .arg( "help:/kontact" )
01080 .arg( i18n( "Read Manual" ) )
01081 .arg( i18n( "Learn more about Kontact and its components" ) )
01082 .arg( "http://kontact.org" )
01083 .arg( iconSize )
01084 .arg( iconSize )
01085 .arg( html_icon_path )
01086 .arg( "http://kontact.org" )
01087 .arg( i18n( "Visit Kontact Website" ) )
01088 .arg( i18n( "Access online resources and tutorials" ) )
01089 .arg( "exec:/gwwizard" )
01090 .arg( iconSize )
01091 .arg( iconSize )
01092 .arg( wizard_icon_path )
01093 .arg( "exec:/gwwizard" )
01094 .arg( i18n( "Configure Kontact as Groupware Client" ) )
01095 .arg( i18n( "Prepare Kontact for use in corporate networks" ) )
01096 .arg( "exec:/switch" );
01097 return info;
01098 }
01099
01100 #include "mainwindow.moc"