• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kalarm

  • sources
  • kde-4.14
  • kdepim
  • kalarm
eventlistmodel.cpp
Go to the documentation of this file.
1 /*
2  * eventlistmodel.cpp - model class for lists of alarms or templates
3  * Program: kalarm
4  * Copyright © 2007-2012 by David Jarvie <djarvie@kde.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 #include "kalarm.h"
22 
23 #include "resources/alarmresource.h"
24 #include "resources/alarmresources.h"
25 #include "alarmcalendar.h"
26 #include "alarmtime.h"
27 #include "preferences.h"
28 #include "synchtimer.h"
29 #include "eventlistmodel.moc"
30 
31 #include <kalarmcal/alarmtext.h>
32 
33 #include <klocale.h>
34 #include <kiconloader.h>
35 #include <kdebug.h>
36 
37 #include <QPixmap>
38 
39 /*=============================================================================
40 = Class: EventListModel
41 = Contains all active/archived alarms, or all alarm templates, unsorted.
42 =============================================================================*/
43 
44 EventListModel* EventListModel::mAlarmInstance = 0;
45 EventListModel* EventListModel::mTemplateInstance = 0;
46 QPixmap* EventListModel::mTextIcon = 0;
47 QPixmap* EventListModel::mFileIcon = 0;
48 QPixmap* EventListModel::mCommandIcon = 0;
49 QPixmap* EventListModel::mEmailIcon = 0;
50 QPixmap* EventListModel::mAudioIcon = 0;
51 QSize EventListModel::mIconSize;
52 int EventListModel::mTimeHourPos = -2;
53 
54 
55 EventListModel* EventListModel::alarms()
56 {
57  if (!mAlarmInstance)
58  {
59  mAlarmInstance = new EventListModel(CalEvent::ACTIVE | CalEvent::ARCHIVED);
60  Preferences::connect(SIGNAL(archivedColourChanged(QColor)), mAlarmInstance, SLOT(slotUpdateArchivedColour(QColor)));
61  Preferences::connect(SIGNAL(disabledColourChanged(QColor)), mAlarmInstance, SLOT(slotUpdateDisabledColour(QColor)));
62  Preferences::connect(SIGNAL(holidaysChanged(KHolidays::HolidayRegion)), mAlarmInstance, SLOT(slotUpdateHolidays()));
63  Preferences::connect(SIGNAL(workTimeChanged(QTime,QTime,QBitArray)), mAlarmInstance, SLOT(slotUpdateWorkingHours()));
64  }
65  return mAlarmInstance;
66 }
67 
68 EventListModel* EventListModel::templates()
69 {
70  if (!mTemplateInstance)
71  mTemplateInstance = new EventListModel(CalEvent::TEMPLATE);
72  return mTemplateInstance;
73 }
74 
75 EventListModel::~EventListModel()
76 {
77  if (this == mAlarmInstance)
78  mAlarmInstance = 0;
79  else if (this == mTemplateInstance)
80  mTemplateInstance = 0;
81 }
82 
83 EventListModel::EventListModel(CalEvent::Types status, QObject* parent)
84  : QAbstractTableModel(parent),
85  mStatus(status)
86 {
87  // Load the current list of alarms.
88  // The list will be updated whenever a signal is received notifying changes.
89  // We need to store the list so that when deletions occur, the deleted alarm's
90  // position in the list can be determined.
91  mEvents = AlarmCalendar::resources()->events(mStatus);
92  mHaveEvents = !mEvents.isEmpty();
93 //for(int x=0; x<mEvents.count(); ++x)kDebug(0)<<"Resource"<<(void*)mEvents[x]->resource()<<"Event"<<(void*)mEvents[x];
94  if (!mTextIcon)
95  {
96  mTextIcon = new QPixmap(SmallIcon("dialog-information"));
97  mFileIcon = new QPixmap(SmallIcon("document-open"));
98  mCommandIcon = new QPixmap(SmallIcon("system-run"));
99  mEmailIcon = new QPixmap(SmallIcon("mail-message-unread"));
100  mAudioIcon = new QPixmap(SmallIcon("audio-x-generic"));
101  mIconSize = mTextIcon->size().expandedTo(mFileIcon->size()).expandedTo(mCommandIcon->size()).expandedTo(mEmailIcon->size()).expandedTo(mAudioIcon->size());
102  }
103  MinuteTimer::connect(this, SLOT(slotUpdateTimeTo()));
104  AlarmResources* resources = AlarmResources::instance();
105  connect(resources, SIGNAL(resourceStatusChanged(AlarmResource*,AlarmResources::Change)),
106  SLOT(slotResourceStatusChanged(AlarmResource*,AlarmResources::Change)));
107  connect(resources, SIGNAL(resourceLoaded(AlarmResource*,bool)),
108  SLOT(slotResourceLoaded(AlarmResource*,bool)));
109 }
110 
111 int EventListModel::rowCount(const QModelIndex& parent) const
112 {
113  if (parent.isValid())
114  return 0;
115  return mEvents.count();
116 }
117 
118 int EventListModel::columnCount(const QModelIndex& parent) const
119 {
120  if (parent.isValid())
121  return 0;
122  return ColumnCount;
123 }
124 
125 QModelIndex EventListModel::index(int row, int column, const QModelIndex& parent) const
126 {
127  if (parent.isValid() || row >= mEvents.count())
128  return QModelIndex();
129  return createIndex(row, column, mEvents[row]);
130 }
131 
132 QVariant EventListModel::data(const QModelIndex& index, int role) const
133 {
134  int column = index.column();
135  if (role == Qt::WhatsThisRole)
136  return whatsThisText(column);
137  KAEvent* event = static_cast<KAEvent*>(index.internalPointer());
138  if (!event)
139  return QVariant();
140  bool resourceColour = false;
141  switch (column)
142  {
143  case TimeColumn:
144  switch (role)
145  {
146  case Qt::BackgroundRole:
147  resourceColour = true;
148  break;
149  case Qt::DisplayRole:
150  {
151  DateTime due = event->expired() ? event->startDateTime() : event->nextTrigger(KAEvent::DISPLAY_TRIGGER);
152  return AlarmTime::alarmTimeText(due);
153  }
154  case SortRole:
155  {
156  DateTime due = event->expired() ? event->startDateTime() : event->nextTrigger(KAEvent::DISPLAY_TRIGGER);
157  return due.isValid() ? due.effectiveKDateTime().toUtc().dateTime()
158  : QDateTime(QDate(9999,12,31), QTime(0,0,0));
159  }
160  default:
161  break;
162  }
163  break;
164  case TimeToColumn:
165  switch (role)
166  {
167  case Qt::BackgroundRole:
168  resourceColour = true;
169  break;
170  case Qt::DisplayRole:
171  if (event->expired())
172  return QString();
173  return AlarmTime::timeToAlarmText(event->nextTrigger(KAEvent::DISPLAY_TRIGGER));
174  case SortRole:
175  {
176  if (event->expired())
177  return -1;
178  KDateTime now = KDateTime::currentUtcDateTime();
179  DateTime due = event->nextTrigger(KAEvent::DISPLAY_TRIGGER);
180  if (due.isDateOnly())
181  return now.date().daysTo(due.date()) * 1440;
182  return (now.secsTo(due.effectiveKDateTime()) + 59) / 60;
183  }
184  }
185  break;
186  case RepeatColumn:
187  switch (role)
188  {
189  case Qt::BackgroundRole:
190  resourceColour = true;
191  break;
192  case Qt::DisplayRole:
193  return repeatText(event);
194  case Qt::TextAlignmentRole:
195  return Qt::AlignHCenter;
196  case SortRole:
197  return repeatOrder(event);
198  }
199  break;
200  case ColourColumn:
201  switch (role)
202  {
203  case Qt::BackgroundRole:
204  switch (event->actionTypes())
205  {
206  case KAEvent::ACT_DISPLAY_COMMAND:
207  case KAEvent::ACT_DISPLAY:
208  return event->bgColour();
209  case KAEvent::ACT_COMMAND:
210  if (event->commandError() != KAEvent::CMD_NO_ERROR)
211  return Qt::red;
212  break;
213  default:
214  break;
215  }
216  break;
217  case Qt::ForegroundRole:
218  if (event->commandError() != KAEvent::CMD_NO_ERROR)
219  {
220  if (event->actionTypes() == KAEvent::ACT_COMMAND)
221  return Qt::white;
222  QColor colour = Qt::red;
223  int r, g, b;
224  event->bgColour().getRgb(&r, &g, &b);
225  if (r > 128 && g <= 128 && b <= 128)
226  colour = Qt::white;
227  return colour;
228  }
229  break;
230  case Qt::DisplayRole:
231  if (event->commandError() != KAEvent::CMD_NO_ERROR)
232  return QString::fromLatin1("!");
233  break;
234  case SortRole:
235  {
236  unsigned i = (event->actionTypes() == KAEvent::ACT_DISPLAY)
237  ? event->bgColour().rgb() : 0;
238  return QString("%1").arg(i, 6, 10, QLatin1Char('0'));
239  }
240  default:
241  break;
242  }
243  break;
244  case TypeColumn:
245  switch (role)
246  {
247  case Qt::DecorationRole:
248  {
249  QVariant v;
250  v.setValue(*eventIcon(event));
251  return v;
252  }
253  case Qt::TextAlignmentRole:
254  return Qt::AlignHCenter;
255  case Qt::SizeHintRole:
256  return mIconSize;
257  case Qt::AccessibleTextRole:
258 #ifdef __GNUC__
259 #warning Implement this
260 #endif
261  return QString();
262  case ValueRole:
263  return static_cast<int>(event->actionSubType());
264  case SortRole:
265  return QString("%1").arg(event->actionSubType(), 2, 10, QLatin1Char('0'));
266  }
267  break;
268  case TextColumn:
269  switch (role)
270  {
271  case Qt::BackgroundRole:
272  resourceColour = true;
273  break;
274  case Qt::DisplayRole:
275  case SortRole:
276  return AlarmText::summary(*event, 1);
277  case Qt::ToolTipRole:
278  return AlarmText::summary(*event, 10);
279  default:
280  break;
281  }
282  break;
283  case TemplateNameColumn:
284  switch (role)
285  {
286  case Qt::BackgroundRole:
287  resourceColour = true;
288  break;
289  case Qt::DisplayRole:
290  return event->templateName();
291  case SortRole:
292  return event->templateName().toUpper();
293  }
294  break;
295  default:
296  break;
297  }
298 
299  switch (role)
300  {
301  case Qt::ForegroundRole:
302  if (!event->enabled())
303  return Preferences::disabledColour();
304  if (event->expired())
305  return Preferences::archivedColour();
306  break; // use the default for normal active alarms
307  case Qt::ToolTipRole:
308  // Show the last command execution error message
309  switch (event->commandError())
310  {
311  case KAEvent::CMD_ERROR:
312  return i18nc("@info:tooltip", "Command execution failed");
313  case KAEvent::CMD_ERROR_PRE:
314  return i18nc("@info:tooltip", "Pre-alarm action execution failed");
315  case KAEvent::CMD_ERROR_POST:
316  return i18nc("@info:tooltip", "Post-alarm action execution failed");
317  case KAEvent::CMD_ERROR_PRE_POST:
318  return i18nc("@info:tooltip", "Pre- and post-alarm action execution failed");
319  default:
320  case KAEvent::CMD_NO_ERROR:
321  break;
322  }
323  break;
324  case StatusRole:
325  return event->category();
326  case EnabledRole:
327  return event->enabled();
328  default:
329  break;
330  }
331 
332  if (resourceColour)
333  {
334  AlarmResource* resource = AlarmResources::instance()->resourceForIncidence(event->id());
335  if (resource && resource->colour().isValid())
336  return resource->colour();
337  }
338  return QVariant();
339 }
340 
341 bool EventListModel::setData(const QModelIndex& ix, const QVariant&, int role)
342 {
343  if (ix.isValid() && role == Qt::EditRole)
344  {
345  int row = ix.row();
346  emit dataChanged(index(row, 0), index(row, ColumnCount - 1));
347  return true;
348  }
349  return false;
350 }
351 
352 QVariant EventListModel::headerData(int section, Qt::Orientation orientation, int role) const
353 {
354  if (orientation == Qt::Horizontal)
355  {
356  if (role == Qt::DisplayRole)
357  {
358  switch (section)
359  {
360  case TimeColumn:
361  return i18nc("@title:column", "Time");
362  case TimeToColumn:
363  return i18nc("@title:column", "Time To");
364  case RepeatColumn:
365  return i18nc("@title:column", "Repeat");
366  case ColourColumn:
367  return QString();
368  case TypeColumn:
369  return QString();
370  case TextColumn:
371  return i18nc("@title:column", "Message, File or Command");
372  case TemplateNameColumn:
373  return i18nc("@title:column Template name", "Name");
374  }
375  }
376  else if (role == Qt::WhatsThisRole)
377  return whatsThisText(section);
378  }
379  return QVariant();
380 }
381 
382 Qt::ItemFlags EventListModel::flags(const QModelIndex& index) const
383 {
384  if (!index.isValid())
385  return Qt::ItemIsEnabled;
386  return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
387 }
388 
389 /******************************************************************************
390 * Signal every minute that the time-to-alarm values have changed.
391 */
392 void EventListModel::slotUpdateTimeTo()
393 {
394  int n = mEvents.count();
395  if (n > 0)
396  emit dataChanged(index(0, TimeToColumn), index(n - 1, TimeToColumn));
397 }
398 
399 /******************************************************************************
400 * Called when the colour used to display archived alarms has changed.
401 */
402 void EventListModel::slotUpdateArchivedColour(const QColor&)
403 {
404  kDebug();
405  int firstRow = -1;
406  for (int row = 0, end = mEvents.count(); row < end; ++row)
407  {
408  if (mEvents[row]->category() == CalEvent::ARCHIVED)
409  {
410  // For efficiency, emit a single signal for each group
411  // of consecutive archived alarms, rather than a separate
412  // signal for each alarm.
413  if (firstRow < 0)
414  firstRow = row;
415  }
416  else if (firstRow >= 0)
417  {
418  emit dataChanged(index(firstRow, 0), index(row - 1, ColumnCount - 1));
419  firstRow = -1;
420  }
421  }
422  if (firstRow >= 0)
423  emit dataChanged(index(firstRow, 0), index(mEvents.count() - 1, ColumnCount - 1));
424 }
425 
426 /******************************************************************************
427 * Called when the colour used to display disabled alarms has changed.
428 */
429 void EventListModel::slotUpdateDisabledColour(const QColor&)
430 {
431  kDebug();
432  int firstRow = -1;
433  for (int row = 0, end = mEvents.count(); row < end; ++row)
434  {
435  if (!mEvents[row]->enabled())
436  {
437  // For efficiency, emit a single signal for each group
438  // of consecutive disabled alarms, rather than a separate
439  // signal for each alarm.
440  if (firstRow < 0)
441  firstRow = row;
442  }
443  else if (firstRow >= 0)
444  {
445  emit dataChanged(index(firstRow, 0), index(row - 1, ColumnCount - 1));
446  firstRow = -1;
447  }
448  }
449  if (firstRow >= 0)
450  emit dataChanged(index(firstRow, 0), index(mEvents.count() - 1, ColumnCount - 1));
451 }
452 
453 /******************************************************************************
454 * Called when the definition of holidays has changed.
455 * Update the next trigger time for all alarms which are set to recur only on
456 * non-holidays.
457 */
458 void EventListModel::slotUpdateHolidays()
459 {
460  kDebug();
461  int firstRow = -1;
462  for (int row = 0, end = mEvents.count(); row < end; ++row)
463  {
464  if (mEvents[row]->holidaysExcluded())
465  {
466  // For efficiency, emit a single signal for each group
467  // of consecutive alarms to update, rather than a separate
468  // signal for each alarm.
469  if (firstRow < 0)
470  firstRow = row;
471  }
472  else if (firstRow >= 0)
473  {
474  emit dataChanged(index(firstRow, TimeColumn), index(row - 1, TimeColumn));
475  emit dataChanged(index(firstRow, TimeToColumn), index(row - 1, TimeToColumn));
476  firstRow = -1;
477  }
478  }
479  if (firstRow >= 0)
480  {
481  emit dataChanged(index(firstRow, TimeColumn), index(mEvents.count() - 1, TimeColumn));
482  emit dataChanged(index(firstRow, TimeToColumn), index(mEvents.count() - 1, TimeToColumn));
483  }
484 }
485 
486 /******************************************************************************
487 * Called when the definition of working hours has changed.
488 * Update the next trigger time for all alarms which are set to recur only
489 * during working hours.
490 */
491 void EventListModel::slotUpdateWorkingHours()
492 {
493  kDebug();
494  int firstRow = -1;
495  for (int row = 0, end = mEvents.count(); row < end; ++row)
496  {
497  if (mEvents[row]->workTimeOnly())
498  {
499  // For efficiency, emit a single signal for each group
500  // of consecutive alarms to update, rather than a separate
501  // signal for each alarm.
502  if (firstRow < 0)
503  firstRow = row;
504  }
505  else if (firstRow >= 0)
506  {
507  emit dataChanged(index(firstRow, TimeColumn), index(row - 1, TimeColumn));
508  emit dataChanged(index(firstRow, TimeToColumn), index(row - 1, TimeToColumn));
509  firstRow = -1;
510  }
511  }
512  if (firstRow >= 0)
513  {
514  emit dataChanged(index(firstRow, TimeColumn), index(mEvents.count() - 1, TimeColumn));
515  emit dataChanged(index(firstRow, TimeToColumn), index(mEvents.count() - 1, TimeToColumn));
516  }
517 }
518 
519 /******************************************************************************
520 * Called when the command error status of an alarm has changed.
521 * Update the visual command error indication.
522 */
523 void EventListModel::updateCommandError(const QString& eventId)
524 {
525  int row = findEvent(eventId);
526  if (row >= 0)
527  {
528  QModelIndex ix = index(row, ColourColumn);
529  emit dataChanged(ix, ix);
530  }
531 }
532 
533 /******************************************************************************
534 * Called when loading of a resource is complete.
535 */
536 void EventListModel::slotResourceLoaded(AlarmResource* resource, bool active)
537 {
538  if (active)
539  slotResourceStatusChanged(resource, AlarmResources::Added);
540 }
541 
542 /******************************************************************************
543 * Static method called when a resource status has changed.
544 */
545 void EventListModel::resourceStatusChanged(AlarmResource* resource, AlarmResources::Change change)
546 {
547  if (mAlarmInstance)
548  mAlarmInstance->slotResourceStatusChanged(resource, change);
549  if (mTemplateInstance)
550  mTemplateInstance->slotResourceStatusChanged(resource, change);
551 }
552 
553 /******************************************************************************
554 * Called when a resource status has changed.
555 */
556 void EventListModel::slotResourceStatusChanged(AlarmResource* resource, AlarmResources::Change change)
557 {
558  bool added = false;
559  switch (change)
560  {
561  case AlarmResources::Added:
562  kDebug() << resource->resourceName() << "Added";
563  added = true;
564  break;
565  case AlarmResources::Deleted:
566  kDebug() << resource->resourceName() << "Deleted";
567  removeResource(resource);
568  return;
569  case AlarmResources::Invalidated:
570  kDebug() << resource->resourceName() << "Invalidated";
571  removeResource(resource);
572  return;
573  case AlarmResources::Location:
574  kDebug() << resource->resourceName() << "Location";
575  removeResource(resource);
576  added = true;
577  break;
578  case AlarmResources::Enabled:
579  if (resource->isActive())
580  added = true;
581  else
582  removeResource(resource);
583  break;
584  case AlarmResources::Colour:
585  {
586  kDebug() << "Colour";
587  int firstRow = -1;
588  for (int row = 0, end = mEvents.count(); row < end; ++row)
589  {
590  if (mEvents[row]->resource() == resource)
591  {
592  // For efficiency, emit a single signal for each group
593  // of consecutive alarms for the resource, rather than a separate
594  // signal for each alarm.
595  if (firstRow < 0)
596  firstRow = row;
597  }
598  else if (firstRow >= 0)
599  {
600  emit dataChanged(index(firstRow, 0), index(row - 1, ColumnCount - 1));
601  firstRow = -1;
602  }
603  }
604  if (firstRow >= 0)
605  emit dataChanged(index(firstRow, 0), index(mEvents.count() - 1, ColumnCount - 1));
606  return;
607  }
608  case AlarmResources::ReadOnly:
609  case AlarmResources::WrongType:
610  return;
611  }
612 
613  if (added)
614  {
615  KAEvent::List list = AlarmCalendar::resources()->events(resource, mStatus);
616  for (int i = list.count(); --i >= 0; )
617  {
618  if (mEvents.indexOf(list[i]) >= 0)
619  list.remove(i); // avoid creating duplicate entries
620  }
621  if (!list.isEmpty())
622  {
623  int row = mEvents.count();
624  beginInsertRows(QModelIndex(), row, row + list.count() - 1);
625  mEvents += list;
626  endInsertRows();
627  if (!mHaveEvents)
628  updateHaveEvents(true);
629  }
630  }
631 }
632 
633 /******************************************************************************
634 * Remove a resource's events from the list.
635 * This has to be called before the resource is actually deleted or reloaded. If
636 * not, timer based updates can occur between the resource being deleted and
637 * slotResourceStatusChanged(Deleted) being triggered, leading to crashes when
638 * data from the resource's events is fetched.
639 */
640 void EventListModel::removeResource(AlarmResource* resource)
641 {
642  kDebug();
643  int lastRow = -1;
644  for (int row = mEvents.count(); --row >= 0; )
645  {
646  AlarmResource* r = mEvents[row]->resource();
647  if (!r || r == resource)
648  {
649  // For efficiency, delete each group of consecutive
650  // alarms for the resource, rather than deleting each
651  // alarm separately.
652  if (lastRow < 0)
653  lastRow = row;
654  }
655  else if (lastRow >= 0)
656  {
657  beginRemoveRows(QModelIndex(), row + 1, lastRow);
658  while (lastRow > row)
659  mEvents.remove(lastRow--);
660  endRemoveRows();
661  lastRow = -1;
662  }
663  }
664  if (lastRow >= 0)
665  {
666  beginRemoveRows(QModelIndex(), 0, lastRow);
667  while (lastRow >= 0)
668  mEvents.remove(lastRow--);
669  endRemoveRows();
670  }
671  if (mHaveEvents && mEvents.isEmpty())
672  updateHaveEvents(false);
673 }
674 
675 /******************************************************************************
676 * Reload the event list.
677 */
678 void EventListModel::reload()
679 {
680  // This would be better done by a reset(), but the signals are private to QAbstractItemModel
681  if (!mEvents.isEmpty())
682  {
683  beginRemoveRows(QModelIndex(), 0, mEvents.count() - 1);
684  mEvents.clear();
685  endRemoveRows();
686  }
687  KAEvent::List list = AlarmCalendar::resources()->events(mStatus);
688  if (!list.isEmpty())
689  {
690  beginInsertRows(QModelIndex(), 0, list.count() - 1);
691  mEvents = list;
692  endInsertRows();
693  }
694  if (mHaveEvents == mEvents.isEmpty())
695  updateHaveEvents(!mHaveEvents);
696 }
697 
698 /******************************************************************************
699 * Return the index to a specified event.
700 */
701 QModelIndex EventListModel::eventIndex(const QString& eventId) const
702 {
703  for (int row = 0, end = mEvents.count(); row < end; ++row)
704  {
705  if (mEvents[row]->id() == eventId)
706  return createIndex(row, 0, mEvents[row]);
707  }
708  return QModelIndex();
709 }
710 
711 /******************************************************************************
712 * Return the index to a specified event.
713 */
714 QModelIndex EventListModel::eventIndex(const KAEvent* event) const
715 {
716  int row = mEvents.indexOf(const_cast<KAEvent*>(event));
717  if (row < 0)
718  return QModelIndex();
719  return createIndex(row, 0, mEvents[row]);
720 }
721 
722 /******************************************************************************
723 * Add an event to the list.
724 */
725 void EventListModel::addEvent(KAEvent* event)
726 {
727  if (!(event->category() & mStatus) || mEvents.contains(event))
728  return;
729  int row = mEvents.count();
730  beginInsertRows(QModelIndex(), row, row);
731  mEvents += event;
732  endInsertRows();
733  if (!mHaveEvents)
734  updateHaveEvents(true);
735 }
736 
737 /******************************************************************************
738 * Add an event to the list.
739 */
740 void EventListModel::addEvents(const KAEvent::List& events)
741 {
742  KAEvent::List evs;
743  for (int i = 0, count = events.count(); i < count; ++i)
744  if (events[i]->category() & mStatus)
745  evs += events[i];
746  int row = mEvents.count();
747  beginInsertRows(QModelIndex(), row, row + evs.count() - 1);
748  mEvents += evs;
749  endInsertRows();
750  if (!mHaveEvents)
751  updateHaveEvents(true);
752 }
753 
754 /******************************************************************************
755 * Remove an event from the list.
756 */
757 void EventListModel::removeEvent(int row)
758 {
759  if (row < 0)
760  return;
761  beginRemoveRows(QModelIndex(), row, row);
762  mEvents.remove(row);
763  endRemoveRows();
764  if (mHaveEvents && mEvents.isEmpty())
765  updateHaveEvents(false);
766 }
767 
768 /******************************************************************************
769 * Notify that an event in the list has been updated.
770 */
771 bool EventListModel::updateEvent(int row)
772 {
773  if (row < 0)
774  return false;
775  emit dataChanged(index(row, 0), index(row, ColumnCount - 1));
776  return true;
777 }
778 
779 bool EventListModel::updateEvent(const QString& oldId, KAEvent* newEvent)
780 {
781  int row = findEvent(oldId);
782  if (row < 0)
783  return false;
784  mEvents[row] = newEvent;
785  emit dataChanged(index(row, 0), index(row, ColumnCount - 1));
786  return true;
787 }
788 
789 /******************************************************************************
790 * Find the row of an event in the list, given its unique ID.
791 */
792 int EventListModel::findEvent(const QString& eventId) const
793 {
794  for (int row = 0, end = mEvents.count(); row < end; ++row)
795  {
796  if (mEvents[row]->id() == eventId)
797  return row;
798  }
799  return -1;
800 }
801 
802 /******************************************************************************
803 * Return the event for a given row.
804 */
805 KAEvent* EventListModel::event(int row) const
806 {
807  if (row < 0 || row >= mEvents.count())
808  return 0;
809  return mEvents[row];
810 }
811 
812 /******************************************************************************
813 * Return the event referred to by an index.
814 */
815 KAEvent* EventListModel::event(const QModelIndex& index)
816 {
817  if (!index.isValid())
818  return 0;
819  return static_cast<KAEvent*>(index.internalPointer());
820 }
821 
822 /******************************************************************************
823 * Return the repetition text.
824 */
825 QString EventListModel::repeatText(const KAEvent* event) const
826 {
827  QString repeatText = event->recurrenceText(true);
828  if (repeatText.isEmpty())
829  repeatText = event->repetitionText(true);
830  return repeatText;
831 }
832 
833 /******************************************************************************
834 * Return a string for sorting the repetition column.
835 */
836 QString EventListModel::repeatOrder(const KAEvent* event) const
837 {
838  int repeatOrder = 0;
839  int repeatInterval = 0;
840  if (event->repeatAtLogin())
841  repeatOrder = 1;
842  else
843  {
844  repeatInterval = event->recurInterval();
845  switch (event->recurType())
846  {
847  case KARecurrence::MINUTELY:
848  repeatOrder = 2;
849  break;
850  case KARecurrence::DAILY:
851  repeatOrder = 3;
852  break;
853  case KARecurrence::WEEKLY:
854  repeatOrder = 4;
855  break;
856  case KARecurrence::MONTHLY_DAY:
857  case KARecurrence::MONTHLY_POS:
858  repeatOrder = 5;
859  break;
860  case KARecurrence::ANNUAL_DATE:
861  case KARecurrence::ANNUAL_POS:
862  repeatOrder = 6;
863  break;
864  case KARecurrence::NO_RECUR:
865  default:
866  break;
867  }
868  }
869  return QString("%1%2").arg(static_cast<char>('0' + repeatOrder)).arg(repeatInterval, 8, 10, QLatin1Char('0'));
870 }
871 
872 /******************************************************************************
873 * Return the icon associated with the event's action.
874 */
875 QPixmap* EventListModel::eventIcon(const KAEvent* event) const
876 {
877  switch (event->actionTypes())
878  {
879  case KAEvent::ACT_EMAIL:
880  return mEmailIcon;
881  case KAEvent::ACT_AUDIO:
882  return mAudioIcon;
883  case KAEvent::ACT_COMMAND:
884  return mCommandIcon;
885  case KAEvent::ACT_DISPLAY:
886  if (event->actionSubType() == KAEvent::FILE)
887  return mFileIcon;
888  // fall through to ACT_DISPLAY_COMMAND
889  case KAEvent::ACT_DISPLAY_COMMAND:
890  default:
891  return mTextIcon;
892  }
893 }
894 
895 /******************************************************************************
896 * Returns the QWhatsThis text for a specified column.
897 */
898 QString EventListModel::whatsThisText(int column) const
899 {
900  switch (column)
901  {
902  case TimeColumn:
903  return i18nc("@info:whatsthis", "Next scheduled date and time of the alarm");
904  case TimeToColumn:
905  return i18nc("@info:whatsthis", "How long until the next scheduled trigger of the alarm");
906  case RepeatColumn:
907  return i18nc("@info:whatsthis", "How often the alarm recurs");
908  case ColourColumn:
909  return i18nc("@info:whatsthis", "Background color of alarm message");
910  case TypeColumn:
911  return i18nc("@info:whatsthis", "Alarm type (message, file, command or email)");
912  case TextColumn:
913  return i18nc("@info:whatsthis", "Alarm message text, URL of text file to display, command to execute, or email subject line");
914  case TemplateNameColumn:
915  return i18nc("@info:whatsthis", "Name of the alarm template");
916  default:
917  return QString();
918  }
919 }
920 
921 
922 /*=============================================================================
923 = Class: EventListFilterModel
924 = Base class for all filters on EventListModel.
925 =============================================================================*/
926 
927 EventListFilterModel::EventListFilterModel(EventListModel* baseModel, QObject* parent)
928  : QSortFilterProxyModel(parent)
929 {
930  setSourceModel(baseModel);
931  setSortRole(EventListModel::SortRole);
932  setDynamicSortFilter(true);
933 }
934 
935 /******************************************************************************
936 * Return the event referred to by an index.
937 */
938 KAEvent* EventListFilterModel::event(const QModelIndex& index) const
939 {
940  return static_cast<EventListModel*>(sourceModel())->event(mapToSource(index));
941 }
942 
943 KAEvent* EventListFilterModel::event(int row) const
944 {
945  return static_cast<EventListModel*>(sourceModel())->event(mapToSource(index(row, 0)));
946 }
947 
948 /******************************************************************************
949 * Return the index to a specified event.
950 */
951 QModelIndex EventListFilterModel::eventIndex(const QString& eventId) const
952 {
953  return mapFromSource(static_cast<EventListModel*>(sourceModel())->eventIndex(eventId));
954 }
955 
956 /******************************************************************************
957 * Return the index to a specified event.
958 */
959 QModelIndex EventListFilterModel::eventIndex(const KAEvent* event) const
960 {
961  return mapFromSource(static_cast<EventListModel*>(sourceModel())->eventIndex(event));
962 }
963 
964 void EventListFilterModel::slotDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
965 {
966  emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight));
967 }
968 
969 // vim: et sw=4:
QSortFilterProxyModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
EventListModel::resourceStatusChanged
static void resourceStatusChanged(AlarmResource *, AlarmResources::Change)
Definition: eventlistmodel.cpp:545
QModelIndex
QSortFilterProxyModel::setSortRole
void setSortRole(int role)
QPixmap::size
QSize size() const
synchtimer.h
EventListModel::StatusRole
Definition: eventlistmodel.h:51
EventListModel::alarms
static EventListModel * alarms()
Definition: eventlistmodel.cpp:55
QSortFilterProxyModel::setSourceModel
virtual void setSourceModel(QAbstractItemModel *sourceModel)
QAbstractTableModel
AlarmCalendar::resources
static AlarmCalendar * resources()
Definition: alarmcalendar.h:130
alarmtime.h
EventListModel::updateCommandError
void updateCommandError(const QString &eventId)
Definition: eventlistmodel.cpp:523
EventListModel::eventIndex
QModelIndex eventIndex(const KAEvent *) const
Definition: eventlistmodel.cpp:714
EventListModel::ValueRole
Definition: eventlistmodel.h:52
EventListModel::SortRole
Definition: eventlistmodel.h:53
EventListModel::addEvents
void addEvents(const KAEvent::List &)
Definition: eventlistmodel.cpp:740
alarmcalendar.h
EventListModel::removeEvent
void removeEvent(const KAEvent *event)
Definition: eventlistmodel.h:75
QTime
EventListModel::TimeColumn
Definition: eventlistmodel.h:46
EventListModel::RepeatColumn
Definition: eventlistmodel.h:46
QModelIndex::isValid
bool isValid() const
EventListModel::ColourColumn
Definition: eventlistmodel.h:46
QAbstractItemModel::dataChanged
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
QAbstractItemModel::endInsertRows
void endInsertRows()
EventListModel::headerData
virtual QVariant headerData(int section, Qt::Orientation, int role=Qt::DisplayRole) const
Definition: eventlistmodel.cpp:352
EventListModel::~EventListModel
~EventListModel()
Definition: eventlistmodel.cpp:75
QObject
QString::isEmpty
bool isEmpty() const
EventListModel::TemplateNameColumn
Definition: eventlistmodel.h:47
AlarmTime::timeToAlarmText
static QString timeToAlarmText(const KAlarmCal::DateTime &dateTime)
Definition: alarmtime.cpp:77
QAbstractItemModel::beginRemoveRows
void beginRemoveRows(const QModelIndex &parent, int first, int last)
QModelIndex::row
int row() const
EventListModel::reload
void reload()
Definition: eventlistmodel.cpp:678
EventListModel::ColumnCount
Definition: eventlistmodel.h:48
QSortFilterProxyModel::setDynamicSortFilter
void setDynamicSortFilter(bool enable)
QModelIndex::internalPointer
void * internalPointer() const
QDate
EventListModel::rowCount
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Definition: eventlistmodel.cpp:111
MinuteTimer::connect
static void connect(QObject *receiver, const char *member)
QString
QColor
QBitArray
EventListModel::data
virtual QVariant data(const QModelIndex &, int role=Qt::DisplayRole) const
Definition: eventlistmodel.cpp:132
QPixmap
QAbstractItemModel::createIndex
QModelIndex createIndex(int row, int column, void *ptr) const
EventListFilterModel::EventListFilterModel
EventListFilterModel(EventListModel *baseModel, QObject *parent=0)
Definition: eventlistmodel.cpp:927
EventListModel::TypeColumn
Definition: eventlistmodel.h:46
QSize
QLatin1Char
QSortFilterProxyModel
preferences.h
QVariant::setValue
void setValue(const T &value)
Preferences::connect
static void connect(const char *signal, const QObject *receiver, const char *member)
Definition: preferences.cpp:369
QAbstractItemModel::beginInsertRows
void beginInsertRows(const QModelIndex &parent, int first, int last)
EventListModel::templates
static EventListModel * templates()
Definition: eventlistmodel.cpp:68
EventListModel::EnabledRole
Definition: eventlistmodel.h:54
EventListModel::updateEvent
bool updateEvent(KAEvent *event)
Definition: eventlistmodel.h:72
EventListModel::TimeToColumn
Definition: eventlistmodel.h:46
AlarmTime::alarmTimeText
static QString alarmTimeText(const KAlarmCal::DateTime &dateTime)
Definition: alarmtime.cpp:39
QAbstractProxyModel::sourceModel
QAbstractItemModel * sourceModel() const
QSortFilterProxyModel::mapToSource
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const
EventListModel::index
virtual QModelIndex index(int row, int column=0, const QModelIndex &parent=QModelIndex()) const
Definition: eventlistmodel.cpp:125
EventListModel
Definition: eventlistmodel.h:41
QSize::expandedTo
QSize expandedTo(const QSize &otherSize) const
QSortFilterProxyModel::mapFromSource
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
EventListModel::event
KAEvent * event(int row) const
Definition: eventlistmodel.cpp:805
EventListModel::setData
virtual bool setData(const QModelIndex &, const QVariant &value, int role=Qt::EditRole)
Definition: eventlistmodel.cpp:341
kalarm.h
QColor::getRgb
void getRgb(int *r, int *g, int *b, int *a) const
EventListModel::TextColumn
Definition: eventlistmodel.h:46
EventListModel::flags
virtual Qt::ItemFlags flags(const QModelIndex &) const
Definition: eventlistmodel.cpp:382
QModelIndex::column
int column() const
QString::fromLatin1
QString fromLatin1(const char *str, int size)
AlarmCalendar::events
KAEvent::List events(CalEvent::Types s=CalEvent::EMPTY) const
Definition: alarmcalendar.h:96
EventListFilterModel::eventIndex
QModelIndex eventIndex(const KAEvent *) const
Definition: eventlistmodel.cpp:959
EventListModel::removeResource
void removeResource(AlarmResource *)
Definition: eventlistmodel.cpp:640
QAbstractItemModel::endRemoveRows
void endRemoveRows()
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
EventListModel::columnCount
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition: eventlistmodel.cpp:118
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
EventListFilterModel::event
KAEvent * event(int row) const
Definition: eventlistmodel.cpp:943
QDateTime
EventListModel::addEvent
void addEvent(KAEvent *)
Definition: eventlistmodel.cpp:725
QVariant
Qt::ItemFlags
typedef ItemFlags
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kalarm

Skip menu "kalarm"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal