kontact

summaryview_part.cpp

00001 /*
00002    This file is part of KDE Kontact.
00003 
00004    Copyright (C) 2003 Sven Lüppken <sven@kde.org>
00005    Copyright (C) 2003 Tobias König <tokoe@kde.org>
00006    Copyright (C) 2003 Daniel Molkentin <molkentin@kde.org>
00007 
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Library General Public
00010    License as published by the Free Software Foundation; either
00011    version 2 of the License, or (at your option) any later version.
00012 
00013    This library 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 GNU
00016    Library General Public License for more details.
00017 
00018    You should have received a copy of the GNU Library General Public License
00019    along with this library; see the file COPYING.LIB.  If not, write to
00020    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021    Boston, MA 02110-1301, USA.
00022 */
00023 
00024 #include <tqframe.h>
00025 #include <tqlabel.h>
00026 #include <tqlayout.h>
00027 #include <tqtimer.h>
00028 
00029 #include <dcopclient.h>
00030 #include <tdeaction.h>
00031 #include <tdeapplication.h>
00032 #include <tdeconfig.h>
00033 #include <kdcopservicestarter.h>
00034 #include <kdebug.h>
00035 #include <kdialog.h>
00036 #include <tdelocale.h>
00037 #include <tdemessagebox.h>
00038 #include <kservice.h>
00039 #include <ktrader.h>
00040 #include <kstandarddirs.h>
00041 #include <tqscrollview.h>
00042 #include <tdeglobal.h>
00043 #include <tdelocale.h>
00044 #include <kcmultidialog.h>
00045 
00046 #include <tdeparts/componentfactory.h>
00047 #include <tdeparts/event.h>
00048 
00049 #include <libkpimidentities/identity.h>
00050 #include <libkpimidentities/identitymanager.h>
00051 
00052 #include <infoextension.h>
00053 #include <sidebarextension.h>
00054 
00055 #include "plugin.h"
00056 #include "summary.h"
00057 
00058 #include "summaryview_part.h"
00059 
00060 #include "broadcaststatus.h"
00061 using KPIM::BroadcastStatus;
00062 
00063 namespace Kontact
00064 {
00065   class MainWindow;
00066 }
00067 
00068 SummaryViewPart::SummaryViewPart( Kontact::Core *core, const char*,
00069                                   const TDEAboutData *aboutData,
00070                                   TQObject *parent, const char *name )
00071   : KParts::ReadOnlyPart( parent, name ),
00072     mCore( core ), mFrame( 0 ), mConfigAction( 0 )
00073 {
00074   setInstance( new TDEInstance( aboutData ) );
00075 
00076   loadLayout();
00077 
00078   initGUI( core );
00079 
00080   connect( kapp, TQT_SIGNAL( tdedisplayPaletteChanged() ), TQT_SLOT( slotAdjustPalette() ) );
00081   slotAdjustPalette();
00082 
00083   setDate( TQDate::currentDate() );
00084   connect( mCore, TQT_SIGNAL( dayChanged( const TQDate& ) ),
00085            TQT_SLOT( setDate( const TQDate& ) ) );
00086 
00087   KParts::InfoExtension *info = new KParts::InfoExtension( this, "Summary" );
00088   connect( this, TQT_SIGNAL( textChanged( const TQString& ) ),
00089            info, TQT_SIGNAL( textChanged( const TQString& ) ) );
00090 
00091   mConfigAction = new TDEAction( i18n( "&Configure Summary View..." ),
00092                                "configure", 0, this,
00093                                TQT_SLOT( slotConfigure() ), actionCollection(),
00094                                "summaryview_configure" );
00095 
00096   setXMLFile( "kontactsummary_part.rc" );
00097 
00098   TQTimer::singleShot( 0, this, TQT_SLOT( slotTextChanged() ) );
00099 }
00100 
00101 SummaryViewPart::~SummaryViewPart()
00102 {
00103   saveLayout();
00104 }
00105 
00106 bool SummaryViewPart::openFile()
00107 {
00108   kdDebug(5006) << "SummaryViewPart:openFile()" << endl;
00109   return true;
00110 }
00111 
00112 void SummaryViewPart::partActivateEvent( KParts::PartActivateEvent *event )
00113 {
00114   // inform the plugins that the part has been activated so that they can
00115   // update the displayed information
00116   if ( event->activated() && ( event->part() == this ) ) {
00117     updateSummaries();
00118   }
00119 
00120   KParts::ReadOnlyPart::partActivateEvent( event );
00121 }
00122 
00123 void SummaryViewPart::updateSummaries()
00124 {
00125   TQMap<TQString, Kontact::Summary*>::Iterator it;
00126   for ( it = mSummaries.begin(); it != mSummaries.end(); ++it )
00127     it.data()->updateSummary( false );
00128 }
00129 
00130 void SummaryViewPart::updateWidgets()
00131 {
00132   mMainWidget->setUpdatesEnabled( false );
00133 
00134   delete mFrame;
00135 
00136   KPIM::IdentityManager idm( true, this );
00137   const KPIM::Identity &id = idm.defaultIdentity();
00138 
00139   TQString currentUser = i18n( "Summary for %1" ).arg( id.fullName() );
00140   mUsernameLabel->setText( TQString::fromLatin1( "<b>%1</b>" ).arg( currentUser ) );
00141 
00142   mSummaries.clear();
00143 
00144   mFrame = new DropWidget( mMainWidget );
00145   connect( mFrame, TQT_SIGNAL( summaryWidgetDropped( TQWidget*, TQWidget*, int ) ),
00146            this, TQT_SLOT( summaryWidgetMoved( TQWidget*, TQWidget*, int ) ) );
00147 
00148   mMainLayout->insertWidget( 2, mFrame );
00149 
00150   TQStringList activeSummaries;
00151 
00152   TDEConfig config( "kontact_summaryrc" );
00153   if ( !config.hasKey( "ActiveSummaries" ) ) {
00154     activeSummaries << "kontact_kmailplugin";
00155     activeSummaries << "kontact_specialdatesplugin";
00156     activeSummaries << "kontact_korganizerplugin";
00157     activeSummaries << "kontact_todoplugin";
00158     activeSummaries << "kontact_newstickerplugin";
00159   } else {
00160     activeSummaries = config.readListEntry( "ActiveSummaries" );
00161   }
00162 
00163   // Collect all summary widgets with a summaryHeight > 0
00164   TQStringList loadedSummaries;
00165 
00166   TQValueList<Kontact::Plugin*> plugins = mCore->pluginList();
00167   TQValueList<Kontact::Plugin*>::ConstIterator end = plugins.end();
00168   TQValueList<Kontact::Plugin*>::ConstIterator it = plugins.begin();
00169   for ( ; it != end; ++it ) {
00170     Kontact::Plugin *plugin = *it;
00171     if ( activeSummaries.find( plugin->identifier() ) == activeSummaries.end() )
00172       continue;
00173 
00174     Kontact::Summary *summary = plugin->createSummaryWidget( mFrame );
00175     if ( summary ) {
00176       if ( summary->summaryHeight() > 0 ) {
00177         mSummaries.insert( plugin->identifier(), summary );
00178 
00179         connect( summary, TQT_SIGNAL( message( const TQString& ) ),
00180                  BroadcastStatus::instance(), TQT_SLOT( setStatusMsg( const TQString& ) ) );
00181         connect( summary, TQT_SIGNAL( summaryWidgetDropped( TQWidget*, TQWidget*, int ) ),
00182                  this, TQT_SLOT( summaryWidgetMoved( TQWidget*, TQWidget*, int ) ) );
00183 
00184         if ( !mLeftColumnSummaries.contains( plugin->identifier() ) &&
00185              !mRightColumnSummaries.contains( plugin->identifier() ) ) {
00186           mLeftColumnSummaries.append( plugin->identifier() );
00187         }
00188 
00189         loadedSummaries.append( plugin->identifier() );
00190       } else {
00191         summary->hide();
00192       }
00193     }
00194   }
00195 
00196   // Remove all unavailable summary widgets
00197   {
00198     TQStringList::Iterator strIt;
00199     for ( strIt = mLeftColumnSummaries.begin(); strIt != mLeftColumnSummaries.end(); ++strIt ) {
00200       if ( loadedSummaries.find( *strIt ) == loadedSummaries.end() ) {
00201         strIt = mLeftColumnSummaries.remove( strIt );
00202         --strIt;
00203       }
00204     }
00205     for ( strIt = mRightColumnSummaries.begin(); strIt != mRightColumnSummaries.end(); ++strIt ) {
00206       if ( loadedSummaries.find( *strIt ) == loadedSummaries.end() ) {
00207         strIt = mRightColumnSummaries.remove( strIt );
00208         --strIt;
00209       }
00210     }
00211   }
00212 
00213   // Add vertical line between the two rows of summary widgets.
00214   TQFrame *vline = new TQFrame( mFrame );
00215   vline->setFrameStyle( TQFrame::VLine | TQFrame::Plain );
00216 
00217   TQHBoxLayout *layout = new TQHBoxLayout( mFrame );
00218 
00219   mLeftColumn = new TQVBoxLayout( layout, KDialog::spacingHint() );
00220   layout->addWidget( vline );
00221   mRightColumn = new TQVBoxLayout( layout, KDialog::spacingHint()  );
00222 
00223 
00224   TQStringList::Iterator strIt;
00225   for ( strIt = mLeftColumnSummaries.begin(); strIt != mLeftColumnSummaries.end(); ++strIt ) {
00226     if ( mSummaries.find( *strIt ) != mSummaries.end() )
00227       mLeftColumn->addWidget( mSummaries[ *strIt ] );
00228   }
00229 
00230   for ( strIt = mRightColumnSummaries.begin(); strIt != mRightColumnSummaries.end(); ++strIt ) {
00231     if ( mSummaries.find( *strIt ) != mSummaries.end() )
00232       mRightColumn->addWidget( mSummaries[ *strIt ] );
00233   }
00234 
00235   mFrame->show();
00236 
00237   mMainWidget->setUpdatesEnabled( true );
00238   mMainWidget->update();
00239 
00240   mLeftColumn->addStretch();
00241   mRightColumn->addStretch();
00242 }
00243 
00244 void SummaryViewPart::summaryWidgetMoved( TQWidget *target, TQWidget *widget, int alignment )
00245 {
00246   if ( target == widget )
00247     return;
00248 
00249   if ( target == mFrame ) {
00250     if ( mLeftColumn->findWidget( widget ) == -1 && mRightColumn->findWidget( widget ) == -1 )
00251       return;
00252   } else {
00253     if ( mLeftColumn->findWidget( target ) == -1 && mRightColumn->findWidget( target ) == -1 ||
00254          mLeftColumn->findWidget( widget ) == -1 && mRightColumn->findWidget( widget ) == -1 )
00255       return;
00256   }
00257 
00258   if ( mLeftColumn->findWidget( widget ) != -1 ) {
00259     mLeftColumn->remove( widget );
00260     mLeftColumnSummaries.remove( widgetName( widget ) );
00261   } else if ( mRightColumn->findWidget( widget ) != -1 ) {
00262     mRightColumn->remove( widget );
00263     mRightColumnSummaries.remove( widgetName( widget ) );
00264   }
00265 
00266   if ( target == mFrame ) {
00267     int pos = 0;
00268 
00269     if ( alignment & TQt::AlignTop )
00270       pos = 0;
00271 
00272     if ( alignment & TQt::AlignLeft ) {
00273       if ( alignment & TQt::AlignBottom )
00274         pos = mLeftColumnSummaries.count();
00275 
00276       mLeftColumn->insertWidget( pos, widget );
00277       mLeftColumnSummaries.insert( mLeftColumnSummaries.at( pos ), widgetName( widget ) );
00278     } else {
00279       if ( alignment & TQt::AlignBottom )
00280         pos = mRightColumnSummaries.count();
00281 
00282       mRightColumn->insertWidget( pos, widget );
00283       mRightColumnSummaries.insert( mRightColumnSummaries.at( pos ), widgetName( widget ) );
00284     }
00285 
00286     return;
00287   }
00288 
00289   int targetPos = mLeftColumn->findWidget( target );
00290   if ( targetPos != -1 ) {
00291     if ( alignment == TQt::AlignBottom )
00292       targetPos++;
00293 
00294     mLeftColumn->insertWidget( targetPos, widget );
00295     mLeftColumnSummaries.insert( mLeftColumnSummaries.at( targetPos ), widgetName( widget ) );
00296   } else {
00297     targetPos = mRightColumn->findWidget( target );
00298 
00299     if ( alignment == TQt::AlignBottom )
00300       targetPos++;
00301 
00302     mRightColumn->insertWidget( targetPos, widget );
00303     mRightColumnSummaries.insert( mRightColumnSummaries.at( targetPos ), widgetName( widget ) );
00304   }
00305 }
00306 
00307 void SummaryViewPart::slotTextChanged()
00308 {
00309   emit textChanged( i18n( "What's next?" ) );
00310 }
00311 
00312 void SummaryViewPart::slotAdjustPalette()
00313 {
00314   mMainWidget->setPaletteBackgroundColor( kapp->palette().active().base() );
00315 }
00316 
00317 void SummaryViewPart::setDate( const TQDate& newDate )
00318 {
00319   TQString date( "<b>%1</b>" );
00320   date = date.arg( TDEGlobal::locale()->formatDate( newDate ) );
00321   mDateLabel->setText( date );
00322 }
00323 
00324 void SummaryViewPart::slotConfigure()
00325 {
00326   KCMultiDialog dlg( mMainWidget, "ConfigDialog", true );
00327 
00328   TQStringList modules = configModules();
00329   modules.prepend( "kcmkontactsummary.desktop" );
00330   connect( &dlg, TQT_SIGNAL( configCommitted() ),
00331            this, TQT_SLOT( updateWidgets() ) );
00332 
00333   TQStringList::ConstIterator strIt;
00334   for ( strIt = modules.begin(); strIt != modules.end(); ++strIt )
00335     dlg.addModule( *strIt );
00336 
00337   dlg.exec();
00338 }
00339 
00340 TQStringList SummaryViewPart::configModules() const
00341 {
00342   TQStringList modules;
00343 
00344   TQMap<TQString, Kontact::Summary*>::ConstIterator it;
00345   for ( it = mSummaries.begin(); it != mSummaries.end(); ++it ) {
00346     TQStringList cm = it.data()->configModules();
00347     TQStringList::ConstIterator strIt;
00348     for ( strIt = cm.begin(); strIt != cm.end(); ++strIt )
00349       if ( !(*strIt).isEmpty() && !modules.contains( *strIt ) )
00350         modules.append( *strIt );
00351   }
00352 
00353   return modules;
00354 }
00355 
00356 void SummaryViewPart::initGUI( Kontact::Core *core )
00357 {
00358   TQScrollView *sv = new TQScrollView( core );
00359 
00360   sv->setResizePolicy( TQScrollView::AutoOneFit );
00361   sv->setFrameStyle( TQFrame::NoFrame | TQFrame::Plain );
00362   sv->setHScrollBarMode( TQScrollView::AlwaysOff );
00363 
00364   mMainWidget = new TQFrame( sv->viewport() );
00365   sv->addChild( mMainWidget );
00366   mMainWidget->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
00367   sv->setFocusPolicy( TQ_StrongFocus );
00368   setWidget( sv );
00369 
00370   mMainLayout = new TQVBoxLayout( mMainWidget,KDialog::marginHint(),
00371                                  KDialog::spacingHint() );
00372 
00373   TQHBoxLayout *hbl = new TQHBoxLayout( mMainLayout );
00374   mUsernameLabel = new TQLabel( mMainWidget );
00375   hbl->addWidget( mUsernameLabel );
00376   mDateLabel = new TQLabel( mMainWidget );
00377   mDateLabel->setAlignment( AlignRight );
00378   hbl->addWidget( mDateLabel );
00379 
00380   TQFrame *hline = new TQFrame( mMainWidget );
00381   hline->setFrameStyle( TQFrame::HLine | TQFrame::Plain );
00382   mMainLayout->insertWidget( 1, hline );
00383 
00384   mFrame = new DropWidget( mMainWidget );
00385   mMainLayout->insertWidget( 2, mFrame );
00386 
00387   connect( mFrame, TQT_SIGNAL( summaryWidgetDropped( TQWidget*, TQWidget*, int ) ),
00388            this, TQT_SLOT( summaryWidgetMoved( TQWidget*, TQWidget*, int ) ) );
00389 
00390   updateWidgets();
00391 }
00392 
00393 void SummaryViewPart::loadLayout()
00394 {
00395   TDEConfig config( "kontact_summaryrc" );
00396 
00397   if ( !config.hasKey( "LeftColumnSummaries" ) ) {
00398     mLeftColumnSummaries << "kontact_korganizerplugin";
00399     mLeftColumnSummaries << "kontact_todoplugin";
00400     mLeftColumnSummaries << "kontact_kaddressbookplugin";
00401     mLeftColumnSummaries << "kontact_specialdatesplugin";
00402   } else {
00403     mLeftColumnSummaries = config.readListEntry( "LeftColumnSummaries" );
00404   }
00405 
00406   if ( !config.hasKey( "RightColumnSummaries" ) ) {
00407     mRightColumnSummaries << "kontact_newstickerplugin";
00408   } else {
00409     mRightColumnSummaries = config.readListEntry( "RightColumnSummaries" );
00410   }
00411 }
00412 
00413 void SummaryViewPart::saveLayout()
00414 {
00415   TDEConfig config( "kontact_summaryrc" );
00416 
00417   config.writeEntry( "LeftColumnSummaries", mLeftColumnSummaries );
00418   config.writeEntry( "RightColumnSummaries", mRightColumnSummaries );
00419 
00420   config.sync();
00421 }
00422 
00423 TQString SummaryViewPart::widgetName( TQWidget *widget ) const
00424 {
00425   TQMap<TQString, Kontact::Summary*>::ConstIterator it;
00426   for ( it = mSummaries.begin(); it != mSummaries.end(); ++it ) {
00427     if ( it.data() == widget )
00428       return it.key();
00429   }
00430 
00431   return TQString();
00432 }
00433 
00434 #include "summaryview_part.moc"