bool KOMailClient::mailTo( IncidenceBase *incidence, const Identity &identity,
                           const QString &from, bool bccMe,
                           const QString &recipients, const QString &attachment,
                           bool useSendmail )
{
  QString subject;

  if ( incidence->type() != "FreeBusy" ) {
    Incidence *inc = static_cast<Incidence *>( incidence );
    subject = inc->summary();
  } else {
    subject = "Free Busy Message";
  }
  QString body = IncidenceFormatter::mailBodyStr( incidence, KSystemTimeZones::local() );

  return send( identity, from, recipients, QString(), subject, body, false,
               bccMe, attachment, useSendmail );
}
示例#2
0
void KOIncidenceEditor::cancelRemovedAttendees(Incidence *incidence)
{
    if(!incidence) return;

    // cancelAttendeeEvent removes all attendees from the incidence,
    // and then only adds those that need to be cancelled (i.e. a mail needs to be sent to them).
    if(KOPrefs::instance()->thatIsMe(incidence->organizer().email()))
    {
        Incidence *ev = incidence->clone();
        ev->registerObserver(0);
        mAttendeeEditor->cancelAttendeeEvent(ev);
        if(ev->attendeeCount() > 0)
        {
            emit deleteAttendee(ev);
        }
        delete(ev);
    }

}
示例#3
0
QMimeData *DndFactory::createMimeData( Incidence *incidence )
{
  CalendarLocal cal( d->mCalendar->timeSpec() );
  Incidence *i = incidence->clone();
  cal.addIncidence( i );

  QMimeData *mimeData = new QMimeData;

  ICalDrag::populateMimeData( mimeData, &cal );
  VCalDrag::populateMimeData( mimeData, &cal );

  KUrl uri = i->uri();
  if ( uri.isValid() ) {
    QMap<QString, QString> metadata;
    metadata["labels"] = KUrl::toPercentEncoding( i->summary() );
    uri.populateMimeData( mimeData, metadata );
  }

  return mimeData;
}
示例#4
0
QMap<Todo *,KOTodoViewItem *>::ConstIterator
  KOTodoView::insertTodoItem(Todo *todo)
{
//  kdDebug(5850) << "KOTodoView::insertTodoItem(): " << todo->getSummary() << endl;
  Incidence *incidence = todo->relatedTo();
  if (incidence && incidence->type() == "Todo") {
    // Use dynamic_cast, because in the future the related item might also be an event
    Todo *relatedTodo = dynamic_cast<Todo *>(incidence);

    // just make sure we know we have this item already to avoid endless recursion (Bug 101696)
    mTodoMap.insert(todo,0);

//    kdDebug(5850) << "  has Related" << endl;
    QMap<Todo *,KOTodoViewItem *>::ConstIterator itemIterator;
    itemIterator = mTodoMap.find(relatedTodo);
    if (itemIterator == mTodoMap.end()) {
//      kdDebug(5850) << "    related not yet in list" << endl;
      itemIterator = insertTodoItem (relatedTodo);
    }
    // isn't this pretty stupid? We give one Todo  to the KOTodoViewItem
    // and one into the map. Sure finding is more easy but why? -zecke
    KOTodoViewItem *todoItem;

    // in case we found a related parent, which has no KOTodoViewItem yet, this must
    // be the case where 2 items refer to each other, therefore simply create item as root item
    if ( *itemIterator == 0 ) {
      todo->setRelatedTo(0);  // break the recursion, else we will have troubles later
      todoItem = new KOTodoViewItem(mTodoListView,todo,this);
    }
    else
      todoItem = new KOTodoViewItem(*itemIterator,todo,this);

    return mTodoMap.insert(todo,todoItem);
  } else {
//    kdDebug(5850) << "  no Related" << endl;
      // see above -zecke
    KOTodoViewItem *todoItem = new KOTodoViewItem(mTodoListView,todo,this);
    return mTodoMap.insert(todo,todoItem);
  }
}
示例#5
0
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;
}
bool KOMailClient::mailOrganizer( IncidenceBase *incidence,
                                  const Identity &identity,
                                  const QString &from, bool bccMe,
                                  const QString &attachment,
                                  const QString &sub, bool useSendmail )
{
  QString to = incidence->organizer().fullName();

  QString subject = sub;
  if ( incidence->type() != "FreeBusy" ) {
    Incidence *inc = static_cast<Incidence *>( incidence );
    if ( subject.isEmpty() ) {
      subject = inc->summary();
    }
  } else {
    subject = "Free Busy Message";
  }

  QString body = IncidenceFormatter::mailBodyStr( incidence, KSystemTimeZones::local() );

  return send( identity, from, to, QString(), subject, body, false,
               bccMe, attachment, useSendmail );
}
示例#7
0
// When this is called, the todo have already been added to the calendar.
// This method is only about linking related todos
void Calendar::setupRelations(Incidence *forincidence)
{
    if(!forincidence) return;
    // kdDebug(5850) << "Calendar::setupRelations for incidence " << forincidence << " with UID " << forincidence->uid() << ", summary: " << forincidence->summary() << endl;
    QString uid = forincidence->uid();

    // First, go over the list of orphans and see if this is their parent
    while(Incidence *i = mOrphans[ uid ])
    {
        mOrphans.remove(uid);
        i->setRelatedTo(forincidence);
        forincidence->addRelation(i);
        mOrphanUids.remove(i->uid());
    }

    // Now see about this incidences parent
    if(!forincidence->relatedTo() && !forincidence->relatedToUid().isEmpty())
    {
        // This incidence has a uid it is related to but is not registered to it yet
        // Try to find it
        Incidence *parent = incidence(forincidence->relatedToUid());
        if(parent)
        {
            // Found it
            forincidence->setRelatedTo(parent);
            parent->addRelation(forincidence);
        }
        else
        {
            // Not found, put this in the mOrphans list
            // Note that the mOrphans dict might have several entries with the same key! That are
            // multiple children that wait for the parent incidence to be inserted.
            mOrphans.insert(forincidence->relatedToUid(), forincidence);
            mOrphanUids.insert(forincidence->uid(), forincidence);
        }
    }
}
示例#8
0
void KOTodoEditor::writeTodo(Todo *todo)
{
    Incidence *oldIncidence = todo->clone();

    mRecurrence->writeIncidence(todo);
    mGeneral->writeTodo(todo);
    mDetails->writeEvent(todo);

    if(*(oldIncidence->recurrence()) != *(todo->recurrence()))
    {
        todo->setDtDue(todo->dtDue(), true);
        if(todo->hasStartDate())
            todo->setDtStart(todo->dtStart());
    }
    writeDesignerFields(todo);

    // set related incidence, i.e. parent to-do in this case.
    if(mRelatedTodo)
    {
        todo->setRelatedTo(mRelatedTodo);
    }

    cancelRemovedAttendees(todo);
}
示例#9
0
bool Scheduler::acceptPublish( IncidenceBase *newIncBase,
                               ScheduleMessage::Status status, Method method )
{
    if( newIncBase->type() == "FreeBusy" ) {
        return acceptFreeBusy( newIncBase, method );
    }

    bool res = false;
    kdDebug(5800) << "Scheduler::acceptPublish, status="
                  << ScheduleMessage::statusName( status ) << endl;
    Incidence *newInc = static_cast<Incidence *>( newIncBase );
    Incidence *calInc = mCalendar->incidence( newIncBase->uid() );
    switch ( status ) {
    case ScheduleMessage::Unknown:
    case ScheduleMessage::PublishNew:
    case ScheduleMessage::PublishUpdate:
        res = true;
        if ( calInc ) {
            if ( (newInc->revision() > calInc->revision()) ||
                    (newInc->revision() == calInc->revision() &&
                     newInc->lastModified() > calInc->lastModified() ) ) {
                mCalendar->deleteIncidence( calInc );
            } else
                res = false;
        }
        if ( res )
            mCalendar->addIncidence( newInc );
        break;
    case ScheduleMessage::Obsolete:
        res = true;
        break;
    default:
        break;
    }
    deleteTransaction( newIncBase );
    return res;
}
示例#10
0
QString ICalFormat::createScheduleMessage(IncidenceBase *incidence,
        Scheduler::Method method)
{
    icalcomponent *message = 0;

    // Handle scheduling ID being present
    if(incidence->type() == "Event" || incidence->type() == "Todo")
    {
        Incidence *i = static_cast<Incidence *>(incidence);
        if(i->schedulingID() != i->uid())
        {
            // We have a separation of scheduling ID and UID
            i = i->clone();
            i->setUid(i->schedulingID());
            i->setSchedulingID(QString::null);

            // Build the message with the cloned incidence
            message = mImpl->createScheduleComponent(i, method);

            // And clean up
            delete i;
        }
    }

    if(message == 0)
        message = mImpl->createScheduleComponent(incidence, method);

    // FIXME TODO: Don't we have to free message? What about the ical_string? MEMLEAK
    QString messageText = QString::fromUtf8(icalcomponent_as_ical_string(message));

#if 0
    kdDebug(5800) << "ICalFormat::createScheduleMessage: message START\n"
                  << messageText
                  << "ICalFormat::createScheduleMessage: message END" << endl;
#endif

    return messageText;
}
示例#11
0
bool Scheduler::acceptRequest(IncidenceBase *newIncBase, ScheduleMessage::Status /* status */)
{
    if (newIncBase->type()=="FreeBusy") {
        // reply to this request is handled in korganizer's incomingdialog
        return true;
    }
    Incidence *newInc = dynamic_cast<Incidence *>( newIncBase );
    if ( newInc ) {
        bool res = true;
        Incidence *exInc = mCalendar->incidenceFromSchedulingID( newIncBase->uid() );
        if ( exInc ) {
            res = false;
            if ( (newInc->revision() > exInc->revision()) ||
                    (newInc->revision() == exInc->revision() &&
                     newInc->lastModified()>exInc->lastModified()) ) {
                mCalendar->deleteIncidence( exInc );
                res = true;
            }
        }
        if ( res ) {
            // Move the uid to be the schedulingID and make a unique UID
            newInc->setSchedulingID( newInc->uid() );
            newInc->setUid( CalFormat::createUniqueId() );

            mCalendar->addIncidence(newInc);
        }
        deleteTransaction( newIncBase );
        return res;
    }
    return false;
}
void KCalResourceSlox::slotUploadResult( KJob *job )
{
  kDebug();

  if ( job->error() ) {
    saveError( job->errorString() );
  } else {
    kDebug() << "success";

    if ( !mUploadJob )
    {
        kDebug() << "mUploadJob was 0";
        return;
    }

    QDomDocument doc = mUploadJob->response();

    kDebug() << "UPLOAD RESULT:";
    kDebug() << doc.toString( 2 );

    QDomElement docElement = doc.documentElement();

    QDomNode responseNode;
    for( responseNode = docElement.firstChild(); !responseNode.isNull();
         responseNode = responseNode.nextSibling() ) {
      QDomElement responseElement = responseNode.toElement();
      if ( responseElement.tagName() == "response" ) {
        QDomNode propstat = responseElement.namedItem( "propstat" );
        if ( propstat.isNull() ) {
          kError() << "Unable to find propstat tag.";
          continue;
        }

        QDomNode status = propstat.namedItem( "status" );
        if ( !status.isNull() ) {
          QDomElement statusElement = status.toElement();
          QString response = statusElement.text();
        if ( !response.contains( "200" ) ) {
            QString error = '\'' + mUploadedIncidence->summary() + "'\n";
            error += response;
            QDomNode dn = propstat.namedItem( "responsedescription" );
            QString d = dn.toElement().text();
            if ( !d.isEmpty() ) error += '\n' + d;
            saveError( error );
            continue;
          }
        }

        QDomNode prop = propstat.namedItem( "prop" );
        if ( prop.isNull() ) {
          kError() << "Unable to find WebDAV property";
          continue;
        }

        QDomNode sloxIdNode = prop.namedItem( fieldName( ObjectId ) );
        if ( sloxIdNode.isNull() ) {
          kError() << "Unable to find SLOX id.";
          continue;
        }
        QDomElement sloxIdElement = sloxIdNode.toElement();
        QString sloxId = sloxIdElement.text();
        kDebug() << "SLOXID:" << sloxId;

        if ( mUploadIsDelete ) {
          kDebug() << "Incidence deleted";
        } else {
          QDomNode clientIdNode = prop.namedItem( fieldName( ClientId ) );
          if ( clientIdNode.isNull() ) {
            kError() << "Unable to find client id.";
            continue;
          }
          QDomElement clientidElement = clientIdNode.toElement();
          QString clientId = clientidElement.text();

          kDebug() << "CLIENTID:" << clientId;

          Incidence *i = mUploadedIncidence->clone();
          QString uid;
          if ( i->type() == "Event" ) uid = sloxIdToEventUid( sloxId );
          else if ( i->type() == "Todo" ) uid = sloxIdToTodoUid( sloxId );
          else {
            kError() << "Unknown type:"
                     << i->type();
          }
          i->setUid( uid );
          i->setCustomProperty( "SLOX", "ID", sloxId );

          if ( type() == "ox" ) {
            // Update the last_modified property
            const QDomNode lastModifiedNode = prop.namedItem( fieldName( LastModified ) );
            if ( !lastModifiedNode.isNull() ) {
              const QDomElement lastModifiedElement = lastModifiedNode.toElement();
              const QString lastModified = lastModifiedElement.text();
              i->setCustomProperty( "SLOX", "LastModified", lastModified );
            }
          }

          disableChangeNotification();
          calendar()->deleteIncidence( mUploadedIncidence );
          calendar()->addIncidence( i );
          saveToCache();
          enableChangeNotification();

          emit resourceChanged( this );
        }
      }
    }
  }

  mUploadJob = 0;

  mUploadProgress->setComplete();
  mUploadProgress = 0;

  clearChange( mUploadedIncidence );

  uploadIncidences();
}
示例#13
0
void SearchDialog::search(const QRegExp &re)
{
    QDate startDt = mStartDate->date();
    QDate endDt = mEndDate->date();

    Event::List events;
    if(mEventsCheck->isChecked())
    {
        events = mCalendar->events(startDt, endDt, mInclusiveCheck->isChecked());
    }
    Todo::List todos;
    if(mTodosCheck->isChecked())
    {
        if(mIncludeUndatedTodos->isChecked())
        {
            Todo::List alltodos = mCalendar->todos();
            Todo::List::iterator it;
            Todo *todo;
            for(it = alltodos.begin(); it != alltodos.end(); ++it)
            {
                todo = *it;
                if((!todo->hasStartDate() && !todo->hasDueDate()) ||    // undated
                        (todo->hasStartDate() && (todo->dtStart() >= startDt) && (todo->dtStart() <= endDt)) ||   // start dt in range
                        (todo->hasDueDate() && (todo->dtDue().date() >= startDt) && (todo->dtDue() <= endDt)) ||   // due dt in range
                        (todo->hasCompletedDate() && (todo->completed().date() >= startDt) && (todo->completed() <= endDt)))    // completed dt in range
                {
                    todos.append(todo);
                }
            }
        }
        else
        {
            QDate dt = startDt;
            while(dt <= endDt)
            {
                todos += mCalendar->todos(dt);
                dt = dt.addDays(1);
            }
        }
    }

    Journal::List journals;
    if(mJournalsCheck->isChecked())
    {
        QDate dt = startDt;
        while(dt <= endDt)
        {
            journals += mCalendar->journals(dt);
            dt = dt.addDays(1);
        }
    }

    Incidence::List allIncidences = Calendar::mergeIncidenceList(events, todos, journals);

    mMatchedEvents.clear();
    Incidence::List::ConstIterator it;
    for(it = allIncidences.begin(); it != allIncidences.end(); ++it)
    {
        Incidence *ev = *it;
        if(mSummaryCheck->isChecked())
        {
#if QT_VERSION >= 300
            if(re.search(ev->summary()) != -1)
            {
#else
            if(re.match(ev->summary()) != -1)
            {
#endif
                mMatchedEvents.append(ev);
                continue;
            }
        }
        if(mDescriptionCheck->isChecked())
        {
#if QT_VERSION >= 300
            if(re.search(ev->description()) != -1)
            {
#else
            if(re.match(ev->description()) != -1)
            {
#endif
                mMatchedEvents.append(ev);
                continue;
            }
        }
        if(mCategoryCheck->isChecked())
        {
#if QT_VERSION >= 300
            if(re.search(ev->categoriesStr()) != -1)
            {
#else
            if(re.match(ev->categoriesStr()) != -1)
            {
#endif
                mMatchedEvents.append(ev);
                continue;
            }
        }
    }
}
示例#14
0
ScheduleMessage *ICalFormat::parseScheduleMessage(Calendar *cal,
        const QString &messageText)
{
    setTimeZone(cal->timeZoneId(), !cal->isLocalTime());
    clearException();

    if(messageText.isEmpty())
    {
        setException(new ErrorFormat(ErrorFormat::ParseErrorKcal, QString::fromLatin1("messageText was empty, unable to parse into a ScheduleMessage")));
        return 0;
    }
    // TODO FIXME: Don't we have to ical-free message??? MEMLEAK
    icalcomponent *message;
    message = icalparser_parse_string(messageText.utf8());

    if(!message)
    {
        setException(new ErrorFormat(ErrorFormat::ParseErrorKcal, QString::fromLatin1("icalparser was unable to parse messageText into a ScheduleMessage")));
        return 0;
    }

    icalproperty *m = icalcomponent_get_first_property(message,
                      ICAL_METHOD_PROPERTY);
    if(!m)
    {
        setException(new ErrorFormat(ErrorFormat::ParseErrorKcal, QString::fromLatin1("message didn't contain an ICAL_METHOD_PROPERTY")));
        return 0;
    }

    icalcomponent *c;

    IncidenceBase *incidence = 0;
    c = icalcomponent_get_first_component(message, ICAL_VEVENT_COMPONENT);
    if(c)
    {
        icalcomponent *ctz = icalcomponent_get_first_component(message, ICAL_VTIMEZONE_COMPONENT);
        incidence = mImpl->readEvent(c, ctz);
    }

    if(!incidence)
    {
        c = icalcomponent_get_first_component(message, ICAL_VTODO_COMPONENT);
        if(c)
        {
            incidence = mImpl->readTodo(c);
        }
    }

    if(!incidence)
    {
        c = icalcomponent_get_first_component(message, ICAL_VJOURNAL_COMPONENT);
        if(c)
        {
            incidence = mImpl->readJournal(c);
        }
    }

    if(!incidence)
    {
        c = icalcomponent_get_first_component(message, ICAL_VFREEBUSY_COMPONENT);
        if(c)
        {
            incidence = mImpl->readFreeBusy(c);
        }
    }



    if(!incidence)
    {
        kdDebug(5800) << "ICalFormat:parseScheduleMessage: object is not a freebusy, event, todo or journal" << endl;
        setException(new ErrorFormat(ErrorFormat::ParseErrorKcal, QString::fromLatin1("object is not a freebusy, event, todo or journal")));
        return 0;
    }

    kdDebug(5800) << "ICalFormat::parseScheduleMessage() getting method..." << endl;

    icalproperty_method icalmethod = icalproperty_get_method(m);
    Scheduler::Method method;

    switch(icalmethod)
    {
        case ICAL_METHOD_PUBLISH:
            method = Scheduler::Publish;
            break;
        case ICAL_METHOD_REQUEST:
            method = Scheduler::Request;
            break;
        case ICAL_METHOD_REFRESH:
            method = Scheduler::Refresh;
            break;
        case ICAL_METHOD_CANCEL:
            method = Scheduler::Cancel;
            break;
        case ICAL_METHOD_ADD:
            method = Scheduler::Add;
            break;
        case ICAL_METHOD_REPLY:
            method = Scheduler::Reply;
            break;
        case ICAL_METHOD_COUNTER:
            method = Scheduler::Counter;
            break;
        case ICAL_METHOD_DECLINECOUNTER:
            method = Scheduler::Declinecounter;
            break;
        default:
            method = Scheduler::NoMethod;
            kdDebug(5800) << "ICalFormat::parseScheduleMessage(): Unknow method" << endl;
            break;
    }

    kdDebug(5800) << "ICalFormat::parseScheduleMessage() restriction..." << endl;

    if(!icalrestriction_check(message))
    {
        kdWarning(5800) << k_funcinfo << endl << "libkcal reported a problem while parsing:" << endl;
        kdWarning(5800) << Scheduler::translatedMethodName(method) + ": " + mImpl->extractErrorProperty(c) << endl;
        /*
        setException(new ErrorFormat(ErrorFormat::Restriction,
                                       Scheduler::translatedMethodName(method) + ": " +
                                       mImpl->extractErrorProperty(c)));
        delete incidence;
        return 0;
        */
    }
    icalcomponent *calendarComponent = mImpl->createCalendarComponent(cal);

    Incidence *existingIncidence =
        cal->incidenceFromSchedulingID(incidence->uid());
    if(existingIncidence)
    {
        // TODO: check, if cast is required, or if it can be done by virtual funcs.
        // TODO: Use a visitor for this!
        if(existingIncidence->type() == "Todo")
        {
            Todo *todo = static_cast<Todo *>(existingIncidence);
            icalcomponent_add_component(calendarComponent,
                                        mImpl->writeTodo(todo));
        }
        if(existingIncidence->type() == "Event")
        {
            Event *event = static_cast<Event *>(existingIncidence);
            icalcomponent_add_component(calendarComponent,
                                        mImpl->writeEvent(event));
        }
    }
    else
    {
        calendarComponent = 0;
    }

    kdDebug(5800) << "ICalFormat::parseScheduleMessage() classify..." << endl;

    icalproperty_xlicclass result = icalclassify(message, calendarComponent,
                                    (char *)"");

    kdDebug(5800) << "ICalFormat::parseScheduleMessage() returning..." << endl;
    kdDebug(5800) << "ICalFormat::parseScheduleMessage(), result = " << result << endl;

    ScheduleMessage::Status status;

    switch(result)
    {
        case ICAL_XLICCLASS_PUBLISHNEW:
            status = ScheduleMessage::PublishNew;
            break;
        case ICAL_XLICCLASS_PUBLISHUPDATE:
            status = ScheduleMessage::PublishUpdate;
            break;
        case ICAL_XLICCLASS_OBSOLETE:
            status = ScheduleMessage::Obsolete;
            break;
        case ICAL_XLICCLASS_REQUESTNEW:
            status = ScheduleMessage::RequestNew;
            break;
        case ICAL_XLICCLASS_REQUESTUPDATE:
            status = ScheduleMessage::RequestUpdate;
            break;
        case ICAL_XLICCLASS_UNKNOWN:
        default:
            status = ScheduleMessage::Unknown;
            break;
    }

    kdDebug(5800) << "ICalFormat::parseScheduleMessage(), status = " << status << endl;
    // TODO FIXME: Don't we have to free calendarComponent??? MEMLEAK

    return new ScheduleMessage(incidence, method, status);
}
示例#15
0
// 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);
            }
        }
    }
}
示例#16
0
void KOTodoListView::contentsDropEvent( QDropEvent *e )
{
#ifndef KORG_NODND
  kdDebug(5850) << "KOTodoListView::contentsDropEvent" << endl;

  if ( !mCalendar || !mChanger ||
       ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) &&
         !QTextDrag::canDecode( e ) ) ) {
    e->ignore();
    return;
  }

  DndFactory factory( mCalendar );
  Todo *todo = factory.createDropTodo(e);

  if ( todo ) {
    e->acceptAction();

    KOTodoViewItem *destination =
        (KOTodoViewItem *)itemAt(contentsToViewport(e->pos()));
    Todo *destinationEvent = 0;
    if (destination) destinationEvent = destination->todo();

    Todo *existingTodo = mCalendar->todo(todo->uid());

    if( existingTodo ) {
       kdDebug(5850) << "Drop existing Todo " << existingTodo << " onto " << destinationEvent << endl;
      Incidence *to = destinationEvent;
      while(to) {
        if (to->uid() == todo->uid()) {
          KMessageBox::information(this,
              i18n("Cannot move to-do to itself or a child of itself."),
              i18n("Drop To-do"), "NoDropTodoOntoItself" );
          delete todo;
          return;
        }
        to = to->relatedTo();
      }
      Todo*oldTodo = existingTodo->clone();
      if ( mChanger->beginChange( existingTodo ) ) {
        existingTodo->setRelatedTo( destinationEvent );
        mChanger->changeIncidence( oldTodo, existingTodo, KOGlobals::RELATION_MODIFIED );
        mChanger->endChange( existingTodo );
      } else {
        KMessageBox::sorry( this, i18n("Unable to change to-do's parent, "
                            "because the to-do cannot be locked.") );
      }
      delete oldTodo;
      delete todo;
    } else {
//      kdDebug(5850) << "Drop new Todo" << endl;
      todo->setRelatedTo(destinationEvent);
      if ( !mChanger->addIncidence( todo, this ) ) {
        KODialogManager::errorSaveIncidence( this, todo );
        delete todo;
        return;
      }
    }
  }
  else {
    QString text;
    KOTodoViewItem *todoi = dynamic_cast<KOTodoViewItem *>(itemAt( contentsToViewport(e->pos()) ));
    if ( ! todoi ) {
      // Not dropped on a todo item:
      e->ignore();
      kdDebug( 5850 ) << "KOTodoListView::contentsDropEvent(): Not dropped on a todo item" << endl;
      kdDebug( 5850 ) << "TODO: Create a new todo with the given data" << endl;
      // FIXME: Create a new todo with the given text/contact/whatever
    } else if ( QTextDrag::decode(e, text) ) {
      //QListViewItem *qlvi = itemAt( contentsToViewport(e->pos()) );
      kdDebug(5850) << "Dropped : " << text << endl;
      Todo*todo = todoi->todo();
      if( mChanger->beginChange( todo ) ) {
        Todo*oldtodo = todo->clone();

        if( text.startsWith( "file:" ) ) {
          todo->addAttachment( new Attachment( text ) );
        } else {
          QStringList emails = KPIM::splitEmailAddrList( text );
          for(QStringList::ConstIterator it = emails.begin();it!=emails.end();++it) {
            kdDebug(5850) << " Email: " << (*it) << endl;
            int pos = (*it).find("<");
            QString name = (*it).left(pos);
            QString email = (*it).mid(pos);
            if (!email.isEmpty() && todoi) {
              todo->addAttendee( new Attendee( name, email ) );
            }
          }
        }
        mChanger->changeIncidence( oldtodo, todo );
        mChanger->endChange( todo );
      } else {
        KMessageBox::sorry( this, i18n("Unable to add attendees to the to-do, "
            "because the to-do cannot be locked.") );
      }
    }
    else {
      kdDebug(5850) << "KOTodoListView::contentsDropEvent(): Todo from drop not decodable" << endl;
      e->ignore();
    }
  }
#endif
}
示例#17
0
/** 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;
}
示例#18
0
bool KOMailClient::mailAttendees( IncidenceBase *incidence,
                                  const Identity &identity,
                                  bool bccMe, const QString &attachment,
                                  bool useSendmail )
{
  Attendee::List attendees = incidence->attendees();
  if ( attendees.count() == 0 ) {
    return false;
  }

  const QString from = incidence->organizer().fullName();
  const QString organizerEmail = incidence->organizer().email();

  QStringList toList;
  QStringList ccList;
  for ( int i=0; i<attendees.count(); ++i ) {
    Attendee *a = attendees.at(i);

    const QString email = a->email();
    if ( email.isEmpty() ) {
      continue;
    }

    // In case we (as one of our identities) are the organizer we are sending
    // this mail. We could also have added ourselves as an attendee, in which
    // case we don't want to send ourselves a notification mail.
    if ( organizerEmail == email ) {
      continue;
    }

    // Build a nice address for this attendee including the CN.
    QString tname, temail;
    const QString username = KPIMUtils::quoteNameIfNecessary( a->name() );
    // ignore the return value from extractEmailAddressAndName() because
    // it will always be false since tusername does not contain "@domain".
    KPIMUtils::extractEmailAddressAndName( username, temail, tname );
    tname += " <" + email + '>';

    // Optional Participants and Non-Participants are copied on the email
    if ( a->role() == Attendee::OptParticipant ||
         a->role() == Attendee::NonParticipant ) {
      ccList << tname;
    } else {
      toList << tname;
    }
  }
  if( toList.count() == 0 && ccList.count() == 0 ) {
    // Not really to be called a groupware meeting, eh
    return false;
  }
  QString to;
  if ( toList.count() > 0 ) {
    to = toList.join( ", " );
  }
  QString cc;
  if ( ccList.count() > 0 ) {
    cc = ccList.join( ", " );
  }

  QString subject;
  if ( incidence->type() != "FreeBusy" ) {
    Incidence *inc = static_cast<Incidence *>( incidence );
    subject = inc->summary();
  } else {
    subject = "Free Busy Object";
  }

  QString body = IncidenceFormatter::mailBodyStr( incidence, KSystemTimeZones::local() );

  return send( identity, from, to, cc, subject, body, false,
               bccMe, attachment, useSendmail );
}
示例#19
0
int main(int argc, char **argv)
{
    KAboutData aboutData("testrecurrencenew", "Load recurrence rules with the new class and print out debug messages", "0.1");
    KCmdLineArgs::init(argc, argv, &aboutData);
    KCmdLineArgs::addCmdLineOptions(options);

    KApplication app(false, false);

    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

    if(args->count() < 1)
    {
        args->usage("Wrong number of arguments.");
    }

    // use zoneinfo data from source dir
    set_zone_directory(KDETOPSRCDIR "/libkcal/libical/zoneinfo");

    QString input = QFile::decodeName(args->arg(0));
    kdDebug(5800) << "Input file: " << input << endl;

    QTextStream *outstream;
    outstream = 0;
    QString fn("");
    if(args->count() > 1)
    {
        fn = args->arg(1);
        kdDebug() << "We have a file name given: " << fn << endl;
    }
    QFile outfile(fn);
    if(!fn.isEmpty() && outfile.open(IO_WriteOnly))
    {
        kdDebug() << "Opened output file!!!" << endl;
        outstream = new QTextStream(&outfile);
    }

    CalendarLocal cal(QString::fromLatin1("UTC"));

    if(!cal.load(input)) return 1;
    QString tz = cal.nonKDECustomProperty("X-LibKCal-Testsuite-OutTZ");
    if(!tz.isEmpty())
    {
        cal.setTimeZoneIdViewOnly(tz);
    }

    Incidence::List inc = cal.incidences();

    for(Incidence::List::Iterator it = inc.begin(); it != inc.end(); ++it)
    {
        Incidence *incidence = *it;
        kdDebug(5800) << "*+*+*+*+*+*+*+*+*+*" << endl;
        kdDebug(5800) << " -> " << incidence->summary() << " <- " << endl;

        incidence->recurrence()->dump();

        QDateTime dt(incidence->recurrence()->endDateTime());
        int i = 0;
        if(outstream)
        {
            if(!dt.isValid()) dt = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 1));
            else dt = dt.addYears(2);
            kdDebug(5800) << "-------------------------------------------" << endl;
            kdDebug(5800) << " *~*~*~*~ Starting with date: " << dt << endl;
            // Output to file for testing purposes
            while(dt.isValid() && i < 500)
            {
                dt = dt.addSecs(-1);
                ++i;
                dt = incidence->recurrence()->getPreviousDateTime(dt);
                (*outstream) << dt.toString(Qt::ISODate) << endl;
            }
        }
        else
        {
            if(!dt.isValid()) dt = QDateTime(QDate(2005, 7, 31), QTime(23, 59, 59));
            else dt = dt.addYears(2);
            incidence->recurrence()->dump();
            kdDebug(5800) << "-------------------------------------------" << endl;
            kdDebug(5800) << " *~*~*~*~ Starting with date: " << dt << endl;
            // Output to konsole
            while(dt.isValid() && i < 50)
            {
                dt = dt.addSecs(-1);
                ++i;
                kdDebug(5800) << "-------------------------------------------" << endl;
                dt = incidence->recurrence()->getPreviousDateTime(dt);
                kdDebug(5800) << " *~*~*~*~ Previous date is: " << dt << endl;
            }
        }
    }

    delete outstream;
    outfile.close();
    return 0;
}