eventlistview.cpp 8.02 KB
Newer Older
David Jarvie's avatar
David Jarvie committed
1
/*
2
 *  eventlistview.cpp  -  base class for widget showing list of alarms
David Jarvie's avatar
David Jarvie committed
3
 *  Program:  kalarm
David Jarvie's avatar
David Jarvie committed
4
 *  Copyright © 2007-2013 by David Jarvie <djarvie@kde.org>
David Jarvie's avatar
David Jarvie committed
5 6 7 8 9 10 11 12 13 14 15
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
David Jarvie's avatar
David Jarvie committed
16 17 18
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
David Jarvie's avatar
David Jarvie committed
19 20 21
 */

#include "kalarm.h"
Laurent Montel's avatar
Laurent Montel committed
22
#include "eventlistview.h"
David Jarvie's avatar
David Jarvie committed
23

24
#include "find.h"
David Jarvie's avatar
David Jarvie committed
25

26
#include <kglobalsettings.h>
27
#include <KLocalizedString>
David Jarvie's avatar
David Jarvie committed
28

29 30 31
#include <QMouseEvent>
#include <QToolTip>
#include <QApplication>
Laurent Montel's avatar
Laurent Montel committed
32
#include "kalarm_debug.h"
David Jarvie's avatar
David Jarvie committed
33 34


35
EventListView::EventListView(QWidget* parent)
36
    : QTreeView(parent),
Laurent Montel's avatar
Laurent Montel committed
37
      mFind(Q_NULLPTR),
David Jarvie's avatar
David Jarvie committed
38
      mEditOnSingleClick(false)
David Jarvie's avatar
David Jarvie committed
39
{
40 41 42 43 44 45 46 47
    setRootIsDecorated(false);    // don't show expander icons for child-less items
    setSortingEnabled(true);
    setAllColumnsShowFocus(true);
    setSelectionMode(ExtendedSelection);
    setSelectionBehavior(SelectRows);
    setTextElideMode(Qt::ElideRight);
    // Set default WhatsThis text to be displayed when no actual item is clicked on
    setWhatsThis(i18nc("@info:whatsthis", "List of scheduled alarms"));
David Jarvie's avatar
David Jarvie committed
48 49
}

50 51 52
/******************************************************************************
* Return the event referred to by an index.
*/
53 54
KAEvent EventListView::event(const QModelIndex& index) const
{
55
    return itemModel()->event(index);
56 57 58 59
}

KAEvent EventListView::event(int row) const
{
60
    return itemModel()->event(itemModel()->index(row, 0));
61
}
62

David Jarvie's avatar
David Jarvie committed
63
/******************************************************************************
64
* Select one event and make it the current item.
David Jarvie's avatar
David Jarvie committed
65
*/
66 67
void EventListView::select(Akonadi::Item::Id eventId)
{
68
    select(itemModel()->eventIndex(eventId));
69
}
David Jarvie's avatar
David Jarvie committed
70

