2 * eventlistview.cpp - base class for widget showing list of alarms
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.
22 #include "eventlistview.moc"
26 #include "eventlistmodel.h"
27 #include "templatelistfiltermodel.h"
30 #include <kglobalsettings.h>
34 #include <QHeaderView>
35 #include <QMouseEvent>
37 #include <QApplication>
40 EventListView::EventListView(QWidget
* parent
)
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.
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));
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
);
80 /******************************************************************************
81 * Select one event and make it the current item.
84 void EventListView::select(Akonadi::Item::Id eventId
)
86 select(itemModel()->eventIndex(eventId
));
89 void EventListView::select(const QString
& eventId
, bool scrollToEvent
)
91 select(eventFilterModel()->eventIndex(eventId
), scrollToEvent
);
95 void EventListView::select(const QModelIndex
& index
, bool scrollToIndex
)
97 selectionModel()->select(index
, QItemSelectionModel::SelectCurrent
| QItemSelectionModel::Rows
);
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();
119 /******************************************************************************
120 * Return the single selected event.
121 * Reply = null if no items are selected, or if multiple items are selected.
124 KAEvent
EventListView::selectedEvent() const
126 QModelIndexList list
= selectionModel()->selectedRows();
127 if (list
.count() != 1)
129 kDebug(0)<<"SelectedEvent() count="<<list
.count();
130 const ItemListModel
* model
= static_cast<const ItemListModel
*>(list
[0].model());
131 return model
->event(list
[0]);
134 KAEvent
* EventListView::selectedEvent() const
136 QModelIndexList list
= selectionModel()->selectedRows();
137 if (list
.count() != 1)
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());
146 /******************************************************************************
147 * Return the selected events.
150 QVector
<KAEvent
> EventListView::selectedEvents() const
152 KAEvent::List
EventListView::selectedEvents() const
156 QVector
<KAEvent
> elist
;
160 QModelIndexList ixlist
= selectionModel()->selectedRows();
161 int count
= ixlist
.count();
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
]);
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());
180 /******************************************************************************
181 * Called when the Find action is selected.
182 * Display the non-modal Find dialog.
184 void EventListView::slotFind()
188 mFind
= new Find(this);
189 connect(mFind
, SIGNAL(active(bool)), SIGNAL(findActive(bool)));
194 /******************************************************************************
195 * Called when the Find Next or Find Prev action is selected.
197 void EventListView::findNext(bool forward
)
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'));
220 ItemListModel
* m
= qobject_cast
<ItemListModel
*>(model());
221 if (!m
|| m
->event(index
).commandError() == KAEvent::CMD_NO_ERROR
)
223 EventListFilterModel
* m
= qobject_cast
<EventListFilterModel
*>(model());
224 if (!m
|| m
->event(index
)->commandError() == KAEvent::CMD_NO_ERROR
)
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);
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.
262 case QEvent::MouseButtonPress
:
263 case QEvent::MouseMove
:
265 case QEvent::MouseButtonDblClick
:
267 case QEvent::MouseButtonRelease
:
269 if (!static_cast<EventListView
*>(parent())->editOnSingleClick()
270 || !KGlobalSettings::singleClick())
272 QMouseEvent
* me
= static_cast<QMouseEvent
*>(e
);
273 if (me
->button() != Qt::LeftButton
|| me
->buttons()
274 || me
->modifiers() != Qt::NoModifier
)
285 ItemListModel
* itemModel
= qobject_cast
<ItemListModel
*>(model
);
287 kError() << "Invalid cast to ItemListModel*";
290 KAEvent event
= itemModel
->event(index
);
291 edit(&event
, static_cast<EventListView
*>(parent()));
295 QModelIndex source
= static_cast<QAbstractProxyModel
*>(model
)->mapToSource(index
);
296 KAEvent
* event
= static_cast<KAEvent
*>(source
.internalPointer());
297 edit(event
, static_cast<EventListView
*>(parent()));
301 return false; // indicate that the event has not been handled