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 <tdestandarddirs.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!
81KOWindowList *ActionManager::mWindowList = 0;
82
83ActionManager::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
100ActionManager::~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
212void 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
220void 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
719void 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
857bool 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
917bool 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
963void 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
1038void 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
1058void 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
1104bool 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
1211void 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
1221void 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
1281void 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
1326void ActionManager::dumpText( const TQString &str )
1327{
1328 kdDebug(5850) << "ActionManager::dumpText(): " << str << endl;
1329}
1330
1331void ActionManager::toggleDateNavigator()
1332{
1333 bool visible = mDateNavigatorShowAction->isChecked();
1334 if ( mCalendarView ) mCalendarView->showDateNavigator( visible );
1335}
1336
1337void ActionManager::toggleTodoView()
1338{
1339 bool visible = mTodoViewShowAction->isChecked();
1340 if ( mCalendarView ) mCalendarView->showTodoView( visible );
1341}
1342
1343void ActionManager::toggleEventViewer()
1344{
1345 bool visible = mEventViewerShowAction->isChecked();
1346 if ( mCalendarView ) mCalendarView->showEventViewer( visible );
1347}
1348
1349void 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
1359void 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
1368bool ActionManager::openURL( const TQString &url )
1369{
1370 return openURL( KURL( url ) );
1371}
1372
1373bool ActionManager::mergeURL( const TQString &url )
1374{
1375 return openURL( KURL( url ),true );
1376}
1377
1378bool ActionManager::saveAsURL( const TQString &url )
1379{
1380 return saveAsURL( KURL( url ) );
1381}
1382
1384{
1385 return mURL.url();
1386}
1387
1388bool ActionManager::editIncidence( const TQString &uid )
1389{
1390 return mCalendarView->editIncidence( uid );
1391}
1392
1393bool ActionManager::editIncidence( const TQString &uid, const TQDate &date )
1394{
1395 return mCalendarView->editIncidence( uid, date );
1396}
1397
1398bool ActionManager::deleteIncidence( const TQString& uid, bool force )
1399{
1400 return mCalendarView->deleteIncidence( uid, force );
1401}
1402
1403bool ActionManager::addIncidence( const TQString& ical )
1404{
1405 return mCalendarView->addIncidence( ical );
1406}
1407
1408void ActionManager::configureDateTimeFinished( TDEProcess *proc )
1409{
1410 delete proc;
1411}
1412
1413void ActionManager::downloadNewStuff()
1414{
1415 kdDebug(5850) << "ActionManager::downloadNewStuff()" << endl;
1416
1417 if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
1418 mNewStuff->download();
1419}
1420
1421void ActionManager::uploadNewStuff()
1422{
1423 if ( !mNewStuff ) mNewStuff = new KONewStuff( mCalendarView );
1424 mNewStuff->upload();
1425}
1426
1427TQString ActionManager::localFileName()
1428{
1429 return mFile;
1430}
1431
1432class 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
1471void 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
1495void 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
1514void 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
1527void ActionManager::loadParts()
1528{
1529 mParts = KOCore::self()->loadParts( mMainWindow );
1530}
1531
1532void ActionManager::setTitle()
1533{
1534 mMainWindow->setTitle();
1535}
1536
1537KCalendarIface::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
1547TQPair<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
1566bool 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
1635void 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
1643void 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
1651void 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
1659void 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
1756void 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
1764void 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
1772void 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
1781void 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
1826void ActionManager::openJournalEditor( const TQDate& date )
1827{
1828 TQPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
1829 mCalendarView->newJournal( p.first, p.second, date );
1830}
1831
1832void 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
1838void 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
1856void ActionManager::showJournalView()
1857{
1858 mCalendarView->viewManager()->showJournalView();
1859}
1860
1861void ActionManager::showTodoView()
1862{
1863 mCalendarView->viewManager()->showTodoView();
1864}
1865
1866void ActionManager::showEventView()
1867{
1868 mCalendarView->viewManager()->showEventView();
1869}
1870
1871void ActionManager::goDate( const TQDate& date )
1872{
1873 mCalendarView->goDate( date );
1874}
1875
1876void ActionManager::goDate( const TQString& date )
1877{
1878 goDate( TDEGlobal::locale()->readDate( date ) );
1879}
1880
1881void ActionManager::showDate(const TQDate & date)
1882{
1883 mCalendarView->showDate( date );
1884}
1885
1886
1887void 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
1899void 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
1911bool 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
2005void 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
2029void 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
2055void 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
2077namespace {
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
2086void 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
2095bool 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 tdeApp 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 tdeApp 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
TQString subResourceCalendar() const
Return subResourceCalendar of this view.
Definition: baseview.h:105
ResourceCalendar * resourceCalendar()
Return resourceCalendar of this view.
Definition: baseview.h:100
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.