00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kalarm.h"
00022
00023 #include <qwhatsthis.h>
00024 #include <qheader.h>
00025 #include <qpainter.h>
00026 #include <qstyle.h>
00027
00028 #include <kglobal.h>
00029 #include <klocale.h>
00030 #include <klistview.h>
00031 #include <kiconloader.h>
00032 #include <kdebug.h>
00033
00034 #include "kalarmapp.h"
00035 #include "alarmcalendar.h"
00036 #include "alarmlistview.moc"
00037
00038
00039 class AlarmListWhatsThis : public QWhatsThis
00040 {
00041 public:
00042 AlarmListWhatsThis(AlarmListView* lv) : QWhatsThis(lv), listView(lv) { }
00043 virtual QString text(const QPoint&);
00044 private:
00045 AlarmListView* listView;
00046 };
00047
00048
00049
00050
00051
00052
00053
00054 AlarmListView::AlarmListView(QWidget* parent, const char* name)
00055 : KListView(parent, name),
00056 drawMessageInColour_(false)
00057 {
00058 addColumn(i18n("Time"));
00059 addColumn(i18n("Repeat"));
00060 addColumn(QString::null);
00061 addColumn(i18n("Message, File or Command"));
00062 setColumnWidthMode(MESSAGE_COLUMN, QListView::Maximum);
00063 setAllColumnsShowFocus(true);
00064 setSorting(TIME_COLUMN);
00065 setShowSortIndicator(true);
00066 lastColumnHeaderWidth_ = columnWidth(MESSAGE_COLUMN);
00067 setColumnAlignment(REPEAT_COLUMN, Qt::AlignHCenter);
00068 setColumnWidthMode(REPEAT_COLUMN, QListView::Manual);
00069
00070
00071 setColumnWidth(COLOUR_COLUMN, itemHeight() * 3/4);
00072 setColumnWidthMode(COLOUR_COLUMN, QListView::Manual);
00073 new AlarmListWhatsThis(this);
00074 }
00075
00076 void AlarmListView::clear()
00077 {
00078 entries.clear();
00079 KListView::clear();
00080 }
00081
00082
00083
00084
00085 void AlarmListView::refresh()
00086 {
00087 QPtrList<Event> events = theApp()->getCalendar().events();
00088 clear();
00089 KAlarmEvent event;
00090 for (Event* kcalEvent = events.first(); kcalEvent; kcalEvent = events.next())
00091 {
00092 event.set(*kcalEvent);
00093 addEntry(event);
00094 }
00095 resizeLastColumn();
00096 }
00097
00098 AlarmListViewItem* AlarmListView::getEntry(const QString& eventID)
00099 {
00100 for (EntryMap::ConstIterator it = entries.begin(); it != entries.end(); ++it)
00101 if (it.data().event.id() == eventID)
00102 return it.key();
00103 return 0L;
00104 }
00105
00106 AlarmListViewItem* AlarmListView::addEntry(const KAlarmEvent& event, bool setSize)
00107 {
00108 QDateTime dateTime = event.dateTime();
00109 AlarmItemData data;
00110 data.event = event;
00111 data.messageText = event.cleanText();
00112 int newline = data.messageText.find('\n');
00113 if (newline >= 0)
00114 data.messageText = data.messageText.left(newline) + QString::fromLatin1("...");
00115 data.dateTimeText = KGlobal::locale()->formatDate(dateTime.date(), true);
00116 if (!event.anyTime())
00117 {
00118 data.dateTimeText += ' ';
00119 data.dateTimeText += KGlobal::locale()->formatTime(dateTime.time()) + ' ';
00120 }
00121 QString dateTimeOrder;
00122 dateTimeOrder.sprintf("%04d%03d%02d%02d", dateTime.date().year(), dateTime.date().dayOfYear(),
00123 dateTime.time().hour(), dateTime.time().minute());
00124
00125 int repeatOrder = 0;
00126 int repeatInterval = 0;
00127 data.repeatText = QString();
00128 if (event.repeatAtLogin())
00129 {
00130 repeatOrder = 1;
00131 data.repeatText = i18n("Login");
00132 }
00133 else
00134 {
00135 repeatInterval = event.recurInterval();
00136 switch (event.recurs())
00137 {
00138 case KAlarmEvent::MINUTELY:
00139 repeatOrder = 2;
00140 if (repeatInterval < 60)
00141 {
00142 data.repeatText = i18n("1 Minute", "%n Minutes", repeatInterval);
00143 }
00144 else if (repeatInterval % 60 == 0)
00145 {
00146 data.repeatText = i18n("1 Hour", "%n Hours", repeatInterval/60);
00147 }
00148 else
00149 {
00150 QString mins;
00151 data.repeatText = i18n("Hours and Minutes", "%1H %2M").arg(QString::number(repeatInterval/60)).arg(mins.sprintf("%02d", repeatInterval%60));
00152 }
00153 break;
00154 case KAlarmEvent::DAILY:
00155 repeatOrder = 3;
00156 data.repeatText = i18n("1 Day","%n Days",repeatInterval);
00157 break;
00158 case KAlarmEvent::WEEKLY:
00159 repeatOrder = 4;
00160 data.repeatText = i18n("1 Week","%n Weeks",repeatInterval);
00161 break;
00162 case KAlarmEvent::MONTHLY_DAY:
00163 case KAlarmEvent::MONTHLY_POS:
00164 repeatOrder = 5;
00165 data.repeatText = i18n("1 Month","%n Months",repeatInterval);
00166 break;
00167 case KAlarmEvent::ANNUAL_DATE:
00168 case KAlarmEvent::ANNUAL_POS:
00169 case KAlarmEvent::ANNUAL_DAY:
00170 repeatOrder = 6;
00171 data.repeatText = i18n("1 Year","%n Years",repeatInterval);
00172 break;
00173 case KAlarmEvent::NO_RECUR:
00174 default:
00175 break;
00176 }
00177 }
00178
00179
00180 AlarmListViewItem* item = new AlarmListViewItem(this, data.dateTimeText, data.messageText);
00181 data.messageWidth = item->width(fontMetrics(), this, MESSAGE_COLUMN);
00182 setColumnWidthMode(REPEAT_COLUMN, QListView::Maximum);
00183 item->setText(REPEAT_COLUMN, data.repeatText);
00184 setColumnWidthMode(REPEAT_COLUMN, QListView::Manual);
00185
00186
00187
00188 item->setText(TIME_COLUMN, dateTimeOrder);
00189 item->setText(REPEAT_COLUMN, QString().sprintf("%c%08d", '0' + repeatOrder, repeatInterval));
00190 item->setText(COLOUR_COLUMN, QString().sprintf("%06u", (event.type() == KAlarmAlarm::COMMAND ? 0 : event.colour().rgb())));
00191 item->setText(MESSAGE_COLUMN, data.messageText.lower());
00192 entries[item] = data;
00193 if (setSize)
00194 resizeLastColumn();
00195 return item;
00196 }
00197
00198 AlarmListViewItem* AlarmListView::updateEntry(AlarmListViewItem* item, const KAlarmEvent& newEvent, bool setSize)
00199 {
00200 deleteEntry(item);
00201 return addEntry(newEvent, setSize);
00202 }
00203
00204 void AlarmListView::deleteEntry(AlarmListViewItem* item, bool setSize)
00205 {
00206 EntryMap::Iterator it = entries.find(item);
00207 if (it != entries.end())
00208 {
00209 entries.remove(it);
00210 delete item;
00211 if (setSize)
00212 resizeLastColumn();
00213 emit itemDeleted();
00214 }
00215 }
00216
00217 const AlarmItemData* AlarmListView::getData(AlarmListViewItem* item) const
00218 {
00219 EntryMap::ConstIterator it = entries.find(item);
00220 if (it == entries.end())
00221 return 0L;
00222 return &it.data();
00223 }
00224
00225
00226
00227
00228
00229 void AlarmListView::resizeLastColumn()
00230 {
00231 int messageWidth = lastColumnHeaderWidth_;
00232 for (EntryMap::ConstIterator it = entries.begin(); it != entries.end(); ++it)
00233 {
00234 int mw = it.data().messageWidth;
00235 if (mw > messageWidth)
00236 messageWidth = mw;
00237 }
00238 int x = header()->sectionPos(AlarmListView::MESSAGE_COLUMN);
00239 int width = visibleWidth();
00240 width -= x;
00241 if (width < messageWidth)
00242 width = messageWidth;
00243 setColumnWidth(AlarmListView::MESSAGE_COLUMN, width);
00244 if (contentsWidth() > x + width)
00245 resizeContents(x + width, contentsHeight());
00246 }
00247
00248 int AlarmListView::itemHeight()
00249 {
00250 EntryMap::ConstIterator it = entries.begin();
00251 if (it == entries.end())
00252 {
00253
00254 QListViewItem* item = new QListViewItem(this, QString::null);
00255 int height = item->height();
00256 delete item;
00257 return height;
00258 }
00259 else
00260 return it.key()->height();
00261 }
00262
00263
00264
00265
00266
00267 QPixmap* AlarmListViewItem::textIcon;
00268 QPixmap* AlarmListViewItem::fileIcon;
00269 QPixmap* AlarmListViewItem::commandIcon;
00270
00271 AlarmListViewItem::AlarmListViewItem(QListView* parent, const QString& dateTime, const QString& message)
00272 : QListViewItem(parent, dateTime, QString(), message)
00273 {
00274 }
00275
00276 void AlarmListViewItem::paintCell(QPainter* painter, const QColorGroup& cg, int column, int width, int )
00277 {
00278 const AlarmListView* listView = alarmListView();
00279 const AlarmItemData* data = listView->getData(this);
00280 int margin = listView->itemMargin();
00281 QRect box (margin, margin, width - margin*2, height() - margin*2);
00282 bool selected = isSelected();
00283 QColor bgColour = selected ? cg.highlight() : cg.base();
00284 painter->setPen(selected ? cg.highlightedText() : cg.text());
00285 painter->fillRect(0, 0, width, height(), bgColour);
00286 switch (column)
00287 {
00288 case AlarmListView::TIME_COLUMN:
00289 painter->drawText(box, AlignVCenter, data->dateTimeText);
00290 break;
00291 case AlarmListView::REPEAT_COLUMN:
00292 painter->drawText(box, AlignVCenter | AlignHCenter, data->repeatText);
00293 break;
00294 case AlarmListView::COLOUR_COLUMN:
00295
00296 if (data->event.type() == KAlarmAlarm::MESSAGE || data->event.type() == KAlarmAlarm::FILE)
00297 painter->fillRect(box, data->event.colour());
00298 break;
00299 case AlarmListView::MESSAGE_COLUMN:
00300 {
00301 QPixmap* pixmap;
00302 switch (data->event.type())
00303 {
00304 case KAlarmAlarm::FILE:
00305 if (!fileIcon)
00306 fileIcon = new QPixmap(SmallIcon("file"));
00307 pixmap = fileIcon;
00308 break;
00309 case KAlarmAlarm::COMMAND:
00310 if (!commandIcon)
00311 commandIcon = new QPixmap(SmallIcon("exec"));
00312 pixmap = commandIcon;
00313 break;
00314 case KAlarmAlarm::MESSAGE:
00315 default:
00316 if (!textIcon)
00317 textIcon = new QPixmap(SmallIcon("message"));
00318 pixmap = textIcon;
00319 break;
00320 }
00321 int diff = box.height() - pixmap->height();
00322 QRect pixmapRect = pixmap->rect();
00323 if (diff < 0)
00324 {
00325 pixmapRect.setTop(-diff / 2);
00326 pixmapRect.setHeight(box.height());
00327 }
00328 QRect iconRect(box.left(), box.top() + (diff > 0 ? diff / 2 : 0), pixmap->width(), (diff > 0 ? pixmap->height() : box.height()));
00329 QRect textRect = box;
00330 textRect.setLeft(box.left() + pixmap->width() + 2*listView->style().defaultFrameWidth());
00331 if (!selected && listView->drawMessageInColour())
00332 {
00333 QColor colour = data->event.colour();
00334 painter->fillRect(box, colour);
00335 painter->setBackgroundColor(colour);
00336
00337 }
00338 painter->drawPixmap(iconRect.topLeft(), *pixmap, pixmapRect);
00339 painter->drawText(textRect, AlignVCenter, data->messageText);
00340 break;
00341 }
00342 }
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 QString AlarmListWhatsThis::text(const QPoint& pt)
00352 {
00353 QRect frame = listView->header()->frameGeometry();
00354 if (frame.contains(pt)
00355 || listView->itemAt(QPoint(listView->itemMargin(), pt.y())) && frame.contains(QPoint(pt.x(), frame.y())))
00356 {
00357 switch (listView->header()->sectionAt(pt.x()))
00358 {
00359 case AlarmListView::TIME_COLUMN: return i18n("Next scheduled date and time of the alarm");
00360 case AlarmListView::COLOUR_COLUMN: return i18n("Background color of alarm message");
00361 case AlarmListView::MESSAGE_COLUMN: return i18n("Alarm message text, URL of text file to display, or command to execute. The alarm type is indicated by the icon at the left.");
00362 case AlarmListView::REPEAT_COLUMN: return i18n("The alarm's repetition type or recurrence interval.");
00363 }
00364 }
00365 return i18n("List of scheduled alarms");
00366 }
00367