korganizer

koviewmanager.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020 
00021     As a special exception, permission is given to link this program
00022     with any edition of Qt, and distribute the resulting executable,
00023     without including the source code for Qt in the source distribution.
00024 */
00025 
00026 #include <qwidgetstack.h>
00027 #include <qtabwidget.h>
00028 
00029 #include <libkcal/calendarresources.h>
00030 #include <kactioncollection.h>
00031 #include <kconfig.h>
00032 #include <kglobal.h>
00033 
00034 #include "actionmanager.h"
00035 #include "calendarview.h"
00036 #include "datenavigator.h"
00037 #include "kotodoview.h"
00038 #include "koagendaview.h"
00039 #include "komonthview.h"
00040 #include "kolistview.h"
00041 #include "kowhatsnextview.h"
00042 #include "kojournalview.h"
00043 #include "kotimelineview.h"
00044 #include "koprefs.h"
00045 #include "koglobals.h"
00046 #include "navigatorbar.h"
00047 #include "multiagendaview.h"
00048 #include <korganizer/mainwindow.h>
00049 
00050 #include "koviewmanager.h"
00051 #include "koviewmanager.moc"
00052 
00053 KOViewManager::KOViewManager( CalendarView *mainView ) :
00054   QObject(), mMainView( mainView )
00055 {
00056   mCurrentView = 0;
00057 
00058   mLastEventView = 0;
00059 
00060   mWhatsNextView = 0;
00061   mTodoView = 0;
00062   mAgendaView = 0;
00063   mAgendaSideBySideView = 0;
00064   mMonthView = 0;
00065   mListView = 0;
00066   mJournalView = 0;
00067   mTimelineView = 0;
00068   mAgendaViewTabs = 0;
00069   mAgendaMode = AGENDA_NONE;
00070 }
00071 
00072 KOViewManager::~KOViewManager()
00073 {
00074 }
00075 
00076 
00077 KOrg::BaseView *KOViewManager::currentView()
00078 {
00079   return mCurrentView;
00080 }
00081 
00082 void KOViewManager::readSettings(KConfig *config)
00083 {
00084   config->setGroup("General");
00085   QString view = config->readEntry("Current View");
00086 
00087   if (view == "WhatsNext") showWhatsNextView();
00088   else if (view == "Month") showMonthView();
00089   else if (view == "List") showListView();
00090   else if (view == "Journal") showJournalView();
00091   else if (view == "Todo") showTodoView();
00092   else if (view == "Timeline") showTimelineView();
00093   else {
00094     mAgendaMode = AgendaMode( config->readNumEntry( "Agenda Mode", AGENDA_OTHER ) );
00095 
00096     switch ( mAgendaMode ) {
00097       case AGENDA_WORK_WEEK:
00098         showWorkWeekView();
00099         break;
00100       case AGENDA_WEEK:
00101         showWeekView();
00102         break;
00103       case AGENDA_NEXTX:
00104         showNextXView();
00105         break;
00106       case AGENDA_DAY:
00107         showDayView();
00108         break;
00109       case AGENDA_NONE:
00110         // Someone has been playing with the config file.
00111       default:
00112         mAgendaMode = AGENDA_OTHER;
00113         showAgendaView();
00114     }
00115   }
00116 }
00117 
00118 void KOViewManager::writeSettings(KConfig *config)
00119 {
00120   config->setGroup("General");
00121 
00122   QString view;
00123   if (mCurrentView == mWhatsNextView) view = "WhatsNext";
00124   else if (mCurrentView == mMonthView) view = "Month";
00125   else if (mCurrentView == mListView) view = "List";
00126   else if (mCurrentView == mJournalView) view = "Journal";
00127   else if (mCurrentView == mTodoView) view = "Todo";
00128   else if (mCurrentView == mTimelineView) view = "Timeline";
00129   else {
00130     view = "Agenda";
00131     config->writeEntry( "Agenda Mode", mAgendaMode );
00132   }
00133 
00134   config->writeEntry("Current View",view);
00135 
00136   if (mAgendaView) {
00137     mAgendaView->writeSettings(config);
00138   }
00139   if (mListView) {
00140     mListView->writeSettings(config);
00141   }
00142   if (mTodoView) {
00143     mTodoView->saveLayout(config,"Todo View");
00144   }
00145 }
00146 
00147 void KOViewManager::showView(KOrg::BaseView *view)
00148 {
00149   if( view == mCurrentView ) return;
00150 
00151   mCurrentView = view;
00152 
00153   if ( mCurrentView && mCurrentView->isEventView() ) {
00154     mLastEventView = mCurrentView;
00155   }
00156 
00157   if ( mAgendaView ) mAgendaView->deleteSelectedDateTime();
00158 
00159   raiseCurrentView();
00160 
00161   mMainView->processIncidenceSelection( 0, QDate() );
00162 
00163   mMainView->updateView();
00164 
00165   mMainView->adaptNavigationUnits();
00166 }
00167 
00168 void KOViewManager::goMenu( bool enable )
00169 {
00170   KOrg::MainWindow *w = ActionManager::findInstance( KURL() );
00171   if ( w ) {
00172     KActionCollection *ac = w->getActionCollection();
00173     if ( ac ) {
00174       KAction *action;
00175       action = ac->action( "go_today" );
00176       if ( action ) {
00177         action->setEnabled( enable );
00178       }
00179       action = ac->action( "go_previous" );
00180       if ( action ) {
00181         action->setEnabled( enable );
00182       }
00183       action = ac->action( "go_next" );
00184       if ( action ) {
00185         action->setEnabled( enable );
00186       }
00187     }
00188   }
00189 }
00190 
00191 void KOViewManager::raiseCurrentView()
00192 {
00193   if ((mMonthView && KOPrefs::instance()->mFullViewMonth && mCurrentView == mMonthView) ||
00194       (mTodoView && KOPrefs::instance()->mFullViewTodo && mCurrentView == mTodoView)) {
00195     mMainView->showLeftFrame( false );
00196     if ( mCurrentView == mTodoView ) {
00197       mMainView->navigatorBar()->hide();
00198     } else {
00199       mMainView->navigatorBar()->show();
00200     }
00201   } else {
00202     mMainView->showLeftFrame( true );
00203     mMainView->navigatorBar()->hide();
00204   }
00205   mMainView->viewStack()->raiseWidget( widgetForView( mCurrentView  ) );
00206 }
00207 
00208 void KOViewManager::updateView()
00209 {
00210   if ( mCurrentView ) mCurrentView->updateView();
00211 }
00212 
00213 void KOViewManager::updateView(const QDate &start, const QDate &end)
00214 {
00215 //  kdDebug(5850) << "KOViewManager::updateView()" << endl;
00216 
00217   if (mCurrentView) mCurrentView->showDates(start, end);
00218 
00219   if (mTodoView) mTodoView->updateView();
00220 }
00221 
00222 void KOViewManager::connectView(KOrg::BaseView *view)
00223 {
00224   if (!view) return;
00225 
00226   // selecting an incidence
00227   connect( view, SIGNAL( incidenceSelected( Incidence *,const QDate & ) ),
00228            mMainView, SLOT( processMainViewSelection( Incidence *,const QDate & ) ) );
00229 
00230   // showing/editing/deleting an incidence. The calendar view takes care of the action.
00231   connect( view, SIGNAL(showIncidenceSignal(Incidence *,const QDate &)),
00232            mMainView, SLOT(showIncidence(Incidence *,const QDate &)) );
00233   connect( view, SIGNAL(editIncidenceSignal(Incidence *,const QDate &)),
00234            mMainView, SLOT(editIncidence(Incidence *,const QDate &)) );
00235   connect( view, SIGNAL(deleteIncidenceSignal(Incidence *)),
00236            mMainView, SLOT(deleteIncidence(Incidence *)) );
00237   connect( view, SIGNAL(copyIncidenceSignal(Incidence *)),
00238            mMainView, SLOT(copyIncidence(Incidence *)) );
00239   connect( view, SIGNAL(cutIncidenceSignal(Incidence *)),
00240            mMainView, SLOT(cutIncidence(Incidence *)) );
00241   connect( view, SIGNAL(pasteIncidenceSignal()),
00242            mMainView, SLOT(pasteIncidence()));
00243   connect( view, SIGNAL(toggleAlarmSignal(Incidence *)),
00244            mMainView, SLOT(toggleAlarm(Incidence *)) );
00245   connect( view,SIGNAL(dissociateOccurrenceSignal(Incidence *,const QDate &)),
00246            mMainView, SLOT(dissociateOccurrence(Incidence *,const QDate &)) );
00247   connect( view,SIGNAL(dissociateFutureOccurrenceSignal(Incidence *,const QDate &)),
00248            mMainView, SLOT(dissociateFutureOccurrence(Incidence *,const QDate &)) );
00249 
00250   // signals to create new incidences
00251   connect( view, SIGNAL(newEventSignal(ResourceCalendar *,const QString &)),
00252            mMainView, SLOT(newEvent(ResourceCalendar *,const QString &)) );
00253   connect( view, SIGNAL(newEventSignal(ResourceCalendar *,const QString &,const QDate &)),
00254            mMainView, SLOT(newEvent(ResourceCalendar *,const QString &,const QDate &)) );
00255   connect( view, SIGNAL(newEventSignal(ResourceCalendar *,const QString &,const QDateTime &)),
00256            mMainView, SLOT(newEvent(ResourceCalendar *,const QString &,const QDateTime &)) );
00257   connect( view, SIGNAL(newEventSignal(ResourceCalendar *,const QString &,const QDateTime &,const QDateTime &)),
00258            mMainView, SLOT(newEvent(ResourceCalendar *,const QString &,const QDateTime &,const QDateTime &)) );
00259 
00260   connect( view, SIGNAL(newTodoSignal(ResourceCalendar *,const QString &,const QDate &)),
00261            mMainView, SLOT(newTodo(ResourceCalendar *,const QString &,const QDate &)) );
00262   connect( view, SIGNAL(newSubTodoSignal(Todo *)),
00263            mMainView, SLOT(newSubTodo(Todo *)) );
00264 
00265   connect( view, SIGNAL(newJournalSignal(ResourceCalendar *,const QString &,const QDate &)),
00266            mMainView, SLOT(newJournal(ResourceCalendar *,const QString &,const QDate &)) );
00267 
00268   // reload settings
00269   connect(mMainView, SIGNAL(configChanged()), view, SLOT(updateConfig()));
00270 
00271   // Notifications about added, changed and deleted incidences
00272   connect( mMainView, SIGNAL( dayPassed( const QDate & ) ),
00273            view, SLOT( dayPassed( const QDate & ) ) );
00274   connect( view, SIGNAL( startMultiModify( const QString & ) ),
00275            mMainView, SLOT( startMultiModify( const QString & ) ) );
00276   connect( view, SIGNAL( endMultiModify() ),
00277            mMainView, SLOT( endMultiModify() ) );
00278 
00279   connect( mMainView, SIGNAL( newIncidenceChanger( IncidenceChangerBase* ) ),
00280            view, SLOT( setIncidenceChanger( IncidenceChangerBase * ) ) );
00281   view->setIncidenceChanger( mMainView->incidenceChanger() );
00282 }
00283 
00284 void KOViewManager::connectTodoView( KOTodoView* todoView )
00285 {
00286   if (!todoView) return;
00287 
00288   // SIGNALS/SLOTS FOR TODO VIEW
00289   connect( todoView, SIGNAL( purgeCompletedSignal() ),
00290            mMainView, SLOT( purgeCompleted() ) );
00291   connect( todoView, SIGNAL( unSubTodoSignal() ),
00292            mMainView, SLOT( todo_unsub() ) );
00293   connect( todoView, SIGNAL( unAllSubTodoSignal() ),
00294            mMainView, SLOT( makeSubTodosIndependents() ) );
00295 }
00296 
00297 void KOViewManager::zoomInHorizontally()
00298 {
00299   if( mAgendaView == mCurrentView ) mAgendaView->zoomInHorizontally();
00300 }
00301 void KOViewManager::zoomOutHorizontally()
00302 {
00303   if( mAgendaView== mCurrentView ) mAgendaView->zoomOutHorizontally();
00304 }
00305 void KOViewManager::zoomInVertically()
00306 {
00307   if( mAgendaView== mCurrentView ) mAgendaView->zoomInVertically();
00308 }
00309 void KOViewManager::zoomOutVertically()
00310 {
00311   if( mAgendaView== mCurrentView ) mAgendaView->zoomOutVertically();
00312 }
00313 
00314 void KOViewManager::addView(KOrg::BaseView *view)
00315 {
00316   connectView( view );
00317 #if QT_VERSION >= 300
00318   mMainView->viewStack()->addWidget( view );
00319 #else
00320   mMainView->viewStack()->addWidget( view, 1 );
00321 #endif
00322 }
00323 
00324 void KOViewManager::showWhatsNextView()
00325 {
00326   if (!mWhatsNextView) {
00327     mWhatsNextView = new KOWhatsNextView(mMainView->calendar(),mMainView->viewStack(),
00328                                          "KOViewManager::WhatsNextView");
00329     addView(mWhatsNextView);
00330   }
00331   goMenu( true );
00332   showView(mWhatsNextView);
00333 }
00334 
00335 void KOViewManager::showListView()
00336 {
00337   if (!mListView) {
00338     mListView = new KOListView(mMainView->calendar(), mMainView->viewStack(), "KOViewManager::ListView");
00339     addView(mListView);
00340   }
00341   goMenu( true );
00342   showView(mListView);
00343 }
00344 
00345 void KOViewManager::showAgendaView()
00346 {
00347   // If the user opens a local file, through menu->open ( for example ), then
00348   // it doesn't make sense to use multiagenda.
00349   CalendarResources *calres = dynamic_cast<CalendarResources*>( mMainView->calendar() );
00350   bool isLocalFile = !calres;
00351 
00352   int mode = KOPrefs::instance()->agendaViewCalendarDisplay();
00353 
00354   const bool showBoth = ( mode == KOPrefs::AllCalendarViews && !isLocalFile );
00355 
00356   const bool showMerged = showBoth || mode == KOPrefs::CalendarsMerged || isLocalFile;
00357 
00358   const bool showSideBySide = !isLocalFile && ( showBoth || mode == KOPrefs::CalendarsSideBySide );
00359 
00360   QWidget *parent = mMainView->viewStack();
00361   if ( !mAgendaViewTabs && showBoth ) {
00362     mAgendaViewTabs = new QTabWidget( mMainView->viewStack() );
00363     connect( mAgendaViewTabs, SIGNAL( currentChanged( QWidget* ) ),
00364              this, SLOT( currentAgendaViewTabChanged( QWidget* ) ) );
00365     parent = mAgendaViewTabs;
00366   }
00367 
00368   if ( !mAgendaView && showMerged ) {
00369     mAgendaView = new KOAgendaView( mMainView->calendar(),
00370                                     mMainView,
00371                                     parent,
00372                                     "KOViewManager::AgendaView" );
00373 
00374     addView(mAgendaView);
00375 
00376     connect(mAgendaView, SIGNAL( toggleExpand() ),
00377             mMainView, SLOT( toggleExpand() ) );
00378     connect(mMainView, SIGNAL( calendarViewExpanded( bool ) ),
00379             mAgendaView, SLOT( setExpandedButton( bool ) ) );
00380 
00381     connect( mAgendaView,SIGNAL( zoomViewHorizontally(const QDate &, int )),
00382              mMainView->dateNavigator(),SLOT( selectDates( const QDate &, int ) ) );
00383     mAgendaView->readSettings();
00384   }
00385 
00386   if ( !mAgendaSideBySideView && showSideBySide ) {
00387     mAgendaSideBySideView =
00388       new MultiAgendaView( mMainView->calendar(), mMainView, parent,
00389                         "KOViewManager::AgendaSideBySideView" );
00390 
00391     addView(mAgendaSideBySideView);
00392 
00393 /*    connect(mAgendaSideBySideView, SIGNAL( toggleExpand() ),
00394             mMainView, SLOT( toggleExpand() ) );
00395     connect(mMainView, SIGNAL( calendarViewExpanded( bool ) ),
00396             mAgendaSideBySideView, SLOT( setExpandedButton( bool ) ) );
00397 
00398     connect( mAgendaSideBySideView,SIGNAL( zoomViewHorizontally(const QDate &, int )),
00399              mMainView->dateNavigator(),SLOT( selectDates( const QDate &, int ) ) );*/
00400   }
00401 
00402   if ( showBoth && mAgendaViewTabs ) {
00403     if ( mAgendaView && mAgendaViewTabs->indexOf( mAgendaView ) < 0 )
00404       mAgendaViewTabs->addTab( mAgendaView, i18n("Merged calendar") );
00405     if ( mAgendaSideBySideView  && mAgendaViewTabs->indexOf( mAgendaSideBySideView ) < 0 )
00406       mAgendaViewTabs->addTab( mAgendaSideBySideView, i18n("Calendars Side by Side") );
00407   } else {
00408     if ( mAgendaView && mMainView->viewStack()->id( mAgendaView ) < 0 )
00409       mMainView->viewStack()->addWidget( mAgendaView );
00410     if ( mAgendaSideBySideView && mMainView->viewStack()->id( mAgendaSideBySideView ) < 0 )
00411       mMainView->viewStack()->addWidget( mAgendaSideBySideView );
00412   }
00413 
00414   goMenu( true );
00415   if ( mAgendaViewTabs && showBoth )
00416     showView( static_cast<KOrg::BaseView*>( mAgendaViewTabs->currentPage() ) );
00417   else if ( mAgendaView && showMerged )
00418     showView( mAgendaView );
00419   else if ( mAgendaSideBySideView && showSideBySide )
00420     showView( mAgendaSideBySideView );
00421 }
00422 
00423 void KOViewManager::showDayView()
00424 {
00425   mAgendaMode = AGENDA_DAY;
00426   showAgendaView();
00427   mMainView->dateNavigator()->selectDates( 1 );
00428 }
00429 
00430 void KOViewManager::showWorkWeekView()
00431 {
00432   mAgendaMode = AGENDA_WORK_WEEK;
00433   showAgendaView();
00434   mMainView->dateNavigator()->selectWorkWeek();
00435 }
00436 
00437 void KOViewManager::showWeekView()
00438 {
00439   mAgendaMode = AGENDA_WEEK;
00440   showAgendaView();
00441   mMainView->dateNavigator()->selectWeek();
00442 }
00443 
00444 void KOViewManager::showNextXView()
00445 {
00446   mAgendaMode = AGENDA_NEXTX;
00447   showAgendaView();
00448   mMainView->dateNavigator()->selectDates( QDate::currentDate(),
00449                                            KOPrefs::instance()->mNextXDays );
00450 }
00451 
00452 void KOViewManager::showMonthView()
00453 {
00454   if (!mMonthView) {
00455     mMonthView = new KOMonthView(mMainView->calendar(), mMainView->viewStack(), "KOViewManager::MonthView");
00456     addView(mMonthView);
00457   }
00458 
00459   goMenu( true );
00460   showView(mMonthView);
00461 }
00462 
00463 void KOViewManager::showTodoView()
00464 {
00465   if ( !mTodoView ) {
00466     mTodoView = new KOTodoView( mMainView->calendar(), mMainView->viewStack(),
00467                                 "KOViewManager::TodoView" );
00468     mTodoView->setCalendar( mMainView->calendar() );
00469     addView( mTodoView );
00470     connectTodoView( mTodoView );
00471 
00472     KConfig *config = KOGlobals::self()->config();
00473     mTodoView->restoreLayout( config, "Todo View" );
00474   }
00475 
00476   goMenu( false );
00477   showView( mTodoView );
00478 }
00479 
00480 void KOViewManager::showJournalView()
00481 {
00482   if (!mJournalView) {
00483     mJournalView = new KOJournalView(mMainView->calendar(),mMainView->viewStack(),
00484                                      "KOViewManager::JournalView");
00485     addView(mJournalView);
00486   }
00487 
00488   goMenu( true );
00489   showView(mJournalView);
00490 }
00491 
00492 
00493 void KOViewManager::showTimelineView()
00494 {
00495   if (!mTimelineView) {
00496     mTimelineView = new KOTimelineView(mMainView->calendar(),mMainView->viewStack(),
00497                                      "KOViewManager::TimelineView");
00498     addView(mTimelineView);
00499   }
00500   goMenu( true );
00501   showView(mTimelineView);
00502 }
00503 
00504 void KOViewManager::showEventView()
00505 {
00506   if ( mLastEventView ) {
00507     goMenu( true );
00508     showView( mLastEventView );
00509   } else {
00510     showWeekView();
00511   }
00512 }
00513 
00514 Incidence *KOViewManager::currentSelection()
00515 {
00516   if ( !mCurrentView ) return 0;
00517   Incidence::List incidenceList = mCurrentView->selectedIncidences();
00518   if ( incidenceList.isEmpty() ) return 0;
00519 
00520   return incidenceList.first();
00521 }
00522 
00523 QDate KOViewManager::currentSelectionDate()
00524 {
00525   QDate qd;
00526   if (mCurrentView) {
00527     DateList qvl = mCurrentView->selectedIncidenceDates();
00528     if (!qvl.isEmpty()) qd = qvl.first();
00529   }
00530   return qd;
00531 }
00532 
00533 void KOViewManager::setDocumentId( const QString &id )
00534 {
00535   if (mTodoView) mTodoView->setDocumentId( id );
00536 }
00537 
00538 
00539 QWidget* KOViewManager::widgetForView( KOrg::BaseView* view ) const
00540 {
00541   const bool showBoth = KOPrefs::instance()->agendaViewCalendarDisplay() == KOPrefs::AllCalendarViews;
00542   if ( (view == mAgendaView || view == mAgendaSideBySideView) && mAgendaViewTabs && showBoth ) {
00543     return mAgendaViewTabs;
00544   }
00545   return view;
00546 }
00547 
00548 
00549 void KOViewManager::currentAgendaViewTabChanged( QWidget* widget )
00550 {
00551   goMenu( true );
00552   showView( static_cast<KOrg::BaseView*>( widget ) );
00553 }
00554 
00555 void KOViewManager::resourcesChanged()
00556 {
00557   if ( mAgendaView )
00558     mAgendaView->resourcesChanged();
00559   if ( mAgendaSideBySideView )
00560     mAgendaSideBySideView->resourcesChanged();
00561 }
00562 
00563 void KOViewManager::updateMultiCalendarDisplay()
00564 {
00565   if ( agendaIsSelected() ) {
00566     showAgendaView();
00567   } else {
00568     updateView();
00569   }
00570 }
00571 
00572 bool KOViewManager::agendaIsSelected() const
00573 {
00574   return mCurrentView == mAgendaView            ||
00575          mCurrentView == mAgendaSideBySideView  ||
00576         ( mAgendaViewTabs && mCurrentView == mAgendaViewTabs->currentPage() );
00577 }
KDE Home | KDE Accessibility Home | Description of Access Keys