You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/kontact/src/mainwindow.cpp

1209 lines
36 KiB

/*
This file is part of KDE Kontact.
Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
Copyright (c) 2002-2005 Daniel Molkentin <molkentin@kde.org>
Copyright (c) 2003-2005 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <tqaction.h>
#include <tqcombobox.h>
#include <tqdockarea.h>
#include <tqguardedptr.h>
#include <tqhbox.h>
#include <tqimage.h>
#include <tqobjectlist.h>
#include <tqprogressbar.h>
#include <tqpushbutton.h>
#include <tqsplitter.h>
#include <tqtimer.h>
#include <tqwhatsthis.h>
#include <dcopclient.h>
#include <kapplication.h>
#include <tdeconfig.h>
#include <kdebug.h>
#include <kedittoolbar.h>
#include <kguiitem.h>
#include <khelpmenu.h>
#include <kiconloader.h>
#include <kkeydialog.h>
#include <klibloader.h>
#include <klistbox.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <tdeparts/componentfactory.h>
#include <kplugininfo.h>
#include <kpopupmenu.h>
#include <ksettings/dialog.h>
#include <ksettings/dispatcher.h>
#include <kshortcut.h>
#include <kstandarddirs.h>
#include <kstatusbar.h>
#include <kstdaction.h>
#include <ktip.h>
#include <ktrader.h>
#include <ksettings/componentsdialog.h>
#include <kstringhandler.h>
#include <krsqueezedtextlabel.h>
#include <tdehtml_part.h>
#include <tdehtmlview.h>
#include <libtdepim/tdefileio.h>
#include <kcursor.h>
#include <krun.h>
#include <kaboutdata.h>
#include <kmenubar.h>
#include <kstdaccel.h>
#include <kcmultidialog.h>
#include <kipc.h>
#include "aboutdialog.h"
#include "iconsidepane.h"
#include "mainwindow.h"
#include "plugin.h"
#include "prefs.h"
#include "profiledialog.h"
#include "profilemanager.h"
#include "progressdialog.h"
#include "statusbarprogresswidget.h"
#include "broadcaststatus.h"
using namespace Kontact;
class SettingsDialogWrapper : public KSettings::Dialog
{
public:
SettingsDialogWrapper( ContentInListView content, TQWidget * parent = 0 )
: KSettings::Dialog( content, parent, 0 )
{
}
void fixButtonLabel( TQWidget *widget )
{
TQObject *object = widget->child( "KJanusWidget::buttonBelowList" );
TQPushButton *button = static_cast<TQPushButton*>( TQT_TQWIDGET(object) );
if ( button )
button->setText( i18n( "Select Components ..." ) );
}
};
MainWindow::MainWindow()
: Kontact::Core(), mTopWidget( 0 ), mSplitter( 0 ),
mCurrentPlugin( 0 ), mAboutDialog( 0 ), mReallyClose( false ), mSyncActionsEnabled( true )
{
// Set this to be the group leader for all subdialogs - this means
// modal subdialogs will only affect this dialog, not the other windows
setWFlags( getWFlags() | WGroupLeader );
initGUI();
initObject();
}
void MainWindow::initGUI()
{
initWidgets();
setupActions();
setHelpMenuEnabled( false );
KHelpMenu *helpMenu = new KHelpMenu( this, 0, true, actionCollection() );
connect( helpMenu, TQT_SIGNAL( showAboutApplication() ),
TQT_SLOT( showAboutDialog() ) );
KTrader::OfferList offers = KTrader::self()->query(
TQString::fromLatin1( "Kontact/Plugin" ),
TQString( "[X-TDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );
mPluginInfos = KPluginInfo::fromServices( offers, Prefs::self()->config(), "Plugins" );
KPluginInfo::List::Iterator it;
for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) {
(*it)->load();
KAction *action = new KAction( (*it)->name(), (*it)->icon(), KShortcut(),
TQT_TQOBJECT(this), TQT_SLOT(slotActionTriggered()),
actionCollection(), (*it)->pluginName().latin1() );
action->setName( (*it)->pluginName().latin1() );
action->setWhatsThis( i18n( "Switch to plugin %1" ).arg( (*it)->name() ) );
TQVariant hasPartProp = (*it)->property( "X-TDE-KontactPluginHasPart" );
if ( !hasPartProp.isValid() || hasPartProp.toBool() ) {
mActionPlugins.append( action );
}
}
KStdAction::keyBindings( TQT_TQOBJECT(this), TQT_SLOT( configureShortcuts() ), actionCollection() );
KStdAction::configureToolbars( TQT_TQOBJECT(this), TQT_SLOT( configureToolbars() ), actionCollection() );
setXMLFile( "kontactui.rc" );
setStandardToolBarMenuEnabled( true );
createGUI( 0 );
loadPlugins();
resize( 700, 520 ); // initial size to prevent a scrollbar in sidepane
setAutoSaveSettings();
connect( Kontact::ProfileManager::self(), TQT_SIGNAL( profileLoaded( const TQString& ) ),
this, TQT_SLOT( slotLoadProfile( const TQString& ) ) );
connect( Kontact::ProfileManager::self(), TQT_SIGNAL( saveToProfileRequested( const TQString& ) ),
this, TQT_SLOT( slotSaveToProfile( const TQString& ) ) );
}
void MainWindow::initObject()
{
// prepare the part manager
mPartManager = new KParts::PartManager( this );
connect( mPartManager, TQT_SIGNAL( activePartChanged( KParts::Part* ) ),
this, TQT_SLOT( slotActivePartChanged( KParts::Part* ) ) );
if ( mSidePane ) {
mSidePane->updatePlugins();
}
KSettings::Dispatcher::self()->registerInstance( instance(), TQT_TQOBJECT(this),
TQT_SLOT( updateConfig() ) );
loadSettings();
statusBar()->show();
showTip( false );
// done initializing
slotShowStatusMsg( TQString() );
connect( KPIM::BroadcastStatus::instance(), TQT_SIGNAL( statusMsg( const TQString& ) ),
this, TQT_SLOT( slotShowStatusMsg( const TQString& ) ) );
// launch commandline specified module if any
activatePluginModule();
if ( Prefs::lastVersionSeen() == kapp->aboutData()->version() ) {
selectPlugin( mCurrentPlugin );
}
paintAboutScreen( introductionString() );
Prefs::setLastVersionSeen( kapp->aboutData()->version() );
}
MainWindow::~MainWindow()
{
saveSettings();
TQPtrList<KParts::Part> parts = *mPartManager->parts();
for ( KParts::Part *p = parts.last(); p; p = parts.prev() ) {
delete p;
p = 0;
}
Prefs::self()->writeConfig();
}
void MainWindow::setActivePluginModule( const TQString &module )
{
mActiveModule = module;
activatePluginModule();
}
void MainWindow::activatePluginModule()
{
if ( !mActiveModule.isEmpty() ) {
PluginList::ConstIterator end = mPlugins.end();
for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
if ( ( *it )->identifier().contains( mActiveModule ) ) {
selectPlugin( *it );
return;
}
}
}
void MainWindow::initWidgets()
{
// includes sidebar and part stack
mTopWidget = new TQHBox( this );
mTopWidget->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
setCentralWidget( mTopWidget );
TQHBox *mBox = 0;
mSplitter = new TQSplitter( mTopWidget );
mBox = new TQHBox( mTopWidget );
mSidePane = new IconSidePane( this, mSplitter );
mSidePane->setSizePolicy( TQSizePolicy( TQSizePolicy::Maximum,
TQSizePolicy::Preferred ) );
// donÄt occupy screen estate on load
TQValueList<int> sizes;
sizes << 0;
mSplitter->setSizes(sizes);
connect( mSidePane, TQT_SIGNAL( pluginSelected( Kontact::Plugin * ) ),
TQT_SLOT( selectPlugin( Kontact::Plugin * ) ) );
TQVBox *vBox;
if ( mSplitter ) {
vBox = new TQVBox( mSplitter );
} else {
vBox = new TQVBox( mBox );
}
vBox->setSpacing( 0 );
mPartsStack = new TQWidgetStack( vBox );
initAboutScreen();
TQString loading = i18n( "<h2 style='text-align:center; margin-top: 0px; margin-bottom: 0px'>%1</h2>" )
.arg( i18n("Loading Kontact...") );
paintAboutScreen( loading );
/* Create a progress dialog and hide it. */
KPIM::ProgressDialog *progressDialog = new KPIM::ProgressDialog( statusBar(), this );
progressDialog->hide();
mLittleProgress = new KPIM::StatusbarProgressWidget( progressDialog, statusBar() );
mStatusMsgLabel = new KRSqueezedTextLabel( i18n( " Initializing..." ), statusBar() );
mStatusMsgLabel->setAlignment( AlignLeft | AlignVCenter );
statusBar()->addWidget( mStatusMsgLabel, 10 , false );
statusBar()->addWidget( mLittleProgress, 0 , true );
mLittleProgress->show();
}
void MainWindow::paintAboutScreen( const TQString& msg )
{
TQString location = locate( "data", "kontact/about/main.html" );
TQString content = KPIM::kFileToString( location );
content = content.arg( locate( "data", "libtdepim/about/kde_infopage.css" ) );
if ( kapp->reverseLayout() )
content = content.arg( "@import \"%1\";" ).arg( locate( "data", "libtdepim/about/kde_infopage_rtl.css" ) );
else
content = content.arg( "" );
mIntroPart->begin( KURL( location ) );
TQString appName( i18n( "TDE Kontact" ) );
TQString catchPhrase( i18n( "Get Organized!" ) );
TQString quickDescription( i18n( "The TDE Personal Information Management Suite" ) );
mIntroPart->write( content.arg( TQFont().pointSize() + 2 ).arg( appName )
.arg( catchPhrase ).arg( quickDescription ).arg( msg ) );
mIntroPart->end();
}
void MainWindow::initAboutScreen()
{
TQHBox *introbox = new TQHBox( mPartsStack );
mPartsStack->addWidget( introbox );
mPartsStack->raiseWidget( introbox );
mIntroPart = new KHTMLPart( introbox );
mIntroPart->widget()->setFocusPolicy( TQ_WheelFocus );
// Let's better be paranoid and disable plugins (it defaults to enabled):
mIntroPart->setPluginsEnabled( false );
mIntroPart->setJScriptEnabled( false ); // just make this explicit
mIntroPart->setJavaEnabled( false ); // just make this explicit
mIntroPart->setMetaRefreshEnabled( false );
mIntroPart->setURLCursor( KCursor::handCursor() );
mIntroPart->view()->setLineWidth( 0 );
connect( mIntroPart->browserExtension(),
TQT_SIGNAL( openURLRequest( const KURL&, const KParts::URLArgs& ) ),
TQT_SLOT( slotOpenUrl( const KURL& ) ) );
connect( mIntroPart->browserExtension(),
TQT_SIGNAL( createNewWindow( const KURL&, const KParts::URLArgs& ) ),
TQT_SLOT( slotOpenUrl( const KURL& ) ) );
}
void MainWindow::setupActions()
{
KStdAction::quit( TQT_TQOBJECT(this), TQT_SLOT( slotQuit() ), actionCollection() );
mNewActions = new KToolBarPopupAction( KGuiItem( i18n( "New" ), "" ),
KStdAccel::shortcut(KStdAccel::New), TQT_TQOBJECT(this), TQT_SLOT( slotNewClicked() ),
actionCollection(), "action_new" );
TDEConfig* const cfg = Prefs::self()->config();
cfg->setGroup( "Kontact Groupware Settings" );
mSyncActionsEnabled = cfg->readBoolEntry( "GroupwareMailFoldersEnabled", true );
if ( mSyncActionsEnabled ) {
mSyncActions = new KToolBarPopupAction( KGuiItem( i18n( "Synchronize" ), "kitchensync" ),
KStdAccel::shortcut(KStdAccel::Reload), TQT_TQOBJECT(this), TQT_SLOT( slotSyncClicked() ),
actionCollection(), "action_sync" );
}
new KAction( i18n( "Configure Kontact..." ), "configure", 0, TQT_TQOBJECT(this), TQT_SLOT( slotPreferences() ),
actionCollection(), "settings_configure_kontact" );
new KAction( i18n( "Configure &Profiles..." ), 0, TQT_TQOBJECT(this), TQT_SLOT( slotConfigureProfiles() ),
actionCollection(), "settings_configure_kontact_profiles" );
new KAction( i18n( "&Kontact Introduction" ), 0, TQT_TQOBJECT(this), TQT_SLOT( slotShowIntroduction() ),
actionCollection(), "help_introduction" );
new KAction( i18n( "&Tip of the Day" ), 0, TQT_TQOBJECT(this), TQT_SLOT( slotShowTip() ),
actionCollection(), "help_tipofday" );
KWidgetAction* spacerAction = new KWidgetAction( new TQWidget( this ), "SpacerAction", "", 0, 0, actionCollection(), "navigator_spacer_item" );
spacerAction->setAutoSized( true );
}
void MainWindow::slotConfigureProfiles()
{
TQGuardedPtr<Kontact::ProfileDialog> dlg = new Kontact::ProfileDialog( this );
dlg->setModal( true );
dlg->exec();
delete dlg;
}
namespace {
void copyConfigEntry( TDEConfig* source, TDEConfig* dest, const TQString& group, const TQString& key, const TQString& defaultValue=TQString() )
{
source->setGroup( group );
dest->setGroup( group );
dest->writeEntry( key, source->readEntry( key, defaultValue ) );
}
}
void MainWindow::slotSaveToProfile( const TQString& id )
{
const TQString path = Kontact::ProfileManager::self()->profileById( id ).saveLocation();
if ( path.isNull() )
return;
TDEConfig* const cfg = Prefs::self()->config();
Prefs::self()->writeConfig();
saveMainWindowSettings( cfg );
saveSettings();
TDEConfig profile( path+"/kontactrc", /*read-only=*/false, /*useglobals=*/false );
::copyConfigEntry( cfg, &profile, "MainWindow Toolbar navigatorToolBar", "Hidden", "true" );
::copyConfigEntry( cfg, &profile, "View", "SidePaneSplitter" );
::copyConfigEntry( cfg, &profile, "Icons", "Theme" );
for ( PluginList::Iterator it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
if ( !(*it)->isRunningStandalone() ) {
(*it)->part();
}
(*it)->saveToProfile( path );
}
}
void MainWindow::slotLoadProfile( const TQString& id )
{
const TQString path = Kontact::ProfileManager::self()->profileById( id ).saveLocation();
if ( path.isNull() )
return;
TDEConfig* const cfg = Prefs::self()->config();
Prefs::self()->writeConfig();
saveMainWindowSettings( cfg );
saveSettings();
const TDEConfig profile( path+"/kontactrc", /*read-only=*/false, /*useglobals=*/false );
const TQStringList groups = profile.groupList();
for ( TQStringList::ConstIterator it = groups.begin(), end = groups.end(); it != end; ++it )
{
cfg->setGroup( *it );
typedef TQMap<TQString, TQString> StringMap;
const StringMap entries = profile.entryMap( *it );
for ( StringMap::ConstIterator it2 = entries.begin(), end = entries.end(); it2 != end; ++it2 )
{
if ( it2.data() == "KONTACT_PROFILE_DELETE_KEY" )
cfg->deleteEntry( it2.key() );
else
cfg->writeEntry( it2.key(), it2.data() );
}
}
cfg->sync();
Prefs::self()->readConfig();
applyMainWindowSettings( cfg );
KIconTheme::reconfigure();
const WId wid = winId();
KIPC::sendMessage( KIPC::PaletteChanged, wid );
KIPC::sendMessage( KIPC::FontChanged, wid );
KIPC::sendMessage( KIPC::StyleChanged, wid );
KIPC::sendMessage( KIPC::SettingsChanged, wid );
for ( int i = 0; i < KIcon::LastGroup; ++i )
KIPC::sendMessage( KIPC::IconChanged, wid, i );
loadSettings();
for ( PluginList::Iterator it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
if ( !(*it)->isRunningStandalone() ) {
kdDebug() << "Ensure loaded: " << (*it)->identifier() << endl;
(*it)->part();
}
(*it)->loadProfile( path );
}
}
bool MainWindow::isPluginLoaded( const KPluginInfo *info )
{
return (pluginFromInfo( info ) != 0);
}
Plugin *MainWindow::pluginFromInfo( const KPluginInfo *info )
{
PluginList::ConstIterator end = mPlugins.end();
for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
if ( (*it)->identifier() == info->pluginName() )
return *it;
return 0;
}
Plugin *MainWindow::pluginFromAction( const KAction *action )
{
PluginList::ConstIterator end = mPlugins.end();
for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) {
if ( (*it)->identifier() == action->name() ) {
return *it;
}
}
return 0;
}
bool MainWindow::isPluginLoadedByAction( const KAction *action )
{
KPluginInfo::List::ConstIterator it;
for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) {
if ( !(*it)->isPluginEnabled() )
continue;
if ( isPluginLoaded( *it ) ) {
Plugin *plugin = pluginFromInfo( *it );
if ( plugin ) {
if ( plugin->identifier() == action->name() ) {
return true;
}
}
}
}
return false;
}
void MainWindow::sortActionsByWeight()
{
TQPtrList<KAction> sorted;
TQPtrListIterator<KAction> eit( mActionPlugins );
KAction *action;
while ( ( action = eit.current() ) != 0 ) {
++eit;
TQPtrListIterator<KAction> sortIt( sorted );
uint at = 0;
KAction *saction;
Plugin *p1 = pluginFromAction( action );
while ( ( saction = sortIt.current() ) != 0 ) {
Plugin *p2 = pluginFromAction( saction );
if ( p1 && p2 && p1->weight() >= p2->weight() ) {
++sortIt;
++at;
} else {
break;
}
}
sorted.insert( at, action );
}
mActionPlugins = sorted;
}
void MainWindow::loadPlugins()
{
TQPtrList<Plugin> plugins;
TQPtrList<KParts::Part> loadDelayed;
uint i;
KPluginInfo::List::ConstIterator it;
for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) {
if ( !(*it)->isPluginEnabled() )
continue;
if ( isPluginLoaded( *it ) ) {
Plugin *plugin = pluginFromInfo( *it );
if ( plugin )
plugin->configUpdated();
continue;
}
kdDebug(5600) << "Loading Plugin: " << (*it)->name() << endl;
Kontact::Plugin *plugin =
KParts::ComponentFactory::createInstanceFromService<Kontact::Plugin>(
(*it)->service(), TQT_TQOBJECT(this) );
if ( !plugin )
continue;
plugin->setIdentifier( (*it)->pluginName() );
plugin->setTitle( (*it)->name() );
plugin->setIcon( (*it)->icon() );
TQVariant libNameProp = (*it)->property( "X-TDE-KontactPartLibraryName" );
TQVariant exeNameProp = (*it)->property( "X-TDE-KontactPartExecutableName" );
TQVariant loadOnStart = (*it)->property( "X-TDE-KontactPartLoadOnStart" );
TQVariant hasPartProp = (*it)->property( "X-TDE-KontactPluginHasPart" );
if ( !loadOnStart.isNull() && loadOnStart.toBool() )
mDelayedPreload.append( plugin );
kdDebug(5600) << "LIBNAMEPART: " << libNameProp.toString() << endl;
plugin->setPartLibraryName( libNameProp.toString().utf8() );
plugin->setExecutableName( exeNameProp.toString() );
if ( hasPartProp.isValid() )
plugin->setShowInSideBar( hasPartProp.toBool() );
for ( i = 0; i < plugins.count(); ++i ) {
Plugin *p = plugins.at( i );
if ( plugin->weight() < p->weight() )
break;
}
plugins.insert( i, plugin );
}
for ( i = 0; i < plugins.count(); ++ i ) {
Plugin *plugin = plugins.at( i );
KAction *action;
TQPtrList<KAction> *actionList = plugin->newActions();
for ( action = actionList->first(); action; action = actionList->next() ) {
kdDebug(5600) << "Plugging " << action->name() << endl;
action->plug( mNewActions->popupMenu() );
if ( action->name() == plugin->identifier() ) {
mPluginAction.insert( plugin, action );
}
}
if ( mSyncActionsEnabled ) {
actionList = plugin->syncActions();
for ( action = actionList->first(); action; action = actionList->next() ) {
kdDebug(5600) << "Plugging " << action->name() << endl;
action->plug( mSyncActions->popupMenu() );
}
}
addPlugin( plugin );
}
updateShortcuts();
mNewActions->setEnabled( mPlugins.size() != 0 );
if ( mSyncActionsEnabled )
mSyncActions->setEnabled( mPlugins.size() != 0 );
}
void MainWindow::unloadPlugins()
{
KPluginInfo::List::ConstIterator end = mPluginInfos.constEnd();
KPluginInfo::List::ConstIterator it;
for ( it = mPluginInfos.constBegin(); it != end; ++it ) {
if ( !(*it)->isPluginEnabled() )
removePlugin( *it );
}
}
void MainWindow::updateShortcuts()
{
TQPtrList<KAction> loadedActions;
sortActionsByWeight();
TQPtrListIterator<KAction> it( mActionPlugins );
int i = 1;
KAction *action;
while ( ( action = it.current() ) != 0 ) {
++it;
if ( isPluginLoadedByAction( action ) ) {
loadedActions.append( action );
TQString shortcut = TQString( "CTRL+%1" ).arg( i );
action->setShortcut( KShortcut( shortcut ) );
i++;
} else {
action->setShortcut( KShortcut() );
}
}
unplugActionList( "navigator_actionlist" );
factory()->plugActionList( this, TQString( "navigator_actionlist" ), loadedActions );
}
bool MainWindow::removePlugin( const KPluginInfo *info )
{
PluginList::Iterator end = mPlugins.end();
for ( PluginList::Iterator it = mPlugins.begin(); it != end; ++it ) {
if ( ( *it )->identifier() == info->pluginName() ) {
Plugin *plugin = *it;
KAction *action;
TQPtrList<KAction> *actionList = plugin->newActions();
for ( action = actionList->first(); action; action = actionList->next() ) {
kdDebug(5600) << "Unplugging " << action->name() << endl;
action->unplug( mNewActions->popupMenu() );
}
if ( mSyncActionsEnabled ) {
actionList = plugin->syncActions();
for ( action = actionList->first(); action; action = actionList->next() ) {
kdDebug(5600) << "Unplugging " << action->name() << endl;
action->unplug( mSyncActions->popupMenu() );
}
}
removeChildClient( plugin );
if ( mCurrentPlugin == plugin )
mCurrentPlugin = 0;
plugin->deleteLater(); // removes the part automatically
mPlugins.remove( it );
if ( plugin->showInSideBar() ) {
mPluginAction.remove( plugin );
}
if ( mCurrentPlugin == 0 ) {
PluginList::Iterator it;
for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
if ( (*it)->showInSideBar() ) {
selectPlugin( *it );
return true;
}
}
}
return true;
}
}
return false;
}
void MainWindow::addPlugin( Kontact::Plugin *plugin )
{
kdDebug(5600) << "Added plugin" << endl;
mPlugins.append( plugin );
// merge the plugins GUI into the main window
insertChildClient( plugin );
}
void MainWindow::partLoaded( Kontact::Plugin*, KParts::ReadOnlyPart *part )
{
// See if we have this part already (e.g. due to two plugins sharing it)
if ( mPartsStack->id( part->widget() ) != -1 )
return;
mPartsStack->addWidget( part->widget() );
mPartManager->addPart( part, false );
// Workaround for KParts misbehavior: addPart calls show!
part->widget()->hide();
}
void MainWindow::slotActivePartChanged( KParts::Part *part )
{
if ( !part ) {
createGUI( 0 );
return;
}
kdDebug(5600) << "Part activated: " << part << " with stack id. "
<< mPartsStack->id( part->widget() )<< endl;
//createGUI( part ); // moved to selectPlugin()
statusBar()->clear();
}
void MainWindow::slotNewClicked()
{
KAction *action = mCurrentPlugin->newActions()->first();
if ( action ) {
action->activate();
} else {
PluginList::Iterator it;
for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
action = (*it)->newActions()->first();
if ( action ) {
action->activate();
return;
}
}
}
}
void MainWindow::slotSyncClicked()
{
KAction *action = mCurrentPlugin->syncActions()->first();
if ( action ) {
action->activate();
} else {
PluginList::Iterator it;
for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
action = (*it)->syncActions()->first();
if ( action ) {
action->activate();
return;
}
}
}
}
KToolBar* Kontact::MainWindow::findToolBar(const char* name)
{
// like KMainWindow::toolBar, but which doesn't create the toolbar if not found
return static_cast<KToolBar *>(TQT_TQWIDGET(child(name, "KToolBar")));
}
void MainWindow::slotActionTriggered()
{
const KAction *actionSender = static_cast<const KAction*>( sender() );
TQString identifier = actionSender->name();
if ( !identifier.isEmpty() ) {
selectPlugin( identifier );
}
}
void MainWindow::selectPlugin( Kontact::Plugin *plugin )
{
if ( !plugin )
return;
if ( plugin->isRunningStandalone() ) {
statusBar()->message( i18n( "Application is running standalone. Foregrounding..." ), 1000 );
mSidePane->indicateForegrunding( plugin );
plugin->bringToForeground();
return;
}
TDEApplication::setOverrideCursor( TQCursor( TQt::WaitCursor ) );
KParts::Part *part = plugin->part();
if ( !part ) {
TDEApplication::restoreOverrideCursor();
KMessageBox::error( this, i18n( "Cannot load part for %1." )
.arg( plugin->title() )
+ "\n" + lastErrorMessage() );
plugin->setDisabled( true );
mSidePane->updatePlugins();
return;
}
// store old focus widget
TQWidget *focusWidget = kapp->focusWidget();
if ( mCurrentPlugin && focusWidget ) {
// save the focus widget only when it belongs to the activated part
TQWidget *parent = focusWidget->parentWidget();
while ( parent ) {
if ( parent == mCurrentPlugin->part()->widget() )
mFocusWidgets.insert( mCurrentPlugin->identifier(), TQGuardedPtr<TQWidget>( focusWidget ) );
parent = parent->parentWidget();
}
}
if ( mSidePane ) {
mSidePane->selectPlugin( plugin->identifier() );
}
plugin->select();
mPartManager->setActivePart( part );
TQWidget *view = part->widget();
Q_ASSERT( view );
if ( view ) {
mPartsStack->raiseWidget( view );
view->show();
if ( mFocusWidgets.contains( plugin->identifier() ) ) {
focusWidget = mFocusWidgets[ plugin->identifier() ];
if ( focusWidget )
focusWidget->setFocus();
} else
view->setFocus();
mCurrentPlugin = plugin;
KAction *newAction = plugin->newActions()->first();
KAction *syncAction = plugin->syncActions()->first();
createGUI( plugin->part() );
KToolBar* navigatorToolBar = findToolBar( "navigatorToolBar" );
// Let the navigator toolbar be always the last one, if it's in the top dockwindow
if ( navigatorToolBar && !navigatorToolBar->isHidden() &&
navigatorToolBar->barPos() == KToolBar::Top ) {
topDock()->moveDockWindow( navigatorToolBar, -1 );
}
setCaption( i18n( "Plugin dependent window title" ,"%1 - Kontact" ).arg( plugin->title() ) );
if ( newAction ) {
mNewActions->setIcon( newAction->icon() );
mNewActions->setText( newAction->text() );
} else { // we'll use the action of the first plugin which offers one
PluginList::Iterator it;
for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
newAction = (*it)->newActions()->first();
if ( newAction ) {
mNewActions->setIcon( newAction->icon() );
mNewActions->setText( newAction->text() );
break;
}
}
}
if ( mSyncActionsEnabled ) {
if ( syncAction ) {
mSyncActions->setIcon( syncAction->icon() );
mSyncActions->setText( syncAction->text() );
} else { // we'll use the action of the first plugin which offers one
PluginList::Iterator it;
for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
syncAction = (*it)->syncActions()->first();
if ( syncAction ) {
mSyncActions->setIcon( syncAction->icon() );
mSyncActions->setText( syncAction->text() );
break;
}
}
}
}
}
TQStringList invisibleActions = plugin->invisibleToolbarActions();
TQStringList::ConstIterator it;
for ( it = invisibleActions.begin(); it != invisibleActions.end(); ++it ) {
KAction *action = part->actionCollection()->action( (*it).latin1() );
if ( action ) {
TQPtrListIterator<KToolBar> it( toolBarIterator() );
for ( ; it.current() ; ++it ) {
action->unplug( it.current() );
}
}
}
TDEApplication::restoreOverrideCursor();
}
void MainWindow::selectPlugin( const TQString &pluginName )
{
PluginList::ConstIterator end = mPlugins.end();
for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
if ( ( *it )->identifier() == pluginName ) {
selectPlugin( *it );
return;
}
}
void MainWindow::loadSettings()
{
if ( mSplitter )
mSplitter->setSizes( Prefs::self()->mSidePaneSplitter );
// Preload Plugins. This _must_ happen before the default part is loaded
PluginList::ConstIterator it;
for ( it = mDelayedPreload.begin(); it != mDelayedPreload.end(); ++it )
selectPlugin( *it );
selectPlugin( Prefs::self()->mActivePlugin );
}
void MainWindow::saveSettings()
{
if ( mSplitter )
Prefs::self()->mSidePaneSplitter = mSplitter->sizes();
if ( mCurrentPlugin )
Prefs::self()->mActivePlugin = mCurrentPlugin->identifier();
}
void MainWindow::slotShowTip()
{
showTip( true );
}
void MainWindow::slotShowIntroduction()
{
mPartsStack->raiseWidget( 0 ); // ###
}
void MainWindow::showTip( bool force )
{
TQStringList tips;
PluginList::ConstIterator end = mPlugins.end();
for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) {
TQString file = (*it)->tipFile();
if ( !file.isEmpty() )
tips.append( file );
}
KTipDialog::showMultiTip( this, tips, force );
}
void MainWindow::slotQuit()
{
mReallyClose = true;
close();
}
void MainWindow::slotPreferences()
{
static SettingsDialogWrapper *dlg = 0;
if ( !dlg ) {
// do not show settings of components running standalone
TQValueList<KPluginInfo*> filteredPlugins = mPluginInfos;
PluginList::ConstIterator it;
for ( it = mPlugins.begin(); it != mPlugins.end(); ++it )
if ( (*it)->isRunningStandalone() ) {
TQValueList<KPluginInfo*>::ConstIterator infoIt;
for ( infoIt = filteredPlugins.begin(); infoIt != filteredPlugins.end(); ++infoIt ) {
if ( (*infoIt)->pluginName() == (*it)->identifier() ) {
filteredPlugins.remove( *infoIt );
break;
}
}
}
dlg = new SettingsDialogWrapper( KSettings::Dialog::Configurable, this );
dlg->addPluginInfos( filteredPlugins );
connect( dlg, TQT_SIGNAL( pluginSelectionChanged() ),
TQT_SLOT( pluginsChanged() ) );
}
dlg->show();
dlg->fixButtonLabel( this );
}
int MainWindow::startServiceFor( const TQString& serviceType,
const TQString& constraint,
const TQString& preferences,
TQString *error, TQCString* dcopService,
int flags )
{
PluginList::ConstIterator end = mPlugins.end();
for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) {
if ( (*it)->createDCOPInterface( serviceType ) ) {
kdDebug(5600) << "found interface for " << serviceType << endl;
if ( dcopService )
*dcopService = (*it)->dcopClient()->appId();
kdDebug(5600) << "appId=" << (*it)->dcopClient()->appId() << endl;
return 0; // success
}
}
kdDebug(5600) <<
"Didn't find dcop interface, falling back to external process" << endl;
return KDCOPServiceStarter::startServiceFor( serviceType, constraint,
preferences, error, dcopService, flags );
}
void MainWindow::pluginsChanged()
{
unloadPlugins();
loadPlugins();
mSidePane->updatePlugins();
updateShortcuts();
}
void MainWindow::updateConfig()
{
kdDebug( 5600 ) << k_funcinfo << endl;
saveSettings();
loadSettings();
}
void MainWindow::showAboutDialog()
{
TDEApplication::setOverrideCursor( TQCursor( TQt::WaitCursor ) );
if ( !mAboutDialog )
mAboutDialog = new AboutDialog( this );
mAboutDialog->show();
mAboutDialog->raise();
TDEApplication::restoreOverrideCursor();
}
void MainWindow::configureShortcuts()
{
KKeyDialog dialog( true, this );
dialog.insert( actionCollection() );
if ( mCurrentPlugin && mCurrentPlugin->part() )
dialog.insert( mCurrentPlugin->part()->actionCollection() );
dialog.configure();
}
void MainWindow::configureToolbars()
{
saveMainWindowSettings( TDEGlobal::config(), "MainWindow" );
KEditToolbar edit( factory() );
connect( &edit, TQT_SIGNAL( newToolbarConfig() ),
this, TQT_SLOT( slotNewToolbarConfig() ) );
edit.exec();
}
void MainWindow::slotNewToolbarConfig()
{
if ( mCurrentPlugin && mCurrentPlugin->part() ) {
createGUI( mCurrentPlugin->part() );
}
if ( mCurrentPlugin ) {
applyMainWindowSettings( TDEGlobal::config(), "MainWindow" );
}
updateShortcuts(); // for the plugActionList call
}
void MainWindow::slotOpenUrl( const KURL &url )
{
if ( url.protocol() == "exec" ) {
if ( url.path() == "/switch" ) {
selectPlugin( mCurrentPlugin );
}
if ( url.path() == "/gwwizard" ) {
KRun::runCommand( "groupwarewizard" );
slotQuit();
}
if ( url.path().startsWith( "/help" ) ) {
TQString app( "kontact" );
if ( !url.query().isEmpty() ) {
app = url.query().mid( 1 );
}
kapp->invokeHelp( TQString(), app );
}
} else {
new KRun( url, this );
}
}
void MainWindow::readProperties( TDEConfig *config )
{
Core::readProperties( config );
TQStringList activePlugins = config->readListEntry( "ActivePlugins" );
TQValueList<Plugin*>::ConstIterator it = mPlugins.begin();
TQValueList<Plugin*>::ConstIterator end = mPlugins.end();
for ( ; it != end; ++it ) {
Plugin *plugin = *it;
if ( !plugin->isRunningStandalone() ) {
TQStringList::ConstIterator activePlugin = activePlugins.find( plugin->identifier() );
if ( activePlugin != activePlugins.end() ) {
plugin->readProperties( config );
}
}
}
}
void MainWindow::saveProperties( TDEConfig *config )
{
Core::saveProperties( config );
TQStringList activePlugins;
KPluginInfo::List::Iterator it = mPluginInfos.begin();
KPluginInfo::List::Iterator end = mPluginInfos.end();
for ( ; it != end; ++it ) {
KPluginInfo *info = *it;
if ( info->isPluginEnabled() ) {
Plugin *plugin = pluginFromInfo( info );
if ( plugin ) {
activePlugins.append( plugin->identifier() );
plugin->saveProperties( config );
}
}
}
config->writeEntry( "ActivePlugins", activePlugins );
}
bool MainWindow::queryClose()
{
//if ( kapp->sessionSaving() || mReallyClose )
if ( kapp->sessionSaving() )
return true;
bool localClose = true;
TQValueList<Plugin*>::ConstIterator end = mPlugins.end();
TQValueList<Plugin*>::ConstIterator it = mPlugins.begin();
for ( ; it != end; ++it ) {
Plugin *plugin = *it;
if ( !plugin->isRunningStandalone() )
if ( !plugin->queryClose() )
localClose = false;
}
return localClose;
}
void MainWindow::slotShowStatusMsg( const TQString &msg )
{
if ( !statusBar() || !mStatusMsgLabel )
return;
mStatusMsgLabel->setText( msg );
}
TQString MainWindow::introductionString()
{
KIconLoader *iconloader = TDEGlobal::iconLoader();
int iconSize = iconloader->currentSize( KIcon::Desktop );
TQString handbook_icon_path = iconloader->iconPath( "contents2", KIcon::Desktop );
TQString html_icon_path = iconloader->iconPath( "html", KIcon::Desktop );
TQString wizard_icon_path = iconloader->iconPath( "wizard", KIcon::Desktop );
TQString info = i18n( "<h2 style='text-align:center; margin-top: 0px;'>Welcome to Kontact %1</h2>"
"<p>%1</p>"
"<table align=\"center\">"
"<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
"<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
"<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
"<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
"<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
"<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
"</table>"
"<p style=\"margin-bottom: 0px\"> <a href=\"%1\">Skip this introduction</a></p>" )
.arg( kapp->aboutData()->version() )
.arg( i18n( "Kontact handles your e-mail, addressbook, calendar, to-do list and more." ) )
.arg( "exec:/help?kontact" )
.arg( iconSize )
.arg( iconSize )
.arg( handbook_icon_path )
.arg( "exec:/help?kontact" )
.arg( i18n( "Read Manual" ) )
.arg( i18n( "Learn more about Kontact and its components" ) )
.arg( "http://kontact.org" )
.arg( iconSize )
.arg( iconSize )
.arg( html_icon_path )
.arg( "http://kontact.org" )
.arg( i18n( "Visit Kontact Website" ) )
.arg( i18n( "Access online resources and tutorials" ) )
.arg( "exec:/gwwizard" )
.arg( iconSize )
.arg( iconSize )
.arg( wizard_icon_path )
.arg( "exec:/gwwizard" )
.arg( i18n( "Configure Kontact as Groupware Client" ) )
.arg( i18n( "Prepare Kontact for use in corporate networks" ) )
.arg( "exec:/switch" );
return info;
}
#include "mainwindow.moc"