kontact

mainwindow.cpp

00001 /*
00002     This file is part of KDE Kontact.
00003 
00004     Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
00005     Copyright (c) 2002-2005 Daniel Molkentin <molkentin@kde.org>
00006     Copyright (c) 2003-2005 Cornelius Schumacher <schumacher@kde.org>
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include <qcombobox.h>
00024 #include <qhbox.h>
00025 #include <qimage.h>
00026 #include <qobjectlist.h>
00027 #include <qprogressbar.h>
00028 #include <qpushbutton.h>
00029 #include <qsplitter.h>
00030 #include <qtimer.h>
00031 #include <qwhatsthis.h>
00032 
00033 #include <dcopclient.h>
00034 #include <kapplication.h>
00035 #include <kconfig.h>
00036 #include <kdebug.h>
00037 #include <kedittoolbar.h>
00038 #include <kguiitem.h>
00039 #include <khelpmenu.h>
00040 #include <kiconloader.h>
00041 #include <kkeydialog.h>
00042 #include <klibloader.h>
00043 #include <klistbox.h>
00044 #include <klocale.h>
00045 #include <kmessagebox.h>
00046 #include <kparts/componentfactory.h>
00047 #include <kplugininfo.h>
00048 #include <kpopupmenu.h>
00049 #include <ksettings/dialog.h>
00050 #include <ksettings/dispatcher.h>
00051 #include <kshortcut.h>
00052 #include <kstandarddirs.h>
00053 #include <kstatusbar.h>
00054 #include <kstdaction.h>
00055 #include <ktip.h>
00056 #include <ktrader.h>
00057 #include <ksettings/componentsdialog.h>
00058 #include <kstringhandler.h>
00059 #include <krsqueezedtextlabel.h>
00060 #include <khtml_part.h>
00061 #include <khtmlview.h>
00062 #include <libkdepim/kfileio.h>
00063 #include <kcursor.h>
00064 #include <krun.h>
00065 #include <kaboutdata.h>
00066 #include <kmenubar.h>
00067 #include <kstdaccel.h>
00068 
00069 #include "aboutdialog.h"
00070 #include "iconsidepane.h"
00071 #include "mainwindow.h"
00072 #include "plugin.h"
00073 #include "prefs.h"
00074 #include "progressdialog.h"
00075 #include "statusbarprogresswidget.h"
00076 #include "broadcaststatus.h"
00077 
00078 using namespace Kontact;
00079 
00080 class SettingsDialogWrapper : public KSettings::Dialog
00081 {
00082   public:
00083     SettingsDialogWrapper( ContentInListView content, QWidget * parent = 0 )
00084       : KSettings::Dialog( content, parent, 0 )
00085     {
00086     }
00087 
00088 
00089     void fixButtonLabel( QWidget *widget )
00090     {
00091       QObject *object = widget->child( "KJanusWidget::buttonBelowList" );
00092       QPushButton *button = static_cast<QPushButton*>( object );
00093       if ( button )
00094         button->setText( i18n( "Select Components..." ) );
00095     }
00096 };
00097 
00098 MainWindow::MainWindow()
00099   : Kontact::Core(), mTopWidget( 0 ), mSplitter( 0 ),
00100     mCurrentPlugin( 0 ), mAboutDialog( 0 ), mReallyClose( false )
00101 {
00102   // Set this to be the group leader for all subdialogs - this means
00103   // modal subdialogs will only affect this dialog, not the other windows
00104   setWFlags( getWFlags() | WGroupLeader );
00105 
00106   initGUI();
00107   initObject();
00108 }
00109 
00110 void MainWindow::initGUI()
00111 {
00112   initWidgets();
00113   setupActions();
00114   setHelpMenuEnabled( false );
00115   KHelpMenu *helpMenu = new KHelpMenu( this, 0, true, actionCollection() );
00116   connect( helpMenu, SIGNAL( showAboutApplication() ),
00117            SLOT( showAboutDialog() ) );
00118 
00119   KStdAction::keyBindings( this, SLOT( configureShortcuts() ), actionCollection() );
00120   KStdAction::configureToolbars( this, SLOT( configureToolbars() ), actionCollection() );
00121   setXMLFile( "kontactui.rc" );
00122 
00123   setStandardToolBarMenuEnabled( true );
00124 
00125   createGUI( 0 );
00126 
00127   resize( 700, 520 ); // initial size to prevent a scrollbar in sidepane
00128   setAutoSaveSettings();
00129 }
00130 
00131 
00132 void MainWindow::initObject()
00133 {
00134   KTrader::OfferList offers = KTrader::self()->query(
00135       QString::fromLatin1( "Kontact/Plugin" ),
00136       QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );
00137   mPluginInfos = KPluginInfo::fromServices( offers, Prefs::self()->config(), "Plugins" );
00138 
00139   KPluginInfo::List::Iterator it;
00140   for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) {
00141     ( *it )->load();
00142   }
00143 
00144 
00145   // prepare the part manager
00146   mPartManager = new KParts::PartManager( this );
00147   connect( mPartManager, SIGNAL( activePartChanged( KParts::Part* ) ),
00148            this, SLOT( slotActivePartChanged( KParts::Part* ) ) );
00149 
00150   loadPlugins();
00151 
00152   if ( mSidePane ) {
00153     mSidePane->updatePlugins();
00154     plugActionList( "navigator_actionlist", mSidePane->actions() );
00155   }
00156 
00157   KSettings::Dispatcher::self()->registerInstance( instance(), this,
00158                                                    SLOT( updateConfig() ) );
00159 
00160   loadSettings();
00161 
00162   statusBar()->show();
00163 
00164   showTip( false );
00165 
00166   // done initializing
00167   slotShowStatusMsg( QString::null );
00168 
00169   connect( KPIM::BroadcastStatus::instance(), SIGNAL( statusMsg( const QString& ) ),
00170            this, SLOT( slotShowStatusMsg( const QString&  ) ) );
00171 
00172   // launch commandline specified module if any
00173   activatePluginModule();
00174 
00175   if ( Prefs::lastVersionSeen() == kapp->aboutData()->version() ) {
00176     selectPlugin( mCurrentPlugin );
00177   }
00178 
00179   paintAboutScreen( introductionString() );
00180   Prefs::setLastVersionSeen( kapp->aboutData()->version() );
00181 }
00182 
00183 MainWindow::~MainWindow()
00184 {
00185   saveSettings();
00186 
00187   QPtrList<KParts::Part> parts = *mPartManager->parts();
00188 
00189   for ( KParts::Part *p = parts.last(); p; p = parts.prev() ) {
00190     delete p;
00191     p = 0;
00192   }
00193 
00194   Prefs::self()->writeConfig();
00195 }
00196 
00197 void MainWindow::setActivePluginModule( const QString &module )
00198 {
00199   mActiveModule = module;
00200   activatePluginModule();
00201 }
00202 
00203 void MainWindow::activatePluginModule()
00204 {
00205   if ( !mActiveModule.isEmpty() ) {
00206     PluginList::ConstIterator end = mPlugins.end();
00207     for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
00208       if ( ( *it )->identifier().contains( mActiveModule ) ) {
00209         selectPlugin( *it );
00210         return;
00211       }
00212   }
00213 }
00214 
00215 void MainWindow::initWidgets()
00216 {
00217   // includes sidebar and part stack
00218   mTopWidget = new QHBox( this );
00219   mTopWidget->setFrameStyle( QFrame::Panel | QFrame::Sunken );
00220   setCentralWidget( mTopWidget );
00221 
00222   QHBox *mBox = 0;
00223   mSplitter = new QSplitter( mTopWidget );
00224   mBox = new QHBox( mTopWidget );
00225   mSidePane = new IconSidePane( this, mSplitter );
00226   mSidePane->setSizePolicy( QSizePolicy( QSizePolicy::Maximum,
00227                                          QSizePolicy::Preferred ) );
00228   // donÄt occupy screen estate on load
00229   QValueList<int> sizes;
00230   sizes << 0;
00231   mSplitter->setSizes(sizes);
00232 
00233   mSidePane->setActionCollection( actionCollection() );
00234 
00235   connect( mSidePane, SIGNAL( pluginSelected( Kontact::Plugin * ) ),
00236            SLOT( selectPlugin( Kontact::Plugin * ) ) );
00237 
00238   QVBox *vBox;
00239   if ( mSplitter ) {
00240     vBox = new QVBox( mSplitter );
00241   } else {
00242     vBox = new QVBox( mBox );
00243   }
00244 
00245   vBox->setSpacing( 0 );
00246 
00247   mPartsStack = new QWidgetStack( vBox );
00248   initAboutScreen();
00249 
00250   QString loading = i18n( "<h2 style='text-align:center; margin-top: 0px; margin-bottom: 0px'>%1</h2>" )
00251                     .arg( i18n("Loading Kontact...") );
00252 
00253   paintAboutScreen( loading );
00254 
00255   /* Create a progress dialog and hide it. */
00256   KPIM::ProgressDialog *progressDialog = new KPIM::ProgressDialog( statusBar(), this );
00257   progressDialog->hide();
00258 
00259   mLittleProgress = new KPIM::StatusbarProgressWidget( progressDialog, statusBar() );
00260 
00261   mStatusMsgLabel = new KRSqueezedTextLabel( i18n( " Initializing..." ), statusBar() );
00262   mStatusMsgLabel->setAlignment( AlignLeft | AlignVCenter );
00263 
00264   statusBar()->addWidget( mStatusMsgLabel, 10 , false );
00265   statusBar()->addWidget( mLittleProgress, 0 , true );
00266   mLittleProgress->show();
00267 }
00268 
00269 
00270 void MainWindow::paintAboutScreen( const QString& msg )
00271 {
00272   QString location = locate( "data", "kontact/about/main.html" );
00273   QString content = KPIM::kFileToString( location );
00274   content = content.arg( locate( "data", "libkdepim/about/kde_infopage.css" ) );
00275   if ( kapp->reverseLayout() )
00276     content = content.arg( "@import \"%1\";" ).arg( locate( "data", "libkdepim/about/kde_infopage_rtl.css" ) );
00277   else
00278     content = content.arg( "" );
00279 
00280   mIntroPart->begin( KURL( location ) );
00281 
00282   QString appName( i18n( "KDE Kontact" ) );
00283   QString catchPhrase( i18n( "Get Organized!" ) );
00284   QString quickDescription( i18n( "The KDE Personal Information Management Suite" ) );
00285 
00286   mIntroPart->write( content.arg( QFont().pointSize() + 2 ).arg( appName )
00287       .arg( catchPhrase ).arg( quickDescription ).arg( msg ) );
00288   mIntroPart->end();
00289 }
00290 
00291 void MainWindow::initAboutScreen()
00292 {
00293   QHBox *introbox = new QHBox( mPartsStack );
00294   mPartsStack->addWidget( introbox );
00295   mPartsStack->raiseWidget( introbox );
00296   mIntroPart = new KHTMLPart( introbox );
00297   mIntroPart->widget()->setFocusPolicy( WheelFocus );
00298   // Let's better be paranoid and disable plugins (it defaults to enabled):
00299   mIntroPart->setPluginsEnabled( false );
00300   mIntroPart->setJScriptEnabled( false ); // just make this explicit
00301   mIntroPart->setJavaEnabled( false );    // just make this explicit
00302   mIntroPart->setMetaRefreshEnabled( false );
00303   mIntroPart->setURLCursor( KCursor::handCursor() );
00304   mIntroPart->view()->setLineWidth( 0 );
00305 
00306   connect( mIntroPart->browserExtension(),
00307            SIGNAL( openURLRequest( const KURL&, const KParts::URLArgs& ) ),
00308            SLOT( slotOpenUrl( const KURL& ) ) );
00309 
00310   connect( mIntroPart->browserExtension(),
00311            SIGNAL( createNewWindow( const KURL&, const KParts::URLArgs& ) ),
00312            SLOT( slotOpenUrl( const KURL& ) ) );
00313 }
00314 
00315 void MainWindow::setupActions()
00316 {
00317   KStdAction::quit( this, SLOT( slotQuit() ), actionCollection() );
00318   mNewActions = new KToolBarPopupAction( KGuiItem( i18n( "New" ), "" ),
00319                                          KStdAccel::shortcut(KStdAccel::New), this, SLOT( slotNewClicked() ),
00320                                          actionCollection(), "action_new" );
00321 
00322   new KAction( i18n( "Configure Kontact..." ), "configure", 0, this, SLOT( slotPreferences() ),
00323                actionCollection(), "settings_configure_kontact" );
00324 
00325   new KAction( i18n( "&Kontact Introduction" ), 0, this, SLOT( slotShowIntroduction() ),
00326                actionCollection(), "help_introduction" );
00327   new KAction( i18n( "&Tip of the Day" ), 0, this, SLOT( slotShowTip() ),
00328                actionCollection(), "help_tipofday" );
00329   new KAction( i18n( "&Request Feature..." ), 0, this, SLOT( slotRequestFeature() ),
00330                actionCollection(), "help_requestfeature" );
00331 }
00332 
00333 bool MainWindow::isPluginLoaded( const KPluginInfo *info )
00334 {
00335   return (pluginFromInfo( info ) != 0);
00336 }
00337 
00338 Plugin *MainWindow::pluginFromInfo( const KPluginInfo *info )
00339 {
00340   PluginList::ConstIterator end = mPlugins.end();
00341   for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
00342     if ( (*it)->identifier() == info->pluginName() )
00343       return *it;
00344 
00345   return 0;
00346 }
00347 
00348 void MainWindow::loadPlugins()
00349 {
00350   QPtrList<Plugin> plugins;
00351   QPtrList<KParts::Part> loadDelayed;
00352 
00353   uint i;
00354   KPluginInfo::List::ConstIterator it;
00355   for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) {
00356     if ( !(*it)->isPluginEnabled() )
00357       continue;
00358     if ( isPluginLoaded( *it ) ) {
00359       Plugin *plugin = pluginFromInfo( *it );
00360       if ( plugin )
00361         plugin->configUpdated();
00362       continue;
00363     }
00364 
00365     kdDebug(5600) << "Loading Plugin: " << (*it)->name() << endl;
00366     Kontact::Plugin *plugin =
00367       KParts::ComponentFactory::createInstanceFromService<Kontact::Plugin>(
00368           (*it)->service(), this );
00369 
00370     if ( !plugin )
00371       continue;
00372 
00373     plugin->setIdentifier( (*it)->pluginName() );
00374     plugin->setTitle( (*it)->name() );
00375     plugin->setIcon( (*it)->icon() );
00376 
00377     QVariant libNameProp = (*it)->property( "X-KDE-KontactPartLibraryName" );
00378     QVariant exeNameProp = (*it)->property( "X-KDE-KontactPartExecutableName" );
00379     QVariant loadOnStart = (*it)->property( "X-KDE-KontactPartLoadOnStart" );
00380     QVariant hasPartProp = (*it)->property( "X-KDE-KontactPluginHasPart" );
00381 
00382     if ( !loadOnStart.isNull() && loadOnStart.toBool() )
00383       mDelayedPreload.append( plugin );
00384 
00385     kdDebug(5600) << "LIBNAMEPART: " << libNameProp.toString() << endl;
00386 
00387     plugin->setPartLibraryName( libNameProp.toString().utf8() );
00388     plugin->setExecutableName( exeNameProp.toString() );
00389     if ( hasPartProp.isValid() )
00390       plugin->setShowInSideBar( hasPartProp.toBool() );
00391 
00392     for ( i = 0; i < plugins.count(); ++i ) {
00393       Plugin *p = plugins.at( i );
00394       if ( plugin->weight() < p->weight() )
00395         break;
00396     }
00397 
00398     plugins.insert( i, plugin );
00399   }
00400 
00401   for ( i = 0; i < plugins.count(); ++ i ) {
00402     Plugin *plugin = plugins.at( i );
00403 
00404     KAction *action;
00405     QPtrList<KAction> *actionList = plugin->newActions();
00406 
00407     for ( action = actionList->first(); action; action = actionList->next() ) {
00408       kdDebug(5600) << "Plugging " << action->name() << endl;
00409       action->plug( mNewActions->popupMenu() );
00410     }
00411 
00412     addPlugin( plugin );
00413   }
00414 
00415   mNewActions->setEnabled( mPlugins.size() != 0 );
00416 }
00417 
00418 void MainWindow::unloadPlugins()
00419 {
00420   KPluginInfo::List::ConstIterator end = mPluginInfos.end();
00421   KPluginInfo::List::ConstIterator it;
00422   for ( it = mPluginInfos.begin(); it != end; ++it ) {
00423     if ( !(*it)->isPluginEnabled() )
00424       removePlugin( *it );
00425   }
00426 }
00427 
00428 bool MainWindow::removePlugin( const KPluginInfo *info )
00429 {
00430   PluginList::Iterator end = mPlugins.end();
00431   for ( PluginList::Iterator it = mPlugins.begin(); it != end; ++it )
00432     if ( ( *it )->identifier() == info->pluginName() ) {
00433       Plugin *plugin = *it;
00434 
00435       KAction *action;
00436       QPtrList<KAction> *actionList = plugin->newActions();
00437 
00438       for ( action = actionList->first(); action; action = actionList->next() ) {
00439         kdDebug(5600) << "Unplugging " << action->name() << endl;
00440         action->unplug( mNewActions->popupMenu() );
00441       }
00442 
00443       removeChildClient( plugin );
00444 
00445       if ( mCurrentPlugin == plugin )
00446         mCurrentPlugin = 0;
00447 
00448       delete plugin; // removes the part automatically
00449       mPlugins.remove( it );
00450 
00451       if ( mCurrentPlugin == 0 ) {
00452         PluginList::Iterator it;
00453         for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00454           if ( (*it)->showInSideBar() ) {
00455             selectPlugin( *it );
00456             return true;
00457           }
00458         }
00459       }
00460 
00461       return true;
00462     }
00463 
00464   return false;
00465 }
00466 
00467 void MainWindow::addPlugin( Kontact::Plugin *plugin )
00468 {
00469   kdDebug(5600) << "Added plugin" << endl;
00470 
00471   mPlugins.append( plugin );
00472 
00473   // merge the plugins GUI into the main window
00474   insertChildClient( plugin );
00475 }
00476 
00477 void MainWindow::partLoaded( Kontact::Plugin*, KParts::ReadOnlyPart *part )
00478 {
00479   // See if we have this part already (e.g. due to two plugins sharing it)
00480   if ( mPartsStack->id( part->widget() ) != -1 )
00481     return;
00482 
00483   mPartsStack->addWidget( part->widget() );
00484 
00485   mPartManager->addPart( part, false );
00486   // Workaround for KParts misbehavior: addPart calls show!
00487   part->widget()->hide();
00488 }
00489 
00490 void MainWindow::slotActivePartChanged( KParts::Part *part )
00491 {
00492   if ( !part ) {
00493     createGUI( 0 );
00494     return;
00495   }
00496 
00497   kdDebug(5600) << "Part activated: " << part << " with stack id. "
00498       << mPartsStack->id( part->widget() )<< endl;
00499 
00500   //createGUI( part ); // moved to selectPlugin()
00501 
00502   statusBar()->clear();
00503 }
00504 
00505 void MainWindow::slotNewClicked()
00506 {
00507   KAction *action = mCurrentPlugin->newActions()->first();
00508   if ( action ) {
00509     action->activate();
00510   } else {
00511     PluginList::Iterator it;
00512     for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00513       action = (*it)->newActions()->first();
00514       if ( action ) {
00515         action->activate();
00516         return;
00517       }
00518     }
00519   }
00520 }
00521 
00522 void MainWindow::selectPlugin( Kontact::Plugin *plugin )
00523 {
00524   if ( !plugin )
00525     return;
00526 
00527   if ( plugin->isRunningStandalone() ) {
00528     statusBar()->message( i18n( "Application is running standalone. Foregrounding..." ), 1000 );
00529     mSidePane->indicateForegrunding( plugin );
00530     plugin->bringToForeground();
00531     return;
00532   }
00533 
00534   KApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
00535 
00536   KParts::Part *part = plugin->part();
00537 
00538   if ( !part ) {
00539     KApplication::restoreOverrideCursor();
00540     KMessageBox::error( this, i18n( "Cannot load part for %1." )
00541                               .arg( plugin->title() )
00542                         + "\n" + lastErrorMessage() );
00543     return;
00544   }
00545 
00546   // store old focus widget
00547   QWidget *focusWidget = kapp->focusWidget();
00548   if ( mCurrentPlugin && focusWidget ) {
00549     // save the focus widget only when it belongs to the activated part
00550     QWidget *parent = focusWidget->parentWidget();
00551     while ( parent ) {
00552       if ( parent == mCurrentPlugin->part()->widget() )
00553         mFocusWidgets.insert( mCurrentPlugin->identifier(), QGuardedPtr<QWidget>( focusWidget ) );
00554 
00555       parent = parent->parentWidget();
00556     }
00557   }
00558 
00559   if ( mSidePane )
00560     mSidePane->selectPlugin( plugin );
00561 
00562   plugin->select();
00563 
00564   mPartManager->setActivePart( part );
00565   QWidget *view = part->widget();
00566   Q_ASSERT( view );
00567 
00568   if ( view ) {
00569     mPartsStack->raiseWidget( view );
00570     view->show();
00571 
00572     if ( mFocusWidgets.contains( plugin->identifier() ) ) {
00573       focusWidget = mFocusWidgets[ plugin->identifier() ];
00574       if ( focusWidget )
00575         focusWidget->setFocus();
00576     } else
00577       view->setFocus();
00578 
00579     mCurrentPlugin = plugin;
00580     KAction *action = plugin->newActions()->first();
00581 
00582     createGUI( plugin->part() );
00583 
00584     setCaption( i18n( "Plugin dependent window title" ,"%1 - Kontact" ).arg( plugin->title() ) );
00585 
00586     if ( action ) {
00587       mNewActions->setIcon( action->icon() );
00588       mNewActions->setText( action->text() );
00589     } else { // we'll use the action of the first plugin which offers one
00590       PluginList::Iterator it;
00591       for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
00592         action = (*it)->newActions()->first();
00593         if ( action ) {
00594           mNewActions->setIcon( action->icon() );
00595           mNewActions->setText( action->text() );
00596           break;
00597         }
00598       }
00599     }
00600   }
00601 
00602   QStringList invisibleActions = plugin->invisibleToolbarActions();
00603 
00604   QStringList::ConstIterator it;
00605   for ( it = invisibleActions.begin(); it != invisibleActions.end(); ++it ) {
00606     KAction *action = part->actionCollection()->action( (*it).latin1() );
00607     if ( action ) {
00608       QPtrListIterator<KToolBar> it(  toolBarIterator() );
00609       for (  ; it.current() ; ++it ) {
00610         action->unplug( it.current() );
00611       }
00612     }
00613   }
00614 
00615   KApplication::restoreOverrideCursor();
00616 }
00617 
00618 void MainWindow::selectPlugin( const QString &pluginName )
00619 {
00620   PluginList::ConstIterator end = mPlugins.end();
00621   for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
00622     if ( ( *it )->identifier() == pluginName ) {
00623       selectPlugin( *it );
00624       return;
00625     }
00626 }
00627 
00628 void MainWindow::loadSettings()
00629 {
00630   if ( mSplitter )
00631     mSplitter->setSizes( Prefs::self()->mSidePaneSplitter );
00632 
00633   // Preload Plugins. This _must_ happen before the default part is loaded
00634   PluginList::ConstIterator it;
00635   for ( it = mDelayedPreload.begin(); it != mDelayedPreload.end(); ++it )
00636     selectPlugin( *it );
00637 
00638   selectPlugin( Prefs::self()->mActivePlugin );
00639 }
00640 
00641 void MainWindow::saveSettings()
00642 {
00643   if ( mSplitter )
00644     Prefs::self()->mSidePaneSplitter = mSplitter->sizes();
00645 
00646   if ( mCurrentPlugin )
00647     Prefs::self()->mActivePlugin = mCurrentPlugin->identifier();
00648 }
00649 
00650 void MainWindow::slotShowTip()
00651 {
00652   showTip( true );
00653 }
00654 
00655 void MainWindow::slotRequestFeature()
00656 {
00657   if ( kapp )
00658     kapp->invokeBrowser( "http://kontact.org/shopping" );
00659 }
00660 
00661 void MainWindow::slotShowIntroduction()
00662 {
00663   mPartsStack->raiseWidget( 0 ); // ###
00664 }
00665 
00666 void MainWindow::showTip( bool force )
00667 {
00668   QStringList tips;
00669   PluginList::ConstIterator end = mPlugins.end();
00670   for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) {
00671     QString file = (*it)->tipFile();
00672     if ( !file.isEmpty() )
00673       tips.append( file );
00674   }
00675 
00676   KTipDialog::showMultiTip( this, tips, force );
00677 }
00678 
00679 void MainWindow::slotQuit()
00680 {
00681   mReallyClose = true;
00682   close();
00683 }
00684 
00685 void MainWindow::slotPreferences()
00686 {
00687   static SettingsDialogWrapper *dlg = 0;
00688   if ( !dlg ) {
00689     dlg = new SettingsDialogWrapper( KSettings::Dialog::Configurable, this );
00690 
00691     // do not show settings of components running standalone
00692     QValueList<KPluginInfo*> filteredPlugins = mPluginInfos;
00693     PluginList::ConstIterator it;
00694     for ( it = mPlugins.begin(); it != mPlugins.end(); ++it )
00695       if ( (*it)->isRunningStandalone() ) {
00696         QValueList<KPluginInfo*>::ConstIterator infoIt;
00697         for ( infoIt = filteredPlugins.begin(); infoIt != filteredPlugins.end(); ++infoIt ) {
00698           if ( (*infoIt)->pluginName() == (*it)->identifier() ) {
00699             filteredPlugins.remove( *infoIt );
00700             break;
00701           }
00702         }
00703       }
00704 
00705     dlg->addPluginInfos( filteredPlugins );
00706     connect( dlg, SIGNAL( pluginSelectionChanged() ),
00707              SLOT( pluginsChanged() ) );
00708   }
00709 
00710   dlg->show();
00711   dlg->fixButtonLabel( this );
00712 }
00713 
00714 int MainWindow::startServiceFor( const QString& serviceType,
00715                                  const QString& constraint,
00716                                  const QString& preferences,
00717                                  QString *error, QCString* dcopService,
00718                                  int flags )
00719 {
00720   PluginList::ConstIterator end = mPlugins.end();
00721   for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) {
00722     if ( (*it)->createDCOPInterface( serviceType ) ) {
00723       kdDebug(5600) << "found interface for " << serviceType << endl;
00724       if ( dcopService )
00725         *dcopService = (*it)->dcopClient()->appId();
00726       kdDebug(5600) << "appId=" << (*it)->dcopClient()->appId() << endl;
00727       return 0; // success
00728     }
00729   }
00730 
00731   kdDebug(5600) <<
00732     "Didn't find dcop interface, falling back to external process" << endl;
00733 
00734   return KDCOPServiceStarter::startServiceFor( serviceType, constraint,
00735       preferences, error, dcopService, flags );
00736 }
00737 
00738 void MainWindow::pluginsChanged()
00739 {
00740   unplugActionList( "navigator_actionlist" );
00741   unloadPlugins();
00742   loadPlugins();
00743   mSidePane->updatePlugins();
00744   plugActionList( "navigator_actionlist", mSidePane->actions() );
00745 }
00746 
00747 void MainWindow::updateConfig()
00748 {
00749   kdDebug( 5600 ) << k_funcinfo << endl;
00750 
00751   saveSettings();
00752   loadSettings();
00753 }
00754 
00755 void MainWindow::showAboutDialog()
00756 {
00757   KApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
00758 
00759   if ( !mAboutDialog )
00760     mAboutDialog = new AboutDialog( this );
00761 
00762   mAboutDialog->show();
00763   mAboutDialog->raise();
00764   KApplication::restoreOverrideCursor();
00765 }
00766 
00767 void MainWindow::configureShortcuts()
00768 {
00769   KKeyDialog dialog( true, this );
00770   dialog.insert( actionCollection() );
00771 
00772   if ( mCurrentPlugin && mCurrentPlugin->part() )
00773     dialog.insert( mCurrentPlugin->part()->actionCollection() );
00774 
00775   dialog.configure();
00776 }
00777 
00778 void MainWindow::configureToolbars()
00779 {
00780   saveMainWindowSettings( KGlobal::config(), "MainWindow" );
00781 
00782   KEditToolbar edit( factory() );
00783   connect( &edit, SIGNAL( newToolbarConfig() ),
00784            this, SLOT( slotNewToolbarConfig() ) );
00785   edit.exec();
00786 }
00787 
00788 void MainWindow::slotNewToolbarConfig()
00789 {
00790   createGUI( mCurrentPlugin->part() );
00791   applyMainWindowSettings( KGlobal::config(), "MainWindow" );
00792 }
00793 
00794 void MainWindow::slotOpenUrl( const KURL &url )
00795 {
00796   if ( url.protocol() == "exec" ) {
00797     if ( url.path() == "/switch" ) {
00798       selectPlugin( mCurrentPlugin );
00799     }
00800     if ( url.path() == "/gwwizard" ) {
00801       KRun::runCommand( "groupwarewizard" );
00802       slotQuit();
00803     }
00804   } else
00805     new KRun( url, this );
00806 }
00807 
00808 void MainWindow::readProperties( KConfig *config )
00809 {
00810   Core::readProperties( config );
00811 
00812   QStringList activePlugins = config->readListEntry( "ActivePlugins" );
00813   QValueList<Plugin*>::ConstIterator it = mPlugins.begin();
00814   QValueList<Plugin*>::ConstIterator end = mPlugins.end();
00815   for ( ; it != end; ++it ) {
00816     Plugin *plugin = *it;
00817     if ( !plugin->isRunningStandalone() ) {
00818       QStringList::ConstIterator activePlugin = activePlugins.find( plugin->identifier() );
00819       if ( activePlugin != activePlugins.end() ) {
00820         plugin->readProperties( config );
00821       }
00822     }
00823   }
00824 }
00825 
00826 void MainWindow::saveProperties( KConfig *config )
00827 {
00828   Core::saveProperties( config );
00829 
00830   QStringList activePlugins;
00831 
00832   KPluginInfo::List::Iterator it = mPluginInfos.begin();
00833   KPluginInfo::List::Iterator end = mPluginInfos.end();
00834   for ( ; it != end; ++it ) {
00835     KPluginInfo *info = *it;
00836     if ( info->isPluginEnabled() ) {
00837       Plugin *plugin = pluginFromInfo( info );
00838       if ( plugin ) {
00839         activePlugins.append( plugin->identifier() );
00840         plugin->saveProperties( config );
00841       }
00842     }
00843   }
00844 
00845   config->writeEntry( "ActivePlugins", activePlugins );
00846 }
00847 
00848 bool MainWindow::queryClose()
00849 {
00850   if ( kapp->sessionSaving() || mReallyClose )
00851     return true;
00852 
00853   bool localClose = true;
00854   QValueList<Plugin*>::ConstIterator end = mPlugins.end();
00855   QValueList<Plugin*>::ConstIterator it = mPlugins.begin();
00856   for ( ; it != end; ++it ) {
00857     Plugin *plugin = *it;
00858     if ( !plugin->isRunningStandalone() )
00859       if ( !plugin->queryClose() )
00860         localClose = false;
00861   }
00862 
00863   return localClose;
00864 }
00865 
00866 void MainWindow::slotShowStatusMsg( const QString &msg )
00867 {
00868   if ( !statusBar() || !mStatusMsgLabel )
00869      return;
00870 
00871   mStatusMsgLabel->setText( msg );
00872 }
00873 
00874 QString MainWindow::introductionString()
00875 {
00876   KIconLoader *iconloader = KGlobal::iconLoader();
00877   int iconSize = iconloader->currentSize( KIcon::Desktop );
00878 
00879   QString handbook_icon_path = iconloader->iconPath( "contents2",  KIcon::Desktop );
00880   QString html_icon_path = iconloader->iconPath( "html",  KIcon::Desktop );
00881   QString wizard_icon_path = iconloader->iconPath( "wizard",  KIcon::Desktop );
00882 
00883   QString info = i18n( "<h2 style='text-align:center; margin-top: 0px;'>Welcome to Kontact %1</h2>"
00884       "<p>%1</p>"
00885       "<table align=\"center\">"
00886       "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
00887       "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
00888       "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
00889       "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
00890       "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
00891       "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
00892       "</table>"
00893       "<p style=\"margin-bottom: 0px\"> <a href=\"%1\">Skip this introduction</a></p>" )
00894       .arg( kapp->aboutData()->version() )
00895       .arg( i18n( "Kontact handles your e-mail, addressbook, calendar, to-do list and more." ) )
00896       .arg( "help:/kontact" )
00897       .arg( iconSize )
00898       .arg( iconSize )
00899       .arg( handbook_icon_path )
00900       .arg( "help:/kontact" )
00901       .arg( i18n( "Read Manual" ) )
00902       .arg( i18n( "Learn more about Kontact and its components" ) )
00903       .arg( "http://kontact.org" )
00904       .arg( iconSize )
00905       .arg( iconSize )
00906       .arg( html_icon_path )
00907       .arg( "http://kontact.org" )
00908       .arg( i18n( "Visit Kontact Website" ) )
00909       .arg( i18n( "Access online resources and tutorials" ) )
00910       .arg( "exec:/gwwizard" )
00911       .arg( iconSize )
00912       .arg( iconSize )
00913       .arg( wizard_icon_path )
00914       .arg( "exec:/gwwizard" )
00915       .arg( i18n( "Configure Kontact as Groupware Client" ) )
00916       .arg( i18n( "Prepare Kontact for use in corporate networks" ) )
00917       .arg( "exec:/switch" );
00918   return info;
00919 }
00920 
00921 
00922 #include "mainwindow.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys