void HtmlExport::formatAttendees( QTextStream *ts, Incidence *event ) { Attendee::List attendees = event->attendees(); if (attendees.count()) { *ts << "<em>"; #ifndef KORG_NOKABC KABC::AddressBook *add_book = KABC::StdAddressBook::self( true ); KABC::Addressee::List addressList; addressList = add_book->findByEmail(event->organizer().email()); KABC::Addressee o = addressList.first(); if (!o.isEmpty() && addressList.size()<2) { *ts << "<a href=\"mailto:" << event->organizer().email() << "\">"; *ts << cleanChars(o.formattedName()) << "</a>\n"; } else *ts << event->organizer().fullName(); #else *ts << event->organizer().fullName(); #endif *ts << "</em><br />"; Attendee::List::ConstIterator it; for( it = attendees.begin(); it != attendees.end(); ++it ) { Attendee *a = *it; if (!a->email().isEmpty()) { *ts << "<a href=\"mailto:" << a->email(); *ts << "\">" << cleanChars(a->name()) << "</a>"; } else { *ts << " " << cleanChars(a->name()); } *ts << "<br />" << "\n"; } } else { *ts << " \n"; } }
bool Scheduler::acceptFreeBusy(IncidenceBase *incidence, Method method) { if ( !d->mFreeBusyCache ) { kdError() << "KCal::Scheduler: no FreeBusyCache." << endl; return false; } FreeBusy *freebusy = static_cast<FreeBusy *>(incidence); kdDebug(5800) << "acceptFreeBusy:: freeBusyDirName: " << freeBusyDir() << endl; Person from; if(method == Scheduler::Publish) { from = freebusy->organizer(); } if((method == Scheduler::Reply) && (freebusy->attendeeCount() == 1)) { Attendee *attendee = freebusy->attendees().first(); from = attendee->email(); } if ( !d->mFreeBusyCache->saveFreeBusy( freebusy, from ) ) return false; deleteTransaction(incidence); return true; }
bool IncidenceChanger::myAttendeeStatusChanged( Incidence *oldInc, Incidence *newInc ) { Attendee *oldMe = oldInc->attendeeByMails( KOPrefs::instance()->allEmails() ); Attendee *newMe = newInc->attendeeByMails( KOPrefs::instance()->allEmails() ); if ( oldMe && newMe && ( oldMe->status() != newMe->status() ) ) return true; return false; }
void KOEditorDetails::fillIncidence( Incidence *incidence ) { incidence->clearAttendees(); QVector<Q3ListViewItem*> toBeDeleted; Q3ListViewItem *item; AttendeeListItem *a; for ( item = mListView->firstChild(); item; item = item->nextSibling() ) { a = (AttendeeListItem *)item; Attendee *attendee = a->data(); Q_ASSERT( attendee ); /* Check if the attendee is a distribution list and expand it */ if ( attendee->email().isEmpty() ) { KPIM::DistributionList list = KPIM::DistributionList::findByName( KABC::StdAddressBook::self(), attendee->name() ); if ( !list.isEmpty() ) { toBeDeleted.push_back( item ); // remove it once we are done expanding KPIM::DistributionList::Entry::List entries = list.entries( KABC::StdAddressBook::self() ); KPIM::DistributionList::Entry::List::Iterator it( entries.begin() ); while ( it != entries.end() ) { KPIM::DistributionList::Entry &e = ( *it ); ++it; // this calls insertAttendee, which appends insertAttendeeFromAddressee( e.addressee, attendee ); // TODO: duplicate check, in case it was already added manually } } } else { bool skip = false; if ( attendee->email().endsWith( QLatin1String( "example.net" ) ) ) { if ( KMessageBox::warningYesNo( this, i18nc( "@info", "%1 does not look like a valid email address. " "Are you sure you want to invite this participant?", attendee->email() ), i18nc( "@title", "Invalid Email Address" ) ) != KMessageBox::Yes ) { skip = true; } } if ( !skip ) { incidence->addAttendee( new Attendee( *attendee ) ); } } } KOAttendeeEditor::fillIncidence( incidence ); // cleanup qDeleteAll( toBeDeleted ); toBeDeleted.clear(); }
void KOEditorFreeBusy::writeEvent(KCal::Event * event) { event->clearAttendees(); QValueVector<FreeBusyItem*> toBeDeleted; for ( FreeBusyItem *item = static_cast<FreeBusyItem *>( mGanttView->firstChild() ); item; item = static_cast<FreeBusyItem*>( item->nextSibling() ) ) { Attendee *attendee = item->attendee(); Q_ASSERT( attendee ); /* Check if the attendee is a distribution list and expand it */ if ( attendee->email().isEmpty() ) { KPIM::DistributionList list = KPIM::DistributionList::findByName( KABC::StdAddressBook::self(), attendee->name() ); if ( !list.isEmpty() ) { toBeDeleted.push_back( item ); // remove it once we are done expanding KPIM::DistributionList::Entry::List entries = list.entries( KABC::StdAddressBook::self() ); KPIM::DistributionList::Entry::List::Iterator it( entries.begin() ); while ( it != entries.end() ) { KPIM::DistributionList::Entry &e = ( *it ); ++it; // this calls insertAttendee, which appends insertAttendeeFromAddressee( e.addressee, attendee ); // TODO: duplicate check, in case it was already added manually } } } else { bool skip = false; if ( attendee->email().endsWith( "example.net" ) ) { if ( KMessageBox::warningYesNo( this, i18n("%1 does not look like a valid email address. " "Are you sure you want to invite this participant?").arg( attendee->email() ), i18n("Invalid email address") ) != KMessageBox::Yes ) { skip = true; } } if ( !skip ) { event->addAttendee( new Attendee( *attendee ) ); } } } KOAttendeeEditor::writeEvent( event ); // cleanup QValueVector<FreeBusyItem*>::iterator it; for( it = toBeDeleted.begin(); it != toBeDeleted.end(); ++it ) { delete *it; } }
void KOAttendeeEditor::insertAttendeeFromAddressee( const KABC::Addressee &a, const Attendee *at ) { bool myself = KOPrefs::instance()->thatIsMe( a.preferredEmail() ); bool sameAsOrganizer = mOrganizerCombo && KPIMUtils::compareEmail( a.preferredEmail(), mOrganizerCombo->currentText(), false ); KCal::Attendee::PartStat partStat = at ? at->status() : KCal::Attendee::NeedsAction; bool rsvp = at? at->RSVP() : true; if ( myself && sameAsOrganizer ) { partStat = KCal::Attendee::Accepted; rsvp = false; } Attendee *newAt = new Attendee( a.realName(), a.preferredEmail(), !myself, partStat, at ? at->role() : Attendee::ReqParticipant, a.uid() ); newAt->setRSVP( rsvp ); insertAttendee( newAt, true ); }
void FreeBusyItem::updateItem() { setListViewText( 0, mAttendee->fullName() ); switch ( mAttendee->status() ) { case Attendee::Accepted: setPixmap( 0, KOGlobals::self()->smallIcon( "ok" ) ); break; case Attendee::Declined: setPixmap( 0, KOGlobals::self()->smallIcon( "no" ) ); break; case Attendee::NeedsAction: case Attendee::InProcess: setPixmap( 0, KOGlobals::self()->smallIcon( "help" ) ); break; case Attendee::Tentative: setPixmap( 0, KOGlobals::self()->smallIcon( "apply" ) ); break; case Attendee::Delegated: setPixmap( 0, KOGlobals::self()->smallIcon( "mail_forward" ) ); break; default: setPixmap( 0, QPixmap() ); } }
void KCalResourceSlox::parseMembersAttribute( const QDomElement &e, Incidence *incidence ) { incidence->clearAttendees(); QDomNode n; for( n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) { QDomElement memberElement = n.toElement(); if ( memberElement.tagName() == fieldName( Participant ) ) { QString member = memberElement.text(); KABC::Addressee account; if ( mAccounts ) account = mAccounts->lookupUser( member ); else kError() << "KCalResourceSlox: no accounts set"; QString name; QString email; Attendee *a = incidence->attendeeByUid( member ); if ( account.isEmpty() ) { if ( a ) continue; name = member; email = member + '@' + KUrl( mPrefs->url() ).host(); } else { name = account.realName(); email = account.preferredEmail(); } if ( a ) { a->setName( name ); a->setEmail( email ); } else { a = new Attendee( name, email ); a->setUid( member ); incidence->addAttendee( a ); } QString status = memberElement.attribute( "confirm" ); if ( !status.isEmpty() ) { if ( status == "accept" ) { a->setStatus( Attendee::Accepted ); } else if ( status == "decline" ) { a->setStatus( Attendee::Declined ); } else { a->setStatus( Attendee::NeedsAction ); } } } else { kDebug() << "Unknown tag in members attribute:" << memberElement.tagName(); } } }
void KOAttendeeEditor::updateAttendee() { Attendee *a = currentAttendee(); if ( !a || mDisableItemUpdate ) return; QString name; QString email; KPIM::getNameAndMail(mNameEdit->text(), name, email); bool iAmTheOrganizer = mOrganizerCombo && KOPrefs::instance()->thatIsMe( mOrganizerCombo->currentText() ); if ( iAmTheOrganizer ) { bool myself = KPIM::compareEmail( email, mOrganizerCombo->currentText(), false ); bool wasMyself = KPIM::compareEmail( a->email(), mOrganizerCombo->currentText(), false ); if ( myself ) { mStatusCombo->setCurrentItem( KCal::Attendee::Accepted ); mRsvpButton->setChecked( false ); mRsvpButton->setEnabled( false ); } else if ( wasMyself ) { // this was me, but is no longer, reset mStatusCombo->setCurrentItem( KCal::Attendee::NeedsAction ); mRsvpButton->setChecked( true ); mRsvpButton->setEnabled( true ); } } a->setName( name ); a->setUid( mUid ); a->setEmail( email ); a->setRole( Attendee::Role( mRoleCombo->currentItem() ) ); a->setStatus( Attendee::PartStat( mStatusCombo->currentItem() ) ); a->setRSVP( mRsvpButton->isChecked() ); updateCurrentItem(); }
void KOWhatsNextView::updateView() { KIconLoader kil("kdepim"); QString *ipath = new QString(); kil.loadIcon("kdepim",KIcon::NoGroup,32,KIcon::DefaultState,ipath); mText = "<table width=\"100%\">\n"; mText += "<tr bgcolor=\"#3679AD\"><td><h1>"; mText += "<img src=\""; mText += *ipath; mText += "\">"; mText += "<font color=\"white\"> "; mText += i18n("What's Next?") + "</font></h1>"; mText += "</td></tr>\n<tr><td>"; mText += "<h2>"; if ( mStartDate.daysTo( mEndDate ) < 1 ) { mText += KGlobal::locale()->formatDate( mStartDate ); } else { mText += i18n("Date from - to", "%1 - %2") .arg( KGlobal::locale()->formatDate( mStartDate ) ) .arg( KGlobal::locale()->formatDate( mEndDate ) ); } mText+="</h2>\n"; Event::List events; for ( QDate date = mStartDate; date <= mEndDate; date = date.addDays( 1 ) ) events += calendar()->events(date, EventSortStartDate, SortDirectionAscending); if (events.count() > 0) { mText += "<p></p>"; kil.loadIcon("appointment",KIcon::NoGroup,22,KIcon::DefaultState,ipath); mText += "<h2><img src=\""; mText += *ipath; mText += "\">"; mText += i18n("Events:") + "</h2>\n"; mText += "<table>\n"; Event::List::ConstIterator it; for( it = events.begin(); it != events.end(); ++it ) { Event *ev = *it; if ( !ev->doesRecur() ){ appendEvent(ev); } else { // FIXME: This should actually be cleaned up. Libkcal should // provide a method to return a list of all recurrences in a // given time span. Recurrence *recur = ev->recurrence(); int duration = ev->dtStart().secsTo( ev->dtEnd() ); QDateTime start = recur->getPreviousDateTime( QDateTime( mStartDate, QTime() ) ); QDateTime end = start.addSecs( duration ); if ( end.date() >= mStartDate ) { appendEvent( ev, start, end ); } start = recur->getNextDateTime( start ); while ( start.isValid() && start.date() <= mEndDate ) { appendEvent( ev, start ); start = recur->getNextDateTime( start ); } } } mText += "</table>\n"; } mTodos.clear(); Todo::List todos = calendar()->todos( TodoSortDueDate, SortDirectionAscending ); if ( todos.count() > 0 ) { kil.loadIcon("todo",KIcon::NoGroup,22,KIcon::DefaultState,ipath); mText += "<h2><img src=\""; mText += *ipath; mText += "\">"; mText += i18n("To-do:") + "</h2>\n"; mText += "<ul>\n"; Todo::List::ConstIterator it; for( it = todos.begin(); it != todos.end(); ++it ) { Todo *todo = *it; if ( !todo->isCompleted() && todo->hasDueDate() && todo->dtDue().date() <= mEndDate ) appendTodo(todo); } bool gotone = false; int priority = 1; while (!gotone && priority<=9 ) { for( it = todos.begin(); it != todos.end(); ++it ) { Todo *todo = *it; if (!todo->isCompleted() && (todo->priority() == priority) ) { appendTodo(todo); gotone = true; } } priority++; kdDebug(5850) << "adding the todos..." << endl; } mText += "</ul>\n"; } QStringList myEmails( KOPrefs::instance()->allEmails() ); int replies = 0; events = calendar()->events( QDate::currentDate(), QDate(2975,12,6) ); Event::List::ConstIterator it2; for( it2 = events.begin(); it2 != events.end(); ++it2 ) { Event *ev = *it2; Attendee *me = ev->attendeeByMails( myEmails ); if (me!=0) { if (me->status()==Attendee::NeedsAction && me->RSVP()) { if (replies == 0) { mText += "<p></p>"; kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath); mText += "<h2><img src=\""; mText += *ipath; mText += "\">"; mText += i18n("Events and to-dos that need a reply:") + "</h2>\n"; mText += "<table>\n"; } replies++; appendEvent( ev ); } } } todos = calendar()->todos(); Todo::List::ConstIterator it3; for( it3 = todos.begin(); it3 != todos.end(); ++it3 ) { Todo *to = *it3; Attendee *me = to->attendeeByMails( myEmails ); if (me!=0) { if (me->status()==Attendee::NeedsAction && me->RSVP()) { if (replies == 0) { mText += "<p></p>"; kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath); mText += "<h2><img src=\""; mText += *ipath; mText += "\">"; mText += i18n("Events and to-dos that need a reply:") + "</h2>\n"; mText += "<table>\n"; } replies++; appendEvent(to); } } kdDebug () << "check for todo-replies..." << endl; } if (replies > 0 ) mText += "</table>\n"; mText += "</td></tr>\n</table>\n"; kdDebug(5850) << "KOWhatsNextView::updateView: text: " << mText << endl; delete ipath; mView->setText(mText); }
void KOAttendeeEditor::readIncidence( KCal::Incidence *incidence ) { qDeleteAll( mDelAttendees ); mDelAttendees.clear(); if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) || incidence->organizer().isEmpty() ) { //TODO: make a new private method for creating the mOrganizerCombo //and use it here and initOrganizerWidgets() above. if ( !mOrganizerCombo ) { mOrganizerCombo = new KComboBox( mOrganizerHBox ); mOrganizerCombo->setToolTip( i18nc( "@info:tooltip", "Select the organizer" ) ); mOrganizerCombo->setWhatsThis( i18nc( "@info:whatsthis", "Select the identity to use as the organizer for this incidence." ) ); fillOrganizerCombo(); } mOrganizerLabel->setText( i18nc( "@label", "Identity as organizer:" ) ); int found = -1; QString fullOrganizer = incidence->organizer().fullName(); for ( int i = 0; i < mOrganizerCombo->count(); ++i ) { if ( mOrganizerCombo->itemText( i ) == fullOrganizer ) { found = i; mOrganizerCombo->setCurrentIndex( i ); break; } } if ( found < 0 ) { mOrganizerCombo->addItem( fullOrganizer, 0 ); mOrganizerCombo->setCurrentIndex( 0 ); } } else { // someone else is the organizer if ( mOrganizerCombo ) { delete mOrganizerCombo; mOrganizerCombo = 0; } mOrganizerLabel->setText( i18nc( "@label", "Organizer: %1", incidence->organizer().fullName() ) ); } Attendee::List al = incidence->attendees(); Attendee::List::ConstIterator it; Attendee *first = 0; for ( it = al.constBegin(); it != al.constEnd(); ++it ) { Attendee *a = new Attendee( **it ); if ( !first ) { first = a; } insertAttendee( a, true ); } // Set the initial editing values to the first attendee in the list. if ( first ) { // Don't update the item here, the user didn't edit it, so it's not needed. // Also, AttendeeEditor's subclasses didn't set the current Item at this point // so if updateAttendee is called now what will happen is that a random item // will get the text of "first". mDisableItemUpdate = true; mNameEdit->setText( first->fullName() ); mUid = first->uid(); mRoleCombo->setCurrentIndex( first->role() ); if ( first->status() != KCal::Attendee::None ) { mStatusCombo->setCurrentIndex( first->status() ); } else { mStatusCombo->setCurrentIndex( KCal::Attendee::NeedsAction ); } mRsvpButton->setChecked( first->RSVP() ); mRsvpButton->setEnabled( true ); mDisableItemUpdate = false; } }
bool KCal::operator==(const Attendee &a1, const Attendee &a2) { return (operator==((const Person &)a1, (const Person &) a2) && a1.RSVP() == a2.RSVP() && a1.role() == a2.role() && a1.status() == a2.status() && a1.uid() == a2.uid() && a1.delegate() == a2.delegate() && a1.delegator() == a2.delegator()); }
bool Scheduler::acceptReply(IncidenceBase *incidence,ScheduleMessage::Status /* status */, Method method) { if(incidence->type()=="FreeBusy") { return acceptFreeBusy(incidence, method); } bool ret = false; Event *ev = mCalendar->event(incidence->uid()); Todo *to = mCalendar->todo(incidence->uid()); // try harder to find the correct incidence if ( !ev && !to ) { const Incidence::List list = mCalendar->incidences(); for ( Incidence::List::ConstIterator it = list.begin(), end = list.end(); it != end; ++it ) { if ( (*it)->schedulingID() == incidence->uid() ) { ev = dynamic_cast<Event*>( *it ); to = dynamic_cast<Todo*>( *it ); break; } } } if (ev || to) { //get matching attendee in calendar kdDebug(5800) << "Scheduler::acceptTransaction match found!" << endl; Attendee::List attendeesIn = incidence->attendees(); Attendee::List attendeesEv; Attendee::List attendeesNew; if (ev) attendeesEv = ev->attendees(); if (to) attendeesEv = to->attendees(); Attendee::List::ConstIterator inIt; Attendee::List::ConstIterator evIt; for ( inIt = attendeesIn.begin(); inIt != attendeesIn.end(); ++inIt ) { Attendee *attIn = *inIt; bool found = false; for ( evIt = attendeesEv.begin(); evIt != attendeesEv.end(); ++evIt ) { Attendee *attEv = *evIt; if (attIn->email().lower()==attEv->email().lower()) { //update attendee-info kdDebug(5800) << "Scheduler::acceptTransaction update attendee" << endl; attEv->setStatus(attIn->status()); attEv->setDelegate(attIn->delegate()); attEv->setDelegator(attIn->delegator()); ret = true; found = true; } } if ( !found && attIn->status() != Attendee::Declined ) attendeesNew.append( attIn ); } bool attendeeAdded = false; for ( Attendee::List::ConstIterator it = attendeesNew.constBegin(); it != attendeesNew.constEnd(); ++it ) { Attendee* attNew = *it; QString msg = i18n("%1 wants to attend %2 but was not invited.").arg( attNew->fullName() ) .arg( ev ? ev->summary() : to->summary() ); if ( !attNew->delegator().isEmpty() ) msg = i18n("%1 wants to attend %2 on behalf of %3.").arg( attNew->fullName() ) .arg( ev ? ev->summary() : to->summary() ) .arg( attNew->delegator() ); if ( KMessageBox::questionYesNo( 0, msg, i18n("Uninvited attendee"), KGuiItem(i18n("Accept Attendance")), KGuiItem(i18n("Reject Attendance")) ) != KMessageBox::Yes ) { KCal::Incidence *cancel = dynamic_cast<Incidence*>( incidence ); if ( cancel ) cancel->addComment( i18n( "The organizer rejected your attendance at this meeting." ) ); performTransaction( cancel ? cancel : incidence, Scheduler::Cancel, attNew->fullName() ); delete cancel; continue; } Attendee *a = new Attendee( attNew->name(), attNew->email(), attNew->RSVP(), attNew->status(), attNew->role(), attNew->uid() ); a->setDelegate( attNew->delegate() ); a->setDelegator( attNew->delegator() ); if ( ev ) ev->addAttendee( a ); else if ( to ) to->addAttendee( a ); ret = true; attendeeAdded = true; } // send update about new participants if ( attendeeAdded ) { if ( ev ) { ev->setRevision( ev->revision() + 1 ); performTransaction( ev, Scheduler::Request ); } if ( to ) { to->setRevision( ev->revision() + 1 ); performTransaction( to, Scheduler::Request ); } } if ( ret ) { // We set at least one of the attendees, so the incidence changed // Note: This should not result in a sequence number bump if ( ev ) ev->updated(); else if ( to ) to->updated(); } if ( to ) { // for VTODO a REPLY can be used to update the completion status of // a task. see RFC2446 3.4.3 Todo *update = dynamic_cast<Todo*> ( incidence ); Q_ASSERT( update ); if ( update && ( to->percentComplete() != update->percentComplete() ) ) { to->setPercentComplete( update->percentComplete() ); to->updated(); } } } else kdError(5800) << "No incidence for scheduling\n"; if (ret) deleteTransaction(incidence); return ret; }
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 ); }