71
void EventListView::select(const QModelIndex& index, bool scrollToIndex)
David Jarvie's avatar
David Jarvie committed
72
{
73
    selectionModel()->select(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
74 75
    if (scrollToIndex)
        scrollTo(index);
David Jarvie's avatar
David Jarvie committed
76 77
}

78 79 80 81 82
void EventListView::clearSelection()
{
    selectionModel()->clearSelection();
}

David Jarvie's avatar
David Jarvie committed
83
/******************************************************************************
84 85
* Return the single selected item.
* Reply = invalid if no items are selected, or if multiple items are selected.
David Jarvie's avatar
David Jarvie committed
86
*/
87
QModelIndex EventListView::selectedIndex() const
David Jarvie's avatar
David Jarvie committed
88
{
89 90 91 92
    QModelIndexList list = selectionModel()->selectedRows();
    if (list.count() != 1)
        return QModelIndex();
    return list[0];
David Jarvie's avatar
David Jarvie committed
93 94 95
}

/******************************************************************************
96 97
* Return the single selected event.
* Reply = null if no items are selected, or if multiple items are selected.
David Jarvie's avatar
David Jarvie committed
98
*/
99 100
KAEvent EventListView::selectedEvent() const
{
101 102 103
    QModelIndexList list = selectionModel()->selectedRows();
    if (list.count() != 1)
        return KAEvent();
Laurent Montel's avatar
Laurent Montel committed
104
qCDebug(KALARM_LOG)<<"SelectedEvent() count="<<list.count();
105 106
    const ItemListModel* model = static_cast<const ItemListModel*>(list[0].model());
    return model->event(list[0]);
107
}
108

David Jarvie's avatar
David Jarvie committed
109
/******************************************************************************
110
* Return the selected events.
David Jarvie's avatar
David Jarvie committed
111
*/
112
QVector<KAEvent> EventListView::selectedEvents() const
David Jarvie's avatar
David Jarvie committed
113
{
114
    QVector<KAEvent> elist;
115 116 117 118 119
    QModelIndexList ixlist = selectionModel()->selectedRows();
    int count = ixlist.count();
    if (count)
    {
        const ItemListModel* model = static_cast<const ItemListModel*>(ixlist[0].model());
Laurent Montel's avatar
Laurent Montel committed
120
        elist.reserve(count);
121 122 123 124
        for (int i = 0;  i < count;  ++i)
            elist += model->event(ixlist[i]);
    }
    return elist;
David Jarvie's avatar
David Jarvie committed
125 126
}

David Jarvie's avatar
David Jarvie committed
127
/******************************************************************************
David Jarvie's avatar
David Jarvie committed
128 129
* Called when the Find action is selected.
* Display the non-modal Find dialog.
David Jarvie's avatar
David Jarvie committed
130 131 132
*/
void EventListView::slotFind()
{
133 134 135
    if (!mFind)
    {
        mFind = new Find(this);
Laurent Montel's avatar
Laurent Montel committed
136
        connect(mFind, &Find::active, this, &EventListView::findActive);
137 138
    }
    mFind->display();
David Jarvie's avatar
David Jarvie committed
139 140 141
}

/******************************************************************************
David Jarvie's avatar
David Jarvie committed
142
* Called when the Find Next or Find Prev action is selected.
David Jarvie's avatar
David Jarvie committed
143 144 145
*/
void EventListView::findNext(bool forward)
{
146 147
    if (mFind)
        mFind->findNext(forward);
David Jarvie's avatar
David Jarvie committed
148 149
}

David Jarvie's avatar
David Jarvie committed
150
/******************************************************************************
151 152
* Called when a ToolTip or WhatsThis event occurs.
*/
David Jarvie's avatar
David Jarvie committed
153 154
bool EventListView::viewportEvent(QEvent* e)
{
155 156 157 158 159 160 161 162
    if (e->type() == QEvent::ToolTip  &&  isActiveWindow())
    {
        QHelpEvent* he = static_cast<QHelpEvent*>(e);
        QModelIndex index = indexAt(he->pos());
        QVariant value = model()->data(index, Qt::ToolTipRole);
        if (qVariantCanConvert<QString>(value))
        {
            QString toolTip = value.toString();
Laurent Montel's avatar
Laurent Montel committed
163
            int i = toolTip.indexOf(QLatin1Char('\n'));
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
            if (i < 0)
            {
                ItemListModel* m = qobject_cast<ItemListModel*>(model());
                if (!m  ||  m->event(index).commandError() == KAEvent::CMD_NO_ERROR)
                {
                    // Single line tooltip. Only display it if the text column
                    // is truncated in the view display.
                    value = model()->data(index, Qt::FontRole);
                    QFontMetrics fm(qvariant_cast<QFont>(value).resolve(viewOptions().font));
                    int textWidth = fm.boundingRect(toolTip).width() + 1;
                    const int margin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
                    int left = columnViewportPosition(index.column()) + margin;
                    int right = left + textWidth;
                    if (left >= 0  &&  right <= width() - 2*frameWidth())
                        toolTip.clear();    // prevent any tooltip showing
                }
            }
            QToolTip::showText(he->globalPos(), toolTip, this);
            return true;
        }
    }
    return QTreeView::viewportEvent(e);
David Jarvie's avatar
David Jarvie committed
186 187
}

David Jarvie's avatar
David Jarvie committed
188
/******************************************************************************
David Jarvie's avatar
David Jarvie committed
189
* Called when a context menu event is requested by mouse or key.
David Jarvie's avatar
David Jarvie committed
190
*/
David Jarvie's avatar
David Jarvie committed
191
void EventListView::contextMenuEvent(QContextMenuEvent* e)
David Jarvie's avatar
David Jarvie committed
192
{
Laurent Montel's avatar
Laurent Montel committed
193
    Q_EMIT contextMenuRequested(e->globalPos());
194
}
195 196 197 198


bool EventListDelegate::editorEvent(QEvent* e, QAbstractItemModel* model, const QStyleOptionViewItem&, const QModelIndex& index)
{
199 200 201 202 203 204 205 206 207 208 209 210
    // Don't invoke the editor unless it's either a double click or,
    // if KDE is in single click mode and it's a left button release
    // with no other buttons pressed and no keyboard modifiers.
    switch (e->type())
    {
        case QEvent::MouseButtonPress:
        case QEvent::MouseMove:
            return false;
        case QEvent::MouseButtonDblClick:
            break;
        case QEvent::MouseButtonRelease:
        {
David Jarvie's avatar
David Jarvie committed
211 212 213
            EventListView* view = static_cast<EventListView*>(parent());
            if (!view->editOnSingleClick()
            ||  !view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, Q_NULLPTR, view))
214 215 216 217 218 219 220 221 222 223 224 225
                return false;
            QMouseEvent* me = static_cast<QMouseEvent*>(e);
            if (me->button() != Qt::LeftButton  ||  me->buttons()
            ||  me->modifiers() != Qt::NoModifier)
                return false;
            break;
        }
        default:
            break;
    }
    if (index.isValid())
    {
Laurent Montel's avatar
Laurent Montel committed
226
        qCDebug(KALARM_LOG);
227 228
        ItemListModel* itemModel = qobject_cast<ItemListModel*>(model);
        if (!itemModel)
Laurent Montel's avatar
Laurent Montel committed
229
            qCCritical(KALARM_LOG) << "Invalid cast to ItemListModel*";
230 231 232 233 234 235 236 237 238
        else
        {
            KAEvent event = itemModel->event(index);
            edit(&event, static_cast<EventListView*>(parent()));
            return true;
        }
    }
    return false;   // indicate that the event has not been handled
}    
Laurent Montel's avatar
Laurent Montel committed
239

240
// vim: et sw=4: