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::editIncidence( const QString &uid, const QDate &date )
01392 {
01393   return mCalendarView->editIncidence( uid, date );
01394 }
01395 
01396 bool ActionManager::deleteIncidence( const QString& uid, bool force )
01397 {
01398   return mCalendarView->deleteIncidence( uid, force );
01399 }
01400 
01401 bool ActionManager::addIncidence( const QString& ical )
01402 {
01403   return mCalendarView->addIncidence( ical );
01404 }
01405 
01406 void ActionManager::configureDateTimeFinished( KProcess *proc )
01407 {
01408   delete proc;
01409 }
01410 
01411 void ActionManager::downloadNewStuff()
01412 {
01413   kdDebug(5850) << "ActionManager::downloadNewStuff()" << endl;
01414 
01415   if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
01416   mNewStuff->download();
01417 }
01418 
01419 void ActionManager::uploadNewStuff()
01420 {
01421   if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
01422   mNewStuff->upload();
01423 }
01424 
01425 QString ActionManager::localFileName()
01426 {
01427   return mFile;
01428 }
01429 
01430 class ActionManager::ActionStringsVisitor : public IncidenceBase::Visitor
01431 {
01432   public:
01433     ActionStringsVisitor() : mShow( 0 ), mEdit( 0 ), mDelete( 0 ) {}
01434 
01435     bool act( IncidenceBase *incidence, KAction *show, KAction *edit, KAction *del )
01436     {
01437       mShow = show;
01438       mEdit = edit;
01439       mDelete = del;
01440       return incidence->accept( *this );
01441     }
01442 
01443   protected:
01444     bool visit( Event * ) {
01445       if ( mShow ) mShow->setText( i18n("&Show Event") );
01446       if ( mEdit ) mEdit->setText( i18n("&Edit Event...") );
01447       if ( mDelete ) mDelete->setText( i18n("&Delete Event") );
01448       return true;
01449     }
01450     bool visit( Todo * ) {
01451       if ( mShow ) mShow->setText( i18n("&Show To-do") );
01452       if ( mEdit ) mEdit->setText( i18n("&Edit To-do...") );
01453       if ( mDelete ) mDelete->setText( i18n("&Delete To-do") );
01454       return true;
01455     }
01456     bool visit( Journal * ) { return assignDefaultStrings(); }
01457   protected:
01458     bool assignDefaultStrings() {
01459       if ( mShow ) mShow->setText( i18n("&Show") );
01460       if ( mEdit ) mEdit->setText( i18n("&Edit...") );
01461       if ( mDelete ) mDelete->setText( i18n("&Delete") );
01462       return true;
01463     }
01464     KAction *mShow;
01465     KAction *mEdit;
01466     KAction *mDelete;
01467 };
01468 
01469 void ActionManager::processIncidenceSelection( Incidence *incidence, const QDate & )
01470 {
01471 //  kdDebug(5850) << "ActionManager::processIncidenceSelection()" << endl;
01472 
01473   if ( !incidence ) {
01474     enableIncidenceActions( false );
01475     return;
01476   }
01477 
01478   enableIncidenceActions( true );
01479 
01480   if ( incidence->isReadOnly() ) {
01481     mCutAction->setEnabled( false );
01482     mDeleteAction->setEnabled( false );
01483   }
01484 
01485   ActionStringsVisitor v;
01486   if ( !v.act( incidence, mShowIncidenceAction, mEditIncidenceAction, mDeleteIncidenceAction ) ) {
01487     mShowIncidenceAction->setText( i18n("&Show") );
01488     mEditIncidenceAction->setText( i18n("&Edit...") );
01489     mDeleteIncidenceAction->setText( i18n("&Delete") );
01490   }
01491 }
01492 
01493 void ActionManager::enableIncidenceActions( bool enabled )
01494 {
01495   mShowIncidenceAction->setEnabled( enabled );
01496   mEditIncidenceAction->setEnabled( enabled );
01497   mDeleteIncidenceAction->setEnabled( enabled );
01498 //   mAssignResourceAction->setEnabled( enabled );
01499 
01500   mCutAction->setEnabled( enabled );
01501   mCopyAction->setEnabled( enabled );
01502   mDeleteAction->setEnabled( enabled );
01503   mPublishEvent->setEnabled( enabled );
01504   mForwardEvent->setEnabled( enabled );
01505   mSendInvitation->setEnabled( enabled );
01506   mSendCancel->setEnabled( enabled );
01507   mSendStatusUpdate->setEnabled( enabled );
01508   mRequestChange->setEnabled( enabled );
01509   mRequestUpdate->setEnabled( enabled );
01510 }
01511 
01512 void ActionManager::keyBindings()
01513 {
01514   KKeyDialog dlg( false, view() );
01515   if ( mMainWindow )
01516     dlg.insert( mMainWindow->getActionCollection() );
01517 
01518   KOrg::Part *part;
01519   for ( part = mParts.first(); part; part = mParts.next() ) {
01520     dlg.insert( part->actionCollection(), part->shortInfo() );
01521   }
01522   dlg.configure();
01523 }
01524 
01525 void ActionManager::loadParts()
01526 {
01527   mParts = KOCore::self()->loadParts( mMainWindow );
01528 }
01529 
01530 void ActionManager::setTitle()
01531 {
01532   mMainWindow->setTitle();
01533 }
01534 
01535 KCalendarIface::ResourceRequestReply ActionManager::resourceRequest( const QValueList<QPair<QDateTime, QDateTime> >&,
01536  const QCString& resource,
01537  const QString& vCalIn )
01538 {
01539     kdDebug(5850) << k_funcinfo << "resource=" << resource << " vCalIn=" << vCalIn << endl;
01540     KCalendarIface::ResourceRequestReply reply;
01541     reply.vCalOut = "VCalOut";
01542     return reply;
01543 }
01544 
01545 void ActionManager::openEventEditor( const QString& text )
01546 {
01547   mCalendarView->newEvent( 0, QString(), text );
01548 }
01549 
01550 void ActionManager::openEventEditor( const QString& summary,
01551                                      const QString& description,
01552                                      const QString& attachment )
01553 {
01554   mCalendarView->newEvent( 0, QString(), summary, description, attachment );
01555 }
01556 
01557 void ActionManager::openEventEditor( const QString& summary,
01558                                      const QString& description,
01559                                      const QString& attachment,
01560                                      const QStringList& attendees )
01561 {
01562   mCalendarView->newEvent( 0,  QString(), summary, description, attachment, attendees );
01563 }
01564 
01565 void ActionManager::openEventEditor( const QString & summary,
01566                                      const QString & description,
01567                                      const QString & uri,
01568                                      const QString & file,
01569                                      const QStringList & attendees,
01570                                      const QString & attachmentMimetype )
01571 {
01572   int action = KOPrefs::instance()->defaultEmailAttachMethod();
01573   if ( attachmentMimetype != "message/rfc822" ) {
01574     action = KOPrefs::Link;
01575   } else if ( KOPrefs::instance()->defaultEmailAttachMethod() == KOPrefs::Ask ) {
01576     KPopupMenu *menu = new KPopupMenu( 0 );
01577     menu->insertItem( i18n("Attach as &link"), KOPrefs::Link );
01578     menu->insertItem( i18n("Attach &inline"), KOPrefs::InlineFull );
01579     menu->insertItem( i18n("Attach inline &without attachments"), KOPrefs::InlineBody );
01580     menu->insertSeparator();
01581     menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::Ask );
01582     action = menu->exec( QCursor::pos(), 0 );
01583     delete menu;
01584   }
01585 
01586   QString attData;
01587   KTempFile tf;
01588   tf.setAutoDelete( true );
01589   switch ( action ) {
01590     case KOPrefs::Ask:
01591       return;
01592     case KOPrefs::Link:
01593       attData = uri;
01594       break;
01595     case KOPrefs::InlineFull:
01596       attData = file;
01597       break;
01598     case KOPrefs::InlineBody:
01599     {
01600       QFile f( file );
01601       if ( !f.open( IO_ReadOnly ) )
01602         return;
01603       KMime::Message *msg = new KMime::Message();
01604       msg->setContent( QCString( f.readAll() ) );
01605       QCString head = msg->head();
01606       msg->parse();
01607       if ( msg == msg->textContent() || msg->textContent() == 0 ) { // no attachments
01608         attData = file;
01609       } else {
01610         if ( KMessageBox::warningContinueCancel( 0,
01611               i18n("Removing attachments from an email might invalidate its signature."),
01612               i18n("Remove Attachments"), KStdGuiItem::cont(), "BodyOnlyInlineAttachment" )
01613               != KMessageBox::Continue )
01614           return;
01615         // due to kmime shortcomings in KDE3, we need to assemble the result manually
01616         int begin = 0;
01617         int end = head.find( '\n' );
01618         bool skipFolded = false;
01619         while ( end >= 0 && end > begin ) {
01620           if ( head.find( "Content-Type:", begin, false ) != begin &&
01621                 head.find( "Content-Transfer-Encoding:", begin, false ) != begin &&
01622                 !(skipFolded && (head[begin] == ' ' || head[end] == '\t')) ) {
01623             QCString line = head.mid( begin, end - begin );
01624             tf.file()->writeBlock( line.data(), line.length() );
01625             tf.file()->writeBlock( "\n", 1 );
01626             skipFolded = false;
01627           } else {
01628             skipFolded = true;
01629           }
01630 
01631           begin = end + 1;
01632           end = head.find( '\n', begin );
01633           if ( end < 0 && begin < (int)head.length() )
01634             end = head.length() - 1;
01635         }
01636         QCString cte = msg->textContent()->contentTransferEncoding()->as7BitString();
01637         if ( !cte.stripWhiteSpace().isEmpty() ) {
01638           tf.file()->writeBlock( cte.data(), cte.length() );
01639           tf.file()->writeBlock( "\n", 1 );
01640         }
01641         QCString ct = msg->textContent()->contentType()->as7BitString();
01642         if ( !ct.stripWhiteSpace().isEmpty() )
01643           tf.file()->writeBlock( ct.data(), ct.length() );
01644         tf.file()->writeBlock( "\n", 1 );
01645         tf.file()->writeBlock( msg->textContent()->body() );
01646         attData = tf.name();
01647       }
01648       tf.close();
01649       delete msg;
01650       break;
01651     }
01652     default:
01653       // menu could have been closed by cancel, if so, do nothing
01654       return;
01655   }
01656 
01657   mCalendarView->newEvent( 0, QString(), summary, description, attData,
01658                            attendees, attachmentMimetype, action != KOPrefs::Link );
01659 }
01660 
01661 void ActionManager::openTodoEditor( const QString& text )
01662 {
01663   mCalendarView->newTodo( 0, QString(), text );
01664 }
01665 
01666 void ActionManager::openTodoEditor( const QString& summary,
01667                                     const QString& description,
01668                                     const QString& attachment )
01669 {
01670   mCalendarView->newTodo( 0, QString(), summary, description, attachment );
01671 }
01672 
01673 void ActionManager::openTodoEditor( const QString& summary,
01674                                     const QString& description,
01675                                     const QString& attachment,
01676                                     const QStringList& attendees )
01677 {
01678   mCalendarView->newTodo( 0, QString(), summary, description, attachment, attendees );
01679 }
01680 
01681 void ActionManager::openTodoEditor(const QString & summary,
01682                                    const QString & description,
01683                                    const QString & uri,
01684                                    const QString & file,
01685                                    const QStringList & attendees,
01686                                    const QString & attachmentMimetype,
01687                                    bool isTask )
01688 {
01689   int action = KOPrefs::instance()->defaultTodoAttachMethod();
01690   if ( attachmentMimetype != "message/rfc822" ) {
01691     action = KOPrefs::TodoAttachLink;
01692   } else if ( KOPrefs::instance()->defaultTodoAttachMethod() == KOPrefs::TodoAttachAsk ) {
01693     KPopupMenu *menu = new KPopupMenu( 0 );
01694     menu->insertItem( i18n("Attach as &link"), KOPrefs::TodoAttachLink );
01695     menu->insertItem( i18n("Attach &inline"), KOPrefs::TodoAttachInlineFull );
01696     menu->insertSeparator();
01697     menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::TodoAttachAsk );
01698     action = menu->exec( QCursor::pos(), 0 );
01699     delete menu;
01700   }
01701 
01702   QStringList attData;
01703   switch ( action ) {
01704     case KOPrefs::TodoAttachAsk:
01705       return;
01706     case KOPrefs::TodoAttachLink:
01707       attData << uri;
01708       break;
01709   case KOPrefs::TodoAttachInlineFull:
01710       attData << file;
01711       break;
01712     default:
01713       // menu could have been closed by cancel, if so, do nothing
01714       return;
01715   }
01716 
01717   mCalendarView->newTodo( 0, QString(),
01718                           summary, description,
01719                           attData, attendees,
01720                           QStringList( attachmentMimetype ),
01721                           action != KOPrefs::TodoAttachLink,
01722                           isTask );
01723 }
01724 
01725 void ActionManager::openJournalEditor( const QDate& date )
01726 {
01727   mCalendarView->newJournal( 0, QString(), date );
01728 }
01729 
01730 void ActionManager::openJournalEditor( const QString& text, const QDate& date )
01731 {
01732   mCalendarView->newJournal( 0, QString(), text, date );
01733 }
01734 
01735 void ActionManager::openJournalEditor( const QString& text )
01736 {
01737   mCalendarView->newJournal( 0, QString(), text );
01738 }
01739 
01740 //TODO:
01741 // void ActionManager::openJournalEditor( const QString& summary,
01742 //                                        const QString& description,
01743 //                                        const QString& attachment )
01744 // {
01745 //   mCalendarView->newJournal( 0, QString(),summary, description, attachment );
01746 // }
01747 
01748 
01749 void ActionManager::showJournalView()
01750 {
01751   mCalendarView->viewManager()->showJournalView();
01752 }
01753 
01754 void ActionManager::showTodoView()
01755 {
01756   mCalendarView->viewManager()->showTodoView();
01757 }
01758 
01759 void ActionManager::showEventView()
01760 {
01761   mCalendarView->viewManager()->showEventView();
01762 }
01763 
01764 void ActionManager::goDate( const QDate& date )
01765 {
01766   mCalendarView->goDate( date );
01767 }
01768 
01769 void ActionManager::goDate( const QString& date )
01770 {
01771   goDate( KGlobal::locale()->readDate( date ) );
01772 }
01773 
01774 void ActionManager::showDate(const QDate & date)
01775 {
01776   mCalendarView->showDate( date );
01777 }
01778 
01779 
01780 void ActionManager::updateUndoAction( const QString &text )
01781 {
01782   if ( text.isNull() ) {
01783     mUndoAction->setEnabled( false );
01784     mUndoAction->setText( i18n("Undo") );
01785   } else {
01786     mUndoAction->setEnabled( true );
01787     if ( text.isEmpty() ) mUndoAction->setText( i18n("Undo") );
01788     else mUndoAction->setText( i18n("Undo (%1)").arg( text ) );
01789   }
01790 }
01791 
01792 void ActionManager::updateRedoAction( const QString &text )
01793 {
01794   if ( text.isNull() ) {
01795     mRedoAction->setEnabled( false );
01796     mRedoAction->setText( i18n( "Redo" ) );
01797   } else {
01798     mRedoAction->setEnabled( true );
01799     if ( text.isEmpty() ) mRedoAction->setText( i18n("Redo") );
01800     else mRedoAction->setText( i18n( "Redo (%1)" ).arg( text ) );
01801   }
01802 }
01803 
01804 bool ActionManager::queryClose()
01805 {
01806   kdDebug(5850) << "ActionManager::queryClose()" << endl;
01807 
01808   bool close = true;
01809 
01810   if ( mCalendar && mCalendar->isModified() ) {
01811     int res = KMessageBox::questionYesNoCancel( dialogParent(),
01812       i18n("The calendar contains unsaved changes. Do you want to save them before exiting?"), QString::null, KStdGuiItem::save(), KStdGuiItem::discard() );
01813     // Exit on yes and no, don't exit on cancel. If saving fails, ask for exiting.
01814     if ( res == KMessageBox::Yes ) {
01815       close = saveModifiedURL();
01816       if ( !close ) {
01817         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() );
01818         close = ( res1 == KMessageBox::Yes );
01819       }
01820     } else {
01821       close = ( res == KMessageBox::No );
01822     }
01823   } else if ( mCalendarResources ) {
01824     if ( !mIsClosing ) {
01825       kdDebug(5850) << "!mIsClosing" << endl;
01826       if ( !saveResourceCalendar() ) return false;
01827 
01828       // FIXME: Put main window into a state indicating final saving.
01829       mIsClosing = true;
01830 // FIXME: Close main window when save is finished
01831 //      connect( mCalendarResources, SIGNAL( calendarSaved() ),
01832 //               mMainWindow, SLOT( close() ) );
01833     }
01834     if ( mCalendarResources->isSaving() ) {
01835       kdDebug(5850) << "ActionManager::queryClose(): isSaving" << endl;
01836       close = false;
01837       KMessageBox::information( dialogParent(),
01838           i18n("Unable to exit. Saving still in progress.") );
01839     } else {
01840       kdDebug(5850) << "ActionManager::queryClose(): close = true" << endl;
01841       close = true;
01842     }
01843   } else {
01844     close = true;
01845   }
01846 
01847   return close;
01848 }
01849 
01850 void ActionManager::saveCalendar()
01851 {
01852   if ( mCalendar ) {
01853     if ( view()->isModified() ) {
01854       if ( !url().isEmpty() ) {
01855         saveURL();
01856       } else {
01857         QString location = locateLocal( "data", "korganizer/kontact.ics" );
01858         saveAsURL( location );
01859       }
01860     }
01861   } else if ( mCalendarResources ) {
01862     mCalendarResources->save();
01863     // FIXME: Make sure that asynchronous saves don't fail.
01864   }
01865 }
01866 
01867 bool ActionManager::saveResourceCalendar()
01868 {
01869   if ( !mCalendarResources ) return false;
01870   CalendarResourceManager *m = mCalendarResources->resourceManager();
01871 
01872   CalendarResourceManager::ActiveIterator it;
01873   for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
01874     if ( (*it)->readOnly() ) continue;
01875     if ( !(*it)->save() ) {
01876       int result = KMessageBox::warningContinueCancel( view(),
01877         i18n( "Saving of '%1' failed. Check that the resource is "
01878              "properly configured.\nIgnore problem and continue without "
01879              "saving or cancel save?" ).arg( (*it)->resourceName() ),
01880         i18n("Save Error"), KStdGuiItem::dontSave() );
01881       if ( result == KMessageBox::Cancel ) return false;
01882     }
01883   }
01884   return true;
01885 }
01886 
01887 void ActionManager::importCalendar( const KURL &url )
01888 {
01889   if ( !url.isValid() ) {
01890     KMessageBox::error( dialogParent(),
01891                         i18n("URL '%1' is invalid.").arg( url.prettyURL() ) );
01892     return;
01893   }
01894 
01895   ImportDialog *dialog;
01896   dialog = new ImportDialog( url, mMainWindow->topLevelWidget() );
01897   connect( dialog, SIGNAL( dialogFinished( ImportDialog * ) ),
01898            SLOT( slotImportDialogFinished( ImportDialog * ) ) );
01899   connect( dialog, SIGNAL( openURL( const KURL &, bool ) ),
01900            SLOT( openURL( const KURL &, bool ) ) );
01901   connect( dialog, SIGNAL( newWindow( const KURL & ) ),
01902            SIGNAL( actionNew( const KURL & ) ) );
01903   connect( dialog, SIGNAL( addResource( const KURL & ) ),
01904            SLOT( addResource( const KURL & ) ) );
01905 
01906   dialog->show();
01907 }
01908 
01909 void ActionManager::slotImportDialogFinished( ImportDialog *dlg )
01910 {
01911   dlg->deleteLater();
01912   mCalendarView->updateView();
01913 }
01914 
01915 void ActionManager::slotAutoArchivingSettingsModified()
01916 {
01917   if ( KOPrefs::instance()->mAutoArchive )
01918     mAutoArchiveTimer->start( 4 * 60 * 60 * 1000, true ); // check again in 4 hours
01919   else
01920     mAutoArchiveTimer->stop();
01921 }
01922 
01923 void ActionManager::slotAutoArchive()
01924 {
01925   if ( !mCalendarView->calendar() ) // can this happen?
01926     return;
01927   mAutoArchiveTimer->stop();
01928   EventArchiver archiver;
01929   connect( &archiver, SIGNAL( eventsDeleted() ), mCalendarView, SLOT( updateView() ) );
01930   archiver.runAuto( mCalendarView->calendar(), mCalendarView, false /*no gui*/ );
01931   // restart timer with the correct delay ( especially useful for the first time )
01932   slotAutoArchivingSettingsModified();
01933 }
01934 
01935 void ActionManager::loadProfile( const QString & path )
01936 {
01937   KOPrefs::instance()->writeConfig();
01938   KConfig* const cfg = KOPrefs::instance()->config();
01939 
01940   const KConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
01941   const QStringList groups = profile.groupList();
01942   for ( QStringList::ConstIterator it = groups.begin(), end = groups.end(); it != end; ++it )
01943   {
01944     cfg->setGroup( *it );
01945     typedef QMap<QString, QString> StringMap;
01946     const StringMap entries = profile.entryMap( *it );
01947     for ( StringMap::ConstIterator it2 = entries.begin(), end = entries.end(); it2 != end; ++it2 )
01948     {
01949       cfg->writeEntry( it2.key(), it2.data() );
01950     }
01951   }
01952 
01953   cfg->sync();
01954   KOPrefs::instance()->readConfig();
01955 }
01956 
01957 namespace {
01958     void copyConfigEntry( KConfig* source, KConfig* dest, const QString& group, const QString& key, const QString& defaultValue=QString() )
01959     {
01960         source->setGroup( group );
01961         dest->setGroup( group );
01962         dest->writeEntry( key, source->readEntry( key, defaultValue ) );
01963     }
01964 }
01965 
01966 void ActionManager::saveToProfile( const QString & path ) const
01967 {
01968   KOPrefs::instance()->writeConfig();
01969   KConfig* const cfg = KOPrefs::instance()->config();
01970 
01971   KConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
01972   ::copyConfigEntry( cfg, &profile, "Views", "Agenda View Calendar Display" );
01973 }
01974 
01975 QWidget *ActionManager::dialogParent()
01976 {
01977   return mCalendarView->topLevelWidget();
01978 }
01979 
01980 #include "actionmanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys