29 #include "alarmresources.h"
47 #include <kalarmcal/identities.h>
48 #include <kalarmcal/kaevent.h>
51 #include <kcalcore/event.h>
52 #include <kcalcore/icalformat.h>
53 #include <kcalcore/person.h>
54 #include <kcalcore/duration.h>
55 using namespace KCalCore;
57 #include <kcal/event.h>
58 #include <kcal/icalformat.h>
59 #include <kcal/person.h>
60 #include <kcal/duration.h>
63 #include <kpimidentities/identitymanager.h>
64 #include <kpimidentities/identity.h>
65 #include <kholidays/holidays.h>
67 #include <kconfiggroup.h>
69 #include <ktoggleaction.h>
70 #include <kactioncollection.h>
71 #include <kdbusservicestarter.h>
74 #include <kstandarddirs.h>
76 #include <ksystemtimezone.h>
77 #include <kstandardguiitem.h>
78 #include <kstandardshortcut.h>
79 #include <kfiledialog.h>
81 #include <kio/netaccess.h>
82 #include <kfileitem.h>
84 #include <ktoolinvocation.h>
87 #include <kwindowsystem.h>
88 #include <kxmessages.h>
89 #include <kstartupinfo.h>
96 #include <QDesktopWidget>
97 #include <QtDBus/QtDBus>
102 using namespace Akonadi;
108 bool refreshAlarmsQueued =
false;
111 struct UpdateStatusData
117 explicit UpdateStatusData(KAlarm::UpdateStatus s = KAlarm::UPDATE_OK) : status(s), warnErr(0), warnKOrg(0) {}
119 void setError(KAlarm::UpdateStatus st,
int errorCount = -1)
125 warnErr = errorCount;
130 if (result.
status != KAlarm::UPDATE_OK)
133 if (result.
status > status.status)
143 const QLatin1String KORG_DBUS_IFACE(
"org.kde.korganizer.Korganizer");
145 #define KORG_DBUS_PATH "/Korganizer"
146 #define KORG_DBUS_LOAD_PATH "/korganizer_PimApplication"
149 const QLatin1String KORG_MIME_TYPE(
"application/x-vnd.akonadi.calendar.event");
154 const char* DONT_SHOW_ERRORS_GROUP =
"DontShowErrors";
157 void displayUpdateError(
QWidget* parent, KAlarm::UpdateError,
const UpdateStatusData&,
bool showKOrgError =
true);
168 Private* Private::mInstance = 0;
174 MainWindow* displayMainWindowSelected(Akonadi::Item::Id eventId)
182 if (
theApp()->checkCalendar())
192 win->setWindowState(win->windowState() & ~Qt::WindowMinimized);
195 win->activateWindow();
198 if (win && eventId >= 0)
210 KToggleAction* createAlarmEnableAction(
QObject* parent)
212 KToggleAction* action =
new KToggleAction(i18nc(
"@action",
"Enable &Alarms"), parent);
213 action->setChecked(
theApp()->alarmsEnabled());
223 KAction* createStopPlayAction(
QObject* parent)
225 KAction* action =
new KAction(KIcon(
QLatin1String(
"media-playback-stop")), i18nc(
"@action",
"Stop Play"), parent);
236 KToggleAction* createSpreadWindowsAction(
QObject* parent)
238 KToggleAction* action =
new KToggleAction(i18nc(
"@action",
"Spread Windows"), parent);
253 UpdateResult addEvent(KAEvent& event, Collection* calendar,
QWidget* msgParent,
int options,
bool showKOrgErr)
255 UpdateResult addEvent(KAEvent& event, AlarmResource* calendar,
QWidget* msgParent,
int options,
bool showKOrgErr)
258 kDebug() <<
event.id();
259 bool cancelled =
false;
260 UpdateStatusData status;
261 if (!
theApp()->checkCalendar())
262 status.status = UPDATE_FAILED;
269 if (!cal->
addEvent(event, msgParent, (options & USE_EVENT_ID), calendar, (options & NO_RESOURCE_PROMPT), &cancelled))
271 KAEvent* newev =
new KAEvent(event);
272 if (!cal->
addEvent(newev, msgParent, (options & USE_EVENT_ID), calendar, (options & NO_RESOURCE_PROMPT), &cancelled))
278 status.status = UPDATE_FAILED;
286 status.status = SAVE_FAILED;
288 if (status.status == UPDATE_OK)
290 if ((options & ALLOW_KORG_UPDATE) &&
event.copyToKOrganizer())
292 UpdateResult st = sendToKOrganizer(event);
293 status.korgUpdate(st);
303 if (status.status != UPDATE_OK && !cancelled && msgParent)
304 displayUpdateError(msgParent, ERR_ADD, status, showKOrgErr);
305 return status.status;
315 kDebug() << events.
count();
317 return UpdateResult(UPDATE_OK);
318 UpdateStatusData status;
320 Collection collection;
322 AlarmResource* resource;
325 status.status = UPDATE_FAILED;
330 if (!collection.isValid())
332 resource = AlarmResources::instance()->destination(CalEvent::ACTIVE, msgParent);
336 kDebug() <<
"No calendar";
337 status.status = UPDATE_FAILED;
340 if (status.status == UPDATE_OK)
344 for (
int i = 0, end = events.
count(); i < end; ++i)
348 if (!cal->
addEvent(events[i], msgParent,
false, &collection))
350 KAEvent* newev =
new KAEvent(events[i]);
351 if (!cal->
addEvent(newev, msgParent,
false, resource))
357 status.setError(UPDATE_ERROR);
363 if (allowKOrgUpdate && events[i].copyToKOrganizer())
365 UpdateResult st = sendToKOrganizer(events[i]);
366 status.korgUpdate(st);
375 if (status.warnErr == events.
count())
376 status.status = UPDATE_FAILED;
377 else if (!cal->
save())
378 status.setError(SAVE_FAILED, events.
count());
381 if (status.status != UPDATE_OK && msgParent)
382 displayUpdateError(msgParent, ERR_ADD, status, showKOrgErr);
383 return status.status;
391 bool addArchivedEvent(KAEvent& event, Collection* collection)
393 bool addArchivedEvent(KAEvent& event, AlarmResource* resource)
396 kDebug() <<
event.id();
398 bool archiving = (
event.category() == CalEvent::ACTIVE);
399 if (archiving && !Preferences::archivedKeepDays())
403 KAEvent newevent(event);
404 newevent.setItemId(-1);
405 KAEvent*
const newev = &newevent;
407 KAEvent* newev =
new KAEvent(event);
411 newev->setCategory(CalEvent::ARCHIVED);
412 newev->setCreatedDateTime(KDateTime::currentUtcDateTime());
416 if (!cal->
addEvent(newevent, 0,
false, collection))
419 if (!cal->
addEvent(newev, 0,
false, resource))
446 UpdateResult addTemplate(KAEvent& event, Collection* collection,
QWidget* msgParent)
448 UpdateResult addTemplate(KAEvent& event, AlarmResource* resource,
QWidget* msgParent)
451 kDebug() <<
event.id();
452 UpdateStatusData status;
457 KAEvent newev(event);
458 if (!cal->
addEvent(newev, msgParent,
false, collection))
459 status.status = UPDATE_FAILED;
461 KAEvent* newev =
new KAEvent(event);
462 if (!cal->
addEvent(newev, msgParent,
false, resource))
465 status.status = UPDATE_FAILED;
476 status.status = SAVE_FAILED;
483 return UpdateResult(UPDATE_OK);
488 displayUpdateError(msgParent, ERR_TEMPLATE, status);
489 return status.status;
497 UpdateResult modifyEvent(KAEvent& oldEvent, KAEvent& newEvent,
QWidget* msgParent,
bool showKOrgErr)
499 kDebug() << oldEvent.id();
501 UpdateStatusData status;
502 if (!newEvent.isValid())
504 deleteEvent(oldEvent,
true);
505 status.status = UPDATE_FAILED;
514 if (oldEvent.copyToKOrganizer())
520 deleteFromKOrganizer(oldId.eventId());
522 deleteFromKOrganizer(oldId);
529 status.status = UPDATE_FAILED;
536 KAEvent* newev =
new KAEvent(newEvent);
541 status.status = UPDATE_FAILED;
550 status.status = SAVE_FAILED;
551 if (status.status == UPDATE_OK)
553 if (newEvent.copyToKOrganizer())
555 UpdateResult st = sendToKOrganizer(newEvent);
556 status.korgUpdate(st);
560 setDontShowErrors(oldId);
570 if (status.status != UPDATE_OK && msgParent)
571 displayUpdateError(msgParent, ERR_MODIFY, status, showKOrgErr);
572 return status.status;
582 UpdateResult updateEvent(KAEvent& event,
QWidget* msgParent,
bool archiveOnDelete)
584 kDebug() <<
event.id();
586 if (!event.isValid())
587 deleteEvent(event, archiveOnDelete);
600 displayUpdateError(msgParent, ERR_ADD, UpdateStatusData(SAVE_FAILED));
601 return UpdateResult(SAVE_FAILED);
609 return UpdateResult(UPDATE_OK);
617 UpdateResult updateTemplate(KAEvent& event,
QWidget* msgParent)
621 UpdateStatus status = UPDATE_OK;
623 status = UPDATE_FAILED;
624 else if (!cal->
save())
625 status = SAVE_FAILED;
626 if (status != UPDATE_OK)
629 displayUpdateError(msgParent, ERR_TEMPLATE, UpdateStatusData(SAVE_FAILED));
630 return UpdateResult(status);
636 return UpdateResult(UPDATE_OK);
643 UpdateResult deleteEvent(KAEvent& event,
bool archive,
QWidget* msgParent,
bool showKOrgErr)
648 KAEvent::List events;
651 return deleteEvents(events, archive, msgParent, showKOrgErr);
657 UpdateResult deleteEvents(KAEvent::List& events,
bool archive,
QWidget* msgParent,
bool showKOrgErr)
660 kDebug() << events.count();
661 if (events.isEmpty())
662 return UpdateResult(UPDATE_OK);
663 UpdateStatusData status;
665 bool deleteWakeFromSuspendAlarm =
false;
666 QString wakeFromSuspendId = checkRtcWakeConfig().
value(0);
667 for (
int i = 0, end = events.count(); i < end; ++i)
671 KAEvent*
event = &events[i];
673 KAEvent*
event = events[i];
680 event->setCommandError(KAEvent::CMD_NO_ERROR);
684 if (event->category() != CalEvent::ARCHIVED)
686 if (event->copyToKOrganizer())
691 UpdateResult st = deleteFromKOrganizer(
id);
692 status.korgUpdate(st);
694 if (archive && event->toBeArchived())
697 addArchivedEvent(ev);
705 status.setError(UPDATE_ERROR);
707 if (
id == wakeFromSuspendId)
708 deleteWakeFromSuspendAlarm =
true;
712 setDontShowErrors(
EventId(*event));
714 setDontShowErrors(
id);
718 if (status.warnErr == events.count())
719 status.status = UPDATE_FAILED;
720 else if (!cal->
save())
721 status.setError(SAVE_FAILED, events.count());
722 if (status.status != UPDATE_OK && msgParent)
723 displayUpdateError(msgParent, ERR_DELETE, status, showKOrgErr);
726 if (deleteWakeFromSuspendAlarm && !wakeFromSuspendId.
isEmpty())
727 cancelRtcWake(msgParent, wakeFromSuspendId);
729 return status.status;
736 UpdateResult deleteTemplates(
const KAEvent::List& events,
QWidget* msgParent)
742 int count = events.count();
744 int count = eventIDs.
count();
748 return UpdateResult(UPDATE_OK);
749 UpdateStatusData status;
751 for (
int i = 0, end = count; i < end; ++i)
766 status.setError(UPDATE_ERROR);
769 if (status.warnErr == count)
770 status.status = UPDATE_FAILED;
771 else if (!cal->
save())
772 status.setError(SAVE_FAILED, count);
773 if (status.status != UPDATE_OK && msgParent)
774 displayUpdateError(msgParent, ERR_TEMPLATE, status);
775 return status.status;
781 void deleteDisplayEvent(
const QString& eventID)
787 cal->deleteDisplayEvent(eventID,
true);
799 UpdateResult reactivateEvent(KAEvent& event, Collection* calendar,
QWidget* msgParent,
bool showKOrgErr)
801 UpdateResult reactivateEvent(KAEvent& event, AlarmResource* calendar,
QWidget* msgParent,
bool showKOrgErr)
809 KAEvent::List events;
812 return reactivateEvents(events, ids, calendar, msgParent, showKOrgErr);
818 UpdateResult reactivateEvents(KAEvent::List& events,
QStringList& ineligibleIDs, AlarmResource* resource,
QWidget* msgParent,
bool showKOrgErr)
821 kDebug() << events.count();
822 ineligibleIDs.
clear();
823 if (events.isEmpty())
824 return UpdateResult(UPDATE_OK);
825 UpdateStatusData status;
827 Collection collection;
830 if (!collection.isValid())
832 if (!collection.isValid())
835 resource = AlarmResources::instance()->destination(CalEvent::ACTIVE, msgParent);
839 kDebug() <<
"No calendar";
840 status.setError(UPDATE_FAILED, events.count());
847 KDateTime now = KDateTime::currentUtcDateTime();
848 for (
int i = 0, end = events.count(); i < end; ++i)
852 KAEvent*
event = &events[i];
854 KAEvent*
event = events[i];
856 if (event->category() != CalEvent::ARCHIVED
857 || !
event->occursAfter(now,
true))
860 ineligibleIDs +=
EventId(*event);
862 ineligibleIDs +=
event->id();
869 KAEvent newevent(*event);
870 KAEvent*
const newev = &newevent;
872 KAEvent* newev =
new KAEvent(*event);
875 newev->setCategory(CalEvent::ACTIVE);
876 if (newev->recurs() || newev->repetition())
877 newev->setNextOccurrence(now);
883 if (!cal->
addEvent(newevent, msgParent,
true, &collection))
885 if (!cal->
addEvent(newev, msgParent,
true, resource))
891 status.setError(UPDATE_ERROR);
894 if (newev->copyToKOrganizer())
896 UpdateResult st = sendToKOrganizer(*newev);
897 status.korgUpdate(st);
910 if (cal->
event(oldid)
913 status.setError(UPDATE_ERROR);
915 events[i] = newevent;
921 if (status.warnErr == count)
922 status.status = UPDATE_FAILED;
924 if (!cal->
save() && status.status != UPDATE_FAILED)
925 status.setError(SAVE_FAILED, count);
927 if (status.status != UPDATE_OK && msgParent)
928 displayUpdateError(msgParent, ERR_REACTIVATE, status, showKOrgErr);
929 return status.status;
939 UpdateResult enableEvents(KAEvent::List& events,
bool enable,
QWidget* msgParent)
942 kDebug() << events.count();
943 if (events.isEmpty())
944 return UpdateResult(UPDATE_OK);
945 UpdateStatusData status;
947 bool deleteWakeFromSuspendAlarm =
false;
948 QString wakeFromSuspendId = checkRtcWakeConfig().
value(0);
949 for (
int i = 0, end = events.count(); i < end; ++i)
952 KAEvent*
event = &events[i];
954 KAEvent*
event = events[i];
956 if (event->category() == CalEvent::ACTIVE
957 && enable !=
event->enabled())
959 event->setEnabled(enable);
961 if (!enable && event->id() == wakeFromSuspendId)
962 deleteWakeFromSuspendAlarm =
true;
967 kError() <<
"Error updating event in calendar:" <<
event->id();
973 if (!enable && (event->actionTypes() & KAEvent::ACT_DISPLAY))
992 status.setError(SAVE_FAILED, events.count());
993 if (status.status != UPDATE_OK && msgParent)
994 displayUpdateError(msgParent, ERR_ADD, status);
997 if (deleteWakeFromSuspendAlarm && !wakeFromSuspendId.
isEmpty())
998 cancelRtcWake(msgParent, wakeFromSuspendId);
1000 return status.status;
1011 void purgeArchive(
int purgeDays)
1015 kDebug() << purgeDays;
1016 QDate cutoff = KDateTime::currentLocalDate().
addDays(-purgeDays);
1019 if (!collection.isValid())
1022 for (
int i = 0; i < events.count(); )
1024 if (purgeDays && events[i]->createdDateTime().date() >= cutoff)
1030 AlarmResource* resource = AlarmResources::instance()->getStandardResource(CalEvent::ARCHIVED);
1034 for (
int i = 0; i < events.count(); )
1036 KAEvent*
event = events[i];
1037 Incidence* kcalIncidence = resource->incidence(event->id());
1038 if (purgeDays && kcalIncidence && kcalIncidence->created().date() >= cutoff)
1044 if (!events.isEmpty())
1062 (*model)->setEventTypeFilter(CalEvent::ACTIVE);
1066 for (
int i = 0, count = (*model)->rowCount(); i < count; ++i)
1068 KAEvent
event = (*model)->event(i);
1069 if (event.enabled() && !
event.expired())
1078 KAEvent::List getSortedActiveEvents(
const KDateTime& startTime,
const KDateTime& endTime)
1080 KAEvent::List events;
1081 if (endTime.isValid())
1085 KAEvent::List result;
1086 for (
int i = 0, count = events.count(); i < count; ++i)
1088 KAEvent*
event = events[i];
1089 if (event->enabled() && !
event->expired())
1099 void displayKOrgUpdateError(
QWidget* parent, UpdateError code, UpdateResult korgError,
int nAlarms)
1105 case ERR_REACTIVATE:
1106 errmsg = (nAlarms > 1) ? i18nc(
"@info",
"Unable to show alarms in KOrganizer")
1107 : i18nc(
"@info",
"Unable to show alarm in KOrganizer");
1110 errmsg = i18nc(
"@info",
"Unable to update alarm in KOrganizer");
1113 errmsg = (nAlarms > 1) ? i18nc(
"@info",
"Unable to delete alarms from KOrganizer")
1114 : i18nc(
"@info",
"Unable to delete alarm from KOrganizer");
1119 bool showDetail = !korgError.message.isEmpty();
1121 switch (korgError.status)
1123 case UPDATE_KORG_ERRINIT:
1124 msg = i18nc(
"@info",
"<para>%1</para><para>(Could not start KOrganizer)</para>", errmsg);
1126 case UPDATE_KORG_ERRSTART:
1127 msg = i18nc(
"@info",
"<para>%1</para><para>(KOrganizer not fully started)</para>", errmsg);
1129 case UPDATE_KORG_ERR:
1130 msg = i18nc(
"@info",
"<para>%1</para><para>(Error communicating with KOrganizer)</para>", errmsg);
1154 void editNewAlarm(KAEvent::SubAction action,
QWidget* parent,
const AlarmText*
text)
1156 bool setAction =
false;
1160 case KAEvent::MESSAGE:
1165 case KAEvent::COMMAND:
1168 case KAEvent::EMAIL:
1171 case KAEvent::AUDIO:
1178 if (setAction || text)
1180 execNewAlarmDlg(editDlg);
1187 void editNewAlarm(
const KAEvent* preset,
QWidget* parent)
1199 new PrivateNewAlarmDlg(editDlg);
1202 editDlg->activateWindow();
1208 connect(dlg, SIGNAL(accepted()), SLOT(okClicked()));
1209 connect(dlg, SIGNAL(rejected()), SLOT(cancelClicked()));
1216 void PrivateNewAlarmDlg::okClicked()
1228 Collection calendar;
1230 AlarmResource* calendar;
1232 editDlg->
getEvent(event, calendar);
1236 UpdateResult status = addEvent(event, &calendar, editDlg);
1238 UpdateResult status = addEvent(event, calendar, editDlg);
1244 case UPDATE_KORG_ERR:
1245 case UPDATE_KORG_ERRINIT:
1246 case UPDATE_KORG_ERRSTART:
1247 case UPDATE_KORG_FUNCERR:
1248 displayKOrgUpdateError(editDlg, ERR_ADD, status);
1255 outputAlarmWarnings(editDlg, &event);
1257 editDlg->deleteLater();
1263 void PrivateNewAlarmDlg::cancelClicked()
1276 if (templateEvent->isValid())
1278 editNewAlarm(templateEvent, parent);
1281 kWarning() << templateName <<
": template not found";
1291 ::editNewTemplate(type, 0, parent);
1297 void editNewTemplate(
const KAEvent* preset,
QWidget* parent)
1312 QStringList checkRtcWakeConfig(
bool checkEventExists)
1314 KConfigGroup config(KGlobal::config(),
"General");
1317 if (params.
count() == 3 && params[2].toUInt() > KDateTime::currentUtcDateTime().toTime_t())
1319 if (params.
count() == 2 && params[1].toUInt() > KDateTime::currentUtcDateTime().toTime_t())
1332 config.deleteEntry(
"RtcWake");
1341 void deleteRtcWakeConfig()
1343 KConfigGroup config(KGlobal::config(),
"General");
1344 config.deleteEntry(
"RtcWake");
1354 if (!wakeup.
isEmpty() && (eventId.
isEmpty() || wakeup[0] == eventId))
1368 deleteRtcWakeConfig();
1377 bool setRtcWakeTime(
unsigned triggerTime,
QWidget* parent)
1381 KAuth::Action action(
QLatin1String(
"org.kde.kalarmrtcwake.settimer"));
1383 action.setParentWidget(parent);
1384 action.setArguments(args);
1385 KAuth::ActionReply reply = action.execute();
1388 QString errmsg = reply.errorDescription();
1389 kDebug() <<
"Error code=" << reply.errorCode() << errmsg;
1392 int errcode = reply.errorCode();
1393 switch (reply.type())
1395 case KAuth::ActionReply::KAuthError:
1396 kDebug() <<
"Authorisation error:" << errcode;
1399 case KAuth::ActionReply::AuthorizationDenied:
1400 case KAuth::ActionReply::UserCancelled:
1406 case KAuth::ActionReply::HelperError:
1407 kDebug() <<
"Helper error:" << errcode;
1413 errmsg = i18nc(
"@info",
"Error obtaining authorization (%1)", errcode);
1435 if (!AlarmResources::instance()->activeCount(CalEvent::TEMPLATE,
true))
1438 KAMessageBox::sorry(parent, i18nc(
"@info",
"You must enable a template calendar to save the template in"));
1449 if (editDlg->exec() == QDialog::Accepted)
1453 Akonadi::Collection calendar;
1455 AlarmResource* calendar;
1457 editDlg->
getEvent(event, calendar);
1461 KAlarm::addTemplate(event, &calendar, editDlg);
1463 KAlarm::addTemplate(event, calendar, editDlg);
1477 void editAlarm(KAEvent* event,
QWidget* parent)
1485 viewAlarm(event, parent);
1497 if (editDlg->exec() == QDialog::Accepted)
1503 PrivateNewAlarmDlg().accept(editDlg);
1508 Collection calendar;
1510 AlarmResource* calendar;
1512 bool changeDeferral = !editDlg->
getEvent(newEvent, calendar);
1519 if (updateEvent(newEvent, editDlg,
true) != UPDATE_OK)
1524 UpdateResult status = modifyEvent(*event, newEvent, editDlg);
1525 if (status.status != UPDATE_OK && status.status <= UPDATE_KORG_ERR)
1526 displayKOrgUpdateError(editDlg, ERR_MODIFY, status);
1530 outputAlarmWarnings(editDlg, &newEvent);
1546 const QString eventID(
id.eventId());
1550 if (
id.collectionId() != -1)
1551 kWarning() <<
"Event ID not found, or duplicated:" << eventID;
1553 kWarning() <<
"Event ID not found:" << eventID;
1561 kError() << eventID <<
": event ID not found";
1567 kError() << eventID <<
": read-only";
1570 switch (event->category())
1572 case CalEvent::ACTIVE:
1573 case CalEvent::TEMPLATE:
1576 kError() << eventID <<
": event not active or template";
1579 editAlarm(event, parent);
1587 void editTemplate(KAEvent* event,
QWidget* parent)
1607 if (editDlg->exec() == QDialog::Accepted)
1611 Akonadi::Collection calendar;
1613 AlarmResource* calendar;
1615 editDlg->
getEvent(newEvent, calendar);
1617 newEvent.setEventId(
id);
1619 newEvent.setCollectionId(event->collectionId());
1620 newEvent.setItemId(event->itemId());
1625 updateTemplate(newEvent, editDlg);
1633 void viewAlarm(
const KAEvent* event,
QWidget* parent)
1648 void updateEditedAlarm(
EditAlarmDlg* editDlg, KAEvent& event, Collection& calendar)
1650 void updateEditedAlarm(
EditAlarmDlg* editDlg, KAEvent& event, AlarmResource* calendar)
1656 Akonadi::Collection cal;
1663 UpdateResult status;
1672 status = modifyEvent(event, newEvent, editDlg);
1679 status = addEvent(newEvent, &calendar, editDlg);
1681 status = addEvent(newEvent, calendar, editDlg);
1686 if (status.status != UPDATE_OK && status.status <= UPDATE_KORG_ERR)
1687 displayKOrgUpdateError(editDlg, ERR_MODIFY, status);
1688 outputAlarmWarnings(editDlg, &newEvent);
1697 KAEvent::List templateList()
1699 KAEvent::List templates;
1702 for (
int i = 0, end = events.count(); i < end; ++i)
1704 KAEvent*
event = events[i];
1705 if (includeCmdAlarms || !(event->actionTypes() & KAEvent::ACT_COMMAND))
1706 templates.append(event);
1716 void outputAlarmWarnings(
QWidget* parent,
const KAEvent* event)
1718 if (event && event->actionTypes() == KAEvent::ACT_EMAIL
1725 if (
KAMessageBox::warningYesNo(parent, i18nc(
"@info",
"<para>Alarms are currently disabled.</para><para>Do you want to enable alarms now?</para>"),
1726 QString(), KGuiItem(i18nc(
"@action:button",
"Enable")), KGuiItem(i18nc(
"@action:button",
"Keep Disabled")),
1728 == KMessageBox::Yes)
1736 void refreshAlarms()
1739 if (!refreshAlarmsQueued)
1741 refreshAlarmsQueued =
true;
1752 void refreshAlarmsIfQueued()
1754 if (refreshAlarmsQueued)
1761 for (
int i = 0, end = events.count(); i < end; ++i)
1763 KAEvent*
event = events[i];
1764 if (!event->enabled() && (
event->actionTypes() & KAEvent::ACT_DISPLAY))
1776 refreshAlarmsQueued =
false;
1785 QString runKMail(
bool minimise)
1796 kError() <<
"Couldn't start KMail (" << errmsg <<
")";
1797 return i18nc(
"@info",
"Unable to start <application>KMail</application><nl/>(<message>%1</message>)", errmsg);
1811 if (i.isSupported(NET::WM2KDETemporaryRules))
1813 kDebug() <<
"using rules";
1816 "wmclasscomplete=false\n"
1817 "minimize=true\nminimizerule=3\n"
1819 msg.broadcastMessage(
"_KDE_NET_WM_TEMPORARY_RULES", message, -1,
false);
1825 kDebug() <<
"connecting to window add";
1830 KStartupInfoId
id = KStartupInfo::currentStartupIdEnv();
1833 int pid = proc->startDetached();
1836 KStartupInfo::sendFinish(
id);
1839 KStartupInfoData data;
1841 data.setName(QLatin1String(
"kmail"));
1842 data.setBin(QLatin1String(
"kmail"));
1843 KStartupInfo::sendChange(
id, data);
1857 static const int SUPPORTED_TYPES = NET::NormalMask | NET::DesktopMask | NET::DockMask
1858 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
1859 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask;
1860 KWindowInfo kwinfo = KWindowSystem::windowInfo(w, NET::WMWindowType | NET::WMName);
1861 if (kwinfo.windowType(SUPPORTED_TYPES) == NET::TopMenu
1862 || kwinfo.windowType(SUPPORTED_TYPES) == NET::Toolbar
1863 || kwinfo.windowType(SUPPORTED_TYPES) == NET::Desktop)
1874 hints->flags |= StateHint;
1875 hints->initial_state = IconicState;
1879 info.setWindowType(NET::Normal);
1906 KConfig config(KStandardDirs::locateLocal(
"appdata", ALARM_OPTS_FILE));
1907 KConfigGroup group(&config, DONT_SHOW_ERRORS_GROUP);
1929 return tags.
indexOf(tag) >= 0;
1944 KConfig config(KStandardDirs::locateLocal(
"appdata", ALARM_OPTS_FILE));
1945 KConfigGroup group(&config, DONT_SHOW_ERRORS_GROUP);
1952 group.deleteEntry(
id);
1954 group.writeEntry(
id, tags);
1963 void setDontShowErrors(
const EventId& eventId,
const QString& tag)
1965 void setDontShowErrors(
const QString& eventId,
const QString& tag)
1970 KConfig config(KStandardDirs::locateLocal(
"appdata", ALARM_OPTS_FILE));
1971 KConfigGroup group(&config, DONT_SHOW_ERRORS_GROUP);
1981 group.writeEntry(
id, tags);
1992 bool readConfigWindowSize(
const char* window,
QSize& result,
int* splitterWidth)
1994 KConfigGroup config(KGlobal::config(), window);
1995 QWidget* desktop = KApplication::desktop();
2010 void writeConfigWindowSize(
const char* window,
const QSize& size,
int splitterWidth)
2012 KConfigGroup config(KGlobal::config(), window);
2013 QWidget* desktop = KApplication::desktop();
2016 if (splitterWidth >= 0)
2026 FileType fileType(
const KMimeType::Ptr& mimetype)
2029 return TextFormatted;
2030 if (mimetype->is(
QLatin1String(
"application/x-executable")))
2031 return TextApplication;
2044 FileErr checkFileExists(
QString& filename, KUrl& url)
2047 FileErr err = FileErr_None;
2050 if (f.indexIn(file) >= 0)
2051 file = file.
mid(f.matchedLength() - 1);
2059 filename = url.prettyUrl();
2062 err = FileErr_Nonexistent;
2065 KFileItem fi(uds, url);
2066 if (fi.isDir()) err = FileErr_Directory;
2067 else if (!fi.isReadable()) err = FileErr_Unreadable;
2071 err = FileErr_Blank;
2077 filename = info.absoluteFilePath();
2078 url.setPath(filename);
2079 if (info.isDir()) err = FileErr_Directory;
2080 else if (!info.exists()) err = FileErr_Nonexistent;
2081 else if (!info.isReadable()) err = FileErr_Unreadable;
2091 bool showFileErrMessage(
const QString& filename, FileErr err, FileErr blankError,
QWidget* errmsgParent)
2093 if (err != FileErr_None)
2098 if (f.indexIn(file) >= 0)
2099 file = file.
mid(f.matchedLength() - 1);
2105 if (blankError == FileErr_BlankDisplay)
2106 errmsg = i18nc(
"@info",
"Please select a file to display");
2107 else if (blankError == FileErr_BlankPlay)
2108 errmsg = i18nc(
"@info",
"Please select a file to play");
2110 kFatal() <<
"Program error";
2113 case FileErr_Directory:
2114 KAMessageBox::sorry(errmsgParent, i18nc(
"@info",
"<filename>%1</filename> is a folder", file));
2116 case FileErr_Nonexistent: errmsg = i18nc(
"@info",
"<filename>%1</filename> not found", file);
break;
2117 case FileErr_Unreadable: errmsg = i18nc(
"@info",
"<filename>%1</filename> is not readable", file);
break;
2118 case FileErr_NotTextImage: errmsg = i18nc(
"@info",
"<filename>%1</filename> appears not to be a text or image file", file);
break;
2123 == KMessageBox::Cancel)
2135 return (localfile.indexIn(url) >= 0) ? url.
mid(localfile.matchedLength() - 1) : url;
2155 : !defaultDir.
isEmpty() ? defaultDir
2161 fileDlg->setOperationMode(mode & KFile::ExistingOnly ? KFileDialog::Opening : KFileDialog::Saving);
2162 fileDlg->setMode(KFile::File | mode);
2163 fileDlg->setCaption(caption);
2165 fileDlg->setSelection(initialFile);
2166 if (fileDlg->exec() != QDialog::Accepted)
2168 KUrl url = fileDlg->selectedUrl();
2171 defaultDir = url.isLocalFile() ? url.upUrl().toLocalFile() : url.directory();
2172 return (mode & KFile::LocalOnly) ? url.pathOrUrl() : url.prettyUrl();
2187 ? i18nc(
"@info",
"Calendar <resource>%1</resource> is in an old format (<application>KAlarm</application> version %2), "
2188 "and will be read-only unless you choose to update it to the current format.",
2189 calendarName, calendarVersion)
2190 : i18nc(
"@info",
"Some or all of the alarms in calendar <resource>%1</resource> are in an old <application>KAlarm</application> format, "
2191 "and will be read-only unless you choose to update them to the current format.",
2193 return i18nc(
"@info",
"<para>%1</para><para>"
2194 "<warning>Do not update the calendar if it is also used with an older version of <application>KAlarm</application> "
2195 "(e.g. on another computer). If you do so, the calendar may become unusable there.</warning></para>"
2196 "<para>Do you wish to update the calendar?</para>", msg);
2204 void setTestModeConditions()
2206 const QByteArray newTime = qgetenv(
"KALARM_TIME");
2211 setSimulatedSystemTime(dt);
2218 void setSimulatedSystemTime(
const KDateTime& dt)
2220 KDateTime::setSimulatedSystemTime(dt);
2221 kDebug() <<
"New time =" << qPrintable(KDateTime::currentLocalDateTime().
toString(
QLatin1String(
"%Y-%m-%d %H:%M %:Z")));
2232 void displayUpdateError(
QWidget* parent, KAlarm::UpdateError code,
const UpdateStatusData& status,
bool showKOrgError)
2235 if (status.status.status > KAlarm::UPDATE_KORG_ERR)
2239 case KAlarm::ERR_ADD:
2240 case KAlarm::ERR_MODIFY:
2241 errmsg = (status.warnErr > 1) ? i18nc(
"@info",
"Error saving alarms")
2242 : i18nc(
"@info",
"Error saving alarm");
2244 case KAlarm::ERR_DELETE:
2245 errmsg = (status.warnErr > 1) ? i18nc(
"@info",
"Error deleting alarms")
2246 : i18nc(
"@info",
"Error deleting alarm");
2248 case KAlarm::ERR_REACTIVATE:
2249 errmsg = (status.warnErr > 1) ? i18nc(
"@info",
"Error saving reactivated alarms")
2250 : i18nc(
"@info",
"Error saving reactivated alarm");
2252 case KAlarm::ERR_TEMPLATE:
2253 errmsg = (status.warnErr > 1) ? i18nc(
"@info",
"Error saving alarm templates")
2254 : i18nc(
"@info",
"Error saving alarm template");
2259 else if (showKOrgError)
2260 displayKOrgUpdateError(parent, code, status.status, status.warnKOrg);
2271 Event::Ptr kcalEvent(
new KCalCore::Event);
2272 event.updateKCalEvent(kcalEvent, KAEvent::UID_IGNORE);
2277 QString uid = uidKOrganizer(event.id());
2278 kcalEvent->setUid(uid);
2279 kcalEvent->clearAlarms();
2281 switch (event.actionTypes())
2283 case KAEvent::ACT_DISPLAY:
2284 case KAEvent::ACT_COMMAND:
2285 case KAEvent::ACT_DISPLAY_COMMAND:
2286 kcalEvent->setSummary(event.cleanText());
2289 case KAEvent::ACT_EMAIL:
2292 ? Identities::identityManager()->identityForUoid(event.emailFromId()).fullEmailAddr()
2296 kcalEvent->setSummary(atext.displayText());
2300 case KAEvent::ACT_AUDIO:
2301 kcalEvent->setSummary(event.audioFile());
2307 Person::Ptr person(
new Person(
QString(), userEmail));
2308 kcalEvent->setOrganizer(person);
2310 kcalEvent->setOrganizer(KCal::Person(
QString(), userEmail));
2312 kcalEvent->setDuration(Duration(Preferences::kOrgEventDuration() * 60, Duration::Seconds));
2317 QString iCal = format.toICalString(kcalEvent);
2324 if (status != KAlarm::UPDATE_OK)
2331 if (reply.
error().
type() == QDBusError::UnknownObject)
2333 status = KAlarm::UPDATE_KORG_ERRSTART;
2334 kError() <<
"addIncidence() D-Bus error: still starting";
2339 kError() <<
"addIncidence(" << uid <<
") D-Bus call failed:" << status.
message;
2342 else if (!reply.
value())
2344 status = KAlarm::UPDATE_KORG_FUNCERR;
2345 kDebug() <<
"addIncidence(" << uid <<
") D-Bus call returned false";
2348 kDebug() << uid <<
": success";
2357 const QString newID = uidKOrganizer(eventID);
2358 #if defined(USE_AKONADI) && KDE_IS_VERSION(4,12,4) // kdepimlibs/kdepim-runtime 4.12.4 are required
2359 new CollectionSearch(KORG_MIME_TYPE, newID,
true);
2364 if (status != KAlarm::UPDATE_OK)
2367 args << newID <<
true;
2371 if (reply.
error().
type() == QDBusError::UnknownObject)
2373 kError() <<
"deleteIncidence() D-Bus error: still starting";
2374 status = KAlarm::UPDATE_KORG_ERRSTART;
2379 kError() <<
"deleteIncidence(" << newID <<
") D-Bus call failed:" << status.
message;
2382 else if (!reply.
value())
2384 status = KAlarm::UPDATE_KORG_FUNCERR;
2385 kDebug() <<
"deleteIncidence(" << newID <<
") D-Bus call returned false";
2388 kDebug() << newID <<
": success";
2400 int result = KDBusServiceStarter::self()->findServiceFor(
QLatin1String(
"DBUS/Organizer"),
QString(), &error, &dbusService);
2403 status.
set(KAlarm::UPDATE_KORG_ERRINIT, error);
2404 kWarning() <<
"Unable to start DBUS/Organizer:" << status.
message;
2411 if (!iface.isValid())
2413 status.
set(KAlarm::UPDATE_KORG_ERR, iface.lastError().message());
2419 && iface.lastError().type() != QDBusError::UnknownMethod)
2421 status.
set(KAlarm::UPDATE_KORG_ERR, iface.lastError().message());
2422 kWarning() <<
"Loading KOrganizer failed:" << status.
message;
2428 if (!korgInterface || !korgInterface->
isValid())
2430 delete korgInterface;
2432 if (!korgInterface->
isValid())
2436 delete korgInterface;
2452 return result.
insert(i, KORGANIZER_UID);
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
static Akonadi::Collection getStandard(CalEvent::Type, bool useDefault=false)
Return the standard collection for a specified mime type.
void setAlarmsEnabled(bool)
bool deleteEvent(const QString &eventID, bool save=false)
static EventListModel * alarms()
void disabledChanged(const KAEvent *)
bool alarmsEnabled() const
static Private * instance()
static bool isAudioPlaying()
bool eventReadOnly(const QString &uniqueID) const
virtual QByteArray text(quint32 serialNumber) const =0
bool caseInsensitiveLessThan(const QString &s1, const QString &s2)
KAEvent * updateEvent(const KAEvent &)
Qt::HANDLE appRootWindow(int screen)
QDBusConnectionInterface * interface() const
Result of calendar update.
static AlarmCalendar * resources()
static void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Options(Notify|WindowModal))
bool addEvent(KAEvent *, QWidget *promptParent=0, bool useEventID=false, AlarmResource *=0, bool noPrompt=false, bool *cancelled=0)
static void saveEdit(const Event &oldEvent, const KAEvent &newEvent)
QDBusConnection sessionBus()
void removeEvent(const KAEvent *event)
QString & remove(int position, int n)
QDBusReply< bool > isServiceRegistered(const QString &serviceName) const
static MainWindow * firstWindow()
KAEvent * templateEvent(const QString &templateName)
static MessageWin * findEvent(const QString &eventId, MessageWin *exclude=0)
static bool startKMailMinimised()
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
virtual bool event(QEvent *e)
static KAEvent * getEvent(const QString &uniqueId)
the KAlarm application object
static bool convertTimeString(const QByteArray &timeString, KDateTime &dateTime, const KDateTime &defaultDt=KDateTime(), bool allowTZ=true)
MessageWin: A window to display an alarm or error message.
int count(const T &value) const
bool modifyEvent(const QString &oldEventId, KAEvent *newEvent)
QString & insert(int position, QChar ch)
static CollectionControlModel * instance()
void purgeEvents(const KAEvent::List &)
static KTimeZone timeZone(bool reload=false)
static Akonadi::Collection destination(CalEvent::Type, QWidget *promptParent=0, bool noPrompt=false, bool *cancelled=0)
Find the collection to be used to store an event of a given type.
void selectEvent(const QString &eventID)
virtual void setAction(KAEvent::SubAction, const AlarmText &=AlarmText())=0
displays an alarm message
bool setCurrent(const QString &path)
static EditAlarmDlg * create(bool Template, Type, QWidget *parent=0, GetResourceType=RES_PROMPT)
bool getEvent(KAEvent &, AlarmResource *&)
static QString i18n_NeedFromEmailAddress()
static MainWindow * create(bool restored=false)
static void detailedError(QWidget *parent, const QString &text, const QString &details, const QString &caption=QString(), Options options=Options(Notify|WindowModal))
KCal::Event * createKCalEvent(const KAEvent *e) const
static Akonadi::Collection::List enabledCollections(CalEvent::Type, bool writable)
Return the enabled collections which contain a specified mime type.
static EventListModel * templates()
bool updateEvent(KAEvent *event)
void accept(EditAlarmDlg *)
static void saveAdd(const KAEvent &, AlarmResource *, const QString &name=QString())
Unique event identifier for Akonadi.
QString mid(int position, int n) const
char * toString(const T &value)
static int warningYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous|WindowModal))
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Options(Notify|WindowModal))
QString & setNum(short n, int base)
#define KORG_DBUS_LOAD_PATH
static QString emailAddress()
int count(const T &value) const
static int warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Options(Notify|WindowModal))
QString fromLatin1(const char *str, int size)
Provides read and write access to calendar files and resources.
int indexOf(const QRegExp &rx, int from) const
static AlarmCalendar * displayCalendarOpen()
KAEvent::List events(CalEvent::Types s=CalEvent::EMPTY) const
QDate addDays(int ndays) const
QDBusError lastError() const
KAEvent * event(const QString &uniqueId)
static MainWindow * mainMainWindow()
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
const QDBusError & error()
QDBusMessage callWithArgumentList(QDBus::CallMode mode, const QString &method, const QList< QVariant > &args)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
static void information(QWidget *parent, const QString &text, const QString &caption=QString(), const QString &dontShowAgainName=QString(), Options options=Options(Notify|WindowModal))