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

KCalUtils Library

  • sources
  • kde-4.14
  • kdepimlibs
  • 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 
53 using namespace KCalCore;
54 using namespace KCalUtils;
55 
60 //@cond PRIVATE
61 class KCalUtils::DndFactory::Private
62 {
63 public:
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 
136 DndFactory::DndFactory(const MemoryCalendar::Ptr &calendar)
137  : d(new KCalUtils::DndFactory::Private(calendar))
138 {
139 }
140 
141 DndFactory::~DndFactory()
142 {
143  delete d;
144 }
145 
146 QMimeData *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 
156 QDrag *DndFactory::createDrag(QWidget *owner)
157 {
158  QDrag *drag = new QDrag(owner);
159  drag->setMimeData(createMimeData());
160 
161  return drag;
162 }
163 
164 QMimeData *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 
187 QDrag *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 
196 MemoryCalendar::Ptr DndFactory::createDropCalendar(const QMimeData *mimeData)
197 {
198  return createDropCalendar(mimeData, d->mCalendar->timeSpec());
199 }
200 
201 MemoryCalendar::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 
214 MemoryCalendar::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 
224 Event::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 
239 Event::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 
250 Todo::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 
266 Todo::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 
277 void DndFactory::cutIncidence(const Incidence::Ptr &selectedIncidence)
278 {
279  Incidence::List list;
280  list.append(selectedIncidence);
281  cutIncidences(list);
282 }
283 
284 bool 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 
297 bool 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 
323 bool DndFactory::copyIncidence(const Incidence::Ptr &selectedInc)
324 {
325  Incidence::List list;
326  list.append(selectedInc);
327  return copyIncidences(list);
328 }
329 
330 Incidence::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 
373 Incidence::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 }
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
QWidget
QDropEvent::mimeData
const QMimeData * mimeData() const
QClipboard::mimeData
const QMimeData * mimeData(Mode mode) const
QDrag::setMimeData
void setMimeData(QMimeData *data)
KCalUtils::DndFactory::createDropTodo
KCalCore::Todo::Ptr createDropTodo(const QMimeData *md)
Create Todo object from mime data.
Definition: dndfactory.cpp:250
KCalUtils::DndFactory::cutIncidence
void cutIncidence(const KCalCore::Incidence::Ptr &)
Cut the incidence to the clipboard.
Definition: dndfactory.cpp:277
QDrag::setPixmap
void setPixmap(const QPixmap &pixmap)
QMap
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
QVector::first
T & first()
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
QMimeData
QClipboard
KCalUtils::DndFactory::createDropEvent
KCalCore::Event::Ptr createDropEvent(const QMimeData *md)
Create Event object from mime data.
Definition: dndfactory.cpp:224
QFlags
KCalCore::MemoryCalendar
QSharedPointer
QApplication::clipboard
QClipboard * clipboard()
QHash
QDropEvent
QDrag
QDate
QString
QClipboard::setMimeData
void setMimeData(QMimeData *src, Mode mode)
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
dndfactory.h
This file is part of the API for handling calendar data and defines the DndFactory class...
QDate::setDate
bool setDate(int year, int month, int day)
QVector
QLatin1String
KCalUtils::DndFactory::createDrag
QDrag * createDrag(QWidget *owner)
Create a drag object for the whole calendar.
Definition: dndfactory.cpp:156
QVector::isEmpty
bool isEmpty() const
KCalCore::Todo
KCalCore::Event
KCalUtils::DndFactory::copyIncidence
bool copyIncidence(const KCalCore::Incidence::Ptr &)
Copy the incidence to clipboard/.
Definition: dndfactory.cpp:323
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::createMimeData
QMimeData * createMimeData()
Create the mime data for the whole calendar.
Definition: dndfactory.cpp:146
QHash::contains
bool contains(const Key &key) const
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
KCalUtils::DndFactory
vCalendar/iCalendar Drag-and-Drop object factory.
Definition: dndfactory.h:58
KCalUtils::DndFactory::cutIncidences
bool cutIncidences(const KCalCore::Incidence::List &incidences)
Cuts a list of incidences to the clipboard.
Definition: dndfactory.cpp:284
KCalUtils::DndFactory::copyIncidences
bool copyIncidences(const KCalCore::Incidence::List &incidences)
Copies a list of incidences to the clipboard.
Definition: dndfactory.cpp:297
QSharedPointer::staticCast
QSharedPointer< X > staticCast() const
QDropEvent::accept
void accept(bool accept)
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
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:37:46 by doxygen 1.8.7 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 API Reference

Skip menu "kdepimlibs 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

Search



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