24 #include "alarmcalendar.h"
26 #include "alarmlistview.h"
32 #include "preferences.h"
33 #include "shellprocess.h"
34 #include "templatelistview.h"
35 #include "templatemenuaction.h"
37 #include <tqdeepcopy.h>
41 #include <tdeconfig.h>
42 #include <tdeaction.h>
43 #include <tdeglobal.h>
44 #include <tdelocale.h>
45 #include <kstdguiitem.h>
46 #include <tdestdaccel.h>
47 #include <tdemessagebox.h>
48 #include <tdefiledialog.h>
49 #include <dcopclient.h>
51 #include <kdcopservicestarter.h>
54 #include <libkcal/event.h>
55 #include <libkcal/icalformat.h>
56 #include <libkpimidentities/identitymanager.h>
57 #include <libkpimidentities/identity.h>
58 #include <libkcal/person.h>
63 bool resetDaemonQueued =
false;
64 TQCString korganizerName =
"korganizer";
65 TQString korgStartError;
66 #define KORG_DCOP_OBJECT "KOrganizerIface"
68 const char* KMAIL_DCOP_WINDOW =
"kmail-mainwindow#1";
70 bool sendToKOrganizer(
const KAEvent&);
71 bool deleteFromKOrganizer(
const TQString& eventID);
82 MainWindow* displayMainWindowSelected(
const TQString& eventID)
84 MainWindow* win = MainWindow::firstWindow();
87 if (theApp()->checkCalendarDaemon())
89 win = MainWindow::create();
96 bool visible = win->isVisible();
99 if (!visible || win->isMinimized())
102 win->setActiveWindow();
104 if (win && !eventID.isEmpty())
105 win->selectEvent(eventID);
112 TDEAction* createNewAlarmAction(
const TQString& label, TQObject* receiver,
const char* slot, TDEActionCollection* actions,
const char* name)
114 return new TDEAction(label,
"document-new", TDEStdAccel::openNew(), receiver, slot, actions, name);
120 TemplateMenuAction* createNewFromTemplateAction(
const TQString& label, TQObject* receiver,
const char* slot, TDEActionCollection* actions,
const char* name)
122 return new TemplateMenuAction(label,
"new_from_template", receiver, slot, actions, name);
132 UpdateStatus addEvent(
KAEvent& event, AlarmListView* selectionView, TQWidget* errmsgParent,
bool useEventID,
bool allowKOrgUpdate)
134 kdDebug(5950) <<
"KAlarm::addEvent(): " <<
event.id() << endl;
136 if (!theApp()->checkCalendarDaemon())
137 return UPDATE_FAILED;
142 if (!cal->addEvent(event, useEventID))
143 status = UPDATE_FAILED;
144 else if (!cal->save())
145 status = SAVE_FAILED;
147 if (status == UPDATE_OK)
149 if (allowKOrgUpdate && event.copyToKOrganizer())
151 if (!sendToKOrganizer(event))
152 status = UPDATE_KORG_ERR;
156 AlarmListView::addEvent(event, selectionView);
161 displayUpdateError(errmsgParent, status, ERR_ADD, 1);
169 bool addExpiredEvent(
KAEvent& event)
171 kdDebug(5950) <<
"KAlarm::addExpiredEvent(" <<
event.id() <<
")\n";
175 bool archiving = (KAEvent::uidStatus(event.id()) == KAEvent::ACTIVE);
177 event.setSaveDateTime(TQDateTime::currentDateTime());
183 AlarmListView::addEvent(event, 0);
185 AlarmListView::modifyEvent(
KAEvent(*kcalEvent), 0);
196 UpdateStatus addTemplate(
KAEvent& event, TemplateListView* selectionView, TQWidget* errmsgParent)
198 kdDebug(5950) <<
"KAlarm::addTemplate(): " <<
event.id() << endl;
203 if (!cal || !cal->addEvent(event))
204 status = UPDATE_FAILED;
205 else if (!cal->save())
206 status = SAVE_FAILED;
209 cal->emitEmptyStatus();
212 TemplateListView::addEvent(event, selectionView);
217 displayUpdateError(errmsgParent, status, ERR_TEMPLATE, 1);
230 kdDebug(5950) <<
"KAlarm::modifyEvent(): '" << oldEvent.id() << endl;
233 if (!newEvent.valid())
235 deleteEvent(oldEvent,
true);
236 status = UPDATE_FAILED;
240 if (oldEvent.copyToKOrganizer())
245 deleteFromKOrganizer(oldEvent.id());
250 if (!cal->deleteEvent(oldEvent.id())
251 || !cal->addEvent(
const_cast<KAEvent&
>(newEvent),
true))
252 status = UPDATE_FAILED;
253 else if (!cal->save())
254 status = SAVE_FAILED;
255 if (status == UPDATE_OK)
257 if (newEvent.copyToKOrganizer())
259 if (!sendToKOrganizer(newEvent))
260 status = UPDATE_KORG_ERR;
264 AlarmListView::modifyEvent(oldEvent.id(), newEvent, selectionView);
270 displayUpdateError(errmsgParent, status, ERR_ADD, 1);
283 UpdateStatus updateEvent(
KAEvent& event, AlarmListView* selectionView, TQWidget* errmsgParent,
bool archiveOnDelete,
bool incRevision)
285 kdDebug(5950) <<
"KAlarm::updateEvent(): " <<
event.id() << endl;
288 deleteEvent(event, archiveOnDelete);
293 event.incrementRevision();
295 cal->updateEvent(event);
299 displayUpdateError(errmsgParent, SAVE_FAILED, ERR_ADD, 1);
304 AlarmListView::modifyEvent(event, selectionView);
314 UpdateStatus updateTemplate(
const KAEvent& event, TemplateListView* selectionView, TQWidget* errmsgParent)
319 status = UPDATE_FAILED;
322 cal->updateEvent(event);
324 status = SAVE_FAILED;
327 TemplateListView::modifyEvent(event.id(), event, selectionView);
333 displayUpdateError(errmsgParent, SAVE_FAILED, ERR_TEMPLATE, 1);
343 TQString
id =
event.id();
344 kdDebug(5950) <<
"KAlarm::deleteEvent(): " <<
id << endl;
347 AlarmListView::deleteEvent(
id);
353 if (KAEvent::uidStatus(
id) == KAEvent::EXPIRED)
355 cal = AlarmCalendar::expiredCalendarOpen();
357 status = UPDATE_FAILED;
361 if (event.copyToKOrganizer())
366 if (!deleteFromKOrganizer(event.id()))
367 status = UPDATE_KORG_ERR;
369 if (archive && event.toBeArchived())
370 addExpiredEvent(event);
371 cal = AlarmCalendar::activeCalendar();
373 if (status != UPDATE_FAILED)
375 if (!cal->deleteEvent(
id,
true))
376 status = SAVE_FAILED;
378 if (status > UPDATE_KORG_ERR && errmsgParent)
379 displayUpdateError(errmsgParent, SAVE_FAILED, ERR_DELETE, 1);
388 TQString
id =
event.id();
393 return UPDATE_FAILED;
394 if (!cal->deleteEvent(
id,
true))
396 cal->emitEmptyStatus();
399 TemplateListView::deleteEvent(
id);
406 void deleteDisplayEvent(
const TQString& eventID)
408 kdDebug(5950) <<
"KAlarm::deleteDisplayEvent(" << eventID <<
")\n";
410 if (KAEvent::uidStatus(eventID) == KAEvent::DISPLAYING)
414 cal->deleteEvent(eventID,
true);
424 UpdateStatus reactivateEvent(
KAEvent& event, AlarmListView* selectionView,
bool useEventID)
426 TQString
id =
event.id();
427 kdDebug(5950) <<
"KAlarm::reactivateEvent(): " <<
id << endl;
430 if (KAEvent::uidStatus(
id) == KAEvent::EXPIRED)
432 TQDateTime now = TQDateTime::currentDateTime();
433 if (event.occursAfter(now,
true))
435 if (event.recurs() || event.repeatCount())
436 event.setNextOccurrence(now);
441 if (!cal->addEvent(event, useEventID))
442 return UPDATE_FAILED;
447 if (event.copyToKOrganizer())
449 if (!sendToKOrganizer(event))
450 status = UPDATE_KORG_ERR;
454 AlarmListView::undeleteEvent(
id, event, selectionView);
456 cal = AlarmCalendar::expiredCalendarOpen();
458 cal->deleteEvent(
id,
true);
462 return UPDATE_FAILED;
473 kdDebug(5950) <<
"KAlarm::enableEvent(" << enable <<
"): " <<
event.id() << endl;
475 if (enable != event.enabled())
477 event.setEnabled(enable);
481 cal->updateEvent(event);
486 if (!enable && event.displayAction())
488 MessageWin* win = MessageWin::findEvent(event.id());
493 AlarmListView::modifyEvent(event, selectionView);
501 void displayUpdateError(TQWidget* parent, UpdateStatus, UpdateError code,
int nAlarms)
507 errmsg = (nAlarms > 1) ? i18n(
"Error saving alarms")
508 : i18n(
"Error saving alarm");
511 errmsg = (nAlarms > 1) ? i18n(
"Error deleting alarms")
512 : i18n(
"Error deleting alarm");
515 errmsg = (nAlarms > 1) ? i18n(
"Error saving reactivated alarms")
516 : i18n(
"Error saving reactivated alarm");
519 errmsg = i18n(
"Error saving alarm template");
522 KMessageBox::error(parent, errmsg);
528 void displayKOrgUpdateError(TQWidget* parent, KOrgUpdateError code,
int nAlarms)
534 errmsg = (nAlarms > 1) ? i18n(
"Unable to show alarms in KOrganizer")
535 : i18n(
"Unable to show alarm in KOrganizer");
537 case KORG_ERR_MODIFY:
538 errmsg = i18n(
"Unable to update alarm in KOrganizer");
540 case KORG_ERR_DELETE:
541 errmsg = (nAlarms > 1) ? i18n(
"Unable to delete alarms from KOrganizer")
542 : i18n(
"Unable to delete alarm from KOrganizer");
545 KMessageBox::error(parent, errmsg);
551 bool edit(
const TQString& eventID)
554 switch (KAEvent::uidStatus(eventID))
556 case KAEvent::ACTIVE:
557 cal = AlarmCalendar::activeCalendar();
559 case KAEvent::TEMPLATE:
560 cal = AlarmCalendar::templateCalendarOpen();
563 kdError(5950) <<
"KAlarm::edit(" << eventID <<
"): event not active or template" << endl;
569 kdError(5950) <<
"KAlarm::edit(): event ID not found: " << eventID << endl;
573 MainWindow::executeEdit(event);
581 bool editNew(
const TQString& templateName)
584 if (!templateName.isEmpty())
589 KAEvent templateEvent = KAEvent::findTemplateName(*cal, templateName);
590 if (templateEvent.valid())
592 MainWindow::executeNew(templateEvent);
595 kdWarning(5950) <<
"KAlarm::editNew(" << templateName <<
"): template not found" << endl;
599 MainWindow::executeNew();
607 TQValueList<KAEvent> templateList()
609 TQValueList<KAEvent> templates;
613 bool includeCmdAlarms = ShellProcess::authorised();
614 KCal::Event::List events = cal->events();
615 for (KCal::Event::List::ConstIterator it = events.begin(); it != events.end(); ++it)
619 if (includeCmdAlarms || event.action() != KAEvent::COMMAND)
620 templates.append(event);
631 void outputAlarmWarnings(TQWidget* parent,
const KAEvent* event)
633 if (event && event->action() == KAEvent::EMAIL
634 && Preferences::emailAddress().isEmpty())
635 KMessageBox::information(parent, i18n(
"Please set the 'From' email address...",
636 "%1\nPlease set it in the Preferences dialog.").arg(KAMail::i18n_NeedFromEmailAddress()));
638 if (!Daemon::monitoringAlarms())
640 if (KMessageBox::warningYesNo(parent, i18n(
"Alarms are currently disabled.\nDo you want to enable alarms now?"),
641 TQString(), i18n(
"Enable"), i18n(
"Keep Disabled"),
642 TQString::fromLatin1(
"EditEnableAlarms"))
644 Daemon::setAlarmsEnabled();
654 kdDebug(5950) <<
"KAlarm::resetDaemon()" << endl;
655 if (!resetDaemonQueued)
657 resetDaemonQueued =
true;
658 theApp()->processQueue();
669 void resetDaemonIfQueued()
671 if (resetDaemonQueued)
673 kdDebug(5950) <<
"KAlarm::resetDaemonIfNeeded()" << endl;
674 AlarmCalendar::activeCalendar()->reload();
675 AlarmCalendar::expiredCalendar()->reload();
679 KCal::Event::List events = AlarmCalendar::activeCalendar()->events();
680 for (KCal::Event::List::ConstIterator it = events.begin(); it != events.end(); ++it)
683 event.set(*kcalEvent);
684 if (!event.enabled() && event.displayAction())
686 MessageWin* win = MessageWin::findEvent(event.id());
691 MainWindow::refresh();
692 if (!Daemon::reset())
694 resetDaemonQueued =
false;
703 TQString runKMail(
bool minimise)
707 if (!runProgram(
"kmail", (minimise ? KMAIL_DCOP_WINDOW :
""), dcopName, errmsg))
708 return i18n(
"Unable to start KMail\n(%1)").arg(errmsg);
719 bool runProgram(
const TQCString& program,
const TQCString& windowName, TQCString& dcopName, TQString& errorMessage)
721 if (!kapp->dcopClient()->isApplicationRegistered(program))
724 if (TDEApplication::startServiceByDesktopName(TQString::fromLatin1(program), TQString(), &errorMessage, &dcopName))
726 kdError(5950) <<
"runProgram(): couldn't start " << program <<
" (" << errorMessage <<
")\n";
732 kapp->dcopClient()->send(dcopName, windowName,
"minimize()", TQString());
734 else if (dcopName.isEmpty())
736 errorMessage = TQString();
746 bool readConfigWindowSize(
const char* window, TQSize& result)
748 TDEConfig* config = TDEGlobal::config();
749 config->setGroup(TQString::fromLatin1(window));
750 TQWidget* desktop = TDEApplication::desktop();
751 TQSize s = TQSize(config->readNumEntry(TQString::fromLatin1(
"Width %1").arg(desktop->width()), 0),
752 config->readNumEntry(TQString::fromLatin1(
"Height %1").arg(desktop->height()), 0));
763 void writeConfigWindowSize(
const char* window,
const TQSize& size)
765 TDEConfig* config = TDEGlobal::config();
766 config->setGroup(TQString::fromLatin1(window));
767 TQWidget* desktop = TDEApplication::desktop();
768 config->writeEntry(TQString::fromLatin1(
"Width %1").arg(desktop->width()), size.width());
769 config->writeEntry(TQString::fromLatin1(
"Height %1").arg(desktop->height()), size.height());
778 static int version = 0;
780 version = getVersionNumber(KALARM_VERSION);
790 int getVersionNumber(
const TQString& version, TQString* subVersion)
795 *subVersion = TQString();
796 int count = version.contains(
'.') + 1;
800 unsigned vernum = version.section(
'.', 0, 0).toUInt(&ok) * 10000;
803 unsigned v = version.section(
'.', 1, 1).toUInt(&ok);
806 vernum += (v < 99 ? v : 99) * 100;
810 TQString issue = version.section(
'.', 2);
811 if (!issue.at(0).isDigit())
813 int n = issue.length();
815 for (i = 0; i < n && issue.at(i).isDigit(); ++i) ;
817 *subVersion = issue.mid(i);
818 v = issue.left(i).toUInt();
819 vernum += (v < 99 ? v : 99);
829 FileType fileType(
const TQString& mimetype)
831 static const char* applicationTypes[] = {
832 "x-shellscript",
"x-nawk",
"x-awk",
"x-perl",
"x-python",
833 "x-desktop",
"x-troff", 0 };
834 static const char* formattedTextTypes[] = {
837 if (mimetype.startsWith(TQString::fromLatin1(
"image/")))
839 int slash = mimetype.find(
'/');
842 TQString type = mimetype.mid(slash + 1);
843 const char* typel = type.latin1();
844 if (mimetype.startsWith(TQString::fromLatin1(
"application")))
846 for (
int i = 0; applicationTypes[i]; ++i)
847 if (!strcmp(typel, applicationTypes[i]))
848 return TextApplication;
850 else if (mimetype.startsWith(TQString::fromLatin1(
"text")))
852 for (
int i = 0; formattedTextTypes[i]; ++i)
853 if (!strcmp(typel, formattedTextTypes[i]))
854 return TextFormatted;
870 TQString browseFile(
const TQString& caption, TQString& defaultDir,
const TQString& initialFile,
871 const TQString& filter,
int mode, TQWidget* parent,
const char* name)
873 TQString initialDir = !initialFile.isEmpty() ? TQString(initialFile).remove(TQRegExp(
"/[^/]*$"))
874 : !defaultDir.isEmpty() ? defaultDir
875 : TQDir::homeDirPath();
876 KFileDialog fileDlg(initialDir, filter, parent, name,
true);
877 fileDlg.setOperationMode(mode & KFile::ExistingOnly ? KFileDialog::Opening : KFileDialog::Saving);
878 fileDlg.setMode(KFile::File | mode);
879 fileDlg.setCaption(caption);
880 if (!initialFile.isEmpty())
881 fileDlg.setSelection(initialFile);
882 if (fileDlg.exec() != TQDialog::Accepted)
884 KURL url = fileDlg.selectedURL();
885 defaultDir = url.path();
886 return (mode & KFile::LocalOnly) ? url.path() : url.prettyURL();
893 int localeFirstDayOfWeek()
895 static int firstDay = 0;
897 firstDay = TDEGlobal::locale()->weekStartDay();
904 TQString stripAccel(
const TQString& text)
906 unsigned len = text.length();
907 TQString out = TQDeepCopy<TQString>(text);
908 TQChar *corig = (TQChar*)out.unicode();
909 TQChar *cout = corig;
925 unsigned newlen = cout - corig;
926 if (newlen != out.length())
927 out.truncate(newlen);
941 bool sendToKOrganizer(
const KAEvent& event)
944 TQString uid = KAEvent::uid(event.id(), KAEvent::KORGANIZER);
948 switch (event.action())
950 case KAEvent::MESSAGE:
952 case KAEvent::COMMAND:
954 userEmail = Preferences::emailAddress();
958 TQString from =
event.emailFromId()
959 ? KAMail::identityManager()->identityForUoid(event.emailFromId()).fullEmailAddr()
960 : Preferences::emailAddress();
962 atext.setEmail(event.emailAddresses(
", "), from, TQString(), TQString(), event.emailSubject(), TQString());
974 kdDebug(5950)<<
"Korg->"<<iCal<<endl;
978 if (!runKOrganizer())
980 TQByteArray data, replyData;
982 TQDataStream arg(data, IO_WriteOnly);
984 if (kapp->dcopClient()->call(korganizerName, KORG_DCOP_OBJECT,
"addIncidence(TQString)", data, replyType, replyData)
985 && replyType ==
"bool")
988 TQDataStream reply(replyData, IO_ReadOnly);
992 kdDebug(5950) <<
"sendToKOrganizer(" << uid <<
"): success\n";
996 kdError(5950) <<
"sendToKOrganizer(): KOrganizer addEvent(" << uid <<
") dcop call failed\n";
1003 bool deleteFromKOrganizer(
const TQString& eventID)
1005 if (!runKOrganizer())
1007 TQString newID = KAEvent::uid(eventID, KAEvent::KORGANIZER);
1008 TQByteArray data, replyData;
1009 TQCString replyType;
1010 TQDataStream arg(data, IO_WriteOnly);
1011 arg << newID <<
true;
1012 if (kapp->dcopClient()->call(korganizerName, KORG_DCOP_OBJECT,
"deleteIncidence(TQString,bool)", data, replyType, replyData)
1013 && replyType ==
"bool")
1016 TQDataStream reply(replyData, IO_ReadOnly);
1020 kdDebug(5950) <<
"deleteFromKOrganizer(" << newID <<
"): success\n";
1024 kdError(5950) <<
"sendToKOrganizer(): KOrganizer deleteEvent(" << newID <<
") dcop call failed\n";
1031 bool runKOrganizer()
1034 TQCString dcopService;
1035 int result = KDCOPServiceStarter::self()->findServiceFor(
"DCOP/Organizer", TQString(), TQString(), &error, &dcopService);
1038 kdDebug(5950) <<
"Unable to start DCOP/Organizer: " << dcopService <<
" " << error << endl;
1045 if (!kapp->dcopClient()->findObject(dcopService, KORG_DCOP_OBJECT,
"", TQByteArray(), dummy, dummy))
1047 DCOPRef ref(dcopService, dcopService);
1048 DCOPReply reply = ref.call(
"load()");
1049 if (!reply.isValid() || !(
bool)reply)
1051 kdWarning(5950) <<
"Error loading " << dcopService << endl;
1054 if (!kapp->dcopClient()->findObject(dcopService, KORG_DCOP_OBJECT,
"", TQByteArray(), dummy, dummy))
1056 kdWarning(5950) <<
"Unable to access KOrganizer's " KORG_DCOP_OBJECT
" DCOP object" << endl;
1066 #include <X11/keysym.h>
1067 #include <X11/extensions/XTest.h>
1068 #include <tqwindowdefs.h>
1074 void x11_cancelScreenSaver()
1076 kdDebug(5950) <<
"KAlarm::cancelScreenSaver()" << endl;
1077 Display* display = tqt_xdisplay();
1078 static int XTestKeyCode = 0;
1080 XTestKeyCode = XKeysymToKeycode(display, XK_Shift_L);
1081 XTestFakeKeyEvent(display, XTestKeyCode,
true, CurrentTime);
1082 XTestFakeKeyEvent(display, XTestKeyCode,
false, CurrentTime);
1083 XSync(display,
false);
represents calendar alarms and events
Provides read and write access to calendar files.
KAEvent corresponds to a KCal::Event instance.
void setOrganizer(const Person &o)
void setUid(const TQString &)
void setSummary(const TQString &summary)
MessageWin: A window to display an alarm message.
UpdateStatus
Return codes from calendar update functions.
FileType
Return codes from fileType()
the KAlarm application object
displays an alarm message