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

kalarm

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

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