diff --git a/src/dndfactory.cpp b/src/dndfactory.cpp index 922a25603..cd6a24770 100644 --- a/src/dndfactory.cpp +++ b/src/dndfactory.cpp @@ -1,387 +1,384 @@ /* This file is part of the kcalutils library. Copyright (c) 1998 Preston Brown Copyright (c) 2001,2002 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer Copyright (c) 2005 Rafal Rzepecki Copyright (c) 2008 Thomas Thrainer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** @file This file is part of the API for handling calendar data and defines the DndFactory class. @brief vCalendar/iCalendar Drag-and-Drop object factory. @author Preston Brown \ @author Cornelius Schumacher \ @author Reinhold Kainhofer \ */ #include "dndfactory.h" #include "icaldrag.h" #include "vcaldrag.h" #include "kcalutils_debug.h" #include // for BarIcon #include #include #include #include #include #include #include #include #include #include using namespace KCalCore; using namespace KCalUtils; /** DndFactoryPrivate class that helps to provide binary compatibility between releases. @internal */ //@cond PRIVATE class KCalUtils::DndFactoryPrivate { public: DndFactoryPrivate(const MemoryCalendar::Ptr &calendar) : mCalendar(calendar) { } Incidence::Ptr pasteIncidence(const Incidence::Ptr &incidence, QDateTime newDateTime, DndFactory::PasteFlags pasteOptions) { Incidence::Ptr inc(incidence); if (inc) { inc = Incidence::Ptr(inc->clone()); inc->recreate(); } if (inc && newDateTime.isValid()) { if (inc->type() == Incidence::TypeEvent) { Event::Ptr event = inc.staticCast(); if (pasteOptions & DndFactory::FlagPasteAtOriginalTime) { // Set date and preserve time and timezone stuff const QDate date = newDateTime.date(); newDateTime = event->dtStart(); newDateTime.setDate(date); } // in seconds const int durationInSeconds = event->dtStart().secsTo(event->dtEnd()); const int durationInDays = event->dtStart().daysTo(event->dtEnd()); if (incidence->allDay()) { event->setDtStart(QDateTime(newDateTime.date(), {})); event->setDtEnd(newDateTime.addDays(durationInDays)); } else { event->setDtStart(newDateTime); event->setDtEnd(newDateTime.addSecs(durationInSeconds)); } } else if (inc->type() == Incidence::TypeTodo) { Todo::Ptr aTodo = inc.staticCast(); const bool pasteAtDtStart = (pasteOptions & DndFactory::FlagTodosPasteAtDtStart); if (pasteOptions & DndFactory::FlagPasteAtOriginalTime) { // Set date and preserve time and timezone stuff const QDate date = newDateTime.date(); newDateTime = pasteAtDtStart ? aTodo->dtStart() : aTodo->dtDue(); newDateTime.setDate(date); } if (pasteAtDtStart) { aTodo->setDtStart(newDateTime); } else { aTodo->setDtDue(newDateTime); } } else if (inc->type() == Incidence::TypeJournal) { if (pasteOptions & DndFactory::FlagPasteAtOriginalTime) { // Set date and preserve time and timezone stuff const QDate date = newDateTime.date(); newDateTime = inc->dtStart(); newDateTime.setDate(date); } inc->setDtStart(newDateTime); } else { qCDebug(KCALUTILS_LOG) << "Trying to paste unknown incidence of type" << int(inc->type()); } } return inc; } MemoryCalendar::Ptr mCalendar; }; //@endcond DndFactory::DndFactory(const MemoryCalendar::Ptr &calendar) : d(new KCalUtils::DndFactoryPrivate(calendar)) { } DndFactory::~DndFactory() { delete d; } QMimeData *DndFactory::createMimeData() { QMimeData *mimeData = new QMimeData; ICalDrag::populateMimeData(mimeData, d->mCalendar); - VCalDrag::populateMimeData(mimeData, d->mCalendar); return mimeData; } QDrag *DndFactory::createDrag(QWidget *owner) { QDrag *drag = new QDrag(owner); drag->setMimeData(createMimeData()); return drag; } QMimeData *DndFactory::createMimeData(const Incidence::Ptr &incidence) { MemoryCalendar::Ptr cal(new MemoryCalendar(d->mCalendar->timeZone())); Incidence::Ptr i(incidence->clone()); //strip recurrence id's, We don't want to drag the exception but the occurrence. i->setRecurrenceId({}); cal->addIncidence(i); QMimeData *mimeData = new QMimeData; ICalDrag::populateMimeData(mimeData, cal); - VCalDrag::populateMimeData(mimeData, cal); QUrl uri = i->uri(); if (uri.isValid()) { QMap metadata; metadata[QStringLiteral("labels")] = QLatin1String(QUrl::toPercentEncoding(i->summary())); mimeData->setUrls(QList() << uri); KUrlMimeData::setMetaData(metadata, mimeData); } return mimeData; } QDrag *DndFactory::createDrag(const Incidence::Ptr &incidence, QWidget *owner) { QDrag *drag = new QDrag(owner); drag->setMimeData(createMimeData(incidence)); drag->setPixmap(BarIcon(incidence->iconName())); return drag; } MemoryCalendar::Ptr DndFactory::createDropCalendar(const QMimeData *mimeData) { if (mimeData) { MemoryCalendar::Ptr calendar(new MemoryCalendar(QTimeZone::systemTimeZone())); if (ICalDrag::fromMimeData(mimeData, calendar) || VCalDrag::fromMimeData(mimeData, calendar)) { return calendar; } } return MemoryCalendar::Ptr(); } MemoryCalendar::Ptr DndFactory::createDropCalendar(QDropEvent *dropEvent) { MemoryCalendar::Ptr calendar(createDropCalendar(dropEvent->mimeData())); if (calendar) { dropEvent->accept(); return calendar; } return MemoryCalendar::Ptr(); } Event::Ptr DndFactory::createDropEvent(const QMimeData *mimeData) { //qCDebug(KCALUTILS_LOG); Event::Ptr event; MemoryCalendar::Ptr calendar(createDropCalendar(mimeData)); if (calendar) { Event::List events = calendar->events(); if (!events.isEmpty()) { event = Event::Ptr(new Event(*events.first())); } } return event; } Event::Ptr DndFactory::createDropEvent(QDropEvent *dropEvent) { Event::Ptr event = createDropEvent(dropEvent->mimeData()); if (event) { dropEvent->accept(); } return event; } Todo::Ptr DndFactory::createDropTodo(const QMimeData *mimeData) { //qCDebug(KCALUTILS_LOG); Todo::Ptr todo; MemoryCalendar::Ptr calendar(createDropCalendar(mimeData)); if (calendar) { Todo::List todos = calendar->todos(); if (!todos.isEmpty()) { todo = Todo::Ptr(new Todo(*todos.first())); } } return todo; } Todo::Ptr DndFactory::createDropTodo(QDropEvent *dropEvent) { Todo::Ptr todo = createDropTodo(dropEvent->mimeData()); if (todo) { dropEvent->accept(); } return todo; } void DndFactory::cutIncidence(const Incidence::Ptr &selectedIncidence) { Incidence::List list; list.append(selectedIncidence); cutIncidences(list); } bool DndFactory::cutIncidences(const Incidence::List &incidences) { if (copyIncidences(incidences)) { Incidence::List::ConstIterator it; const Incidence::List::ConstIterator end(incidences.constEnd()); for (it = incidences.constBegin(); it != end; ++it) { d->mCalendar->deleteIncidence(*it); } return true; } else { return false; } } bool DndFactory::copyIncidences(const Incidence::List &incidences) { QClipboard *clipboard = QApplication::clipboard(); Q_ASSERT(clipboard); MemoryCalendar::Ptr calendar(new MemoryCalendar(d->mCalendar->timeZone())); Incidence::List::ConstIterator it; const Incidence::List::ConstIterator end(incidences.constEnd()); for (it = incidences.constBegin(); it != end; ++it) { if (*it) { calendar->addIncidence(Incidence::Ptr((*it)->clone())); } } QMimeData *mimeData = new QMimeData; ICalDrag::populateMimeData(mimeData, calendar); - VCalDrag::populateMimeData(mimeData, calendar); if (calendar->incidences().isEmpty()) { return false; } else { clipboard->setMimeData(mimeData); return true; } } bool DndFactory::copyIncidence(const Incidence::Ptr &selectedInc) { Incidence::List list; list.append(selectedInc); return copyIncidences(list); } Incidence::List DndFactory::pasteIncidences(const QDateTime &newDateTime, PasteFlags pasteOptions) { QClipboard *clipboard = QApplication::clipboard(); Q_ASSERT(clipboard); MemoryCalendar::Ptr calendar(createDropCalendar(clipboard->mimeData())); Incidence::List list; if (!calendar) { qCDebug(KCALUTILS_LOG) << "Can't parse clipboard"; return list; } // All pasted incidences get new uids, must keep track of old uids, // so we can update child's parents QHash oldUidToNewInc; Incidence::List::ConstIterator it; const Incidence::List incidences = calendar->incidences(); Incidence::List::ConstIterator end(incidences.constEnd()); for (it = incidences.constBegin(); it != end; ++it) { Incidence::Ptr incidence = d->pasteIncidence(*it, newDateTime, pasteOptions); if (incidence) { list.append(incidence); oldUidToNewInc[(*it)->uid()] = *it; } } // update relations end = list.constEnd(); for (it = list.constBegin(); it != end; ++it) { Incidence::Ptr incidence = *it; if (oldUidToNewInc.contains(incidence->relatedTo())) { Incidence::Ptr parentInc = oldUidToNewInc[incidence->relatedTo()]; incidence->setRelatedTo(parentInc->uid()); } else { // not related to anything in the clipboard incidence->setRelatedTo(QString()); } } return list; } Incidence::Ptr DndFactory::pasteIncidence(const QDateTime &newDateTime, PasteFlags pasteOptions) { QClipboard *clipboard = QApplication::clipboard(); MemoryCalendar::Ptr calendar(createDropCalendar(clipboard->mimeData())); if (!calendar) { qCDebug(KCALUTILS_LOG) << "Can't parse clipboard"; return Incidence::Ptr(); } Incidence::List incidenceList = calendar->incidences(); Incidence::Ptr incidence = incidenceList.isEmpty() ? Incidence::Ptr() : incidenceList.first(); return d->pasteIncidence(incidence, newDateTime, pasteOptions); } diff --git a/src/vcaldrag.cpp b/src/vcaldrag.cpp index 7650338a6..cfeab80e6 100644 --- a/src/vcaldrag.cpp +++ b/src/vcaldrag.cpp @@ -1,73 +1,63 @@ /* This file is part of the kcalutils library. Copyright (c) 1998 Preston Brown Copyright (c) 2001 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "vcaldrag.h" #include using namespace KCalCore; #include #include using namespace KCalUtils; using namespace VCalDrag; QString VCalDrag::mimeType() { return QStringLiteral("text/x-vCalendar"); } -bool VCalDrag::populateMimeData(QMimeData *e, const MemoryCalendar::Ptr &cal) -{ - VCalFormat format; - QString calstr(format.toString(cal)); - if (e && !calstr.isEmpty()) { - e->setData(mimeType(), calstr.toUtf8()); - } - return canDecode(e); -} - bool VCalDrag::canDecode(const QMimeData *me) { if (me) { return me->hasFormat(mimeType()); } else { return false; } } bool VCalDrag::fromMimeData(const QMimeData *de, const MemoryCalendar::Ptr &cal) { if (!canDecode(de)) { return false; } bool success = false; const QByteArray payload = de->data(mimeType()); if (!payload.isEmpty()) { const QString txt = QString::fromUtf8(payload.data()); VCalFormat format; success = format.fromString(cal, txt); } return success; } diff --git a/src/vcaldrag.h b/src/vcaldrag.h index 03344357b..509c0d9ab 100644 --- a/src/vcaldrag.h +++ b/src/vcaldrag.h @@ -1,57 +1,52 @@ /* This file is part of the kcalutils library. Copyright (c) 1998 Preston Brown Copyright (c) 2001-2003 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KCALUTILS_VCALDRAG_H #define KCALUTILS_VCALDRAG_H #include "kcalutils_export.h" #include class QMimeData; namespace KCalUtils { /** vCalendar drag&drop class. */ namespace VCalDrag { /** Mime-type of iCalendar */ KCALUTILS_EXPORT QString mimeType(); -/** - Sets the vCalendar representation as data of the drag object -*/ -KCALUTILS_EXPORT bool populateMimeData(QMimeData *e, const KCalCore::MemoryCalendar::Ptr &cal); - /** Return, if drag&drop object can be decode to vCalendar. */ KCALUTILS_EXPORT bool canDecode(const QMimeData *); /** Decode drag&drop object to vCalendar component \a vcal. */ KCALUTILS_EXPORT bool fromMimeData(const QMimeData *e, const KCalCore::MemoryCalendar::Ptr &cal); } } #endif