diff --git a/CMakeLists.txt b/CMakeLists.txt index 57df43f6..03d97ad5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,141 +1,141 @@ cmake_minimum_required(VERSION 3.1) # Do NOT add quote set(KDEPIM_DEV_VERSION alpha) # add an extra space if(DEFINED KDEPIM_DEV_VERSION) set(KDEPIM_DEV_VERSION " ${KDEPIM_DEV_VERSION}") endif() set(KDEPIM_VERSION_NUMBER "5.8.40") set(KDEPIM_VERSION "${KDEPIM_VERSION_NUMBER}${KDEPIM_DEV_VERSION}") project(korganizer VERSION ${KDEPIM_VERSION_NUMBER}) if(POLICY CMP0063) cmake_policy(SET CMP0063 NEW) endif() set(KF5_VERSION "5.44.0") find_package(ECM ${KF5_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) include(ECMOptionalAddSubdirectory) include(ECMInstallIcons) include(ECMSetupVersion) include(ECMAddTests) include(ECMMarkNonGuiExecutable) include(GenerateExportHeader) include(ECMGenerateHeaders) include(CMakePackageConfigHelpers) include(FeatureSummary) include(CheckFunctionExists) include(ECMGeneratePriFile) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(ECMAddAppIcon) include(ECMQtDeclareLoggingCategory) include(ECMCoverageOption) set(AKONADI_MIMELIB_VERSION "5.7.80") set(AKONADI_CONTACT_VERSION "5.7.80") set(KCALENDARCORE_LIB_VERSION "5.7.80") set(IDENTITYMANAGEMENT_LIB_VERSION "5.7.80") set(KLDAP_LIB_VERSION "5.7.80") set(KMAILTRANSPORT_LIB_VERSION "5.7.80") set(CALENDARUTILS_LIB_VERSION "5.7.80") set(AKONADICALENDAR_LIB_VERSION "5.7.80") set(KONTACTINTERFACE_LIB_VERSION "5.7.80") set(KMIME_LIB_VERSION "5.7.80") set(KPIMTEXTEDIT_LIB_VERSION "5.7.80") set(AKONADI_VERSION "5.7.80") set(KDEPIM_LIB_VERSION "${KDEPIM_VERSION_NUMBER}") set(KDEPIM_LIB_SOVERSION "5") set(AKONADINOTES_LIB_VERSION "5.7.80") set(QT_REQUIRED_VERSION "5.9.0") option(KDEPIM_ENTERPRISE_BUILD "Enable features specific to the enterprise branch, which are normally disabled. Also, it disables many components not needed for Kontact such as the Kolab client." FALSE) find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED DBus Gui Widgets Test UiTools) set(KDEPIM_APPS_LIB_VERSION_LIB "5.7.80") set(PIMCOMMON_LIB_VERSION_LIB "5.7.80") set(LIBKDEPIM_LIB_VERSION_LIB "5.7.80") set(LIBINCIDENCEEDITOR_LIB_VERSION_LIB "5.7.80") -set(CALENDARSUPPORT_LIB_VERSION_LIB "5.7.80") +set(CALENDARSUPPORT_LIB_VERSION_LIB "5.8.41") set(EVENTVIEW_LIB_VERSION_LIB "5.8.41") set(KCONTACTS_LIB_VERSION "5.7.80") find_package(KF5AkonadiSearch "5.7.80" CONFIG REQUIRED) set_package_properties(KF5AkonadiSearch PROPERTIES DESCRIPTION "The Akonadi Search libraries" URL "http://www.kde.org" TYPE REQUIRED PURPOSE "Provides search capabilities in KMail and Akonadi") # Find KF5 package find_package(KF5Codecs ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Completion ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Config ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5ConfigWidgets ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5CoreAddons ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Crash ${KF5_VERSION} REQUIRED) find_package(KF5DBusAddons ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5DocTools ${KF5_VERSION} REQUIRED) find_package(KF5IconThemes ${KF5_VERSION} REQUIRED) find_package(KF5ItemViews ${KF5_VERSION} REQUIRED) find_package(KF5JobWidgets ${KF5_VERSION} REQUIRED) find_package(KF5KCMUtils ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5NewStuff ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Parts ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Service ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5WidgetsAddons ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5WindowSystem ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5XmlGui ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Notifications ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Holidays ${KF5_VERSION} CONFIG REQUIRED) # Find KdepimLibs Package find_package(KF5PimTextEdit ${KPIMTEXTEDIT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Akonadi ${AKONADI_VERSION} CONFIG REQUIRED) find_package(KF5Contacts ${KCONTACTS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5CalendarCore ${KCALENDARCORE_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiContact ${AKONADI_CONTACT_VERSION} CONFIG REQUIRED) find_package(KF5IdentityManagement ${IDENTITYMANAGEMENT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5MailTransportAkonadi ${KMAILTRANSPORT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiMime ${AKONADI_MIMELIB_VERSION} CONFIG REQUIRED) find_package(KF5CalendarUtils ${CALENDARUTILS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Ldap ${KLDAP_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiCalendar ${AKONADICALENDAR_LIB_VERSION} CONFIG REQUIRED) find_package(Phonon4Qt5 CONFIG REQUIRED) find_package(KF5KontactInterface ${KONTACTINTERFACE_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Mime ${KMIME_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiNotes ${AKONADINOTES_LIB_VERSION} CONFIG REQUIRED) find_package(KF5KdepimDBusInterfaces ${KDEPIM_APPS_LIB_VERSION_LIB} CONFIG REQUIRED) find_package(KF5PimCommonAkonadi ${PIMCOMMON_LIB_VERSION_LIB} CONFIG REQUIRED) find_package(KF5LibkdepimAkonadi ${LIBKDEPIM_LIB_VERSION_LIB} CONFIG REQUIRED) find_package(KF5IncidenceEditor ${LIBINCIDENCEEDITOR_LIB_VERSION_LIB} CONFIG REQUIRED) find_package(KF5CalendarSupport ${CALENDARSUPPORT_LIB_VERSION_LIB} CONFIG REQUIRED) find_package(KF5EventViews ${EVENTVIEW_LIB_VERSION_LIB} CONFIG REQUIRED) if(NOT APPLE) find_package(X11) endif() set(KDEPIM_HAVE_X11 ${X11_FOUND}) add_definitions(-DQT_NO_URL_CAST_FROM_STRING) add_definitions(-DQT_USE_QSTRINGBUILDER) configure_file(config-korganizer.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-korganizer.h) configure_file(korgac/config-enterprise.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-enterprise.h) include_directories(${korganizer_SOURCE_DIR} ${korganizer_BINARY_DIR} ${korgac_SOURCE_DIR} ${korgac_BINARY_DIR}) configure_file(korganizer-version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/korganizer-version.h @ONLY) add_definitions(-DQT_NO_CAST_FROM_ASCII) add_definitions(-DQT_NO_CAST_TO_ASCII) add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) add_subdirectory(src) add_subdirectory(korgac) install(FILES korganizer.renamecategories korganizer.categories DESTINATION ${KDE_INSTALL_CONFDIR}) add_subdirectory(doc) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/views/collectionview/calendardelegate.cpp b/src/views/collectionview/calendardelegate.cpp index 27423cd6..f7c35d15 100644 --- a/src/views/collectionview/calendardelegate.cpp +++ b/src/views/collectionview/calendardelegate.cpp @@ -1,292 +1,299 @@ /* * 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 "controller.h" #include "kohelper.h" #include "korganizer_debug.h" #include +#include #include #include #include #include #include #include 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) + const QModelIndex &index, 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); + QWidget *w = const_cast(opt.widget); + if (w) { + const Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); + w->setToolTip(CalendarSupport::toolTipString(col)); + } 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(QLatin1String("akonadi_search_resource")); const bool isKolabCollection = col.resource().startsWith(QLatin1String( "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; opt.font = QFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont)); opt.textElideMode = Qt::ElideLeft; 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); + QStyleOptionButton buttonOption = buttonOpt(opt, mPixmap.value(action), index, 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, nullptr); } else { - QStyleOptionButton buttonOption = buttonOpt(opt, QPixmap(), i); + QStyleOptionButton buttonOption = buttonOpt(opt, QPixmap(), index, 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, nullptr); } 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::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) { 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. + // 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; }