diff --git a/CMakeLists.txt b/CMakeLists.txt index fad42f7..4581cdf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,95 +1,95 @@ cmake_minimum_required(VERSION 3.5) set(PIM_VERSION "5.11.90") project(calendarsupport VERSION ${PIM_VERSION}) set(KF5_MIN_VERSION "5.60.0") find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) set(LIBRARY_NAMELINK) include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(ECMGeneratePriFile) include(ECMSetupVersion) include(FeatureSummary) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMQtDeclareLoggingCategory) include(ECMAddTests) set(CALENDARSUPPORT_LIB_VERSION ${PIM_VERSION}) set(AKONADI_MIMELIB_VERSION "5.11.80") set(KDEPIM_LIB_VERSION "5.11.80") set(QT_REQUIRED_VERSION "5.11.0") set(KMIME_LIB_VERSION "5.11.80") set(CALENDARUTILS_LIB_VERSION "5.11.80") -set(KCALENDARCORE_LIB_VERSION "5.11.80") +set(KCALENDARCORE_LIB_VERSION "5.11.90") set(IDENTITYMANAGEMENT_LIB_VERSION "5.11.80") set(AKONADICALENDAR_LIB_VERSION "5.11.80") set(PIMCOMMON_LIB_VERSION "5.11.80") set(AKONADI_VERSION "5.11.80") find_package(KF5Akonadi ${AKONADI_VERSION} CONFIG REQUIRED) find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets Test UiTools PrintSupport) find_package(KF5I18n ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5IconThemes ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5GuiAddons ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5KIO ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Mime ${KMIME_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiMime ${AKONADI_MIMELIB_VERSION} CONFIG REQUIRED) find_package(KF5Codecs ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5CalendarUtils ${CALENDARUTILS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5CalendarCore ${KCALENDARCORE_LIB_VERSION} CONFIG REQUIRED) find_package(KF5IdentityManagement ${IDENTITYMANAGEMENT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Holidays ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiCalendar ${AKONADICALENDAR_LIB_VERSION} CONFIG REQUIRED) find_package(KF5PimCommon ${PIMCOMMON_LIB_VERSION} CONFIG REQUIRED) find_package(KF5KdepimDBusInterfaces ${KDEPIM_LIB_VERSION} CONFIG REQUIRED) ecm_setup_version(PROJECT VARIABLE_PREFIX CALENDARSUPPORT VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/calendarsupport_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5CalendarSupportConfigVersion.cmake" SOVERSION 5 ) ########### Targets ########### add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) ########### CMake Config Files ########### set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5CalendarSupport") configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KF5CalendarSupportConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KF5CalendarSupportConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KF5CalendarSupportConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KF5CalendarSupportConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(EXPORT KF5CalendarSupportTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5CalendarSupportTargets.cmake NAMESPACE KF5::) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/calendarsupport_version.h DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5} COMPONENT Devel ) add_definitions(-DQT_NO_FOREACH) add_subdirectory(src) install(FILES calendarsupport.categories calendarsupport.renamecategories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/attachmenthandler.cpp b/src/attachmenthandler.cpp index 38b3d13..f0b59e1 100644 --- a/src/attachmenthandler.cpp +++ b/src/attachmenthandler.cpp @@ -1,330 +1,330 @@ /* Copyright (c) 2010 Klarlvdalens Datakonsult AB, a KDAB Group company Author: Allen Winter Copyright (C) 2014 Sergio Martins This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** @file This file is part of the API for handling calendar data and provides static functions for dealing with calendar incidence attachments. @brief vCalendar/iCalendar attachment handling. @author Allen Winter \ */ #include "attachmenthandler.h" #include "calendarsupport_debug.h" #include "calendarsupport/utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include -using namespace KCalCore; +using namespace KCalendarCore; using namespace Akonadi; namespace CalendarSupport { struct ReceivedInfo { QString uid; QString attachmentName; }; class Q_DECL_HIDDEN AttachmentHandler::Private { public: Private(QWidget *parent) : mParent(parent) { } QMap mJobToReceivedInfo; QPointer mParent; }; AttachmentHandler::AttachmentHandler(QWidget *parent) : QObject(parent) , d(new Private(parent)) { } AttachmentHandler::~AttachmentHandler() { delete d; } Attachment AttachmentHandler::find(const QString &attachmentName, const Incidence::Ptr &incidence) { if (!incidence) { return Attachment(); } // get the attachment by name from the incidence const Attachment::List as = incidence->attachments(); Attachment a; if (!as.isEmpty()) { Attachment::List::ConstIterator it; Attachment::List::ConstIterator end(as.constEnd()); for (it = as.constBegin(); it != end; ++it) { if ((*it).label() == attachmentName) { a = *it; break; } } } if (a.isEmpty()) { KMessageBox::error( d->mParent, i18n("No attachment named \"%1\" found in the incidence.", attachmentName)); return Attachment(); } if (a.isUri()) { auto job = KIO::stat(QUrl(a.uri()), KIO::StatJob::SourceSide, 0); KJobWidgets::setWindow(job, d->mParent); if (!job->exec()) { KMessageBox::sorry( d->mParent, i18n("The attachment \"%1\" is a web link that is inaccessible from this computer. ", QUrl::fromPercentEncoding(a.uri().toLatin1()))); return Attachment(); } } return a; } Attachment AttachmentHandler::find(const QString &attachmentName, const ScheduleMessage::Ptr &message) { if (!message) { return Attachment(); } Incidence::Ptr incidence = message->event().dynamicCast(); if (!incidence) { KMessageBox::error( d->mParent, i18n("The calendar invitation stored in this email message is broken in some way. " "Unable to continue.")); return Attachment(); } return find(attachmentName, incidence); } static QTemporaryFile *s_tempFile = nullptr; static QUrl tempFileForAttachment(const Attachment &attachment) { QUrl url; QMimeDatabase db; QStringList patterns = db.mimeTypeForName(attachment.mimeType()).globPatterns(); if (!patterns.empty()) { s_tempFile = new QTemporaryFile(QDir::tempPath() + QLatin1String( "/attachementview_XXXXXX") + patterns.first().remove(QLatin1Char('*'))); } else { s_tempFile = new QTemporaryFile(); } s_tempFile->setAutoRemove(false); s_tempFile->open(); s_tempFile->setPermissions(QFile::ReadUser); s_tempFile->write(QByteArray::fromBase64(attachment.data())); s_tempFile->close(); QFile tf(s_tempFile->fileName()); if (tf.size() != attachment.size()) { //whoops. failed to write the entire attachment. return an invalid URL. delete s_tempFile; s_tempFile = nullptr; return url; } url.setPath(s_tempFile->fileName()); return url; } bool AttachmentHandler::view(const Attachment &attachment) { if (attachment.isEmpty()) { return false; } bool stat = true; if (attachment.isUri()) { QDesktopServices::openUrl(QUrl(attachment.uri())); } else { // put the attachment in a temporary file and launch it QUrl tempUrl = tempFileForAttachment(attachment); if (tempUrl.isValid()) { KRun::RunFlags flags; flags |= KRun::DeleteTemporaryFiles; flags |= KRun::RunExecutables; stat = KRun::runUrl(tempUrl, attachment.mimeType(), nullptr, flags); } else { stat = false; KMessageBox::error( d->mParent, i18n("Unable to create a temporary file for the attachment.")); } delete s_tempFile; s_tempFile = nullptr; } return stat; } bool AttachmentHandler::view(const QString &attachmentName, const Incidence::Ptr &incidence) { return view(find(attachmentName, incidence)); } void AttachmentHandler::view(const QString &attachmentName, const QString &uid) { Item item; item.setGid(uid); ItemFetchJob *job = new ItemFetchJob(item); connect(job, &ItemFetchJob::result, this, &AttachmentHandler::slotFinishView); ReceivedInfo info; info.attachmentName = attachmentName; info.uid = uid; d->mJobToReceivedInfo[job] = info; } bool AttachmentHandler::view(const QString &attachmentName, const ScheduleMessage::Ptr &message) { return view(find(attachmentName, message)); } bool AttachmentHandler::saveAs(const Attachment &attachment) { // get the saveas file name const QString saveAsFile = QFileDialog::getSaveFileName(d->mParent, i18n( "Save Attachment"), attachment.label()); if (saveAsFile.isEmpty()) { return false; } bool stat = false; if (attachment.isUri()) { // save the attachment url auto job = KIO::file_copy(QUrl(attachment.uri()), QUrl::fromLocalFile(saveAsFile)); stat = job->exec(); } else { // put the attachment in a temporary file and save it QUrl tempUrl = tempFileForAttachment(attachment); if (tempUrl.isValid()) { auto job = KIO::file_copy(tempUrl, QUrl::fromLocalFile(saveAsFile)); stat = job->exec(); if (!stat && job->error()) { KMessageBox::error(d->mParent, job->errorString()); } } else { stat = false; KMessageBox::error( d->mParent, i18n("Unable to create a temporary file for the attachment.")); } delete s_tempFile; s_tempFile = nullptr; } return stat; } bool AttachmentHandler::saveAs(const QString &attachmentName, const Incidence::Ptr &incidence) { return saveAs(find(attachmentName, incidence)); } void AttachmentHandler::saveAs(const QString &attachmentName, const QString &uid) { Item item; item.setGid(uid); ItemFetchJob *job = new ItemFetchJob(item); connect(job, &ItemFetchJob::result, this, &AttachmentHandler::slotFinishView); ReceivedInfo info; info.attachmentName = attachmentName; info.uid = uid; d->mJobToReceivedInfo[job] = info; } bool AttachmentHandler::saveAs(const QString &attachmentName, const ScheduleMessage::Ptr &message) { return saveAs(find(attachmentName, message)); } void AttachmentHandler::slotFinishSaveAs(KJob *job) { ReceivedInfo info = d->mJobToReceivedInfo[job]; bool success = false; if (job->error() != 0) { ItemFetchJob *fetchJob = qobject_cast(job); const Item::List items = fetchJob->items(); if (!items.isEmpty()) { Incidence::Ptr incidence = CalendarSupport::incidence(items.first()); success = incidence && saveAs(info.attachmentName, incidence); } else { qCWarning(CALENDARSUPPORT_LOG) << Q_FUNC_INFO << "No item found"; } } else { qCWarning(CALENDARSUPPORT_LOG) << Q_FUNC_INFO << "Job error:" << job->errorString(); } Q_EMIT saveAsFinished(info.uid, info.attachmentName, success); d->mJobToReceivedInfo.remove(job); } void AttachmentHandler::slotFinishView(KJob *job) { ReceivedInfo info = d->mJobToReceivedInfo[job]; bool success = false; if (job->error()) { ItemFetchJob *fetchJob = qobject_cast(job); const Item::List items = fetchJob->items(); if (!items.isEmpty()) { Incidence::Ptr incidence = CalendarSupport::incidence(items.first()); success = incidence && view(info.attachmentName, incidence); } else { qCWarning(CALENDARSUPPORT_LOG) << Q_FUNC_INFO << "No item found"; } } else { qCWarning(CALENDARSUPPORT_LOG) << Q_FUNC_INFO << "Job error:" << job->errorString(); } Q_EMIT viewFinished(info.uid, info.attachmentName, success); d->mJobToReceivedInfo.remove(job); } } // namespace CalendarSupport diff --git a/src/attachmenthandler.h b/src/attachmenthandler.h index 532cff2..bd3e636 100644 --- a/src/attachmenthandler.h +++ b/src/attachmenthandler.h @@ -1,176 +1,176 @@ /* Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** @file This file is part of the API for handling calendar data and provides static functions for dealing with calendar incidence attachments. @author Allen Winter \ */ #ifndef CALENDARSUPPORT_ATTACHMENTHANDLER_H #define CALENDARSUPPORT_ATTACHMENTHANDLER_H -#include -#include -#include +#include +#include +#include #include class KJob; class QWidget; namespace CalendarSupport { /** @brief Provides methods to handle incidence attachments. Includes functions to view and save attachments. */ class AttachmentHandler : public QObject { Q_OBJECT public: /** * Constructs an AttachmentHandler. * @param parent is the parent widget for the dialogs used by this class. */ explicit AttachmentHandler(QWidget *parent); ~AttachmentHandler(); /** * Finds the attachment in the user's calendar, by @p attachmentName and @p incidence. * * @param attachmentName is the name of the attachment * @param incidence is a pointer to a valid Incidence object containing the attachment. * @return a pointer to the Attachment object located; 0 if no such attachment could be found. */ - KCalCore::Attachment find(const QString &attachmentName, - const KCalCore::Incidence::Ptr &incidence); + KCalendarCore::Attachment find(const QString &attachmentName, + const KCalendarCore::Incidence::Ptr &incidence); /** * Finds the attachment in the user's calendar, by @p attachmentName and a scheduler message; * in other words, this function is intended to retrieve attachments from calendar invitations. * * @param attachmentName is the name of the attachment * @param message is a pointer to a valid ScheduleMessage object containing the attachment. * @return a pointer to the Attachment object located; 0 if no such attachment could be found. */ - KCalCore::Attachment find(const QString &attachmentName, - const KCalCore::ScheduleMessage::Ptr &message); + KCalendarCore::Attachment find(const QString &attachmentName, + const KCalendarCore::ScheduleMessage::Ptr &message); /** * Launches a viewer on the specified attachment. * * @param attachment is a pointer to a valid Attachment object. * @return true if the viewer program successfully launched; false otherwise. */ - bool view(const KCalCore::Attachment &attachment); + bool view(const KCalendarCore::Attachment &attachment); /** * Launches a viewer on the specified attachment. * * @param attachmentName is the name of the attachment * @param incidence is a pointer to a valid Incidence object containing the attachment. * @return true if the attachment could be found and the viewer program successfully launched; * false otherwise. */ - bool view(const QString &attachmentName, const KCalCore::Incidence::Ptr &incidence); + bool view(const QString &attachmentName, const KCalendarCore::Incidence::Ptr &incidence); /** Launches a viewer on the specified attachment. @param attachmentName is the name of the attachment @param uid is a QString containing a UID of the incidence containing the attachment. This function is async and will return immediately. Listen to signal viewFinished() if you're interested on the success of this operation. */ void view(const QString &attachmentName, const QString &uid); /** Launches a viewer on the specified attachment. @param attachmentName is the name of the attachment @param message is a pointer to a valid ScheduleMessage object containing the attachment. @return true if the attachment could be found and the viewer program successfully launched; false otherwise. */ - bool view(const QString &attachmentName, const KCalCore::ScheduleMessage::Ptr &message); + bool view(const QString &attachmentName, const KCalendarCore::ScheduleMessage::Ptr &message); /** Saves the specified attachment to a file of the user's choice. @param attachment is a pointer to a valid Attachment object. @return true if the save operation was successful; false otherwise. */ - bool saveAs(const KCalCore::Attachment &attachment); + bool saveAs(const KCalendarCore::Attachment &attachment); /** Saves the specified attachment to a file of the user's choice. @param attachmentName is the name of the attachment @param incidence is a pointer to a valid Incidence object containing the attachment. @return true if the attachment could be found and the save operation was successful; false otherwise. */ - bool saveAs(const QString &attachmentName, const KCalCore::Incidence::Ptr &incidence); + bool saveAs(const QString &attachmentName, const KCalendarCore::Incidence::Ptr &incidence); /** Saves the specified attachment to a file of the user's choice. @param attachmentName is the name of the attachment @param uid is a QString containing a UID of the incidence containing the attachment. This function is async, it will return immediately. Listen to signal saveAsFinished() if you're interested on the success of this operation. */ void saveAs(const QString &attachmentName, const QString &uid); /** Saves the specified attachment to a file of the user's choice. @param attachmentName is the name of the attachment @param message is a pointer to a valid ScheduleMessage object containing the attachment. @return true if the attachment could be found and the save operation was successful; false otherwise. */ - bool saveAs(const QString &attachmentName, const KCalCore::ScheduleMessage::Ptr &message); + bool saveAs(const QString &attachmentName, const KCalendarCore::ScheduleMessage::Ptr &message); Q_SIGNALS: void viewFinished(const QString &uid, const QString &attachmentName, bool success); void saveAsFinished(const QString &uid, const QString &attachmentName, bool success); private: void slotFinishView(KJob *job); void slotFinishSaveAs(KJob *job); //@cond PRIVATE class Private; Private *const d; //@endcond }; // class AttachmentHandler } // namespace CalendarSupport #endif diff --git a/src/calendarsingleton.cpp b/src/calendarsingleton.cpp index 895f7b9..201e0a9 100644 --- a/src/calendarsingleton.cpp +++ b/src/calendarsingleton.cpp @@ -1,46 +1,46 @@ /* Copyright (c) 2013 Sérgio Martins 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 "calendarsingleton.h" #include "kcalprefs.h" #include -#include +#include /** * Singleton is implemented through qApp parenting because we can't rely on K_GLOBAL_STATIC. * * QWidgets and QAbstractItemModels can't be global because their dtor depends on other globals * and the order of global destruction is undefined. */ Akonadi::ETMCalendar::Ptr CalendarSupport::calendarSingleton(bool createIfNull) { static Akonadi::ETMCalendar::Ptr calendar; if (!calendar && createIfNull) { calendar = Akonadi::ETMCalendar::Ptr(new Akonadi::ETMCalendar()); calendar->setCollectionFilteringEnabled(false); - calendar->setOwner(KCalCore::Person(KCalPrefs::instance()->fullName(), KCalPrefs::instance()->email())); + calendar->setOwner(KCalendarCore::Person(KCalPrefs::instance()->fullName(), KCalPrefs::instance()->email())); } return calendar; } diff --git a/src/calendarutils.cpp b/src/calendarutils.cpp index da633fc..32347cd 100644 --- a/src/calendarutils.cpp +++ b/src/calendarutils.cpp @@ -1,268 +1,268 @@ /* Copyright (C) 2010 Bertjan Broeksema 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. */ // NOTE: The code of the following methods is taken from // kdepim/korganizer/calendarview.cpp: // - makeIndependent (was incidence_unsub) // - makeChildrenIndependent #include "calendarutils.h" #include "utils.h" -#include +#include #include #include #include #include #include "calendarsupport_debug.h" using namespace CalendarSupport; -using namespace KCalCore; +using namespace KCalendarCore; /// CalendarUtilsPrivate struct MultiChange { Akonadi::Item parent; QVector children; bool success; explicit MultiChange(const Akonadi::Item &parent = Akonadi::Item()) : parent(parent) , success(true) { } bool inProgress() const { return parent.isValid() && !children.isEmpty(); } }; namespace CalendarSupport { class CalendarUtilsPrivate { public: /// Methods CalendarUtilsPrivate(const Akonadi::ETMCalendar::Ptr &calendar, CalendarUtils *qq); void handleChangeFinish(int changeId, const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString); - bool purgeCompletedSubTodos(const KCalCore::Todo::Ptr &todo, bool &allPurged); + bool purgeCompletedSubTodos(const KCalendarCore::Todo::Ptr &todo, bool &allPurged); /// Members Akonadi::ETMCalendar::Ptr mCalendar; Akonadi::IncidenceChanger *mChanger = nullptr; MultiChange mMultiChange; private: CalendarUtils *const q_ptr; Q_DECLARE_PUBLIC(CalendarUtils) }; } CalendarUtilsPrivate::CalendarUtilsPrivate(const Akonadi::ETMCalendar::Ptr &calendar, CalendarUtils *qq) : mCalendar(calendar) , mChanger(new Akonadi::IncidenceChanger(qq)) , q_ptr(qq) { Q_Q(CalendarUtils); Q_ASSERT(mCalendar); q->connect(mChanger, SIGNAL(modifyFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)), SLOT(handleChangeFinish(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString))); } void CalendarUtilsPrivate::handleChangeFinish(int, const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString) { Q_Q(CalendarUtils); const bool success = resultCode == Akonadi::IncidenceChanger::ResultCodeSuccess; if (mMultiChange.inProgress()) { mMultiChange.children.remove(mMultiChange.children.indexOf(item.id())); mMultiChange.success = mMultiChange.success && success; // Are we still in progress? if (!mMultiChange.inProgress()) { const Akonadi::Item parent = mMultiChange.parent; const bool success = mMultiChange.success; // Reset the multi change. mMultiChange = MultiChange(); Q_ASSERT(!mMultiChange.inProgress()); if (success) { qCDebug(CALENDARSUPPORT_LOG) << "MultiChange finished"; Q_EMIT q->actionFinished(parent); } else { qCDebug(CALENDARSUPPORT_LOG) << "MultiChange failed"; Q_EMIT q->actionFailed(parent, QString()); } } } else { if (success) { qCDebug(CALENDARSUPPORT_LOG) << "Change finished"; Q_EMIT q->actionFinished(item); } else { qCDebug(CALENDARSUPPORT_LOG) << "Change failed"; Q_EMIT q->actionFailed(Akonadi::Item(), errorString); } } } -bool CalendarUtilsPrivate::purgeCompletedSubTodos(const KCalCore::Todo::Ptr &todo, bool &allPurged) +bool CalendarUtilsPrivate::purgeCompletedSubTodos(const KCalendarCore::Todo::Ptr &todo, bool &allPurged) { if (!todo) { return true; } bool deleteThisTodo = true; const Akonadi::Item::List subTodos = mCalendar->childItems(todo->uid()); for (const Akonadi::Item &item : subTodos) { if (CalendarSupport::hasTodo(item)) { deleteThisTodo - &= purgeCompletedSubTodos(item.payload(), allPurged); + &= purgeCompletedSubTodos(item.payload(), allPurged); } } if (deleteThisTodo) { if (todo->isCompleted()) { if (!mChanger->deleteIncidence(mCalendar->item(todo), nullptr)) { allPurged = false; } } else { deleteThisTodo = false; } } else { if (todo->isCompleted()) { allPurged = false; } } return deleteThisTodo; } /// CalendarUtils CalendarUtils::CalendarUtils(const Akonadi::ETMCalendar::Ptr &calendar, QObject *parent) : QObject(parent) , d_ptr(new CalendarUtilsPrivate(calendar, this)) { Q_ASSERT(calendar); } CalendarUtils::~CalendarUtils() { delete d_ptr; } Akonadi::ETMCalendar::Ptr CalendarUtils::calendar() const { Q_D(const CalendarUtils); return d->mCalendar; } bool CalendarUtils::makeIndependent(const Akonadi::Item &item) { Q_D(CalendarUtils); Q_ASSERT(item.isValid()); if (d->mMultiChange.inProgress() && !d->mMultiChange.children.contains(item.id())) { return false; } const Incidence::Ptr inc = CalendarSupport::incidence(item); if (!inc || inc->relatedTo().isEmpty()) { return false; } Incidence::Ptr oldInc(inc->clone()); inc->setRelatedTo(QString()); return d->mChanger->modifyIncidence(item, oldInc); } bool CalendarUtils::makeChildrenIndependent(const Akonadi::Item &item) { Q_D(CalendarUtils); Q_ASSERT(item.isValid()); if (d->mMultiChange.inProgress()) { return false; } const Incidence::Ptr inc = CalendarSupport::incidence(item); const Akonadi::Item::List subIncs = d->mCalendar->childItems(item.id()); if (!inc || subIncs.isEmpty()) { return false; } d->mMultiChange = MultiChange(item); bool allStarted = true; for (const Akonadi::Item &subInc : qAsConst(subIncs)) { d->mMultiChange.children.append(subInc.id()); allStarted = allStarted && makeIndependent(subInc); } Q_ASSERT(allStarted); // OKay, maybe we should not assert here, but one or // changes could have been started, so just returning // false isn't suitable either. return true; } /// Todo specific methods. void CalendarUtils::purgeCompletedTodos() { Q_D(CalendarUtils); bool allDeleted = true; // startMultiModify( i18n( "Purging completed to-dos" ) ); - KCalCore::Todo::List todos = calendar()->rawTodos(); - KCalCore::Todo::List rootTodos; + KCalendarCore::Todo::List todos = calendar()->rawTodos(); + KCalendarCore::Todo::List rootTodos; - for (const KCalCore::Todo::Ptr &todo : qAsConst(todos)) { + for (const KCalendarCore::Todo::Ptr &todo : qAsConst(todos)) { if (todo && todo->relatedTo().isEmpty()) { // top level todo //REVIEW(AKONADI_PORT) rootTodos.append(todo); } } // now that we have a list of all root todos, check them and their children - for (const KCalCore::Todo::Ptr &todo : qAsConst(rootTodos)) { + for (const KCalendarCore::Todo::Ptr &todo : qAsConst(rootTodos)) { d->purgeCompletedSubTodos(todo, allDeleted); } // endMultiModify(); if (!allDeleted) { KMessageBox::information( nullptr, i18nc("@info", "Unable to purge to-dos with uncompleted children."), i18nc("@title:window", "Delete To-do"), QStringLiteral("UncompletedChildrenPurgeTodos")); } } #include "moc_calendarutils.cpp" diff --git a/src/eventarchiver.cpp b/src/eventarchiver.cpp index 0e72431..eab24ab 100644 --- a/src/eventarchiver.cpp +++ b/src/eventarchiver.cpp @@ -1,349 +1,349 @@ /* Copyright (c) 2000,2001 Cornelius Schumacher Copyright (c) 2004 David Faure Copyright (C) 2004 Reinhold Kainhofer 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 "eventarchiver.h" #include "kcalprefs.h" #include "utils.h" #include -#include -#include -#include +#include +#include +#include #include #include "calendarsupport_debug.h" #include #include #include #include #include #include #include #include -using namespace KCalCore; +using namespace KCalendarCore; using namespace KCalUtils; using namespace CalendarSupport; class GroupwareScoppedDisabler { public: GroupwareScoppedDisabler(Akonadi::IncidenceChanger *changer) : m_changer(changer) { m_wasEnabled = m_changer->groupwareCommunication(); m_changer->setGroupwareCommunication(false); } ~GroupwareScoppedDisabler() { m_changer->setGroupwareCommunication(m_wasEnabled); } bool m_wasEnabled; Akonadi::IncidenceChanger *m_changer = nullptr; }; EventArchiver::EventArchiver(QObject *parent) : QObject(parent) { } EventArchiver::~EventArchiver() { } void EventArchiver::runOnce(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, const QDate &limitDate, QWidget *widget) { run(calendar, changer, limitDate, widget, true, true); } void EventArchiver::runAuto(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, QWidget *widget, bool withGUI) { QDate limitDate(QDate::currentDate()); const int expiryTime = KCalPrefs::instance()->mExpiryTime; switch (KCalPrefs::instance()->mExpiryUnit) { case KCalPrefs::UnitDays: // Days limitDate = limitDate.addDays(-expiryTime); break; case KCalPrefs::UnitWeeks: // Weeks limitDate = limitDate.addDays(-expiryTime * 7); break; case KCalPrefs::UnitMonths: // Months limitDate = limitDate.addMonths(-expiryTime); break; default: return; } run(calendar, changer, limitDate, widget, withGUI, false); } void EventArchiver::run(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, const QDate &limitDate, QWidget *widget, bool withGUI, bool errorIfNone) { GroupwareScoppedDisabler disabler(changer); // Disables groupware communication temporarily // We need to use rawEvents, otherwise events hidden by filters will not be archived. - KCalCore::Event::List events; - KCalCore::Todo::List todos; - KCalCore::Journal::List journals; + KCalendarCore::Event::List events; + KCalendarCore::Todo::List todos; + KCalendarCore::Journal::List journals; if (KCalPrefs::instance()->mArchiveEvents) { events = calendar->rawEvents( QDate(1769, 12, 1), // #29555, also advertised by the "limitDate not included" in the class docu limitDate.addDays(-1), QTimeZone::systemTimeZone(), true); } if (KCalPrefs::instance()->mArchiveTodos) { - const KCalCore::Todo::List rawTodos = calendar->rawTodos(); + const KCalendarCore::Todo::List rawTodos = calendar->rawTodos(); - for (const KCalCore::Todo::Ptr &todo : rawTodos) { + for (const KCalendarCore::Todo::Ptr &todo : rawTodos) { Q_ASSERT(todo); if (isSubTreeComplete(calendar, todo, limitDate)) { todos.append(todo); } } } - const KCalCore::Incidence::List incidences = calendar->mergeIncidenceList(events, todos, + const KCalendarCore::Incidence::List incidences = calendar->mergeIncidenceList(events, todos, journals); qCDebug(CALENDARSUPPORT_LOG) << "archiving incidences before" << limitDate << " ->" << incidences.count() << " incidences found."; if (incidences.isEmpty()) { if (withGUI && errorIfNone) { KMessageBox::information(widget, i18n("There are no items before %1", QLocale::system().toString(limitDate, QLocale::ShortFormat)), QStringLiteral("ArchiverNoIncidences")); } return; } switch (KCalPrefs::instance()->mArchiveAction) { case KCalPrefs::actionDelete: deleteIncidences(changer, limitDate, widget, calendar->itemList(incidences), withGUI); break; case KCalPrefs::actionArchive: archiveIncidences(calendar, changer, limitDate, widget, incidences, withGUI); break; } } void EventArchiver::deleteIncidences(Akonadi::IncidenceChanger *changer, const QDate &limitDate, QWidget *widget, const Akonadi::Item::List &items, bool withGUI) { QStringList incidenceStrs; Akonadi::Item::List::ConstIterator it; Akonadi::Item::List::ConstIterator end(items.constEnd()); incidenceStrs.reserve(items.count()); for (it = items.constBegin(); it != end; ++it) { incidenceStrs.append(CalendarSupport::incidence(*it)->summary()); } if (withGUI) { const int result = KMessageBox::warningContinueCancelList( widget, i18n("Delete all items before %1 without saving?\n" "The following items will be deleted:", QLocale::system().toString(limitDate, QLocale::ShortFormat)), incidenceStrs, i18n("Delete Old Items"), KStandardGuiItem::del()); if (result != KMessageBox::Continue) { return; } } changer->deleteIncidences(items, /**parent=*/ widget); // TODO: Q_EMIT only after hearing back from incidence changer Q_EMIT eventsDeleted(); } void EventArchiver::archiveIncidences(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, const QDate &limitDate, - QWidget *widget, const KCalCore::Incidence::List &incidences, + QWidget *widget, const KCalendarCore::Incidence::List &incidences, bool withGUI) { Q_UNUSED(limitDate); Q_UNUSED(withGUI); FileStorage storage(calendar); QString tmpFileName; // KSaveFile cannot be called with an open File Handle on Windows. // So we use QTemporaryFile only to generate a unique filename // and then close/delete the file again. This file must be deleted // here. { QTemporaryFile tmpFile; tmpFile.open(); tmpFileName = tmpFile.fileName(); } // Save current calendar to disk storage.setFileName(tmpFileName); if (!storage.save()) { qCDebug(CALENDARSUPPORT_LOG) << "Can't save calendar to temp file"; return; } // Duplicate current calendar by loading in new calendar object MemoryCalendar::Ptr archiveCalendar(new MemoryCalendar(QTimeZone::systemTimeZone())); FileStorage archiveStore(archiveCalendar); archiveStore.setFileName(tmpFileName); ICalFormat *format = new ICalFormat(); archiveStore.setSaveFormat(format); if (!archiveStore.load()) { qCDebug(CALENDARSUPPORT_LOG) << "Can't load calendar from temp file"; QFile::remove(tmpFileName); return; } // Strip active events from calendar so that only events to be archived // remain. This is not really efficient, but there is no other easy way. QStringList uids; Incidence::List allIncidences = archiveCalendar->rawIncidences(); uids.reserve(incidences.count()); - for (const KCalCore::Incidence::Ptr &incidence : qAsConst(incidences)) { + for (const KCalendarCore::Incidence::Ptr &incidence : qAsConst(incidences)) { uids.append(incidence->uid()); } - for (const KCalCore::Incidence::Ptr &incidence : qAsConst(allIncidences)) { + for (const KCalendarCore::Incidence::Ptr &incidence : qAsConst(allIncidences)) { if (!uids.contains(incidence->uid())) { archiveCalendar->deleteIncidence(incidence); } } // Get or create the archive file QUrl archiveURL(KCalPrefs::instance()->mArchiveFile); QString archiveFile; QTemporaryFile downloadTempFile; bool fileExists = false; if (archiveURL.isLocalFile()) { fileExists = QFile::exists(archiveURL.toLocalFile()); } else { auto job = KIO::stat(archiveURL, KIO::StatJob::SourceSide, 0); KJobWidgets::setWindow(job, widget); fileExists = job->exec(); } if (fileExists) { archiveFile = downloadTempFile.fileName(); auto job = KIO::file_copy(archiveURL, QUrl::fromLocalFile(archiveFile)); KJobWidgets::setWindow(job, widget); if (!job->exec()) { qCDebug(CALENDARSUPPORT_LOG) << "Can't download archive file"; QFile::remove(tmpFileName); return; } // Merge with events to be archived. archiveStore.setFileName(archiveFile); if (!archiveStore.load()) { qCDebug(CALENDARSUPPORT_LOG) << "Can't merge with archive file"; QFile::remove(tmpFileName); return; } } else { archiveFile = tmpFileName; } // Save archive calendar if (!archiveStore.save()) { QString errmess; if (format->exception()) { errmess = Stringify::errorMessage(*format->exception()); } else { errmess = i18nc("save failure cause unknown", "Reason unknown"); } KMessageBox::error(widget, i18n("Cannot write archive file %1. %2", archiveStore.fileName(), errmess)); QFile::remove(tmpFileName); return; } // Upload if necessary QUrl srcUrl = QUrl::fromLocalFile(archiveFile); if (srcUrl != archiveURL) { auto job = KIO::file_copy(QUrl::fromLocalFile(archiveFile), archiveURL); KJobWidgets::setWindow(job, widget); if (!job->exec()) { KMessageBox::error(widget, i18n("Cannot write archive. %1", job->errorString())); QFile::remove(tmpFileName); return; } } QFile::remove(tmpFileName); // We don't want it to ask to send invitations for each incidence. changer->startAtomicOperation(i18n("Archiving events")); // Delete archived events from calendar const Akonadi::Item::List items = calendar->itemList(incidences); for (const Akonadi::Item &item : items) { changer->deleteIncidence(item, widget); } // TODO: Q_EMIT only after hearing back from incidence changer changer->endAtomicOperation(); Q_EMIT eventsDeleted(); } bool EventArchiver::isSubTreeComplete(const Akonadi::ETMCalendar::Ptr &calendar, const Todo::Ptr &todo, const QDate &limitDate, QStringList checkedUids) const { if (!todo->isCompleted() || todo->completed().date() >= limitDate) { return false; } // This QList is only to prevent infinit recursion if (checkedUids.contains(todo->uid())) { // Probably will never happen, calendar.cpp checks for this qCWarning(CALENDARSUPPORT_LOG) << "To-do hierarchy loop detected!"; return false; } checkedUids.append(todo->uid()); - const KCalCore::Incidence::List childs = calendar->childIncidences(todo->uid()); - for (const KCalCore::Incidence::Ptr &incidence : childs) { - const Todo::Ptr t = incidence.dynamicCast(); + const KCalendarCore::Incidence::List childs = calendar->childIncidences(todo->uid()); + for (const KCalendarCore::Incidence::Ptr &incidence : childs) { + const Todo::Ptr t = incidence.dynamicCast(); if (t && !isSubTreeComplete(calendar, t, limitDate, checkedUids)) { return false; } } return true; } diff --git a/src/eventarchiver.h b/src/eventarchiver.h index b4416f1..d0b5f66 100644 --- a/src/eventarchiver.h +++ b/src/eventarchiver.h @@ -1,109 +1,109 @@ /* Copyright (c) 2000,2001 Cornelius Schumacher Copyright (c) 2004 David Faure Copyright (C) 2004 Reinhold Kainhofer 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 CALENDARSUPPORT_EVENTARCHIVER_H #define CALENDARSUPPORT_EVENTARCHIVER_H #include "calendarsupport_export.h" #include #include -#include -#include +#include +#include #include class QDate; namespace Akonadi { class IncidenceChanger; } namespace CalendarSupport { /** * This class handles expiring and archiving of events. * It is used directly by the archivedialog, and it is also * triggered by actionmanager's timer for auto-archiving. * * The settings are not held in this class, but directly in KOPrefs (from korganizer.kcfg) * Be sure to set mArchiveAction and mArchiveFile before a manual archiving * mAutoArchive is used for auto archiving. */ class CALENDARSUPPORT_EXPORT EventArchiver : public QObject { Q_OBJECT public: explicit EventArchiver(QObject *parent = nullptr); ~EventArchiver() override; /** * Delete or archive events once * @param calendar the calendar to archive * @param limitDate all events *before* the limitDate (not included) will be deleted/archived. * @param widget parent widget for message boxes * Confirmation and "no events to process" dialogs will be shown */ void runOnce(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, const QDate &limitDate, QWidget *widget); /** * Delete or archive events. This is called regularly, when auto-archiving * is enabled * @param calendar the calendar to archive * @param widget parent widget for message boxes * @param withGUI whether this is called from the dialog, so message boxes should be shown. * Note that error dialogs like "cannot save" are shown even if from this method, so widget * should be set in all cases. */ void runAuto(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, QWidget *widget, bool withGUI); Q_SIGNALS: void eventsDeleted(); private: void run(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, const QDate &limitDate, QWidget *widget, bool withGUI, bool errorIfNone); void deleteIncidences(Akonadi::IncidenceChanger *changer, const QDate &limitDate, QWidget *widget, const Akonadi::Item::List &items, bool withGUI); void archiveIncidences(const Akonadi::ETMCalendar::Ptr &calendar, Akonadi::IncidenceChanger *changer, const QDate &limitDate, - QWidget *widget, const KCalCore::Incidence::List &incidences, + QWidget *widget, const KCalendarCore::Incidence::List &incidences, bool withGUI); /** * Checks if all to-dos under @p todo and including @p todo were completed before @p limitDate. * If not, we can't archive this to-do. * @param todo root of the sub-tree we are checking * @param limitDate * @param checkedUids used internaly to prevent infinit recursion due to invalid calendar files */ bool isSubTreeComplete(const Akonadi::ETMCalendar::Ptr &calendar, - const KCalCore::Todo::Ptr &todo, const QDate &limitDate, + const KCalendarCore::Todo::Ptr &todo, const QDate &limitDate, QStringList checkedUids = QStringList()) const; }; } #endif // EVENTARCHIVER_H diff --git a/src/freebusymodel/autotests/testfreebusyitemmodel.cpp b/src/freebusymodel/autotests/testfreebusyitemmodel.cpp index 4dfca61..05d9405 100644 --- a/src/freebusymodel/autotests/testfreebusyitemmodel.cpp +++ b/src/freebusymodel/autotests/testfreebusyitemmodel.cpp @@ -1,243 +1,243 @@ /* Copyright (C) 2010 Casey Link Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "testfreebusyitemmodel.h" #include "modeltest.h" #include "../freebusyitemmodel.h" #include "../freebusyitem.h" -#include +#include #include using namespace CalendarSupport; // Workaround QTBUG-51789 causing a crash when QtWebEngineWidgets // is linked into a QCoreApplication. QTEST_GUILESS_MAIN(FreeBusyItemModelTest) void FreeBusyItemModelTest::testModelValidity() { FreeBusyItemModel *model = new FreeBusyItemModel(this); new ModelTest(model, this); QVERIFY(model->rowCount() == 0); const QDateTime dt1(QDate(2010, 7, 24), QTime(7, 0, 0), Qt::UTC); const QDateTime dt2(QDate(2010, 7, 24), QTime(10, 0, 0), Qt::UTC); - KCalCore::Attendee a1(QStringLiteral("fred"), QStringLiteral( "fred@example.com")); - KCalCore::FreeBusy::Ptr fb1(new KCalCore::FreeBusy()); + KCalendarCore::Attendee a1(QStringLiteral("fred"), QStringLiteral( "fred@example.com")); + KCalendarCore::FreeBusy::Ptr fb1(new KCalendarCore::FreeBusy()); - fb1->addPeriod(dt1, KCalCore::Duration(60 * 60)); - fb1->addPeriod(dt2, KCalCore::Duration(60 * 60)); + fb1->addPeriod(dt1, KCalendarCore::Duration(60 * 60)); + fb1->addPeriod(dt2, KCalendarCore::Duration(60 * 60)); FreeBusyItem::Ptr item1(new FreeBusyItem(a1, nullptr)); item1->setFreeBusy(fb1); model->addItem(item1); QVERIFY(model->rowCount() == 1); QVERIFY(model->containsAttendee(a1)); QModelIndex i = model->index(0, 0); QCOMPARE(a1.fullName(), model->data(i, Qt::DisplayRole).toString()); QCOMPARE(a1, - model->data(i, FreeBusyItemModel::AttendeeRole).value()); + model->data(i, FreeBusyItemModel::AttendeeRole).value()); QCOMPARE(item1->freeBusy(), - model->data(i, FreeBusyItemModel::FreeBusyRole).value()); + model->data(i, FreeBusyItemModel::FreeBusyRole).value()); QCOMPARE(model->rowCount(i), 2); model->removeRow(0); QVERIFY(model->rowCount() == 0); model->addItem(item1); QVERIFY(model->rowCount() == 1); model->removeAttendee(a1); QVERIFY(model->rowCount() == 0); model->addItem(item1); QVERIFY(model->rowCount() == 1); model->removeItem(item1); QVERIFY(model->rowCount() == 0); model->addItem(item1); QVERIFY(model->rowCount() == 1); model->clear(); QVERIFY(model->rowCount() == 0); } void FreeBusyItemModelTest::testModelValidity2() { FreeBusyItemModel *model = new FreeBusyItemModel(this); new ModelTest(model, this); const QDateTime dt1(QDate(2010, 7, 24), QTime(7, 0, 0), Qt::UTC); const QDateTime dt2(QDate(2010, 7, 24), QTime(10, 0, 0), Qt::UTC); const QDateTime dt3(QDate(2010, 7, 24), QTime(12, 0, 0), Qt::UTC); const QDateTime dt4(QDate(2010, 7, 24), QTime(14, 0, 0), Qt::UTC); - KCalCore::Attendee a1(QStringLiteral("fred"), QStringLiteral( "fred@example.com")); - KCalCore::Attendee a2(QStringLiteral("joe"), QStringLiteral( "joe@example.com")); - KCalCore::Attendee a3(QStringLiteral("max"), QStringLiteral( "max@example.com")); - KCalCore::FreeBusy::Ptr fb1(new KCalCore::FreeBusy()); - KCalCore::FreeBusy::Ptr fb2(new KCalCore::FreeBusy()); - KCalCore::FreeBusy::Ptr fb3(new KCalCore::FreeBusy()); + KCalendarCore::Attendee a1(QStringLiteral("fred"), QStringLiteral( "fred@example.com")); + KCalendarCore::Attendee a2(QStringLiteral("joe"), QStringLiteral( "joe@example.com")); + KCalendarCore::Attendee a3(QStringLiteral("max"), QStringLiteral( "max@example.com")); + KCalendarCore::FreeBusy::Ptr fb1(new KCalendarCore::FreeBusy()); + KCalendarCore::FreeBusy::Ptr fb2(new KCalendarCore::FreeBusy()); + KCalendarCore::FreeBusy::Ptr fb3(new KCalendarCore::FreeBusy()); - fb1->addPeriod(dt1, KCalCore::Duration(60 * 60)); - fb1->addPeriod(dt2, KCalCore::Duration(60 * 60)); + fb1->addPeriod(dt1, KCalendarCore::Duration(60 * 60)); + fb1->addPeriod(dt2, KCalendarCore::Duration(60 * 60)); - fb2->addPeriod(dt1, KCalCore::Duration(60 * 60)); - fb2->addPeriod(dt2, KCalCore::Duration(60 * 60)); - fb2->addPeriod(dt3, KCalCore::Duration(60 * 60)); + fb2->addPeriod(dt1, KCalendarCore::Duration(60 * 60)); + fb2->addPeriod(dt2, KCalendarCore::Duration(60 * 60)); + fb2->addPeriod(dt3, KCalendarCore::Duration(60 * 60)); - fb3->addPeriod(dt1, KCalCore::Duration(60 * 60)); - fb3->addPeriod(dt2, KCalCore::Duration(60 * 60)); - fb3->addPeriod(dt4, KCalCore::Duration(60 * 60 * 2)); + fb3->addPeriod(dt1, KCalendarCore::Duration(60 * 60)); + fb3->addPeriod(dt2, KCalendarCore::Duration(60 * 60)); + fb3->addPeriod(dt4, KCalendarCore::Duration(60 * 60 * 2)); FreeBusyItem::Ptr item1(new FreeBusyItem(a1, nullptr)); item1->setFreeBusy(fb1); FreeBusyItem::Ptr item2(new FreeBusyItem(a2, nullptr)); FreeBusyItem::Ptr item3(new FreeBusyItem(a3, nullptr)); model->addItem(item1); model->addItem(item2); model->addItem(item3); QCOMPARE(model->rowCount(), 3); QVERIFY(model->containsAttendee(a1)); QVERIFY(model->containsAttendee(a2)); QVERIFY(model->containsAttendee(a3)); QModelIndex i1 = model->index(0, 0); QCOMPARE(a1.fullName(), model->data(i1, Qt::DisplayRole).toString()); QCOMPARE(a1, - model->data(i1, FreeBusyItemModel::AttendeeRole).value()); + model->data(i1, FreeBusyItemModel::AttendeeRole).value()); QCOMPARE(item1->freeBusy(), - model->data(i1, FreeBusyItemModel::FreeBusyRole).value()); + model->data(i1, FreeBusyItemModel::FreeBusyRole).value()); QModelIndex i2 = model->index(1, 0); QCOMPARE(a2.fullName(), model->data(i2, Qt::DisplayRole).toString()); QCOMPARE(a2, - model->data(i2, FreeBusyItemModel::AttendeeRole).value()); + model->data(i2, FreeBusyItemModel::AttendeeRole).value()); QVERIFY(model->rowCount(i2) == 0); QVERIFY(model->data(i2, FreeBusyItemModel::FreeBusyRole).isValid() == false); QModelIndex i3 = model->index(2, 0); QCOMPARE(a3.fullName(), model->data(i3, Qt::DisplayRole).toString()); QCOMPARE(a3, - model->data(i3, FreeBusyItemModel::AttendeeRole).value()); + model->data(i3, FreeBusyItemModel::AttendeeRole).value()); QVERIFY(model->rowCount(i3) == 0); QVERIFY(model->data(i3, FreeBusyItemModel::FreeBusyRole).isValid() == false); model->slotInsertFreeBusy(fb2, QStringLiteral("joe@example.com")); QCOMPARE(item2->freeBusy(), - model->data(i2, FreeBusyItemModel::FreeBusyRole).value()); + model->data(i2, FreeBusyItemModel::FreeBusyRole).value()); QVERIFY(model->rowCount(i2) == fb2->fullBusyPeriods().size()); QModelIndex i2_0 = model->index(0, 0, i2); QCOMPARE(fb2->fullBusyPeriods().first(), model->data( - i2_0, FreeBusyItemModel::FreeBusyPeriodRole).value()); + i2_0, FreeBusyItemModel::FreeBusyPeriodRole).value()); QModelIndex i2_1 = model->index(1, 0, i2); QCOMPARE(fb2->fullBusyPeriods().at(1), model->data( - i2_1, FreeBusyItemModel::FreeBusyPeriodRole).value()); + i2_1, FreeBusyItemModel::FreeBusyPeriodRole).value()); QModelIndex i2_2 = model->index(2, 0, i2); QCOMPARE(fb2->fullBusyPeriods().last(), model->data( - i2_2, FreeBusyItemModel::FreeBusyPeriodRole).value()); + i2_2, FreeBusyItemModel::FreeBusyPeriodRole).value()); model->slotInsertFreeBusy(fb3, QStringLiteral("max@example.com")); QCOMPARE(item3->freeBusy(), - model->data(i3, FreeBusyItemModel::FreeBusyRole).value()); + model->data(i3, FreeBusyItemModel::FreeBusyRole).value()); QVERIFY(model->rowCount(i3) == fb3->fullBusyPeriods().size()); QModelIndex i3_0 = model->index(0, 0, i3); QCOMPARE(fb3->fullBusyPeriods().first(), model->data( - i3_0, FreeBusyItemModel::FreeBusyPeriodRole).value()); + i3_0, FreeBusyItemModel::FreeBusyPeriodRole).value()); QModelIndex i3_1 = model->index(1, 0, i3); QCOMPARE(fb3->fullBusyPeriods().at(1), model->data( - i3_1, FreeBusyItemModel::FreeBusyPeriodRole).value()); + i3_1, FreeBusyItemModel::FreeBusyPeriodRole).value()); QModelIndex i3_2 = model->index(2, 0, i3); QCOMPARE(fb3->fullBusyPeriods().last(), model->data( - i3_2, FreeBusyItemModel::FreeBusyPeriodRole).value()); + i3_2, FreeBusyItemModel::FreeBusyPeriodRole).value()); model->removeAttendee(a2); QCOMPARE(2, model->rowCount()); QVERIFY(model->containsAttendee(a1) == true); QVERIFY(model->containsAttendee(a2) == false); QVERIFY(model->containsAttendee(a3) == true); i3_0 = model->index(0, 0, i3); QCOMPARE(fb3->fullBusyPeriods().first(), model->data( - i3_0, FreeBusyItemModel::FreeBusyPeriodRole).value()); + i3_0, FreeBusyItemModel::FreeBusyPeriodRole).value()); i3_1 = model->index(1, 0, i3); QCOMPARE(fb3->fullBusyPeriods().at(1), model->data( - i3_1, FreeBusyItemModel::FreeBusyPeriodRole).value()); + i3_1, FreeBusyItemModel::FreeBusyPeriodRole).value()); i3_2 = model->index(2, 0, i3); QCOMPARE(fb3->fullBusyPeriods().last(), model->data( - i3_2, FreeBusyItemModel::FreeBusyPeriodRole).value()); + i3_2, FreeBusyItemModel::FreeBusyPeriodRole).value()); } void FreeBusyItemModelTest::testInsertFreeBusy() { FreeBusyItemModel *model = new FreeBusyItemModel(this); new ModelTest(model, this); const QDateTime dt1(QDate(2010, 7, 24), QTime(7, 0, 0), Qt::UTC); const QDateTime dt2(QDate(2010, 7, 24), QTime(10, 0, 0), Qt::UTC); - KCalCore::Attendee a1(QStringLiteral("fred"), QStringLiteral( "fred@example.com")); - KCalCore::FreeBusy::Ptr fb1(new KCalCore::FreeBusy()); - fb1->addPeriod(dt1, KCalCore::Duration(60 * 60)); - fb1->addPeriod(dt2, KCalCore::Duration(60 * 60)); + KCalendarCore::Attendee a1(QStringLiteral("fred"), QStringLiteral( "fred@example.com")); + KCalendarCore::FreeBusy::Ptr fb1(new KCalendarCore::FreeBusy()); + fb1->addPeriod(dt1, KCalendarCore::Duration(60 * 60)); + fb1->addPeriod(dt2, KCalendarCore::Duration(60 * 60)); const QDateTime dt3(QDate(2010, 7, 24), QTime(12, 0, 0), Qt::UTC); const QDateTime dt4(QDate(2010, 7, 24), QTime(14, 0, 0), Qt::UTC); - KCalCore::FreeBusy::Ptr fb2(new KCalCore::FreeBusy()); - fb2->addPeriod(dt1, KCalCore::Duration(60 * 60)); - fb2->addPeriod(dt2, KCalCore::Duration(60 * 60)); - fb2->addPeriod(dt3, KCalCore::Duration(60 * 60)); - fb2->addPeriod(dt4, KCalCore::Duration(60 * 60 * 2)); + KCalendarCore::FreeBusy::Ptr fb2(new KCalendarCore::FreeBusy()); + fb2->addPeriod(dt1, KCalendarCore::Duration(60 * 60)); + fb2->addPeriod(dt2, KCalendarCore::Duration(60 * 60)); + fb2->addPeriod(dt3, KCalendarCore::Duration(60 * 60)); + fb2->addPeriod(dt4, KCalendarCore::Duration(60 * 60 * 2)); FreeBusyItem::Ptr item1(new FreeBusyItem(a1, nullptr)); item1->setFreeBusy(fb1); model->addItem(item1); QModelIndex i = model->index(0, 0); QCOMPARE(model->rowCount(i), 2); model->slotInsertFreeBusy(fb2, QStringLiteral("fred@example.com")); QCOMPARE(model->rowCount(i), 4); } diff --git a/src/freebusymodel/autotests/testfreeperiodmodel.cpp b/src/freebusymodel/autotests/testfreeperiodmodel.cpp index 9e1c375..cc0cba6 100644 --- a/src/freebusymodel/autotests/testfreeperiodmodel.cpp +++ b/src/freebusymodel/autotests/testfreeperiodmodel.cpp @@ -1,88 +1,88 @@ /* Copyright (C) 2010 Casey Link Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "testfreeperiodmodel.h" #include "modeltest.h" #include "../freeperiodmodel.h" -#include -#include +#include +#include #include using namespace CalendarSupport; // Workaround QTBUG-51789 causing a crash when QtWebEngineWidgets // is linked into a QCoreApplication. QTEST_GUILESS_MAIN(FreePeriodModelTest) void FreePeriodModelTest::testModelValidity() { FreePeriodModel *model = new FreePeriodModel(this); new ModelTest(model, this); const QDateTime dt1(QDate(2010, 7, 24), QTime(7, 0, 0), Qt::UTC); const QDateTime dt2(QDate(2010, 7, 24), QTime(10, 0, 0), Qt::UTC); - KCalCore::Period::List list; + KCalendarCore::Period::List list; - list << KCalCore::Period(dt1, KCalCore::Duration(60 * 60)); - list << KCalCore::Period(dt2, KCalCore::Duration(60 * 60)); + list << KCalendarCore::Period(dt1, KCalendarCore::Duration(60 * 60)); + list << KCalendarCore::Period(dt2, KCalendarCore::Duration(60 * 60)); QCOMPARE(model->rowCount(), 0); model->slotNewFreePeriods(list); QCOMPARE(model->rowCount(), 2); } void FreePeriodModelTest::testSplitByDay() { FreePeriodModel *model = new FreePeriodModel(this); new ModelTest(model, this); const QDateTime startDt(QDate(2010, 7, 24), QTime(8, 0, 0), Qt::UTC); const QDateTime endDt(QDate(2010, 7, 25), QTime(8, 0, 0), Qt::UTC); - KCalCore::Period::List list; + KCalendarCore::Period::List list; // This period goes from 8am on the 24th to 8am on the 25th - list << KCalCore::Period(startDt, endDt); + list << KCalendarCore::Period(startDt, endDt); QCOMPARE(model->rowCount(), 0); // as part of adding the new periods // the model should split the above period into two // one from 8am-12 on the 24th, and the second from 00-08 on the 25th model->slotNewFreePeriods(list); const QDateTime endPeriod1(QDate(2010, 7, 24), QTime(23, 59, 59, 999), Qt::UTC); const QDateTime startPeriod2(QDate(2010, 7, 25), QTime(0, 0, 0, 0), Qt::UTC); QModelIndex index = model->index(0, 0); - KCalCore::Period period1 - = model->data(index, FreePeriodModel::PeriodRole).value(); + KCalendarCore::Period period1 + = model->data(index, FreePeriodModel::PeriodRole).value(); index = model->index(1, 0); - KCalCore::Period period2 - = model->data(index, FreePeriodModel::PeriodRole).value(); + KCalendarCore::Period period2 + = model->data(index, FreePeriodModel::PeriodRole).value(); QCOMPARE(period1.start(), startDt); QCOMPARE(period1.end(), endPeriod1); QCOMPARE(period2.start(), startPeriod2); QCOMPARE(period2.end(), endDt); } diff --git a/src/freebusymodel/freebusycalendar.cpp b/src/freebusymodel/freebusycalendar.cpp index 854bf73..9531098 100644 --- a/src/freebusymodel/freebusycalendar.cpp +++ b/src/freebusymodel/freebusycalendar.cpp @@ -1,187 +1,187 @@ /* * Copyright 2014 Sandro Knauß * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see . * */ #include "freebusycalendar.h" #include "calendarsupport_debug.h" -#include -#include -#include -#include +#include +#include +#include +#include #include #include using namespace CalendarSupport; class CalendarSupport::FreeBusyCalendarPrivate { public: FreeBusyCalendarPrivate() { } FreeBusyItemModel *mModel = nullptr; - KCalCore::Calendar::Ptr mCalendar; - QMap mFbEvent; + KCalendarCore::Calendar::Ptr mCalendar; + QMap mFbEvent; }; FreeBusyCalendar::FreeBusyCalendar(QObject *parent) : QObject(parent) , d(new CalendarSupport::FreeBusyCalendarPrivate) { d->mCalendar - = KCalCore::Calendar::Ptr(new KCalCore::MemoryCalendar(QTimeZone::systemTimeZone())); + = KCalendarCore::Calendar::Ptr(new KCalendarCore::MemoryCalendar(QTimeZone::systemTimeZone())); qCDebug(CALENDARSUPPORT_LOG) << "creating" << this; } FreeBusyCalendar::~FreeBusyCalendar() { qCDebug(CALENDARSUPPORT_LOG) << "deleting" << this; delete d; } -KCalCore::Calendar::Ptr FreeBusyCalendar::calendar() const +KCalendarCore::Calendar::Ptr FreeBusyCalendar::calendar() const { return d->mCalendar; } FreeBusyItemModel *FreeBusyCalendar::model() const { return d->mModel; } void FreeBusyCalendar::setModel(FreeBusyItemModel *model) { if (model != d->mModel) { if (d->mModel) { disconnect(d->mModel, nullptr, nullptr, nullptr); } d->mModel = model; connect(d->mModel, &QAbstractItemModel::layoutChanged, this, &FreeBusyCalendar::onLayoutChanged); connect(d->mModel, &QAbstractItemModel::modelReset, this, &FreeBusyCalendar::onLayoutChanged); connect(d->mModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &FreeBusyCalendar::onRowsRemoved); connect(d->mModel, &QAbstractItemModel::rowsInserted, this, &FreeBusyCalendar::onRowsInserted); connect(d->mModel, &QAbstractItemModel::dataChanged, this, &FreeBusyCalendar::onRowsChanged); } } void FreeBusyCalendar::deleteAllEvents() { - const KCalCore::Event::List lstEvents = d->mCalendar->events(); - for (const KCalCore::Event::Ptr &event : lstEvents) { + const KCalendarCore::Event::List lstEvents = d->mCalendar->events(); + for (const KCalendarCore::Event::Ptr &event : lstEvents) { d->mCalendar->deleteEvent(event); } } void FreeBusyCalendar::onLayoutChanged() { if (!d->mFbEvent.isEmpty()) { deleteAllEvents(); d->mFbEvent.clear(); for (int i = d->mModel->rowCount() - 1; i >= 0; --i) { QModelIndex parent = d->mModel->index(i, 0); onRowsInserted(parent, 0, d->mModel->rowCount(parent) - 1); } } } void FreeBusyCalendar::onRowsInserted(const QModelIndex &parent, int first, int last) { if (!parent.isValid()) { return; } for (int i = first; i <= last; ++i) { QModelIndex index = d->mModel->index(i, 0, parent); - const KCalCore::FreeBusyPeriod &period = d->mModel->data(index, + const KCalendarCore::FreeBusyPeriod &period = d->mModel->data(index, FreeBusyItemModel::FreeBusyPeriodRole) - .value(); - const KCalCore::FreeBusy::Ptr &fb + .value(); + const KCalendarCore::FreeBusy::Ptr &fb = d->mModel->data(parent, - FreeBusyItemModel::FreeBusyRole).value(); + FreeBusyItemModel::FreeBusyRole).value(); - KCalCore::Event::Ptr inc = KCalCore::Event::Ptr(new KCalCore::Event()); + KCalendarCore::Event::Ptr inc = KCalendarCore::Event::Ptr(new KCalendarCore::Event()); inc->setDtStart(period.start()); inc->setDtEnd(period.end()); inc->setUid(QLatin1String("fb-") + fb->uid() + QLatin1String("-") + QString::number(i)); inc->setCustomProperty("FREEBUSY", "STATUS", QString::number(period.type())); QString summary = period.summary(); if (summary.isEmpty()) { switch (period.type()) { - case KCalCore::FreeBusyPeriod::Free: + case KCalendarCore::FreeBusyPeriod::Free: summary = i18n("Free"); break; - case KCalCore::FreeBusyPeriod::Busy: + case KCalendarCore::FreeBusyPeriod::Busy: summary = i18n("Busy"); break; - case KCalCore::FreeBusyPeriod::BusyUnavailable: + case KCalendarCore::FreeBusyPeriod::BusyUnavailable: summary = i18n("Unavailable"); break; - case KCalCore::FreeBusyPeriod::BusyTentative: + case KCalendarCore::FreeBusyPeriod::BusyTentative: summary = i18n("Tentative"); break; default: summary = i18n("Unknown"); } } inc->setSummary(summary); d->mFbEvent.insert(index, inc); d->mCalendar->addEvent(inc); } } void FreeBusyCalendar::onRowsRemoved(const QModelIndex &parent, int first, int last) { if (!parent.isValid()) { for (int i = first; i <= last; ++i) { QModelIndex index = d->mModel->index(i, 0); onRowsRemoved(index, 0, d->mModel->rowCount(index) - 1); } } else { for (int i = first; i <= last; ++i) { QModelIndex index = d->mModel->index(i, 0, parent); - KCalCore::Event::Ptr inc = d->mFbEvent.take(index); + KCalendarCore::Event::Ptr inc = d->mFbEvent.take(index); d->mCalendar->deleteEvent(inc); } } } void FreeBusyCalendar::onRowsChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { if (!topLeft.parent().isValid()) { return; } for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { QModelIndex index = d->mModel->index(i, 0, topLeft.parent()); - KCalCore::Event::Ptr inc = d->mFbEvent.value(index); + KCalendarCore::Event::Ptr inc = d->mFbEvent.value(index); d->mCalendar->beginChange(inc); d->mCalendar->endChange(inc); } } diff --git a/src/freebusymodel/freebusycalendar.h b/src/freebusymodel/freebusycalendar.h index 1c9b3ae..99e3498 100644 --- a/src/freebusymodel/freebusycalendar.h +++ b/src/freebusymodel/freebusycalendar.h @@ -1,55 +1,55 @@ /* * Copyright 2014 Sandro Knauß * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see . * */ #ifndef FREEBUSYCALENDAR_H #define FREEBUSYCALENDAR_H #include "calendarsupport_export.h" #include "freebusyitemmodel.h" -#include -#include +#include +#include namespace CalendarSupport { class FreeBusyCalendarPrivate; class CALENDARSUPPORT_EXPORT FreeBusyCalendar : public QObject { Q_OBJECT public: explicit FreeBusyCalendar(QObject *parent = nullptr); ~FreeBusyCalendar() override; void setModel(FreeBusyItemModel *model); FreeBusyItemModel *model() const; - KCalCore::Calendar::Ptr calendar() const; + KCalendarCore::Calendar::Ptr calendar() const; private: void onRowsChanged(const QModelIndex &, const QModelIndex &); void onRowsInserted(const QModelIndex &, int, int); void onRowsRemoved(const QModelIndex &, int, int); void onLayoutChanged(); void deleteAllEvents(); FreeBusyCalendarPrivate *const d; }; } #endif // FREEBUSYCALENDAR_H diff --git a/src/freebusymodel/freebusyitem.cpp b/src/freebusymodel/freebusyitem.cpp index 213e155..07761a5 100644 --- a/src/freebusymodel/freebusyitem.cpp +++ b/src/freebusymodel/freebusyitem.cpp @@ -1,87 +1,87 @@ /* Copyright (c) 2000,2001,2004 Cornelius Schumacher Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com Copyright (c) 2010 Andras Mantia Copyright (C) 2010 Casey Link This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "freebusyitem.h" #include using namespace CalendarSupport; -FreeBusyItem::FreeBusyItem(const KCalCore::Attendee &attendee, QWidget *parentWidget) +FreeBusyItem::FreeBusyItem(const KCalendarCore::Attendee &attendee, QWidget *parentWidget) : mAttendee(attendee) , mTimerID(0) , mIsDownloading(false) , mParentWidget(parentWidget) { Q_ASSERT(!attendee.isNull()); - setFreeBusy(KCalCore::FreeBusy::Ptr()); + setFreeBusy(KCalendarCore::FreeBusy::Ptr()); } -KCalCore::Attendee FreeBusyItem::attendee() const +KCalendarCore::Attendee FreeBusyItem::attendee() const { return mAttendee; } -void FreeBusyItem::setFreeBusy(const KCalCore::FreeBusy::Ptr &fb) +void FreeBusyItem::setFreeBusy(const KCalendarCore::FreeBusy::Ptr &fb) { mFreeBusy = fb; mIsDownloading = false; } -KCalCore::FreeBusy::Ptr FreeBusyItem::freeBusy() const +KCalendarCore::FreeBusy::Ptr FreeBusyItem::freeBusy() const { return mFreeBusy; } QString FreeBusyItem::email() const { return mAttendee.email(); } void FreeBusyItem::setUpdateTimerID(int id) { mTimerID = id; } int FreeBusyItem::updateTimerID() const { return mTimerID; } void FreeBusyItem::startDownload(bool forceDownload) { mIsDownloading = true; Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self(); if (!m->retrieveFreeBusy(attendee().email(), forceDownload, mParentWidget)) { mIsDownloading = false; } } void FreeBusyItem::setIsDownloading(bool d) { mIsDownloading = d; } bool FreeBusyItem::isDownloading() const { return mIsDownloading; } diff --git a/src/freebusymodel/freebusyitem.h b/src/freebusymodel/freebusyitem.h index f432a00..d4c13a1 100644 --- a/src/freebusymodel/freebusyitem.h +++ b/src/freebusymodel/freebusyitem.h @@ -1,76 +1,76 @@ /* Copyright (c) 2000,2001,2004 Cornelius Schumacher Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com Copyright (c) 2010 Andras Mantia Copyright (C) 2010 Casey Link This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef INCIDENCEEDITOR_FREEBUSYITEM_H #define INCIDENCEEDITOR_FREEBUSYITEM_H #include "calendarsupport_export.h" -#include +#include namespace CalendarSupport { /** * The FreeBusyItem is the whole line for a given attendee.. */ class CALENDARSUPPORT_EXPORT FreeBusyItem { public: typedef QSharedPointer Ptr; /** * @param parentWidget is passed to Akonadi when fetching free/busy data. */ - FreeBusyItem(const KCalCore::Attendee &attendee, QWidget *parentWidget); + FreeBusyItem(const KCalendarCore::Attendee &attendee, QWidget *parentWidget); ~FreeBusyItem() { } - KCalCore::Attendee attendee() const; - void setFreeBusy(const KCalCore::FreeBusy::Ptr &fb); - KCalCore::FreeBusy::Ptr freeBusy() const; + KCalendarCore::Attendee attendee() const; + void setFreeBusy(const KCalendarCore::FreeBusy::Ptr &fb); + KCalendarCore::FreeBusy::Ptr freeBusy() const; Q_REQUIRED_RESULT QString email() const; void setUpdateTimerID(int id); Q_REQUIRED_RESULT int updateTimerID() const; void startDownload(bool forceDownload); void setIsDownloading(bool d); Q_REQUIRED_RESULT bool isDownloading() const; Q_SIGNALS: - void attendeeChanged(const KCalCore::Attendee &attendee); - void freebusyChanged(const KCalCore::FreeBusy::Ptr fb); + void attendeeChanged(const KCalendarCore::Attendee &attendee); + void freebusyChanged(const KCalendarCore::FreeBusy::Ptr fb); private: - KCalCore::Attendee mAttendee; - KCalCore::FreeBusy::Ptr mFreeBusy; + KCalendarCore::Attendee mAttendee; + KCalendarCore::FreeBusy::Ptr mFreeBusy; // This is used for the update timer int mTimerID; // Only run one download job at a time bool mIsDownloading = false; QWidget *mParentWidget = nullptr; }; } #endif diff --git a/src/freebusymodel/freebusyitemmodel.cpp b/src/freebusymodel/freebusyitemmodel.cpp index b3d45ac..ef9e541 100644 --- a/src/freebusymodel/freebusyitemmodel.cpp +++ b/src/freebusymodel/freebusyitemmodel.cpp @@ -1,425 +1,425 @@ /* Copyright (C) 2010 Casey Link Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "freebusyitemmodel.h" #include #include #include #include using namespace CalendarSupport; class ItemPrivateData { public: ItemPrivateData(ItemPrivateData *parent) : parentItem(parent) { } ~ItemPrivateData() { qDeleteAll(childItems); } ItemPrivateData *child(int row) { return childItems.value(row); } void appendChild(ItemPrivateData *item) { childItems.append(item); } ItemPrivateData *removeChild(int row) { return childItems.takeAt(row); } int childCount() const { return childItems.count(); } int row() const { if (parentItem) { return parentItem->childItems.indexOf(const_cast(this)); } return 0; } ItemPrivateData *parent() { return parentItem; } private: QList childItems; ItemPrivateData *parentItem = nullptr; }; class CalendarSupport::FreeBusyItemModelPrivate { public: FreeBusyItemModelPrivate() : mForceDownload(false) , mRootData(nullptr) { } ~FreeBusyItemModelPrivate() { delete mRootData; } QTimer mReloadTimer; bool mForceDownload = false; QList mFreeBusyItems; ItemPrivateData *mRootData = nullptr; }; FreeBusyItemModel::FreeBusyItemModel(QObject *parent) : QAbstractItemModel(parent) , d(new CalendarSupport::FreeBusyItemModelPrivate) { - qRegisterMetaType(); - qRegisterMetaType("KCalCore::FreeBusy::Ptr"); - qRegisterMetaType("KCalCore::Period"); + qRegisterMetaType(); + qRegisterMetaType("KCalendarCore::FreeBusy::Ptr"); + qRegisterMetaType("KCalendarCore::Period"); Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self(); connect(m, &Akonadi::FreeBusyManager::freeBusyRetrieved, this, &FreeBusyItemModel::slotInsertFreeBusy); connect(&d->mReloadTimer, &QTimer::timeout, this, &FreeBusyItemModel::autoReload); d->mReloadTimer.setSingleShot(true); d->mRootData = new ItemPrivateData(nullptr); } FreeBusyItemModel::~FreeBusyItemModel() { delete d; } QVariant FreeBusyItemModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } ItemPrivateData *data = (ItemPrivateData *)index.internalPointer(); if (data->parent() == d->mRootData) { int row = index.row(); if (row >= d->mFreeBusyItems.size()) { return QVariant(); } switch (role) { case Qt::DisplayRole: return d->mFreeBusyItems.at(row)->attendee().fullName(); case FreeBusyItemModel::AttendeeRole: return QVariant::fromValue(d->mFreeBusyItems.at(row)->attendee()); case FreeBusyItemModel::FreeBusyRole: if (d->mFreeBusyItems.at(row)->freeBusy()) { return QVariant::fromValue(d->mFreeBusyItems.at(row)->freeBusy()); } else { return QVariant(); } default: return QVariant(); } } FreeBusyItem::Ptr fbitem = d->mFreeBusyItems.at(data->parent()->row()); if (!fbitem->freeBusy() || index.row() >= fbitem->freeBusy()->busyPeriods().size()) { return QVariant(); } - KCalCore::FreeBusyPeriod period = fbitem->freeBusy()->fullBusyPeriods().at(index.row()); + KCalendarCore::FreeBusyPeriod period = fbitem->freeBusy()->fullBusyPeriods().at(index.row()); switch (role) { case Qt::DisplayRole: // return something to make modeltest happy return QStringLiteral("%1 - %2"). arg(QLocale().toString(period.start().toLocalTime(), QLocale::ShortFormat), QLocale().toString(period.end().toLocalTime(), QLocale::ShortFormat)); case FreeBusyItemModel::FreeBusyPeriodRole: return QVariant::fromValue(period); default: return QVariant(); } } int FreeBusyItemModel::rowCount(const QModelIndex &parent) const { ItemPrivateData *parentData = nullptr; if (parent.column() > 0) { return 0; } if (!parent.isValid()) { parentData = d->mRootData; } else { parentData = static_cast(parent.internalPointer()); } return parentData->childCount(); } int FreeBusyItemModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 1; } QModelIndex FreeBusyItemModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) { return QModelIndex(); } ItemPrivateData *parentData = nullptr; if (!parent.isValid()) { parentData = d->mRootData; } else { parentData = static_cast(parent.internalPointer()); } ItemPrivateData *childData = parentData->child(row); if (childData) { return createIndex(row, column, childData); } else { return QModelIndex(); } } QModelIndex FreeBusyItemModel::parent(const QModelIndex &child) const { if (!child.isValid()) { return QModelIndex(); } ItemPrivateData *childData = static_cast(child.internalPointer()); ItemPrivateData *parentData = childData->parent(); if (parentData == d->mRootData) { return QModelIndex(); } return createIndex(parentData->row(), 0, parentData); } QVariant FreeBusyItemModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal && section == 0) { return i18n("Attendee"); } return QVariant(); } void FreeBusyItemModel::addItem(const FreeBusyItem::Ptr &freebusy) { int row = d->mFreeBusyItems.size(); beginInsertRows(QModelIndex(), row, row); d->mFreeBusyItems.append(freebusy); ItemPrivateData *data = new ItemPrivateData(d->mRootData); d->mRootData->appendChild(data); endInsertRows(); if (freebusy->freeBusy() && freebusy->freeBusy()->fullBusyPeriods().size() > 0) { QModelIndex parent = index(row, 0); setFreeBusyPeriods(parent, freebusy->freeBusy()->fullBusyPeriods()); } updateFreeBusyData(freebusy); } void FreeBusyItemModel::setFreeBusyPeriods(const QModelIndex &parent, - const KCalCore::FreeBusyPeriod::List &list) + const KCalendarCore::FreeBusyPeriod::List &list) { if (!parent.isValid()) { return; } ItemPrivateData *parentData = static_cast(parent.internalPointer()); int fb_count = list.size(); int childCount = parentData->childCount(); QModelIndex first = index(0, 0, parent); QModelIndex last = index(childCount - 1, 0, parent); if (childCount > 0 && fb_count < childCount) { beginRemoveRows(parent, fb_count - 1 < 0 ? 0 : fb_count - 1, childCount - 1); for (int i = childCount - 1; i > fb_count; --i) { delete parentData->removeChild(i); } endRemoveRows(); if (fb_count > 0) { last = index(fb_count - 1, 0, parent); Q_EMIT dataChanged(first, last); } } else if (fb_count > childCount) { beginInsertRows(parent, childCount, fb_count - 1); for (int i = childCount; i < fb_count; ++i) { ItemPrivateData *childData = new ItemPrivateData(parentData); parentData->appendChild(childData); } endInsertRows(); if (childCount > 0) { last = index(childCount - 1, 0, parent); Q_EMIT dataChanged(first, last); } } else if (fb_count == childCount && fb_count > 0) { Q_EMIT dataChanged(first, last); } } void FreeBusyItemModel::clear() { beginResetModel(); d->mFreeBusyItems.clear(); delete d->mRootData; d->mRootData = new ItemPrivateData(nullptr); endResetModel(); } void FreeBusyItemModel::removeRow(int row) { beginRemoveRows(QModelIndex(), row, row); d->mFreeBusyItems.removeAt(row); ItemPrivateData *data = d->mRootData->removeChild(row); delete data; endRemoveRows(); } void FreeBusyItemModel::removeItem(const FreeBusyItem::Ptr &freebusy) { int row = d->mFreeBusyItems.indexOf(freebusy); if (row >= 0) { removeRow(row); } } -void FreeBusyItemModel::removeAttendee(const KCalCore::Attendee &attendee) +void FreeBusyItemModel::removeAttendee(const KCalendarCore::Attendee &attendee) { FreeBusyItem::Ptr anItem; for (int i = 0; i < d->mFreeBusyItems.count(); ++i) { anItem = d->mFreeBusyItems[i]; if (anItem->attendee() == attendee) { if (anItem->updateTimerID() != 0) { killTimer(anItem->updateTimerID()); } removeRow(i); break; } } } -bool FreeBusyItemModel::containsAttendee(const KCalCore::Attendee &attendee) +bool FreeBusyItemModel::containsAttendee(const KCalendarCore::Attendee &attendee) { FreeBusyItem::Ptr anItem; for (int i = 0; i < d->mFreeBusyItems.count(); ++i) { anItem = d->mFreeBusyItems[i]; if (anItem->attendee() == attendee) { return true; } } return false; } void FreeBusyItemModel::updateFreeBusyData(const FreeBusyItem::Ptr &item) { if (item->isDownloading()) { // This item is already in the process of fetching the FB list return; } if (item->updateTimerID() != 0) { // An update timer is already running. Reset it killTimer(item->updateTimerID()); } // This item does not have a download running, and no timer is set // Do the download in one second item->setUpdateTimerID(startTimer(1000)); } void FreeBusyItemModel::timerEvent(QTimerEvent *event) { killTimer(event->timerId()); for (FreeBusyItem::Ptr item : qAsConst(d->mFreeBusyItems)) { if (item->updateTimerID() == event->timerId()) { item->setUpdateTimerID(0); item->startDownload(d->mForceDownload); return; } } } -void FreeBusyItemModel::slotInsertFreeBusy(const KCalCore::FreeBusy::Ptr &fb, const QString &email) +void FreeBusyItemModel::slotInsertFreeBusy(const KCalendarCore::FreeBusy::Ptr &fb, const QString &email) { if (!fb) { return; } if (fb->fullBusyPeriods().isEmpty()) { return; } fb->sortList(); for (FreeBusyItem::Ptr item : qAsConst(d->mFreeBusyItems)) { if (item->email() == email) { item->setFreeBusy(fb); const int row = d->mFreeBusyItems.indexOf(item); const QModelIndex parent = index(row, 0); Q_EMIT dataChanged(parent, parent); setFreeBusyPeriods(parent, fb->fullBusyPeriods()); } } } void FreeBusyItemModel::autoReload() { d->mForceDownload = false; reload(); } void FreeBusyItemModel::reload() { for (FreeBusyItem::Ptr item : qAsConst(d->mFreeBusyItems)) { if (d->mForceDownload) { item->startDownload(d->mForceDownload); } else { updateFreeBusyData(item); } } } void FreeBusyItemModel::triggerReload() { d->mReloadTimer.start(1000); } void FreeBusyItemModel::cancelReload() { d->mReloadTimer.stop(); } diff --git a/src/freebusymodel/freebusyitemmodel.h b/src/freebusymodel/freebusyitemmodel.h index 2782b4d..1c1d085 100644 --- a/src/freebusymodel/freebusyitemmodel.h +++ b/src/freebusymodel/freebusyitemmodel.h @@ -1,106 +1,106 @@ /* Copyright (C) 2010 Casey Link Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef FBMODEL_FREEBUSYITEMMODEL_H #define FBMODEL_FREEBUSYITEMMODEL_H #include "calendarsupport_export.h" #include "freebusyitem.h" #include #include class ItemPrivateData; namespace CalendarSupport { /** * The FreeBusyItemModel is a 2-level tree structure. * * The top level parent nodes represent the freebusy items, and * the 2nd-level child nodes represent the FreeBusyPeriods of the parent * freebusy item. */ class FreeBusyItemModelPrivate; class CALENDARSUPPORT_EXPORT FreeBusyItemModel : public QAbstractItemModel { Q_OBJECT public: enum Roles { AttendeeRole = Qt::UserRole, FreeBusyRole, FreeBusyPeriodRole }; explicit FreeBusyItemModel(QObject *parent = nullptr); ~FreeBusyItemModel() override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &child) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; void addItem(const FreeBusyItem::Ptr &freebusy); void clear(); - void removeAttendee(const KCalCore::Attendee &attendee); + void removeAttendee(const KCalendarCore::Attendee &attendee); void removeItem(const FreeBusyItem::Ptr &freebusy); void removeRow(int row); - Q_REQUIRED_RESULT bool containsAttendee(const KCalCore::Attendee &attendee); + Q_REQUIRED_RESULT bool containsAttendee(const KCalendarCore::Attendee &attendee); /** * Queues a reload of free/busy data. * All current attendees will have their free/busy data * redownloaded from Akonadi. */ void triggerReload(); /** * cancel reloading */ void cancelReload(); /** * Reload FB items */ void reload(); public Q_SLOTS: - void slotInsertFreeBusy(const KCalCore::FreeBusy::Ptr &fb, const QString &email); + void slotInsertFreeBusy(const KCalendarCore::FreeBusy::Ptr &fb, const QString &email); protected: void timerEvent(QTimerEvent *) override; private: // Only download FB if the auto-download option is set in config void autoReload(); - void setFreeBusyPeriods(const QModelIndex &parent, const KCalCore::FreeBusyPeriod::List &list); + void setFreeBusyPeriods(const QModelIndex &parent, const KCalendarCore::FreeBusyPeriod::List &list); void updateFreeBusyData(const FreeBusyItem::Ptr &); FreeBusyItemModelPrivate *const d; }; } #endif diff --git a/src/freebusymodel/freeperiodmodel.cpp b/src/freebusymodel/freeperiodmodel.cpp index 39a8d36..d77e29c 100644 --- a/src/freebusymodel/freeperiodmodel.cpp +++ b/src/freebusymodel/freeperiodmodel.cpp @@ -1,211 +1,211 @@ /* Copyright (C) 2010 Casey Link Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "freeperiodmodel.h" -#include +#include #include #include #include #include #include #include using namespace CalendarSupport; FreePeriodModel::FreePeriodModel(QObject *parent) : QAbstractTableModel(parent) { } FreePeriodModel::~FreePeriodModel() { } QVariant FreePeriodModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || !hasIndex(index.row(), index.column())) { return QVariant(); } if (index.column() == 0) { //day switch (role) { case Qt::DisplayRole: return day(index.row()); case Qt::ToolTipRole: return tooltipify(index.row()); case FreePeriodModel::PeriodRole: return QVariant::fromValue(mPeriodList.at(index.row())); case Qt::TextAlignmentRole: return static_cast(Qt::AlignRight | Qt::AlignVCenter); default: return QVariant(); } } else { // everything else switch (role) { case Qt::DisplayRole: return date(index.row()); case Qt::ToolTipRole: return tooltipify(index.row()); case FreePeriodModel::PeriodRole: return QVariant::fromValue(mPeriodList.at(index.row())); case Qt::TextAlignmentRole: return static_cast(Qt::AlignLeft | Qt::AlignVCenter); default: return QVariant(); } } } int FreePeriodModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { return mPeriodList.size(); } return 0; } int FreePeriodModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 2; } QVariant FreePeriodModel::headerData(int section, Qt::Orientation orientation, int role) const { return QAbstractItemModel::headerData(section, orientation, role); } -void FreePeriodModel::slotNewFreePeriods(const KCalCore::Period::List &freePeriods) +void FreePeriodModel::slotNewFreePeriods(const KCalendarCore::Period::List &freePeriods) { beginResetModel(); mPeriodList.clear(); mPeriodList = splitPeriodsByDay(freePeriods); std::sort(mPeriodList.begin(), mPeriodList.end()); endResetModel(); } -KCalCore::Period::List FreePeriodModel::splitPeriodsByDay( - const KCalCore::Period::List &freePeriods) +KCalendarCore::Period::List FreePeriodModel::splitPeriodsByDay( + const KCalendarCore::Period::List &freePeriods) { - KCalCore::Period::List splitList; - for (const KCalCore::Period &period : freePeriods) { + KCalendarCore::Period::List splitList; + for (const KCalendarCore::Period &period : freePeriods) { if (period.start().date() == period.end().date()) { splitList << period; // period occurs on the same day continue; } const int validPeriodSecs = 300; // 5 minutes - KCalCore::Period tmpPeriod = period; + KCalendarCore::Period tmpPeriod = period; while (tmpPeriod.start().date() != tmpPeriod.end().date()) { const QDateTime midnight(tmpPeriod.start().date(), QTime(23, 59, 59, 999), tmpPeriod.start().timeZone()); - KCalCore::Period firstPeriod(tmpPeriod.start(), midnight); - KCalCore::Period secondPeriod(midnight.addMSecs(1), tmpPeriod.end()); + KCalendarCore::Period firstPeriod(tmpPeriod.start(), midnight); + KCalendarCore::Period secondPeriod(midnight.addMSecs(1), tmpPeriod.end()); if (firstPeriod.duration().asSeconds() >= validPeriodSecs) { splitList << firstPeriod; } tmpPeriod = secondPeriod; } if (tmpPeriod.duration().asSeconds() >= validPeriodSecs) { splitList << tmpPeriod; } } // Perform some jiggery pokery to remove duplicates - QList tmpList = splitList.toList(); - const QSet set = tmpList.toSet(); - tmpList = QList::fromSet(set); - return KCalCore::Period::List::fromList(tmpList); + QList tmpList = splitList.toList(); + const QSet set = tmpList.toSet(); + tmpList = QList::fromSet(set); + return KCalendarCore::Period::List::fromList(tmpList); } QString FreePeriodModel::day(int index) const { - KCalCore::Period period = mPeriodList.at(index); + KCalendarCore::Period period = mPeriodList.at(index); const QDate startDate = period.start().date(); return ki18nc("@label Day of the week name, example: Monday,", "%1,"). subs(QLocale::system().dayName(startDate.dayOfWeek(), QLocale::LongFormat)).toString(); } QString FreePeriodModel::date(int index) const { - KCalCore::Period period = mPeriodList.at(index); + KCalendarCore::Period period = mPeriodList.at(index); const QDate startDate = period.start().date(); const QString startTime = QLocale::system().toString(period.start().time(), QLocale::ShortFormat); const QString endTime = QLocale::system().toString(period.end().time(), QLocale::ShortFormat); const QString longMonthName = QLocale::system().monthName(startDate.month()); return ki18nc("@label A time period duration. It is preceded/followed (based on the " "orientation) by the name of the week, see the message above. " "example: 12 June, 8:00am to 9:30am", "%1 %2, %3 to %4"). subs(startDate.day()). subs(longMonthName). subs(startTime). subs(endTime).toString(); } QString FreePeriodModel::stringify(int index) const { - KCalCore::Period period = mPeriodList.at(index); + KCalendarCore::Period period = mPeriodList.at(index); const QDate startDate = period.start().date(); const QString startTime = QLocale().toString(period.start().time(), QLocale::ShortFormat); const QString endTime = QLocale().toString(period.end().time(), QLocale::ShortFormat); const QString longMonthName = QLocale::system().monthName(startDate.month(), QLocale::LongFormat); const QString dayofWeek = QLocale::system().dayName(startDate.dayOfWeek(), QLocale::LongFormat); // TODO i18n, ping chusslove return ki18nc("@label A time period duration. KLocale is used to format the components. " "example: Monday, 12 June, 8:00am to 9:30am", "%1, %2 %3, %4 to %5"). subs(dayofWeek). subs(startDate.day()). subs(longMonthName). subs(startTime). subs(endTime).toString(); } QString FreePeriodModel::tooltipify(int index) const { - KCalCore::Period period = mPeriodList.at(index); + KCalendarCore::Period period = mPeriodList.at(index); unsigned long duration = period.duration().asSeconds() * 1000; // we want milliseconds QString toolTip = QStringLiteral(""); toolTip += QLatin1String("") + i18nc("@info:tooltip", "Free Period") + QLatin1String(""); toolTip += QLatin1String("
"); toolTip += QLatin1String("") + i18nc("@info:tooltip period start time", "Start:") + QLatin1String(" "); toolTip += QLocale().toString(period.start().toLocalTime(), QLocale::ShortFormat); toolTip += QLatin1String("
"); toolTip += QLatin1String("") + i18nc("@info:tooltip period end time", "End:") + QLatin1String(" "); toolTip += QLocale().toString(period.end().toLocalTime(), QLocale::ShortFormat); toolTip += QLatin1String("
"); toolTip += QLatin1String("") + i18nc("@info:tooltip period duration", "Duration:") + QLatin1String(" "); toolTip += KFormat().formatSpelloutDuration(duration); toolTip += QLatin1String("
"); return toolTip; } diff --git a/src/freebusymodel/freeperiodmodel.h b/src/freebusymodel/freeperiodmodel.h index f25255e..33a796a 100644 --- a/src/freebusymodel/freeperiodmodel.h +++ b/src/freebusymodel/freeperiodmodel.h @@ -1,63 +1,63 @@ /* Copyright (C) 2010 Casey Link Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef INCIDENCEEDITOR_FREEPERIODMODEL_H #define INCIDENCEEDITOR_FREEPERIODMODEL_H #include "calendarsupport_export.h" -#include +#include #include namespace CalendarSupport { class CALENDARSUPPORT_EXPORT FreePeriodModel : public QAbstractTableModel { Q_OBJECT public: enum Roles { PeriodRole = Qt::UserRole }; explicit FreePeriodModel(QObject *parent = nullptr); ~FreePeriodModel() override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; Q_REQUIRED_RESULT int rowCount(const QModelIndex &parent = QModelIndex()) const override; Q_REQUIRED_RESULT int columnCount(const QModelIndex &parent = QModelIndex()) const override; Q_REQUIRED_RESULT QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; public Q_SLOTS: - void slotNewFreePeriods(const KCalCore::Period::List &freePeriods); + void slotNewFreePeriods(const KCalendarCore::Period::List &freePeriods); private: /** Splits period blocks in the provided list, so that each period occurs on one day */ - KCalCore::Period::List splitPeriodsByDay(const KCalCore::Period::List &freePeriods); + KCalendarCore::Period::List splitPeriodsByDay(const KCalendarCore::Period::List &freePeriods); QString day(int index) const; QString date(int index) const; QString stringify(int index) const; QString tooltipify(int index) const; - KCalCore::Period::List mPeriodList; + KCalendarCore::Period::List mPeriodList; friend class FreePeriodModelTest; }; } #endif diff --git a/src/incidenceattachmentmodel.cpp b/src/incidenceattachmentmodel.cpp index 695653c..0f767c1 100644 --- a/src/incidenceattachmentmodel.cpp +++ b/src/incidenceattachmentmodel.cpp @@ -1,216 +1,216 @@ /* Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company Author: Stephen Kelly This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "incidenceattachmentmodel.h" #include #include #include #include using namespace CalendarSupport; using namespace Akonadi; namespace CalendarSupport { class IncidenceAttachmentModelPrivate { IncidenceAttachmentModelPrivate(IncidenceAttachmentModel *qq, const QPersistentModelIndex &modelIndex, const Akonadi::Item &item = Akonadi::Item()) : q_ptr(qq) , m_modelIndex(modelIndex) , m_item(item) , m_monitor(nullptr) { if (modelIndex.isValid()) { QObject::connect(modelIndex.model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), qq, SLOT(resetModel())); } else if (item.isValid()) { createMonitor(); resetInternalData(); } } void resetModel() { Q_Q(IncidenceAttachmentModel); q->beginResetModel(); resetInternalData(); q->endResetModel(); Q_EMIT q->rowCountChanged(); } void itemFetched(Akonadi::Item::List list) { Q_ASSERT(list.size() == 1); setItem(list.first()); } void setItem(const Akonadi::Item &item); void createMonitor() { if (m_monitor) { return; } m_monitor = new Akonadi::Monitor(q_ptr); m_monitor->setObjectName(QStringLiteral("IncidenceAttachmentModelMonitor")); m_monitor->setItemMonitored(m_item); m_monitor->itemFetchScope().fetchFullPayload(true); QObject::connect(m_monitor, SIGNAL(itemChanged(Akonadi::Item,QSet)), q_ptr, SLOT(resetModel())); QObject::connect(m_monitor, SIGNAL(itemRemoved(Akonadi::Item)), q_ptr, SLOT(resetModel())); } void resetInternalData() { Item item = m_item; if (m_modelIndex.isValid()) { item = m_modelIndex.data(EntityTreeModel::ItemRole).value(); } - if (!item.isValid() || !item.hasPayload()) { - m_incidence = KCalCore::Incidence::Ptr(); + if (!item.isValid() || !item.hasPayload()) { + m_incidence = KCalendarCore::Incidence::Ptr(); return; } - m_incidence = item.payload(); + m_incidence = item.payload(); } Q_DECLARE_PUBLIC(IncidenceAttachmentModel) IncidenceAttachmentModel *const q_ptr; QModelIndex m_modelIndex; Akonadi::Item m_item; - KCalCore::Incidence::Ptr m_incidence; + KCalendarCore::Incidence::Ptr m_incidence; Akonadi::Monitor *m_monitor = nullptr; }; } IncidenceAttachmentModel::IncidenceAttachmentModel(const QPersistentModelIndex &modelIndex, QObject *parent) : QAbstractListModel(parent) , d_ptr(new IncidenceAttachmentModelPrivate(this, modelIndex)) { } IncidenceAttachmentModel::IncidenceAttachmentModel(const Akonadi::Item &item, QObject *parent) : QAbstractListModel(parent) , d_ptr(new IncidenceAttachmentModelPrivate(this, QModelIndex(), item)) { } IncidenceAttachmentModel::IncidenceAttachmentModel(QObject *parent) : QAbstractListModel(parent) , d_ptr(new IncidenceAttachmentModelPrivate(this, QModelIndex())) { } IncidenceAttachmentModel::~IncidenceAttachmentModel() { delete d_ptr; } -KCalCore::Incidence::Ptr IncidenceAttachmentModel::incidence() const +KCalendarCore::Incidence::Ptr IncidenceAttachmentModel::incidence() const { Q_D(const IncidenceAttachmentModel); return d->m_incidence; } void IncidenceAttachmentModel::setIndex(const QPersistentModelIndex &modelIndex) { Q_D(IncidenceAttachmentModel); beginResetModel(); d->m_modelIndex = modelIndex; d->m_item = Akonadi::Item(); d->resetInternalData(); endResetModel(); Q_EMIT rowCountChanged(); } void IncidenceAttachmentModel::setItem(const Akonadi::Item &item) { Q_D(IncidenceAttachmentModel); - if (!item.hasPayload()) { + if (!item.hasPayload()) { ItemFetchJob *job = new ItemFetchJob(item); job->fetchScope().fetchFullPayload(true); connect(job, SIGNAL(itemsReceived(Akonadi::Item::List)), SLOT(itemFetched(Akonadi::Item::List))); return; } d->setItem(item); } void IncidenceAttachmentModelPrivate::setItem(const Akonadi::Item &item) { Q_Q(IncidenceAttachmentModel); q->beginResetModel(); m_modelIndex = QModelIndex(); m_item = item; createMonitor(); resetInternalData(); q->endResetModel(); Q_EMIT q->rowCountChanged(); } int IncidenceAttachmentModel::rowCount(const QModelIndex &) const { Q_D(const IncidenceAttachmentModel); if (!d->m_incidence) { return 0; } else { return d->m_incidence->attachments().size(); } } QVariant IncidenceAttachmentModel::data(const QModelIndex &index, int role) const { Q_D(const IncidenceAttachmentModel); if (!d->m_incidence) { return QVariant(); } - const KCalCore::Attachment attachment = d->m_incidence->attachments().at(index.row()); + const KCalendarCore::Attachment attachment = d->m_incidence->attachments().at(index.row()); switch (role) { case Qt::DisplayRole: return attachment.label(); case AttachmentDataRole: return attachment.decodedData(); case MimeTypeRole: return attachment.mimeType(); } return QVariant(); } QVariant IncidenceAttachmentModel::headerData(int section, Qt::Orientation orientation, int role) const { return QAbstractItemModel::headerData(section, orientation, role); } QHash CalendarSupport::IncidenceAttachmentModel::roleNames() const { QHash roleNames = QAbstractListModel::roleNames(); roleNames.insert(IncidenceAttachmentModel::MimeTypeRole, "mimeType"); return roleNames; } #include "moc_incidenceattachmentmodel.cpp" diff --git a/src/incidenceattachmentmodel.h b/src/incidenceattachmentmodel.h index 3a78932..5a66fa2 100644 --- a/src/incidenceattachmentmodel.h +++ b/src/incidenceattachmentmodel.h @@ -1,86 +1,86 @@ /* Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company Author: Stephen Kelly This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CALENDARSUPPORT_INCIDENCEATTACHMENTMODEL_H #define CALENDARSUPPORT_INCIDENCEATTACHMENTMODEL_H #include #include -#include +#include #include namespace Akonadi { class Item; } namespace CalendarSupport { class IncidenceAttachmentModelPrivate; class IncidenceAttachmentModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int attachmentCount READ rowCount NOTIFY rowCountChanged) public: enum Roles { AttachmentDataRole = Qt::UserRole, MimeTypeRole, AttachmentCountRole, UserRole = Qt::UserRole + 100 }; explicit IncidenceAttachmentModel(const QPersistentModelIndex &modelIndex, QObject *parent = nullptr); explicit IncidenceAttachmentModel(const Akonadi::Item &item, QObject *parent = nullptr); explicit IncidenceAttachmentModel(QObject *parent = nullptr); ~IncidenceAttachmentModel() override; - KCalCore::Incidence::Ptr incidence() const; + KCalendarCore::Incidence::Ptr incidence() const; void setItem(const Akonadi::Item &item); void setIndex(const QPersistentModelIndex &modelIndex); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; QHash roleNames() const override; Q_SIGNALS: void rowCountChanged(); private: Q_DECLARE_PRIVATE(IncidenceAttachmentModel) IncidenceAttachmentModelPrivate *const d_ptr; Q_PRIVATE_SLOT(d_func(), void resetModel()) Q_PRIVATE_SLOT(d_func(), void itemFetched(Akonadi::Item::List)) }; } #endif diff --git a/src/kcalmodel.cpp b/src/kcalmodel.cpp index 38757a8..da3fac6 100644 --- a/src/kcalmodel.cpp +++ b/src/kcalmodel.cpp @@ -1,203 +1,203 @@ /* Copyright (c) 2008 Bruno Virlet This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kcalmodel.h" #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include using namespace CalendarSupport; class Q_DECL_HIDDEN KCalModel::Private { public: Private(KCalModel *model) : q(model) { } static QStringList allMimeTypes() { QStringList types; - types << KCalCore::Event::eventMimeType() - << KCalCore::Todo::todoMimeType() - << KCalCore::Journal::journalMimeType() - << KCalCore::FreeBusy::freeBusyMimeType(); + types << KCalendarCore::Event::eventMimeType() + << KCalendarCore::Todo::todoMimeType() + << KCalendarCore::Journal::journalMimeType() + << KCalendarCore::FreeBusy::freeBusyMimeType(); return types; } bool collectionMatchesMimeTypes() const { const QStringList lst = allMimeTypes(); for (const QString &type : lst) { if (q->collection().contentMimeTypes().contains(type)) { return true; } } return false; } bool collectionIsValid() { return !q->collection().isValid() || collectionMatchesMimeTypes() || q->collection().contentMimeTypes() == QStringList(QStringLiteral("inode/directory")); } private: KCalModel *q; }; KCalModel::KCalModel(QObject *parent) : ItemModel(parent) , d(new Private(this)) { fetchScope().fetchFullPayload(); } KCalModel::~KCalModel() { delete d; } QStringList KCalModel::mimeTypes() const { return QStringList() << QStringLiteral("text/uri-list") << d->allMimeTypes(); } int KCalModel::columnCount(const QModelIndex &) const { if (d->collectionIsValid()) { return 4; } else { return 1; } } int KCalModel::rowCount(const QModelIndex &) const { if (d->collectionIsValid()) { return ItemModel::rowCount(); } else { return 1; } } QVariant KCalModel::data(const QModelIndex &index, int role) const { if (role == ItemModel::IdRole) { return ItemModel::data(index, role); } if (!index.isValid() || index.row() >= rowCount()) { return QVariant(); } // guard against use with collections that do not have the right contents if (!d->collectionIsValid()) { if (role == Qt::DisplayRole) { return i18nc("@info", "This model can only handle event, task, journal or free-busy list folders. " "The current collection holds mimetypes: %1", collection().contentMimeTypes().join(QLatin1Char(','))); } return QVariant(); } const Akonadi::Item item = itemForIndex(index); - if (!item.hasPayload()) { + if (!item.hasPayload()) { return QVariant(); } - const KCalCore::Incidence::Ptr incidence = item.payload(); + const KCalendarCore::Incidence::Ptr incidence = item.payload(); // Icon for the model entry switch (role) { case Qt::DecorationRole: if (index.column() == 0) { - if (incidence->type() == KCalCore::Incidence::TypeTodo) { + if (incidence->type() == KCalendarCore::Incidence::TypeTodo) { return QIcon::fromTheme(QStringLiteral("view-pim-tasks")); - } else if (incidence->type() == KCalCore::Incidence::TypeJournal) { + } else if (incidence->type() == KCalendarCore::Incidence::TypeJournal) { return QIcon::fromTheme(QStringLiteral("view-pim-journal")); - } else if (incidence->type() == KCalCore::Incidence::TypeEvent) { + } else if (incidence->type() == KCalendarCore::Incidence::TypeEvent) { return QIcon::fromTheme(QStringLiteral("view-calendar")); } else { return QIcon::fromTheme(QStringLiteral("network-wired")); } } break; case Qt::DisplayRole: switch (index.column()) { case Summary: return incidence->summary(); case DateTimeStart: return incidence->dtStart().toString(); case DateTimeEnd: - return incidence->dateTime(KCalCore::Incidence::RoleEnd).toString(); + return incidence->dateTime(KCalendarCore::Incidence::RoleEnd).toString(); case Type: return incidence->type(); default: break; } break; default: return QVariant(); } return QVariant(); } QVariant KCalModel::headerData(int section, Qt::Orientation orientation, int role) const { if (!d->collectionIsValid()) { return QVariant(); } if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case Summary: return i18nc("@title:column, calendar event summary", "Summary"); case DateTimeStart: return i18nc("@title:column, calendar event start date and time", "Start date and time"); case DateTimeEnd: return i18nc("@title:column, calendar event end date and time", "End date and time"); case Type: return i18nc("@title:column, calendar event type", "Type"); default: return QString(); } } return Akonadi::ItemModel::headerData(section, orientation, role); } diff --git a/src/next/incidenceviewer.cpp b/src/next/incidenceviewer.cpp index e523794..bc601e1 100644 --- a/src/next/incidenceviewer.cpp +++ b/src/next/incidenceviewer.cpp @@ -1,257 +1,257 @@ /* Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company Author: Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "incidenceviewer.h" #include "incidenceviewer_p.h" #include "attachmenthandler.h" #include "utils.h" #include "KdepimDBusInterfaces/UriHandler" #include "incidenceattachmentmodel.h" #include #include #include #include #include #include #include using namespace CalendarSupport; TextBrowser::TextBrowser(QWidget *parent) : QTextBrowser(parent) { setFrameStyle(QFrame::NoFrame); } void TextBrowser::setSource(const QUrl &name) { QString uri = name.toString(); // QTextBrowser for some reason insists on putting // or / in links, // this is a crude workaround if (uri.startsWith(QLatin1String("uid:")) || uri.startsWith(QLatin1String("kmail:")) || uri.startsWith(QStringLiteral("urn:x-ical").section(QLatin1Char(':'), 0, 0)) || uri.startsWith(QLatin1String("news:")) || uri.startsWith(QLatin1String("mailto:"))) { uri.replace(QRegExp(QLatin1String("^([^:]+:)/+")), QStringLiteral("\\1")); } if (uri.startsWith(QStringLiteral("ATTACH:"))) { Q_EMIT attachmentUrlClicked(uri); } else { UriHandler::process(uri); } } class Q_DECL_HIDDEN IncidenceViewer::Private { public: Private(IncidenceViewer *parent) : mCalendar(nullptr) , mParent(parent) , mParentCollectionFetchJob(nullptr) , mAttachmentModel(nullptr) , mDelayedClear(false) { mAttachmentHandler = new AttachmentHandler(parent); mBrowser = new TextBrowser; parent->connect(mBrowser, &TextBrowser::attachmentUrlClicked, parent, [this](const QString &str) { slotAttachmentUrlClicked(str); }); } void updateView() { QString text; if (mCurrentItem.isValid()) { text = KCalUtils::IncidenceFormatter::extensiveDisplayStr( CalendarSupport::displayName(mCalendar, mParentCollection), CalendarSupport::incidence(mCurrentItem), mDate); text.prepend(mHeaderText); mBrowser->setHtml(text); } else { text = mDefaultText; if (!mDelayedClear) { mBrowser->setHtml(text); } } } void slotParentCollectionFetched(KJob *job) { mParentCollectionFetchJob = nullptr; mParentCollection = Akonadi::Collection(); if (!job->error()) { Akonadi::CollectionFetchJob *fetchJob = qobject_cast(job); if (!fetchJob->collections().isEmpty()) { mParentCollection = fetchJob->collections().at(0); } } updateView(); } void slotAttachmentUrlClicked(const QString &uri) { const QString attachmentName = QString::fromUtf8(QByteArray::fromBase64(uri.mid(7).toUtf8())); mAttachmentHandler->view(attachmentName, CalendarSupport::incidence(mCurrentItem)); } Akonadi::ETMCalendar *mCalendar = nullptr; IncidenceViewer *mParent = nullptr; TextBrowser *mBrowser = nullptr; Akonadi::Item mCurrentItem; QString mHeaderText; QString mDefaultText; Akonadi::Collection mParentCollection; Akonadi::CollectionFetchJob *mParentCollectionFetchJob = nullptr; IncidenceAttachmentModel *mAttachmentModel = nullptr; AttachmentHandler *mAttachmentHandler = nullptr; QDate mDate; bool mDelayedClear = false; }; IncidenceViewer::IncidenceViewer(Akonadi::ETMCalendar *calendar, QWidget *parent) : QWidget(parent) , d(new Private(this)) { d->mCalendar = calendar; init(); } IncidenceViewer::IncidenceViewer(QWidget *parent) : QWidget(parent) , d(new Private(this)) { d->mCalendar = nullptr; init(); } void IncidenceViewer::init() { QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); d->mBrowser->setOpenLinks(true); d->mBrowser->setMinimumHeight(1); layout->addWidget(d->mBrowser); // always fetch full payload for incidences fetchScope().fetchFullPayload(); fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::Parent); d->updateView(); } IncidenceViewer::~IncidenceViewer() { delete d; } void IncidenceViewer::setCalendar(Akonadi::ETMCalendar *calendar) { d->mCalendar = calendar; } Akonadi::Item IncidenceViewer::incidence() const { return ItemMonitor::item(); } QDate IncidenceViewer::activeDate() const { return d->mDate; } QAbstractItemModel *IncidenceViewer::attachmentModel() const { if (!d->mAttachmentModel) { d->mAttachmentModel = new IncidenceAttachmentModel(const_cast(this)); } return d->mAttachmentModel; } void IncidenceViewer::setDelayedClear(bool delayed) { d->mDelayedClear = delayed; } void IncidenceViewer::setDefaultMessage(const QString &message) { d->mDefaultText = message; } void IncidenceViewer::setHeaderText(const QString &text) { d->mHeaderText = text; } void IncidenceViewer::setIncidence(const Akonadi::Item &incidence, const QDate &date) { d->mDate = date; ItemMonitor::setItem(incidence); d->updateView(); } void IncidenceViewer::itemChanged(const Akonadi::Item &item) { - if (!item.hasPayload()) { + if (!item.hasPayload()) { d->mBrowser->clear(); return; } d->mCurrentItem = item; if (d->mAttachmentModel) { d->mAttachmentModel->setItem(d->mCurrentItem); } if (d->mParentCollectionFetchJob) { disconnect(d->mParentCollectionFetchJob, SIGNAL(result(KJob*)), this, SLOT(slotParentCollectionFetched(KJob*))); delete d->mParentCollectionFetchJob; } d->mParentCollectionFetchJob = new Akonadi::CollectionFetchJob(d->mCurrentItem.parentCollection(), Akonadi::CollectionFetchJob::Base, this); connect(d->mParentCollectionFetchJob, SIGNAL(result(KJob*)), this, SLOT(slotParentCollectionFetched(KJob*))); } void IncidenceViewer::itemRemoved() { d->mCurrentItem = Akonadi::Item(); d->mBrowser->clear(); } #include "moc_incidenceviewer.cpp" #include "moc_incidenceviewer_p.cpp" diff --git a/src/printing/calprintdefaultplugins.cpp b/src/printing/calprintdefaultplugins.cpp index 59f8ba2..cf0f243 100644 --- a/src/printing/calprintdefaultplugins.cpp +++ b/src/printing/calprintdefaultplugins.cpp @@ -1,1660 +1,1660 @@ /* Copyright (c) 1998 Preston Brown Copyright (C) 2003 Reinhold Kainhofer Copyright (c) 2003 Cornelius Schumacher Copyright (c) 2008 Ron Goodheart Copyright (C) 2010-2019 Laurent Montel Copyright (c) 2012-2013 Allen Winter 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 "calprintdefaultplugins.h" #include "kcalprefs.h" #include "utils.h" #include -#include +#include #include #include #include #include #include #include using namespace CalendarSupport; static QString cleanStr(const QString &instr) { QString ret = instr; return ret.replace(QLatin1Char('\n'), QLatin1Char(' ')); } /************************************************************** * Print Incidence **************************************************************/ CalPrintIncidence::CalPrintIncidence() : CalPrintPluginBase() { } CalPrintIncidence::~CalPrintIncidence() { } QWidget *CalPrintIncidence::createConfigWidget(QWidget *w) { return new CalPrintIncidenceConfig(w); } void CalPrintIncidence::readSettingsWidget() { CalPrintIncidenceConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { mUseColors = cfg->mColors->isChecked(); mPrintFooter = cfg->mPrintFooter->isChecked(); mShowOptions = cfg->mShowDetails->isChecked(); mShowSubitemsNotes = cfg->mShowSubitemsNotes->isChecked(); mShowAttendees = cfg->mShowAttendees->isChecked(); mShowAttachments = cfg->mShowAttachments->isChecked(); mShowNoteLines = cfg->mShowNoteLines->isChecked(); } } void CalPrintIncidence::setSettingsWidget() { CalPrintIncidenceConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { cfg->mColors->setChecked(mUseColors); cfg->mPrintFooter->setChecked(mPrintFooter); cfg->mShowDetails->setChecked(mShowOptions); cfg->mShowSubitemsNotes->setChecked(mShowSubitemsNotes); cfg->mShowAttendees->setChecked(mShowAttendees); cfg->mShowAttachments->setChecked(mShowAttachments); cfg->mShowNoteLines->setChecked(mShowNoteLines); } } void CalPrintIncidence::loadConfig() { if (mConfig) { KConfigGroup grp(mConfig, groupName()); mShowOptions = grp.readEntry("Show Options", false); mShowSubitemsNotes = grp.readEntry("Show Subitems and Notes", false); mShowAttendees = grp.readEntry("Use Attendees", false); mShowAttachments = grp.readEntry("Use Attachments", false); mShowNoteLines = grp.readEntry("Note Lines", false); } setSettingsWidget(); } void CalPrintIncidence::saveConfig() { readSettingsWidget(); if (mConfig) { KConfigGroup grp(mConfig, groupName()); grp.writeEntry("Show Options", mShowOptions); grp.writeEntry("Show Subitems and Notes", mShowSubitemsNotes); grp.writeEntry("Use Attendees", mShowAttendees); grp.writeEntry("Use Attachments", mShowAttachments); grp.writeEntry("Note Lines", mShowNoteLines); } } -class TimePrintStringsVisitor : public KCalCore::Visitor +class TimePrintStringsVisitor : public KCalendarCore::Visitor { public: TimePrintStringsVisitor() { } - bool act(KCalCore::IncidenceBase::Ptr incidence) + bool act(KCalendarCore::IncidenceBase::Ptr incidence) { return incidence->accept(*this, incidence); } QString mStartCaption, mStartString; QString mEndCaption, mEndString; QString mDurationCaption, mDurationString; protected: - bool visit(const KCalCore::Event::Ptr &event) override + bool visit(const KCalendarCore::Event::Ptr &event) override { if (event->dtStart().isValid()) { mStartCaption = i18n("Start date: "); mStartString = KCalUtils::IncidenceFormatter::dateTimeToString( event->dtStart(), event->allDay(), false); } else { mStartCaption = i18n("No start date"); mStartString.clear(); } if (event->hasEndDate()) { mEndCaption = i18n("End date: "); mEndString = KCalUtils::IncidenceFormatter::dateTimeToString( event->dtEnd(), event->allDay(), false); } else if (event->hasDuration()) { mEndCaption = i18n("Duration: "); int mins = event->duration().asSeconds() / 60; if (mins >= 60) { mEndString += i18np("1 hour ", "%1 hours ", mins / 60); } if (mins % 60 > 0) { mEndString += i18np("1 minute ", "%1 minutes ", mins % 60); } } else { mEndCaption = i18n("No end date"); mEndString.clear(); } return true; } - bool visit(const KCalCore::Todo::Ptr &todo) override + bool visit(const KCalendarCore::Todo::Ptr &todo) override { if (todo->hasStartDate()) { mStartCaption = i18n("Start date: "); mStartString = KCalUtils::IncidenceFormatter::dateTimeToString( todo->dtStart(), todo->allDay(), false); } else { mStartCaption = i18n("No start date"); mStartString.clear(); } if (todo->hasDueDate()) { mEndCaption = i18n("Due date: "); mEndString = KCalUtils::IncidenceFormatter::dateTimeToString( todo->dtDue(), todo->allDay(), false); } else { mEndCaption = i18n("No due date"); mEndString.clear(); } return true; } - bool visit(const KCalCore::Journal::Ptr &journal) override + bool visit(const KCalendarCore::Journal::Ptr &journal) override { mStartCaption = i18n("Start date: "); mStartString = KCalUtils::IncidenceFormatter::dateTimeToString( journal->dtStart(), journal->allDay(), false); mEndCaption.clear(); mEndString.clear(); return true; } - bool visit(const KCalCore::FreeBusy::Ptr &fb) override + bool visit(const KCalendarCore::FreeBusy::Ptr &fb) override { Q_UNUSED(fb); return true; } }; int CalPrintIncidence::printCaptionAndText(QPainter &p, const QRect &box, const QString &caption, const QString &text, const QFont &captionFont, const QFont &textFont) { QFontMetrics captionFM(captionFont); int textWd = captionFM.boundingRect(caption).width(); QRect textRect(box); QFont oldFont(p.font()); p.setFont(captionFont); p.drawText(box, Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, caption); if (!text.isEmpty()) { textRect.setLeft(textRect.left() + textWd); p.setFont(textFont); p.drawText(textRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, text); } p.setFont(oldFont); return textRect.bottom(); } void CalPrintIncidence::print(QPainter &p, int width, int height) { QFont oldFont(p.font()); QFont textFont(QStringLiteral("sans-serif"), 11, QFont::Normal); QFont captionFont(QStringLiteral("sans-serif"), 11, QFont::Bold); p.setFont(textFont); int lineHeight = p.fontMetrics().lineSpacing(); QString cap, txt; - KCalCore::Incidence::List::ConstIterator it; + KCalendarCore::Incidence::List::ConstIterator it; for (it = mSelectedIncidences.constBegin(); it != mSelectedIncidences.constEnd(); ++it) { // don't do anything on a 0-pointer! if (!(*it)) { continue; } if (it != mSelectedIncidences.constBegin()) { mPrinter->newPage(); } - const bool isJournal = ((*it)->type() == KCalCore::Incidence::TypeJournal); + const bool isJournal = ((*it)->type() == KCalendarCore::Incidence::TypeJournal); // PAGE Layout (same for landscape and portrait! astonishingly, it looks good with both!): // +-----------------------------------+ // | Header: Summary | // +===================================+ // | start: ______ end: _________ | // | repeats: ___________________ | // | reminder: __________________ | // +-----------------------------------+ // | Location: ______________________ | // +------------------------+----------+ // | Description: | Notes or | // | | Subitems | // | | | // | | | // | | | // | | | // | | | // | | | // | | | // | | | // +------------------------+----------+ // | Attachments: | Settings | // | | | // +------------------------+----------+ // | Attendees: | // | | // +-----------------------------------+ // | Categories: _____________________ | // +-----------------------------------+ QRect box(0, 0, width, height); QRect titleBox(box); titleBox.setHeight(headerHeight()); QColor headerColor = categoryBgColor(*it); // Draw summary as header, no small calendars in title bar, expand height if needed int titleBottom = drawHeader(p, (*it)->summary(), QDate(), QDate(), titleBox, true, headerColor); titleBox.setBottom(titleBottom); QRect timesBox(titleBox); timesBox.setTop(titleBox.bottom() + padding()); timesBox.setHeight(height / 8); TimePrintStringsVisitor stringVis; int h = timesBox.top(); if (stringVis.act(*it)) { QRect textRect(timesBox.left() + padding(), timesBox.top() + padding(), 0, lineHeight); textRect.setRight(timesBox.center().x()); h = printCaptionAndText(p, textRect, stringVis.mStartCaption, stringVis.mStartString, captionFont, textFont); textRect.setLeft(textRect.right()); textRect.setRight(timesBox.right() - padding()); h = qMax(printCaptionAndText(p, textRect, stringVis.mEndCaption, stringVis.mEndString, captionFont, textFont), h); } // Recurrence Printing if ((*it)->recurs()) { QRect recurBox(timesBox.left() + padding(), h + padding(), timesBox.right() - padding(), lineHeight); - KCalCore::Recurrence *recurs = (*it)->recurrence(); + KCalendarCore::Recurrence *recurs = (*it)->recurrence(); QString displayString = KCalUtils::IncidenceFormatter::recurrenceString((*it)); // exception dates QString exceptString; if (!recurs->exDates().isEmpty()) { exceptString = i18nc("except for listed dates", " except"); for (int i = 0; i < recurs->exDates().size(); ++i) { exceptString.append(QLatin1Char(' ')); exceptString.append(QLocale::system().toString(recurs->exDates().at(i), QLocale::ShortFormat)); } } displayString.append(exceptString); h = qMax(printCaptionAndText(p, recurBox, i18n("Repeats: "), displayString, captionFont, textFont), h); } if (!isJournal) { // Alarms Printing QRect alarmBox(timesBox.left() + padding(), h + padding(), timesBox.right() - padding(), lineHeight); - KCalCore::Alarm::List alarms = (*it)->alarms(); + KCalendarCore::Alarm::List alarms = (*it)->alarms(); if (alarms.isEmpty()) { cap = i18n("No reminders"); txt.clear(); } else { cap = i18np("Reminder: ", "%1 reminders: ", alarms.count()); QStringList alarmStrings; - KCalCore::Alarm::List::ConstIterator it; + KCalendarCore::Alarm::List::ConstIterator it; alarmStrings.reserve(alarms.count()); for (it = alarms.constBegin(); it != alarms.constEnd(); ++it) { - KCalCore::Alarm::Ptr alarm = *it; + KCalendarCore::Alarm::Ptr alarm = *it; // Alarm offset, copied from koeditoralarms.cpp: KLocalizedString offsetstr; int offset = 0; if (alarm->hasStartOffset()) { offset = alarm->startOffset().asSeconds(); if (offset < 0) { offsetstr = ki18nc("N days/hours/minutes before/after the start/end", "%1 before the start"); offset = -offset; } else { offsetstr = ki18nc("N days/hours/minutes before/after the start/end", "%1 after the start"); } } else if (alarm->hasEndOffset()) { offset = alarm->endOffset().asSeconds(); if (offset < 0) { offsetstr = ki18nc("N days/hours/minutes before/after the start/end", "%1 before the end"); offset = -offset; } else { offsetstr = ki18nc("N days/hours/minutes before/after the start/end", "%1 after the end"); } } offset = offset / 60; // make minutes int useoffset = offset; if (offset % (24 * 60) == 0 && offset > 0) { // divides evenly into days? useoffset = offset / (24 * 60); offsetstr = offsetstr.subs(i18np("1 day", "%1 days", useoffset)); } else if (offset % 60 == 0 && offset > 0) { // divides evenly into hours? useoffset = offset / 60; offsetstr = offsetstr.subs(i18np("1 hour", "%1 hours", useoffset)); } else { useoffset = offset; offsetstr = offsetstr.subs(i18np("1 minute", "%1 minutes", useoffset)); } alarmStrings << offsetstr.toString(); } txt = alarmStrings.join(i18nc("Spacer for the joined list of categories", ", ")); } h = qMax(printCaptionAndText(p, alarmBox, cap, txt, captionFont, textFont), h); } QRect organizerBox(timesBox.left() + padding(), h + padding(), timesBox.right() - padding(), lineHeight); h = qMax(printCaptionAndText(p, organizerBox, i18n("Organizer: "), (*it)->organizer().fullName(), captionFont, textFont), h); // Finally, draw the frame around the time information... timesBox.setBottom(qMax(timesBox.bottom(), h + padding())); drawBox(p, BOX_BORDER_WIDTH, timesBox); QRect locationBox(timesBox); locationBox.setTop(timesBox.bottom() + padding()); locationBox.setHeight(0); int locationBottom = 0; if (!isJournal) { locationBottom = drawBoxWithCaption(p, locationBox, i18n("Location: "), (*it)->location(), /*sameLine=*/ true, /*expand=*/ true, captionFont, textFont); } locationBox.setBottom(locationBottom); // Now start constructing the boxes from the bottom: QRect footerBox(locationBox); footerBox.setBottom(box.bottom()); footerBox.setTop(footerBox.bottom() - lineHeight - 2 * padding()); QRect categoriesBox(footerBox); categoriesBox.setBottom(footerBox.top()); categoriesBox.setTop(categoriesBox.bottom() - lineHeight - 2 * padding()); QRect attendeesBox(box.left(), categoriesBox.top() - padding() - box.height() / 9, box.width(), box.height() / 9); QRect attachmentsBox(box.left(), attendeesBox.top() - padding() - box.height() / 9, box.width() * 3 / 4 - padding(), box.height() / 9); QRect optionsBox(isJournal ? box.left() : attachmentsBox.right() + padding(), attachmentsBox.top(), 0, 0); optionsBox.setRight(box.right()); optionsBox.setBottom(attachmentsBox.bottom()); QRect notesBox(optionsBox.left(), isJournal ? (timesBox.bottom() + padding()) : (locationBox.bottom() + padding()), optionsBox.width(), 0); notesBox.setBottom(optionsBox.top() - padding()); QRect descriptionBox(notesBox); descriptionBox.setLeft(box.left()); descriptionBox.setRight(attachmentsBox.right()); // Adjust boxes depending on the show options... if (!mShowSubitemsNotes || isJournal) { descriptionBox.setRight(box.right()); } if (!mShowAttachments || !mShowAttendees) { descriptionBox.setBottom(attachmentsBox.bottom()); optionsBox.setTop(attendeesBox.top()); optionsBox.setBottom(attendeesBox.bottom()); notesBox.setBottom(attachmentsBox.bottom()); if (mShowOptions) { attendeesBox.setRight(attachmentsBox.right()); } if (!mShowAttachments && !mShowAttendees) { if (mShowSubitemsNotes) { descriptionBox.setBottom(attendeesBox.bottom()); } if (!mShowOptions) { descriptionBox.setBottom(attendeesBox.bottom()); notesBox.setBottom(attendeesBox.bottom()); } } } if (mShowAttachments && !isJournal) { if (!mShowOptions) { attachmentsBox.setRight(box.right()); attachmentsBox.setRight(box.right()); } if (!mShowAttendees) { attachmentsBox.setTop(attendeesBox.top()); attachmentsBox.setBottom(attendeesBox.bottom()); } } int newBottom = drawBoxWithCaption(p, descriptionBox, i18n("Description:"), (*it)->description(), /*sameLine=*/ false, /*expand=*/ false, captionFont, textFont, (*it)->descriptionIsRich()); if (mShowNoteLines) { drawNoteLines(p, descriptionBox, newBottom); } Akonadi::Item item = mCalendar->item((*it)->uid()); Akonadi::Item::List relations = mCalendar->childItems(item.id()); if (mShowSubitemsNotes && !isJournal) { - if (relations.isEmpty() || (*it)->type() != KCalCore::Incidence::TypeTodo) { + if (relations.isEmpty() || (*it)->type() != KCalendarCore::Incidence::TypeTodo) { int notesPosition = drawBoxWithCaption(p, notesBox, i18n("Notes:"), QString(), /*sameLine=*/ false, /*expand=*/ false, captionFont, textFont); drawNoteLines(p, notesBox, notesPosition); } else { QString subitemCaption; if (relations.isEmpty()) { subitemCaption = i18n("No Subitems"); txt.clear(); } else { subitemCaption = i18np("1 Subitem:", "%1 Subitems:", relations.count()); } QString subitemString; QString statusString; QString datesString; int count = 0; for (const Akonadi::Item &item : qAsConst(relations)) { - KCalCore::Todo::Ptr todo = CalendarSupport::todo(item); + KCalendarCore::Todo::Ptr todo = CalendarSupport::todo(item); ++count; if (!todo) { // defensive, skip any zero pointers continue; } // format the status statusString = KCalUtils::Stringify::incidenceStatus(todo->status()); if (statusString.isEmpty()) { - if (todo->status() == KCalCore::Incidence::StatusNone) { + if (todo->status() == KCalendarCore::Incidence::StatusNone) { statusString = i18nc("no status", "none"); } else { statusString = i18nc("unknown status", "unknown"); } } // format the dates if provided datesString.clear(); if (todo->dtStart().isValid()) { datesString += i18nc("subitem start date", "Start Date: %1\n", QLocale().toString(todo->dtStart().toLocalTime().date(), QLocale::ShortFormat)); if (!todo->allDay()) { datesString += i18nc("subitem start time", "Start Time: %1\n", QLocale().toString(todo->dtStart().toLocalTime(). time(), QLocale::ShortFormat)); } } - if (todo->dateTime(KCalCore::Incidence::RoleEnd).isValid()) { + if (todo->dateTime(KCalendarCore::Incidence::RoleEnd).isValid()) { subitemString += i18nc("subitem due date", "Due Date: %1\n", - QLocale().toString(todo->dateTime(KCalCore::Incidence + QLocale().toString(todo->dateTime(KCalendarCore::Incidence ::RoleEnd). toLocalTime().date(), QLocale::ShortFormat)); if (!todo->allDay()) { subitemString += i18nc("subitem due time", "Due Time: %1\n", - QLocale().toString(todo->dateTime(KCalCore:: + QLocale().toString(todo->dateTime(KCalendarCore:: Incidence:: RoleEnd). toLocalTime().time(), QLocale::ShortFormat)); } } subitemString += i18nc("subitem counter", "%1: ", count); subitemString += todo->summary(); subitemString += QLatin1Char('\n'); if (!datesString.isEmpty()) { subitemString += datesString; subitemString += QLatin1Char('\n'); } subitemString += i18nc("subitem Status: statusString", "Status: %1\n", statusString); subitemString += KCalUtils::IncidenceFormatter::recurrenceString(todo) + QLatin1Char('\n'); subitemString += i18nc("subitem Priority: N", "Priority: %1\n", QString::number(todo->priority())); subitemString += i18nc("subitem Secrecy: secrecyString", "Secrecy: %1\n", KCalUtils::Stringify::incidenceSecrecy(todo->secrecy())); subitemString += QLatin1Char('\n'); } drawBoxWithCaption(p, notesBox, subitemCaption, subitemString, /*sameLine=*/ false, /*expand=*/ false, captionFont, textFont); } } if (mShowAttachments && !isJournal) { - const KCalCore::Attachment::List attachments = (*it)->attachments(); + const KCalendarCore::Attachment::List attachments = (*it)->attachments(); QString attachmentCaption; if (attachments.isEmpty()) { attachmentCaption = i18n("No Attachments"); txt.clear(); } else { attachmentCaption = i18np("1 Attachment:", "%1 Attachments:", attachments.count()); } QString attachmentString; - KCalCore::Attachment::List::ConstIterator ait = attachments.constBegin(); + KCalendarCore::Attachment::List::ConstIterator ait = attachments.constBegin(); for (; ait != attachments.constEnd(); ++ait) { if (!attachmentString.isEmpty()) { attachmentString += i18nc("Spacer for list of attachments", " "); } attachmentString.append((*ait).label()); } drawBoxWithCaption(p, attachmentsBox, attachmentCaption, attachmentString, /*sameLine=*/ false, /*expand=*/ false, captionFont, textFont); } if (mShowAttendees) { - const KCalCore::Attendee::List attendees = (*it)->attendees(); + const KCalendarCore::Attendee::List attendees = (*it)->attendees(); QString attendeeCaption; if (attendees.isEmpty()) { attendeeCaption = i18n("No Attendees"); } else { attendeeCaption = i18np("1 Attendee:", "%1 Attendees:", attendees.count()); } QString attendeeString; - KCalCore::Attendee::List::ConstIterator ait = attendees.constBegin(); + KCalendarCore::Attendee::List::ConstIterator ait = attendees.constBegin(); for (; ait != attendees.constEnd(); ++ait) { if (!attendeeString.isEmpty()) { attendeeString += QLatin1Char('\n'); } attendeeString += i18nc( "Formatting of an attendee: " "'Name (Role): Status', e.g. 'Reinhold Kainhofer " " (Participant): Awaiting Response'", "%1 (%2): %3", (*ait).fullName(), KCalUtils::Stringify::attendeeRole((*ait).role()), KCalUtils::Stringify::attendeeStatus((*ait).status())); } drawBoxWithCaption(p, attendeesBox, attendeeCaption, attendeeString, /*sameLine=*/ false, /*expand=*/ false, captionFont, textFont); } if (mShowOptions) { QString optionsString; if (!KCalUtils::Stringify::incidenceStatus((*it)->status()).isEmpty()) { optionsString += i18n("Status: %1", KCalUtils::Stringify::incidenceStatus((*it)->status())); optionsString += QLatin1Char('\n'); } if (!KCalUtils::Stringify::incidenceSecrecy((*it)->secrecy()).isEmpty()) { optionsString += i18n("Secrecy: %1", KCalUtils::Stringify::incidenceSecrecy((*it)->secrecy())); optionsString += QLatin1Char('\n'); } - if ((*it)->type() == KCalCore::Incidence::TypeEvent) { - KCalCore::Event::Ptr e = (*it).staticCast(); - if (e->transparency() == KCalCore::Event::Opaque) { + if ((*it)->type() == KCalendarCore::Incidence::TypeEvent) { + KCalendarCore::Event::Ptr e = (*it).staticCast(); + if (e->transparency() == KCalendarCore::Event::Opaque) { optionsString += i18n("Show as: Busy"); } else { optionsString += i18n("Show as: Free"); } optionsString += QLatin1Char('\n'); - } else if ((*it)->type() == KCalCore::Incidence::TypeTodo) { - KCalCore::Todo::Ptr t = (*it).staticCast(); + } else if ((*it)->type() == KCalendarCore::Incidence::TypeTodo) { + KCalendarCore::Todo::Ptr t = (*it).staticCast(); if (t->isOverdue()) { optionsString += i18n("This task is overdue!"); optionsString += QLatin1Char('\n'); } - } else if ((*it)->type() == KCalCore::Incidence::TypeJournal) { + } else if ((*it)->type() == KCalendarCore::Incidence::TypeJournal) { //TODO: Anything Journal-specific? } drawBoxWithCaption(p, optionsBox, i18n("Settings: "), optionsString, /*sameLine=*/ false, /*expand=*/ false, captionFont, textFont); } drawBoxWithCaption(p, categoriesBox, i18n("Categories: "), (*it)->categories().join(i18nc("Spacer for the joined list of categories", ", ")), /*sameLine=*/ true, /*expand=*/ false, captionFont, textFont); if (mPrintFooter) { drawFooter(p, footerBox); } } p.setFont(oldFont); } /************************************************************** * Print Day **************************************************************/ CalPrintDay::CalPrintDay() : CalPrintPluginBase() { } CalPrintDay::~CalPrintDay() { } QWidget *CalPrintDay::createConfigWidget(QWidget *w) { return new CalPrintDayConfig(w); } void CalPrintDay::readSettingsWidget() { CalPrintDayConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { mFromDate = cfg->mFromDate->date(); mToDate = cfg->mToDate->date(); if (cfg->mPrintTypeFilofax->isChecked()) { mDayPrintType = Filofax; } else if (cfg->mPrintTypeTimetable->isChecked()) { mDayPrintType = Timetable; } else { mDayPrintType = SingleTimetable; } mStartTime = cfg->mFromTime->time(); mEndTime = cfg->mToTime->time(); mIncludeAllEvents = cfg->mIncludeAllEvents->isChecked(); mIncludeDescription = cfg->mIncludeDescription->isChecked(); mSingleLineLimit = cfg->mSingleLineLimit->isChecked(); mIncludeTodos = cfg->mIncludeTodos->isChecked(); mUseColors = cfg->mColors->isChecked(); mPrintFooter = cfg->mPrintFooter->isChecked(); mShowNoteLines = cfg->mShowNoteLines->isChecked(); mExcludeTime = cfg->mExcludeTime->isChecked(); mExcludeConfidential = cfg->mExcludeConfidential->isChecked(); mExcludePrivate = cfg->mExcludePrivate->isChecked(); } } void CalPrintDay::setSettingsWidget() { CalPrintDayConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { cfg->mFromDate->setDate(mFromDate); cfg->mToDate->setDate(mToDate); cfg->mPrintTypeFilofax->setChecked(mDayPrintType == Filofax); cfg->mPrintTypeTimetable->setChecked(mDayPrintType == Timetable); cfg->mPrintTypeSingleTimetable->setChecked(mDayPrintType == SingleTimetable); cfg->mFromTime->setTime(mStartTime); cfg->mToTime->setTime(mEndTime); cfg->mIncludeAllEvents->setChecked(mIncludeAllEvents); cfg->mIncludeDescription->setChecked(mIncludeDescription); cfg->mSingleLineLimit->setChecked(mSingleLineLimit); cfg->mIncludeTodos->setChecked(mIncludeTodos); cfg->mColors->setChecked(mUseColors); cfg->mPrintFooter->setChecked(mPrintFooter); cfg->mShowNoteLines->setChecked(mShowNoteLines); cfg->mExcludeTime->setChecked(mExcludeTime); cfg->mExcludeConfidential->setChecked(mExcludeConfidential); cfg->mExcludePrivate->setChecked(mExcludePrivate); } } void CalPrintDay::loadConfig() { if (mConfig) { KConfigGroup grp(mConfig, groupName()); QDate dt = QDate::currentDate(); // any valid QDate will do QTime tm1(dayStart()); QDateTime startTm(dt, tm1); QDateTime endTm(dt, tm1.addSecs(12 * 60 * 60)); mStartTime = grp.readEntry("Start time", startTm).time(); mEndTime = grp.readEntry("End time", endTm).time(); mIncludeDescription = grp.readEntry("Include description", false); mIncludeTodos = grp.readEntry("Include todos", false); mIncludeAllEvents = grp.readEntry("Include all events", false); mDayPrintType = static_cast(grp.readEntry("Print type", static_cast(Timetable))); mSingleLineLimit = grp.readEntry("Single line limit", false); mShowNoteLines = grp.readEntry("Note Lines", false); mExcludeTime = grp.readEntry("Exclude time", false); mExcludeConfidential = grp.readEntry("Exclude confidential", true); mExcludePrivate = grp.readEntry("Exclude private", true); } setSettingsWidget(); } void CalPrintDay::saveConfig() { readSettingsWidget(); if (mConfig) { KConfigGroup grp(mConfig, groupName()); QDateTime dt = QDateTime::currentDateTime(); // any valid QDateTime will do dt.setTime(mStartTime); grp.writeEntry("Start time", dt); dt.setTime(mEndTime); grp.writeEntry("End time", dt); grp.writeEntry("Include description", mIncludeDescription); grp.writeEntry("Include todos", mIncludeTodos); grp.writeEntry("Include all events", mIncludeAllEvents); grp.writeEntry("Print type", int(mDayPrintType)); grp.writeEntry("Single line limit", mSingleLineLimit); grp.writeEntry("Note Lines", mShowNoteLines); grp.writeEntry("Exclude time", mExcludeTime); grp.writeEntry("Exclude confidential", mExcludeConfidential); grp.writeEntry("Exclude private", mExcludePrivate); } } void CalPrintDay::setDateRange(const QDate &from, const QDate &to) { CalPrintPluginBase::setDateRange(from, to); CalPrintDayConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { cfg->mFromDate->setDate(from); cfg->mToDate->setDate(to); } } void CalPrintDay::print(QPainter &p, int width, int height) { QDate curDay(mFromDate); QRect headerBox(0, 0, width, headerHeight()); QRect footerBox(0, height - footerHeight(), width, footerHeight()); height -= footerHeight(); auto local = QLocale::system(); switch (mDayPrintType) { case Filofax: case SingleTimetable: { QRect daysBox(headerBox); daysBox.setTop(headerBox.bottom() + padding()); daysBox.setBottom(height); QString line1 = local.toString(mFromDate, QLocale::ShortFormat); QString line2 = local.toString(mToDate, QLocale::ShortFormat); QString title; if (orientation() == QPrinter::Landscape) { title = i18nc("date from-to", "%1 - %2", line1, line2); } else { title = i18nc("date from-\nto", "%1 -\n%2", line1, line2); } drawHeader(p, title, mFromDate, QDate(), headerBox); if (mDayPrintType == Filofax) { drawDays(p, mFromDate, mToDate, mStartTime, mEndTime, daysBox, mSingleLineLimit, mShowNoteLines, mIncludeDescription, mExcludeConfidential, mExcludePrivate); } else if (mDayPrintType == SingleTimetable) { drawTimeTable(p, mFromDate, mToDate, mIncludeAllEvents, mStartTime, mEndTime, daysBox, mIncludeDescription, mExcludeTime, mExcludeConfidential, mExcludePrivate); } if (mPrintFooter) { drawFooter(p, footerBox); } break; } case Timetable: default: do { QTime curStartTime(mStartTime); QTime curEndTime(mEndTime); // For an invalid time range, simply show one hour, starting at the hour // before the given start time if (curEndTime <= curStartTime) { curStartTime = QTime(curStartTime.hour(), 0, 0); curEndTime = curStartTime.addSecs(3600); } drawHeader(p, local.toString(curDay, QLocale::ShortFormat), curDay, QDate(), headerBox); - KCalCore::Event::List eventList = mCalendar->events(curDay, QTimeZone::systemTimeZone(), - KCalCore::EventSortStartDate, - KCalCore::SortDirectionAscending); + KCalendarCore::Event::List eventList = mCalendar->events(curDay, QTimeZone::systemTimeZone(), + KCalendarCore::EventSortStartDate, + KCalendarCore::SortDirectionAscending); // split out the all day events as they will be printed in a separate box - KCalCore::Event::List alldayEvents, timedEvents; - for (const KCalCore::Event::Ptr &event : qAsConst(eventList)) { + KCalendarCore::Event::List alldayEvents, timedEvents; + for (const KCalendarCore::Event::Ptr &event : qAsConst(eventList)) { if (event->allDay()) { alldayEvents.append(event); } else { timedEvents.append(event); } } int fontSize = 11; QFont textFont(QStringLiteral("sans-serif"), fontSize, QFont::Normal); p.setFont(textFont); int lineSpacing = p.fontMetrics().lineSpacing(); int maxAllDayEvents = 8; // the max we allow to be printed, sorry. int allDayHeight = qMin(alldayEvents.count(), maxAllDayEvents) * lineSpacing; allDayHeight = qMax(allDayHeight, (5 * lineSpacing)) + (2 * padding()); QRect allDayBox(TIMELINE_WIDTH + padding(), headerBox.bottom() + padding(), width - TIMELINE_WIDTH - padding(), allDayHeight); if (!alldayEvents.isEmpty()) { // draw the side bar for all-day events QFont oldFont(p.font()); p.setFont(QFont(QStringLiteral("sans-serif"), 9, QFont::Normal)); drawVerticalBox(p, BOX_BORDER_WIDTH, QRect(0, headerBox.bottom() + padding(), TIMELINE_WIDTH, allDayHeight), i18n("Today's Events"), Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap); p.setFont(oldFont); // now draw at most maxAllDayEvents in the all-day box drawBox(p, BOX_BORDER_WIDTH, allDayBox); QRect eventBox(allDayBox); eventBox.setLeft(TIMELINE_WIDTH + (2 * padding())); eventBox.setTop(eventBox.top() + padding()); eventBox.setBottom(eventBox.top() + lineSpacing); int count = 0; - for (const KCalCore::Event::Ptr &event : qAsConst(alldayEvents)) { + for (const KCalendarCore::Event::Ptr &event : qAsConst(alldayEvents)) { if (count == maxAllDayEvents) { break; } count++; QString str; if (event->location().isEmpty()) { str = cleanStr(event->summary()); } else { str = i18nc("summary, location", "%1, %2", cleanStr(event->summary()), cleanStr(event->location())); } printEventString(p, eventBox, str); eventBox.setTop(eventBox.bottom()); eventBox.setBottom(eventBox.top() + lineSpacing); } } else { allDayBox.setBottom(headerBox.bottom()); } QRect dayBox(allDayBox); dayBox.setTop(allDayBox.bottom() + padding()); dayBox.setBottom(height); QList workDays = CalendarSupport::workDays(curDay, curDay); drawAgendaDayBox(p, timedEvents, curDay, mIncludeAllEvents, curStartTime, curEndTime, dayBox, mIncludeDescription, mExcludeTime, mExcludeConfidential, mExcludePrivate, workDays); QRect tlBox(dayBox); tlBox.setLeft(0); tlBox.setWidth(TIMELINE_WIDTH); drawTimeLine(p, curStartTime, curEndTime, tlBox); if (mPrintFooter) { drawFooter(p, footerBox); } curDay = curDay.addDays(1); if (curDay <= mToDate) { mPrinter->newPage(); } } while (curDay <= mToDate); } //switch } /************************************************************** * Print Week **************************************************************/ CalPrintWeek::CalPrintWeek() : CalPrintPluginBase() { } CalPrintWeek::~CalPrintWeek() { } QWidget *CalPrintWeek::createConfigWidget(QWidget *w) { return new CalPrintWeekConfig(w); } void CalPrintWeek::readSettingsWidget() { CalPrintWeekConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { mFromDate = cfg->mFromDate->date(); mToDate = cfg->mToDate->date(); if (cfg->mPrintTypeFilofax->isChecked()) { mWeekPrintType = Filofax; } else if (cfg->mPrintTypeTimetable->isChecked()) { mWeekPrintType = Timetable; } else if (cfg->mPrintTypeSplitWeek->isChecked()) { mWeekPrintType = SplitWeek; } else { mWeekPrintType = Timetable; } mStartTime = cfg->mFromTime->time(); mEndTime = cfg->mToTime->time(); mShowNoteLines = cfg->mShowNoteLines->isChecked(); mSingleLineLimit = cfg->mSingleLineLimit->isChecked(); mIncludeTodos = cfg->mIncludeTodos->isChecked(); mUseColors = cfg->mColors->isChecked(); mPrintFooter = cfg->mPrintFooter->isChecked(); mIncludeDescription = cfg->mIncludeDescription->isChecked(); mExcludeTime = cfg->mExcludeTime->isChecked(); mExcludeConfidential = cfg->mExcludeConfidential->isChecked(); mExcludePrivate = cfg->mExcludePrivate->isChecked(); } } void CalPrintWeek::setSettingsWidget() { CalPrintWeekConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { cfg->mFromDate->setDate(mFromDate); cfg->mToDate->setDate(mToDate); cfg->mPrintTypeFilofax->setChecked(mWeekPrintType == Filofax); cfg->mPrintTypeTimetable->setChecked(mWeekPrintType == Timetable); cfg->mPrintTypeSplitWeek->setChecked(mWeekPrintType == SplitWeek); cfg->mFromTime->setTime(mStartTime); cfg->mToTime->setTime(mEndTime); cfg->mShowNoteLines->setChecked(mShowNoteLines); cfg->mSingleLineLimit->setChecked(mSingleLineLimit); cfg->mIncludeTodos->setChecked(mIncludeTodos); cfg->mColors->setChecked(mUseColors); cfg->mPrintFooter->setChecked(mPrintFooter); cfg->mIncludeDescription->setChecked(mIncludeDescription); cfg->mExcludeTime->setChecked(mExcludeTime); cfg->mExcludeConfidential->setChecked(mExcludeConfidential); cfg->mExcludePrivate->setChecked(mExcludePrivate); } } void CalPrintWeek::loadConfig() { if (mConfig) { KConfigGroup grp(mConfig, groupName()); QDate dt = QDate::currentDate(); // any valid QDate will do QTime tm1(dayStart()); QDateTime startTm(dt, tm1); QDateTime endTm(dt, tm1.addSecs(43200)); mStartTime = grp.readEntry("Start time", startTm).time(); mEndTime = grp.readEntry("End time", endTm).time(); mShowNoteLines = grp.readEntry("Note Lines", false); mSingleLineLimit = grp.readEntry("Single line limit", false); mIncludeTodos = grp.readEntry("Include todos", false); mWeekPrintType = (eWeekPrintType)(grp.readEntry("Print type", (int)Filofax)); mIncludeDescription = grp.readEntry("Include Description", false); mExcludeTime = grp.readEntry("Exclude Time", false); mExcludeConfidential = grp.readEntry("Exclude confidential", true); mExcludePrivate = grp.readEntry("Exclude private", true); } setSettingsWidget(); } void CalPrintWeek::saveConfig() { readSettingsWidget(); if (mConfig) { KConfigGroup grp(mConfig, groupName()); QDateTime dt = QDateTime::currentDateTime(); // any valid QDateTime will do dt.setTime(mStartTime); grp.writeEntry("Start time", dt); dt.setTime(mEndTime); grp.writeEntry("End time", dt); grp.writeEntry("Note Lines", mShowNoteLines); grp.writeEntry("Single line limit", mSingleLineLimit); grp.writeEntry("Include todos", mIncludeTodos); grp.writeEntry("Print type", int(mWeekPrintType)); grp.writeEntry("Include Description", mIncludeDescription); grp.writeEntry("Exclude Time", mExcludeTime); grp.writeEntry("Exclude confidential", mExcludeConfidential); grp.writeEntry("Exclude private", mExcludePrivate); } } QPrinter::Orientation CalPrintWeek::defaultOrientation() const { if (mWeekPrintType == Filofax) { return QPrinter::Portrait; } else if (mWeekPrintType == SplitWeek) { return QPrinter::Portrait; } else { return QPrinter::Landscape; } } void CalPrintWeek::setDateRange(const QDate &from, const QDate &to) { CalPrintPluginBase::setDateRange(from, to); CalPrintWeekConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { cfg->mFromDate->setDate(from); cfg->mToDate->setDate(to); } } void CalPrintWeek::print(QPainter &p, int width, int height) { QDate curWeek, fromWeek, toWeek; // correct begin and end to first and last day of week int weekdayCol = weekdayColumn(mFromDate.dayOfWeek()); fromWeek = mFromDate.addDays(-weekdayCol); weekdayCol = weekdayColumn(mToDate.dayOfWeek()); toWeek = mToDate.addDays(6 - weekdayCol); curWeek = fromWeek.addDays(6); auto local = QLocale::system(); QString line1, line2, title; QRect headerBox(0, 0, width, headerHeight()); QRect footerBox(0, height - footerHeight(), width, footerHeight()); height -= footerHeight(); QRect weekBox(headerBox); weekBox.setTop(headerBox.bottom() + padding()); weekBox.setBottom(height); switch (mWeekPrintType) { case Filofax: do { line1 = local.toString(curWeek.addDays(-6), QLocale::ShortFormat); line2 = local.toString(curWeek, QLocale::ShortFormat); if (orientation() == QPrinter::Landscape) { title = i18nc("date from-to", "%1 - %2", line1, line2); } else { title = i18nc("date from-\nto", "%1 -\n%2", line1, line2); } drawHeader(p, title, curWeek.addDays(-6), QDate(), headerBox); drawWeek(p, curWeek, mStartTime, mEndTime, weekBox, mSingleLineLimit, mShowNoteLines, mIncludeDescription, mExcludeConfidential, mExcludePrivate); if (mPrintFooter) { drawFooter(p, footerBox); } curWeek = curWeek.addDays(7); if (curWeek <= toWeek) { mPrinter->newPage(); } } while (curWeek <= toWeek); break; case Timetable: default: do { line1 = local.toString(curWeek.addDays(-6), QLocale::ShortFormat); line2 = local.toString(curWeek, QLocale::ShortFormat); if (orientation() == QPrinter::Landscape) { title = i18nc("date from - to (week number)", "%1 - %2 (Week %3)", line1, line2, curWeek.weekNumber()); } else { title = i18nc("date from -\nto (week number)", "%1 -\n%2 (Week %3)", line1, line2, curWeek.weekNumber()); } drawHeader(p, title, curWeek, QDate(), headerBox); drawTimeTable(p, fromWeek, curWeek, false, mStartTime, mEndTime, weekBox, mIncludeDescription, mExcludeTime, mExcludeConfidential, mExcludePrivate); if (mPrintFooter) { drawFooter(p, footerBox); } fromWeek = fromWeek.addDays(7); curWeek = fromWeek.addDays(6); if (curWeek <= toWeek) { mPrinter->newPage(); } } while (curWeek <= toWeek); break; case SplitWeek: { QRect weekBox1(weekBox); // On the left side there are four days (mo-th) plus the timeline, // on the right there are only three days (fr-su) plus the timeline. Don't // use the whole width, but rather give them the same width as on the left. weekBox1.setRight(int((width - TIMELINE_WIDTH) * 3. / 4. + TIMELINE_WIDTH)); do { QDate endLeft(fromWeek.addDays(3)); int hh = headerHeight(); drawSplitHeaderRight(p, fromWeek, curWeek, QDate(), width, hh); drawTimeTable(p, fromWeek, endLeft, false, mStartTime, mEndTime, weekBox, mIncludeDescription, mExcludeTime, mExcludeConfidential, mExcludePrivate); if (mPrintFooter) { drawFooter(p, weekBox1); } mPrinter->newPage(); drawSplitHeaderRight(p, fromWeek, curWeek, QDate(), width, hh); drawTimeTable(p, endLeft.addDays(1), curWeek, false, mStartTime, mEndTime, weekBox1, mIncludeDescription, mExcludeTime, mExcludeConfidential, mExcludePrivate); if (mPrintFooter) { drawFooter(p, footerBox); } fromWeek = fromWeek.addDays(7); curWeek = fromWeek.addDays(6); if (curWeek <= toWeek) { mPrinter->newPage(); } } while (curWeek <= toWeek); break; } } } /************************************************************** * Print Month **************************************************************/ CalPrintMonth::CalPrintMonth() : CalPrintPluginBase() { } CalPrintMonth::~CalPrintMonth() { } QWidget *CalPrintMonth::createConfigWidget(QWidget *w) { return new CalPrintMonthConfig(w); } void CalPrintMonth::readSettingsWidget() { CalPrintMonthConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { mFromDate = QDate(cfg->mFromYear->value(), cfg->mFromMonth->currentIndex() + 1, 1); mToDate = QDate(cfg->mToYear->value(), cfg->mToMonth->currentIndex() + 1, 1); mWeekNumbers = cfg->mWeekNumbers->isChecked(); mRecurDaily = cfg->mRecurDaily->isChecked(); mRecurWeekly = cfg->mRecurWeekly->isChecked(); mIncludeTodos = cfg->mIncludeTodos->isChecked(); mShowNoteLines = cfg->mShowNoteLines->isChecked(); mSingleLineLimit = cfg->mSingleLineLimit->isChecked(); mUseColors = cfg->mColors->isChecked(); mPrintFooter = cfg->mPrintFooter->isChecked(); mIncludeDescription = cfg->mIncludeDescription->isChecked(); mExcludeConfidential = cfg->mExcludeConfidential->isChecked(); mExcludePrivate = cfg->mExcludePrivate->isChecked(); } } void CalPrintMonth::setSettingsWidget() { CalPrintMonthConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { setDateRange(mFromDate, mToDate); cfg->mWeekNumbers->setChecked(mWeekNumbers); cfg->mRecurDaily->setChecked(mRecurDaily); cfg->mRecurWeekly->setChecked(mRecurWeekly); cfg->mIncludeTodos->setChecked(mIncludeTodos); cfg->mShowNoteLines->setChecked(mShowNoteLines); cfg->mSingleLineLimit->setChecked(mSingleLineLimit); cfg->mColors->setChecked(mUseColors); cfg->mPrintFooter->setChecked(mPrintFooter); cfg->mIncludeDescription->setChecked(mIncludeDescription); cfg->mExcludeConfidential->setChecked(mExcludeConfidential); cfg->mExcludePrivate->setChecked(mExcludePrivate); } } void CalPrintMonth::loadConfig() { if (mConfig) { KConfigGroup grp(mConfig, groupName()); mWeekNumbers = grp.readEntry("Print week numbers", true); mRecurDaily = grp.readEntry("Print daily incidences", true); mRecurWeekly = grp.readEntry("Print weekly incidences", true); mIncludeTodos = grp.readEntry("Include todos", false); mSingleLineLimit = grp.readEntry("Single line limit", false); mShowNoteLines = grp.readEntry("Note Lines", false); mIncludeDescription = grp.readEntry("Include description", false); mExcludeConfidential = grp.readEntry("Exclude confidential", true); mExcludePrivate = grp.readEntry("Exclude private", true); } setSettingsWidget(); } void CalPrintMonth::saveConfig() { readSettingsWidget(); if (mConfig) { KConfigGroup grp(mConfig, groupName()); grp.writeEntry("Print week numbers", mWeekNumbers); grp.writeEntry("Print daily incidences", mRecurDaily); grp.writeEntry("Print weekly incidences", mRecurWeekly); grp.writeEntry("Include todos", mIncludeTodos); grp.writeEntry("Single line limit", mSingleLineLimit); grp.writeEntry("Note Lines", mShowNoteLines); grp.writeEntry("Include description", mIncludeDescription); grp.writeEntry("Exclude confidential", mExcludeConfidential); grp.writeEntry("Exclude private", mExcludePrivate); } } void CalPrintMonth::setDateRange(const QDate &from, const QDate &to) { CalPrintPluginBase::setDateRange(from, to); CalPrintMonthConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { cfg->mFromMonth->clear(); for (int i = 0; i < 12; ++i) { cfg->mFromMonth->addItem(QLocale().monthName(i + 1, QLocale::LongFormat)); } cfg->mToMonth->clear(); for (int i = 0; i < 12; ++i) { cfg->mToMonth->addItem(QLocale().monthName(i + 1, QLocale::LongFormat)); } cfg->mFromMonth->setCurrentIndex(from.month() - 1); cfg->mFromYear->setValue(to.year()); cfg->mToMonth->setCurrentIndex(mToDate.month() - 1); cfg->mToYear->setValue(mToDate.year()); } } void CalPrintMonth::print(QPainter &p, int width, int height) { QDate curMonth, fromMonth, toMonth; fromMonth = mFromDate.addDays(-(mFromDate.day() - 1)); toMonth = mToDate.addDays(mToDate.daysInMonth() - mToDate.day()); curMonth = fromMonth; QRect headerBox(0, 0, width, headerHeight()); QRect footerBox(0, height - footerHeight(), width, footerHeight()); height -= footerHeight(); QRect monthBox(0, 0, width, height); monthBox.setTop(headerBox.bottom() + padding()); do { QString title(i18nc("monthname year", "%1 %2", QLocale::system().monthName(curMonth.month()), QString::number(curMonth.year()))); QDate tmp(fromMonth); int weekdayCol = weekdayColumn(tmp.dayOfWeek()); tmp = tmp.addDays(-weekdayCol); drawHeader(p, title, curMonth.addMonths(-1), curMonth.addMonths(1), headerBox); drawMonthTable(p, curMonth, QTime(), QTime(), mWeekNumbers, mRecurDaily, mRecurWeekly, mSingleLineLimit, mShowNoteLines, mIncludeDescription, mExcludeConfidential, mExcludePrivate, monthBox); if (mPrintFooter) { drawFooter(p, footerBox); } curMonth = curMonth.addDays(curMonth.daysInMonth()); if (curMonth <= toMonth) { mPrinter->newPage(); } } while (curMonth <= toMonth); } /************************************************************** * Print Todos **************************************************************/ CalPrintTodos::CalPrintTodos() : CalPrintPluginBase() { mTodoSortField = TodoFieldUnset; mTodoSortDirection = TodoDirectionUnset; } CalPrintTodos::~CalPrintTodos() { } QWidget *CalPrintTodos::createConfigWidget(QWidget *w) { return new CalPrintTodoConfig(w); } void CalPrintTodos::readSettingsWidget() { CalPrintTodoConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { mPageTitle = cfg->mTitle->text(); if (cfg->mPrintAll->isChecked()) { mTodoPrintType = TodosAll; } else if (cfg->mPrintUnfinished->isChecked()) { mTodoPrintType = TodosUnfinished; } else if (cfg->mPrintDueRange->isChecked()) { mTodoPrintType = TodosDueRange; } else { mTodoPrintType = TodosAll; } mFromDate = cfg->mFromDate->date(); mToDate = cfg->mToDate->date(); mIncludeDescription = cfg->mDescription->isChecked(); mIncludePriority = cfg->mPriority->isChecked(); mIncludeDueDate = cfg->mDueDate->isChecked(); mIncludePercentComplete = cfg->mPercentComplete->isChecked(); mConnectSubTodos = cfg->mConnectSubTodos->isChecked(); mStrikeOutCompleted = cfg->mStrikeOutCompleted->isChecked(); mExcludeConfidential = cfg->mExcludeConfidential->isChecked(); mExcludePrivate = cfg->mExcludePrivate->isChecked(); mTodoSortField = (eTodoSortField)cfg->mSortField->currentIndex(); mTodoSortDirection = (eTodoSortDirection)cfg->mSortDirection->currentIndex(); mPrintFooter = cfg->mPrintFooter->isChecked(); } } void CalPrintTodos::setSettingsWidget() { CalPrintTodoConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { cfg->mTitle->setText(mPageTitle); cfg->mPrintAll->setChecked(mTodoPrintType == TodosAll); cfg->mPrintUnfinished->setChecked(mTodoPrintType == TodosUnfinished); cfg->mPrintDueRange->setChecked(mTodoPrintType == TodosDueRange); cfg->mFromDate->setDate(mFromDate); cfg->mToDate->setDate(mToDate); cfg->mDescription->setChecked(mIncludeDescription); cfg->mPriority->setChecked(mIncludePriority); cfg->mDueDate->setChecked(mIncludeDueDate); cfg->mPercentComplete->setChecked(mIncludePercentComplete); cfg->mConnectSubTodos->setChecked(mConnectSubTodos); cfg->mStrikeOutCompleted->setChecked(mStrikeOutCompleted); cfg->mExcludeConfidential->setChecked(mExcludeConfidential); cfg->mExcludePrivate->setChecked(mExcludePrivate); if (mTodoSortField != TodoFieldUnset) { // do not insert if already done so. cfg->mSortField->addItem(i18nc("@option sort by title", "Title")); cfg->mSortField->addItem(i18nc("@option sort by start date/time", "Start Date")); cfg->mSortField->addItem(i18nc("@option sort by due date/time", "Due Date")); cfg->mSortField->addItem(i18nc("@option sort by priority", "Priority")); cfg->mSortField->addItem(i18nc("@option sort by percent completed", "Percent Complete")); cfg->mSortField->setCurrentIndex(mTodoSortField); } if (mTodoSortDirection != TodoDirectionUnset) { // do not insert if already done so. cfg->mSortDirection->addItem(i18nc("@option sort in increasing order", "Ascending")); cfg->mSortDirection->addItem(i18nc("@option sort in descreasing order", "Descending")); cfg->mSortDirection->setCurrentIndex(mTodoSortDirection); } cfg->mPrintFooter->setChecked(mPrintFooter); } } void CalPrintTodos::loadConfig() { if (mConfig) { KConfigGroup grp(mConfig, groupName()); mPageTitle = grp.readEntry("Page title", i18n("To-do list")); mTodoPrintType = (eTodoPrintType)grp.readEntry("Print type", static_cast(TodosAll)); mIncludeDescription = grp.readEntry("Include description", true); mIncludePriority = grp.readEntry("Include priority", true); mIncludeDueDate = grp.readEntry("Include due date", true); mIncludePercentComplete = grp.readEntry("Include percentage completed", true); mConnectSubTodos = grp.readEntry("Connect subtodos", true); mStrikeOutCompleted = grp.readEntry("Strike out completed summaries", true); mTodoSortField = (eTodoSortField)grp.readEntry("Sort field", static_cast(TodoFieldSummary)); mTodoSortDirection = (eTodoSortDirection)grp.readEntry("Sort direction", static_cast(TodoDirectionAscending)); mExcludeConfidential = grp.readEntry("Exclude confidential", true); mExcludePrivate = grp.readEntry("Exclude private", true); } setSettingsWidget(); } void CalPrintTodos::saveConfig() { readSettingsWidget(); if (mConfig) { KConfigGroup grp(mConfig, groupName()); grp.writeEntry("Page title", mPageTitle); grp.writeEntry("Print type", int(mTodoPrintType)); grp.writeEntry("Include description", mIncludeDescription); grp.writeEntry("Include priority", mIncludePriority); grp.writeEntry("Include due date", mIncludeDueDate); grp.writeEntry("Include percentage completed", mIncludePercentComplete); grp.writeEntry("Connect subtodos", mConnectSubTodos); grp.writeEntry("Strike out completed summaries", mStrikeOutCompleted); grp.writeEntry("Sort field", static_cast(mTodoSortField)); grp.writeEntry("Sort direction", static_cast(mTodoSortDirection)); grp.writeEntry("Exclude confidential", mExcludeConfidential); grp.writeEntry("Exclude private", mExcludePrivate); } } void CalPrintTodos::print(QPainter &p, int width, int height) { // TODO: Find a good way to guarantee a nicely designed output int pospriority = 0; int possummary = 100; int posdue = width - 65; int poscomplete = posdue - 70; //Complete column is to right of the Due column QRect headerBox(0, 0, width, headerHeight()); QRect footerBox(0, height - footerHeight(), width, footerHeight()); height -= footerHeight(); // Draw the First Page Header drawHeader(p, mPageTitle, mFromDate, QDate(), headerBox); // Draw the Column Headers int mCurrentLinePos = headerHeight() + 5; QString outStr; QFont oldFont(p.font()); p.setFont(QFont(QStringLiteral("sans-serif"), 9, QFont::Bold)); int lineSpacing = p.fontMetrics().lineSpacing(); mCurrentLinePos += lineSpacing; if (mIncludePriority) { outStr += i18n("Priority"); p.drawText(pospriority, mCurrentLinePos - 2, outStr); } else { pospriority = -1; } outStr.truncate(0); outStr += i18nc("@label to-do summary", "Title"); p.drawText(possummary, mCurrentLinePos - 2, outStr); if (mIncludePercentComplete) { if (!mIncludeDueDate) { //move Complete column to the right poscomplete = posdue; //if not print the Due Date column } outStr.truncate(0); outStr += i18nc("@label to-do percentage complete", "Complete"); p.drawText(poscomplete, mCurrentLinePos - 2, outStr); } else { poscomplete = -1; } if (mIncludeDueDate) { outStr.truncate(0); outStr += i18nc("@label to-do due date", "Due"); p.drawText(posdue, mCurrentLinePos - 2, outStr); } else { posdue = -1; } p.setFont(QFont(QStringLiteral("sans-serif"), 10)); //fontHeight = p.fontMetrics().height(); - KCalCore::Todo::List todoList; - KCalCore::Todo::List tempList; + KCalendarCore::Todo::List todoList; + KCalendarCore::Todo::List tempList; - KCalCore::SortDirection sortDirection = KCalCore::SortDirectionAscending; + KCalendarCore::SortDirection sortDirection = KCalendarCore::SortDirectionAscending; switch (mTodoSortDirection) { case TodoDirectionAscending: - sortDirection = KCalCore::SortDirectionAscending; + sortDirection = KCalendarCore::SortDirectionAscending; break; case TodoDirectionDescending: - sortDirection = KCalCore::SortDirectionDescending; + sortDirection = KCalendarCore::SortDirectionDescending; break; case TodoDirectionUnset: break; } - KCalCore::TodoSortField sortField = KCalCore::TodoSortSummary; + KCalendarCore::TodoSortField sortField = KCalendarCore::TodoSortSummary; switch (mTodoSortField) { case TodoFieldSummary: - sortField = KCalCore::TodoSortSummary; + sortField = KCalendarCore::TodoSortSummary; break; case TodoFieldStartDate: - sortField = KCalCore::TodoSortStartDate; + sortField = KCalendarCore::TodoSortStartDate; break; case TodoFieldDueDate: - sortField = KCalCore::TodoSortDueDate; + sortField = KCalendarCore::TodoSortDueDate; break; case TodoFieldPriority: - sortField = KCalCore::TodoSortPriority; + sortField = KCalendarCore::TodoSortPriority; break; case TodoFieldPercentComplete: - sortField = KCalCore::TodoSortPercentComplete; + sortField = KCalendarCore::TodoSortPercentComplete; break; case TodoFieldUnset: break; } // Create list of to-dos which will be printed todoList = mCalendar->todos(sortField, sortDirection); switch (mTodoPrintType) { case TodosAll: break; case TodosUnfinished: - for (const KCalCore::Todo::Ptr &todo : qAsConst(todoList)) { + for (const KCalendarCore::Todo::Ptr &todo : qAsConst(todoList)) { Q_ASSERT(todo); if (!todo->isCompleted()) { tempList.append(todo); } } todoList = tempList; break; case TodosDueRange: - for (const KCalCore::Todo::Ptr &todo : qAsConst(todoList)) { + for (const KCalendarCore::Todo::Ptr &todo : qAsConst(todoList)) { Q_ASSERT(todo); if (todo->hasDueDate()) { if (todo->dtDue().date() >= mFromDate && todo->dtDue().date() <= mToDate) { tempList.append(todo); } } else { tempList.append(todo); } } todoList = tempList; break; } // Print to-dos int count = 0; - for (const KCalCore::Todo::Ptr &todo : qAsConst(todoList)) { - if ((mExcludeConfidential && todo->secrecy() == KCalCore::Incidence::SecrecyConfidential) - || (mExcludePrivate && todo->secrecy() == KCalCore::Incidence::SecrecyPrivate)) { + for (const KCalendarCore::Todo::Ptr &todo : qAsConst(todoList)) { + if ((mExcludeConfidential && todo->secrecy() == KCalendarCore::Incidence::SecrecyConfidential) + || (mExcludePrivate && todo->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) { continue; } // Skip sub-to-dos. They will be printed recursively in drawTodo() if (todo->relatedTo().isEmpty()) { //review(AKONADI_PORT) count++; drawTodo(count, todo, p, sortField, sortDirection, mConnectSubTodos, mStrikeOutCompleted, mIncludeDescription, pospriority, possummary, posdue, poscomplete, 0, 0, mCurrentLinePos, width, height, todoList, nullptr, mExcludeConfidential, mExcludePrivate); } } if (mPrintFooter) { drawFooter(p, footerBox); } p.setFont(oldFont); } diff --git a/src/printing/calprinter.cpp b/src/printing/calprinter.cpp index 5fce8b1..9829f8a 100644 --- a/src/printing/calprinter.cpp +++ b/src/printing/calprinter.cpp @@ -1,342 +1,342 @@ /* Copyright (c) 1998 Preston Brown Copyright (C) 2003-2004 Reinhold Kainhofer 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 "calprinter.h" #include "calprintdefaultplugins.h" #include "journalprint.h" #include "yearprint.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace CalendarSupport; CalPrinter::CalPrinter(QWidget *parent, const Akonadi::ETMCalendar::Ptr &calendar, bool uniqItem) : QObject(parent) , mUniqItem(uniqItem) { mParent = parent; mConfig = new KConfig(QStringLiteral("calendar_printing.rc"), KConfig::SimpleConfig); init(calendar); } CalPrinter::~CalPrinter() { mPrintPlugins.clear(); delete mConfig; } void CalPrinter::init(const Akonadi::ETMCalendar::Ptr &calendar) { mCalendar = calendar; mPrintPlugins.clear(); if (!mUniqItem) { mPrintPlugins.prepend(new CalPrintYear()); mPrintPlugins.prepend(new CalPrintJournal()); mPrintPlugins.prepend(new CalPrintTodos()); mPrintPlugins.prepend(new CalPrintMonth()); mPrintPlugins.prepend(new CalPrintWeek()); mPrintPlugins.prepend(new CalPrintDay()); } mPrintPlugins.prepend(new CalPrintIncidence()); PrintPlugin::List::Iterator it = mPrintPlugins.begin(); PrintPlugin::List::Iterator end = mPrintPlugins.end(); for (; it != end; ++it) { if (*it) { (*it)->setConfig(mConfig); (*it)->setCalendar(mCalendar); (*it)->doLoadConfig(); } } } void CalPrinter::setDateRange(const QDate &fd, const QDate &td) { PrintPlugin::List::Iterator it = mPrintPlugins.begin(); const PrintPlugin::List::Iterator end = mPrintPlugins.end(); for (; it != end; ++it) { (*it)->setDateRange(fd, td); } } void CalPrinter::print(int type, const QDate &fd, const QDate &td, - const KCalCore::Incidence::List &selectedIncidences, bool preview) + const KCalendarCore::Incidence::List &selectedIncidences, bool preview) { PrintPlugin::List::Iterator it; const PrintPlugin::List::Iterator end = mPrintPlugins.end(); for (it = mPrintPlugins.begin(); it != end; ++it) { (*it)->setSelectedIncidences(selectedIncidences); } QPointer printDialog = new CalPrintDialog(type, mPrintPlugins, mParent, mUniqItem); KConfigGroup grp(mConfig, ""); //orientation setting isn't in a group printDialog->setOrientation(CalPrinter::ePrintOrientation(grp.readEntry("Orientation", 1))); printDialog->setPreview(preview); setDateRange(fd, td); if (printDialog->exec() == QDialog::Accepted) { grp.writeEntry("Orientation", static_cast(printDialog->orientation())); // Save all changes in the dialog for (it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it) { (*it)->doSaveConfig(); } doPrint(printDialog->selectedPlugin(), printDialog->orientation(), preview); } delete printDialog; for (it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it) { - (*it)->setSelectedIncidences(KCalCore::Incidence::List()); + (*it)->setSelectedIncidences(KCalendarCore::Incidence::List()); } } void CalPrinter::doPrint(PrintPlugin *selectedStyle, CalPrinter::ePrintOrientation dlgorientation, bool preview) { if (!selectedStyle) { KMessageBox::error( mParent, i18nc("@info", "Unable to print, an invalid print style was specified."), i18nc("@title:window", "Printing error")); return; } QPrinter printer; switch (dlgorientation) { case eOrientPlugin: printer.setOrientation(selectedStyle->defaultOrientation()); break; case eOrientPortrait: printer.setOrientation(QPrinter::Portrait); break; case eOrientLandscape: printer.setOrientation(QPrinter::Landscape); break; case eOrientPrinter: break; } if (preview) { QPointer printPreview = new PimCommon::KPimPrintPreviewDialog(&printer); connect(printPreview.data(), &QPrintPreviewDialog::paintRequested, this, [selectedStyle, &printer]() { selectedStyle->doPrint(&printer); }); printPreview->exec(); delete printPreview; } else { QPointer printDialog = new QPrintDialog(&printer, mParent); if (printDialog->exec() == QDialog::Accepted) { selectedStyle->doPrint(&printer); } delete printDialog; } } void CalPrinter::updateConfig() { } CalPrintDialog::CalPrintDialog(int initialPrintType, const PrintPlugin::List &plugins, QWidget *parent, bool uniqItem) : QDialog(parent) { setWindowTitle(i18nc("@title:window", "Print")); QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); QVBoxLayout *mainLayout = new QVBoxLayout(this); mOkButton = buttonBox->button(QDialogButtonBox::Ok); mOkButton->setDefault(true); mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &CalPrintDialog::slotOk); connect(buttonBox, &QDialogButtonBox::rejected, this, &CalPrintDialog::reject); setModal(true); QWidget *page = new QWidget(this); QVBoxLayout *pageVBoxLayout = new QVBoxLayout(page); pageVBoxLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addWidget(page); mainLayout->addWidget(buttonBox); QSplitter *splitter = new QSplitter(page); pageVBoxLayout->addWidget(splitter); splitter->setOrientation(Qt::Horizontal); splitter->setChildrenCollapsible(false); QGroupBox *typeBox = new QGroupBox(i18nc("@title:group", "Print Style"), splitter); QBoxLayout *typeLayout = new QVBoxLayout(typeBox); mTypeGroup = new QButtonGroup(typeBox); QWidget *splitterRight = new QWidget(splitter); QGridLayout *splitterRightLayout = new QGridLayout(splitterRight); splitterRightLayout->setContentsMargins(0, 0, 0, 0); //splitterRightLayout->setMargin( marginHint() ); //splitterRightLayout->setSpacing( spacingHint() ); mConfigArea = new QStackedWidget(splitterRight); splitterRightLayout->addWidget(mConfigArea, 0, 0, 1, 2); QLabel *orientationLabel = new QLabel(i18nc("@label", "Page &orientation:"), splitterRight); orientationLabel->setAlignment(Qt::AlignRight); splitterRightLayout->addWidget(orientationLabel, 1, 0); mOrientationSelection = new KComboBox(splitterRight); mOrientationSelection->setToolTip( i18nc("@info:tooltip", "Set the print orientation")); mOrientationSelection->setWhatsThis( i18nc("@info:whatsthis", "Choose if you want your output to be printed in \"portrait\" or " "\"landscape\". You can also default to the orientation best suited to " "the selected style or to your printer's default setting.")); mOrientationSelection->addItem(i18nc("@item:inlistbox", "Use Default Orientation of Selected Style")); mOrientationSelection->addItem(i18nc("@item:inlistbox", "Use Printer Default")); mOrientationSelection->addItem(i18nc("@item:inlistbox", "Portrait")); mOrientationSelection->addItem(i18nc("@item:inlistbox", "Landscape")); splitterRightLayout->addWidget(mOrientationSelection, 1, 1); // signals and slots connections connect(mTypeGroup, QOverload::of( &QButtonGroup::buttonClicked), this, &CalPrintDialog::setPrintType); orientationLabel->setBuddy(mOrientationSelection); // First insert the config widgets into the widget stack. This possibly assigns // proper ids (when two plugins have the same sortID), so store them in a map // and use these new IDs to later sort the plugins for the type selection. for (PrintPlugin::List::ConstIterator it = plugins.constBegin(), total = plugins.constEnd(); it != total; ++it) { int newid = mConfigArea->insertWidget((*it)->sortID(), (*it)->configWidget(mConfigArea)); mPluginIDs[newid] = (*it); } // Insert all plugins in sorted order; plugins with clashing IDs will be first QMap::ConstIterator mapit; bool firstButton = true; int id = 0; for (mapit = mPluginIDs.constBegin(); mapit != mPluginIDs.constEnd(); ++mapit) { PrintPlugin *p = mapit.value(); QRadioButton *radioButton = new QRadioButton(p->description()); radioButton->setEnabled(p->enabled()); radioButton->setToolTip( i18nc("@info:tooltip", "Select the type of print")); radioButton->setWhatsThis( i18nc("@info:whatsthis", "Select one of the following types of prints you want to make. " "You may want to print an individual item, or all the items for a " "specific time range (like a day, week or month), or you may want " "to print your to-do list.")); // Check the first available button (to ensure one is selected initially) and then // the button matching the desired print type -- if such is available! if ((firstButton || p->sortID() == initialPrintType) && p->enabled()) { firstButton = false; radioButton->setChecked(true); setPrintType(id); } mTypeGroup->addButton(radioButton, mapit.key()); typeLayout->addWidget(radioButton); id++; } if (uniqItem) { typeBox->hide(); } typeLayout->insertStretch(-1, 100); setMinimumSize(minimumSizeHint()); resize(minimumSizeHint()); } CalPrintDialog::~CalPrintDialog() { } void CalPrintDialog::setPreview(bool preview) { if (preview) { mOkButton->setText(i18nc("@action:button", "&Preview")); } else { mOkButton->setText(KStandardGuiItem::print().text()); } } void CalPrintDialog::setPrintType(int i) { mConfigArea->setCurrentIndex(i); mConfigArea->currentWidget()->raise(); QAbstractButton *btn = mTypeGroup->button(i); if (btn) { btn->setChecked(true); } } void CalPrintDialog::setOrientation(CalPrinter::ePrintOrientation orientation) { mOrientation = orientation; mOrientationSelection->setCurrentIndex(mOrientation); } CalPrinter::ePrintOrientation CalPrintDialog::orientation() const { return mOrientation; } PrintPlugin *CalPrintDialog::selectedPlugin() { int id = mConfigArea->currentIndex(); if (mPluginIDs.contains(id)) { return mPluginIDs[id]; } else { return nullptr; } } void CalPrintDialog::slotOk() { mOrientation = static_cast(mOrientationSelection->currentIndex()); QMap::ConstIterator it = mPluginIDs.constBegin(); for (; it != mPluginIDs.constEnd(); ++it) { if (it.value()) { it.value()->readSettingsWidget(); } } accept(); } diff --git a/src/printing/calprinter.h b/src/printing/calprinter.h index b89c64d..58c2814 100644 --- a/src/printing/calprinter.h +++ b/src/printing/calprinter.h @@ -1,127 +1,127 @@ /* Copyright (c) 1998 Preston Brown Copyright (C) 2003-2004 Reinhold Kainhofer 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 CALENDARSUPPORT_PRINTING_CALPRINTER_H #define CALENDARSUPPORT_PRINTING_CALPRINTER_H #include "calendarsupport_export.h" #include "printplugin.h" #include #include #include class QButtonGroup; class QStackedWidget; namespace CalendarSupport { /** CalPrinter is a class for printing Calendars. It can print in several different formats (day, week, month). It also provides a way for setting up the printer and remembering these preferences. */ class CALENDARSUPPORT_EXPORT CalPrinter : public QObject, public CalPrinterBase { Q_OBJECT public: enum ePrintOrientation { eOrientPlugin = 0, eOrientPrinter, eOrientPortrait, eOrientLandscape }; public: /** \param par parent widget for dialogs \param cal calendar to be printed \param uniqItem if true, indicates the calendar print dialog will only provide the option to print an single incidence; else, all possible types of print types will be shown */ CalPrinter(QWidget *par, const Akonadi::ETMCalendar::Ptr &calendar, bool uniqItem = false); ~CalPrinter() override; void init(const Akonadi::ETMCalendar::Ptr &calendar); /** Set date range to be printed. \param start Start date \param end End date */ void setDateRange(const QDate &start, const QDate &end); public Q_SLOTS: void updateConfig(); private Q_SLOTS: void doPrint(CalendarSupport::PrintPlugin *selectedStyle, CalendarSupport::CalPrinter::ePrintOrientation dlgorientation, bool preview = false); public: void print(int type, const QDate &fd, const QDate &td, - const KCalCore::Incidence::List &selectedIncidences = KCalCore::Incidence::List(), bool preview = false); + const KCalendarCore::Incidence::List &selectedIncidences = KCalendarCore::Incidence::List(), bool preview = false); Akonadi::ETMCalendar::Ptr calendar() const; KConfig *config() const; protected: PrintPlugin::List mPrintPlugins; private: Akonadi::ETMCalendar::Ptr mCalendar; QWidget *mParent = nullptr; KConfig *mConfig = nullptr; bool mUniqItem; }; class CalPrintDialog : public QDialog { Q_OBJECT public: explicit CalPrintDialog(int initialPrintType, const PrintPlugin::List &plugins, QWidget *parent = nullptr, bool mUniqItem = false); ~CalPrintDialog() override; PrintPlugin *selectedPlugin(); void setOrientation(CalPrinter::ePrintOrientation orientation); CalPrinter::ePrintOrientation orientation() const; public Q_SLOTS: void setPrintType(int); void setPreview(bool); private: void slotOk(); QButtonGroup *mTypeGroup = nullptr; QStackedWidget *mConfigArea = nullptr; QMap mPluginIDs; QString mPreviewText; KComboBox *mOrientationSelection = nullptr; QPushButton *mOkButton = nullptr; CalPrinter::ePrintOrientation mOrientation; }; } #endif diff --git a/src/printing/calprintpluginbase.cpp b/src/printing/calprintpluginbase.cpp index 04641da..7b747e4 100644 --- a/src/printing/calprintpluginbase.cpp +++ b/src/printing/calprintpluginbase.cpp @@ -1,2220 +1,2220 @@ /* Copyright (c) 1998 Preston Brown Copyright (C) 2003 Reinhold Kainhofer Copyright (C) 2008 Ron Goodheart Copyright (c) 2012-2013 Allen Winter 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 "calprintpluginbase.h" #include "cellitem.h" #include "kcalprefs.h" #include "utils.h" #include #include #include "calendarsupport_debug.h" #include #include #include #include #include #include #include #include #include #include // qCeil krazy:exclude=camelcase since no QMath #include #include #include #include using namespace CalendarSupport; static QString cleanStr(const QString &instr) { QString ret = instr; return ret.replace(QLatin1Char('\n'), QLatin1Char(' ')); } /****************************************************************** ** The Todo positioning structure ** ******************************************************************/ class CalPrintPluginBase::TodoParentStart { public: TodoParentStart(const QRect &pt = QRect(), bool hasLine = false, bool page = true) : mRect(pt) , mHasLine(hasLine) , mSamePage(page) { } QRect mRect; bool mHasLine; bool mSamePage; }; /****************************************************************** ** The Print item ** ******************************************************************/ class PrintCellItem : public CellItem { public: - PrintCellItem(const KCalCore::Event::Ptr &event, const QDateTime &start, const QDateTime &end) + PrintCellItem(const KCalendarCore::Event::Ptr &event, const QDateTime &start, const QDateTime &end) : mEvent(event) , mStart(start) , mEnd(end) { } - KCalCore::Event::Ptr event() const + KCalendarCore::Event::Ptr event() const { return mEvent; } QString label() const override { return mEvent->summary(); } QDateTime start() const { return mStart; } QDateTime end() const { return mEnd; } /** Calculate the start and end date/time of the recurrence that happens on the given day */ bool overlaps(CellItem *o) const override { PrintCellItem *other = static_cast(o); return !(other->start() >= end() || other->end() <= start()); } private: - KCalCore::Event::Ptr mEvent; + KCalendarCore::Event::Ptr mEvent; QDateTime mStart, mEnd; }; /****************************************************************** ** The Print plugin ** ******************************************************************/ CalPrintPluginBase::CalPrintPluginBase() : PrintPlugin() , mUseColors(true) , mPrintFooter(true) , mHeaderHeight(-1) , mSubHeaderHeight(SUBHEADER_HEIGHT) , mFooterHeight(-1) , mMargin(MARGIN_SIZE) , mPadding(PADDING_SIZE) { } CalPrintPluginBase::~CalPrintPluginBase() { } QWidget *CalPrintPluginBase::createConfigWidget(QWidget *w) { QFrame *wdg = new QFrame(w); QVBoxLayout *layout = new QVBoxLayout(wdg); QLabel *title = new QLabel(description(), wdg); QFont titleFont(title->font()); titleFont.setPointSize(20); titleFont.setBold(true); title->setFont(titleFont); layout->addWidget(title); layout->addWidget(new QLabel(info(), wdg)); layout->addSpacing(20); layout->addWidget( new QLabel(i18n("This printing style does not have any configuration options."), wdg)); layout->addStretch(); return wdg; } void CalPrintPluginBase::doPrint(QPrinter *printer) { if (!printer) { return; } mPrinter = printer; QPainter p; mPrinter->setColorMode(mUseColors ? QPrinter::Color : QPrinter::GrayScale); p.begin(mPrinter); // TODO: Fix the margins!!! // the painter initially begins at 72 dpi per the Qt docs. // we want half-inch margins. int margins = margin(); p.setViewport(margins, margins, p.viewport().width() - 2 * margins, p.viewport().height() - 2 * margins); // QRect vp( p.viewport() ); // vp.setRight( vp.right()*2 ); // vp.setBottom( vp.bottom()*2 ); // p.setWindow( vp ); int pageWidth = p.window().width(); int pageHeight = p.window().height(); // int pageWidth = p.viewport().width(); // int pageHeight = p.viewport().height(); print(p, pageWidth, pageHeight); p.end(); mPrinter = nullptr; } void CalPrintPluginBase::doLoadConfig() { if (mConfig) { KConfigGroup group(mConfig, groupName()); mConfig->sync(); QDateTime dt = QDateTime::currentDateTime(); mFromDate = group.readEntry("FromDate", dt).date(); mToDate = group.readEntry("ToDate", dt).date(); mUseColors = group.readEntry("UseColors", true); mPrintFooter = group.readEntry("PrintFooter", true); loadConfig(); } else { qCDebug(CALENDARSUPPORT_LOG) << "No config available in loadConfig!!!!"; } } void CalPrintPluginBase::doSaveConfig() { if (mConfig) { KConfigGroup group(mConfig, groupName()); saveConfig(); QDateTime dt = QDateTime::currentDateTime(); // any valid QDateTime will do dt.setDate(mFromDate); group.writeEntry("FromDate", dt); dt.setDate(mToDate); group.writeEntry("ToDate", dt); group.writeEntry("UseColors", mUseColors); group.writeEntry("PrintFooter", mPrintFooter); mConfig->sync(); } else { qCDebug(CALENDARSUPPORT_LOG) << "No config available in saveConfig!!!!"; } } bool CalPrintPluginBase::useColors() const { return mUseColors; } void CalPrintPluginBase::setUseColors(bool useColors) { mUseColors = useColors; } bool CalPrintPluginBase::printFooter() const { return mPrintFooter; } void CalPrintPluginBase::setPrintFooter(bool printFooter) { mPrintFooter = printFooter; } QPrinter::Orientation CalPrintPluginBase::orientation() const { return mPrinter ? mPrinter->orientation() : QPrinter::Portrait; } QColor CalPrintPluginBase::getTextColor(const QColor &c) const { double luminance = (c.red() * 0.299) + (c.green() * 0.587) + (c.blue() * 0.114); return (luminance > 128.0) ? QColor(0, 0, 0) : QColor(255, 255, 255); } QTime CalPrintPluginBase::dayStart() const { QTime start(8, 0, 0); QDateTime dayBegins = KCalPrefs::instance()->dayBegins(); if (dayBegins.isValid()) { start = dayBegins.time(); } return start; } void CalPrintPluginBase::setColorsByIncidenceCategory(QPainter &p, - const KCalCore::Incidence::Ptr &incidence) + const KCalendarCore::Incidence::Ptr &incidence) const { QColor bgColor = categoryBgColor(incidence); if (bgColor.isValid()) { p.setBrush(bgColor); } QColor tColor(getTextColor(bgColor)); if (tColor.isValid()) { p.setPen(tColor); } } QColor CalPrintPluginBase::categoryColor(const QStringList &categories) const { if (categories.isEmpty()) { return KCalPrefs::instance()->unsetCategoryColor(); } // FIXME: Correctly treat events with multiple categories const QString cat = categories.at(0); QColor bgColor; if (cat.isEmpty()) { bgColor = KCalPrefs::instance()->unsetCategoryColor(); } else { bgColor = KCalPrefs::instance()->categoryColor(cat); } return bgColor; } -QColor CalPrintPluginBase::categoryBgColor(const KCalCore::Incidence::Ptr &incidence) const +QColor CalPrintPluginBase::categoryBgColor(const KCalendarCore::Incidence::Ptr &incidence) const { if (incidence) { QColor backColor = categoryColor(incidence->categories()); - if (incidence->type() == KCalCore::Incidence::TypeTodo) { - if ((incidence.staticCast())->isOverdue()) { + if (incidence->type() == KCalendarCore::Incidence::TypeTodo) { + if ((incidence.staticCast())->isOverdue()) { backColor = QColor(255, 100, 100); //was KOPrefs::instance()->todoOverdueColor(); } } return backColor; } else { return QColor(); } } QString CalPrintPluginBase::holidayString(const QDate &date) const { QStringList lst = holiday(date); return lst.join(i18nc("@item:intext delimiter for joining holiday names", ",")); } -KCalCore::Event::Ptr CalPrintPluginBase::holidayEvent(const QDate &date) const +KCalendarCore::Event::Ptr CalPrintPluginBase::holidayEvent(const QDate &date) const { QString hstring(holidayString(date)); if (hstring.isEmpty()) { - return KCalCore::Event::Ptr(); + return KCalendarCore::Event::Ptr(); } - KCalCore::Event::Ptr holiday(new KCalCore::Event); + KCalendarCore::Event::Ptr holiday(new KCalendarCore::Event); holiday->setSummary(hstring); holiday->setCategories(i18n("Holiday")); QDateTime kdt(date, QTime(0, 0), Qt::LocalTime); holiday->setDtStart(kdt); holiday->setDtEnd(kdt); holiday->setAllDay(true); return holiday; } int CalPrintPluginBase::headerHeight() const { if (mHeaderHeight >= 0) { return mHeaderHeight; } else if (orientation() == QPrinter::Portrait) { return PORTRAIT_HEADER_HEIGHT; } else { return LANDSCAPE_HEADER_HEIGHT; } } void CalPrintPluginBase::setHeaderHeight(const int height) { mHeaderHeight = height; } int CalPrintPluginBase::subHeaderHeight() const { return mSubHeaderHeight; } void CalPrintPluginBase::setSubHeaderHeight(const int height) { mSubHeaderHeight = height; } int CalPrintPluginBase::footerHeight() const { if (!mPrintFooter) { return 0; } if (mFooterHeight >= 0) { return mFooterHeight; } else if (orientation() == QPrinter::Portrait) { return PORTRAIT_FOOTER_HEIGHT; } else { return LANDSCAPE_FOOTER_HEIGHT; } } void CalPrintPluginBase::setFooterHeight(const int height) { mFooterHeight = height; } int CalPrintPluginBase::margin() const { return mMargin; } void CalPrintPluginBase::setMargin(const int margin) { mMargin = margin; } int CalPrintPluginBase::padding() const { return mPadding; } void CalPrintPluginBase::setPadding(const int padding) { mPadding = padding; } int CalPrintPluginBase::borderWidth() const { return mBorder; } void CalPrintPluginBase::setBorderWidth(const int borderwidth) { mBorder = borderwidth; } void CalPrintPluginBase::drawBox(QPainter &p, int linewidth, const QRect &rect) { QPen pen(p.pen()); QPen oldpen(pen); // no border if (linewidth >= 0) { pen.setWidth(linewidth); p.setPen(pen); } else { p.setPen(Qt::NoPen); } p.drawRect(rect); p.setPen(oldpen); } void CalPrintPluginBase::drawShadedBox(QPainter &p, int linewidth, const QBrush &brush, const QRect &rect) { QBrush oldbrush(p.brush()); p.setBrush(brush); drawBox(p, linewidth, rect); p.setBrush(oldbrush); } void CalPrintPluginBase::printEventString(QPainter &p, const QRect &box, const QString &str, int flags) { QRect newbox(box); newbox.adjust(3, 1, -1, -1); p.drawText(newbox, (flags == -1) ? (Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap) : flags, str); } void CalPrintPluginBase::showEventBox(QPainter &p, int linewidth, const QRect &box, - const KCalCore::Incidence::Ptr &incidence, const QString &str, + const KCalendarCore::Incidence::Ptr &incidence, const QString &str, int flags) { QPen oldpen(p.pen()); QBrush oldbrush(p.brush()); QColor bgColor(categoryBgColor(incidence)); if (mUseColors && bgColor.isValid()) { p.setBrush(bgColor); } else { p.setBrush(QColor(232, 232, 232)); } drawBox(p, (linewidth > 0) ? linewidth : EVENT_BORDER_WIDTH, box); if (mUseColors && bgColor.isValid()) { p.setPen(getTextColor(bgColor)); } printEventString(p, box, str, flags); p.setPen(oldpen); p.setBrush(oldbrush); } void CalPrintPluginBase::drawSubHeaderBox(QPainter &p, const QString &str, const QRect &box) { drawShadedBox(p, BOX_BORDER_WIDTH, QColor(232, 232, 232), box); QFont oldfont(p.font()); p.setFont(QFont(QStringLiteral("sans-serif"), 10, QFont::Bold)); p.drawText(box, Qt::AlignCenter | Qt::AlignVCenter, str); p.setFont(oldfont); } void CalPrintPluginBase::drawVerticalBox(QPainter &p, int linewidth, const QRect &box, const QString &str, int flags) { p.save(); p.rotate(-90); QRect rotatedBox(-box.top() - box.height(), box.left(), box.height(), box.width()); - showEventBox(p, linewidth, rotatedBox, KCalCore::Incidence::Ptr(), str, + showEventBox(p, linewidth, rotatedBox, KCalendarCore::Incidence::Ptr(), str, (flags == -1) ? Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine : flags); p.restore(); } /* * Return value: If expand, bottom of the printed box, otherwise vertical end * of the printed contents inside the box. */ int CalPrintPluginBase::drawBoxWithCaption(QPainter &p, const QRect &allbox, const QString &caption, const QString &contents, bool sameLine, bool expand, const QFont &captionFont, const QFont &textFont, bool richContents) { QFont oldFont(p.font()); // QFont captionFont( "sans-serif", 11, QFont::Bold ); // QFont textFont( "sans-serif", 11, QFont::Normal ); // QFont captionFont( "Tahoma", 11, QFont::Bold ); // QFont textFont( "Tahoma", 11, QFont::Normal ); QRect box(allbox); // Bounding rectangle for caption, single-line, clip on the right QRect captionBox(box.left() + padding(), box.top() + padding(), 0, 0); p.setFont(captionFont); captionBox = p.boundingRect(captionBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, caption); p.setFont(oldFont); if (captionBox.right() > box.right()) { captionBox.setRight(box.right()); } if (expand && captionBox.bottom() + padding() > box.bottom()) { box.setBottom(captionBox.bottom() + padding()); } // Bounding rectangle for the contents (if any), word break, clip on the bottom QRect textBox(captionBox); if (!contents.isEmpty()) { if (sameLine) { textBox.setLeft(captionBox.right() + padding()); } else { textBox.setTop(captionBox.bottom() + padding()); } textBox.setRight(box.right()); } drawBox(p, BOX_BORDER_WIDTH, box); p.setFont(captionFont); p.drawText(captionBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, caption); if (!contents.isEmpty()) { if (sameLine) { QString contentText = toPlainText(contents); p.setFont(textFont); p.drawText(textBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, contentText); } else { QTextDocument rtb; int borderWidth = 2 * BOX_BORDER_WIDTH; if (richContents) { rtb.setHtml(contents); } else { rtb.setPlainText(contents); } int boxHeight = allbox.height(); if (!sameLine) { boxHeight -= captionBox.height(); } rtb.setPageSize(QSize(textBox.width(), boxHeight)); rtb.setDefaultFont(textFont); p.save(); p.translate(textBox.x() - borderWidth, textBox.y()); QRect clipBox(0, 0, box.width(), boxHeight); rtb.drawContents(&p, clipBox); p.restore(); textBox.setBottom(textBox.y() +rtb.documentLayout()->documentSize().height()); } } p.setFont(oldFont); if (expand) { return box.bottom(); } else { return textBox.bottom(); } } int CalPrintPluginBase::drawHeader(QPainter &p, const QString &title, const QDate &month1, const QDate &month2, const QRect &allbox, bool expand, QColor backColor) { // print previous month for month view, print current for to-do, day and week int smallMonthWidth = (allbox.width() / 4) - 10; if (smallMonthWidth > 100) { smallMonthWidth = 100; } QRect box(allbox); QRect textRect(allbox); QFont oldFont(p.font()); QFont newFont(QStringLiteral("sans-serif"), (textRect.height() < 60) ? 16 : 18, QFont::Bold); if (expand) { p.setFont(newFont); QRect boundingR = p.boundingRect(textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, title); p.setFont(oldFont); int h = boundingR.height(); if (h > allbox.height()) { box.setHeight(h); textRect.setHeight(h); } } if (!backColor.isValid()) { backColor = QColor(232, 232, 232); } drawShadedBox(p, BOX_BORDER_WIDTH, backColor, box); #if 0 // current month title left justified, prev month, next month right justified QRect monthbox2(box.right() - 10 - smallMonthWidth, box.top(), smallMonthWidth, box.height()); if (month2.isValid()) { drawSmallMonth(p, QDate(month2.year(), month2.month(), 1), monthbox2); textRect.setRight(monthbox2.left()); } QRect monthbox1(monthbox2.left() - 10 - smallMonthWidth, box.top(), smallMonthWidth, box.height()); if (month1.isValid()) { drawSmallMonth(p, QDate(month1.year(), month1.month(), 1), monthbox1); textRect.setRight(monthbox1.left()); } // Set the margins p.setFont(newFont); textRect.adjust(5, 0, 0, 0); p.drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, title); p.setFont(oldFont); #endif // prev month left, current month centered, next month right QRect monthbox2(box.right() - 10 - smallMonthWidth, box.top(), smallMonthWidth, box.height()); if (month2.isValid()) { drawSmallMonth(p, QDate(month2.year(), month2.month(), 1), monthbox2); textRect.setRight(monthbox2.left()); } QRect monthbox1(box.left() + 10, box.top(), smallMonthWidth, box.height()); if (month1.isValid()) { drawSmallMonth(p, QDate(month1.year(), month1.month(), 1), monthbox1); textRect.setLeft(monthbox1.right()); } // Set the margins p.setFont(newFont); p.drawText(textRect, Qt::AlignCenter | Qt::AlignVCenter | Qt::TextWordWrap, title); p.setFont(oldFont); return textRect.bottom(); } int CalPrintPluginBase::drawFooter(QPainter &p, const QRect &footbox) { QFont oldfont(p.font()); p.setFont(QFont(QStringLiteral("sans-serif"), 6)); QString dateStr = QLocale::system().toString(QDateTime::currentDateTime(), QLocale::LongFormat); p.drawText(footbox, Qt::AlignCenter | Qt::AlignVCenter | Qt::TextSingleLine, i18nc("print date: formatted-datetime", "printed: %1", dateStr)); p.setFont(oldfont); return footbox.bottom(); } void CalPrintPluginBase::drawSmallMonth(QPainter &p, const QDate &qd, const QRect &box) { int weekdayCol = weekdayColumn(qd.dayOfWeek()); int month = qd.month(); QDate monthDate(QDate(qd.year(), qd.month(), 1)); // correct begin of week QDate monthDate2(monthDate.addDays(-weekdayCol)); double cellWidth = double(box.width()) / double(7); int rownr = 3 + (qd.daysInMonth() + weekdayCol - 1) / 7; // 3 Pixel after month name, 2 after day names, 1 after the calendar double cellHeight = (box.height() - 5) / rownr; QFont oldFont(p.font()); p.setFont(QFont(QStringLiteral("sans-serif"), int(cellHeight - 2), QFont::Normal)); // draw the title QRect titleBox(box); titleBox.setHeight(int(cellHeight + 1)); p.drawText(titleBox, Qt::AlignTop | Qt::AlignHCenter, QLocale::system().monthName(month)); // draw days of week QRect wdayBox(box); wdayBox.setTop(int(box.top() + 3 + cellHeight)); wdayBox.setHeight(int(2 * cellHeight) - int(cellHeight)); for (int col = 0; col < 7; ++col) { QString tmpStr = QLocale::system().dayName(monthDate2.dayOfWeek())[0].toUpper(); wdayBox.setLeft(int(box.left() + col * cellWidth)); wdayBox.setRight(int(box.left() + (col + 1) * cellWidth)); p.drawText(wdayBox, Qt::AlignCenter, tmpStr); monthDate2 = monthDate2.addDays(1); } // draw separator line int calStartY = wdayBox.bottom() + 2; p.drawLine(box.left(), calStartY, box.right(), calStartY); monthDate = monthDate.addDays(-weekdayCol); for (int row = 0; row < (rownr - 2); row++) { for (int col = 0; col < 7; col++) { if (monthDate.month() == month) { QRect dayRect(int(box.left() + col *cellWidth), int(calStartY + row *cellHeight), 0, 0); dayRect.setRight(int(box.left() + (col + 1) * cellWidth)); dayRect.setBottom(int(calStartY + (row + 1) * cellHeight)); p.drawText(dayRect, Qt::AlignCenter, QString::number(monthDate.day())); } monthDate = monthDate.addDays(1); } } p.setFont(oldFont); } /* * This routine draws a header box over the main part of the calendar * containing the days of the week. */ void CalPrintPluginBase::drawDaysOfWeek(QPainter &p, const QDate &fromDate, const QDate &toDate, const QRect &box) { double cellWidth = double(box.width()) / double(fromDate.daysTo(toDate) + 1); QDate cellDate(fromDate); QRect dateBox(box); int i = 0; while (cellDate <= toDate) { dateBox.setLeft(box.left() + int(i * cellWidth)); dateBox.setRight(box.left() + int((i + 1) * cellWidth)); drawDaysOfWeekBox(p, cellDate, dateBox); cellDate = cellDate.addDays(1); ++i; } } void CalPrintPluginBase::drawDaysOfWeekBox(QPainter &p, const QDate &qd, const QRect &box) { drawSubHeaderBox(p, QLocale::system().dayName(qd.dayOfWeek()), box); } void CalPrintPluginBase::drawTimeLine(QPainter &p, const QTime &fromTime, const QTime &toTime, const QRect &box) { drawBox(p, BOX_BORDER_WIDTH, box); int totalsecs = fromTime.secsTo(toTime); float minlen = (float)box.height() * 60. / (float)totalsecs; float cellHeight = (60. * (float)minlen); float currY = box.top(); // TODO: Don't use half of the width, but less, for the minutes! int xcenter = box.left() + box.width() / 2; QTime curTime(fromTime); QTime endTime(toTime); if (fromTime.minute() > 30) { curTime = QTime(fromTime.hour() + 1, 0, 0); } else if (fromTime.minute() > 0) { curTime = QTime(fromTime.hour(), 30, 0); float yy = currY + minlen * (float)fromTime.secsTo(curTime) / 60.; p.drawLine(xcenter, (int)yy, box.right(), (int)yy); curTime = QTime(fromTime.hour() + 1, 0, 0); } currY += (float(fromTime.secsTo(curTime) * minlen) / 60.); while (curTime < endTime) { p.drawLine(box.left(), (int)currY, box.right(), (int)currY); int newY = (int)(currY + cellHeight / 2.); QString numStr; if (newY < box.bottom()) { QFont oldFont(p.font()); // draw the time: if (!QLocale().timeFormat().contains(QLatin1String("AP"))) { // 12h clock p.drawLine(xcenter, (int)newY, box.right(), (int)newY); numStr.setNum(curTime.hour()); if (cellHeight > 30) { p.setFont(QFont(QStringLiteral("sans-serif"), 14, QFont::Bold)); } else { p.setFont(QFont(QStringLiteral("sans-serif"), 12, QFont::Bold)); } p.drawText(box.left() + 4, (int)currY + 2, box.width() / 2 - 2, (int)cellHeight, Qt::AlignTop | Qt::AlignRight, numStr); p.setFont(QFont(QStringLiteral("helvetica"), 10, QFont::Normal)); p.drawText(xcenter + 4, (int)currY + 2, box.width() / 2 + 2, (int)(cellHeight / 2) - 3, Qt::AlignTop | Qt::AlignLeft, QStringLiteral("00")); } else { p.drawLine(box.left(), (int)newY, box.right(), (int)newY); QTime time(curTime.hour(), 0); numStr = QLocale::system().toString(time, QLocale::ShortFormat); if (box.width() < 60) { p.setFont(QFont(QStringLiteral("sans-serif"), 7, QFont::Bold)); // for weekprint } else { p.setFont(QFont(QStringLiteral("sans-serif"), 12, QFont::Bold)); // for dayprint } p.drawText(box.left() + 2, (int)currY + 2, box.width() - 4, (int)cellHeight / 2 - 3, Qt::AlignTop | Qt::AlignLeft, numStr); } currY += cellHeight; p.setFont(oldFont); } // enough space for half-hour line and time if (curTime.secsTo(endTime) > 3600) { curTime = curTime.addSecs(3600); } else { curTime = endTime; } } } /** prints the all-day box for the agenda print view. if expandable is set, height is the cell height of a single cell, and the returned height will be the total height used for the all-day events. If !expandable, only one cell will be used, and multiple events are concatenated using ", ". */ -int CalPrintPluginBase::drawAllDayBox(QPainter &p, const KCalCore::Event::List &eventList_, +int CalPrintPluginBase::drawAllDayBox(QPainter &p, const KCalendarCore::Event::List &eventList_, const QDate &qd, bool expandable, const QRect &box, bool excludeConfidential, bool excludePrivate) { - KCalCore::Event::List::Iterator it; + KCalendarCore::Event::List::Iterator it; int offset = box.top(); QString multiDayStr; - KCalCore::Event::List eventList = eventList_; - KCalCore::Event::Ptr hd = holidayEvent(qd); + KCalendarCore::Event::List eventList = eventList_; + KCalendarCore::Event::Ptr hd = holidayEvent(qd); if (hd) { eventList.prepend(hd); } it = eventList.begin(); while (it != eventList.end()) { - KCalCore::Event::Ptr currEvent = *it; + KCalendarCore::Event::Ptr currEvent = *it; if ((excludeConfidential - && currEvent->secrecy() == KCalCore::Incidence::SecrecyConfidential) - || (excludePrivate && currEvent->secrecy() == KCalCore::Incidence::SecrecyPrivate)) { + && currEvent->secrecy() == KCalendarCore::Incidence::SecrecyConfidential) + || (excludePrivate && currEvent->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) { continue; } if (currEvent && currEvent->allDay()) { // set the colors according to the categories if (expandable) { QRect eventBox(box); eventBox.setTop(offset); showEventBox(p, EVENT_BORDER_WIDTH, eventBox, currEvent, currEvent->summary()); offset += box.height(); } else { if (!multiDayStr.isEmpty()) { multiDayStr += QStringLiteral(", "); } multiDayStr += currEvent->summary(); } it = eventList.erase(it); } else { ++it; } } int ret = box.height(); QRect eventBox(box); if (!expandable) { if (!multiDayStr.isEmpty()) { drawShadedBox(p, BOX_BORDER_WIDTH, QColor(180, 180, 180), eventBox); printEventString(p, eventBox, multiDayStr); } else { drawBox(p, BOX_BORDER_WIDTH, eventBox); } } else { ret = offset - box.top(); eventBox.setBottom(ret); drawBox(p, BOX_BORDER_WIDTH, eventBox); } return ret; } -void CalPrintPluginBase::drawAgendaDayBox(QPainter &p, const KCalCore::Event::List &events, +void CalPrintPluginBase::drawAgendaDayBox(QPainter &p, const KCalendarCore::Event::List &events, const QDate &qd, bool expandable, const QTime &fromTime, const QTime &toTime, const QRect &oldbox, bool includeDescription, bool excludeTime, bool excludeConfidential, bool excludePrivate, const QList &workDays) { QTime myFromTime, myToTime; if (fromTime.isValid()) { myFromTime = fromTime; } else { myFromTime = QTime(0, 0, 0); } if (toTime.isValid()) { myToTime = toTime; } else { myToTime = QTime(23, 59, 59); } if (!workDays.contains(qd)) { drawShadedBox(p, BOX_BORDER_WIDTH, QColor(232, 232, 232), oldbox); } else { drawBox(p, BOX_BORDER_WIDTH, oldbox); } QRect box(oldbox); // Account for the border with and cut away that margin from the interior // box.setRight( box.right()-BOX_BORDER_WIDTH ); if (expandable) { // Adapt start/end times to include complete events - for (const KCalCore::Event::Ptr &event : qAsConst(events)) { + for (const KCalendarCore::Event::Ptr &event : qAsConst(events)) { Q_ASSERT(event); if ((excludeConfidential - && event->secrecy() == KCalCore::Incidence::SecrecyConfidential) - || (excludePrivate && event->secrecy() == KCalCore::Incidence::SecrecyPrivate)) { + && event->secrecy() == KCalendarCore::Incidence::SecrecyConfidential) + || (excludePrivate && event->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) { continue; } // skip items without times so that we do not adjust for all day items if (event->allDay()) { continue; } if (event->dtStart().time() < myFromTime) { myFromTime = event->dtStart().time(); } if (event->dtEnd().time() > myToTime) { myToTime = event->dtEnd().time(); } } } // calculate the height of a cell and of a minute int totalsecs = myFromTime.secsTo(myToTime); float minlen = box.height() * 60. / totalsecs; float cellHeight = 60. * minlen; float currY = box.top(); // print grid: QTime curTime(QTime(myFromTime.hour(), 0, 0)); currY += myFromTime.secsTo(curTime) * minlen / 60; while (curTime < myToTime && curTime.isValid()) { if (currY > box.top()) { p.drawLine(box.left(), int(currY), box.right(), int(currY)); } currY += cellHeight / 2; if ((currY > box.top()) && (currY < box.bottom())) { // enough space for half-hour line QPen oldPen(p.pen()); p.setPen(QColor(192, 192, 192)); p.drawLine(box.left(), int(currY), box.right(), int(currY)); p.setPen(oldPen); } if (curTime.secsTo(myToTime) > 3600) { curTime = curTime.addSecs(3600); } else { curTime = myToTime; } currY += cellHeight / 2; } QDateTime startPrintDate = QDateTime(qd, myFromTime); QDateTime endPrintDate = QDateTime(qd, myToTime); // Calculate horizontal positions and widths of events taking into account // overlapping events QList cells; - for (const KCalCore::Event::Ptr &event : qAsConst(events)) { + for (const KCalendarCore::Event::Ptr &event : qAsConst(events)) { if (event->allDay()) { continue; } QList times = event->startDateTimesForDate(qd, QTimeZone::systemTimeZone()); cells.reserve(times.count()); for (auto it = times.constBegin(); it != times.constEnd(); ++it) { cells.append(new PrintCellItem(event, (*it).toLocalTime(), event->endDateForStart(*it).toLocalTime())); } } QListIterator it1(cells); while (it1.hasNext()) { CellItem *placeItem = it1.next(); CellItem::placeItem(cells, placeItem); } QListIterator it2(cells); while (it2.hasNext()) { PrintCellItem *placeItem = static_cast(it2.next()); drawAgendaItem(placeItem, p, startPrintDate, endPrintDate, minlen, box, includeDescription, excludeTime); } } void CalPrintPluginBase::drawAgendaItem(PrintCellItem *item, QPainter &p, const QDateTime &startPrintDate, const QDateTime &endPrintDate, float minlen, const QRect &box, bool includeDescription, bool excludeTime) { - KCalCore::Event::Ptr event = item->event(); + KCalendarCore::Event::Ptr event = item->event(); // start/end of print area for event QDateTime startTime = item->start(); QDateTime endTime = item->end(); if ((startTime < endPrintDate && endTime > startPrintDate) || (endTime > startPrintDate && startTime < endPrintDate)) { if (startTime < startPrintDate) { startTime = startPrintDate; } if (endTime > endPrintDate) { endTime = endPrintDate; } int currentWidth = box.width() / item->subCells(); int currentX = box.left() + item->subCell() * currentWidth; int currentYPos = int(box.top() + startPrintDate.secsTo(startTime) * minlen / 60.); int currentHeight = int(box.top() + startPrintDate.secsTo(endTime) * minlen / 60.) - currentYPos; QRect eventBox(currentX, currentYPos, currentWidth, currentHeight); QString str; if (excludeTime) { if (event->location().isEmpty()) { str = cleanStr(event->summary()); } else { str = i18nc("summary, location", "%1, %2", cleanStr(event->summary()), cleanStr(event->location())); } } else { if (event->location().isEmpty()) { str = i18nc("starttime - endtime summary", "%1-%2 %3", QLocale::system().toString(item->start().time(), QLocale::ShortFormat), QLocale::system().toString(item->end().time(), QLocale::ShortFormat), cleanStr(event->summary())); } else { str = i18nc("starttime - endtime summary, location", "%1-%2 %3, %4", QLocale::system().toString(item->start().time(), QLocale::ShortFormat), QLocale::system().toString(item->end().time(), QLocale::ShortFormat), cleanStr(event->summary()), cleanStr(event->location())); } } if (includeDescription && !event->description().isEmpty()) { str += QLatin1Char('\n'); if (event->descriptionIsRich()) { str += toPlainText(event->description()); } else { str += event->description(); } } QFont oldFont(p.font()); if (eventBox.height() < 24) { if (eventBox.height() < 12) { if (eventBox.height() < 8) { p.setFont(QFont(QStringLiteral("sans-serif"), 4)); } else { p.setFont(QFont(QStringLiteral("sans-serif"), 5)); } } else { p.setFont(QFont(QStringLiteral("sans-serif"), 6)); } } else { p.setFont(QFont(QStringLiteral("sans-serif"), 8)); } showEventBox(p, EVENT_BORDER_WIDTH, eventBox, event, str); p.setFont(oldFont); } } void CalPrintPluginBase::drawDayBox(QPainter &p, const QDate &qd, const QTime &fromTime, const QTime &toTime, const QRect &box, bool fullDate, bool printRecurDaily, bool printRecurWeekly, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate) { QString dayNumStr; const auto local = QLocale::system(); QTime myFromTime, myToTime; if (fromTime.isValid()) { myFromTime = fromTime; } else { myFromTime = QTime(0, 0, 0); } if (toTime.isValid()) { myToTime = toTime; } else { myToTime = QTime(23, 59, 59); } if (fullDate) { dayNumStr = i18nc("weekday, shortmonthname daynumber", "%1, %2 %3", QLocale::system().dayName(qd.dayOfWeek()), QLocale::system().monthName(qd.month(), QLocale::ShortFormat), QString::number(qd.day())); } else { dayNumStr = QString::number(qd.day()); } QRect subHeaderBox(box); subHeaderBox.setHeight(mSubHeaderHeight); drawShadedBox(p, BOX_BORDER_WIDTH, p.background(), box); drawShadedBox(p, 0, QColor(232, 232, 232), subHeaderBox); drawBox(p, BOX_BORDER_WIDTH, box); QString hstring(holidayString(qd)); const QFont oldFont(p.font()); QRect headerTextBox(subHeaderBox); headerTextBox.setLeft(subHeaderBox.left() + 5); headerTextBox.setRight(subHeaderBox.right() - 5); if (!hstring.isEmpty()) { p.setFont(QFont(QStringLiteral("sans-serif"), 8, QFont::Bold, true)); p.drawText(headerTextBox, Qt::AlignLeft | Qt::AlignVCenter, hstring); } p.setFont(QFont(QStringLiteral("sans-serif"), 10, QFont::Bold)); p.drawText(headerTextBox, Qt::AlignRight | Qt::AlignVCenter, dayNumStr); - const KCalCore::Event::List eventList + const KCalendarCore::Event::List eventList = mCalendar->events(qd, QTimeZone::systemTimeZone(), - KCalCore::EventSortStartDate, - KCalCore::SortDirectionAscending); + KCalendarCore::EventSortStartDate, + KCalendarCore::SortDirectionAscending); QString timeText; p.setFont(QFont(QStringLiteral("sans-serif"), 7)); int textY = mSubHeaderHeight; // gives the relative y-coord of the next printed entry unsigned int visibleEventsCounter = 0; - for (const KCalCore::Event::Ptr &currEvent : qAsConst(eventList)) { + for (const KCalendarCore::Event::Ptr &currEvent : qAsConst(eventList)) { Q_ASSERT(currEvent); if (!currEvent->allDay()) { if (currEvent->dtEnd().toLocalTime().time() <= myFromTime || currEvent->dtStart().toLocalTime().time() > myToTime) { continue; } } - if ((!printRecurDaily && currEvent->recurrenceType() == KCalCore::Recurrence::rDaily) + if ((!printRecurDaily && currEvent->recurrenceType() == KCalendarCore::Recurrence::rDaily) || (!printRecurWeekly - && currEvent->recurrenceType() == KCalCore::Recurrence::rWeekly)) { + && currEvent->recurrenceType() == KCalendarCore::Recurrence::rWeekly)) { continue; } if ((excludeConfidential - && currEvent->secrecy() == KCalCore::Incidence::SecrecyConfidential) - || (excludePrivate && currEvent->secrecy() == KCalCore::Incidence::SecrecyPrivate)) { + && currEvent->secrecy() == KCalendarCore::Incidence::SecrecyConfidential) + || (excludePrivate && currEvent->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) { continue; } if (currEvent->allDay() || currEvent->isMultiDay()) { timeText.clear(); } else { timeText = local.toString( currEvent->dtStart().toLocalTime().time(), QLocale::ShortFormat) + QLatin1Char(' '); } p.save(); setColorsByIncidenceCategory(p, currEvent); QString summaryStr = currEvent->summary(); if (!currEvent->location().isEmpty()) { summaryStr = i18nc("summary, location", "%1, %2", summaryStr, currEvent->location()); } drawIncidence(p, box, timeText, summaryStr, currEvent->description(), textY, singleLineLimit, includeDescription, currEvent->descriptionIsRich()); p.restore(); visibleEventsCounter++; if (textY >= box.height()) { const QChar downArrow(0x21e3); const unsigned int invisibleIncidences = (eventList.count() - visibleEventsCounter) + mCalendar->todos(qd).count(); if (invisibleIncidences > 0) { const QString warningMsg = QStringLiteral("%1 (%2)").arg(downArrow).arg( invisibleIncidences); QFontMetrics fm(p.font()); QRect msgRect = fm.boundingRect(warningMsg); msgRect.setRect(box.right() - msgRect.width() - 2, box.bottom() - msgRect.height() - 2, msgRect.width(), msgRect.height()); p.save(); p.setPen(Qt::red); //krazy:exclude=qenums we don't allow custom print colors p.drawText(msgRect, Qt::AlignLeft, warningMsg); p.restore(); } break; } } if (textY < box.height()) { - KCalCore::Todo::List todos = mCalendar->todos(qd); - for (const KCalCore::Todo::Ptr &todo : qAsConst(todos)) { + KCalendarCore::Todo::List todos = mCalendar->todos(qd); + for (const KCalendarCore::Todo::Ptr &todo : qAsConst(todos)) { if (!todo->allDay()) { if ((todo->hasDueDate() && todo->dtDue().toLocalTime().time() <= myFromTime) || (todo->hasStartDate() && todo->dtStart().toLocalTime().time() > myToTime)) { continue; } } - if ((!printRecurDaily && todo->recurrenceType() == KCalCore::Recurrence::rDaily) - || (!printRecurWeekly && todo->recurrenceType() == KCalCore::Recurrence::rWeekly)) { + if ((!printRecurDaily && todo->recurrenceType() == KCalendarCore::Recurrence::rDaily) + || (!printRecurWeekly && todo->recurrenceType() == KCalendarCore::Recurrence::rWeekly)) { continue; } - if ((excludeConfidential && todo->secrecy() == KCalCore::Incidence::SecrecyConfidential) - || (excludePrivate && todo->secrecy() == KCalCore::Incidence::SecrecyPrivate)) { + if ((excludeConfidential && todo->secrecy() == KCalendarCore::Incidence::SecrecyConfidential) + || (excludePrivate && todo->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) { continue; } if (todo->hasStartDate() && !todo->allDay()) { timeText = QLocale().toString( todo->dtStart().toLocalTime().time(), QLocale::ShortFormat) + QLatin1Char(' '); } else { timeText.clear(); } p.save(); setColorsByIncidenceCategory(p, todo); QString summaryStr = todo->summary(); if (!todo->location().isEmpty()) { summaryStr = i18nc("summary, location", "%1, %2", summaryStr, todo->location()); } QString str; if (todo->hasDueDate()) { if (!todo->allDay()) { str = i18nc("to-do summary (Due: datetime)", "%1 (Due: %2)", summaryStr, QLocale().toString( todo->dtDue().toLocalTime(), QLocale::ShortFormat)); } else { str = i18nc("to-do summary (Due: date)", "%1 (Due: %2)", summaryStr, QLocale().toString(todo->dtDue().toLocalTime().date(), QLocale::ShortFormat)); } } else { str = summaryStr; } drawIncidence(p, box, timeText, i18n("To-do: %1", str), todo->description(), textY, singleLineLimit, includeDescription, todo->descriptionIsRich()); p.restore(); } } if (showNoteLines) { drawNoteLines(p, box, box.y() + textY); } p.setFont(oldFont); } void CalPrintPluginBase::drawIncidence(QPainter &p, const QRect &dayBox, const QString &time, const QString &summary, const QString &description, int &textY, bool singleLineLimit, bool includeDescription, bool richDescription) { qCDebug(CALENDARSUPPORT_LOG) << "summary =" << summary << ", singleLineLimit=" << singleLineLimit; int flags = Qt::AlignLeft | Qt::OpaqueMode; QFontMetrics fm = p.fontMetrics(); const int borderWidth = p.pen().width() + 1; QRect timeBound = p.boundingRect(dayBox.x() + borderWidth, dayBox.y() + textY, dayBox.width(), fm.lineSpacing(), flags, time); int summaryWidth = time.isEmpty() ? 0 : timeBound.width() + 3; QRect summaryBound = QRect(dayBox.x() + borderWidth + summaryWidth, dayBox.y() + textY + 1, dayBox.width() - summaryWidth - (borderWidth * 2), dayBox.height() - textY); QString summaryText = summary; QString descText = toPlainText(description); bool boxOverflow = false; if (singleLineLimit) { if (includeDescription && !descText.isEmpty()) { summaryText += QStringLiteral(", ") + descText; } int totalHeight = fm.lineSpacing() + borderWidth; int textBoxHeight = (totalHeight > (dayBox.height() - textY)) ? dayBox.height() - textY : totalHeight; summaryBound.setHeight(textBoxHeight); QRect lineRect(dayBox.x() + borderWidth, dayBox.y() + textY, dayBox.width() - (borderWidth * 2), textBoxHeight); drawBox(p, 1, lineRect); if (!time.isEmpty()) { p.drawText(timeBound, flags, time); } p.drawText(summaryBound, flags, summaryText); } else { QTextDocument textDoc; QTextCursor textCursor(&textDoc); if (richDescription) { QTextCursor textCursor(&textDoc); textCursor.insertText(summaryText); if (includeDescription && !description.isEmpty()) { textCursor.insertText(QStringLiteral("\n")); textCursor.insertHtml(description); } } else { textCursor.insertText(summaryText); if (includeDescription && !descText.isEmpty()) { textCursor.insertText(QStringLiteral("\n")); textCursor.insertText(descText); } } textDoc.setPageSize(QSize(summaryBound.width(), summaryBound.height())); p.save(); QRect clipBox(0, 0, summaryBound.width(), summaryBound.height()); p.setFont(p.font()); p.translate(summaryBound.x(), summaryBound.y()); summaryBound.setHeight(textDoc.documentLayout()->documentSize().height()); if (summaryBound.bottom() > dayBox.bottom()) { summaryBound.setBottom(dayBox.bottom()); } clipBox.setHeight(summaryBound.height()); p.restore(); p.save(); QRect backBox(timeBound.x(), timeBound.y(), dayBox.width() - (borderWidth * 2), clipBox.height()); drawBox(p, 1, backBox); if (!time.isEmpty()) { if (timeBound.bottom() > dayBox.bottom()) { timeBound.setBottom(dayBox.bottom()); } timeBound.moveTop(timeBound.y() + (summaryBound.height() - timeBound.height()) / 2); p.drawText(timeBound, flags, time); } p.translate(summaryBound.x(), summaryBound.y()); textDoc.drawContents(&p, clipBox); p.restore(); boxOverflow = textDoc.pageCount() > 1; } if (summaryBound.bottom() < dayBox.bottom()) { QPen oldPen(p.pen()); p.setPen(QPen()); p.drawLine(dayBox.x(), summaryBound.bottom(), dayBox.x() + dayBox.width(), summaryBound.bottom()); p.setPen(oldPen); } textY += summaryBound.height(); // show that we have overflowed the box if (boxOverflow) { QPolygon poly(3); int x = dayBox.x() + dayBox.width(); int y = dayBox.y() + dayBox.height(); poly.setPoint(0, x - 10, y); poly.setPoint(1, x, y - 10); poly.setPoint(2, x, y); QBrush oldBrush(p.brush()); p.setBrush(QBrush(Qt::black)); p.drawPolygon(poly); p.setBrush(oldBrush); textY = dayBox.height(); } } void CalPrintPluginBase::drawWeek(QPainter &p, const QDate &qd, const QTime &fromTime, const QTime &toTime, const QRect &box, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate) { QDate weekDate = qd; const bool portrait = (box.height() > box.width()); int cellWidth; int vcells; if (portrait) { cellWidth = box.width() / 2; vcells = 3; } else { cellWidth = box.width() / 6; vcells = 1; } const int cellHeight = box.height() / vcells; // correct begin of week int weekdayCol = weekdayColumn(qd.dayOfWeek()); weekDate = qd.addDays(-weekdayCol); for (int i = 0; i < 7; ++i, weekDate = weekDate.addDays(1)) { // Saturday and sunday share a cell, so we have to special-case sunday int hpos = ((i < 6) ? i : (i - 1)) / vcells; int vpos = ((i < 6) ? i : (i - 1)) % vcells; QRect dayBox( box.left() + cellWidth *hpos, box.top() + cellHeight *vpos + ((i == 6) ? (cellHeight / 2) : 0), cellWidth, (i < 5) ? (cellHeight) : (cellHeight / 2)); drawDayBox(p, weekDate, fromTime, toTime, dayBox, true, true, true, singleLineLimit, showNoteLines, includeDescription, excludeConfidential, excludePrivate); } // for i through all weekdays } void CalPrintPluginBase::drawDays(QPainter &p, const QDate &start, const QDate &end, const QTime &fromTime, const QTime &toTime, const QRect &box, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate) { const int numberOfDays = start.daysTo(end) + 1; int vcells; const bool portrait = (box.height() > box.width()); int cellWidth; if (portrait) { // 2 columns vcells = qCeil(static_cast(numberOfDays) / 2.0); if (numberOfDays > 1) { cellWidth = box.width() / 2; } else { cellWidth = box.width(); } } else { // landscape: N columns vcells = 1; cellWidth = box.width() / numberOfDays; } const int cellHeight = box.height() / vcells; QDate weekDate = start; for (int i = 0; i < numberOfDays; ++i, weekDate = weekDate.addDays(1)) { const int hpos = i / vcells; const int vpos = i % vcells; const QRect dayBox( box.left() + cellWidth *hpos, box.top() + cellHeight *vpos, cellWidth, cellHeight); drawDayBox(p, weekDate, fromTime, toTime, dayBox, true, true, true, singleLineLimit, showNoteLines, includeDescription, excludeConfidential, excludePrivate); } // for i through all selected days } void CalPrintPluginBase::drawTimeTable(QPainter &p, const QDate &fromDate, const QDate &toDate, bool expandable, const QTime &fromTime, const QTime &toTime, const QRect &box, bool includeDescription, bool excludeTime, bool excludeConfidential, bool excludePrivate) { QTime myFromTime = fromTime; QTime myToTime = toTime; if (expandable) { QDate curDate(fromDate); while (curDate <= toDate) { - KCalCore::Event::List eventList + KCalendarCore::Event::List eventList = mCalendar->events(curDate, QTimeZone::systemTimeZone()); - for (const KCalCore::Event::Ptr &event : qAsConst(eventList)) { + for (const KCalendarCore::Event::Ptr &event : qAsConst(eventList)) { Q_ASSERT(event); if (event->allDay()) { continue; } if (event->dtStart().time() < myFromTime) { myFromTime = event->dtStart().time(); } if (event->dtEnd().time() > myToTime) { myToTime = event->dtEnd().time(); } } curDate = curDate.addDays(1); } } // timeline is 1 hour: int alldayHeight = (int)(3600. * box.height() / (myFromTime.secsTo(myToTime) + 3600.)); int timelineWidth = TIMELINE_WIDTH; QRect dowBox(box); dowBox.setLeft(box.left() + timelineWidth); dowBox.setHeight(mSubHeaderHeight); drawDaysOfWeek(p, fromDate, toDate, dowBox); QRect tlBox(box); tlBox.setWidth(timelineWidth); tlBox.setTop(dowBox.bottom() + BOX_BORDER_WIDTH + alldayHeight); drawTimeLine(p, myFromTime, myToTime, tlBox); // draw each day QDate curDate(fromDate); int i = 0; double cellWidth = double(dowBox.width()) / double(fromDate.daysTo(toDate) + 1); const QList workDays = CalendarSupport::workDays(fromDate, toDate); while (curDate <= toDate) { QRect allDayBox(dowBox.left() + int(i *cellWidth), dowBox.bottom() + BOX_BORDER_WIDTH, int((i + 1) * cellWidth) - int(i *cellWidth), alldayHeight); QRect dayBox(allDayBox); dayBox.setTop(tlBox.top()); dayBox.setBottom(box.bottom()); - KCalCore::Event::List eventList = mCalendar->events(curDate, QTimeZone::systemTimeZone(), - KCalCore::EventSortStartDate, - KCalCore::SortDirectionAscending); + KCalendarCore::Event::List eventList = mCalendar->events(curDate, QTimeZone::systemTimeZone(), + KCalendarCore::EventSortStartDate, + KCalendarCore::SortDirectionAscending); alldayHeight = drawAllDayBox(p, eventList, curDate, false, allDayBox, excludeConfidential, excludePrivate); drawAgendaDayBox(p, eventList, curDate, false, myFromTime, myToTime, dayBox, includeDescription, excludeTime, excludeConfidential, excludePrivate, workDays); ++i; curDate = curDate.addDays(1); } } class MonthEventStruct { public: MonthEventStruct() : event(nullptr) { } - MonthEventStruct(const QDateTime &s, const QDateTime &e, const KCalCore::Event::Ptr &ev) + MonthEventStruct(const QDateTime &s, const QDateTime &e, const KCalendarCore::Event::Ptr &ev) { event = ev; start = s; end = e; if (event->allDay()) { start = QDateTime(start.date(), QTime(0, 0, 0)); end = QDateTime(end.date().addDays(1), QTime(0, 0, 0)).addSecs(-1); } } bool operator <(const MonthEventStruct &mes) { return start < mes.start; } QDateTime start; QDateTime end; - KCalCore::Event::Ptr event; + KCalendarCore::Event::Ptr event; }; void CalPrintPluginBase::drawMonth(QPainter &p, const QDate &dt, const QRect &box, int maxdays, int subDailyFlags, int holidaysFlags, bool excludeConfidential, bool excludePrivate) { p.save(); QRect subheaderBox(box); subheaderBox.setHeight(subHeaderHeight()); QRect borderBox(box); borderBox.setTop(subheaderBox.bottom() + 1); drawSubHeaderBox(p, QLocale::system().monthName(dt.month()), subheaderBox); // correct for half the border width int correction = (BOX_BORDER_WIDTH /*-1*/) / 2; QRect daysBox(borderBox); daysBox.adjust(correction, correction, -correction, -correction); int daysinmonth = dt.daysInMonth(); if (maxdays <= 0) { maxdays = daysinmonth; } int d; float dayheight = float(daysBox.height()) / float(maxdays); QColor holidayColor(240, 240, 240); QColor workdayColor(255, 255, 255); int dayNrWidth = p.fontMetrics().boundingRect(QStringLiteral("99")).width(); // Fill the remaining space (if a month has less days than others) with a crossed-out pattern if (daysinmonth < maxdays) { QRect dayBox(box.left(), daysBox.top() + qRound(dayheight *daysinmonth), box.width(), 0); dayBox.setBottom(daysBox.bottom()); p.fillRect(dayBox, Qt::DiagCrossPattern); } // Backgrounded boxes for each day, plus day numbers QBrush oldbrush(p.brush()); QList workDays; { QDate startDate(dt.year(), dt.month(), 1); QDate endDate(dt.year(), dt.month(), daysinmonth); workDays = CalendarSupport::workDays(startDate, endDate); } for (d = 0; d < daysinmonth; ++d) { QDate day(dt.year(), dt.month(), d + 1); QRect dayBox( daysBox.left() /*+rand()%50*/, daysBox.top() + qRound(dayheight *d), daysBox.width() /*-rand()%50*/, 0); // FIXME: When using a border width of 0 for event boxes, // don't let the rectangles overlap, i.e. subtract 1 from the top or bottom! dayBox.setBottom(daysBox.top() + qRound(dayheight * (d + 1)) - 1); p.setBrush(workDays.contains(day) ? workdayColor : holidayColor); p.drawRect(dayBox); QRect dateBox(dayBox); dateBox.setWidth(dayNrWidth + 3); p.drawText(dateBox, Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine, QString::number(d + 1)); } p.setBrush(oldbrush); int xstartcont = box.left() + dayNrWidth + 5; QDate start(dt.year(), dt.month(), 1); QDate end = start.addMonths(1); end = end.addDays(-1); - const KCalCore::Event::List events = mCalendar->events(start, end); + const KCalendarCore::Event::List events = mCalendar->events(start, end); QMap textEvents; QList timeboxItems; // 1) For multi-day events, show boxes spanning several cells, use CellItem // print the summary vertically // 2) For sub-day events, print the concated summaries into the remaining // space of the box (optional, depending on the given flags) // 3) Draw some kind of timeline showing free and busy times // Holidays - QList holidays; + QList holidays; for (QDate d(start); d <= end; d = d.addDays(1)) { - KCalCore::Event::Ptr e = holidayEvent(d); + KCalendarCore::Event::Ptr e = holidayEvent(d); if (e) { holidays.append(e); if (holidaysFlags & TimeBoxes) { timeboxItems.append(new PrintCellItem(e, QDateTime(d, QTime(0, 0, 0)), QDateTime(d.addDays(1), QTime(0, 0, 0)))); } if (holidaysFlags & Text) { textEvents[d.day()] << e->summary(); } } } QList monthentries; - for (const KCalCore::Event::Ptr &e : qAsConst(events)) { + for (const KCalendarCore::Event::Ptr &e : qAsConst(events)) { if (!e) { continue; } - if ((excludeConfidential && e->secrecy() == KCalCore::Incidence::SecrecyConfidential) - || (excludePrivate && e->secrecy() == KCalCore::Incidence::SecrecyPrivate)) { + if ((excludeConfidential && e->secrecy() == KCalendarCore::Incidence::SecrecyConfidential) + || (excludePrivate && e->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) { continue; } if (e->recurs()) { if (e->recursOn(start, QTimeZone::systemTimeZone())) { // This occurrence has possibly started before the beginning of the // month, so obtain the start date before the beginning of the month QList starttimes = e->startDateTimesForDate(start, QTimeZone::systemTimeZone()); for (auto it = starttimes.constBegin(); it != starttimes.constEnd(); ++it) { monthentries.append(MonthEventStruct((*it).toLocalTime(), e->endDateForStart(*it).toLocalTime(), e)); } } // Loop through all remaining days of the month and check if the event // begins on that day (don't use Event::recursOn, as that will // also return events that have started earlier. These start dates // however, have already been treated! - KCalCore::Recurrence *recur = e->recurrence(); + KCalendarCore::Recurrence *recur = e->recurrence(); QDate d1(start.addDays(1)); while (d1 <= end) { if (recur->recursOn(d1, QTimeZone::systemTimeZone())) { - KCalCore::TimeList times(recur->recurTimesOn(d1, QTimeZone::systemTimeZone())); - for (KCalCore::TimeList::ConstIterator it = times.constBegin(); + KCalendarCore::TimeList times(recur->recurTimesOn(d1, QTimeZone::systemTimeZone())); + for (KCalendarCore::TimeList::ConstIterator it = times.constBegin(); it != times.constEnd(); ++it) { QDateTime d1start(d1, *it, Qt::LocalTime); monthentries.append( MonthEventStruct(d1start, e->endDateForStart(d1start).toLocalTime(), e)); } } d1 = d1.addDays(1); } } else { monthentries.append(MonthEventStruct(e->dtStart().toLocalTime(), e->dtEnd().toLocalTime(), e)); } } // TODO: to port the month entries sorting // qSort( monthentries.begin(), monthentries.end() ); QList::ConstIterator mit = monthentries.constBegin(); QDateTime endofmonth(end, QTime(0, 0, 0)); endofmonth = endofmonth.addDays(1); for (; mit != monthentries.constEnd(); ++mit) { if ((*mit).start.date() == (*mit).end.date()) { // Show also single-day events as time line boxes if (subDailyFlags & TimeBoxes) { timeboxItems.append(new PrintCellItem((*mit).event, (*mit).start, (*mit).end)); } // Show as text in the box if (subDailyFlags & Text) { textEvents[(*mit).start.date().day()] << (*mit).event->summary(); } } else { // Multi-day events are always shown as time line boxes QDateTime thisstart((*mit).start); QDateTime thisend((*mit).end); if (thisstart.date() < start) { thisstart.setDate(start); } if (thisend > endofmonth) { thisend = endofmonth; } timeboxItems.append(new PrintCellItem((*mit).event, thisstart, thisend)); } } // For Multi-day events, line them up nicely so that the boxes don't overlap QListIterator it1(timeboxItems); while (it1.hasNext()) { CellItem *placeItem = it1.next(); CellItem::placeItem(timeboxItems, placeItem); } QDateTime starttime(start, QTime(0, 0, 0)); int newxstartcont = xstartcont; QFont oldfont(p.font()); p.setFont(QFont(QStringLiteral("sans-serif"), 7)); while (it1.hasNext()) { PrintCellItem *placeItem = static_cast(it1.next()); int minsToStart = starttime.secsTo(placeItem->start()) / 60; int minsToEnd = starttime.secsTo(placeItem->end()) / 60; QRect eventBox( xstartcont + placeItem->subCell() * 17, daysBox.top() + qRound( double(minsToStart *daysBox.height()) / double(maxdays * 24 * 60)), 14, 0); eventBox.setBottom( daysBox.top() + qRound( double(minsToEnd * daysBox.height()) / double(maxdays * 24 * 60))); drawVerticalBox(p, 0, eventBox, placeItem->event()->summary()); newxstartcont = qMax(newxstartcont, eventBox.right()); } xstartcont = newxstartcont; // For Single-day events, simply print their summaries into the remaining // space of the day's cell for (int d = 0; d < daysinmonth; ++d) { QStringList dayEvents(textEvents[d + 1]); QString txt = dayEvents.join(QStringLiteral(", ")); QRect dayBox(xstartcont, daysBox.top() + qRound(dayheight *d), 0, 0); dayBox.setRight(box.right()); dayBox.setBottom(daysBox.top() + qRound(dayheight * (d + 1))); printEventString(p, dayBox, txt, Qt::AlignTop | Qt::AlignLeft | Qt::TextWrapAnywhere); } p.setFont(oldfont); drawBox(p, BOX_BORDER_WIDTH, borderBox); p.restore(); } void CalPrintPluginBase::drawMonthTable(QPainter &p, const QDate &qd, const QTime &fromTime, const QTime &toTime, bool weeknumbers, bool recurDaily, bool recurWeekly, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate, const QRect &box) { int yoffset = mSubHeaderHeight; int xoffset = 0; QDate monthDate(QDate(qd.year(), qd.month(), 1)); QDate monthFirst(monthDate); QDate monthLast(monthDate.addMonths(1).addDays(-1)); int weekdayCol = weekdayColumn(monthDate.dayOfWeek()); monthDate = monthDate.addDays(-weekdayCol); if (weeknumbers) { xoffset += 14; } int rows = (weekdayCol + qd.daysInMonth() - 1) / 7 + 1; double cellHeight = (box.height() - yoffset) / (1. * rows); double cellWidth = (box.width() - xoffset) / 7.; // Precalculate the grid... // rows is at most 6, so using 8 entries in the array is fine, too! int coledges[8], rowedges[8]; for (int i = 0; i <= 7; ++i) { rowedges[i] = int(box.top() + yoffset + i * cellHeight); coledges[i] = int(box.left() + xoffset + i * cellWidth); } if (weeknumbers) { QFont oldFont(p.font()); QFont newFont(p.font()); newFont.setPointSize(6); p.setFont(newFont); QDate weekDate(monthDate); for (int row = 0; row < rows; ++row) { int calWeek = weekDate.weekNumber(); QRect rc(box.left(), rowedges[row], coledges[0] - 3 - box.left(), rowedges[row + 1] - rowedges[row]); p.drawText(rc, Qt::AlignRight | Qt::AlignVCenter, QString::number(calWeek)); weekDate = weekDate.addDays(7); } p.setFont(oldFont); } QRect daysOfWeekBox(box); daysOfWeekBox.setHeight(mSubHeaderHeight); daysOfWeekBox.setLeft(box.left() + xoffset); drawDaysOfWeek(p, monthDate, monthDate.addDays(6), daysOfWeekBox); QColor back = p.background().color(); bool darkbg = false; for (int row = 0; row < rows; ++row) { for (int col = 0; col < 7; ++col) { // show days from previous/next month with a grayed background if ((monthDate < monthFirst) || (monthDate > monthLast)) { p.setBackground(back.darker(120)); darkbg = true; } QRect dayBox(coledges[col], rowedges[row], coledges[col + 1] - coledges[col], rowedges[row + 1] - rowedges[row]); drawDayBox(p, monthDate, fromTime, toTime, dayBox, false, recurDaily, recurWeekly, singleLineLimit, showNoteLines, includeDescription, excludeConfidential, excludePrivate); if (darkbg) { p.setBackground(back); darkbg = false; } monthDate = monthDate.addDays(1); } } } void CalPrintPluginBase::drawTodoLines(QPainter &p, const QString &entry, int x, int &y, int width, int pageHeight, bool richTextEntry, QList &startPoints, bool connectSubTodos) { QString plainEntry = (richTextEntry) ? toPlainText(entry) : entry; QRect textrect(0, 0, width, -1); int flags = Qt::AlignLeft; QFontMetrics fm = p.fontMetrics(); QStringList lines = plainEntry.split(QLatin1Char('\n')); for (int currentLine = 0; currentLine < lines.count(); currentLine++) { // split paragraphs into lines KWordWrap ww = KWordWrap::formatText(fm, textrect, flags, lines[currentLine]); QStringList textLine = ww.wrappedString().split(QLatin1Char('\n')); // print each individual line for (int lineCount = 0; lineCount < textLine.count(); lineCount++) { if (y >= pageHeight) { if (connectSubTodos) { for (int i = 0; i < startPoints.size(); ++i) { TodoParentStart *rct; rct = startPoints.at(i); int start = rct->mRect.bottom() + 1; int center = rct->mRect.left() + (rct->mRect.width() / 2); int to = y; if (!rct->mSamePage) { start = 0; } if (rct->mHasLine) { p.drawLine(center, start, center, to); } rct->mSamePage = false; } } y = 0; mPrinter->newPage(); } y += fm.height(); p.drawText(x, y, textLine[lineCount]); } } } -void CalPrintPluginBase::drawTodo(int &count, const KCalCore::Todo::Ptr &todo, QPainter &p, - KCalCore::TodoSortField sortField, - KCalCore::SortDirection sortDir, bool connectSubTodos, +void CalPrintPluginBase::drawTodo(int &count, const KCalendarCore::Todo::Ptr &todo, QPainter &p, + KCalendarCore::TodoSortField sortField, + KCalendarCore::SortDirection sortDir, bool connectSubTodos, bool strikeoutCompleted, bool desc, int posPriority, int posSummary, int posDueDt, int posPercentComplete, int level, int x, int &y, int width, int pageHeight, - const KCalCore::Todo::List &todoList, TodoParentStart *r, + const KCalendarCore::Todo::List &todoList, TodoParentStart *r, bool excludeConfidential, bool excludePrivate) { QString outStr; const auto local = QLocale::system(); QRect rect; TodoParentStart startpt; // This list keeps all starting points of the parent to-dos so the connection // lines of the tree can easily be drawn (needed if a new page is started) static QList startPoints; if (level < 1) { startPoints.clear(); } y += 10; // Compute the right hand side of the to-do box int rhs = posPercentComplete; if (rhs < 0) { rhs = posDueDt; //not printing percent completed } if (rhs < 0) { rhs = x + width; //not printing due dates either } int left = posSummary + (level * 10); // If this is a sub-to-do, r will not be 0, and we want the LH side // of the priority line up to the RH side of the parent to-do's priority bool showPriority = posPriority >= 0; int lhs = posPriority; if (r) { lhs = r->mRect.right() + 1; } outStr.setNum(todo->priority()); rect = p.boundingRect(lhs, y + 10, 5, -1, Qt::AlignCenter, outStr); // Make it a more reasonable size rect.setWidth(18); rect.setHeight(18); // Draw a checkbox p.setBrush(QBrush(Qt::NoBrush)); p.drawRect(rect); if (todo->isCompleted()) { // cross out the rectangle for completed to-dos p.drawLine(rect.topLeft(), rect.bottomRight()); p.drawLine(rect.topRight(), rect.bottomLeft()); } lhs = rect.right() + 3; // Priority if (todo->priority() > 0 && showPriority) { p.drawText(rect, Qt::AlignCenter, outStr); } startpt.mRect = rect; //save for later // Connect the dots if (r && level > 0 && connectSubTodos) { int bottom; int center(r->mRect.left() + (r->mRect.width() / 2)); int to(rect.top() + (rect.height() / 2)); int endx(rect.left()); p.drawLine(center, to, endx, to); // side connector if (r->mSamePage) { bottom = r->mRect.bottom() + 1; } else { bottom = 0; } p.drawLine(center, bottom, center, to); } // summary outStr = todo->summary(); rect = p.boundingRect(lhs, rect.top(), (rhs - (left + rect.width() + 5)), -1, Qt::TextWordWrap, outStr); QRect newrect; QFont newFont(p.font()); QFont oldFont(p.font()); if (todo->isCompleted() && strikeoutCompleted) { newFont.setStrikeOut(true); p.setFont(newFont); } p.drawText(rect, Qt::TextWordWrap, outStr, &newrect); p.setFont(oldFont); // due date if (todo->hasDueDate() && posDueDt >= 0) { outStr = local.toString(todo->dtDue().toLocalTime().date(), QLocale::ShortFormat); rect = p.boundingRect(posDueDt, y, x + width, -1, Qt::AlignTop | Qt::AlignLeft, outStr); p.drawText(rect, Qt::AlignTop | Qt::AlignLeft, outStr); } // percentage completed bool showPercentComplete = posPercentComplete >= 0; if (showPercentComplete) { int lwidth = 24; int lheight = 12; //first, draw the progress bar int progress = static_cast(((lwidth * todo->percentComplete()) / 100.0 + 0.5)); p.setBrush(QBrush(Qt::NoBrush)); p.drawRect(posPercentComplete, y + 3, lwidth, lheight); if (progress > 0) { p.setBrush(QColor(128, 128, 128)); p.drawRect(posPercentComplete, y + 3, progress, lheight); } //now, write the percentage outStr = i18n("%1%", todo->percentComplete()); rect = p.boundingRect(posPercentComplete + lwidth + 3, y, x + width, -1, Qt::AlignTop | Qt::AlignLeft, outStr); p.drawText(rect, Qt::AlignTop | Qt::AlignLeft, outStr); } y += 10; // Make a list of all the sub-to-dos related to this to-do. - KCalCore::Todo::List t; - const KCalCore::Incidence::List relations = mCalendar->childIncidences(todo->uid()); + KCalendarCore::Todo::List t; + const KCalendarCore::Incidence::List relations = mCalendar->childIncidences(todo->uid()); - for (const KCalCore::Incidence::Ptr &incidence : relations) { + for (const KCalendarCore::Incidence::Ptr &incidence : relations) { // In the future, to-dos might also be related to events // Manually check if the sub-to-do is in the list of to-dos to print // The problem is that relations() does not apply filters, so // we need to compare manually with the complete filtered list! - KCalCore::Todo::Ptr subtodo = incidence.dynamicCast(); + KCalendarCore::Todo::Ptr subtodo = incidence.dynamicCast(); if (!subtodo) { continue; } #ifdef AKONADI_PORT_DISABLED if (subtodo && todoList.contains(subtodo)) { #else bool subtodoOk = false; if (subtodo) { - for (const KCalCore::Todo::Ptr &tt : qAsConst(todoList)) { + for (const KCalendarCore::Todo::Ptr &tt : qAsConst(todoList)) { if (tt == subtodo) { subtodoOk = true; break; } } } if (subtodoOk) { #endif if ((excludeConfidential - && subtodo->secrecy() == KCalCore::Incidence::SecrecyConfidential) + && subtodo->secrecy() == KCalendarCore::Incidence::SecrecyConfidential) || (excludePrivate - && subtodo->secrecy() == KCalCore::Incidence::SecrecyPrivate)) { + && subtodo->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) { continue; } t.append(subtodo); } } // has sub-todos? startpt.mHasLine = (relations.size() > 0); startPoints.append(&startpt); // description if (!todo->description().isEmpty() && desc) { y = newrect.bottom() + 5; drawTodoLines(p, todo->description(), left, y, width - (left + 10 - x), pageHeight, todo->descriptionIsRich(), startPoints, connectSubTodos); } else { y += 10; } // Sort the sub-to-dos and print them #ifdef AKONADI_PORT_DISABLED - KCalCore::Todo::List sl = mCalendar->sortTodos(&t, sortField, sortDir); + KCalendarCore::Todo::List sl = mCalendar->sortTodos(&t, sortField, sortDir); #else - KCalCore::Todo::List tl; + KCalendarCore::Todo::List tl; tl.reserve(t.count()); - for (const KCalCore::Todo::Ptr &todo : qAsConst(t)) { + for (const KCalendarCore::Todo::Ptr &todo : qAsConst(t)) { tl.append(todo); } - KCalCore::Todo::List sl = mCalendar->sortTodos(tl, sortField, sortDir); + KCalendarCore::Todo::List sl = mCalendar->sortTodos(tl, sortField, sortDir); #endif int subcount = 0; - for (const KCalCore::Todo::Ptr &isl : qAsConst(sl)) { + for (const KCalendarCore::Todo::Ptr &isl : qAsConst(sl)) { count++; if (++subcount == sl.size()) { startpt.mHasLine = false; } drawTodo(count, isl, p, sortField, sortDir, connectSubTodos, strikeoutCompleted, desc, posPriority, posSummary, posDueDt, posPercentComplete, level + 1, x, y, width, pageHeight, todoList, &startpt, excludeConfidential, excludePrivate); } startPoints.removeAll(&startpt); } int CalPrintPluginBase::weekdayColumn(int weekday) { int w = weekday + 7 - QLocale().firstDayOfWeek(); return w % 7; } void CalPrintPluginBase::drawTextLines(QPainter &p, const QString &entry, int x, int &y, int width, int pageHeight, bool richTextEntry) { QString plainEntry = (richTextEntry) ? toPlainText(entry) : entry; QRect textrect(0, 0, width, -1); int flags = Qt::AlignLeft; QFontMetrics fm = p.fontMetrics(); QStringList lines = plainEntry.split(QLatin1Char('\n')); for (int currentLine = 0; currentLine < lines.count(); currentLine++) { // split paragraphs into lines KWordWrap ww = KWordWrap::formatText(fm, textrect, flags, lines[currentLine]); QStringList textLine = ww.wrappedString().split(QLatin1Char('\n')); // print each individual line for (int lineCount = 0; lineCount < textLine.count(); lineCount++) { if (y >= pageHeight) { y = 0; mPrinter->newPage(); } y += fm.height(); p.drawText(x, y, textLine[lineCount]); } } } -void CalPrintPluginBase::drawJournal(const KCalCore::Journal::Ptr &journal, QPainter &p, int x, +void CalPrintPluginBase::drawJournal(const KCalendarCore::Journal::Ptr &journal, QPainter &p, int x, int &y, int width, int pageHeight) { QFont oldFont(p.font()); p.setFont(QFont(QStringLiteral("sans-serif"), 15)); QString headerText; QString dateText(QLocale::system().toString(journal->dtStart().toLocalTime().date(), QLocale::LongFormat)); if (journal->summary().isEmpty()) { headerText = dateText; } else { headerText = i18nc("Description - date", "%1 - %2", journal->summary(), dateText); } QRect rect(p.boundingRect(x, y, width, -1, Qt::TextWordWrap, headerText)); if (rect.bottom() > pageHeight) { // Start new page... y = 0; mPrinter->newPage(); rect = p.boundingRect(x, y, width, -1, Qt::TextWordWrap, headerText); } QRect newrect; p.drawText(rect, Qt::TextWordWrap, headerText, &newrect); p.setFont(oldFont); y = newrect.bottom() + 4; p.drawLine(x + 3, y, x + width - 6, y); y += 5; if (!(journal->organizer().fullName().isEmpty())) { drawTextLines(p, i18n("Person: %1", journal->organizer().fullName()), x, y, width, pageHeight, false); y += 7; } if (!(journal->description().isEmpty())) { drawTextLines(p, journal->description(), x, y, width, pageHeight, journal->descriptionIsRich()); y += 7; } y += 10; } void CalPrintPluginBase::drawSplitHeaderRight(QPainter &p, const QDate &fd, const QDate &td, const QDate &, int width, int height) { QFont oldFont(p.font()); QPen oldPen(p.pen()); QPen pen(Qt::black, 4); QString title; QLocale locale; if (fd.month() == td.month()) { title = i18nc("Date range: Month dayStart - dayEnd", "%1 %2 - %3", locale.monthName(fd.month(), QLocale::LongFormat), locale.toString(fd, QStringLiteral("dd")), locale.toString(td, QStringLiteral("dd"))); } else { title = i18nc("Date range: monthStart dayStart - monthEnd dayEnd", "%1 %2 - %3 %4", locale.monthName(fd.month(), QLocale::LongFormat), locale.toString(fd, QStringLiteral("dd")), locale.monthName(td.month(), QLocale::LongFormat), locale.toString(td, QStringLiteral("dd"))); } if (height < 60) { p.setFont(QFont(QStringLiteral("Times"), 22)); } else { p.setFont(QFont(QStringLiteral("Times"), 28)); } int lineSpacing = p.fontMetrics().lineSpacing(); p.drawText(0, 0, width, lineSpacing, Qt::AlignRight | Qt::AlignTop, title); title.truncate(0); p.setPen(pen); p.drawLine(300, lineSpacing, width, lineSpacing); p.setPen(oldPen); if (height < 60) { p.setFont(QFont(QStringLiteral("Times"), 14, QFont::Bold, true)); } else { p.setFont(QFont(QStringLiteral("Times"), 18, QFont::Bold, true)); } title += QString::number(fd.year()); p.drawText(0, lineSpacing, width, lineSpacing, Qt::AlignRight | Qt::AlignTop, title); p.setFont(oldFont); } void CalPrintPluginBase::drawNoteLines(QPainter &p, const QRect &box, int startY) { int lineHeight = int(p.fontMetrics().lineSpacing() * 1.5); int linePos = box.y(); int startPos = startY; // adjust line to start at multiple from top of box for alignment while (linePos < startPos) { linePos += lineHeight; } QPen oldPen(p.pen()); p.setPen(Qt::DotLine); while (linePos < box.bottom()) { p.drawLine(box.left() + padding(), linePos, box.right() - padding(), linePos); linePos += lineHeight; } p.setPen(oldPen); } QString CalPrintPluginBase::toPlainText(const QString &htmlText) { // this converts possible rich text to plain text return QTextDocumentFragment::fromHtml(htmlText).toPlainText(); } diff --git a/src/printing/calprintpluginbase.h b/src/printing/calprintpluginbase.h index be80ab5..7cbb4fd 100644 --- a/src/printing/calprintpluginbase.h +++ b/src/printing/calprintpluginbase.h @@ -1,636 +1,636 @@ /* Copyright (c) 1998 Preston Brown Copyright (C) 2003 Reinhold Kainhofer Copyright (C) 2008 Ron Goodheart Copyright (c) 2012-2013 Allen Winter 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 CALENDARSUPPORT_PRINTING_CALPRINTPLUGINBASE_H #define CALENDARSUPPORT_PRINTING_CALPRINTPLUGINBASE_H #include "calendarsupport_export.h" #include "printplugin.h" #include -#include -#include -#include +#include +#include +#include #include #include class PrintCellItem; class QWidget; #define PORTRAIT_HEADER_HEIGHT 72 // header height, for portrait orientation #define LANDSCAPE_HEADER_HEIGHT 54 // header height, for landscape orientation #define SUBHEADER_HEIGHT 20 // subheader height, for all orientations #define PORTRAIT_FOOTER_HEIGHT 16 // footer height, for portrait orientation #define LANDSCAPE_FOOTER_HEIGHT 14 // footer height, for landscape orientation #define MARGIN_SIZE 36 // margins, for all orientations #define PADDING_SIZE 7 // padding between the various top-level boxes #define BOX_BORDER_WIDTH 2 // width of the border of all top-level boxes #define EVENT_BORDER_WIDTH 0 // with of the border of all incidence boxes #define TIMELINE_WIDTH 50 // width of timeline (day and timetable) namespace CalendarSupport { /** Base class for Calendar printing classes. Each sub class represents one calendar print format. */ class CalPrintPluginBase : public PrintPlugin { public: enum DisplayFlags { Text = 0x0001, TimeBoxes = 0x0002 }; public: /** Constructor */ CalPrintPluginBase(); ~CalPrintPluginBase() override; /** Returns widget for configuring the print format. */ QWidget *createConfigWidget(QWidget *) override; /** Actually do the printing. @param p QPainter the print result is painted to @param width Width of printable area @param height Height of printable area */ virtual void print(QPainter &p, int width, int height) = 0; /** Start printing. */ void doPrint(QPrinter *printer) override; /** Load print format configuration from config file. */ virtual void loadConfig() = 0; /** Write print format configuration to config file. */ virtual void saveConfig() = 0; /** Load complete config. This also calls loadConfig() of the derived class. */ void doLoadConfig() override; /** Save complete config. This also calls saveConfig() of the derived class. */ void doSaveConfig() override; /** HELPER FUNCTIONS */ public: bool useColors() const; void setUseColors(bool useColors); bool printFooter() const; void setPrintFooter(bool printFooter); /** Determines the column of the given weekday ( 1=Monday, 7=Sunday ), taking the start of the week setting into account as given in kcontrol. @param weekday Index of the weekday */ static int weekdayColumn(int weekday); QPrinter::Orientation orientation() const; /** Returns the height of the page header. If the height was explicitly set using setHeaderHeight, that value is returned, otherwise a default value based on the printer orientation. @return height of the page header of the printout */ int headerHeight() const; void setHeaderHeight(const int height); int subHeaderHeight() const; void setSubHeaderHeight(const int height); /** Returns the height of the page footer. If the height was explicitly set using setFooterHeight, that value is returned, otherwise a default value based on the printer orientation. @return height of the page footer of the printout */ int footerHeight() const; void setFooterHeight(const int height); int margin() const; void setMargin(const int margin); int padding() const; void setPadding(const int margin); int borderWidth() const; void setBorderWidth(const int border); /***************************************************************** ** PRINTING HELPER FUNCTIONS ** *****************************************************************/ public: /** Draw a box with given width at the given coordinates. @param p The printer to be used @param linewidth The border width of the box @param rect The rectangle of the box */ static void drawBox(QPainter &p, int linewidth, const QRect &rect); /** Draw a shaded box with given width at the given coordinates. @param p The printer to be used @param linewidth The border width of the box @param brush The brush to fill the box @param rect The rectangle of the box */ static void drawShadedBox(QPainter &p, int linewidth, const QBrush &brush, const QRect &rect); /** Print the given string (event summary) in the given rectangle. Margins and justification (centered or not) are automatically adjusted. @param p QPainter of the printout @param box Coordinates of the surrounding event box @param str The text to be printed in the box */ void printEventString(QPainter &p, const QRect &box, const QString &str, int flags = -1); /** Print the box for the given event with the given string. @param p QPainter of the printout @param linewidth is the width of the line used to draw the box, ignored if less than 1. @param box Coordinates of the event's box @param incidence The incidence (if available), from which the category color will be deduced, if applicable. @param str The string to print inside the box @param flags is a bitwise OR of Qt::AlignmentFlags and Qt::TextFlags values. */ void showEventBox(QPainter &p, int linewidth, const QRect &box, - const KCalCore::Incidence::Ptr &incidence, const QString &str, + const KCalendarCore::Incidence::Ptr &incidence, const QString &str, int flags = -1); /** Draw a subheader box with a shaded background and the given string @param p QPainter of the printout @param str Text to be printed inside the box @param box Coordinates of the box */ void drawSubHeaderBox(QPainter &p, const QString &str, const QRect &box); /** Draw an event box with vertical text. @param p QPainter of the printout @param linewidth is the width of the line used to draw the box, ignored if less than 1. @param box Coordinates of the box @param str ext to be printed inside the box @param flags is a bitwise OR of Qt::AlignmentFlags and Qt::TextFlags values. */ void drawVerticalBox(QPainter &p, int linewidth, const QRect &box, const QString &str, int flags = -1); /** Draw a component box with a heading (printed in bold). @param p QPainter of the printout @param box Coordinates of the box @param caption Caption string to be printed inside the box @param contents Normal text contents of the box. If contents.isNull(), then no text will be printed, only the caption. @param sameLine Whether the contents should start on the same line as the caption (the space below the caption text will be used as indentation in the subsequent lines) or on the next line (no indentation of the contents) @param expand Whether to expand the box vertically to fit the whole text in it. @param rickContents Whether contents contains rich text. @return The bottom of the printed box. If expand==true, the bottom of the drawn box is returned, if expand==false, the vertical end of the printed contents inside the box is returned. If you want to print some custom graphics or text below the contents, use the return value as the top-value of your custom contents in that case. */ int drawBoxWithCaption(QPainter &p, const QRect &box, const QString &caption, const QString &contents, bool sameLine, bool expand, const QFont &captionFont, const QFont &textFont, bool richContents = false); /** Draw the gray header bar of the printout to the QPainter. It prints the given text and optionally one or two small month views, as specified by the two QDate. The printed text can also contain a line feed. If month2 is invalid, only the month that contains month1 is printed. E.g. the filofax week view draws just the current month, while the month view draws the previous and the next month. @param p QPainter of the printout @param title The string printed as the title of the page (e.g. the date, date range or todo list title) @param month1 Date specifying the month for the left one of the small month views in the title bar. If left empty, only month2 will be printed (or none, it that is invalid as well). @param month2 Date specifying the month for the right one of the small month views in the title bar. If left empty, only month1 will be printed (or none, it that is invalid as well). @param box coordinates of the title bar @param expand Whether to expand the box vertically to fit the whole title in it. @param backColor background color for the header box. @return The bottom of the printed box. If expand==false, this is box.bottom, otherwise it is larger than box.bottom and matches the y-coordinate of the surrounding rectangle. */ int drawHeader(QPainter &p, const QString &title, const QDate &month1, const QDate &month2, const QRect &box, bool expand = false, QColor backColor = QColor()); /** Draw a page footer containing the printing date and possibly other things, like a page number. @param p QPainter of the printout @param box coordinates of the footer @return The bottom of the printed box. */ int drawFooter(QPainter &p, const QRect &box); /** Draw a small calendar with the days of a month into the given area. Used for example in the title bar of the sheet. @param p QPainter of the printout @param qd Arbitrary Date within the month to be printed. @param box coordinates of the small calendar */ void drawSmallMonth(QPainter &p, const QDate &qd, const QRect &box); /** Draw a horizontal bar with the weekday names of the given date range in the given area of the painter. This is used for the weekday-bar on top of the timetable view and the month view. @param p QPainter of the printout @param fromDate First date of the printed dates @param toDate Last date of the printed dates @param box coordinates of the box for the days of the week */ void drawDaysOfWeek(QPainter &p, const QDate &fromDate, const QDate &toDate, const QRect &box); /** Draw a single weekday name in a box inside the given area of the painter. This is called in a loop by drawDaysOfWeek. @param p QPainter of the printout @param qd Date of the printed day @param box coordinates of the weekbox */ void drawDaysOfWeekBox(QPainter &p, const QDate &qd, const QRect &box); /** Draw a (vertical) time scale from time fromTime to toTime inside the given area of the painter. Every hour will have a one-pixel line over the whole width, every half-hour the line will only span the left half of the width. This is used in the day and timetable print styles @param p QPainter of the printout @param fromTime Start time of the time range to display @param toTime End time of the time range to display @param box coordinates of the timeline */ void drawTimeLine(QPainter &p, const QTime &fromTime, const QTime &toTime, const QRect &box); /** Draw the all-day box for the agenda print view (the box on top which doesn't have a time on the time scale associated). If expandable is set, height is the cell height of a single cell, and the returned height will be the total height used for the all-day events. If !expandable, only one cell will be used, and multiple events are concatenated using ", ". @param p QPainter of the printout @param eventList The list of all-day events that are supposed to be printed inside this box @param qd The date of the currently printed day @param expandable If true, height is the height of one single cell, the printout will use as many cells as events in the list and return the total height needed for all of them. If false, height specifies the total height allowed for all events, and the events are displayed in one cell, with their summaries concatenated by ", ". @param box coordinates of the all day box. @param excludeConfidential Whether to exclude Incidence marked confidential. @param excludePrivate Whether to exclude Incidence marked private. @return The height used for the all-day box. */ - int drawAllDayBox(QPainter &p, const KCalCore::Event::List &eventList, const QDate &qd, + int drawAllDayBox(QPainter &p, const KCalendarCore::Event::List &eventList, const QDate &qd, bool expandable, const QRect &box, bool excludeConfidential, bool excludePrivate); /** Draw the agenda box for the day print style (the box showing all events of that day). Also draws a grid with half-hour spacing of the grid lines. Does NOT draw allday events. Use drawAllDayBox for allday events. @param p QPainter of the printout @param eventList The list of the events that are supposed to be printed inside this box @param qd The date of the currently printed day @param expandable If true, the start and end times are adjusted to include the whole range of all events of that day, not just of the given time range. The height of the box will not be affected by this (but the height of one hour will be scaled down so that the whole range fits into the box. fromTime and toTime receive the actual time range printed by this function). @param fromTime Start of the time range to be printed. Might be adjusted to include all events if expandable==true @param toTime End of the time range to be printed. Might be adjusted to include all events if expandable==true @param box coordinates of the agenda day box. @param includeDescription Whether to print the event description as well. @param excludeTime Whether the time is printed in the detail area. @param excludeConfidential Whether to exclude Incidence marked confidential. @param excludePrivate Whether to exclude Incidence marked private. @param workDays List of workDays */ - void drawAgendaDayBox(QPainter &p, const KCalCore::Event::List &eventList, const QDate &qd, + void drawAgendaDayBox(QPainter &p, const KCalendarCore::Event::List &eventList, const QDate &qd, bool expandable, const QTime &fromTime, const QTime &toTime, const QRect &box, bool includeDescription, bool excludeTime, bool excludeConfidential, bool excludePrivate, const QList &workDays); void drawAgendaItem(PrintCellItem *item, QPainter &p, const QDateTime &startPrintDate, const QDateTime &endPrintDate, float minlen, const QRect &box, bool includeDescription, bool excludeTime); /** Draw the box containing a list of all events of the given day (with their times, of course). Used in the Filofax and the month print style. @param p QPainter of the printout @param qd The date of the currently printed day. All events of the calendar that appear on that day will be printed. @param fromTime Start time of the time range to display @param toTime End time of the time range to display @param box coordinates of the day box. @param fullDate Whether the title bar of the box should contain the full date string or just a short. @param printRecurDaily Whether daily recurring incidences should be printed. @param printRecurWeekly Whether weekly recurring incidences should be printed. @param singleLineLimit Whether Incidence text wraps or truncates. @param showNoteLines Whether note lines are printed. @param includeDescription Whether to print the event description as well. @param excludeConfidential Whether to exclude Incidence marked confidential. @param excludePrivate Whether to exclude Incidence marked private. */ void drawDayBox(QPainter &p, const QDate &qd, const QTime &fromTime, const QTime &toTime, const QRect &box, bool fullDate = false, bool printRecurDaily = true, bool printRecurWeekly = true, bool singleLineLimit = true, bool showNoteLines = false, bool includeDescription = false, bool excludeDescription = true, bool excludePrivate = true); /** Draw the week (filofax) table of the week containing the date qd. The first three days of the week will be shown in the first column (using drawDayBox), the remaining four in the second column, where the last two days of the week (typically Saturday and Sunday) only get half the height of the other day boxes. @param p QPainter of the printout @param qd Arbitrary date within the week to be printed. @param fromTime Start time of the displayed time range @param toTime End time of the displayed time range @param box coordinates of the week box. @param singleLineLimit Whether Incidence text wraps or truncates. @param showNoteLines Whether note lines are printed. @param includeDescription Whether to print the event description as well. @param excludeConfidential Whether to exclude Incidence marked confidential. @param excludePrivate Whether to exclude Incidence marked private. */ void drawWeek(QPainter &p, const QDate &qd, const QTime &fromTime, const QTime &toTime, const QRect &box, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate); /** Draw the (filofax) table for a bunch of days, using drawDayBox. @param p QPainter of the printout @param start Start date @param end End date @param fromTime Start time of the displayed time range @param toTime End time of the displayed time range @param box coordinates of the week box. @param singleLineLimit Whether Incidence text wraps or truncates. @param showNoteLines Whether note lines are printed. @param includeDescription Whether to print the event description as well. @param excludeConfidential Whether to exclude Incidence marked confidential. @param excludePrivate Whether to exclude Incidence marked private. */ void drawDays(QPainter &p, const QDate &start, const QDate &end, const QTime &fromTime, const QTime &toTime, const QRect &box, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate); /** Draw the timetable view of the given time range from fromDate to toDate. On the left side the time scale is printed (using drawTimeLine), then each day gets one column (printed using drawAgendaDayBox), and the events are displayed as boxes (like in korganizer's day/week view). The first cell of each column contains the all-day events (using drawAllDayBox with expandable=false). @param p QPainter of the printout @param fromDate First day to be included in the page @param toDate Last day to be included in the page @param expandable If true, the start and end times are adjusted to include the whole range of all events of that day, not just of the given time range. @param fromTime Start time of the displayed time range @param toTime End time of the displayed time range @param box coordinates of the time table. @param includeDescription Whether to print the event description as well. @param excludeTime Whether the time is printed in the detail area. @param excludeConfidential Whether to exclude Incidence marked confidential. @param excludePrivate Whether to exclude Incidence marked private. */ void drawTimeTable(QPainter &p, const QDate &fromDate, const QDate &toDate, bool expandable, const QTime &fromTime, const QTime &toTime, const QRect &box, bool includeDescription, bool excludeTime, bool excludeConfidential, bool excludePrivate); /** Draw the month table of the month containing the date qd. Each day gets one box (using drawDayBox) that contains a list of all events on that day. They are arranged in a matrix, with the first column being the first day of the week (so it might display some days of the previous and the next month). Above the matrix there is a bar showing the weekdays (drawn using drawDaysOfWeek). @param p QPainter of the printout @param qd Arbitrary date within the month to be printed. @param fromTime Start time of the displayed time range @param toTime End time of the displayed time range @param weeknumbers Whether the week numbers are printed left of each row of the matrix @param recurDaily Whether daily recurring incidences should be printed. @param recurWeekly Whether weekly recurring incidences should be printed. @param singleLineLimit Whether Incidence text wraps or truncates. @param showNoteLines Whether note lines are printed. @param includeDescription Whether descriptions are printed. @param excludeConfidential Whether to exclude Incidence marked confidential. @param excludePrivate Whether to exclude Incidence marked private. @param box coordinates of the month. */ void drawMonthTable(QPainter &p, const QDate &qd, const QTime &fromTime, const QTime &toTime, bool weeknumbers, bool recurDaily, bool recurWeekly, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate, const QRect &box); /** Draw a vertical representation of the month containing the date dt. Each day gets one line. @param p QPainter of the printout @param dt Arbitrary date within the month to be printed @param box coordinates of the box reserved for the month @param maxdays Days to print. If a value of -1 is given, the number of days is deduced from the month. If maxdays is larger than the number of days in the month, the remaining boxes are shaded to indicate they are not days of the month. @param subDailyFlags Bitfield consisting of DisplayFlags flags to determine how events that do not cross midnight should be printed. @param holidaysFlags Bitfield consisting of DisplayFlags flags to determine how holidays should be printed. @param excludeConfidential Whether to exclude Incidence marked confidential. @param excludePrivate Whether to exclude Incidence marked private. */ void drawMonth(QPainter &p, const QDate &dt, const QRect &box, int maxdays = -1, int subDailyFlags = TimeBoxes, int holidaysFlags = Text, bool excludeConfidential = false, bool excludePrivate = false); /** Internal class representing the start of a todo. */ class TodoParentStart; /** Draws single to-do and its (intented) sub-to-dos, optionally connects them by a tree-like line, and optionally shows due date, summary, description and priority. @param count The number of the currently printed to-do (count will be incremented for each to-do drawn) @param todo The to-do to be printed. It's sub-to-dos are recursively drawn, so drawTodo should only be called on the to-dos of the highest level. @param p QPainter of the printout @param sortField Specifies on which attribute of the todo you want to sort. @param sortDir Specifies if you want to sort ascending or descending. @param connectSubTodos Whether sub-to-dos shall be connected with their parent by a line (tree-like). @param strikeoutCompleted Whether completed to-dos should be printed with strike-out summaries. @param desc Whether to print the whole description of the to-do (the summary is always printed). @param posPriority x-coordinate where the priority is supposed to be printed. If <0, no priority will be printed. @param posSummary x-coordinate where the summary of the to-do is supposed to be printed. @param posDueDt x-coordinate where the due date is supposed to the be printed. If <0, no due date will be printed. @param posPercentComplete x-coordinate where the percentage complete is supposed to be printed. If <0, percentage complete will not be printed. @param level Level of the current to-do in the to-do hierarchy (0 means highest level of printed to-dos, 1 are their sub-to-dos, etc.) @param x x-coordinate of the upper left coordinate of the first to-do. @param y y-coordinate of the upper left coordinate of the first to-do. @param width width of the whole to-do list. @param pageHeight Total height allowed for the to-do list on a page. If an to-do would be below that line, a new page is started. @param todoList Contains a list of sub-todos for the specified @p todo . @param r Internal (used when printing sub-to-dos to give information about its parent) */ - void drawTodo(int &count, const KCalCore::Todo::Ptr &todo, QPainter &p, - KCalCore::TodoSortField sortField, KCalCore::SortDirection sortDir, + void drawTodo(int &count, const KCalendarCore::Todo::Ptr &todo, QPainter &p, + KCalendarCore::TodoSortField sortField, KCalendarCore::SortDirection sortDir, bool connectSubTodos, bool strikeoutCompleted, bool desc, int posPriority, int posSummary, int posDueDt, int posPercentComplete, int level, int x, int &y, - int width, int pageHeight, const KCalCore::Todo::List &todoList, + int width, int pageHeight, const KCalendarCore::Todo::List &todoList, TodoParentStart *r, bool excludeConfidential, bool excludePrivate); /** Draws single journal item. @param journal The item to be printed. @param p QPainter of the printout @param x x-coordinate of the upper left coordinate of the first item @param y y-coordinate of the upper left coordinate of the first item @param width width of the whole list @param pageHeight Total height allowed for the list on a page. If an item would be below that line, a new page is started. */ - void drawJournal(const KCalCore::Journal::Ptr &journal, QPainter &p, int x, int &y, int width, + void drawJournal(const KCalendarCore::Journal::Ptr &journal, QPainter &p, int x, int &y, int width, int pageHeight); /** Draws text lines splitting on page boundaries. @param p QPainter of the printout @param x x-coordinate of the upper left coordinate of the first item @param y y-coordinate of the upper left coordinate of the first item @param width width of the whole list @param pageHeight size of the page. A new page is started when the text reaches the end of the page. */ void drawTextLines(QPainter &p, const QString &entry, int x, int &y, int width, int pageHeight, bool richTextEntry); void drawSplitHeaderRight(QPainter &p, const QDate &fd, const QDate &td, const QDate &cd, int width, int height); /** Draws dotted lines for notes in a box. @param p QPainter of the printout @param box coordinates of the box where the lines will be placed @param startY starting y-coordinate for the first line */ void drawNoteLines(QPainter &p, const QRect &box, int startY); protected: QTime dayStart() const; - QColor categoryBgColor(const KCalCore::Incidence::Ptr &incidence) const; + QColor categoryBgColor(const KCalendarCore::Incidence::Ptr &incidence) const; void drawIncidence(QPainter &p, const QRect &dayBox, const QString &time, const QString &summary, const QString &description, int &textY, bool singleLineLimit, bool includeDescription, bool richDescription); QString toPlainText(const QString &htmlText); void drawTodoLines(QPainter &p, const QString &entry, int x, int &y, int width, int pageHeight, bool richTextEntry, QList &startPoints, bool connectSubTodos); protected: bool mUseColors; bool mPrintFooter; bool mShowNoteLines; int mHeaderHeight; int mSubHeaderHeight; int mFooterHeight; int mMargin; int mPadding; int mBorder; private: QColor categoryColor(const QStringList &categories) const; /** * Sets the QPainter's brush and pen color according to the Incidence's category. */ - void setColorsByIncidenceCategory(QPainter &p, const KCalCore::Incidence::Ptr &incidence) const; + void setColorsByIncidenceCategory(QPainter &p, const KCalendarCore::Incidence::Ptr &incidence) const; QString holidayString(const QDate &date) const; - KCalCore::Event::Ptr holidayEvent(const QDate &date) const; + KCalendarCore::Event::Ptr holidayEvent(const QDate &date) const; /** * Returns a nice QColor for text, give the input color &c. */ QColor getTextColor(const QColor &c) const; }; } #endif diff --git a/src/printing/journalprint.cpp b/src/printing/journalprint.cpp index 8762c4b..c8d5259 100644 --- a/src/printing/journalprint.cpp +++ b/src/printing/journalprint.cpp @@ -1,132 +1,132 @@ /* Copyright (C) 2004 Reinhold Kainhofer 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 "journalprint.h" #include "utils.h" #include #include "calendarsupport_debug.h" using namespace CalendarSupport; /************************************************************** * Print Journal **************************************************************/ QWidget *CalPrintJournal::createConfigWidget(QWidget *w) { return new CalPrintJournalConfig(w); } void CalPrintJournal::readSettingsWidget() { CalPrintJournalConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { mFromDate = cfg->mFromDate->date(); mToDate = cfg->mToDate->date(); mUseDateRange = cfg->mRangeJournals->isChecked(); } } void CalPrintJournal::setSettingsWidget() { CalPrintJournalConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { cfg->mFromDate->setDate(mFromDate); cfg->mToDate->setDate(mToDate); if (mUseDateRange) { cfg->mRangeJournals->setChecked(true); cfg->mFromDateLabel->setEnabled(true); cfg->mFromDate->setEnabled(true); cfg->mToDateLabel->setEnabled(true); cfg->mToDate->setEnabled(true); } else { cfg->mAllJournals->setChecked(true); cfg->mFromDateLabel->setEnabled(false); cfg->mFromDate->setEnabled(false); cfg->mToDateLabel->setEnabled(false); cfg->mToDate->setEnabled(false); } } } void CalPrintJournal::loadConfig() { if (mConfig) { KConfigGroup config(mConfig, "Journalprint"); mUseDateRange = config.readEntry("JournalsInRange", false); } setSettingsWidget(); } void CalPrintJournal::saveConfig() { qCDebug(CALENDARSUPPORT_LOG); readSettingsWidget(); if (mConfig) { KConfigGroup config(mConfig, "Journalprint"); config.writeEntry("JournalsInRange", mUseDateRange); } } void CalPrintJournal::setDateRange(const QDate &from, const QDate &to) { CalPrintPluginBase::setDateRange(from, to); CalPrintJournalConfig *cfg = dynamic_cast((QWidget *)mConfigWidget); if (cfg) { cfg->mFromDate->setDate(from); cfg->mToDate->setDate(to); } } void CalPrintJournal::print(QPainter &p, int width, int height) { int x = 0, y = 0; - KCalCore::Journal::List journals(mCalendar->journals()); + KCalendarCore::Journal::List journals(mCalendar->journals()); if (mUseDateRange) { - const KCalCore::Journal::List allJournals = journals; + const KCalendarCore::Journal::List allJournals = journals; journals.clear(); - for (const KCalCore::Journal::Ptr &j : allJournals) { + for (const KCalendarCore::Journal::Ptr &j : allJournals) { const QDate dt = j->dtStart().date(); if (mFromDate <= dt && dt <= mToDate) { journals.append(j); } } } QRect headerBox(0, 0, width, headerHeight()); QRect footerBox(0, height - footerHeight(), width, footerHeight()); height -= footerHeight(); drawHeader(p, i18n("Journal entries"), QDate(), QDate(), headerBox); y = headerHeight() + 15; - for (const KCalCore::Journal::Ptr &j : qAsConst(journals)) { + for (const KCalendarCore::Journal::Ptr &j : qAsConst(journals)) { drawJournal(j, p, x, y, width, height); } drawFooter(p, footerBox); } diff --git a/src/printing/printplugin.h b/src/printing/printplugin.h index 11d083e..c3153f7 100644 --- a/src/printing/printplugin.h +++ b/src/printing/printplugin.h @@ -1,221 +1,221 @@ /* Copyright (C) 2003 Reinhold Kainhofer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CALENDARSUPPORT_PRINTING_PRINTPLUGIN_H #define CALENDARSUPPORT_PRINTING_PRINTPLUGIN_H #include "plugin.h" #include -#include +#include #include #include #include namespace CalendarSupport { /** Base class of Calendar printer class. */ class CalPrinterBase { public: enum PrintType { Incidence = 100, Day = 200, Week = 300, Month = 400, Year = 900, Todolist = 1000, Journallist = 2000, WhatsNext = 2100, ItemList = 2200 }; }; /** Base class for Calendar printing classes. Each sub class represents one calendar print format. */ class PrintPlugin : public Plugin { public: PrintPlugin() : Plugin() , mConfigWidget(nullptr) , mPrinter(nullptr) , mCalendar(nullptr) , mConfig(nullptr) { } ~PrintPlugin() override { } typedef QList List; static int interfaceVersion() { return 2; } virtual void setConfig(KConfig *cfg) { mConfig = cfg; } virtual void setCalendar(const Akonadi::ETMCalendar::Ptr &cal) { mCalendar = cal; } - virtual void setSelectedIncidences(const KCalCore::Incidence::List &inc) + virtual void setSelectedIncidences(const KCalendarCore::Incidence::List &inc) { mSelectedIncidences = inc; } - virtual KCalCore::Incidence::List selectedIncidences() const + virtual KCalendarCore::Incidence::List selectedIncidences() const { return mSelectedIncidences; } /** Returns KConfig group name where store settings */ virtual QString groupName() const = 0; /** Returns short description of print format. */ virtual QString description() const = 0; /** Returns long description of print format. */ QString info() const override = 0; /** Returns the sort ID of the plugin. This value will be used to identify the config widget in the widget stack, and to sort the plugin name in the print style selection list. If another plugin uses the same ID or a value of -1 is returned, a unique (negative) ID will be automatically generated and thus the position of the plugin in the selection list is undefined. */ virtual int sortID() const { return -1; } /** Returns true if the plugin should be enabled; false otherwise. */ virtual bool enabled() const { return false; } QWidget *configWidget(QWidget *w) { if (!mConfigWidget) { mConfigWidget = createConfigWidget(w); setSettingsWidget(); } return mConfigWidget; } /* Create the config widget. setSettingsWidget will be automatically called on it */ virtual QWidget *createConfigWidget(QWidget *) = 0; /** Actually do the printing. */ virtual void doPrint(QPrinter *printer) = 0; /** Orientation of printout. Default is Portrait. If your plugin wants to use some other orientation as default (e.g. depending on some config settings), implement this function in your subclass and return the desired orientation. */ virtual QPrinter::Orientation defaultOrientation() const { return QPrinter::Portrait; } /** Load complete config. */ virtual void doLoadConfig() { } /** Save complete config. */ virtual void doSaveConfig() { } public: /** Read settings from configuration widget and apply them to current object. */ virtual void readSettingsWidget() { } /** Set configuration widget to reflect settings of current object. */ virtual void setSettingsWidget() { } /** Set date range which should be printed. */ virtual void setDateRange(const QDate &from, const QDate &to) { mFromDate = from; mToDate = to; } protected: QDate mFromDate; QDate mToDate; protected: QPointer mConfigWidget; /** The printer object. This will only be available in the doPrint method of the selected plugin */ QPrinter *mPrinter = nullptr; Akonadi::ETMCalendar::Ptr mCalendar; - KCalCore::Incidence::List mSelectedIncidences; + KCalendarCore::Incidence::List mSelectedIncidences; KConfig *mConfig = nullptr; }; class PrintPluginFactory : public PluginFactory { Q_OBJECT public: PrintPlugin *createPluginFactory() override = 0; }; } #endif diff --git a/src/utils.cpp b/src/utils.cpp index b27ff90..8fea00c 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,831 +1,831 @@ /* Copyright (c) 2009, 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com Author: Frank Osterfeld Author: Andras Mantia 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 "utils.h" #include "kcalprefs.h" #include #include #include #include #include #include #include #include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "calendarsupport_debug.h" using namespace CalendarSupport; using namespace KHolidays; -using namespace KCalCore; +using namespace KCalendarCore; -KCalCore::Incidence::Ptr CalendarSupport::incidence(const Akonadi::Item &item) +KCalendarCore::Incidence::Ptr CalendarSupport::incidence(const Akonadi::Item &item) { //relying on exception for performance reasons try { - return item.payload(); + return item.payload(); } catch (const Akonadi::PayloadException &) { - return KCalCore::Incidence::Ptr(); + return KCalendarCore::Incidence::Ptr(); } } -KCalCore::Event::Ptr CalendarSupport::event(const Akonadi::Item &item) +KCalendarCore::Event::Ptr CalendarSupport::event(const Akonadi::Item &item) { //relying on exception for performance reasons try { - KCalCore::Incidence::Ptr incidence = item.payload(); + KCalendarCore::Incidence::Ptr incidence = item.payload(); if (hasEvent(incidence)) { - return item.payload(); + return item.payload(); } } catch (const Akonadi::PayloadException &) { - return KCalCore::Event::Ptr(); + return KCalendarCore::Event::Ptr(); } - return KCalCore::Event::Ptr(); + return KCalendarCore::Event::Ptr(); } -KCalCore::Event::Ptr CalendarSupport::event(const KCalCore::Incidence::Ptr &incidence) +KCalendarCore::Event::Ptr CalendarSupport::event(const KCalendarCore::Incidence::Ptr &incidence) { if (hasEvent(incidence)) { - return incidence.staticCast(); + return incidence.staticCast(); } - return KCalCore::Event::Ptr(); + return KCalendarCore::Event::Ptr(); } -KCalCore::Incidence::List CalendarSupport::incidencesFromItems(const Akonadi::Item::List &items) +KCalendarCore::Incidence::List CalendarSupport::incidencesFromItems(const Akonadi::Item::List &items) { - KCalCore::Incidence::List incidences; + KCalendarCore::Incidence::List incidences; for (const Akonadi::Item &item : items) { - if (const KCalCore::Incidence::Ptr e = CalendarSupport::incidence(item)) { + if (const KCalendarCore::Incidence::Ptr e = CalendarSupport::incidence(item)) { incidences.push_back(e); } } return incidences; } -KCalCore::Todo::Ptr CalendarSupport::todo(const Akonadi::Item &item) +KCalendarCore::Todo::Ptr CalendarSupport::todo(const Akonadi::Item &item) { try { - KCalCore::Incidence::Ptr incidence = item.payload(); + KCalendarCore::Incidence::Ptr incidence = item.payload(); if (hasTodo(incidence)) { - return item.payload(); + return item.payload(); } } catch (const Akonadi::PayloadException &) { - return KCalCore::Todo::Ptr(); + return KCalendarCore::Todo::Ptr(); } - return KCalCore::Todo::Ptr(); + return KCalendarCore::Todo::Ptr(); } -KCalCore::Todo::Ptr CalendarSupport::todo(const KCalCore::Incidence::Ptr &incidence) +KCalendarCore::Todo::Ptr CalendarSupport::todo(const KCalendarCore::Incidence::Ptr &incidence) { if (hasTodo(incidence)) { - return incidence.staticCast(); + return incidence.staticCast(); } - return KCalCore::Todo::Ptr(); + return KCalendarCore::Todo::Ptr(); } -KCalCore::Journal::Ptr CalendarSupport::journal(const Akonadi::Item &item) +KCalendarCore::Journal::Ptr CalendarSupport::journal(const Akonadi::Item &item) { try { - KCalCore::Incidence::Ptr incidence = item.payload(); + KCalendarCore::Incidence::Ptr incidence = item.payload(); if (hasJournal(incidence)) { - return item.payload(); + return item.payload(); } } catch (const Akonadi::PayloadException &) { - return KCalCore::Journal::Ptr(); + return KCalendarCore::Journal::Ptr(); } - return KCalCore::Journal::Ptr(); + return KCalendarCore::Journal::Ptr(); } -KCalCore::Journal::Ptr CalendarSupport::journal(const KCalCore::Incidence::Ptr &incidence) +KCalendarCore::Journal::Ptr CalendarSupport::journal(const KCalendarCore::Incidence::Ptr &incidence) { if (hasJournal(incidence)) { - return incidence.staticCast(); + return incidence.staticCast(); } - return KCalCore::Journal::Ptr(); + return KCalendarCore::Journal::Ptr(); } bool CalendarSupport::hasIncidence(const Akonadi::Item &item) { - return item.hasPayload(); + return item.hasPayload(); } bool CalendarSupport::hasEvent(const Akonadi::Item &item) { - return item.hasPayload(); + return item.hasPayload(); } -bool CalendarSupport::hasEvent(const KCalCore::Incidence::Ptr &incidence) +bool CalendarSupport::hasEvent(const KCalendarCore::Incidence::Ptr &incidence) { - return incidence && incidence->type() == KCalCore::Incidence::TypeEvent; + return incidence && incidence->type() == KCalendarCore::Incidence::TypeEvent; } bool CalendarSupport::hasTodo(const Akonadi::Item &item) { - return item.hasPayload(); + return item.hasPayload(); } -bool CalendarSupport::hasTodo(const KCalCore::Incidence::Ptr &incidence) +bool CalendarSupport::hasTodo(const KCalendarCore::Incidence::Ptr &incidence) { - return incidence && incidence->type() == KCalCore::Incidence::TypeTodo; + return incidence && incidence->type() == KCalendarCore::Incidence::TypeTodo; } bool CalendarSupport::hasJournal(const Akonadi::Item &item) { - return item.hasPayload(); + return item.hasPayload(); } -bool CalendarSupport::hasJournal(const KCalCore::Incidence::Ptr &incidence) +bool CalendarSupport::hasJournal(const KCalendarCore::Incidence::Ptr &incidence) { - return incidence && incidence->type() == KCalCore::Incidence::TypeJournal; + return incidence && incidence->type() == KCalendarCore::Incidence::TypeJournal; } QMimeData *CalendarSupport::createMimeData(const Akonadi::Item::List &items) { if (items.isEmpty()) { return nullptr; } - KCalCore::MemoryCalendar::Ptr cal(new KCalCore::MemoryCalendar(QTimeZone::systemTimeZone())); + KCalendarCore::MemoryCalendar::Ptr cal(new KCalendarCore::MemoryCalendar(QTimeZone::systemTimeZone())); QList urls; int incidencesFound = 0; for (const Akonadi::Item &item : items) { - const KCalCore::Incidence::Ptr incidence(CalendarSupport::incidence(item)); + const KCalendarCore::Incidence::Ptr incidence(CalendarSupport::incidence(item)); if (!incidence) { continue; } ++incidencesFound; urls.push_back(item.url()); - KCalCore::Incidence::Ptr i(incidence->clone()); + KCalendarCore::Incidence::Ptr i(incidence->clone()); cal->addIncidence(i); } if (incidencesFound == 0) { return nullptr; } std::unique_ptr mimeData(new QMimeData); mimeData->setUrls(urls); KCalUtils::ICalDrag::populateMimeData(mimeData.get(), cal); return mimeData.release(); } QMimeData *CalendarSupport::createMimeData(const Akonadi::Item &item) { return createMimeData(Akonadi::Item::List() << item); } #ifndef QT_NO_DRAGANDDROP QDrag *CalendarSupport::createDrag(const Akonadi::Item &item, QWidget *parent) { return createDrag(Akonadi::Item::List() << item, parent); } #endif static QByteArray findMostCommonType(const Akonadi::Item::List &items) { QByteArray prev; if (items.isEmpty()) { return "Incidence"; } for (const Akonadi::Item &item : items) { if (!CalendarSupport::hasIncidence(item)) { continue; } const QByteArray type = CalendarSupport::incidence(item)->typeStr(); if (!prev.isEmpty() && type != prev) { return "Incidence"; } prev = type; } return prev; } #ifndef QT_NO_DRAGANDDROP QDrag *CalendarSupport::createDrag(const Akonadi::Item::List &items, QWidget *parent) { std::unique_ptr drag(new QDrag(parent)); drag->setMimeData(CalendarSupport::createMimeData(items)); const QByteArray common = findMostCommonType(items); if (common == "Event") { drag->setPixmap(BarIcon(QStringLiteral("view-calendar-day"))); } else if (common == "Todo") { drag->setPixmap(BarIcon(QStringLiteral("view-calendar-tasks"))); } return drag.release(); } #endif -static bool itemMatches(const Akonadi::Item &item, const KCalCore::CalFilter *filter) +static bool itemMatches(const Akonadi::Item &item, const KCalendarCore::CalFilter *filter) { assert(filter); - KCalCore::Incidence::Ptr inc = CalendarSupport::incidence(item); + KCalendarCore::Incidence::Ptr inc = CalendarSupport::incidence(item); if (!inc) { return false; } return filter->filterIncidence(inc); } Akonadi::Item::List CalendarSupport::applyCalFilter(const Akonadi::Item::List &items_, - const KCalCore::CalFilter *filter) + const KCalendarCore::CalFilter *filter) { Q_ASSERT(filter); Akonadi::Item::List items(items_); items.erase(std::remove_if(items.begin(), items.end(), [filter](const Akonadi::Item &item) { return !itemMatches(item, filter); }), items.end()); return items; } bool CalendarSupport::isValidIncidenceItemUrl(const QUrl &url, const QStringList &supportedMimeTypes) { if (!url.isValid()) { return false; } if (url.scheme() != QLatin1String("akonadi")) { return false; } return supportedMimeTypes.contains(QUrlQuery(url).queryItemValue(QStringLiteral("type"))); } bool CalendarSupport::isValidIncidenceItemUrl(const QUrl &url) { return isValidIncidenceItemUrl(url, - QStringList() << KCalCore::Event::eventMimeType() - << KCalCore::Todo::todoMimeType() - << KCalCore::Journal::journalMimeType() - << KCalCore::FreeBusy::freeBusyMimeType()); + QStringList() << KCalendarCore::Event::eventMimeType() + << KCalendarCore::Todo::todoMimeType() + << KCalendarCore::Journal::journalMimeType() + << KCalendarCore::FreeBusy::freeBusyMimeType()); } static bool containsValidIncidenceItemUrl(const QList &urls) { return std::find_if(urls.begin(), urls.end(), [](const QUrl &url) { return CalendarSupport::isValidIncidenceItemUrl(url); }) != urls.constEnd(); } bool CalendarSupport::canDecode(const QMimeData *md) { if (md) { return containsValidIncidenceItemUrl(md->urls()) || KCalUtils::ICalDrag::canDecode(md) || KCalUtils::VCalDrag::canDecode(md); } else { return false; } } QList CalendarSupport::incidenceItemUrls(const QMimeData *mimeData) { QList urls; const QList urlsList = mimeData->urls(); for (const QUrl &i : urlsList) { if (isValidIncidenceItemUrl(i)) { urls.push_back(i); } } return urls; } QList CalendarSupport::todoItemUrls(const QMimeData *mimeData) { QList urls; const QList urlList = mimeData->urls(); for (const QUrl &i : urlList) { - if (isValidIncidenceItemUrl(i, QStringList() << KCalCore::Todo::todoMimeType())) { + if (isValidIncidenceItemUrl(i, QStringList() << KCalendarCore::Todo::todoMimeType())) { urls.push_back(i); } } return urls; } bool CalendarSupport::mimeDataHasIncidence(const QMimeData *mimeData) { return !incidenceItemUrls(mimeData).isEmpty() || !incidences(mimeData).isEmpty(); } -KCalCore::Todo::List CalendarSupport::todos(const QMimeData *mimeData) +KCalendarCore::Todo::List CalendarSupport::todos(const QMimeData *mimeData) { - KCalCore::Todo::List todos; + KCalendarCore::Todo::List todos; #ifndef QT_NO_DRAGANDDROP - KCalCore::Calendar::Ptr cal(KCalUtils::DndFactory::createDropCalendar(mimeData)); + KCalendarCore::Calendar::Ptr cal(KCalUtils::DndFactory::createDropCalendar(mimeData)); if (cal) { - const KCalCore::Todo::List calTodos = cal->todos(); + const KCalendarCore::Todo::List calTodos = cal->todos(); todos.reserve(calTodos.count()); - for (const KCalCore::Todo::Ptr &i : calTodos) { - todos.push_back(KCalCore::Todo::Ptr(i->clone())); + for (const KCalendarCore::Todo::Ptr &i : calTodos) { + todos.push_back(KCalendarCore::Todo::Ptr(i->clone())); } } #endif return todos; } -KCalCore::Incidence::List CalendarSupport::incidences(const QMimeData *mimeData) +KCalendarCore::Incidence::List CalendarSupport::incidences(const QMimeData *mimeData) { - KCalCore::Incidence::List incidences; + KCalendarCore::Incidence::List incidences; #ifndef QT_NO_DRAGANDDROP - KCalCore::Calendar::Ptr cal(KCalUtils::DndFactory::createDropCalendar(mimeData)); + KCalendarCore::Calendar::Ptr cal(KCalUtils::DndFactory::createDropCalendar(mimeData)); if (cal) { - const KCalCore::Incidence::List calIncidences = cal->incidences(); + const KCalendarCore::Incidence::List calIncidences = cal->incidences(); incidences.reserve(calIncidences.count()); - for (const KCalCore::Incidence::Ptr &i : calIncidences) { - incidences.push_back(KCalCore::Incidence::Ptr(i->clone())); + for (const KCalendarCore::Incidence::Ptr &i : calIncidences) { + incidences.push_back(KCalendarCore::Incidence::Ptr(i->clone())); } } #endif return incidences; } Akonadi::Collection CalendarSupport::selectCollection(QWidget *parent, int &dialogCode, const QStringList &mimeTypes, const Akonadi::Collection &defCollection) { QPointer dlg(new Akonadi::CollectionDialog(parent)); dlg->setWindowTitle(i18n("Select Calendar")); dlg->setDescription(i18n("Select the calendar where this item will be stored.")); dlg->changeCollectionDialogOptions(Akonadi::CollectionDialog::KeepTreeExpanded); qCDebug(CALENDARSUPPORT_LOG) << "selecting collections with mimeType in " << mimeTypes; dlg->setMimeTypeFilter(mimeTypes); dlg->setAccessRightsFilter(Akonadi::Collection::CanCreateItem); if (defCollection.isValid()) { dlg->setDefaultCollection(defCollection); } Akonadi::Collection collection; // FIXME: don't use exec. dialogCode = dlg->exec(); if (dlg && dialogCode == QDialog::Accepted) { collection = dlg->selectedCollection(); if (!collection.isValid()) { qCWarning(CALENDARSUPPORT_LOG) << "An invalid collection was selected!"; } } delete dlg; return collection; } Akonadi::Item CalendarSupport::itemFromIndex(const QModelIndex &idx) { Akonadi::Item item = idx.data(Akonadi::EntityTreeModel::ItemRole).value(); item.setParentCollection( idx.data(Akonadi::EntityTreeModel::ParentCollectionRole).value()); return item; } Akonadi::Collection::List CalendarSupport::collectionsFromModel(const QAbstractItemModel *model, const QModelIndex &parentIndex, int start, int end) { const int endRow = end >= 0 ? end : model->rowCount(parentIndex) - 1; Akonadi::Collection::List collections; int row = start; QModelIndex i = model->index(row, 0, parentIndex); while (row <= endRow) { const Akonadi::Collection collection = collectionFromIndex(i); if (collection.isValid()) { collections << collection; QModelIndex childIndex = model->index(0, 0, i); if (childIndex.isValid()) { collections << collectionsFromModel(model, i); } } ++row; i = i.sibling(row, 0); } return collections; } Akonadi::Item::List CalendarSupport::itemsFromModel(const QAbstractItemModel *model, const QModelIndex &parentIndex, int start, int end) { const int endRow = end >= 0 ? end : model->rowCount(parentIndex) - 1; Akonadi::Item::List items; int row = start; QModelIndex i = model->index(row, 0, parentIndex); while (row <= endRow) { const Akonadi::Item item = itemFromIndex(i); if (CalendarSupport::hasIncidence(item)) { items << item; } else { QModelIndex childIndex = model->index(0, 0, i); if (childIndex.isValid()) { items << itemsFromModel(model, i); } } ++row; i = i.sibling(row, 0); } return items; } Akonadi::Collection CalendarSupport::collectionFromIndex(const QModelIndex &index) { return index.data(Akonadi::EntityTreeModel::CollectionRole).value(); } Akonadi::Collection::Id CalendarSupport::collectionIdFromIndex(const QModelIndex &index) { return index.data(Akonadi::EntityTreeModel::CollectionIdRole).value(); } Akonadi::Collection::List CalendarSupport::collectionsFromIndexes(const QModelIndexList &indexes) { Akonadi::Collection::List l; l.reserve(indexes.count()); for (const QModelIndex &idx : indexes) { l.push_back(collectionFromIndex(idx)); } return l; } QString CalendarSupport::displayName(Akonadi::ETMCalendar *calendar, const Akonadi::Collection &c) { Akonadi::Collection fullCollection; if (calendar && calendar->collection(c.id()).isValid()) { fullCollection = calendar->collection(c.id()); } else { fullCollection = c; } QString cName = fullCollection.name(); const QString resourceName = fullCollection.resource(); // Kolab Groupware if (resourceName.contains(QStringLiteral("kolab"))) { QString typeStr = cName; // contents type: "Calendar", "Tasks", etc QString ownerStr; // folder owner: "fred", "ethel", etc QString nameStr; // folder name: "Public", "Test", etc if (calendar) { Akonadi::Collection p = c.parentCollection(); while (p != Akonadi::Collection::root()) { Akonadi::Collection tCol = calendar->collection(p.id()); const QString tName = tCol.name(); if (tName.startsWith(QLatin1String("shared.cal"), Qt::CaseInsensitive)) { ownerStr = QStringLiteral("Shared"); nameStr = cName; typeStr = i18n("Calendar"); break; } else if (tName.startsWith(QLatin1String("shared.tasks"), Qt::CaseInsensitive) || tName.startsWith(QLatin1String("shared.todo"), Qt::CaseInsensitive)) { ownerStr = QStringLiteral("Shared"); nameStr = cName; typeStr = i18n("Tasks"); break; } else if (tName.startsWith(QLatin1String("shared.journal"), Qt::CaseInsensitive)) { ownerStr = QStringLiteral("Shared"); nameStr = cName; typeStr = i18n("Journal"); break; } else if (tName.startsWith(QLatin1String("shared.notes"), Qt::CaseInsensitive)) { ownerStr = QStringLiteral("Shared"); nameStr = cName; typeStr = i18n("Notes"); break; } else if (tName != i18n("Calendar") && tName != i18n("Tasks") && tName != i18n("Journal") && tName != i18n("Notes")) { ownerStr = tName; break; } else { nameStr = typeStr; typeStr = tName; } p = p.parentCollection(); } } if (!ownerStr.isEmpty()) { if (!ownerStr.compare(QLatin1String("INBOX"), Qt::CaseInsensitive)) { return i18nc("%1 is folder contents", "My Kolab %1", typeStr); } else if (!ownerStr.compare(QLatin1String("SHARED"), Qt::CaseInsensitive) || !ownerStr.compare(QLatin1String("CALENDAR"), Qt::CaseInsensitive) || !ownerStr.compare(QLatin1String("RESOURCES"), Qt::CaseInsensitive)) { return i18nc("%1 is folder name, %2 is folder contents", "Shared Kolab %1 %2", nameStr, typeStr); } else { if (nameStr.isEmpty()) { return i18nc("%1 is folder owner name, %2 is folder contents", "%1's Kolab %2", ownerStr, typeStr); } else { return i18nc( "%1 is folder owner name, %2 is folder name, %3 is folder contents", "%1's %2 Kolab %3", ownerStr, nameStr, typeStr); } } } else { return i18nc("%1 is folder contents", "Kolab %1", typeStr); } } //end kolab section // Dav Groupware if (resourceName.contains(QStringLiteral("davgroupware"))) { const QString resourceDisplayName = Akonadi::AgentManager::self()->instance(resourceName).name(); return i18nc("%1 is the folder name", "%1 in %2", fullCollection.displayName(), resourceDisplayName); } //end caldav section // Google if (resourceName.contains(QStringLiteral("google"))) { QString ownerStr; // folder owner: "user@gmail.com" if (calendar) { Akonadi::Collection p = c.parentCollection(); ownerStr = calendar->collection(p.id()).displayName(); } const QString nameStr = c.displayName(); // folder name: can be anything QString typeStr; const QString mimeStr = c.contentMimeTypes().join(QLatin1Char(',')); if (mimeStr.contains(QStringLiteral(".event"))) { typeStr = i18n("Calendar"); } else if (mimeStr.contains(QStringLiteral(".todo"))) { typeStr = i18n("Tasks"); } else if (mimeStr.contains(QStringLiteral(".journal"))) { typeStr = i18n("Journal"); } else if (mimeStr.contains(QStringLiteral(".note"))) { typeStr = i18n("Notes"); } else { typeStr = mimeStr; } if (!ownerStr.isEmpty()) { const int atChar = ownerStr.lastIndexOf(QLatin1Char('@')); if (atChar >= 0) { ownerStr.truncate(atChar); } if (nameStr.isEmpty()) { return i18nc("%1 is folder owner name, %2 is folder contents", "%1's Google %2", ownerStr, typeStr); } else { return i18nc("%1 is folder owner name, %2 is folder name", "%1's %2", ownerStr, nameStr); } } else { return i18nc("%1 is folder contents", "Google %1", typeStr); } } //end google section // Not groupware so the collection is "mine" const QString dName = fullCollection.displayName(); if (!dName.isEmpty()) { return fullCollection.name().startsWith(QLatin1String("akonadi_")) ? i18n("My %1", dName) : dName; } else if (!fullCollection.name().isEmpty()) { return fullCollection.name(); } else { return i18nc("unknown resource", "Unknown"); } } QString CalendarSupport::toolTipString(const Akonadi::Collection &coll, bool richText) { Q_UNUSED(richText); QString str = QStringLiteral(""); // Display Name QString displayName; if (coll.hasAttribute()) { displayName = coll.attribute()->displayName(); } if (displayName.isEmpty()) { displayName = coll.name(); } str += QLatin1String("") + displayName + QLatin1String(""); str += QLatin1String("
"); // Calendar Type QString calendarType; if (!coll.isVirtual()) { const Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance(coll.resource()); calendarType = instance.type().name(); } else { calendarType = i18nc("unknown calendar type", "unknown"); } str += QLatin1String("") + i18n("Calendar type:") + QLatin1String(""); str += QLatin1String(" ") + calendarType; // Read only? bool isReadOnly = !(coll.rights() & Akonadi::Collection::CanChangeItem); str += QLatin1String("
"); str += QLatin1String("") + i18n("Rights:") + QLatin1String(""); str += QLatin1String(" "); if (isReadOnly) { str += i18nc("the calendar is read-only", "read-only"); } else { str += i18nc("the calendar is read and write", "read+write"); } str += QLatin1String("
"); str += QLatin1String("
"); return str; } -QString CalendarSupport::subMimeTypeForIncidence(const KCalCore::Incidence::Ptr &incidence) +QString CalendarSupport::subMimeTypeForIncidence(const KCalendarCore::Incidence::Ptr &incidence) { return incidence->mimeType(); } QList CalendarSupport::workDays(const QDate &startDate, const QDate &endDate) { QList result; const int mask(~(KCalPrefs::instance()->mWorkWeekMask)); const int numDays = startDate.daysTo(endDate) + 1; for (int i = 0; i < numDays; ++i) { const QDate date = startDate.addDays(i); if (!(mask & (1 << (date.dayOfWeek() - 1)))) { result.append(date); } } if (KCalPrefs::instance()->mExcludeHolidays) { const QStringList holidays = KCalPrefs::instance()->mHolidays; for (const QString ®ionStr : holidays) { KHolidays::HolidayRegion region(regionStr); if (region.isValid()) { const KHolidays::Holiday::List list = region.holidays(startDate, endDate); const int listCount(list.count()); for (int i = 0; i < listCount; ++i) { const Holiday &h = list.at(i); if (h.dayType() == Holiday::NonWorkday) { result.removeAll(h.observedStartDate()); } } } } } return result; } QStringList CalendarSupport::holiday(const QDate &date) { QStringList hdays; bool showCountryCode = (KCalPrefs::instance()->mHolidays.count() > 1); const QStringList holidays = KCalPrefs::instance()->mHolidays; for (const QString ®ionStr : holidays) { KHolidays::HolidayRegion region(regionStr); if (region.isValid()) { const Holiday::List list = region.holidays(date); const int listCount = list.count(); for (int i = 0; i < listCount; ++i) { // don't add duplicates. // TODO: won't find duplicates in different languages however. const QString name = list.at(i).name(); if (showCountryCode) { // If more than one holiday region, append the country code to the holiday // display name to help the user identify which region it belongs to. const QRegularExpression holidaySE( i18nc("search pattern for holidayname", "^%1", name)); if (hdays.filter(holidaySE).isEmpty()) { const QString pholiday = i18n("%1 (%2)", name, region.countryCode()); hdays.append(pholiday); } else { // More than 1 region has the same holiday => remove the country code // i.e don't show "Holiday (US)" and "Holiday(FR)"; just show "Holiday". const QRegularExpression holidayRE( i18nc("replace pattern for holidayname (countrycode)", "^%1 \\(.*\\)", name)); hdays.replaceInStrings(holidayRE, name); hdays.removeDuplicates(); } } else { if (!hdays.contains(name)) { hdays.append(name); } } } } } return hdays; } -QStringList CalendarSupport::categories(const KCalCore::Incidence::List &incidences) +QStringList CalendarSupport::categories(const KCalendarCore::Incidence::List &incidences) { QStringList cats, thisCats; // @TODO: For now just iterate over all incidences. In the future, // the list of categories should be built when reading the file. - for (const KCalCore::Incidence::Ptr &incidence : incidences) { + for (const KCalendarCore::Incidence::Ptr &incidence : incidences) { thisCats = incidence->categories(); const QStringList::ConstIterator send(thisCats.constEnd()); for (QStringList::ConstIterator si = thisCats.constBegin(); si != send; ++si) { if (!cats.contains(*si)) { cats.append(*si); } } } return cats; } bool CalendarSupport::mergeCalendar(const QString &srcFilename, - const KCalCore::Calendar::Ptr &destCalendar) + const KCalendarCore::Calendar::Ptr &destCalendar) { if (srcFilename.isEmpty()) { qCCritical(CALENDARSUPPORT_LOG) << "Empty filename."; return false; } if (!QFile::exists(srcFilename)) { qCCritical(CALENDARSUPPORT_LOG) << "File'" << srcFilename << "' doesn't exist."; } // merge in a file destCalendar->startBatchAdding(); - KCalCore::FileStorage storage(destCalendar); + KCalendarCore::FileStorage storage(destCalendar); storage.setFileName(srcFilename); bool loadedSuccesfully = storage.load(); destCalendar->endBatchAdding(); return loadedSuccesfully; } diff --git a/src/utils.h b/src/utils.h index 77e463a..ac7337d 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,256 +1,256 @@ /* Copyright (c) 2009, 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com Author: Frank Osterfeld Author: Andras Mantia 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 CALENDARSUPPORT_UTILS_H #define CALENDARSUPPORT_UTILS_H #include "calendarsupport_export.h" #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include -namespace KCalCore { +namespace KCalendarCore { class CalFilter; } namespace Akonadi { class ETMCalendar; } class QAbstractItemModel; class QDrag; class QMimeData; typedef QList QModelIndexList; namespace CalendarSupport { class Calendar; /** * returns the incidence from an akonadi item, or a null pointer if the item has no such payload */ -CALENDARSUPPORT_EXPORT KCalCore::Incidence::Ptr incidence(const Akonadi::Item &item); +CALENDARSUPPORT_EXPORT KCalendarCore::Incidence::Ptr incidence(const Akonadi::Item &item); /** * returns the event from an akonadi item, or a null pointer if the item has no such payload */ -CALENDARSUPPORT_EXPORT KCalCore::Event::Ptr event(const Akonadi::Item &item); +CALENDARSUPPORT_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item); /** * returns the event from an incidence, or a null pointer if the item has no such payload */ -CALENDARSUPPORT_EXPORT KCalCore::Event::Ptr event(const KCalCore::Incidence::Ptr &incidence); +CALENDARSUPPORT_EXPORT KCalendarCore::Event::Ptr event(const KCalendarCore::Incidence::Ptr &incidence); /** * returns incidence pointers from an akonadi item. */ -CALENDARSUPPORT_EXPORT KCalCore::Incidence::List incidencesFromItems( +CALENDARSUPPORT_EXPORT KCalendarCore::Incidence::List incidencesFromItems( const Akonadi::Item::List &items); /** * returns the todo from an akonadi item, or a null pointer if the item has no such payload */ -CALENDARSUPPORT_EXPORT KCalCore::Todo::Ptr todo(const Akonadi::Item &item); +CALENDARSUPPORT_EXPORT KCalendarCore::Todo::Ptr todo(const Akonadi::Item &item); /** * returns the todo from an incidence, or a null pointer if the item has no such payload */ -CALENDARSUPPORT_EXPORT KCalCore::Todo::Ptr todo(const KCalCore::Incidence::Ptr &incidence); +CALENDARSUPPORT_EXPORT KCalendarCore::Todo::Ptr todo(const KCalendarCore::Incidence::Ptr &incidence); /** * returns the journal from an akonadi item, or a null pointer if the item has no such payload */ -CALENDARSUPPORT_EXPORT KCalCore::Journal::Ptr journal(const Akonadi::Item &item); +CALENDARSUPPORT_EXPORT KCalendarCore::Journal::Ptr journal(const Akonadi::Item &item); /** * returns the journal from an incidence, or a null pointer if the item has no such payload */ -CALENDARSUPPORT_EXPORT KCalCore::Journal::Ptr journal(const KCalCore::Incidence::Ptr &incidence); +CALENDARSUPPORT_EXPORT KCalendarCore::Journal::Ptr journal(const KCalendarCore::Incidence::Ptr &incidence); /** * returns whether an Akonadi item contains an incidence */ CALENDARSUPPORT_EXPORT bool hasIncidence(const Akonadi::Item &item); /** * returns whether an Akonadi item contains an event */ CALENDARSUPPORT_EXPORT bool hasEvent(const Akonadi::Item &item); /** * returns whether an incidence contains an event */ -CALENDARSUPPORT_EXPORT bool hasEvent(const KCalCore::Incidence::Ptr &incidence); +CALENDARSUPPORT_EXPORT bool hasEvent(const KCalendarCore::Incidence::Ptr &incidence); /** * returns whether an Akonadi item contains a todo */ CALENDARSUPPORT_EXPORT bool hasTodo(const Akonadi::Item &item); /** * returns whether an incidence contains a todo */ -CALENDARSUPPORT_EXPORT bool hasTodo(const KCalCore::Incidence::Ptr &incidence); +CALENDARSUPPORT_EXPORT bool hasTodo(const KCalendarCore::Incidence::Ptr &incidence); /** * returns whether an Akonadi item contains a journal */ CALENDARSUPPORT_EXPORT bool hasJournal(const Akonadi::Item &item); /** * returns whether an incidence contains a journal */ -CALENDARSUPPORT_EXPORT bool hasJournal(const KCalCore::Incidence::Ptr &incidence); +CALENDARSUPPORT_EXPORT bool hasJournal(const KCalendarCore::Incidence::Ptr &incidence); /** * returns @p true if the URL represents an Akonadi item and has one of the given mimetypes. */ bool isValidIncidenceItemUrl(const QUrl &url, const QStringList &supportedMimeTypes); bool isValidIncidenceItemUrl(const QUrl &url); /** * returns @p true if the mime data object contains any of the following: * * - an Akonadi item with a supported KCal mimetype * - an iCalendar * - a VCard */ CALENDARSUPPORT_EXPORT bool canDecode(const QMimeData *mimeData); CALENDARSUPPORT_EXPORT QList incidenceItemUrls(const QMimeData *mimeData); CALENDARSUPPORT_EXPORT QList todoItemUrls(const QMimeData *mimeData); CALENDARSUPPORT_EXPORT bool mimeDataHasIncidence(const QMimeData *mimeData); -CALENDARSUPPORT_EXPORT KCalCore::Todo::List todos(const QMimeData *mimeData); +CALENDARSUPPORT_EXPORT KCalendarCore::Todo::List todos(const QMimeData *mimeData); -CALENDARSUPPORT_EXPORT KCalCore::Incidence::List incidences(const QMimeData *mimeData); +CALENDARSUPPORT_EXPORT KCalendarCore::Incidence::List incidences(const QMimeData *mimeData); /** * creates mime data object for dragging an akonadi item containing an incidence */ CALENDARSUPPORT_EXPORT QMimeData *createMimeData(const Akonadi::Item &item); /** * creates mime data object for dragging akonadi items containing an incidence */ CALENDARSUPPORT_EXPORT QMimeData *createMimeData(const Akonadi::Item::List &items); #ifndef QT_NO_DRAGANDDROP /** * creates a drag object for dragging an akonadi item containing an incidence */ CALENDARSUPPORT_EXPORT QDrag *createDrag(const Akonadi::Item &item, QWidget *parent); /** * creates a drag object for dragging akonadi items containing an incidence */ CALENDARSUPPORT_EXPORT QDrag *createDrag(const Akonadi::Item::List &items, QWidget *parent); #endif /** Applies a filter to a list of items containing incidences. Items not containing incidences or not matching the filter are removed. - Helper method anologous to KCalCore::CalFilter::apply() - @see KCalCore::CalFilter::apply() + Helper method anologous to KCalendarCore::CalFilter::apply() + @see KCalendarCore::CalFilter::apply() @param items the list of items to filter @param filter the filter to apply to the list of items @return the filtered list of items */ CALENDARSUPPORT_EXPORT Akonadi::Item::List applyCalFilter(const Akonadi::Item::List &items, - const KCalCore::CalFilter *filter); + const KCalendarCore::CalFilter *filter); /** Shows a modal dialog that allows to select a collection. @param will contain the dialogCode, QDialog::Accepted if the user pressed Ok, QDialog::Rejected otherwise @param parent The optional parent of the modal dialog. @return The select collection or an invalid collection if there was no collection selected. */ CALENDARSUPPORT_EXPORT Akonadi::Collection selectCollection( QWidget *parent, int &dialogCode, const QStringList &mimeTypes, const Akonadi::Collection &defaultCollection = Akonadi::Collection()); CALENDARSUPPORT_EXPORT Akonadi::Item itemFromIndex(const QModelIndex &index); CALENDARSUPPORT_EXPORT Akonadi::Item::List itemsFromModel( const QAbstractItemModel *model, const QModelIndex &parentIndex = QModelIndex(), int start = 0, int end = -1); CALENDARSUPPORT_EXPORT Akonadi::Collection::List collectionsFromModel( const QAbstractItemModel *model, const QModelIndex &parentIndex = QModelIndex(), int start = 0, int end = -1); CALENDARSUPPORT_EXPORT Akonadi::Collection collectionFromIndex(const QModelIndex &index); CALENDARSUPPORT_EXPORT Akonadi::Collection::Id collectionIdFromIndex(const QModelIndex &index); CALENDARSUPPORT_EXPORT Akonadi::Collection::List collectionsFromIndexes( const QModelIndexList &indexes); CALENDARSUPPORT_EXPORT QString displayName(Akonadi::ETMCalendar *calendar, const Akonadi::Collection &coll); CALENDARSUPPORT_EXPORT QString subMimeTypeForIncidence( - const KCalCore::Incidence::Ptr &incidence); + const KCalendarCore::Incidence::Ptr &incidence); /** * Returns a list containing work days between @p start and @end. */ CALENDARSUPPORT_EXPORT QList workDays(const QDate &start, const QDate &end); /** * Creates a nicely formatted toolTip string for a calendar, containing some quick, * useful information to the user. * * @param coll is the Akonadi collection representing the calendar. * @param richText switches off richText (on by default) [CURRENTLY UNIMPLEMENTED] * * @return a QString containing the calendar info suitable for a toolTip. * @since 5.9 */ CALENDARSUPPORT_EXPORT QString toolTipString(const Akonadi::Collection &coll, bool richText=true); /** * Returns a list of holidays that occur at @param date. */ CALENDARSUPPORT_EXPORT QStringList holiday(const QDate &date); -CALENDARSUPPORT_EXPORT QStringList categories(const KCalCore::Incidence::List &incidences); +CALENDARSUPPORT_EXPORT QStringList categories(const KCalendarCore::Incidence::List &incidences); CALENDARSUPPORT_EXPORT bool mergeCalendar(const QString &srcFilename, - const KCalCore::Calendar::Ptr &destCalendar); + const KCalendarCore::Calendar::Ptr &destCalendar); } #endif