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