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 TQt, and distribute the resulting executable,
00025   without including the source code for TQt in the source distribution.
00026 */
00027 
00028 #include "actionmanager.h"
00029 #include "previewdialog.h"
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 "previewdialog.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 <tdeaction.h>
00059 #include <tdefiledialog.h>
00060 #include <kiconloader.h>
00061 #include <tdeio/netaccess.h>
00062 #include <kkeydialog.h>
00063 #include <tdepopupmenu.h>
00064 #include <kstandarddirs.h>
00065 #include <ktip.h>
00066 #include <tdetempfile.h>
00067 #include <kxmlguiclient.h>
00068 #include <twin.h>
00069 #include <knotifyclient.h>
00070 #include <kstdguiitem.h>
00071 #include <tdeversion.h>
00072 #include <tdeactionclasses.h>
00073 #include <tdecmdlineargs.h>
00074 
00075 #include <tqapplication.h>
00076 #include <tqcursor.h>
00077 #include <tqtimer.h>
00078 #include <tqlabel.h>
00079 
00080 // FIXME: Several places in the file don't use TDEConfigXT yet!
00081 KOWindowList *ActionManager::mWindowList = 0;
00082 
00083 ActionManager::ActionManager( KXMLGUIClient *client, CalendarView *widget,
00084                               TQObject *parent, KOrg::MainWindow *mainWindow,
00085                               bool isPart )
00086   : TQObject( 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       TQTimer::singleShot( 0, TQT_TQOBJECT(this), TQT_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 TQTimer( this );
00141   connect( mAutoSaveTimer,TQT_SIGNAL( timeout() ), TQT_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 TQTimer( this );
00148   connect( mAutoArchiveTimer, TQT_SIGNAL( timeout() ), TQT_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, TQT_SIGNAL( modifiedChanged( bool ) ), TQT_SLOT( setTitle() ) );
00156   connect( mCalendarView, TQT_SIGNAL( configChanged() ), TQT_SLOT( updateConfig() ) );
00157 
00158   connect( mCalendarView, TQT_SIGNAL( incidenceSelected( Incidence *,const TQDate & ) ),
00159            TQT_TQOBJECT(this), TQT_SLOT( processIncidenceSelection( Incidence *,const TQDate & ) ) );
00160   connect( mCalendarView, TQT_SIGNAL( exportHTML( HTMLExportSettings * ) ),
00161            TQT_TQOBJECT(this), TQT_SLOT( exportHTML( HTMLExportSettings * ) ) );
00162 
00163   processIncidenceSelection( 0, TQDate() );
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, TQT_SIGNAL( calendarChanged() ),
00202            mCalendarView, TQT_SLOT( resourcesChanged() ) );
00203   connect( mCalendarResources, TQT_SIGNAL( signalErrorMessage( const TQString & ) ),
00204            mCalendarView, TQT_SLOT( showErrorMessage( const TQString & ) ) );
00205 
00206   connect( mCalendarView, TQT_SIGNAL( configChanged() ),
00207            TQT_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   TDEAction *action;
00223 
00224 
00225   //*************************** FILE MENU **********************************
00226 
00227   //~~~~~~~~~~~~~~~~~~~~~~~ LOADING / SAVING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00228   if ( mIsPart ) {
00229     if ( mMainWindow->hasDocument() ) {
00230       KStdAction::openNew( TQT_TQOBJECT(this), TQT_SLOT(file_new()), mACollection, "korganizer_openNew" );
00231       KStdAction::open( TQT_TQOBJECT(this), TQT_SLOT( file_open() ), mACollection, "korganizer_open" );
00232       mRecent = KStdAction::openRecent( TQT_TQOBJECT(this), TQT_SLOT( file_open( const KURL& ) ),
00233                                      mACollection, "korganizer_openRecent" );
00234       KStdAction::revert( this,TQT_SLOT( file_revert() ), mACollection, "korganizer_revert" );
00235       KStdAction::saveAs( TQT_TQOBJECT(this), TQT_SLOT( file_saveas() ), mACollection,
00236                    "korganizer_saveAs" );
00237       KStdAction::save( TQT_TQOBJECT(this), TQT_SLOT( file_save() ), mACollection, "korganizer_save" );
00238     }
00239     KStdAction::print( TQT_TQOBJECT(mCalendarView), TQT_SLOT( print() ), mACollection, "korganizer_print" );
00240   } else {
00241     KStdAction::openNew( TQT_TQOBJECT(this), TQT_SLOT( file_new() ), mACollection );
00242     KStdAction::open( TQT_TQOBJECT(this), TQT_SLOT( file_open() ), mACollection );
00243     mRecent = KStdAction::openRecent( TQT_TQOBJECT(this), TQT_SLOT( file_open( const KURL& ) ),
00244                                      mACollection );
00245     if ( mMainWindow->hasDocument() ) {
00246       KStdAction::revert( this,TQT_SLOT( file_revert() ), mACollection );
00247       KStdAction::save( TQT_TQOBJECT(this), TQT_SLOT( file_save() ), mACollection );
00248       KStdAction::saveAs( TQT_TQOBJECT(this), TQT_SLOT( file_saveas() ), mACollection );
00249     }
00250     KStdAction::print( TQT_TQOBJECT(mCalendarView), TQT_SLOT( print() ), mACollection );
00251   }
00252 
00253 
00254   //~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT / EXPORT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00255   new TDEAction( i18n("Import &Event/Calendar (ICS-/VCS-File)..."), 0, TQT_TQOBJECT(this), TQT_SLOT( file_merge() ),
00256                mACollection, "import_icalendar" );
00257   new TDEAction( i18n("&Import From UNIX Ical tool (.calendar-File)"), 0, TQT_TQOBJECT(this), TQT_SLOT( file_icalimport() ),
00258                mACollection, "import_ical" );
00259   new TDEAction( i18n("Get &Hot New Stuff..."), 0, this,
00260                TQT_SLOT( downloadNewStuff() ), mACollection,
00261                "downloadnewstuff" );
00262 
00263   new TDEAction( i18n("Export &Web Page..."), "webexport", 0,
00264                TQT_TQOBJECT(mCalendarView), TQT_SLOT( exportWeb() ),
00265                mACollection, "export_web" );
00266   new TDEAction( i18n("&iCalendar..."), 0,
00267                TQT_TQOBJECT(mCalendarView), TQT_SLOT( exportICalendar() ),
00268                mACollection, "export_icalendar" );
00269   new TDEAction( i18n("&vCalendar..."), 0,
00270                TQT_TQOBJECT(mCalendarView), TQT_SLOT( exportVCalendar() ),
00271                mACollection, "export_vcalendar" );
00272   new TDEAction( i18n("Upload &Hot New Stuff..."), 0, TQT_TQOBJECT(this),
00273                TQT_SLOT( uploadNewStuff() ), mACollection,
00274                "uploadnewstuff" );
00275 
00276 
00277 
00278   new TDEAction( i18n("Archive O&ld Entries..."), 0, TQT_TQOBJECT(this), TQT_SLOT( file_archive() ),
00279                     mACollection, "file_archive" );
00280   new TDEAction( i18n("delete completed to-dos", "Pur&ge Completed To-dos"), 0,
00281                TQT_TQOBJECT(mCalendarView), TQT_SLOT( purgeCompleted() ), mACollection,
00282                "purge_completed" );
00283 
00284 
00285 
00286 
00287   //************************** EDIT MENU *********************************
00288   TDEAction *pasteAction;
00289   KOrg::History *h = mCalendarView->history();
00290   if ( mIsPart ) {
00291     // edit menu
00292     mCutAction = KStdAction::cut( TQT_TQOBJECT(mCalendarView), TQT_SLOT( edit_cut() ),
00293                                   mACollection, "korganizer_cut" );
00294     mCopyAction = KStdAction::copy( TQT_TQOBJECT(mCalendarView), TQT_SLOT( edit_copy() ),
00295                                     mACollection, "korganizer_copy" );
00296     pasteAction = KStdAction::paste( TQT_TQOBJECT(mCalendarView), TQT_SLOT( edit_paste() ),
00297                                      mACollection, "korganizer_paste" );
00298     mUndoAction = KStdAction::undo( h, TQT_SLOT( undo() ),
00299                                     mACollection, "korganizer_undo" );
00300     mRedoAction = KStdAction::redo( h, TQT_SLOT( redo() ),
00301                                     mACollection, "korganizer_redo" );
00302   } else {
00303     mCutAction = KStdAction::cut( TQT_TQOBJECT(mCalendarView),TQT_SLOT( edit_cut() ),
00304                                   mACollection );
00305     mCopyAction = KStdAction::copy( TQT_TQOBJECT(mCalendarView),TQT_SLOT( edit_copy() ),
00306                                     mACollection );
00307     pasteAction = KStdAction::paste( TQT_TQOBJECT(mCalendarView),TQT_SLOT( edit_paste() ),
00308                                      mACollection );
00309     mUndoAction = KStdAction::undo( TQT_TQOBJECT(h), TQT_SLOT( undo() ), mACollection );
00310     mRedoAction = KStdAction::redo( TQT_TQOBJECT(h), TQT_SLOT( redo() ), mACollection );
00311   }
00312   mDeleteAction = new TDEAction( i18n("&Delete"), "edit-delete", 0,
00313                                TQT_TQOBJECT(mCalendarView), TQT_SLOT( appointment_delete() ),
00314                                mACollection, "edit_delete" );
00315   if ( mIsPart ) {
00316     KStdAction::find( mCalendarView->dialogManager(), TQT_SLOT( showSearchDialog() ),
00317                       mACollection, "korganizer_find" );
00318   } else {
00319     KStdAction::find( mCalendarView->dialogManager(), TQT_SLOT( showSearchDialog() ),
00320                       mACollection );
00321   }
00322   pasteAction->setEnabled( false );
00323   mUndoAction->setEnabled( false );
00324   mRedoAction->setEnabled( false );
00325   connect( mCalendarView, TQT_SIGNAL( pasteEnabled( bool ) ),
00326            pasteAction, TQT_SLOT( setEnabled( bool ) ) );
00327   connect( h, TQT_SIGNAL( undoAvailable( const TQString & ) ),
00328            TQT_SLOT( updateUndoAction( const TQString & ) ) );
00329   connect( h, TQT_SIGNAL( redoAvailable( const TQString & ) ),
00330            TQT_SLOT( updateRedoAction( const TQString & ) ) );
00331 
00332 
00333 
00334 
00335   //************************** VIEW MENU *********************************
00336 
00337   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VIEWS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00338   new TDEAction( i18n("What's &Next"),
00339                KOGlobals::self()->smallIcon( "whatsnext" ), 0,
00340                mCalendarView->viewManager(), TQT_SLOT( showWhatsNextView() ),
00341                mACollection, "view_whatsnext" );
00342   new TDEAction( i18n("&Day"),
00343                KOGlobals::self()->smallIcon( "1day" ), 0,
00344                mCalendarView->viewManager(), TQT_SLOT( showDayView() ),
00345                mACollection, "view_day" );
00346   mNextXDays = new TDEAction( "",
00347                             KOGlobals::self()->smallIcon( "xdays" ), 0,
00348                             mCalendarView->viewManager(),
00349                             TQT_SLOT( showNextXView() ),
00350                             mACollection, "view_nextx" );
00351   mNextXDays->setText( i18n( "&Next Day", "Ne&xt %n Days",
00352                              KOPrefs::instance()->mNextXDays ) );
00353   new TDEAction( i18n("W&ork Week"),
00354                KOGlobals::self()->smallIcon( "5days" ), 0,
00355                mCalendarView->viewManager(), TQT_SLOT( showWorkWeekView() ),
00356                mACollection, "view_workweek" );
00357   new TDEAction( i18n("&Week"),
00358                KOGlobals::self()->smallIcon( "7days" ), 0,
00359                mCalendarView->viewManager(), TQT_SLOT( showWeekView() ),
00360                mACollection, "view_week" );
00361   new TDEAction( i18n("&Month"),
00362                KOGlobals::self()->smallIcon( "month" ), 0,
00363                mCalendarView->viewManager(), TQT_SLOT( showMonthView() ),
00364                mACollection, "view_month" );
00365   new TDEAction( i18n("&List"),
00366                KOGlobals::self()->smallIcon( "list" ), 0,
00367                mCalendarView->viewManager(), TQT_SLOT( showListView() ),
00368                mACollection, "view_list" );
00369   new TDEAction( i18n("&To-do List"),
00370                KOGlobals::self()->smallIcon( "todo" ), 0,
00371                mCalendarView->viewManager(), TQT_SLOT( showTodoView() ),
00372                mACollection, "view_todo" );
00373   new TDEAction( i18n("&Journal"),
00374                KOGlobals::self()->smallIcon( "journal" ), 0,
00375                mCalendarView->viewManager(), TQT_SLOT( showJournalView() ),
00376                mACollection, "view_journal" );
00377   new TDEAction( i18n("&Timeline View"),
00378                KOGlobals::self()->smallIcon( "timeline" ), 0,
00379                mCalendarView->viewManager(), TQT_SLOT( showTimelineView() ),
00380                mACollection, "view_timeline" );
00381 
00382   //~~~~~~~~~~~~~~~~~~~~~~~~~~~ FILTERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00383   new TDEAction( i18n("&Refresh"), 0,
00384                     TQT_TQOBJECT(mCalendarView), TQT_SLOT( updateView() ),
00385                     mACollection, "update" );
00386 // TODO:
00387 //   new TDEAction( i18n("Hide &Completed To-dos"), 0,
00388 //                     mCalendarView, TQT_SLOT( toggleHideCompleted() ),
00389 //                     mACollection, "hide_completed_todos" );
00390 
00391   mFilterAction = new TDESelectAction( i18n("F&ilter"), 0,
00392                   mACollection, "filter_select" );
00393   mFilterAction->setEditable( false );
00394   connect( mFilterAction, TQT_SIGNAL( activated(int) ),
00395            mCalendarView, TQT_SLOT( filterActivated( int ) ) );
00396   connect( mCalendarView, TQT_SIGNAL( newFilterListSignal( const TQStringList & ) ),
00397            mFilterAction, TQT_SLOT( setItems( const TQStringList & ) ) );
00398   connect( mCalendarView, TQT_SIGNAL( selectFilterSignal( int ) ),
00399            mFilterAction, TQT_SLOT( setCurrentItem( int ) ) );
00400   connect( mCalendarView, TQT_SIGNAL( filterChanged() ),
00401            TQT_TQOBJECT(this), TQT_SLOT( setTitle() ) );
00402 
00403 
00404   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ZOOM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00405   // TODO: try to find / create better icons for the following 4 actions
00406   new TDEAction( i18n( "Zoom In Horizontally" ), "zoom-in", 0,
00407                     mCalendarView->viewManager(), TQT_SLOT( zoomInHorizontally() ),
00408                     mACollection, "zoom_in_horizontally" );
00409   new TDEAction( i18n( "Zoom Out Horizontally" ), "zoom-out", 0,
00410                     mCalendarView->viewManager(), TQT_SLOT( zoomOutHorizontally() ),
00411                     mACollection, "zoom_out_horizontally" );
00412   new TDEAction( i18n( "Zoom In Vertically" ), "zoom-in", 0,
00413                     mCalendarView->viewManager(), TQT_SLOT( zoomInVertically() ),
00414                     mACollection, "zoom_in_vertically" );
00415   new TDEAction( i18n( "Zoom Out Vertically" ), "zoom-out", 0,
00416                     mCalendarView->viewManager(), TQT_SLOT( zoomOutVertically() ),
00417                     mACollection, "zoom_out_vertically" );
00418 
00419 
00420 
00421 
00422   //************************** Actions MENU *********************************
00423 
00424   new TDEAction( i18n("Go to &Today"), "today", 0,
00425                     TQT_TQOBJECT(mCalendarView),TQT_SLOT( goToday() ),
00426                     mACollection, "go_today" );
00427   bool isRTL = TQApplication::reverseLayout();
00428   action = new TDEAction( i18n("Go &Backward"), isRTL ? "forward" : "back", 0,
00429                         TQT_TQOBJECT(mCalendarView),TQT_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, TQT_SIGNAL( changeNavStringPrev( const TQString & ) ),
00436            action, TQT_SLOT( setText( const TQString & ) ) );
00437   connect( mCalendarView, TQT_SIGNAL( changeNavStringPrev( const TQString & ) ),
00438            TQT_TQOBJECT(this), TQT_SLOT( dumpText( const TQString & ) ) );*/
00439 
00440   action = new TDEAction( i18n("Go &Forward"), isRTL ? "back" : "forward", 0,
00441                         TQT_TQOBJECT(mCalendarView),TQT_SLOT( goNext() ),
00442                         mACollection, "go_next" );
00443   /*
00444   connect( mCalendarView,TQT_SIGNAL( changeNavStringNext( const TQString & ) ),
00445            action,TQT_SLOT( setText( const TQString & ) ) );
00446   */
00447 
00448 
00449   //************************** Actions MENU *********************************
00450   new TDEAction( i18n("New E&vent..."),
00451                KOGlobals::self()->smallIcon( "newappointment" ), 0,
00452                TQT_TQOBJECT(mCalendarView), TQT_SLOT(newEvent()),
00453                mACollection, "new_event" );
00454   new TDEAction( i18n("New &To-do..."),
00455                KOGlobals::self()->smallIcon( "newtodo" ), 0,
00456                TQT_TQOBJECT(mCalendarView), TQT_SLOT(newTodo()),
00457                mACollection, "new_todo" );
00458   action = new TDEAction( i18n("New Su&b-to-do..."), 0,
00459                         TQT_TQOBJECT(mCalendarView),TQT_SLOT( newSubTodo() ),
00460                         mACollection, "new_subtodo" );
00461   action->setEnabled( false );
00462   connect( mCalendarView,TQT_SIGNAL( todoSelected( bool ) ),
00463            action,TQT_SLOT( setEnabled( bool ) ) );
00464   new TDEAction( i18n("New &Journal..."),
00465                KOGlobals::self()->smallIcon( "newjournal" ), 0,
00466                TQT_TQOBJECT(mCalendarView), TQT_SLOT(newJournal()),
00467                mACollection, "new_journal" );
00468 
00469   mShowIncidenceAction = new TDEAction( i18n("&Show"), 0,
00470                                       TQT_TQOBJECT(mCalendarView),TQT_SLOT( showIncidence() ),
00471                                       mACollection, "show_incidence" );
00472   mEditIncidenceAction = new TDEAction( i18n("&Edit..."), 0,
00473                                       TQT_TQOBJECT(mCalendarView),TQT_SLOT( editIncidence() ),
00474                                       mACollection, "edit_incidence" );
00475   mDeleteIncidenceAction = new TDEAction( i18n("&Delete"), Key_Delete,
00476                                         TQT_TQOBJECT(mCalendarView),TQT_SLOT( deleteIncidence()),
00477                                         mACollection, "delete_incidence" );
00478 
00479   action = new TDEAction( i18n("&Make Sub-to-do Independent"), 0,
00480                         TQT_TQOBJECT(mCalendarView),TQT_SLOT( todo_unsub() ),
00481                         mACollection, "unsub_todo" );
00482   action->setEnabled( false );
00483   connect( mCalendarView,TQT_SIGNAL( subtodoSelected( bool ) ),
00484            action,TQT_SLOT( setEnabled( bool ) ) );
00485 // TODO: Add item to move the incidence to different resource
00486 //   mAssignResourceAction = new TDEAction( i18n("Assign &Resource..."), 0,
00487 //                                        mCalendarView, TQT_SLOT( assignResource()),
00488 //                                        mACollection, "assign_resource" );
00489 // TODO: Add item to quickly toggle the reminder of a given incidence
00490 //   mToggleAlarmAction = new TDEToggleAction( i18n("&Activate Reminder"), 0,
00491 //                                         mCalendarView, TQT_SLOT( toggleAlarm()),
00492 //                                         mACollection, "activate_alarm" );
00493 
00494 
00495 
00496 
00497   //************************** SCHEDULE MENU ********************************
00498   mPublishEvent = new TDEAction( i18n("&Publish Item Information..."), "mail-send", 0,
00499                                TQT_TQOBJECT(mCalendarView), TQT_SLOT( schedule_publish() ),
00500                                mACollection, "schedule_publish" );
00501   mPublishEvent->setEnabled( false );
00502 
00503   mSendInvitation = new TDEAction( i18n( "Send &Invitation to Attendees" ),
00504                                  "mail_generic", 0,
00505                                  TQT_TQOBJECT(mCalendarView), TQT_SLOT(schedule_request()),
00506                                  mACollection, "schedule_request" );
00507   mSendInvitation->setEnabled( false );
00508   connect( mCalendarView, TQT_SIGNAL(organizerEventsSelected(bool)),
00509            mSendInvitation, TQT_SLOT(setEnabled(bool)) );
00510 
00511   mRequestUpdate = new TDEAction( i18n( "Re&quest Update" ), 0,
00512                                 TQT_TQOBJECT(mCalendarView), TQT_SLOT(schedule_refresh()),
00513                                 mACollection, "schedule_refresh" );
00514   mRequestUpdate->setEnabled( false );
00515   connect( mCalendarView, TQT_SIGNAL(groupEventsSelected(bool)),
00516            mRequestUpdate, TQT_SLOT(setEnabled(bool)) );
00517 
00518   mSendCancel = new TDEAction( i18n( "Send &Cancelation to Attendees" ), 0,
00519                              TQT_TQOBJECT(mCalendarView), TQT_SLOT(schedule_cancel()),
00520                              mACollection, "schedule_cancel" );
00521   mSendCancel->setEnabled( false );
00522   connect( mCalendarView, TQT_SIGNAL(organizerEventsSelected(bool)),
00523            mSendCancel, TQT_SLOT(setEnabled(bool)) );
00524 
00525   mSendStatusUpdate = new TDEAction( i18n( "Send Status &Update" ),
00526                                    "mail-reply-sender", 0,
00527                                    TQT_TQOBJECT(mCalendarView),TQT_SLOT(schedule_reply()),
00528                                    mACollection, "schedule_reply" );
00529   mSendStatusUpdate->setEnabled( false );
00530   connect( mCalendarView, TQT_SIGNAL(groupEventsSelected(bool)),
00531            mSendStatusUpdate, TQT_SLOT(setEnabled(bool)) );
00532 
00533   mRequestChange = new TDEAction( i18n( "counter proposal", "Request Chan&ge" ), 0,
00534                                 TQT_TQOBJECT(mCalendarView), TQT_SLOT(schedule_counter()),
00535                                 mACollection, "schedule_counter" );
00536   mRequestChange->setEnabled( false );
00537   connect( mCalendarView, TQT_SIGNAL(groupEventsSelected(bool)),
00538            mRequestChange, TQT_SLOT(setEnabled(bool)) );
00539 
00540   mForwardEvent = new TDEAction( i18n("&Send as iCalendar..."), "mail-forward", 0,
00541                                TQT_TQOBJECT(mCalendarView), TQT_SLOT(schedule_forward()),
00542                                mACollection, "schedule_forward" );
00543   mForwardEvent->setEnabled( false );
00544 
00545   action = new TDEAction( i18n("&Mail Free Busy Information..."), 0,
00546                         TQT_TQOBJECT(mCalendarView), TQT_SLOT( mailFreeBusy() ),
00547                         mACollection, "mail_freebusy" );
00548   action->setEnabled( true );
00549 
00550   action = new TDEAction( i18n("&Upload Free Busy Information"), 0,
00551                         TQT_TQOBJECT(mCalendarView), TQT_SLOT( uploadFreeBusy() ),
00552                         mACollection, "upload_freebusy" );
00553   action->setEnabled( true );
00554 
00555   if ( !mIsPart ) {
00556       action = new TDEAction( i18n("&Addressbook"),"contents",0,
00557                             TQT_TQOBJECT(mCalendarView),TQT_SLOT( openAddressbook() ),
00558                             mACollection,"addressbook" );
00559   }
00560 
00561 
00562 
00563 
00564   //************************** SETTINGS MENU ********************************
00565 
00566   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIDEBAR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00567   mDateNavigatorShowAction = new TDEToggleAction( i18n("Show Date Navigator"), 0,
00568                       TQT_TQOBJECT(this), TQT_SLOT( toggleDateNavigator() ),
00569                       mACollection, "show_datenavigator" );
00570   mTodoViewShowAction = new TDEToggleAction ( i18n("Show To-do View"), 0,
00571                       TQT_TQOBJECT(this), TQT_SLOT( toggleTodoView() ),
00572                       mACollection, "show_todoview" );
00573   mEventViewerShowAction = new TDEToggleAction ( i18n("Show Item Viewer"), 0,
00574                       TQT_TQOBJECT(this), TQT_SLOT( toggleEventViewer() ),
00575                       mACollection, "show_eventviewer" );
00576   TDEConfig *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 TDEToggleAction ( i18n("Show Resource View"), 0,
00593                         TQT_TQOBJECT(this), TQT_SLOT( toggleResourceView() ),
00594                         mACollection, "show_resourceview" );
00595     mResourceButtonsAction = new TDEToggleAction( i18n("Show &Resource Buttons"), 0,
00596                         TQT_TQOBJECT(this), TQT_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 TDEAction( i18n("Configure &Date && Time..."), 0,
00611                     TQT_TQOBJECT(this), TQT_SLOT( configureDateTime() ),
00612                     mACollection, "conf_datetime" );
00613 // TODO: Add an item to show the resource management dlg
00614 //   new TDEAction( i18n("Manage &Resources..."), 0,
00615 //                     TQT_TQOBJECT(this), TQT_SLOT( manageResources() ),
00616 //                     mACollection, "conf_resources" );
00617   new TDEAction( i18n("Manage View &Filters..."), "configure", 0,
00618                TQT_TQOBJECT(mCalendarView), TQT_SLOT( editFilters() ),
00619                mACollection, "edit_filters" );
00620   new TDEAction( i18n("Manage C&ategories..."), 0,
00621                TQT_TQOBJECT(mCalendarView->dialogManager()), TQT_SLOT( showCategoryEditDialog() ),
00622                mACollection, "edit_categories" );
00623   if ( mIsPart ) {
00624     new TDEAction( i18n("&Configure Calendar..."), "configure", 0,
00625                  TQT_TQOBJECT(mCalendarView), TQT_SLOT( edit_options() ),
00626                  mACollection, "korganizer_configure" );
00627     KStdAction::keyBindings( TQT_TQOBJECT(this), TQT_SLOT( keyBindings() ),
00628                              mACollection, "korganizer_configure_shortcuts" );
00629   } else {
00630     KStdAction::preferences( TQT_TQOBJECT(mCalendarView), TQT_SLOT( edit_options() ),
00631                             mACollection );
00632     KStdAction::keyBindings( TQT_TQOBJECT(this), TQT_SLOT( keyBindings() ), mACollection );
00633   }
00634 
00635 
00636 
00637 
00638   //**************************** HELP MENU **********************************
00639   KStdAction::tipOfDay( TQT_TQOBJECT(this), TQT_SLOT( showTip() ), mACollection,
00640                         "help_tipofday" );
00641 //   new TDEAction( i18n("Show Intro Page"), 0,
00642 //                     mCalendarView,TQT_SLOT( showIntro() ),
00643 //                     mACollection,"show_intro" );
00644 
00645 
00646 
00647 
00648   //************************* TOOLBAR ACTIONS *******************************
00649   TQLabel *filterLabel = new TQLabel( 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 TDEConfig, supplying reasonable
00659   // defaults where none are to be found
00660 
00661   TDEConfig *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   TDEConfig *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   TQString 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   TQString progPath;
00746   KTempFile tmpfn;
00747 
00748   TQString homeDir = TQDir::homeDirPath() + TQString::fromLatin1( "/.calendar" );
00749 
00750   if ( !TQFile::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   TDEProcess proc;
00758   proc << "ical2vcal" << tmpfn.name();
00759   bool success = proc.start( TDEProcess::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   TDEIO::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 ( !TDEStandardDirs::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     TQString tmpFile;
00886     if( TDEIO::NetAccess::download( url, tmpFile, view() ) ) {
00887       kdDebug(5850) << "--- Downloaded to " << tmpFile << endl;
00888       bool success = mCalendarView->openCalendar( tmpFile, merge );
00889       if ( merge ) {
00890         TDEIO::NetAccess::removeTempFile( tmpFile );
00891         if ( success )
00892           showStatusMessageOpen( url, merge );
00893       } else {
00894         if ( success ) {
00895           TDEIO::NetAccess::removeTempFile( mFile );
00896           mURL = url;
00897           mFile = tmpFile;
00898           TDEConfig *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       TQString 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   TQString 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     TQString 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   TQString 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     TQString 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 ( !TDEIO::NetAccess::upload( mFile, mURL, view() ) ) {
01020       TQString 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 tdeconfigxt objects don't
01042   // seem to load the config theirselves
01043   settings.readConfig();
01044 
01045   TQDate qd1;
01046   qd1 = TQDate::currentDate();
01047   TQDate qd2;
01048   qd2 = TQDate::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 ( TQFileInfo( 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   TQDate cdate = settings->dateStart().date();
01076   TQDate qd2 = settings->dateEnd().date();
01077   while ( cdate <= qd2 ) {
01078     TQStringList holidays = KOGlobals::self()->holiday( cdate );
01079     if ( !holidays.isEmpty() ) {
01080       TQStringList::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     TQString tfile = tf.name();
01094     tf.close();
01095     mExport.save( tfile );
01096     if ( !TDEIO::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   TQString 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     TDEIO::NetAccess::removeTempFile( fileOrig );
01134     TDEConfig *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         TQString(),
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   TQString filename = url.fileName( false );
01197 
01198   TQString 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( TDEConfig *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( TDEConfig *config )
01222 {
01223   kdDebug(5850) << "ActionManager::readProperties" << endl;
01224 
01225   bool isResourceCalendar(
01226     config->readBoolEntry( "UseResourceCalendar", true ) );
01227   TQString 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   TDEProcess *proc = new TDEProcess;
01294   *proc << "tdecmshell" << "language";
01295 
01296   connect( proc,TQT_SIGNAL( processExited( TDEProcess * ) ),
01297           TQT_SLOT( configureDateTimeFinished( TDEProcess * ) ) );
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(),TQString(),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 TQString &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 TQString &url )
01369 {
01370   return openURL( KURL( url ) );
01371 }
01372 
01373 bool ActionManager::mergeURL( const TQString &url )
01374 {
01375   return openURL( KURL( url ),true );
01376 }
01377 
01378 bool ActionManager::saveAsURL( const TQString &url )
01379 {
01380   return saveAsURL( KURL( url ) );
01381 }
01382 
01383 TQString ActionManager::getCurrentURLasString() const
01384 {
01385   return mURL.url();
01386 }
01387 
01388 bool ActionManager::editIncidence( const TQString &uid )
01389 {
01390   return mCalendarView->editIncidence( uid );
01391 }
01392 
01393 bool ActionManager::editIncidence( const TQString &uid, const TQDate &date )
01394 {
01395   return mCalendarView->editIncidence( uid, date );
01396 }
01397 
01398 bool ActionManager::deleteIncidence( const TQString& uid, bool force )
01399 {
01400   return mCalendarView->deleteIncidence( uid, force );
01401 }
01402 
01403 bool ActionManager::addIncidence( const TQString& ical )
01404 {
01405   return mCalendarView->addIncidence( ical );
01406 }
01407 
01408 void ActionManager::configureDateTimeFinished( TDEProcess *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 TQString 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, TDEAction *show, TDEAction *edit, TDEAction *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     TDEAction *mShow;
01467     TDEAction *mEdit;
01468     TDEAction *mDelete;
01469 };
01470 
01471 void ActionManager::processIncidenceSelection( Incidence *incidence, const TQDate & )
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 TQValueList<TQPair<TQDateTime, TQDateTime> >&,
01538  const TQCString& resource,
01539  const TQString& 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 TQPair<ResourceCalendar *, TQString> ActionManager::viewSubResourceCalendar()
01548 {
01549   TQPair<ResourceCalendar *, TQString> p( 0, TQString() );
01550 
01551   // return now if we are running as a part and we aren't the currently active part
01552   if ( mIsPart && !mMainWindow->isCurrentlyActivePart() ) {
01553     return p;
01554   }
01555 
01556   KOrg::BaseView *cV = mCalendarView->viewManager()->currentView();
01557   if ( cV && cV == mCalendarView->viewManager()->multiAgendaView() ) {
01558     cV = mCalendarView->viewManager()->multiAgendaView()->selectedAgendaView();
01559   }
01560   if ( cV ) {
01561     p = tqMakePair( cV->resourceCalendar(), cV->subResourceCalendar() );
01562   }
01563   return p;
01564 }
01565 
01566 bool ActionManager::isWritable( ResourceCalendar *res, const TQString &subRes,
01567                                 const TQString &contentsType )
01568 {
01569 
01570   if ( res && res->isActive() ) {
01571     // Check specified resource for writability.
01572     if ( res->readOnly() || !res->subresourceWritable( subRes ) ) {
01573       TQString resName = res->resourceName();
01574       if ( res->canHaveSubresources() ) {
01575         resName = res->labelForSubresource( subRes );
01576       }
01577       KMessageBox::sorry(
01578         dialogParent(),
01579         i18n( "\"%1\" is read-only. "
01580               "Please select a writable calendar before attempting to create a new item." ).
01581         arg( resName ),
01582         i18n( "Read-only calendar" ) );
01583       return false;
01584     } else {
01585       return true;
01586     }
01587   } else {
01588     // No specific resource so let's check all possible calendars for writability.
01589     CalendarResourceManager *m = mCalendarResources->resourceManager();
01590     CalendarResourceManager::ActiveIterator it;
01591     for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
01592       ResourceCalendar *res = (*it);
01593       if ( res->canHaveSubresources() ) {
01594         TQStringList subResources = res->subresources();
01595         for ( TQStringList::ConstIterator subit = subResources.constBegin();
01596               subit != subResources.constEnd(); ++subit ) {
01597           if ( res->subresourceWritable( (*subit) ) && res->subresourceActive( (*subit) ) ) {
01598             if ( res->subresourceType( *subit ).isEmpty() ||
01599                  res->subresourceType( *subit ) == contentsType ) {
01600               return true;
01601             }
01602           }
01603         }
01604       } else if ( !res->readOnly() ) {
01605         return true;
01606       }
01607     }
01608     //  we don't have any writable calendars
01609     TQString errorText;
01610     if ( contentsType == "event" ) {
01611       errorText =
01612         i18n( "You have no active, writable event folder so saving will not be possible.\n"
01613               "Please create or activate at least one writable event folder and try again." );
01614     } else if ( contentsType == "todo" ) {
01615       errorText =
01616         i18n( "You have no active, writable to-do (task) folders so saving will not be possible.\n"
01617               "Please create or activate at least one writable to-do folder and try again." );
01618     } else if ( contentsType == "journal" ) {
01619       errorText =
01620         i18n( "You have no active, writable journal folder so saving will not be possible.\n"
01621               "Please create or activate at least one writable journal folder and try again." );
01622     } else {
01623       errorText =
01624         i18n( "You have no active, writable calendar folder so saving will not be possible.\n"
01625               "Please create or activate at least one writable calendar folder and try again." );
01626     }
01627     KMessageBox::sorry(
01628       dialogParent(),
01629       errorText,
01630       i18n( "No writable calendar" ) );
01631     return false;
01632   }
01633 }
01634 
01635 void ActionManager::openEventEditor( const TQString& text )
01636 {
01637   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01638   if ( isWritable( p.first, p.second, "event" ) ) {
01639     mCalendarView->newEvent( p.first, p.second, text );
01640   }
01641 }
01642 
01643 void ActionManager::openEventEditor( const TQString& summary,
01644                                      const TQString& description,
01645                                      const TQString& attachment )
01646 {
01647   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01648   mCalendarView->newEvent( p.first, p.second, summary, description, attachment );
01649 }
01650 
01651 void ActionManager::openEventEditor( const TQString& summary,
01652                                      const TQString& description,
01653                                      const TQString& attachment,
01654                                      const TQStringList& attendees )
01655 {
01656   mCalendarView->newEvent( 0,  TQString(), summary, description, attachment, attendees );
01657 }
01658 
01659 void ActionManager::openEventEditor( const TQString & summary,
01660                                      const TQString & description,
01661                                      const TQString & uri,
01662                                      const TQString & file,
01663                                      const TQStringList & attendees,
01664                                      const TQString & attachmentMimetype )
01665 {
01666   int action = KOPrefs::instance()->defaultEmailAttachMethod();
01667   if ( attachmentMimetype != "message/rfc822" ) {
01668     action = KOPrefs::Link;
01669   } else if ( KOPrefs::instance()->defaultEmailAttachMethod() == KOPrefs::Ask ) {
01670     TDEPopupMenu *menu = new TDEPopupMenu( 0 );
01671     menu->insertItem( i18n("Attach as &link"), KOPrefs::Link );
01672     menu->insertItem( i18n("Attach &inline"), KOPrefs::InlineFull );
01673     menu->insertItem( i18n("Attach inline &without attachments"), KOPrefs::InlineBody );
01674     menu->insertSeparator();
01675     menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::Ask );
01676     action = menu->exec( TQCursor::pos(), 0 );
01677     delete menu;
01678   }
01679 
01680   TQString attData;
01681   KTempFile tf;
01682   tf.setAutoDelete( true );
01683   switch ( action ) {
01684     case KOPrefs::Ask:
01685       return;
01686     case KOPrefs::Link:
01687       attData = uri;
01688       break;
01689     case KOPrefs::InlineFull:
01690       attData = file;
01691       break;
01692     case KOPrefs::InlineBody:
01693     {
01694       TQFile f( file );
01695       if ( !f.open( IO_ReadOnly ) )
01696         return;
01697       KMime::Message *msg = new KMime::Message();
01698       msg->setContent( TQCString( f.readAll() ) );
01699       TQCString head = msg->head();
01700       msg->parse();
01701       if ( msg == msg->textContent() || msg->textContent() == 0 ) { // no attachments
01702         attData = file;
01703       } else {
01704         if ( KMessageBox::warningContinueCancel( 0,
01705               i18n("Removing attachments from an email might invalidate its signature."),
01706               i18n("Remove Attachments"), KStdGuiItem::cont(), "BodyOnlyInlineAttachment" )
01707               != KMessageBox::Continue )
01708           return;
01709         // due to kmime shortcomings in KDE3, we need to assemble the result manually
01710         int begin = 0;
01711         int end = head.find( '\n' );
01712         bool skipFolded = false;
01713         while ( end >= 0 && end > begin ) {
01714           if ( head.find( "Content-Type:", begin, false ) != begin &&
01715                 head.find( "Content-Transfer-Encoding:", begin, false ) != begin &&
01716                 !(skipFolded && (head[begin] == ' ' || head[end] == '\t')) ) {
01717             TQCString line = head.mid( begin, end - begin );
01718             tf.file()->writeBlock( line.data(), line.length() );
01719             tf.file()->writeBlock( "\n", 1 );
01720             skipFolded = false;
01721           } else {
01722             skipFolded = true;
01723           }
01724 
01725           begin = end + 1;
01726           end = head.find( '\n', begin );
01727           if ( end < 0 && begin < (int)head.length() )
01728             end = head.length() - 1;
01729         }
01730         TQCString cte = msg->textContent()->contentTransferEncoding()->as7BitString();
01731         if ( !cte.stripWhiteSpace().isEmpty() ) {
01732           tf.file()->writeBlock( cte.data(), cte.length() );
01733           tf.file()->writeBlock( "\n", 1 );
01734         }
01735         TQCString ct = msg->textContent()->contentType()->as7BitString();
01736         if ( !ct.stripWhiteSpace().isEmpty() )
01737           tf.file()->writeBlock( ct.data(), ct.length() );
01738         tf.file()->writeBlock( "\n", 1 );
01739         tf.file()->writeBlock( msg->textContent()->body() );
01740         attData = tf.name();
01741       }
01742       tf.close();
01743       delete msg;
01744       break;
01745     }
01746     default:
01747       // menu could have been closed by cancel, if so, do nothing
01748       return;
01749   }
01750 
01751   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01752   mCalendarView->newEvent( p.first, p.second, summary, description, attData,
01753                            attendees, attachmentMimetype, action != KOPrefs::Link );
01754 }
01755 
01756 void ActionManager::openTodoEditor( const TQString& text )
01757 {
01758   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01759   if ( isWritable( p.first, p.second, "todo" ) ) {
01760     mCalendarView->newTodo( p.first, p.second, text );
01761   }
01762 }
01763 
01764 void ActionManager::openTodoEditor( const TQString& summary,
01765                                     const TQString& description,
01766                                     const TQString& attachment )
01767 {
01768   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01769   mCalendarView->newTodo( p.first, p.second, summary, description, attachment );
01770 }
01771 
01772 void ActionManager::openTodoEditor( const TQString& summary,
01773                                     const TQString& description,
01774                                     const TQString& attachment,
01775                                     const TQStringList& attendees )
01776 {
01777   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01778   mCalendarView->newTodo( p.first, p.second, summary, description, attachment, attendees );
01779 }
01780 
01781 void ActionManager::openTodoEditor(const TQString & summary,
01782                                    const TQString & description,
01783                                    const TQString & uri,
01784                                    const TQString & file,
01785                                    const TQStringList & attendees,
01786                                    const TQString & attachmentMimetype,
01787                                    bool isTask )
01788 {
01789   int action = KOPrefs::instance()->defaultTodoAttachMethod();
01790   if ( attachmentMimetype != "message/rfc822" ) {
01791     action = KOPrefs::TodoAttachLink;
01792   } else if ( KOPrefs::instance()->defaultTodoAttachMethod() == KOPrefs::TodoAttachAsk ) {
01793     TDEPopupMenu *menu = new TDEPopupMenu( 0 );
01794     menu->insertItem( i18n("Attach as &link"), KOPrefs::TodoAttachLink );
01795     menu->insertItem( i18n("Attach &inline"), KOPrefs::TodoAttachInlineFull );
01796     menu->insertSeparator();
01797     menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::TodoAttachAsk );
01798     action = menu->exec( TQCursor::pos(), 0 );
01799     delete menu;
01800   }
01801 
01802   TQStringList attData;
01803   switch ( action ) {
01804     case KOPrefs::TodoAttachAsk:
01805       return;
01806     case KOPrefs::TodoAttachLink:
01807       attData << uri;
01808       break;
01809   case KOPrefs::TodoAttachInlineFull:
01810       attData << file;
01811       break;
01812     default:
01813       // menu could have been closed by cancel, if so, do nothing
01814       return;
01815   }
01816 
01817   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01818   mCalendarView->newTodo( p.first, p.second,
01819                           summary, description,
01820                           attData, attendees,
01821                           TQStringList( attachmentMimetype ),
01822                           action != KOPrefs::TodoAttachLink,
01823                           isTask );
01824 }
01825 
01826 void ActionManager::openJournalEditor( const TQDate& date )
01827 {
01828   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01829   mCalendarView->newJournal( p.first, p.second, date );
01830 }
01831 
01832 void ActionManager::openJournalEditor( const TQString& text, const TQDate& date )
01833 {
01834   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01835   mCalendarView->newJournal( p.first, p.second, text, date );
01836 }
01837 
01838 void ActionManager::openJournalEditor( const TQString& text )
01839 {
01840   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01841   if ( isWritable( p.first, p.second, "journal" ) ) {
01842     mCalendarView->newJournal( p.first, p.second, text );
01843   }
01844 }
01845 
01846 //TODO:
01847 // void ActionManager::openJournalEditor( const TQString& summary,
01848 //                                        const TQString& description,
01849 //                                        const TQString& attachment )
01850 // {
01851 //   TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
01852 //   mCalendarView->newJournal( p.first, p.second, summary, description, attachment );
01853 // }
01854 
01855 
01856 void ActionManager::showJournalView()
01857 {
01858   mCalendarView->viewManager()->showJournalView();
01859 }
01860 
01861 void ActionManager::showTodoView()
01862 {
01863   mCalendarView->viewManager()->showTodoView();
01864 }
01865 
01866 void ActionManager::showEventView()
01867 {
01868   mCalendarView->viewManager()->showEventView();
01869 }
01870 
01871 void ActionManager::goDate( const TQDate& date )
01872 {
01873   mCalendarView->goDate( date );
01874 }
01875 
01876 void ActionManager::goDate( const TQString& date )
01877 {
01878   goDate( TDEGlobal::locale()->readDate( date ) );
01879 }
01880 
01881 void ActionManager::showDate(const TQDate & date)
01882 {
01883   mCalendarView->showDate( date );
01884 }
01885 
01886 
01887 void ActionManager::updateUndoAction( const TQString &text )
01888 {
01889   if ( text.isNull() ) {
01890     mUndoAction->setEnabled( false );
01891     mUndoAction->setText( i18n("Undo") );
01892   } else {
01893     mUndoAction->setEnabled( true );
01894     if ( text.isEmpty() ) mUndoAction->setText( i18n("Undo") );
01895     else mUndoAction->setText( i18n("Undo (%1)").arg( text ) );
01896   }
01897 }
01898 
01899 void ActionManager::updateRedoAction( const TQString &text )
01900 {
01901   if ( text.isNull() ) {
01902     mRedoAction->setEnabled( false );
01903     mRedoAction->setText( i18n( "Redo" ) );
01904   } else {
01905     mRedoAction->setEnabled( true );
01906     if ( text.isEmpty() ) mRedoAction->setText( i18n("Redo") );
01907     else mRedoAction->setText( i18n( "Redo (%1)" ).arg( text ) );
01908   }
01909 }
01910 
01911 bool ActionManager::queryClose()
01912 {
01913   kdDebug(5850) << "ActionManager::queryClose()" << endl;
01914 
01915   bool close = true;
01916 
01917   if ( mCalendar && mCalendar->isModified() ) {
01918     int res = KMessageBox::questionYesNoCancel( dialogParent(),
01919       i18n("The calendar contains unsaved changes. Do you want to save them before exiting?"), TQString(), KStdGuiItem::save(), KStdGuiItem::discard() );
01920     // Exit on yes and no, don't exit on cancel. If saving fails, ask for exiting.
01921     if ( res == KMessageBox::Yes ) {
01922       close = saveModifiedURL();
01923       if ( !close ) {
01924         int res1 = KMessageBox::questionYesNo( dialogParent(), i18n("Unable to save the calendar. Do you still want to close this window?"), TQString(), KStdGuiItem::close(), KStdGuiItem::cancel() );
01925         close = ( res1 == KMessageBox::Yes );
01926       }
01927     } else {
01928       close = ( res == KMessageBox::No );
01929     }
01930   } else if ( mCalendarResources ) {
01931     if ( !mIsClosing ) {
01932       kdDebug(5850) << "!mIsClosing" << endl;
01933       if ( !saveResourceCalendar() ) return false;
01934 
01935       // FIXME: Put main window into a state indicating final saving.
01936       mIsClosing = true;
01937 // FIXME: Close main window when save is finished
01938 //      connect( mCalendarResources, TQT_SIGNAL( calendarSaved() ),
01939 //               mMainWindow, TQT_SLOT( close() ) );
01940     }
01941     if ( mCalendarResources->isSaving() ) {
01942       kdDebug(5850) << "ActionManager::queryClose(): isSaving" << endl;
01943       close = false;
01944       KMessageBox::information( dialogParent(),
01945           i18n("Unable to exit. Saving still in progress.") );
01946     } else {
01947       kdDebug(5850) << "ActionManager::queryClose(): close = true" << endl;
01948       close = true;
01949     }
01950   } else {
01951     close = true;
01952   }
01953 
01954   return close;
01955 }
01956 
01957 void ActionManager::saveCalendar()
01958 {
01959   if ( mCalendar ) {
01960     if ( view()->isModified() ) {
01961       if ( !url().isEmpty() ) {
01962         saveURL();
01963       } else {
01964         TQString location = locateLocal( "data", "korganizer/kontact.ics" );
01965         saveAsURL( location );
01966       }
01967     }
01968   } else if ( mCalendarResources ) {
01969     mCalendarResources->save();
01970     // FIXME: Make sure that asynchronous saves don't fail.
01971   }
01972 }
01973 
01974 bool ActionManager::saveResourceCalendar()
01975 {
01976   if ( !mCalendarResources ) return false;
01977   CalendarResourceManager *m = mCalendarResources->resourceManager();
01978 
01979   CalendarResourceManager::ActiveIterator it;
01980   for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
01981     if ( (*it)->readOnly() ) continue;
01982     if ( !(*it)->save() ) {
01983       int result = KMessageBox::warningContinueCancel( view(),
01984         i18n( "Saving of '%1' failed. Check that the resource is "
01985              "properly configured.\nIgnore problem and continue without "
01986              "saving or cancel save?" ).arg( (*it)->resourceName() ),
01987         i18n("Save Error"), KStdGuiItem::dontSave() );
01988       if ( result == KMessageBox::Cancel ) return false;
01989     }
01990   }
01991   return true;
01992 }
01993 
01994 void ActionManager::loadResourceCalendar()
01995 {
01996   if ( !mCalendarResources ) return;
01997   CalendarResourceManager *m = mCalendarResources->resourceManager();
01998 
01999   CalendarResourceManager::ActiveIterator it;
02000   for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
02001     (*it)->load();
02002   }
02003 }
02004 
02005 void ActionManager::importCalendar( const KURL &url )
02006 {
02007   if ( !url.isValid() ) {
02008     KMessageBox::error( dialogParent(),
02009                         i18n("URL '%1' is invalid.").arg( url.prettyURL() ) );
02010     return;
02011   }
02012 
02013   PreviewDialog *dialog;
02014   dialog = new PreviewDialog( url, mMainWindow->topLevelWidget() );
02015   connect( dialog, TQT_SIGNAL( dialogFinished( PreviewDialog * ) ),
02016            TQT_SLOT( slotPreviewDialogFinished( PreviewDialog * ) ) );
02017   connect( dialog, TQT_SIGNAL( openURL( const KURL &, bool ) ),
02018            TQT_SLOT( openURL( const KURL &, bool ) ) );
02019   connect( dialog, TQT_SIGNAL( addResource( const KURL & ) ),
02020            TQT_SLOT( addResource( const KURL & ) ) );
02021 
02022   if ( dialog->loadCalendar() ) {
02023     dialog->show();
02024   } else {
02025     KMessageBox::error( dialogParent(), i18n("Unable to open the calendar") );
02026   }
02027 }
02028 
02029 void ActionManager::slotPreviewDialogFinished( PreviewDialog *dlg )
02030 {
02031   dlg->deleteLater();
02032   mCalendarView->updateView();
02033 }
02034 
02035 void ActionManager::slotAutoArchivingSettingsModified()
02036 {
02037   if ( KOPrefs::instance()->mAutoArchive )
02038     mAutoArchiveTimer->start( 4 * 60 * 60 * 1000, true ); // check again in 4 hours
02039   else
02040     mAutoArchiveTimer->stop();
02041 }
02042 
02043 void ActionManager::slotAutoArchive()
02044 {
02045   if ( !mCalendarView->calendar() ) // can this happen?
02046     return;
02047   mAutoArchiveTimer->stop();
02048   EventArchiver archiver;
02049   connect( &archiver, TQT_SIGNAL( eventsDeleted() ), mCalendarView, TQT_SLOT( updateView() ) );
02050   archiver.runAuto( mCalendarView->calendar(), mCalendarView, false /*no gui*/ );
02051   // restart timer with the correct delay ( especially useful for the first time )
02052   slotAutoArchivingSettingsModified();
02053 }
02054 
02055 void ActionManager::loadProfile( const TQString & path )
02056 {
02057   KOPrefs::instance()->writeConfig();
02058   TDEConfig* const cfg = KOPrefs::instance()->config();
02059 
02060   const TDEConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
02061   const TQStringList groups = profile.groupList();
02062   for ( TQStringList::ConstIterator it = groups.begin(), end = groups.end(); it != end; ++it )
02063   {
02064     cfg->setGroup( *it );
02065     typedef TQMap<TQString, TQString> StringMap;
02066     const StringMap entries = profile.entryMap( *it );
02067     for ( StringMap::ConstIterator it2 = entries.begin(), end = entries.end(); it2 != end; ++it2 )
02068     {
02069       cfg->writeEntry( it2.key(), it2.data() );
02070     }
02071   }
02072 
02073   cfg->sync();
02074   KOPrefs::instance()->readConfig();
02075 }
02076 
02077 namespace {
02078     void copyConfigEntry( TDEConfig* source, TDEConfig* dest, const TQString& group, const TQString& key, const TQString& defaultValue=TQString() )
02079     {
02080         source->setGroup( group );
02081         dest->setGroup( group );
02082         dest->writeEntry( key, source->readEntry( key, defaultValue ) );
02083     }
02084 }
02085 
02086 void ActionManager::saveToProfile( const TQString & path ) const
02087 {
02088   KOPrefs::instance()->writeConfig();
02089   TDEConfig* const cfg = KOPrefs::instance()->config();
02090 
02091   TDEConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
02092   ::copyConfigEntry( cfg, &profile, "Views", "Agenda View Calendar Display" );
02093 }
02094 
02095 bool ActionManager::handleCommandLine()
02096 {
02097   TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
02098   KOrg::MainWindow *mainWindow = ActionManager::findInstance( KURL() );
02099 
02100   bool ret = true;
02101 
02102   if ( !mainWindow ) {
02103     kdError() << "Unable to find default calendar resources view." << endl;
02104     ret = false;
02105   } else if ( args->count() <= 0 ) {
02106     // No filenames given => all other args are meaningless, show main Window
02107     mainWindow->topLevelWidget()->show();
02108   } else if ( !args->isSet( "open" ) ) {
02109     // Import, merge, or ask => we need the resource calendar window anyway.
02110     mainWindow->topLevelWidget()->show();
02111 
02112     // Check for import, merge or ask
02113     if ( args->isSet( "import" ) ) {
02114       for( int i = 0; i < args->count(); ++i ) {
02115         mainWindow->actionManager()->addResource( args->url( i ) );
02116       }
02117     } else if ( args->isSet( "merge" ) ) {
02118       for( int i = 0; i < args->count(); ++i ) {
02119         mainWindow->actionManager()->mergeURL( args->url( i ).url() );
02120       }
02121     } else {
02122       for( int i = 0; i < args->count(); ++i ) {
02123         mainWindow->actionManager()->importCalendar( args->url( i ) );
02124       }
02125     }
02126   }
02127 
02128   return ret;
02129 }
02130 
02131 TQWidget *ActionManager::dialogParent()
02132 {
02133   return mCalendarView->topLevelWidget();
02134 }
02135 
02136 #include "actionmanager.moc"