SVN_SILENT made messages (.desktop file)
[kdepim.git] / kalarm / eventlistview.cpp
blob796f57101892695955a6eca5825124f8e52bf465
1 /*
2 * eventlistview.cpp - base class for widget showing list of alarms
3 * Program: kalarm
4 * Copyright © 2007-2013 by David Jarvie <djarvie@kde.org>
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.
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.
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.
21 #include "kalarm.h"
22 #include "eventlistview.moc"
24 #include "find.h"
25 #ifndef USE_AKONADI
26 #include "eventlistmodel.h"
27 #include "templatelistfiltermodel.h"
28 #endif
30 #include <kglobalsettings.h>
31 #include <klocale.h>
32 #include <kdebug.h>
34 #include <QHeaderView>
35 #include <QMouseEvent>
36 #include <QToolTip>
37 #include <QApplication>
40 EventListView::EventListView(QWidget* parent)
41 : QTreeView(parent),
42 mFind(0),
43 mEditOnSingleClick(false)
45 setRootIsDecorated(false); // don't show expander icons for child-less items
46 setSortingEnabled(true);
47 setAllColumnsShowFocus(true);
48 setSelectionMode(ExtendedSelection);
49 setSelectionBehavior(SelectRows);
50 setTextElideMode(Qt::ElideRight);
51 // Set default WhatsThis text to be displayed when no actual item is clicked on
52 setWhatsThis(i18nc("@info:whatsthis", "List of scheduled alarms"));
55 /******************************************************************************
56 * Return the event referred to by an index.
58 #ifdef USE_AKONADI
59 KAEvent EventListView::event(const QModelIndex& index) const
61 return itemModel()->event(index);
64 KAEvent EventListView::event(int row) const
66 return itemModel()->event(itemModel()->index(row, 0));
68 #else
69 KAEvent* EventListView::event(const QModelIndex& index) const
71 return eventFilterModel()->event(index);
74 KAEvent* EventListView::event(int row) const
76 return eventFilterModel()->event(row);
78 #endif
80 /******************************************************************************
81 * Select one event and make it the current item.
83 #ifdef USE_AKONADI
84 void EventListView::select(Akonadi::Item::Id eventId)
86 select(itemModel()->eventIndex(eventId));
88 #else
89 void EventListView::select(const QString& eventId, bool scrollToEvent)
91 select(eventFilterModel()->eventIndex(eventId), scrollToEvent);
93 #endif
95 void EventListView::select(const QModelIndex& index, bool scrollToIndex)
97 selectionModel()->select(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
98 if (scrollToIndex)
99 scrollTo(index);
102 void EventListView::clearSelection()
104 selectionModel()->clearSelection();
107 /******************************************************************************
108 * Return the single selected item.
109 * Reply = invalid if no items are selected, or if multiple items are selected.
111 QModelIndex EventListView::selectedIndex() const
113 QModelIndexList list = selectionModel()->selectedRows();
114 if (list.count() != 1)
115 return QModelIndex();
116 return list[0];
119 /******************************************************************************
120 * Return the single selected event.
121 * Reply = null if no items are selected, or if multiple items are selected.
123 #ifdef USE_AKONADI
124 KAEvent EventListView::selectedEvent() const
126 QModelIndexList list = selectionModel()->selectedRows();
127 if (list.count() != 1)
128 return KAEvent();
129 kDebug(0)<<"SelectedEvent() count="<<list.count();
130 const ItemListModel* model = static_cast<const ItemListModel*>(list[0].model());
131 return model->event(list[0]);
133 #else
134 KAEvent* EventListView::selectedEvent() const
136 QModelIndexList list = selectionModel()->selectedRows();
137 if (list.count() != 1)
138 return 0;
139 kDebug(0)<<"SelectedEvent() count="<<list.count();
140 const QAbstractProxyModel* proxy = static_cast<const QAbstractProxyModel*>(list[0].model());
141 QModelIndex source = proxy->mapToSource(list[0]);
142 return static_cast<KAEvent*>(source.internalPointer());
144 #endif
146 /******************************************************************************
147 * Return the selected events.
149 #ifdef USE_AKONADI
150 QVector<KAEvent> EventListView::selectedEvents() const
151 #else
152 KAEvent::List EventListView::selectedEvents() const
153 #endif
155 #ifdef USE_AKONADI
156 QVector<KAEvent> elist;
157 #else
158 KAEvent::List elist;
159 #endif
160 QModelIndexList ixlist = selectionModel()->selectedRows();
161 int count = ixlist.count();
162 if (count)
164 #ifdef USE_AKONADI
165 const ItemListModel* model = static_cast<const ItemListModel*>(ixlist[0].model());
166 for (int i = 0; i < count; ++i)
167 elist += model->event(ixlist[i]);
168 #else
169 const QAbstractProxyModel* proxy = static_cast<const QAbstractProxyModel*>(ixlist[0].model());
170 for (int i = 0; i < count; ++i)
172 QModelIndex source = proxy->mapToSource(ixlist[i]);
173 elist += static_cast<KAEvent*>(source.internalPointer());
175 #endif
177 return elist;
180 /******************************************************************************
181 * Called when the Find action is selected.
182 * Display the non-modal Find dialog.
184 void EventListView::slotFind()
186 if (!mFind)
188 mFind = new Find(this);
189 connect(mFind, SIGNAL(active(bool)), SIGNAL(findActive(bool)));
191 mFind->display();
194 /******************************************************************************
195 * Called when the Find Next or Find Prev action is selected.
197 void EventListView::findNext(bool forward)
199 if (mFind)
200 mFind->findNext(forward);
203 /******************************************************************************
204 * Called when a ToolTip or WhatsThis event occurs.
206 bool EventListView::viewportEvent(QEvent* e)
208 if (e->type() == QEvent::ToolTip && isActiveWindow())
210 QHelpEvent* he = static_cast<QHelpEvent*>(e);
211 QModelIndex index = indexAt(he->pos());
212 QVariant value = model()->data(index, Qt::ToolTipRole);
213 if (qVariantCanConvert<QString>(value))
215 QString toolTip = value.toString();
216 int i = toolTip.indexOf(QLatin1Char('\n'));
217 if (i < 0)
219 #ifdef USE_AKONADI
220 ItemListModel* m = qobject_cast<ItemListModel*>(model());
221 if (!m || m->event(index).commandError() == KAEvent::CMD_NO_ERROR)
222 #else
223 EventListFilterModel* m = qobject_cast<EventListFilterModel*>(model());
224 if (!m || m->event(index)->commandError() == KAEvent::CMD_NO_ERROR)
225 #endif
227 // Single line tooltip. Only display it if the text column
228 // is truncated in the view display.
229 value = model()->data(index, Qt::FontRole);
230 QFontMetrics fm(qvariant_cast<QFont>(value).resolve(viewOptions().font));
231 int textWidth = fm.boundingRect(toolTip).width() + 1;
232 const int margin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
233 int left = columnViewportPosition(index.column()) + margin;
234 int right = left + textWidth;
235 if (left >= 0 && right <= width() - 2*frameWidth())
236 toolTip.clear(); // prevent any tooltip showing
239 QToolTip::showText(he->globalPos(), toolTip, this);
240 return true;
243 return QTreeView::viewportEvent(e);
246 /******************************************************************************
247 * Called when a context menu event is requested by mouse or key.
249 void EventListView::contextMenuEvent(QContextMenuEvent* e)
251 emit contextMenuRequested(e->globalPos());
255 bool EventListDelegate::editorEvent(QEvent* e, QAbstractItemModel* model, const QStyleOptionViewItem&, const QModelIndex& index)
257 // Don't invoke the editor unless it's either a double click or,
258 // if KDE is in single click mode and it's a left button release
259 // with no other buttons pressed and no keyboard modifiers.
260 switch (e->type())
262 case QEvent::MouseButtonPress:
263 case QEvent::MouseMove:
264 return false;
265 case QEvent::MouseButtonDblClick:
266 break;
267 case QEvent::MouseButtonRelease:
269 if (!static_cast<EventListView*>(parent())->editOnSingleClick()
270 || !KGlobalSettings::singleClick())
271 return false;
272 QMouseEvent* me = static_cast<QMouseEvent*>(e);
273 if (me->button() != Qt::LeftButton || me->buttons()
274 || me->modifiers() != Qt::NoModifier)
275 return false;
276 break;
278 default:
279 break;
281 if (index.isValid())
283 kDebug();
284 #ifdef USE_AKONADI
285 ItemListModel* itemModel = qobject_cast<ItemListModel*>(model);
286 if (!itemModel)
287 kError() << "Invalid cast to ItemListModel*";
288 else
290 KAEvent event = itemModel->event(index);
291 edit(&event, static_cast<EventListView*>(parent()));
292 return true;
294 #else
295 QModelIndex source = static_cast<QAbstractProxyModel*>(model)->mapToSource(index);
296 KAEvent* event = static_cast<KAEvent*>(source.internalPointer());
297 edit(event, static_cast<EventListView*>(parent()));
298 return true;
299 #endif
301 return false; // indicate that the event has not been handled
304 // vim: et sw=4: