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