alarmcalendar.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kalarm.h"
00022 #include <unistd.h>
00023 #include <time.h>
00024
00025 #include <qfile.h>
00026 #include <qtextstream.h>
00027
00028 #include <kmessagebox.h>
00029 #include <klocale.h>
00030 #include <kstandarddirs.h>
00031 #include <kconfig.h>
00032 #include <kaboutdata.h>
00033 #include <kio/netaccess.h>
00034 #include <kfileitem.h>
00035 #include <ktempfile.h>
00036 #include <dcopclient.h>
00037 #include <kdebug.h>
00038
00039 extern "C" {
00040 #include <libical/ical.h>
00041 }
00042
00043 #include <libkcal/vcaldrag.h>
00044 #include <libkcal/vcalformat.h>
00045 #include <libkcal/icalformat.h>
00046
00047 #include "kalarmapp.h"
00048 #include "alarmcalendar.h"
00049
00050 const QString DEFAULT_CALENDAR_FILE(QString::fromLatin1("calendar.ics"));
00051
00052
00053
00054
00055
00056
00057 void AlarmCalendar::getURL() const
00058 {
00059 if (!mUrl.isValid())
00060 {
00061 KConfig* config = kapp->config();
00062 config->setGroup(QString::fromLatin1("General"));
00063 *const_cast<KURL*>(&mUrl) = config->readEntry(QString::fromLatin1("Calendar"),
00064 locateLocal("appdata", DEFAULT_CALENDAR_FILE));
00065 if (!mUrl.isValid())
00066 {
00067 kdDebug(5950) << "AlarmCalendar::getURL(): invalid name: " << mUrl.prettyURL() << endl;
00068 KMessageBox::error(0L, i18n("Invalid calendar file name: %1").arg(mUrl.prettyURL()),
00069 kapp->aboutData()->programName());
00070 kapp->exit(1);
00071 }
00072 }
00073 }
00074
00075
00076
00077
00078 bool AlarmCalendar::open()
00079 {
00080 getURL();
00081 mCalendar = new CalendarLocal();
00082 mCalendar->setLocalTime();
00083
00084
00085 QString ext = mUrl.filename().right(4);
00086 mVCal = (ext == QString::fromLatin1(".vcs"));
00087
00088 if (!KIO::NetAccess::exists(mUrl))
00089 {
00090 if (!create())
00091 return false;
00092 }
00093
00094
00095 switch (load())
00096 {
00097 case 1:
00098 break;
00099 case 0:
00100 if (!create() || load() <= 0)
00101 return false;
00102 case -1:
00103
00104
00105
00106
00107
00108 return false;
00109 }
00110 return true;
00111 }
00112
00113
00114
00115
00116 bool AlarmCalendar::create()
00117 {
00118
00119 KTempFile* tmpFile = 0L;
00120 QString filename;
00121 if (mUrl.isLocalFile())
00122 filename = mUrl.path();
00123 else
00124 {
00125 tmpFile = new KTempFile;
00126 filename = tmpFile->name();
00127 }
00128 if (!save(filename))
00129 {
00130 delete tmpFile;
00131 return false;
00132 }
00133 delete tmpFile;
00134 return true;
00135 }
00136
00137
00138
00139
00140
00141 int AlarmCalendar::load()
00142 {
00143 getURL();
00144 kdDebug(5950) << "AlarmCalendar::load(): " << mUrl.prettyURL() << endl;
00145 QString tmpFile;
00146 if (!KIO::NetAccess::download(mUrl, tmpFile))
00147 {
00148 kdError(5950) << "AlarmCalendar::load(): Load failure" << endl;
00149 KMessageBox::error(0L, i18n("Cannot open calendar:\n%1").arg(mUrl.prettyURL()), kapp->aboutData()->programName());
00150 return -1;
00151 }
00152 kdDebug(5950) << "AlarmCalendar::load(): --- Downloaded to " << tmpFile << endl;
00153 mKAlarmVersion = -1;
00154 mKAlarmVersion057_UTC = false;
00155 mCalendar->setTimeZoneId(QString::null);
00156 bool loaded = mCalendar->load(tmpFile);
00157 mCalendar->setLocalTime();
00158 if (!loaded)
00159 {
00160
00161 KIO::NetAccess::removeTempFile(tmpFile);
00162 KIO::UDSEntry uds;
00163 KIO::NetAccess::stat(mUrl, uds);
00164 KFileItem fi(uds, mUrl);
00165 if (!fi.size())
00166 return 0;
00167 kdDebug(5950) << "AlarmCalendar::load(): Error loading calendar file '" << tmpFile << "'" << endl;
00168 KMessageBox::error(0L, i18n("Error loading calendar:\n%1\n\nPlease fix or delete the file.").arg(mUrl.prettyURL()),
00169 kapp->aboutData()->programName());
00170 return -1;
00171 }
00172 if (!mLocalFile.isEmpty())
00173 KIO::NetAccess::removeTempFile(mLocalFile);
00174 mLocalFile = tmpFile;
00175
00176
00177
00178 getKAlarmVersion();
00179 if (mKAlarmVersion == KAlarmVersion(0,5,7))
00180 {
00181
00182
00183 mKAlarmVersion057_UTC = isUTC();
00184 kdDebug(5950) << "AlarmCalendar::load(): KAlarm version 0.5.7 (" << (mKAlarmVersion057_UTC ? "" : "non-") << "UTC)\n";
00185 }
00186 else
00187 kdDebug(5950) << "AlarmCalendar::load(): KAlarm version " << mKAlarmVersion << endl;
00188 KAlarmEvent::convertKCalEvents();
00189 return 1;
00190 }
00191
00192
00193
00194
00195
00196 int AlarmCalendar::reload()
00197 {
00198 if (!mCalendar)
00199 return -2;
00200 kdDebug(5950) << "AlarmCalendar::reload(): " << mUrl.prettyURL() << endl;
00201 close();
00202 return load();
00203 }
00204
00205
00206
00207
00208 bool AlarmCalendar::save(const QString& filename)
00209 {
00210 kdDebug(5950) << "AlarmCalendar::save(): " << filename << endl;
00211 CalFormat* format;
00212 if(mVCal)
00213 format = new VCalFormat;
00214 else
00215 format = new ICalFormat;
00216 bool success = mCalendar->save(filename, format);
00217 if (!success)
00218 {
00219 kdDebug(5950) << "AlarmCalendar::save(): calendar save failed." << endl;
00220 return false;
00221 }
00222
00223 getURL();
00224 if (!mUrl.isLocalFile())
00225 {
00226 if (!KIO::NetAccess::upload(filename, mUrl))
00227 {
00228 KMessageBox::error(0L, i18n("Cannot upload calendar to\n'%1'").arg(mUrl.prettyURL()), kapp->aboutData()->programName());
00229 return false;
00230 }
00231 }
00232
00233
00234 QByteArray data;
00235 QDataStream arg(data, IO_WriteOnly);
00236 arg << QCString(kapp->aboutData()->appName()) << mUrl.url();
00237 if (!kapp->dcopClient()->send(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT, "reloadMsgCal(QCString,QString)", data))
00238 kdDebug(5950) << "AlarmCalendar::save(): addCal dcop send failed" << endl;
00239 return true;
00240 }
00241
00242
00243
00244
00245 void AlarmCalendar::close()
00246 {
00247 if (!mLocalFile.isEmpty())
00248 KIO::NetAccess::removeTempFile(mLocalFile);
00249 if (mCalendar)
00250 mCalendar->close();
00251 }
00252
00253
00254
00255
00256 void AlarmCalendar::addEvent(const KAlarmEvent& event)
00257 {
00258 Event* kcalEvent = new Event;
00259 event.updateEvent(*kcalEvent);
00260 mCalendar->addEvent(kcalEvent);
00261 const_cast<KAlarmEvent&>(event).setEventID(kcalEvent->uid());
00262 }
00263
00264
00265
00266
00267
00268 void AlarmCalendar::updateEvent(const KAlarmEvent& evnt)
00269 {
00270 Event* kcalEvent = event(evnt.id());
00271 if (kcalEvent)
00272 evnt.updateEvent(*kcalEvent);
00273 }
00274
00275
00276
00277
00278 void AlarmCalendar::deleteEvent(const QString& eventID)
00279 {
00280 Event* kcalEvent = event(eventID);
00281 if (kcalEvent)
00282 mCalendar->deleteEvent(kcalEvent);
00283 }
00284
00285
00286
00287
00288
00289 void AlarmCalendar::getKAlarmVersion() const
00290 {
00291
00292
00293 mKAlarmVersion = 0;
00294 if (mCalendar)
00295 {
00296 const QString& prodid = mCalendar->loadedProductId();
00297 QString progname = QString(" ") + theApp()->aboutData()->programName() + " ";
00298 int i = prodid.find(progname, 0, false);
00299 if (i >= 0)
00300 {
00301 QString ver = prodid.mid(i + progname.length()).stripWhiteSpace();
00302 i = ver.find('/');
00303 int j = ver.find(' ');
00304 if (j >= 0 && j < i)
00305 i = j;
00306 if (i > 0)
00307 {
00308 ver = ver.left(i);
00309
00310 if ((i = ver.find('.')) > 0)
00311 {
00312 bool ok;
00313 int version = ver.left(i).toInt(&ok) * 10000;
00314 if (ok)
00315 {
00316 ver = ver.mid(i + 1);
00317 if ((i = ver.find('.')) > 0)
00318 {
00319 int v = ver.left(i).toInt(&ok);
00320 if (ok)
00321 {
00322 version += (v < 9 ? v : 9) * 100;
00323 ver = ver.mid(i + 1);
00324 if (ver.at(0).isDigit())
00325 {
00326
00327 v = ver.toInt();
00328 mKAlarmVersion = version + (v < 9 ? v : 9);
00329 }
00330 }
00331 }
00332 else
00333 {
00334
00335 if (ver.at(0).isDigit())
00336 {
00337
00338 int v = ver.toInt();
00339 mKAlarmVersion = version + (v < 9 ? v : 9) * 100;
00340 }
00341 }
00342 }
00343 }
00344 }
00345 }
00346 }
00347 }
00348
00349
00350
00351
00352
00353
00354
00355 bool AlarmCalendar::isUTC() const
00356 {
00357
00358 QFile file(mLocalFile);
00359 if (!file.open(IO_ReadOnly))
00360 return false;
00361 QTextStream ts(&file);
00362 ts.setEncoding(QTextStream::UnicodeUTF8);
00363 QString text = ts.read();
00364 file.close();
00365
00366
00367 bool result = false;
00368 icalcomponent* calendar = icalcomponent_new_from_string(text.local8Bit().data());
00369 if (calendar)
00370 {
00371 if (icalcomponent_isa(calendar) == ICAL_VCALENDAR_COMPONENT)
00372 {
00373 icalcomponent* c = icalcomponent_get_first_component(calendar, ICAL_VEVENT_COMPONENT);
00374 if (c)
00375 {
00376 icalproperty* p = icalcomponent_get_first_property(c, ICAL_CREATED_PROPERTY);
00377 if (p)
00378 {
00379 struct icaltimetype datetime = icalproperty_get_created(p);
00380 if (datetime.is_utc)
00381 result = true;
00382 }
00383 }
00384 }
00385 icalcomponent_free(calendar);
00386 }
00387 return result;
00388 }
This file is part of the documentation for kdelibs Version 3.1.4.