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