• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

KCalUtils Library

  • kcalutils
dndfactory.cpp
Go to the documentation of this file.
1/*
2 This file is part of the kcalutils library.
3
4 Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5 Copyright (c) 2001,2002 Cornelius Schumacher <schumacher@kde.org>
6 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
7 Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
8 Copyright (c) 2008 Thomas Thrainer <tom_t@gmx.at>
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
19
20 You should have received a copy of the GNU Library General Public License
21 along with this library; see the file COPYING.LIB. If not, write to
22 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 Boston, MA 02110-1301, USA.
24*/
37#include "dndfactory.h"
38#include "icaldrag.h"
39#include "vcaldrag.h"
40
41#include <KDebug>
42#include <KIconLoader> // for BarIcon
43#include <KUrl>
44
45#include <QtCore/QMimeData>
46#include <QApplication>
47#include <QClipboard>
48#include <QDrag>
49#include <QDate>
50#include <QWidget>
51#include <QDropEvent>
52
53using namespace KCalCore;
54using namespace KCalUtils;
55
60//@cond PRIVATE
61class KCalUtils::DndFactory::Private
62{
63public:
64 Private(const MemoryCalendar::Ptr &calendar)
65 : mCalendar(calendar)
66 {}
67
68 Incidence::Ptr pasteIncidence(const Incidence::Ptr &incidence,
69 KDateTime newDateTime,
70 const QFlags<PasteFlag> &pasteOptions)
71 {
72 Incidence::Ptr inc(incidence);
73
74 if (inc) {
75 inc = Incidence::Ptr(inc->clone());
76 inc->recreate();
77 }
78
79 if (inc && newDateTime.isValid()) {
80 if (inc->type() == Incidence::TypeEvent) {
81 Event::Ptr event = inc.staticCast<Event>();
82 if (pasteOptions & FlagPasteAtOriginalTime) {
83 // Set date and preserve time and timezone stuff
84 const QDate date = newDateTime.date();
85 newDateTime = event->dtStart();
86 newDateTime.setDate(date);
87 }
88
89 // in seconds
90 const int durationInSeconds = event->dtStart().secsTo(event->dtEnd());
91 const int durationInDays = event->dtStart().daysTo(event->dtEnd());
92
93 event->setDtStart(newDateTime);
94
95 if (newDateTime.isDateOnly()) {
96 event->setDtEnd(newDateTime.addDays(durationInDays));
97 } else {
98 event->setDtEnd(newDateTime.addSecs(durationInSeconds));
99 }
100
101 } else if (inc->type() == Incidence::TypeTodo) {
102 Todo::Ptr aTodo = inc.staticCast<Todo>();
103 const bool pasteAtDtStart = (pasteOptions & FlagTodosPasteAtDtStart);
104 if (pasteOptions & FlagPasteAtOriginalTime) {
105 // Set date and preserve time and timezone stuff
106 const QDate date = newDateTime.date();
107 newDateTime = pasteAtDtStart ? aTodo->dtStart() : aTodo->dtDue();
108 newDateTime.setDate(date);
109 }
110 if (pasteAtDtStart) {
111 aTodo->setDtStart(newDateTime);
112 } else {
113 aTodo->setDtDue(newDateTime);
114 }
115
116 } else if (inc->type() == Incidence::TypeJournal) {
117 if (pasteOptions & FlagPasteAtOriginalTime) {
118 // Set date and preserve time and timezone stuff
119 const QDate date = newDateTime.date();
120 newDateTime = inc->dtStart();
121 newDateTime.setDate(date);
122 }
123 inc->setDtStart(newDateTime);
124 } else {
125 kDebug() << "Trying to paste unknown incidence of type" << int(inc->type());
126 }
127 }
128
129 return inc;
130 }
131
132 MemoryCalendar::Ptr mCalendar;
133};
134//@endcond
135
136DndFactory::DndFactory(const MemoryCalendar::Ptr &calendar)
137 : d(new KCalUtils::DndFactory::Private(calendar))
138{
139}
140
141DndFactory::~DndFactory()
142{
143 delete d;
144}
145
146QMimeData *DndFactory::createMimeData()
147{
148 QMimeData *mimeData = new QMimeData;
149
150 ICalDrag::populateMimeData(mimeData, d->mCalendar);
151 VCalDrag::populateMimeData(mimeData, d->mCalendar);
152
153 return mimeData;
154}
155
156QDrag *DndFactory::createDrag(QWidget *owner)
157{
158 QDrag *drag = new QDrag(owner);
159 drag->setMimeData(createMimeData());
160
161 return drag;
162}
163
164QMimeData *DndFactory::createMimeData(const Incidence::Ptr &incidence)
165{
166 MemoryCalendar::Ptr cal(new MemoryCalendar(d->mCalendar->timeSpec()));
167 Incidence::Ptr i(incidence->clone());
168 //strip recurrence id's, We don't want to drag the exception but the occurrence.
169 i->setRecurrenceId(KDateTime());
170 cal->addIncidence(i);
171
172 QMimeData *mimeData = new QMimeData;
173
174 ICalDrag::populateMimeData(mimeData, cal);
175 VCalDrag::populateMimeData(mimeData, cal);
176
177 KUrl uri = i->uri();
178 if (uri.isValid()) {
179 QMap<QString, QString> metadata;
180 metadata[QLatin1String("labels")] = QLatin1String(KUrl::toPercentEncoding(i->summary()));
181 uri.populateMimeData(mimeData, metadata);
182 }
183
184 return mimeData;
185}
186
187QDrag *DndFactory::createDrag(const Incidence::Ptr &incidence, QWidget *owner)
188{
189 QDrag *drag = new QDrag(owner);
190 drag->setMimeData(createMimeData(incidence));
191 drag->setPixmap(BarIcon(incidence->iconName()));
192
193 return drag;
194}
195
196MemoryCalendar::Ptr DndFactory::createDropCalendar(const QMimeData *mimeData)
197{
198 return createDropCalendar(mimeData, d->mCalendar->timeSpec());
199}
200
201MemoryCalendar::Ptr DndFactory::createDropCalendar(const QMimeData *mimeData,
202 const KDateTime::Spec &timeSpec)
203{
204 MemoryCalendar::Ptr calendar(new MemoryCalendar(timeSpec));
205
206 if (ICalDrag::fromMimeData(mimeData, calendar) ||
207 VCalDrag::fromMimeData(mimeData, calendar)) {
208 return calendar;
209 }
210
211 return MemoryCalendar::Ptr();
212}
213
214MemoryCalendar::Ptr DndFactory::createDropCalendar(QDropEvent *dropEvent)
215{
216 MemoryCalendar::Ptr calendar(createDropCalendar(dropEvent->mimeData()));
217 if (calendar) {
218 dropEvent->accept();
219 return calendar;
220 }
221 return MemoryCalendar::Ptr();
222}
223
224Event::Ptr DndFactory::createDropEvent(const QMimeData *mimeData)
225{
226 //kDebug();
227 Event::Ptr event;
228 MemoryCalendar::Ptr calendar(createDropCalendar(mimeData));
229
230 if (calendar) {
231 Event::List events = calendar->events();
232 if (!events.isEmpty()) {
233 event = Event::Ptr(new Event(*events.first()));
234 }
235 }
236 return event;
237}
238
239Event::Ptr DndFactory::createDropEvent(QDropEvent *dropEvent)
240{
241 Event::Ptr event = createDropEvent(dropEvent->mimeData());
242
243 if (event) {
244 dropEvent->accept();
245 }
246
247 return event;
248}
249
250Todo::Ptr DndFactory::createDropTodo(const QMimeData *mimeData)
251{
252 //kDebug();
253 Todo::Ptr todo;
254 MemoryCalendar::Ptr calendar(createDropCalendar(mimeData));
255
256 if (calendar) {
257 Todo::List todos = calendar->todos();
258 if (!todos.isEmpty()) {
259 todo = Todo::Ptr(new Todo(*todos.first()));
260 }
261 }
262
263 return todo;
264}
265
266Todo::Ptr DndFactory::createDropTodo(QDropEvent *dropEvent)
267{
268 Todo::Ptr todo = createDropTodo(dropEvent->mimeData());
269
270 if (todo) {
271 dropEvent->accept();
272 }
273
274 return todo;
275}
276
277void DndFactory::cutIncidence(const Incidence::Ptr &selectedIncidence)
278{
279 Incidence::List list;
280 list.append(selectedIncidence);
281 cutIncidences(list);
282}
283
284bool DndFactory::cutIncidences(const Incidence::List &incidences)
285{
286 if (copyIncidences(incidences)) {
287 Incidence::List::ConstIterator it;
288 for (it = incidences.constBegin(); it != incidences.constEnd(); ++it) {
289 d->mCalendar->deleteIncidence(*it);
290 }
291 return true;
292 } else {
293 return false;
294 }
295}
296
297bool DndFactory::copyIncidences(const Incidence::List &incidences)
298{
299 QClipboard *clipboard = QApplication::clipboard();
300 Q_ASSERT(clipboard);
301 MemoryCalendar::Ptr calendar(new MemoryCalendar(d->mCalendar->timeSpec()));
302
303 Incidence::List::ConstIterator it;
304 for (it = incidences.constBegin(); it != incidences.constEnd(); ++it) {
305 if (*it) {
306 calendar->addIncidence(Incidence::Ptr((*it)->clone()));
307 }
308 }
309
310 QMimeData *mimeData = new QMimeData;
311
312 ICalDrag::populateMimeData(mimeData, calendar);
313 VCalDrag::populateMimeData(mimeData, calendar);
314
315 if (calendar->incidences().isEmpty()) {
316 return false;
317 } else {
318 clipboard->setMimeData(mimeData);
319 return true;
320 }
321}
322
323bool DndFactory::copyIncidence(const Incidence::Ptr &selectedInc)
324{
325 Incidence::List list;
326 list.append(selectedInc);
327 return copyIncidences(list);
328}
329
330Incidence::List DndFactory::pasteIncidences(const KDateTime &newDateTime,
331 const QFlags<PasteFlag> &pasteOptions)
332{
333 QClipboard *clipboard = QApplication::clipboard();
334 Q_ASSERT(clipboard);
335 MemoryCalendar::Ptr calendar(createDropCalendar(clipboard->mimeData()));
336 Incidence::List list;
337
338 if (!calendar) {
339 kDebug() << "Can't parse clipboard";
340 return list;
341 }
342
343 // All pasted incidences get new uids, must keep track of old uids,
344 // so we can update child's parents
345 QHash<QString, Incidence::Ptr> oldUidToNewInc;
346
347 Incidence::List::ConstIterator it;
348 const Incidence::List incidences = calendar->incidences();
349 for (it = incidences.constBegin();
350 it != incidences.constEnd(); ++it) {
351 Incidence::Ptr incidence = d->pasteIncidence(*it, newDateTime, pasteOptions);
352 if (incidence) {
353 list.append(incidence);
354 oldUidToNewInc[(*it)->uid()] = *it;
355 }
356 }
357
358 // update relations
359 for (it = list.constBegin(); it != list.constEnd(); ++it) {
360 Incidence::Ptr incidence = *it;
361 if (oldUidToNewInc.contains(incidence->relatedTo())) {
362 Incidence::Ptr parentInc = oldUidToNewInc[incidence->relatedTo()];
363 incidence->setRelatedTo(parentInc->uid());
364 } else {
365 // not related to anything in the clipboard
366 incidence->setRelatedTo(QString());
367 }
368 }
369
370 return list;
371}
372
373Incidence::Ptr DndFactory::pasteIncidence(const KDateTime &newDateTime,
374 const QFlags<PasteFlag> &pasteOptions)
375{
376 QClipboard *clipboard = QApplication::clipboard();
377 MemoryCalendar::Ptr calendar(createDropCalendar(clipboard->mimeData()));
378
379 if (!calendar) {
380 kDebug() << "Can't parse clipboard";
381 return Incidence::Ptr();
382 }
383
384 Incidence::List incidenceList = calendar->incidences();
385 Incidence::Ptr incidence = incidenceList.isEmpty() ? Incidence::Ptr() : incidenceList.first();
386
387 return d->pasteIncidence(incidence, newDateTime, pasteOptions);
388}
KCalCore::Event
KCalCore::Event::Ptr
QSharedPointer< Event > Ptr
KCalCore::Event::List
QVector< Ptr > List
KCalCore::IncidenceBase::dtStart
virtual KDateTime dtStart() const
KCalCore::Incidence::List
QVector< Ptr > List
KCalCore::Incidence::Ptr
QSharedPointer< Incidence > Ptr
KCalCore::MemoryCalendar
KCalCore::MemoryCalendar::Ptr
QSharedPointer< MemoryCalendar > Ptr
KCalCore::Todo
KCalCore::Todo::List
QVector< Ptr > List
KCalCore::Todo::Ptr
QSharedPointer< Todo > Ptr
KCalCore::Todo::dtStart
virtual KDateTime dtStart() const
KCalUtils::DndFactory
vCalendar/iCalendar Drag-and-Drop object factory.
Definition: dndfactory.h:59
KCalUtils::DndFactory::pasteIncidence
KCalCore::Incidence::Ptr pasteIncidence(const KDateTime &newDateTime=KDateTime(), const QFlags< PasteFlag > &pasteOptions=QFlags< PasteFlag >())
This function clones the incidence that's in the clipboard and sets the clone's date/time to the spec...
Definition: dndfactory.cpp:373
KCalUtils::DndFactory::cutIncidences
bool cutIncidences(const KCalCore::Incidence::List &incidences)
Cuts a list of incidences to the clipboard.
Definition: dndfactory.cpp:284
KCalUtils::DndFactory::copyIncidence
bool copyIncidence(const KCalCore::Incidence::Ptr &)
Copy the incidence to clipboard/.
Definition: dndfactory.cpp:323
KCalUtils::DndFactory::createDrag
QDrag * createDrag(QWidget *owner)
Create a drag object for the whole calendar.
Definition: dndfactory.cpp:156
KCalUtils::DndFactory::DndFactory
DndFactory(const KCalCore::MemoryCalendar::Ptr &cal)
Private class that helps to provide binary compatibility between releases.
Definition: dndfactory.cpp:136
KCalUtils::DndFactory::createMimeData
QMimeData * createMimeData()
Create the mime data for the whole calendar.
Definition: dndfactory.cpp:146
KCalUtils::DndFactory::createDropEvent
KCalCore::Event::Ptr createDropEvent(const QMimeData *md)
Create Event object from mime data.
Definition: dndfactory.cpp:224
KCalUtils::DndFactory::createDropCalendar
KCalCore::MemoryCalendar::Ptr createDropCalendar(QDropEvent *de)
Create the calendar that is contained in the drop event's data.
Definition: dndfactory.cpp:214
KCalUtils::DndFactory::createDropTodo
KCalCore::Todo::Ptr createDropTodo(const QMimeData *md)
Create Todo object from mime data.
Definition: dndfactory.cpp:250
KCalUtils::DndFactory::pasteIncidences
KCalCore::Incidence::List pasteIncidences(const KDateTime &newDateTime=KDateTime(), const QFlags< PasteFlag > &pasteOptions=QFlags< PasteFlag >())
This function clones the incidences that are in the clipboard and sets the clone's date/time to the s...
Definition: dndfactory.cpp:330
KCalUtils::DndFactory::copyIncidences
bool copyIncidences(const KCalCore::Incidence::List &incidences)
Copies a list of incidences to the clipboard.
Definition: dndfactory.cpp:297
KCalUtils::DndFactory::cutIncidence
void cutIncidence(const KCalCore::Incidence::Ptr &)
Cut the incidence to the clipboard.
Definition: dndfactory.cpp:277
dndfactory.h
This file is part of the API for handling calendar data and defines the DndFactory class.
KCalUtils::ICalDrag::populateMimeData
KCALUTILS_EXPORT bool populateMimeData(QMimeData *e, const KCalCore::MemoryCalendar::Ptr &cal)
Sets the iCalendar representation as data of the drag object.
Definition: icaldrag.cpp:38
KCalUtils::ICalDrag::fromMimeData
KCALUTILS_EXPORT bool fromMimeData(const QMimeData *e, const KCalCore::MemoryCalendar::Ptr &cal)
Decode drag&drop object to iCalendar component cal.
Definition: icaldrag.cpp:54
KCalUtils::VCalDrag::fromMimeData
KCALUTILS_EXPORT bool fromMimeData(const QMimeData *e, const KCalCore::MemoryCalendar::Ptr &cal)
Decode drag&drop object to vCalendar component vcal.
Definition: vcaldrag.cpp:54
KCalUtils::VCalDrag::populateMimeData
KCALUTILS_EXPORT bool populateMimeData(QMimeData *e, const KCalCore::MemoryCalendar::Ptr &cal)
Sets the vCalendar representation as data of the drag object.
Definition: vcaldrag.cpp:38
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jul 21 2022 00:00:00 by doxygen 1.9.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCalUtils Library

Skip menu "KCalUtils Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal