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