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