korganizer

actionmanager.cpp

00001 /*
00002   This file is part of KOrganizer.
00003 
00004   Copyright (c) 2002 Mike Pilone <mpilone@slac.com>
00005   Copyright (c) 2002 Don Sanders <sanders@kde.org>
00006   Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
00007   Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00008 
00009   This program is free software; you can redistribute it and/or modify
00010   it under the terms of the GNU General Public License as published by
00011   the Free Software Foundation; either version 2 of the License, or
00012   (at your option) any later version.
00013 
00014   This program is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00017   GNU General Public License for more details.
00018 
00019   You should have received a copy of the GNU General Public License
00020   along with this program; if not, write to the Free Software
00021   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00022 
00023   As a special exception, permission is given to link this program
00024   with any edition of Qt, and distribute the resulting executable,
00025   without including the source code for Qt in the source distribution.
00026 */
00027 
00028 #include "actionmanager.h"
00029 
00030 #include "alarmclient.h"
00031 #include "calendarview.h"
00032 #include "kocore.h"
00033 #include "kodialogmanager.h"
00034 #include "koglobals.h"
00035 #include "koprefs.h"
00036 #include "koviewmanager.h"
00037 #include "kowindowlist.h"
00038 #include "kprocess.h"
00039 #include "konewstuff.h"
00040 #include "history.h"
00041 #include "kogroupware.h"
00042 #include "resourceview.h"
00043 #include "importdialog.h"
00044 #include "eventarchiver.h"
00045 #include "stdcalendar.h"
00046 
00047 #include <libkcal/calendarlocal.h>
00048 #include <libkcal/calendarresources.h>
00049 #include <libkcal/htmlexport.h>
00050 #include <libkcal/htmlexportsettings.h>
00051 
00052 #include <dcopclient.h>
00053 #include <kaction.h>
00054 #include <kfiledialog.h>
00055 #include <kio/netaccess.h>
00056 #include <kkeydialog.h>
00057 #include <kpopupmenu.h>
00058 #include <kstandarddirs.h>
00059 #include <ktip.h>
00060 #include <ktempfile.h>
00061 #include <kxmlguiclient.h>
00062 #include <kwin.h>
00063 #include <knotifyclient.h>
00064 #include <kstdguiitem.h>
00065 #include <kdeversion.h>
00066 #include <kactionclasses.h>
00067 
00068 #include <qapplication.h>
00069 #include <qtimer.h>
00070 #include <qlabel.h>
00071 
00072 
00073 // FIXME: Several places in the file don't use KConfigXT yet!
00074 KOWindowList *ActionManager::mWindowList = 0;
00075 
00076 ActionManager::ActionManager( KXMLGUIClient *client, CalendarView *widget,
00077                               QObject *parent, KOrg::MainWindow *mainWindow,
00078                               bool isPart )
00079   : QObject( parent ), KCalendarIface(), mRecent( 0 ),
00080     mResourceButtonsAction( 0 ), mResourceViewShowAction( 0 ), mCalendar( 0 ),
00081     mCalendarResources( 0 ), mResourceView( 0 ), mIsClosing( false )
00082 {
00083   mGUIClient = client;
00084   mACollection = mGUIClient->actionCollection();
00085   mCalendarView = widget;
00086   mIsPart = isPart;
00087   mTempFile = 0;
00088   mNewStuff = 0;
00089   mHtmlExportSync = false;
00090   mMainWindow = mainWindow;
00091 }
00092 
00093 ActionManager::~ActionManager()
00094 {
00095   delete mNewStuff;
00096 
00097   // Remove Part plugins
00098   KOCore::self()->unloadParts( mMainWindow, mParts );
00099 
00100   delete mTempFile;
00101 
00102   // Take this window out of the window list.
00103   mWindowList->removeWindow( mMainWindow );
00104 
00105   delete mCalendarView;
00106 
00107   delete mCalendar;
00108 
00109   kdDebug(5850) << "~ActionManager() done" << endl;
00110 }
00111 
00112 // see the Note: below for why this method is necessary
00113 void ActionManager::init()
00114 {
00115   // Construct the groupware object
00116   KOGroupware::create( mCalendarView, mCalendarResources );
00117 
00118   // add this instance of the window to the static list.
00119   if ( !mWindowList ) {
00120     mWindowList = new KOWindowList;
00121     // Show tip of the day, when the first calendar is shown.
00122     if ( !mIsPart )
00123       QTimer::singleShot( 0, this, SLOT( showTipOnStart() ) );
00124   }
00125   // Note: We need this ActionManager to be fully constructed, and
00126   // parent() to have a valid reference to it before the following
00127   // addWindow is called.
00128   mWindowList->addWindow( mMainWindow );
00129 
00130   initActions();
00131 
00132   // set up autoSaving stuff
00133   mAutoSaveTimer = new QTimer( this );
00134   connect( mAutoSaveTimer,SIGNAL( timeout() ), SLOT( checkAutoSave() ) );
00135   if ( KOPrefs::instance()->mAutoSave &&
00136        KOPrefs::instance()->mAutoSaveInterval > 0 ) {
00137     mAutoSaveTimer->start( 1000 * 60 * KOPrefs::instance()->mAutoSaveInterval );
00138   }
00139 
00140   mAutoArchiveTimer = new QTimer( this );
00141   connect( mAutoArchiveTimer, SIGNAL( timeout() ), SLOT( slotAutoArchive() ) );
00142   // First auto-archive should be in 5 minutes (like in kmail).
00143   if ( KOPrefs::instance()->mAutoArchive )
00144     mAutoArchiveTimer->start( 5 * 60 * 1000, true ); // singleshot
00145 
00146   setTitle();
00147 
00148   connect( mCalendarView, SIGNAL( modifiedChanged( bool ) ), SLOT( setTitle() ) );
00149   connect( mCalendarView, SIGNAL( configChanged() ), SLOT( updateConfig() ) );
00150 
00151   connect( mCalendarView, SIGNAL( incidenceSelected( Incidence * ) ),
00152            this, SLOT( processIncidenceSelection( Incidence * ) ) );
00153   connect( mCalendarView, SIGNAL( exportHTML( HTMLExportSettings * ) ),
00154            this, SLOT( exportHTML( HTMLExportSettings * ) ) );
00155 
00156   processIncidenceSelection( 0 );
00157 
00158   // Update state of paste action
00159   mCalendarView->checkClipboard();
00160 }
00161 
00162 void ActionManager::createCalendarLocal()
00163 {
00164   mCalendar = new CalendarLocal( KOPrefs::instance()->mTimeZoneId );
00165   mCalendarView->setCalendar( mCalendar );
00166   mCalendarView->readSettings();
00167 
00168   initCalendar( mCalendar );
00169 }
00170 
00171 void ActionManager::createCalendarResources()
00172 {
00173   mCalendarResources = KOrg::StdCalendar::self();
00174 
00175   CalendarResourceManager *manager = mCalendarResources->resourceManager();
00176 
00177   kdDebug(5850) << "CalendarResources used by KOrganizer:" << endl;
00178   CalendarResourceManager::Iterator it;
00179   for( it = manager->begin(); it != manager->end(); ++it ) {
00180     kdDebug(5850) << "  " << (*it)->resourceName() << endl;
00181     (*it)->setResolveConflict( true );
00182 //    (*it)->dump();
00183   }
00184 
00185   setDestinationPolicy();
00186 
00187   mCalendarView->setCalendar( mCalendarResources );
00188   mCalendarView->readSettings();
00189 
00190   ResourceViewFactory factory( mCalendarResources, mCalendarView );
00191   mCalendarView->addExtension( &factory );
00192   mResourceView = factory.resourceView();
00193 
00194   connect( mCalendarResources, SIGNAL( calendarChanged() ),
00195            mCalendarView, SLOT( slotCalendarChanged() ) );
00196   connect( mCalendarResources, SIGNAL( signalErrorMessage( const QString & ) ),
00197            mCalendarView, SLOT( showErrorMessage( const QString & ) ) );
00198 
00199   connect( mCalendarView, SIGNAL( configChanged() ),
00200            SLOT( updateConfig() ) );
00201 
00202   initCalendar( mCalendarResources );
00203 }
00204 
00205 void ActionManager::initCalendar( Calendar *cal )
00206 {
00207   cal->setOwner( Person( KOPrefs::instance()->fullName(),
00208                          KOPrefs::instance()->email() ) );
00209   // setting fullName and email do not really count as modifying the calendar
00210   mCalendarView->setModified( false );
00211 }
00212 
00213 void ActionManager::initActions()
00214 {
00215   KAction *action;
00216 
00217 
00218   //*************************** FILE MENU **********************************
00219 
00220   //~~~~~~~~~~~~~~~~~~~~~~~ LOADING / SAVING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00221   if ( mIsPart ) {
00222     if ( mMainWindow->hasDocument() ) {
00223       KStdAction::openNew( this, SLOT(file_new()), mACollection, "korganizer_openNew" );
00224       KStdAction::open( this, SLOT( file_open() ), mACollection, "korganizer_open" );
00225       mRecent = KStdAction::openRecent( this, SLOT( file_open( const KURL& ) ),
00226                                      mACollection, "korganizer_openRecent" );
00227       KStdAction::revert( this,SLOT( file_revert() ), mACollection, "korganizer_revert" );
00228       KStdAction::saveAs( this, SLOT( file_saveas() ), mACollection,
00229                    "korganizer_saveAs" );
00230       KStdAction::save( this, SLOT( file_save() ), mACollection, "korganizer_save" );
00231     }
00232     KStdAction::print( mCalendarView, SLOT( print() ), mACollection, "korganizer_print" );
00233   } else {
00234     KStdAction::openNew( this, SLOT( file_new() ), mACollection );
00235     KStdAction::open( this, SLOT( file_open() ), mACollection );
00236     mRecent = KStdAction::openRecent( this, SLOT( file_open( const KURL& ) ),
00237                                      mACollection );
00238     if ( mMainWindow->hasDocument() ) {
00239       KStdAction::revert( this,SLOT( file_revert() ), mACollection );
00240       KStdAction::save( this, SLOT( file_save() ), mACollection );
00241       KStdAction::saveAs( this, SLOT( file_saveas() ), mACollection );
00242     }
00243     KStdAction::print( mCalendarView, SLOT( print() ), mACollection );
00244   }
00245 
00246 
00247   //~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT / EXPORT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00248   new KAction( i18n("Import &Calendar..."), 0, this, SLOT( file_merge() ),
00249                mACollection, "import_icalendar" );
00250   new KAction( i18n("&Import From UNIX Ical tool"), 0, this, SLOT( file_icalimport() ),
00251                mACollection, "import_ical" );
00252   new KAction( i18n("Get &Hot New Stuff..."), 0, this,
00253                SLOT( downloadNewStuff() ), mACollection,
00254                "downloadnewstuff" );
00255 
00256   new KAction( i18n("Export &Web Page..."), "webexport", 0,
00257                mCalendarView, SLOT( exportWeb() ),
00258                mACollection, "export_web" );
00259   new KAction( i18n("&iCalendar..."), 0,
00260                mCalendarView, SLOT( exportICalendar() ),
00261                mACollection, "export_icalendar" );
00262   new KAction( i18n("&vCalendar..."), 0,
00263                mCalendarView, SLOT( exportVCalendar() ),
00264                mACollection, "export_vcalendar" );
00265   new KAction( i18n("Upload &Hot New Stuff..."), 0, this,
00266                SLOT( uploadNewStuff() ), mACollection,
00267                "uploadnewstuff" );
00268 
00269 
00270 
00271   new KAction( i18n("Archive O&ld Entries..."), 0, this, SLOT( file_archive() ),
00272                     mACollection, "file_archive" );
00273   new KAction( i18n("delete completed to-dos", "Pur&ge Completed To-dos"), 0,
00274                mCalendarView, SLOT( purgeCompleted() ), mACollection,
00275                "purge_completed" );
00276 
00277 
00278 
00279 
00280   //************************** EDIT MENU *********************************
00281   KAction *pasteAction;
00282   KOrg::History *h = mCalendarView->history();
00283   if ( mIsPart ) {
00284     // edit menu
00285     mCutAction = KStdAction::cut( mCalendarView, SLOT( edit_cut() ),
00286                                   mACollection, "korganizer_cut" );
00287     mCopyAction = KStdAction::copy( mCalendarView, SLOT( edit_copy() ),
00288                                     mACollection, "korganizer_copy" );
00289     pasteAction = KStdAction::paste( mCalendarView, SLOT( edit_paste() ),
00290                                      mACollection, "korganizer_paste" );
00291     mUndoAction = KStdAction::undo( h, SLOT( undo() ),
00292                                     mACollection, "korganizer_undo" );
00293     mRedoAction = KStdAction::redo( h, SLOT( redo() ),
00294                                     mACollection, "korganizer_redo" );
00295   } else {
00296     mCutAction = KStdAction::cut( mCalendarView,SLOT( edit_cut() ),
00297                                   mACollection );
00298     mCopyAction = KStdAction::copy( mCalendarView,SLOT( edit_copy() ),
00299                                     mACollection );
00300     pasteAction = KStdAction::paste( mCalendarView,SLOT( edit_paste() ),
00301                                      mACollection );
00302     mUndoAction = KStdAction::undo( h, SLOT( undo() ), mACollection );
00303     mRedoAction = KStdAction::redo( h, SLOT( redo() ), mACollection );
00304   }
00305   mDeleteAction = new KAction( i18n("&Delete"), "editdelete", 0,
00306                                mCalendarView, SLOT( appointment_delete() ),
00307                                mACollection, "edit_delete" );
00308   if ( mIsPart ) {
00309     KStdAction::find( mCalendarView->dialogManager(), SLOT( showSearchDialog() ),
00310                      mACollection, "korganizer_find" );
00311   } else {
00312     KStdAction::find( mCalendarView->dialogManager(), SLOT( showSearchDialog() ),
00313                      mACollection );
00314   }
00315   pasteAction->setEnabled( false );
00316   mUndoAction->setEnabled( false );
00317   mRedoAction->setEnabled( false );
00318   connect( mCalendarView, SIGNAL( pasteEnabled( bool ) ),
00319            pasteAction, SLOT( setEnabled( bool ) ) );
00320   connect( h, SIGNAL( undoAvailable( const QString & ) ),
00321            SLOT( updateUndoAction( const QString & ) ) );
00322   connect( h, SIGNAL( redoAvailable( const QString & ) ),
00323            SLOT( updateRedoAction( const QString & ) ) );
00324 
00325 
00326 
00327 
00328   //************************** VIEW MENU *********************************
00329 
00330   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VIEWS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00331   new KAction( i18n("What's &Next"), "whatsnext", 0,
00332                     mCalendarView->viewManager(), SLOT( showWhatsNextView() ),
00333                     mACollection, "view_whatsnext" );
00334   new KAction( i18n("&Day"), "1day", 0,
00335                     mCalendarView->viewManager(), SLOT( showDayView() ),
00336                     mACollection, "view_day" );
00337   mNextXDays = new KAction( "", "xdays", 0, mCalendarView->viewManager(),
00338                     SLOT( showNextXView() ), mACollection, "view_nextx" );
00339   mNextXDays->setText( i18n( "&Next Day", "Ne&xt %n Days",
00340                              KOPrefs::instance()->mNextXDays ) );
00341   new KAction( i18n("W&ork Week"), "5days", 0,
00342                     mCalendarView->viewManager(), SLOT( showWorkWeekView() ),
00343                     mACollection, "view_workweek" );
00344   new KAction( i18n("&Week"), "7days", 0,
00345                     mCalendarView->viewManager(), SLOT( showWeekView() ),
00346                     mACollection, "view_week" );
00347   new KAction( i18n("&Month"), "month", 0,
00348                     mCalendarView->viewManager(), SLOT( showMonthView() ),
00349                     mACollection, "view_month" );
00350   new KAction( i18n("&List"), "list", 0,
00351                     mCalendarView->viewManager(), SLOT( showListView() ),
00352                     mACollection, "view_list" );
00353   new KAction( i18n("&To-do List"), "todo", 0,
00354                     mCalendarView->viewManager(), SLOT( showTodoView() ),
00355                     mACollection, "view_todo" );
00356   new KAction( i18n("&Journal"), "journal", 0,
00357                     mCalendarView->viewManager(), SLOT( showJournalView() ),
00358                     mACollection, "view_journal" );
00359 
00360 
00361   //~~~~~~~~~~~~~~~~~~~~~~~~~~~ FILTERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00362   new KAction( i18n("&Refresh"), 0,
00363                     mCalendarView, SLOT( updateView() ),
00364                     mACollection, "update" );
00365 // TODO:
00366 //   new KAction( i18n("Hide &Completed To-dos"), 0,
00367 //                     mCalendarView, SLOT( toggleHideCompleted() ),
00368 //                     mACollection, "hide_completed_todos" );
00369 
00370   mFilterAction = new KSelectAction( i18n("F&ilter"), 0,
00371                   mACollection, "filter_select" );
00372   mFilterAction->setEditable( false );
00373   connect( mFilterAction, SIGNAL( activated(int) ),
00374            mCalendarView, SLOT( filterActivated( int ) ) );
00375   connect( mCalendarView, SIGNAL( newFilterListSignal( const QStringList & ) ),
00376            mFilterAction, SLOT( setItems( const QStringList & ) ) );
00377   connect( mCalendarView, SIGNAL( selectFilterSignal( int ) ),
00378            mFilterAction, SLOT( setCurrentItem( int ) ) );
00379   connect( mCalendarView, SIGNAL( filterChanged() ),
00380            this, SLOT( setTitle() ) );
00381 
00382 
00383   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ZOOM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00384   // TODO: try to find / create better icons for the following 4 actions
00385   new KAction( i18n( "Zoom In Horizontally" ), "viewmag+", 0,
00386                     mCalendarView->viewManager(), SLOT( zoomInHorizontally() ),
00387                     mACollection, "zoom_in_horizontally" );
00388   new KAction( i18n( "Zoom Out Horizontally" ), "viewmag-", 0,
00389                     mCalendarView->viewManager(), SLOT( zoomOutHorizontally() ),
00390                     mACollection, "zoom_out_horizontally" );
00391   new KAction( i18n( "Zoom In Vertically" ), "viewmag+", 0,
00392                     mCalendarView->viewManager(), SLOT( zoomInVertically() ),
00393                     mACollection, "zoom_in_vertically" );
00394   new KAction( i18n( "Zoom Out Vertically" ), "viewmag-", 0,
00395                     mCalendarView->viewManager(), SLOT( zoomOutVertically() ),
00396                     mACollection, "zoom_out_vertically" );
00397 
00398 
00399 
00400 
00401   //************************** Actions MENU *********************************
00402 
00403   new KAction( i18n("Go to &Today"), "today", 0,
00404                     mCalendarView,SLOT( goToday() ),
00405                     mACollection, "go_today" );
00406   bool isRTL = QApplication::reverseLayout();
00407   action = new KAction( i18n("Go &Backward"), isRTL ? "forward" : "back", 0,
00408                         mCalendarView,SLOT( goPrevious() ),
00409                         mACollection, "go_previous" );
00410 
00411   // Changing the action text by setText makes the toolbar button disappear.   
00412   // This has to be fixed first, before the connects below can be reenabled.   
00413   /*
00414   connect( mCalendarView, SIGNAL( changeNavStringPrev( const QString & ) ),   
00415            action, SLOT( setText( const QString & ) ) );   
00416   connect( mCalendarView, SIGNAL( changeNavStringPrev( const QString & ) ),   
00417            this, SLOT( dumpText( const QString & ) ) );*/
00418 
00419   action = new KAction( i18n("Go &Forward"), isRTL ? "back" : "forward", 0,
00420                         mCalendarView,SLOT( goNext() ),
00421                         mACollection, "go_next" );
00422   /*
00423   connect( mCalendarView,SIGNAL( changeNavStringNext( const QString & ) ),   
00424            action,SLOT( setText( const QString & ) ) );   
00425   */
00426 
00427 
00428   //************************** Actions MENU *********************************
00429   new KAction( i18n("New E&vent..."), "appointment", 0,
00430                mCalendarView,SLOT( newEvent() ),
00431                mACollection, "new_event" );
00432   new KAction( i18n("New &To-do..."), "newtodo", 0,
00433                mCalendarView,SLOT( newTodo() ),
00434                mACollection, "new_todo" );
00435   action = new KAction( i18n("New Su&b-to-do..."), 0,
00436                         mCalendarView,SLOT( newSubTodo() ),
00437                         mACollection, "new_subtodo" );
00438   action->setEnabled( false );
00439   connect( mCalendarView,SIGNAL( todoSelected( bool ) ),
00440            action,SLOT( setEnabled( bool ) ) );
00441   new KAction( i18n("New &Journal..."), 0,
00442                mCalendarView,SLOT( newJournal() ),
00443                mACollection, "new_journal" );
00444 
00445   mShowIncidenceAction = new KAction( i18n("&Show"), 0,
00446                                       mCalendarView,SLOT( showIncidence() ),
00447                                       mACollection, "show_incidence" );
00448   mEditIncidenceAction = new KAction( i18n("&Edit..."), 0,
00449                                       mCalendarView,SLOT( editIncidence() ),
00450                                       mACollection, "edit_incidence" );
00451   mDeleteIncidenceAction = new KAction( i18n("&Delete"), Key_Delete,
00452                                         mCalendarView,SLOT( deleteIncidence()),
00453                                         mACollection, "delete_incidence" );
00454 
00455   action = new KAction( i18n("&Make Sub-to-do Independent"), 0,
00456                         mCalendarView,SLOT( todo_unsub() ),
00457                         mACollection, "unsub_todo" );
00458   action->setEnabled( false );
00459   connect( mCalendarView,SIGNAL( subtodoSelected( bool ) ),
00460            action,SLOT( setEnabled( bool ) ) );
00461 // TODO: Add item to move the incidence to different resource
00462 //   mAssignResourceAction = new KAction( i18n("Assign &Resource..."), 0,
00463 //                                        mCalendarView, SLOT( assignResource()),
00464 //                                        mACollection, "assign_resource" );
00465 // TODO: Add item to quickly toggle the reminder of a given incidence
00466 //   mToggleAlarmAction = new KToggleAction( i18n("&Activate Reminder"), 0,
00467 //                                         mCalendarView, SLOT( toggleAlarm()),
00468 //                                         mACollection, "activate_alarm" );
00469 
00470 
00471 
00472 
00473   //************************** SCHEDULE MENU ********************************
00474   mPublishEvent = new KAction( i18n("&Publish Item Information..."), "mail_send", 0,
00475                                mCalendarView, SLOT( schedule_publish() ),
00476                                mACollection, "schedule_publish" );
00477   mPublishEvent->setEnabled( false );
00478 
00479   action = new KAction( i18n("Send &Invitation to Attendees"),"mail_generic",0,
00480                         mCalendarView,SLOT( schedule_request() ),
00481                         mACollection,"schedule_request" );
00482   action->setEnabled( false );
00483   connect( mCalendarView, SIGNAL( organizerEventsSelected( bool ) ),
00484            action, SLOT( setEnabled( bool ) ) );
00485 
00486   action = new KAction( i18n("Re&quest Update"), 0,
00487                         mCalendarView, SLOT( schedule_refresh() ),
00488                         mACollection, "schedule_refresh" );
00489   action->setEnabled( false );
00490   connect( mCalendarView,SIGNAL( groupEventsSelected( bool ) ),
00491            action,SLOT( setEnabled( bool ) ) );
00492 
00493   action = new KAction( i18n("Send &Cancelation to Attendees"), 0,
00494                         mCalendarView, SLOT( schedule_cancel() ),
00495                         mACollection, "schedule_cancel" );
00496   action->setEnabled( false );
00497   connect( mCalendarView,SIGNAL( organizerEventsSelected( bool ) ),
00498            action,SLOT( setEnabled( bool ) ) );
00499 
00500   action = new KAction( i18n("Send Status &Update"),"mail_reply",0,
00501                         mCalendarView,SLOT( schedule_reply() ),
00502                         mACollection,"schedule_reply" );
00503   action->setEnabled( false );
00504   connect( mCalendarView,SIGNAL( groupEventsSelected( bool ) ),
00505            action,SLOT( setEnabled( bool ) ) );
00506 
00507   action = new KAction( i18n("counter proposal","Request Chan&ge"),0,
00508                         mCalendarView,SLOT( schedule_counter() ),
00509                         mACollection, "schedule_counter" );
00510   action->setEnabled( false );
00511   connect( mCalendarView,SIGNAL( groupEventsSelected( bool ) ),
00512            action,SLOT( setEnabled( bool ) ) );
00513 
00514   action = new KAction( i18n("&Mail Free Busy Information..."), 0,
00515                         mCalendarView, SLOT( mailFreeBusy() ),
00516                         mACollection, "mail_freebusy" );
00517   action->setEnabled( true );
00518 
00519   action = new KAction( i18n("&Upload Free Busy Information"), 0,
00520                         mCalendarView, SLOT( uploadFreeBusy() ),
00521                         mACollection, "upload_freebusy" );
00522   action->setEnabled( true );
00523 
00524   if ( !mIsPart ) {
00525       action = new KAction( i18n("&Addressbook"),"contents",0,
00526                             mCalendarView,SLOT( openAddressbook() ),
00527                             mACollection,"addressbook" );
00528   }
00529 
00530 
00531 
00532 
00533   //************************** SETTINGS MENU ********************************
00534 
00535   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIDEBAR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00536   mDateNavigatorShowAction = new KToggleAction( i18n("Show Date Navigator"), 0,
00537                       this, SLOT( toggleDateNavigator() ),
00538                       mACollection, "show_datenavigator" );
00539   mTodoViewShowAction = new KToggleAction ( i18n("Show To-do View"), 0,
00540                       this, SLOT( toggleTodoView() ),
00541                       mACollection, "show_todoview" );
00542   mEventViewerShowAction = new KToggleAction ( i18n("Show Item Viewer"), 0,
00543                       this, SLOT( toggleEventViewer() ),
00544                       mACollection, "show_eventviewer" );
00545   KConfig *config = KOGlobals::self()->config();
00546   config->setGroup( "Settings" );
00547   mDateNavigatorShowAction->setChecked(
00548       config->readBoolEntry( "DateNavigatorVisible", true ) );
00549   // if we are a kpart, then let's not show the todo in the left pane by
00550   // default since there's also a Todo part and we'll assume they'll be
00551   // using that as well, so let's not duplicate it (by default) here
00552   mTodoViewShowAction->setChecked(
00553       config->readBoolEntry( "TodoViewVisible", mIsPart ? false : true ) );
00554   mEventViewerShowAction->setChecked(
00555       config->readBoolEntry( "EventViewerVisible", true ) );
00556   toggleDateNavigator();
00557   toggleTodoView();
00558   toggleEventViewer();
00559 
00560   if ( !mMainWindow->hasDocument() ) {
00561     mResourceViewShowAction = new KToggleAction ( i18n("Show Resource View"), 0,
00562                         this, SLOT( toggleResourceView() ),
00563                         mACollection, "show_resourceview" );
00564     mResourceButtonsAction = new KToggleAction( i18n("Show &Resource Buttons"), 0,
00565                         this, SLOT( toggleResourceButtons() ),
00566                         mACollection, "show_resourcebuttons" );
00567     mResourceViewShowAction->setChecked(
00568         config->readBoolEntry( "ResourceViewVisible", true ) );
00569     mResourceButtonsAction->setChecked(
00570         config->readBoolEntry( "ResourceButtonsVisible", true ) );
00571 
00572     toggleResourceView();
00573     toggleResourceButtons();
00574   }
00575 
00576 
00577   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIDEBAR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00578 
00579   new KAction( i18n("Configure &Date && Time..."), 0,
00580                     this, SLOT( configureDateTime() ),
00581                     mACollection, "conf_datetime" );
00582 // TODO: Add an item to show the resource management dlg
00583 //   new KAction( i18n("Manage &Resources..."), 0,
00584 //                     this, SLOT( manageResources() ),
00585 //                     mACollection, "conf_resources" );
00586   new KAction( i18n("Manage View &Filters..."), "configure", 0,
00587                mCalendarView, SLOT( editFilters() ),
00588                mACollection, "edit_filters" );
00589   new KAction( i18n("Manage C&ategories..."), 0,
00590                mCalendarView->dialogManager(), SLOT( showCategoryEditDialog() ),
00591                mACollection, "edit_categories" );
00592   if ( mIsPart ) {
00593     new KAction( i18n("&Configure Calendar..."), "configure", 0,
00594                  mCalendarView, SLOT( edit_options() ),
00595                  mACollection, "korganizer_configure" );
00596     KStdAction::keyBindings( this, SLOT( keyBindings() ),
00597                              mACollection, "korganizer_configure_shortcuts" );
00598   } else {
00599     KStdAction::preferences( mCalendarView, SLOT( edit_options() ),
00600                             mACollection );
00601     KStdAction::keyBindings( this, SLOT( keyBindings() ), mACollection );
00602   }
00603 
00604 
00605 
00606 
00607   //**************************** HELP MENU **********************************
00608   KStdAction::tipOfDay( this, SLOT( showTip() ), mACollection,
00609                         "help_tipofday" );
00610 //   new KAction( i18n("Show Intro Page"), 0,
00611 //                     mCalendarView,SLOT( showIntro() ),
00612 //                     mACollection,"show_intro" );
00613 
00614 
00615 
00616 
00617   //************************* TOOLBAR ACTIONS *******************************
00618   QLabel *filterLabel = new QLabel( i18n("Filter: "), mCalendarView );
00619   filterLabel->hide();
00620   new KWidgetAction( filterLabel, i18n("Filter: "), 0, 0, 0,
00621                      mACollection, "filter_label" );
00622 
00623 }
00624 
00625 void ActionManager::readSettings()
00626 {
00627   // read settings from the KConfig, supplying reasonable
00628   // defaults where none are to be found
00629 
00630   KConfig *config = KOGlobals::self()->config();
00631   if ( mRecent ) mRecent->loadEntries( config );
00632   mCalendarView->readSettings();
00633 }
00634 
00635 void ActionManager::writeSettings()
00636 {
00637   kdDebug(5850) << "ActionManager::writeSettings" << endl;
00638 
00639   KConfig *config = KOGlobals::self()->config();
00640   mCalendarView->writeSettings();
00641 
00642   config->setGroup( "Settings" );
00643   if ( mResourceButtonsAction ) {
00644     config->writeEntry( "ResourceButtonsVisible",
00645                         mResourceButtonsAction->isChecked() );
00646   }
00647   if ( mDateNavigatorShowAction ) {
00648     config->writeEntry( "DateNavigatorVisible",
00649                         mDateNavigatorShowAction->isChecked() );
00650   }
00651   if ( mTodoViewShowAction ) {
00652     config->writeEntry( "TodoViewVisible",
00653                         mTodoViewShowAction->isChecked() );
00654   }
00655   if ( mResourceViewShowAction ) {
00656     config->writeEntry( "ResourceViewVisible",
00657                         mResourceViewShowAction->isChecked() );
00658   }
00659   if ( mEventViewerShowAction ) {
00660     config->writeEntry( "EventViewerVisible",
00661                         mEventViewerShowAction->isChecked() );
00662   }
00663 
00664   if ( mRecent ) mRecent->saveEntries( config );
00665 
00666   config->sync();
00667 
00668   if ( mCalendarResources ) {
00669     mCalendarResources->resourceManager()->writeConfig();
00670   }
00671 }
00672 
00673 void ActionManager::file_new()
00674 {
00675   emit actionNew();
00676 }
00677 
00678 void ActionManager::file_open()
00679 {
00680   KURL url;
00681   QString defaultPath = locateLocal( "data","korganizer/" );
00682   url = KFileDialog::getOpenURL( defaultPath,i18n("*.vcs *.ics|Calendar Files"),
00683                                 dialogParent() );
00684 
00685   file_open( url );
00686 }
00687 
00688 void ActionManager::file_open( const KURL &url )
00689 {
00690   if ( url.isEmpty() ) return;
00691 
00692   // is that URL already opened somewhere else? Activate that window
00693   KOrg::MainWindow *korg=ActionManager::findInstance( url );
00694   if ( ( 0 != korg )&&( korg != mMainWindow ) ) {
00695     KWin::setActiveWindow( korg->topLevelWidget()->winId() );
00696     return;
00697   }
00698 
00699   kdDebug(5850) << "ActionManager::file_open(): " << url.prettyURL() << endl;
00700 
00701   // Open the calendar file in the same window only if we have an empty calendar window, and not the resource calendar
00702   if ( !mCalendarView->isModified() && mFile.isEmpty() && !mCalendarResources ) {
00703     openURL( url );
00704   } else {
00705     emit actionNew( url );
00706   }
00707 }
00708 
00709 void ActionManager::file_icalimport()
00710 {
00711   // FIXME: eventually, we will need a dialog box to select import type, etc.
00712   // for now, hard-coded to ical file, $HOME/.calendar.
00713   int retVal = -1;
00714   QString progPath;
00715   KTempFile tmpfn;
00716 
00717   QString homeDir = QDir::homeDirPath() + QString::fromLatin1( "/.calendar" );
00718 
00719   if ( !QFile::exists( homeDir ) ) {
00720     KMessageBox::error( dialogParent(),
00721                        i18n( "You have no ical file in your home directory.\n"
00722                             "Import cannot proceed.\n" ) );
00723     return;
00724   }
00725 
00726   KProcess proc;
00727   proc << "ical2vcal" << tmpfn.name();
00728   bool success = proc.start( KProcess::Block );
00729 
00730   if ( !success ) {
00731     kdDebug(5850) << "Error starting ical2vcal." << endl;
00732     return;
00733   } else {
00734     retVal = proc.exitStatus();
00735   }
00736 
00737   kdDebug(5850) << "ical2vcal return value: " << retVal << endl;
00738 
00739   if ( retVal >= 0 && retVal <= 2 ) {
00740     // now we need to MERGE what is in the iCal to the current calendar.
00741     mCalendarView->openCalendar( tmpfn.name(),1 );
00742     if ( !retVal )
00743       KMessageBox::information( dialogParent(),
00744                                i18n( "KOrganizer successfully imported and "
00745                                     "merged your .calendar file from ical "
00746                                     "into the currently opened calendar." ),
00747                                "dotCalendarImportSuccess" );
00748     else
00749       KMessageBox::information( dialogParent(),
00750                            i18n( "KOrganizer encountered some unknown fields while "
00751                                 "parsing your .calendar ical file, and had to "
00752                                 "discard them; please check to see that all "
00753                                 "your relevant data was correctly imported." ),
00754                                  i18n("ICal Import Successful with Warning") );
00755   } else if ( retVal == -1 ) {
00756     KMessageBox::error( dialogParent(),
00757                          i18n( "KOrganizer encountered an error parsing your "
00758                               ".calendar file from ical; import has failed." ) );
00759   } else if ( retVal == -2 ) {
00760     KMessageBox::error( dialogParent(),
00761                          i18n( "KOrganizer does not think that your .calendar "
00762                               "file is a valid ical calendar; import has failed." ) );
00763   }
00764   tmpfn.unlink();
00765 }
00766 
00767 void ActionManager::file_merge()
00768 {
00769   KURL url = KFileDialog::getOpenURL( locateLocal( "data","korganizer/" ),
00770                                      i18n("*.vcs *.ics|Calendar Files"),
00771                                      dialogParent() );
00772   if ( ! url.isEmpty() )  // isEmpty if user cancelled the dialog
00773     importCalendar( url );
00774 }
00775 
00776 void ActionManager::file_archive()
00777 {
00778   mCalendarView->archiveCalendar();
00779 }
00780 
00781 void ActionManager::file_revert()
00782 {
00783   openURL( mURL );
00784 }
00785 
00786 void ActionManager::file_saveas()
00787 {
00788   KURL url = getSaveURL();
00789 
00790   if ( url.isEmpty() ) return;
00791 
00792   saveAsURL( url );
00793 }
00794 
00795 void ActionManager::file_save()
00796 {
00797   if ( mMainWindow->hasDocument() ) {
00798     if ( mURL.isEmpty() ) {
00799       file_saveas();
00800       return;
00801     } else {
00802       saveURL();
00803     }
00804   } else {
00805     mCalendarView->calendar()->save();
00806   }
00807 
00808   // export to HTML
00809   if ( KOPrefs::instance()->mHtmlWithSave ) {
00810     exportHTML();
00811   }
00812 }
00813 
00814 void ActionManager::file_close()
00815 {
00816   if ( !saveModifiedURL() ) return;
00817 
00818   mCalendarView->closeCalendar();
00819   KIO::NetAccess::removeTempFile( mFile );
00820   mURL="";
00821   mFile="";
00822 
00823   setTitle();
00824 }
00825 
00826 bool ActionManager::openURL( const KURL &url,bool merge )
00827 {
00828   kdDebug(5850) << "ActionManager::openURL()" << endl;
00829 
00830   if ( url.isEmpty() ) {
00831     kdDebug(5850) << "ActionManager::openURL(): Error! Empty URL." << endl;
00832     return false;
00833   }
00834   if ( !url.isValid() ) {
00835     kdDebug(5850) << "ActionManager::openURL(): Error! URL is malformed." << endl;
00836     return false;
00837   }
00838 
00839   if ( url.isLocalFile() ) {
00840     mURL = url;
00841     mFile = url.path();
00842     if ( !KStandardDirs::exists( mFile ) ) {
00843       mMainWindow->showStatusMessage( i18n("New calendar '%1'.")
00844                                       .arg( url.prettyURL() ) );
00845       mCalendarView->setModified();
00846     } else {
00847       bool success = mCalendarView->openCalendar( mFile, merge );
00848       if ( success ) {
00849         showStatusMessageOpen( url, merge );
00850       }
00851     }
00852     setTitle();
00853   } else {
00854     QString tmpFile;
00855     if( KIO::NetAccess::download( url, tmpFile, view() ) ) {
00856       kdDebug(5850) << "--- Downloaded to " << tmpFile << endl;
00857       bool success = mCalendarView->openCalendar( tmpFile, merge );
00858       if ( merge ) {
00859         KIO::NetAccess::removeTempFile( tmpFile );
00860         if ( success )
00861           showStatusMessageOpen( url, merge );
00862       } else {
00863         if ( success ) {
00864           KIO::NetAccess::removeTempFile( mFile );
00865           mURL = url;
00866           mFile = tmpFile;
00867           KConfig *config = KOGlobals::self()->config();
00868           config->setGroup( "General" );
00869           setTitle();
00870           kdDebug(5850) << "-- Add recent URL: " << url.prettyURL() << endl;
00871           if ( mRecent ) mRecent->addURL( url );
00872           showStatusMessageOpen( url, merge );
00873         }
00874       }
00875       return success;
00876     } else {
00877       QString msg;
00878       msg = i18n("Cannot download calendar from '%1'.").arg( url.prettyURL() );
00879       KMessageBox::error( dialogParent(), msg );
00880       return false;
00881     }
00882   }
00883   return true;
00884 }
00885 
00886 bool ActionManager::addResource( const KURL &mUrl )
00887 {
00888   CalendarResources *cr = KOrg::StdCalendar::self();
00889 
00890   CalendarResourceManager *manager = cr->resourceManager();
00891 
00892   ResourceCalendar *resource = 0;
00893 
00894   QString name;
00895 
00896   kdDebug(5850) << "URL: " << mUrl << endl;
00897   if ( mUrl.isLocalFile() ) {
00898     kdDebug(5850) << "Local Resource" << endl;
00899     resource = manager->createResource( "file" );
00900     if ( resource )
00901       resource->setValue( "File", mUrl.path() );
00902     name = mUrl.path();
00903   } else {
00904     kdDebug(5850) << "Remote Resource" << endl;
00905     resource = manager->createResource( "remote" );
00906     if ( resource )
00907       resource->setValue( "DownloadURL", mUrl.url() );
00908     name = mUrl.prettyURL();
00909     resource->setReadOnly( true );
00910   }
00911 
00912   if ( resource ) {
00913     resource->setTimeZoneId( KOPrefs::instance()->mTimeZoneId );
00914     resource->setResourceName( name );
00915     manager->add( resource );
00916     mMainWindow->showStatusMessage( i18n( "Added calendar resource for URL '%1'." )
00917                .arg( name ) );
00918     // we have to call resourceAdded manually, because for in-process changes
00919     // the dcop signals are not connected, so the resource's signals would not
00920     // be connected otherwise
00921     if ( mCalendarResources )
00922       mCalendarResources->resourceAdded( resource );
00923   } else {
00924     QString msg = i18n("Unable to create calendar resource '%1'.")
00925                       .arg( name );
00926     KMessageBox::error( dialogParent(), msg );
00927   }
00928   return true;
00929 }
00930 
00931 
00932 void ActionManager::showStatusMessageOpen( const KURL &url, bool merge )
00933 {
00934   if ( merge ) {
00935     mMainWindow->showStatusMessage( i18n("Merged calendar '%1'.")
00936                                     .arg( url.prettyURL() ) );
00937   } else {
00938     mMainWindow->showStatusMessage( i18n("Opened calendar '%1'.")
00939                                     .arg( url.prettyURL() ) );
00940   }
00941 }
00942 
00943 void ActionManager::closeURL()
00944 {
00945   kdDebug(5850) << "ActionManager::closeURL()" << endl;
00946 
00947   file_close();
00948 }
00949 
00950 bool ActionManager::saveURL()
00951 {
00952   QString ext;
00953 
00954   if ( mURL.isLocalFile() ) {
00955     ext = mFile.right( 4 );
00956   } else {
00957     ext = mURL.filename().right( 4 );
00958   }
00959 
00960   if ( ext == ".vcs" ) {
00961     int result = KMessageBox::warningContinueCancel(
00962         dialogParent(),
00963         i18n( "Your calendar will be saved in iCalendar format. Use "
00964               "'Export vCalendar' to save in vCalendar format." ),
00965         i18n("Format Conversion"), i18n("Proceed"), "dontaskFormatConversion",
00966         true );
00967     if ( result != KMessageBox::Continue ) return false;
00968 
00969     QString filename = mURL.fileName();
00970     filename.replace( filename.length() - 4, 4, ".ics" );
00971     mURL.setFileName( filename );
00972     if ( mURL.isLocalFile() ) {
00973       mFile = mURL.path();
00974     }
00975     setTitle();
00976     if ( mRecent ) mRecent->addURL( mURL );
00977   }
00978 
00979   if ( !mCalendarView->saveCalendar( mFile ) ) {
00980     kdDebug(5850) << "ActionManager::saveURL(): calendar view save failed."
00981                   << endl;
00982     return false;
00983   } else {
00984     mCalendarView->setModified( false );
00985   }
00986 
00987   if ( !mURL.isLocalFile() ) {
00988     if ( !KIO::NetAccess::upload( mFile, mURL, view() ) ) {
00989       QString msg = i18n("Cannot upload calendar to '%1'")
00990                     .arg( mURL.prettyURL() );
00991       KMessageBox::error( dialogParent() ,msg );
00992       return false;
00993     }
00994   }
00995 
00996   // keep saves on a regular interval
00997   if ( KOPrefs::instance()->mAutoSave ) {
00998     mAutoSaveTimer->stop();
00999     mAutoSaveTimer->start( 1000*60*KOPrefs::instance()->mAutoSaveInterval );
01000   }
01001 
01002   mMainWindow->showStatusMessage( i18n("Saved calendar '%1'.").arg( mURL.prettyURL() ) );
01003 
01004   return true;
01005 }
01006 
01007 void ActionManager::exportHTML()
01008 {
01009   HTMLExportSettings settings( "KOrganizer" );
01010   // Manually read in the config, because parametrized kconfigxt objects don't
01011   // seem to load the config theirselves
01012   settings.readConfig();
01013 
01014   QDate qd1;
01015   qd1 = QDate::currentDate();
01016   QDate qd2;
01017   qd2 = QDate::currentDate();
01018   if ( settings.monthView() )
01019     qd2.addMonths( 1 );
01020   else
01021     qd2.addDays( 7 );
01022   settings.setDateStart( qd1 );
01023   settings.setDateEnd( qd2 );
01024   exportHTML( &settings );
01025 }
01026 
01027 void ActionManager::exportHTML( HTMLExportSettings *settings )
01028 {
01029   if ( !settings || settings->outputFile().isEmpty() )
01030     return;
01031   settings->setEMail( KOPrefs::instance()->email() );
01032   settings->setName( KOPrefs::instance()->fullName() );
01033 
01034   settings->setCreditName( "KOrganizer" );
01035   settings->setCreditURL( "http://korganizer.kde.org" );
01036 
01037   KCal::HtmlExport mExport( mCalendarView->calendar(), settings );
01038 
01039   QDate cdate = settings->dateStart().date();
01040   QDate qd2 = settings->dateEnd().date();
01041   while ( cdate <= qd2 ) {
01042     if ( !KOGlobals::self()->holiday( cdate ).isEmpty() )
01043       mExport.addHoliday( cdate, KOGlobals::self()->holiday( cdate ) );
01044     cdate = cdate.addDays( 1 );
01045   }
01046 
01047   KURL dest( settings->outputFile() );
01048   if ( dest.isLocalFile() ) {
01049     mExport.save( dest.path() );
01050   } else {
01051     KTempFile tf;
01052     QString tfile = tf.name();
01053     tf.close();
01054     mExport.save( tfile );
01055     if ( !KIO::NetAccess::upload( tfile, dest, view() ) ) {
01056       KNotifyClient::event ( view()->winId(),
01057                             i18n("Could not upload file.") );
01058     }
01059     tf.unlink();
01060   }
01061 }
01062 
01063 bool ActionManager::saveAsURL( const KURL &url )
01064 {
01065   kdDebug(5850) << "ActionManager::saveAsURL() " << url.prettyURL() << endl;
01066 
01067   if ( url.isEmpty() ) {
01068     kdDebug(5850) << "ActionManager::saveAsURL(): Empty URL." << endl;
01069     return false;
01070   }
01071   if ( !url.isValid() ) {
01072     kdDebug(5850) << "ActionManager::saveAsURL(): Malformed URL." << endl;
01073     return false;
01074   }
01075 
01076   QString fileOrig = mFile;
01077   KURL URLOrig = mURL;
01078 
01079   KTempFile *tempFile = 0;
01080   if ( url.isLocalFile() ) {
01081     mFile = url.path();
01082   } else {
01083     tempFile = new KTempFile;
01084     mFile = tempFile->name();
01085   }
01086   mURL = url;
01087 
01088   bool success = saveURL(); // Save local file and upload local file
01089   if ( success ) {
01090     delete mTempFile;
01091     mTempFile = tempFile;
01092     KIO::NetAccess::removeTempFile( fileOrig );
01093     KConfig *config = KOGlobals::self()->config();
01094     config->setGroup( "General" );
01095     setTitle();
01096     if ( mRecent ) mRecent->addURL( mURL );
01097   } else {
01098     KMessageBox::sorry( dialogParent(), i18n("Unable to save calendar to the file %1.").arg( mFile ), i18n("Error") );
01099     kdDebug(5850) << "ActionManager::saveAsURL() failed" << endl;
01100     mURL = URLOrig;
01101     mFile = fileOrig;
01102     delete tempFile;
01103   }
01104 
01105   return success;
01106 }
01107 
01108 
01109 bool ActionManager::saveModifiedURL()
01110 {
01111   kdDebug(5850) << "ActionManager::saveModifiedURL()" << endl;
01112 
01113   // If calendar isn't modified do nothing.
01114   if ( !mCalendarView->isModified() ) return true;
01115 
01116   mHtmlExportSync = true;
01117   if ( KOPrefs::instance()->mAutoSave && !mURL.isEmpty() ) {
01118     // Save automatically, when auto save is enabled.
01119     return saveURL();
01120   } else {
01121     int result = KMessageBox::warningYesNoCancel(
01122         dialogParent(),
01123         i18n("The calendar has been modified.\nDo you want to save it?"),
01124         QString::null,
01125         KStdGuiItem::save(), KStdGuiItem::discard() );
01126     switch( result ) {
01127       case KMessageBox::Yes:
01128         if ( mURL.isEmpty() ) {
01129           KURL url = getSaveURL();
01130           return saveAsURL( url );
01131         } else {
01132           return saveURL();
01133         }
01134       case KMessageBox::No:
01135         return true;
01136       case KMessageBox::Cancel:
01137       default:
01138         {
01139           mHtmlExportSync = false;
01140           return false;
01141         }
01142     }
01143   }
01144 }
01145 
01146 
01147 KURL ActionManager::getSaveURL()
01148 {
01149   KURL url = KFileDialog::getSaveURL( locateLocal( "data","korganizer/" ),
01150                                      i18n("*.vcs *.ics|Calendar Files"),
01151                                      dialogParent() );
01152 
01153   if ( url.isEmpty() ) return url;
01154 
01155   QString filename = url.fileName( false );
01156 
01157   QString e = filename.right( 4 );
01158   if ( e != ".vcs" && e != ".ics" ) {
01159     // Default save format is iCalendar
01160     filename += ".ics";
01161   }
01162 
01163   url.setFileName( filename );
01164 
01165   kdDebug(5850) << "ActionManager::getSaveURL(): url: " << url.url() << endl;
01166 
01167   return url;
01168 }
01169 
01170 void ActionManager::saveProperties( KConfig *config )
01171 {
01172   kdDebug(5850) << "ActionManager::saveProperties" << endl;
01173 
01174   config->writeEntry( "UseResourceCalendar", !mMainWindow->hasDocument() );
01175   if ( mMainWindow->hasDocument() ) {
01176     config->writePathEntry( "Calendar",mURL.url() );
01177   }
01178 }
01179 
01180 void ActionManager::readProperties( KConfig *config )
01181 {
01182   kdDebug(5850) << "ActionManager::readProperties" << endl;
01183 
01184   bool isResourceCalendar(
01185     config->readBoolEntry( "UseResourceCalendar", true ) );
01186   QString calendarUrl = config->readPathEntry( "Calendar" );
01187 
01188   if ( !isResourceCalendar && !calendarUrl.isEmpty() ) {
01189     mMainWindow->init( true );
01190     KURL u( calendarUrl );
01191     openURL( u );
01192   } else {
01193     mMainWindow->init( false );
01194   }
01195 }
01196 
01197 void ActionManager::checkAutoSave()
01198 {
01199   kdDebug(5850) << "ActionManager::checkAutoSave()" << endl;
01200 
01201   // Don't save if auto save interval is zero
01202   if ( KOPrefs::instance()->mAutoSaveInterval == 0 ) return;
01203 
01204   // has this calendar been saved before? If yes automatically save it.
01205   if ( KOPrefs::instance()->mAutoSave ) {
01206     if ( mCalendarResources || ( mCalendar && !url().isEmpty() ) ) {
01207       saveCalendar();
01208     }
01209   }
01210 }
01211 
01212 
01213 // Configuration changed as a result of the options dialog.
01214 void ActionManager::updateConfig()
01215 {
01216   kdDebug(5850) << "ActionManager::updateConfig()" << endl;
01217 
01218   if ( KOPrefs::instance()->mAutoSave && !mAutoSaveTimer->isActive() ) {
01219     checkAutoSave();
01220     if ( KOPrefs::instance()->mAutoSaveInterval > 0 ) {
01221       mAutoSaveTimer->start( 1000 * 60 *
01222                              KOPrefs::instance()->mAutoSaveInterval );
01223     }
01224   }
01225   if ( !KOPrefs::instance()->mAutoSave ) mAutoSaveTimer->stop();
01226   mNextXDays->setText( i18n( "&Next Day", "&Next %n Days",
01227                              KOPrefs::instance()->mNextXDays ) );
01228 
01229   KOCore::self()->reloadPlugins();
01230   mParts = KOCore::self()->reloadParts( mMainWindow, mParts );
01231 
01232   setDestinationPolicy();
01233 
01234   if ( mResourceView )
01235     mResourceView->updateView();
01236 }
01237 
01238 void ActionManager::setDestinationPolicy()
01239 {
01240   if ( mCalendarResources ) {
01241     if ( KOPrefs::instance()->mDestination == KOPrefs::askDestination )
01242       mCalendarResources->setAskDestinationPolicy();
01243     else
01244       mCalendarResources->setStandardDestinationPolicy();
01245   }
01246 }
01247 
01248 void ActionManager::configureDateTime()
01249 {
01250   KProcess *proc = new KProcess;
01251   *proc << "kcmshell" << "language";
01252 
01253   connect( proc,SIGNAL( processExited( KProcess * ) ),
01254           SLOT( configureDateTimeFinished( KProcess * ) ) );
01255 
01256   if ( !proc->start() ) {
01257       KMessageBox::sorry( dialogParent(),
01258         i18n("Could not start control module for date and time format.") );
01259       delete proc;
01260   }
01261 }
01262 
01263 void ActionManager::showTip()
01264 {
01265   KTipDialog::showTip( dialogParent(),QString::null,true );
01266 }
01267 
01268 void ActionManager::showTipOnStart()
01269 {
01270   KTipDialog::showTip( dialogParent() );
01271 }
01272 
01273 KOrg::MainWindow *ActionManager::findInstance( const KURL &url )
01274 {
01275   if ( mWindowList ) {
01276     if ( url.isEmpty() ) return mWindowList->defaultInstance();
01277     else return mWindowList->findInstance( url );
01278   } else {
01279     return 0;
01280   }
01281 }
01282 
01283 void ActionManager::dumpText( const QString &str )
01284 {
01285   kdDebug(5850) << "ActionManager::dumpText(): " << str << endl;
01286 }
01287 
01288 void ActionManager::toggleDateNavigator()
01289 {
01290   bool visible = mDateNavigatorShowAction->isChecked();
01291   if ( mCalendarView ) mCalendarView->showDateNavigator( visible );
01292 }
01293 
01294 void ActionManager::toggleTodoView()
01295 {
01296   bool visible = mTodoViewShowAction->isChecked();
01297   if ( mCalendarView ) mCalendarView->showTodoView( visible );
01298 }
01299 
01300 void ActionManager::toggleEventViewer()
01301 {
01302   bool visible = mEventViewerShowAction->isChecked();
01303   if ( mCalendarView ) mCalendarView->showEventViewer( visible );
01304 }
01305 
01306 void ActionManager::toggleResourceView()
01307 {
01308   bool visible = mResourceViewShowAction->isChecked();
01309   kdDebug(5850) << "toggleResourceView: " << endl;
01310   if ( mResourceView ) {
01311     if ( visible ) mResourceView->show();
01312     else mResourceView->hide();
01313   }
01314 }
01315 
01316 void ActionManager::toggleResourceButtons()
01317 {
01318   bool visible = mResourceButtonsAction->isChecked();
01319 
01320   kdDebug(5850) << "RESOURCE VIEW " << long( mResourceView ) << endl;
01321 
01322   if ( mResourceView ) mResourceView->showButtons( visible );
01323 }
01324 
01325 bool ActionManager::openURL( const QString &url )
01326 {
01327   return openURL( KURL( url ) );
01328 }
01329 
01330 bool ActionManager::mergeURL( const QString &url )
01331 {
01332   return openURL( KURL( url ),true );
01333 }
01334 
01335 bool ActionManager::saveAsURL( const QString &url )
01336 {
01337   return saveAsURL( KURL( url ) );
01338 }
01339 
01340 QString ActionManager::getCurrentURLasString() const
01341 {
01342   return mURL.url();
01343 }
01344 
01345 bool ActionManager::editIncidence( const QString& uid )
01346 {
01347   return mCalendarView->editIncidence( uid );
01348 }
01349 
01350 bool ActionManager::deleteIncidence( const QString& uid, bool force )
01351 {
01352   return mCalendarView->deleteIncidence( uid, force );
01353 }
01354 
01355 bool ActionManager::addIncidence( const QString& ical )
01356 {
01357   return mCalendarView->addIncidence( ical );
01358 }
01359 
01360 void ActionManager::configureDateTimeFinished( KProcess *proc )
01361 {
01362   delete proc;
01363 }
01364 
01365 void ActionManager::downloadNewStuff()
01366 {
01367   kdDebug(5850) << "ActionManager::downloadNewStuff()" << endl;
01368 
01369   if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
01370   mNewStuff->download();
01371 }
01372 
01373 void ActionManager::uploadNewStuff()
01374 {
01375   if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
01376   mNewStuff->upload();
01377 }
01378 
01379 QString ActionManager::localFileName()
01380 {
01381   return mFile;
01382 }
01383 
01384 class ActionManager::ActionStringsVisitor : public IncidenceBase::Visitor
01385 {
01386   public:
01387     ActionStringsVisitor() : mShow( 0 ), mEdit( 0 ), mDelete( 0 ) {}
01388 
01389     bool act( IncidenceBase *incidence, KAction *show, KAction *edit, KAction *del )
01390     {
01391       mShow = show;
01392       mEdit = edit;
01393       mDelete = del;
01394       return incidence->accept( *this );
01395     }
01396 
01397   protected:
01398     bool visit( Event * ) {
01399       if ( mShow ) mShow->setText( i18n("&Show Event") );
01400       if ( mEdit ) mEdit->setText( i18n("&Edit Event...") );
01401       if ( mDelete ) mDelete->setText( i18n("&Delete Event") );
01402       return true;
01403     }
01404     bool visit( Todo * ) {
01405       if ( mShow ) mShow->setText( i18n("&Show To-do") );
01406       if ( mEdit ) mEdit->setText( i18n("&Edit To-do...") );
01407       if ( mDelete ) mDelete->setText( i18n("&Delete To-do") );
01408       return true;
01409     }
01410     bool visit( Journal * ) { return assignDefaultStrings(); }
01411   protected:
01412     bool assignDefaultStrings() {
01413       if ( mShow ) mShow->setText( i18n("&Show") );
01414       if ( mEdit ) mEdit->setText( i18n("&Edit...") );
01415       if ( mDelete ) mDelete->setText( i18n("&Delete") );
01416       return true;
01417     }
01418     KAction *mShow;
01419     KAction *mEdit;
01420     KAction *mDelete;
01421 };
01422 
01423 void ActionManager::processIncidenceSelection( Incidence *incidence )
01424 {
01425 //  kdDebug(5850) << "ActionManager::processIncidenceSelection()" << endl;
01426 
01427   if ( !incidence ) {
01428     enableIncidenceActions( false );
01429     return;
01430   }
01431 
01432   enableIncidenceActions( true );
01433 
01434   if ( incidence->isReadOnly() ) {
01435     mCutAction->setEnabled( false );
01436     mDeleteAction->setEnabled( false );
01437   }
01438 
01439   ActionStringsVisitor v;
01440   if ( !v.act( incidence, mShowIncidenceAction, mEditIncidenceAction, mDeleteIncidenceAction ) ) {
01441     mShowIncidenceAction->setText( i18n("&Show") );
01442     mEditIncidenceAction->setText( i18n("&Edit...") );
01443     mDeleteIncidenceAction->setText( i18n("&Delete") );
01444   }
01445 }
01446 
01447 void ActionManager::enableIncidenceActions( bool enabled )
01448 {
01449   mShowIncidenceAction->setEnabled( enabled );
01450   mEditIncidenceAction->setEnabled( enabled );
01451   mDeleteIncidenceAction->setEnabled( enabled );
01452 //   mAssignResourceAction->setEnabled( enabled );
01453 
01454   mCutAction->setEnabled( enabled );
01455   mCopyAction->setEnabled( enabled );
01456   mDeleteAction->setEnabled( enabled );
01457   mPublishEvent->setEnabled( enabled );
01458 }
01459 
01460 void ActionManager::keyBindings()
01461 {
01462   KKeyDialog dlg( false, view() );
01463   if ( mMainWindow )
01464     dlg.insert( mMainWindow->getActionCollection() );
01465 
01466   KOrg::Part *part;
01467   for ( part = mParts.first(); part; part = mParts.next() ) {
01468     dlg.insert( part->actionCollection(), part->shortInfo() );
01469   }
01470   dlg.configure();
01471 }
01472 
01473 void ActionManager::loadParts()
01474 {
01475   mParts = KOCore::self()->loadParts( mMainWindow );
01476 }
01477 
01478 void ActionManager::setTitle()
01479 {
01480   mMainWindow->setTitle();
01481 }
01482 
01483 KCalendarIface::ResourceRequestReply ActionManager::resourceRequest( const QValueList<QPair<QDateTime, QDateTime> >&,
01484  const QCString& resource,
01485  const QString& vCalIn )
01486 {
01487     kdDebug(5850) << k_funcinfo << "resource=" << resource << " vCalIn=" << vCalIn << endl;
01488     KCalendarIface::ResourceRequestReply reply;
01489     reply.vCalOut = "VCalOut";
01490     return reply;
01491 }
01492 
01493 void ActionManager::openEventEditor( const QString& text )
01494 {
01495   mCalendarView->newEvent( text );
01496 }
01497 
01498 void ActionManager::openEventEditor( const QString& summary,
01499                                      const QString& description,
01500                                      const QString& attachment )
01501 {
01502   mCalendarView->newEvent( summary, description, attachment );
01503 }
01504 
01505 void ActionManager::openEventEditor( const QString& summary,
01506                                      const QString& description,
01507                                      const QString& attachment,
01508                                      const QStringList& attendees )
01509 {
01510   mCalendarView->newEvent( summary, description, attachment, attendees );
01511 }
01512 
01513 void ActionManager::openTodoEditor( const QString& text )
01514 {
01515   mCalendarView->newTodo( text );
01516 }
01517 
01518 void ActionManager::openTodoEditor( const QString& summary,
01519                                     const QString& description,
01520                                     const QString& attachment )
01521 {
01522   mCalendarView->newTodo( summary, description, attachment );
01523 }
01524 
01525 void ActionManager::openTodoEditor( const QString& summary,
01526                                     const QString& description,
01527                                     const QString& attachment,
01528                                     const QStringList& attendees )
01529 {
01530   mCalendarView->newTodo( summary, description, attachment, attendees );
01531 }
01532 
01533 void ActionManager::openJournalEditor( const QDate& date )
01534 {
01535   mCalendarView->newJournal( date );
01536 }
01537 
01538 void ActionManager::openJournalEditor( const QString& text, const QDate& date )
01539 {
01540   mCalendarView->newJournal( text, date );
01541 }
01542 
01543 void ActionManager::openJournalEditor( const QString& text )
01544 {
01545   mCalendarView->newJournal( text );
01546 }
01547 
01548 //TODO:
01549 // void ActionManager::openJournalEditor( const QString& summary,
01550 //                                        const QString& description,
01551 //                                        const QString& attachment )
01552 // {
01553 //   mCalendarView->newJournal( summary, description, attachment );
01554 // }
01555 
01556 
01557 void ActionManager::showJournalView()
01558 {
01559   mCalendarView->viewManager()->showJournalView();
01560 }
01561 
01562 void ActionManager::showTodoView()
01563 {
01564   mCalendarView->viewManager()->showTodoView();
01565 }
01566 
01567 void ActionManager::showEventView()
01568 {
01569   mCalendarView->viewManager()->showEventView();
01570 }
01571 
01572 void ActionManager::goDate( const QDate& date )
01573 {
01574   mCalendarView->goDate( date );
01575 }
01576 
01577 void ActionManager::goDate( const QString& date )
01578 {
01579   goDate( KGlobal::locale()->readDate( date ) );
01580 }
01581 
01582 void ActionManager::updateUndoAction( const QString &text )
01583 {
01584   if ( text.isNull() ) {
01585     mUndoAction->setEnabled( false );
01586     mUndoAction->setText( i18n("Undo") );
01587   } else {
01588     mUndoAction->setEnabled( true );
01589     if ( text.isEmpty() ) mUndoAction->setText( i18n("Undo") );
01590     else mUndoAction->setText( i18n("Undo (%1)").arg( text ) );
01591   }
01592 }
01593 
01594 void ActionManager::updateRedoAction( const QString &text )
01595 {
01596   if ( text.isNull() ) {
01597     mRedoAction->setEnabled( false );
01598     mRedoAction->setText( i18n( "Redo" ) );
01599   } else {
01600     mRedoAction->setEnabled( true );
01601     if ( text.isEmpty() ) mRedoAction->setText( i18n("Redo") );
01602     else mRedoAction->setText( i18n( "Redo (%1)" ).arg( text ) );
01603   }
01604 }
01605 
01606 bool ActionManager::queryClose()
01607 {
01608   kdDebug(5850) << "ActionManager::queryClose()" << endl;
01609 
01610   bool close = true;
01611 
01612   if ( mCalendar && mCalendar->isModified() ) {
01613     int res = KMessageBox::questionYesNoCancel( dialogParent(),
01614       i18n("The calendar contains unsaved changes. Do you want to save them before exiting?"), QString::null, KStdGuiItem::save(), KStdGuiItem::discard() );
01615     // Exit on yes and no, don't exit on cancel. If saving fails, ask for exiting.
01616     if ( res == KMessageBox::Yes ) {
01617       close = saveModifiedURL();
01618       if ( !close ) {
01619         int res1 = KMessageBox::questionYesNo( dialogParent(), i18n("Unable to save the calendar. Do you still want to close this window?"), QString::null, KStdGuiItem::close(), KStdGuiItem::cancel() );
01620         close = ( res1 == KMessageBox::Yes );
01621       }
01622     } else {
01623       close = ( res == KMessageBox::No );
01624     }
01625   } else if ( mCalendarResources ) {
01626     if ( !mIsClosing ) {
01627       kdDebug(5850) << "!mIsClosing" << endl;
01628       if ( !saveResourceCalendar() ) return false;
01629 
01630       // FIXME: Put main window into a state indicating final saving.
01631       mIsClosing = true;
01632 // FIXME: Close main window when save is finished
01633 //      connect( mCalendarResources, SIGNAL( calendarSaved() ),
01634 //               mMainWindow, SLOT( close() ) );
01635     }
01636     if ( mCalendarResources->isSaving() ) {
01637       kdDebug(5850) << "ActionManager::queryClose(): isSaving" << endl;
01638       close = false;
01639       KMessageBox::information( dialogParent(),
01640           i18n("Unable to exit. Saving still in progress.") );
01641     } else {
01642       kdDebug(5850) << "ActionManager::queryClose(): close = true" << endl;
01643       close = true;
01644     }
01645   } else {
01646     close = true;
01647   }
01648 
01649   return close;
01650 }
01651 
01652 void ActionManager::saveCalendar()
01653 {
01654   if ( mCalendar ) {
01655     if ( view()->isModified() ) {
01656       if ( !url().isEmpty() ) {
01657         saveURL();
01658       } else {
01659         QString location = locateLocal( "data", "korganizer/kontact.ics" );
01660         saveAsURL( location );
01661       }
01662     }
01663   } else if ( mCalendarResources ) {
01664     mCalendarResources->save();
01665     // FIXME: Make sure that asynchronous saves don't fail.
01666   }
01667 }
01668 
01669 bool ActionManager::saveResourceCalendar()
01670 {
01671   if ( !mCalendarResources ) return false;
01672   CalendarResourceManager *m = mCalendarResources->resourceManager();
01673 
01674   CalendarResourceManager::ActiveIterator it;
01675   for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
01676     if ( (*it)->readOnly() ) continue;
01677     if ( !(*it)->save() ) {
01678       int result = KMessageBox::warningContinueCancel( view(),
01679         i18n( "Saving of '%1' failed. Check that the resource is "
01680              "properly configured.\nIgnore problem and continue without "
01681              "saving or cancel save?" ).arg( (*it)->resourceName() ),
01682         i18n("Save Error"), KStdGuiItem::dontSave() );
01683       if ( result == KMessageBox::Cancel ) return false;
01684     }
01685   }
01686   return true;
01687 }
01688 
01689 void ActionManager::importCalendar( const KURL &url )
01690 {
01691   if ( !url.isValid() ) {
01692     KMessageBox::error( dialogParent(),
01693                         i18n("URL '%1' is invalid.").arg( url.prettyURL() ) );
01694     return;
01695   }
01696 
01697   ImportDialog *dialog;
01698   dialog = new ImportDialog( url, mMainWindow->topLevelWidget() );
01699   connect( dialog, SIGNAL( dialogFinished( ImportDialog * ) ),
01700            SLOT( slotImportDialogFinished( ImportDialog * ) ) );
01701   connect( dialog, SIGNAL( openURL( const KURL &, bool ) ),
01702            SLOT( openURL( const KURL &, bool ) ) );
01703   connect( dialog, SIGNAL( newWindow( const KURL & ) ),
01704            SIGNAL( actionNew( const KURL & ) ) );
01705   connect( dialog, SIGNAL( addResource( const KURL & ) ),
01706            SLOT( addResource( const KURL & ) ) );
01707 
01708   dialog->show();
01709 }
01710 
01711 void ActionManager::slotImportDialogFinished( ImportDialog *dlg )
01712 {
01713   dlg->deleteLater();
01714   mCalendarView->updateView();
01715 }
01716 
01717 void ActionManager::slotAutoArchivingSettingsModified()
01718 {
01719   if ( KOPrefs::instance()->mAutoArchive )
01720     mAutoArchiveTimer->start( 4 * 60 * 60 * 1000, true ); // check again in 4 hours
01721   else
01722     mAutoArchiveTimer->stop();
01723 }
01724 
01725 void ActionManager::slotAutoArchive()
01726 {
01727   if ( !mCalendarView->calendar() ) // can this happen?
01728     return;
01729   mAutoArchiveTimer->stop();
01730   EventArchiver archiver;
01731   connect( &archiver, SIGNAL( eventsDeleted() ), mCalendarView, SLOT( updateView() ) );
01732   archiver.runAuto( mCalendarView->calendar(), mCalendarView, false /*no gui*/ );
01733   // restart timer with the correct delay ( especially useful for the first time )
01734   slotAutoArchivingSettingsModified();
01735 }
01736 
01737 QWidget *ActionManager::dialogParent()
01738 {
01739   return mCalendarView->topLevelWidget();
01740 }
01741 
01742 #include "actionmanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys