diff --git a/src/views/collectionview/calendardelegate.cpp b/src/views/collectionview/calendardelegate.cpp index 32a77870..fdb38e4d 100644 --- a/src/views/collectionview/calendardelegate.cpp +++ b/src/views/collectionview/calendardelegate.cpp @@ -1,273 +1,278 @@ /* * Copyright (c) 2014 Christian Mollekopf * * 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. * * 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. * * As a special exception, permission is given to link this program * with any edition of Qt, and distribute the resulting executable, * without including the source code for Qt in the source distribution. */ #include "calendardelegate.h" #include #include #include #include #include #include #include #include "korganizer_debug.h" #include "controller.h" StyledCalendarDelegate::StyledCalendarDelegate(QObject *parent) : QStyledItemDelegate(parent) { mPixmap.insert(Enable, KIconLoader::global()->loadIcon(QStringLiteral("bookmarks"), KIconLoader::Small)); mPixmap.insert(RemoveFromList, KIconLoader::global()->loadIcon(QStringLiteral("list-remove"), KIconLoader::Small)); mPixmap.insert(AddToList, KIconLoader::global()->loadIcon(QStringLiteral("list-add"), KIconLoader::Small)); mPixmap.insert(Quickview, KIconLoader::global()->loadIcon(QStringLiteral("quickview"), KIconLoader::Small)); } StyledCalendarDelegate::~StyledCalendarDelegate() { } static QRect enableButtonRect(const QRect &rect, int pos = 1) { //2px border on each side of the icon static int border = 2; const int side = rect.height() - (2 * border); const int offset = side * pos + border * (pos + 1); return rect.adjusted(rect.width() - (offset + side), border, -offset, -border); } static QStyle *style(const QStyleOptionViewItem &option) { QWidget const *widget = nullptr; if (const QStyleOptionViewItem *v3 = qstyleoption_cast(&option)) { widget = v3->widget; } QStyle *style = widget ? widget->style() : QApplication::style(); return style; } static QStyleOptionButton buttonOpt(const QStyleOptionViewItem &opt, const QPixmap &pixmap, int pos = 1) { QStyleOptionButton option; option.icon = pixmap; QRect r = opt.rect; const int h = r.height() - 4; option.rect = enableButtonRect(r, pos); option.state = QStyle::State_Active | QStyle::State_Enabled; option.iconSize = QSize(h, h); return option; } static bool isChildOfPersonCollection(const QModelIndex &index) { QModelIndex parent = index.parent(); while (parent.isValid()) { if (parent.data(NodeTypeRole).toInt() == PersonNodeRole) { return true; } parent = parent.parent(); } return false; } static Akonadi::Collection personCollection(const QModelIndex &index) { QModelIndex parent = index.parent(); while (parent.isValid()) { if (parent.data(NodeTypeRole).toInt() == PersonNodeRole) { return CalendarSupport::collectionFromIndex(parent); } parent = parent.parent(); } return Akonadi::Collection(); } QList StyledCalendarDelegate::getActions(const QStyleOptionViewItem &option, const QModelIndex &index) const { const bool isSearchResult = index.data(IsSearchResultRole).toBool(); const bool hover = option.state & QStyle::State_MouseOver; const Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); Qt::CheckState enabled = static_cast(index.data(EnabledRole).toInt()); // qCDebug(KORGANIZER_LOG) << index.data().toString() << enabled; const bool isSearchCollection = col.resource().startsWith(QStringLiteral("akonadi_search_resource")); const bool isKolabCollection = col.resource().startsWith(QStringLiteral("akonadi_kolab_resource")); const bool isTopLevelCollection = (col.parentCollection() == Akonadi::Collection::root()); const bool isToplevelSearchCollection = (isTopLevelCollection && isSearchCollection); const bool isToplevelKolabCollection = (isTopLevelCollection && isKolabCollection); QList buttons; if (!isSearchCollection && !isToplevelKolabCollection) { if (isSearchResult) { buttons << AddToList; } else { if (hover) { if (enabled != Qt::Checked) { buttons << Enable; } //The remove button should not be available for person subfolders if (!isChildOfPersonCollection(index)) { buttons << RemoveFromList; } } else { if (enabled == Qt::Checked) { buttons << Enable; } } } } if (!isToplevelSearchCollection && !isToplevelKolabCollection) { buttons << Quickview; } if (isSearchCollection && !isToplevelSearchCollection) { buttons << Total; } return buttons; } void StyledCalendarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_ASSERT(index.isValid()); const Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); //We display the toolbuttons while hovering const bool showButtons = option.state & QStyle::State_MouseOver; // const bool enabled = col.shouldList(Akonadi::Collection::ListDisplay); Qt::CheckState enabled = static_cast(index.data(EnabledRole).toInt()); QStyleOptionViewItem opt = option; initStyleOption(&opt, index); QStyledItemDelegate::paint(painter, opt, index); QStyle *s = style(option); //Buttons { int i = 1; Q_FOREACH (Action action, getActions(option, index)) { if (action != Total) { QStyleOptionButton buttonOption = buttonOpt(opt, mPixmap.value(action), i); if (action == Enable && showButtons) { buttonOption.state = QStyle::State_Active; } if (action == Enable && !showButtons && enabled == Qt::PartiallyChecked) { buttonOption.state = QStyle::State_Active; } s->drawControl(QStyle::CE_PushButton, &buttonOption, painter, 0); } else { QStyleOptionButton buttonOption = buttonOpt(opt, QPixmap(), i); buttonOption.features = QStyleOptionButton::Flat; buttonOption.rect.setHeight(buttonOption.rect.height() + 4); if (col.statistics().count() > 0) { buttonOption.text = QString::number(col.statistics().count()); } s->drawControl(QStyle::CE_PushButton, &buttonOption, painter, 0); } i++; } } //Color indicator if (opt.checkState) { QColor color = KOHelper::resourceColorKnown(col); if (!color.isValid() && isChildOfPersonCollection(index)) { const Akonadi::Collection parentCol = personCollection(index); if (parentCol.isValid()) { color = KOHelper::resourceColor(parentCol); KOHelper::setResourceColor(col, color); } else { color = KOHelper::resourceColor(col); } } else { color = KOHelper::resourceColor(col); } if (color.isValid()) { painter->save(); painter->setRenderHint(QPainter::Antialiasing); QPen pen = painter->pen(); pen.setColor(color); QPainterPath path; path.addRoundedRect(enableButtonRect(opt.rect, 0), 5, 5); color.setAlpha(200); painter->fillPath(path, color); painter->strokePath(path, pen); painter->restore(); } } } bool StyledCalendarDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { Q_ASSERT(event); Q_ASSERT(model); + // double-click mouse starts the quickview dialog + if (event->type() == QEvent::MouseButtonDblClick) { + Q_EMIT action(index, Quickview); + return true; + } + int button = -1; // make sure that we have the right event type - if ((event->type() == QEvent::MouseButtonRelease) - || (event->type() == QEvent::MouseButtonDblClick) - || (event->type() == QEvent::MouseButtonPress)) { + if ((event->type() == QEvent::MouseButtonRelease) || + (event->type() == QEvent::MouseButtonPress)) { QMouseEvent *me = static_cast(event); for (int i = 1; i < 4; i++) { if (enableButtonRect(option.rect, i).contains(me->pos())) { button = i; break; } } + if (me->button() != Qt::LeftButton || button < 0) { return QStyledItemDelegate::editorEvent(event, model, option, index); } - if ((event->type() == QEvent::MouseButtonPress) - || (event->type() == QEvent::MouseButtonDblClick)) { + if (event->type() == QEvent::MouseButtonPress) { return true; } + } else { return QStyledItemDelegate::editorEvent(event, model, option, index); } Q_ASSERT(button > 0); QStyleOptionViewItem opt = option; opt.state |= QStyle::State_MouseOver; QList actions = getActions(opt, index); if (actions.count() >= button) { const Action a = actions.at(button - 1); Q_EMIT action(index, a); return true; } return QStyledItemDelegate::editorEvent(event, model, option, index); } QSize StyledCalendarDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize size = QStyledItemDelegate::sizeHint(option, index); //Without this adjustment toplevel resource folders get a slightly greater height, which looks silly and breaks the toolbutton position. size.setHeight(mPixmap.value(AddToList).height() + 4); return size; } -