-rw-r--r-- | libkcal/vcalformat.cpp | 141 |
1 files changed, 74 insertions, 67 deletions
diff --git a/libkcal/vcalformat.cpp b/libkcal/vcalformat.cpp index a6ae1bc..df93209 100644 --- a/libkcal/vcalformat.cpp +++ b/libkcal/vcalformat.cpp | |||
@@ -41,77 +41,79 @@ | |||
41 | #include "calendar.h" | 41 | #include "calendar.h" |
42 | 42 | ||
43 | #include "vcalformat.h" | 43 | #include "vcalformat.h" |
44 | 44 | ||
45 | using namespace KCal; | 45 | using namespace KCal; |
46 | 46 | ||
47 | VCalFormat::VCalFormat() | 47 | VCalFormat::VCalFormat() |
48 | { | 48 | { |
49 | mCalendar = 0; | 49 | mCalendar = 0; |
50 | useLocalTime = false; | 50 | useLocalTime = false; |
51 | } | 51 | } |
52 | 52 | ||
53 | VCalFormat::~VCalFormat() | 53 | VCalFormat::~VCalFormat() |
54 | { | 54 | { |
55 | } | 55 | } |
56 | 56 | ||
57 | void VCalFormat::setLocalTime ( bool b ) | 57 | void VCalFormat::setLocalTime ( bool b ) |
58 | { | 58 | { |
59 | useLocalTime = b; | 59 | useLocalTime = b; |
60 | } | 60 | } |
61 | bool VCalFormat::load(Calendar *calendar, const QString &fileName) | 61 | bool VCalFormat::load(Calendar *calendar, const QString &fileName) |
62 | { | 62 | { |
63 | mCalendar = calendar; | 63 | mCalendar = calendar; |
64 | clearException(); | 64 | clearException(); |
65 | useLocalTime = mCalendar->isLocalTime(); | 65 | if ( ! useLocalTime ) |
66 | useLocalTime = mCalendar->isLocalTime(); | ||
66 | VObject *vcal = 0; | 67 | VObject *vcal = 0; |
67 | 68 | ||
68 | // this is not necessarily only 1 vcal. Could be many vcals, or include | 69 | // this is not necessarily only 1 vcal. Could be many vcals, or include |
69 | // a vcard... | 70 | // a vcard... |
70 | vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data())); | 71 | vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data())); |
71 | 72 | ||
72 | if (!vcal) { | 73 | if (!vcal) { |
73 | setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); | 74 | setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); |
74 | return FALSE; | 75 | return FALSE; |
75 | } | 76 | } |
76 | 77 | ||
77 | // any other top-level calendar stuff should be added/initialized here | 78 | // any other top-level calendar stuff should be added/initialized here |
78 | 79 | ||
79 | // put all vobjects into their proper places | 80 | // put all vobjects into their proper places |
80 | populate(vcal); | 81 | populate(vcal); |
81 | 82 | ||
82 | // clean up from vcal API stuff | 83 | // clean up from vcal API stuff |
83 | cleanVObjects(vcal); | 84 | cleanVObjects(vcal); |
84 | cleanStrTbl(); | 85 | cleanStrTbl(); |
85 | 86 | ||
86 | return true; | 87 | return true; |
87 | } | 88 | } |
88 | 89 | ||
89 | 90 | ||
90 | bool VCalFormat::save(Calendar *calendar, const QString &fileName) | 91 | bool VCalFormat::save(Calendar *calendar, const QString &fileName) |
91 | { | 92 | { |
92 | mCalendar = calendar; | 93 | mCalendar = calendar; |
93 | useLocalTime = mCalendar->isLocalTime(); | 94 | if ( ! useLocalTime ) |
95 | useLocalTime = mCalendar->isLocalTime(); | ||
94 | 96 | ||
95 | QString tmpStr; | 97 | QString tmpStr; |
96 | VObject *vcal, *vo; | 98 | VObject *vcal, *vo; |
97 | 99 | ||
98 | 100 | ||
99 | vcal = newVObject(VCCalProp); | 101 | vcal = newVObject(VCCalProp); |
100 | 102 | ||
101 | // addPropValue(vcal,VCLocationProp, "0.0"); | 103 | // addPropValue(vcal,VCLocationProp, "0.0"); |
102 | addPropValue(vcal,VCProdIdProp, productId()); | 104 | addPropValue(vcal,VCProdIdProp, productId()); |
103 | tmpStr = mCalendar->getTimeZoneStr(); | 105 | tmpStr = mCalendar->getTimeZoneStr(); |
104 | //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() ); | 106 | //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() ); |
105 | addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); | 107 | addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); |
106 | addPropValue(vcal,VCVersionProp, _VCAL_VERSION); | 108 | addPropValue(vcal,VCVersionProp, _VCAL_VERSION); |
107 | 109 | ||
108 | // TODO STUFF | 110 | // TODO STUFF |
109 | QPtrList<Todo> todoList = mCalendar->rawTodos(); | 111 | QPtrList<Todo> todoList = mCalendar->rawTodos(); |
110 | QPtrListIterator<Todo> qlt(todoList); | 112 | QPtrListIterator<Todo> qlt(todoList); |
111 | for (; qlt.current(); ++qlt) { | 113 | for (; qlt.current(); ++qlt) { |
112 | vo = eventToVTodo(qlt.current()); | 114 | vo = eventToVTodo(qlt.current()); |
113 | addVObjectProp(vcal, vo); | 115 | addVObjectProp(vcal, vo); |
114 | } | 116 | } |
115 | 117 | ||
116 | // EVENT STUFF | 118 | // EVENT STUFF |
117 | QPtrList<Event> events = mCalendar->rawEvents(); | 119 | QPtrList<Event> events = mCalendar->rawEvents(); |
@@ -1151,114 +1153,118 @@ Event* VCalFormat::VEventToEvent(VObject *vevent) | |||
1151 | int index2 = tmpStr.find(' ', index); | 1153 | int index2 = tmpStr.find(' ', index); |
1152 | tmpDay = tmpStr.mid(index, (index2-index)).toShort(); | 1154 | tmpDay = tmpStr.mid(index, (index2-index)).toShort(); |
1153 | index = index2-1; | 1155 | index = index2-1; |
1154 | if (tmpStr.mid(index, 1) == "-") | 1156 | if (tmpStr.mid(index, 1) == "-") |
1155 | tmpDay = 0 - tmpDay; | 1157 | tmpDay = 0 - tmpDay; |
1156 | index += 2; // advance the index; | 1158 | index += 2; // advance the index; |
1157 | anEvent->recurrence()->addMonthlyDay(tmpDay); | 1159 | anEvent->recurrence()->addMonthlyDay(tmpDay); |
1158 | } // while != # | 1160 | } // while != # |
1159 | } | 1161 | } |
1160 | index = last; if (tmpStr.mid(index,1) == "#") index++; | 1162 | index = last; if (tmpStr.mid(index,1) == "#") index++; |
1161 | if (tmpStr.find('T', index) != -1) { | 1163 | if (tmpStr.find('T', index) != -1) { |
1162 | QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); | 1164 | QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); |
1163 | anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate); | 1165 | anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate); |
1164 | } else { | 1166 | } else { |
1165 | int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); | 1167 | int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); |
1166 | if (rDuration == 0) | 1168 | if (rDuration == 0) |
1167 | anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1); | 1169 | anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1); |
1168 | else | 1170 | else |
1169 | anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration); | 1171 | anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration); |
1170 | } | 1172 | } |
1171 | } | 1173 | } |
1172 | 1174 | ||
1173 | /*********************** YEARLY-BY-MONTH *******************************/ | 1175 | /*********************** YEARLY-BY-MONTH *******************************/ |
1174 | else if (tmpStr.left(2) == "YM") { | 1176 | else if (tmpStr.left(2) == "YM") { |
1175 | int index = tmpStr.find(' '); | 1177 | // we have to set this such that recurrence accepts addYearlyNum(tmpDay); |
1176 | int last = tmpStr.findRev(' ') + 1; | 1178 | anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, 1, -1); |
1177 | int rFreq = tmpStr.mid(2, (index-1)).toInt(); | 1179 | int index = tmpStr.find(' '); |
1178 | index += 1; | 1180 | int last = tmpStr.findRev(' ') + 1; |
1179 | short tmpMonth; | 1181 | int rFreq = tmpStr.mid(2, (index-1)).toInt(); |
1180 | if( index == last ) { | 1182 | index += 1; |
1181 | // e.g. YM1 #0 | 1183 | short tmpMonth; |
1182 | tmpMonth = anEvent->dtStart().date().month(); | 1184 | if( index == last ) { |
1183 | anEvent->recurrence()->addYearlyNum(tmpMonth); | 1185 | // e.g. YM1 #0 |
1184 | } | 1186 | tmpMonth = anEvent->dtStart().date().month(); |
1185 | else { | 1187 | anEvent->recurrence()->addYearlyNum(tmpMonth); |
1186 | // e.g. YM1 3 #0 | 1188 | } |
1187 | while (index < last) { | 1189 | else { |
1188 | int index2 = tmpStr.find(' ', index); | 1190 | // e.g. YM1 3 #0 |
1189 | tmpMonth = tmpStr.mid(index, (index2-index)).toShort(); | 1191 | while (index < last) { |
1190 | index = index2+1; | 1192 | int index2 = tmpStr.find(' ', index); |
1191 | anEvent->recurrence()->addYearlyNum(tmpMonth); | 1193 | tmpMonth = tmpStr.mid(index, (index2-index)).toShort(); |
1192 | } // while != # | 1194 | index = index2+1; |
1193 | } | 1195 | anEvent->recurrence()->addYearlyNum(tmpMonth); |
1194 | index = last; if (tmpStr.mid(index,1) == "#") index++; | 1196 | } // while != # |
1195 | if (tmpStr.find('T', index) != -1) { | 1197 | } |
1196 | QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); | 1198 | index = last; if (tmpStr.mid(index,1) == "#") index++; |
1197 | anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate); | 1199 | if (tmpStr.find('T', index) != -1) { |
1198 | } else { | 1200 | QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); |
1199 | int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); | 1201 | anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate); |
1200 | if (rDuration == 0) | 1202 | } else { |
1201 | anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1); | 1203 | int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); |
1202 | else | 1204 | if (rDuration == 0) |
1203 | anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration); | 1205 | anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1); |
1204 | } | 1206 | else |
1207 | anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration); | ||
1208 | } | ||
1205 | } | 1209 | } |
1206 | 1210 | ||
1207 | /*********************** YEARLY-BY-DAY *********************************/ | 1211 | /*********************** YEARLY-BY-DAY *********************************/ |
1208 | else if (tmpStr.left(2) == "YD") { | 1212 | else if (tmpStr.left(2) == "YD") { |
1209 | int index = tmpStr.find(' '); | 1213 | // we have to set this such that recurrence accepts addYearlyNum(tmpDay); |
1210 | int last = tmpStr.findRev(' ') + 1; | 1214 | anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, 1, -1); |
1211 | int rFreq = tmpStr.mid(2, (index-1)).toInt(); | 1215 | int index = tmpStr.find(' '); |
1212 | index += 1; | 1216 | int last = tmpStr.findRev(' ') + 1; |
1213 | short tmpDay; | 1217 | int rFreq = tmpStr.mid(2, (index-1)).toInt(); |
1214 | if( index == last ) { | 1218 | index += 1; |
1215 | // e.g. YD1 #0 | 1219 | short tmpDay; |
1216 | tmpDay = anEvent->dtStart().date().dayOfYear(); | 1220 | if( index == last ) { |
1217 | anEvent->recurrence()->addYearlyNum(tmpDay); | 1221 | // e.g. YD1 #0 |
1218 | } | 1222 | tmpDay = anEvent->dtStart().date().dayOfYear(); |
1219 | else { | 1223 | anEvent->recurrence()->addYearlyNum(tmpDay); |
1220 | // e.g. YD1 123 #0 | 1224 | } |
1221 | while (index < last) { | 1225 | else { |
1222 | int index2 = tmpStr.find(' ', index); | 1226 | // e.g. YD1 123 #0 |
1223 | tmpDay = tmpStr.mid(index, (index2-index)).toShort(); | 1227 | while (index < last) { |
1224 | index = index2+1; | 1228 | int index2 = tmpStr.find(' ', index); |
1225 | anEvent->recurrence()->addYearlyNum(tmpDay); | 1229 | tmpDay = tmpStr.mid(index, (index2-index)).toShort(); |
1226 | } // while != # | 1230 | index = index2+1; |
1227 | } | 1231 | anEvent->recurrence()->addYearlyNum(tmpDay); |
1228 | index = last; if (tmpStr.mid(index,1) == "#") index++; | 1232 | } // while != # |
1229 | if (tmpStr.find('T', index) != -1) { | 1233 | } |
1230 | QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); | 1234 | index = last; if (tmpStr.mid(index,1) == "#") index++; |
1231 | anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate); | 1235 | if (tmpStr.find('T', index) != -1) { |
1232 | } else { | 1236 | QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); |
1233 | int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); | 1237 | anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate); |
1234 | if (rDuration == 0) | 1238 | } else { |
1235 | anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1); | 1239 | int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); |
1236 | else | 1240 | if (rDuration == 0) |
1237 | anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration); | 1241 | anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1); |
1238 | } | 1242 | else |
1243 | anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration); | ||
1244 | } | ||
1239 | } else { | 1245 | } else { |
1240 | kdDebug(5800) << "we don't understand this type of recurrence!" << endl; | 1246 | kdDebug(5800) << "we don't understand this type of recurrence!" << endl; |
1241 | } // if | 1247 | } // if |
1242 | } // repeats | 1248 | } // repeats |
1243 | 1249 | ||
1244 | 1250 | ||
1245 | // recurrence exceptions | 1251 | // recurrence exceptions |
1246 | if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) { | 1252 | if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) { |
1247 | s = fakeCString(vObjectUStringZValue(vo)); | 1253 | s = fakeCString(vObjectUStringZValue(vo)); |
1248 | QStringList exDates = QStringList::split(",",s); | 1254 | QStringList exDates = QStringList::split(",",s); |
1249 | QStringList::ConstIterator it; | 1255 | QStringList::ConstIterator it; |
1250 | for(it = exDates.begin(); it != exDates.end(); ++it ) { | 1256 | for(it = exDates.begin(); it != exDates.end(); ++it ) { |
1251 | anEvent->addExDate(ISOToQDate(*it)); | 1257 | anEvent->addExDate(ISOToQDate(*it)); |
1252 | } | 1258 | } |
1253 | deleteStr(s); | 1259 | deleteStr(s); |
1254 | } | 1260 | } |
1255 | 1261 | ||
1256 | // summary | 1262 | // summary |
1257 | if ((vo = isAPropertyOf(vevent, VCSummaryProp))) { | 1263 | if ((vo = isAPropertyOf(vevent, VCSummaryProp))) { |
1258 | s = fakeCString(vObjectUStringZValue(vo)); | 1264 | s = fakeCString(vObjectUStringZValue(vo)); |
1259 | anEvent->setSummary(QString::fromLocal8Bit(s)); | 1265 | anEvent->setSummary(QString::fromLocal8Bit(s)); |
1260 | deleteStr(s); | 1266 | deleteStr(s); |
1261 | } | 1267 | } |
1262 | if ((vo = isAPropertyOf(vevent, VCLocationProp))) { | 1268 | if ((vo = isAPropertyOf(vevent, VCLocationProp))) { |
1263 | s = fakeCString(vObjectUStringZValue(vo)); | 1269 | s = fakeCString(vObjectUStringZValue(vo)); |
1264 | anEvent->setLocation(QString::fromLocal8Bit(s)); | 1270 | anEvent->setLocation(QString::fromLocal8Bit(s)); |
@@ -1515,54 +1521,55 @@ void VCalFormat::populate(VObject *vcal) | |||
1515 | delete methodType; | 1521 | delete methodType; |
1516 | } | 1522 | } |
1517 | 1523 | ||
1518 | // warn the user that we might have trouble reading non-known calendar. | 1524 | // warn the user that we might have trouble reading non-known calendar. |
1519 | if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) { | 1525 | if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) { |
1520 | char *s = fakeCString(vObjectUStringZValue(curVO)); | 1526 | char *s = fakeCString(vObjectUStringZValue(curVO)); |
1521 | if (strcmp(productId().local8Bit(), s) != 0) | 1527 | if (strcmp(productId().local8Bit(), s) != 0) |
1522 | kdDebug() << "This vCalendar file was not created by KOrganizer " | 1528 | kdDebug() << "This vCalendar file was not created by KOrganizer " |
1523 | "or any other product we support. Loading anyway..." << endl; | 1529 | "or any other product we support. Loading anyway..." << endl; |
1524 | mLoadedProductId = s; | 1530 | mLoadedProductId = s; |
1525 | deleteStr(s); | 1531 | deleteStr(s); |
1526 | } | 1532 | } |
1527 | 1533 | ||
1528 | // warn the user we might have trouble reading this unknown version. | 1534 | // warn the user we might have trouble reading this unknown version. |
1529 | if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { | 1535 | if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { |
1530 | char *s = fakeCString(vObjectUStringZValue(curVO)); | 1536 | char *s = fakeCString(vObjectUStringZValue(curVO)); |
1531 | if (strcmp(_VCAL_VERSION, s) != 0) | 1537 | if (strcmp(_VCAL_VERSION, s) != 0) |
1532 | kdDebug() << "This vCalendar file has version " << s | 1538 | kdDebug() << "This vCalendar file has version " << s |
1533 | << "We only support " << _VCAL_VERSION << endl; | 1539 | << "We only support " << _VCAL_VERSION << endl; |
1534 | deleteStr(s); | 1540 | deleteStr(s); |
1535 | } | 1541 | } |
1536 | 1542 | ||
1537 | // set the time zone | 1543 | // set the time zone |
1538 | if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { | 1544 | if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { |
1539 | char *s = fakeCString(vObjectUStringZValue(curVO)); | 1545 | if ( vObjectUStringZValue(curVO) != 0 ) { |
1540 | mCalendar->setTimeZone(s); | 1546 | char *s = fakeCString(vObjectUStringZValue(curVO)); |
1541 | deleteStr(s); | 1547 | mCalendar->setTimeZone(s); |
1548 | deleteStr(s); | ||
1549 | } | ||
1542 | } | 1550 | } |
1543 | 1551 | ||
1544 | |||
1545 | // Store all events with a relatedTo property in a list for post-processing | 1552 | // Store all events with a relatedTo property in a list for post-processing |
1546 | mEventsRelate.clear(); | 1553 | mEventsRelate.clear(); |
1547 | mTodosRelate.clear(); | 1554 | mTodosRelate.clear(); |
1548 | 1555 | ||
1549 | initPropIterator(&i, vcal); | 1556 | initPropIterator(&i, vcal); |
1550 | 1557 | ||
1551 | // go through all the vobjects in the vcal | 1558 | // go through all the vobjects in the vcal |
1552 | while (moreIteration(&i)) { | 1559 | while (moreIteration(&i)) { |
1553 | curVO = nextVObject(&i); | 1560 | curVO = nextVObject(&i); |
1554 | 1561 | ||
1555 | /************************************************************************/ | 1562 | /************************************************************************/ |
1556 | 1563 | ||
1557 | // now, check to see that the object is an event or todo. | 1564 | // now, check to see that the object is an event or todo. |
1558 | if (strcmp(vObjectName(curVO), VCEventProp) == 0) { | 1565 | if (strcmp(vObjectName(curVO), VCEventProp) == 0) { |
1559 | 1566 | ||
1560 | if ((curVOProp = isAPropertyOf(curVO, XPilotStatusProp)) != 0) { | 1567 | if ((curVOProp = isAPropertyOf(curVO, XPilotStatusProp)) != 0) { |
1561 | char *s; | 1568 | char *s; |
1562 | s = fakeCString(vObjectUStringZValue(curVOProp)); | 1569 | s = fakeCString(vObjectUStringZValue(curVOProp)); |
1563 | // check to see if event was deleted by the kpilot conduit | 1570 | // check to see if event was deleted by the kpilot conduit |
1564 | if (atoi(s) == Event::SYNCDEL) { | 1571 | if (atoi(s) == Event::SYNCDEL) { |
1565 | deleteStr(s); | 1572 | deleteStr(s); |
1566 | kdDebug(5800) << "skipping pilot-deleted event" << endl; | 1573 | kdDebug(5800) << "skipping pilot-deleted event" << endl; |
1567 | goto SKIP; | 1574 | goto SKIP; |
1568 | } | 1575 | } |