Incidence::List DndFactory::pasteIncidences( const QDate &newDate, const QTime *newTime ) { QClipboard *cb = QApplication::clipboard(); Calendar *cal = createDropCalendar( cb->mimeData() ); Incidence::List list; if ( !cal ) { kDebug() << "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<QString,Incidence*> oldUidToNewInc; Incidence::List::ConstIterator it; const Incidence::List incs = cal->incidences(); for ( it = incs.constBegin(); it != incs.constEnd(); ++it ) { Incidence *inc = d->pasteIncidence( *it, newDate, newTime ); if ( inc ) { list.append( inc ); oldUidToNewInc[( *it )->uid()] = inc; } } // update relations for ( it = list.constBegin(); it != list.constEnd(); ++it ) { Incidence *inc = *it; if ( oldUidToNewInc.contains( inc->relatedToUid() ) ) { Incidence *parentInc = oldUidToNewInc[inc->relatedToUid()]; inc->setRelatedToUid( parentInc->uid() ); inc->setRelatedTo( parentInc ); } else { // not related to anything in the clipboard inc->setRelatedToUid( QString() ); inc->setRelatedTo( 0 ); } } return list; }
Incidence *DndFactory::pasteIncidence( const QDate &newDate, const QTime *newTime ) { QClipboard *cb = QApplication::clipboard(); Calendar *cal = createDropCalendar( cb->mimeData() ); if ( !cal ) { kDebug() << "Can't parse clipboard"; return 0; } Incidence::List incList = cal->incidences(); Incidence *inc = incList.isEmpty() ? 0 : incList.first(); Incidence *newInc = d->pasteIncidence( inc, newDate, newTime ); newInc->setRelatedTo( 0 ); return newInc; }
// If a task with subtasks is deleted, move it's subtasks to the orphans list void Calendar::removeRelations(Incidence *incidence) { if(!incidence) { kdDebug(5800) << "Warning: Calendar::removeRelations( 0 )!\n"; return; } // kdDebug(5850) << "Calendar::removeRelations for incidence " << forincidence << " with UID " << forincidence->uid() << ", summary: " << forincidence->summary() << endl; QString uid = incidence->uid(); Incidence::List relations = incidence->relations(); Incidence::List::ConstIterator it; for(it = relations.begin(); it != relations.end(); ++it) { Incidence *i = *it; if(!mOrphanUids.find(i->uid())) { mOrphans.insert(uid, i); mOrphanUids.insert(i->uid(), i); i->setRelatedTo(0); i->setRelatedToUid(uid); } } // If this incidence is related to something else, tell that about it if(incidence->relatedTo()) incidence->relatedTo()->removeRelation(incidence); // Remove this one from the orphans list if(mOrphanUids.remove(uid)) { // This incidence is located in the orphans list - it should be removed // Since the mOrphans dict might contain the same key (with different // child incidence pointers!) multiple times, take care that we remove // the correct one. So we need to remove all items with the given // parent UID, and readd those that are not for this item. Also, there // might be other entries with differnet UID that point to this // incidence (this might happen when the relatedTo of the item is // changed before its parent is inserted. This might happen with // groupware servers....). Remove them, too QStringList relatedToUids; // First get the list of all keys in the mOrphans list that point to the removed item relatedToUids << incidence->relatedToUid(); for(QDictIterator<Incidence> it(mOrphans); it.current(); ++it) { if(it.current()->uid() == uid) { relatedToUids << it.currentKey(); } } // now go through all uids that have one entry that point to the incidence for(QStringList::Iterator uidit = relatedToUids.begin(); uidit != relatedToUids.end(); ++uidit) { Incidence::List tempList; // Remove all to get access to the remaining entries while(Incidence *i = mOrphans[ *uidit ]) { mOrphans.remove(*uidit); if(i != incidence) tempList.append(i); } // Readd those that point to a different orphan incidence for(Incidence::List::Iterator incit = tempList.begin(); incit != tempList.end(); ++incit) { mOrphans.insert(*uidit, *incit); } } } }
/** Dissociate a single occurrence or all future occurrences from a recurring sequence. The new incidence is returned, but not automatically inserted into the calendar, which is left to the calling application */ Incidence *Calendar::dissociateOccurrence(Incidence *incidence, QDate date, bool single) { if(!incidence || !incidence->doesRecur()) return 0; Incidence *newInc = incidence->clone(); newInc->recreate(); newInc->setRelatedTo(incidence); Recurrence *recur = newInc->recurrence(); if(single) { recur->clear(); } else { // Adjust the recurrence for the future incidences. In particular // adjust the "end after n occurrences" rules! "No end date" and "end by ..." // don't need to be modified. int duration = recur->duration(); if(duration > 0) { int doneduration = recur->durationTo(date.addDays(-1)); if(doneduration >= duration) { kdDebug(5850) << "The dissociated event already occurred more often " << "than it was supposed to ever occur. ERROR!" << endl; recur->clear(); } else { recur->setDuration(duration - doneduration); } } } // Adjust the date of the incidence if(incidence->type() == "Event") { Event *ev = static_cast<Event *>(newInc); QDateTime start(ev->dtStart()); int daysTo = start.date().daysTo(date); ev->setDtStart(start.addDays(daysTo)); ev->setDtEnd(ev->dtEnd().addDays(daysTo)); } else if(incidence->type() == "Todo") { Todo *td = static_cast<Todo *>(newInc); bool haveOffset = false; int daysTo = 0; if(td->hasDueDate()) { QDateTime due(td->dtDue()); daysTo = due.date().daysTo(date); td->setDtDue(due.addDays(daysTo), true); haveOffset = true; } if(td->hasStartDate()) { QDateTime start(td->dtStart()); if(!haveOffset) daysTo = start.date().daysTo(date); td->setDtStart(start.addDays(daysTo)); haveOffset = true; } } recur = incidence->recurrence(); if(recur) { if(single) { recur->addExDate(date); } else { // Make sure the recurrence of the past events ends // at the corresponding day recur->setEndDate(date.addDays(-1)); } } return newInc; }