2 This file is part of KOrganizer.
4 Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 As a special exception, permission is given to link this program
22 with any edition of Qt, and distribute the resulting executable,
23 without including the source code for Qt in the source distribution.
26 #include "koeventpopupmenu.h"
27 #include "actionmanager.h"
28 #include "kocorehelper.h"
29 #include "koglobals.h"
30 #include "dialog/noteeditdialog.h"
32 #include <CalendarSupport/KCalPrefs>
33 #include <CalendarSupport/Utils>
34 #include <CalendarSupport/CalPrinter>
35 #include <CalendarSupport/CalPrintDefaultPlugins>
37 #include <KCalCore/CalFormat>
38 #include <KCalCore/Incidence>
39 #include <Akonadi/Notes/NoteUtils>
40 #include <AkonadiCore/CollectionFetchJob>
41 #include <AkonadiCore/CollectionFetchScope>
42 #include <AkonadiCore/ItemCreateJob>
44 #include <KActionCollection>
45 #include <KMime/Message>
46 #include <KMimeTypeTrader>
47 #include "korganizer_debug.h"
49 #include <IncidenceEditorsng/IncidenceDialogFactory>
50 #include <IncidenceEditorsng/IncidenceDialog>
52 KOEventPopupMenu::KOEventPopupMenu(Akonadi::ETMCalendar
*calendar
, QWidget
*parent
)
53 : QMenu(parent
), mCalendar(calendar
)
55 mHasAdditionalItems
= false;
57 addAction(QIcon::fromTheme(QStringLiteral("document-preview")), i18n("&Show"),
58 this, SLOT(popupShow()));
59 mEditOnlyItems
.append(
60 addAction(QIcon::fromTheme(QStringLiteral("document-edit")), i18n("&Edit..."),
61 this, SLOT(popupEdit())));
62 mEditOnlyItems
.append(addSeparator());
63 addAction(QIcon::fromTheme(QStringLiteral("document-print")), i18n("&Print..."),
65 addAction(QIcon::fromTheme(QStringLiteral("document-print-preview")),
66 i18n("Print Previe&w..."),
67 this, SLOT(printPreview()));
69 //------------------------------------------------------------------------
70 mEditOnlyItems
.append(addSeparator());
71 mEditOnlyItems
.append(addAction(QIcon::fromTheme(QStringLiteral("edit-cut")),
72 i18nc("cut this event", "C&ut"),
73 this, SLOT(popupCut())));
74 mEditOnlyItems
.append(addAction(QIcon::fromTheme(QStringLiteral("edit-copy")),
75 i18nc("copy this event", "&Copy"),
76 this, SLOT(popupCopy())));
77 // paste is always possible
78 mEditOnlyItems
.append(addAction(QIcon::fromTheme(QStringLiteral("edit-paste")),
80 this, SLOT(popupPaste())));
81 mEditOnlyItems
.append(addAction(QIcon::fromTheme(QStringLiteral("edit-delete")),
82 i18nc("delete this incidence", "&Delete"),
83 this, SLOT(popupDelete())));
84 //------------------------------------------------------------------------
87 action
= addAction(QIcon::fromTheme(QStringLiteral("task-new")),
89 this, SLOT(createTodo()));
90 action
->setObjectName(QStringLiteral("createtodo"));
91 mEventOnlyItems
.append(action
);
93 action
= addAction(QIcon::fromTheme(QStringLiteral("appointment-new")),
95 this, SLOT(createEvent()));
96 action
->setObjectName(QStringLiteral("createevent"));
97 mTodoOnlyItems
.append(action
);
99 action
= addAction(QIcon::fromTheme(QStringLiteral("view-pim-notes")),
101 this, SLOT(createNote()));
102 action
->setObjectName(QStringLiteral("createnote"));
103 //------------------------------------------------------------------------
105 mTodoOnlyItems
.append(addAction(QIcon::fromTheme(QStringLiteral("task-complete")),
106 i18n("Togg&le To-do Completed"),
107 this, SLOT(toggleTodoCompleted())));
108 mToggleReminder
= addAction(QIcon(QIcon::fromTheme(QStringLiteral("appointment-reminder"))),
109 i18n("&Toggle Reminder"), this, SLOT(toggleAlarm()));
110 mEditOnlyItems
.append(mToggleReminder
);
111 //------------------------------------------------------------------------
112 mRecurrenceItems
.append(addSeparator());
113 mDissociateOccurrences
= addAction(i18n("&Dissociate From Recurrence..."),
114 this, SLOT(dissociateOccurrences()));
115 mRecurrenceItems
.append(mDissociateOccurrences
);
118 addAction(QIcon::fromTheme(QStringLiteral("mail-forward")),
119 i18n("Send as iCalendar..."),
120 this, SLOT(forward()));
124 void KOEventPopupMenu::showIncidencePopup(const Akonadi::Item
&item
, const QDate
&qd
)
126 mCurrentIncidence
= item
;
129 if (!CalendarSupport::hasIncidence(mCurrentIncidence
)/*&& qd.isValid()*/) {
130 qCDebug(KORGANIZER_LOG
) << "No event selected";
136 qCDebug(KORGANIZER_LOG
) << "Calendar is 0";
140 const bool hasChangeRights
= mCalendar
->hasRight(mCurrentIncidence
, Akonadi::Collection::CanChangeItem
);
142 KCalCore::Incidence::Ptr incidence
= CalendarSupport::incidence(mCurrentIncidence
);
144 if (incidence
->recurs()) {
145 const KDateTime
thisDateTime(qd
, CalendarSupport::KCalPrefs::instance()->timeSpec());
146 const bool isLastOccurrence
=
147 !incidence
->recurrence()->getNextDateTime(thisDateTime
).isValid();
148 const bool isFirstOccurrence
=
149 !incidence
->recurrence()->getPreviousDateTime(thisDateTime
).isValid();
150 mDissociateOccurrences
->setEnabled(
151 !(isFirstOccurrence
&& isLastOccurrence
) && hasChangeRights
);
154 // Enable/Disabled menu items only valid for editable events.
155 QList
<QAction
*>::Iterator it
;
156 QList
<QAction
*>::Iterator
end(mEditOnlyItems
.end());
157 for (it
= mEditOnlyItems
.begin(); it
!= end
; ++it
) {
158 (*it
)->setEnabled(hasChangeRights
);
160 mToggleReminder
->setVisible((incidence
->type() != KCalCore::Incidence::TypeJournal
));
161 end
= mRecurrenceItems
.end();
162 for (it
= mRecurrenceItems
.begin(); it
!= end
; ++it
) {
163 (*it
)->setVisible(incidence
->recurs());
165 end
= mTodoOnlyItems
.end();
166 for (it
= mTodoOnlyItems
.begin(); it
!= end
; ++it
) {
167 (*it
)->setVisible(incidence
->type() == KCalCore::Incidence::TypeTodo
);
168 (*it
)->setEnabled(hasChangeRights
);
170 for (it
= mEventOnlyItems
.begin(); it
!= mEventOnlyItems
.end(); ++it
) {
171 (*it
)->setVisible(incidence
->type() == KCalCore::Incidence::TypeEvent
);
172 (*it
)->setEnabled(hasChangeRights
);
174 popup(QCursor::pos());
177 void KOEventPopupMenu::popupShow()
179 if (CalendarSupport::hasIncidence(mCurrentIncidence
)) {
180 Q_EMIT
showIncidenceSignal(mCurrentIncidence
);
184 void KOEventPopupMenu::popupEdit()
186 if (CalendarSupport::hasIncidence(mCurrentIncidence
)) {
187 Q_EMIT
editIncidenceSignal(mCurrentIncidence
);
191 void KOEventPopupMenu::print()
196 void KOEventPopupMenu::print(bool preview
)
199 CalendarSupport::CalPrinter
printer(this, mCalendar
, true);
200 connect(this, &KOEventPopupMenu::configChanged
, &printer
, &CalendarSupport::CalPrinter::updateConfig
);
202 //Item::List selectedIncidences;
203 KCalCore::Incidence::List selectedIncidences
;
204 Q_ASSERT(mCurrentIncidence
.hasPayload
<KCalCore::Incidence::Ptr
>());
205 selectedIncidences
.append(mCurrentIncidence
.payload
<KCalCore::Incidence::Ptr
>());
207 printer
.print(CalendarSupport::CalPrinterBase::Incidence
,
208 mCurrentDate
, mCurrentDate
, selectedIncidences
, preview
);
211 void KOEventPopupMenu::printPreview()
216 void KOEventPopupMenu::popupDelete()
218 if (CalendarSupport::hasIncidence(mCurrentIncidence
)) {
219 Q_EMIT
deleteIncidenceSignal(mCurrentIncidence
);
223 void KOEventPopupMenu::popupCut()
225 if (CalendarSupport::hasIncidence(mCurrentIncidence
)) {
226 Q_EMIT
cutIncidenceSignal(mCurrentIncidence
);
230 void KOEventPopupMenu::popupCopy()
232 if (CalendarSupport::hasIncidence(mCurrentIncidence
)) {
233 Q_EMIT
copyIncidenceSignal(mCurrentIncidence
);
237 void KOEventPopupMenu::popupPaste()
239 Q_EMIT
pasteIncidenceSignal();
242 void KOEventPopupMenu::toggleAlarm()
244 if (CalendarSupport::hasIncidence(mCurrentIncidence
)) {
245 Q_EMIT
toggleAlarmSignal(mCurrentIncidence
);
249 void KOEventPopupMenu::dissociateOccurrences()
251 if (CalendarSupport::hasIncidence(mCurrentIncidence
)) {
252 Q_EMIT
dissociateOccurrencesSignal(mCurrentIncidence
, mCurrentDate
);
256 void KOEventPopupMenu::forward()
258 KOrg::MainWindow
*w
= ActionManager::findInstance(QUrl());
259 if (!w
|| !CalendarSupport::hasIncidence(mCurrentIncidence
)) {
263 KActionCollection
*ac
= w
->getActionCollection();
264 QAction
*action
= ac
->action(QStringLiteral("schedule_forward"));
268 qCCritical(KORGANIZER_LOG
) << "What happened to the schedule_forward action?";
272 void KOEventPopupMenu::createEvent(const Akonadi::Item
&item
)
274 mCurrentIncidence
= item
;
278 void KOEventPopupMenu::createEvent()
280 // Must be a Incidence
281 if (!CalendarSupport::hasIncidence(mCurrentIncidence
)) {
284 // Event ->event doesn't make sense
285 if (CalendarSupport::hasEvent(mCurrentIncidence
)) {
289 if (CalendarSupport::hasTodo(mCurrentIncidence
)) {
290 KCalCore::Todo::Ptr
todo(CalendarSupport::todo(mCurrentIncidence
));
291 KCalCore::Event::Ptr
event(new KCalCore::Event(*todo
));
292 event
->setUid(KCalCore::CalFormat::createUniqueId());
293 event
->setDtStart(todo
->dtStart());
294 event
->setAllDay(todo
->allDay());
295 event
->setDtEnd(todo
->dtDue());
296 Akonadi::Item newEventItem
;
297 newEventItem
.setMimeType(KCalCore::Event::eventMimeType());
298 newEventItem
.setPayload
<KCalCore::Event::Ptr
>(event
);
300 IncidenceEditorNG::IncidenceDialog
*dlg
= IncidenceEditorNG::IncidenceDialogFactory::create(true, KCalCore::IncidenceBase::TypeEvent
, 0, this);
301 dlg
->setObjectName(QStringLiteral("incidencedialog"));
302 dlg
->load(newEventItem
);
307 void KOEventPopupMenu::createNote(const Akonadi::Item
&item
)
309 mCurrentIncidence
= item
;
313 void KOEventPopupMenu::createNote()
315 // Must be a Incidence
316 if (CalendarSupport::hasIncidence(mCurrentIncidence
)) {
317 KCalCore::Incidence::Ptr
incidence(CalendarSupport::incidence(mCurrentIncidence
));
318 Akonadi::NoteUtils::NoteMessageWrapper note
;
319 note
.setTitle(incidence
->summary());
320 note
.setText(incidence
->description(), incidence
->descriptionIsRich() ? Qt::RichText
: Qt::PlainText
);
321 note
.setFrom(QCoreApplication::applicationName() + QCoreApplication::applicationVersion());
322 note
.setLastModifiedDate(QDateTime::currentDateTimeUtc());
323 Akonadi::NoteUtils::Attachment
attachment(mCurrentIncidence
.url().url(), mCurrentIncidence
.mimeType());
324 note
.attachments().append(attachment
);
325 Akonadi::Item newNoteItem
;
326 newNoteItem
.setMimeType(Akonadi::NoteUtils::noteMimeType());
327 newNoteItem
.setPayload(note
.message());
329 NoteEditDialog
*noteedit
= new NoteEditDialog(this);
330 connect(noteedit
, &NoteEditDialog::createNote
, this, &KOEventPopupMenu::slotCreateNote
);
331 noteedit
->load(newNoteItem
);
336 void KOEventPopupMenu::slotCreateNote(const Akonadi::Item
¬eItem
, const Akonadi::Collection
&collection
)
338 Akonadi::ItemCreateJob
*createJob
= new Akonadi::ItemCreateJob(noteItem
, collection
, this);
339 connect(createJob
, &Akonadi::ItemCreateJob::result
, this, &KOEventPopupMenu::slotCreateNewNoteJobFinished
);
343 void KOEventPopupMenu::slotCreateNewNoteJobFinished(KJob
*job
)
346 qCDebug(KORGANIZER_LOG
) << "Error during create new Note " << job
->errorString();
350 void KOEventPopupMenu::createTodo()
352 // Must be a Incidence
353 if (!CalendarSupport::hasIncidence(mCurrentIncidence
)) {
356 // Todo->Todo doesn't make sense
357 if (CalendarSupport::hasTodo(mCurrentIncidence
)) {
361 if (CalendarSupport::hasEvent(mCurrentIncidence
)) {
362 KCalCore::Event::Ptr
event(CalendarSupport::event(mCurrentIncidence
));
363 KCalCore::Todo::Ptr
todo(new KCalCore::Todo(*event
));
364 todo
->setUid(KCalCore::CalFormat::createUniqueId());
365 todo
->setDtStart(event
->dtStart());
366 todo
->setAllDay(event
->allDay());
367 todo
->setDtDue(event
->dtEnd());
368 Akonadi::Item newTodoItem
;
369 newTodoItem
.setMimeType(KCalCore::Todo::todoMimeType());
370 newTodoItem
.setPayload
<KCalCore::Todo::Ptr
>(todo
);
372 IncidenceEditorNG::IncidenceDialog
*dlg
= IncidenceEditorNG::IncidenceDialogFactory::create(true, KCalCore::IncidenceBase::TypeTodo
, 0, this);
373 dlg
->setObjectName(QStringLiteral("incidencedialog"));
374 dlg
->load(newTodoItem
);
379 void KOEventPopupMenu::toggleTodoCompleted()
381 if (CalendarSupport::hasTodo(mCurrentIncidence
)) {
382 Q_EMIT
toggleTodoCompletedSignal(mCurrentIncidence
);
386 void KOEventPopupMenu::setCalendar(const Akonadi::ETMCalendar::Ptr
&calendar
)
388 mCalendar
= calendar
;