Fix Bug 361605 - kmail crash on double click email
[kdepim.git] / korganizer / calendarview.h
blobe62890fe606c89ddea6779c0484e322b376ca561
1 /*
2 This file is part of KOrganizer.
4 Copyright (c) 2000,2001,2003,2004 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6 Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 As a special exception, permission is given to link this program
23 with any edition of Qt, and distribute the resulting executable,
24 without including the source code for Qt in the source distribution.
27 #ifndef KORG_CALENDARVIEW_H
28 #define KORG_CALENDARVIEW_H
30 #include "korganizerprivate_export.h"
31 #include "helper/searchcollectionhelper.h"
33 #include "interfaces/korganizer/calendarviewbase.h"
35 #include <KCalCore/Incidence>
36 #include <KCalCore/Visitor>
37 #include <KCalCore/ScheduleMessage>
39 #include <Akonadi/Calendar/ITIPHandler>
41 #include <CalendarSupport/MessageWidget>
43 class DateChecker;
44 class DateNavigator;
45 class DateNavigatorContainer;
46 class KODialogManager;
47 class KOTodoView;
48 class KOViewManager;
49 class NavigatorBar;
50 class KOCheckableProxyModel;
51 class AkonadiCollectionView;
52 namespace KOrg
54 class HTMLExportSettings;
57 namespace CalendarSupport
59 class CalPrinter;
60 class IncidenceViewer;
63 namespace IncidenceEditorNG
65 class IncidenceDialog;
68 namespace Akonadi
70 class History;
71 class IncidenceChanger;
72 class CalendarClipboard;
73 class TodoPurger;
76 class QSplitter;
77 class QStackedWidget;
79 using namespace KOrg;
81 class CalendarViewExtension : public QWidget
83 public:
84 explicit CalendarViewExtension(QWidget *parent) : QWidget(parent) {}
86 class Factory
88 public:
89 virtual ~Factory() {}
90 virtual CalendarViewExtension *create(QWidget *parent) = 0;
94 /**
95 This is the main calendar widget. It provides the different views on the
96 calendar data as well as the date navigator. It also handles synchronization
97 of the different views and controls the different dialogs like preferences,
98 event editor, search dialog etc.
100 @short main calendar view widget
101 @author Cornelius Schumacher
103 class KORGANIZERPRIVATE_EXPORT CalendarView : public KOrg::CalendarViewBase,
104 public Akonadi::ETMCalendar::CalendarObserver
106 Q_OBJECT
107 public:
109 Constructs a new calendar view widget.
110 @param parent parent window
112 explicit CalendarView(QWidget *parent = Q_NULLPTR);
113 virtual ~CalendarView();
115 class CalendarViewVisitor : public KCalCore::Visitor
117 public:
118 CalendarViewVisitor() : mView(Q_NULLPTR)
122 bool act(KCalCore::IncidenceBase::Ptr &incidence, CalendarView *view)
124 mView = view;
125 return incidence->accept(*this, incidence);
128 protected:
129 CalendarView *mView;
132 void setCalendar(const Akonadi::ETMCalendar::Ptr &);
133 Akonadi::ETMCalendar::Ptr calendar() const Q_DECL_OVERRIDE;
135 void showMessage(const QString &message, KMessageWidget::MessageType);
137 Akonadi::History *history() const;
138 void setCheckableProxyModel(KOCheckableProxyModel *);
140 KOViewManager *viewManager() const
142 return mViewManager;
144 KODialogManager *dialogManager() const
146 return mDialogManager;
149 QStackedWidget *viewStack() const
151 return mRightFrame;
153 QWidget *leftFrame() const
155 return mLeftFrame;
157 NavigatorBar *navigatorBar() const
159 return mNavigatorBar;
161 DateNavigator *dateNavigator() const
163 return mDateNavigator;
165 // TODO_NG
166 //IncidenceEditors::IncidenceEditor *editorDialog( const Akonadi::Item &item ) const;
167 Akonadi::IncidenceChanger *incidenceChanger() const Q_DECL_OVERRIDE
169 return mChanger;
173 * Informs the date navigator which incidence types should be used
174 * to embolden days, this function is mainly called when the view changes
175 * or when the config changes.
177 void updateHighlightModes();
179 QDate startDate() Q_DECL_OVERRIDE;
180 QDate endDate() Q_DECL_OVERRIDE;
182 KOrg::BaseView *currentView() const;
183 void addView(KOrg::BaseView *) Q_DECL_OVERRIDE;
184 void showView(KOrg::BaseView *) Q_DECL_OVERRIDE;
187 * Adds a calendar view extension widget. CalendarView takes ownership of the
188 * objects created by the factory.
190 void addExtension(CalendarViewExtension::Factory *);
193 * Returns the item selected in the current view (or an invalid one if none selected)
194 * @reimp
196 Akonadi::Item currentSelection() Q_DECL_OVERRIDE;
199 * Returns a pointer to the incidence selected in the current view. If there
200 * is no selection, return the selected todo from the todo list on the left.
202 Akonadi::Item selectedIncidence();
205 * Returns true if there's a filter applied.
207 bool isFiltered() const;
210 * Returns the name of the current filter.
212 QString currentFilterName() const;
214 Q_SIGNALS:
215 /** when change is made to options dialog, the topwidget will catch this
216 * and Q_EMIT this signal which notifies all widgets which have registered
217 * for notification to update their settings. */
218 void configChanged();
220 /** Emitted right before we die */
221 void closed(QWidget *);
223 /** Emitted when state of modified flag changes */
224 void modifiedChanged(bool);
226 /** Emitted when state of read-only flag changes */
227 void readOnlyChanged(bool);
229 /** Emitted when the unit of navigation changes */
230 void changeNavStringPrev(const QString &);
231 void changeNavStringNext(const QString &);
233 /** Emitted when state of events selection has changed and user is organizer*/
234 void organizerEventsSelected(bool);
235 /** Emitted when state of events selection has changed and user is attendee*/
236 void groupEventsSelected(bool);
238 Emitted when an incidence gets selected. If the selection is cleared the
239 signal is emitted with 0 as argument.
241 void incidenceSelected(const Akonadi::Item &incidence, const QDate &date);
242 /** Emitted, when a todoitem is selected or deselected.
243 the connected slots enables/disables the corresponding menu items */
244 void todoSelected(bool);
245 void subtodoSelected(bool);
247 /** Emitted, when a day changed (i.e. korganizer was running at midnight).
248 The argument is the new date */
249 void dayPassed(const QDate &);
252 Emitted, when clipboard content changes. Parameter indicates if paste
253 is possible or not.
255 void pasteEnabled(bool);
256 /** Send status message, which can e.g. be displayed in the status bar. */
257 void statusMessage(const QString &);
259 void calendarViewExpanded(bool);
261 /** Emitted when auto-archiving options were modified */
262 void autoArchivingSettingsModified();
264 void newIncidenceChanger(Akonadi::IncidenceChanger *) Q_DECL_OVERRIDE;
265 void exportHTML(KOrg::HTMLExportSettings *);
267 void filtersUpdated(const QStringList &, int);
268 void filterChanged();
270 public Q_SLOTS:
271 /** options dialog made a changed to the configuration. we catch this
272 * and notify all widgets which need to update their configuration. */
273 void updateConfig();
274 void updateConfig(const QByteArray &);
276 void handleIncidenceCreated(const Akonadi::Item &item);
279 Save calendar data to file. Return true if calendar could be
280 successfully saved.
281 @param filename The file name to save the calendar to
283 bool saveCalendar(const QString &filename);
285 /** Archive old events of calendar */
286 void archiveCalendar();
288 void newEvent(const QDate &);
291 create new event without having a date hint. Takes current date as
292 default hint.
294 void newEvent();
297 create an editeventwin with supplied date/time, and if bool is true,
298 make the event take all day.
300 void newEvent(const QDateTime &startDt);
302 void newEvent(const QDateTime &startDt, const QDateTime &EndDt, bool allDay = false);
305 Create new Event from given summary, description, attachment list and
306 attendees list
308 void newEvent(const QString &summary,
309 const QString &description = QString(),
310 const QStringList &attachment = QStringList(),
311 const QStringList &attendees = QStringList(),
312 const QStringList &attachmentMimetypes = QStringList(),
313 bool inlineAttachment = false);
314 void newFloatingEvent();
316 /** Create a read-only viewer dialog for the supplied incidence.
317 It calls the correct showXXX method */
318 void showIncidence(const Akonadi::Item &item);
319 bool showIncidence(Akonadi::Item::Id id);
320 void showIncidence();
323 Show an incidence in context. This means showing the todo, agenda or
324 journal view (as appropriate) and scrolling it to show the incidence.
325 @param incidence The incidence to show.
327 void showIncidenceContext(const Akonadi::Item &incidence);
328 bool showIncidenceContext(Akonadi::Item::Id id);
330 /** Create an editor for the supplied incidence. It calls the correct editXXX method*/
331 bool editIncidence(const Akonadi::Item &item, bool isCounter = false) Q_DECL_OVERRIDE;
332 bool editIncidence(Akonadi::Item::Id id);
333 void editIncidence();
336 Delete the supplied incidence. It calls the correct deleteXXX method
337 @param force If true, all recurrences and sub-todos (if applicable) will be
338 deleted without prompting for confirmation.
339 @param force If true, all recurrences and sub-todos (if applicable) will be
340 deleted without prompting for confirmation.
342 bool deleteIncidence(const Akonadi::Item &item, bool force = false);
343 bool deleteIncidence(Akonadi::Item::Id id, bool force = false);
344 void deleteIncidence();
347 Add an incidence to the active calendar.
348 @param ical A calendar in iCalendar format containing the incidence. The
349 calendar must consist of a VCALENDAR component which contains
350 the incidence (VEVENT, VTODO, VJOURNAL or VFREEBUSY) and
351 optionally a VTIMEZONE component. If there is more than one
352 incidence, only the first is added to KOrganizer's calendar.
354 bool addIncidence(const QString &ical);
355 bool addIncidence(const KCalCore::Incidence::Ptr &incidence);
358 Cuts the selected incidence using the edit_cut() method
360 void cutIncidence(const Akonadi::Item &);
363 Copies the selected incidence using the edit_copy() method
365 void copyIncidence(const Akonadi::Item &);
368 Pastes the current incidence using the edit_paste() method
370 void pasteIncidence();
372 /** Delete the supplied todo and all sub-todos */
373 void deleteSubTodosIncidence(const Akonadi::Item &todo);
376 Delete the todo incidence, and its sub-to-dos.
377 @param todo The todo to delete.
378 @param force If true, all sub-todos will be deleted without prompting for confirmation.
380 void deleteTodoIncidence(const Akonadi::Item &todo, bool force = false);
382 /** create new todo */
383 void newTodo();
385 /** create new todo, due on date */
386 void newTodo(const QDate &date);
388 /** create new todo **/
389 void newTodo(const Akonadi::Collection &collection);
391 /** create new todo with a parent todo */
392 void newSubTodo();
394 /** create new todo with a parent todo */
395 void newSubTodo(const Akonadi::Item &todo);
397 /** create new todo with parent todo */
398 void newSubTodo(const Akonadi::Collection &collection);
400 void newTodo(const QString &summary, const QString &description = QString(),
401 const QStringList &attachments = QStringList(),
402 const QStringList &attendees = QStringList(),
403 const QStringList &attachmentMimetypes = QStringList(),
404 bool inlineAttachment = false);
406 void newJournal();
407 void newJournal(const QDate &date);
408 void newJournal(const QString &text, const QDate &date = QDate());
409 void newJournal(const Akonadi::Collection &collection);
411 void configureCurrentView();
413 void toggleAlarm(const Akonadi::Item &incidence);
414 void toggleTodoCompleted(const Akonadi::Item &incidence);
415 void copyIncidenceToResource(const Akonadi::Item &incidence, const Akonadi::Collection &col);
416 void moveIncidenceToResource(const Akonadi::Item &incidence, const Akonadi::Collection &col);
417 void dissociateOccurrences(const Akonadi::Item &incidence, const QDate &date);
420 Check if clipboard contains vCalendar event. The signal pasteEnabled() is
421 emitted as result.
423 void checkClipboard();
426 Using the KConfig associated with the kapp variable, read in the
427 settings from the config file.
429 You have to call setCalendar before calling readSettings.
431 void readSettings();
433 /** write current state to config file. */
434 void writeSettings();
436 /** read settings for calendar filters */
437 void readFilterSettings(KConfig *config);
439 /** write settings for calendar filters */
440 void writeFilterSettings(KConfig *config);
442 /** passes on the message that an event has changed to the currently
443 * activated view so that it can make appropriate display changes. */
444 void changeIncidenceDisplay(const Akonadi::Item &incidence,
445 Akonadi::IncidenceChanger::ChangeType);
447 void slotCreateFinished(int changeId,
448 const Akonadi::Item &item,
449 Akonadi::IncidenceChanger::ResultCode resultCode,
450 const QString &errorString);
452 void slotModifyFinished(int changeId,
453 const Akonadi::Item &item,
454 Akonadi::IncidenceChanger::ResultCode resultCode,
455 const QString &errorString);
457 void slotDeleteFinished(int changeId,
458 const QVector<Akonadi::Item::Id> &itemIdList,
459 Akonadi::IncidenceChanger::ResultCode resultCode,
460 const QString &errorString);
462 void startMultiModify(const QString &text);
463 void endMultiModify();
465 void updateView(const QDate &start, const QDate &end,
466 const QDate &preferredMonth, const bool updateTodos = true);
467 void updateView() Q_DECL_OVERRIDE;
469 void updateUnmanagedViews();
471 /** cut the current appointment to the clipboard */
472 void edit_cut();
474 /** copy the current appointment(s) to the clipboard */
475 void edit_copy();
477 /** paste the current vobject(s) in the clipboard buffer into calendar */
478 void edit_paste();
480 void onCutFinished();
482 /** edit viewing and configuration options. */
483 void edit_options();
486 Functions for printing, previewing a print, and setting up printing
487 parameters.
489 void print();
490 void printPreview();
492 /** Export as HTML file */
493 void exportWeb();
495 /** Export as iCalendar file */
496 void exportICalendar();
498 /** Export as vCalendar file */
499 void exportVCalendar();
501 /** pop up a dialog to show an existing appointment. */
502 void appointment_show();
504 * pop up an Appointment Dialog to edit an existing appointment. Get
505 * information on the appointment from the list of unique IDs that is
506 * currently in the View, called currIds.
508 void appointment_edit();
511 * pop up dialog confirming deletion of currently selected event in the
512 * View.
514 void appointment_delete();
516 /** Frees a subtodo from it's relation, update the view */
517 void todo_unsub();
519 /* Frees an incidence's children from it's relation, without the view update
520 Works with any incidence type, although currently we only pass to-dos
522 bool incidence_unsub(const Akonadi::Item &item);
524 /** Make all sub-to-dos of the selected todo independent, update the view */
525 bool makeSubTodosIndependent();
527 /** Make all children of incidence independent, not update the view
528 Works with any incidence type, although currently we only pass to-dos
530 bool makeChildrenIndependent(const Akonadi::Item &item);
532 /** Take ownership of selected event. */
533 void takeOverEvent();
535 /** query if the calendar is read-only. */
536 bool isReadOnly() const;
538 /** set state of calendar to read-only
539 @param readOnly whether the calendar view should be set read-only or not
541 void setReadOnly(bool readOnly = true);
543 void eventUpdated(const Akonadi::Item &incidence);
545 /* iTIP scheduling actions */
546 void schedule_publish(const Akonadi::Item &incidence = Akonadi::Item());
547 void schedule_request(const Akonadi::Item &incidence = Akonadi::Item());
548 void schedule_refresh(const Akonadi::Item &incidence = Akonadi::Item());
549 void schedule_cancel(const Akonadi::Item &incidence = Akonadi::Item());
550 void schedule_add(const Akonadi::Item &incidence = Akonadi::Item());
551 void schedule_reply(const Akonadi::Item &incidence = Akonadi::Item());
552 void schedule_counter(const Akonadi::Item &incidence = Akonadi::Item());
553 void schedule_declinecounter(const Akonadi::Item &incidence = Akonadi::Item());
554 void schedule_forward(const Akonadi::Item &incidence = Akonadi::Item());
555 void mailFreeBusy(int daysToPublish = 30);
556 void uploadFreeBusy();
558 void openAddressbook();
560 void editFilters();
562 void updateFilter();
564 void showIntro();
566 void showDateNavigator(bool);
567 void showTodoView(bool);
568 void showEventViewer(bool);
570 /** Move the current view date to the specified date */
571 void goDate(const QDate &date);
573 /** Show the given date without changing date selection length. */
574 void showDate(const QDate &date);
576 /** Move the current view date to today */
577 void goToday();
579 /** Move to the next date(s) in the current view */
580 void goNext();
582 /** Move to the previous date(s) in the current view */
583 void goPrevious();
585 void showLeftFrame(bool show = true);
587 void dialogClosing(const Akonadi::Item &incidence);
589 void processMainViewSelection(const Akonadi::Item &incidence, const QDate &date);
590 void processTodoListSelection(const Akonadi::Item &incidence, const QDate &date);
592 void processIncidenceSelection(const Akonadi::Item &incidence, const QDate &date);
594 void purgeCompleted();
596 void slotAutoArchivingSettingsModified()
598 Q_EMIT autoArchivingSettingsModified();
601 void showErrorMessage(const QString &);
602 void schedule(KCalCore::iTIPMethod, const Akonadi::Item &incidence);
603 void addIncidenceOn(const Akonadi::Item &incidence, const QDate &);
604 void moveIncidenceTo(const Akonadi::Item &incidence, const QDate &);
605 void filterActivated(int filterNum);
607 void resourcesChanged();
610 * The user clicked on a week number in the date navigator
612 * Select a week or a work week depending on the user's config option.
614 * @param preferredMonth Holds the month that should be selected when
615 * the week crosses months. It's a QDate instead of uint so it can be
616 * easily fed to KCalendarSystem's functions.
618 void selectWeek(const QDate &week, const QDate &preferredMonth);
621 * Use as much of the full window as possible for the view.
623 * @param fullView if true, expand the view as much as possible within the
624 * main view (hiding the sidebar for example); else put back the normal view.
626 void changeFullView(bool fullView);
628 protected Q_SLOTS:
630 * Select a view or adapt the current view to display the specified dates.
631 * @p preferredMonth is useful when the datelist crosses months, if valid,
632 * any month-like component should honour this
634 void showDates(const KCalCore::DateList &, const QDate &preferredMonth = QDate());
636 public:
637 int msgCalModified();
640 * Adapts navigation units according to the current view's navigation step size.
642 void adaptNavigationUnits();
645 * Returns the date of the selected incidence.
647 * If the selected incidence is recurring, it will return the date
648 * of the selected occurrence.
650 QDate activeIncidenceDate();
653 Returns the best guess at the current active date in the view.
654 This has nothing to do with selected incidences, use activeIncidenceDate()
655 for that, for example, agenda supports time selection and incidence selection
656 and they can have diferent dates.
658 @param fallbackToToday If guessing doesn't work, some views will prefer
659 today to be returned instead of the first select date in the day matrix,
660 Journal view for example.
662 QDate activeDate(bool fallbackToToday = false);
664 protected:
665 int msgItemDelete(const Akonadi::Item &incidence);
667 Akonadi::Item selectedTodo();
668 IncidenceEditorNG::IncidenceDialog *incidenceDialog(const Akonadi::Item &);
670 void warningChangeFailed(const Akonadi::Item &);
671 void checkForFilteredChange(const Akonadi::Item &incidence);
674 Adjust the given date/times by valid defaults (selection or configured
675 defaults, if invalid values are given) and allow the view to adjust the type.
677 void dateTimesForNewEvent(QDateTime &startDt, QDateTime &endDt, bool &allDay);
678 IncidenceEditorNG::IncidenceDialog *newEventEditor(const KCalCore::Event::Ptr &event);
680 bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE;
682 private Q_SLOTS:
683 void onCheckableProxyAboutToToggle(bool newState);
684 void onCheckableProxyToggled(bool newState);
685 void onTodosPurged(bool success, int numDeleted, int numIgnored);
687 private:
688 void init();
689 Akonadi::Collection selectedCollection() const;
690 Akonadi::Collection::List checkedCollections() const;
692 void createPrinter();
694 void dissociateOccurrence(const Akonadi::Item &incidence, const QDate &, bool futureOccurrences);
697 * Returns the default collection.
698 * The view's collection takes precedence, only then the config one is used.
699 * If mimeType is set, the collection to return will have to support that mime type.
700 * If no valid collection is found, an invalid one is returned.
702 Akonadi::Collection defaultCollection(
703 const QLatin1String &mimeType = QLatin1String("")) const;
706 * Creates a new incidence editor and chooses a decent default for the collection
707 * in the collection combo.
709 IncidenceEditorNG::IncidenceDialog *createIncidenceEditor(
710 const Akonadi::Item &item, const Akonadi::Collection &collection = Akonadi::Collection());
712 CalendarSupport::CalPrinter *mCalPrinter;
713 Akonadi::TodoPurger *mTodoPurger;
715 QSplitter *mPanner;
716 QSplitter *mLeftSplitter;
717 QWidget *mLeftFrame;
718 QStackedWidget *mRightFrame;
719 CalendarSupport::MessageWidget *mMessageWidget;
721 // This navigator bar is used when in full window month view
722 // It has nothing to do with the date navigator
723 NavigatorBar *mNavigatorBar;
725 DateNavigatorContainer *mDateNavigatorContainer;
727 QList<CalendarViewExtension *> mExtensions;
729 Akonadi::ETMCalendar::Ptr mCalendar;
731 DateNavigator *mDateNavigator;
732 DateChecker *mDateChecker;
734 QWidget *mEventViewerBox;
735 CalendarSupport::IncidenceViewer *mEventViewer;
736 KOViewManager *mViewManager;
737 KODialogManager *mDialogManager;
739 // Calendar filters
740 QList<KCalCore::CalFilter *> mFilters;
741 KCalCore::CalFilter *mCurrentFilter;
743 // various housekeeping variables.
744 bool mReadOnly; // flag indicating if calendar is read-only
746 Akonadi::Item mSelectedIncidence;
747 QDate mSaveDate;
749 KOTodoView *mTodoList;
750 Akonadi::IncidenceChanger *mChanger;
751 Akonadi::ITIPHandler *mITIPHandler;
752 QList<int> mMainSplitterSizes; // temp store for main splitter sizes while left frame is hidden
753 bool mSplitterSizesValid;
754 bool mCreatingEnabled;
756 Akonadi::CalendarClipboard *mCalendarClipboard;
757 KOCheckableProxyModel *mCheckableProxyModel;
758 AkonadiCollectionView *mETMCollectionView;
760 SearchCollectionHelper mSearchCollectionHelper;
763 #endif