korganizer

actionmanager.cpp
1 /*
2  This file is part of KOrganizer.
3 
4  Copyright (c) 2002 Mike Pilone <mpilone@slac.com>
5  Copyright (c) 2002 Don Sanders <sanders@kde.org>
6  Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
7  Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
8 
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 
23  As a special exception, permission is given to link this program
24  with any edition of TQt, and distribute the resulting executable,
25  without including the source code for TQt in the source distribution.
26 */
27 
28 #include "actionmanager.h"
29 #include "previewdialog.h"
30 #include "alarmclient.h"
31 #include "calendarview.h"
32 #include "kocore.h"
33 #include "kodialogmanager.h"
34 #include "koglobals.h"
35 #include "koprefs.h"
36 #include "koviewmanager.h"
37 #include "koagendaview.h"
38 #include "multiagendaview.h"
39 #include "kowindowlist.h"
40 #include "kprocess.h"
41 #include "konewstuff.h"
42 #include "history.h"
43 #include "kogroupware.h"
44 #include "resourceview.h"
45 #include "previewdialog.h"
46 #include "eventarchiver.h"
47 #include "stdcalendar.h"
48 #include "freebusymanager.h"
49 
50 #include <libkcal/calendarlocal.h>
52 #include <libkcal/htmlexport.h>
53 #include <libkcal/htmlexportsettings.h>
54 
55 #include <libkmime/kmime_message.h>
56 
57 #include <dcopclient.h>
58 #include <tdeaction.h>
59 #include <tdefiledialog.h>
60 #include <kiconloader.h>
61 #include <tdeio/netaccess.h>
62 #include <kkeydialog.h>
63 #include <tdepopupmenu.h>
64 #include <kstandarddirs.h>
65 #include <ktip.h>
66 #include <tdetempfile.h>
67 #include <kxmlguiclient.h>
68 #include <twin.h>
69 #include <knotifyclient.h>
70 #include <kstdguiitem.h>
71 #include <tdeactionclasses.h>
72 #include <tdecmdlineargs.h>
73 
74 #include <tqapplication.h>
75 #include <tqcursor.h>
76 #include <tqtimer.h>
77 #include <tqlabel.h>
78 
79 // FIXME: Several places in the file don't use TDEConfigXT yet!
80 KOWindowList *ActionManager::mWindowList = 0;
81 
82 ActionManager::ActionManager( KXMLGUIClient *client, CalendarView *widget,
83  TQObject *parent, KOrg::MainWindow *mainWindow,
84  bool isPart )
85  : TQObject( parent ), KCalendarIface(), mRecent( 0 ),
86  mResourceButtonsAction( 0 ), mResourceViewShowAction( 0 ), mCalendar( 0 ),
87  mCalendarResources( 0 ), mResourceView( 0 ), mIsClosing( false )
88 {
89  mGUIClient = client;
90  mACollection = mGUIClient->actionCollection();
91  mCalendarView = widget;
92  mIsPart = isPart;
93  mTempFile = 0;
94  mNewStuff = 0;
95  mHtmlExportSync = false;
96  mMainWindow = mainWindow;
97 }
98 
99 ActionManager::~ActionManager()
100 {
101  delete mNewStuff;
102 
103  // Remove Part plugins
104  KOCore::self()->unloadParts( mMainWindow, mParts );
105 
106  delete mTempFile;
107 
108  // Take this window out of the window list.
109  mWindowList->removeWindow( mMainWindow );
110 
111  delete mCalendarView;
112 
113  delete mCalendar;
114 
115  kdDebug(5850) << "~ActionManager() done" << endl;
116 }
117 
118 // see the Note: below for why this method is necessary
120 {
121  // Construct the groupware object
122  KOGroupware::create( mCalendarView, mCalendarResources );
123 
124  // add this instance of the window to the static list.
125  if ( !mWindowList ) {
126  mWindowList = new KOWindowList;
127  // Show tip of the day, when the first calendar is shown.
128  if ( !mIsPart )
129  TQTimer::singleShot( 0, this, TQ_SLOT( showTipOnStart() ) );
130  }
131  // Note: We need this ActionManager to be fully constructed, and
132  // parent() to have a valid reference to it before the following
133  // addWindow is called.
134  mWindowList->addWindow( mMainWindow );
135 
136  initActions();
137 
138  // set up autoSaving stuff
139  mAutoSaveTimer = new TQTimer( this );
140  connect( mAutoSaveTimer,TQ_SIGNAL( timeout() ), TQ_SLOT( checkAutoSave() ) );
141  if ( KOPrefs::instance()->mAutoSave &&
142  KOPrefs::instance()->mAutoSaveInterval > 0 ) {
143  mAutoSaveTimer->start( 1000 * 60 * KOPrefs::instance()->mAutoSaveInterval );
144  }
145 
146  mAutoArchiveTimer = new TQTimer( this );
147  connect( mAutoArchiveTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( slotAutoArchive() ) );
148  // First auto-archive should be in 5 minutes (like in kmail).
149  if ( KOPrefs::instance()->mAutoArchive )
150  mAutoArchiveTimer->start( 5 * 60 * 1000, true ); // singleshot
151 
152  setTitle();
153 
154  connect( mCalendarView, TQ_SIGNAL( modifiedChanged( bool ) ), TQ_SLOT( setTitle() ) );
155  connect( mCalendarView, TQ_SIGNAL( configChanged() ), TQ_SLOT( updateConfig() ) );
156 
157  connect( mCalendarView, TQ_SIGNAL( incidenceSelected( Incidence *,const TQDate & ) ),
158  this, TQ_SLOT( processIncidenceSelection( Incidence *,const TQDate & ) ) );
159  connect( mCalendarView, TQ_SIGNAL( exportHTML( HTMLExportSettings * ) ),
160  this, TQ_SLOT( exportHTML( HTMLExportSettings * ) ) );
161 
162  processIncidenceSelection( 0, TQDate() );
163 
164  // Update state of paste action
165  mCalendarView->checkClipboard();
166 }
167 
169 {
170  mCalendar = new CalendarLocal( KOPrefs::instance()->mTimeZoneId );
171  mCalendarView->setCalendar( mCalendar );
172  mCalendarView->readSettings();
173 
174  initCalendar( mCalendar );
175 }
176 
178 {
179  mCalendarResources = KOrg::StdCalendar::self();
180 
181  CalendarResourceManager *manager = mCalendarResources->resourceManager();
182 
183  kdDebug(5850) << "CalendarResources used by KOrganizer:" << endl;
184  CalendarResourceManager::Iterator it;
185  for( it = manager->begin(); it != manager->end(); ++it ) {
186  kdDebug(5850) << " " << (*it)->resourceName() << endl;
187  (*it)->setResolveConflict( true );
188 // (*it)->dump();
189  }
190 
191  setDestinationPolicy();
192 
193  mCalendarView->setCalendar( mCalendarResources );
194  mCalendarView->readSettings();
195 
196  ResourceViewFactory factory( mCalendarResources, mCalendarView );
197  mCalendarView->addExtension( &factory );
198  mResourceView = factory.resourceView();
199 
200  connect( mCalendarResources, TQ_SIGNAL( calendarChanged() ),
201  mCalendarView, TQ_SLOT( resourcesChanged() ) );
202  connect( mCalendarResources, TQ_SIGNAL( signalErrorMessage( const TQString & ) ),
203  mCalendarView, TQ_SLOT( showErrorMessage( const TQString & ) ) );
204 
205  connect( mCalendarView, TQ_SIGNAL( configChanged() ),
206  TQ_SLOT( updateConfig() ) );
207 
208  initCalendar( mCalendarResources );
209 }
210 
211 void ActionManager::initCalendar( Calendar *cal )
212 {
213  cal->setOwner( Person( KOPrefs::instance()->fullName(),
214  KOPrefs::instance()->email() ) );
215  // setting fullName and email do not really count as modifying the calendar
216  mCalendarView->setModified( false );
217 }
218 
219 void ActionManager::initActions()
220 {
221  TDEAction *action;
222 
223 
224  //*************************** FILE MENU **********************************
225 
226  //~~~~~~~~~~~~~~~~~~~~~~~ LOADING / SAVING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
227  if ( mIsPart ) {
228  if ( mMainWindow->hasDocument() ) {
229  KStdAction::openNew( this, TQ_SLOT(file_new()), mACollection, "korganizer_openNew" );
230  KStdAction::open( this, TQ_SLOT( file_open() ), mACollection, "korganizer_open" );
231  mRecent = KStdAction::openRecent( this, TQ_SLOT( file_open( const KURL& ) ),
232  mACollection, "korganizer_openRecent" );
233  KStdAction::revert( this,TQ_SLOT( file_revert() ), mACollection, "korganizer_revert" );
234  KStdAction::saveAs( this, TQ_SLOT( file_saveas() ), mACollection,
235  "korganizer_saveAs" );
236  KStdAction::save( this, TQ_SLOT( file_save() ), mACollection, "korganizer_save" );
237  }
238  KStdAction::print( mCalendarView, TQ_SLOT( print() ), mACollection, "korganizer_print" );
239  } else {
240  KStdAction::openNew( this, TQ_SLOT( file_new() ), mACollection );
241  KStdAction::open( this, TQ_SLOT( file_open() ), mACollection );
242  mRecent = KStdAction::openRecent( this, TQ_SLOT( file_open( const KURL& ) ),
243  mACollection );
244  if ( mMainWindow->hasDocument() ) {
245  KStdAction::revert( this,TQ_SLOT( file_revert() ), mACollection );
246  KStdAction::save( this, TQ_SLOT( file_save() ), mACollection );
247  KStdAction::saveAs( this, TQ_SLOT( file_saveas() ), mACollection );
248  }
249  KStdAction::print( mCalendarView, TQ_SLOT( print() ), mACollection );
250  }
251 
252 
253  //~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT / EXPORT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
254  new TDEAction( i18n("Import &Event/Calendar (ICS-/VCS-File)..."), 0, this, TQ_SLOT( file_merge() ),
255  mACollection, "import_icalendar" );
256  new TDEAction( i18n("&Import From UNIX Ical tool (.calendar-File)"), 0, this, TQ_SLOT( file_icalimport() ),
257  mACollection, "import_ical" );
258  new TDEAction( i18n("Get &Hot New Stuff..."), 0, this,
259  TQ_SLOT( downloadNewStuff() ), mACollection,
260  "downloadnewstuff" );
261 
262  new TDEAction( i18n("Export &Web Page..."), "webexport", 0,
263  mCalendarView, TQ_SLOT( exportWeb() ),
264  mACollection, "export_web" );
265  new TDEAction( i18n("&iCalendar..."), 0,
266  mCalendarView, TQ_SLOT( exportICalendar() ),
267  mACollection, "export_icalendar" );
268  new TDEAction( i18n("&vCalendar..."), 0,
269  mCalendarView, TQ_SLOT( exportVCalendar() ),
270  mACollection, "export_vcalendar" );
271  new TDEAction( i18n("Upload &Hot New Stuff..."), 0, this,
272  TQ_SLOT( uploadNewStuff() ), mACollection,
273  "uploadnewstuff" );
274 
275 
276 
277  new TDEAction( i18n("Archive O&ld Entries..."), 0, this, TQ_SLOT( file_archive() ),
278  mACollection, "file_archive" );
279  new TDEAction( i18n("delete completed to-dos", "Pur&ge Completed To-dos"), 0,
280  mCalendarView, TQ_SLOT( purgeCompleted() ), mACollection,
281  "purge_completed" );
282 
283 
284 
285 
286  //************************** EDIT MENU *********************************
287  TDEAction *pasteAction;
288  KOrg::History *h = mCalendarView->history();
289  if ( mIsPart ) {
290  // edit menu
291  mCutAction = KStdAction::cut( mCalendarView, TQ_SLOT( edit_cut() ),
292  mACollection, "korganizer_cut" );
293  mCopyAction = KStdAction::copy( mCalendarView, TQ_SLOT( edit_copy() ),
294  mACollection, "korganizer_copy" );
295  pasteAction = KStdAction::paste( mCalendarView, TQ_SLOT( edit_paste() ),
296  mACollection, "korganizer_paste" );
297  mUndoAction = KStdAction::undo( h, TQ_SLOT( undo() ),
298  mACollection, "korganizer_undo" );
299  mRedoAction = KStdAction::redo( h, TQ_SLOT( redo() ),
300  mACollection, "korganizer_redo" );
301  } else {
302  mCutAction = KStdAction::cut( mCalendarView,TQ_SLOT( edit_cut() ),
303  mACollection );
304  mCopyAction = KStdAction::copy( mCalendarView,TQ_SLOT( edit_copy() ),
305  mACollection );
306  pasteAction = KStdAction::paste( mCalendarView,TQ_SLOT( edit_paste() ),
307  mACollection );
308  mUndoAction = KStdAction::undo( h, TQ_SLOT( undo() ), mACollection );
309  mRedoAction = KStdAction::redo( h, TQ_SLOT( redo() ), mACollection );
310  }
311  mDeleteAction = new TDEAction( i18n("&Delete"), "edit-delete", 0,
312  mCalendarView, TQ_SLOT( appointment_delete() ),
313  mACollection, "edit_delete" );
314  if ( mIsPart ) {
315  KStdAction::find( mCalendarView->dialogManager(), TQ_SLOT( showSearchDialog() ),
316  mACollection, "korganizer_find" );
317  } else {
318  KStdAction::find( mCalendarView->dialogManager(), TQ_SLOT( showSearchDialog() ),
319  mACollection );
320  }
321  pasteAction->setEnabled( false );
322  mUndoAction->setEnabled( false );
323  mRedoAction->setEnabled( false );
324  connect( mCalendarView, TQ_SIGNAL( pasteEnabled( bool ) ),
325  pasteAction, TQ_SLOT( setEnabled( bool ) ) );
326  connect( h, TQ_SIGNAL( undoAvailable( const TQString & ) ),
327  TQ_SLOT( updateUndoAction( const TQString & ) ) );
328  connect( h, TQ_SIGNAL( redoAvailable( const TQString & ) ),
329  TQ_SLOT( updateRedoAction( const TQString & ) ) );
330 
331 
332 
333 
334  //************************** VIEW MENU *********************************
335 
336  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VIEWS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
337  new TDEAction( i18n("What's &Next"),
338  KOGlobals::self()->smallIcon( "whatsnext" ), 0,
339  mCalendarView->viewManager(), TQ_SLOT( showWhatsNextView() ),
340  mACollection, "view_whatsnext" );
341  new TDEAction( i18n("&Day"),
342  KOGlobals::self()->smallIcon( "1day" ), 0,
343  mCalendarView->viewManager(), TQ_SLOT( showDayView() ),
344  mACollection, "view_day" );
345  mNextXDays = new TDEAction( "",
346  KOGlobals::self()->smallIcon( "xdays" ), 0,
347  mCalendarView->viewManager(),
348  TQ_SLOT( showNextXView() ),
349  mACollection, "view_nextx" );
350  mNextXDays->setText( i18n( "&Next Day", "Ne&xt %n Days",
351  KOPrefs::instance()->mNextXDays ) );
352  new TDEAction( i18n("W&ork Week"),
353  KOGlobals::self()->smallIcon( "5days" ), 0,
354  mCalendarView->viewManager(), TQ_SLOT( showWorkWeekView() ),
355  mACollection, "view_workweek" );
356  new TDEAction( i18n("&Week"),
357  KOGlobals::self()->smallIcon( "7days" ), 0,
358  mCalendarView->viewManager(), TQ_SLOT( showWeekView() ),
359  mACollection, "view_week" );
360  new TDEAction( i18n("&Month"),
361  KOGlobals::self()->smallIcon( "month" ), 0,
362  mCalendarView->viewManager(), TQ_SLOT( showMonthView() ),
363  mACollection, "view_month" );
364  new TDEAction( i18n("&List"),
365  KOGlobals::self()->smallIcon( "list" ), 0,
366  mCalendarView->viewManager(), TQ_SLOT( showListView() ),
367  mACollection, "view_list" );
368  new TDEAction( i18n("&To-do List"),
369  KOGlobals::self()->smallIcon( "todo" ), 0,
370  mCalendarView->viewManager(), TQ_SLOT( showTodoView() ),
371  mACollection, "view_todo" );
372  new TDEAction( i18n("&Journal"),
373  KOGlobals::self()->smallIcon( "journal" ), 0,
374  mCalendarView->viewManager(), TQ_SLOT( showJournalView() ),
375  mACollection, "view_journal" );
376  new TDEAction( i18n("&Timeline View"),
377  KOGlobals::self()->smallIcon( "timeline" ), 0,
378  mCalendarView->viewManager(), TQ_SLOT( showTimelineView() ),
379  mACollection, "view_timeline" );
380 
381  //~~~~~~~~~~~~~~~~~~~~~~~~~~~ FILTERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382  new TDEAction( i18n("&Refresh"), 0,
383  mCalendarView, TQ_SLOT( updateView() ),
384  mACollection, "update" );
385 // TODO:
386 // new TDEAction( i18n("Hide &Completed To-dos"), 0,
387 // mCalendarView, TQ_SLOT( toggleHideCompleted() ),
388 // mACollection, "hide_completed_todos" );
389 
390  mFilterAction = new TDESelectAction( i18n("F&ilter"), 0,
391  mACollection, "filter_select" );
392  mFilterAction->setEditable( false );
393  connect( mFilterAction, TQ_SIGNAL( activated(int) ),
394  mCalendarView, TQ_SLOT( filterActivated( int ) ) );
395  connect( mCalendarView, TQ_SIGNAL( newFilterListSignal( const TQStringList & ) ),
396  mFilterAction, TQ_SLOT( setItems( const TQStringList & ) ) );
397  connect( mCalendarView, TQ_SIGNAL( selectFilterSignal( int ) ),
398  mFilterAction, TQ_SLOT( setCurrentItem( int ) ) );
399  connect( mCalendarView, TQ_SIGNAL( filterChanged() ),
400  this, TQ_SLOT( setTitle() ) );
401 
402 
403  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ZOOM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
404  // TODO: try to find / create better icons for the following 4 actions
405  new TDEAction( i18n( "Zoom In Horizontally" ), "zoom-in", 0,
406  mCalendarView->viewManager(), TQ_SLOT( zoomInHorizontally() ),
407  mACollection, "zoom_in_horizontally" );
408  new TDEAction( i18n( "Zoom Out Horizontally" ), "zoom-out", 0,
409  mCalendarView->viewManager(), TQ_SLOT( zoomOutHorizontally() ),
410  mACollection, "zoom_out_horizontally" );
411  new TDEAction( i18n( "Zoom In Vertically" ), "zoom-in", 0,
412  mCalendarView->viewManager(), TQ_SLOT( zoomInVertically() ),
413  mACollection, "zoom_in_vertically" );
414  new TDEAction( i18n( "Zoom Out Vertically" ), "zoom-out", 0,
415  mCalendarView->viewManager(), TQ_SLOT( zoomOutVertically() ),
416  mACollection, "zoom_out_vertically" );
417 
418 
419 
420 
421  //************************** Actions MENU *********************************
422 
423  new TDEAction( i18n("Go to &Today"), "today", 0,
424  mCalendarView,TQ_SLOT( goToday() ),
425  mACollection, "go_today" );
426  bool isRTL = TQApplication::reverseLayout();
427  action = new TDEAction( i18n("Go &Backward"), isRTL ? "forward" : "back", 0,
428  mCalendarView,TQ_SLOT( goPrevious() ),
429  mACollection, "go_previous" );
430 
431  // Changing the action text by setText makes the toolbar button disappear.
432  // This has to be fixed first, before the connects below can be reenabled.
433  /*
434  connect( mCalendarView, TQ_SIGNAL( changeNavStringPrev( const TQString & ) ),
435  action, TQ_SLOT( setText( const TQString & ) ) );
436  connect( mCalendarView, TQ_SIGNAL( changeNavStringPrev( const TQString & ) ),
437  this, TQ_SLOT( dumpText( const TQString & ) ) );*/
438 
439  action = new TDEAction( i18n("Go &Forward"), isRTL ? "back" : "forward", 0,
440  mCalendarView,TQ_SLOT( goNext() ),
441  mACollection, "go_next" );
442  /*
443  connect( mCalendarView,TQ_SIGNAL( changeNavStringNext( const TQString & ) ),
444  action,TQ_SLOT( setText( const TQString & ) ) );
445  */
446 
447 
448  //************************** Actions MENU *********************************
449  new TDEAction( i18n("New E&vent..."),
450  KOGlobals::self()->smallIcon( "newappointment" ), 0,
451  mCalendarView, TQ_SLOT(newEvent()),
452  mACollection, "new_event" );
453  new TDEAction( i18n("New &To-do..."),
454  KOGlobals::self()->smallIcon( "newtodo" ), 0,
455  mCalendarView, TQ_SLOT(newTodo()),
456  mACollection, "new_todo" );
457  action = new TDEAction( i18n("New Su&b-to-do..."), 0,
458  mCalendarView,TQ_SLOT( newSubTodo() ),
459  mACollection, "new_subtodo" );
460  action->setEnabled( false );
461  connect( mCalendarView,TQ_SIGNAL( todoSelected( bool ) ),
462  action,TQ_SLOT( setEnabled( bool ) ) );
463  new TDEAction( i18n("New &Journal..."),
464  KOGlobals::self()->smallIcon( "newjournal" ), 0,
465  mCalendarView, TQ_SLOT(newJournal()),
466  mACollection, "new_journal" );
467 
468  mShowIncidenceAction = new TDEAction( i18n("&Show"), 0,
469  mCalendarView,TQ_SLOT( showIncidence() ),
470  mACollection, "show_incidence" );
471  mEditIncidenceAction = new TDEAction( i18n("&Edit..."), 0,
472  mCalendarView,TQ_SLOT( editIncidence() ),
473  mACollection, "edit_incidence" );
474  mDeleteIncidenceAction = new TDEAction( i18n("&Delete"), Key_Delete,
475  mCalendarView,TQ_SLOT( deleteIncidence()),
476  mACollection, "delete_incidence" );
477 
478  action = new TDEAction( i18n("&Make Sub-to-do Independent"), 0,
479  mCalendarView,TQ_SLOT( todo_unsub() ),
480  mACollection, "unsub_todo" );
481  action->setEnabled( false );
482  connect( mCalendarView,TQ_SIGNAL( subtodoSelected( bool ) ),
483  action,TQ_SLOT( setEnabled( bool ) ) );
484 // TODO: Add item to move the incidence to different resource
485 // mAssignResourceAction = new TDEAction( i18n("Assign &Resource..."), 0,
486 // mCalendarView, TQ_SLOT( assignResource()),
487 // mACollection, "assign_resource" );
488 // TODO: Add item to quickly toggle the reminder of a given incidence
489 // mToggleAlarmAction = new TDEToggleAction( i18n("&Activate Reminder"), 0,
490 // mCalendarView, TQ_SLOT( toggleAlarm()),
491 // mACollection, "activate_alarm" );
492 
493 
494 
495 
496  //************************** SCHEDULE MENU ********************************
497  mPublishEvent = new TDEAction( i18n("&Publish Item Information..."), "mail-send", 0,
498  mCalendarView, TQ_SLOT( schedule_publish() ),
499  mACollection, "schedule_publish" );
500  mPublishEvent->setEnabled( false );
501 
502  mSendInvitation = new TDEAction( i18n( "Send &Invitation to Attendees" ),
503  "mail_generic", 0,
504  mCalendarView, TQ_SLOT(schedule_request()),
505  mACollection, "schedule_request" );
506  mSendInvitation->setEnabled( false );
507  connect( mCalendarView, TQ_SIGNAL(organizerEventsSelected(bool)),
508  mSendInvitation, TQ_SLOT(setEnabled(bool)) );
509 
510  mRequestUpdate = new TDEAction( i18n( "Re&quest Update" ), 0,
511  mCalendarView, TQ_SLOT(schedule_refresh()),
512  mACollection, "schedule_refresh" );
513  mRequestUpdate->setEnabled( false );
514  connect( mCalendarView, TQ_SIGNAL(groupEventsSelected(bool)),
515  mRequestUpdate, TQ_SLOT(setEnabled(bool)) );
516 
517  mSendCancel = new TDEAction( i18n( "Send &Cancelation to Attendees" ), 0,
518  mCalendarView, TQ_SLOT(schedule_cancel()),
519  mACollection, "schedule_cancel" );
520  mSendCancel->setEnabled( false );
521  connect( mCalendarView, TQ_SIGNAL(organizerEventsSelected(bool)),
522  mSendCancel, TQ_SLOT(setEnabled(bool)) );
523 
524  mSendStatusUpdate = new TDEAction( i18n( "Send Status &Update" ),
525  "mail-reply-sender", 0,
526  mCalendarView,TQ_SLOT(schedule_reply()),
527  mACollection, "schedule_reply" );
528  mSendStatusUpdate->setEnabled( false );
529  connect( mCalendarView, TQ_SIGNAL(groupEventsSelected(bool)),
530  mSendStatusUpdate, TQ_SLOT(setEnabled(bool)) );
531 
532  mRequestChange = new TDEAction( i18n( "counter proposal", "Request Chan&ge" ), 0,
533  mCalendarView, TQ_SLOT(schedule_counter()),
534  mACollection, "schedule_counter" );
535  mRequestChange->setEnabled( false );
536  connect( mCalendarView, TQ_SIGNAL(groupEventsSelected(bool)),
537  mRequestChange, TQ_SLOT(setEnabled(bool)) );
538 
539  mForwardEvent = new TDEAction( i18n("&Send as iCalendar..."), "mail-forward", 0,
540  mCalendarView, TQ_SLOT(schedule_forward()),
541  mACollection, "schedule_forward" );
542  mForwardEvent->setEnabled( false );
543 
544  action = new TDEAction( i18n("&Mail Free Busy Information..."), 0,
545  mCalendarView, TQ_SLOT( mailFreeBusy() ),
546  mACollection, "mail_freebusy" );
547  action->setEnabled( true );
548 
549  action = new TDEAction( i18n("&Upload Free Busy Information"), 0,
550  mCalendarView, TQ_SLOT( uploadFreeBusy() ),
551  mACollection, "upload_freebusy" );
552  action->setEnabled( true );
553 
554  if ( !mIsPart ) {
555  action = new TDEAction( i18n("&Addressbook"),"contents",0,
556  mCalendarView,TQ_SLOT( openAddressbook() ),
557  mACollection,"addressbook" );
558  }
559 
560 
561 
562 
563  //************************** SETTINGS MENU ********************************
564 
565  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIDEBAR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
566  mDateNavigatorShowAction = new TDEToggleAction( i18n("Show Date Navigator"), 0,
567  this, TQ_SLOT( toggleDateNavigator() ),
568  mACollection, "show_datenavigator" );
569  mTodoViewShowAction = new TDEToggleAction ( i18n("Show To-do View"), 0,
570  this, TQ_SLOT( toggleTodoView() ),
571  mACollection, "show_todoview" );
572  mEventViewerShowAction = new TDEToggleAction ( i18n("Show Item Viewer"), 0,
573  this, TQ_SLOT( toggleEventViewer() ),
574  mACollection, "show_eventviewer" );
575  TDEConfig *config = KOGlobals::self()->config();
576  config->setGroup( "Settings" );
577  mDateNavigatorShowAction->setChecked(
578  config->readBoolEntry( "DateNavigatorVisible", true ) );
579  // if we are a kpart, then let's not show the todo in the left pane by
580  // default since there's also a Todo part and we'll assume they'll be
581  // using that as well, so let's not duplicate it (by default) here
582  mTodoViewShowAction->setChecked(
583  config->readBoolEntry( "TodoViewVisible", mIsPart ? false : true ) );
584  mEventViewerShowAction->setChecked(
585  config->readBoolEntry( "EventViewerVisible", true ) );
586  toggleDateNavigator();
587  toggleTodoView();
588  toggleEventViewer();
589 
590  if ( !mMainWindow->hasDocument() ) {
591  mResourceViewShowAction = new TDEToggleAction ( i18n("Show Resource View"), 0,
592  this, TQ_SLOT( toggleResourceView() ),
593  mACollection, "show_resourceview" );
594  mResourceButtonsAction = new TDEToggleAction( i18n("Show &Resource Buttons"), 0,
595  this, TQ_SLOT( toggleResourceButtons() ),
596  mACollection, "show_resourcebuttons" );
597  mResourceViewShowAction->setChecked(
598  config->readBoolEntry( "ResourceViewVisible", true ) );
599  mResourceButtonsAction->setChecked(
600  config->readBoolEntry( "ResourceButtonsVisible", true ) );
601 
602  toggleResourceView();
603  toggleResourceButtons();
604  }
605 
606 
607  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIDEBAR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
608 
609  new TDEAction( i18n("Configure &Date && Time..."), 0,
610  this, TQ_SLOT( configureDateTime() ),
611  mACollection, "conf_datetime" );
612 // TODO: Add an item to show the resource management dlg
613 // new TDEAction( i18n("Manage &Resources..."), 0,
614 // this, TQ_SLOT( manageResources() ),
615 // mACollection, "conf_resources" );
616  new TDEAction( i18n("Manage View &Filters..."), "configure", 0,
617  mCalendarView, TQ_SLOT( editFilters() ),
618  mACollection, "edit_filters" );
619  new TDEAction( i18n("Manage C&ategories..."), 0,
620  mCalendarView->dialogManager(), TQ_SLOT( showCategoryEditDialog() ),
621  mACollection, "edit_categories" );
622  if ( mIsPart ) {
623  new TDEAction( i18n("&Configure Calendar..."), "configure", 0,
624  mCalendarView, TQ_SLOT( edit_options() ),
625  mACollection, "korganizer_configure" );
626  KStdAction::keyBindings( this, TQ_SLOT( keyBindings() ),
627  mACollection, "korganizer_configure_shortcuts" );
628  } else {
629  KStdAction::preferences( mCalendarView, TQ_SLOT( edit_options() ),
630  mACollection );
631  KStdAction::keyBindings( this, TQ_SLOT( keyBindings() ), mACollection );
632  }
633 
634 
635 
636 
637  //**************************** HELP MENU **********************************
638  KStdAction::tipOfDay( this, TQ_SLOT( showTip() ), mACollection,
639  "help_tipofday" );
640 // new TDEAction( i18n("Show Intro Page"), 0,
641 // mCalendarView,TQ_SLOT( showIntro() ),
642 // mACollection,"show_intro" );
643 
644 
645 
646 
647  //************************* TOOLBAR ACTIONS *******************************
648  TQLabel *filterLabel = new TQLabel( i18n("Filter: "), mCalendarView );
649  filterLabel->hide();
650  new KWidgetAction( filterLabel, i18n("Filter: "), 0, 0, 0,
651  mACollection, "filter_label" );
652 
653 }
654 
656 {
657  // read settings from the TDEConfig, supplying reasonable
658  // defaults where none are to be found
659 
660  TDEConfig *config = KOGlobals::self()->config();
661  if ( mRecent ) mRecent->loadEntries( config );
662  mCalendarView->readSettings();
663 }
664 
666 {
667  kdDebug(5850) << "ActionManager::writeSettings" << endl;
668 
669  TDEConfig *config = KOGlobals::self()->config();
670  mCalendarView->writeSettings();
671 
672  config->setGroup( "Settings" );
673  if ( mResourceButtonsAction ) {
674  config->writeEntry( "ResourceButtonsVisible",
675  mResourceButtonsAction->isChecked() );
676  }
677  if ( mDateNavigatorShowAction ) {
678  config->writeEntry( "DateNavigatorVisible",
679  mDateNavigatorShowAction->isChecked() );
680  }
681  if ( mTodoViewShowAction ) {
682  config->writeEntry( "TodoViewVisible",
683  mTodoViewShowAction->isChecked() );
684  }
685  if ( mResourceViewShowAction ) {
686  config->writeEntry( "ResourceViewVisible",
687  mResourceViewShowAction->isChecked() );
688  }
689  if ( mEventViewerShowAction ) {
690  config->writeEntry( "EventViewerVisible",
691  mEventViewerShowAction->isChecked() );
692  }
693 
694  if ( mRecent ) mRecent->saveEntries( config );
695 
696  config->sync();
697 
698  if ( mCalendarResources ) {
699  mCalendarResources->resourceManager()->writeConfig();
700  }
701 }
702 
704 {
705  emit actionNew();
706 }
707 
709 {
710  KURL url;
711  TQString defaultPath = locateLocal( "data","korganizer/" );
712  url = KFileDialog::getOpenURL( defaultPath,i18n("*.vcs *.ics|Calendar Files"),
713  dialogParent() );
714 
715  file_open( url );
716 }
717 
718 void ActionManager::file_open( const KURL &url )
719 {
720  if ( url.isEmpty() ) return;
721 
722  // is that URL already opened somewhere else? Activate that window
724  if ( ( 0 != korg )&&( korg != mMainWindow ) ) {
725  KWin::activateWindow( korg->topLevelWidget()->winId() );
726  return;
727  }
728 
729  kdDebug(5850) << "ActionManager::file_open(): " << url.prettyURL() << endl;
730 
731  // Open the calendar file in the same window only if we have an empty calendar window, and not the resource calendar
732  if ( !mCalendarView->isModified() && mFile.isEmpty() && !mCalendarResources ) {
733  openURL( url );
734  } else {
735  emit actionNew( url );
736  }
737 }
738 
740 {
741  // FIXME: eventually, we will need a dialog box to select import type, etc.
742  // for now, hard-coded to ical file, $HOME/.calendar.
743  int retVal = -1;
744  TQString progPath;
745  KTempFile tmpfn;
746 
747  TQString homeDir = TQDir::homeDirPath() + TQString::fromLatin1( "/.calendar" );
748 
749  if ( !TQFile::exists( homeDir ) ) {
750  KMessageBox::error( dialogParent(),
751  i18n( "You have no .calendar file in your home directory.\n"
752  "Import cannot proceed.\n" ) );
753  return;
754  }
755 
756  TDEProcess proc;
757  proc << "ical2vcal" << tmpfn.name();
758  bool success = proc.start( TDEProcess::Block );
759 
760  if ( !success ) {
761  kdDebug(5850) << "Error starting ical2vcal." << endl;
762  return;
763  } else {
764  retVal = proc.exitStatus();
765  }
766 
767  kdDebug(5850) << "ical2vcal return value: " << retVal << endl;
768 
769  if ( retVal >= 0 && retVal <= 2 ) {
770  // now we need to MERGE what is in the iCal to the current calendar.
771  mCalendarView->openCalendar( tmpfn.name(),1 );
772  if ( !retVal )
773  KMessageBox::information( dialogParent(),
774  i18n( "KOrganizer successfully imported and "
775  "merged your .calendar file from ical "
776  "into the currently opened calendar." ),
777  "dotCalendarImportSuccess" );
778  else
779  KMessageBox::information( dialogParent(),
780  i18n( "KOrganizer encountered some unknown fields while "
781  "parsing your .calendar ical file, and had to "
782  "discard them; please check to see that all "
783  "your relevant data was correctly imported." ),
784  i18n("ICal Import Successful with Warning") );
785  } else if ( retVal == -1 ) {
786  KMessageBox::error( dialogParent(),
787  i18n( "KOrganizer encountered an error parsing your "
788  ".calendar file from ical; import has failed." ) );
789  } else if ( retVal == -2 ) {
790  KMessageBox::error( dialogParent(),
791  i18n( "KOrganizer does not think that your .calendar "
792  "file is a valid ical calendar; import has failed." ) );
793  }
794  tmpfn.unlink();
795 }
796 
798 {
799  KURL url = KFileDialog::getOpenURL( locateLocal( "data","korganizer/" ),
800  i18n("*.vcs *.ics|Calendar Files"),
801  dialogParent() );
802  if ( ! url.isEmpty() ) // isEmpty if user cancelled the dialog
803  importCalendar( url );
804 }
805 
807 {
808  mCalendarView->archiveCalendar();
809 }
810 
812 {
813  openURL( mURL );
814 }
815 
817 {
818  KURL url = getSaveURL();
819 
820  if ( url.isEmpty() ) return;
821 
822  saveAsURL( url );
823 }
824 
826 {
827  if ( mMainWindow->hasDocument() ) {
828  if ( mURL.isEmpty() ) {
829  file_saveas();
830  return;
831  } else {
832  saveURL();
833  }
834  } else {
835  mCalendarView->calendar()->save();
836  }
837 
838  // export to HTML
839  if ( KOPrefs::instance()->mHtmlWithSave ) {
840  exportHTML();
841  }
842 }
843 
845 {
846  if ( !saveModifiedURL() ) return;
847 
848  mCalendarView->closeCalendar();
849  TDEIO::NetAccess::removeTempFile( mFile );
850  mURL="";
851  mFile="";
852 
853  setTitle();
854 }
855 
856 bool ActionManager::openURL( const KURL &url,bool merge )
857 {
858  kdDebug(5850) << "ActionManager::openURL()" << endl;
859 
860  if ( url.isEmpty() ) {
861  kdDebug(5850) << "ActionManager::openURL(): Error! Empty URL." << endl;
862  return false;
863  }
864  if ( !url.isValid() ) {
865  kdDebug(5850) << "ActionManager::openURL(): Error! URL is malformed." << endl;
866  return false;
867  }
868 
869  if ( url.isLocalFile() ) {
870  mURL = url;
871  mFile = url.path();
872  if ( !TDEStandardDirs::exists( mFile ) ) {
873  mMainWindow->showStatusMessage( i18n("New calendar '%1'.")
874  .arg( url.prettyURL() ) );
875  mCalendarView->setModified();
876  } else {
877  bool success = mCalendarView->openCalendar( mFile, merge );
878  if ( success ) {
879  showStatusMessageOpen( url, merge );
880  }
881  }
882  setTitle();
883  } else {
884  TQString tmpFile;
885  if( TDEIO::NetAccess::download( url, tmpFile, view() ) ) {
886  kdDebug(5850) << "--- Downloaded to " << tmpFile << endl;
887  bool success = mCalendarView->openCalendar( tmpFile, merge );
888  if ( merge ) {
889  TDEIO::NetAccess::removeTempFile( tmpFile );
890  if ( success )
891  showStatusMessageOpen( url, merge );
892  } else {
893  if ( success ) {
894  TDEIO::NetAccess::removeTempFile( mFile );
895  mURL = url;
896  mFile = tmpFile;
897  TDEConfig *config = KOGlobals::self()->config();
898  config->setGroup( "General" );
899  setTitle();
900  kdDebug(5850) << "-- Add recent URL: " << url.prettyURL() << endl;
901  if ( mRecent ) mRecent->addURL( url );
902  showStatusMessageOpen( url, merge );
903  }
904  }
905  return success;
906  } else {
907  TQString msg;
908  msg = i18n("Cannot download calendar from '%1'.").arg( url.prettyURL() );
909  KMessageBox::error( dialogParent(), msg );
910  return false;
911  }
912  }
913  return true;
914 }
915 
916 bool ActionManager::addResource( const KURL &mUrl )
917 {
918  CalendarResources *cr = KOrg::StdCalendar::self();
919 
920  CalendarResourceManager *manager = cr->resourceManager();
921 
922  ResourceCalendar *resource = 0;
923 
924  TQString name;
925 
926  kdDebug(5850) << "URL: " << mUrl << endl;
927  if ( mUrl.isLocalFile() ) {
928  kdDebug(5850) << "Local Resource" << endl;
929  resource = manager->createResource( "file" );
930  if ( resource )
931  resource->setValue( "File", mUrl.path() );
932  name = mUrl.path();
933  } else {
934  kdDebug(5850) << "Remote Resource" << endl;
935  resource = manager->createResource( "remote" );
936  if ( resource )
937  resource->setValue( "DownloadURL", mUrl.url() );
938  name = mUrl.prettyURL();
939  resource->setReadOnly( true );
940  }
941 
942  if ( resource ) {
943  resource->setTimeZoneId( KOPrefs::instance()->mTimeZoneId );
944  resource->setResourceName( name );
945  manager->add( resource );
946  mMainWindow->showStatusMessage( i18n( "Added calendar resource for URL '%1'." )
947  .arg( name ) );
948  // we have to call resourceAdded manually, because for in-process changes
949  // the dcop signals are not connected, so the resource's signals would not
950  // be connected otherwise
951  if ( mCalendarResources )
952  mCalendarResources->resourceAdded( resource );
953  } else {
954  TQString msg = i18n("Unable to create calendar resource '%1'.")
955  .arg( name );
956  KMessageBox::error( dialogParent(), msg );
957  }
958  return true;
959 }
960 
961 
962 void ActionManager::showStatusMessageOpen( const KURL &url, bool merge )
963 {
964  if ( merge ) {
965  mMainWindow->showStatusMessage( i18n("Merged calendar '%1'.")
966  .arg( url.prettyURL() ) );
967  } else {
968  mMainWindow->showStatusMessage( i18n("Opened calendar '%1'.")
969  .arg( url.prettyURL() ) );
970  }
971 }
972 
974 {
975  kdDebug(5850) << "ActionManager::closeURL()" << endl;
976 
977  file_close();
978 }
979 
981 {
982  TQString ext;
983 
984  if ( mURL.isLocalFile() ) {
985  ext = mFile.right( 4 );
986  } else {
987  ext = mURL.filename().right( 4 );
988  }
989 
990  if ( ext == ".vcs" ) {
991  int result = KMessageBox::warningContinueCancel(
992  dialogParent(),
993  i18n( "Your calendar will be saved in iCalendar format. Use "
994  "'Export vCalendar' to save in vCalendar format." ),
995  i18n("Format Conversion"), i18n("Proceed"), "dontaskFormatConversion",
996  true );
997  if ( result != KMessageBox::Continue ) return false;
998 
999  TQString filename = mURL.fileName();
1000  filename.replace( filename.length() - 4, 4, ".ics" );
1001  mURL.setFileName( filename );
1002  if ( mURL.isLocalFile() ) {
1003  mFile = mURL.path();
1004  }
1005  setTitle();
1006  if ( mRecent ) mRecent->addURL( mURL );
1007  }
1008 
1009  if ( !mCalendarView->saveCalendar( mFile ) ) {
1010  kdDebug(5850) << "ActionManager::saveURL(): calendar view save failed."
1011  << endl;
1012  return false;
1013  } else {
1014  mCalendarView->setModified( false );
1015  }
1016 
1017  if ( !mURL.isLocalFile() ) {
1018  if ( !TDEIO::NetAccess::upload( mFile, mURL, view() ) ) {
1019  TQString msg = i18n("Cannot upload calendar to '%1'")
1020  .arg( mURL.prettyURL() );
1021  KMessageBox::error( dialogParent() ,msg );
1022  return false;
1023  }
1024  }
1025 
1026  // keep saves on a regular interval
1027  if ( KOPrefs::instance()->mAutoSave ) {
1028  mAutoSaveTimer->stop();
1029  mAutoSaveTimer->start( 1000*60*KOPrefs::instance()->mAutoSaveInterval );
1030  }
1031 
1032  mMainWindow->showStatusMessage( i18n("Saved calendar '%1'.").arg( mURL.prettyURL() ) );
1033 
1034  return true;
1035 }
1036 
1037 void ActionManager::exportHTML()
1038 {
1039  HTMLExportSettings settings( "KOrganizer" );
1040  // Manually read in the config, because parametrized tdeconfigxt objects don't
1041  // seem to load the config theirselves
1042  settings.readConfig();
1043 
1044  TQDate qd1;
1045  qd1 = TQDate::currentDate();
1046  TQDate qd2;
1047  qd2 = TQDate::currentDate();
1048  if ( settings.monthView() )
1049  qd2.addMonths( 1 );
1050  else
1051  qd2.addDays( 7 );
1052  settings.setDateStart( qd1 );
1053  settings.setDateEnd( qd2 );
1054  exportHTML( &settings );
1055 }
1056 
1057 void ActionManager::exportHTML( HTMLExportSettings *settings )
1058 {
1059  if ( !settings || settings->outputFile().isEmpty() )
1060  return;
1061  kdDebug()<<" settings->outputFile() :"<<settings->outputFile()<<endl;
1062  if ( TQFileInfo( settings->outputFile() ).exists() ) {
1063  if(KMessageBox::questionYesNo( dialogParent(), i18n("Do you want to overwrite file \"%1\"").arg( settings->outputFile()) ) == KMessageBox::No)
1064  return;
1065  }
1066  settings->setEMail( KOPrefs::instance()->email() );
1067  settings->setName( KOPrefs::instance()->fullName() );
1068 
1069  settings->setCreditName( "KOrganizer" );
1070  settings->setCreditURL( "http://korganizer.kde.org" );
1071 
1072  KCal::HtmlExport mExport( mCalendarView->calendar(), settings );
1073 
1074  TQDate cdate = settings->dateStart().date();
1075  TQDate qd2 = settings->dateEnd().date();
1076  while ( cdate <= qd2 ) {
1077  TQStringList holidays = KOGlobals::self()->holiday( cdate );
1078  if ( !holidays.isEmpty() ) {
1079  TQStringList::ConstIterator it = holidays.begin();
1080  for ( ; it != holidays.end(); ++it ) {
1081  mExport.addHoliday( cdate, *it );
1082  }
1083  }
1084  cdate = cdate.addDays( 1 );
1085  }
1086 
1087  KURL dest( settings->outputFile() );
1088  if ( dest.isLocalFile() ) {
1089  mExport.save( dest.path() );
1090  } else {
1091  KTempFile tf;
1092  TQString tfile = tf.name();
1093  tf.close();
1094  mExport.save( tfile );
1095  if ( !TDEIO::NetAccess::upload( tfile, dest, view() ) ) {
1096  KNotifyClient::event ( view()->winId(),
1097  i18n("Could not upload file.") );
1098  }
1099  tf.unlink();
1100  }
1101 }
1102 
1103 bool ActionManager::saveAsURL( const KURL &url )
1104 {
1105  kdDebug(5850) << "ActionManager::saveAsURL() " << url.prettyURL() << endl;
1106 
1107  if ( url.isEmpty() ) {
1108  kdDebug(5850) << "ActionManager::saveAsURL(): Empty URL." << endl;
1109  return false;
1110  }
1111  if ( !url.isValid() ) {
1112  kdDebug(5850) << "ActionManager::saveAsURL(): Malformed URL." << endl;
1113  return false;
1114  }
1115 
1116  TQString fileOrig = mFile;
1117  KURL URLOrig = mURL;
1118 
1119  KTempFile *tempFile = 0;
1120  if ( url.isLocalFile() ) {
1121  mFile = url.path();
1122  } else {
1123  tempFile = new KTempFile;
1124  mFile = tempFile->name();
1125  }
1126  mURL = url;
1127 
1128  bool success = saveURL(); // Save local file and upload local file
1129  if ( success ) {
1130  delete mTempFile;
1131  mTempFile = tempFile;
1132  TDEIO::NetAccess::removeTempFile( fileOrig );
1133  TDEConfig *config = KOGlobals::self()->config();
1134  config->setGroup( "General" );
1135  setTitle();
1136  if ( mRecent ) mRecent->addURL( mURL );
1137  } else {
1138  KMessageBox::sorry( dialogParent(), i18n("Unable to save calendar to the file %1.").arg( mFile ), i18n("Error") );
1139  kdDebug(5850) << "ActionManager::saveAsURL() failed" << endl;
1140  mURL = URLOrig;
1141  mFile = fileOrig;
1142  delete tempFile;
1143  }
1144 
1145  return success;
1146 }
1147 
1148 
1150 {
1151  kdDebug(5850) << "ActionManager::saveModifiedURL()" << endl;
1152 
1153  // If calendar isn't modified do nothing.
1154  if ( !mCalendarView->isModified() ) return true;
1155 
1156  mHtmlExportSync = true;
1157  if ( KOPrefs::instance()->mAutoSave && !mURL.isEmpty() ) {
1158  // Save automatically, when auto save is enabled.
1159  return saveURL();
1160  } else {
1161  int result = KMessageBox::warningYesNoCancel(
1162  dialogParent(),
1163  i18n("The calendar has been modified.\nDo you want to save it?"),
1164  TQString(),
1165  KStdGuiItem::save(), KStdGuiItem::discard() );
1166  switch( result ) {
1167  case KMessageBox::Yes:
1168  if ( mURL.isEmpty() ) {
1169  KURL url = getSaveURL();
1170  return saveAsURL( url );
1171  } else {
1172  return saveURL();
1173  }
1174  case KMessageBox::No:
1175  return true;
1176  case KMessageBox::Cancel:
1177  default:
1178  {
1179  mHtmlExportSync = false;
1180  return false;
1181  }
1182  }
1183  }
1184 }
1185 
1186 
1188 {
1189  KURL url = KFileDialog::getSaveURL( locateLocal( "data","korganizer/" ),
1190  i18n("*.vcs *.ics|Calendar Files"),
1191  dialogParent() );
1192 
1193  if ( url.isEmpty() ) return url;
1194 
1195  TQString filename = url.fileName( false );
1196 
1197  TQString e = filename.right( 4 );
1198  if ( e != ".vcs" && e != ".ics" ) {
1199  // Default save format is iCalendar
1200  filename += ".ics";
1201  }
1202 
1203  url.setFileName( filename );
1204 
1205  kdDebug(5850) << "ActionManager::getSaveURL(): url: " << url.url() << endl;
1206 
1207  return url;
1208 }
1209 
1210 void ActionManager::saveProperties( TDEConfig *config )
1211 {
1212  kdDebug(5850) << "ActionManager::saveProperties" << endl;
1213 
1214  config->writeEntry( "UseResourceCalendar", !mMainWindow->hasDocument() );
1215  if ( mMainWindow->hasDocument() ) {
1216  config->writePathEntry( "Calendar",mURL.url() );
1217  }
1218 }
1219 
1220 void ActionManager::readProperties( TDEConfig *config )
1221 {
1222  kdDebug(5850) << "ActionManager::readProperties" << endl;
1223 
1224  bool isResourceCalendar(
1225  config->readBoolEntry( "UseResourceCalendar", true ) );
1226  TQString calendarUrl = config->readPathEntry( "Calendar" );
1227 
1228  if ( !isResourceCalendar && !calendarUrl.isEmpty() ) {
1229  mMainWindow->init( true );
1230  KURL u( calendarUrl );
1231  openURL( u );
1232  } else {
1233  mMainWindow->init( false );
1234  }
1235 }
1236 
1238 {
1239  kdDebug(5850) << "ActionManager::checkAutoSave()" << endl;
1240 
1241  // Don't save if auto save interval is zero
1242  if ( KOPrefs::instance()->mAutoSaveInterval == 0 ) return;
1243 
1244  // has this calendar been saved before? If yes automatically save it.
1245  if ( KOPrefs::instance()->mAutoSave ) {
1246  if ( mCalendarResources || ( mCalendar && !url().isEmpty() ) ) {
1247  saveCalendar();
1248  }
1249  }
1250 }
1251 
1252 
1253 // Configuration changed as a result of the options dialog.
1255 {
1256  kdDebug(5850) << "ActionManager::updateConfig()" << endl;
1257 
1258  if ( KOPrefs::instance()->mAutoSave && !mAutoSaveTimer->isActive() ) {
1259  checkAutoSave();
1260  if ( KOPrefs::instance()->mAutoSaveInterval > 0 ) {
1261  mAutoSaveTimer->start( 1000 * 60 *
1262  KOPrefs::instance()->mAutoSaveInterval );
1263  }
1264  }
1265  if ( !KOPrefs::instance()->mAutoSave ) mAutoSaveTimer->stop();
1266  mNextXDays->setText( i18n( "&Next Day", "&Next %n Days",
1267  KOPrefs::instance()->mNextXDays ) );
1268 
1269  KOCore::self()->reloadPlugins();
1270  mParts = KOCore::self()->reloadParts( mMainWindow, mParts );
1271 
1272  setDestinationPolicy();
1273 
1274  if ( mResourceView )
1275  mResourceView->updateView();
1276 
1277  KOGroupware::instance()->freeBusyManager()->setBrokenUrl( false );
1278 }
1279 
1280 void ActionManager::setDestinationPolicy()
1281 {
1282  if ( mCalendarResources ) {
1283  if ( KOPrefs::instance()->mDestination == KOPrefs::askDestination )
1284  mCalendarResources->setAskDestinationPolicy();
1285  else
1286  mCalendarResources->setStandardDestinationPolicy();
1287  }
1288 }
1289 
1291 {
1292  TDEProcess *proc = new TDEProcess;
1293  *proc << "tdecmshell" << "language";
1294 
1295  connect( proc,TQ_SIGNAL( processExited( TDEProcess * ) ),
1296  TQ_SLOT( configureDateTimeFinished( TDEProcess * ) ) );
1297 
1298  if ( !proc->start() ) {
1299  KMessageBox::sorry( dialogParent(),
1300  i18n("Could not start control module for date and time format.") );
1301  delete proc;
1302  }
1303 }
1304 
1306 {
1307  KTipDialog::showTip( dialogParent(),TQString(),true );
1308 }
1309 
1311 {
1312  KTipDialog::showTip( dialogParent() );
1313 }
1314 
1316 {
1317  if ( mWindowList ) {
1318  if ( url.isEmpty() ) return mWindowList->defaultInstance();
1319  else return mWindowList->findInstance( url );
1320  } else {
1321  return 0;
1322  }
1323 }
1324 
1325 void ActionManager::dumpText( const TQString &str )
1326 {
1327  kdDebug(5850) << "ActionManager::dumpText(): " << str << endl;
1328 }
1329 
1330 void ActionManager::toggleDateNavigator()
1331 {
1332  bool visible = mDateNavigatorShowAction->isChecked();
1333  if ( mCalendarView ) mCalendarView->showDateNavigator( visible );
1334 }
1335 
1336 void ActionManager::toggleTodoView()
1337 {
1338  bool visible = mTodoViewShowAction->isChecked();
1339  if ( mCalendarView ) mCalendarView->showTodoView( visible );
1340 }
1341 
1342 void ActionManager::toggleEventViewer()
1343 {
1344  bool visible = mEventViewerShowAction->isChecked();
1345  if ( mCalendarView ) mCalendarView->showEventViewer( visible );
1346 }
1347 
1348 void ActionManager::toggleResourceView()
1349 {
1350  bool visible = mResourceViewShowAction->isChecked();
1351  kdDebug(5850) << "toggleResourceView: " << endl;
1352  if ( mResourceView ) {
1353  if ( visible ) mResourceView->show();
1354  else mResourceView->hide();
1355  }
1356 }
1357 
1358 void ActionManager::toggleResourceButtons()
1359 {
1360  bool visible = mResourceButtonsAction->isChecked();
1361 
1362  kdDebug(5850) << "RESOURCE VIEW " << long( mResourceView ) << endl;
1363 
1364  if ( mResourceView ) mResourceView->showButtons( visible );
1365 }
1366 
1367 bool ActionManager::openURL( const TQString &url )
1368 {
1369  return openURL( KURL( url ) );
1370 }
1371 
1372 bool ActionManager::mergeURL( const TQString &url )
1373 {
1374  return openURL( KURL( url ),true );
1375 }
1376 
1377 bool ActionManager::saveAsURL( const TQString &url )
1378 {
1379  return saveAsURL( KURL( url ) );
1380 }
1381 
1383 {
1384  return mURL.url();
1385 }
1386 
1387 bool ActionManager::editIncidence( const TQString &uid )
1388 {
1389  return mCalendarView->editIncidence( uid );
1390 }
1391 
1392 bool ActionManager::editIncidence( const TQString &uid, const TQDate &date )
1393 {
1394  return mCalendarView->editIncidence( uid, date );
1395 }
1396 
1397 bool ActionManager::deleteIncidence( const TQString& uid, bool force )
1398 {
1399  return mCalendarView->deleteIncidence( uid, force );
1400 }
1401 
1402 bool ActionManager::addIncidence( const TQString& ical )
1403 {
1404  return mCalendarView->addIncidence( ical );
1405 }
1406 
1407 void ActionManager::configureDateTimeFinished( TDEProcess *proc )
1408 {
1409  delete proc;
1410 }
1411 
1412 void ActionManager::downloadNewStuff()
1413 {
1414  kdDebug(5850) << "ActionManager::downloadNewStuff()" << endl;
1415 
1416  if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
1417  mNewStuff->download();
1418 }
1419 
1420 void ActionManager::uploadNewStuff()
1421 {
1422  if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
1423  mNewStuff->upload();
1424 }
1425 
1426 TQString ActionManager::localFileName()
1427 {
1428  return mFile;
1429 }
1430 
1431 class ActionManager::ActionStringsVisitor : public IncidenceBase::Visitor
1432 {
1433  public:
1434  ActionStringsVisitor() : mShow( 0 ), mEdit( 0 ), mDelete( 0 ) {}
1435 
1436  bool act( IncidenceBase *incidence, TDEAction *show, TDEAction *edit, TDEAction *del )
1437  {
1438  mShow = show;
1439  mEdit = edit;
1440  mDelete = del;
1441  return incidence->accept( *this );
1442  }
1443 
1444  protected:
1445  bool visit( Event * ) {
1446  if ( mShow ) mShow->setText( i18n("&Show Event") );
1447  if ( mEdit ) mEdit->setText( i18n("&Edit Event...") );
1448  if ( mDelete ) mDelete->setText( i18n("&Delete Event") );
1449  return true;
1450  }
1451  bool visit( Todo * ) {
1452  if ( mShow ) mShow->setText( i18n("&Show To-do") );
1453  if ( mEdit ) mEdit->setText( i18n("&Edit To-do...") );
1454  if ( mDelete ) mDelete->setText( i18n("&Delete To-do") );
1455  return true;
1456  }
1457  bool visit( Journal * ) { return assignDefaultStrings(); }
1458  protected:
1459  bool assignDefaultStrings() {
1460  if ( mShow ) mShow->setText( i18n("&Show") );
1461  if ( mEdit ) mEdit->setText( i18n("&Edit...") );
1462  if ( mDelete ) mDelete->setText( i18n("&Delete") );
1463  return true;
1464  }
1465  TDEAction *mShow;
1466  TDEAction *mEdit;
1467  TDEAction *mDelete;
1468 };
1469 
1470 void ActionManager::processIncidenceSelection( Incidence *incidence, const TQDate & )
1471 {
1472 // kdDebug(5850) << "ActionManager::processIncidenceSelection()" << endl;
1473 
1474  if ( !incidence ) {
1475  enableIncidenceActions( false );
1476  return;
1477  }
1478 
1479  enableIncidenceActions( true );
1480 
1481  if ( incidence->isReadOnly() ) {
1482  mCutAction->setEnabled( false );
1483  mDeleteAction->setEnabled( false );
1484  }
1485 
1486  ActionStringsVisitor v;
1487  if ( !v.act( incidence, mShowIncidenceAction, mEditIncidenceAction, mDeleteIncidenceAction ) ) {
1488  mShowIncidenceAction->setText( i18n("&Show") );
1489  mEditIncidenceAction->setText( i18n("&Edit...") );
1490  mDeleteIncidenceAction->setText( i18n("&Delete") );
1491  }
1492 }
1493 
1494 void ActionManager::enableIncidenceActions( bool enabled )
1495 {
1496  mShowIncidenceAction->setEnabled( enabled );
1497  mEditIncidenceAction->setEnabled( enabled );
1498  mDeleteIncidenceAction->setEnabled( enabled );
1499 // mAssignResourceAction->setEnabled( enabled );
1500 
1501  mCutAction->setEnabled( enabled );
1502  mCopyAction->setEnabled( enabled );
1503  mDeleteAction->setEnabled( enabled );
1504  mPublishEvent->setEnabled( enabled );
1505  mForwardEvent->setEnabled( enabled );
1506  mSendInvitation->setEnabled( enabled );
1507  mSendCancel->setEnabled( enabled );
1508  mSendStatusUpdate->setEnabled( enabled );
1509  mRequestChange->setEnabled( enabled );
1510  mRequestUpdate->setEnabled( enabled );
1511 }
1512 
1513 void ActionManager::keyBindings()
1514 {
1515  KKeyDialog dlg( false, view() );
1516  if ( mMainWindow )
1517  dlg.insert( mMainWindow->getActionCollection() );
1518 
1519  KOrg::Part *part;
1520  for ( part = mParts.first(); part; part = mParts.next() ) {
1521  dlg.insert( part->actionCollection(), part->shortInfo() );
1522  }
1523  dlg.configure();
1524 }
1525 
1526 void ActionManager::loadParts()
1527 {
1528  mParts = KOCore::self()->loadParts( mMainWindow );
1529 }
1530 
1531 void ActionManager::setTitle()
1532 {
1533  mMainWindow->setTitle();
1534 }
1535 
1536 KCalendarIface::ResourceRequestReply ActionManager::resourceRequest( const TQValueList<TQPair<TQDateTime, TQDateTime> >&,
1537  const TQCString& resource,
1538  const TQString& vCalIn )
1539 {
1540  kdDebug(5850) << k_funcinfo << "resource=" << resource << " vCalIn=" << vCalIn << endl;
1542  reply.vCalOut = "VCalOut";
1543  return reply;
1544 }
1545 
1546 TQPair<ResourceCalendar *, TQString> ActionManager::viewSubResourceCalendar()
1547 {
1548  TQPair<ResourceCalendar *, TQString> p( 0, TQString() );
1549 
1550  // return now if we are running as a part and we aren't the currently active part
1551  if ( mIsPart && !mMainWindow->isCurrentlyActivePart() ) {
1552  return p;
1553  }
1554 
1555  KOrg::BaseView *cV = mCalendarView->viewManager()->currentView();
1556  if ( cV && cV == mCalendarView->viewManager()->multiAgendaView() ) {
1557  cV = mCalendarView->viewManager()->multiAgendaView()->selectedAgendaView();
1558  }
1559  if ( cV ) {
1560  p = qMakePair( cV->resourceCalendar(), cV->subResourceCalendar() );
1561  }
1562  return p;
1563 }
1564 
1565 bool ActionManager::isWritable( ResourceCalendar *res, const TQString &subRes,
1566  const TQString &contentsType )
1567 {
1568 
1569  if ( res && res->isActive() ) {
1570  // Check specified resource for writability.
1571  if ( res->readOnly() || !res->subresourceWritable( subRes ) ) {
1572  TQString resName = res->resourceName();
1573  if ( res->canHaveSubresources() ) {
1574  resName = res->labelForSubresource( subRes );
1575  }
1576  KMessageBox::sorry(
1577  dialogParent(),
1578  i18n( "\"%1\" is read-only. "
1579  "Please select a writable calendar before attempting to create a new item." ).
1580  arg( resName ),
1581  i18n( "Read-only calendar" ) );
1582  return false;
1583  } else {
1584  return true;
1585  }
1586  } else {
1587  // No specific resource so let's check all possible calendars for writability.
1588  CalendarResourceManager *m = mCalendarResources->resourceManager();
1589  CalendarResourceManager::ActiveIterator it;
1590  for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
1591  ResourceCalendar *res = (*it);
1592  if ( res->canHaveSubresources() ) {
1593  TQStringList subResources = res->subresources();
1594  for ( TQStringList::ConstIterator subit = subResources.constBegin();
1595  subit != subResources.constEnd(); ++subit ) {
1596  if ( res->subresourceWritable( (*subit) ) && res->subresourceActive( (*subit) ) ) {
1597  if ( res->subresourceType( *subit ).isEmpty() ||
1598  res->subresourceType( *subit ) == contentsType ) {
1599  return true;
1600  }
1601  }
1602  }
1603  } else if ( !res->readOnly() ) {
1604  return true;
1605  }
1606  }
1607  // we don't have any writable calendars
1608  TQString errorText;
1609  if ( contentsType == "event" ) {
1610  errorText =
1611  i18n( "You have no active, writable event folder so saving will not be possible.\n"
1612  "Please create or activate at least one writable event folder and try again." );
1613  } else if ( contentsType == "todo" ) {
1614  errorText =
1615  i18n( "You have no active, writable to-do (task) folders so saving will not be possible.\n"
1616  "Please create or activate at least one writable to-do folder and try again." );
1617  } else if ( contentsType == "journal" ) {
1618  errorText =
1619  i18n( "You have no active, writable journal folder so saving will not be possible.\n"
1620  "Please create or activate at least one writable journal folder and try again." );
1621  } else {
1622  errorText =
1623  i18n( "You have no active, writable calendar folder so saving will not be possible.\n"
1624  "Please create or activate at least one writable calendar folder and try again." );
1625  }
1626  KMessageBox::sorry(
1627  dialogParent(),
1628  errorText,
1629  i18n( "No writable calendar" ) );
1630  return false;
1631  }
1632 }
1633 
1634 void ActionManager::openEventEditor( const TQString& text )
1635 {
1636  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1637  if ( isWritable( p.first, p.second, "event" ) ) {
1638  mCalendarView->newEvent( p.first, p.second, text );
1639  }
1640 }
1641 
1642 void ActionManager::openEventEditor( const TQString& summary,
1643  const TQString& description,
1644  const TQString& attachment )
1645 {
1646  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1647  mCalendarView->newEvent( p.first, p.second, summary, description, attachment );
1648 }
1649 
1650 void ActionManager::openEventEditor( const TQString& summary,
1651  const TQString& description,
1652  const TQString& attachment,
1653  const TQStringList& attendees )
1654 {
1655  mCalendarView->newEvent( 0, TQString(), summary, description, attachment, attendees );
1656 }
1657 
1658 void ActionManager::openEventEditor( const TQString & summary,
1659  const TQString & description,
1660  const TQString & uri,
1661  const TQString & file,
1662  const TQStringList & attendees,
1663  const TQString & attachmentMimetype )
1664 {
1665  int action = KOPrefs::instance()->defaultEmailAttachMethod();
1666  if ( attachmentMimetype != "message/rfc822" ) {
1667  action = KOPrefs::Link;
1668  } else if ( KOPrefs::instance()->defaultEmailAttachMethod() == KOPrefs::Ask ) {
1669  TDEPopupMenu *menu = new TDEPopupMenu( 0 );
1670  menu->insertItem( i18n("Attach as &link"), KOPrefs::Link );
1671  menu->insertItem( i18n("Attach &inline"), KOPrefs::InlineFull );
1672  menu->insertItem( i18n("Attach inline &without attachments"), KOPrefs::InlineBody );
1673  menu->insertSeparator();
1674  menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::Ask );
1675  action = menu->exec( TQCursor::pos(), 0 );
1676  delete menu;
1677  }
1678 
1679  TQString attData;
1680  KTempFile tf;
1681  tf.setAutoDelete( true );
1682  switch ( action ) {
1683  case KOPrefs::Ask:
1684  return;
1685  case KOPrefs::Link:
1686  attData = uri;
1687  break;
1688  case KOPrefs::InlineFull:
1689  attData = file;
1690  break;
1691  case KOPrefs::InlineBody:
1692  {
1693  TQFile f( file );
1694  if ( !f.open( IO_ReadOnly ) )
1695  return;
1696  KMime::Message *msg = new KMime::Message();
1697  msg->setContent( TQCString( f.readAll() ) );
1698  TQCString head = msg->head();
1699  msg->parse();
1700  if ( msg == msg->textContent() || msg->textContent() == 0 ) { // no attachments
1701  attData = file;
1702  } else {
1703  if ( KMessageBox::warningContinueCancel( 0,
1704  i18n("Removing attachments from an email might invalidate its signature."),
1705  i18n("Remove Attachments"), KStdGuiItem::cont(), "BodyOnlyInlineAttachment" )
1706  != KMessageBox::Continue )
1707  return;
1708  // due to kmime shortcomings in KDE3, we need to assemble the result manually
1709  int begin = 0;
1710  int end = head.find( '\n' );
1711  bool skipFolded = false;
1712  while ( end >= 0 && end > begin ) {
1713  if ( head.find( "Content-Type:", begin, false ) != begin &&
1714  head.find( "Content-Transfer-Encoding:", begin, false ) != begin &&
1715  !(skipFolded && (head[begin] == ' ' || head[end] == '\t')) ) {
1716  TQCString line = head.mid( begin, end - begin );
1717  tf.file()->writeBlock( line.data(), line.length() );
1718  tf.file()->writeBlock( "\n", 1 );
1719  skipFolded = false;
1720  } else {
1721  skipFolded = true;
1722  }
1723 
1724  begin = end + 1;
1725  end = head.find( '\n', begin );
1726  if ( end < 0 && begin < (int)head.length() )
1727  end = head.length() - 1;
1728  }
1729  TQCString cte = msg->textContent()->contentTransferEncoding()->as7BitString();
1730  if ( !cte.stripWhiteSpace().isEmpty() ) {
1731  tf.file()->writeBlock( cte.data(), cte.length() );
1732  tf.file()->writeBlock( "\n", 1 );
1733  }
1734  TQCString ct = msg->textContent()->contentType()->as7BitString();
1735  if ( !ct.stripWhiteSpace().isEmpty() )
1736  tf.file()->writeBlock( ct.data(), ct.length() );
1737  tf.file()->writeBlock( "\n", 1 );
1738  tf.file()->writeBlock( msg->textContent()->body() );
1739  attData = tf.name();
1740  }
1741  tf.close();
1742  delete msg;
1743  break;
1744  }
1745  default:
1746  // menu could have been closed by cancel, if so, do nothing
1747  return;
1748  }
1749 
1750  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1751  mCalendarView->newEvent( p.first, p.second, summary, description, attData,
1752  attendees, attachmentMimetype, action != KOPrefs::Link );
1753 }
1754 
1755 void ActionManager::openTodoEditor( const TQString& text )
1756 {
1757  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1758  if ( isWritable( p.first, p.second, "todo" ) ) {
1759  mCalendarView->newTodo( p.first, p.second, text );
1760  }
1761 }
1762 
1763 void ActionManager::openTodoEditor( const TQString& summary,
1764  const TQString& description,
1765  const TQString& attachment )
1766 {
1767  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1768  mCalendarView->newTodo( p.first, p.second, summary, description, attachment );
1769 }
1770 
1771 void ActionManager::openTodoEditor( const TQString& summary,
1772  const TQString& description,
1773  const TQString& attachment,
1774  const TQStringList& attendees )
1775 {
1776  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1777  mCalendarView->newTodo( p.first, p.second, summary, description, attachment, attendees );
1778 }
1779 
1780 void ActionManager::openTodoEditor(const TQString & summary,
1781  const TQString & description,
1782  const TQString & uri,
1783  const TQString & file,
1784  const TQStringList & attendees,
1785  const TQString & attachmentMimetype,
1786  bool isTask )
1787 {
1788  int action = KOPrefs::instance()->defaultTodoAttachMethod();
1789  if ( attachmentMimetype != "message/rfc822" ) {
1790  action = KOPrefs::TodoAttachLink;
1791  } else if ( KOPrefs::instance()->defaultTodoAttachMethod() == KOPrefs::TodoAttachAsk ) {
1792  TDEPopupMenu *menu = new TDEPopupMenu( 0 );
1793  menu->insertItem( i18n("Attach as &link"), KOPrefs::TodoAttachLink );
1794  menu->insertItem( i18n("Attach &inline"), KOPrefs::TodoAttachInlineFull );
1795  menu->insertSeparator();
1796  menu->insertItem( SmallIcon("cancel"), i18n("C&ancel"), KOPrefs::TodoAttachAsk );
1797  action = menu->exec( TQCursor::pos(), 0 );
1798  delete menu;
1799  }
1800 
1801  TQStringList attData;
1802  switch ( action ) {
1803  case KOPrefs::TodoAttachAsk:
1804  return;
1805  case KOPrefs::TodoAttachLink:
1806  attData << uri;
1807  break;
1808  case KOPrefs::TodoAttachInlineFull:
1809  attData << file;
1810  break;
1811  default:
1812  // menu could have been closed by cancel, if so, do nothing
1813  return;
1814  }
1815 
1816  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1817  mCalendarView->newTodo( p.first, p.second,
1818  summary, description,
1819  attData, attendees,
1820  TQStringList( attachmentMimetype ),
1821  action != KOPrefs::TodoAttachLink,
1822  isTask );
1823 }
1824 
1825 void ActionManager::openJournalEditor( const TQDate& date )
1826 {
1827  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1828  mCalendarView->newJournal( p.first, p.second, date );
1829 }
1830 
1831 void ActionManager::openJournalEditor( const TQString& text, const TQDate& date )
1832 {
1833  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1834  mCalendarView->newJournal( p.first, p.second, text, date );
1835 }
1836 
1837 void ActionManager::openJournalEditor( const TQString& text )
1838 {
1839  TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1840  if ( isWritable( p.first, p.second, "journal" ) ) {
1841  mCalendarView->newJournal( p.first, p.second, text );
1842  }
1843 }
1844 
1845 //TODO:
1846 // void ActionManager::openJournalEditor( const TQString& summary,
1847 // const TQString& description,
1848 // const TQString& attachment )
1849 // {
1850 // TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1851 // mCalendarView->newJournal( p.first, p.second, summary, description, attachment );
1852 // }
1853 
1854 
1855 void ActionManager::showJournalView()
1856 {
1857  mCalendarView->viewManager()->showJournalView();
1858 }
1859 
1860 void ActionManager::showTodoView()
1861 {
1862  mCalendarView->viewManager()->showTodoView();
1863 }
1864 
1865 void ActionManager::showEventView()
1866 {
1867  mCalendarView->viewManager()->showEventView();
1868 }
1869 
1870 void ActionManager::goDate( const TQDate& date )
1871 {
1872  mCalendarView->goDate( date );
1873 }
1874 
1875 void ActionManager::goDate( const TQString& date )
1876 {
1877  goDate( TDEGlobal::locale()->readDate( date ) );
1878 }
1879 
1880 void ActionManager::showDate(const TQDate & date)
1881 {
1882  mCalendarView->showDate( date );
1883 }
1884 
1885 
1886 void ActionManager::updateUndoAction( const TQString &text )
1887 {
1888  if ( text.isNull() ) {
1889  mUndoAction->setEnabled( false );
1890  mUndoAction->setText( i18n("Undo") );
1891  } else {
1892  mUndoAction->setEnabled( true );
1893  if ( text.isEmpty() ) mUndoAction->setText( i18n("Undo") );
1894  else mUndoAction->setText( i18n("Undo (%1)").arg( text ) );
1895  }
1896 }
1897 
1898 void ActionManager::updateRedoAction( const TQString &text )
1899 {
1900  if ( text.isNull() ) {
1901  mRedoAction->setEnabled( false );
1902  mRedoAction->setText( i18n( "Redo" ) );
1903  } else {
1904  mRedoAction->setEnabled( true );
1905  if ( text.isEmpty() ) mRedoAction->setText( i18n("Redo") );
1906  else mRedoAction->setText( i18n( "Redo (%1)" ).arg( text ) );
1907  }
1908 }
1909 
1910 bool ActionManager::queryClose()
1911 {
1912  kdDebug(5850) << "ActionManager::queryClose()" << endl;
1913 
1914  bool close = true;
1915 
1916  if ( mCalendar && mCalendar->isModified() ) {
1917  int res = KMessageBox::questionYesNoCancel( dialogParent(),
1918  i18n("The calendar contains unsaved changes. Do you want to save them before exiting?"), TQString(), KStdGuiItem::save(), KStdGuiItem::discard() );
1919  // Exit on yes and no, don't exit on cancel. If saving fails, ask for exiting.
1920  if ( res == KMessageBox::Yes ) {
1921  close = saveModifiedURL();
1922  if ( !close ) {
1923  int res1 = KMessageBox::questionYesNo( dialogParent(), i18n("Unable to save the calendar. Do you still want to close this window?"), TQString(), KStdGuiItem::close(), KStdGuiItem::cancel() );
1924  close = ( res1 == KMessageBox::Yes );
1925  }
1926  } else {
1927  close = ( res == KMessageBox::No );
1928  }
1929  } else if ( mCalendarResources ) {
1930  if ( !mIsClosing ) {
1931  kdDebug(5850) << "!mIsClosing" << endl;
1932  if ( !saveResourceCalendar() ) return false;
1933 
1934  // FIXME: Put main window into a state indicating final saving.
1935  mIsClosing = true;
1936 // FIXME: Close main window when save is finished
1937 // connect( mCalendarResources, TQ_SIGNAL( calendarSaved() ),
1938 // mMainWindow, TQ_SLOT( close() ) );
1939  }
1940  if ( mCalendarResources->isSaving() ) {
1941  kdDebug(5850) << "ActionManager::queryClose(): isSaving" << endl;
1942  close = false;
1943  KMessageBox::information( dialogParent(),
1944  i18n("Unable to exit. Saving still in progress.") );
1945  } else {
1946  kdDebug(5850) << "ActionManager::queryClose(): close = true" << endl;
1947  close = true;
1948  }
1949  } else {
1950  close = true;
1951  }
1952 
1953  return close;
1954 }
1955 
1957 {
1958  if ( mCalendar ) {
1959  if ( view()->isModified() ) {
1960  if ( !url().isEmpty() ) {
1961  saveURL();
1962  } else {
1963  TQString location = locateLocal( "data", "korganizer/kontact.ics" );
1964  saveAsURL( location );
1965  }
1966  }
1967  } else if ( mCalendarResources ) {
1968  mCalendarResources->save();
1969  // FIXME: Make sure that asynchronous saves don't fail.
1970  }
1971 }
1972 
1974 {
1975  if ( !mCalendarResources ) return false;
1976  CalendarResourceManager *m = mCalendarResources->resourceManager();
1977 
1978  CalendarResourceManager::ActiveIterator it;
1979  for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
1980  if ( (*it)->readOnly() ) continue;
1981  if ( !(*it)->save() ) {
1982  int result = KMessageBox::warningContinueCancel( view(),
1983  i18n( "Saving of '%1' failed. Check that the resource is "
1984  "properly configured.\nIgnore problem and continue without "
1985  "saving or cancel save?" ).arg( (*it)->resourceName() ),
1986  i18n("Save Error"), KStdGuiItem::dontSave() );
1987  if ( result == KMessageBox::Cancel ) return false;
1988  }
1989  }
1990  return true;
1991 }
1992 
1994 {
1995  if ( !mCalendarResources ) return;
1996  CalendarResourceManager *m = mCalendarResources->resourceManager();
1997 
1998  CalendarResourceManager::ActiveIterator it;
1999  for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
2000  (*it)->load();
2001  }
2002 }
2003 
2004 void ActionManager::importCalendar( const KURL &url )
2005 {
2006  if ( !url.isValid() ) {
2007  KMessageBox::error( dialogParent(),
2008  i18n("URL '%1' is invalid.").arg( url.prettyURL() ) );
2009  return;
2010  }
2011 
2012  PreviewDialog *dialog;
2013  dialog = new PreviewDialog( url, mMainWindow->topLevelWidget() );
2014  connect( dialog, TQ_SIGNAL( dialogFinished( PreviewDialog * ) ),
2015  TQ_SLOT( slotPreviewDialogFinished( PreviewDialog * ) ) );
2016  connect( dialog, TQ_SIGNAL( openURL( const KURL &, bool ) ),
2017  TQ_SLOT( openURL( const KURL &, bool ) ) );
2018  connect( dialog, TQ_SIGNAL( addResource( const KURL & ) ),
2019  TQ_SLOT( addResource( const KURL & ) ) );
2020 
2021  if ( dialog->loadCalendar() ) {
2022  dialog->show();
2023  } else {
2024  KMessageBox::error( dialogParent(), i18n("Unable to open the calendar") );
2025  }
2026 }
2027 
2028 void ActionManager::slotPreviewDialogFinished( PreviewDialog *dlg )
2029 {
2030  dlg->deleteLater();
2031  mCalendarView->updateView();
2032 }
2033 
2035 {
2036  if ( KOPrefs::instance()->mAutoArchive )
2037  mAutoArchiveTimer->start( 4 * 60 * 60 * 1000, true ); // check again in 4 hours
2038  else
2039  mAutoArchiveTimer->stop();
2040 }
2041 
2043 {
2044  if ( !mCalendarView->calendar() ) // can this happen?
2045  return;
2046  mAutoArchiveTimer->stop();
2047  EventArchiver archiver;
2048  connect( &archiver, TQ_SIGNAL( eventsDeleted() ), mCalendarView, TQ_SLOT( updateView() ) );
2049  archiver.runAuto( mCalendarView->calendar(), mCalendarView, false /*no gui*/ );
2050  // restart timer with the correct delay ( especially useful for the first time )
2052 }
2053 
2054 void ActionManager::loadProfile( const TQString & path )
2055 {
2056  KOPrefs::instance()->writeConfig();
2057  TDEConfig* const cfg = KOPrefs::instance()->config();
2058 
2059  const TDEConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
2060  const TQStringList groups = profile.groupList();
2061  for ( TQStringList::ConstIterator it = groups.begin(), end = groups.end(); it != end; ++it )
2062  {
2063  cfg->setGroup( *it );
2064  typedef TQMap<TQString, TQString> StringMap;
2065  const StringMap entries = profile.entryMap( *it );
2066  for ( StringMap::ConstIterator it2 = entries.begin(), end = entries.end(); it2 != end; ++it2 )
2067  {
2068  cfg->writeEntry( it2.key(), it2.data() );
2069  }
2070  }
2071 
2072  cfg->sync();
2073  KOPrefs::instance()->readConfig();
2074 }
2075 
2076 namespace {
2077  void copyConfigEntry( TDEConfig* source, TDEConfig* dest, const TQString& group, const TQString& key, const TQString& defaultValue=TQString() )
2078  {
2079  source->setGroup( group );
2080  dest->setGroup( group );
2081  dest->writeEntry( key, source->readEntry( key, defaultValue ) );
2082  }
2083 }
2084 
2085 void ActionManager::saveToProfile( const TQString & path ) const
2086 {
2087  KOPrefs::instance()->writeConfig();
2088  TDEConfig* const cfg = KOPrefs::instance()->config();
2089 
2090  TDEConfig profile( path+"/korganizerrc", /*read-only=*/false, /*useglobals=*/false );
2091  ::copyConfigEntry( cfg, &profile, "Views", "Agenda View Calendar Display" );
2092 }
2093 
2094 bool ActionManager::handleCommandLine()
2095 {
2096  TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
2097  KOrg::MainWindow *mainWindow = ActionManager::findInstance( KURL() );
2098 
2099  bool ret = true;
2100 
2101  if ( !mainWindow ) {
2102  kdError() << "Unable to find default calendar resources view." << endl;
2103  ret = false;
2104  } else if ( args->count() <= 0 ) {
2105  // No filenames given => all other args are meaningless, show main Window
2106  mainWindow->topLevelWidget()->show();
2107  } else if ( !args->isSet( "open" ) ) {
2108  // Import, merge, or ask => we need the resource calendar window anyway.
2109  mainWindow->topLevelWidget()->show();
2110 
2111  // Check for import, merge or ask
2112  if ( args->isSet( "import" ) ) {
2113  for( int i = 0; i < args->count(); ++i ) {
2114  mainWindow->actionManager()->addResource( args->url( i ) );
2115  }
2116  } else if ( args->isSet( "merge" ) ) {
2117  for( int i = 0; i < args->count(); ++i ) {
2118  mainWindow->actionManager()->mergeURL( args->url( i ).url() );
2119  }
2120  } else {
2121  for( int i = 0; i < args->count(); ++i ) {
2122  mainWindow->actionManager()->importCalendar( args->url( i ) );
2123  }
2124  }
2125  }
2126 
2127  return ret;
2128 }
2129 
2131 {
2132  return mCalendarView->topLevelWidget();
2133 }
2134 
2135 #include "actionmanager.moc"
bool mergeURL(const TQString &url)
Open calendar file from URL.
bool saveURL()
Save calendar file to URL of current calendar.
KURL getSaveURL()
Get URL for saving.
void file_open()
open a file, load it into the calendar.
TQString getCurrentURLasString() const
Get current URL as TQString.
void slotAutoArchivingSettingsModified()
connected to CalendarView's signal which comes from the ArchiveDialog
void file_close()
close a file, prompt for save if changes made.
bool addIncidence(const TQString &ical)
Add an incidence to the active calendar.
void file_save()
save a file with the current fileName.
void file_icalimport()
import a calendar from another program like ical.
void createCalendarResources()
Create Calendar object based on the resource framework and set it on the view.
void loadResourceCalendar()
Load the resource based calendar.
void file_new()
open new window
void showTipOnStart()
Show tip of the day.
void createCalendarLocal()
Create Calendar object based on local file and set it on the view.
void readSettings()
Using the TDEConfig associated with the kapp variable, read in the settings from the config file.
bool saveResourceCalendar()
Save the resource based calendar.
void saveCalendar()
Save calendar to disk.
void showTip()
Show tip of the day.
TQWidget * dialogParent()
Return widget used as parent for dialogs and message boxes.
void updateConfig()
Options dialog made a changed to the configuration.
void writeSettings()
Write current state to config file.
void closeURL()
Close calendar file opened from URL.
bool saveModifiedURL()
Save calendar if it is modified by the user.
void slotAutoArchive()
called by the auto archive timer to automatically delete/archive events
void file_revert()
revert to saved
void checkAutoSave()
called by the autoSaveTimer to automatically save the calendar
static KOrg::MainWindow * findInstance(const KURL &url)
Is there a instance with this URL?
void file_merge()
open a calendar and add the contents to the current calendar.
void actionNew(const KURL &url=KURL())
Emitted when the "New" action is activated.
void init()
Peform initialization that requires this* to be full constructed.
void file_archive()
delete or archive old entries in your calendar for speed/space.
virtual bool deleteIncidence(const TQString &uid, bool force=false)
Delete the incidence with the given unique id from current calendar.
void configChanged()
When change is made to options dialog, the topwidget will catch this and emit this signal which notif...
bool saveAsURL(const KURL &kurl)
Save calendar file to URL.
bool addResource(const KURL &mUrl)
Add a new resource.
bool openURL(const KURL &url, bool merge=false)
Open calendar file from URL.
KURL url() const
Get current URL.
void file_saveas()
save a file under a (possibly) different filename.
void configureDateTime()
Open kcontrol module for configuring date and time formats.
This is the main calendar widget.
Definition: calendarview.h:82
bool openCalendar(const TQString &filename, bool merge=false)
Load calendar from file filename.
void readSettings()
Using the TDEConfig associated with the kapp variable, read in the settings from the config file.
bool addIncidence(const TQString &ical)
Add an incidence to the active calendar.
void newEvent()
create new event without having a date hint.
void writeSettings()
write current state to config file.
void checkClipboard()
Check if clipboard contains vCalendar event.
bool isModified()
query whether or not the calendar is "dirty".
void showDate(const TQDate &date)
Show the given date without changing date selection length.
void addExtension(CalendarViewExtension::Factory *)
Add calendar view extension widget.
void newTodo()
create new todo
void closeCalendar()
Close calendar.
void setModified(bool modified=true)
set the state of calendar.
void archiveCalendar()
Archive old events of calendar.
void goDate(const TQDate &date)
Move the current view date to the specified date.
bool saveCalendar(const TQString &filename)
Save calendar data to file.
This class handles expiring and archiving of events.
Definition: eventarchiver.h:48
void runAuto(Calendar *calendar, TQWidget *widget, bool withGUI)
Delete or archive events.
CalendarResourceManager * resourceManager() const
virtual bool save(Ticket *ticket, Incidence *incidence=0)
void resourceAdded(ResourceCalendar *resource)
bool isModified() const
virtual void save()=0
void setOwner(const Person &owner)
virtual bool visit(Event *)
virtual bool accept(Visitor &)
bool isReadOnly() const
virtual bool setValue(const TQString &key, const TQString &value)
virtual TQStringList subresources() const
virtual bool subresourceWritable(const TQString &) const
virtual TQString subresourceType(const TQString &resource)
virtual bool subresourceActive(const TQString &) const
virtual bool canHaveSubresources() const
virtual const TQString labelForSubresource(const TQString &resource) const
virtual void setTimeZoneId(const TQString &timeZoneId)=0
Interface class for calendar requests.
This class manages a list of KOrganizer instances, each associated with a window displaying a calenda...
Definition: kowindowlist.h:44
KOrg::MainWindow * findInstance(const KURL &url)
Is there a instance with this URL?
void addWindow(KOrg::MainWindow *)
Register a main window.
void removeWindow(KOrg::MainWindow *)
Unregister a main window.
KOrg::MainWindow * defaultInstance()
Return default instance.
This class provides an interface for all views being displayed within the main calendar view.
Definition: baseview.h:60
ResourceCalendar * resourceCalendar()
Return resourceCalendar of this view.
Definition: baseview.h:100
TQString subResourceCalendar() const
Return subResourceCalendar of this view.
Definition: baseview.h:105
interface for korganizer main window
Definition: mainwindow.h:41
virtual TDEActionCollection * getActionCollection() const =0
Return actionCollection of this main window.
virtual ActionManager * actionManager()=0
Return ActionManager of this main window.
virtual void showStatusMessage(const TQString &message)=0
Show status mesage in status bar.
virtual TQWidget * topLevelWidget()=0
Return widget whcih represents this main window.
virtual void setTitle()=0
Set window title.