23 #include <tqtooltip.h>
24 #include <tqpainter.h>
29 #include <tdeglobal.h>
30 #include <tdelocale.h>
33 #include <libkcal/icaldrag.h>
34 #include <libkcal/calendarlocal.h>
36 #include "alarmcalendar.h"
37 #include "alarmtext.h"
40 #include "preferences.h"
41 #include "alarmlistview.moc"
44 class AlarmListTooltip :
public TQToolTip
47 AlarmListTooltip(TQWidget* parent) : TQToolTip(parent) { }
48 virtual ~AlarmListTooltip() {}
50 virtual void maybeTip(
const TQPoint&);
58 TQValueList<EventListViewBase*> AlarmListView::mInstanceList;
59 bool AlarmListView::mDragging =
false;
62 AlarmListView::AlarmListView(
const TQValueList<int>& order, TQWidget* parent,
const char* name)
63 : EventListViewBase(parent, name),
65 mDrawMessageInColour(false),
68 static TQString titles[COLUMN_COUNT] = {
74 i18n(
"Message, File or Command")
77 setSelectionMode(TQListView::Extended);
82 if (order.count() >= COLUMN_COUNT)
85 bool posns[COLUMN_COUNT];
86 for (i = 0; i < COLUMN_COUNT; ++i)
88 for (i = 0; i < COLUMN_COUNT; ++i)
91 if (ord < COLUMN_COUNT && ord >= 0)
98 for (i = 0; i < COLUMN_COUNT; ++i)
101 if (ok && mColumn[MESSAGE_COLUMN] != MESSAGE_COLUMN)
105 int messageCol = mColumn[MESSAGE_COLUMN];
106 for (i = 0; i < COLUMN_COUNT; ++i)
107 if (mColumn[i] > messageCol)
109 mColumn[MESSAGE_COLUMN] = MESSAGE_COLUMN;
116 for (i = 0; i < COLUMN_COUNT; ++i)
121 for (i = 0; i < COLUMN_COUNT; ++i)
123 for (
int j = 0; j < COLUMN_COUNT; ++j)
126 if (j != MESSAGE_COLUMN)
127 addColumn(titles[j]);
131 addLastColumn(titles[MESSAGE_COLUMN]);
133 setSorting(mColumn[TIME_COLUMN]);
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);
140 setColumnWidth(mColumn[COLOUR_COLUMN], itemHeight() * 3/4);
141 setColumnWidthMode(mColumn[COLOUR_COLUMN], TQListView::Manual);
146 setColumnWidth(mColumn[TYPE_COLUMN], AlarmListViewItem::typeIconWidth(
this));
147 setColumnWidthMode(mColumn[TYPE_COLUMN], TQListView::Manual);
148 header()->setResizeEnabled(
false, mColumn[TYPE_COLUMN]);
150 mInstanceList.append(
this);
152 mTooltip =
new AlarmListTooltip(viewport());
155 AlarmListView::~AlarmListView()
159 mInstanceList.remove(
this);
165 void AlarmListView::populate()
168 KCal::Event::List events;
169 KCal::Event::List::ConstIterator it;
170 TQDateTime now = TQDateTime::currentDateTime();
176 events = cal->events();
177 for (it = events.begin(); it != events.end(); ++it)
180 if (kcalEvent->
alarms().count() > 0)
182 event.set(*kcalEvent);
183 addEntry(event, now);
188 events = AlarmCalendar::activeCalendar()->events();
189 for (it = events.begin(); it != events.end(); ++it)
192 event.set(*kcalEvent);
193 if (mShowExpired || !event.expired())
194 addEntry(event, now);
201 void AlarmListView::selectTimeColumns(
bool time,
bool timeTo)
203 if (!time && !timeTo)
205 bool changed =
false;
206 int w = columnWidth(mColumn[TIME_COLUMN]);
210 int colWidth = mTimeColumnHeaderWidth;
211 TQFontMetrics fm = fontMetrics();
212 for (AlarmListViewItem* item = firstChild(); item; item = item->nextSibling())
214 int w = item->width(fm,
this, mColumn[TIME_COLUMN]);
218 setColumnWidth(mColumn[TIME_COLUMN], colWidth);
219 setColumnWidthMode(mColumn[TIME_COLUMN], TQListView::Maximum);
225 setColumnWidthMode(mColumn[TIME_COLUMN], TQListView::Manual);
226 setColumnWidth(mColumn[TIME_COLUMN], 0);
229 w = columnWidth(mColumn[TIME_TO_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);
239 else if (!timeTo && w)
242 setColumnWidthMode(mColumn[TIME_TO_COLUMN], TQListView::Manual);
243 setColumnWidth(mColumn[TIME_TO_COLUMN], 0);
256 void AlarmListView::updateTimeToAlarms(
bool forceDisplay)
258 if (forceDisplay || columnWidth(mColumn[TIME_TO_COLUMN]))
260 TQDateTime now = TQDateTime::currentDateTime();
261 for (AlarmListViewItem* item = firstChild(); item; item = item->nextSibling())
262 item->updateTimeToAlarm(now, forceDisplay);
270 void AlarmListView::addEvent(
const KAEvent& event, EventListViewBase* view)
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));
280 AlarmListViewItem* AlarmListView::addEntry(
const KAEvent& event,
const TQDateTime& now,
bool setSize,
bool reselect)
282 if (!mShowExpired && event.expired())
284 AlarmListViewItem* item =
new AlarmListViewItem(
this, event, now);
285 return static_cast<AlarmListViewItem*
>(EventListViewBase::addEntry(item, setSize, reselect));
291 EventListViewItemBase* AlarmListView::createItem(
const KAEvent& event)
293 return new AlarmListViewItem(
this, event, TQDateTime::currentDateTime());
299 bool AlarmListView::expired(AlarmListViewItem* item)
const
301 return item->event().expired();
307 TQValueList<int> AlarmListView::columnOrder()
const
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];
326 TQString AlarmListView::whatsThisText(
int column)
const
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");
348 void AlarmListView::contentsMousePressEvent(TQMouseEvent* e)
350 TQListView::contentsMousePressEvent(e);
351 if (e->button() == TQt::LeftButton)
353 TQPoint p(contentsToViewport(e->pos()));
356 mMousePressPos = e->pos();
357 mMousePressed =
true;
367 void AlarmListView::contentsMouseMoveEvent(TQMouseEvent* e)
369 TQListView::contentsMouseMoveEvent(e);
371 && (mMousePressPos - e->pos()).manhattanLength() > TQApplication::startDragDistance())
374 kdDebug(5950) <<
"AlarmListView::contentsMouseMoveEvent(): drag started" << endl;
375 mMousePressed =
false;
378 TQValueList<EventListViewItemBase*> items = selectedItems();
381 for (TQValueList<EventListViewItemBase*>::Iterator it = items.begin(); it != items.end(); ++it)
383 const KAEvent&
event = (*it)->event();
385 event.updateKCalEvent(*kcalEvent,
false,
true);
386 kcalEvent->
setUid(event.id());
387 cal.addEvent(kcalEvent);
402 void AlarmListView::contentsMouseReleaseEvent(TQMouseEvent *e)
404 TQListView::contentsMouseReleaseEvent(e);
405 mMousePressed =
false;
414 int AlarmListViewItem::mTimeHourPos = -2;
415 int AlarmListViewItem::mDigitWidth = -1;
417 AlarmListViewItem::AlarmListViewItem(AlarmListView* parent,
const KAEvent& event,
const TQDateTime& now)
418 : EventListViewItemBase(parent, event),
419 mMessageTruncated(false),
420 mTimeToAlarmShown(false)
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)
429 TQString tta = timeToAlarmText(now);
430 setText(parent->column(AlarmListView::TIME_TO_COLUMN), tta);
431 mTimeToAlarmShown = !tta.isNull();
433 TQTime t = dateTime.time();
434 mDateTimeOrder.sprintf(
"%04d%03d%02d%02d", dateTime.date().year(), dateTime.date().dayOfYear(),
435 t.hour(), t.minute());
438 int repeatInterval = 0;
439 TQString repeatText =
event.recurrenceText(
true);
440 if (repeatText.isEmpty())
441 repeatText =
event.repetitionText(
true);
442 if (event.repeatAtLogin())
446 repeatInterval =
event.recurInterval();
447 switch (event.recurType())
449 case KARecurrence::MINUTELY:
452 case KARecurrence::DAILY:
455 case KARecurrence::WEEKLY:
458 case KARecurrence::MONTHLY_DAY:
459 case KARecurrence::MONTHLY_POS:
462 case KARecurrence::ANNUAL_DATE:
463 case KARecurrence::ANNUAL_POS:
466 case KARecurrence::NO_RECUR:
471 setText(parent->column(AlarmListView::REPEAT_COLUMN), repeatText);
472 mRepeatOrder.sprintf(
"%c%08d",
'0' + repeatOrder, repeatInterval);
474 bool showColour = (
event.action() == KAEvent::MESSAGE ||
event.action() == KAEvent::FILE);
475 mColourOrder.sprintf(
"%06u", (showColour ? event.bgColour().rgb() : 0));
477 mTypeOrder.sprintf(
"%02d", event.action());
483 TQString AlarmListViewItem::alarmText(
const KAEvent& event)
const
486 TQString text = AlarmText::summary(event, 1, &truncated);
487 mMessageTruncated = truncated;
494 TQString AlarmListViewItem::alarmTimeText(
const DateTime& dateTime)
const
496 TDELocale* locale = TDEGlobal::locale();
497 TQString dateTimeText = locale->formatDate(dateTime.date(),
true);
498 if (!dateTime.isDateOnly())
501 TQString time = locale->formatTime(dateTime.time());
502 if (mTimeHourPos == -2)
507 if (!TQApplication::reverseLayout())
509 TQString fmt = locale->timeFormat();
510 int i = fmt.find(TQRegExp(
"%[kl]"));
511 if (i >= 0 && i == fmt.find(
'%'))
515 if (mTimeHourPos >= 0 && (
int)time.length() > mTimeHourPos + 1
516 && time[mTimeHourPos].isDigit() && !time[mTimeHourPos + 1].isDigit())
518 dateTimeText += time;
520 return dateTimeText +
' ';
526 TQString AlarmListViewItem::timeToAlarmText(
const TQDateTime& now)
const
528 if (event().expired())
530 DateTime dateTime = event().displayDateTime();
531 if (dateTime.isDateOnly())
533 int days = now.date().daysTo(dateTime.date());
534 return i18n(
"n days",
" %1d ").arg(days);
536 int mins = (now.secsTo(dateTime.dateTime()) + 59) / 60;
539 char minutes[3] =
"00";
540 minutes[0] = (mins%60) / 10 +
'0';
541 minutes[1] = (mins%60) % 10 +
'0';
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);
554 void AlarmListViewItem::updateTimeToAlarm(
const TQDateTime& now,
bool forceDisplay)
556 if (event().expired())
558 if (forceDisplay || mTimeToAlarmShown)
560 setText(alarmListView()->column(AlarmListView::TIME_TO_COLUMN), TQString());
561 mTimeToAlarmShown =
false;
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();
576 void AlarmListViewItem::paintCell(TQPainter* painter,
const TQColorGroup& cg,
int column,
int width,
int )
578 const AlarmListView* listView = alarmListView();
579 int margin = listView->itemMargin();
580 TQRect box(margin, margin, width - margin*2, height() - margin*2);
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);
589 if (column == listView->column(AlarmListView::TIME_COLUMN))
592 TQString str = text(column);
593 if (mTimeHourPos >= 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));
609 painter->drawText(box, AlignVCenter, str);
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))
618 if (event().action() == KAEvent::MESSAGE || event().action() == KAEvent::FILE)
619 painter->fillRect(box, event().bgColour());
621 else if (column == listView->column(AlarmListView::TYPE_COLUMN))
624 TQPixmap* pixmap = eventIcon();
625 TQRect pixmapRect = pixmap->rect();
626 int diff = box.height() - pixmap->height();
629 pixmapRect.setTop(-diff / 2);
630 pixmapRect.setHeight(box.height());
632 TQPoint iconTopLeft(box.left() + (box.width() - pixmapRect.width()) / 2,
633 box.top() + (diff > 0 ? diff / 2 : 0));
634 painter->drawPixmap(iconTopLeft, *pixmap, pixmapRect);
636 else if (column == listView->column(AlarmListView::MESSAGE_COLUMN))
638 if (!selected && listView->drawMessageInColour())
640 painter->fillRect(box, event().bgColour());
641 painter->setBackgroundColor(event().bgColour());
644 TQString txt = text(column);
645 painter->drawText(box, AlignVCenter, txt);
646 mMessageColWidth = listView->fontMetrics().boundingRect(txt).width();
653 int AlarmListViewItem::typeIconWidth(AlarmListView* v)
655 return iconWidth() + 2 * v->style().pixelMetric(TQStyle::PM_DefaultFrameWidth);
661 TQString AlarmListViewItem::key(
int column,
bool)
const
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))
669 if (column == listView->column(AlarmListView::COLOUR_COLUMN))
671 if (column == listView->column(AlarmListView::TYPE_COLUMN))
673 return text(column).lower();
685 void AlarmListTooltip::maybeTip(
const TQPoint& pt)
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)
692 AlarmListViewItem* item = (AlarmListViewItem*)listView->itemAt(pt);
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)
700 if (columnX + widthNeeded <= listView->viewport()->width())
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));
Provides read and write access to calendar files.
KAEvent corresponds to a KCal::Event instance.
void setUid(const TQString &)
const Alarm::List & alarms() const
the KAlarm application object