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