23 #include "resources/alarmresource.h"
24 #include "resources/alarmresources.h"
29 #include "eventlistmodel.moc"
31 #include <kalarmcal/alarmtext.h>
34 #include <kiconloader.h>
37 #include <QApplication>
47 QPixmap* EventListModel::mTextIcon = 0;
48 QPixmap* EventListModel::mFileIcon = 0;
49 QPixmap* EventListModel::mCommandIcon = 0;
50 QPixmap* EventListModel::mEmailIcon = 0;
51 QPixmap* EventListModel::mAudioIcon = 0;
52 QSize EventListModel::mIconSize;
53 int EventListModel::mTimeHourPos = -2;
60 mAlarmInstance =
new EventListModel(CalEvent::ACTIVE | CalEvent::ARCHIVED);
61 Preferences::connect(SIGNAL(archivedColourChanged(QColor)), mAlarmInstance, SLOT(slotUpdateArchivedColour(QColor)));
62 Preferences::connect(SIGNAL(disabledColourChanged(QColor)), mAlarmInstance, SLOT(slotUpdateDisabledColour(QColor)));
63 Preferences::connect(SIGNAL(holidaysChanged(KHolidays::HolidayRegion)), mAlarmInstance, SLOT(slotUpdateHolidays()));
64 Preferences::connect(SIGNAL(workTimeChanged(QTime,QTime,QBitArray)), mAlarmInstance, SLOT(slotUpdateWorkingHours()));
66 return mAlarmInstance;
71 if (!mTemplateInstance)
73 return mTemplateInstance;
78 if (
this == mAlarmInstance)
80 else if (
this == mTemplateInstance)
81 mTemplateInstance = 0;
84 EventListModel::EventListModel(CalEvent::Types status,
QObject* parent)
93 mHaveEvents = !mEvents.isEmpty();
97 mTextIcon =
new QPixmap(SmallIcon(
"dialog-information"));
98 mFileIcon =
new QPixmap(SmallIcon(
"document-open"));
99 mCommandIcon =
new QPixmap(SmallIcon(
"system-run"));
100 mEmailIcon =
new QPixmap(SmallIcon(
"mail-message-unread"));
101 mAudioIcon =
new QPixmap(SmallIcon(
"audio-x-generic"));
102 mIconSize = mTextIcon->size().expandedTo(mFileIcon->size()).expandedTo(mCommandIcon->size()).expandedTo(mEmailIcon->size()).expandedTo(mAudioIcon->size());
105 AlarmResources* resources = AlarmResources::instance();
107 SLOT(slotResourceStatusChanged(AlarmResource*,AlarmResources::Change)));
108 connect(resources, SIGNAL(resourceLoaded(AlarmResource*,
bool)),
109 SLOT(slotResourceLoaded(AlarmResource*,
bool)));
114 if (parent.isValid())
116 return mEvents.count();
121 if (parent.isValid())
128 if (parent.isValid() || row >= mEvents.count())
129 return QModelIndex();
130 return createIndex(row, column, mEvents[row]);
135 int column = index.column();
136 if (role == Qt::WhatsThisRole)
137 return whatsThisText(column);
138 KAEvent*
event =
static_cast<KAEvent*
>(index.internalPointer());
141 bool resourceColour =
false;
147 case Qt::BackgroundRole:
148 resourceColour =
true;
150 case Qt::DisplayRole:
152 DateTime due =
event->expired() ?
event->startDateTime() :
event->nextTrigger(KAEvent::DISPLAY_TRIGGER);
157 DateTime due =
event->expired() ?
event->startDateTime() :
event->nextTrigger(KAEvent::DISPLAY_TRIGGER);
158 return due.isValid() ? due.effectiveKDateTime().toUtc().dateTime()
159 : QDateTime(QDate(9999,12,31), QTime(0,0,0));
168 case Qt::BackgroundRole:
169 resourceColour =
true;
171 case Qt::DisplayRole:
172 if (
event->expired())
177 if (
event->expired())
179 KDateTime now = KDateTime::currentUtcDateTime();
180 DateTime due =
event->nextTrigger(KAEvent::DISPLAY_TRIGGER);
181 if (due.isDateOnly())
182 return now.date().daysTo(due.date()) * 1440;
183 return (now.secsTo(due.effectiveKDateTime()) + 59) / 60;
190 case Qt::BackgroundRole:
191 resourceColour =
true;
193 case Qt::DisplayRole:
194 return repeatText(
event);
195 case Qt::TextAlignmentRole:
196 return Qt::AlignHCenter;
198 return repeatOrder(
event);
204 case Qt::BackgroundRole:
205 switch (
event->actionTypes())
207 case KAEvent::ACT_DISPLAY_COMMAND:
208 case KAEvent::ACT_DISPLAY:
209 return event->bgColour();
210 case KAEvent::ACT_COMMAND:
211 if (
event->commandError() != KAEvent::CMD_NO_ERROR)
218 case Qt::ForegroundRole:
219 if (
event->commandError() != KAEvent::CMD_NO_ERROR)
221 if (
event->actionTypes() == KAEvent::ACT_COMMAND)
223 QColor colour = Qt::red;
225 event->bgColour().getRgb(&r, &g, &b);
226 if (r > 128 && g <= 128 && b <= 128)
231 case Qt::DisplayRole:
232 if (
event->commandError() != KAEvent::CMD_NO_ERROR)
233 return QString::fromLatin1(
"!");
237 unsigned i = (
event->actionTypes() == KAEvent::ACT_DISPLAY)
238 ?
event->bgColour().rgb() : 0;
239 return QString(
"%1").arg(i, 6, 10, QLatin1Char(
'0'));
248 case Qt::DecorationRole:
251 v.setValue(*eventIcon(
event));
254 case Qt::TextAlignmentRole:
255 return Qt::AlignHCenter;
256 case Qt::SizeHintRole:
258 case Qt::AccessibleTextRole:
260 #warning Implement this
264 return static_cast<int>(
event->actionSubType());
266 return QString(
"%1").arg(
event->actionSubType(), 2, 10, QLatin1Char(
'0'));
272 case Qt::BackgroundRole:
273 resourceColour =
true;
275 case Qt::DisplayRole:
277 return AlarmText::summary(*
event, 1);
278 case Qt::ToolTipRole:
279 return AlarmText::summary(*
event, 10);
287 case Qt::BackgroundRole:
288 resourceColour =
true;
290 case Qt::DisplayRole:
291 return event->templateName();
293 return event->templateName().toUpper();
302 case Qt::ForegroundRole:
303 if (!
event->enabled())
305 if (
event->expired())
308 case Qt::ToolTipRole:
310 switch (
event->commandError())
312 case KAEvent::CMD_ERROR:
313 return i18nc(
"@info:tooltip",
"Command execution failed");
314 case KAEvent::CMD_ERROR_PRE:
315 return i18nc(
"@info:tooltip",
"Pre-alarm action execution failed");
316 case KAEvent::CMD_ERROR_POST:
317 return i18nc(
"@info:tooltip",
"Post-alarm action execution failed");
318 case KAEvent::CMD_ERROR_PRE_POST:
319 return i18nc(
"@info:tooltip",
"Pre- and post-alarm action execution failed");
321 case KAEvent::CMD_NO_ERROR:
326 return event->category();
328 return event->enabled();
335 AlarmResource* resource = AlarmResources::instance()->resourceForIncidence(
event->id());
336 if (resource && resource->colour().isValid())
337 return resource->colour();
344 if (ix.isValid() && role == Qt::EditRole)
355 if (orientation == Qt::Horizontal)
357 if (role == Qt::DisplayRole)
362 return i18nc(
"@title:column",
"Time");
364 return i18nc(
"@title:column",
"Time To");
366 return i18nc(
"@title:column",
"Repeat");
372 return i18nc(
"@title:column",
"Message, File or Command");
374 return i18nc(
"@title:column Template name",
"Name");
377 else if (role == Qt::WhatsThisRole)
378 return whatsThisText(section);
385 if (!index.isValid())
386 return Qt::ItemIsEnabled;
387 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
393 void EventListModel::slotUpdateTimeTo()
395 int n = mEvents.count();
403 void EventListModel::slotUpdateArchivedColour(
const QColor&)
407 for (
int row = 0, end = mEvents.count(); row < end; ++row)
409 if (mEvents[row]->category() == CalEvent::ARCHIVED)
417 else if (firstRow >= 0)
430 void EventListModel::slotUpdateDisabledColour(
const QColor&)
434 for (
int row = 0, end = mEvents.count(); row < end; ++row)
436 if (!mEvents[row]->enabled())
444 else if (firstRow >= 0)
459 void EventListModel::slotUpdateHolidays()
463 for (
int row = 0, end = mEvents.count(); row < end; ++row)
465 if (mEvents[row]->holidaysExcluded())
473 else if (firstRow >= 0)
492 void EventListModel::slotUpdateWorkingHours()
496 for (
int row = 0, end = mEvents.count(); row < end; ++row)
498 if (mEvents[row]->workTimeOnly())
506 else if (firstRow >= 0)
526 int row = findEvent(eventId);
530 emit dataChanged(ix, ix);
537 void EventListModel::slotResourceLoaded(AlarmResource* resource,
bool active)
540 slotResourceStatusChanged(resource, AlarmResources::Added);
549 mAlarmInstance->slotResourceStatusChanged(resource, change);
550 if (mTemplateInstance)
551 mTemplateInstance->slotResourceStatusChanged(resource, change);
557 void EventListModel::slotResourceStatusChanged(AlarmResource* resource, AlarmResources::Change change)
562 case AlarmResources::Added:
563 kDebug() << resource->resourceName() <<
"Added";
566 case AlarmResources::Deleted:
567 kDebug() << resource->resourceName() <<
"Deleted";
570 case AlarmResources::Invalidated:
571 kDebug() << resource->resourceName() <<
"Invalidated";
574 case AlarmResources::Location:
575 kDebug() << resource->resourceName() <<
"Location";
579 case AlarmResources::Enabled:
580 if (resource->isActive())
585 case AlarmResources::Colour:
587 kDebug() <<
"Colour";
589 for (
int row = 0, end = mEvents.count(); row < end; ++row)
591 if (mEvents[row]->resource() == resource)
599 else if (firstRow >= 0)
609 case AlarmResources::ReadOnly:
610 case AlarmResources::WrongType:
617 for (
int i = list.count(); --i >= 0; )
619 if (mEvents.indexOf(list[i]) >= 0)
624 int row = mEvents.count();
625 beginInsertRows(QModelIndex(), row, row + list.count() - 1);
629 updateHaveEvents(
true);
645 for (
int row = mEvents.count(); --row >= 0; )
647 AlarmResource* r = mEvents[row]->resource();
648 if (!r || r == resource)
656 else if (lastRow >= 0)
658 beginRemoveRows(QModelIndex(), row + 1, lastRow);
659 while (lastRow > row)
660 mEvents.remove(lastRow--);
667 beginRemoveRows(QModelIndex(), 0, lastRow);
669 mEvents.remove(lastRow--);
672 if (mHaveEvents && mEvents.isEmpty())
673 updateHaveEvents(
false);
682 if (!mEvents.isEmpty())
684 beginRemoveRows(QModelIndex(), 0, mEvents.count() - 1);
691 beginInsertRows(QModelIndex(), 0, list.count() - 1);
695 if (mHaveEvents == mEvents.isEmpty())
696 updateHaveEvents(!mHaveEvents);
704 for (
int row = 0, end = mEvents.count(); row < end; ++row)
706 if (mEvents[row]->
id() == eventId)
707 return createIndex(row, 0, mEvents[row]);
709 return QModelIndex();
717 int row = mEvents.indexOf(const_cast<KAEvent*>(event));
719 return QModelIndex();
720 return createIndex(row, 0, mEvents[row]);
728 if (!(event->category() & mStatus) || mEvents.contains(event))
730 int row = mEvents.count();
731 beginInsertRows(QModelIndex(), row, row);
735 updateHaveEvents(
true);
744 for (
int i = 0, count = events.count(); i < count; ++i)
745 if (events[i]->category() & mStatus)
747 int row = mEvents.count();
748 beginInsertRows(QModelIndex(), row, row + evs.count() - 1);
752 updateHaveEvents(
true);
762 beginRemoveRows(QModelIndex(), row, row);
765 if (mHaveEvents && mEvents.isEmpty())
766 updateHaveEvents(
false);
782 int row = findEvent(oldId);
785 mEvents[row] = newEvent;
793 int EventListModel::findEvent(
const QString& eventId)
const
795 for (
int row = 0, end = mEvents.count(); row < end; ++row)
797 if (mEvents[row]->
id() == eventId)
808 if (row < 0 || row >= mEvents.count())
818 if (!index.isValid())
820 return static_cast<KAEvent*
>(index.internalPointer());
826 QString EventListModel::repeatText(
const KAEvent* event)
const
828 QString repeatText =
event->recurrenceText(
true);
829 if (repeatText.isEmpty())
830 repeatText = event->repetitionText(
true);
837 QString EventListModel::repeatOrder(
const KAEvent* event)
const
840 int repeatInterval = 0;
841 if (event->repeatAtLogin())
845 repeatInterval =
event->recurInterval();
846 switch (event->recurType())
848 case KARecurrence::MINUTELY:
851 case KARecurrence::DAILY:
854 case KARecurrence::WEEKLY:
857 case KARecurrence::MONTHLY_DAY:
858 case KARecurrence::MONTHLY_POS:
861 case KARecurrence::ANNUAL_DATE:
862 case KARecurrence::ANNUAL_POS:
865 case KARecurrence::NO_RECUR:
870 return QString(
"%1%2").arg(static_cast<char>(
'0' + repeatOrder)).arg(repeatInterval, 8, 10, QLatin1Char(
'0'));
876 QPixmap* EventListModel::eventIcon(
const KAEvent* event)
const
878 switch (event->actionTypes())
880 case KAEvent::ACT_EMAIL:
882 case KAEvent::ACT_AUDIO:
884 case KAEvent::ACT_COMMAND:
886 case KAEvent::ACT_DISPLAY:
887 if (event->actionSubType() == KAEvent::FILE)
890 case KAEvent::ACT_DISPLAY_COMMAND:
899 QString EventListModel::whatsThisText(
int column)
const
904 return i18nc(
"@info:whatsthis",
"Next scheduled date and time of the alarm");
906 return i18nc(
"@info:whatsthis",
"How long until the next scheduled trigger of the alarm");
908 return i18nc(
"@info:whatsthis",
"How often the alarm recurs");
910 return i18nc(
"@info:whatsthis",
"Background color of alarm message");
912 return i18nc(
"@info:whatsthis",
"Alarm type (message, file, command or email)");
914 return i18nc(
"@info:whatsthis",
"Alarm message text, URL of text file to display, command to execute, or email subject line");
916 return i18nc(
"@info:whatsthis",
"Name of the alarm template");
931 setSourceModel(baseModel);
933 setDynamicSortFilter(
true);
954 return mapFromSource(static_cast<EventListModel*>(sourceModel())->
eventIndex(eventId));
962 return mapFromSource(static_cast<EventListModel*>(sourceModel())->
eventIndex(event));
965 void EventListFilterModel::slotDataChanged(
const QModelIndex& topLeft,
const QModelIndex& bottomRight)
967 emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight));
static void resourceStatusChanged(AlarmResource *, AlarmResources::Change)
static EventListModel * alarms()
static AlarmCalendar * resources()
void updateCommandError(const QString &eventId)
QModelIndex eventIndex(const KAEvent *) const
void addEvents(const KAEvent::List &)
void removeEvent(const KAEvent *event)
virtual QVariant headerData(int section, Qt::Orientation, int role=Qt::DisplayRole) const
static QColor disabledColour()
Get Disabled alarm color.
static QString timeToAlarmText(const KAlarmCal::DateTime &dateTime)
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
static void connect(QObject *receiver, const char *member)
virtual QVariant data(const QModelIndex &, int role=Qt::DisplayRole) const
EventListFilterModel(EventListModel *baseModel, QObject *parent=0)
static void connect(const char *signal, const QObject *receiver, const char *member)
static EventListModel * templates()
static QColor archivedColour()
Get Archived alarm color.
bool updateEvent(KAEvent *event)
static QString alarmTimeText(const KAlarmCal::DateTime &dateTime)
virtual QModelIndex index(int row, int column=0, const QModelIndex &parent=QModelIndex()) const
KAEvent * event(int row) const
virtual bool setData(const QModelIndex &, const QVariant &value, int role=Qt::EditRole)
virtual Qt::ItemFlags flags(const QModelIndex &) const
KAEvent::List events(CalEvent::Types s=CalEvent::EMPTY) const
QModelIndex eventIndex(const KAEvent *) const
void removeResource(AlarmResource *)
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
KAEvent * event(int row) const