-rw-r--r-- | Makefile | 16 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmcal.c | 85 | ||||
-rw-r--r-- | kdepim-desktop.pro | 6 | ||||
-rw-r--r-- | kopi-desktop.pro | 6 | ||||
-rw-r--r-- | korganizer/calendarview.cpp | 2 | ||||
-rw-r--r-- | korganizer/korganizer.pro | 1 | ||||
-rw-r--r-- | libkcal/incidence.cpp | 5 | ||||
-rw-r--r-- | libkcal/incidence.h | 2 | ||||
-rw-r--r-- | libkcal/phoneformat.cpp | 1464 | ||||
-rw-r--r-- | libkcal/phoneformat.h | 14 | ||||
-rw-r--r-- | libkcal/vcalformat.cpp | 5 | ||||
-rw-r--r-- | libkcal/vcalformat.h | 5 |
12 files changed, 259 insertions, 1352 deletions
@@ -1,157 +1,169 @@ ############################################################################# # Makefile for building: kopi-desktop -# Generated by qmake (1.07a) (Qt 3.3.1) on: Sun Aug 29 13:39:55 2004 +# Generated by qmake (1.07a) (Qt 3.3.1) on: Sun Aug 29 18:50:00 2004 # Project: kopi-desktop.pro # Template: subdirs # Command: $(QMAKE) -o Makefile kopi-desktop.pro ############################################################################# MAKEFILE = Makefile QMAKE = qmake DEL_FILE = rm -f CHK_DIR_EXISTS= test -d MKDIR = mkdir -p SUBTARGETS = \ sub-gammu-emb-common \ + sub-gammu-emb-gammu \ sub-libical \ sub-libkcal \ sub-microkde \ sub-libkdepim \ sub-kabc \ sub-korganizer \ sub-kaddressbook \ sub-kabc-plugins-file \ sub-kabc-plugins-dir first: all all: Makefile $(SUBTARGETS) gammu/emb/common/$(MAKEFILE): @$(CHK_DIR_EXISTS) "gammu/emb/common" || $(MKDIR) "gammu/emb/common" cd gammu/emb/common && $(QMAKE) common.pro -o $(MAKEFILE) sub-gammu-emb-common: gammu/emb/common/$(MAKEFILE) FORCE cd gammu/emb/common && $(MAKE) -f $(MAKEFILE) +gammu/emb/gammu/$(MAKEFILE): + @$(CHK_DIR_EXISTS) "gammu/emb/gammu" || $(MKDIR) "gammu/emb/gammu" + cd gammu/emb/gammu && $(QMAKE) gammu.pro -o $(MAKEFILE) +sub-gammu-emb-gammu: gammu/emb/gammu/$(MAKEFILE) FORCE + cd gammu/emb/gammu && $(MAKE) -f $(MAKEFILE) + libical/$(MAKEFILE): @$(CHK_DIR_EXISTS) "libical" || $(MKDIR) "libical" cd libical && $(QMAKE) libical.pro -o $(MAKEFILE) sub-libical: libical/$(MAKEFILE) FORCE cd libical && $(MAKE) -f $(MAKEFILE) libkcal/$(MAKEFILE): @$(CHK_DIR_EXISTS) "libkcal" || $(MKDIR) "libkcal" cd libkcal && $(QMAKE) libkcal.pro -o $(MAKEFILE) sub-libkcal: libkcal/$(MAKEFILE) FORCE cd libkcal && $(MAKE) -f $(MAKEFILE) microkde/$(MAKEFILE): @$(CHK_DIR_EXISTS) "microkde" || $(MKDIR) "microkde" cd microkde && $(QMAKE) microkde.pro -o $(MAKEFILE) sub-microkde: microkde/$(MAKEFILE) FORCE cd microkde && $(MAKE) -f $(MAKEFILE) libkdepim/$(MAKEFILE): @$(CHK_DIR_EXISTS) "libkdepim" || $(MKDIR) "libkdepim" cd libkdepim && $(QMAKE) libkdepim.pro -o $(MAKEFILE) sub-libkdepim: libkdepim/$(MAKEFILE) FORCE cd libkdepim && $(MAKE) -f $(MAKEFILE) kabc/$(MAKEFILE): @$(CHK_DIR_EXISTS) "kabc" || $(MKDIR) "kabc" cd kabc && $(QMAKE) kabc.pro -o $(MAKEFILE) sub-kabc: kabc/$(MAKEFILE) FORCE cd kabc && $(MAKE) -f $(MAKEFILE) korganizer/$(MAKEFILE): @$(CHK_DIR_EXISTS) "korganizer" || $(MKDIR) "korganizer" cd korganizer && $(QMAKE) korganizer.pro -o $(MAKEFILE) sub-korganizer: korganizer/$(MAKEFILE) FORCE cd korganizer && $(MAKE) -f $(MAKEFILE) kaddressbook/$(MAKEFILE): @$(CHK_DIR_EXISTS) "kaddressbook" || $(MKDIR) "kaddressbook" cd kaddressbook && $(QMAKE) kaddressbook.pro -o $(MAKEFILE) sub-kaddressbook: kaddressbook/$(MAKEFILE) FORCE cd kaddressbook && $(MAKE) -f $(MAKEFILE) kabc/plugins/file/$(MAKEFILE): @$(CHK_DIR_EXISTS) "kabc/plugins/file" || $(MKDIR) "kabc/plugins/file" cd kabc/plugins/file && $(QMAKE) file.pro -o $(MAKEFILE) sub-kabc-plugins-file: kabc/plugins/file/$(MAKEFILE) FORCE cd kabc/plugins/file && $(MAKE) -f $(MAKEFILE) kabc/plugins/dir/$(MAKEFILE): @$(CHK_DIR_EXISTS) "kabc/plugins/dir" || $(MKDIR) "kabc/plugins/dir" cd kabc/plugins/dir && $(QMAKE) dir.pro -o $(MAKEFILE) sub-kabc-plugins-dir: kabc/plugins/dir/$(MAKEFILE) FORCE cd kabc/plugins/dir && $(MAKE) -f $(MAKEFILE) Makefile: kopi-desktop.pro /usr/lib/qt3/mkspecs/default/qmake.conf $(QMAKE) -o Makefile kopi-desktop.pro qmake: qmake_all @$(QMAKE) -o Makefile kopi-desktop.pro all: $(SUBTARGETS) -qmake_all: gammu/emb/common/$(MAKEFILE) libical/$(MAKEFILE) libkcal/$(MAKEFILE) microkde/$(MAKEFILE) libkdepim/$(MAKEFILE) kabc/$(MAKEFILE) korganizer/$(MAKEFILE) kaddressbook/$(MAKEFILE) kabc/plugins/file/$(MAKEFILE) kabc/plugins/dir/$(MAKEFILE) +qmake_all: gammu/emb/common/$(MAKEFILE) gammu/emb/gammu/$(MAKEFILE) libical/$(MAKEFILE) libkcal/$(MAKEFILE) microkde/$(MAKEFILE) libkdepim/$(MAKEFILE) kabc/$(MAKEFILE) korganizer/$(MAKEFILE) kaddressbook/$(MAKEFILE) kabc/plugins/file/$(MAKEFILE) kabc/plugins/dir/$(MAKEFILE) ( [ -d gammu/emb/common ] && cd gammu/emb/common ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true + ( [ -d gammu/emb/gammu ] && cd gammu/emb/gammu ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true ( [ -d libical ] && cd libical ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true ( [ -d libkcal ] && cd libkcal ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true ( [ -d microkde ] && cd microkde ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true ( [ -d libkdepim ] && cd libkdepim ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true ( [ -d kabc ] && cd kabc ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true ( [ -d korganizer ] && cd korganizer ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true ( [ -d kaddressbook ] && cd kaddressbook ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true ( [ -d kabc/plugins/file ] && cd kabc/plugins/file ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true ( [ -d kabc/plugins/dir ] && cd kabc/plugins/dir ; grep "^qmake_all:" $(MAKEFILE) && $(MAKE) -f $(MAKEFILE) qmake_all; ) || true clean uicables mocables uiclean mocclean lexclean yaccclean : qmake_all FORCE ( [ -d gammu/emb/common ] && cd gammu/emb/common ; $(MAKE) -f $(MAKEFILE) $@; ) || true + ( [ -d gammu/emb/gammu ] && cd gammu/emb/gammu ; $(MAKE) -f $(MAKEFILE) $@; ) || true ( [ -d libical ] && cd libical ; $(MAKE) -f $(MAKEFILE) $@; ) || true ( [ -d libkcal ] && cd libkcal ; $(MAKE) -f $(MAKEFILE) $@; ) || true ( [ -d microkde ] && cd microkde ; $(MAKE) -f $(MAKEFILE) $@; ) || true ( [ -d libkdepim ] && cd libkdepim ; $(MAKE) -f $(MAKEFILE) $@; ) || true ( [ -d kabc ] && cd kabc ; $(MAKE) -f $(MAKEFILE) $@; ) || true ( [ -d korganizer ] && cd korganizer ; $(MAKE) -f $(MAKEFILE) $@; ) || true ( [ -d kaddressbook ] && cd kaddressbook ; $(MAKE) -f $(MAKEFILE) $@; ) || true ( [ -d kabc/plugins/file ] && cd kabc/plugins/file ; $(MAKE) -f $(MAKEFILE) $@; ) || true ( [ -d kabc/plugins/dir ] && cd kabc/plugins/dir ; $(MAKE) -f $(MAKEFILE) $@; ) || true uninstall_subdirs: qmake_all FORCE ( [ -d gammu/emb/common ] && cd gammu/emb/common ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true + ( [ -d gammu/emb/gammu ] && cd gammu/emb/gammu ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true ( [ -d libical ] && cd libical ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true ( [ -d libkcal ] && cd libkcal ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true ( [ -d microkde ] && cd microkde ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true ( [ -d libkdepim ] && cd libkdepim ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true ( [ -d kabc ] && cd kabc ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true ( [ -d korganizer ] && cd korganizer ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true ( [ -d kaddressbook ] && cd kaddressbook ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true ( [ -d kabc/plugins/file ] && cd kabc/plugins/file ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true ( [ -d kabc/plugins/dir ] && cd kabc/plugins/dir ; $(MAKE) -f $(MAKEFILE) uninstall; ) || true install_subdirs: qmake_all FORCE ( [ -d gammu/emb/common ] && cd gammu/emb/common ; $(MAKE) -f $(MAKEFILE) install; ) || true + ( [ -d gammu/emb/gammu ] && cd gammu/emb/gammu ; $(MAKE) -f $(MAKEFILE) install; ) || true ( [ -d libical ] && cd libical ; $(MAKE) -f $(MAKEFILE) install; ) || true ( [ -d libkcal ] && cd libkcal ; $(MAKE) -f $(MAKEFILE) install; ) || true ( [ -d microkde ] && cd microkde ; $(MAKE) -f $(MAKEFILE) install; ) || true ( [ -d libkdepim ] && cd libkdepim ; $(MAKE) -f $(MAKEFILE) install; ) || true ( [ -d kabc ] && cd kabc ; $(MAKE) -f $(MAKEFILE) install; ) || true ( [ -d korganizer ] && cd korganizer ; $(MAKE) -f $(MAKEFILE) install; ) || true ( [ -d kaddressbook ] && cd kaddressbook ; $(MAKE) -f $(MAKEFILE) install; ) || true ( [ -d kabc/plugins/file ] && cd kabc/plugins/file ; $(MAKE) -f $(MAKEFILE) install; ) || true ( [ -d kabc/plugins/dir ] && cd kabc/plugins/dir ; $(MAKE) -f $(MAKEFILE) install; ) || true distclean: qmake_all FORCE ( [ -d gammu/emb/common ] && cd gammu/emb/common ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true + ( [ -d gammu/emb/gammu ] && cd gammu/emb/gammu ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true ( [ -d libical ] && cd libical ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true ( [ -d libkcal ] && cd libkcal ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true ( [ -d microkde ] && cd microkde ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true ( [ -d libkdepim ] && cd libkdepim ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true ( [ -d kabc ] && cd kabc ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true ( [ -d korganizer ] && cd korganizer ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true ( [ -d kaddressbook ] && cd kaddressbook ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true ( [ -d kabc/plugins/file ] && cd kabc/plugins/file ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true ( [ -d kabc/plugins/dir ] && cd kabc/plugins/dir ; $(MAKE) -f $(MAKEFILE) $@; $(DEL_FILE) $(MAKEFILE); ) || true install: install_subdirs uninstall: uninstall_subdirs FORCE: diff --git a/gammu/emb/common/service/gsmcal.c b/gammu/emb/common/service/gsmcal.c index 950e35e..598292c 100644 --- a/gammu/emb/common/service/gsmcal.c +++ b/gammu/emb/common/service/gsmcal.c @@ -1,509 +1,512 @@ /* (c) 2002-2003 by Marcin Wiacek */ #include <string.h> #include "gsmcal.h" #include "gsmmisc.h" #include "../misc/coding/coding.h" bool IsCalendarNoteFromThePast(GSM_CalendarEntry *note) { bool Past = true; int i; GSM_DateTime DT; GSM_GetCurrentDateTime (&DT); for (i = 0; i < note->EntriesNum; i++) { switch (note->Entries[i].EntryType) { case CAL_RECURRANCE: Past = false; break; case CAL_START_DATETIME : if (note->Entries[i].Date.Year > DT.Year) Past = false; if (note->Entries[i].Date.Year == DT.Year && note->Entries[i].Date.Month > DT.Month) Past = false; if (note->Entries[i].Date.Year == DT.Year && note->Entries[i].Date.Month == DT.Month && note->Entries[i].Date.Day > DT.Day) Past = false; break; default: break; } if (!Past) break; } switch (note->Type) { case GSM_CAL_BIRTHDAY: Past = false; break; default: break; } return Past; } void GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(GSM_CalendarEntry *entry, int *Text, int *Time, int *Alarm, int *Phone, int *Recurrance, int *EndTime, int *Location) { int i; *Text = -1; *Time = -1; *Alarm = -1; *Phone = -1; *Recurrance = -1; *EndTime = -1; *Location = -1; for (i = 0; i < entry->EntriesNum; i++) { switch (entry->Entries[i].EntryType) { case CAL_START_DATETIME : if (*Time == -1) *Time = i; break; case CAL_END_DATETIME : if (*EndTime == -1) *EndTime = i; break; case CAL_ALARM_DATETIME : case CAL_SILENT_ALARM_DATETIME: if (*Alarm == -1) *Alarm = i; break; case CAL_RECURRANCE: if (*Recurrance == -1) *Recurrance = i; break; case CAL_TEXT: if (*Text == -1) *Text = i; break; case CAL_PHONE: if (*Phone == -1) *Phone = i; break; case CAL_LOCATION: if (*Location == -1) *Location = i; break; default: break; } } } GSM_Error GSM_EncodeVCALENDAR(char *Buffer, int *Length, GSM_CalendarEntry *note, bool header, GSM_VCalendarVersion Version) { int Text, Time, Alarm, Phone, Recurrance, EndTime, Location; char buffer[2000]; GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location); if (header) { *Length+=sprintf(Buffer, "BEGIN:VCALENDAR%c%c",13,10); *Length+=sprintf(Buffer+(*Length), "VERSION:1.0%c%c",13,10); } *Length+=sprintf(Buffer+(*Length), "BEGIN:VEVENT%c%c",13,10); if (Version == Nokia_VCalendar) { *Length+=sprintf(Buffer+(*Length), "CATEGORIES:"); switch (note->Type) { case GSM_CAL_REMINDER: - *Length+=sprintf(Buffer+(*Length), "REMINDER%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Reminder%c%c",13,10); break; case GSM_CAL_MEMO: - *Length+=sprintf(Buffer+(*Length), "MISCELLANEOUS%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Miscellaneous%c%c",13,10); break; case GSM_CAL_CALL: - *Length+=sprintf(Buffer+(*Length), "PHONE CALL%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Phone Call%c%c",13,10); break; case GSM_CAL_BIRTHDAY: - *Length+=sprintf(Buffer+(*Length), "SPECIAL OCCASION%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Special Occasion%c%c",13,10); break; case GSM_CAL_MEETING: default: - *Length+=sprintf(Buffer+(*Length), "MEETING%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "MeetingDEF%c%c",13,10); break; } if (note->Type == GSM_CAL_CALL) { buffer[0] = 0; buffer[1] = 0; if (Phone != -1) CopyUnicodeString(buffer,note->Entries[Phone].Text); if (Text != -1) { if (Phone != -1) EncodeUnicode(buffer+UnicodeLength(buffer)*2," ",1); CopyUnicodeString(buffer+UnicodeLength(buffer)*2,note->Entries[Text].Text); } SaveVCALText(Buffer, Length, buffer, "SUMMARY"); } else { SaveVCALText(Buffer, Length, note->Entries[Text].Text, "SUMMARY"); } if (note->Type == GSM_CAL_MEETING && Location != -1) { SaveVCALText(Buffer, Length, note->Entries[Location].Text, "LOCATION"); } if (Time == -1) return ERR_UNKNOWN; SaveVCALDateTime(Buffer, Length, ¬e->Entries[Time].Date, "DTSTART"); if (EndTime != -1) { SaveVCALDateTime(Buffer, Length, ¬e->Entries[EndTime].Date, "DTEND"); } if (Alarm != -1) { if (note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) { SaveVCALDateTime(Buffer, Length, ¬e->Entries[Alarm].Date, "DALARM"); } else { SaveVCALDateTime(Buffer, Length, ¬e->Entries[Alarm].Date, "AALARM"); } } /* Birthday is known to be recurranced */ if (Recurrance != -1 && note->Type != GSM_CAL_BIRTHDAY) { switch(note->Entries[Recurrance].Number/24) { case 1 : *Length+=sprintf(Buffer+(*Length), "RRULE:D1 #0%c%c",13,10); break; case 7 : *Length+=sprintf(Buffer+(*Length), "RRULE:W1 #0%c%c",13,10); break; case 14 : *Length+=sprintf(Buffer+(*Length), "RRULE:W2 #0%c%c",13,10); break; case 365 : *Length+=sprintf(Buffer+(*Length), "RRULE:YD1 #0%c%c",13,10); break; } } } else if (Version == Siemens_VCalendar) { *Length+=sprintf(Buffer+(*Length), "CATEGORIES:"); switch (note->Type) { case GSM_CAL_MEETING: - *Length+=sprintf(Buffer+(*Length), "MEETING%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Meeting%c%c",13,10); break; case GSM_CAL_CALL: - *Length+=sprintf(Buffer+(*Length), "PHONE CALL%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Phone Call%c%c",13,10); break; case GSM_CAL_BIRTHDAY: - *Length+=sprintf(Buffer+(*Length), "ANNIVERSARY%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Anniversary%c%c",13,10); break; case GSM_CAL_MEMO: default: - *Length+=sprintf(Buffer+(*Length), "MISCELLANEOUS%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Miscellaneous%c%c",13,10); break; } if (Time == -1) return ERR_UNKNOWN; SaveVCALDateTime(Buffer, Length, ¬e->Entries[Time].Date, "DTSTART"); if (Alarm != -1) { SaveVCALDateTime(Buffer, Length, ¬e->Entries[Alarm].Date, "DALARM"); } if (Recurrance != -1) { switch(note->Entries[Recurrance].Number/24) { case 1 : *Length+=sprintf(Buffer+(*Length), "RRULE:D1%c%c",13,10); break; case 7 : *Length+=sprintf(Buffer+(*Length), "RRULE:D7%c%c",13,10); break; case 30 : *Length+=sprintf(Buffer+(*Length), "RRULE:MD1%c%c",13,10); break; case 365 : *Length+=sprintf(Buffer+(*Length), "RRULE:YD1%c%c",13,10); break; } } if (note->Type == GSM_CAL_CALL) { buffer[0] = 0; buffer[1] = 0; if (Phone != -1) CopyUnicodeString(buffer,note->Entries[Phone].Text); if (Text != -1) { if (Phone != -1) EncodeUnicode(buffer+UnicodeLength(buffer)*2," ",1); CopyUnicodeString(buffer+UnicodeLength(buffer)*2,note->Entries[Text].Text); } SaveVCALText(Buffer, Length, buffer, "DESCRIPTION"); } else { SaveVCALText(Buffer, Length, note->Entries[Text].Text, "DESCRIPTION"); } } else if (Version == SonyEricsson_VCalendar) { *Length+=sprintf(Buffer+(*Length), "CATEGORIES:"); switch (note->Type) { case GSM_CAL_MEETING: - *Length+=sprintf(Buffer+(*Length), "MEETING%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Meeting%c%c",13,10); break; case GSM_CAL_REMINDER: - *Length+=sprintf(Buffer+(*Length), "DATE%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Date%c%c",13,10); break; case GSM_CAL_TRAVEL: - *Length+=sprintf(Buffer+(*Length), "TRAVEL%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Travel%c%c",13,10); break; case GSM_CAL_VACATION: - *Length+=sprintf(Buffer+(*Length), "VACATION%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Vacation%c%c",13,10); break; case GSM_CAL_BIRTHDAY: - *Length+=sprintf(Buffer+(*Length), "ANNIVERSARY%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Anninversary%c%c",13,10); break; case GSM_CAL_MEMO: default: - *Length+=sprintf(Buffer+(*Length), "MISCELLANEOUS%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "Miscellaneous%c%c",13,10); break; } if (Time == -1) return ERR_UNKNOWN; SaveVCALDateTime(Buffer, Length, ¬e->Entries[Time].Date, "DTSTART"); if (EndTime != -1) { SaveVCALDateTime(Buffer, Length, ¬e->Entries[EndTime].Date, "DTEND"); } if (Alarm != -1) { SaveVCALDateTime(Buffer, Length, ¬e->Entries[Alarm].Date, "AALARM"); } SaveVCALText(Buffer, Length, note->Entries[Text].Text, "SUMMARY"); if (Location != -1) { SaveVCALText(Buffer, Length, note->Entries[Location].Text, "LOCATION"); } } + *Length+=sprintf(Buffer+(*Length), "X-PILOTID:%d%c%c",note->Location,13,10); *Length+=sprintf(Buffer+(*Length), "END:VEVENT%c%c",13,10); if (header) *Length+=sprintf(Buffer+(*Length), "END:VCALENDAR%c%c",13,10); return ERR_NONE; } void GSM_ToDoFindDefaultTextTimeAlarmCompleted(GSM_ToDoEntry *entry, int *Text, int *Alarm, int *Completed, int *EndTime, int *Phone) { int i; *Text = -1; *EndTime = -1; *Alarm = -1; *Completed = -1; *Phone = -1; for (i = 0; i < entry->EntriesNum; i++) { switch (entry->Entries[i].EntryType) { case TODO_END_DATETIME : if (*EndTime == -1) *EndTime = i; break; case TODO_ALARM_DATETIME : case TODO_SILENT_ALARM_DATETIME: if (*Alarm == -1) *Alarm = i; break; case TODO_TEXT: if (*Text == -1) *Text = i; break; case TODO_COMPLETED: if (*Completed == -1) *Completed = i; break; case TODO_PHONE: if (*Phone == -1) *Phone = i; break; default: break; } } } GSM_Error GSM_EncodeVTODO(char *Buffer, int *Length, GSM_ToDoEntry *note, bool header, GSM_VToDoVersion Version) { int Text, Alarm, Completed, EndTime, Phone; GSM_ToDoFindDefaultTextTimeAlarmCompleted(note, &Text, &Alarm, &Completed, &EndTime, &Phone); if (header) { *Length+=sprintf(Buffer, "BEGIN:VCALENDAR%c%c",13,10); *Length+=sprintf(Buffer+(*Length), "VERSION:1.0%c%c",13,10); } *Length+=sprintf(Buffer+(*Length), "BEGIN:VTODO%c%c",13,10); if (Version == Nokia_VToDo) { if (Text == -1) return ERR_UNKNOWN; SaveVCALText(Buffer, Length, note->Entries[Text].Text, "SUMMARY"); if (Completed == -1) { - *Length+=sprintf(Buffer+(*Length), "STATUS:NEEDS ACTION%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "PERCENT-COMPLETE:0%c%c",13,10); } else { - *Length+=sprintf(Buffer+(*Length), "STATUS:COMPLETED%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "PERCENT-COMPLETE:100%c%c",13,10); } switch (note->Priority) { - case GSM_Priority_Low : *Length+=sprintf(Buffer+(*Length), "PRIORITY:1%c%c",13,10); break; - case GSM_Priority_Medium: *Length+=sprintf(Buffer+(*Length), "PRIORITY:2%c%c",13,10); break; - case GSM_Priority_High : *Length+=sprintf(Buffer+(*Length), "PRIORITY:3%c%c",13,10); break; + case GSM_Priority_Low : *Length+=sprintf(Buffer+(*Length), "PRIORITY:5%c%c",13,10); break; + case GSM_Priority_Medium: *Length+=sprintf(Buffer+(*Length), "PRIORITY:3%c%c",13,10); break; + case GSM_Priority_High : *Length+=sprintf(Buffer+(*Length), "PRIORITY:1%c%c",13,10); break; } if (EndTime != -1) { SaveVCALDateTime(Buffer, Length, ¬e->Entries[EndTime].Date, "DUE"); } if (Alarm != -1) { if (note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) { SaveVCALDateTime(Buffer, Length, ¬e->Entries[Alarm].Date, "DALARM"); } else { SaveVCALDateTime(Buffer, Length, ¬e->Entries[Alarm].Date, "AALARM"); } } } else if (Version == SonyEricsson_VToDo) { if (Text == -1) return ERR_UNKNOWN; SaveVCALText(Buffer, Length, note->Entries[Text].Text, "SUMMARY"); if (Completed == -1) { - *Length+=sprintf(Buffer+(*Length), "STATUS:NEEDS ACTION%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "PERCENT-COMPLETE:0%c%c",13,10); } else { - *Length+=sprintf(Buffer+(*Length), "STATUS:COMPLETED%c%c",13,10); + *Length+=sprintf(Buffer+(*Length), "PERCENT-COMPLETE:100%c%c",13,10); } switch (note->Priority) { - case GSM_Priority_Low : *Length+=sprintf(Buffer+(*Length), "PRIORITY:3%c%c",13,10); break; - case GSM_Priority_Medium: *Length+=sprintf(Buffer+(*Length), "PRIORITY:2%c%c",13,10); break; + case GSM_Priority_Low : *Length+=sprintf(Buffer+(*Length), "PRIORITY:5%c%c",13,10); break; + case GSM_Priority_Medium: *Length+=sprintf(Buffer+(*Length), "PRIORITY:3%c%c",13,10); break; case GSM_Priority_High : *Length+=sprintf(Buffer+(*Length), "PRIORITY:1%c%c",13,10); break; } if (Alarm != -1) { SaveVCALDateTime(Buffer, Length, ¬e->Entries[Alarm].Date, "AALARM"); } } + *Length+=sprintf(Buffer+(*Length), "X-PILOTID:%d%c%c",note->Location,13,10); *Length+=sprintf(Buffer+(*Length), "END:VTODO%c%c",13,10); if (header) { *Length+=sprintf(Buffer+(*Length), "END:VCALENDAR%c%c",13,10); } return ERR_NONE; } GSM_Error GSM_DecodeVCALENDAR_VTODO(unsigned char *Buffer, int *Pos, GSM_CalendarEntry *Calendar, GSM_ToDoEntry *ToDo, GSM_VCalendarVersion CalVer, GSM_VToDoVersion ToDoVer) { unsigned char Line[2000],Buff[2000]; int Level = 0; Calendar->EntriesNum = 0; ToDo->EntriesNum = 0; while (1) { MyGetLine(Buffer, Pos, Line, strlen(Buffer)); if (strlen(Line) == 0) break; switch (Level) { case 0: if (strstr(Line,"BEGIN:VEVENT")) { Calendar->Type = GSM_CAL_MEMO; Level = 1; } if (strstr(Line,"BEGIN:VTODO")) { - ToDo->Priority = GSM_Priority_Low; + ToDo->Priority = GSM_Priority_Medium; Level = 2; } break; case 1: /* Calendar note */ if (strstr(Line,"END:VEVENT")) { if (Calendar->EntriesNum == 0) return ERR_EMPTY; return ERR_NONE; - } - if (strstr(Line,"CATEGORIES:REMINDER")) Calendar->Type = GSM_CAL_REMINDER; - if (strstr(Line,"CATEGORIES:DATE")) Calendar->Type = GSM_CAL_REMINDER;//SE - if (strstr(Line,"CATEGORIES:TRAVEL")) Calendar->Type = GSM_CAL_TRAVEL; //SE - if (strstr(Line,"CATEGORIES:VACATION")) Calendar->Type = GSM_CAL_VACATION;//SE - if (strstr(Line,"CATEGORIES:MISCELLANEOUS")) Calendar->Type = GSM_CAL_MEMO; - if (strstr(Line,"CATEGORIES:PHONE CALL")) Calendar->Type = GSM_CAL_CALL; - if (strstr(Line,"CATEGORIES:SPECIAL OCCASION")) Calendar->Type = GSM_CAL_BIRTHDAY; - if (strstr(Line,"CATEGORIES:ANNIVERSARY")) Calendar->Type = GSM_CAL_BIRTHDAY; - if (strstr(Line,"CATEGORIES:MEETING")) Calendar->Type = GSM_CAL_MEETING; - if (strstr(Line,"CATEGORIES:APPOINTMENT")) Calendar->Type = GSM_CAL_MEETING; + } + Calendar->Type = GSM_CAL_MEETING; + if (strstr(Line,"CATEGORIES:Reminder")) Calendar->Type = GSM_CAL_REMINDER; + if (strstr(Line,"CATEGORIES:Date")) Calendar->Type = GSM_CAL_REMINDER;//SE + if (strstr(Line,"CATEGORIES:Travel")) Calendar->Type = GSM_CAL_TRAVEL; //SE + if (strstr(Line,"CATEGORIES:Vacation")) Calendar->Type = GSM_CAL_VACATION;//SE + if (strstr(Line,"CATEGORIES:Miscellaneous")) Calendar->Type = GSM_CAL_MEMO; + if (strstr(Line,"CATEGORIES:Phone Call")) Calendar->Type = GSM_CAL_CALL; + if (strstr(Line,"CATEGORIES:Special Occasion")) Calendar->Type = GSM_CAL_BIRTHDAY; + if (strstr(Line,"CATEGORIES:Anniversary")) Calendar->Type = GSM_CAL_BIRTHDAY; + if (strstr(Line,"CATEGORIES:Meeting")) Calendar->Type = GSM_CAL_MEETING; + if (strstr(Line,"CATEGORIES:Appointment")) Calendar->Type = GSM_CAL_MEETING; if (strstr(Line,"RRULE:D1")) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_RECURRANCE; Calendar->Entries[Calendar->EntriesNum].Number = 1*24; Calendar->EntriesNum++; } if ((strstr(Line,"RRULE:W1")) || (strstr(Line,"RRULE:D7"))) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_RECURRANCE; Calendar->Entries[Calendar->EntriesNum].Number = 7*24; Calendar->EntriesNum++; } if (strstr(Line,"RRULE:W2")) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_RECURRANCE; Calendar->Entries[Calendar->EntriesNum].Number = 14*24; Calendar->EntriesNum++; } if (strstr(Line,"RRULE:MD1")) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_RECURRANCE; Calendar->Entries[Calendar->EntriesNum].Number = 30*24; Calendar->EntriesNum++; } if (strstr(Line,"RRULE:YD1")) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_RECURRANCE; Calendar->Entries[Calendar->EntriesNum].Number = 365*24; Calendar->EntriesNum++; } if ((ReadVCALText(Line, "SUMMARY", Buff)) || (ReadVCALText(Line, "DESCRIPTION", Buff))) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_TEXT; CopyUnicodeString(Calendar->Entries[Calendar->EntriesNum].Text,Buff); Calendar->EntriesNum++; } if (ReadVCALText(Line, "LOCATION", Buff)) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_LOCATION; CopyUnicodeString(Calendar->Entries[Calendar->EntriesNum].Text,Buff); Calendar->EntriesNum++; } if (ReadVCALText(Line, "DTSTART", Buff)) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_START_DATETIME; ReadVCALDateTime(DecodeUnicodeString(Buff), &Calendar->Entries[Calendar->EntriesNum].Date); Calendar->EntriesNum++; } if (ReadVCALText(Line, "DTEND", Buff)) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_END_DATETIME; ReadVCALDateTime(DecodeUnicodeString(Buff), &Calendar->Entries[Calendar->EntriesNum].Date); Calendar->EntriesNum++; } if (ReadVCALText(Line, "DALARM", Buff)) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_SILENT_ALARM_DATETIME; ReadVCALDateTime(DecodeUnicodeString(Buff), &Calendar->Entries[Calendar->EntriesNum].Date); Calendar->EntriesNum++; } if (ReadVCALText(Line, "AALARM", Buff)) { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_ALARM_DATETIME; ReadVCALDateTime(DecodeUnicodeString(Buff), &Calendar->Entries[Calendar->EntriesNum].Date); Calendar->EntriesNum++; } break; case 2: /* ToDo note */ if (strstr(Line,"END:VTODO")) { if (ToDo->EntriesNum == 0) return ERR_EMPTY; return ERR_NONE; } if (ReadVCALText(Line, "DUE", Buff)) { ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_END_DATETIME; ReadVCALDateTime(DecodeUnicodeString(Buff), &ToDo->Entries[ToDo->EntriesNum].Date); ToDo->EntriesNum++; } if (ReadVCALText(Line, "DALARM", Buff)) { ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_SILENT_ALARM_DATETIME; ReadVCALDateTime(DecodeUnicodeString(Buff), &ToDo->Entries[ToDo->EntriesNum].Date); ToDo->EntriesNum++; } if (ReadVCALText(Line, "AALARM", Buff)) { ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_ALARM_DATETIME; ReadVCALDateTime(DecodeUnicodeString(Buff), &ToDo->Entries[ToDo->EntriesNum].Date); ToDo->EntriesNum++; } if (ReadVCALText(Line, "SUMMARY", Buff)) { ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_TEXT; CopyUnicodeString(ToDo->Entries[ToDo->EntriesNum].Text,Buff); ToDo->EntriesNum++; } if (ReadVCALText(Line, "PRIORITY", Buff)) { if (ToDoVer == SonyEricsson_VToDo) { ToDo->Priority = GSM_Priority_Low; - if (atoi(DecodeUnicodeString(Buff))==2) ToDo->Priority = GSM_Priority_Medium; - if (atoi(DecodeUnicodeString(Buff))==1) ToDo->Priority = GSM_Priority_High; + if (atoi(DecodeUnicodeString(Buff))>3) ToDo->Priority = GSM_Priority_Low; + if (atoi(DecodeUnicodeString(Buff))<3) ToDo->Priority = GSM_Priority_High; dbgprintf("atoi is %i %s\n",atoi(DecodeUnicodeString(Buff)),DecodeUnicodeString(Buff)); } else if (ToDoVer == Nokia_VToDo) { ToDo->Priority = GSM_Priority_Low; - if (atoi(DecodeUnicodeString(Buff))==2) ToDo->Priority = GSM_Priority_Medium; - if (atoi(DecodeUnicodeString(Buff))==3) ToDo->Priority = GSM_Priority_High; + if (atoi(DecodeUnicodeString(Buff))>3) ToDo->Priority = GSM_Priority_Low; + if (atoi(DecodeUnicodeString(Buff))<3) ToDo->Priority = GSM_Priority_High; } } - if (strstr(Line,"STATUS:COMPLETED")) { + if (strstr(Line,"PERCENT-COMPLETE:100")) { ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_COMPLETED; ToDo->Entries[ToDo->EntriesNum].Number = 1; ToDo->EntriesNum++; } break; } } if (Calendar->EntriesNum == 0 && ToDo->EntriesNum == 0) return ERR_EMPTY; return ERR_NONE; } GSM_Error GSM_EncodeVNTFile(unsigned char *Buffer, int *Length, GSM_NoteEntry *Note) { *Length+=sprintf(Buffer+(*Length), "BEGIN:VNOTE%c%c",13,10); *Length+=sprintf(Buffer+(*Length), "VERSION:1.1%c%c",13,10); SaveVCALText(Buffer, Length, Note->Text, "BODY"); *Length+=sprintf(Buffer+(*Length), "END:VNOTE%c%c",13,10); return ERR_NONE; } /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/kdepim-desktop.pro b/kdepim-desktop.pro new file mode 100644 index 0000000..7a3a96e --- a/dev/null +++ b/kdepim-desktop.pro @@ -0,0 +1,6 @@ + + +TEMPLATE = subdirs +SUBDIRS = gammu/emb/common gammu/emb/gammu libical libkcal microkde libkdepim kabc korganizer kaddressbook kabc/plugins/file kabc/plugins/dir +#kalarmd + diff --git a/kopi-desktop.pro b/kopi-desktop.pro deleted file mode 100644 index 69c874f..0000000 --- a/kopi-desktop.pro +++ b/dev/null @@ -1,6 +0,0 @@ - - -TEMPLATE = subdirs -SUBDIRS = gammu/emb/common libical libkcal microkde libkdepim kabc korganizer kaddressbook kabc/plugins/file kabc/plugins/dir -#kalarmd - diff --git a/korganizer/calendarview.cpp b/korganizer/calendarview.cpp index 7444bad..db07713 100644 --- a/korganizer/calendarview.cpp +++ b/korganizer/calendarview.cpp @@ -854,2049 +854,2049 @@ Event* CalendarView::getLastSyncEvent() lse = mCalendar->event( "last-syncEvent-"+mCurrentSyncDevice ); if (!lse) { lse = new Event(); lse->setUid( "last-syncEvent-"+mCurrentSyncDevice ); QString sum = ""; if ( KOPrefs::instance()->mExternSyncProfiles.contains( mCurrentSyncDevice ) ) sum = "E: "; lse->setSummary(sum+mCurrentSyncDevice + i18n(" - sync event")); lse->setDtStart( mLastCalendarSync ); lse->setDtEnd( mLastCalendarSync.addSecs( 7200 ) ); lse->setCategories( i18n("SyncEvent") ); lse->setReadOnly( true ); mCalendar->addEvent( lse ); } return lse; } // probaly useless void CalendarView::setupExternSyncProfiles() { Event* lse; mExternLastSyncEvent.clear(); int i; for ( i = 0; i < KOPrefs::instance()->mExternSyncProfiles.count(); ++i ) { lse = mCalendar->event( "last-syncEvent-"+ KOPrefs::instance()->mExternSyncProfiles[i] ); if ( lse ) mExternLastSyncEvent.append( lse ); else qDebug("Last Sync event not found for %s ", KOPrefs::instance()->mExternSyncProfiles[i].latin1()); } } // we check, if the to delete event has a id for a profile // if yes, we set this id in the profile to delete void CalendarView::checkExternSyncEvent( QPtrList<Event> lastSync , Incidence* toDelete ) { if ( lastSync.count() == 0 ) { //qDebug(" lastSync.count() == 0"); return; } if ( toDelete->type() == "Journal" ) return; Event* eve = lastSync.first(); while ( eve ) { QString id = toDelete->getID( eve->uid().mid( 15 ) ); // this is the sync profile name if ( !id.isEmpty() ) { QString des = eve->description(); QString pref = "e"; if ( toDelete->type() == "Todo" ) pref = "t"; des += pref+ id + ","; eve->setReadOnly( false ); eve->setDescription( des ); //qDebug("setdes %s ", des.latin1()); eve->setReadOnly( true ); } eve = lastSync.next(); } } void CalendarView::checkExternalId( Incidence * inc ) { QPtrList<Event> lastSync = mCalendar->getExternLastSyncEvents() ; checkExternSyncEvent( lastSync, inc ); } bool CalendarView::synchronizeCalendar( Calendar* local, Calendar* remote, int mode ) { bool syncOK = true; int addedEvent = 0; int addedEventR = 0; int deletedEventR = 0; int deletedEventL = 0; int changedLocal = 0; int changedRemote = 0; //QPtrList<Event> el = local->rawEvents(); Event* eventR; QString uid; int take; Event* eventL; Event* eventRSync; Event* eventLSync; QPtrList<Event> eventRSyncSharp = remote->getExternLastSyncEvents(); QPtrList<Event> eventLSyncSharp = local->getExternLastSyncEvents(); bool fullDateRange = false; local->resetTempSyncStat(); mLastCalendarSync = QDateTime::currentDateTime(); QDateTime modifiedCalendar = mLastCalendarSync;; eventR = remote->event("last-syncEvent-"+mCurrentSyncName ); if ( eventR ) { eventRSync = (Event*) eventR->clone(); remote->deleteEvent(eventR ); } else { fullDateRange = true; eventRSync = new Event(); eventRSync->setSummary(mCurrentSyncName + i18n(" - sync event")); eventRSync->setUid("last-syncEvent-"+mCurrentSyncName ); eventRSync->setDtStart( mLastCalendarSync ); eventRSync->setDtEnd( mLastCalendarSync.addSecs( 7200 ) ); eventRSync->setCategories( i18n("SyncEvent") ); } eventLSync = getLastSyncEvent(); if ( eventLSync->dtStart() == mLastCalendarSync ) fullDateRange = true; if ( ! fullDateRange ) { if ( eventLSync->dtStart() != eventRSync->dtStart() ) { // qDebug("set fulldate to true %s %s" ,eventLSync->dtStart().toString().latin1(), eventRSync->dtStart().toString().latin1() ); //qDebug("%d %d %d %d ", eventLSync->dtStart().time().second(), eventLSync->dtStart().time().msec() , eventRSync->dtStart().time().second(), eventRSync->dtStart().time().msec()); fullDateRange = true; } } if ( fullDateRange ) mLastCalendarSync = QDateTime::currentDateTime().addDays( -100*365); else mLastCalendarSync = eventLSync->dtStart(); // for resyncing if own file has changed if ( mCurrentSyncDevice == "deleteaftersync" ) { mLastCalendarSync = loadedFileVersion; qDebug("setting mLastCalendarSync "); } //qDebug("*************************** "); qDebug("mLastCalendarSync %s ",mLastCalendarSync.toString().latin1() ); QPtrList<Incidence> er = remote->rawIncidences(); Incidence* inR = er.first(); Incidence* inL; QProgressBar bar( er.count(),0 ); bar.setCaption (i18n("Syncing - close to abort!") ); int w = 300; if ( QApplication::desktop()->width() < 320 ) w = 220; int h = bar.sizeHint().height() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); bar.show(); int modulo = (er.count()/10)+1; int incCounter = 0; while ( inR ) { if ( ! bar.isVisible() ) return false; if ( incCounter % modulo == 0 ) bar.setProgress( incCounter ); ++incCounter; uid = inR->uid(); bool skipIncidence = false; if ( uid.left(15) == QString("last-syncEvent-") ) skipIncidence = true; qApp->processEvents(); if ( !skipIncidence ) { inL = local->incidence( uid ); if ( inL ) { // maybe conflict - same uid in both calendars int maxrev = inL->revision(); if ( maxrev < inR->revision() ) maxrev = inR->revision(); if ( (take = takeEvent( inL, inR, mode, fullDateRange )) > 0 ) { //qDebug("take %d %s ", take, inL->summary().latin1()); if ( take == 3 ) return false; if ( take == 1 ) {// take local inL->setCsum( mCurrentSyncDevice, inR->getCsum(mCurrentSyncDevice) ); remote->deleteIncidence( inR ); if ( inL->revision() < maxrev ) inL->setRevision( maxrev ); remote->addIncidence( inL->clone() ); ++changedRemote; } else { if ( inR->revision() < maxrev ) inR->setRevision( maxrev ); local->deleteIncidence( inL ); local->addIncidence( inR->clone() ); ++changedLocal; } } } else { // no conflict if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) { QString des = eventLSync->description(); QString pref = "e"; if ( inR->type() == "Todo" ) pref = "t"; if ( des.find(pref+ inR->getID(mCurrentSyncDevice) +"," ) >= 0 && mode != 5) { // delete it inR->setTempSyncStat( SYNC_TEMPSTATE_DELETE ); //remote->deleteIncidence( inR ); ++deletedEventR; } else { inR->setLastModified( modifiedCalendar ); local->addIncidence( inR->clone() ); ++addedEvent; } } else { if ( inR->lastModified() > mLastCalendarSync || mode == 5 ) { inR->setLastModified( modifiedCalendar ); local->addIncidence( inR->clone() ); ++addedEvent; } else { checkExternSyncEvent(eventRSyncSharp, inR); remote->deleteIncidence( inR ); ++deletedEventR; } } } } inR = er.next(); } QPtrList<Incidence> el = local->rawIncidences(); inL = el.first(); modulo = (el.count()/10)+1; bar.setCaption (i18n("Add / remove events") ); bar.setTotalSteps ( el.count() ) ; bar.show(); incCounter = 0; while ( inL ) { qApp->processEvents(); if ( ! bar.isVisible() ) return false; if ( incCounter % modulo == 0 ) bar.setProgress( incCounter ); ++incCounter; uid = inL->uid(); bool skipIncidence = false; if ( uid.left(15) == QString("last-syncEvent-") ) skipIncidence = true; if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL && inL->type() == "Journal" ) skipIncidence = true; if ( !skipIncidence ) { inR = remote->incidence( uid ); if ( ! inR ) { if ( mGlobalSyncMode == SYNC_MODE_EXTERNAL ) { if ( !inL->getID(mCurrentSyncDevice).isEmpty() && mode != 4 ) { local->deleteIncidence( inL ); ++deletedEventL; } else { if ( ! KOPrefs::instance()->mWriteBackExistingOnly ) { inL->removeID(mCurrentSyncDevice ); ++addedEventR; inL->setLastModified( modifiedCalendar ); remote->addIncidence( inL->clone() ); } } } else { if ( inL->lastModified() < mLastCalendarSync && mode != 4 ) { checkExternSyncEvent(eventLSyncSharp, inL); local->deleteIncidence( inL ); ++deletedEventL; } else { if ( ! KOPrefs::instance()->mWriteBackExistingOnly ) { ++addedEventR; inL->setLastModified( modifiedCalendar ); remote->addIncidence( inL->clone() ); } } } } } inL = el.next(); } bar.hide(); mLastCalendarSync = QDateTime::currentDateTime().addSecs( 1 ); eventLSync->setReadOnly( false ); eventLSync->setDtStart( mLastCalendarSync ); eventRSync->setDtStart( mLastCalendarSync ); eventLSync->setDtEnd( mLastCalendarSync.addSecs( 3600 ) ); eventRSync->setDtEnd( mLastCalendarSync.addSecs( 3600 ) ); eventRSync->setLocation( i18n("Remote from: ")+mCurrentSyncName ) ; eventLSync->setLocation(i18n("Local from: ") + mCurrentSyncName ); eventLSync->setReadOnly( true ); if ( mGlobalSyncMode == SYNC_MODE_NORMAL) remote->addEvent( eventRSync ); QString mes; mes .sprintf( i18n("Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n"),addedEvent, addedEventR, changedLocal, changedRemote, deletedEventL, deletedEventR ); if ( KOPrefs::instance()->mShowSyncSummary ) { KMessageBox::information(this, mes, i18n("KO/Pi Synchronization") ); } qDebug( mes ); mCalendar->checkAlarmForIncidence( 0, true ); return syncOK; } void CalendarView::setSyncDevice( QString s ) { mCurrentSyncDevice= s; } void CalendarView::setSyncName( QString s ) { mCurrentSyncName= s; } bool CalendarView::syncCalendar(QString filename, int mode) { mGlobalSyncMode = SYNC_MODE_NORMAL; CalendarLocal* calendar = new CalendarLocal(); calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); FileStorage* storage = new FileStorage( calendar ); bool syncOK = false; storage->setFileName( filename ); // qDebug("loading ... "); if ( storage->load(KOPrefs::instance()->mUseQuicksave) ) { getEventViewerDialog()->setSyncMode( true ); syncOK = synchronizeCalendar( mCalendar, calendar, mode ); getEventViewerDialog()->setSyncMode( false ); if ( syncOK ) { if ( KOPrefs::instance()->mWriteBackFile ) { storage->setSaveFormat( new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); storage->save(); } } setModified( true ); } delete storage; delete calendar; if ( syncOK ) updateView(); return syncOK; } void CalendarView::syncPhone() { syncExternal( 1 ); } void CalendarView::syncExternal( int mode ) { mGlobalSyncMode = SYNC_MODE_EXTERNAL; //mCurrentSyncDevice = "sharp-DTM"; if ( KOPrefs::instance()->mAskForPreferences ) edit_sync_options(); qApp->processEvents(); CalendarLocal* calendar = new CalendarLocal(); calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); bool syncOK = false; bool loadSuccess = false; PhoneFormat* phoneFormat = 0; #ifndef DESKTOP_VERSION SharpFormat* sharpFormat = 0; if ( mode == 0 ) { // sharp sharpFormat = new SharpFormat () ; loadSuccess = sharpFormat->load( calendar, mCalendar ); } else #endif if ( mode == 1 ) { // phone phoneFormat = new PhoneFormat (mCurrentSyncDevice, KOPrefs::instance()->mPhoneDevice, KOPrefs::instance()->mPhoneConnection, KOPrefs::instance()->mPhoneModel); loadSuccess = phoneFormat->load( calendar,mCalendar); } else return; if ( loadSuccess ) { getEventViewerDialog()->setSyncMode( true ); syncOK = synchronizeCalendar( mCalendar, calendar, KOPrefs::instance()->mSyncAlgoPrefs ); getEventViewerDialog()->setSyncMode( false ); qApp->processEvents(); if ( syncOK ) { if ( KOPrefs::instance()->mWriteBackFile ) { QPtrList<Incidence> iL = mCalendar->rawIncidences(); Incidence* inc = iL.first(); /* obsolete while ( inc ) { inc->setZaurusStat( inc->revision () ); inc = iL.next(); } */ #ifndef DESKTOP_VERSION if ( sharpFormat ) sharpFormat->save(calendar); #endif if ( phoneFormat ) phoneFormat->save(calendar); iL = calendar->rawIncidences(); inc = iL.first(); Incidence* loc; while ( inc ) { if ( inc->tempSyncStat() == SYNC_TEMPSTATE_NEW_ID ) { loc = mCalendar->incidence(inc->uid() ); if ( loc ) { loc->setID(mCurrentSyncDevice, inc->getID(mCurrentSyncDevice) ); loc->setCsum( mCurrentSyncDevice, inc->getCsum(mCurrentSyncDevice) ); } } inc = iL.next(); } Incidence* lse = getLastSyncEvent(); if ( lse ) { lse->setReadOnly( false ); lse->setDescription( "" ); lse->setReadOnly( true ); } } } setModified( true ); } else { QString question = i18n("Sorry, the database access\ncommand failed!\n\nNothing synced!\n") ; QMessageBox::information( 0, i18n("KO/Pi Import - ERROR"), question, i18n("Ok")) ; } delete calendar; updateView(); return ;//syncOK; } void CalendarView::syncSharp() { syncExternal( 0 ); } #include <kabc/stdaddressbook.h> bool CalendarView::importBday() { KABC::StdAddressBook* AddressBook = KABC::StdAddressBook::self( true ); KABC::AddressBook::Iterator it; int count = 0; for( it = AddressBook->begin(); it != AddressBook->end(); ++it ) { ++count; } QProgressBar bar(count,0 ); int w = 300; if ( QApplication::desktop()->width() < 320 ) w = 220; int h = bar.sizeHint().height() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); bar.show(); bar.setCaption (i18n("Reading addressbook - close to abort!") ); qApp->processEvents(); count = 0; int addCount = 0; KCal::Attendee* a = 0; for( it = AddressBook->begin(); it != AddressBook->end(); ++it ) { if ( ! bar.isVisible() ) return false; bar.setProgress( count++ ); qApp->processEvents(); //qDebug("add BDay %s %s", (*it).realName().latin1(),(*it).birthday().date().toString().latin1() ); if ( (*it).birthday().date().isValid() ){ a = new KCal::Attendee( (*it).realName(), (*it).preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,(*it).uid()) ; if ( addAnniversary( (*it).birthday().date(), (*it).assembledName(), a, true ) ) ++addCount; } QDate anni = KGlobal::locale()->readDate( (*it).custom("KADDRESSBOOK", "X-Anniversary" ), "%Y-%m-%d"); if ( anni.isValid() ){ a = new KCal::Attendee( (*it).realName(), (*it).preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,(*it).uid()) ; if ( addAnniversary( anni, (*it).assembledName(), a, false ) ) ++addCount; } } updateView(); topLevelWidget()->setCaption(QString::number( addCount )+ i18n(" birthdays/anniversaries added!")); return true; } bool CalendarView::addAnniversary( QDate date, QString name, KCal::Attendee* a, bool birthday) { //qDebug("addAnni "); Event * ev = new Event(); if ( a ) { ev->addAttendee( a ); } QString kind; if ( birthday ) kind = i18n( "Birthday" ); else kind = i18n( "Anniversary" ); ev->setSummary( name + " - " + kind ); ev->setOrganizer( "nobody@nowhere" ); ev->setCategories( kind ); ev->setDtStart( QDateTime(date) ); ev->setDtEnd( QDateTime(date) ); ev->setFloats( true ); Recurrence * rec = ev->recurrence(); rec->setYearly(Recurrence::rYearlyMonth,1,-1); rec->addYearlyNum( date.month() ); if ( !mCalendar->addAnniversaryNoDup( ev ) ) { delete ev; return false; } return true; } bool CalendarView::importQtopia( const QString &categories, const QString &datebook, const QString &todolist ) { QtopiaFormat qtopiaFormat; qtopiaFormat.setCategoriesList ( &(KOPrefs::instance()->mCustomCategories)); if ( !categories.isEmpty() ) qtopiaFormat.load( mCalendar, categories ); if ( !datebook.isEmpty() ) qtopiaFormat.load( mCalendar, datebook ); if ( !todolist.isEmpty() ) qtopiaFormat.load( mCalendar, todolist ); updateView(); return true; #if 0 mGlobalSyncMode = SYNC_MODE_QTOPIA; mCurrentSyncDevice = "qtopia-XML"; if ( KOPrefs::instance()->mAskForPreferences ) edit_sync_options(); qApp->processEvents(); CalendarLocal* calendar = new CalendarLocal(); calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); bool syncOK = false; QtopiaFormat qtopiaFormat; qtopiaFormat.setCategoriesList ( &(KOPrefs::instance()->mCustomCategories)); bool loadOk = true; if ( !categories.isEmpty() ) loadOk = qtopiaFormat.load( calendar, categories ); if ( loadOk && !datebook.isEmpty() ) loadOk = qtopiaFormat.load( calendar, datebook ); if ( loadOk && !todolist.isEmpty() ) loadOk = qtopiaFormat.load( calendar, todolist ); if ( loadOk ) { getEventViewerDialog()->setSyncMode( true ); syncOK = synchronizeCalendar( mCalendar, calendar, KOPrefs::instance()->mSyncAlgoPrefs ); getEventViewerDialog()->setSyncMode( false ); qApp->processEvents(); if ( syncOK ) { if ( KOPrefs::instance()->mWriteBackFile ) { // write back XML file } setModified( true ); } } else { QString question = i18n("Sorry, the file loading\ncommand failed!\n\nNothing synced!\n") ; QMessageBox::information( 0, i18n("KO/Pi Sync - ERROR"), question, i18n("Ok")) ; } delete calendar; updateView(); return syncOK; #endif } void CalendarView::setSyncEventsReadOnly() { Event * ev; QPtrList<Event> eL = mCalendar->rawEvents(); ev = eL.first(); while ( ev ) { if ( ev->uid().left(15) == QString("last-syncEvent-") ) ev->setReadOnly( true ); ev = eL.next(); } } bool CalendarView::openCalendar(QString filename, bool merge) { if (filename.isEmpty()) { return false; } if (!QFile::exists(filename)) { KMessageBox::error(this,i18n("File does not exist:\n '%1'.").arg(filename)); return false; } globalFlagBlockAgenda = 1; if (!merge) mCalendar->close(); mStorage->setFileName( filename ); if ( mStorage->load(KOPrefs::instance()->mUseQuicksave) ) { if ( merge ) ;//setModified( true ); else { //setModified( true ); mViewManager->setDocumentId( filename ); mDialogManager->setDocumentId( filename ); mTodoList->setDocumentId( filename ); } globalFlagBlockAgenda = 2; // if ( getLastSyncEvent() ) // getLastSyncEvent()->setReadOnly( true ); mCalendar->reInitAlarmSettings(); setSyncEventsReadOnly(); updateUnmanagedViews(); updateView(); if ( filename != MainWindow::defaultFileName() ) saveCalendar( MainWindow::defaultFileName() ); loadedFileVersion = QDateTime::currentDateTime(); return true; } else { // while failing to load, the calendar object could // have become partially populated. Clear it out. if ( !merge ) mCalendar->close(); KMessageBox::error(this,i18n("Couldn't load calendar\n '%1'.").arg(filename)); globalFlagBlockAgenda = 2; updateView(); } return false; } void CalendarView::setLoadedFileVersion(QDateTime dt) { loadedFileVersion = dt; } bool CalendarView::checkFileChanged(QString fn) { QFileInfo finf ( fn ); if ( !finf.exists() ) return true; QDateTime dt = finf.lastModified (); if ( dt <= loadedFileVersion ) return false; return true; } bool CalendarView::checkFileVersion(QString fn) { QFileInfo finf ( fn ); if ( !finf.exists() ) return true; QDateTime dt = finf.lastModified (); //qDebug("loaded file version %s",loadedFileVersion.toString().latin1()); //qDebug("file on disk version %s",dt.toString().latin1()); if ( dt <= loadedFileVersion ) return true; int km = KMessageBox::warningYesNoCancel(this, i18n("\nThe file on disk has changed!\nFile size: %1 bytes.\nLast modified: %2\nDo you want to:\n\n - Save and overwrite file?\n - Sync with file, then save?\n - Cancel without saving? \n").arg( QString::number( finf.size())).arg( KGlobal::locale()->formatDateTime(finf.lastModified (), true, false)) , i18n("KO/Pi Warning"),i18n("Overwrite"), i18n("Sync+save")); if ( km == KMessageBox::Cancel ) return false; if ( km == KMessageBox::Yes ) return true; setSyncDevice("deleteaftersync" ); KOPrefs::instance()->mAskForPreferences = true; KOPrefs::instance()->mSyncAlgoPrefs = 3; KOPrefs::instance()->mWriteBackFile = false; KOPrefs::instance()->mWriteBackExistingOnly = false; KOPrefs::instance()->mShowSyncSummary = false; syncCalendar( fn, 3 ); Event * e = getLastSyncEvent(); mCalendar->deleteEvent ( e ); updateView(); return true; } bool CalendarView::saveCalendar( QString filename ) { // Store back all unsaved data into calendar object // qDebug("file %s %d ", filename.latin1() , mViewManager->currentView() ); if ( mViewManager->currentView() ) mViewManager->currentView()->flushView(); //mStorage->setFileName( filename ); mStorage->setSaveFormat( new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); mStorage->setFileName( filename ); bool success; success = mStorage->save(); if ( !success ) { return false; } return true; } void CalendarView::closeCalendar() { // child windows no longer valid emit closingDown(); mCalendar->close(); setModified(false); updateView(); } void CalendarView::archiveCalendar() { mDialogManager->showArchiveDialog(); } void CalendarView::readSettings() { // mViewManager->showAgendaView(); QString str; //qDebug("CalendarView::readSettings() "); // read settings from the KConfig, supplying reasonable // defaults where none are to be found KConfig *config = KOGlobals::config(); #ifndef KORG_NOSPLITTER config->setGroup("KOrganizer Geometry"); QValueList<int> sizes = config->readIntListEntry("Separator1"); if (sizes.count() != 2) { sizes << mDateNavigator->minimumSizeHint().width(); sizes << 300; } mPanner->setSizes(sizes); sizes = config->readIntListEntry("Separator2"); if ( ( mResourceView && sizes.count() == 4 ) || ( !mResourceView && sizes.count() == 3 ) ) { mLeftSplitter->setSizes(sizes); } #endif globalFlagBlockAgenda = 1; mViewManager->showAgendaView(); //mViewManager->readSettings( config ); mTodoList->restoreLayout(config,QString("Todo Layout")); readFilterSettings(config); config->setGroup( "Views" ); int dateCount = config->readNumEntry( "ShownDatesCount", 7 ); if ( dateCount == 5 ) mNavigator->selectWorkWeek(); else if ( dateCount == 7 ) mNavigator->selectWeek(); else mNavigator->selectDates( dateCount ); // mViewManager->readSettings( config ); updateConfig(); globalFlagBlockAgenda = 2; mViewManager->readSettings( config ); #ifdef DESKTOP_VERSION config->setGroup("WidgetLayout"); QStringList list; list = config->readListEntry("MainLayout"); int x,y,w,h; if ( ! list.isEmpty() ) { x = list[0].toInt(); y = list[1].toInt(); w = list[2].toInt(); h = list[3].toInt(); topLevelWidget()->setGeometry(x,y,w,h); } else { topLevelWidget()->setGeometry( 40 ,40 , 640, 440); } list = config->readListEntry("EditEventLayout"); if ( ! list.isEmpty() ) { x = list[0].toInt(); y = list[1].toInt(); w = list[2].toInt(); h = list[3].toInt(); mEventEditor->setGeometry(x,y,w,h); } list = config->readListEntry("EditTodoLayout"); if ( ! list.isEmpty() ) { x = list[0].toInt(); y = list[1].toInt(); w = list[2].toInt(); h = list[3].toInt(); mTodoEditor->setGeometry(x,y,w,h); } list = config->readListEntry("ViewerLayout"); if ( ! list.isEmpty() ) { x = list[0].toInt(); y = list[1].toInt(); w = list[2].toInt(); h = list[3].toInt(); getEventViewerDialog()->setGeometry(x,y,w,h); } #endif } void CalendarView::writeSettings() { // kdDebug() << "CalendarView::writeSettings" << endl; KConfig *config = KOGlobals::config(); #ifndef KORG_NOSPLITTER config->setGroup("KOrganizer Geometry"); QValueList<int> list = mPanner->sizes(); config->writeEntry("Separator1",list); list = mLeftSplitter->sizes(); config->writeEntry("Separator2",list); #endif mViewManager->writeSettings( config ); mTodoList->saveLayout(config,QString("Todo Layout")); mDialogManager->writeSettings( config ); //KOPrefs::instance()->usrWriteConfig(); KOPrefs::instance()->writeConfig(); writeFilterSettings(config); config->setGroup( "Views" ); config->writeEntry( "ShownDatesCount", mNavigator->selectedDates().count() ); #ifdef DESKTOP_VERSION config->setGroup("WidgetLayout"); QStringList list ;//= config->readListEntry("MainLayout"); int x,y,w,h; QWidget* wid; wid = topLevelWidget(); x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("MainLayout",list ); wid = mEventEditor; x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("EditEventLayout",list ); wid = mTodoEditor; x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("EditTodoLayout",list ); wid = getEventViewerDialog(); x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("ViewerLayout",list ); wid = mDialogManager->getSearchDialog(); if ( wid ) { x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("SearchLayout",list ); } #endif config->sync(); } void CalendarView::readFilterSettings(KConfig *config) { // kdDebug() << "CalendarView::readFilterSettings()" << endl; mFilters.clear(); config->setGroup("General"); QStringList filterList = config->readListEntry("CalendarFilters"); QStringList::ConstIterator it = filterList.begin(); QStringList::ConstIterator end = filterList.end(); while(it != end) { // kdDebug() << " filter: " << (*it) << endl; CalFilter *filter; filter = new CalFilter(*it); config->setGroup("Filter_" + (*it)); //qDebug("readFilterSettings %d ",config->readNumEntry("Criteria",0) ); filter->setCriteria(config->readNumEntry("Criteria",0)); filter->setCategoryList(config->readListEntry("CategoryList")); mFilters.append(filter); ++it; } if (mFilters.count() == 0) { CalFilter *filter = new CalFilter(i18n("Default")); mFilters.append(filter); } mFilterView->updateFilters(); config->setGroup("FilterView"); mFilterView->blockSignals(true); mFilterView->setFiltersEnabled(config->readBoolEntry("FilterEnabled")); mFilterView->setSelectedFilter(config->readEntry("Current Filter")); mFilterView->blockSignals(false); // We do it manually to avoid it being done twice by the above calls updateFilter(); } void CalendarView::writeFilterSettings(KConfig *config) { // kdDebug() << "CalendarView::writeFilterSettings()" << endl; QStringList filterList; CalFilter *filter = mFilters.first(); while(filter) { // kdDebug() << " fn: " << filter->name() << endl; filterList << filter->name(); config->setGroup("Filter_" + filter->name()); config->writeEntry("Criteria",filter->criteria()); config->writeEntry("CategoryList",filter->categoryList()); filter = mFilters.next(); } config->setGroup("General"); config->writeEntry("CalendarFilters",filterList); config->setGroup("FilterView"); config->writeEntry("FilterEnabled",mFilterView->filtersEnabled()); config->writeEntry("Current Filter",mFilterView->selectedFilter()->name()); } void CalendarView::goToday() { mNavigator->selectToday(); } void CalendarView::goNext() { mNavigator->selectNext(); } void CalendarView::goPrevious() { mNavigator->selectPrevious(); } void CalendarView::goNextMonth() { mNavigator->selectNextMonth(); } void CalendarView::goPreviousMonth() { mNavigator->selectPreviousMonth(); } void CalendarView::writeLocale() { KGlobal::locale()->setHore24Format( !KOPrefs::instance()->mPreferredTime ); KGlobal::locale()->setWeekStartMonday( !KOPrefs::instance()->mWeekStartsOnSunday ); KGlobal::locale()->setIntDateFormat( (KLocale::IntDateFormat)KOPrefs::instance()->mPreferredDate ); KGlobal::locale()->setLanguage( KOPrefs::instance()->mPreferredLanguage ); QString dummy = KOPrefs::instance()->mUserDateFormatLong; KGlobal::locale()->setDateFormat(dummy.replace( QRegExp("K"), QString(",") )); dummy = KOPrefs::instance()->mUserDateFormatShort; KGlobal::locale()->setDateFormatShort(dummy.replace( QRegExp("K"), QString(",") )); KGlobal::locale()->setDaylightSaving( KOPrefs::instance()->mUseDaylightsaving, KOPrefs::instance()->mDaylightsavingStart, KOPrefs::instance()->mDaylightsavingEnd ); KGlobal::locale()->setTimezone( KOPrefs::instance()->mTimeZoneId ); } void CalendarView::updateConfig() { writeLocale(); if ( KOPrefs::instance()->mUseAppColors ) QApplication::setPalette( QPalette (KOPrefs::instance()->mAppColor1, KOPrefs::instance()->mAppColor2), true ); emit configChanged(); mTodoList->updateConfig(); // mDateNavigator->setFont ( KOPrefs::instance()->mDateNavigatorFont); mCalendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); // To make the "fill window" configurations work //mViewManager->raiseCurrentView(); } void CalendarView::eventChanged(Event *event) { changeEventDisplay(event,KOGlobals::EVENTEDITED); //updateUnmanagedViews(); } void CalendarView::eventAdded(Event *event) { changeEventDisplay(event,KOGlobals::EVENTADDED); } void CalendarView::eventToBeDeleted(Event *) { kdDebug() << "CalendarView::eventToBeDeleted(): to be implemented" << endl; } void CalendarView::eventDeleted() { changeEventDisplay(0,KOGlobals::EVENTDELETED); } void CalendarView::changeTodoDisplay(Todo *which, int action) { changeIncidenceDisplay((Incidence *)which, action); mDateNavigator->updateView(); //mDialogManager->updateSearchDialog(); if (which) { mViewManager->currentView()->updateView(); - mTodoList->updateView(); + //mTodoList->updateView(); } } void CalendarView::changeIncidenceDisplay(Incidence *which, int action) { updateUnmanagedViews(); //qDebug(" CalendarView::changeIncidenceDisplay++++++++++++++++++++++++++ %d %d ",which, action ); if ( action == KOGlobals::EVENTDELETED ) { //delete mCalendar->checkAlarmForIncidence( 0, true ); if ( mEventViewerDialog ) mEventViewerDialog->hide(); } else mCalendar->checkAlarmForIncidence( which , false ); } // most of the changeEventDisplays() right now just call the view's // total update mode, but they SHOULD be recoded to be more refresh-efficient. void CalendarView::changeEventDisplay(Event *which, int action) { // kdDebug() << "CalendarView::changeEventDisplay" << endl; changeIncidenceDisplay((Incidence *)which, action); mDateNavigator->updateView(); //mDialogManager->updateSearchDialog(); if (which) { // If there is an event view visible update the display mViewManager->currentView()->changeEventDisplay(which,action); // TODO: check, if update needed // if (which->getTodoStatus()) { mTodoList->updateView(); // } } else { mViewManager->currentView()->updateView(); } } void CalendarView::updateTodoViews() { mTodoList->updateView(); mViewManager->currentView()->updateView(); } void CalendarView::updateView(const QDate &start, const QDate &end) { mTodoList->updateView(); mViewManager->updateView(start, end); //mDateNavigator->updateView(); } void CalendarView::updateView() { DateList tmpList = mNavigator->selectedDates(); // We assume that the navigator only selects consecutive days. updateView( tmpList.first(), tmpList.last() ); } void CalendarView::updateUnmanagedViews() { mDateNavigator->updateDayMatrix(); } int CalendarView::msgItemDelete() { return KMessageBox::warningContinueCancel(this, i18n("This item will be\npermanently deleted."), i18n("KO/Pi Confirmation"),i18n("Delete")); } void CalendarView::edit_cut() { Event *anEvent=0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } DndFactory factory( mCalendar ); factory.cutEvent(anEvent); changeEventDisplay(anEvent, KOGlobals::EVENTDELETED); } void CalendarView::edit_copy() { Event *anEvent=0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } DndFactory factory( mCalendar ); factory.copyEvent(anEvent); } void CalendarView::edit_paste() { QDate date = mNavigator->selectedDates().first(); DndFactory factory( mCalendar ); Event *pastedEvent = factory.pasteEvent( date ); changeEventDisplay( pastedEvent, KOGlobals::EVENTADDED ); } void CalendarView::edit_options() { mDialogManager->showOptionsDialog(); //writeSettings(); } void CalendarView::edit_sync_options() { //mDialogManager->showSyncOptions(); //KOPrefs::instance()->mSyncAlgoPrefs QDialog dia( this, "dia", true ); dia.setCaption( i18n("Device: " ) +mCurrentSyncDevice ); QButtonGroup gr ( 1, Qt::Horizontal, i18n("Sync preferences"), &dia); QVBoxLayout lay ( &dia ); lay.setSpacing( 2 ); lay.setMargin( 3 ); lay.addWidget(&gr); QRadioButton loc ( i18n("Take local entry on conflict"), &gr ); QRadioButton rem ( i18n("Take remote entry on conflict"), &gr ); QRadioButton newest( i18n("Take newest entry on conflict"), &gr ); QRadioButton ask( i18n("Ask for every entry on conflict"), &gr ); QRadioButton f_loc( i18n("Force: Take local entry always"), &gr ); QRadioButton f_rem( i18n("Force: Take remote entry always"), &gr ); //QRadioButton both( i18n("Take both on conflict"), &gr ); QPushButton pb ( "OK", &dia); lay.addWidget( &pb ); connect(&pb, SIGNAL( clicked() ), &dia, SLOT ( accept() ) ); switch ( KOPrefs::instance()->mSyncAlgoPrefs ) { case 0: loc.setChecked( true); break; case 1: rem.setChecked( true ); break; case 2: newest.setChecked( true); break; case 3: ask.setChecked( true); break; case 4: f_loc.setChecked( true); break; case 5: f_rem.setChecked( true); break; case 6: // both.setChecked( true); break; default: break; } if ( dia.exec() ) { KOPrefs::instance()->mSyncAlgoPrefs = rem.isChecked()*1+newest.isChecked()*2+ ask.isChecked()*3+ f_loc.isChecked()*4+ f_rem.isChecked()*5;//+ both.isChecked()*6 ; } } void CalendarView::slotSelectPickerDate( QDate d) { mDateFrame->hide(); if ( mDatePickerMode == 1 ) { mNavigator->slotDaySelect( d ); } else if ( mDatePickerMode == 2 ) { if ( mMoveIncidence->type() == "Todo" ) { Todo * to = (Todo *) mMoveIncidence; QTime tim; if ( to->hasDueDate() ) tim = to->dtDue().time(); else { tim = QTime ( 0,0,0 ); to->setFloats( true ); to->setHasDueDate( true ); } QDateTime dt ( d,tim ); to->setDtDue( dt ); todoChanged( to ); } else { QTime tim = mMoveIncidence->dtStart().time(); int secs = mMoveIncidence->dtStart().secsTo( mMoveIncidence->dtEnd()); QDateTime dt ( d,tim ); mMoveIncidence->setDtStart( dt ); ((Event*)mMoveIncidence)->setDtEnd( dt.addSecs( secs ) ); changeEventDisplay((Event*)mMoveIncidence, KOGlobals::EVENTEDITED); } mMoveIncidence->setRevision( mMoveIncidence->revision()+1 ); } } void CalendarView::removeCategories() { QPtrList<Incidence> incList = mCalendar->rawIncidences(); QStringList catList = KOPrefs::instance()->mCustomCategories; QStringList catIncList; QStringList newCatList; Incidence* inc = incList.first(); int i; int count = 0; while ( inc ) { newCatList.clear(); catIncList = inc->categories() ; for( i = 0; i< catIncList.count(); ++i ) { if ( catList.contains (catIncList[i])) newCatList.append( catIncList[i] ); } newCatList.sort(); inc->setCategories( newCatList.join(",") ); inc = incList.next(); } } int CalendarView::addCategories() { QPtrList<Incidence> incList = mCalendar->rawIncidences(); QStringList catList = KOPrefs::instance()->mCustomCategories; QStringList catIncList; Incidence* inc = incList.first(); int i; int count = 0; while ( inc ) { catIncList = inc->categories() ; for( i = 0; i< catIncList.count(); ++i ) { if ( !catList.contains (catIncList[i])) { catList.append( catIncList[i] ); //qDebug("add cat %s ", catIncList[i].latin1()); ++count; } } inc = incList.next(); } catList.sort(); KOPrefs::instance()->mCustomCategories = catList; return count; } void CalendarView::manageCategories() { KOCatPrefs* cp = new KOCatPrefs(); cp->show(); int w =cp->sizeHint().width() ; int h = cp->sizeHint().height() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); cp->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); if ( !cp->exec() ) { delete cp; return; } int count = 0; if ( cp->addCat() ) { count = addCategories(); if ( count ) { topLevelWidget()->setCaption(QString::number( count )+ i18n(" Categories added to list! ")); writeSettings(); } } else { removeCategories(); updateView(); } delete cp; } void CalendarView::beamIncidence(Incidence * Inc) { QPtrList<Incidence> delSel ; delSel.append(Inc); beamIncidenceList( delSel ); } void CalendarView::beamCalendar() { QPtrList<Incidence> delSel = mCalendar->rawIncidences(); //qDebug("beamCalendar() "); beamIncidenceList( delSel ); } void CalendarView::beamFilteredCalendar() { QPtrList<Incidence> delSel = mCalendar->incidences(); //qDebug("beamFilteredCalendar() "); beamIncidenceList( delSel ); } void CalendarView::beamIncidenceList(QPtrList<Incidence> delSel ) { if ( beamDialog->exec () == QDialog::Rejected ) return; QString fn = "/tmp/kopibeamfile"; QString mes; bool createbup = true; if ( createbup ) { QString description = "\n"; CalendarLocal* cal = new CalendarLocal(); if ( beamDialog->beamLocal() ) cal->setLocalTime(); else cal->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); Incidence *incidence = delSel.first(); bool addText = false; if ( delSel.count() < 10 ) addText = true; else { description.sprintf(i18n(" %d items?"),delSel.count() ); } while ( incidence ) { Incidence *in = incidence->clone(); if ( addText ) description += in->summary() + "\n"; cal->addIncidence( in ); incidence = delSel.next(); } if ( beamDialog->beamVcal() ) { fn += ".vcs"; FileStorage storage( cal, fn, new VCalFormat ); storage.save(); } else { fn += ".ics"; FileStorage storage( cal, fn, new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); storage.save(); } delete cal; mes = i18n("KO/Pi: Ready for beaming"); setCaption(mes); #ifndef DESKTOP_VERSION Ir *ir = new Ir( this ); connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) ); ir->send( fn, description, "text/x-vCalendar" ); #endif } } void CalendarView::beamDone( Ir *ir ) { #ifndef DESKTOP_VERSION delete ir; #endif } void CalendarView::moveIncidence(Incidence * inc ) { if ( !inc ) return; // qDebug("showDatePickerForIncidence( ) "); if ( mDateFrame->isVisible() ) mDateFrame->hide(); else { int w =mDatePicker->sizeHint().width()+2*mDateFrame->lineWidth() ; int h = mDatePicker->sizeHint().height()+2*mDateFrame->lineWidth() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); mDateFrame->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); mDateFrame->show(); } mDatePickerMode = 2; mMoveIncidence = inc ; QDate da; if ( mMoveIncidence->type() == "Todo" ) { Todo * to = (Todo *) mMoveIncidence; if ( to->hasDueDate() ) da = to->dtDue().date(); else da = QDate::currentDate(); } else { da = mMoveIncidence->dtStart().date(); } mDatePicker->setDate( da ); } void CalendarView::showDatePicker( ) { //qDebug("CalendarView::showDatePicker( ) "); if ( mDateFrame->isVisible() ) mDateFrame->hide(); else { int w =mDatePicker->sizeHint().width() ; int h = mDatePicker->sizeHint().height() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); mDateFrame->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); mDateFrame->show(); } mDatePickerMode = 1; mDatePicker->setDate( mNavigator->selectedDates().first() ); } void CalendarView::showEventEditor() { #ifdef DESKTOP_VERSION mEventEditor->show(); #else mEventEditor->showMaximized(); #endif } void CalendarView::showTodoEditor() { #ifdef DESKTOP_VERSION mTodoEditor->show(); #else mTodoEditor->showMaximized(); #endif } void CalendarView::cancelIncidence(Incidence * inc ) { inc->setCancelled( ! inc->cancelled() ); changeIncidenceDisplay( inc,KOGlobals::EVENTEDITED ); updateView(); } void CalendarView::cloneIncidence(Incidence * orgInc ) { Incidence * newInc = orgInc->clone(); newInc->recreate(); if ( newInc->type() == "Todo" ) { Todo* t = (Todo*) newInc; mTodoEditor->editTodo( t ); showTodoEditor(); if ( mTodoEditor->exec() ) { mCalendar->addTodo( t ); updateView(); } else { delete t; } } else { Event* e = (Event*) newInc; mEventEditor->editEvent( e ); showEventEditor(); if ( mEventEditor->exec() ) { mCalendar->addEvent( e ); updateView(); } else { delete e; } } } void CalendarView::newEvent() { // TODO: Replace this code by a common eventDurationHint of KOBaseView. KOAgendaView *aView = mViewManager->agendaView(); if (aView) { if (aView->selectionStart().isValid()) { if (aView->selectedIsAllDay()) { newEvent(aView->selectionStart(),aView->selectionEnd(),true); } else { newEvent(aView->selectionStart(),aView->selectionEnd()); } return; } } QDate date = mNavigator->selectedDates().first(); QDateTime current = QDateTime::currentDateTime(); if ( date <= current.date() ) { int hour = current.time().hour() +1; newEvent( QDateTime( current.date(), QTime( hour, 0, 0 ) ), QDateTime( current.date(), QTime( hour+ KOPrefs::instance()->mDefaultDuration, 0, 0 ) ) ); } else newEvent( QDateTime( date, QTime( KOPrefs::instance()->mStartTime, 0, 0 ) ), QDateTime( date, QTime( KOPrefs::instance()->mStartTime + KOPrefs::instance()->mDefaultDuration, 0, 0 ) ) ); } void CalendarView::newEvent(QDateTime fh) { newEvent(fh, QDateTime(fh.addSecs(3600*KOPrefs::instance()->mDefaultDuration))); } void CalendarView::newEvent(QDate dt) { newEvent(QDateTime(dt, QTime(0,0,0)), QDateTime(dt, QTime(0,0,0)), true); } void CalendarView::newEvent(QDateTime fromHint, QDateTime toHint, bool allDay) { mEventEditor->newEvent(fromHint,toHint,allDay); if ( mFilterView->filtersEnabled() ) { CalFilter *filter = mFilterView->selectedFilter(); if (filter && filter->showCategories()) { mEventEditor->setCategories(filter->categoryList().join(",") ); } if ( filter ) mEventEditor->setSecrecy( filter->getSecrecy() ); } showEventEditor(); } void CalendarView::todoAdded(Todo * t) { changeTodoDisplay ( t ,KOGlobals::EVENTADDED); updateTodoViews(); } void CalendarView::todoChanged(Todo * t) { emit todoModified( t, 4 ); // updateTodoViews(); } void CalendarView::todoToBeDeleted(Todo *) { //qDebug("todoToBeDeleted(Todo *) "); updateTodoViews(); } void CalendarView::todoDeleted() { //qDebug(" todoDeleted()"); updateTodoViews(); } void CalendarView::newTodo() { mTodoEditor->newTodo(QDateTime::currentDateTime().addDays(7),0,true); if ( mFilterView->filtersEnabled() ) { CalFilter *filter = mFilterView->selectedFilter(); if (filter && filter->showCategories()) { mTodoEditor->setCategories(filter->categoryList().join(",") ); } if ( filter ) mTodoEditor->setSecrecy( filter->getSecrecy() ); } showTodoEditor(); } void CalendarView::newSubTodo() { Todo *todo = selectedTodo(); if ( todo ) newSubTodo( todo ); } void CalendarView::newSubTodo(Todo *parentEvent) { mTodoEditor->newTodo(QDateTime::currentDateTime().addDays(7),parentEvent,true); showTodoEditor(); } void CalendarView::newFloatingEvent() { DateList tmpList = mNavigator->selectedDates(); QDate date = tmpList.first(); newEvent( QDateTime( date, QTime( 12, 0, 0 ) ), QDateTime( date, QTime( 12, 0, 0 ) ), true ); } void CalendarView::editEvent( Event *event ) { if ( !event ) return; if ( event->isReadOnly() ) { showEvent( event ); return; } mEventEditor->editEvent( event , mFlagEditDescription); showEventEditor(); } void CalendarView::editJournal( Journal *jour ) { if ( !jour ) return; mDialogManager->hideSearchDialog(); mViewManager->showJournalView(); mNavigator->slotDaySelect( jour->dtStart().date() ); } void CalendarView::editTodo( Todo *todo ) { if ( !todo ) return; if ( todo->isReadOnly() ) { showTodo( todo ); return; } mTodoEditor->editTodo( todo ,mFlagEditDescription); showTodoEditor(); } KOEventViewerDialog* CalendarView::getEventViewerDialog() { if ( !mEventViewerDialog ) { mEventViewerDialog = new KOEventViewerDialog(this); connect( mEventViewerDialog, SIGNAL( editIncidence( Incidence* )), this, SLOT(editIncidence( Incidence* ) ) ); connect( this, SIGNAL(configChanged()), mEventViewerDialog, SLOT(updateConfig())); connect( mEventViewerDialog, SIGNAL(jumpToTime( const QDate &)), dateNavigator(), SLOT( selectWeek( const QDate & ) ) ); connect( mEventViewerDialog, SIGNAL(showAgendaView( bool ) ), viewManager(), SLOT( showAgendaView( bool ) ) ); mEventViewerDialog->resize( 640, 480 ); } return mEventViewerDialog; } void CalendarView::showEvent(Event *event) { getEventViewerDialog()->setEvent(event); getEventViewerDialog()->showMe(); } void CalendarView::showTodo(Todo *event) { getEventViewerDialog()->setTodo(event); getEventViewerDialog()->showMe(); } void CalendarView::showJournal( Journal *jour ) { getEventViewerDialog()->setJournal(jour); getEventViewerDialog()->showMe(); } // void CalendarView::todoModified (Todo *event, int changed) // { // // if (mDialogList.find (event) != mDialogList.end ()) { // // kdDebug() << "Todo modified and open" << endl; // // KOTodoEditor* temp = (KOTodoEditor *) mDialogList[event]; // // temp->modified (changed); // // } // mViewManager->updateView(); // } void CalendarView::appointment_show() { Event *anEvent = 0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } showEvent(anEvent); } void CalendarView::appointment_edit() { Event *anEvent = 0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } editEvent(anEvent); } void CalendarView::appointment_delete() { Event *anEvent = 0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } deleteEvent(anEvent); } void CalendarView::todo_unsub(Todo *anTodo ) { // Todo *anTodo = selectedTodo(); if (!anTodo) return; if (!anTodo->relatedTo()) return; anTodo->relatedTo()->removeRelation(anTodo); anTodo->setRelatedTo(0); anTodo->updated(); anTodo->setRelatedToUid(""); setModified(true); updateView(); } void CalendarView::deleteTodo(Todo *todo) { if (!todo) { KNotifyClient::beep(); return; } if (KOPrefs::instance()->mConfirm) { switch (msgItemDelete()) { case KMessageBox::Continue: // OK if (!todo->relations().isEmpty()) { KMessageBox::sorry(this,i18n("Cannot delete To-Do\nwhich has children."), i18n("Delete To-Do")); } else { checkExternalId( todo ); calendar()->deleteTodo(todo); changeTodoDisplay( todo,KOGlobals::EVENTDELETED ); updateView(); } break; } // switch } else { if (!todo->relations().isEmpty()) { KMessageBox::sorry(this,i18n("Cannot delete To-Do\nwhich has children."), i18n("Delete To-Do")); } else { checkExternalId( todo ); mCalendar->deleteTodo(todo); changeTodoDisplay( todo,KOGlobals::EVENTDELETED ); updateView(); } } emit updateSearchDialog(); } void CalendarView::deleteJournal(Journal *jour) { if (!jour) { KNotifyClient::beep(); return; } if (KOPrefs::instance()->mConfirm) { switch (msgItemDelete()) { case KMessageBox::Continue: // OK calendar()->deleteJournal(jour); updateView(); break; } // switch } else { calendar()->deleteJournal(jour);; updateView(); } emit updateSearchDialog(); } void CalendarView::deleteEvent(Event *anEvent) { if (!anEvent) { KNotifyClient::beep(); return; } if (anEvent->recurrence()->doesRecur()) { QDate itemDate = mViewManager->currentSelectionDate(); int km; if (!itemDate.isValid()) { //kdDebug() << "Date Not Valid" << endl; if (KOPrefs::instance()->mConfirm) { km = KMessageBox::warningContinueCancel(this,anEvent->summary() + i18n("\nThis event recurs\nover multiple dates.\nAre you sure you want\nto delete this event\nand all its recurrences?"), i18n("KO/Pi Confirmation"),i18n("Delete All")); if ( km == KMessageBox::Continue ) km = KMessageBox::No; // No = all below } else km = KMessageBox::No; } else { km = KMessageBox::warningYesNoCancel(this,anEvent->summary() + i18n("\nThis event recurs\nover multiple dates.\nDo you want to delete\nall it's recurrences,\nor only the current one on:\n")+ KGlobal::locale()->formatDate(itemDate)+i18n(" ?\n\nDelete:\n"), i18n("KO/Pi Confirmation"),i18n("Current"), i18n("All")); } switch(km) { case KMessageBox::No: // Continue // all //qDebug("KMessageBox::No "); if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0) schedule(Scheduler::Cancel,anEvent); checkExternalId( anEvent); mCalendar->deleteEvent(anEvent); changeEventDisplay(anEvent,KOGlobals::EVENTDELETED); break; // Disabled because it does not work //#if 0 case KMessageBox::Yes: // just this one //QDate qd = mNavigator->selectedDates().first(); //if (!qd.isValid()) { // kdDebug() << "no date selected, or invalid date" << endl; // KNotifyClient::beep(); // return; //} //while (!anEvent->recursOn(qd)) qd = qd.addDays(1); if (itemDate!=QDate(1,1,1) || itemDate.isValid()) { anEvent->addExDate(itemDate); int duration = anEvent->recurrence()->duration(); if ( duration > 0 ) { anEvent->recurrence()->setDuration( duration - 1 ); } changeEventDisplay(anEvent, KOGlobals::EVENTEDITED); } break; //#endif } // switch } else { if (KOPrefs::instance()->mConfirm) { switch (KMessageBox::warningContinueCancel(this,anEvent->summary() + i18n("\nAre you sure you want\nto delete this event?"), i18n("KO/Pi Confirmation"),i18n("Delete"))) { case KMessageBox::Continue: // OK if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0) schedule(Scheduler::Cancel,anEvent); checkExternalId( anEvent); mCalendar->deleteEvent(anEvent); changeEventDisplay(anEvent, KOGlobals::EVENTDELETED); break; } // switch } else { if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0) schedule(Scheduler::Cancel,anEvent); checkExternalId( anEvent); mCalendar->deleteEvent(anEvent); changeEventDisplay(anEvent, KOGlobals::EVENTDELETED); } } // if-else emit updateSearchDialog(); } bool CalendarView::deleteEvent(const QString &uid) { Event *ev = mCalendar->event(uid); if (ev) { deleteEvent(ev); return true; } else { return false; } } /*****************************************************************************/ void CalendarView::action_mail() { #ifndef KORG_NOMAIL KOMailClient mailClient; Incidence *incidence = currentSelection(); if (!incidence) { KMessageBox::sorry(this,i18n("Can't generate mail:\nNo event selected.")); return; } if(incidence->attendeeCount() == 0 ) { KMessageBox::sorry(this, i18n("Can't generate mail:\nNo attendees defined.\n")); return; } CalendarLocal cal_tmp; Event *event = 0; Event *ev = 0; if ( incidence && incidence->type() == "Event" ) { event = static_cast<Event *>(incidence); ev = new Event(*event); cal_tmp.addEvent(ev); } ICalFormat mForm( KOPrefs::instance()->mUseQuicksave); QString attachment = mForm.toString( &cal_tmp ); if (ev) delete(ev); mailClient.mailAttendees(currentSelection(), attachment); #endif #if 0 Event *anEvent = 0; if (mViewManager->currentView()->isEventView()) { anEvent = dynamic_cast<Event *>((mViewManager->currentView()->selectedIncidences()).first()); } if (!anEvent) { KMessageBox::sorry(this,i18n("Can't generate mail:\nNo event selected.")); return; } if(anEvent->attendeeCount() == 0 ) { KMessageBox::sorry(this, i18n("Can't generate mail:\nNo attendees defined.\n")); return; } mailobject.emailEvent(anEvent); #endif } void CalendarView::schedule_publish(Incidence *incidence) { Event *event = 0; Todo *todo = 0; if (incidence == 0) { incidence = mViewManager->currentView()->selectedIncidences().first(); if (incidence == 0) { incidence = mTodoList->selectedIncidences().first(); } } if ( incidence && incidence->type() == "Event" ) { event = static_cast<Event *>(incidence); } else { if ( incidence && incidence->type() == "Todo" ) { todo = static_cast<Todo *>(incidence); } } if (!event && !todo) { KMessageBox::sorry(this,i18n("No event selected.")); return; } PublishDialog *publishdlg = new PublishDialog(); if (incidence->attendeeCount()>0) { QPtrList<Attendee> attendees = incidence->attendees(); attendees.first(); while ( attendees.current()!=0 ) { publishdlg->addAttendee(attendees.current()); attendees.next(); } } bool send = true; if ( KOPrefs::instance()->mMailClient == KOPrefs::MailClientSendmail ) { if ( publishdlg->exec() != QDialog::Accepted ) send = false; } if ( send ) { OutgoingDialog *dlg = mDialogManager->outgoingDialog(); if ( event ) { Event *ev = new Event(*event); ev->registerObserver(0); ev->clearAttendees(); if (!dlg->addMessage(ev,Scheduler::Publish,publishdlg->addresses())) { delete(ev); } } else { if ( todo ) { Todo *ev = new Todo(*todo); ev->registerObserver(0); ev->clearAttendees(); if (!dlg->addMessage(ev,Scheduler::Publish,publishdlg->addresses())) { delete(ev); } } } } delete publishdlg; } void CalendarView::schedule_request(Incidence *incidence) { schedule(Scheduler::Request,incidence); } void CalendarView::schedule_refresh(Incidence *incidence) { schedule(Scheduler::Refresh,incidence); } void CalendarView::schedule_cancel(Incidence *incidence) { schedule(Scheduler::Cancel,incidence); } void CalendarView::schedule_add(Incidence *incidence) { schedule(Scheduler::Add,incidence); } void CalendarView::schedule_reply(Incidence *incidence) { schedule(Scheduler::Reply,incidence); } void CalendarView::schedule_counter(Incidence *incidence) { schedule(Scheduler::Counter,incidence); } void CalendarView::schedule_declinecounter(Incidence *incidence) { schedule(Scheduler::Declinecounter,incidence); } void CalendarView::schedule_publish_freebusy(int daysToPublish) { diff --git a/korganizer/korganizer.pro b/korganizer/korganizer.pro index 9fdcd2f..543db86 100644 --- a/korganizer/korganizer.pro +++ b/korganizer/korganizer.pro @@ -1,193 +1,192 @@ TEMPLATE = app CONFIG = qt warn_on TARGET = kopi OBJECTS_DIR = _obj/ MOC_DIR = _moc DESTDIR= ../bin include( ../variables.pri ) INCLUDEPATH += ../microkde ../ interfaces ../microkde/kdecore ../microkde/kdeui ../microkde/kio/kfile ../microkde/kio/kio ../libkdepim #../qtcompat DEFINES += KORG_NODND KORG_NOPLUGINS KORG_NOARCHIVE KORG_NOMAIL DEFINES += KORG_NODCOP KORG_NOKALARMD KORG_NORESOURCEVIEW KORG_NOSPLITTER #KORG_NOPRINTER KORG_NOKABC DEFINES += KORG_NOLVALTERNATION DEFINES += DESKTOP_VERSION unix : { LIBS += ../bin/libmicrokdepim.so LIBS += ../bin/libmicrokcal.so LIBS += ../bin/libmicrokde.so LIBS += ../bin/libmicrokabc.so -LIBS += ../bin/libmicrogammu.so LIBS += -lbluetooth LIBS += -lsdp LIBS += -lldap OBJECTS_DIR = obj/unix MOC_DIR = moc/unix } win32: { DEFINES += _WIN32_ LIBS += ../bin/microkdepim.lib LIBS += ../bin/microkcal.lib LIBS += ../bin/microkde.lib LIBS += ../bin/microkabc.lib LIBS += ../libical/lib/ical.lib LIBS += ../libical/lib/icalss.lib #LIBS += atls.lib LIBS += mfc71u.lib QMAKE_LINK += /NODEFAULTLIB:LIBC #QMAKE_LINK += /NODEFAULTLIB:MSVCRT #QMAKE_LINK += /NODEFAULTLIB:uafxcw.lib OBJECTS_DIR = obj/win MOC_DIR = moc/win } INTERFACES = kofilterview_base.ui # filteredit_base.ui # kdateedit.h \ HEADERS = \ filteredit_base.h \ alarmclient.h \ calendarview.h \ customlistviewitem.h \ datenavigator.h \ docprefs.h \ filtereditdialog.h \ incomingdialog.h \ incomingdialog_base.h \ interfaces/korganizer/baseview.h \ interfaces/korganizer/calendarviewbase.h \ journalentry.h \ kdatenavigator.h \ koagenda.h \ koagendaitem.h \ koagendaview.h \ kocounterdialog.h \ kodaymatrix.h \ kodialogmanager.h \ koeditordetails.h \ koeditorgeneral.h \ koeditorgeneralevent.h \ koeditorgeneraltodo.h \ koeditorrecurrence.h \ koeventeditor.h \ koeventpopupmenu.h \ koeventview.h \ koeventviewer.h \ koeventviewerdialog.h \ kofilterview.h \ koglobals.h \ koincidenceeditor.h \ kojournalview.h \ kolistview.h \ kolocationbox.h \ komonthview.h \ koprefs.h \ koprefsdialog.h \ kotimespanview.h \ kotodoeditor.h \ kotodoview.h \ kotodoviewitem.h \ koviewmanager.h \ kowhatsnextview.h \ ktimeedit.h \ lineview.h \ mainwindow.h \ navigatorbar.h \ outgoingdialog.h \ outgoingdialog_base.h \ publishdialog.h \ publishdialog_base.h \ savetemplatedialog.h \ searchdialog.h \ simplealarmclient.h \ statusdialog.h \ timeline.h \ timespanview.h \ version.h \ ../kalarmd/alarmdialog.h \ SOURCES = \ filteredit_base.cpp \ calendarview.cpp \ datenavigator.cpp \ docprefs.cpp \ filtereditdialog.cpp \ incomingdialog.cpp \ incomingdialog_base.cpp \ journalentry.cpp \ kdatenavigator.cpp \ koagenda.cpp \ koagendaitem.cpp \ koagendaview.cpp \ kocounterdialog.cpp \ kodaymatrix.cpp \ kodialogmanager.cpp \ koeditordetails.cpp \ koeditorgeneral.cpp \ koeditorgeneralevent.cpp \ koeditorgeneraltodo.cpp \ koeditorrecurrence.cpp \ koeventeditor.cpp \ koeventpopupmenu.cpp \ koeventview.cpp \ koeventviewer.cpp \ koeventviewerdialog.cpp \ kofilterview.cpp \ koglobals.cpp \ koincidenceeditor.cpp \ kojournalview.cpp \ kolistview.cpp \ kolocationbox.cpp \ komonthview.cpp \ koprefs.cpp \ koprefsdialog.cpp \ kotimespanview.cpp \ kotodoeditor.cpp \ kotodoview.cpp \ kotodoviewitem.cpp \ koviewmanager.cpp \ kowhatsnextview.cpp \ ktimeedit.cpp \ lineview.cpp \ main.cpp \ mainwindow.cpp \ navigatorbar.cpp \ outgoingdialog.cpp \ outgoingdialog_base.cpp \ publishdialog.cpp \ publishdialog_base.cpp \ savetemplatedialog.cpp \ searchdialog.cpp \ simplealarmclient.cpp \ statusdialog.cpp \ timeline.cpp \ timespanview.cpp \ ../kalarmd/alarmdialog.cpp HEADERS += calprintbase.h calprinter.h calprintplugins.h cellitem.h INTERFACES += calprintdayconfig_base.ui \ calprintmonthconfig_base.ui \ calprinttodoconfig_base.ui \ calprintweekconfig_base.ui SOURCES += calprintbase.cpp calprinter.cpp calprintplugins.cpp cellitem.cpp win32: { HEADERS += ../outport/msoutl9.h \ koimportoldialog.h SOURCES += ../outport/msoutl9.cpp \ koimportoldialog.cpp } diff --git a/libkcal/incidence.cpp b/libkcal/incidence.cpp index d9bda64..56c9801 100644 --- a/libkcal/incidence.cpp +++ b/libkcal/incidence.cpp @@ -1,594 +1,599 @@ /* This file is part of libkcal. Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <kglobal.h> #include <klocale.h> #include <kdebug.h> #include "calformat.h" #include "incidence.h" #include "todo.h" using namespace KCal; Incidence::Incidence() : IncidenceBase(), mRelatedTo(0), mSecrecy(SecrecyPublic), mPriority(3) { mRecurrence = new Recurrence(this); mCancelled = false; recreate(); mHasStartDate = true; mAlarms.setAutoDelete(true); mAttachments.setAutoDelete(true); } Incidence::Incidence( const Incidence &i ) : IncidenceBase( i ) { // TODO: reenable attributes currently commented out. mRevision = i.mRevision; mCreated = i.mCreated; mDescription = i.mDescription; mSummary = i.mSummary; mCategories = i.mCategories; // Incidence *mRelatedTo; Incidence *mRelatedTo; mRelatedTo = 0; mRelatedToUid = i.mRelatedToUid; // QPtrList<Incidence> mRelations; QPtrList<Incidence> mRelations; mExDates = i.mExDates; mAttachments = i.mAttachments; mResources = i.mResources; mSecrecy = i.mSecrecy; mPriority = i.mPriority; mLocation = i.mLocation; mCancelled = i.mCancelled; mHasStartDate = i.mHasStartDate; QPtrListIterator<Alarm> it( i.mAlarms ); const Alarm *a; while( (a = it.current()) ) { Alarm *b = new Alarm( *a ); b->setParent( this ); mAlarms.append( b ); ++it; } mAlarms.setAutoDelete(true); mRecurrence = new Recurrence( *(i.mRecurrence), this ); } Incidence::~Incidence() { Incidence *ev; QPtrList<Incidence> Relations = relations(); for (ev=Relations.first();ev;ev=Relations.next()) { if (ev->relatedTo() == this) ev->setRelatedTo(0); } if (relatedTo()) relatedTo()->removeRelation(this); delete mRecurrence; } bool Incidence::cancelled() const { return mCancelled; } void Incidence::setCancelled( bool b ) { mCancelled = b; updated(); } bool Incidence::hasStartDate() const { return mHasStartDate; } void Incidence::setHasStartDate(bool f) { if (mReadOnly) return; mHasStartDate = f; updated(); } // A string comparison that considers that null and empty are the same static bool stringCompare( const QString& s1, const QString& s2 ) { if ( s1.isEmpty() && s2.isEmpty() ) return true; return s1 == s2; } bool KCal::operator==( const Incidence& i1, const Incidence& i2 ) { if( i1.alarms().count() != i2.alarms().count() ) { return false; // no need to check further } if ( i1.alarms().count() > 0 ) { if ( !( *(i1.alarms().first()) == *(i2.alarms().first())) ) { qDebug("alarm not equal "); return false; } } #if 0 QPtrListIterator<Alarm> a1( i1.alarms() ); QPtrListIterator<Alarm> a2( i2.alarms() ); for( ; a1.current() && a2.current(); ++a1, ++a2 ) { if( *a1.current() == *a2.current() ) { continue; } else { return false; } } #endif if ( ! operator==( (const IncidenceBase&)i1, (const IncidenceBase&)i2 ) ) return false; if ( i1.hasStartDate() == i2.hasStartDate() ) { if ( i1.hasStartDate() ) { if ( i1.dtStart() != i2.dtStart() ) return false; } } else { return false; } if (!( *i1.recurrence() == *i2.recurrence()) ) { qDebug("recurrence is NOT equal "); return false; } return // i1.created() == i2.created() && stringCompare( i1.description(), i2.description() ) && stringCompare( i1.summary(), i2.summary() ) && i1.categories() == i2.categories() && // no need to compare mRelatedTo stringCompare( i1.relatedToUid(), i2.relatedToUid() ) && // i1.relations() == i2.relations() && i1.exDates() == i2.exDates() && i1.attachments() == i2.attachments() && i1.resources() == i2.resources() && i1.secrecy() == i2.secrecy() && i1.priority() == i2.priority() && stringCompare( i1.location(), i2.location() ); } void Incidence::recreate() { setCreated(QDateTime::currentDateTime()); setUid(CalFormat::createUniqueId()); setRevision(0); setLastModified(QDateTime::currentDateTime()); } void Incidence::setReadOnly( bool readOnly ) { IncidenceBase::setReadOnly( readOnly ); recurrence()->setRecurReadOnly( readOnly); } void Incidence::setCreated(QDateTime created) { if (mReadOnly) return; mCreated = getEvenTime(created); } QDateTime Incidence::created() const { return mCreated; } void Incidence::setRevision(int rev) { if (mReadOnly) return; mRevision = rev; updated(); } int Incidence::revision() const { return mRevision; } void Incidence::setDtStart(const QDateTime &dtStart) { QDateTime dt = getEvenTime(dtStart); recurrence()->setRecurStart( dt); IncidenceBase::setDtStart( dt ); } void Incidence::setDescription(const QString &description) { if (mReadOnly) return; mDescription = description; updated(); } QString Incidence::description() const { return mDescription; } void Incidence::setSummary(const QString &summary) { if (mReadOnly) return; mSummary = summary; updated(); } QString Incidence::summary() const { return mSummary; } void Incidence::setCategories(const QStringList &categories) { if (mReadOnly) return; mCategories = categories; updated(); } // TODO: remove setCategories(QString) function void Incidence::setCategories(const QString &catStr) { if (mReadOnly) return; mCategories.clear(); if (catStr.isEmpty()) return; mCategories = QStringList::split(",",catStr); QStringList::Iterator it; for(it = mCategories.begin();it != mCategories.end(); ++it) { *it = (*it).stripWhiteSpace(); } updated(); } QStringList Incidence::categories() const { return mCategories; } QString Incidence::categoriesStr() { return mCategories.join(","); } void Incidence::setRelatedToUid(const QString &relatedToUid) { if (mReadOnly) return; mRelatedToUid = relatedToUid; } QString Incidence::relatedToUid() const { return mRelatedToUid; } void Incidence::setRelatedTo(Incidence *relatedTo) { //qDebug("Incidence::setRelatedTo %d ", relatedTo); //qDebug("setRelatedTo(Incidence *relatedTo) %s %s", summary().latin1(), relatedTo->summary().latin1() ); if (mReadOnly || mRelatedTo == relatedTo) return; if(mRelatedTo) { // updated(); mRelatedTo->removeRelation(this); } mRelatedTo = relatedTo; if (mRelatedTo) mRelatedTo->addRelation(this); } Incidence *Incidence::relatedTo() const { return mRelatedTo; } QPtrList<Incidence> Incidence::relations() const { return mRelations; } void Incidence::addRelation(Incidence *event) { if( mRelations.findRef( event ) == -1 ) { mRelations.append(event); //updated(); } } void Incidence::removeRelation(Incidence *event) { mRelations.removeRef(event); // if (event->getRelatedTo() == this) event->setRelatedTo(0); } bool Incidence::recursOn(const QDate &qd) const { if (recurrence()->recursOnPure(qd) && !isException(qd)) return true; else return false; } void Incidence::setExDates(const DateList &exDates) { if (mReadOnly) return; mExDates = exDates; recurrence()->setRecurExDatesCount(mExDates.count()); updated(); } void Incidence::addExDate(const QDate &date) { if (mReadOnly) return; mExDates.append(date); recurrence()->setRecurExDatesCount(mExDates.count()); updated(); } DateList Incidence::exDates() const { return mExDates; } bool Incidence::isException(const QDate &date) const { DateList::ConstIterator it; for( it = mExDates.begin(); it != mExDates.end(); ++it ) { if ( (*it) == date ) { return true; } } return false; } void Incidence::addAttachment(Attachment *attachment) { if (mReadOnly || !attachment) return; mAttachments.append(attachment); updated(); } void Incidence::deleteAttachment(Attachment *attachment) { mAttachments.removeRef(attachment); } void Incidence::deleteAttachments(const QString& mime) { Attachment *at = mAttachments.first(); while (at) { if (at->mimeType() == mime) mAttachments.remove(); else at = mAttachments.next(); } } QPtrList<Attachment> Incidence::attachments() const { return mAttachments; } QPtrList<Attachment> Incidence::attachments(const QString& mime) const { QPtrList<Attachment> attachments; QPtrListIterator<Attachment> it( mAttachments ); Attachment *at; while ( (at = it.current()) ) { if (at->mimeType() == mime) attachments.append(at); ++it; } return attachments; } void Incidence::setResources(const QStringList &resources) { if (mReadOnly) return; mResources = resources; updated(); } QStringList Incidence::resources() const { return mResources; } void Incidence::setPriority(int priority) { if (mReadOnly) return; mPriority = priority; updated(); } int Incidence::priority() const { return mPriority; } void Incidence::setSecrecy(int sec) { if (mReadOnly) return; mSecrecy = sec; updated(); } int Incidence::secrecy() const { return mSecrecy; } QString Incidence::secrecyStr() const { return secrecyName(mSecrecy); } QString Incidence::secrecyName(int secrecy) { switch (secrecy) { case SecrecyPublic: return i18n("Public"); break; case SecrecyPrivate: return i18n("Private"); break; case SecrecyConfidential: return i18n("Confidential"); break; default: return i18n("Undefined"); break; } } QStringList Incidence::secrecyList() { QStringList list; list << secrecyName(SecrecyPublic); list << secrecyName(SecrecyPrivate); list << secrecyName(SecrecyConfidential); return list; } QPtrList<Alarm> Incidence::alarms() const { return mAlarms; } Alarm* Incidence::newAlarm() { Alarm* alarm = new Alarm(this); mAlarms.append(alarm); // updated(); return alarm; } void Incidence::addAlarm(Alarm *alarm) { mAlarms.append(alarm); updated(); } void Incidence::removeAlarm(Alarm *alarm) { mAlarms.removeRef(alarm); updated(); } void Incidence::clearAlarms() { mAlarms.clear(); updated(); } bool Incidence::isAlarmEnabled() const { Alarm* alarm; for (QPtrListIterator<Alarm> it(mAlarms); (alarm = it.current()) != 0; ++it) { if (alarm->enabled()) return true; } return false; } Recurrence *Incidence::recurrence() const { return mRecurrence; } +void Incidence::setRecurrence( Recurrence * r) +{ + delete mRecurrence; + mRecurrence = r; +} void Incidence::setLocation(const QString &location) { if (mReadOnly) return; mLocation = location; updated(); } QString Incidence::location() const { return mLocation; } ushort Incidence::doesRecur() const { if ( mRecurrence ) return mRecurrence->doesRecur(); else return Recurrence::rNone; } QDateTime Incidence::getNextOccurence( const QDateTime& dt, bool* ok ) const { QDateTime incidenceStart = dt; *ok = false; if ( doesRecur() ) { bool last; recurrence()->getPreviousDateTime( incidenceStart , &last ); int count = 0; if ( !last ) { while ( !last ) { ++count; incidenceStart = recurrence()->getNextDateTime( incidenceStart, &last ); if ( recursOn( incidenceStart.date() ) ) { last = true; // exit while llop } else { if ( last ) { // no alarm on last recurrence return QDateTime (); } int year = incidenceStart.date().year(); // workaround for bug in recurrence if ( count == 100 || year < 1980 || year > 5000 ) { return QDateTime (); } incidenceStart = incidenceStart.addSecs( 1 ); } } } else { return QDateTime (); } } else { if ( hasStartDate () ) { incidenceStart = dtStart(); } } if ( incidenceStart > dt ) *ok = true; return incidenceStart; } diff --git a/libkcal/incidence.h b/libkcal/incidence.h index d1972cb..7dc6f10 100644 --- a/libkcal/incidence.h +++ b/libkcal/incidence.h @@ -1,298 +1,298 @@ /* This file is part of libkcal. Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef INCIDENCE_H #define INCIDENCE_H // // Incidence - base class of calendaring components // #include <qdatetime.h> #include <qstringlist.h> #include <qvaluelist.h> #include "recurrence.h" #include "alarm.h" #include "attachment.h" #include "listbase.h" #include "incidencebase.h" namespace KCal { class Event; class Todo; class Journal; /** This class provides the base class common to all calendar components. */ class Incidence : public IncidenceBase { public: /** This class provides the interface for a visitor of calendar components. It serves as base class for concrete visitors, which implement certain actions on calendar components. It allows to add functions, which operate on the concrete types of calendar components, without changing the calendar component classes. */ class Visitor { public: /** Destruct Incidence::Visitor */ virtual ~Visitor() {} /** Reimplement this function in your concrete subclass of IncidenceVisitor to perform actions on an Event object. */ virtual bool visit(Event *) { return false; } /** Reimplement this function in your concrete subclass of IncidenceVisitor to perform actions on an Todo object. */ virtual bool visit(Todo *) { return false; } /** Reimplement this function in your concrete subclass of IncidenceVisitor to perform actions on an Journal object. */ virtual bool visit(Journal *) { return false; } protected: /** Constructor is protected to prevent direct creation of visitor base class. */ Visitor() {} }; /** This class implements a visitor for adding an Incidence to a resource supporting addEvent(), addTodo() and addJournal() calls. */ template<class T> class AddVisitor : public Visitor { public: AddVisitor( T *r ) : mResource( r ) {} bool visit( Event *e ) { return mResource->addEvent( e ); } bool visit( Todo *t ) { return mResource->addTodo( t ); } bool visit( Journal *j ) { return mResource->addJournal( j ); } private: T *mResource; }; /** enumeration for describing an event's secrecy. */ enum { SecrecyPublic = 0, SecrecyPrivate = 1, SecrecyConfidential = 2 }; typedef ListBase<Incidence> List; Incidence(); Incidence(const Incidence &); ~Incidence(); /** Accept IncidenceVisitor. A class taking part in the visitor mechanism has to provide this implementation: <pre> bool accept(Visitor &v) { return v.visit(this); } </pre> */ virtual bool accept(Visitor &) { return false; } virtual Incidence *clone() = 0; virtual QDateTime getNextAlarmDateTime( bool * ok, int * offset ) const = 0; void setReadOnly( bool ); /** Recreate event. The event is made a new unique event, but already stored event information is preserved. Sets uniquie id, creation date, last modification date and revision number. */ void recreate(); /** set creation date */ void setCreated(QDateTime); /** return time and date of creation. */ QDateTime created() const; /** set the number of revisions this event has seen */ void setRevision(int rev); /** return the number of revisions this event has seen */ int revision() const; /** Set starting date/time. */ virtual void setDtStart(const QDateTime &dtStart); /** Return the incidence's ending date/time as a QDateTime. */ virtual QDateTime dtEnd() const { return QDateTime(); } /** sets the event's lengthy description. */ void setDescription(const QString &description); /** returns a reference to the event's description. */ QString description() const; /** sets the event's short summary. */ void setSummary(const QString &summary); /** returns a reference to the event's summary. */ QString summary() const; /** set event's applicable categories */ void setCategories(const QStringList &categories); /** set event's categories based on a comma delimited string */ void setCategories(const QString &catStr); /** return categories in a list */ QStringList categories() const; /** return categories as a comma separated string */ QString categoriesStr(); /** point at some other event to which the event relates. This function should * only be used when constructing a calendar before the related Event * exists. */ void setRelatedToUid(const QString &); /** what event does this one relate to? This function should * only be used when constructing a calendar before the related Event * exists. */ QString relatedToUid() const; /** point at some other event to which the event relates */ void setRelatedTo(Incidence *relatedTo); /** what event does this one relate to? */ Incidence *relatedTo() const; /** All events that are related to this event */ QPtrList<Incidence> relations() const; /** Add an event which is related to this event */ void addRelation(Incidence *); /** Remove event that is related to this event */ void removeRelation(Incidence *); /** returns the list of dates which are exceptions to the recurrence rule */ DateList exDates() const; /** sets the list of dates which are exceptions to the recurrence rule */ void setExDates(const DateList &_exDates); void setExDates(const char *dates); /** Add a date to the list of exceptions of the recurrence rule. */ void addExDate(const QDate &date); /** returns true if there is an exception for this date in the recurrence rule set, or false otherwise. */ bool isException(const QDate &qd) const; /** add attachment to this event */ void addAttachment(Attachment *attachment); /** remove and delete a specific attachment */ void deleteAttachment(Attachment *attachment); /** remove and delete all attachments with this mime type */ void deleteAttachments(const QString& mime); /** return list of all associated attachments */ QPtrList<Attachment> attachments() const; /** find a list of attachments with this mime type */ QPtrList<Attachment> attachments(const QString& mime) const; /** sets the event's status the value specified. See the enumeration * above for possible values. */ void setSecrecy(int); /** return the event's secrecy. */ int secrecy() const; /** return the event's secrecy in string format. */ QString secrecyStr() const; /** return list of all availbale secrecy classes */ static QStringList secrecyList(); /** return human-readable name of secrecy class */ static QString secrecyName(int); /** returns TRUE if the date specified is one on which the event will * recur. */ bool recursOn(const QDate &qd) const; // VEVENT and VTODO, but not VJOURNAL (move to EventBase class?): /** set resources used, such as Office, Car, etc. */ void setResources(const QStringList &resources); /** return list of current resources */ QStringList resources() const; /** set the event's priority, 0 is undefined, 1 highest (decreasing order) */ void setPriority(int priority); /** get the event's priority */ int priority() const; /** All alarms that are associated with this incidence */ QPtrList<Alarm> alarms() const; /** Create a new alarm which is associated with this incidence */ Alarm* newAlarm(); /** Add an alarm which is associated with this incidence */ void addAlarm(Alarm*); /** Remove an alarm that is associated with this incidence */ void removeAlarm(Alarm*); /** Remove all alarms that are associated with this incidence */ void clearAlarms(); /** return whether any alarm associated with this incidence is enabled */ bool isAlarmEnabled() const; /** Return the recurrence rule associated with this incidence. If there is none, returns an appropriate (non-0) object. */ Recurrence *recurrence() const; - + void setRecurrence(Recurrence * r); /** Forward to Recurrence::doesRecur(). */ ushort doesRecur() const; /** set the event's/todo's location. Do _not_ use it with journal */ void setLocation(const QString &location); /** return the event's/todo's location. Do _not_ use it with journal */ QString location() const; /** returns TRUE or FALSE depending on whether the todo has a start date */ bool hasStartDate() const; /** sets the event's hasStartDate value. */ void setHasStartDate(bool f); QDateTime getNextOccurence( const QDateTime& dt, bool* yes ) const; bool cancelled() const; void setCancelled( bool b ); protected: QPtrList<Alarm> mAlarms; private: int mRevision; bool mCancelled; // base components of jounal, event and todo QDateTime mCreated; QString mDescription; QString mSummary; QStringList mCategories; Incidence *mRelatedTo; QString mRelatedToUid; QPtrList<Incidence> mRelations; DateList mExDates; QPtrList<Attachment> mAttachments; QStringList mResources; bool mHasStartDate; // if todo has associated start date int mSecrecy; int mPriority; // 1 = highest, 2 = less, etc. //QPtrList<Alarm> mAlarms; Recurrence *mRecurrence; QString mLocation; }; bool operator==( const Incidence&, const Incidence& ); } #endif diff --git a/libkcal/phoneformat.cpp b/libkcal/phoneformat.cpp index 1769b37..0bc9125 100644 --- a/libkcal/phoneformat.cpp +++ b/libkcal/phoneformat.cpp @@ -1,1691 +1,581 @@ /* This file is part of libkcal. - Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + Copyright (c) 2004 Lutz Rogowski <rogowski@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qdatetime.h> #include <qstring.h> #include <qapplication.h> #include <qptrlist.h> #include <qregexp.h> #include <qmessagebox.h> #include <qclipboard.h> #include <qfile.h> #include <qtextstream.h> #include <qtextcodec.h> #include <qxml.h> #include <qlabel.h> #include <kdebug.h> #include <klocale.h> #include <kglobal.h> #include "calendar.h" #include "alarm.h" #include "recurrence.h" #include "calendarlocal.h" #include "phoneformat.h" #include "syncdefines.h" using namespace KCal; - class PhoneParser : public QObject { public: - PhoneParser( Calendar *calendar, QString profileName ) : mCalendar( calendar ), mProfileName ( profileName ) { + PhoneParser( ) { ; } - bool readTodo( Calendar *existingCalendar,GSM_ToDoEntry *ToDo, GSM_StateMachine* s) - { - - int id = ToDo->Location; - Todo *todo; - todo = existingCalendar->todo( mProfileName ,QString::number( id ) ); - if (todo ) - todo = (Todo *)todo->clone(); - else - todo = new Todo; - todo->setID( mProfileName,QString::number( id ) ); - todo->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL ); - int priority; - switch (ToDo->Priority) { - case GSM_Priority_Low : priority = 5; break; - case GSM_Priority_Medium : priority = 3; break; - case GSM_Priority_High : priority = 1; break; - default :priority = 3 ; break; - } - todo->setPriority( priority ); - GSM_Phone_Functions *Phone; - Phone=s->Phone.Functions; - int j; - GSM_DateTime* dtp; - bool alarm = false; - QDateTime alarmDt; - GSM_Category Category; - int error; - for (j=0;j<ToDo->EntriesNum;j++) { - - //qDebug(" for todo %d",ToDo->Location ); - switch (ToDo->Entries[j].EntryType) { - case TODO_END_DATETIME: - dtp = &ToDo->Entries[j].Date ; - todo->setDtDue (fromGSM ( dtp )); - break; - case TODO_COMPLETED: - if ( ToDo->Entries[j].Number == 1 ) { - todo->setCompleted( true ); - } - else { - todo->setCompleted( false ); - } - break; - case TODO_ALARM_DATETIME: - dtp = &ToDo->Entries[j].Date ; - alarm = true; - alarmDt = fromGSM ( dtp ); - break; - case TODO_SILENT_ALARM_DATETIME: - dtp = &ToDo->Entries[j].Date ; - alarm = true; - alarmDt = fromGSM ( dtp ); - break; - case TODO_TEXT: - //qDebug(" text *%s* ", (const char*) DecodeUnicodeConsole(ToDo->Entries[j].Text )); - todo->setSummary( QString::fromUtf8 ( (const char*)DecodeUnicodeConsole(ToDo->Entries[j].Text ))); - break; - case TODO_PRIVATE: - if ( ToDo->Entries[j].Number == 1 ) - todo->setSecrecy( Incidence::SecrecyPrivate ); - else - todo->setSecrecy( Incidence::SecrecyPublic ); - break; - case TODO_CATEGORY: - Category.Location = ToDo->Entries[j].Number; - Category.Type = Category_ToDo; - error=Phone->GetCategory(s, &Category); - if (error == ERR_NONE) { - QStringList cat = todo->categories(); - QString nCat = QString ( (const char*)Category.Name ); - if ( !nCat.isEmpty() ) - if ( !cat.contains( nCat )) { - cat << nCat; - todo->setCategories( cat ); - } - } - break; - case TODO_CONTACTID: -#if 0 - // not supported - entry.Location = ToDo->Entries[j].Number; - entry.MemoryType = MEM_ME; - error=Phone->GetMemory(s, &entry); - if (error == ERR_NONE) { - name = GSM_PhonebookGetEntryName(&entry); - if (name != NULL) { - printmsg("Contact ID : \"%s\" (%d)\n", DecodeUnicodeConsole(name), ToDo->Entries[j].Number); - } else { - printmsg("Contact ID : %d\n",ToDo->Entries[j].Number); - } - } else { - printmsg("Contact : %d\n",ToDo->Entries[j].Number); - } -#endif - break; - case TODO_PHONE: -#if 0 - // not supported - printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(ToDo->Entries[j].Text)); -#endif - break; - } - } - QString alarmString = "na"; - if ( alarm ) { - Alarm *alarm; - if ( todo->alarms().count() > 0 ) - alarm = todo->alarms().first(); - else { - alarm = new Alarm( todo ); - todo->addAlarm( alarm ); - } - alarm->setType( Alarm::Audio ); - alarm->setEnabled( true ); - int alarmOffset = alarmDt.secsTo( todo->dtStart() ); - alarm->setStartOffset( -alarmOffset ); - alarmString = QString::number( alarmOffset ); - } else { - Alarm *alarm; - if ( todo->alarms().count() > 0 ) { - alarm = todo->alarms().first(); - alarm->setType( Alarm::Audio ); - alarm->setStartOffset( -60*15 ); - alarm->setEnabled( false ); - } - } - // csum ***************************************** - uint cSum; - cSum = PhoneFormat::getCsumTodo( todo ); - todo->setCsum( mProfileName, QString::number( cSum )); - todo->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); - mCalendar->addTodo( todo); - - return true; - } - bool readEvent( Calendar *existingCalendar, GSM_CalendarEntry* Note) - { - - int id = Note->Location; - Event *event; - event = existingCalendar->event( mProfileName ,QString::number( id ) ); - if ( event ) - event = (Event*)event->clone(); - else - event = new Event; - event->setID( mProfileName,QString::number( id ) ); - event->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL ); - - - int i = 0; - bool repeating = false; - int repeat_dayofweek = -1; - int repeat_day = -1; - int repeat_weekofmonth = -1; - int repeat_month = -1; - int repeat_frequency = -1; - int rec_type = -1; - GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0}; - GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0}; - GSM_DateTime* dtp; - bool alarm = false; - QDateTime alarmDt; - repeat_startdate.Day = 0; - repeat_stopdate.Day = 0; - for (i=0;i<Note->EntriesNum;i++) { - - //qDebug(" for ev"); - switch (Note->Entries[i].EntryType) { - case CAL_START_DATETIME: - dtp = &Note->Entries[i].Date ; - if ( dtp->Hour > 24 ) { - event->setFloats( true ); - event->setDtStart( QDateTime (datefromGSM ( dtp ), QTime(0,0,0 ))); - } else { - event->setDtStart (fromGSM ( dtp )); - - } - //Note->Entries[i].Date.Hour = 5; - break; - case CAL_END_DATETIME: - dtp = &Note->Entries[i].Date ; - if ( dtp->Hour > 24 ) { - event->setFloats( true ); - event->setDtEnd( QDateTime (datefromGSM ( dtp ), QTime(0,0,0 ))); - } else { - event->setDtEnd (fromGSM ( dtp )); - } - break; - case CAL_ALARM_DATETIME: - dtp = &Note->Entries[i].Date ; - alarm = true; - alarmDt = fromGSM ( dtp ); - break; - case CAL_SILENT_ALARM_DATETIME: - dtp = &Note->Entries[i].Date ; - alarm = true; - alarmDt = fromGSM ( dtp ); - break; - case CAL_RECURRANCE: - rec_type = Note->Entries[i].Number; - //printmsg("Repeat : %d day%s\n",Note->Entries[i].Number/24,((Note->Entries[i].Number/24)>1) ? "s":"" ); - break; - case CAL_TEXT: - //qDebug(" ev text %s", DecodeUnicodeConsole(Note->Entries[i].Text) ); - event->setSummary( QString::fromUtf8 ( (const char*)DecodeUnicodeConsole( Note->Entries[i].Text ))); - break; - case CAL_LOCATION: - event->setLocation(QString::fromUtf8 ((const char*) DecodeUnicodeConsole(Note->Entries[i].Text) )); - break; - case CAL_PHONE: - //printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(Note->Entries[i].Text)); - break; - case CAL_PRIVATE: - if ( Note->Entries[i].Number == 1 ) - event->setSecrecy( Incidence::SecrecyPrivate ); - else - event->setSecrecy( Incidence::SecrecyPublic ); - - break; - case CAL_CONTACTID: -#if 0 - entry.Location = Note->Entries[i].Number; - entry.MemoryType = MEM_ME; - error=Phone->GetMemory(&s, &entry); - if (error == ERR_NONE) { - name = GSM_PhonebookGetEntryName(&entry); - if (name != NULL) { - //printmsg("Contact ID : \"%s\" (%d)\n", DecodeUnicodeConsole(name), Note->Entries[i].Number); - } else { - //printmsg("Contact ID : %d\n",Note->Entries[i].Number); - } - } else { - //printmsg("Contact ID : %d\n",Note->Entries[i].Number); - } -#endif - break; - case CAL_REPEAT_DAYOFWEEK: - repeat_dayofweek = Note->Entries[i].Number; - repeating = true; - break; - case CAL_REPEAT_DAY: - repeat_day = Note->Entries[i].Number; - repeating = true; - break; - case CAL_REPEAT_WEEKOFMONTH: - repeat_weekofmonth = Note->Entries[i].Number; - repeating = true; - break; - case CAL_REPEAT_MONTH: - repeat_month = Note->Entries[i].Number; - repeating = true; - break; - case CAL_REPEAT_FREQUENCY: - repeat_frequency = Note->Entries[i].Number; - repeating = true; - break; - case CAL_REPEAT_STARTDATE: - repeat_startdate = Note->Entries[i].Date; - repeating = true; - break; - case CAL_REPEAT_STOPDATE: - repeat_stopdate = Note->Entries[i].Date; - repeating = true; - break; - } - } -#if 0 - event->setDescription( attList[4] ); - bool repeating = false; - int repeat_dayofweek = -1; - int repeat_day = -1; - int repeat_weekofmonth = -1; - int repeat_month = -1; - int repeat_frequency = -1; - GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0}; - GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0}; - -#endif - - QString recurString = "no"; - if ( repeating && repeat_frequency != -1) { - recurString = "y"; - if ( repeat_dayofweek >= 0 ) - recurString += "dow" + QString::number (repeat_dayofweek); - if ( repeat_day >= 0 ) - recurString += "d" + QString::number (repeat_day); - if ( repeat_weekofmonth >= 0 ) - recurString += "w" + QString::number (repeat_weekofmonth); - if ( repeat_month >= 0 ) - recurString += "m" + QString::number ( repeat_month ); - if ( repeat_frequency >= 0 ) - recurString += "f" + QString::number (repeat_frequency ); - - int rtype = 0; - // qDebug("recurs "); - QDate startDate, endDate; - if ( repeat_startdate.Day > 0 ) { - startDate = datefromGSM ( &repeat_startdate ); - event->setDtStart(QDateTime ( startDate, event->dtStart().time())); - } else { - startDate = event->dtStart().date(); - } - int freq = repeat_frequency; - bool hasEndDate = false; - if ( repeat_stopdate.Day > 0 ) { - endDate = datefromGSM ( &repeat_stopdate ); - hasEndDate = true; - } - - uint weekDaysNum = repeat_dayofweek ; - // 1 == monday, 7 == sunday - QBitArray weekDays( 7 ); - int i; - int bb = 1; - for( i = 1; i <= 7; ++i ) { - weekDays.setBit( i - 1, ( bb & weekDaysNum )); - bb = 2 << (i-1); - //qDebug(" %d bit %d ",i-1,weekDays.at(i-1) ); - } - // qDebug("next "); - int pos = 0; - Recurrence *r = event->recurrence(); - /* - 0 daily; - 1 weekly;x - 2 monthpos;x - 3 monthlyday; - 4 rYearlyMont - bool repeating = false; - int repeat_dayofweek = -1; - int repeat_day = -1; - int repeat_weekofmonth = -1; - int repeat_month = -1; - int repeat_frequency = -1; - */ - int dayOfWeek = startDate.dayOfWeek(); - if ( repeat_weekofmonth >= 0 ) { - rtype = 2; // ************************ 2 MonthlyPos - pos = repeat_weekofmonth; - if ( repeat_dayofweek >= 0 ) - dayOfWeek = repeat_dayofweek; - if (repeat_month > 0) { - if ( repeat_month != event->dtStart().date().month() ) { - QDate date (event->dtStart().date().year(),repeat_month,event->dtStart().date().day() ); - event->setDtStart(QDateTime ( date , event->dtStart().time()) ); - } - if ( freq == 1 ) - freq = 12; - } - } else if ( repeat_dayofweek >= 0 ) { - rtype = 1;// ************************ 1 Weekly - } else if ( repeat_day >= 0 ) { - if ( repeat_month > 0) { - rtype = 4; - } else { - rtype = 3; - } - } else { - rtype = 0 ; - } - - if ( rtype == 0 ) { - if ( hasEndDate ) r->setDaily( freq, endDate ); - else r->setDaily( freq, -1 ); - } else if ( rtype == 1 ) { - if ( hasEndDate ) r->setWeekly( freq, weekDays, endDate ); - else r->setWeekly( freq, weekDays, -1 ); - } else if ( rtype == 3 ) { - if ( hasEndDate ) - r->setMonthly( Recurrence::rMonthlyDay, freq, endDate ); - else - r->setMonthly( Recurrence::rMonthlyDay, freq, -1 ); - r->addMonthlyDay( startDate.day() ); - } else if ( rtype == 2 ) { - if ( hasEndDate ) - r->setMonthly( Recurrence::rMonthlyPos, freq, endDate ); - else - r->setMonthly( Recurrence::rMonthlyPos, freq, -1 ); - QBitArray days( 7 ); - days.fill( false ); - days.setBit( dayOfWeek - 1 ); - r->addMonthlyPos( pos, days ); - } else if ( rtype == 4 ) { - if ( hasEndDate ) - r->setYearly( Recurrence::rYearlyMonth, freq, endDate ); - else - r->setYearly( Recurrence::rYearlyMonth, freq, -1 ); - r->addYearlyNum( startDate.month() ); - } - } else { - event->recurrence()->unsetRecurs(); - } - - QStringList cat = event->categories(); - QString nCat = getCategory( Note ); - - if ( !nCat.isEmpty() ) - if ( !cat.contains( nCat )) { - cat << nCat; - event->setCategories( cat ); - } - - if ( alarm ) { - Alarm *alarm; - if ( event->alarms().count() > 0 ) - alarm = event->alarms().first(); - else { - alarm = new Alarm( event ); - event->addAlarm( alarm ); - } - alarm->setType( Alarm::Audio ); - alarm->setEnabled( true ); - int alarmOffset = alarmDt.secsTo( event->dtStart() ); - alarm->setStartOffset( -alarmOffset ); - } else { - Alarm *alarm; - if ( event->alarms().count() > 0 ) { - alarm = event->alarms().first(); - alarm->setType( Alarm::Audio ); - alarm->setStartOffset( -60*15 ); - alarm->setEnabled( false ); - } - } - // csum ***************************************** - - uint cSum; - cSum = PhoneFormat::getCsumEvent( event ); - event->setCsum( mProfileName, QString::number( cSum )); - event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); - mCalendar->addEvent( event); - - return true; - } - - - QDateTime fromGSM ( GSM_DateTime* dtp, bool useTz = false ) { - QDateTime dt; - int y,m,t,h,min,sec; - y = dtp->Year; - m = dtp->Month; - t = dtp->Day; - h = dtp->Hour; - min = dtp->Minute; - sec = dtp->Second; - dt = QDateTime(QDate(y,m,t), QTime(h,min,sec)); - // dtp->Timezone: offset in hours - int offset = KGlobal::locale()->localTimeOffset( dt ); - if ( useTz ) - dt = dt.addSecs ( offset*60); - return dt; - - } - + static QString dtToString( const QDateTime& dti, bool useTZ = false ) { QString datestr; QString timestr; int offset = KGlobal::locale()->localTimeOffset( dti ); QDateTime dt; if (useTZ) dt = dti.addSecs ( -(offset*60)); else dt = dti; if(dt.date().isValid()){ const QDate& date = dt.date(); datestr.sprintf("%04d%02d%02d", date.year(), date.month(), date.day()); } if(dt.time().isValid()){ const QTime& time = dt.time(); timestr.sprintf("T%02d%02d%02d", time.hour(), time.minute(), time.second()); } return datestr + timestr; } - QDate datefromGSM ( GSM_DateTime* dtp ) { - return QDate ( dtp->Year, dtp->Month, dtp->Day ); - } - QString getCategory( GSM_CalendarEntry* Note) - { - QString CATEGORY; - switch (Note->Type) { - case GSM_CAL_REMINDER : CATEGORY = QString("Reminder"); break; - case GSM_CAL_CALL : CATEGORY = QString("Call"); break; - //case GSM_CAL_MEETING : CATEGORY = QString("Meeting"); break; - case GSM_CAL_BIRTHDAY : CATEGORY = QString("Birthday"); break; - case GSM_CAL_MEMO : CATEGORY = QString("Memo"); break; - case GSM_CAL_TRAVEL : CATEGORY = QString("Travel"); break; - case GSM_CAL_VACATION : CATEGORY = QString("Vacation"); break; - case GSM_CAL_ALARM : CATEGORY = QString("Alarm"); break; - case GSM_CAL_DAILY_ALARM : CATEGORY = QString("Daily alarm"); break; - case GSM_CAL_T_ATHL : CATEGORY = QString("Training/Athletism"); break; - case GSM_CAL_T_BALL : CATEGORY = QString("Training/Ball Games"); break; - case GSM_CAL_T_CYCL : CATEGORY = QString("Training/Cycling"); break; - case GSM_CAL_T_BUDO : CATEGORY = QString("Training/Budo"); break; - case GSM_CAL_T_DANC : CATEGORY = QString("Training/Dance"); break; - case GSM_CAL_T_EXTR : CATEGORY = QString("Training/Extreme Sports"); break; - case GSM_CAL_T_FOOT : CATEGORY = QString("Training/Football"); break; - case GSM_CAL_T_GOLF : CATEGORY = QString("Training/Golf"); break; - case GSM_CAL_T_GYM : CATEGORY = QString("Training/Gym"); break; - case GSM_CAL_T_HORS : CATEGORY = QString("Training/Horse Races"); break; - case GSM_CAL_T_HOCK : CATEGORY = QString("Training/Hockey"); break; - case GSM_CAL_T_RACE : CATEGORY = QString("Training/Races"); break; - case GSM_CAL_T_RUGB : CATEGORY = QString("Training/Rugby"); break; - case GSM_CAL_T_SAIL : CATEGORY = QString("Training/Sailing"); break; - case GSM_CAL_T_STRE : CATEGORY = QString("Training/Street Games"); break; - case GSM_CAL_T_SWIM : CATEGORY = QString("Training/Swimming"); break; - case GSM_CAL_T_TENN : CATEGORY = QString("Training/Tennis"); break; - case GSM_CAL_T_TRAV : CATEGORY = QString("Training/Travels"); break; - case GSM_CAL_T_WINT : CATEGORY = QString("Training/Winter Games"); break; - default : CATEGORY = QString(""); - } - return CATEGORY; - } -protected: -private: - Calendar *mCalendar; - QString mProfileName ; }; + PhoneFormat::PhoneFormat(QString profileName, QString device,QString connection, QString model ) { mProfileName = profileName; mDevice = device; mConnection = connection; mModel = model; } PhoneFormat::~PhoneFormat() { } +#if 0 int PhoneFormat::initDevice(GSM_StateMachine *s) { GSM_ReadConfig(NULL, &s->Config[0], 0); s->ConfigNum = 1; GSM_Config *cfg = &s->Config[0]; if ( ! mConnection.isEmpty() ) { cfg->Connection = strdup(mConnection.latin1()); cfg->DefaultConnection = false; qDebug("Connection set %s ", cfg->Connection ); } if ( ! mDevice.isEmpty() ) { cfg->Device = strdup(mDevice.latin1()); cfg->DefaultDevice = false; qDebug("Device set %s ", cfg->Device); } if ( ! mModel.isEmpty() ) { strcpy(cfg->Model,mModel.latin1() ); cfg->DefaultModel = false; qDebug("Model set %s ",cfg->Model ); } int error=GSM_InitConnection(s,3); return error; } +#endif ulong PhoneFormat::getCsumTodo( Todo* todo ) { QStringList attList; if ( todo->hasDueDate() ) attList << PhoneParser::dtToString ( todo->dtDue() ); attList << todo->summary(); QString completedString = "no"; if ( todo->isCompleted() ) completedString = "yes"; attList << completedString; attList << QString::number( todo->priority() ); QString alarmString = "na"; Alarm *alarm; if ( todo->alarms().count() > 0 ) { alarm = todo->alarms().first(); if ( alarm->enabled() ) { alarmString = QString::number(alarm->startOffset().asSeconds() ); } } attList << alarmString; attList << todo->categoriesStr(); attList << todo->secrecyStr(); return PhoneFormat::getCsum(attList ); } ulong PhoneFormat::getCsumEvent( Event* event ) { QStringList attList; attList << PhoneParser::dtToString ( event->dtStart() ); attList << PhoneParser::dtToString ( event->dtEnd() ); attList << event->summary(); attList << event->location(); QString alarmString = "na"; Alarm *alarm; if ( event->alarms().count() > 0 ) { alarm = event->alarms().first(); if ( alarm->enabled() ) { alarmString = QString::number( alarm->startOffset().asSeconds() ); } } attList << alarmString; Recurrence* rec = event->recurrence(); QStringList list; bool writeEndDate = false; switch ( rec->doesRecur() ) { case Recurrence::rDaily: // 0 list.append( "0" ); list.append( QString::number( rec->frequency() ));//12 list.append( "0" ); list.append( "0" ); writeEndDate = true; break; case Recurrence::rWeekly:// 1 list.append( "1" ); list.append( QString::number( rec->frequency()) );//12 list.append( "0" ); { int days = 0; QBitArray weekDays = rec->days(); int i; for( i = 1; i <= 7; ++i ) { if ( weekDays[i-1] ) { days += 1 << (i-1); } } list.append( QString::number( days ) ); } //pending weekdays writeEndDate = true; break; case Recurrence::rMonthlyPos:// 2 list.append( "2" ); list.append( QString::number( rec->frequency()) );//12 writeEndDate = true; { int count = 1; QPtrList<Recurrence::rMonthPos> rmp; rmp = rec->monthPositions(); if ( rmp.first()->negative ) count = 5 - rmp.first()->rPos - 1; else count = rmp.first()->rPos - 1; list.append( QString::number( count ) ); } list.append( "0" ); break; case Recurrence::rMonthlyDay:// 3 list.append( "3" ); list.append( QString::number( rec->frequency()) );//12 list.append( "0" ); list.append( "0" ); writeEndDate = true; break; case Recurrence::rYearlyMonth://4 list.append( "4" ); list.append( QString::number( rec->frequency()) );//12 list.append( "0" ); list.append( "0" ); writeEndDate = true; break; default: list.append( "255" ); list.append( QString() ); list.append( "0" ); list.append( QString() ); list.append( "0" ); list.append( "20991231T000000" ); break; } if ( writeEndDate ) { if ( rec->endDate().isValid() ) { // 15 + 16 list.append( "1" ); list.append( PhoneParser::dtToString( rec->endDate()) ); } else { list.append( "0" ); list.append( "20991231T000000" ); } } attList << list.join(""); attList << event->categoriesStr(); attList << event->secrecyStr(); return PhoneFormat::getCsum(attList ); } ulong PhoneFormat::getCsum( const QStringList & attList) { int max = attList.count() -1; ulong cSum = 0; int j,k,i; int add; for ( i = 1; i < max ; ++i ) { QString s = attList[i]; if ( ! s.isEmpty() ){ j = s.length(); for ( k = 0; k < j; ++k ) { int mul = k +1; add = s[k].unicode (); if ( k < 16 ) mul = mul * mul; add = add * mul *i*i*i; cSum += add; } } } return cSum; } //extern "C" GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum); #include <stdlib.h> #define DEBUGMODE false bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal) { - GSM_StateMachine s; - qDebug(" load "); - s.opened = false; - s.msg = NULL; - s.ConfigNum = 0; - QLabel status ( i18n("Opening device ..."), 0 ); - int w = status.sizeHint().width()+20 ; - if ( w < 200 ) w = 230; - int h = status.sizeHint().height()+20 ; - int dw = QApplication::desktop()->width(); - int dh = QApplication::desktop()->height(); - status.setCaption(i18n("Reading phone...") ); - status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); - status.show(); - status.raise(); - qApp->processEvents(); - int error=initDevice(&s); - qDebug("GSM Init %d (no error is %d)", error, ERR_NONE); - if ( error != ERR_NONE ) + QString fileName; +#ifdef _WIN32_ + fileName = locateLocal("data", "korganizer") + "\\tempfile.vcs"; +#else + fileName = "/tmp/kdepimtemp.vcs"; +#endif + QString command ="./kammu --backup " + fileName + " -yes"; + int ret = system ( command.latin1() ); + if ( ret != 0 ) return false; - GSM_Phone_Functions *Phone; - GSM_CalendarEntry note; - bool start = true; - Phone=s.Phone.Functions; - bool gshutdown = false; - PhoneParser handler( calendar, mProfileName ); - int ccc = 0; - QString message = i18n(" Reading event # "); - int procCount = 0; - qDebug("Debug: only 10 calender items are downloaded "); - while (!gshutdown && ccc++ < 10) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - qDebug("readEvent %d ", ccc); - error=Phone->GetNextCalendar(&s,¬e,start); - if (error == ERR_EMPTY) break; - start = false; - handler.readEvent( existingCal, ¬e ); - qDebug("Org loc %d ",note.Location); - //note.Location = 0; - error=Phone->SetCalendar(&s,¬e); - qDebug("new loc %d ",note.Location); + VCalFormat vfload; + vfload.setLocalTime ( true ); + if ( ! vfload.load( calendar, fileName ) ) + return false; + QPtrList<Event> er = calendar->rawEvents(); + Event* ev = er.first(); + while ( ev ) { + int id = ev->pilotId(); + Event *event; + event = existingCal->event( mProfileName ,QString::number( id ) ); + if ( event ) { + event = (Event*)event->clone(); + copyEvent( event, ev ); + calendar->deleteEvent( ev ); + calendar->addEvent( event); + } + else + event = ev; + uint cSum; + cSum = PhoneFormat::getCsumEvent( event ); + event->setCsum( mProfileName, QString::number( cSum )); + event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); + event->setID( mProfileName,QString::number( id ) ); + ev = er.next(); + } + { + QPtrList<Todo> tr = calendar->rawTodos(); + Todo* ev = tr.first(); + while ( ev ) { + + QStringList cat = ev->categories(); + if ( cat.contains( "MeetingDEF" )) { + ev->setCategories( QStringList() ); + } + int id = ev->pilotId(); + Todo *event; + event = existingCal->todo( mProfileName ,QString::number( id ) ); + if ( event ) { + event = (Todo*)event->clone(); + copyTodo( event, ev ); + calendar->deleteTodo( ev ); + calendar->addTodo( event); + } + else + event = ev; + uint cSum; + cSum = PhoneFormat::getCsumTodo( event ); + event->setCsum( mProfileName, QString::number( cSum )); + event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); + event->setID( mProfileName,QString::number( id ) ); + ev = tr.next(); + } } - - start = true; - GSM_ToDoEntry ToDo; - ccc = 0; - message = i18n(" Reading todo # "); - procCount = 0; - while (!gshutdown && ccc++ < 10) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - error = Phone->GetNextToDo(&s, &ToDo, start); - if (error == ERR_EMPTY) break; - start = false; - qDebug("ReadTodo %d ", ccc); - handler.readTodo( existingCal, &ToDo, &s); - - } - - error=GSM_TerminateConnection(&s); - return true; } -#include <qcstring.h> -void PhoneFormat::event2GSM( Calendar *cal,Event* ev, GSM_CalendarEntry*Note ) +void PhoneFormat::copyEvent( Event* to, Event* from ) { - QString eText = vfconverter.eventToString( ev, cal ); - int pos = 0; - GSM_ToDoEntry dummy; - qDebug( "Convert event"); - QByteArray ba; - QDataStream s ( ba, IO_WriteOnly ); - s << eText.utf8(); - GSM_DecodeVCALENDAR_VTODO( (unsigned char*) ba.data(), &pos, Note , &dummy, Nokia_VCalendar, Nokia_VToDo ); - qDebug( "Convert event done"); - Note->Location = 0; - QString loc = ev->getID(mProfileName); - if ( !loc.isEmpty() ){ - Note->Location = loc.toInt(); + if ( from->dtStart().isValid() ) + to->setDtStart( from->dtStart() ); + if ( from->dtEnd().isValid() ) + to->setDtEnd( from->dtEnd() ); + if ( !from->location().isEmpty() ) + to->setLocation( from->location() ); + if ( !from->description().isEmpty() ) + to->setDescription( from->description() ); + if ( !from->summary().isEmpty() ) + to->setSummary( from->summary() ); + + QPtrListIterator<Alarm> it( from->alarms() ); + to->clearAlarms(); + const Alarm *a; + while( (a = it.current()) ) { + Alarm *b = new Alarm( *a ); + b->setParent( to ); + to->addAlarm( b ); + ++it; + } + QStringList cat = to->categories(); + QStringList catFrom = from->categories(); + QString nCat; + int iii; + for ( iii = 0; iii < catFrom.count();++iii ) { + nCat = catFrom[iii]; + if ( !nCat.isEmpty() ) + if ( !cat.contains( nCat )) { + cat << nCat; + } } + to->setCategories( cat ); + Recurrence * r = new Recurrence( *from->recurrence(),to); + to->setRecurrence( r ) ; + } -void PhoneFormat::todo2GSM( Calendar *cal, Todo* todo, GSM_ToDoEntry *gsmTodo ) +void PhoneFormat::copyTodo( Todo* to, Todo* from ) { - qDebug( "Convert todo1"); - QString tText = vfconverter.todoToString( todo, cal ); - int pos = 0; - GSM_CalendarEntry dummy; - QByteArray ba; - QDataStream s ( ba, IO_WriteOnly ); - s << tText.utf8(); - GSM_DecodeVCALENDAR_VTODO( (unsigned char*) ba.data(), &pos, &dummy, gsmTodo, Nokia_VCalendar, Nokia_VToDo ); - qDebug( "Convert todo done "); - gsmTodo->Location = 0; - QString loc = todo->getID(mProfileName); - if ( !loc.isEmpty() ){ - gsmTodo->Location = loc.toInt(); + if ( from->dtStart().isValid() ) + to->setDtStart( from->dtStart() ); + if ( from->dtDue().isValid() ) + to->setDtDue( from->dtDue() ); + if ( !from->location().isEmpty() ) + to->setLocation( from->location() ); + if ( !from->description().isEmpty() ) + to->setDescription( from->description() ); + if ( !from->summary().isEmpty() ) + to->setSummary( from->summary() ); + + QPtrListIterator<Alarm> it( from->alarms() ); + to->clearAlarms(); + const Alarm *a; + while( (a = it.current()) ) { + Alarm *b = new Alarm( *a ); + b->setParent( to ); + to->addAlarm( b ); + ++it; + } + QStringList cat = to->categories(); + QStringList catFrom = from->categories(); + QString nCat; + int iii; + for ( iii = 0; iii < catFrom.count();++iii ) { + nCat = catFrom[iii]; + if ( !nCat.isEmpty() ) + if ( !cat.contains( nCat )) { + cat << nCat; + } } - + to->setCategories( cat ); + if ( from->isCompleted() ) { + to->setCompleted( true ); + if( from->completed().isValid() ) + to->setCompleted( from->completed() ); + } else { + // set percentcomplete only, if to->isCompleted() + if ( to->isCompleted() ) + to->setPercentComplete(from->percentComplete()); + } + to->setPriority(from->priority()); + } +#include <qcstring.h> + void PhoneFormat::afterSave( Incidence* inc) { uint csum; inc->removeID( mProfileName ); if ( inc->type() == "Event") csum = PhoneFormat::getCsumEvent( (Event*) inc ); else csum = PhoneFormat::getCsumTodo( (Todo*) inc ); inc->setCsum( mProfileName, QString::number( csum )); inc->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID ); } bool PhoneFormat::save( Calendar *calendar) { - - GSM_StateMachine s; - qDebug(" save "); - s.opened = false; - s.msg = NULL; - s.ConfigNum = 0; QLabel status ( i18n(" Opening device ..."), 0 ); int w = status.sizeHint().width()+20 ; if ( w < 200 ) w = 230; int h = status.sizeHint().height()+20 ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); status.setCaption(i18n("Writing to phone...") ); status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); status.show(); status.raise(); qApp->processEvents(); - - int error=initDevice(&s); - qDebug("GSM Init %d (no error is %d)", error, ERR_NONE); - if ( error != ERR_NONE ) - return false; - GSM_Phone_Functions *Phone; - GSM_CalendarEntry Note; - bool start = true; - Phone=s.Phone.Functions; - bool gshutdown = false; - QPtrList<Event> er = calendar->rawEvents(); - Event* ev = er.first(); - QString message = i18n(" Deleting event # "); - int procCount = 0; - int diffProc = 0; - bool setPossible = true; + QString message; #ifdef _WIN32_ QString fileName = locateLocal("data", "korganizer") + "\\tempfile.vcs"; #else QString fileName = "/tmp/kdepimtemp.vcs"; #endif - //algo 1 delete event - while ( ev ) { - if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { // event was changed during sync or is a new one - - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - qDebug("del event1 %d ", procCount); - //event2GSM( calendar, ev, &Note ); - if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete - QString loc = ev->getID(mProfileName); - if ( !loc.isEmpty() ){ - Note.Location = loc.toInt(); - } else { - qDebug("error: loc is empty "); - } - error = Phone->DeleteCalendar(&s, &Note); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - qDebug(" e error delete1 planB %d ", error); - break; - } - } - else if ( ev->getID(mProfileName).isEmpty() ) { // add new - // we have to do this later after deleting - - } - else { // change existing + // 1 remove events which should be deleted + QPtrList<Event> er = calendar->rawEvents(); + Event* ev = er.first(); + while ( ev ) { + if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { + calendar->deleteEvent( ev ); + } else { - QString loc = ev->getID(mProfileName); - if ( !loc.isEmpty() ){ - Note.Location = loc.toInt(); - } else { - qDebug("error3: loc is empty "); - } - error = Phone->DeleteCalendar(&s, &Note); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - qDebug(" e error delete2 planB %d ", error); - break; - } - ev->removeID( mProfileName ); - } - } + } ev = er.next(); } - //algo 1 delete todo - GSM_ToDoEntry ToDoEntry; + // 2 remove todos which should be deleted QPtrList<Todo> tl = calendar->rawTodos(); Todo* to = tl.first(); - message = i18n(" Deleting todo # "); - procCount = 0; while ( to ) { - if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { - qDebug("todo3 %d ", procCount); - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - qDebug("todo5 %d ", procCount); - // todo2GSM( calendar, to, &ToDoEntry ); - QString loc = to->getID(mProfileName); - if ( !loc.isEmpty() ){ - ToDoEntry.Location = loc.toInt(); - } else { - qDebug("error2: loc is empty "); - } - if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete - error=Phone->DeleteToDo(&s,&ToDoEntry); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - qDebug("delete planB %d ", error); - } - } - else if ( to->getID(mProfileName).isEmpty() ) { // add new - ; - } - else { // change existing - error=Phone->DeleteToDo(&s,&ToDoEntry); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - qDebug("set planB %d ", error); - } - to->removeID( mProfileName ); - } + if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { + calendar->deleteTodo( to ); } to = tl.next(); } - //algo 2 add event - ev = er.first(); - QString filec; - message = i18n(" Preparing event # "); - procCount = 0; - while ( ev ) { - if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && ev->tempSyncStat() != SYNC_TEMPSTATE_DELETE) { - if ( ev->getID(mProfileName).isEmpty() ) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - filec += vfconverter.eventToString( ev, calendar )+ "\n"; - afterSave ( ev ); - - } - } - ev = er.next(); - } - //algo 2 add todo - to = tl.first(); - procCount = 0; - message = i18n(" Preparing todo # "); - while ( to ) { - qDebug("todo2 %d ", procCount); - if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && to->tempSyncStat() != SYNC_TEMPSTATE_DELETE) { - qDebug("todo4 %d ", procCount); - if ( to->getID(mProfileName).isEmpty() ) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - filec += vfconverter.todoToString( to, calendar )+ "\n"; - afterSave ( to ); - } - } - to = tl.next(); - } - if ( filec.isEmpty() ) { - qDebug("Nothing to write back.Finished. "); - error=GSM_TerminateConnection(&s); - return true; - } - //algo 3 saving file - message = i18n(" Saving temp file ... "); - status.setText ( message ); - qApp->processEvents(); - QFile file( fileName ); - if (!file.open( IO_WriteOnly ) ) { - qDebug("error open file "); - error=GSM_TerminateConnection(&s); + // 3 save file + VCalFormat vfsave; + vfsave.setLocalTime ( true ); + if ( ! vfsave.save( calendar, fileName ) ) return false; - } - QTextStream ts( &file ); - ts.setCodec( QTextCodec::codecForName("utf8") ); - ts << filec ; - file.close(); - - - message = i18n(" Parsing temp file ... "); - status.setText ( message ); - qApp->processEvents(); - GSM_Backup Backup; - error=GSM_ReadBackupFile( (char*) fileName.latin1() ,&Backup); - qDebug("Read file result %d ",error ); - //algo 4 writing event - int max, i; - procCount = 0; - message = i18n(" Writing event # "); - if (Backup.Calendar[0] != NULL) { - max = 0; - while (Backup.Calendar[max]!=NULL) max++; - - GSM_DateTime* dtp; - - for (i=0;i<max;i++) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - Note = *Backup.Calendar[i]; - -#if 0 - int j; - for (j=0;j<Note.EntriesNum;j++) { - //qDebug(" for ev"); - switch (Note.Entries[j].EntryType) { - case CAL_START_DATETIME: - //Note->Entries[i].Date.Hour = 5; - dtp = &Note.Entries[j].Date; - qDebug("start event %d %d %d - %d %d %d", dtp->Year, dtp->Month, dtp->Day, dtp->Hour, dtp->Minute, dtp->Second ); - break; - case CAL_END_DATETIME: - dtp = &Note.Entries[j].Date; - qDebug("end event %d %d %d - %d %d %d", dtp->Year, dtp->Month, dtp->Day, dtp->Hour, dtp->Minute, dtp->Second ); - break; - } - } - int type = Note.Type; - qDebug(" event type %d - %d %d - %d %d %d",type, GSM_CAL_CALL , GSM_CAL_MEETING ,GSM_CAL_BIRTHDAY, GSM_CAL_MEMO ,GSM_CAL_ALARM ); -#endif - - Note.Type = GSM_CAL_MEETING; - // pending: fix in gammu GSM_ReadBackupFile the type settings - int loc = Note.Location; - Note.Location = 0; - error=Phone->AddCalendar(&s,&Note); - qDebug("add event %d %d %d", error, Note.Location, loc ); - } - } - //algo 4 writing todo - procCount = 0; - message = i18n(" Writing todo # "); - if (Backup.ToDo[0] != NULL) { - max = 0; - while (Backup.ToDo[max]!=NULL) max++; - for (i=0;i<max;i++) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - ToDoEntry = *Backup.ToDo[i]; - error = Phone->AddToDo(&s,&ToDoEntry); - qDebug("add todo %d ", error); - } - } - //algo 5 reread + // 4 call kammu + QString command ="./kammu --restore " + fileName ; + int ret = system ( command.latin1() ); + if ( ret != 0 ) + return false; + // 5 reread data message = i18n(" Rereading all data ... "); status.setText ( message ); qApp->processEvents(); - error=GSM_TerminateConnection(&s); CalendarLocal* calendarTemp = new CalendarLocal(); calendarTemp->setTimeZoneId( calendar->timeZoneId()); if ( ! load( calendarTemp,calendar) ){ qDebug("error reloading calendar "); delete calendarTemp; return false; } + // 6 compare data - - //algo 6 compare event +//algo 6 compare event + er = calendar->rawEvents(); ev = er.first(); message = i18n(" Comparing event # "); QPtrList<Event> er1 = calendarTemp->rawEvents(); Event* ev1; - procCount = 0; + int procCount = 0; while ( ev ) { - if ( ev->tempSyncStat() == SYNC_TEMPSTATE_NEW_ID) { qDebug("event new ID "); status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); QString cSum = ev->getCsum(mProfileName); ev1 = er1.first(); while ( ev1 ) { if ( ev1->getCsum( mProfileName ) == cSum ) { er1.remove( ev1 ); + afterSave( ev ); ev->setID(mProfileName, ev1->getID(mProfileName) ); break; } ev1 = er1.next(); } if ( ! ev1 ) { ev->removeID(mProfileName); qDebug("ERROR: No event found on phone for %s ", ev->summary().latin1()); - qDebug("Probably writing back of events not supported "); } - } + ev = er.next(); } //algo 6 compare todo to = tl.first(); procCount = 0; QPtrList<Todo> tl1 = calendarTemp->rawTodos(); Todo* to1 ; message = i18n(" Comparing todo # "); while ( to ) { qDebug("todo2 %d ", procCount); - if ( to->tempSyncStat() == SYNC_TEMPSTATE_NEW_ID) { status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); QString cSum = to->getCsum(mProfileName); Todo* to1 = tl1.first(); while ( to1 ) { if ( to1->getCsum( mProfileName ) == cSum ) { tl1.remove( to1 ); + afterSave( to ); to->setID(mProfileName, to1->getID(mProfileName) ); break; } to1 = tl1.next(); } if ( ! to1 ) { to->removeID(mProfileName); qDebug("ERROR: No todo found on phone for %s ", to->summary().latin1()); - qDebug("Probably writing back of todos not supported "); } - } + to = tl.next(); } delete calendarTemp; return true; - // ******************************************************************* - // ******************************************************************* - // ******************************************************************* -#if 0 - while ( ev && ! planB) { - if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { // event was changed during sync or is a new one - - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - qDebug("event1 %d ", procCount); - event2GSM( calendar, ev, &Note ); - if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete - error = Phone->DeleteCalendar(&s, &Note); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - planB = true; - qDebug(" e delete1 planB %d ", error); - break; - } - } - else if ( ev->getID(mProfileName).isEmpty() ) { // add new - // we have to do this later after deleting - - } - else { // change existing - if ( setPossible ) { - error = Phone->SetCalendar(&s, &Note); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - setPossible = false; - ++diffProc; - qDebug("Set cal not supported %d ", error); - break; - } - } - if ( ! setPossible) { - ++diffProc; - error = Phone->DeleteCalendar(&s, &Note); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - planB = true; - qDebug(" e delete2 planB %d ", error); - break; - } - ev->removeID( mProfileName ); - } - qDebug("Change Calendar. Location %d status: %d",Note.Location, error ); - } - } - ev = er.next(); - } - ev = er.first(); - // pending get empty slots - int loc = 0; - procCount -= diffProc; - while ( ev && ! planB) { - if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && ev->tempSyncStat() != SYNC_TEMPSTATE_DELETE) { - qDebug("event2 %d ", procCount); - if ( ev->getID(mProfileName).isEmpty() ) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - //int newID ;//= pending - //ev->setID(mProfileName, QString::number( newID )); - event2GSM( calendar, ev, &Note ); - ++loc; - Note.Location = loc; - error = Phone->AddCalendar(&s, &Note); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - planB = true; - qDebug(" e add planB %d ", error); - break; - } - ev->setID( mProfileName, QString::number( Note.Location ) ); - qDebug("New Calendar. Location %d stat %d %d",Note.Location ,error, ERR_UNKNOWN); - afterSave( ev ); - } else { - afterSave( ev ); // setting temp sync stat for changed items - } - } - ev = er.next(); - } - if ( planB ) { - qDebug("delete all calendar..."); - status.setText ( i18n("Deleting all calendar...")); - qApp->processEvents(); - error=Phone->DeleteAllCalendar(&s); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - message = i18n(" Deleting event # "); - procCount = 0; - while (1) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - qDebug("deleting event ... %d", procCount); - error = Phone->GetNextCalendar(&s,&Note,true); - if (error != ERR_NONE) break; - error = Phone->DeleteCalendar(&s,&Note); - } - qDebug("deleting calendar ... finished"); - } else { - status.setText ( i18n("All calendar deleted!")); - qDebug("all cal deleted"); - } - bool planC = false; - ev = er.first(); - procCount = 0; - message = i18n(" Writing event # "); - while ( ev && ! planC) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - event2GSM( calendar, ev, &Note ); - Note.Location = procCount; - error=Phone->AddCalendar(&s,&Note); - if (error != ERR_NONE ) { - // we have currently no planC :-( - // planC = true; - //qDebug("add planC %d ", error); - //break; - // we remove the ID such that this todo is not deleted after next sync - ev->removeID(mProfileName); - ev->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID ); - qDebug("error :cal adding loc %d planB stat %d ", Note.Location ,error); - } else { - qDebug("cal adding loc %d planB stat %d ", Note.Location ,error); - ev->setID(mProfileName, QString::number( Note.Location )); - afterSave( ev ); - } - ev = er.next(); - } - if ( planC ) { - qDebug("writing cal went wrong..."); - // we have currently no planC :-( - } - } - GSM_ToDoEntry ToDoEntry; - QPtrList<Todo> tl = calendar->rawTodos(); - Todo* to = tl.first(); - - message = i18n(" Processing todo # "); - procCount = 0; - planB = false; - while ( to && ! planB ) { - if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { - qDebug("todo3 %d ", procCount); - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - qDebug("todo5 %d ", procCount); - todo2GSM( calendar, to, &ToDoEntry ); - if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete - error=Phone->DeleteToDo(&s,&ToDoEntry); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - planB = true; - qDebug("delete planB %d ", error); - } - } - else if ( to->getID(mProfileName).isEmpty() ) { // add new - ; - } - else { // change existing - error=Phone->SetToDo(&s,&ToDoEntry); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - planB = true; - qDebug("set planB %d ", error); - } - qDebug("Old Todo. Location %d %d",ToDoEntry.Location , error ); - } - } - to = tl.next(); - } - - // pending get empty slots - to = tl.first(); - while ( to && ! planB ) { - qDebug("todo2 %d ", procCount); - if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && to->tempSyncStat() != SYNC_TEMPSTATE_DELETE) { - qDebug("todo4 %d ", procCount); - if ( to->getID(mProfileName).isEmpty() ) { - status.setText ( message + QString::number ( ++procCount ) ); - qApp->processEvents(); - //int newID ;//= pending - //to->setID(mProfileName, QString::number( newID )); - todo2GSM( calendar,to, &ToDoEntry ); - ToDoEntry.Location = 0; - error=Phone->AddToDo(&s,&ToDoEntry); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - planB = true; - qDebug("new planB %d ", error); - } - to->setID(mProfileName, QString::number( ToDoEntry.Location )); - afterSave( to ); - qDebug("New Todo. Location %d %d",ToDoEntry.Location, error ); - } else { - afterSave( to ); - } - } - to = tl.next(); - } - if ( planB ) { - qDebug("delete all ..."); - error=Phone->DeleteAllToDo(&s); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - while (1) { - qDebug("deleting todo ..."); - error = Phone->GetNextToDo(&s,&ToDoEntry,true); - if (error != ERR_NONE) break; - error = Phone->DeleteToDo(&s,&ToDoEntry); - } - qDebug("deleting todo ... finished"); - } else { - qDebug("all todo deleted"); - } - bool planC = false; - to = tl.first(); - while ( to && ! planC ) { - todo2GSM( calendar,to, &ToDoEntry ); - ToDoEntry.Location = 0; - error=Phone->AddToDo(&s,&ToDoEntry); - if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { - // we have currently no planC :-( - // planC = true; - //qDebug("add planC %d ", error); - //break; - // we remove the ID such that this todo is not deleted after next sync - to->removeID(mProfileName); - to->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID ); - } else { - qDebug("adding %d planB %d ", ToDoEntry.Location ,error); - to->setID(mProfileName, QString::number( ToDoEntry.Location )); - afterSave( to ); - } - to = tl.next(); - } - if ( planC ) { - // we have currently no planC :-( - } - } - return true; -#endif -} -QString PhoneFormat::dtToGSM( const QDateTime& dti, bool useTZ ) -{ - QString datestr; - QString timestr; - int offset = KGlobal::locale()->localTimeOffset( dti ); - QDateTime dt; - if (useTZ) - dt = dti.addSecs ( -(offset*60)); - else - dt = dti; - if(dt.date().isValid()){ - const QDate& date = dt.date(); - datestr.sprintf("%04d%02d%02d", - date.year(), date.month(), date.day()); - } - if(dt.time().isValid()){ - const QTime& time = dt.time(); - timestr.sprintf("T%02d%02d%02d", - time.hour(), time.minute(), time.second()); - } - return datestr + timestr; -} -QString PhoneFormat::getEventString( Event* event ) -{ -#if 0 - QStringList list; - list.append( QString::number(event->zaurusId() ) ); - list.append( event->categories().join(",") ); - if ( !event->summary().isEmpty() ) - list.append( event->summary() ); - else - list.append("" ); - if ( !event->location().isEmpty() ) - list.append( event->location() ); - else - list.append("" ); - if ( !event->description().isEmpty() ) - list.append( event->description() ); - else - list.append( "" ); - if ( event->doesFloat () ) { - list.append( dtToString( QDateTime(event->dtStart().date(), QTime(0,0,0)), false )); - list.append( dtToString( QDateTime(event->dtEnd().date(),QTime(23,59,59)), false )); //6 - list.append( "1" ); - - } - else { - list.append( dtToString( event->dtStart()) ); - list.append( dtToString( event->dtEnd()) ); //6 - list.append( "0" ); - } - bool noAlarm = true; - if ( event->alarms().count() > 0 ) { - Alarm * al = event->alarms().first(); - if ( al->enabled() ) { - noAlarm = false; - list.append( "0" ); // yes, 0 == alarm - list.append( QString::number( al->startOffset().asSeconds()/(-60) ) ); - if ( al->type() == Alarm::Audio ) - list.append( "1" ); // type audio - else - list.append( "0" ); // type silent - } - } - if ( noAlarm ) { - list.append( "1" ); // yes, 1 == no alarm - list.append( "0" ); // no alarm offset - list.append( "1" ); // type - } - // next is: 11 - // next is: 11-16 are recurrence - Recurrence* rec = event->recurrence(); - - bool writeEndDate = false; - switch ( rec->doesRecur() ) - { - case Recurrence::rDaily: // 0 - list.append( "0" ); - list.append( QString::number( rec->frequency() ));//12 - list.append( "0" ); - list.append( "0" ); - writeEndDate = true; - break; - case Recurrence::rWeekly:// 1 - list.append( "1" ); - list.append( QString::number( rec->frequency()) );//12 - list.append( "0" ); - { - int days = 0; - QBitArray weekDays = rec->days(); - int i; - for( i = 1; i <= 7; ++i ) { - if ( weekDays[i-1] ) { - days += 1 << (i-1); - } - } - list.append( QString::number( days ) ); - } - //pending weekdays - writeEndDate = true; - - break; - case Recurrence::rMonthlyPos:// 2 - list.append( "2" ); - list.append( QString::number( rec->frequency()) );//12 - - writeEndDate = true; - { - int count = 1; - QPtrList<Recurrence::rMonthPos> rmp; - rmp = rec->monthPositions(); - if ( rmp.first()->negative ) - count = 5 - rmp.first()->rPos - 1; - else - count = rmp.first()->rPos - 1; - list.append( QString::number( count ) ); - - } - - list.append( "0" ); - break; - case Recurrence::rMonthlyDay:// 3 - list.append( "3" ); - list.append( QString::number( rec->frequency()) );//12 - list.append( "0" ); - list.append( "0" ); - writeEndDate = true; - break; - case Recurrence::rYearlyMonth://4 - list.append( "4" ); - list.append( QString::number( rec->frequency()) );//12 - list.append( "0" ); - list.append( "0" ); - writeEndDate = true; - break; - - default: - list.append( "255" ); - list.append( QString() ); - list.append( "0" ); - list.append( QString() ); - list.append( "0" ); - list.append( "20991231T000000" ); - break; - } - if ( writeEndDate ) { - - if ( rec->endDate().isValid() ) { // 15 + 16 - list.append( "1" ); - list.append( dtToString( rec->endDate()) ); - } else { - list.append( "0" ); - list.append( "20991231T000000" ); - } - - } - if ( event->doesFloat () ) { - list.append( dtToString( event->dtStart(), false ).left( 8 )); - list.append( dtToString( event->dtEnd(), false ).left( 8 )); //6 - - } - else { - list.append( QString() ); - list.append( QString() ); - - } - if (event->dtStart().date() == event->dtEnd().date() ) - list.append( "0" ); - else - list.append( "1" ); - - - for(QStringList::Iterator it=list.begin(); - it!=list.end(); ++it){ - QString& s = (*it); - s.replace(QRegExp("\""), "\"\""); - if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){ - s.prepend('\"'); - s.append('\"'); - } else if(s.isEmpty() && !s.isNull()){ - s = "\"\""; - } - } - return list.join(","); -#endif - return QString(); - -} -QString PhoneFormat::getTodoString( Todo* todo ) -{ -#if 0 - QStringList list; - list.append( QString::number( todo->zaurusId() ) ); - list.append( todo->categories().join(",") ); - - if ( todo->hasStartDate() ) { - list.append( dtToString( todo->dtStart()) ); - } else - list.append( QString() ); - - if ( todo->hasDueDate() ) { - QTime tim; - if ( todo->doesFloat()) { - list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ; - } else { - list.append( dtToString(todo->dtDue() ) ); - } - } else - list.append( QString() ); - - if ( todo->isCompleted() ) { - list.append( dtToString( todo->completed()) ); - list.append( "0" ); // yes 0 == completed - } else { - list.append( dtToString( todo->completed()) ); - list.append( "1" ); - } - list.append( QString::number( todo->priority() )); - if( ! todo->summary().isEmpty() ) - list.append( todo->summary() ); - else - list.append( "" ); - if (! todo->description().isEmpty() ) - list.append( todo->description() ); - else - list.append( "" ); - for(QStringList::Iterator it=list.begin(); - it!=list.end(); ++it){ - QString& s = (*it); - s.replace(QRegExp("\""), "\"\""); - if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){ - s.prepend('\"'); - s.append('\"'); - } else if(s.isEmpty() && !s.isNull()){ - s = "\"\""; - } - } - return list.join(","); -#endif - return QString(); } QString PhoneFormat::toString( Calendar * ) { return QString::null; } bool PhoneFormat::fromString( Calendar *calendar, const QString & text) { return false; } diff --git a/libkcal/phoneformat.h b/libkcal/phoneformat.h index 2c2e51c..8286098 100644 --- a/libkcal/phoneformat.h +++ b/libkcal/phoneformat.h @@ -1,67 +1,61 @@ /* This file is part of libkcal. Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef PHONEFORMAT_H #define PHONEFORMAT_H #include <qstring.h> #include "scheduler.h" #include "vcalformat.h" #include "calformat.h" -extern "C" { -#include "../gammu/emb/common/gammu.h" -} + namespace KCal { /** This class implements the calendar format used by Phone. */ class Event; class Todo; class PhoneFormat : public QObject { public: /** Create new iCalendar format. */ PhoneFormat(QString profileName, QString device,QString connection, QString model); virtual ~PhoneFormat(); bool load( Calendar * ,Calendar * ); bool save( Calendar * ); bool fromString( Calendar *, const QString & ); QString toString( Calendar * ); static ulong getCsum( const QStringList & ); static ulong getCsumTodo( Todo* to ); static ulong getCsumEvent( Event* ev ); private: - VCalFormat vfconverter; - void event2GSM( Calendar *, Event* ev, GSM_CalendarEntry*Note ); - void todo2GSM( Calendar *, Todo* ev, GSM_ToDoEntry *ToDo ); - int initDevice(GSM_StateMachine *s); - QString getEventString( Event* ); - QString getTodoString( Todo* ); - QString dtToGSM( const QDateTime& dt, bool useTZ = true ); + void copyEvent( Event* to, Event* from ); + void copyTodo( Todo* to, Todo* from ); + //int initDevice(GSM_StateMachine *s); QString mProfileName, mDevice, mConnection, mModel; void afterSave( Incidence* ); }; } #endif diff --git a/libkcal/vcalformat.cpp b/libkcal/vcalformat.cpp index 0ebd7d1..4727a7a 100644 --- a/libkcal/vcalformat.cpp +++ b/libkcal/vcalformat.cpp @@ -1,1084 +1,1087 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brwon Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qapplication.h> #include <qdatetime.h> #include <qstring.h> #include <qptrlist.h> #include <qregexp.h> #include <qclipboard.h> #include <qdialog.h> #include <qfile.h> #include <kdebug.h> #include <kglobal.h> #include <kmessagebox.h> #include <kiconloader.h> #include <klocale.h> #include "vcc.h" #include "vobject.h" #include "vcaldrag.h" #include "calendar.h" #include "vcalformat.h" using namespace KCal; VCalFormat::VCalFormat() { mCalendar = 0; useLocalTime = false; } VCalFormat::~VCalFormat() { } +void VCalFormat::setLocalTime ( bool b ) +{ + useLocalTime = b; +} bool VCalFormat::load(Calendar *calendar, const QString &fileName) { mCalendar = calendar; - clearException(); kdDebug(5800) << "VCalFormat::load() " << fileName << endl; VObject *vcal = 0; // this is not necessarily only 1 vcal. Could be many vcals, or include // a vcard... vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data())); if (!vcal) { setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); return FALSE; } // any other top-level calendar stuff should be added/initialized here // put all vobjects into their proper places populate(vcal); // clean up from vcal API stuff cleanVObjects(vcal); cleanStrTbl(); return true; } bool VCalFormat::save(Calendar *calendar, const QString &fileName) { mCalendar = calendar; QString tmpStr; VObject *vcal, *vo; kdDebug(5800) << "VCalFormat::save(): " << fileName << endl; vcal = newVObject(VCCalProp); // addPropValue(vcal,VCLocationProp, "0.0"); addPropValue(vcal,VCProdIdProp, productId()); tmpStr = mCalendar->getTimeZoneStr(); //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() ); addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); addPropValue(vcal,VCVersionProp, _VCAL_VERSION); // TODO STUFF QPtrList<Todo> todoList = mCalendar->rawTodos(); QPtrListIterator<Todo> qlt(todoList); for (; qlt.current(); ++qlt) { vo = eventToVTodo(qlt.current()); addVObjectProp(vcal, vo); } // EVENT STUFF QPtrList<Event> events = mCalendar->rawEvents(); Event *ev; for(ev=events.first();ev;ev=events.next()) { vo = eventToVEvent(ev); addVObjectProp(vcal, vo); } writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal); cleanVObjects(vcal); cleanStrTbl(); if (QFile::exists(fileName)) { kdDebug(5800) << "No error" << endl; return true; } else { kdDebug(5800) << "Error" << endl; return false; // error } } bool VCalFormat::fromString( Calendar *calendar, const QString &text ) { // TODO: Factor out VCalFormat::fromString() QCString data = text.utf8(); if ( !data.size() ) return false; VObject *vcal = Parse_MIME( data.data(), data.size()); if ( !vcal ) return false; VObjectIterator i; VObject *curvo; initPropIterator( &i, vcal ); // we only take the first object. TODO: parse all incidences. do { curvo = nextVObject( &i ); } while ( strcmp( vObjectName( curvo ), VCEventProp ) && strcmp( vObjectName( curvo ), VCTodoProp ) ); if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) { Event *event = VEventToEvent( curvo ); calendar->addEvent( event ); } else { kdDebug(5800) << "VCalFormat::fromString(): Unknown object type." << endl; deleteVObject( vcal ); return false; } deleteVObject( vcal ); return true; } QString VCalFormat::eventToString( Event * event, Calendar *calendar, bool useLocal) { if ( !event ) return QString::null; bool useL = useLocalTime; useLocalTime = useLocal; mCalendar = calendar; VObject *vevent = eventToVEvent( event ); char *buf = writeMemVObject( 0, 0, vevent ); QString result( buf ); cleanVObject( vevent ); useLocalTime = useL; return result; } QString VCalFormat::todoToString( Todo * todo, Calendar *calendar, bool useLocal ) { if ( !todo ) return QString::null; bool useL = useLocalTime; useLocalTime = useLocal; mCalendar = calendar; VObject *vevent = eventToVTodo( todo ); char *buf = writeMemVObject( 0, 0, vevent ); QString result( buf ); cleanVObject( vevent ); useLocalTime = useL; return result; } QString VCalFormat::toString( Calendar *calendar ) { // TODO: Factor out VCalFormat::asString() VObject *vcal = newVObject(VCCalProp); addPropValue( vcal, VCProdIdProp, CalFormat::productId() ); QString tmpStr = mCalendar->getTimeZoneStr(); addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() ); addPropValue( vcal, VCVersionProp, _VCAL_VERSION ); // TODO: Use all data. QPtrList<Event> events = calendar->events(); Event *event = events.first(); if ( !event ) return QString::null; VObject *vevent = eventToVEvent( event ); addVObjectProp( vcal, vevent ); char *buf = writeMemVObject( 0, 0, vcal ); QString result( buf ); cleanVObject( vcal ); return result; } VObject *VCalFormat::eventToVTodo(const Todo *anEvent) { VObject *vtodo; QString tmpStr; QStringList tmpStrList; vtodo = newVObject(VCTodoProp); // due date if (anEvent->hasDueDate()) { tmpStr = qDateTimeToISO(anEvent->dtDue(), !anEvent->doesFloat()); addPropValue(vtodo, VCDueProp, tmpStr.local8Bit()); } // start date if (anEvent->hasStartDate()) { tmpStr = qDateTimeToISO(anEvent->dtStart(), !anEvent->doesFloat()); addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit()); } // creation date tmpStr = qDateTimeToISO(anEvent->created()); addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit()); // unique id addPropValue(vtodo, VCUniqueStringProp, anEvent->uid().local8Bit()); // revision tmpStr.sprintf("%i", anEvent->revision()); addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit()); // last modification date tmpStr = qDateTimeToISO(anEvent->lastModified()); addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit()); // organizer stuff tmpStr = "MAILTO:" + anEvent->organizer(); addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit()); // attendees if (anEvent->attendeeCount() != 0) { QPtrList<Attendee> al = anEvent->attendees(); QPtrListIterator<Attendee> ai(al); Attendee *curAttendee; for (; ai.current(); ++ai) { curAttendee = ai.current(); if (!curAttendee->email().isEmpty() && !curAttendee->name().isEmpty()) tmpStr = "MAILTO:" + curAttendee->name() + " <" + curAttendee->email() + ">"; else if (curAttendee->name().isEmpty()) tmpStr = "MAILTO: " + curAttendee->email(); else if (curAttendee->email().isEmpty()) tmpStr = "MAILTO: " + curAttendee->name(); else if (curAttendee->name().isEmpty() && curAttendee->email().isEmpty()) kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl; VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit()); addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE"); addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); } } // description BL: if (!anEvent->description().isEmpty()) { VObject *d = addPropValue(vtodo, VCDescriptionProp, anEvent->description().local8Bit()); if (anEvent->description().find('\n') != -1) addProp(d, VCQuotedPrintableProp); } // summary if (!anEvent->summary().isEmpty()) addPropValue(vtodo, VCSummaryProp, anEvent->summary().local8Bit()); if (!anEvent->location().isEmpty()) addPropValue(vtodo, VCLocationProp, anEvent->location().local8Bit()); // completed // status // backward compatibility, KOrganizer used to interpret only these two values addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" : "NEEDS_ACTION"); // completion date if (anEvent->hasCompletedDate()) { tmpStr = qDateTimeToISO(anEvent->completed()); addPropValue(vtodo, VCCompletedProp, tmpStr.local8Bit()); } // priority tmpStr.sprintf("%i",anEvent->priority()); addPropValue(vtodo, VCPriorityProp, tmpStr.local8Bit()); // related event if (anEvent->relatedTo()) { addPropValue(vtodo, VCRelatedToProp, anEvent->relatedTo()->uid().local8Bit()); } // categories tmpStrList = anEvent->categories(); tmpStr = ""; QString catStr; for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) { catStr = *it; if (catStr[0] == ' ') tmpStr += catStr.mid(1); else tmpStr += catStr; // this must be a ';' character as the vCalendar specification requires! // vcc.y has been hacked to translate the ';' to a ',' when the vcal is // read in. tmpStr += ";"; } if (!tmpStr.isEmpty()) { tmpStr.truncate(tmpStr.length()-1); addPropValue(vtodo, VCCategoriesProp, tmpStr.local8Bit()); } // alarm stuff kdDebug(5800) << "vcalformat::eventToVTodo was called" << endl; QPtrList<Alarm> alarms = anEvent->alarms(); Alarm* alarm; for (alarm = alarms.first(); alarm; alarm = alarms.next()) { if (alarm->enabled()) { VObject *a; tmpStr = qDateTimeToISO(alarm->time()); if (alarm->type() == Alarm::Audio) { a = addProp(vtodo, VCAAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); } else if (alarm->type() == Alarm::Procedure) { a = addProp(vtodo, VCPAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); } else { a = addProp(vtodo, VCDAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCDisplayStringProp, "beep!"); } } } if (anEvent->pilotId()) { // pilot sync stuff tmpStr.sprintf("%i",anEvent->pilotId()); addPropValue(vtodo, XPilotIdProp, tmpStr.local8Bit()); tmpStr.sprintf("%i",anEvent->syncStatus()); addPropValue(vtodo, XPilotStatusProp, tmpStr.local8Bit()); } return vtodo; } VObject* VCalFormat::eventToVEvent(const Event *anEvent) { VObject *vevent; QString tmpStr; QStringList tmpStrList; vevent = newVObject(VCEventProp); // start and end time tmpStr = qDateTimeToISO(anEvent->dtStart(), !anEvent->doesFloat()); addPropValue(vevent, VCDTstartProp, tmpStr.local8Bit()); // events that have time associated but take up no time should // not have both DTSTART and DTEND. if (anEvent->dtStart() != anEvent->dtEnd()) { tmpStr = qDateTimeToISO(anEvent->dtEnd(), !anEvent->doesFloat()); addPropValue(vevent, VCDTendProp, tmpStr.local8Bit()); } // creation date tmpStr = qDateTimeToISO(anEvent->created()); addPropValue(vevent, VCDCreatedProp, tmpStr.local8Bit()); // unique id addPropValue(vevent, VCUniqueStringProp, anEvent->uid().local8Bit()); // revision tmpStr.sprintf("%i", anEvent->revision()); addPropValue(vevent, VCSequenceProp, tmpStr.local8Bit()); // last modification date tmpStr = qDateTimeToISO(anEvent->lastModified()); addPropValue(vevent, VCLastModifiedProp, tmpStr.local8Bit()); // attendee and organizer stuff tmpStr = "MAILTO:" + anEvent->organizer(); addPropValue(vevent, ICOrganizerProp, tmpStr.local8Bit()); if (anEvent->attendeeCount() != 0) { QPtrList<Attendee> al = anEvent->attendees(); QPtrListIterator<Attendee> ai(al); Attendee *curAttendee; // TODO: Put this functionality into Attendee class for (; ai.current(); ++ai) { curAttendee = ai.current(); if (!curAttendee->email().isEmpty() && !curAttendee->name().isEmpty()) tmpStr = "MAILTO:" + curAttendee->name() + " <" + curAttendee->email() + ">"; else if (curAttendee->name().isEmpty()) tmpStr = "MAILTO: " + curAttendee->email(); else if (curAttendee->email().isEmpty()) tmpStr = "MAILTO: " + curAttendee->name(); else if (curAttendee->name().isEmpty() && curAttendee->email().isEmpty()) kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl; VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.local8Bit()); addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");; addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); } } // recurrence rule stuff if (anEvent->recurrence()->doesRecur()) { // some more variables QPtrList<Recurrence::rMonthPos> tmpPositions; QPtrList<int> tmpDays; int *tmpDay; Recurrence::rMonthPos *tmpPos; QString tmpStr2; int i; switch(anEvent->recurrence()->doesRecur()) { case Recurrence::rDaily: tmpStr.sprintf("D%i ",anEvent->recurrence()->frequency()); // if (anEvent->rDuration > 0) // tmpStr += "#"; break; case Recurrence::rWeekly: tmpStr.sprintf("W%i ",anEvent->recurrence()->frequency()); for (i = 0; i < 7; i++) { if (anEvent->recurrence()->days().testBit(i)) tmpStr += dayFromNum(i); } break; case Recurrence::rMonthlyPos: tmpStr.sprintf("MP%i ", anEvent->recurrence()->frequency()); // write out all rMonthPos's tmpPositions = anEvent->recurrence()->monthPositions(); for (tmpPos = tmpPositions.first(); tmpPos; tmpPos = tmpPositions.next()) { tmpStr2.sprintf("%i", tmpPos->rPos); if (tmpPos->negative) tmpStr2 += "- "; else tmpStr2 += "+ "; tmpStr += tmpStr2; for (i = 0; i < 7; i++) { if (tmpPos->rDays.testBit(i)) tmpStr += dayFromNum(i); } } // loop for all rMonthPos's break; case Recurrence::rMonthlyDay: tmpStr.sprintf("MD%i ", anEvent->recurrence()->frequency()); // write out all rMonthDays; tmpDays = anEvent->recurrence()->monthDays(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; case Recurrence::rYearlyMonth: tmpStr.sprintf("YM%i ", anEvent->recurrence()->frequency()); // write out all the rYearNums; tmpDays = anEvent->recurrence()->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; case Recurrence::rYearlyDay: tmpStr.sprintf("YD%i ", anEvent->recurrence()->frequency()); // write out all the rYearNums; tmpDays = anEvent->recurrence()->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; default: kdDebug(5800) << "ERROR, it should never get here in eventToVEvent!" << endl; break; } // switch if (anEvent->recurrence()->duration() > 0) { tmpStr2.sprintf("#%i",anEvent->recurrence()->duration()); tmpStr += tmpStr2; } else if (anEvent->recurrence()->duration() == -1) { tmpStr += "#0"; // defined as repeat forever } else { tmpStr += qDateTimeToISO(anEvent->recurrence()->endDate(), FALSE); } addPropValue(vevent,VCRRuleProp, tmpStr.local8Bit()); } // event repeats // exceptions to recurrence DateList dateList = anEvent->exDates(); DateList::ConstIterator it; QString tmpStr2; for (it = dateList.begin(); it != dateList.end(); ++it) { tmpStr = qDateToISO(*it) + ";"; tmpStr2 += tmpStr; } if (!tmpStr2.isEmpty()) { tmpStr2.truncate(tmpStr2.length()-1); addPropValue(vevent, VCExpDateProp, tmpStr2.local8Bit()); } // description if (!anEvent->description().isEmpty()) { VObject *d = addPropValue(vevent, VCDescriptionProp, anEvent->description().local8Bit()); if (anEvent->description().find('\n') != -1) addProp(d, VCQuotedPrintableProp); } // summary if (!anEvent->summary().isEmpty()) addPropValue(vevent, VCSummaryProp, anEvent->summary().local8Bit()); if (!anEvent->location().isEmpty()) addPropValue(vevent, VCLocationProp, anEvent->location().local8Bit()); // status // TODO: define Event status // addPropValue(vevent, VCStatusProp, anEvent->statusStr().local8Bit()); // secrecy const char *text = 0; switch (anEvent->secrecy()) { case Incidence::SecrecyPublic: text = "PUBLIC"; break; case Incidence::SecrecyPrivate: text = "PRIVATE"; break; case Incidence::SecrecyConfidential: text = "CONFIDENTIAL"; break; } if (text) { addPropValue(vevent, VCClassProp, text); } // categories tmpStrList = anEvent->categories(); tmpStr = ""; QString catStr; for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) { catStr = *it; if (catStr[0] == ' ') tmpStr += catStr.mid(1); else tmpStr += catStr; // this must be a ';' character as the vCalendar specification requires! // vcc.y has been hacked to translate the ';' to a ',' when the vcal is // read in. tmpStr += ";"; } if (!tmpStr.isEmpty()) { tmpStr.truncate(tmpStr.length()-1); addPropValue(vevent, VCCategoriesProp, tmpStr.local8Bit()); } // attachments // TODO: handle binary attachments! QPtrList<Attachment> attachments = anEvent->attachments(); for ( Attachment *at = attachments.first(); at; at = attachments.next() ) addPropValue(vevent, VCAttachProp, at->uri().local8Bit()); // resources tmpStrList = anEvent->resources(); tmpStr = tmpStrList.join(";"); if (!tmpStr.isEmpty()) addPropValue(vevent, VCResourcesProp, tmpStr.local8Bit()); // alarm stuff QPtrList<Alarm> alarms = anEvent->alarms(); Alarm* alarm; for (alarm = alarms.first(); alarm; alarm = alarms.next()) { if (alarm->enabled()) { VObject *a ; tmpStr = qDateTimeToISO(alarm->time()); if (alarm->type() == Alarm::Audio) { a = addProp(vevent, VCAAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); } if (alarm->type() == Alarm::Procedure) { a = addProp(vevent, VCPAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); } else { a = addProp(vevent, VCDAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCDisplayStringProp, "beep!"); } } } // priority tmpStr.sprintf("%i",anEvent->priority()); addPropValue(vevent, VCPriorityProp, tmpStr.local8Bit()); // transparency tmpStr.sprintf("%i",anEvent->transparency()); addPropValue(vevent, VCTranspProp, tmpStr.local8Bit()); // related event if (anEvent->relatedTo()) { addPropValue(vevent, VCRelatedToProp, anEvent->relatedTo()->uid().local8Bit()); } if (anEvent->pilotId()) { // pilot sync stuff tmpStr.sprintf("%i",anEvent->pilotId()); addPropValue(vevent, XPilotIdProp, tmpStr.local8Bit()); tmpStr.sprintf("%i",anEvent->syncStatus()); addPropValue(vevent, XPilotStatusProp, tmpStr.local8Bit()); } return vevent; } Todo *VCalFormat::VTodoToEvent(VObject *vtodo) { VObject *vo; VObjectIterator voi; char *s; Todo *anEvent = new Todo; // creation date if ((vo = isAPropertyOf(vtodo, VCDCreatedProp)) != 0) { anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // unique id vo = isAPropertyOf(vtodo, VCUniqueStringProp); // while the UID property is preferred, it is not required. We'll use the // default Event UID if none is given. if (vo) { anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } // last modification date if ((vo = isAPropertyOf(vtodo, VCLastModifiedProp)) != 0) { anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setLastModified(QDateTime(QDate::currentDate(), QTime::currentTime())); // organizer // if our extension property for the event's ORGANIZER exists, add it. if ((vo = isAPropertyOf(vtodo, ICOrganizerProp)) != 0) { anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else { anEvent->setOrganizer(mCalendar->getEmail()); } // attendees. initPropIterator(&voi, vtodo); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { Attendee *a; VObject *vp; s = fakeCString(vObjectUStringZValue(vo)); QString tmpStr = QString::fromLocal8Bit(s); deleteStr(s); tmpStr = tmpStr.simplifyWhiteSpace(); int emailPos1, emailPos2; if ((emailPos1 = tmpStr.find('<')) > 0) { // both email address and name emailPos2 = tmpStr.findRev('>'); a = new Attendee(tmpStr.left(emailPos1 - 1), tmpStr.mid(emailPos1 + 1, emailPos2 - (emailPos1 + 1))); } else if (tmpStr.find('@') > 0) { // just an email address a = new Attendee(0, tmpStr); } else { // just a name QString email = tmpStr.replace( QRegExp(" "), "." ); a = new Attendee(tmpStr,email); } // is there an RSVP property? if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) a->setRSVP(vObjectStringZValue(vp)); // is there a status property? if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) a->setStatus(readStatus(vObjectStringZValue(vp))); // add the attendee anEvent->addAttendee(a); } } // description for todo if ((vo = isAPropertyOf(vtodo, VCDescriptionProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); anEvent->setDescription(QString::fromLocal8Bit(s)); deleteStr(s); } // summary if ((vo = isAPropertyOf(vtodo, VCSummaryProp))) { s = fakeCString(vObjectUStringZValue(vo)); anEvent->setSummary(QString::fromLocal8Bit(s)); deleteStr(s); } if ((vo = isAPropertyOf(vtodo, VCLocationProp))) { s = fakeCString(vObjectUStringZValue(vo)); anEvent->setLocation(QString::fromLocal8Bit(s)); deleteStr(s); } // completed // was: status if ((vo = isAPropertyOf(vtodo, VCStatusProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); if (strcmp(s,"COMPLETED") == 0) { anEvent->setCompleted(true); } else { anEvent->setCompleted(false); } deleteStr(s); } else anEvent->setCompleted(false); // completion date if ((vo = isAPropertyOf(vtodo, VCCompletedProp)) != 0) { anEvent->setCompleted(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // priority if ((vo = isAPropertyOf(vtodo, VCPriorityProp))) { anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // due date if ((vo = isAPropertyOf(vtodo, VCDueProp)) != 0) { anEvent->setDtDue(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); anEvent->setHasDueDate(true); } else { anEvent->setHasDueDate(false); } // start time if ((vo = isAPropertyOf(vtodo, VCDTstartProp)) != 0) { anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; deleteStr(s); anEvent->setHasStartDate(true); } else { anEvent->setHasStartDate(false); } /* alarm stuff */ //kdDebug(5800) << "vcalformat::VTodoToEvent called" << endl; if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) { Alarm* alarm = anEvent->newAlarm(); VObject *a; if ((a = isAPropertyOf(vo, VCRunTimeProp))) { alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); deleteStr(s); } alarm->setEnabled(true); if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) { if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setProcedureAlarm(QFile::decodeName(s)); deleteStr(s); } } if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) { if ((a = isAPropertyOf(vo, VCAudioContentProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setAudioAlarm(QFile::decodeName(s)); deleteStr(s); } } } // related todo if ((vo = isAPropertyOf(vtodo, VCRelatedToProp)) != 0) { anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); mTodosRelate.append(anEvent); } // categories QStringList tmpStrList; int index1 = 0; int index2 = 0; if ((vo = isAPropertyOf(vtodo, VCCategoriesProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); QString categories = QString::fromLocal8Bit(s); deleteStr(s); //const char* category; QString category; while ((index2 = categories.find(',', index1)) != -1) { //category = (const char *) categories.mid(index1, (index2 - index1)); category = categories.mid(index1, (index2 - index1)); tmpStrList.append(category); index1 = index2+1; } // get last category category = categories.mid(index1, (categories.length()-index1)); tmpStrList.append(category); anEvent->setCategories(tmpStrList); } /* PILOT SYNC STUFF */ if ((vo = isAPropertyOf(vtodo, XPilotIdProp))) { anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setPilotId(0); if ((vo = isAPropertyOf(vtodo, XPilotStatusProp))) { anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setSyncStatus(Event::SYNCMOD); return anEvent; } Event* VCalFormat::VEventToEvent(VObject *vevent) { VObject *vo; VObjectIterator voi; char *s; Event *anEvent = new Event; // creation date if ((vo = isAPropertyOf(vevent, VCDCreatedProp)) != 0) { anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // unique id vo = isAPropertyOf(vevent, VCUniqueStringProp); // while the UID property is preferred, it is not required. We'll use the // default Event UID if none is given. if (vo) { anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } // revision // again NSCAL doesn't give us much to work with, so we improvise... if ((vo = isAPropertyOf(vevent, VCSequenceProp)) != 0) { anEvent->setRevision(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setRevision(0); // last modification date if ((vo = isAPropertyOf(vevent, VCLastModifiedProp)) != 0) { anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setLastModified(QDateTime(QDate::currentDate(), QTime::currentTime())); // organizer // if our extension property for the event's ORGANIZER exists, add it. if ((vo = isAPropertyOf(vevent, ICOrganizerProp)) != 0) { anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else { anEvent->setOrganizer(mCalendar->getEmail()); } // deal with attendees. initPropIterator(&voi, vevent); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { Attendee *a; VObject *vp; s = fakeCString(vObjectUStringZValue(vo)); QString tmpStr = QString::fromLocal8Bit(s); deleteStr(s); tmpStr = tmpStr.simplifyWhiteSpace(); int emailPos1, emailPos2; if ((emailPos1 = tmpStr.find('<')) > 0) { // both email address and name emailPos2 = tmpStr.findRev('>'); a = new Attendee(tmpStr.left(emailPos1 - 1), tmpStr.mid(emailPos1 + 1, emailPos2 - (emailPos1 + 1))); } else if (tmpStr.find('@') > 0) { // just an email address a = new Attendee(0, tmpStr); } else { // just a name QString email = tmpStr.replace( QRegExp(" "), "." ); a = new Attendee(tmpStr,email); } // is there an RSVP property? if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) a->setRSVP(vObjectStringZValue(vp)); // is there a status property? if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) a->setStatus(readStatus(vObjectStringZValue(vp))); // add the attendee anEvent->addAttendee(a); } } // This isn't strictly true. An event that doesn't have a start time // or an end time doesn't "float", it has an anchor in time but it doesn't // "take up" any time. /*if ((isAPropertyOf(vevent, VCDTstartProp) == 0) || (isAPropertyOf(vevent, VCDTendProp) == 0)) { anEvent->setFloats(TRUE); } else { }*/ anEvent->setFloats(FALSE); // start time if ((vo = isAPropertyOf(vevent, VCDTstartProp)) != 0) { anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; deleteStr(s); if (anEvent->dtStart().time().isNull()) anEvent->setFloats(TRUE); } // stop time if ((vo = isAPropertyOf(vevent, VCDTendProp)) != 0) { anEvent->setDtEnd(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); if (anEvent->dtEnd().time().isNull()) anEvent->setFloats(TRUE); } // at this point, there should be at least a start or end time. // fix up for events that take up no time but have a time associated if (!(vo = isAPropertyOf(vevent, VCDTstartProp))) anEvent->setDtStart(anEvent->dtEnd()); if (!(vo = isAPropertyOf(vevent, VCDTendProp))) anEvent->setDtEnd(anEvent->dtStart()); /////////////////////////////////////////////////////////////////////////// // repeat stuff if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) { QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); tmpStr.simplifyWhiteSpace(); tmpStr = tmpStr.upper(); /********************************* DAILY ******************************/ if (tmpStr.left(1) == "D") { int index = tmpStr.find(' '); int rFreq = tmpStr.mid(1, (index-1)).toInt(); index = tmpStr.findRev(' ') + 1; // advance to last field if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setDaily(rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) // VEvents set this to 0 forever, we use -1 anEvent->recurrence()->setDaily(rFreq, -1); else anEvent->recurrence()->setDaily(rFreq, rDuration); } } /********************************* WEEKLY ******************************/ else if (tmpStr.left(1) == "W") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(1, (index-1)).toInt(); index += 1; // advance to beginning of stuff after freq QBitArray qba(7); QString dayStr; if( index == last ) { // e.g. W1 #0 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); } else { // e.g. W1 SU #0 while (index < last) { dayStr = tmpStr.mid(index, 3); int dayNum = numFromDay(dayStr); qba.setBit(dayNum); index += 3; // advance to next day, or possibly "#" } } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setWeekly(rFreq, qba, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setWeekly(rFreq, qba, -1); else diff --git a/libkcal/vcalformat.h b/libkcal/vcalformat.h index 848be78..5bef7ed 100644 --- a/libkcal/vcalformat.h +++ b/libkcal/vcalformat.h @@ -1,111 +1,112 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _VCALFORMAT_H #define _VCALFORMAT_H #include "calformat.h" #define _VCAL_VERSION "1.0" class VObject; namespace KCal { /** This class implements the vCalendar format. It provides methods for loading/saving/converting vCalendar format data into the internal KOrganizer representation as Calendar and Events. @short vCalendar format implementation */ class VCalFormat : public CalFormat { public: VCalFormat(); virtual ~VCalFormat(); /** loads a calendar on disk in vCalendar format into the current calendar. * any information already present is lost. Returns TRUE if successful, * else returns FALSE. * @param fileName the name of the calendar on disk. */ - bool load(Calendar *,const QString &fileName); + bool load(Calendar *,const QString &fileName ); /** writes out the calendar to disk in vCalendar format. Returns true if * successful and false on error. * @param fileName the name of the file */ - bool save(Calendar *,const QString &fileName); + bool save(Calendar *,const QString &fileName ); /** Parse string and populate calendar with that information. */ bool fromString( Calendar *, const QString & ); /** Return calendar information as string. */ + void setLocalTime ( bool ); QString toString( Calendar * ); QString eventToString( Event *, Calendar *calendar, bool useLocalTime = true ); QString todoToString( Todo * ,Calendar *calendar, bool useLocalTime = true ); protected: /** translates a VObject of the TODO type into a Event */ Todo *VTodoToEvent(VObject *vtodo); /** translates a VObject into a Event and returns a pointer to it. */ Event *VEventToEvent(VObject *vevent); /** translate a Event into a VTodo-type VObject and return pointer */ VObject *eventToVTodo(const Todo *anEvent); /** translate a Event into a VObject and returns a pointer to it. */ VObject* eventToVEvent(const Event *anEvent); /** takes a QDate and returns a string in the format YYYYMMDDTHHMMSS */ QString qDateToISO(const QDate &); /** takes a QDateTime and returns a string in format YYYYMMDDTHHMMSS */ QString qDateTimeToISO(const QDateTime &, bool zulu=TRUE); /** takes a string in the format YYYYMMDDTHHMMSS and returns a * valid QDateTime. */ QDateTime ISOToQDateTime(const QString & dtStr); /** takes a string in the format YYYYMMDD and returns a * valid QDate. */ QDate ISOToQDate(const QString & dtStr); /** takes a vCalendar tree of VObjects, and puts all of them that have * the "event" property into the dictionary, todos in the todo-list, etc. */ void populate(VObject *vcal); /** takes a number 0 - 6 and returns the two letter string of that day, * i.e. MO, TU, WE, etc. */ const char *dayFromNum(int day); /** the reverse of the above function. */ int numFromDay(const QString &day); Attendee::PartStat readStatus(const char *s) const; QCString writeStatus(Attendee::PartStat status) const; private: Calendar *mCalendar; bool useLocalTime; QPtrList<Event> mEventsRelate; // events with relations QPtrList<Todo> mTodosRelate; // todos with relations }; } #endif |