20 #include "calendarclipboard_p.h" 21 #include <kcalutils/dndfactory.h> 22 #include <kcalutils/icaldrag.h> 24 #include <KLocalizedString> 25 #include <KMessageBox> 27 #include <QApplication> 32 CalendarClipboard::Private::Private(
const Akonadi::CalendarBase::Ptr &calendar,
33 Akonadi::IncidenceChanger *changer,
35 , m_calendar(calendar)
37 , m_abortCurrentOperation(false)
42 m_changer =
new Akonadi::IncidenceChanger(
this);
43 m_changer->setHistoryEnabled(
false);
44 m_changer->setGroupwareCommunication(
false);
47 m_dndfactory =
new KCalUtils::DndFactory(m_calendar);
50 SIGNAL(
modifyFinished(
int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)),
51 SLOT(slotModifyFinished(
int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)));
54 SIGNAL(
deleteFinished(
int,QVector<Akonadi::Item::Id>,Akonadi::IncidenceChanger::ResultCode,QString)),
55 SLOT(slotDeleteFinished(
int,QVector<Akonadi::Item::Id>,Akonadi::IncidenceChanger::ResultCode,QString)));
58 CalendarClipboard::Private::~Private()
63 void CalendarClipboard::Private::getIncidenceHierarchy(
const KCalCore::Incidence::Ptr &incidence,
67 if (incidence && !uids.contains(incidence->uid())) {
68 KCalCore::Incidence::List immediateChildren = m_calendar->childIncidences(incidence->uid());
70 foreach(
const KCalCore::Incidence::Ptr &child, immediateChildren) {
71 getIncidenceHierarchy(child, uids);
73 uids.append(incidence->uid());
77 void CalendarClipboard::Private::cut(
const KCalCore::Incidence::List &incidences)
79 const bool result = m_dndfactory->copyIncidences(incidences);
80 m_pendingChangeIds.clear();
84 Akonadi::Item::List
items = m_calendar->itemList(incidences);
85 const int result = m_changer->deleteIncidences(items);
87 emit q->cutFinished(
false, i18n(
"Error performing deletion."));
89 m_pendingChangeIds << result;
92 emit q->cutFinished(
false, i18n(
"Error performing copy."));
96 void CalendarClipboard::Private::cut(
const KCalCore::Incidence::Ptr &incidence)
98 KCalCore::Incidence::List incidences;
99 incidences << incidence;
103 void CalendarClipboard::Private::makeChildsIndependent(
const KCalCore::Incidence::Ptr &incidence)
106 const KCalCore::Incidence::List childs = m_calendar->childIncidences(incidence->uid());
108 if (childs.isEmpty()) {
111 m_pendingChangeIds.clear();
112 m_abortCurrentOperation =
false;
113 foreach(
const KCalCore::Incidence::Ptr &child, childs) {
114 Akonadi::Item childItem = m_calendar->item(incidence);
115 if (!childItem.isValid()) {
116 emit q->cutFinished(
false, i18n(
"Can't find item: %1", childItem.id()));
120 KCalCore::Incidence::Ptr newIncidence(child->clone());
121 newIncidence->setRelatedTo(QString());
122 childItem.setPayload<KCalCore::Incidence::Ptr>(newIncidence);
123 const int changeId = m_changer->modifyIncidence(childItem, child);
124 if (changeId == -1) {
125 m_abortCurrentOperation =
true;
128 m_pendingChangeIds << changeId;
131 if (m_pendingChangeIds.isEmpty() && m_abortCurrentOperation) {
132 emit q->cutFinished(
false, i18n(
"Error while removing relations."));
137 void CalendarClipboard::Private::slotModifyFinished(
int changeId,
const Akonadi::Item &
item,
138 IncidenceChanger::ResultCode resultCode,
139 const QString &errorMessage)
141 if (!m_pendingChangeIds.contains(changeId))
144 m_pendingChangeIds.remove(changeId);
145 const bool isLastChange = m_pendingChangeIds.isEmpty();
148 Q_UNUSED(errorMessage);
149 if (m_abortCurrentOperation && isLastChange) {
150 emit q->cutFinished(
false, i18n(
"Error while removing relations."));
151 }
else if (!m_abortCurrentOperation) {
152 if (resultCode == IncidenceChanger::ResultCodeSuccess) {
155 Q_ASSERT(item.isValid() && item.hasPayload());
156 cut(item.payload<KCalCore::Incidence::Ptr>());
159 m_abortCurrentOperation =
true;
164 void CalendarClipboard::Private::slotDeleteFinished(
int changeId,
const QVector<Akonadi::Item::Id> &ids,
165 Akonadi::IncidenceChanger::ResultCode result,
166 const QString &errorMessage)
168 if (!m_pendingChangeIds.contains(changeId))
171 m_pendingChangeIds.remove(changeId);
174 if (result == IncidenceChanger::ResultCodeSuccess) {
175 emit q->cutFinished(
true, QString());
177 emit q->cutFinished(
false, i18n(
"Error while deleting incidences: %1",
183 Akonadi::IncidenceChanger *changer,
184 QObject *parent) : QObject(parent)
185 , d(new Private(calendar, changer, this))
197 const bool hasChildren = !d->m_calendar->childIncidences(incidence->uid()).isEmpty();
198 if (mode ==
AskMode && hasChildren) {
199 const int km = KMessageBox::questionYesNoCancel(0,
200 i18n(
"The item \"%1\" has sub-to-dos. " 201 "Do you want to cut just this item and " 202 "make all its sub-to-dos independent, or " 203 "cut the to-do with all its sub-to-dos?",
204 incidence->summary()),
205 i18n(
"KOrganizer Confirmation"),
206 KGuiItem(i18n(
"Cut Only This")),
207 KGuiItem(i18n(
"Cut All")));
209 if (km == KMessageBox::Cancel) {
219 d->makeChildsIndependent(incidence);
222 d->getIncidenceHierarchy(incidence, uids);
223 Q_ASSERT(!uids.isEmpty());
224 KCalCore::Incidence::List incidencesToCut;
225 foreach(
const QString &uid, uids) {
226 KCalCore::Incidence::Ptr child = d->m_calendar->incidence(uid);
228 incidencesToCut << child;
230 d->cut(incidencesToCut);
237 const bool hasChildren = !d->m_calendar->childIncidences(incidence->uid()).isEmpty();
238 if (mode ==
AskMode && hasChildren) {
239 const int km = KMessageBox::questionYesNoCancel(0,
240 i18n(
"The item \"%1\" has sub-to-dos. " 241 "Do you want to copy just this item or " 242 "copy the to-do with all its sub-to-dos?",
243 incidence->summary()),
244 i18n(
"KOrganizer Confirmation"),
245 KGuiItem(i18n(
"Copy Only This")),
246 KGuiItem(i18n(
"Copy All")));
247 if (km == KMessageBox::Cancel) {
255 KCalCore::Incidence::List incidencesToCopy;
257 incidencesToCopy << incidence;
260 d->getIncidenceHierarchy(incidence, uids);
261 Q_ASSERT(!uids.isEmpty());
262 foreach(
const QString &uid, uids) {
263 KCalCore::Incidence::Ptr child = d->m_calendar->incidence(uid);
265 incidencesToCopy << child;
269 return d->m_dndfactory->copyIncidences(incidencesToCopy);
274 return KCalUtils::ICalDrag::canDecode(QApplication::clipboard()->mimeData());
The specified incidence's children are also cut/copied.
Akonadi::Item::List items() const
Returns the list of items contained in this calendar.
Akonadi::Item item(const QString &uid) const
Returns the Item containing the incidence with uid uid or an invalid Item if the incidence isn't foun...
bool pasteAvailable() const
Returns if there's any ical mime data available for pasting.
void deleteFinished(bool success, const QString &errorMessage)
This signal is emitted when an incidence is deleted in akonadi through delete{Incidence,Event,Todo,Journal} or deleteAll{Events,Todos,Journals}.
void modifyFinished(bool success, const QString &errorMessage)
This signal is emitted when an incidence is modified in akonadi through modifyIncidence().
The user is asked if he wants children to be cut/copied too.
Only the specified incidence is cut/copied.
CalendarClipboard(const Akonadi::CalendarBase::Ptr &calendar, Akonadi::IncidenceChanger *changer=0, QObject *parent=0)
Constructs a new CalendarClipboard.
bool copyIncidence(const KCalCore::Incidence::Ptr &incidence, CalendarClipboard::Mode mode=RecursiveMode)
Copies the specified incidence into the clipboard.
FreeBusyManager::Singleton.
~CalendarClipboard()
Destroys the CalendarClipboard instance.
void cutFinished(bool success, const QString &errorMessage)
Emitted after cutIncidences() finishes.
Class to copy or cut calendar incidences.
void cutIncidence(const KCalCore::Incidence::Ptr &incidence, CalendarClipboard::Mode mode=RecursiveMode)
Copies the specified incidence into the clipboard and then deletes it from akonadi.