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 *,const QDate & ) ),
00157            this, SLOT( processIncidenceSelection( Incidence *,const QDate & ) ) );
00158   connect( mCalendarView, SIGNAL( exportHTML( HTMLExportSettings * ) ),
00159            this, SLOT( exportHTML( HTMLExportSettings * ) ) );
00160 
00161   processIncidenceSelection( 0, QDate() );
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( resourcesChanged() ) );
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   kdDebug()<<" settings->outputFile() :"<<settings->outputFile()<<endl;
01059   if ( QFileInfo( settings->outputFile() ).exists() ) {
01060     if(KMessageBox::questionYesNo( dialogParent(), i18n("Do you want to overwrite file \"%1\"").arg( settings->outputFile()) ) == KMessageBox::No)
01061       return;
01062   }
01063   settings->setEMail( KOPrefs::instance()->email() );
01064   settings->setName( KOPrefs::instance()->fullName() );
01065 
01066   settings->setCreditName( "KOrganizer" );
01067   settings->setCreditURL( "http://korganizer.kde.org" );
01068 
01069   KCal::HtmlExport mExport( mCalendarView->calendar(), settings );
01070 
01071   QDate cdate = settings->dateStart().date();
01072   QDate qd2 = settings->dateEnd().date();
01073   while ( cdate <= qd2 ) {
01074     QStringList holidays = KOGlobals::self()->holiday( cdate );
01075     if ( !holidays.isEmpty() ) {
01076       QStringList::ConstIterator it = holidays.begin();
01077       for ( ; it != holidays.end(); ++it ) {
01078         mExport.addHoliday( cdate, *it );
01079       }
01080     }
01081     cdate = cdate.addDays( 1 );
01082   }
01083 
01084   KURL dest( settings->outputFile() );
01085   if ( dest.isLocalFile() ) {
01086     mExport.save( dest.path() );
01087   } else {
01088     KTempFile tf;
01089     QString tfile = tf.name();
01090     tf.close();
01091     mExport.save( tfile );
01092     if ( !KIO::NetAccess::upload( tfile, dest, view() ) ) {
01093       KNotifyClient::event ( view()->winId(),
01094                             i18n("Could not upload file.") );
01095     }
01096     tf.unlink();
01097   }
01098 }
01099 
01100 bool ActionManager::saveAsURL( const KURL &url )
01101 {
01102   kdDebug(5850) << "ActionManager::saveAsURL() " << url.prettyURL() << endl;
01103 
01104   if ( url.isEmpty() ) {
01105     kdDebug(5850) << "ActionManager::saveAsURL(): Empty URL." << endl;
01106     return false;
01107   }
01108   if ( !url.isValid() ) {
01109     kdDebug(5850) << "ActionManager::saveAsURL(): Malformed URL." << endl;
01110     return false;
01111   }
01112 
01113   QString fileOrig = mFile;
01114   KURL URLOrig = mURL;
01115 
01116   KTempFile *tempFile = 0;
01117   if ( url.isLocalFile() ) {
01118     mFile = url.path();
01119   } else {
01120     tempFile = new KTempFile;
01121     mFile = tempFile->name();
01122   }
01123   mURL = url;
01124 
01125   bool success = saveURL(); // Save local file and upload local file
01126   if ( success ) {
01127     delete mTempFile;
01128     mTempFile = tempFile;
01129     KIO::NetAccess::removeTempFile( fileOrig );
01130     KConfig *config = KOGlobals::self()->config();
01131     config->setGroup( "General" );
01132     setTitle();
01133     if ( mRecent ) mRecent->addURL( mURL );
01134   } else {
01135     KMessageBox::sorry( dialogParent(), i18n("Unable to save calendar to the file %1.").arg( mFile ), i18n("Error") );
01136     kdDebug(5850) << "ActionManager::saveAsURL() failed" << endl;
01137     mURL = URLOrig;
01138     mFile = fileOrig;
01139     delete tempFile;
01140   }
01141 
01142   return success;
01143 }
01144 
01145 
01146 bool ActionManager::saveModifiedURL()
01147 {
01148   kdDebug(5850) << "ActionManager::saveModifiedURL()" << endl;
01149 
01150   // If calendar isn't modified do nothing.
01151   if ( !mCalendarView->isModified() ) return true;
01152 
01153   mHtmlExportSync = true;
01154   if ( KOPrefs::instance()->mAutoSave && !mURL.isEmpty() ) {
01155     // Save automatically, when auto save is enabled.
01156     return saveURL();
01157   } else {
01158     int result = KMessageBox::warningYesNoCancel(
01159         dialogParent(),
01160         i18n("The calendar has been modified.\nDo you want to save it?"),
01161         QString::null,
01162         KStdGuiItem::save(), KStdGuiItem::discard() );
01163     switch( result ) {
01164       case KMessageBox::Yes:
01165         if ( mURL.isEmpty() ) {
01166           KURL url = getSaveURL();
01167           return saveAsURL( url );
01168         } else {
01169           return saveURL();
01170         }
01171       case KMessageBox::No:
01172         return true;
01173       case KMessageBox::Cancel:
01174       default:
01175         {
01176           mHtmlExportSync = false;
01177           return false;
01178         }
01179     }
01180   }
01181 }
01182 
01183 
01184 KURL ActionManager::getSaveURL()
01185 {
01186   KURL url = KFileDialog::getSaveURL( locateLocal( "data","korganizer/" ),
01187                                      i18n("*.vcs *.ics|Calendar Files"),
01188                                      dialogParent() );
01189 
01190   if ( url.isEmpty() ) return url;
01191 
01192   QString filename = url.fileName( false );
01193 
01194   QString e = filename.right( 4 );
01195   if ( e != ".vcs" && e != ".ics" ) {
01196     // Default save format is iCalendar
01197     filename += ".ics";
01198   }
01199 
01200   url.setFileName( filename );
01201 
01202   kdDebug(5850) << "ActionManager::getSaveURL(): url: " << url.url() << endl;
01203 
01204   return url;
01205 }
01206 
01207 void ActionManager::saveProperties( KConfig *config )
01208 {
01209   kdDebug(5850) << "ActionManager::saveProperties" << endl;
01210 
01211   config->writeEntry( "UseResourceCalendar", !mMainWindow->hasDocument() );
01212   if ( mMainWindow->hasDocument() ) {
01213     config->writePathEntry( "Calendar",mURL.url() );
01214   }
01215 }
01216 
01217 void ActionManager::readProperties( KConfig *config )
01218 {
01219   kdDebug(5850) << "ActionManager::readProperties" << endl;
01220 
01221   bool isResourceCalendar(
01222     config->readBoolEntry( "UseResourceCalendar", true ) );
01223   QString calendarUrl = config->readPathEntry( "Calendar" );
01224 
01225   if ( !isResourceCalendar && !calendarUrl.isEmpty() ) {
01226     mMainWindow->init( true );
01227     KURL u( calendarUrl );
01228     openURL( u );
01229   } else {
01230     mMainWindow->init( false );
01231   }
01232 }
01233 
01234 void ActionManager::checkAutoSave()
01235 {
01236   kdDebug(5850) << "ActionManager::checkAutoSave()" << endl;
01237 
01238   // Don't save if auto save interval is zero
01239   if ( KOPrefs::instance()->mAutoSaveInterval == 0 ) return;
01240 
01241   // has this calendar been saved before? If yes automatically save it.
01242   if ( KOPrefs::instance()->mAutoSave ) {
01243     if ( mCalendarResources || ( mCalendar && !url().isEmpty() ) ) {
01244       saveCalendar();
01245     }
01246   }
01247 }
01248 
01249 
01250 // Configuration changed as a result of the options dialog.
01251 void ActionManager::updateConfig()
01252 {
01253   kdDebug(5850) << "ActionManager::updateConfig()" << endl;
01254 
01255   if ( KOPrefs::instance()->mAutoSave && !mAutoSaveTimer->isActive() ) {
01256     checkAutoSave();
01257     if ( KOPrefs::instance()->mAutoSaveInterval > 0 ) {
01258       mAutoSaveTimer->start( 1000 * 60 *
01259                              KOPrefs::instance()->mAutoSaveInterval );
01260     }
01261   }
01262   if ( !KOPrefs::instance()->mAutoSave ) mAutoSaveTimer->stop();
01263   mNextXDays->setText( i18n( "&Next Day", "&Next %n Days",
01264                              KOPrefs::instance()->mNextXDays ) );
01265 
01266   KOCore::self()->reloadPlugins();
01267   mParts = KOCore::self()->reloadParts( mMainWindow, mParts );
01268 
01269   setDestinationPolicy();
01270 
01271   if ( mResourceView )
01272     mResourceView->updateView();
01273 
01274   KOGroupware::instance()->freeBusyManager()->setBrokenUrl( false );
01275 }
01276 
01277 void ActionManager::setDestinationPolicy()
01278 {
01279   if ( mCalendarResources ) {
01280     if ( KOPrefs::instance()->mDestination == KOPrefs::askDestination )
01281       mCalendarResources->setAskDestinationPolicy();
01282     else
01283       mCalendarResources->setStandardDestinationPolicy();
01284   }
01285 }
01286 
01287 void ActionManager::configureDateTime()
01288 {
01289   KProcess *proc = new KProcess;
01290   *proc << "kcmshell" << "language";
01291 
01292   connect( proc,SIGNAL( processExited( KProcess * ) ),
01293           SLOT( configureDateTimeFinished( KProcess * ) ) );
01294 
01295   if ( !proc->start() ) {
01296       KMessageBox::sorry( dialogParent(),
01297         i18n("Could not start control module for date and time format.") );
01298       delete proc;
01299   }
01300 }
01301 
01302 void ActionManager::showTip()
01303 {
01304   KTipDialog::showTip( dialogParent(),QString::null,true );
01305 }
01306 
01307 void ActionManager::showTipOnStart()
01308 {
01309   KTipDialog::showTip( dialogParent() );
01310 }
01311 
01312 KOrg::MainWindow *ActionManager::findInstance( const KURL &url )
01313 {
01314   if ( mWindowList ) {
01315     if ( url.isEmpty() ) return mWindowList->defaultInstance();
01316     else return mWindowList->findInstance( url );
01317   } else {
01318     return 0;
01319   }
01320 }
01321 
01322 void ActionManager::dumpText( const QString &str )
01323 {
01324   kdDebug(5850) << "ActionManager::dumpText(): " << str << endl;
01325 }
01326 
01327 void ActionManager::toggleDateNavigator()
01328 {
01329   bool visible = mDateNavigatorShowAction->isChecked();
01330   if ( mCalendarView ) mCalendarView->showDateNavigator( visible );
01331 }
01332 
01333 void ActionManager::toggleTodoView()
01334 {
01335   bool visible = mTodoViewShowAction->isChecked();
01336   if ( mCalendarView ) mCalendarView->showTodoView( visible );
01337 }
01338 
01339 void ActionManager::toggleEventViewer()
01340 {
01341   bool visible = mEventViewerShowAction->isChecked();
01342   if ( mCalendarView ) mCalendarView->showEventViewer( visible );
01343 }
01344 
01345 void ActionManager::toggleResourceView()
01346 {
01347   bool visible = mResourceViewShowAction->isChecked();
01348   kdDebug(5850) << "toggleResourceView: " << endl;
01349   if ( mResourceView ) {
01350     if ( visible ) mResourceView->show();
01351     else mResourceView->hide();
01352   }
01353 }
01354 
01355 void ActionManager::toggleResourceButtons()
01356 {
01357   bool visible = mResourceButtonsAction->isChecked();
01358 
01359   kdDebug(5850) << "RESOURCE VIEW " << long( mResourceView ) << endl;
01360 
01361   if ( mResourceView ) mResourceView->showButtons( visible );
01362 }
01363 
01364 bool ActionManager::openURL( const QString &url )
01365 {
01366   return openURL( KURL( url ) );
01367 }
01368 
01369 bool ActionManager::mergeURL( const QString &url )
01370 {
01371   return openURL( KURL( url ),true );
01372 }
01373 
01374 bool ActionManager::saveAsURL( const QString &url )
01375 {
01376   return saveAsURL( KURL( url ) );
01377 }
01378 
01379 QString ActionManager::getCurrentURLasString() const
01380 {
01381   return mURL.url();
01382 }
01383 
01384 bool ActionManager::editIncidence( const QString& uid )
01385 {
01386   return mCalendarView->editIncidence( uid );
01387 }
01388 
01389 bool ActionManager::deleteIncidence( const QString& uid, bool force )
01390 {
01391   return mCalendarView->deleteIncidence( uid, force );
01392 }
01393 
01394 bool ActionManager::addIncidence( const QString& ical )
01395 {
01396   return mCalendarView->addIncidence( ical );
01397 }
01398 
01399 void ActionManager::configureDateTimeFinished( KProcess *proc )
01400 {
01401   delete proc;
01402 }
01403 
01404 void ActionManager::downloadNewStuff()
01405 {
01406   kdDebug(5850) << "ActionManager::downloadNewStuff()" << endl;
01407 
01408   if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
01409   mNewStuff->download();
01410 }
01411 
01412 void ActionManager::uploadNewStuff()
01413 {
01414   if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
01415   mNewStuff->upload();
01416 }
01417 
01418 QString ActionManager::localFileName()
01419 {
01420   return mFile;
01421 }
01422 
01423 class ActionManager::ActionStringsVisitor : public IncidenceBase::Visitor
01424 {
01425   public:
01426     ActionStringsVisitor() : mShow( 0 ), mEdit( 0 ), mDelete( 0 ) {}
01427 
01428     bool act( IncidenceBase *incidence, KAction *show, KAction *edit, KAction *del )
01429     {
01430       mShow = show;
01431       mEdit = edit;
01432       mDelete = del;
01433       return incidence->accept( *this );
01434     }
01435 
01436   protected:
01437     bool visit( Event * ) {
01438       if ( mShow ) mShow->setText( i18n("&Show Event") );
01439       if ( mEdit ) mEdit->setText( i18n("&Edit Event...") );
01440       if ( mDelete ) mDelete->setText( i18n("&Delete Event") );
01441       return true;
01442     }
01443     bool visit( Todo * ) {
01444       if ( mShow ) mShow->setText( i18n("&Show To-do") );
01445       if ( mEdit ) mEdit->setText( i18n("&Edit To-do...") );
01446       if ( mDelete ) mDelete->setText( i18n("&Delete To-do") );
01447       return true;
01448     }
01449     bool visit( Journal * ) { return assignDefaultStrings(); }
01450   protected:
01451     bool assignDefaultStrings() {
01452       if ( mShow ) mShow->setText( i18n("&Show") );
01453       if ( mEdit ) mEdit->setText( i18n("&Edit...") );
01454       if ( mDelete ) mDelete->setText( i18n("&Delete") );
01455       return true;
01456     }
01457     KAction *mShow;
01458     KAction *mEdit;
01459     KAction *mDelete;
01460 };
01461 
01462 void ActionManager::processIncidenceSelection( Incidence *incidence, const QDate & )
01463 {
01464 //  kdDebug(5850) << "ActionManager::processIncidenceSelection()" << endl;
01465 
01466   if ( !incidence ) {
01467     enableIncidenceActions( false );
01468     return;
01469   }
01470 
01471   enableIncidenceActions( true );
01472 
01473   if ( incidence->isReadOnly() ) {
01474     mCutAction->setEnabled( false );
01475     mDeleteAction->setEnabled( false );
01476   }
01477 
01478   ActionStringsVisitor v;
01479   if ( !v.act( incidence, mShowIncidenceAction, mEditIncidenceAction, mDeleteIncidenceAction ) ) {
01480     mShowIncidenceAction->setText( i18n("&Show") );
01481     mEditIncidenceAction->setText( i18n("&Edit...") );
01482     mDeleteIncidenceAction->setText( i18n("&Delete") );
01483   }
01484 }
01485 
01486 void ActionManager::enableIncidenceActions( bool enabled )
01487 {
01488   mShowIncidenceAction->setEnabled( enabled );
01489   mEditIncidenceAction->setEnabled( enabled );
01490   mDeleteIncidenceAction->setEnabled( enabled );
01491 //   mAssignResourceAction->setEnabled( enabled );
01492 
01493   mCutAction->setEnabled( enabled );
01494   mCopyAction->setEnabled( enabled );
01495   mDeleteAction->setEnabled( enabled );
01496   mPublishEvent->setEnabled( enabled );
01497   mForwardEvent->setEnabled( enabled );
01498 }
01499 
01500 void ActionManager::keyBindings()
01501 {
01502   KKeyDialog dlg( false, view() );
01503   if ( mMainWindow )
01504     dlg.insert( mMainWindow->getActionCollection() );
01505 
01506   KOrg::Part *part;
01507   for ( part = mParts.first(); part; part = mParts.next() ) {
01508     dlg.insert( part->actionCollection(), part->shortInfo() );
01509   }
01510   dlg.configure();
01511 }
01512 
01513 void ActionManager::loadParts()
01514 {
01515   mParts = KOCore::self()->loadParts( mMainWindow );
01516 }
01517 
01518 void ActionManager::setTitle()
01519 {
01520   mMainWindow->setTitle();
01521 }
01522 
01523 KCalendarIface::ResourceRequestReply ActionManager::resourceRequest( const QValueList<QPair<QDateTime, QDateTime> >&,
01524  const QCString& resource,
01525  const QString& vCalIn )
01526 {
01527     kdDebug(5850) << k_funcinfo << "resource=" << resource << " vCalIn=" << vCalIn << endl;
01528     KCalendarIface::ResourceRequestReply reply;
01529     reply.vCalOut = "VCalOut";
01530     return reply;
01531 }
01532 
01533 void ActionManager::openEventEditor( const QString& text )
01534 {
01535   mCalendarView->newEvent( text );
01536 }
01537 
01538 void ActionManager::openEventEditor( const QString& summary,
01539                                      const QString& description,
01540                                      const QString& attachment )
01541 {
01542   mCalendarView->newEvent( summary, description, attachment );
01543 }
01544 
01545 void ActionManager::openEventEditor( const QString& summary,
01546                                      const QString& description,
01547                                      const QString& attachment,
01548                                      const QStringList& attendees )
01549 {
01550   mCalendarView->newEvent( summary, description, attachment, attendees );
01551 }
01552 
01553 void ActionManager::openEventEditor( const QString & summary,
01554                                      const QString & description,
01555                                      const QString & uri,
01556                                      const QString & file,
01557                                      const QStringList & attendees,
01558                                      const QString & attachmentMimetype )
01559 {
01560   int action = KOPrefs::instance()->defaultEmailAttachMethod();
01561   if ( attachmentMimetype != "message/rfc822" ) {
01562     action = KOPrefs::Link;
01563   } else if ( KOPrefs::instance()->defaultEmailAttachMethod() == KOPrefs::Ask ) {
01564     KPopupMenu *menu = new KPopupMenu( 0 );
01565     menu->insertItem( i18n("Attach as &link"), KOPrefs::Link );
01566     menu->insertItem( i18n("Attach &inline"), KOPrefs::InlineFull );
01567     menu->insertItem( i18n("Attach inline &without attachments"), KOPrefs::InlineBody );
01568     menu->insertSeparator();
01569     menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::Ask );
01570     action = menu->exec( QCursor::pos(), 0 );
01571     delete menu;
01572   }
01573 
01574   QString attData;
01575   KTempFile tf;
01576   tf.setAutoDelete( true );
01577   switch ( action ) {
01578     case KOPrefs::Ask:
01579       return;
01580     case KOPrefs::Link:
01581       attData = uri;
01582       break;
01583     case KOPrefs::InlineFull:
01584       attData = file;
01585       break;
01586     case KOPrefs::InlineBody:
01587     {
01588       QFile f( file );
01589       if ( !f.open( IO_ReadOnly ) )
01590         return;
01591       KMime::Message *msg = new KMime::Message();
01592       msg->setContent( QCString( f.readAll() ) );
01593       QCString head = msg->head();
01594       msg->parse();
01595       if ( msg == msg->textContent() || msg->textContent() == 0 ) { // no attachments
01596         attData = file;
01597       } else {
01598         if ( KMessageBox::warningContinueCancel( 0,
01599               i18n("Removing attachments from an email might invalidate its signature."),
01600               i18n("Remove Attachments"), KStdGuiItem::cont(), "BodyOnlyInlineAttachment" )
01601               != KMessageBox::Continue )
01602           return;
01603         // due to kmime shortcomings in KDE3, we need to assemble the result manually
01604         int begin = 0;
01605         int end = head.find( '\n' );
01606         bool skipFolded = false;
01607         while ( end >= 0 && end > begin ) {
01608           if ( head.find( "Content-Type:", begin, false ) != begin &&
01609                 head.find( "Content-Transfer-Encoding:", begin, false ) != begin &&
01610                 !(skipFolded && (head[begin] == ' ' || head[end] == '\t')) ) {
01611             QCString line = head.mid( begin, end - begin );
01612             tf.file()->writeBlock( line.data(), line.length() );
01613             tf.file()->writeBlock( "\n", 1 );
01614             skipFolded = false;
01615           } else {
01616             skipFolded = true;
01617           }
01618 
01619           begin = end + 1;
01620           end = head.find( '\n', begin );
01621           if ( end < 0 && begin < (int)head.length() )
01622             end = head.length() - 1;
01623         }
01624         QCString cte = msg->textContent()->contentTransferEncoding()->as7BitString();
01625         if ( !cte.stripWhiteSpace().isEmpty() ) {
01626           tf.file()->writeBlock( cte.data(), cte.length() );
01627           tf.file()->writeBlock( "\n", 1 );
01628         }
01629         QCString ct = msg->textContent()->contentType()->as7BitString();
01630         if ( !ct.stripWhiteSpace().isEmpty() )
01631           tf.file()->writeBlock( ct.data(), ct.length() );
01632         tf.file()->writeBlock( "\n", 1 );
01633         tf.file()->writeBlock( msg->textContent()->body() );
01634         attData = tf.name();
01635       }
01636       tf.close();
01637       delete msg;
01638       break;
01639     }
01640     default:
01641       // menu could have been closed by cancel, if so, do nothing
01642       return;
01643   }
01644 
01645   mCalendarView->newEvent( summary, description, attData, attendees, attachmentMimetype, action != KOPrefs::Link );
01646 }
01647 
01648 void ActionManager::openTodoEditor( const QString& text )
01649 {
01650   mCalendarView->newTodo( text );
01651 }
01652 
01653 void ActionManager::openTodoEditor( const QString& summary,
01654                                     const QString& description,
01655                                     const QString& attachment )
01656 {
01657   mCalendarView->newTodo( summary, description, attachment );
01658 }
01659 
01660 void ActionManager::openTodoEditor( const QString& summary,
01661                                     const QString& description,
01662                                     const QString& attachment,
01663                                     const QStringList& attendees )
01664 {
01665   mCalendarView->newTodo( summary, description, attachment, attendees );
01666 }
01667 
01668 void ActionManager::openTodoEditor(const QString & summary,
01669                                    const QString & description,
01670                                    const QString & uri,
01671                                    const QString & file,
01672                                    const QStringList & attendees,
01673                                    const QString & attachmentMimetype,
01674                                    bool isTask )
01675 {
01676   int action = KOPrefs::instance()->defaultTodoAttachMethod();
01677   if ( attachmentMimetype != "message/rfc822" ) {
01678     action = KOPrefs::TodoAttachLink;
01679   } else if ( KOPrefs::instance()->defaultTodoAttachMethod() == KOPrefs::TodoAttachAsk ) {
01680     KPopupMenu *menu = new KPopupMenu( 0 );
01681     menu->insertItem( i18n("Attach as &link"), KOPrefs::TodoAttachLink );
01682     menu->insertItem( i18n("Attach &inline"), KOPrefs::TodoAttachInlineFull );
01683     menu->insertSeparator();
01684     menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::TodoAttachAsk );
01685     action = menu->exec( QCursor::pos(), 0 );
01686     delete menu;
01687   }
01688 
01689   QStringList attData;
01690   switch ( action ) {
01691     case KOPrefs::TodoAttachAsk:
01692       return;
01693     case KOPrefs::TodoAttachLink:
01694       attData << uri;
01695       break;
01696   case KOPrefs::TodoAttachInlineFull:
01697       attData << file;
01698       break;
01699     default:
01700       // menu could have been closed by cancel, if so, do nothing
01701       return;
01702   }
01703 
01704   mCalendarView->newTodo( summary, description,
01705                           attData, attendees,
01706                           QStringList( attachmentMimetype ),
01707                           action != KOPrefs::TodoAttachLink,
01708                           isTask );
01709 }
01710 
01711 void ActionManager::openJournalEditor( const QDate& date )
01712 {
01713   mCalendarView->newJournal( date );
01714 }
01715 
01716 void ActionManager::openJournalEditor( const QString& text, const QDate& date )
01717 {
01718   mCalendarView->newJournal( text, date );
01719 }
01720 
01721 void ActionManager::openJournalEditor( const QString& text )
01722 {
01723   mCalendarView->newJournal( text );
01724 }
01725 
01726 //TODO:
01727 // void ActionManager::openJournalEditor( const QString& summary,
01728 //                                        const QString& description,
01729 //                                        const QString& attachment )
01730 // {
01731 //   mCalendarView->newJournal( summary, description, attachment );
01732 // }
01733 
01734 
01735 void ActionManager::showJournalView()
01736 {
01737   mCalendarView->viewManager()->showJournalView();
01738 }
01739 
01740 void ActionManager::showTodoView()
01741 {
01742   mCalendarView->viewManager()->showTodoView();
01743 }
01744 
01745 void ActionManager::showEventView()
01746 {
01747   mCalendarView->viewManager()->showEventView();
01748 }
01749 
01750 void ActionManager::goDate( const QDate& date )
01751 {
01752   mCalendarView->goDate( date );
01753 }
01754 
01755 void ActionManager::goDate( const QString& date )
01756 {
01757   goDate( KGlobal::locale()->readDate( date ) );
01758 }
01759 
01760 void ActionManager::showDate(const QDate & date)
01761 {
01762   mCalendarView->showDate( date );
01763 }
01764 
01765 
01766 void ActionManager::updateUndoAction( const QString &text )
01767 {
01768   if ( text.isNull() ) {
01769     mUndoAction->setEnabled( false );
01770     mUndoAction->setText( i18n("Undo") );
01771   } else {
01772     mUndoAction->setEnabled( true );
01773     if ( text.isEmpty() ) mUndoAction->setText( i18n("Undo") );
01774     else mUndoAction->setText( i18n("Undo (%1)").arg( text ) );
01775   }
01776 }
01777 
01778 void ActionManager::updateRedoAction( const QString &text )
01779 {
01780   if ( text.isNull() ) {
01781     mRedoAction->setEnabled( false );
01782     mRedoAction->setText( i18n( "Redo" ) );
01783   } else {
01784     mRedoAction->setEnabled( true );
01785     if ( text.isEmpty() ) mRedoAction->setText( i18n("Redo") );
01786     else mRedoAction->setText( i18n( "Redo (%1)" ).arg( text ) );
01787   }
01788 }
01789 
01790 bool ActionManager::queryClose()
01791 {
01792   kdDebug(5850) << "ActionManager::queryClose()" << endl;
01793 
01794   bool close = true;
01795 
01796   if ( mCalendar && mCalendar->isModified() ) {
01797     int res = KMessageBox::questionYesNoCancel( dialogParent(),
01798       i18n("The calendar contains unsaved changes. Do you want to save them before exiting?"), QString::null, KStdGuiItem::save(), KStdGuiItem::discard() );
01799     // Exit on yes and no, don't exit on cancel. If saving fails, ask for exiting.
01800     if ( res == KMessageBox::Yes ) {
01801       close = saveModifiedURL();
01802       if ( !close ) {
01803         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() );
01804         close = ( res1 == KMessageBox::Yes );
01805       }
01806     } else {
01807       close = ( res == KMessageBox::No );
01808     }
01809   } else if ( mCalendarResources ) {
01810     if ( !mIsClosing ) {
01811       kdDebug(5850) << "!mIsClosing" << endl;
01812       if ( !saveResourceCalendar() ) return false;
01813 
01814       // FIXME: Put main window into a state indicating final saving.
01815       mIsClosing = true;
01816 // FIXME: Close main window when save is finished
01817 //      connect( mCalendarResources, SIGNAL( calendarSaved() ),
01818 //               mMainWindow, SLOT( close() ) );
01819     }
01820     if ( mCalendarResources->isSaving() ) {
01821       kdDebug(5850) << "ActionManager::queryClose(): isSaving" << endl;
01822       close = false;
01823       KMessageBox::information( dialogParent(),
01824           i18n("Unable to exit. Saving still in progress.") );
01825     } else {
01826       kdDebug(5850) << "ActionManager::queryClose(): close = true" << endl;
01827       close = true;
01828     }
01829   } else {
01830     close = true;
01831   }
01832 
01833   return close;
01834 }
01835 
01836 void ActionManager::saveCalendar()
01837 {
01838   if ( mCalendar ) {
01839     if ( view()->isModified() ) {
01840       if ( !url().isEmpty() ) {
01841         saveURL();
01842       } else {
01843         QString location = locateLocal( "data", "korganizer/kontact.ics" );
01844         saveAsURL( location );
01845       }
01846     }
01847   } else if ( mCalendarResources ) {
01848     mCalendarResources->save();
01849     // FIXME: Make sure that asynchronous saves don't fail.
01850   }
01851 }
01852 
01853 bool ActionManager::saveResourceCalendar()
01854 {
01855   if ( !mCalendarResources ) return false;
01856   CalendarResourceManager *m = mCalendarResources->resourceManager();
01857 
01858   CalendarResourceManager::ActiveIterator it;
01859   for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
01860     if ( (*it)->readOnly() ) continue;
01861     if ( !(*it)->save() ) {
01862       int result = KMessageBox::warningContinueCancel( view(),
01863         i18n( "Saving of '%1' failed. Check that the resource is "
01864              "properly configured.\nIgnore problem and continue without "
01865              "saving or cancel save?" ).arg( (*it)->resourceName() ),
01866         i18n("Save Error"), KStdGuiItem::dontSave() );
01867       if ( result == KMessageBox::Cancel ) return false;
01868     }
01869   }
01870   return true;
01871 }
01872 
01873 void ActionManager::importCalendar( const KURL &url )
01874 {
01875   if ( !url.isValid() ) {
01876     KMessageBox::error( dialogParent(),
01877                         i18n("URL '%1' is invalid.").arg( url.prettyURL() ) );
01878     return;
01879   }
01880 
01881   ImportDialog *dialog;
01882   dialog = new ImportDialog( url, mMainWindow->topLevelWidget() );
01883   connect( dialog, SIGNAL( dialogFinished( ImportDialog * ) ),
01884            SLOT( slotImportDialogFinished( ImportDialog * ) ) );
01885   connect( dialog, SIGNAL( openURL( const KURL &, bool ) ),
01886            SLOT( openURL( const KURL &, bool ) ) );
01887   connect( dialog, SIGNAL( newWindow( const KURL & ) ),
01888            SIGNAL( actionNew( const KURL & ) ) );
01889   connect( dialog, SIGNAL( addResource( const KURL & ) ),
01890            SLOT( addResource( const KURL & ) ) );
01891 
01892   dialog->show();
01893 }
01894 
01895 void ActionManager::slotImportDialogFinished( ImportDialog *dlg )
01896 {
01897   dlg->deleteLater();
01898   mCalendarView->updateView();
01899 }
01900 
01901 void ActionManager::slotAutoArchivingSettingsModified()
01902 {
01903   if ( KOPrefs::instance()->mAutoArchive )
01904     mAutoArchiveTimer->start( 4 * 60 * 60 * 1000, true ); // check again in 4 hours
01905   else
01906     mAutoArchiveTimer->stop();
01907 }
01908 
01909 void ActionManager::slotAutoArchive()
01910 {
01911   if ( !mCalendarView->calendar() ) // can this happen?
01912     return;
01913   mAutoArchiveTimer->stop();
01914   EventArchiver archiver;
01915   connect( &archiver, SIGNAL( eventsDeleted() ), mCalendarView, SLOT( updateView() ) );
01916   archiver.runAuto( mCalendarView->calendar(), mCalendarView, false /*no gui*/ );
01917   // restart timer with the correct delay ( especially useful for the first time )
01918   slotAutoArchivingSettingsModified();
01919 }
01920 
01921 void ActionManager::loadProfile( const QString & path )
01922 {
01923   KOPrefs::instance()->writeConfig();
01924   KConfig* const cfg = KOPrefs::instance()->config();
01925 
01926   const KConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
01927   const QStringList groups = profile.groupList();
01928   for ( QStringList::ConstIterator it = groups.begin(), end = groups.end(); it != end; ++it )
01929   {
01930     cfg->setGroup( *it );
01931     typedef QMap<QString, QString> StringMap;
01932     const StringMap entries = profile.entryMap( *it );
01933     for ( StringMap::ConstIterator it2 = entries.begin(), end = entries.end(); it2 != end; ++it2 )
01934     {
01935       cfg->writeEntry( it2.key(), it2.data() );
01936     }
01937   }
01938 
01939   cfg->sync();
01940   KOPrefs::instance()->readConfig();
01941 }
01942 
01943 namespace {
01944     void copyConfigEntry( KConfig* source, KConfig* dest, const QString& group, const QString& key, const QString& defaultValue=QString() )
01945     {
01946         source->setGroup( group );
01947         dest->setGroup( group );
01948         dest->writeEntry( key, source->readEntry( key, defaultValue ) );
01949     }
01950 }
01951 
01952 void ActionManager::saveToProfile( const QString & path ) const
01953 {
01954   KOPrefs::instance()->writeConfig();
01955   KConfig* const cfg = KOPrefs::instance()->config();
01956 
01957   KConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
01958   ::copyConfigEntry( cfg, &profile, "Views", "Agenda View Calendar Display" );
01959 }
01960 
01961 QWidget *ActionManager::dialogParent()
01962 {
01963   return mCalendarView->topLevelWidget();
01964 }
01965 
01966 #include "actionmanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys