kalarm

alarmlistview.cpp
1/*
2 * alarmlistview.cpp - widget showing list of outstanding alarms
3 * Program: kalarm
4 * Copyright © 2001-2007 by David Jarvie <software@astrojar.org.uk>
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 <tqtooltip.h>
24#include <tqpainter.h>
25#include <tqstyle.h>
26#include <tqheader.h>
27#include <tqregexp.h>
28
29#include <tdeglobal.h>
30#include <tdelocale.h>
31#include <kdebug.h>
32
33#include <libkcal/icaldrag.h>
34#include <libkcal/calendarlocal.h>
35
36#include "alarmcalendar.h"
37#include "alarmtext.h"
38#include "functions.h"
39#include "kalarmapp.h"
40#include "preferences.h"
41#include "alarmlistview.moc"
42
43
44class AlarmListTooltip : public TQToolTip
45{
46 public:
47 AlarmListTooltip(TQWidget* parent) : TQToolTip(parent) { }
48 virtual ~AlarmListTooltip() {}
49 protected:
50 virtual void maybeTip(const TQPoint&);
51};
52
53
54/*=============================================================================
55= Class: AlarmListView
56= Displays the list of outstanding alarms.
57=============================================================================*/
58TQValueList<EventListViewBase*> AlarmListView::mInstanceList;
59bool AlarmListView::mDragging = false;
60
61
62AlarmListView::AlarmListView(const TQValueList<int>& order, TQWidget* parent, const char* name)
63 : EventListViewBase(parent, name),
64 mMousePressed(false),
65 mDrawMessageInColour(false),
66 mShowExpired(false)
67{
68 static TQString titles[COLUMN_COUNT] = {
69 i18n("Time"),
70 i18n("Time To"),
71 i18n("Repeat"),
72 TQString(),
73 TQString(),
74 i18n("Message, File or Command")
75 };
76
77 setSelectionMode(TQListView::Extended);
78
79 // Set the column order
80 int i;
81 bool ok = false;
82 if (order.count() >= COLUMN_COUNT)
83 {
84 // The column order is specified
85 bool posns[COLUMN_COUNT];
86 for (i = 0; i < COLUMN_COUNT; ++i)
87 posns[i] = false;
88 for (i = 0; i < COLUMN_COUNT; ++i)
89 {
90 int ord = order[i];
91 if (ord < COLUMN_COUNT && ord >= 0)
92 {
93 mColumn[i] = ord;
94 posns[ord] = true;
95 }
96 }
97 ok = true;
98 for (i = 0; i < COLUMN_COUNT; ++i)
99 if (!posns[i])
100 ok = false;
101 if (ok && mColumn[MESSAGE_COLUMN] != MESSAGE_COLUMN)
102 {
103 // Shift the message column to be last, since otherwise
104 // column widths get screwed up.
105 int messageCol = mColumn[MESSAGE_COLUMN];
106 for (i = 0; i < COLUMN_COUNT; ++i)
107 if (mColumn[i] > messageCol)
108 --mColumn[i];
109 mColumn[MESSAGE_COLUMN] = MESSAGE_COLUMN;
110 }
111 }
112 if (!ok)
113 {
114 // Either no column order was specified, or it was invalid,
115 // so use the default order
116 for (i = 0; i < COLUMN_COUNT; ++i)
117 mColumn[i] = i;
118 }
119
120 // Initialise the columns
121 for (i = 0; i < COLUMN_COUNT; ++i)
122 {
123 for (int j = 0; j < COLUMN_COUNT; ++j)
124 if (mColumn[j] == i)
125 {
126 if (j != MESSAGE_COLUMN)
127 addColumn(titles[j]);
128 break;
129 }
130 }
131 addLastColumn(titles[MESSAGE_COLUMN]);
132
133 setSorting(mColumn[TIME_COLUMN]); // sort initially by date/time
134 mTimeColumnHeaderWidth = columnWidth(mColumn[TIME_COLUMN]);
135 mTimeToColumnHeaderWidth = columnWidth(mColumn[TIME_TO_COLUMN]);
136 setColumnAlignment(mColumn[REPEAT_COLUMN], TQt::AlignHCenter);
137 setColumnWidthMode(mColumn[REPEAT_COLUMN], TQListView::Maximum);
138
139 // Set the width of the colour column in proportion to height
140 setColumnWidth(mColumn[COLOUR_COLUMN], itemHeight() * 3/4);
141 setColumnWidthMode(mColumn[COLOUR_COLUMN], TQListView::Manual);
142
143 // Set the width of the alarm type column to exactly accommodate the icons.
144 // Don't allow the user to resize it (to avoid refresh problems, and bearing
145 // in mind that resizing doesn't seem very useful anyway).
146 setColumnWidth(mColumn[TYPE_COLUMN], AlarmListViewItem::typeIconWidth(this));
147 setColumnWidthMode(mColumn[TYPE_COLUMN], TQListView::Manual);
148 header()->setResizeEnabled(false, mColumn[TYPE_COLUMN]);
149
150 mInstanceList.append(this);
151
152 mTooltip = new AlarmListTooltip(viewport());
153}
154
155AlarmListView::~AlarmListView()
156{
157 delete mTooltip;
158 mTooltip = 0;
159 mInstanceList.remove(this);
160}
161
162/******************************************************************************
163* Add all the current alarms to the list.
164*/
165void AlarmListView::populate()
166{
167 KAEvent event;
168 KCal::Event::List events;
169 KCal::Event::List::ConstIterator it;
170 TQDateTime now = TQDateTime::currentDateTime();
171 if (mShowExpired)
172 {
173 AlarmCalendar* cal = AlarmCalendar::expiredCalendarOpen();
174 if (cal)
175 {
176 events = cal->events();
177 for (it = events.begin(); it != events.end(); ++it)
178 {
179 KCal::Event* kcalEvent = *it;
180 if (kcalEvent->alarms().count() > 0)
181 {
182 event.set(*kcalEvent);
183 addEntry(event, now);
184 }
185 }
186 }
187 }
188 events = AlarmCalendar::activeCalendar()->events();
189 for (it = events.begin(); it != events.end(); ++it)
190 {
191 KCal::Event* kcalEvent = *it;
192 event.set(*kcalEvent);
193 if (mShowExpired || !event.expired())
194 addEntry(event, now);
195 }
196}
197
198/******************************************************************************
199* Set which time columns are to be displayed.
200*/
201void AlarmListView::selectTimeColumns(bool time, bool timeTo)
202{
203 if (!time && !timeTo)
204 return; // always show at least one time column
205 bool changed = false;
206 int w = columnWidth(mColumn[TIME_COLUMN]);
207 if (time && !w)
208 {
209 // Unhide the time column
210 int colWidth = mTimeColumnHeaderWidth;
211 TQFontMetrics fm = fontMetrics();
212 for (AlarmListViewItem* item = firstChild(); item; item = item->nextSibling())
213 {
214 int w = item->width(fm, this, mColumn[TIME_COLUMN]);
215 if (w > colWidth)
216 colWidth = w;
217 }
218 setColumnWidth(mColumn[TIME_COLUMN], colWidth);
219 setColumnWidthMode(mColumn[TIME_COLUMN], TQListView::Maximum);
220 changed = true;
221 }
222 else if (!time && w)
223 {
224 // Hide the time column
225 setColumnWidthMode(mColumn[TIME_COLUMN], TQListView::Manual);
226 setColumnWidth(mColumn[TIME_COLUMN], 0);
227 changed = true;
228 }
229 w = columnWidth(mColumn[TIME_TO_COLUMN]);
230 if (timeTo && !w)
231 {
232 // Unhide the time-to-alarm column
233 setColumnWidthMode(mColumn[TIME_TO_COLUMN], TQListView::Maximum);
234 updateTimeToAlarms(true);
235 if (columnWidth(mColumn[TIME_TO_COLUMN]) < mTimeToColumnHeaderWidth)
236 setColumnWidth(mColumn[TIME_TO_COLUMN], mTimeToColumnHeaderWidth);
237 changed = true;
238 }
239 else if (!timeTo && w)
240 {
241 // Hide the time-to-alarm column
242 setColumnWidthMode(mColumn[TIME_TO_COLUMN], TQListView::Manual);
243 setColumnWidth(mColumn[TIME_TO_COLUMN], 0);
244 changed = true;
245 }
246 if (changed)
247 {
248 resizeLastColumn();
249 triggerUpdate(); // ensure scroll bar appears if needed
250 }
251}
252
253/******************************************************************************
254* Update all the values in the time-to-alarm column.
255*/
256void AlarmListView::updateTimeToAlarms(bool forceDisplay)
257{
258 if (forceDisplay || columnWidth(mColumn[TIME_TO_COLUMN]))
259 {
260 TQDateTime now = TQDateTime::currentDateTime();
261 for (AlarmListViewItem* item = firstChild(); item; item = item->nextSibling())
262 item->updateTimeToAlarm(now, forceDisplay);
263 }
264}
265
266/******************************************************************************
267* Add an event to every list instance.
268* The selection highlight is moved to the new event in the specified instance only.
269*/
270void AlarmListView::addEvent(const KAEvent& event, EventListViewBase* view)
271{
272 TQDateTime now = TQDateTime::currentDateTime();
273 for (InstanceListConstIterator it = mInstanceList.begin(); it != mInstanceList.end(); ++it)
274 static_cast<AlarmListView*>(*it)->addEntry(event, now, true, (*it == view));
275}
276
277/******************************************************************************
278* Add a new item to the list.
279*/
280AlarmListViewItem* AlarmListView::addEntry(const KAEvent& event, const TQDateTime& now, bool setSize, bool reselect)
281{
282 if (!mShowExpired && event.expired())
283 return 0;
284 AlarmListViewItem* item = new AlarmListViewItem(this, event, now);
285 return static_cast<AlarmListViewItem*>(EventListViewBase::addEntry(item, setSize, reselect));
286}
287
288/******************************************************************************
289* Create a new list item for addEntry().
290*/
291EventListViewItemBase* AlarmListView::createItem(const KAEvent& event)
292{
293 return new AlarmListViewItem(this, event, TQDateTime::currentDateTime());
294}
295
296/******************************************************************************
297* Check whether an item's alarm has expired.
298*/
299bool AlarmListView::expired(AlarmListViewItem* item) const
300{
301 return item->event().expired();
302}
303
304/******************************************************************************
305* Return the column order.
306*/
307TQValueList<int> AlarmListView::columnOrder() const
308{
309 TQHeader* hdr = header();
310 int order[COLUMN_COUNT];
311 order[TIME_COLUMN] = hdr->mapToIndex(mColumn[TIME_COLUMN]);
312 order[TIME_TO_COLUMN] = hdr->mapToIndex(mColumn[TIME_TO_COLUMN]);
313 order[REPEAT_COLUMN] = hdr->mapToIndex(mColumn[REPEAT_COLUMN]);
314 order[COLOUR_COLUMN] = hdr->mapToIndex(mColumn[COLOUR_COLUMN]);
315 order[TYPE_COLUMN] = hdr->mapToIndex(mColumn[TYPE_COLUMN]);
316 order[MESSAGE_COLUMN] = hdr->mapToIndex(mColumn[MESSAGE_COLUMN]);
317 TQValueList<int> orderList;
318 for (int i = 0; i < COLUMN_COUNT; ++i)
319 orderList += order[i];
320 return orderList;
321}
322
323/******************************************************************************
324* Returns the TQWhatsThis text for a specified column.
325*/
326TQString AlarmListView::whatsThisText(int column) const
327{
328 if (column == mColumn[TIME_COLUMN])
329 return i18n("Next scheduled date and time of the alarm");
330 if (column == mColumn[TIME_TO_COLUMN])
331 return i18n("How long until the next scheduled trigger of the alarm");
332 if (column == mColumn[REPEAT_COLUMN])
333 return i18n("How often the alarm recurs");
334 if (column == mColumn[COLOUR_COLUMN])
335 return i18n("Background color of alarm message");
336 if (column == mColumn[TYPE_COLUMN])
337 return i18n("Alarm type (message, file, command or email)");
338 if (column == mColumn[MESSAGE_COLUMN])
339 return i18n("Alarm message text, URL of text file to display, command to execute, or email subject line");
340 return i18n("List of scheduled alarms");
341}
342
343/******************************************************************************
344* Called when the mouse button is pressed.
345* Records the position of the mouse when the left button is pressed, for use
346* in drag operations.
347*/
348void AlarmListView::contentsMousePressEvent(TQMouseEvent* e)
349{
350 TQListView::contentsMousePressEvent(e);
351 if (e->button() == TQt::LeftButton)
352 {
353 TQPoint p(contentsToViewport(e->pos()));
354 if (itemAt(p))
355 {
356 mMousePressPos = e->pos();
357 mMousePressed = true;
358 }
359 mDragging = false;
360 }
361}
362
363/******************************************************************************
364* Called when the mouse is moved.
365* Creates a drag object when the mouse drags one or more selected items.
366*/
367void AlarmListView::contentsMouseMoveEvent(TQMouseEvent* e)
368{
369 TQListView::contentsMouseMoveEvent(e);
370 if (mMousePressed
371 && (mMousePressPos - e->pos()).manhattanLength() > TQApplication::startDragDistance())
372 {
373 // Create a calendar object containing all the currently selected alarms
374 kdDebug(5950) << "AlarmListView::contentsMouseMoveEvent(): drag started" << endl;
375 mMousePressed = false;
376 KCal::CalendarLocal cal(TQString::fromLatin1("UTC"));
377 cal.setLocalTime(); // write out using local time (i.e. no time zone)
378 TQValueList<EventListViewItemBase*> items = selectedItems();
379 if (!items.count())
380 return;
381 for (TQValueList<EventListViewItemBase*>::Iterator it = items.begin(); it != items.end(); ++it)
382 {
383 const KAEvent& event = (*it)->event();
384 KCal::Event* kcalEvent = new KCal::Event;
385 event.updateKCalEvent(*kcalEvent, false, true);
386 kcalEvent->setUid(event.id());
387 cal.addEvent(kcalEvent);
388 }
389
390 // Create the drag object for the destination program to receive
391 mDragging = true;
392 KCal::ICalDrag* dobj = new KCal::ICalDrag(&cal, this);
393 dobj->dragCopy(); // the drag operation will copy the alarms
394 }
395}
396
397/******************************************************************************
398* Called when the mouse button is released.
399* Notes that the mouse left button is no longer pressed, for use in drag
400* operations.
401*/
402void AlarmListView::contentsMouseReleaseEvent(TQMouseEvent *e)
403{
404 TQListView::contentsMouseReleaseEvent(e);
405 mMousePressed = false;
406 mDragging = false;
407}
408
409
410/*=============================================================================
411= Class: AlarmListViewItem
412= Contains the details of one alarm for display in the AlarmListView.
413=============================================================================*/
414int AlarmListViewItem::mTimeHourPos = -2;
415int AlarmListViewItem::mDigitWidth = -1;
416
417AlarmListViewItem::AlarmListViewItem(AlarmListView* parent, const KAEvent& event, const TQDateTime& now)
418 : EventListViewItemBase(parent, event),
419 mMessageTruncated(false),
420 mTimeToAlarmShown(false)
421{
422 setLastColumnText(); // set the message column text
423
424 DateTime dateTime = event.expired() ? event.startDateTime() : event.displayDateTime();
425 if (parent->column(AlarmListView::TIME_COLUMN) >= 0)
426 setText(parent->column(AlarmListView::TIME_COLUMN), alarmTimeText(dateTime));
427 if (parent->column(AlarmListView::TIME_TO_COLUMN) >= 0)
428 {
429 TQString tta = timeToAlarmText(now);
430 setText(parent->column(AlarmListView::TIME_TO_COLUMN), tta);
431 mTimeToAlarmShown = !tta.isNull();
432 }
433 TQTime t = dateTime.time();
434 mDateTimeOrder.sprintf("%04d%03d%02d%02d", dateTime.date().year(), dateTime.date().dayOfYear(),
435 t.hour(), t.minute());
436
437 int repeatOrder = 0;
438 int repeatInterval = 0;
439 TQString repeatText = event.recurrenceText(true); // text displayed in Repeat column
440 if (repeatText.isEmpty())
441 repeatText = event.repetitionText(true);
442 if (event.repeatAtLogin())
443 repeatOrder = 1;
444 else
445 {
446 repeatInterval = event.recurInterval();
447 switch (event.recurType())
448 {
449 case KARecurrence::MINUTELY:
450 repeatOrder = 2;
451 break;
452 case KARecurrence::DAILY:
453 repeatOrder = 3;
454 break;
455 case KARecurrence::WEEKLY:
456 repeatOrder = 4;
457 break;
458 case KARecurrence::MONTHLY_DAY:
459 case KARecurrence::MONTHLY_POS:
460 repeatOrder = 5;
461 break;
462 case KARecurrence::ANNUAL_DATE:
463 case KARecurrence::ANNUAL_POS:
464 repeatOrder = 6;
465 break;
466 case KARecurrence::NO_RECUR:
467 default:
468 break;
469 }
470 }
471 setText(parent->column(AlarmListView::REPEAT_COLUMN), repeatText);
472 mRepeatOrder.sprintf("%c%08d", '0' + repeatOrder, repeatInterval);
473
474 bool showColour = (event.action() == KAEvent::MESSAGE || event.action() == KAEvent::FILE);
475 mColourOrder.sprintf("%06u", (showColour ? event.bgColour().rgb() : 0));
476
477 mTypeOrder.sprintf("%02d", event.action());
478}
479
480/******************************************************************************
481* Return the single line alarm summary text.
482*/
483TQString AlarmListViewItem::alarmText(const KAEvent& event) const
484{
485 bool truncated;
486 TQString text = AlarmText::summary(event, 1, &truncated);
487 mMessageTruncated = truncated;
488 return text;
489}
490
491/******************************************************************************
492* Return the alarm time text in the form "date time".
493*/
494TQString AlarmListViewItem::alarmTimeText(const DateTime& dateTime) const
495{
496 TDELocale* locale = TDEGlobal::locale();
497 TQString dateTimeText = locale->formatDate(dateTime.date(), true);
498 if (!dateTime.isDateOnly())
499 {
500 dateTimeText += ' ';
501 TQString time = locale->formatTime(dateTime.time());
502 if (mTimeHourPos == -2)
503 {
504 // Initialise the position of the hour within the time string, if leading
505 // zeroes are omitted, so that displayed times can be aligned with each other.
506 mTimeHourPos = -1; // default = alignment isn't possible/sensible
507 if (!TQApplication::reverseLayout()) // don't try to align right-to-left languages
508 {
509 TQString fmt = locale->timeFormat();
510 int i = fmt.find(TQRegExp("%[kl]")); // check if leading zeroes are omitted
511 if (i >= 0 && i == fmt.find('%')) // and whether the hour is first
512 mTimeHourPos = i; // yes, so need to align
513 }
514 }
515 if (mTimeHourPos >= 0 && (int)time.length() > mTimeHourPos + 1
516 && time[mTimeHourPos].isDigit() && !time[mTimeHourPos + 1].isDigit())
517 dateTimeText += '~'; // improve alignment of times with no leading zeroes
518 dateTimeText += time;
519 }
520 return dateTimeText + ' ';
521}
522
523/******************************************************************************
524* Return the time-to-alarm text.
525*/
526TQString AlarmListViewItem::timeToAlarmText(const TQDateTime& now) const
527{
528 if (event().expired())
529 return TQString();
530 DateTime dateTime = event().displayDateTime();
531 if (dateTime.isDateOnly())
532 {
533 int days = now.date().daysTo(dateTime.date());
534 return i18n("n days", " %1d ").arg(days);
535 }
536 int mins = (now.secsTo(dateTime.dateTime()) + 59) / 60;
537 if (mins < 0)
538 return TQString();
539 char minutes[3] = "00";
540 minutes[0] = (mins%60) / 10 + '0';
541 minutes[1] = (mins%60) % 10 + '0';
542 if (mins < 24*60)
543 return i18n("hours:minutes", " %1:%2 ").arg(mins/60).arg(minutes);
544 int days = mins / (24*60);
545 mins = mins % (24*60);
546 return i18n("days hours:minutes", " %1d %2:%3 ").arg(days).arg(mins/60).arg(minutes);
547}
548
549/******************************************************************************
550* Update the displayed time-to-alarm value.
551* The updated value is only displayed if it is different from the existing value,
552* or if 'forceDisplay' is true.
553*/
554void AlarmListViewItem::updateTimeToAlarm(const TQDateTime& now, bool forceDisplay)
555{
556 if (event().expired())
557 {
558 if (forceDisplay || mTimeToAlarmShown)
559 {
560 setText(alarmListView()->column(AlarmListView::TIME_TO_COLUMN), TQString());
561 mTimeToAlarmShown = false;
562 }
563 }
564 else
565 {
566 TQString tta = timeToAlarmText(now);
567 if (forceDisplay || tta != text(alarmListView()->column(AlarmListView::TIME_TO_COLUMN)))
568 setText(alarmListView()->column(AlarmListView::TIME_TO_COLUMN), tta);
569 mTimeToAlarmShown = !tta.isNull();
570 }
571}
572
573/******************************************************************************
574* Paint one value in one of the columns in the list view.
575*/
576void AlarmListViewItem::paintCell(TQPainter* painter, const TQColorGroup& cg, int column, int width, int /*align*/)
577{
578 const AlarmListView* listView = alarmListView();
579 int margin = listView->itemMargin();
580 TQRect box(margin, margin, width - margin*2, height() - margin*2); // area within which to draw
581 bool selected = isSelected();
582 TQColor bgColour = selected ? cg.highlight() : cg.base();
583 TQColor fgColour = selected ? cg.highlightedText()
584 : !event().enabled() ? Preferences::disabledColour()
585 : event().expired() ? Preferences::expiredColour() : cg.text();
586 painter->setPen(fgColour);
587 painter->fillRect(0, 0, width, height(), bgColour);
588
589 if (column == listView->column(AlarmListView::TIME_COLUMN))
590 {
591 int i = -1;
592 TQString str = text(column);
593 if (mTimeHourPos >= 0)
594 {
595 // Need to pad out spacing to align times without leading zeroes
596 i = str.find(" ~");
597 if (i >= 0)
598 {
599 if (mDigitWidth < 0)
600 mDigitWidth = painter->fontMetrics().width("0");
601 TQString date = str.left(i + 1);
602 int w = painter->fontMetrics().width(date) + mDigitWidth;
603 painter->drawText(box, AlignVCenter, date);
604 box.setLeft(box.left() + w);
605 painter->drawText(box, AlignVCenter, str.mid(i + 2));
606 }
607 }
608 if (i < 0)
609 painter->drawText(box, AlignVCenter, str);
610 }
611 else if (column == listView->column(AlarmListView::TIME_TO_COLUMN))
612 painter->drawText(box, AlignVCenter | AlignRight, text(column));
613 else if (column == listView->column(AlarmListView::REPEAT_COLUMN))
614 painter->drawText(box, AlignVCenter | AlignHCenter, text(column));
615 else if (column == listView->column(AlarmListView::COLOUR_COLUMN))
616 {
617 // Paint the cell the colour of the alarm message
618 if (event().action() == KAEvent::MESSAGE || event().action() == KAEvent::FILE)
619 painter->fillRect(box, event().bgColour());
620 }
621 else if (column == listView->column(AlarmListView::TYPE_COLUMN))
622 {
623 // Display the alarm type icon, horizontally and vertically centred in the cell
624 TQPixmap* pixmap = eventIcon();
625 TQRect pixmapRect = pixmap->rect();
626 int diff = box.height() - pixmap->height();
627 if (diff < 0)
628 {
629 pixmapRect.setTop(-diff / 2);
630 pixmapRect.setHeight(box.height());
631 }
632 TQPoint iconTopLeft(box.left() + (box.width() - pixmapRect.width()) / 2,
633 box.top() + (diff > 0 ? diff / 2 : 0));
634 painter->drawPixmap(iconTopLeft, *pixmap, pixmapRect);
635 }
636 else if (column == listView->column(AlarmListView::MESSAGE_COLUMN))
637 {
638 if (!selected && listView->drawMessageInColour())
639 {
640 painter->fillRect(box, event().bgColour());
641 painter->setBackgroundColor(event().bgColour());
642// painter->setPen(event().fgColour());
643 }
644 TQString txt = text(column);
645 painter->drawText(box, AlignVCenter, txt);
646 mMessageColWidth = listView->fontMetrics().boundingRect(txt).width();
647 }
648}
649
650/******************************************************************************
651* Return the width needed for the icons in the alarm type column.
652*/
653int AlarmListViewItem::typeIconWidth(AlarmListView* v)
654{
655 return iconWidth() + 2 * v->style().pixelMetric(TQStyle::PM_DefaultFrameWidth);
656}
657
658/******************************************************************************
659* Return the column sort order for one item in the list.
660*/
661TQString AlarmListViewItem::key(int column, bool) const
662{
663 AlarmListView* listView = alarmListView();
664 if (column == listView->column(AlarmListView::TIME_COLUMN)
665 || column == listView->column(AlarmListView::TIME_TO_COLUMN))
666 return mDateTimeOrder;
667 if (column == listView->column(AlarmListView::REPEAT_COLUMN))
668 return mRepeatOrder;
669 if (column == listView->column(AlarmListView::COLOUR_COLUMN))
670 return mColourOrder;
671 if (column == listView->column(AlarmListView::TYPE_COLUMN))
672 return mTypeOrder;
673 return text(column).lower();
674}
675
676
677/*=============================================================================
678= Class: AlarmListTooltip
679= Displays the full alarm text in a tooltip when necessary.
680=============================================================================*/
681
682/******************************************************************************
683* Displays the full alarm text in a tooltip, if not all the text is displayed.
684*/
685void AlarmListTooltip::maybeTip(const TQPoint& pt)
686{
687 AlarmListView* listView = (AlarmListView*)parentWidget()->parentWidget();
688 int column = listView->column(AlarmListView::MESSAGE_COLUMN);
689 int xOffset = listView->contentsX();
690 if (listView->header()->sectionAt(pt.x() + xOffset) == column)
691 {
692 AlarmListViewItem* item = (AlarmListViewItem*)listView->itemAt(pt);
693 if (item)
694 {
695 int columnX = listView->header()->sectionPos(column) - xOffset;
696 int columnWidth = listView->columnWidth(column);
697 int widthNeeded = item->messageColWidthNeeded();
698 if (!item->messageTruncated() && columnWidth >= widthNeeded)
699 {
700 if (columnX + widthNeeded <= listView->viewport()->width())
701 return;
702 }
703 TQRect rect = listView->itemRect(item);
704 rect.setLeft(columnX);
705 rect.setWidth(columnWidth);
706 kdDebug(5950) << "AlarmListTooltip::maybeTip(): display\n";
707 tip(rect, AlarmText::summary(item->event(), 10)); // display up to 10 lines of text
708 }
709 }
710}
711
Provides read and write access to calendar files.
Definition: alarmcalendar.h:37
KAEvent corresponds to a KCal::Event instance.
Definition: alarmevent.h:232
void setUid(const TQString &)
const Alarm::List & alarms() const
miscellaneous functions
the KAlarm application object