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/Event (ICS-/VCS-File)..."), 0, this, SLOT( file_merge() ),
00254                mACollection, "import_icalendar" );
00255   new KAction( i18n("&Import From UNIX Ical tool (.calendar-File)"), 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   mSendInvitation = new KAction( i18n( "Send &Invitation to Attendees" ),
00502                                  "mail_generic", 0,
00503                                  mCalendarView, SLOT(schedule_request()),
00504                                  mACollection, "schedule_request" );
00505   mSendInvitation->setEnabled( false );
00506   connect( mCalendarView, SIGNAL(organizerEventsSelected(bool)),
00507            mSendInvitation, SLOT(setEnabled(bool)) );
00508 
00509   mRequestUpdate = new KAction( i18n( "Re&quest Update" ), 0,
00510                                 mCalendarView, SLOT(schedule_refresh()),
00511                                 mACollection, "schedule_refresh" );
00512   mRequestUpdate->setEnabled( false );
00513   connect( mCalendarView, SIGNAL(groupEventsSelected(bool)),
00514            mRequestUpdate, SLOT(setEnabled(bool)) );
00515 
00516   mSendCancel = new KAction( i18n( "Send &Cancelation to Attendees" ), 0,
00517                              mCalendarView, SLOT(schedule_cancel()),
00518                              mACollection, "schedule_cancel" );
00519   mSendCancel->setEnabled( false );
00520   connect( mCalendarView, SIGNAL(organizerEventsSelected(bool)),
00521            mSendCancel, SLOT(setEnabled(bool)) );
00522 
00523   mSendStatusUpdate = new KAction( i18n( "Send Status &Update" ),
00524                                    "mail_reply", 0,
00525                                    mCalendarView,SLOT(schedule_reply()),
00526                                    mACollection, "schedule_reply" );
00527   mSendStatusUpdate->setEnabled( false );
00528   connect( mCalendarView, SIGNAL(groupEventsSelected(bool)),
00529            mSendStatusUpdate, SLOT(setEnabled(bool)) );
00530 
00531   mRequestChange = new KAction( i18n( "counter proposal", "Request Chan&ge" ), 0,
00532                                 mCalendarView, SLOT(schedule_counter()),
00533                                 mACollection, "schedule_counter" );
00534   mRequestChange->setEnabled( false );
00535   connect( mCalendarView, SIGNAL(groupEventsSelected(bool)),
00536            mRequestChange, SLOT(setEnabled(bool)) );
00537 
00538   mForwardEvent = new KAction( i18n("&Send as iCalendar..."), "mail_forward", 0,
00539                                mCalendarView, SLOT(schedule_forward()),
00540                                mACollection, "schedule_forward" );
00541   mForwardEvent->setEnabled( false );
00542 
00543   action = new KAction( i18n("&Mail Free Busy Information..."), 0,
00544                         mCalendarView, SLOT( mailFreeBusy() ),
00545                         mACollection, "mail_freebusy" );
00546   action->setEnabled( true );
00547 
00548   action = new KAction( i18n("&Upload Free Busy Information"), 0,
00549                         mCalendarView, SLOT( uploadFreeBusy() ),
00550                         mACollection, "upload_freebusy" );
00551   action->setEnabled( true );
00552 
00553   if ( !mIsPart ) {
00554       action = new KAction( i18n("&Addressbook"),"contents",0,
00555                             mCalendarView,SLOT( openAddressbook() ),
00556                             mACollection,"addressbook" );
00557   }
00558 
00559 
00560 
00561 
00562   //************************** SETTINGS MENU ********************************
00563 
00564   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIDEBAR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00565   mDateNavigatorShowAction = new KToggleAction( i18n("Show Date Navigator"), 0,
00566                       this, SLOT( toggleDateNavigator() ),
00567                       mACollection, "show_datenavigator" );
00568   mTodoViewShowAction = new KToggleAction ( i18n("Show To-do View"), 0,
00569                       this, SLOT( toggleTodoView() ),
00570                       mACollection, "show_todoview" );
00571   mEventViewerShowAction = new KToggleAction ( i18n("Show Item Viewer"), 0,
00572                       this, SLOT( toggleEventViewer() ),
00573                       mACollection, "show_eventviewer" );
00574   KConfig *config = KOGlobals::self()->config();
00575   config->setGroup( "Settings" );
00576   mDateNavigatorShowAction->setChecked(
00577       config->readBoolEntry( "DateNavigatorVisible", true ) );
00578   // if we are a kpart, then let's not show the todo in the left pane by
00579   // default since there's also a Todo part and we'll assume they'll be
00580   // using that as well, so let's not duplicate it (by default) here
00581   mTodoViewShowAction->setChecked(
00582       config->readBoolEntry( "TodoViewVisible", mIsPart ? false : true ) );
00583   mEventViewerShowAction->setChecked(
00584       config->readBoolEntry( "EventViewerVisible", true ) );
00585   toggleDateNavigator();
00586   toggleTodoView();
00587   toggleEventViewer();
00588 
00589   if ( !mMainWindow->hasDocument() ) {
00590     mResourceViewShowAction = new KToggleAction ( i18n("Show Resource View"), 0,
00591                         this, SLOT( toggleResourceView() ),
00592                         mACollection, "show_resourceview" );
00593     mResourceButtonsAction = new KToggleAction( i18n("Show &Resource Buttons"), 0,
00594                         this, SLOT( toggleResourceButtons() ),
00595                         mACollection, "show_resourcebuttons" );
00596     mResourceViewShowAction->setChecked(
00597         config->readBoolEntry( "ResourceViewVisible", true ) );
00598     mResourceButtonsAction->setChecked(
00599         config->readBoolEntry( "ResourceButtonsVisible", true ) );
00600 
00601     toggleResourceView();
00602     toggleResourceButtons();
00603   }
00604 
00605 
00606   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIDEBAR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00607 
00608   new KAction( i18n("Configure &Date && Time..."), 0,
00609                     this, SLOT( configureDateTime() ),
00610                     mACollection, "conf_datetime" );
00611 // TODO: Add an item to show the resource management dlg
00612 //   new KAction( i18n("Manage &Resources..."), 0,
00613 //                     this, SLOT( manageResources() ),
00614 //                     mACollection, "conf_resources" );
00615   new KAction( i18n("Manage View &Filters..."), "configure", 0,
00616                mCalendarView, SLOT( editFilters() ),
00617                mACollection, "edit_filters" );
00618   new KAction( i18n("Manage C&ategories..."), 0,
00619                mCalendarView->dialogManager(), SLOT( showCategoryEditDialog() ),
00620                mACollection, "edit_categories" );
00621   if ( mIsPart ) {
00622     new KAction( i18n("&Configure Calendar..."), "configure", 0,
00623                  mCalendarView, SLOT( edit_options() ),
00624                  mACollection, "korganizer_configure" );
00625     KStdAction::keyBindings( this, SLOT( keyBindings() ),
00626                              mACollection, "korganizer_configure_shortcuts" );
00627   } else {
00628     KStdAction::preferences( mCalendarView, SLOT( edit_options() ),
00629                             mACollection );
00630     KStdAction::keyBindings( this, SLOT( keyBindings() ), mACollection );
00631   }
00632 
00633 
00634 
00635 
00636   //**************************** HELP MENU **********************************
00637   KStdAction::tipOfDay( this, SLOT( showTip() ), mACollection,
00638                         "help_tipofday" );
00639 //   new KAction( i18n("Show Intro Page"), 0,
00640 //                     mCalendarView,SLOT( showIntro() ),
00641 //                     mACollection,"show_intro" );
00642 
00643 
00644 
00645 
00646   //************************* TOOLBAR ACTIONS *******************************
00647   QLabel *filterLabel = new QLabel( i18n("Filter: "), mCalendarView );
00648   filterLabel->hide();
00649   new KWidgetAction( filterLabel, i18n("Filter: "), 0, 0, 0,
00650                      mACollection, "filter_label" );
00651 
00652 }
00653 
00654 void ActionManager::readSettings()
00655 {
00656   // read settings from the KConfig, supplying reasonable
00657   // defaults where none are to be found
00658 
00659   KConfig *config = KOGlobals::self()->config();
00660   if ( mRecent ) mRecent->loadEntries( config );
00661   mCalendarView->readSettings();
00662 }
00663 
00664 void ActionManager::writeSettings()
00665 {
00666   kdDebug(5850) << "ActionManager::writeSettings" << endl;
00667 
00668   KConfig *config = KOGlobals::self()->config();
00669   mCalendarView->writeSettings();
00670 
00671   config->setGroup( "Settings" );
00672   if ( mResourceButtonsAction ) {
00673     config->writeEntry( "ResourceButtonsVisible",
00674                         mResourceButtonsAction->isChecked() );
00675   }
00676   if ( mDateNavigatorShowAction ) {
00677     config->writeEntry( "DateNavigatorVisible",
00678                         mDateNavigatorShowAction->isChecked() );
00679   }
00680   if ( mTodoViewShowAction ) {
00681     config->writeEntry( "TodoViewVisible",
00682                         mTodoViewShowAction->isChecked() );
00683   }
00684   if ( mResourceViewShowAction ) {
00685     config->writeEntry( "ResourceViewVisible",
00686                         mResourceViewShowAction->isChecked() );
00687   }
00688   if ( mEventViewerShowAction ) {
00689     config->writeEntry( "EventViewerVisible",
00690                         mEventViewerShowAction->isChecked() );
00691   }
00692 
00693   if ( mRecent ) mRecent->saveEntries( config );
00694 
00695   config->sync();
00696 
00697   if ( mCalendarResources ) {
00698     mCalendarResources->resourceManager()->writeConfig();
00699   }
00700 }
00701 
00702 void ActionManager::file_new()
00703 {
00704   emit actionNew();
00705 }
00706 
00707 void ActionManager::file_open()
00708 {
00709   KURL url;
00710   QString defaultPath = locateLocal( "data","korganizer/" );
00711   url = KFileDialog::getOpenURL( defaultPath,i18n("*.vcs *.ics|Calendar Files"),
00712                                 dialogParent() );
00713 
00714   file_open( url );
00715 }
00716 
00717 void ActionManager::file_open( const KURL &url )
00718 {
00719   if ( url.isEmpty() ) return;
00720 
00721   // is that URL already opened somewhere else? Activate that window
00722   KOrg::MainWindow *korg=ActionManager::findInstance( url );
00723   if ( ( 0 != korg )&&( korg != mMainWindow ) ) {
00724     KWin::activateWindow( korg->topLevelWidget()->winId() );
00725     return;
00726   }
00727 
00728   kdDebug(5850) << "ActionManager::file_open(): " << url.prettyURL() << endl;
00729 
00730   // Open the calendar file in the same window only if we have an empty calendar window, and not the resource calendar
00731   if ( !mCalendarView->isModified() && mFile.isEmpty() && !mCalendarResources ) {
00732     openURL( url );
00733   } else {
00734     emit actionNew( url );
00735   }
00736 }
00737 
00738 void ActionManager::file_icalimport()
00739 {
00740   // FIXME: eventually, we will need a dialog box to select import type, etc.
00741   // for now, hard-coded to ical file, $HOME/.calendar.
00742   int retVal = -1;
00743   QString progPath;
00744   KTempFile tmpfn;
00745 
00746   QString homeDir = QDir::homeDirPath() + QString::fromLatin1( "/.calendar" );
00747 
00748   if ( !QFile::exists( homeDir ) ) {
00749     KMessageBox::error( dialogParent(),
00750                        i18n( "You have no .calendar file in your home directory.\n"
00751                             "Import cannot proceed.\n" ) );
00752     return;
00753   }
00754 
00755   KProcess proc;
00756   proc << "ical2vcal" << tmpfn.name();
00757   bool success = proc.start( KProcess::Block );
00758 
00759   if ( !success ) {
00760     kdDebug(5850) << "Error starting ical2vcal." << endl;
00761     return;
00762   } else {
00763     retVal = proc.exitStatus();
00764   }
00765 
00766   kdDebug(5850) << "ical2vcal return value: " << retVal << endl;
00767 
00768   if ( retVal >= 0 && retVal <= 2 ) {
00769     // now we need to MERGE what is in the iCal to the current calendar.
00770     mCalendarView->openCalendar( tmpfn.name(),1 );
00771     if ( !retVal )
00772       KMessageBox::information( dialogParent(),
00773                                i18n( "KOrganizer successfully imported and "
00774                                     "merged your .calendar file from ical "
00775                                     "into the currently opened calendar." ),
00776                                "dotCalendarImportSuccess" );
00777     else
00778       KMessageBox::information( dialogParent(),
00779                            i18n( "KOrganizer encountered some unknown fields while "
00780                                 "parsing your .calendar ical file, and had to "
00781                                 "discard them; please check to see that all "
00782                                 "your relevant data was correctly imported." ),
00783                                  i18n("ICal Import Successful with Warning") );
00784   } else if ( retVal == -1 ) {
00785     KMessageBox::error( dialogParent(),
00786                          i18n( "KOrganizer encountered an error parsing your "
00787                               ".calendar file from ical; import has failed." ) );
00788   } else if ( retVal == -2 ) {
00789     KMessageBox::error( dialogParent(),
00790                          i18n( "KOrganizer does not think that your .calendar "
00791                               "file is a valid ical calendar; import has failed." ) );
00792   }
00793   tmpfn.unlink();
00794 }
00795 
00796 void ActionManager::file_merge()
00797 {
00798   KURL url = KFileDialog::getOpenURL( locateLocal( "data","korganizer/" ),
00799                                      i18n("*.vcs *.ics|Calendar Files"),
00800                                      dialogParent() );
00801   if ( ! url.isEmpty() )  // isEmpty if user cancelled the dialog
00802     importCalendar( url );
00803 }
00804 
00805 void ActionManager::file_archive()
00806 {
00807   mCalendarView->archiveCalendar();
00808 }
00809 
00810 void ActionManager::file_revert()
00811 {
00812   openURL( mURL );
00813 }
00814 
00815 void ActionManager::file_saveas()
00816 {
00817   KURL url = getSaveURL();
00818 
00819   if ( url.isEmpty() ) return;
00820 
00821   saveAsURL( url );
00822 }
00823 
00824 void ActionManager::file_save()
00825 {
00826   if ( mMainWindow->hasDocument() ) {
00827     if ( mURL.isEmpty() ) {
00828       file_saveas();
00829       return;
00830     } else {
00831       saveURL();
00832     }
00833   } else {
00834     mCalendarView->calendar()->save();
00835   }
00836 
00837   // export to HTML
00838   if ( KOPrefs::instance()->mHtmlWithSave ) {
00839     exportHTML();
00840   }
00841 }
00842 
00843 void ActionManager::file_close()
00844 {
00845   if ( !saveModifiedURL() ) return;
00846 
00847   mCalendarView->closeCalendar();
00848   KIO::NetAccess::removeTempFile( mFile );
00849   mURL="";
00850   mFile="";
00851 
00852   setTitle();
00853 }
00854 
00855 bool ActionManager::openURL( const KURL &url,bool merge )
00856 {
00857   kdDebug(5850) << "ActionManager::openURL()" << endl;
00858 
00859   if ( url.isEmpty() ) {
00860     kdDebug(5850) << "ActionManager::openURL(): Error! Empty URL." << endl;
00861     return false;
00862   }
00863   if ( !url.isValid() ) {
00864     kdDebug(5850) << "ActionManager::openURL(): Error! URL is malformed." << endl;
00865     return false;
00866   }
00867 
00868   if ( url.isLocalFile() ) {
00869     mURL = url;
00870     mFile = url.path();
00871     if ( !KStandardDirs::exists( mFile ) ) {
00872       mMainWindow->showStatusMessage( i18n("New calendar '%1'.")
00873                                       .arg( url.prettyURL() ) );
00874       mCalendarView->setModified();
00875     } else {
00876       bool success = mCalendarView->openCalendar( mFile, merge );
00877       if ( success ) {
00878         showStatusMessageOpen( url, merge );
00879       }
00880     }
00881     setTitle();
00882   } else {
00883     QString tmpFile;
00884     if( KIO::NetAccess::download( url, tmpFile, view() ) ) {
00885       kdDebug(5850) << "--- Downloaded to " << tmpFile << endl;
00886       bool success = mCalendarView->openCalendar( tmpFile, merge );
00887       if ( merge ) {
00888         KIO::NetAccess::removeTempFile( tmpFile );
00889         if ( success )
00890           showStatusMessageOpen( url, merge );
00891       } else {
00892         if ( success ) {
00893           KIO::NetAccess::removeTempFile( mFile );
00894           mURL = url;
00895           mFile = tmpFile;
00896           KConfig *config = KOGlobals::self()->config();
00897           config->setGroup( "General" );
00898           setTitle();
00899           kdDebug(5850) << "-- Add recent URL: " << url.prettyURL() << endl;
00900           if ( mRecent ) mRecent->addURL( url );
00901           showStatusMessageOpen( url, merge );
00902         }
00903       }
00904       return success;
00905     } else {
00906       QString msg;
00907       msg = i18n("Cannot download calendar from '%1'.").arg( url.prettyURL() );
00908       KMessageBox::error( dialogParent(), msg );
00909       return false;
00910     }
00911   }
00912   return true;
00913 }
00914 
00915 bool ActionManager::addResource( const KURL &mUrl )
00916 {
00917   CalendarResources *cr = KOrg::StdCalendar::self();
00918 
00919   CalendarResourceManager *manager = cr->resourceManager();
00920 
00921   ResourceCalendar *resource = 0;
00922 
00923   QString name;
00924 
00925   kdDebug(5850) << "URL: " << mUrl << endl;
00926   if ( mUrl.isLocalFile() ) {
00927     kdDebug(5850) << "Local Resource" << endl;
00928     resource = manager->createResource( "file" );
00929     if ( resource )
00930       resource->setValue( "File", mUrl.path() );
00931     name = mUrl.path();
00932   } else {
00933     kdDebug(5850) << "Remote Resource" << endl;
00934     resource = manager->createResource( "remote" );
00935     if ( resource )
00936       resource->setValue( "DownloadURL", mUrl.url() );
00937     name = mUrl.prettyURL();
00938     resource->setReadOnly( true );
00939   }
00940 
00941   if ( resource ) {
00942     resource->setTimeZoneId( KOPrefs::instance()->mTimeZoneId );
00943     resource->setResourceName( name );
00944     manager->add( resource );
00945     mMainWindow->showStatusMessage( i18n( "Added calendar resource for URL '%1'." )
00946                .arg( name ) );
00947     // we have to call resourceAdded manually, because for in-process changes
00948     // the dcop signals are not connected, so the resource's signals would not
00949     // be connected otherwise
00950     if ( mCalendarResources )
00951       mCalendarResources->resourceAdded( resource );
00952   } else {
00953     QString msg = i18n("Unable to create calendar resource '%1'.")
00954                       .arg( name );
00955     KMessageBox::error( dialogParent(), msg );
00956   }
00957   return true;
00958 }
00959 
00960 
00961 void ActionManager::showStatusMessageOpen( const KURL &url, bool merge )
00962 {
00963   if ( merge ) {
00964     mMainWindow->showStatusMessage( i18n("Merged calendar '%1'.")
00965                                     .arg( url.prettyURL() ) );
00966   } else {
00967     mMainWindow->showStatusMessage( i18n("Opened calendar '%1'.")
00968                                     .arg( url.prettyURL() ) );
00969   }
00970 }
00971 
00972 void ActionManager::closeURL()
00973 {
00974   kdDebug(5850) << "ActionManager::closeURL()" << endl;
00975 
00976   file_close();
00977 }
00978 
00979 bool ActionManager::saveURL()
00980 {
00981   QString ext;
00982 
00983   if ( mURL.isLocalFile() ) {
00984     ext = mFile.right( 4 );
00985   } else {
00986     ext = mURL.filename().right( 4 );
00987   }
00988 
00989   if ( ext == ".vcs" ) {
00990     int result = KMessageBox::warningContinueCancel(
00991         dialogParent(),
00992         i18n( "Your calendar will be saved in iCalendar format. Use "
00993               "'Export vCalendar' to save in vCalendar format." ),
00994         i18n("Format Conversion"), i18n("Proceed"), "dontaskFormatConversion",
00995         true );
00996     if ( result != KMessageBox::Continue ) return false;
00997 
00998     QString filename = mURL.fileName();
00999     filename.replace( filename.length() - 4, 4, ".ics" );
01000     mURL.setFileName( filename );
01001     if ( mURL.isLocalFile() ) {
01002       mFile = mURL.path();
01003     }
01004     setTitle();
01005     if ( mRecent ) mRecent->addURL( mURL );
01006   }
01007 
01008   if ( !mCalendarView->saveCalendar( mFile ) ) {
01009     kdDebug(5850) << "ActionManager::saveURL(): calendar view save failed."
01010                   << endl;
01011     return false;
01012   } else {
01013     mCalendarView->setModified( false );
01014   }
01015 
01016   if ( !mURL.isLocalFile() ) {
01017     if ( !KIO::NetAccess::upload( mFile, mURL, view() ) ) {
01018       QString msg = i18n("Cannot upload calendar to '%1'")
01019                     .arg( mURL.prettyURL() );
01020       KMessageBox::error( dialogParent() ,msg );
01021       return false;
01022     }
01023   }
01024 
01025   // keep saves on a regular interval
01026   if ( KOPrefs::instance()->mAutoSave ) {
01027     mAutoSaveTimer->stop();
01028     mAutoSaveTimer->start( 1000*60*KOPrefs::instance()->mAutoSaveInterval );
01029   }
01030 
01031   mMainWindow->showStatusMessage( i18n("Saved calendar '%1'.").arg( mURL.prettyURL() ) );
01032 
01033   return true;
01034 }
01035 
01036 void ActionManager::exportHTML()
01037 {
01038   HTMLExportSettings settings( "KOrganizer" );
01039   // Manually read in the config, because parametrized kconfigxt objects don't
01040   // seem to load the config theirselves
01041   settings.readConfig();
01042 
01043   QDate qd1;
01044   qd1 = QDate::currentDate();
01045   QDate qd2;
01046   qd2 = QDate::currentDate();
01047   if ( settings.monthView() )
01048     qd2.addMonths( 1 );
01049   else
01050     qd2.addDays( 7 );
01051   settings.setDateStart( qd1 );
01052   settings.setDateEnd( qd2 );
01053   exportHTML( &settings );
01054 }
01055 
01056 void ActionManager::exportHTML( HTMLExportSettings *settings )
01057 {
01058   if ( !settings || settings->outputFile().isEmpty() )
01059     return;
01060   kdDebug()<<" settings->outputFile() :"<<settings->outputFile()<<endl;
01061   if ( QFileInfo( settings->outputFile() ).exists() ) {
01062     if(KMessageBox::questionYesNo( dialogParent(), i18n("Do you want to overwrite file \"%1\"").arg( settings->outputFile()) ) == KMessageBox::No)
01063       return;
01064   }
01065   settings->setEMail( KOPrefs::instance()->email() );
01066   settings->setName( KOPrefs::instance()->fullName() );
01067 
01068   settings->setCreditName( "KOrganizer" );
01069   settings->setCreditURL( "http://korganizer.kde.org" );
01070 
01071   KCal::HtmlExport mExport( mCalendarView->calendar(), settings );
01072 
01073   QDate cdate = settings->dateStart().date();
01074   QDate qd2 = settings->dateEnd().date();
01075   while ( cdate <= qd2 ) {
01076     QStringList holidays = KOGlobals::self()->holiday( cdate );
01077     if ( !holidays.isEmpty() ) {
01078       QStringList::ConstIterator it = holidays.begin();
01079       for ( ; it != holidays.end(); ++it ) {
01080         mExport.addHoliday( cdate, *it );
01081       }
01082     }
01083     cdate = cdate.addDays( 1 );
01084   }
01085 
01086   KURL dest( settings->outputFile() );
01087   if ( dest.isLocalFile() ) {
01088     mExport.save( dest.path() );
01089   } else {
01090     KTempFile tf;
01091     QString tfile = tf.name();
01092     tf.close();
01093     mExport.save( tfile );
01094     if ( !KIO::NetAccess::upload( tfile, dest, view() ) ) {
01095       KNotifyClient::event ( view()->winId(),
01096                             i18n("Could not upload file.") );
01097     }
01098     tf.unlink();
01099   }
01100 }
01101 
01102 bool ActionManager::saveAsURL( const KURL &url )
01103 {
01104   kdDebug(5850) << "ActionManager::saveAsURL() " << url.prettyURL() << endl;
01105 
01106   if ( url.isEmpty() ) {
01107     kdDebug(5850) << "ActionManager::saveAsURL(): Empty URL." << endl;
01108     return false;
01109   }
01110   if ( !url.isValid() ) {
01111     kdDebug(5850) << "ActionManager::saveAsURL(): Malformed URL." << endl;
01112     return false;
01113   }
01114 
01115   QString fileOrig = mFile;
01116   KURL URLOrig = mURL;
01117 
01118   KTempFile *tempFile = 0;
01119   if ( url.isLocalFile() ) {
01120     mFile = url.path();
01121   } else {
01122     tempFile = new KTempFile;
01123     mFile = tempFile->name();
01124   }
01125   mURL = url;
01126 
01127   bool success = saveURL(); // Save local file and upload local file
01128   if ( success ) {
01129     delete mTempFile;
01130     mTempFile = tempFile;
01131     KIO::NetAccess::removeTempFile( fileOrig );
01132     KConfig *config = KOGlobals::self()->config();
01133     config->setGroup( "General" );
01134     setTitle();
01135     if ( mRecent ) mRecent->addURL( mURL );
01136   } else {
01137     KMessageBox::sorry( dialogParent(), i18n("Unable to save calendar to the file %1.").arg( mFile ), i18n("Error") );
01138     kdDebug(5850) << "ActionManager::saveAsURL() failed" << endl;
01139     mURL = URLOrig;
01140     mFile = fileOrig;
01141     delete tempFile;
01142   }
01143 
01144   return success;
01145 }
01146 
01147 
01148 bool ActionManager::saveModifiedURL()
01149 {
01150   kdDebug(5850) << "ActionManager::saveModifiedURL()" << endl;
01151 
01152   // If calendar isn't modified do nothing.
01153   if ( !mCalendarView->isModified() ) return true;
01154 
01155   mHtmlExportSync = true;
01156   if ( KOPrefs::instance()->mAutoSave && !mURL.isEmpty() ) {
01157     // Save automatically, when auto save is enabled.
01158     return saveURL();
01159   } else {
01160     int result = KMessageBox::warningYesNoCancel(
01161         dialogParent(),
01162         i18n("The calendar has been modified.\nDo you want to save it?"),
01163         QString::null,
01164         KStdGuiItem::save(), KStdGuiItem::discard() );
01165     switch( result ) {
01166       case KMessageBox::Yes:
01167         if ( mURL.isEmpty() ) {
01168           KURL url = getSaveURL();
01169           return saveAsURL( url );
01170         } else {
01171           return saveURL();
01172         }
01173       case KMessageBox::No:
01174         return true;
01175       case KMessageBox::Cancel:
01176       default:
01177         {
01178           mHtmlExportSync = false;
01179           return false;
01180         }
01181     }
01182   }
01183 }
01184 
01185 
01186 KURL ActionManager::getSaveURL()
01187 {
01188   KURL url = KFileDialog::getSaveURL( locateLocal( "data","korganizer/" ),
01189                                      i18n("*.vcs *.ics|Calendar Files"),
01190                                      dialogParent() );
01191 
01192   if ( url.isEmpty() ) return url;
01193 
01194   QString filename = url.fileName( false );
01195 
01196   QString e = filename.right( 4 );
01197   if ( e != ".vcs" && e != ".ics" ) {
01198     // Default save format is iCalendar
01199     filename += ".ics";
01200   }
01201 
01202   url.setFileName( filename );
01203 
01204   kdDebug(5850) << "ActionManager::getSaveURL(): url: " << url.url() << endl;
01205 
01206   return url;
01207 }
01208 
01209 void ActionManager::saveProperties( KConfig *config )
01210 {
01211   kdDebug(5850) << "ActionManager::saveProperties" << endl;
01212 
01213   config->writeEntry( "UseResourceCalendar", !mMainWindow->hasDocument() );
01214   if ( mMainWindow->hasDocument() ) {
01215     config->writePathEntry( "Calendar",mURL.url() );
01216   }
01217 }
01218 
01219 void ActionManager::readProperties( KConfig *config )
01220 {
01221   kdDebug(5850) << "ActionManager::readProperties" << endl;
01222 
01223   bool isResourceCalendar(
01224     config->readBoolEntry( "UseResourceCalendar", true ) );
01225   QString calendarUrl = config->readPathEntry( "Calendar" );
01226 
01227   if ( !isResourceCalendar && !calendarUrl.isEmpty() ) {
01228     mMainWindow->init( true );
01229     KURL u( calendarUrl );
01230     openURL( u );
01231   } else {
01232     mMainWindow->init( false );
01233   }
01234 }
01235 
01236 void ActionManager::checkAutoSave()
01237 {
01238   kdDebug(5850) << "ActionManager::checkAutoSave()" << endl;
01239 
01240   // Don't save if auto save interval is zero
01241   if ( KOPrefs::instance()->mAutoSaveInterval == 0 ) return;
01242 
01243   // has this calendar been saved before? If yes automatically save it.
01244   if ( KOPrefs::instance()->mAutoSave ) {
01245     if ( mCalendarResources || ( mCalendar && !url().isEmpty() ) ) {
01246       saveCalendar();
01247     }
01248   }
01249 }
01250 
01251 
01252 // Configuration changed as a result of the options dialog.
01253 void ActionManager::updateConfig()
01254 {
01255   kdDebug(5850) << "ActionManager::updateConfig()" << endl;
01256 
01257   if ( KOPrefs::instance()->mAutoSave && !mAutoSaveTimer->isActive() ) {
01258     checkAutoSave();
01259     if ( KOPrefs::instance()->mAutoSaveInterval > 0 ) {
01260       mAutoSaveTimer->start( 1000 * 60 *
01261                              KOPrefs::instance()->mAutoSaveInterval );
01262     }
01263   }
01264   if ( !KOPrefs::instance()->mAutoSave ) mAutoSaveTimer->stop();
01265   mNextXDays->setText( i18n( "&Next Day", "&Next %n Days",
01266                              KOPrefs::instance()->mNextXDays ) );
01267 
01268   KOCore::self()->reloadPlugins();
01269   mParts = KOCore::self()->reloadParts( mMainWindow, mParts );
01270 
01271   setDestinationPolicy();
01272 
01273   if ( mResourceView )
01274     mResourceView->updateView();
01275 
01276   KOGroupware::instance()->freeBusyManager()->setBrokenUrl( false );
01277 }
01278 
01279 void ActionManager::setDestinationPolicy()
01280 {
01281   if ( mCalendarResources ) {
01282     if ( KOPrefs::instance()->mDestination == KOPrefs::askDestination )
01283       mCalendarResources->setAskDestinationPolicy();
01284     else
01285       mCalendarResources->setStandardDestinationPolicy();
01286   }
01287 }
01288 
01289 void ActionManager::configureDateTime()
01290 {
01291   KProcess *proc = new KProcess;
01292   *proc << "kcmshell" << "language";
01293 
01294   connect( proc,SIGNAL( processExited( KProcess * ) ),
01295           SLOT( configureDateTimeFinished( KProcess * ) ) );
01296 
01297   if ( !proc->start() ) {
01298       KMessageBox::sorry( dialogParent(),
01299         i18n("Could not start control module for date and time format.") );
01300       delete proc;
01301   }
01302 }
01303 
01304 void ActionManager::showTip()
01305 {
01306   KTipDialog::showTip( dialogParent(),QString::null,true );
01307 }
01308 
01309 void ActionManager::showTipOnStart()
01310 {
01311   KTipDialog::showTip( dialogParent() );
01312 }
01313 
01314 KOrg::MainWindow *ActionManager::findInstance( const KURL &url )
01315 {
01316   if ( mWindowList ) {
01317     if ( url.isEmpty() ) return mWindowList->defaultInstance();
01318     else return mWindowList->findInstance( url );
01319   } else {
01320     return 0;
01321   }
01322 }
01323 
01324 void ActionManager::dumpText( const QString &str )
01325 {
01326   kdDebug(5850) << "ActionManager::dumpText(): " << str << endl;
01327 }
01328 
01329 void ActionManager::toggleDateNavigator()
01330 {
01331   bool visible = mDateNavigatorShowAction->isChecked();
01332   if ( mCalendarView ) mCalendarView->showDateNavigator( visible );
01333 }
01334 
01335 void ActionManager::toggleTodoView()
01336 {
01337   bool visible = mTodoViewShowAction->isChecked();
01338   if ( mCalendarView ) mCalendarView->showTodoView( visible );
01339 }
01340 
01341 void ActionManager::toggleEventViewer()
01342 {
01343   bool visible = mEventViewerShowAction->isChecked();
01344   if ( mCalendarView ) mCalendarView->showEventViewer( visible );
01345 }
01346 
01347 void ActionManager::toggleResourceView()
01348 {
01349   bool visible = mResourceViewShowAction->isChecked();
01350   kdDebug(5850) << "toggleResourceView: " << endl;
01351   if ( mResourceView ) {
01352     if ( visible ) mResourceView->show();
01353     else mResourceView->hide();
01354   }
01355 }
01356 
01357 void ActionManager::toggleResourceButtons()
01358 {
01359   bool visible = mResourceButtonsAction->isChecked();
01360 
01361   kdDebug(5850) << "RESOURCE VIEW " << long( mResourceView ) << endl;
01362 
01363   if ( mResourceView ) mResourceView->showButtons( visible );
01364 }
01365 
01366 bool ActionManager::openURL( const QString &url )
01367 {
01368   return openURL( KURL( url ) );
01369 }
01370 
01371 bool ActionManager::mergeURL( const QString &url )
01372 {
01373   return openURL( KURL( url ),true );
01374 }
01375 
01376 bool ActionManager::saveAsURL( const QString &url )
01377 {
01378   return saveAsURL( KURL( url ) );
01379 }
01380 
01381 QString ActionManager::getCurrentURLasString() const
01382 {
01383   return mURL.url();
01384 }
01385 
01386 bool ActionManager::editIncidence( const QString& uid )
01387 {
01388   return mCalendarView->editIncidence( uid );
01389 }
01390 
01391 bool ActionManager::deleteIncidence( const QString& uid, bool force )
01392 {
01393   return mCalendarView->deleteIncidence( uid, force );
01394 }
01395 
01396 bool ActionManager::addIncidence( const QString& ical )
01397 {
01398   return mCalendarView->addIncidence( ical );
01399 }
01400 
01401 void ActionManager::configureDateTimeFinished( KProcess *proc )
01402 {
01403   delete proc;
01404 }
01405 
01406 void ActionManager::downloadNewStuff()
01407 {
01408   kdDebug(5850) << "ActionManager::downloadNewStuff()" << endl;
01409 
01410   if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
01411   mNewStuff->download();
01412 }
01413 
01414 void ActionManager::uploadNewStuff()
01415 {
01416   if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
01417   mNewStuff->upload();
01418 }
01419 
01420 QString ActionManager::localFileName()
01421 {
01422   return mFile;
01423 }
01424 
01425 class ActionManager::ActionStringsVisitor : public IncidenceBase::Visitor
01426 {
01427   public:
01428     ActionStringsVisitor() : mShow( 0 ), mEdit( 0 ), mDelete( 0 ) {}
01429 
01430     bool act( IncidenceBase *incidence, KAction *show, KAction *edit, KAction *del )
01431     {
01432       mShow = show;
01433       mEdit = edit;
01434       mDelete = del;
01435       return incidence->accept( *this );
01436     }
01437 
01438   protected:
01439     bool visit( Event * ) {
01440       if ( mShow ) mShow->setText( i18n("&Show Event") );
01441       if ( mEdit ) mEdit->setText( i18n("&Edit Event...") );
01442       if ( mDelete ) mDelete->setText( i18n("&Delete Event") );
01443       return true;
01444     }
01445     bool visit( Todo * ) {
01446       if ( mShow ) mShow->setText( i18n("&Show To-do") );
01447       if ( mEdit ) mEdit->setText( i18n("&Edit To-do...") );
01448       if ( mDelete ) mDelete->setText( i18n("&Delete To-do") );
01449       return true;
01450     }
01451     bool visit( Journal * ) { return assignDefaultStrings(); }
01452   protected:
01453     bool assignDefaultStrings() {
01454       if ( mShow ) mShow->setText( i18n("&Show") );
01455       if ( mEdit ) mEdit->setText( i18n("&Edit...") );
01456       if ( mDelete ) mDelete->setText( i18n("&Delete") );
01457       return true;
01458     }
01459     KAction *mShow;
01460     KAction *mEdit;
01461     KAction *mDelete;
01462 };
01463 
01464 void ActionManager::processIncidenceSelection( Incidence *incidence, const QDate & )
01465 {
01466 //  kdDebug(5850) << "ActionManager::processIncidenceSelection()" << endl;
01467 
01468   if ( !incidence ) {
01469     enableIncidenceActions( false );
01470     return;
01471   }
01472 
01473   enableIncidenceActions( true );
01474 
01475   if ( incidence->isReadOnly() ) {
01476     mCutAction->setEnabled( false );
01477     mDeleteAction->setEnabled( false );
01478   }
01479 
01480   ActionStringsVisitor v;
01481   if ( !v.act( incidence, mShowIncidenceAction, mEditIncidenceAction, mDeleteIncidenceAction ) ) {
01482     mShowIncidenceAction->setText( i18n("&Show") );
01483     mEditIncidenceAction->setText( i18n("&Edit...") );
01484     mDeleteIncidenceAction->setText( i18n("&Delete") );
01485   }
01486 }
01487 
01488 void ActionManager::enableIncidenceActions( bool enabled )
01489 {
01490   mShowIncidenceAction->setEnabled( enabled );
01491   mEditIncidenceAction->setEnabled( enabled );
01492   mDeleteIncidenceAction->setEnabled( enabled );
01493 //   mAssignResourceAction->setEnabled( enabled );
01494 
01495   mCutAction->setEnabled( enabled );
01496   mCopyAction->setEnabled( enabled );
01497   mDeleteAction->setEnabled( enabled );
01498   mPublishEvent->setEnabled( enabled );
01499   mForwardEvent->setEnabled( enabled );
01500   mSendInvitation->setEnabled( enabled );
01501   mSendCancel->setEnabled( enabled );
01502   mSendStatusUpdate->setEnabled( enabled );
01503   mRequestChange->setEnabled( enabled );
01504   mRequestUpdate->setEnabled( enabled );
01505 }
01506 
01507 void ActionManager::keyBindings()
01508 {
01509   KKeyDialog dlg( false, view() );
01510   if ( mMainWindow )
01511     dlg.insert( mMainWindow->getActionCollection() );
01512 
01513   KOrg::Part *part;
01514   for ( part = mParts.first(); part; part = mParts.next() ) {
01515     dlg.insert( part->actionCollection(), part->shortInfo() );
01516   }
01517   dlg.configure();
01518 }
01519 
01520 void ActionManager::loadParts()
01521 {
01522   mParts = KOCore::self()->loadParts( mMainWindow );
01523 }
01524 
01525 void ActionManager::setTitle()
01526 {
01527   mMainWindow->setTitle();
01528 }
01529 
01530 KCalendarIface::ResourceRequestReply ActionManager::resourceRequest( const QValueList<QPair<QDateTime, QDateTime> >&,
01531  const QCString& resource,
01532  const QString& vCalIn )
01533 {
01534     kdDebug(5850) << k_funcinfo << "resource=" << resource << " vCalIn=" << vCalIn << endl;
01535     KCalendarIface::ResourceRequestReply reply;
01536     reply.vCalOut = "VCalOut";
01537     return reply;
01538 }
01539 
01540 void ActionManager::openEventEditor( const QString& text )
01541 {
01542   mCalendarView->newEvent( 0, QString(), text );
01543 }
01544 
01545 void ActionManager::openEventEditor( const QString& summary,
01546                                      const QString& description,
01547                                      const QString& attachment )
01548 {
01549   mCalendarView->newEvent( 0, QString(), summary, description, attachment );
01550 }
01551 
01552 void ActionManager::openEventEditor( const QString& summary,
01553                                      const QString& description,
01554                                      const QString& attachment,
01555                                      const QStringList& attendees )
01556 {
01557   mCalendarView->newEvent( 0,  QString(), summary, description, attachment, attendees );
01558 }
01559 
01560 void ActionManager::openEventEditor( const QString & summary,
01561                                      const QString & description,
01562                                      const QString & uri,
01563                                      const QString & file,
01564                                      const QStringList & attendees,
01565                                      const QString & attachmentMimetype )
01566 {
01567   int action = KOPrefs::instance()->defaultEmailAttachMethod();
01568   if ( attachmentMimetype != "message/rfc822" ) {
01569     action = KOPrefs::Link;
01570   } else if ( KOPrefs::instance()->defaultEmailAttachMethod() == KOPrefs::Ask ) {
01571     KPopupMenu *menu = new KPopupMenu( 0 );
01572     menu->insertItem( i18n("Attach as &link"), KOPrefs::Link );
01573     menu->insertItem( i18n("Attach &inline"), KOPrefs::InlineFull );
01574     menu->insertItem( i18n("Attach inline &without attachments"), KOPrefs::InlineBody );
01575     menu->insertSeparator();
01576     menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::Ask );
01577     action = menu->exec( QCursor::pos(), 0 );
01578     delete menu;
01579   }
01580 
01581   QString attData;
01582   KTempFile tf;
01583   tf.setAutoDelete( true );
01584   switch ( action ) {
01585     case KOPrefs::Ask:
01586       return;
01587     case KOPrefs::Link:
01588       attData = uri;
01589       break;
01590     case KOPrefs::InlineFull:
01591       attData = file;
01592       break;
01593     case KOPrefs::InlineBody:
01594     {
01595       QFile f( file );
01596       if ( !f.open( IO_ReadOnly ) )
01597         return;
01598       KMime::Message *msg = new KMime::Message();
01599       msg->setContent( QCString( f.readAll() ) );
01600       QCString head = msg->head();
01601       msg->parse();
01602       if ( msg == msg->textContent() || msg->textContent() == 0 ) { // no attachments
01603         attData = file;
01604       } else {
01605         if ( KMessageBox::warningContinueCancel( 0,
01606               i18n("Removing attachments from an email might invalidate its signature."),
01607               i18n("Remove Attachments"), KStdGuiItem::cont(), "BodyOnlyInlineAttachment" )
01608               != KMessageBox::Continue )
01609           return;
01610         // due to kmime shortcomings in KDE3, we need to assemble the result manually
01611         int begin = 0;
01612         int end = head.find( '\n' );
01613         bool skipFolded = false;
01614         while ( end >= 0 && end > begin ) {
01615           if ( head.find( "Content-Type:", begin, false ) != begin &&
01616                 head.find( "Content-Transfer-Encoding:", begin, false ) != begin &&
01617                 !(skipFolded && (head[begin] == ' ' || head[end] == '\t')) ) {
01618             QCString line = head.mid( begin, end - begin );
01619             tf.file()->writeBlock( line.data(), line.length() );
01620             tf.file()->writeBlock( "\n", 1 );
01621             skipFolded = false;
01622           } else {
01623             skipFolded = true;
01624           }
01625 
01626           begin = end + 1;
01627           end = head.find( '\n', begin );
01628           if ( end < 0 && begin < (int)head.length() )
01629             end = head.length() - 1;
01630         }
01631         QCString cte = msg->textContent()->contentTransferEncoding()->as7BitString();
01632         if ( !cte.stripWhiteSpace().isEmpty() ) {
01633           tf.file()->writeBlock( cte.data(), cte.length() );
01634           tf.file()->writeBlock( "\n", 1 );
01635         }
01636         QCString ct = msg->textContent()->contentType()->as7BitString();
01637         if ( !ct.stripWhiteSpace().isEmpty() )
01638           tf.file()->writeBlock( ct.data(), ct.length() );
01639         tf.file()->writeBlock( "\n", 1 );
01640         tf.file()->writeBlock( msg->textContent()->body() );
01641         attData = tf.name();
01642       }
01643       tf.close();
01644       delete msg;
01645       break;
01646     }
01647     default:
01648       // menu could have been closed by cancel, if so, do nothing
01649       return;
01650   }
01651 
01652   mCalendarView->newEvent( 0, QString(), summary, description, attData,
01653                            attendees, attachmentMimetype, action != KOPrefs::Link );
01654 }
01655 
01656 void ActionManager::openTodoEditor( const QString& text )
01657 {
01658   mCalendarView->newTodo( 0, QString(), text );
01659 }
01660 
01661 void ActionManager::openTodoEditor( const QString& summary,
01662                                     const QString& description,
01663                                     const QString& attachment )
01664 {
01665   mCalendarView->newTodo( 0, QString(), summary, description, attachment );
01666 }
01667 
01668 void ActionManager::openTodoEditor( const QString& summary,
01669                                     const QString& description,
01670                                     const QString& attachment,
01671                                     const QStringList& attendees )
01672 {
01673   mCalendarView->newTodo( 0, QString(), summary, description, attachment, attendees );
01674 }
01675 
01676 void ActionManager::openTodoEditor(const QString & summary,
01677                                    const QString & description,
01678                                    const QString & uri,
01679                                    const QString & file,
01680                                    const QStringList & attendees,
01681                                    const QString & attachmentMimetype,
01682                                    bool isTask )
01683 {
01684   int action = KOPrefs::instance()->defaultTodoAttachMethod();
01685   if ( attachmentMimetype != "message/rfc822" ) {
01686     action = KOPrefs::TodoAttachLink;
01687   } else if ( KOPrefs::instance()->defaultTodoAttachMethod() == KOPrefs::TodoAttachAsk ) {
01688     KPopupMenu *menu = new KPopupMenu( 0 );
01689     menu->insertItem( i18n("Attach as &link"), KOPrefs::TodoAttachLink );
01690     menu->insertItem( i18n("Attach &inline"), KOPrefs::TodoAttachInlineFull );
01691     menu->insertSeparator();
01692     menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::TodoAttachAsk );
01693     action = menu->exec( QCursor::pos(), 0 );
01694     delete menu;
01695   }
01696 
01697   QStringList attData;
01698   switch ( action ) {
01699     case KOPrefs::TodoAttachAsk:
01700       return;
01701     case KOPrefs::TodoAttachLink:
01702       attData << uri;
01703       break;
01704   case KOPrefs::TodoAttachInlineFull:
01705       attData << file;
01706       break;
01707     default:
01708       // menu could have been closed by cancel, if so, do nothing
01709       return;
01710   }
01711 
01712   mCalendarView->newTodo( 0, QString(),
01713                           summary, description,
01714                           attData, attendees,
01715                           QStringList( attachmentMimetype ),
01716                           action != KOPrefs::TodoAttachLink,
01717                           isTask );
01718 }
01719 
01720 void ActionManager::openJournalEditor( const QDate& date )
01721 {
01722   mCalendarView->newJournal( 0, QString(), date );
01723 }
01724 
01725 void ActionManager::openJournalEditor( const QString& text, const QDate& date )
01726 {
01727   mCalendarView->newJournal( 0, QString(), text, date );
01728 }
01729 
01730 void ActionManager::openJournalEditor( const QString& text )
01731 {
01732   mCalendarView->newJournal( 0, QString(), text );
01733 }
01734 
01735 //TODO:
01736 // void ActionManager::openJournalEditor( const QString& summary,
01737 //                                        const QString& description,
01738 //                                        const QString& attachment )
01739 // {
01740 //   mCalendarView->newJournal( 0, QString(),summary, description, attachment );
01741 // }
01742 
01743 
01744 void ActionManager::showJournalView()
01745 {
01746   mCalendarView->viewManager()->showJournalView();
01747 }
01748 
01749 void ActionManager::showTodoView()
01750 {
01751   mCalendarView->viewManager()->showTodoView();
01752 }
01753 
01754 void ActionManager::showEventView()
01755 {
01756   mCalendarView->viewManager()->showEventView();
01757 }
01758 
01759 void ActionManager::goDate( const QDate& date )
01760 {
01761   mCalendarView->goDate( date );
01762 }
01763 
01764 void ActionManager::goDate( const QString& date )
01765 {
01766   goDate( KGlobal::locale()->readDate( date ) );
01767 }
01768 
01769 void ActionManager::showDate(const QDate & date)
01770 {
01771   mCalendarView->showDate( date );
01772 }
01773 
01774 
01775 void ActionManager::updateUndoAction( const QString &text )
01776 {
01777   if ( text.isNull() ) {
01778     mUndoAction->setEnabled( false );
01779     mUndoAction->setText( i18n("Undo") );
01780   } else {
01781     mUndoAction->setEnabled( true );
01782     if ( text.isEmpty() ) mUndoAction->setText( i18n("Undo") );
01783     else mUndoAction->setText( i18n("Undo (%1)").arg( text ) );
01784   }
01785 }
01786 
01787 void ActionManager::updateRedoAction( const QString &text )
01788 {
01789   if ( text.isNull() ) {
01790     mRedoAction->setEnabled( false );
01791     mRedoAction->setText( i18n( "Redo" ) );
01792   } else {
01793     mRedoAction->setEnabled( true );
01794     if ( text.isEmpty() ) mRedoAction->setText( i18n("Redo") );
01795     else mRedoAction->setText( i18n( "Redo (%1)" ).arg( text ) );
01796   }
01797 }
01798 
01799 bool ActionManager::queryClose()
01800 {
01801   kdDebug(5850) << "ActionManager::queryClose()" << endl;
01802 
01803   bool close = true;
01804 
01805   if ( mCalendar && mCalendar->isModified() ) {
01806     int res = KMessageBox::questionYesNoCancel( dialogParent(),
01807       i18n("The calendar contains unsaved changes. Do you want to save them before exiting?"), QString::null, KStdGuiItem::save(), KStdGuiItem::discard() );
01808     // Exit on yes and no, don't exit on cancel. If saving fails, ask for exiting.
01809     if ( res == KMessageBox::Yes ) {
01810       close = saveModifiedURL();
01811       if ( !close ) {
01812         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() );
01813         close = ( res1 == KMessageBox::Yes );
01814       }
01815     } else {
01816       close = ( res == KMessageBox::No );
01817     }
01818   } else if ( mCalendarResources ) {
01819     if ( !mIsClosing ) {
01820       kdDebug(5850) << "!mIsClosing" << endl;
01821       if ( !saveResourceCalendar() ) return false;
01822 
01823       // FIXME: Put main window into a state indicating final saving.
01824       mIsClosing = true;
01825 // FIXME: Close main window when save is finished
01826 //      connect( mCalendarResources, SIGNAL( calendarSaved() ),
01827 //               mMainWindow, SLOT( close() ) );
01828     }
01829     if ( mCalendarResources->isSaving() ) {
01830       kdDebug(5850) << "ActionManager::queryClose(): isSaving" << endl;
01831       close = false;
01832       KMessageBox::information( dialogParent(),
01833           i18n("Unable to exit. Saving still in progress.") );
01834     } else {
01835       kdDebug(5850) << "ActionManager::queryClose(): close = true" << endl;
01836       close = true;
01837     }
01838   } else {
01839     close = true;
01840   }
01841 
01842   return close;
01843 }
01844 
01845 void ActionManager::saveCalendar()
01846 {
01847   if ( mCalendar ) {
01848     if ( view()->isModified() ) {
01849       if ( !url().isEmpty() ) {
01850         saveURL();
01851       } else {
01852         QString location = locateLocal( "data", "korganizer/kontact.ics" );
01853         saveAsURL( location );
01854       }
01855     }
01856   } else if ( mCalendarResources ) {
01857     mCalendarResources->save();
01858     // FIXME: Make sure that asynchronous saves don't fail.
01859   }
01860 }
01861 
01862 bool ActionManager::saveResourceCalendar()
01863 {
01864   if ( !mCalendarResources ) return false;
01865   CalendarResourceManager *m = mCalendarResources->resourceManager();
01866 
01867   CalendarResourceManager::ActiveIterator it;
01868   for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
01869     if ( (*it)->readOnly() ) continue;
01870     if ( !(*it)->save() ) {
01871       int result = KMessageBox::warningContinueCancel( view(),
01872         i18n( "Saving of '%1' failed. Check that the resource is "
01873              "properly configured.\nIgnore problem and continue without "
01874              "saving or cancel save?" ).arg( (*it)->resourceName() ),
01875         i18n("Save Error"), KStdGuiItem::dontSave() );
01876       if ( result == KMessageBox::Cancel ) return false;
01877     }
01878   }
01879   return true;
01880 }
01881 
01882 void ActionManager::importCalendar( const KURL &url )
01883 {
01884   if ( !url.isValid() ) {
01885     KMessageBox::error( dialogParent(),
01886                         i18n("URL '%1' is invalid.").arg( url.prettyURL() ) );
01887     return;
01888   }
01889 
01890   ImportDialog *dialog;
01891   dialog = new ImportDialog( url, mMainWindow->topLevelWidget() );
01892   connect( dialog, SIGNAL( dialogFinished( ImportDialog * ) ),
01893            SLOT( slotImportDialogFinished( ImportDialog * ) ) );
01894   connect( dialog, SIGNAL( openURL( const KURL &, bool ) ),
01895            SLOT( openURL( const KURL &, bool ) ) );
01896   connect( dialog, SIGNAL( newWindow( const KURL & ) ),
01897            SIGNAL( actionNew( const KURL & ) ) );
01898   connect( dialog, SIGNAL( addResource( const KURL & ) ),
01899            SLOT( addResource( const KURL & ) ) );
01900 
01901   dialog->show();
01902 }
01903 
01904 void ActionManager::slotImportDialogFinished( ImportDialog *dlg )
01905 {
01906   dlg->deleteLater();
01907   mCalendarView->updateView();
01908 }
01909 
01910 void ActionManager::slotAutoArchivingSettingsModified()
01911 {
01912   if ( KOPrefs::instance()->mAutoArchive )
01913     mAutoArchiveTimer->start( 4 * 60 * 60 * 1000, true ); // check again in 4 hours
01914   else
01915     mAutoArchiveTimer->stop();
01916 }
01917 
01918 void ActionManager::slotAutoArchive()
01919 {
01920   if ( !mCalendarView->calendar() ) // can this happen?
01921     return;
01922   mAutoArchiveTimer->stop();
01923   EventArchiver archiver;
01924   connect( &archiver, SIGNAL( eventsDeleted() ), mCalendarView, SLOT( updateView() ) );
01925   archiver.runAuto( mCalendarView->calendar(), mCalendarView, false /*no gui*/ );
01926   // restart timer with the correct delay ( especially useful for the first time )
01927   slotAutoArchivingSettingsModified();
01928 }
01929 
01930 void ActionManager::loadProfile( const QString & path )
01931 {
01932   KOPrefs::instance()->writeConfig();
01933   KConfig* const cfg = KOPrefs::instance()->config();
01934 
01935   const KConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
01936   const QStringList groups = profile.groupList();
01937   for ( QStringList::ConstIterator it = groups.begin(), end = groups.end(); it != end; ++it )
01938   {
01939     cfg->setGroup( *it );
01940     typedef QMap<QString, QString> StringMap;
01941     const StringMap entries = profile.entryMap( *it );
01942     for ( StringMap::ConstIterator it2 = entries.begin(), end = entries.end(); it2 != end; ++it2 )
01943     {
01944       cfg->writeEntry( it2.key(), it2.data() );
01945     }
01946   }
01947 
01948   cfg->sync();
01949   KOPrefs::instance()->readConfig();
01950 }
01951 
01952 namespace {
01953     void copyConfigEntry( KConfig* source, KConfig* dest, const QString& group, const QString& key, const QString& defaultValue=QString() )
01954     {
01955         source->setGroup( group );
01956         dest->setGroup( group );
01957         dest->writeEntry( key, source->readEntry( key, defaultValue ) );
01958     }
01959 }
01960 
01961 void ActionManager::saveToProfile( const QString & path ) const
01962 {
01963   KOPrefs::instance()->writeConfig();
01964   KConfig* const cfg = KOPrefs::instance()->config();
01965 
01966   KConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
01967   ::copyConfigEntry( cfg, &profile, "Views", "Agenda View Calendar Display" );
01968 }
01969 
01970 QWidget *ActionManager::dialogParent()
01971 {
01972   return mCalendarView->topLevelWidget();
01973 }
01974 
01975 #include "actionmanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys