📄 event.cpp
字号:
QValueList<QDate>::ConstIterator it; QString val; const QValueList<QDate> datelist = ((PrEvent &)e).exceptions(); for (it = datelist.begin(); it != datelist.end(); it++) { if (it != datelist.begin()) val += " "; val += TimeConversion::toISO8601(*it, FALSE); } // list of ISO (not UTC) dates. may need to express as datetimes. safeAddPropValue( event, VCExpDateProp, val ); } } qpe_endVObjectOutput(event,"Calendar",&e); // No tr return vcal;}static void parseRrule( PimEvent &e, const QString &v){ QString value = v.simplifyWhiteSpace(); enum state { type, interval, occurrencelist, weekdaylist, daynumberlist, monthlist, daylist, // not used, we don't do this type. duration, }; state st = type; // state; int i = 0; // index; int acc = 0; // for building ints. for (i = 0; i < (int)value.length(); i++) { switch (st) { case type: // repeat class/type // work out the basic rule type. if (value[i] == QChar('D')) { e.setRepeatType(PimEvent::Daily); } else if (value[i] == QChar('W')) { e.setRepeatType(PimEvent::Weekly); } else if (value[i] == QChar('M')) { i++; if (i >= (int)value.length()) break; // may need to change from MonthlyDay to MonthlyEndDay // later. if (value[i] == QChar('P')) e.setRepeatType(PimEvent::MonthlyDay); else e.setRepeatType(PimEvent::MonthlyDate); } else if (value[i] == QChar('Y')) { i++; if (i >= (int)value.length() || value[i] != QChar('M')) { // force exit from lup i = (int)value.length(); break;; // only know Yearly Month. } e.setRepeatType(PimEvent::Yearly); } st = interval; // frequency; break; case interval: // repeat frequency if (value[i].isSpace()) { // finished frequency; e.setFrequency(acc); if (e.repeatType() == PimEvent::Daily) st = duration; // duration; else if (e.repeatType() == PimEvent::Weekly) st = weekdaylist; else if (e.repeatType() == PimEvent::MonthlyDay) st = occurrencelist; else if (e.repeatType() == PimEvent::MonthlyDate) st = daylist; else st = monthlist; acc = 0; } else if (value[i].isDigit()) { if (acc) acc *=10; acc += value[i].digitValue(); } else { // fail. parse error. qDebug("failed to parse RRULE: non-digit in frequency"); return; } break; case occurrencelist: // this could actually be duration. // read next two to check, i+1 should be either // a + or a -; if (i+1 < (int)value.length() && value[i].isDigit()) { // what the digit is won't help, we always work // of the start date. if (value[i+1] == QChar('+')) { e.setRepeatType(PimEvent::MonthlyDay); i += 2; // get past inevitable ' ' st = weekdaylist; break; } else if (value[i+1] == QChar(' ')) { e.setRepeatType(PimEvent::MonthlyDay); i += 1; // get past ' ' st = weekdaylist; break; } else if (value[i+1] == QChar('-')) { e.setRepeatType(PimEvent::MonthlyEndDay); st = weekdaylist; i += 2; // get past inevitable ' ' break;; } } // not an occurance list, but still monthly day. i--; st = weekdaylist;; break; case weekdaylist: // end on digit or #. otherwise try it as a day. if (value[i] == QChar('#') || value[i].isDigit()) { st = duration; i--; break; } // read the next 2/3 (if third is space) if (i+1 >= (int)value.length()) { i = (int)value.length(); break; // only know Yearly Month. } if (value[i] == QChar('M')) e.setRepeatOnWeekDay(1, TRUE); else if (value[i] == QChar('T') && value[i+1] == QChar('U')) e.setRepeatOnWeekDay(2, TRUE); else if (value[i] == QChar('W')) e.setRepeatOnWeekDay(3, TRUE); else if (value[i] == QChar('T') && value[i+1] == QChar('H')) e.setRepeatOnWeekDay(4, TRUE); else if (value[i] == QChar('F')) e.setRepeatOnWeekDay(5, TRUE); else if (value[i] == QChar('S') && value[i+1] == QChar('A')) e.setRepeatOnWeekDay(6, TRUE); else if (value[i] == QChar('S') && value[i+1] == QChar('U')) e.setRepeatOnWeekDay(7, TRUE); // no to the inc. i += 2; // safe, as either while will cut out, or i+1 would be a ' ' break; // can't use either of these of these. case daylist: // FALL THROUGH case daynumberlist: // FALL THROUGH case monthlist: // find the optional duration. // find a # or more than 3 digets from end. // note we will be at the start of the string here. { int space = value.findRev(QChar(' ')); if (space < i-1) { i = (int)value.length(); break; } if (space + 4 < (int)value.length() || value[i] == QChar('#')) { i = space; st = duration; } else { i = (int)value.length(); break; } } break; case duration: // repeat duration // duration. // expect either a # or a datetime. // if # just finish of the number now. if (value[i] == QChar('#')) { i++; acc = 0; while (i < (int)value.length()) { if (value[i].isDigit()) { acc *= 10; acc += value[i].digitValue(); } else { qDebug("failed to parse RRULE: non-digit in duration count"); } i++; } // if 0, repeat forever. if anything else will need if (acc == 0) e.setRepeatForever(TRUE); i = (int)value.length(); // XXX Could add code to work out the count -> date. } else { // from hear till the end is an ISO value, and we want it. e.setRepeatTill( TimeConversion::fromISO8601( QCString(value.mid(i))).date()); i = (int)value.length(); } } } // out without errors. if (!(e.frequency() % 12) && e.repeatType() == PimEvent::MonthlyDate) { e.setRepeatType(PimEvent::Yearly); e.setFrequency(e.frequency() / 12); }}static PimEvent parseVObject( VObject *obj ){ PimEvent e; bool haveAlarm = FALSE; bool haveStart = FALSE; bool haveEnd = FALSE; QDateTime alarmTime; QDateTime startTime; PimEvent::SoundTypeChoice soundType = PimEvent::Silent; VObjectIterator it; initPropIterator( &it, obj ); QString summary, description, attach; // vCal properties, not Qtopias while( moreIteration( &it ) ) { VObject *o = nextVObject( &it ); QCString name = vObjectName( o ); // check this key/value for a CHARSET field. VObjectIterator tnit; initPropIterator( &tnit, o ); QTextCodec *tc = 0; while( moreIteration( &tnit ) ) { VObject *otc = nextVObject( &tnit ); if ( qstrcmp(vObjectName(otc), VCCharSetProp ) == 0) { tc = QTextCodec::codecForName(vObjectStringZValue(otc)); break; } } QString value; if (tc) value = tc->toUnicode( vObjectStringZValue( o ) ); else value = vObjectStringZValue( o ); // XXX We may need to modify this by timezone later if there // is a timezone. if you have a recieve event bug, check // this first. if ( name == VCDTstartProp ) { // check string-length. if no time, its an allday. if (value.length() == 8) e.setAllDay(TRUE); startTime = TimeConversion::fromISO8601( QCString(value) ); e.setStart( startTime ); haveStart = TRUE; } else if ( name == VCDTendProp ) { e.setEnd( TimeConversion::fromISO8601( QCString(value) ) ); haveEnd = TRUE; } // X-Qtopia-NOTES is for 1.5.0 compatibility else if ( name == "X-Qtopia-NOTES" || name == VCAttachProp) { attach = value; } else if ( name == VCSummaryProp ) { summary = value; } else if ( name == VCDescriptionProp ) { description = value; } else if ( name == VCLocationProp ) { e.setLocation( value ); } else if ( name == VCAAlarmProp || name == VCDAlarmProp ) { haveAlarm = TRUE; VObjectIterator nit; initPropIterator( &nit, o ); while( moreIteration( &nit ) ) { VObject *o = nextVObject( &nit ); QCString subname = vObjectName( o ); QCString subvalue = vObjectStringZValue( o ); if ( subname == VCRunTimeProp ) { alarmTime = TimeConversion::fromISO8601( subvalue ); } } if ( name == VCAAlarmProp ) soundType = PimEvent::Loud; } // We don't use VCTimeZoneProp as that has the form +05:30. // We are a bit better at timezones than this so we need the actual name // We _may_ want to use VCGeoLocationProp ( lang long ) else if ( name == "X-Qtopia-TIMEZONE") { e.setTimeZone( TimeZone(value) ); } else if ( name == VCRRuleProp) { parseRrule(e, value); } else if ( name == VCExpDateProp ) { QStringList list = QStringList::split(' ', value); for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { ((PrEvent&)e).addException(TimeConversion::fromISO8601(QCString(*it)).date()); } } else { qpe_setVObjectProperty(name,value,"Calendar",&e); // No tr } } // Find best mapping from (Summary,Description,Attach) to our (Description,Notes) // Similar code in task.cpp if ( !!summary && !!description && summary != description ) { e.setDescription( summary ); e.setNotes( description ); // all 3 - drop attach } else if ( !!summary ) { e.setDescription( summary ); e.setNotes( attach ); } else { e.setDescription( description ); e.setNotes( attach ); } if ( !haveStart && !haveEnd ) e.setStart( QDateTime::currentDateTime() ); if ( !haveEnd ) { QDateTime end = e.start(); end.setTime(QTime(32, 59, 59)); e.setEnd( end ); } if ( haveAlarm ) { int minutes = alarmTime.secsTo( startTime ) / 60; e.setAlarm( minutes, soundType ); } return e;}/*! Write the list of \a events as vCalendar objects to the file specified by \a filename. \sa readVCalendar()*/void PimEvent::writeVCalendar( const QString &filename, const QValueList<PimEvent> &events){ QFileDirect f( filename.utf8().data() ); if ( !f.open( IO_WriteOnly ) ) { qWarning("Unable to open vcard write"); return; } QValueList<PimEvent>::ConstIterator it; for( it = events.begin(); it != events.end(); ++it ) { VObject *obj = createVObject( *it ); writeVObject( f.directHandle() , obj ); cleanVObject( obj ); } cleanStrTbl();}/*! Write the \a event as a vCalendar to the file specified by \a filename. \sa readVCalendar()*/void PimEvent::writeVCalendar( const QString &filename, const PimEvent &event){ QFileDirect f( filename.utf8().data() ); if ( !f.open( IO_WriteOnly ) ) { qWarning("Unable to open vcard write"); return; } VObject *obj = createVObject( event ); writeVObject( f.directHandle() , obj ); cleanVObject( obj ); cleanStrTbl();}/*! Reads the file specified by \a filename as a list of vCalendar objects and returns the list of near equivalent events. \sa writeVCalendar()*/QValueList<PimEvent> PimEvent::readVCalendar( const QString &filename ){ VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); QValueList<PimEvent> events; qpe_startVObjectInput(); while ( obj ) { QCString name = vObjectName( obj ); if ( name == VCCalProp ) { VObjectIterator nit; initPropIterator( &nit, obj ); while( moreIteration( &nit ) ) { VObject *o = nextVObject( &nit ); QCString name = vObjectName( o ); if ( name == VCEventProp ) events.append( parseVObject( o ) ); } } else if ( name == VCEventProp ) { // shouldn't happen, but just to be sure events.append( parseVObject( obj ) ); } VObject *t = obj; obj = nextVObjectInList(obj); cleanVObject( t ); } qpe_endVObjectInput(); return events;}/*! returns the color associated with the event.*/QColor PimEvent::color() const{ return color(mType != NoRepeat);}/*! \internal*/QColor PimEvent::color(bool t){ if (t) return QColor(0,0,255); else return QColor(255,0,0);}/*! Returns the start time of the event in the current system timezone. \sa start()*/QDateTime PimEvent::startInCurrentTZ() const{ if (!timeZone().isValid()) return start(); // if no zone given.. assume local return timeZone().toCurrent(start());}/*! Returns the end time of the event in the current system timezone. \sa end()*/QDateTime PimEvent::endInCurrentTZ() const{ if (!timeZone().isValid()) return end(); QDateTime nStart = timeZone().toCurrent(start()); return end().addSecs(start().secsTo(nStart));}/*! Returns the date the event will repeat till in the current system timezone. \sa repeatTill()*/QDate PimEvent::repeatTillInCurrentTZ() const{ if (!timeZone().isValid()) return repeatTill(); // duration should be the same... shift the start.. dif to end. // if no zone given.. assume local QDateTime nStart = timeZone().toCurrent(start()); QDateTime rtDateTime = QDateTime(repeatTill(), QTime(0,0,0)); return rtDateTime.addSecs(start().secsTo(nStart)).date();}time_t asUTC(const QDateTime &dt, const TimeZone &z){ if (z.isValid()) return z.toTime_t(dt); else return TimeZone::utc().toTime_t(dt);}QDateTime asDateTime( time_t dt, const TimeZone &z){ if (z.isValid()) return z.fromTime_t(dt); else return TimeZone::utc().fromTime_t(dt);}/*! \internal*/time_t PimEvent::startAsUTC() const{ return asUTC(start(), timeZone());}/*! \internal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -