diff --git a/CMakeLists.txt b/CMakeLists.txt index 44520e8..95f2aca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,101 +1,101 @@ cmake_minimum_required(VERSION 3.0) -set(PIM_VERSION "5.8.40") +set(PIM_VERSION "5.8.41") project(eventviews VERSION ${PIM_VERSION}) # ECM setup set(KF5_VERSION "5.44.0") find_package(ECM ${KF5_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) set(LIBRARY_NAMELINK) if(POLICY CMP0053) cmake_policy(SET CMP0053 NEW) endif() include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(ECMGeneratePriFile) include(CMakePackageConfigHelpers) include(ECMSetupVersion) include(FeatureSummary) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMQtDeclareLoggingCategory) include(ECMAddTests) include(ECMCoverageOption) set(EVENTVIEW_LIB_VERSION ${PIM_VERSION}) set(CALENDARUTILS_LIB_VERSION "5.7.80") set(AKONADI_LIB_VERSION "5.7.80") set(QT_REQUIRED_VERSION "5.8.0") set(KCALENDARCORE_LIB_VERSION "5.7.80") set(AKONADICALENDAR_LIB_VERSION "5.7.80") set(KMIME_LIB_VERSION "5.7.80") set(LIBKDEPIM_LIB_VERSION "5.7.80") set(CALENDARSUPPORT_LIB_VERSION "5.7.80") find_package(KF5Akonadi ${AKONADI_LIB_VERSION} CONFIG REQUIRED) find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets UiTools) find_package(KF5I18n ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Codecs ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5GuiAddons ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5IconThemes ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Service ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Completion ${KF5_VERSION} CONFIG REQUIRED) set(KDIAGRAM_LIB_VERSION "1.4.0") find_package(KGantt ${KDIAGRAM_LIB_VERSION} CONFIG REQUIRED) find_package(KF5LibkdepimAkonadi ${LIBKDEPIM_LIB_VERSION} CONFIG REQUIRED) find_package(KF5CalendarUtils ${CALENDARUTILS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5CalendarCore ${KCALENDARCORE_LIB_VERSION} CONFIG REQUIRED) find_package(KF5CalendarSupport ${CALENDARSUPPORT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiCalendar ${AKONADICALENDAR_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Mime ${KMIME_LIB_VERSION} CONFIG REQUIRED) ecm_setup_version(PROJECT VARIABLE_PREFIX EVENTVIEWS VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/eventviews_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5EventViewsConfigVersion.cmake" SOVERSION 5 ) ########### Targets ########### add_definitions("-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII") add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) #add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) add_definitions(-DQT_NO_URL_CAST_FROM_STRING) ########### CMake Config Files ########### set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5EventViews") configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KF5EventViewsConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KF5EventViewsConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KF5EventViewsConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KF5EventViewsConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(EXPORT KF5EventViewsTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5EventViewsTargets.cmake NAMESPACE KF5::) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eventviews_version.h DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5} COMPONENT Devel ) add_subdirectory(src) if(BUILD_TESTING) find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Test) add_subdirectory(tests) endif() install(FILES eventviews.renamecategories eventviews.categories DESTINATION ${KDE_INSTALL_CONFDIR}) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/eventviews.kcfg b/src/eventviews.kcfg index 3a48833..3013282 100644 --- a/src/eventviews.kcfg +++ b/src/eventviews.kcfg @@ -1,709 +1,715 @@ The default way of attaching dropped emails to an event Ask Check this box to export the calendar to a HTML-file every time you save it. By default, this file will be called calendar.html and placed in the user home folder. false Check this box to save your calendar file automatically when you exit KOrganizer without asking and periodically, as you work. This setting does not affect the automatic saving of the standard calendar, which is automatically saved after each change. true Set the interval between automatic saving of calendar events in minutes here. This setting only applies to files that are opened manually. The standard KDE-wide calendar is automatically saved after each change. 10 1 Check this box to display a confirmation dialog when deleting items. true Select this option to always record new events, to-dos and journal entries using the standard calendar. Select this option to choose the calendar to be used to record the item each time you create a new event, to-do or journal entry. This choice is recommended if you intend to use the shared folders functionality of the Kolab server or have to manage multiple accounts using Kontact as a KDE Kolab client. askDestination Check this box to show the KOrganizer reminder daemon in the system tray. true Select your timezone from the list of locations in this drop down box. If your city is not listed, select one which shares the same timezone. KOrganizer will automatically adjust for daylight savings. Enter the start time for events here. This time should be the earliest time that you use for events, as it will be displayed at the top. QDateTime(QDate(1752,1,1), QTime(7,0)) Enter the start time for the working hours here. The working hours will be marked with color by KOrganizer. QDateTime(QDate(1752,1,1), QTime(8,0)) Enter the ending time for the working hours here. The working hours will be marked with color by KOrganizer. QDateTime(QDate(1752,1,1), QTime(17,0)) + + + Select the first day of each week + Select the first day of each week. Normally, you can ignore this since it is set in your locale. + QLocale().firstDayOfWeek()-1 + Check this box to display summary tooltips when hovering the mouse over an event or a to-do. true Check this box so that to-dos will use category colors and not colors specific to their due, due today or overdue state false Select the number of "x" days to be displayed in the next days view. To access the next "x" days view, choose the "Next X Days" menu item from the "View" menu. Show this many days at a time in the Next "x" days view 3 Check this box to show the days containing daily recurring events in bold typeface in the Date Navigator, or uncheck it to give more prominence to other (non daily recurring) events. true Check this box to show the days containing weekly recurring events in bold typeface in the Date Navigator, or uncheck it to give more prominence to other (non weekly recurring) events. true Check this box to show the days containing to-dos in bold typeface in the Date Navigator when in to-do view. true Check this box to show the days containing journals in bold typeface in the Date Navigator when in journal view. true Check this box to select a working week when clicking on the Date Navigator's week numbers, or uncheck it to choose the whole week. false Select the height of the hour rows in the agenda grid, in pixels. Increasing this value will make each row in the agenda grid taller. Set the height (in pixels) for an hour in the agenda grid 10 4 30 Check this box to display icons (alarm, recursion, etc.) in agenda view items. Display icons in agenda view items true Check this box to display to-dos in the agenda view. Display to-dos in the agenda view true Check this box to display a line in the day or week view indicating the current-time line (Marcus Bains line). Display the current-time indicator true Check this box if you want to show seconds on the current-time line. Display seconds with the current-time indicator false Check this box to start the event editor automatically when you select a time range in the daily and weekly view. To select a time range, drag the mouse from the start time to the end time of the event you are about to plan. Enable automatic event editor with time range selection false Select the "Category inside, calendar outside" option if you would like to draw calendar items in their associated category color, with the item's border drawn in the color of its calendar. Please use the Colors and Fonts configuration page for setting these colors. Draw agenda items in their category color inside and calendar color for their border Select the "Calendar inside, category outside" option if you would like to draw calendar items in their associated calendar color, with the item's border drawn in the color of its category. Please use the Colors and Fonts configuration page for setting these colors. Draw agenda items in their calendar color inside and category color for their border Select the "Only category" option if you would like to draw calendar items (both inside and border) in the color of their associated category. Please use the Colors and Fonts configuration page for setting these colors. Draw agenda items using their category color for the inside and border Select the "Only calendar" option if you would like to draw calendar items (both inside and border) in the color of their calendar. Please use the Colors and Fonts configuration page for setting these colors. Draw agenda items using their calendar color for the inside and border CategoryInsideResourceOutside Check this box if you want agenda's background to be filled with a different color on days which have at least one all day event marked as busy. Also, you can change the background color used for this option on the Colors configuration page. Look for the "Busy days background color" setting. false Select the "Merge all calendars into one view" option if you would like all your calendars to be shown together in one agenda view. Show all calendars merged together Select the "Show calendars side by side" option if you would like to see two calendars at once, in a side-by-side view. Show two calendars side-by-side Select "Switch between views with tabs" if you would like to alternate between calendars using the tab key. Tab through calendars CalendarsMerged Check this box to display icons (alarm, recursion, etc.) in month view items. Display icons in month view items true Check this box to display the time in month view items. Display time in month view items false Check this box to display to-dos in the month view. Display to-dos in the month view true Check this box to display journals in the month view. Display journals in the month view true Check this box to use the full KOrganizer window when displaying the month view. If this box is checked, you will gain some space for the monthly view, but other widgets, such as the date navigator, the item details and the calendars list, will not be displayed. false Select the "Category inside, calendar outside" option if you would like to draw calendar items in their associated category color, with the item's border drawn in the color of its calendar. Please use the Colors and Fonts configuration page for setting these colors. Draw month items in their category color inside and calendar color for their border Select the "Calendar inside, category outside" option if you would like to draw calendar items in their associated calendar color, with the item's border drawn in the color of its category. Please use the Colors and Fonts configuration page for setting these colors. Draw month items in their calendar color inside and category color for their border Select the "Only category" option if you would like to draw calendar items (both inside and border) in the color of their associated category. Please use the Colors and Fonts configuration page for setting these colors. Draw month items using their category color for the inside and border Select the "Only calendar" option if you would like to draw calendar items (both inside and border) in the color of their calendar. Please use the Colors and Fonts configuration page for setting these colors. Draw month items using their calendar color for the inside and border MonthItemCategoryInsideResourceOutside Check this box if you want month view's background to be filled with a different color on days which have at least one all day event marked as busy. Also, you can change the background color used for this option on the Colors configuration page. Look for the "Busy days background color" setting. false Check this box if you want all completed to-dos to be always grouped at the bottom of the to-do list. true Check this box to use the full KOrganizer window when displaying the to-do list view. If this box is checked, you will gain some space for the to-do list view, but other widgets, such as the date navigator, the to-do details and the calendars list, will not be displayed. true Display to-dos as a flat list instead of a hierarchical tree Check this box if you want to see all your to-dos in a flat list instead of being arranged in a hierarchical tree. false Check this box to record the completion of a to-do in a new entry of your journal automatically. false Select the holiday color here. The holiday color will be used for the holiday name in the month view and the holiday number in the date navigator. 255, 100, 100 Select the agenda view background color here. 255, 255, 255 When you have an all day event marked as busy, you can have a different agenda or month view background color for that day. Select the color here. 136, 255, 219 Select a color to use for the current-time (Marcus Bains) line. Use this color for the Agenda View current-time (Marcus Bains) line 255,0,0 Select the working hours color for the agenda view here. 255, 235, 154 Select the to-do due today color here. 255, 200, 50 Select the to-do overdue color here. 255, 100, 100 Press this button to configure the time bar font. The time bar is the widget that shows the hours in the agenda view. This button will open the "Select Font" dialog, allowing you to choose the hour font for the time bar. Press this button to configure the month view font. This button will open the "Select Font" dialog, allowing you to choose the font for the items in the month view. Press this button to configure the agenda view font. This button will open the "Select Font" dialog, allowing you to choose the font for the events in the agenda view. Press this button to configure the current-time line font. This button will open the "Select Font" dialog, allowing you to choose the font for the current-time line in the agenda view. true true The default way of attaching dropped emails to a task TodoAttachInlineFull false true 0 #c1d4e7,#d0e7c1,#e3e7c1,#e7c1e6,#a1b1c1 true Select the agenda view background color here. 255, 255, 255 Select the highlight color here. The highlight color will be used for marking the currently selected area in your agenda and in the date navigator. 100, 100, 255 Select the working hours background color for the agenda view here. 225, 225, 255 255, 100, 100 255, 100, 100 255, 100, 100 255, 100, 100 255, 100, 100 Select the to-do due today color here. 255, 200, 50 Select the to-do overdue color here. 255, 100, 100 Select the holiday color here. The holiday color will be used for the holiday name in the month view and the holiday number in the date navigator. 255, 100, 100 Select the Month view background color here. 255, 255, 255 Select the highlight color here. The highlight color will be used for marking the currently selected area in your Month and in the date navigator. 100, 100, 255 Select the working hours background color for the Month view here. 225, 225, 255 255, 100, 100 255, 100, 100 Select the default event color here. The default event color will be used for events categories in your Month. Note that you can specify a separate color for each event category below. 151, 235, 121 255, 100, 100 255, 100, 100 255, 100, 100 Select the to-do due today color here. 255, 200, 50 Select the to-do overdue color here. 255, 100, 100 Select the holiday color here. The holiday color will be used for the holiday name in the month view and the holiday number in the date navigator. 255, 100, 100 diff --git a/src/month/monthview.cpp b/src/month/monthview.cpp index 86e2e1e..e10b12d 100644 --- a/src/month/monthview.cpp +++ b/src/month/monthview.cpp @@ -1,639 +1,638 @@ /* Copyright (c) 2008 Bruno Virlet Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Author: Bertjan Broeksema, broeksema@kde.org 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 "monthview.h" #include "monthgraphicsitems.h" #include "monthitem.h" #include "monthscene.h" #include "prefs.h" #include #include #include #include #include #include #include #include #include "calendarview_debug.h" #include #include #include #include -#include using namespace EventViews; namespace EventViews { class MonthViewPrivate : public Akonadi::ETMCalendar::CalendarObserver { MonthView *q; public: /// Methods explicit MonthViewPrivate(MonthView *qq); void addIncidence(const Akonadi::Item &incidence); void moveStartDate(int weeks, int months); // void setUpModels(); void triggerDelayedReload(EventView::Change reason); public: /// Members QTimer reloadTimer; MonthScene *scene = nullptr; QDate selectedItemDate; Akonadi::Item::Id selectedItemId; MonthGraphicsView *view = nullptr; QToolButton *fullView = nullptr; // List of uids for QDate QMap mBusyDays; protected: /* reimplemented from KCalCore::Calendar::CalendarObserver */ void calendarIncidenceAdded(const KCalCore::Incidence::Ptr &incidence) override; void calendarIncidenceChanged(const KCalCore::Incidence::Ptr &incidence) override; void calendarIncidenceDeleted(const KCalCore::Incidence::Ptr &incidence, const KCalCore::Calendar *calendar) override; private: //quiet --overloaded-virtual warning using KCalCore::Calendar::CalendarObserver::calendarIncidenceDeleted; }; } MonthViewPrivate::MonthViewPrivate(MonthView *qq) : q(qq) , scene(new MonthScene(qq)) , selectedItemId(-1) , view(new MonthGraphicsView(qq)) , fullView(nullptr) { reloadTimer.setSingleShot(true); view->setScene(scene); } void MonthViewPrivate::addIncidence(const Akonadi::Item &incidence) { Q_UNUSED(incidence); //TODO: add some more intelligence here... q->setChanges(q->changes() | EventView::IncidencesAdded); reloadTimer.start(50); } void MonthViewPrivate::moveStartDate(int weeks, int months) { auto start = q->startDateTime(); auto end = q->endDateTime(); start = start.addDays(weeks * 7); end = end.addDays(weeks * 7); start = start.addMonths(months); end = end.addMonths(months); KCalCore::DateList dateList; QDate d = start.date(); const QDate e = end.date(); dateList.reserve(d.daysTo(e) + 1); while (d <= e) { dateList.append(d); d = d.addDays(1); } /** * If we call q->setDateRange( start, end ); directly, * it will change the selected dates in month view, * but the application won't know about it. * The correct way is to Q_EMIT datesSelected() * #250256 * */ Q_EMIT q->datesSelected(dateList); } void MonthViewPrivate::triggerDelayedReload(EventView::Change reason) { q->setChanges(q->changes() | reason); if (!reloadTimer.isActive()) { reloadTimer.start(50); } } void MonthViewPrivate::calendarIncidenceAdded(const KCalCore::Incidence::Ptr &) { triggerDelayedReload(MonthView::IncidencesAdded); } void MonthViewPrivate::calendarIncidenceChanged(const KCalCore::Incidence::Ptr &) { triggerDelayedReload(MonthView::IncidencesEdited); } void MonthViewPrivate::calendarIncidenceDeleted(const KCalCore::Incidence::Ptr &incidence, const KCalCore::Calendar *calendar) { Q_UNUSED(calendar); Q_ASSERT(!incidence->uid().isEmpty()); scene->removeIncidence(incidence->uid()); } /// MonthView MonthView::MonthView(NavButtonsVisibility visibility, QWidget *parent) : EventView(parent) , d(new MonthViewPrivate(this)) { QHBoxLayout *topLayout = new QHBoxLayout(this); topLayout->addWidget(d->view); topLayout->setMargin(0); if (visibility == Visible) { QVBoxLayout *rightLayout = new QVBoxLayout(); rightLayout->setSpacing(0); rightLayout->setMargin(0); // push buttons to the bottom rightLayout->addStretch(1); d->fullView = new QToolButton(this); d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen"))); d->fullView->setAutoRaise(true); d->fullView->setCheckable(true); d->fullView->setChecked(preferences()->fullViewMonth()); d->fullView->isChecked() ? d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a normal size")) : d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a full window")); d->fullView->setWhatsThis( i18nc("@info:whatsthis", "Click this button and the month view will be enlarged to fill the " "maximum available window space / or shrunk back to its normal size.")); connect(d->fullView, &QAbstractButton::clicked, this, &MonthView::changeFullView); QToolButton *minusMonth = new QToolButton(this); minusMonth->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up-double"))); minusMonth->setAutoRaise(true); minusMonth->setToolTip(i18nc("@info:tooltip", "Go back one month")); minusMonth->setWhatsThis( i18nc("@info:whatsthis", "Click this button and the view will be scrolled back in time by 1 month.")); connect(minusMonth, &QAbstractButton::clicked, this, &MonthView::moveBackMonth); QToolButton *minusWeek = new QToolButton(this); minusWeek->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up"))); minusWeek->setAutoRaise(true); minusWeek->setToolTip(i18nc("@info:tooltip", "Go back one week")); minusWeek->setWhatsThis( i18nc("@info:whatsthis", "Click this button and the view will be scrolled back in time by 1 week.")); connect(minusWeek, &QAbstractButton::clicked, this, &MonthView::moveBackWeek); QToolButton *plusWeek = new QToolButton(this); plusWeek->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down"))); plusWeek->setAutoRaise(true); plusWeek->setToolTip(i18nc("@info:tooltip", "Go forward one week")); plusWeek->setWhatsThis( i18nc("@info:whatsthis", "Click this button and the view will be scrolled forward in time by 1 week.")); connect(plusWeek, &QAbstractButton::clicked, this, &MonthView::moveFwdWeek); QToolButton *plusMonth = new QToolButton(this); plusMonth->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down-double"))); plusMonth->setAutoRaise(true); plusMonth->setToolTip(i18nc("@info:tooltip", "Go forward one month")); plusMonth->setWhatsThis( i18nc("@info:whatsthis", "Click this button and the view will be scrolled forward in time by 1 month.")); connect(plusMonth, &QAbstractButton::clicked, this, &MonthView::moveFwdMonth); rightLayout->addWidget(d->fullView); rightLayout->addWidget(minusMonth); rightLayout->addWidget(minusWeek); rightLayout->addWidget(plusWeek); rightLayout->addWidget(plusMonth); topLayout->addLayout(rightLayout); } else { d->view->setFrameStyle(QFrame::NoFrame); } connect(d->scene, &MonthScene::showIncidencePopupSignal, this, &MonthView::showIncidencePopupSignal); connect(d->scene, &MonthScene::incidenceSelected, this, &EventView::incidenceSelected); connect(d->scene, SIGNAL(newEventSignal()), SIGNAL(newEventSignal())); connect(d->scene, &MonthScene::showNewEventPopupSignal, this, &MonthView::showNewEventPopupSignal); connect(&d->reloadTimer, &QTimer::timeout, this, &MonthView::reloadIncidences); updateConfig(); // d->setUpModels(); d->reloadTimer.start(50); } MonthView::~MonthView() { if (calendar()) { calendar()->unregisterObserver(d); } delete d; } void MonthView::updateConfig() { d->scene->update(); setChanges(changes() | ConfigChanged); d->reloadTimer.start(50); } int MonthView::currentDateCount() const { return actualStartDateTime().date().daysTo(actualEndDateTime().date()); } KCalCore::DateList MonthView::selectedIncidenceDates() const { KCalCore::DateList list; if (d->scene->selectedItem()) { IncidenceMonthItem *tmp = qobject_cast(d->scene->selectedItem()); if (tmp) { QDate selectedItemDate = tmp->realStartDate(); if (selectedItemDate.isValid()) { list << selectedItemDate; } } } else if (d->scene->selectedCell()) { list << d->scene->selectedCell()->date(); } return list; } QDateTime MonthView::selectionStart() const { if (d->scene->selectedCell()) { return QDateTime(d->scene->selectedCell()->date()); } else { return QDateTime(); } } QDateTime MonthView::selectionEnd() const { // Only one cell can be selected (for now) return selectionStart(); } void MonthView::setDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth) { EventView::setDateRange(start, end, preferredMonth); setChanges(changes() | DatesChanged); d->reloadTimer.start(50); } bool MonthView::eventDurationHint(QDateTime &startDt, QDateTime &endDt, bool &allDay) const { if (d->scene->selectedCell()) { startDt.setDate(d->scene->selectedCell()->date()); endDt.setDate(d->scene->selectedCell()->date()); allDay = true; return true; } return false; } void MonthView::showIncidences(const Akonadi::Item::List &incidenceList, const QDate &date) { Q_UNUSED(incidenceList); Q_UNUSED(date); } void MonthView::changeIncidenceDisplay(const Akonadi::Item &incidence, int action) { Q_UNUSED(incidence); Q_UNUSED(action); //TODO: add some more intelligence here... // don't call reloadIncidences() directly. It would delete all // MonthItems, but this changeIncidenceDisplay()-method was probably // called by one of the MonthItem objects. So only schedule a reload // as event setChanges(changes() | IncidencesEdited); d->reloadTimer.start(50); } void MonthView::updateView() { d->view->update(); } #ifndef QT_NO_WHEELEVENT void MonthView::wheelEvent(QWheelEvent *event) { // invert direction to get scroll-like behaviour if (event->delta() > 0) { d->moveStartDate(-1, 0); } else if (event->delta() < 0) { d->moveStartDate(1, 0); } // call accept in every case, we do not want anybody else to react event->accept(); } #endif void MonthView::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_PageUp) { d->moveStartDate(0, -1); event->accept(); } else if (event->key() == Qt::Key_PageDown) { d->moveStartDate(0, 1); event->accept(); } else if (processKeyEvent(event)) { event->accept(); } else { event->ignore(); } } void MonthView::keyReleaseEvent(QKeyEvent *event) { if (processKeyEvent(event)) { event->accept(); } else { event->ignore(); } } void MonthView::changeFullView() { bool fullView = d->fullView->isChecked(); if (fullView) { d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-restore"))); d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a normal size")); } else { d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen"))); d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a full window")); } preferences()->setFullViewMonth(fullView); preferences()->writeConfig(); Q_EMIT fullViewChanged(fullView); } void MonthView::moveBackMonth() { d->moveStartDate(0, -1); } void MonthView::moveBackWeek() { d->moveStartDate(-1, 0); } void MonthView::moveFwdWeek() { d->moveStartDate(1, 0); } void MonthView::moveFwdMonth() { d->moveStartDate(0, 1); } void MonthView::showDates(const QDate &start, const QDate &end, const QDate &preferedMonth) { Q_UNUSED(start); Q_UNUSED(end); Q_UNUSED(preferedMonth); d->triggerDelayedReload(DatesChanged); } QPair MonthView::actualDateRange(const QDateTime &start, const QDateTime &, const QDate &preferredMonth) const { QDateTime dayOne = preferredMonth.isValid() ? QDateTime(preferredMonth) : start; dayOne.setDate(QDate(dayOne.date().year(), dayOne.date().month(), 1)); - const int weekdayCol = (dayOne.date().dayOfWeek() + 7 - QLocale().firstDayOfWeek()) % 7; + const int weekdayCol = (dayOne.date().dayOfWeek() + 7 - preferences()->firstDayOfWeek()) % 7; QDateTime actualStart = dayOne.addDays(-weekdayCol); actualStart.setTime(QTime(0, 0, 0, 0)); QDateTime actualEnd = actualStart.addDays(6 * 7 - 1); actualEnd.setTime(QTime(23, 59, 59, 99)); return qMakePair(actualStart, actualEnd); } Akonadi::Item::List MonthView::selectedIncidences() const { Akonadi::Item::List selected; if (d->scene->selectedItem()) { IncidenceMonthItem *tmp = qobject_cast(d->scene->selectedItem()); if (tmp) { Akonadi::Item incidenceSelected = tmp->akonadiItem(); if (incidenceSelected.isValid()) { selected.append(incidenceSelected); } } } return selected; } void MonthView::reloadIncidences() { if (changes() == NothingChanged) { return; } // keep selection if it exists Akonadi::Item incidenceSelected; MonthItem *itemToReselect = nullptr; if (IncidenceMonthItem *tmp = qobject_cast(d->scene->selectedItem())) { d->selectedItemId = tmp->akonadiItem().id(); d->selectedItemDate = tmp->realStartDate(); if (!d->selectedItemDate.isValid()) { return; } } d->scene->resetAll(); d->mBusyDays.clear(); // build monthcells hash int i = 0; for (QDate date = actualStartDateTime().date(); date <= actualEndDateTime().date(); date = date.addDays(1)) { d->scene->mMonthCellMap[ date ] = new MonthCell(i, date, d->scene); i++; } // build global event list const bool colorMonthBusyDays = preferences()->colorMonthBusyDays(); KCalCore::OccurrenceIterator occurIter(*calendar(), actualStartDateTime(), actualEndDateTime()); while (occurIter.hasNext()) { occurIter.next(); // Remove the two checks when filtering is done through a proxyModel, when using calendar search - if (!preferences()->showTodosMonthView() - && occurIter.incidence()->type() == KCalCore::Incidence::TypeTodo) { + if (!preferences()->showTodosMonthView() && + occurIter.incidence()->type() == KCalCore::Incidence::TypeTodo) { continue; } - if (!preferences()->showJournalsMonthView() - && occurIter.incidence()->type() == KCalCore::Incidence::TypeJournal) { + if (!preferences()->showJournalsMonthView() && + occurIter.incidence()->type() == KCalCore::Incidence::TypeJournal) { continue; } const bool busyDay = colorMonthBusyDays && makesWholeDayBusy(occurIter.incidence()); if (busyDay) { QStringList &list = d->mBusyDays[occurIter.occurrenceStartDate().date()]; list.append(occurIter.incidence()->uid()); } const Akonadi::Item item = calendar()->item(occurIter.incidence()); if (!item.isValid()) { continue; } Q_ASSERT(item.isValid()); Q_ASSERT(item.hasPayload()); MonthItem *manager = new IncidenceMonthItem(d->scene, calendar(), item, occurIter.incidence(), occurIter.occurrenceStartDate().toLocalTime().date()); d->scene->mManagerList << manager; - if (d->selectedItemId == item.id() - && manager->realStartDate() == d->selectedItemDate) { + if (d->selectedItemId == item.id() && + manager->realStartDate() == d->selectedItemDate) { // only select it outside the loop because we are still creating items itemToReselect = manager; } } if (itemToReselect) { d->scene->selectItem(itemToReselect); } // add holidays const QList workDays = CalendarSupport::workDays(actualStartDateTime().date(), actualEndDateTime().date()); for (QDate date = actualStartDateTime().date(); date <= actualEndDateTime().date(); date = date.addDays(1)) { // Only call CalendarSupport::holiday() if it's not a workDay, saves come cpu cicles. if (!workDays.contains(date)) { QStringList holidays(CalendarSupport::holiday(date)); if (!holidays.isEmpty()) { MonthItem *holidayItem = new HolidayMonthItem( d->scene, date, holidays.join(i18nc("@item:intext delimiter for joining holiday names", ","))); d->scene->mManagerList << holidayItem; } } } // sort it std::sort(d->scene->mManagerList.begin(), d->scene->mManagerList.end(), MonthItem::greaterThan); // build each month's cell event list foreach (MonthItem *manager, d->scene->mManagerList) { for (QDate date = manager->startDate(); date <= manager->endDate(); date = date.addDays(1)) { MonthCell *cell = d->scene->mMonthCellMap.value(date); if (cell) { cell->mMonthItemList << manager; } } } foreach (MonthItem *manager, d->scene->mManagerList) { manager->updateMonthGraphicsItems(); manager->updatePosition(); } foreach (MonthItem *manager, d->scene->mManagerList) { manager->updateGeometry(); } d->scene->setInitialized(true); d->view->update(); d->scene->update(); } void MonthView::calendarReset() { qCDebug(CALENDARVIEW_LOG); d->triggerDelayedReload(ResourcesChanged); } QDate MonthView::averageDate() const { return actualStartDateTime().date().addDays( actualStartDateTime().date().daysTo(actualEndDateTime().date()) / 2); } int MonthView::currentMonth() const { return averageDate().month(); } bool MonthView::usesFullWindow() { return preferences()->fullViewMonth(); } bool MonthView::isBusyDay(const QDate &day) const { return !d->mBusyDays[day].isEmpty(); } void MonthView::setCalendar(const Akonadi::ETMCalendar::Ptr &cal) { Q_ASSERT(cal); if (calendar()) { calendar()->unregisterObserver(d); } EventView::setCalendar(cal); calendar()->registerObserver(d); } diff --git a/src/prefs.cpp b/src/prefs.cpp index 8d94241..96f9d70 100644 --- a/src/prefs.cpp +++ b/src/prefs.cpp @@ -1,1128 +1,1138 @@ /* Copyright (c) 2001,2003 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Author: Kevin Krammer, krake@kdab.com 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 "prefs.h" #include "prefs_base.h" #include "calendarview_debug.h" -#include #include #include +#include + using namespace EventViews; QSet iconArrayToSet(const QByteArray &array) { QSet set; for (int i = 0; i < array.count(); ++i) { if (i >= EventViews::EventView::IconCount) { qCWarning(CALENDARVIEW_LOG) << "Icon array is too big: " << array.count(); return set; } if (array[i] != 0) { set.insert(static_cast(i)); } } return set; } QByteArray iconSetToArray(const QSet &set) { QByteArray array; for (int i = 0; i < EventViews::EventView::IconCount; ++i) { const bool contains = set.contains(static_cast(i)); array.append(contains ? 1 : 0); } return array; } QByteArray agendaViewIconDefaults() { QByteArray iconDefaults; iconDefaults[EventViews::EventView::CalendarCustomIcon] = 1; iconDefaults[EventViews::EventView::TaskIcon] = 1; iconDefaults[EventViews::EventView::JournalIcon] = 1; iconDefaults[EventViews::EventView::RecurringIcon] = 1; iconDefaults[EventViews::EventView::ReminderIcon] = 1; iconDefaults[EventViews::EventView::ReadOnlyIcon] = 1; iconDefaults[EventViews::EventView::ReplyIcon] = 0; return iconDefaults; } QByteArray monthViewIconDefaults() { QByteArray iconDefaults; iconDefaults[EventViews::EventView::CalendarCustomIcon] = 1; iconDefaults[EventViews::EventView::TaskIcon] = 1; iconDefaults[EventViews::EventView::JournalIcon] = 1; iconDefaults[EventViews::EventView::RecurringIcon] = 0; iconDefaults[EventViews::EventView::ReminderIcon] = 0; iconDefaults[EventViews::EventView::ReadOnlyIcon] = 1; iconDefaults[EventViews::EventView::ReplyIcon] = 0; return iconDefaults; } class BaseConfig : public PrefsBase { public: BaseConfig(); void setResourceColor(const QString &resource, const QColor &color); void setTimeScaleTimezones(const QStringList &timeZones); QStringList timeScaleTimezones() const; public: QHash mResourceColors; QColor mDefaultResourceColor; QFont mDefaultMonthViewFont; QFont mDefaultAgendaTimeLabelsFont; QStringList mTimeScaleTimeZones; QSet mAgendaViewIcons; QSet mMonthViewIcons; protected: void usrSetDefaults() override; void usrRead() override; bool usrSave() override; }; BaseConfig::BaseConfig() : PrefsBase() { mDefaultResourceColor = QColor(); //Default is a color invalid mDefaultAgendaTimeLabelsFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont); // make a large default time bar font, at least 16 points. mDefaultAgendaTimeLabelsFont.setPointSize( qMax(mDefaultAgendaTimeLabelsFont.pointSize() + 4, 16)); mDefaultMonthViewFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont); // make it a bit smaller mDefaultMonthViewFont.setPointSize( qMax(mDefaultMonthViewFont.pointSize() - 2, 6)); agendaTimeLabelsFontItem()->setDefaultValue(mDefaultAgendaTimeLabelsFont); agendaTimeLabelsFontItem()->setDefault(); monthViewFontItem()->setDefaultValue(mDefaultMonthViewFont); monthViewFontItem()->setDefault(); } void BaseConfig::setResourceColor(const QString &resource, const QColor &color) { mResourceColors.insert(resource, color); } void BaseConfig::setTimeScaleTimezones(const QStringList &list) { mTimeScaleTimeZones = list; } QStringList BaseConfig::timeScaleTimezones() const { return mTimeScaleTimeZones; } void BaseConfig::usrSetDefaults() { setAgendaTimeLabelsFont(mDefaultAgendaTimeLabelsFont); setMonthViewFont(mDefaultMonthViewFont); PrefsBase::usrSetDefaults(); } void BaseConfig::usrRead() { // Note that the [Category Colors] group was removed after 3.2 due to // an algorithm change. That's why we now use [Category Colors2] // Resource colors KConfigGroup rColorsConfig(config(), "Resources Colors"); const QStringList colorKeyList = rColorsConfig.keyList(); QStringList::ConstIterator it3; QStringList::ConstIterator end3(colorKeyList.end()); for (it3 = colorKeyList.begin(); it3 != end3; ++it3) { QColor color = rColorsConfig.readEntry(*it3, mDefaultResourceColor); //qCDebug(CALENDARVIEW_LOG) << "key:" << (*it3) << "value:" << color; setResourceColor(*it3, color); } #if 0 config()->setGroup("FreeBusy"); if (mRememberRetrievePw) { mRetrievePassword = KStringHandler::obscure(config()->readEntry("Retrieve Server Password")); } #endif KConfigGroup timeScaleConfig(config(), "Timescale"); setTimeScaleTimezones(timeScaleConfig.readEntry("Timescale Timezones", QStringList())); KConfigGroup monthViewConfig(config(), "Month View"); KConfigGroup agendaViewConfig(config(), "Agenda View"); const QByteArray agendaIconArray = agendaViewConfig.readEntry("agendaViewItemIcons", agendaViewIconDefaults()); const QByteArray monthIconArray = monthViewConfig.readEntry("monthViewItemIcons", monthViewIconDefaults()); mAgendaViewIcons = iconArrayToSet(agendaIconArray); mMonthViewIcons = iconArrayToSet(monthIconArray); KConfigSkeleton::usrRead(); } bool BaseConfig::usrSave() { KConfigGroup rColorsConfig(config(), "Resources Colors"); QHash::const_iterator i = mResourceColors.constBegin(); QHash::const_iterator end(mResourceColors.constEnd()); while (i != end) { rColorsConfig.writeEntry(i.key(), i.value()); ++i; } #if 0 if (mRememberRetrievePw) { config()->writeEntry("Retrieve Server Password", KStringHandler::obscure(mRetrievePassword)); } else { config()->deleteEntry("Retrieve Server Password"); } #endif KConfigGroup timeScaleConfig(config(), "Timescale"); timeScaleConfig.writeEntry("Timescale Timezones", timeScaleTimezones()); KConfigGroup monthViewConfig(config(), "Month View"); KConfigGroup agendaViewConfig(config(), "Agenda View"); const QByteArray agendaIconArray = iconSetToArray(mAgendaViewIcons); const QByteArray monthIconArray = iconSetToArray(mMonthViewIcons); agendaViewConfig.writeEntry("agendaViewItemIcons", agendaIconArray); monthViewConfig.writeEntry("monthViewItemIcons", monthIconArray); return KConfigSkeleton::usrSave(); } class Q_DECL_HIDDEN Prefs::Private { public: - Private(Prefs *parent) : mAppConfig(nullptr) + Private(Prefs *parent) + : mAppConfig(nullptr) , q(parent) { } Private(Prefs *parent, KCoreConfigSkeleton *appConfig) : mAppConfig(appConfig) , q(parent) { } KConfigSkeletonItem *appConfigItem(const KConfigSkeletonItem *baseConfigItem) const; void setBool(KCoreConfigSkeleton::ItemBool *baseConfigItem, bool value); bool getBool(const KCoreConfigSkeleton::ItemBool *baseConfigItem) const; void setInt(KCoreConfigSkeleton::ItemInt *baseConfigItem, int value); int getInt(const KCoreConfigSkeleton::ItemInt *baseConfigItem) const; void setString(KCoreConfigSkeleton::ItemString *baseConfigItem, const QString &value); QString getString(const KCoreConfigSkeleton::ItemString *baseConfigItem) const; void setDateTime(KCoreConfigSkeleton::ItemDateTime *baseConfigItem, const QDateTime &value); QDateTime getDateTime(const KCoreConfigSkeleton::ItemDateTime *baseConfigItem) const; void setStringList(KCoreConfigSkeleton::ItemStringList *baseConfigItem, const QStringList &value); QStringList getStringList(const KCoreConfigSkeleton::ItemStringList *baseConfigItem) const; void setColor(KConfigSkeleton::ItemColor *baseConfigItem, const QColor &value); QColor getColor(const KConfigSkeleton::ItemColor *baseConfigItem) const; void setFont(KConfigSkeleton::ItemFont *baseConfigItem, const QFont &value); QFont getFont(const KConfigSkeleton::ItemFont *baseConfigItem) const; public: BaseConfig mBaseConfig; KCoreConfigSkeleton *mAppConfig = nullptr; private: Prefs *q; }; KConfigSkeletonItem *Prefs::Private::appConfigItem( const KConfigSkeletonItem *baseConfigItem) const { Q_ASSERT(baseConfigItem); if (mAppConfig) { return mAppConfig->findItem(baseConfigItem->name()); } return nullptr; } void Prefs::Private::setBool(KCoreConfigSkeleton::ItemBool *baseConfigItem, bool value) { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemBool *item = dynamic_cast(appItem); if (item) { item->setValue(value); } else { qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Bool"; } } else { baseConfigItem->setValue(value); } } bool Prefs::Private::getBool(const KCoreConfigSkeleton::ItemBool *baseConfigItem) const { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemBool *item = dynamic_cast(appItem); if (item) { return item->value(); } qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Bool"; } return baseConfigItem->value(); } void Prefs::Private::setInt(KCoreConfigSkeleton::ItemInt *baseConfigItem, int value) { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemInt *item = dynamic_cast(appItem); if (item) { item->setValue(value); } else { qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Int"; } } else { baseConfigItem->setValue(value); } } int Prefs::Private::getInt(const KCoreConfigSkeleton::ItemInt *baseConfigItem) const { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemInt *item = dynamic_cast(appItem); if (item) { return item->value(); } qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Int"; } return baseConfigItem->value(); } void Prefs::Private::setString(KCoreConfigSkeleton::ItemString *baseConfigItem, const QString &value) { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemString *item = dynamic_cast(appItem); if (item) { item->setValue(value); } else { qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type String"; } } else { baseConfigItem->setValue(value); } } QString Prefs::Private::getString(const KCoreConfigSkeleton::ItemString *baseConfigItem) const { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemString *item = dynamic_cast(appItem); if (item) { return item->value(); } qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type String"; } return baseConfigItem->value(); } void Prefs::Private::setDateTime(KCoreConfigSkeleton::ItemDateTime *baseConfigItem, const QDateTime &value) { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemDateTime *item = dynamic_cast(appItem); if (item) { item->setValue(value); } else { qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type DateTime"; } } else { baseConfigItem->setValue(value); } } QDateTime Prefs::Private::getDateTime( const KCoreConfigSkeleton::ItemDateTime *baseConfigItem) const { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemDateTime *item = dynamic_cast(appItem); if (item) { return item->value(); } qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type DateTime"; } return baseConfigItem->value(); } void Prefs::Private::setStringList(KCoreConfigSkeleton::ItemStringList *baseConfigItem, const QStringList &value) { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemStringList *item = dynamic_cast(appItem); if (item) { item->setValue(value); } else { qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type StringList"; } } else { baseConfigItem->setValue(value); } } QStringList Prefs::Private::getStringList( const KCoreConfigSkeleton::ItemStringList *baseConfigItem) const { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KCoreConfigSkeleton::ItemStringList *item = dynamic_cast(appItem); if (item) { return item->value(); } qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type StringList"; } return baseConfigItem->value(); } void Prefs::Private::setColor(KConfigSkeleton::ItemColor *baseConfigItem, const QColor &value) { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KConfigSkeleton::ItemColor *item = dynamic_cast(appItem); if (item) { item->setValue(value); } else { qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Color"; } } else { baseConfigItem->setValue(value); } } QColor Prefs::Private::getColor(const KConfigSkeleton::ItemColor *baseConfigItem) const { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KConfigSkeleton::ItemColor *item = dynamic_cast(appItem); if (item) { return item->value(); } qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Color"; } return baseConfigItem->value(); } void Prefs::Private::setFont(KConfigSkeleton::ItemFont *baseConfigItem, const QFont &value) { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KConfigSkeleton::ItemFont *item = dynamic_cast(appItem); if (item) { item->setValue(value); } else { qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Font"; } } else { baseConfigItem->setValue(value); } } QFont Prefs::Private::getFont(const KConfigSkeleton::ItemFont *baseConfigItem) const { KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem); if (appItem) { KConfigSkeleton::ItemFont *item = dynamic_cast(appItem); if (item) { return item->value(); } qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Font"; } return baseConfigItem->value(); } Prefs::Prefs() : d(new Private(this)) { // necessary to use CollectionColorAttribute in the EventViews::resourceColor and EventViews::setResourceColor Akonadi::AttributeFactory::registerAttribute(); } Prefs::Prefs(KCoreConfigSkeleton *appConfig) : d(new Private(this, appConfig)) { // necessary to use CollectionColorAttribute in the EventViews::resourceColor and EventViews::setResourceColor Akonadi::AttributeFactory::registerAttribute(); } Prefs::~Prefs() { delete d; } void Prefs::readConfig() { d->mBaseConfig.load(); if (d->mAppConfig) { d->mAppConfig->load(); } } void Prefs::writeConfig() { d->mBaseConfig.save(); if (d->mAppConfig) { d->mAppConfig->save(); } } void Prefs::setMarcusBainsShowSeconds(bool showSeconds) { d->setBool(d->mBaseConfig.marcusBainsShowSecondsItem(), showSeconds); } bool Prefs::marcusBainsShowSeconds() const { return d->getBool(d->mBaseConfig.marcusBainsShowSecondsItem()); } void Prefs::setAgendaMarcusBainsLineLineColor(const QColor &color) { d->setColor(d->mBaseConfig.agendaMarcusBainsLineLineColorItem(), color); } QColor Prefs::agendaMarcusBainsLineLineColor() const { return d->getColor(d->mBaseConfig.agendaMarcusBainsLineLineColorItem()); } void Prefs::setMarcusBainsEnabled(bool enabled) { d->setBool(d->mBaseConfig.marcusBainsEnabledItem(), enabled); } bool Prefs::marcusBainsEnabled() const { return d->getBool(d->mBaseConfig.marcusBainsEnabledItem()); } void Prefs::setAgendaMarcusBainsLineFont(const QFont &font) { d->setFont(d->mBaseConfig.agendaMarcusBainsLineFontItem(), font); } QFont Prefs::agendaMarcusBainsLineFont() const { return d->getFont(d->mBaseConfig.agendaMarcusBainsLineFontItem()); } void Prefs::setHourSize(int size) { d->setInt(d->mBaseConfig.hourSizeItem(), size); } int Prefs::hourSize() const { return d->getInt(d->mBaseConfig.hourSizeItem()); } void Prefs::setDayBegins(const QDateTime &dateTime) { d->setDateTime(d->mBaseConfig.dayBeginsItem(), dateTime); } QDateTime Prefs::dayBegins() const { return d->getDateTime(d->mBaseConfig.dayBeginsItem()); } +void Prefs::setFirstDayOfWeek(const int day) +{ + d->setInt(d->mBaseConfig.weekStartDayItem(), day - 1); +} + +int Prefs::firstDayOfWeek() const +{ + return d->getInt(d->mBaseConfig.weekStartDayItem()) + 1; +} + void Prefs::setWorkingHoursStart(const QDateTime &dateTime) { d->setDateTime(d->mBaseConfig.workingHoursStartItem(), dateTime); } QDateTime Prefs::workingHoursStart() const { return d->getDateTime(d->mBaseConfig.workingHoursStartItem()); } void Prefs::setWorkingHoursEnd(const QDateTime &dateTime) { d->setDateTime(d->mBaseConfig.workingHoursEndItem(), dateTime); } QDateTime Prefs::workingHoursEnd() const { return d->getDateTime(d->mBaseConfig.workingHoursEndItem()); } void Prefs::setSelectionStartsEditor(bool startEditor) { d->setBool(d->mBaseConfig.selectionStartsEditorItem(), startEditor); } bool Prefs::selectionStartsEditor() const { return d->getBool(d->mBaseConfig.selectionStartsEditorItem()); } void Prefs::setAgendaGridWorkHoursBackgroundColor(const QColor &color) { d->setColor(d->mBaseConfig.agendaGridWorkHoursBackgroundColorItem(), color); } QColor Prefs::agendaGridWorkHoursBackgroundColor() const { return d->getColor(d->mBaseConfig.agendaGridWorkHoursBackgroundColorItem()); } void Prefs::setAgendaGridHighlightColor(const QColor &color) { d->setColor(d->mBaseConfig.agendaGridHighlightColorItem(), color); } QColor Prefs::agendaGridHighlightColor() const { return d->getColor(d->mBaseConfig.agendaGridHighlightColorItem()); } void Prefs::setAgendaGridBackgroundColor(const QColor &color) { d->setColor(d->mBaseConfig.agendaGridBackgroundColorItem(), color); } QColor Prefs::agendaGridBackgroundColor() const { return d->getColor(d->mBaseConfig.agendaGridBackgroundColorItem()); } void Prefs::setEnableAgendaItemIcons(bool enable) { d->setBool(d->mBaseConfig.enableAgendaItemIconsItem(), enable); } bool Prefs::enableAgendaItemIcons() const { return d->getBool(d->mBaseConfig.enableAgendaItemIconsItem()); } void Prefs::setTodosUseCategoryColors(bool useColors) { d->setBool(d->mBaseConfig.todosUseCategoryColorsItem(), useColors); } bool Prefs::todosUseCategoryColors() const { return d->getBool(d->mBaseConfig.todosUseCategoryColorsItem()); } void Prefs::setAgendaHolidaysBackgroundColor(const QColor &color) const { d->setColor(d->mBaseConfig.agendaHolidaysBackgroundColorItem(), color); } QColor Prefs::agendaHolidaysBackgroundColor() const { return d->getColor(d->mBaseConfig.agendaHolidaysBackgroundColorItem()); } void Prefs::setAgendaViewColors(int colors) { d->setInt(d->mBaseConfig.agendaViewColorsItem(), colors); } int Prefs::agendaViewColors() const { return d->getInt(d->mBaseConfig.agendaViewColorsItem()); } void Prefs::setAgendaViewFont(const QFont &font) { d->setFont(d->mBaseConfig.agendaViewFontItem(), font); } QFont Prefs::agendaViewFont() const { return d->getFont(d->mBaseConfig.agendaViewFontItem()); } void Prefs::setMonthViewFont(const QFont &font) { d->setFont(d->mBaseConfig.monthViewFontItem(), font); } QFont Prefs::monthViewFont() const { return d->getFont(d->mBaseConfig.monthViewFontItem()); } QColor Prefs::monthGridBackgroundColor() const { return d->getColor(d->mBaseConfig.monthGridBackgroundColorItem()); } void Prefs::setMonthGridBackgroundColor(const QColor &color) { d->setColor(d->mBaseConfig.monthGridBackgroundColorItem(), color); } QColor Prefs::monthGridWorkHoursBackgroundColor() const { return d->getColor(d->mBaseConfig.monthGridWorkHoursBackgroundColorItem()); } void Prefs::monthGridWorkHoursBackgroundColor(const QColor &color) { d->setColor(d->mBaseConfig.monthGridWorkHoursBackgroundColorItem(), color); } int Prefs::monthViewColors() const { return d->getInt(d->mBaseConfig.monthViewColorsItem()); } void Prefs::setMonthViewColors(int colors) const { d->setInt(d->mBaseConfig.monthViewColorsItem(), colors); } void Prefs::setEnableMonthItemIcons(bool enable) { d->setBool(d->mBaseConfig.enableMonthItemIconsItem(), enable); } bool Prefs::enableMonthItemIcons() const { return d->getBool(d->mBaseConfig.enableMonthItemIconsItem()); } bool Prefs::showTimeInMonthView() const { return d->getBool(d->mBaseConfig.showTimeInMonthViewItem()); } void Prefs::setShowTimeInMonthView(bool show) { d->setBool(d->mBaseConfig.showTimeInMonthViewItem(), show); } bool Prefs::showTodosMonthView() const { return d->getBool(d->mBaseConfig.showTodosMonthViewItem()); } void Prefs::setShowTodosMonthView(bool enable) { d->setBool(d->mBaseConfig.showTodosMonthViewItem(), enable); } bool Prefs::showJournalsMonthView() const { return d->getBool(d->mBaseConfig.showJournalsMonthViewItem()); } void Prefs::setShowJournalsMonthView(bool enable) { d->setBool(d->mBaseConfig.showJournalsMonthViewItem(), enable); } bool Prefs::fullViewMonth() const { return d->getBool(d->mBaseConfig.fullViewMonthItem()); } void Prefs::setFullViewMonth(bool fullView) { d->setBool(d->mBaseConfig.fullViewMonthItem(), fullView); } bool Prefs::sortCompletedTodosSeparately() const { return d->getBool(d->mBaseConfig.sortCompletedTodosSeparatelyItem()); } void Prefs::setSortCompletedTodosSeparately(bool enable) { d->setBool(d->mBaseConfig.sortCompletedTodosSeparatelyItem(), enable); } void Prefs::setEnableToolTips(bool enable) { d->setBool(d->mBaseConfig.enableToolTipsItem(), enable); } bool Prefs::enableToolTips() const { return d->getBool(d->mBaseConfig.enableToolTipsItem()); } void Prefs::setShowTodosAgendaView(bool show) { d->setBool(d->mBaseConfig.showTodosAgendaViewItem(), show); } bool Prefs::showTodosAgendaView() const { return d->getBool(d->mBaseConfig.showTodosAgendaViewItem()); } void Prefs::setAgendaTimeLabelsFont(const QFont &font) { d->setFont(d->mBaseConfig.agendaTimeLabelsFontItem(), font); } QFont Prefs::agendaTimeLabelsFont() const { return d->getFont(d->mBaseConfig.agendaTimeLabelsFontItem()); } QTimeZone Prefs::timeZone() const { return QTimeZone::systemTimeZone(); } bool Prefs::colorAgendaBusyDays() const { return d->getBool(d->mBaseConfig.colorBusyDaysEnabledItem()); } bool Prefs::colorMonthBusyDays() const { return d->getBool(d->mBaseConfig.colorMonthBusyDaysEnabledItem()); } QColor Prefs::viewBgBusyColor() const { return d->getColor(d->mBaseConfig.viewBgBusyColorItem()); } void Prefs::setViewBgBusyColor(const QColor &color) { d->mBaseConfig.mViewBgBusyColor = color; } QColor Prefs::holidayColor() const { return d->getColor(d->mBaseConfig.holidayColorItem()); } void Prefs::setHolidayColor(const QColor &color) { d->mBaseConfig.mHolidayColor = color; } QColor Prefs::agendaViewBackgroundColor() const { return d->getColor(d->mBaseConfig.agendaBgColorItem()); } void Prefs::setAgendaViewBackgroundColor(const QColor &color) { d->mBaseConfig.mAgendaBgColor = color; } QColor Prefs::workingHoursColor() const { return d->getColor(d->mBaseConfig.workingHoursColorItem()); } void Prefs::setWorkingHoursColor(const QColor &color) { d->mBaseConfig.mWorkingHoursColor = color; } QColor Prefs::todoDueTodayColor() const { return d->getColor(d->mBaseConfig.todoDueTodayColorItem()); } void Prefs::setTodoDueTodayColor(const QColor &color) { d->mBaseConfig.mTodoDueTodayColor = color; } QColor Prefs::todoOverdueColor() const { return d->getColor(d->mBaseConfig.todoOverdueColorItem()); } void Prefs::setTodoOverdueColor(const QColor &color) { d->mBaseConfig.mTodoOverdueColor = color; } void Prefs::setColorAgendaBusyDays(bool enable) { d->mBaseConfig.mColorBusyDaysEnabled = enable; } void Prefs::setColorMonthBusyDays(bool enable) { d->mBaseConfig.mColorMonthBusyDaysEnabled = enable; } void Prefs::setResourceColor(const QString &cal, const QColor &color) { d->mBaseConfig.setResourceColor(cal, color); } #define USE_RANDOM void Prefs::createNewColor(QColor &defColor, int seed) { #ifdef USE_RANDOM Q_UNUSED(seed); QColor col = QColor(qrand() % 256, qrand() % 256, qrand() % 256); defColor = col; #else int h, s, v; defColor.getHsv(&h, &s, &v); h = (seed % 12) * 30; s -= s * static_cast(((seed / 12) % 2) * 0.5); defColor.setHsv(h, s, v); #endif } QColor Prefs::resourceColorKnown(const QString &cal) const { QColor color; - if (!cal.isEmpty() - && d->mBaseConfig.mResourceColors.contains(cal)) { + if (!cal.isEmpty() && d->mBaseConfig.mResourceColors.contains(cal)) { color = d->mBaseConfig.mResourceColors.value(cal); } return color; } QColor Prefs::resourceColor(const QString &cal) { if (cal.isEmpty()) { return d->mBaseConfig.mDefaultResourceColor; } QColor color = resourceColorKnown(cal); // assign default color if enabled - if (!color.isValid() - && d->getBool(d->mBaseConfig.assignDefaultResourceColorsItem())) { + if (!color.isValid() && d->getBool(d->mBaseConfig.assignDefaultResourceColorsItem())) { QColor defColor(0x37, 0x7A, 0xBC); const int seed = d->getInt(d->mBaseConfig.defaultResourceColorSeedItem()); const QStringList colors = d->getStringList(d->mBaseConfig.defaultResourceColorsItem()); if (seed > 0 && seed - 1 < (int)colors.size()) { defColor = QColor(colors[seed - 1]); } else { createNewColor(defColor, seed); } d->setInt(d->mBaseConfig.defaultResourceColorSeedItem(), (seed + 1)); d->mBaseConfig.setResourceColor(cal, defColor); color = d->mBaseConfig.mResourceColors[cal]; } if (color.isValid()) { return color; } else { return d->mBaseConfig.mDefaultResourceColor; } } QStringList Prefs::timeScaleTimezones() const { return d->mBaseConfig.timeScaleTimezones(); } void Prefs::setTimeScaleTimezones(const QStringList &list) { d->mBaseConfig.setTimeScaleTimezones(list); } KConfigSkeleton::ItemFont *Prefs::fontItem(const QString &name) const { KConfigSkeletonItem *item = d->mAppConfig ? d->mAppConfig->findItem(name) : nullptr; if (!item) { item = d->mBaseConfig.findItem(name); } return dynamic_cast(item); } QStringList Prefs::selectedPlugins() const { return d->mBaseConfig.mSelectedPlugins; } QStringList Prefs::decorationsAtAgendaViewTop() const { return d->mBaseConfig.decorationsAtAgendaViewTop(); } QStringList Prefs::decorationsAtAgendaViewBottom() const { return d->mBaseConfig.decorationsAtAgendaViewBottom(); } void Prefs::setSelectedPlugins(const QStringList &plugins) { d->mBaseConfig.setSelectedPlugins(plugins); } void Prefs::setDecorationsAtAgendaViewTop(const QStringList &decorations) { d->mBaseConfig.setDecorationsAtAgendaViewTop(decorations); } void Prefs::setDecorationsAtAgendaViewBottom(const QStringList &decorations) { d->mBaseConfig.setDecorationsAtAgendaViewBottom(decorations); } QSet Prefs::agendaViewIcons() const { return d->mBaseConfig.mAgendaViewIcons; } void Prefs::setAgendaViewIcons(const QSet &icons) { d->mBaseConfig.mAgendaViewIcons = icons; } QSet Prefs::monthViewIcons() const { return d->mBaseConfig.mMonthViewIcons; } void Prefs::setMonthViewIcons(const QSet &icons) { d->mBaseConfig.mMonthViewIcons = icons; } void Prefs::setFlatListTodo(bool enable) { d->mBaseConfig.mFlatListTodo = enable; } bool Prefs::flatListTodo() const { return d->mBaseConfig.mFlatListTodo; } void Prefs::setFullViewTodo(bool enable) { d->mBaseConfig.mFullViewTodo = enable; } bool Prefs::fullViewTodo() const { return d->mBaseConfig.mFullViewTodo; } bool Prefs::enableTodoQuickSearch() const { return d->mBaseConfig.mEnableTodoQuickSearch; } void Prefs::setEnableTodoQuickSearch(bool enable) { d->mBaseConfig.mEnableTodoQuickSearch = enable; } bool Prefs::enableQuickTodo() const { return d->mBaseConfig.mEnableQuickTodo; } void Prefs::setEnableQuickTodo(bool enable) { d->mBaseConfig.mEnableQuickTodo = enable; } bool Prefs::highlightTodos() const { return d->mBaseConfig.mHighlightTodos; } void Prefs::setHighlightTodos(bool highlight) { d->mBaseConfig.mHighlightTodos = highlight; } KConfig *Prefs::config() const { return d->mAppConfig ? d->mAppConfig->config() : d->mBaseConfig.config(); } diff --git a/src/prefs.h b/src/prefs.h index 903eab2..a075a61 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -1,224 +1,229 @@ /* Copyright (c) 2000,2001 Cornelius Schumacher Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Author: Kevin Krammer, krake@kdab.com 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. */ #ifndef EVENTVIEWS_PREFS_H #define EVENTVIEWS_PREFS_H #include "eventviews_export.h" #include "eventview.h" #include + #include namespace EventViews { + class EVENTVIEWS_EXPORT Prefs { public: /** Creates an instance of Prefs with just base config */ Prefs(); /** Creates an instance of Prefs with base config and application override config The passed @p appConfig will be queried for matching items whenever one of the accessors is called. If one is found it is used for setting/getting the value otherwise the one from the eventviews base config is used. */ explicit Prefs(KCoreConfigSkeleton *appConfig); ~Prefs(); void readConfig(); void writeConfig(); public: void setMarcusBainsShowSeconds(bool showSeconds); bool marcusBainsShowSeconds() const; void setAgendaMarcusBainsLineLineColor(const QColor &color); QColor agendaMarcusBainsLineLineColor() const; void setMarcusBainsEnabled(bool enabled); bool marcusBainsEnabled() const; void setAgendaMarcusBainsLineFont(const QFont &font); QFont agendaMarcusBainsLineFont() const; void setHourSize(int size); int hourSize() const; void setDayBegins(const QDateTime &dateTime); QDateTime dayBegins() const; void setWorkingHoursStart(const QDateTime &dateTime); QDateTime workingHoursStart() const; void setWorkingHoursEnd(const QDateTime &dateTime); QDateTime workingHoursEnd() const; void setSelectionStartsEditor(bool startEditor); bool selectionStartsEditor() const; void setAgendaGridWorkHoursBackgroundColor(const QColor &color); QColor agendaGridWorkHoursBackgroundColor() const; void setAgendaGridHighlightColor(const QColor &color); QColor agendaGridHighlightColor() const; void setAgendaGridBackgroundColor(const QColor &color); QColor agendaGridBackgroundColor() const; void setEnableAgendaItemIcons(bool enable); bool enableAgendaItemIcons() const; void setTodosUseCategoryColors(bool useColors); bool todosUseCategoryColors() const; void setAgendaHolidaysBackgroundColor(const QColor &color) const; QColor agendaHolidaysBackgroundColor() const; void setAgendaViewColors(int colors); int agendaViewColors() const; void setAgendaViewFont(const QFont &font); QFont agendaViewFont() const; void setMonthViewFont(const QFont &font); QFont monthViewFont() const; QColor monthGridBackgroundColor() const; void setMonthGridBackgroundColor(const QColor &color); QColor monthGridWorkHoursBackgroundColor() const; void monthGridWorkHoursBackgroundColor(const QColor &color); void setMonthViewColors(int colors) const; int monthViewColors() const; bool enableMonthItemIcons() const; void setEnableMonthItemIcons(bool enable); bool showTimeInMonthView() const; void setShowTimeInMonthView(bool show); bool showTodosMonthView() const; void setShowTodosMonthView(bool show); bool showJournalsMonthView() const; void setShowJournalsMonthView(bool show); bool fullViewMonth() const; void setFullViewMonth(bool fullView); bool sortCompletedTodosSeparately() const; void setSortCompletedTodosSeparately(bool sort); void setEnableToolTips(bool enable); bool enableToolTips() const; void setShowTodosAgendaView(bool show); bool showTodosAgendaView() const; void setAgendaTimeLabelsFont(const QFont &font); QFont agendaTimeLabelsFont() const; KConfigSkeleton::ItemFont *fontItem(const QString &name) const; void setResourceColor(const QString &, const QColor &); QColor resourceColor(const QString &); QColor resourceColorKnown(const QString &) const; QTimeZone timeZone() const; QStringList timeScaleTimezones() const; void setTimeScaleTimezones(const QStringList &list); QStringList selectedPlugins() const; void setSelectedPlugins(const QStringList &); QStringList decorationsAtAgendaViewTop() const; void setDecorationsAtAgendaViewTop(const QStringList &); QStringList decorationsAtAgendaViewBottom() const; void setDecorationsAtAgendaViewBottom(const QStringList &); bool colorAgendaBusyDays() const; void setColorAgendaBusyDays(bool enable); bool colorMonthBusyDays() const; void setColorMonthBusyDays(bool enable); QColor viewBgBusyColor() const; void setViewBgBusyColor(const QColor &); QColor holidayColor() const; void setHolidayColor(const QColor &color); QColor agendaViewBackgroundColor() const; void setAgendaViewBackgroundColor(const QColor &color); QColor workingHoursColor() const; void setWorkingHoursColor(const QColor &color); QColor todoDueTodayColor() const; void setTodoDueTodayColor(const QColor &color); QColor todoOverdueColor() const; void setTodoOverdueColor(const QColor &color); QSet agendaViewIcons() const; void setAgendaViewIcons(const QSet &icons); QSet monthViewIcons() const; void setMonthViewIcons(const QSet &icons); void setFlatListTodo(bool); bool flatListTodo() const; void setFullViewTodo(bool); bool fullViewTodo() const; bool enableTodoQuickSearch() const; void setEnableTodoQuickSearch(bool enable); bool enableQuickTodo() const; void setEnableQuickTodo(bool enable); bool highlightTodos() const; void setHighlightTodos(bool); + void setFirstDayOfWeek(const int day); + int firstDayOfWeek() const; + KConfig *config() const; void createNewColor(QColor &defColor, int seed); private: class Private; Private *const d; }; typedef QSharedPointer PrefsPtr; } #endif