diff --git a/CMakeLists.txt b/CMakeLists.txt index 1066998..ea03a5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,103 +1,105 @@ cmake_minimum_required(VERSION 3.5) set(PIM_VERSION "5.12.40") set(KGAPI_LIB_VERSION ${PIM_VERSION}) project(kgapi VERSION ${KGAPI_LIB_VERSION}) +set(CMAKE_CXX_STANDARD 14) + # ECM setup set(KF5_MIN_VERSION "5.62.0") find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(GenerateExportHeader) include(ECMGenerateHeaders) include(ECMGeneratePriFile) include(ECMPoQmTools) include(ECMSetupVersion) include(FeatureSummary) set(KCALENDARCORE_LIB_VERSION "5.12.40") set(KCONTACTS_LIB_VERSION "5.12.40") ecm_setup_version(PROJECT VARIABLE_PREFIX KGAPI VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kgapi_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KPimGAPIConfigVersion.cmake" SOVERSION 5 ) ############## Find Packages ############## set(QT_REQUIRED_VERSION "5.11.0") find_package(Qt5 ${QT_REQUIRED_VERSION} REQUIRED COMPONENTS Core Network Widgets WebEngineWidgets Xml ) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS KIO WindowSystem Wallet ) find_package(KF5CalendarCore ${KCALENDARCORE_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Contacts ${KCONTACTS_LIB_VERSION} CONFIG REQUIRED) find_package(Sasl2) set_package_properties(Sasl2 PROPERTIES TYPE REQUIRED) if (EXISTS "${CMAKE_SOURCE_DIR}/.git") add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) endif() ############## Targets ############## add_subdirectory(src) if (KGAPI_BUILD_EXAMPLES) add_subdirectory(examples) endif() if (BUILD_TESTING) add_subdirectory(autotests) endif() ############## CMake Config Files ############## set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KPimGAPI") set(KGAPI_KF5_COMPAT FALSE) configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KPimGAPIConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KPimGAPIConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KPimGAPIConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KPimGAPIConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(EXPORT KPimGAPITargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KPimGAPITargets.cmake NAMESPACE KPim:: ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kgapi_version.h" DESTINATION "${KDE_INSTALL_INCLUDEDIR}/KPim" COMPONENT Devel ) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/calendar/calendar.cpp b/src/calendar/calendar.cpp index ad0ae4d..92d5c6c 100644 --- a/src/calendar/calendar.cpp +++ b/src/calendar/calendar.cpp @@ -1,224 +1,203 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "calendar.h" #include "reminder.h" #include "../debug.h" using namespace KGAPI2; class Q_DECL_HIDDEN Calendar::Private { public: - Private(); - Private(const Private &other); - ~Private() {} + Private() = default; + Private(const Private &other) = default; QString uid; QString title; QString details; QString timezone; QString location; bool editable = false; QColor backgroundColor; QColor foregroundColor; RemindersList reminders; }; -Calendar::Private::Private() -{ -} - -Calendar::Private::Private(const Private &other) : - uid(other.uid), - title(other.title), - details(other.details), - timezone(other.timezone), - location(other.location), - editable(other.editable), - backgroundColor(other.backgroundColor), - foregroundColor(other.foregroundColor), - reminders(other.reminders) -{ -} - Calendar::Calendar() : Object(), d(new Private) { } Calendar::Calendar(const Calendar &other) : Object(other), - d(new Private(*(other.d))) + d(new Private(*(other.d.get()))) { } -Calendar::~Calendar() -{ - delete d; -} +Calendar::~Calendar() = default; bool Calendar::operator==(const Calendar &other) const { if (d->uid != other.d->uid) { qCDebug(KGAPIDebug) << "UIDs don't match"; return false; } if (d->title != other.d->title) { qCDebug(KGAPIDebug) << "Titles don't match"; return false; } if (d->details != other.d->details) { qCDebug(KGAPIDebug) << "Details don't match"; return false; } if (d->timezone != other.d->timezone) { qCDebug(KGAPIDebug) << "Timezones don't match"; return false; } if (d->location != other.d->location) { qCDebug(KGAPIDebug) << "Locations don't match"; return false; } if (d->editable != other.d->editable) { qCDebug(KGAPIDebug) << "Editable doesn't match"; return false; } if (d->backgroundColor != other.d->backgroundColor) { qCDebug(KGAPIDebug) << "BackgroundColors don't match"; return false; } if (d->foregroundColor != other.d->foregroundColor) { qCDebug(KGAPIDebug) << "ForegroundColors don't match"; return false; } for (const auto &reminder : qAsConst(d->reminders)) { if (std::find_if(other.d->reminders.cbegin(), other.d->reminders.cend(), [reminder](const ReminderPtr &otherReminder) { return *reminder == *otherReminder; }) == other.d->reminders.cend()) { qCDebug(KGAPIDebug) << "Reminders don't match"; return false; } } return true; } void Calendar::setUid(const QString &uid) { d->uid = uid; } QString Calendar::uid() const { return d->uid; } QString Calendar::title() const { return d->title; } void Calendar::setTitle(const QString &title) { d->title = title; } QString Calendar::details() const { return d->details; } void Calendar::setDetails(const QString &details) { d->details = details; } QString Calendar::location() const { return d->location; } void Calendar::setLocation(const QString &location) { d->location = location; } QString Calendar::timezone() const { return d->timezone; } void Calendar::setTimezone(const QString &timezone) { d->timezone = timezone; } bool Calendar::editable() const { return d->editable; } void Calendar::setEditable(const bool editable) { d->editable = editable; } void Calendar::setDefaultReminders(const RemindersList &reminders) { d->reminders = reminders; } void Calendar::addDefaultReminer(const ReminderPtr &reminder) { d->reminders.append(reminder); } RemindersList Calendar::defaultReminders() const { return d->reminders; } QColor Calendar::backgroundColor() const { return d->backgroundColor; } void Calendar::setBackgroundColor(const QColor &color) { d->backgroundColor = color; } QColor Calendar::foregroundColor() const { return d->foregroundColor; } void Calendar::setForegroundColor(const QColor &color) { d->foregroundColor = color; } diff --git a/src/calendar/calendar.h b/src/calendar/calendar.h index 9e499ba..2e16545 100644 --- a/src/calendar/calendar.h +++ b/src/calendar/calendar.h @@ -1,193 +1,194 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_CALENDAR_H #define LIBKGAPI2_CALENDAR_H #include "object.h" #include "types.h" #include "kgapicalendar_export.h" #include +#include namespace KGAPI2 { /** * @brief An object that represents a Google calendar. * * @author Daniel Vrátil * @since 0.1 */ class KGAPICALENDAR_EXPORT Calendar: public KGAPI2::Object { public: /** * @brief Constructor */ explicit Calendar(); /** * @brief Copy constructor */ Calendar(const Calendar &other); /** * @brief Destructor */ ~Calendar() override; bool operator==(const Calendar &other) const; /** * @brief Returns uID of the calendar. */ QString uid() const; /** * @brief Sets UID of the calendar. * * @param uid */ void setUid(const QString &uid); /** * @brief Returns calendar title (name). */ QString title() const; /** * @brief Sets a calendar title (name). * * @param title */ void setTitle(const QString &title); /** * @brief Returns detailed description of the calendar. */ QString details() const; /** * @brief Sets detailed description of a calendar. * * @param details */ void setDetails(const QString &details); /** * @brief Returns geographic location of the calendar. */ QString location() const; /** * @brief Sets geographic location of the calendar. * * @param location */ void setLocation(const QString &location); /** * @brief Returns timezone of the calendar. */ QString timezone() const; /** * @brief Sets timezone of the calendar. * * @param timezone */ void setTimezone(const QString &timezone); /** * @brief Returns whether calendar is editable or read-only. */ bool editable() const; /** * @brief Sets calendar to read-only or editable. * * @param editable */ void setEditable(const bool editable); /** * @brief Sets default reminders for all new events in the calendar. * * @param reminders */ void setDefaultReminders(const RemindersList &reminders); /** * @brief Adds a default reminder for all events in the calendar. * * @param reminder */ void addDefaultReminer(const ReminderPtr &reminder); /** * @brief Returns default reminders for all events in the calendar. */ RemindersList defaultReminders() const; /** * @brief Returns calendar background color. * * @since 2.1 */ QColor backgroundColor() const; /** * @brief Sets calendar background color. * * @param color * * @since 2.1 */ void setBackgroundColor(const QColor &color); /** * @brief Returns calendar foreground color. * * @since 2.1 */ QColor foregroundColor() const; /** * @brief Sets calendar foreground color * * @param color * * @since 2.1 */ void setForegroundColor(const QColor &color); protected: class Private; - Private * const d; + QScopedPointer const d; }; } // namespace KGAPI2 #endif // LIBKGAPI2_CALENDAR_H diff --git a/src/calendar/calendarcreatejob.cpp b/src/calendar/calendarcreatejob.cpp index 7ab4f25..9a08f64 100644 --- a/src/calendar/calendarcreatejob.cpp +++ b/src/calendar/calendarcreatejob.cpp @@ -1,107 +1,94 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "calendarcreatejob.h" #include "calendarservice.h" #include "object.h" #include "account.h" #include "calendar.h" #include "../debug.h" #include "utils.h" #include "private/queuehelper_p.h" #include #include using namespace KGAPI2; class Q_DECL_HIDDEN CalendarCreateJob::Private { public: QueueHelper calendars; }; CalendarCreateJob::CalendarCreateJob(const CalendarPtr& calendar, const AccountPtr& account, QObject* parent): CreateJob(account, parent), d(new Private) { d->calendars << calendar; } CalendarCreateJob::CalendarCreateJob(const CalendarsList& calendars, const AccountPtr& account, QObject* parent): CreateJob(account, parent), d(new Private) { d->calendars = calendars; } -CalendarCreateJob::~CalendarCreateJob() -{ - delete d; -} +CalendarCreateJob::~CalendarCreateJob() = default; void CalendarCreateJob::start() { if (d->calendars.atEnd()) { emitFinished(); return; } - CalendarPtr calendar = d->calendars.current(); - const QUrl url = CalendarService::createCalendarUrl(); - QNetworkRequest request(url); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); - + const CalendarPtr calendar = d->calendars.current(); + const auto request = CalendarService::prepareRequest(CalendarService::createCalendarUrl()); const QByteArray rawData = CalendarService::calendarToJSON(calendar); - QStringList headers; - const auto rawHeaderList = request.rawHeaderList(); - headers.reserve(rawHeaderList.size()); - for (const QByteArray &str : qAsConst(rawHeaderList)) { - headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); - } - enqueueRequest(request, rawData, QStringLiteral("application/json")); } ObjectsList CalendarCreateJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); ObjectsList items; if (ct != KGAPI2::JSON) { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } items << CalendarService::JSONToCalendar(rawData).dynamicCast(); d->calendars.currentProcessed(); start(); return items; } diff --git a/src/calendar/calendarcreatejob.h b/src/calendar/calendarcreatejob.h index 76a20d7..fa16dfe 100644 --- a/src/calendar/calendarcreatejob.h +++ b/src/calendar/calendarcreatejob.h @@ -1,96 +1,98 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_CALENDARCREATEJOB_H #define LIBKGAPI2_CALENDARCREATEJOB_H #include "createjob.h" #include "kgapicalendar_export.h" +#include + namespace KGAPI2 { /** * @brief A job to create one or more new calendars in user's Google Calendar * account * * @author Daniel Vrátil * @since 2.0 */ class KGAPICALENDAR_EXPORT CalendarCreateJob : public KGAPI2::CreateJob { Q_OBJECT public: /** - * @brief Constructs a job that will create given @p calendar in user's + * @brief Constructs a job that will create given @p calendar in user's * Google Calendar account * * @param calendar Calendar to create * @param account Account to authenticate the request * @param parent */ explicit CalendarCreateJob(const CalendarPtr &calendar, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Constructs a job that will create given @p calendars in user's * Google Calendar account * * @param calendars Calendars to create * @param account Account to authenticate the request * @param parent */ explicit CalendarCreateJob(const CalendarsList &calendars, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Destructor */ ~CalendarCreateJob() override; protected: /** * @brief KGAPI2::Job::start implementation */ void start() override; /** * @brief KGAPI2::CreateJob::handleReplyWithItems implementation * * @param reply * @param rawData */ ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } // namespace KGAPI2 #endif // LIBKGAPI2_CALENDARCREATEJOB_H diff --git a/src/calendar/calendardeletejob.cpp b/src/calendar/calendardeletejob.cpp index 2450969..98c1dc9 100644 --- a/src/calendar/calendardeletejob.cpp +++ b/src/calendar/calendardeletejob.cpp @@ -1,106 +1,94 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "calendardeletejob.h" #include "calendarservice.h" #include "account.h" #include "calendar.h" #include "../debug.h" #include "private/queuehelper_p.h" #include using namespace KGAPI2; class Q_DECL_HIDDEN CalendarDeleteJob::Private { public: QueueHelper calendarsIds; }; CalendarDeleteJob::CalendarDeleteJob(const CalendarPtr& calendar, const AccountPtr& account, QObject* parent): DeleteJob(account, parent), d(new Private) { d->calendarsIds << calendar->uid(); } CalendarDeleteJob::CalendarDeleteJob(const CalendarsList& calendars, const AccountPtr& account, QObject* parent): DeleteJob(account, parent), d(new Private) { for (const CalendarPtr &calendar : calendars) { d->calendarsIds << calendar->uid(); } } CalendarDeleteJob::CalendarDeleteJob(const QString &calendarId, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private) { d->calendarsIds << calendarId; } CalendarDeleteJob::CalendarDeleteJob(const QStringList &calendarsIds, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private) { d->calendarsIds = calendarsIds; } -CalendarDeleteJob::~CalendarDeleteJob() -{ - delete d; -} +CalendarDeleteJob::~CalendarDeleteJob() = default; void CalendarDeleteJob::start() { if (d->calendarsIds.atEnd()) { emitFinished(); return; } const QString calendarId = d->calendarsIds.current(); - const QUrl url = CalendarService::removeCalendarUrl(calendarId); - QNetworkRequest request(url); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); - - QStringList headers; - const auto rawHeaderList = request.rawHeaderList(); - headers.reserve(rawHeaderList.size()); - for (const QByteArray &str : qAsConst(rawHeaderList)) { - headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); - } + const auto request = CalendarService::prepareRequest(CalendarService::removeCalendarUrl(calendarId)); enqueueRequest(request); } void CalendarDeleteJob::handleReply(const QNetworkReply* reply, const QByteArray& rawData) { d->calendarsIds.currentProcessed(); KGAPI2::DeleteJob::handleReply(reply, rawData); } diff --git a/src/calendar/calendardeletejob.h b/src/calendar/calendardeletejob.h index c46e266..d0c25ec 100644 --- a/src/calendar/calendardeletejob.h +++ b/src/calendar/calendardeletejob.h @@ -1,118 +1,120 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_CALENDARDELETEJOB_H #define LIBKGAPI2_CALENDARDELETEJOB_H #include "deletejob.h" #include "kgapicalendar_export.h" +#include + namespace KGAPI2 { /** * @brief A job to delete one or more calendars from user's Google Calendar * account. * * Note that all events in these calendars will be removed too. All operations * are irreversible. * * @author Daniel Vrátil * @since 2.0 */ class KGAPICALENDAR_EXPORT CalendarDeleteJob : public KGAPI2::DeleteJob { Q_OBJECT public: /** * @brief Constructs a new job that will delete given @p calendar from user's * Google Calendar account * * @param calendar Calendar to delete * @param account Account to authenticate the request * @param parent */ explicit CalendarDeleteJob(const CalendarPtr &calendar, const AccountPtr &account, QObject* parent); /** * @brief Constructs a new job that will delete given @p calendars from user's * Google Calendar account * * @param calendars Calendars to delete * @param account Account to authenticate the request * @param parent */ explicit CalendarDeleteJob(const CalendarsList &calendars, const AccountPtr &account, QObject* parent); /** * @brief Constructs a new job that will delete calendar with given * @p calendarId from user's Google Calendar account * * @param calendarId ID of calendar to delete * @param account Account to authenticate the request * @param parent */ explicit CalendarDeleteJob(const QString &calendarId, const AccountPtr &account, QObject *parent); /** * @brief Constructs a new job that will delete calendars with given * @p calendarsIds from user's Google Calendar account * * @param calendarsIds IDs of calendar to delete * @param account Account to authenticate the request * @param parent */ explicit CalendarDeleteJob(const QStringList &calendarsIds, const AccountPtr &account, QObject *parent); /** * @brief Destructor */ ~CalendarDeleteJob() override; protected: /** * @brief KGAPI2::Job::start implementation */ void start() override; /** * @brief KGAPI2::Job::handleReply implementation * * @param reply * @param rawData */ void handleReply(const QNetworkReply* reply, const QByteArray& rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } // namespace KGAPI2 #endif // LIBKGAPI2_CALENDARDELETEJOB_H diff --git a/src/calendar/calendarfetchjob.cpp b/src/calendar/calendarfetchjob.cpp index 6f2ef7d..4842eb6 100644 --- a/src/calendar/calendarfetchjob.cpp +++ b/src/calendar/calendarfetchjob.cpp @@ -1,129 +1,99 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "calendarfetchjob.h" #include "calendarservice.h" #include "account.h" #include "calendar.h" #include "../debug.h" #include "utils.h" #include #include using namespace KGAPI2; class Q_DECL_HIDDEN CalendarFetchJob::Private { - public: - Private(CalendarFetchJob *parent); - - QNetworkRequest createRequest(const QUrl &url); - +public: QString calendarId; - - private: - CalendarFetchJob * const q; }; -CalendarFetchJob::Private::Private(CalendarFetchJob* parent): - q(parent) -{ -} - -QNetworkRequest CalendarFetchJob::Private::createRequest(const QUrl& url) -{ - QNetworkRequest request(url); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); - - QStringList headers; - const auto rawHeaderList = request.rawHeaderList(); - headers.reserve(rawHeaderList.size()); - for (const QByteArray &str : qAsConst(rawHeaderList)) { - headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); - } - - return request; -} - CalendarFetchJob::CalendarFetchJob(const AccountPtr& account, QObject* parent): FetchJob(account, parent), - d(new Private(this)) + d(new Private()) { } CalendarFetchJob::CalendarFetchJob(const QString& calendarId, const AccountPtr& account, QObject* parent): FetchJob(account, parent), - d(new Private(this)) + d(new Private()) { d->calendarId = calendarId; } -CalendarFetchJob::~CalendarFetchJob() -{ - delete d; -} +CalendarFetchJob::~CalendarFetchJob() = default; void CalendarFetchJob::start() { QUrl url; if (d->calendarId.isEmpty()) { url = CalendarService::fetchCalendarsUrl(); } else { url = CalendarService::fetchCalendarUrl(d->calendarId); } - const QNetworkRequest request = d->createRequest(url); + const auto request = CalendarService::prepareRequest(url); enqueueRequest(request); } ObjectsList CalendarFetchJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) { FeedData feedData; feedData.requestUrl = reply->request().url(); ObjectsList items; const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); if (ct == KGAPI2::JSON) { if (d->calendarId.isEmpty()) { items = CalendarService::parseCalendarJSONFeed(rawData, feedData); } else { items << CalendarService::JSONToCalendar(rawData); } } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } if (feedData.nextPageUrl.isValid()) { - const QNetworkRequest request = d->createRequest(feedData.nextPageUrl); + const auto request = CalendarService::prepareRequest(feedData.nextPageUrl); enqueueRequest(request); } return items; } diff --git a/src/calendar/calendarfetchjob.h b/src/calendar/calendarfetchjob.h index d76e4f7..7f5aab0 100644 --- a/src/calendar/calendarfetchjob.h +++ b/src/calendar/calendarfetchjob.h @@ -1,93 +1,95 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_CALENDARFETCHJOB_H #define LIBKGAPI2_CALENDARFETCHJOB_H #include "fetchjob.h" #include "kgapicalendar_export.h" +#include + namespace KGAPI2 { /** * @brief A job to fetch calendars from user's Google Calendar account. * * @author Daniel Vrátil * @since 2.0 */ class KGAPICALENDAR_EXPORT CalendarFetchJob : public KGAPI2::FetchJob { Q_OBJECT public: /** * @brief Constructs a job that will fetch all calendars from user's * Google Calendar account * * @param account Account to authenticate the request * @param parent */ explicit CalendarFetchJob(const AccountPtr &account, QObject* parent = nullptr); /** * @brief Constructs a job that will fetch a single calendar with given * @p calendarId from user's Google Calendar account * * @param calendarId ID of calendar to fetch * @param account Account to authenticate the request * @param parent */ explicit CalendarFetchJob(const QString &calendarId, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Destructor */ ~CalendarFetchJob() override; protected: /** * @brief KGAPI2::Job::start implementation */ void start() override; /** * @brief KGAPI2::FetchJob::handleReplyWithItems implementation * * @param reply * @param rawData */ ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } // namespace KGAPI2 #endif // LIBKGAPI2_CALENDARFETCHJOB_H diff --git a/src/calendar/calendarmodifyjob.cpp b/src/calendar/calendarmodifyjob.cpp index 0e77a08..8a7badb 100644 --- a/src/calendar/calendarmodifyjob.cpp +++ b/src/calendar/calendarmodifyjob.cpp @@ -1,107 +1,93 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "calendarmodifyjob.h" #include "calendarservice.h" #include "account.h" #include "calendar.h" #include "../debug.h" #include "utils.h" #include "private/queuehelper_p.h" #include #include using namespace KGAPI2; class Q_DECL_HIDDEN CalendarModifyJob::Private { public: QueueHelper calendars; }; CalendarModifyJob::CalendarModifyJob(const CalendarPtr& calendar, const AccountPtr& account, QObject* parent): ModifyJob(account, parent), d(new Private) { d->calendars << calendar; } CalendarModifyJob::CalendarModifyJob(const CalendarsList& calendars, const AccountPtr& account, QObject* parent): ModifyJob(account, parent), d(new Private) { d->calendars = calendars; } -CalendarModifyJob::~CalendarModifyJob() -{ - delete d; -} +CalendarModifyJob::~CalendarModifyJob() = default; void CalendarModifyJob::start() { if (d->calendars.atEnd()) { emitFinished(); return; } const CalendarPtr calendar = d->calendars.current(); - - const QUrl url = CalendarService::updateCalendarUrl(calendar->uid()); - QNetworkRequest request(url); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); - + const auto request = CalendarService::prepareRequest(CalendarService::updateCalendarUrl(calendar->uid())); const QByteArray rawData = CalendarService::calendarToJSON(calendar); - QStringList headers; - const auto rawHeaderList = request.rawHeaderList(); - headers.reserve(rawHeaderList.size()); - for (const QByteArray &str : qAsConst(rawHeaderList)) { - headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); - } - enqueueRequest(request, rawData, QStringLiteral("application/json")); } ObjectsList CalendarModifyJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); ObjectsList items; if (ct != KGAPI2::JSON) { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } items << CalendarService::JSONToCalendar(rawData).dynamicCast(); d->calendars.currentProcessed(); // Enqueue next item or finish start(); return items; } diff --git a/src/calendar/calendarmodifyjob.h b/src/calendar/calendarmodifyjob.h index e45440c..49f3156 100644 --- a/src/calendar/calendarmodifyjob.h +++ b/src/calendar/calendarmodifyjob.h @@ -1,94 +1,96 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_CALENDARMODIFYJOB_H #define LIBKGAPI2_CALENDARMODIFYJOB_H #include "modifyjob.h" #include "kgapicalendar_export.h" +#include + namespace KGAPI2 { /** * @brief A job to modify calendars on user's Google Calendar account. * * @author Daniel Vrátil * @since 2.0 */ class KGAPICALENDAR_EXPORT CalendarModifyJob : public KGAPI2::ModifyJob { Q_OBJECT public: /** * @brief Constructs a job that will write changes in given @p calendar to * corresponding calendar on user's Google Calendar account * * @param calendar Calendar to modify * @param account Account to authenticate the request * @param parent */ explicit CalendarModifyJob(const CalendarPtr &calendar, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Constructs a job that will write changes in given @p calendars to * corresponding calendars on user's Google Calendar account * * @param calendars Calendars to modify * @param account Account to authenticate requests * @param parent */ explicit CalendarModifyJob(const CalendarsList &calendars, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Destructor */ ~CalendarModifyJob() override; protected: /** * @brief KGAPI2::Job::start implementation */ void start() override; /** * @brief KGAPI2::ModifyJob::handleReplyWithItems implementation * * @param reply * @param rawData */ ObjectsList handleReplyWithItems(const QNetworkReply *reply, - const QByteArray& rawData) override; + const QByteArray& rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } // namespace KGAPI2 #endif // LIBKGAPI2_CALENDARMODIFYJOB_H diff --git a/src/calendar/calendarservice.cpp b/src/calendar/calendarservice.cpp index 23e762e..cfb9423 100644 --- a/src/calendar/calendarservice.cpp +++ b/src/calendar/calendarservice.cpp @@ -1,1117 +1,1148 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "calendarservice.h" #include "calendar.h" #include "event.h" #include "reminder.h" #include "utils.h" #include "../debug.h" #include #include #include #include #include #include #include #include #include #include #include #include +#include + +#include +#include namespace KGAPI2 { namespace CalendarService { namespace Private { KCalendarCore::DateList parseRDate(const QString &rule); ObjectPtr JSONToCalendar(const QVariantMap &data); ObjectPtr JSONToEvent(const QVariantMap &data, const QString &timezone = QString()); /** - * Checks whether TZID is in Olson format and converts it to it if neccessary - * - * This is mainly to handle crazy Microsoft TZIDs like - * "(GMT) Greenwich Mean Time/Dublin/Edinburgh/London", because Google only - * accepts TZIDs in Olson format ("Europe/London"). - * - * It first tries to match the given \p tzid to all TZIDs in KTimeZones::zones(). - * If it fails, it parses the \p event, looking for X-MICROSOFT-CDO-TZID - * property and than matches it to Olson-formatted TZID using a table. - * - * When the method fails to process the TZID, it returns the original \p tzid - * in hope, that Google will cope with it. - */ + * Checks whether TZID is in Olson format and converts it to it if neccessary + * + * This is mainly to handle crazy Microsoft TZIDs like + * "(GMT) Greenwich Mean Time/Dublin/Edinburgh/London", because Google only + * accepts TZIDs in Olson format ("Europe/London"). + * + * It first tries to match the given \p tzid to all TZIDs in KTimeZones::zones(). + * If it fails, it parses the \p event, looking for X-MICROSOFT-CDO-TZID + * property and than matches it to Olson-formatted TZID using a table. + * + * When the method fails to process the TZID, it returns the original \p tzid + * in hope, that Google will cope with it. + */ QString checkAndConverCDOTZID(const QString &tzid, const EventPtr& event); static const QUrl GoogleApisUrl(QStringLiteral("https://www.googleapis.com")); static const QString CalendarListBasePath(QStringLiteral("/calendar/v3/users/me/calendarList")); static const QString CalendarBasePath(QStringLiteral("/calendar/v3/calendars")); } +QNetworkRequest prepareRequest(const QUrl &url) +{ + QNetworkRequest request(url); + request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); + + return request; +} + /************* URLS **************/ QUrl fetchCalendarsUrl() { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarListBasePath); return url; } QUrl fetchCalendarUrl(const QString& calendarID) { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarListBasePath % QLatin1Char('/') % calendarID); return url; } QUrl updateCalendarUrl(const QString &calendarID) { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarBasePath % QLatin1Char('/') % calendarID); return url; } QUrl createCalendarUrl() { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarBasePath); return url; } QUrl removeCalendarUrl(const QString& calendarID) { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarBasePath % QLatin1Char('/') % calendarID); return url; } QUrl fetchEventsUrl(const QString& calendarID) { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarBasePath % QLatin1Char('/') % calendarID % QLatin1String("/events")); return url; } QUrl fetchEventUrl(const QString& calendarID, const QString& eventID) { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarBasePath % QLatin1Char('/') % calendarID % QLatin1String("/events/") % eventID); return url; } namespace { QString sendUpdatesPolicyToString(SendUpdatesPolicy policy) { switch (policy) { case SendUpdatesPolicy::All: return QStringLiteral("all"); case SendUpdatesPolicy::ExternalOnly: return QStringLiteral("externalOnly"); case SendUpdatesPolicy::None: return QStringLiteral("none"); } Q_UNREACHABLE(); } +static const QString sendUpatesQueryParam = QStringLiteral("sendUpdates"); +static const QString destinationQueryParam = QStringLiteral("destination"); } QUrl updateEventUrl(const QString& calendarID, const QString& eventID, SendUpdatesPolicy updatePolicy) { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarBasePath % QLatin1Char('/') % calendarID % QLatin1String("/events/") % eventID); QUrlQuery query(url); - query.addQueryItem(QStringLiteral("sendUpdates"), sendUpdatesPolicyToString(updatePolicy)); + query.addQueryItem(sendUpatesQueryParam, sendUpdatesPolicyToString(updatePolicy)); url.setQuery(query); return url; } QUrl createEventUrl(const QString& calendarID, SendUpdatesPolicy updatePolicy) { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarBasePath % QLatin1Char('/') % calendarID % QLatin1String("/events")); QUrlQuery query(url); - query.addQueryItem(QStringLiteral("sendUpdates"), sendUpdatesPolicyToString(updatePolicy)); + query.addQueryItem(sendUpatesQueryParam, sendUpdatesPolicyToString(updatePolicy)); url.setQuery(query); return url; } QUrl removeEventUrl(const QString& calendarID, const QString& eventID) { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarBasePath % QLatin1Char('/') % calendarID % QLatin1String("/events/") % eventID); return url; } QUrl moveEventUrl(const QString& sourceCalendar, const QString& destCalendar, const QString& eventID) { QUrl url(Private::GoogleApisUrl); url.setPath(Private::CalendarBasePath % QLatin1Char('/') % sourceCalendar % QLatin1String("/events/") % eventID); QUrlQuery query(url); - query.addQueryItem(QStringLiteral("destination"), destCalendar); + query.addQueryItem(destinationQueryParam, destCalendar); url.setQuery(query); return url; } QUrl freeBusyQueryUrl() { QUrl url(Private::GoogleApisUrl); url.setPath(QStringLiteral("/calendar/v3/freeBusy")); return url; } +namespace { + +static const auto kindParam = QStringLiteral("kind"); +static const auto idParam = QStringLiteral("id"); +static const auto etagParam = QStringLiteral("etag"); + +static const auto nextPageTokenParam = QStringLiteral("nextPageToken"); +static const auto pageTokenParam = QStringLiteral("pageToken"); +static const auto itemsParam = QStringLiteral("items"); + +static const auto calendarSummaryParam = QStringLiteral("summary"); +static const auto calendarDescriptionParam = QStringLiteral("description"); +static const auto calendarLocationParam = QStringLiteral("location"); +static const auto calendarTimezoneParam = QStringLiteral("timeZone"); +static const auto calendarBackgroundColorParam = QStringLiteral("backgroundColor"); +static const auto calendarForegroundColorParam = QStringLiteral("foregroundColor"); +static const auto calendarAccessRoleParam = QStringLiteral("accessRole"); +static const auto calendarDefaultRemindersParam = QStringLiteral("defaultReminders"); +static const auto reminderMethodParam = QStringLiteral("method"); +static const auto reminderMinutesParam = QStringLiteral("minutes"); + +static const auto eventiCalUIDParam = QStringLiteral("iCalUID"); +static const auto eventStatusParam = QStringLiteral("status"); +static const auto eventCreatedParam = QStringLiteral("created"); +static const auto eventUpdatedParam = QStringLiteral("updated"); +static const auto eventSummaryParam = QStringLiteral("summary"); +static const auto eventDescriptionParam = QStringLiteral("description"); +static const auto eventLocationParam = QStringLiteral("location"); +static const auto eventStartPram = QStringLiteral("start"); +static const auto eventEndParam = QStringLiteral("end"); +static const auto eventOriginalStartTimeParam = QStringLiteral("originalStartTime"); +static const auto eventTransparencyParam = QStringLiteral("transparency"); +static const auto eventOrganizerParam = QStringLiteral("organizer"); +static const auto eventAttendeesParam = QStringLiteral("attendees"); +static const auto eventRecurrenceParam = QStringLiteral("recurrence"); +static const auto eventRemindersParam = QStringLiteral("reminders"); +static const auto eventExtendedPropertiesParam = QStringLiteral("extendedProperties"); +static const auto eventRecurringEventIdParam = QStringLiteral("recurringEventId"); + +static const auto attendeeDisplayNameParam = QStringLiteral("displayName"); +static const auto attendeeEmailParam = QStringLiteral("email"); +static const auto attendeeResponseStatusParam = QStringLiteral("responseStatus"); +static const auto attendeeOptionalParam = QStringLiteral("optional"); + +static const auto organizerDisplayNameParam = QStringLiteral("displayName"); +static const auto organizerEmailParam = QStringLiteral("email"); + +static const auto reminderUseDefaultParam = QStringLiteral("useDefault"); +static const auto reminderOverridesParam = QStringLiteral("overrides"); + +static const auto propertyPrivateParam = QStringLiteral("private"); +static const auto propertySharedParam = QStringLiteral("shared"); + +static const auto dateParam = QStringLiteral("date"); +static const auto dateTimeParam = QStringLiteral("dateTime"); +static const auto timeZoneParam = QStringLiteral("timeZone"); + + +static const auto calendarListKind = QLatin1String("calendar#calendarList"); +static const auto calendarListEntryKind = QLatin1String("calendar#calendarListEntry"); +static const auto calendarKind = QLatin1String("calendar#calendar"); +static const auto eventKind = QLatin1String("calendar#event"); +static const auto eventsKind = QLatin1String("calendar#events"); + +static const auto writerAccessRole = QLatin1String("writer"); +static const auto ownerAccessRole = QLatin1String("owner"); +static const auto emailMethod = QLatin1String("email"); +static const auto popupMethod = QLatin1String("popup"); + +static const auto confirmedStatus = QLatin1String("confirmed"); +static const auto canceledStatus = QLatin1String("cancalled"); +static const auto tentativeStatus = QLatin1String("tentative"); +static const auto acceptedStatus = QLatin1String("accepted"); +static const auto needsActionStatus = QLatin1String("needsAction"); +static const auto transparentTransparency = QLatin1String("transparent"); +static const auto opaqueTransparency = QLatin1String("opaque"); +static const auto declinedStatus = QLatin1String("declined"); +static const auto categoriesProperty = QLatin1String("categories"); + +} + QString APIVersion() { return QStringLiteral("3"); } CalendarPtr JSONToCalendar(const QByteArray& jsonData) { - QJsonDocument document = QJsonDocument::fromJson(jsonData); - QVariantMap calendar = document.toVariant().toMap(); + const auto document = QJsonDocument::fromJson(jsonData); + const auto calendar = document.toVariant().toMap(); - if ((calendar.value(QStringLiteral("kind")) != QLatin1String("calendar#calendarListEntry")) && - (calendar.value(QStringLiteral("kind")) != QLatin1String("calendar#calendar"))) { + if (calendar.value(kindParam).toString() != calendarListEntryKind && calendar.value(kindParam).toString() != calendarKind) { return CalendarPtr(); } return Private::JSONToCalendar(calendar).staticCast(); } ObjectPtr Private::JSONToCalendar(const QVariantMap& data) { - CalendarPtr calendar(new Calendar); + auto calendar = CalendarPtr::create(); - QString id = QUrl::fromPercentEncoding(data.value(QStringLiteral("id")).toByteArray()); + const auto id = QUrl::fromPercentEncoding(data.value(idParam).toByteArray()); calendar->setUid(id); - calendar->setEtag(data.value(QStringLiteral("etag")).toString()); - calendar->setTitle(data.value(QStringLiteral("summary")).toString()); - calendar->setDetails(data.value(QStringLiteral("description")).toString()); - calendar->setLocation(data.value(QStringLiteral("location")).toString()); - calendar->setTimezone(data.value(QStringLiteral("timeZone")).toString()); - calendar->setBackgroundColor(QColor(data.value(QStringLiteral("backgroundColor")).toString())); - calendar->setForegroundColor(QColor(data.value(QStringLiteral("foregroundColor")).toString())); - - if ((data.value(QStringLiteral("accessRole")).toString() == QLatin1String("writer")) || - (data.value(QStringLiteral("accessRole")).toString() == QLatin1String("owner"))) { + calendar->setEtag(data.value(etagParam).toString()); + calendar->setTitle(data.value(calendarSummaryParam).toString()); + calendar->setDetails(data.value(calendarDescriptionParam).toString()); + calendar->setLocation(data.value(calendarLocationParam).toString()); + calendar->setTimezone(data.value(calendarTimezoneParam).toString()); + calendar->setBackgroundColor(QColor(data.value(calendarBackgroundColorParam).toString())); + calendar->setForegroundColor(QColor(data.value(calendarForegroundColorParam).toString())); + + if ((data.value(calendarAccessRoleParam).toString() == writerAccessRole) || + (data.value(calendarAccessRoleParam).toString() == ownerAccessRole)) { calendar->setEditable(true); } else { calendar->setEditable(false); } - const QVariantList reminders = data.value(QStringLiteral("defaultReminders")).toList(); - for (const QVariant &r : reminders) { - QVariantMap reminder = r.toMap(); + const auto reminders = data.value(calendarDefaultRemindersParam).toList(); + for (const auto &r : reminders) { + const auto reminder = r.toMap(); - ReminderPtr rem(new Reminder()); - if (reminder.value(QStringLiteral("method")).toString() == QLatin1String("email")) { + auto rem = ReminderPtr::create(); + if (reminder.value(reminderMethodParam).toString() == emailMethod) { rem->setType(KCalendarCore::Alarm::Email); - } else if (reminder.value(QStringLiteral("method")).toString() == QLatin1String("popup")) { + } else if (reminder.value(reminderMethodParam).toString() == popupMethod) { rem->setType(KCalendarCore::Alarm::Display); } else { rem->setType(KCalendarCore::Alarm::Invalid); } - rem->setStartOffset(KCalendarCore::Duration(reminder.value(QStringLiteral("minutes")).toInt() * (-60))); + rem->setStartOffset(KCalendarCore::Duration(reminder.value(reminderMinutesParam).toInt() * (-60))); calendar->addDefaultReminer(rem); } return calendar.dynamicCast(); } QByteArray calendarToJSON(const CalendarPtr& calendar) { QVariantMap output, entry; if (!calendar->uid().isEmpty()) { - entry.insert(QStringLiteral("id"), calendar->uid()); + entry.insert(idParam, calendar->uid()); } - entry.insert(QStringLiteral("summary"), calendar->title()); - entry.insert(QStringLiteral("description"), calendar->details()); - entry.insert(QStringLiteral("location"), calendar->location()); + entry.insert(calendarSummaryParam, calendar->title()); + entry.insert(calendarDescriptionParam, calendar->details()); + entry.insert(calendarLocationParam, calendar->location()); if (!calendar->timezone().isEmpty()) { - entry.insert(QStringLiteral("timeZone"), calendar->timezone()); + entry.insert(calendarTimezoneParam, calendar->timezone()); } - QJsonDocument document = QJsonDocument::fromVariant(entry); + const auto document = QJsonDocument::fromVariant(entry); return document.toJson(QJsonDocument::Compact); } + ObjectsList parseCalendarJSONFeed(const QByteArray& jsonFeed, FeedData& feedData) { - QJsonDocument document = QJsonDocument::fromJson(jsonFeed); - QVariantMap data = document.toVariant().toMap(); + const auto document = QJsonDocument::fromJson(jsonFeed); + const auto data = document.toVariant().toMap(); ObjectsList list; - if (data.value(QStringLiteral("kind")) == QLatin1String("calendar#calendarList")) { - if (data.contains(QLatin1String("nextPageToken"))) { + if (data.value(kindParam).toString() == calendarListKind) { + if (data.contains(nextPageTokenParam)) { feedData.nextPageUrl = fetchCalendarsUrl(); QUrlQuery query(feedData.nextPageUrl); - query.addQueryItem(QStringLiteral("pageToken"), data.value(QStringLiteral("nextPageToken")).toString()); + query.addQueryItem(pageTokenParam, data.value(nextPageTokenParam).toString()); feedData.nextPageUrl.setQuery(query); } } else { - return ObjectsList(); + return {}; } - const QVariantList items = data.value(QStringLiteral("items")).toList(); + const auto items = data.value(itemsParam).toList(); list.reserve(items.size()); - for (const QVariant &i : items) { - list.append(Private::JSONToCalendar(i.toMap())); + for (const auto &i : items) { + list.push_back(Private::JSONToCalendar(i.toMap())); } return list; } EventPtr JSONToEvent(const QByteArray& jsonData) { QJsonParseError error; QJsonDocument document = QJsonDocument::fromJson(jsonData, &error); if (error.error != QJsonParseError::NoError) { qCWarning(KGAPIDebug) << "Error parsing event JSON: " << error.errorString(); } QVariantMap data = document.toVariant().toMap(); - if (data.value(QStringLiteral("kind")) != QLatin1String("calendar#event")) { + if (data.value(kindParam).toString() != eventKind) { return EventPtr(); } return Private::JSONToEvent(data).staticCast(); } namespace { struct ParsedDt { QDateTime dt; bool isAllDay; }; ParsedDt parseDt(const QVariantMap &data, const QString &timezone, bool isDtEnd) { - if (data.contains(QLatin1String("date"))) { - auto dt = QDateTime::fromString(data.value(QStringLiteral("date")).toString(), Qt::ISODate); + if (data.contains(dateParam)) { + auto dt = QDateTime::fromString(data.value(dateParam).toString(), Qt::ISODate); if (isDtEnd) { // Google reports all-day events to end on the next day, e.g. a // Monday all-day event will be reporting as starting on Monday and // ending on Tuesday, while KCalendarCore/iCal uses the same day for // dtEnd, so adjust the end date here. dt = dt.addDays(-1); } return {dt, true}; - } else if (data.contains(QLatin1String("dateTime"))) { - auto dt = Utils::rfc3339DateFromString(data.value(QStringLiteral("dateTime")).toString()); + } else if (data.contains(dateTimeParam)) { + auto dt = Utils::rfc3339DateFromString(data.value(dateTimeParam).toString()); // If there's a timezone specified in the "start" entity, then use it - if (data.contains(QLatin1String("timeZone"))) { - const QTimeZone tz = QTimeZone(data.value(QStringLiteral("timeZone")).toString().toUtf8()); + if (data.contains(timeZoneParam)) { + const QTimeZone tz = QTimeZone(data.value(timeZoneParam).toString().toUtf8()); if (tz.isValid()) { dt = dt.toTimeZone(tz); } else { - qCWarning(KGAPIDebug) << "Invalid timezone" << data.value(QStringLiteral("timeZone")).toString(); + qCWarning(KGAPIDebug) << "Invalid timezone" << data.value(timeZoneParam).toString(); } // Otherwise try to fallback to calendar-wide timezone } else if (!timezone.isEmpty()) { const QTimeZone tz(timezone.toUtf8()); if (tz.isValid()) { dt.setTimeZone(tz); } else { qCWarning(KGAPIDebug) << "Invalid timezone" << timezone; } } return {dt, false}; } else { return {{}, false}; } } +void setEventCategories(EventPtr &event, const QVariantMap &properties) +{ + for (auto iter = properties.cbegin(), end = properties.cend(); iter != end; ++iter) { + if (iter.key() == categoriesProperty) { + event->setCategories(iter.value().toString()); + } + } } +} // namespace + ObjectPtr Private::JSONToEvent(const QVariantMap& data, const QString &timezone) { - EventPtr event(new Event); + auto event = EventPtr::create(); - /* ID */ - event->setId(data.value(QStringLiteral("id")).toString()); + event->setId(data.value(idParam).toString()); + event->setUid(data.value(eventiCalUIDParam).toString()); + event->setEtag(data.value(etagParam).toString()); - /* UID */ - event->setUid(data.value(QStringLiteral("iCalUID")).toString()); - - /* ETAG */ - event->setEtag(data.value(QStringLiteral("etag")).toString()); - - /* Status */ - if (data.value(QStringLiteral("status")).toString() == QLatin1String("confirmed")) { + if (data.value(eventStatusParam).toString() == confirmedStatus) { event->setStatus(KCalendarCore::Incidence::StatusConfirmed); - } else if (data.value(QStringLiteral("status")).toString() == QLatin1String("cancelled")) { + } else if (data.value(eventStatusParam).toString() == canceledStatus) { event->setStatus(KCalendarCore::Incidence::StatusCanceled); event->setDeleted(true); - } else if (data.value(QStringLiteral("status")).toString() == QLatin1String("tentative")) { + } else if (data.value(eventStatusParam).toString() == tentativeStatus) { event->setStatus(KCalendarCore::Incidence::StatusTentative); } else { event->setStatus(KCalendarCore::Incidence::StatusNone); } - /* Created */ - event->setCreated(Utils::rfc3339DateFromString(data.value(QStringLiteral("created")).toString())); - - /* Last updated */ - event->setLastModified(Utils::rfc3339DateFromString(data.value(QStringLiteral("updated")).toString())); - - /* Summary */ - event->setSummary(data.value(QStringLiteral("summary")).toString()); + event->setCreated(Utils::rfc3339DateFromString(data.value(eventCreatedParam).toString())); + event->setLastModified(Utils::rfc3339DateFromString(data.value(eventUpdatedParam).toString())); + event->setSummary(data.value(eventSummaryParam).toString()); + event->setDescription(data.value(eventDescriptionParam).toString()); + event->setLocation(data.value(eventLocationParam).toString()); - /* Description */ - event->setDescription(data.value(QStringLiteral("description")).toString()); - - /* Location */ - event->setLocation(data.value(QStringLiteral("location")).toString()); - - /* Start date */ - const auto dtStart = parseDt(data.value(QStringLiteral("start")).toMap(), timezone, false); + const auto dtStart = parseDt(data.value(eventStartPram).toMap(), timezone, false); event->setDtStart(dtStart.dt); event->setAllDay(dtStart.isAllDay); - /* End date */ - const auto dtEnd = parseDt(data.value(QStringLiteral("end")).toMap(), timezone, true); + const auto dtEnd = parseDt(data.value(eventEndParam).toMap(), timezone, true); event->setDtEnd(dtEnd.dt); - /* Recurrence ID */ - if (data.contains(QLatin1String("originalStartTime"))) { - const auto recurrenceId = parseDt(data.value(QStringLiteral("originalStartTime")).toMap(), timezone, false); + if (data.contains(eventOriginalStartTimeParam)) { + const auto recurrenceId = parseDt(data.value(eventOriginalStartTimeParam).toMap(), timezone, false); event->setRecurrenceId(recurrenceId.dt); } - /* Transparency */ - if (data.value(QStringLiteral("transparency")).toString() == QLatin1String("transparent")) { + if (data.value(eventTransparencyParam).toString() == transparentTransparency) { event->setTransparency(Event::Transparent); } else { /* Assume opaque as default transparency */ event->setTransparency(Event::Opaque); } - /* Attendees */ - const QVariantList attendees = data.value(QStringLiteral("attendees")).toList(); - for (const QVariant & a : attendees) { - QVariantMap att = a.toMap(); + const auto attendees = data.value(eventAttendeesParam).toList(); + for (const auto &a : attendees) { + const auto att = a.toMap(); KCalendarCore::Attendee attendee( - att.value(QStringLiteral("displayName")).toString(), - att.value(QStringLiteral("email")).toString()); - - if (att.value(QStringLiteral("responseStatus")).toString() == QLatin1String("accepted")) + att.value(attendeeDisplayNameParam).toString(), + att.value(attendeeEmailParam).toString()); + const auto responseStatus = att.value(attendeeResponseStatusParam).toString(); + if (responseStatus == acceptedStatus) { attendee.setStatus(KCalendarCore::Attendee::Accepted); - else if (att.value(QStringLiteral("responseStatus")).toString() == QLatin1String("declined")) + } else if (responseStatus == declinedStatus) { attendee.setStatus(KCalendarCore::Attendee::Declined); - else if (att.value(QStringLiteral("responseStatus")).toString() == QLatin1String("tentative")) + } else if (responseStatus == tentativeStatus) { attendee.setStatus(KCalendarCore::Attendee::Tentative); - else + } else { attendee.setStatus(KCalendarCore::Attendee::NeedsAction); + } - if (att.value(QStringLiteral("optional")).toBool()) { + if (att.value(attendeeOptionalParam).toBool()) { attendee.setRole(KCalendarCore::Attendee::OptParticipant); } - const auto uid = att.value(QStringLiteral("id")).toString(); + const auto uid = att.value(idParam).toString(); if (!uid.isEmpty()) { attendee.setUid(uid); } else { // Set some UID, just so that the results are reproducible attendee.setUid(QString::number(qHash(attendee.email()))); } event->addAttendee(attendee, true); } /* According to RFC, only events with attendees can have an organizer. * Google seems to ignore it, so we must take care of it here */ if (event->attendeeCount() > 0) { KCalendarCore::Person organizer; - QVariantMap organizerData = data.value(QStringLiteral("organizer")).toMap(); - organizer.setName(organizerData.value(QStringLiteral("displayName")).toString()); - organizer.setEmail(organizerData.value(QStringLiteral("email")).toString()); + const auto organizerData = data.value(eventOrganizerParam).toMap(); + organizer.setName(organizerData.value(organizerDisplayNameParam).toString()); + organizer.setEmail(organizerData.value(organizerEmailParam).toString()); event->setOrganizer(organizer); } - /* Recurrence */ - const QStringList recrs = data.value(QStringLiteral("recurrence")).toStringList(); + const QStringList recrs = data.value(eventRecurrenceParam).toStringList(); for (const QString & rec : recrs) { KCalendarCore::ICalFormat format; - if (rec.left(5) == QLatin1String("RRULE")) { - KCalendarCore::RecurrenceRule *recurrenceRule = new KCalendarCore::RecurrenceRule(); - format.fromString(recurrenceRule, rec.mid(6)); + if (rec.leftRef(5) == QLatin1String("RRULE")) { + auto recurrenceRule = std::make_unique(); + const auto ok = format.fromString(recurrenceRule.get(), rec.mid(6)); Q_UNUSED(ok); recurrenceRule->setRRule(rec); - event->recurrence()->addRRule(recurrenceRule); - } else if (rec.left(6) == QLatin1String("EXRULE")) { - KCalendarCore::RecurrenceRule *recurrenceRule = new KCalendarCore::RecurrenceRule(); - format.fromString(recurrenceRule, rec.mid(7)); + event->recurrence()->addRRule(recurrenceRule.release()); + } else if (rec.leftRef(6) == QLatin1String("EXRULE")) { + auto recurrenceRule = std::make_unique(); + const auto ok = format.fromString(recurrenceRule.get(), rec.mid(7)); Q_UNUSED(ok); recurrenceRule->setRRule(rec); - event->recurrence()->addExRule(recurrenceRule); - } else if (rec.left(6) == QLatin1String("EXDATE")) { + event->recurrence()->addExRule(recurrenceRule.release()); + } else if (rec.leftRef(6) == QLatin1String("EXDATE")) { KCalendarCore::DateList exdates = Private::parseRDate(rec); event->recurrence()->setExDates(exdates); - } else if (rec.left(5) == QLatin1String("RDATE")) { + } else if (rec.leftRef(5) == QLatin1String("RDATE")) { KCalendarCore::DateList rdates = Private::parseRDate(rec); event->recurrence()->setRDates(rdates); } } - QVariantMap reminders = data.value(QStringLiteral("reminders")).toMap(); - if (reminders.contains(QLatin1String("useDefault")) && reminders.value(QStringLiteral("useDefault")).toBool()) { + const auto reminders = data.value(eventRemindersParam).toMap(); + if (reminders.contains(reminderUseDefaultParam) && reminders.value(reminderUseDefaultParam).toBool()) { event->setUseDefaultReminders(true); } else { event->setUseDefaultReminders(false); } - const QVariantList overrides = reminders.value(QStringLiteral("overrides")).toList(); - for (const QVariant & r : overrides) { - QVariantMap override = r.toMap(); - KCalendarCore::Alarm::Ptr alarm(new KCalendarCore::Alarm(static_cast(event.data()))); + const auto overrides = reminders.value(reminderOverridesParam).toList(); + for (const auto &r : overrides) { + const auto reminderOverride = r.toMap(); + auto alarm = KCalendarCore::Alarm::Ptr::create(static_cast(event.data())); alarm->setTime(event->dtStart()); - if (override.value(QStringLiteral("method")).toString() == QLatin1String("popup")) { + if (reminderOverride.value(reminderMethodParam).toString() == popupMethod) { alarm->setType(KCalendarCore::Alarm::Display); - } else if (override.value(QStringLiteral("method")).toString() == QLatin1String("email")) { + } else if (reminderOverride.value(reminderMethodParam).toString() == emailMethod) { alarm->setType(KCalendarCore::Alarm::Email); } else { alarm->setType(KCalendarCore::Alarm::Invalid); continue; } - alarm->setStartOffset(KCalendarCore::Duration(override.value(QStringLiteral("minutes")).toInt() * (-60))); + alarm->setStartOffset(KCalendarCore::Duration(reminderOverride.value(reminderMinutesParam).toInt() * (-60))); alarm->setEnabled(true); event->addAlarm(alarm); } - /* Extended properties */ - QVariantMap extendedProperties = data.value(QStringLiteral("extendedProperties")).toMap(); - - QVariantMap privateProperties = extendedProperties.value(QStringLiteral("private")).toMap(); - QMap< QString, QVariant >::const_iterator iter = privateProperties.constBegin(); - while (iter != privateProperties.constEnd()) { - if (iter.key() == QLatin1String("categories")) { - event->setCategories(iter.value().toString()); - } - - ++iter; - } - - QVariantMap sharedProperties = extendedProperties.value(QStringLiteral("shared")).toMap(); - iter = sharedProperties.constBegin(); - while (iter != sharedProperties.constEnd()) { - if (iter.key() == QLatin1String("categories")) { - event->setCategories(iter.value().toString()); - } - - ++iter; - } + const auto extendedProperties = data.value(eventExtendedPropertiesParam).toMap(); + setEventCategories(event, extendedProperties.value(propertyPrivateParam).toMap()); + setEventCategories(event, extendedProperties.value(propertySharedParam).toMap()); return event.dynamicCast(); } namespace { enum class SerializeDtFlag { AllDay = 1 << 0, IsDtEnd = 1 << 1, HasRecurrence = 1 << 2 }; using SerializeDtFlags = QFlags; -Q_DECLARE_OPERATORS_FOR_FLAGS(SerializeDtFlags) - QVariantMap serializeDt(const EventPtr &event, const QDateTime &dt, SerializeDtFlags flags) { QVariantMap rv; if (flags & SerializeDtFlag::AllDay) { /* For Google, all-day events starts on Monday and ends on Tuesday, * while in KDE, it both starts and ends on Monday. */ - auto adjusted = dt.addDays(flags & SerializeDtFlag::IsDtEnd ? 1 : 0); - rv.insert(QStringLiteral("date"), adjusted.toString(QStringLiteral("yyyy-MM-dd"))); + const auto adjusted = dt.addDays(flags & SerializeDtFlag::IsDtEnd ? 1 : 0); + rv.insert(dateParam, adjusted.toString(QStringLiteral("yyyy-MM-dd"))); } else { - rv.insert(QStringLiteral("dateTime"), Utils::rfc3339DateToString(dt)); + rv.insert(dateTimeParam, Utils::rfc3339DateToString(dt)); QString tzEnd = QString::fromUtf8(dt.timeZone().id()); if (flags & SerializeDtFlag::HasRecurrence && tzEnd.isEmpty()) { tzEnd = QString::fromUtf8(QTimeZone::utc().id()); } if (!tzEnd.isEmpty()) { - rv.insert(QStringLiteral("timeZone"), Private::checkAndConverCDOTZID(tzEnd, event)); + rv.insert(timeZoneParam, Private::checkAndConverCDOTZID(tzEnd, event)); } } return rv; } } // namespace QByteArray eventToJSON(const EventPtr& event, EventSerializeFlags flags) { QVariantMap data; - /* Type */ - data.insert(QStringLiteral("kind"), QStringLiteral("calendar#event")); + data.insert(kindParam, eventKind); - /* ID */ if (!(flags & EventSerializeFlag::NoID)) { - data.insert(QStringLiteral("id"), event->id()); + data.insert(idParam, event->id()); } - /* UID */ - data.insert(QStringLiteral("iCalUID"), event->uid()); + data.insert(eventiCalUIDParam, event->uid()); - /* Status */ if (event->status() == KCalendarCore::Incidence::StatusConfirmed) { - data.insert(QStringLiteral("status"), QStringLiteral("confirmed")); + data.insert(eventStatusParam, confirmedStatus); } else if (event->status() == KCalendarCore::Incidence::StatusCanceled) { - data.insert(QStringLiteral("status"), QStringLiteral("canceled")); + data.insert(eventStatusParam, canceledStatus); } else if (event->status() == KCalendarCore::Incidence::StatusTentative) { - data.insert(QStringLiteral("status"), QStringLiteral("tentative")); + data.insert(eventStatusParam, tentativeStatus); } - /* Summary */ - data.insert(QStringLiteral("summary"), event->summary()); - - /* Description */ - data.insert(QStringLiteral("description"), event->description()); + data.insert(eventSummaryParam, event->summary()); + data.insert(eventDescriptionParam, event->description()); + data.insert(eventLocationParam, event->location()); - /* Location */ - data.insert(QStringLiteral("location"), event->location()); - - /* Recurrence */ QVariantList recurrence; KCalendarCore::ICalFormat format; const auto exRules = event->recurrence()->exRules(); const auto rRules = event->recurrence()->rRules(); recurrence.reserve(rRules.size() + rRules.size() + 2); for (KCalendarCore::RecurrenceRule *rRule : rRules) { - recurrence << format.toString(rRule).remove(QStringLiteral("\r\n")); + recurrence.push_back(format.toString(rRule).remove(QStringLiteral("\r\n"))); } - for (KCalendarCore::RecurrenceRule *rRule : exRules) { - recurrence << format.toString(rRule).remove(QStringLiteral("\r\n")); + recurrence.push_back(format.toString(rRule).remove(QStringLiteral("\r\n"))); } QStringList dates; const auto rDates = event->recurrence()->rDates(); dates.reserve(rDates.size()); - for (const QDate & rDate : rDates) { - dates << rDate.toString(QStringLiteral("yyyyMMdd")); + for (const auto &rDate : rDates) { + dates.push_back(rDate.toString(QStringLiteral("yyyyMMdd"))); } if (!dates.isEmpty()) { - recurrence << QString(QStringLiteral("RDATE;VALUE=DATA:") + dates.join(QLatin1Char(','))); + recurrence.push_back(QString(QStringLiteral("RDATE;VALUE=DATA:") + dates.join(QLatin1Char(',')))); } dates.clear(); const auto exDates = event->recurrence()->exDates(); dates.reserve(exDates.size()); - for (const QDate & exDate : exDates) { - dates << exDate.toString(QStringLiteral("yyyyMMdd")); + for (const auto &exDate : exDates) { + dates.push_back(exDate.toString(QStringLiteral("yyyyMMdd"))); } if (!dates.isEmpty()) { - recurrence << QString(QStringLiteral("EXDATE;VALUE=DATE:") + dates.join(QLatin1Char(','))); + recurrence.push_back(QString(QStringLiteral("EXDATE;VALUE=DATE:") + dates.join(QLatin1Char(',')))); } if (!recurrence.isEmpty()) { - data.insert(QStringLiteral("recurrence"), recurrence); + data.insert(eventRecurrenceParam, recurrence); } SerializeDtFlags dtFlags; if (event->allDay()) { dtFlags |= SerializeDtFlag::AllDay; } if (!recurrence.isEmpty()) { dtFlags |= SerializeDtFlag::HasRecurrence; } - /* Start */ - data.insert(QStringLiteral("start"), serializeDt(event, event->dtStart(), dtFlags)); - - /* End */ - data.insert(QStringLiteral("end"), serializeDt(event, event->dtEnd(), dtFlags | SerializeDtFlag::IsDtEnd)); + data.insert(eventStartPram, serializeDt(event, event->dtStart(), dtFlags)); + data.insert(eventEndParam, serializeDt(event, event->dtEnd(), dtFlags | SerializeDtFlag::IsDtEnd)); if (event->hasRecurrenceId()) { - data.insert(QStringLiteral("originalStartTime"), serializeDt(event, event->recurrenceId(), dtFlags)); - data.insert(QStringLiteral("recurringEventId"), event->id()); + data.insert(eventOrganizerParam, serializeDt(event, event->recurrenceId(), dtFlags)); + data.insert(eventRecurringEventIdParam, event->id()); } - /* Transparency */ if (event->transparency() == Event::Transparent) { - data.insert(QStringLiteral("transparency"), QStringLiteral("transparent")); + data.insert(eventTransparencyParam, transparentTransparency); } else { - data.insert(QStringLiteral("transparency"), QStringLiteral("opaque")); + data.insert(eventTransparencyParam, opaqueTransparency); } - /* Attendees */ QVariantList atts; - Q_FOREACH(const KCalendarCore::Attendee& attee, event->attendees()) { - QVariantMap att; - - att.insert(QStringLiteral("displayName"), attee.name()); - att.insert(QStringLiteral("email"), attee.email()); + const auto attendees = event->attendees(); + for (const auto &attee : attendees) { + QVariantMap att{{attendeeDisplayNameParam, attee.name()}, + {attendeeEmailParam, attee.email()}}; if (attee.status() == KCalendarCore::Attendee::Accepted) { - att.insert(QStringLiteral("responseStatus"), QStringLiteral("accepted")); + att.insert(attendeeResponseStatusParam, acceptedStatus); } else if (attee.status() == KCalendarCore::Attendee::Declined) { - att.insert(QStringLiteral("responseStatus"), QStringLiteral("declined")); + att.insert(attendeeResponseStatusParam, declinedStatus); } else if (attee.status() == KCalendarCore::Attendee::Tentative) { - att.insert(QStringLiteral("responseStatus"), QStringLiteral("tentative")); + att.insert(attendeeResponseStatusParam, tentativeStatus); } else { - att.insert(QStringLiteral("responseStatus"), QStringLiteral("needsAction")); + att.insert(attendeeResponseStatusParam, needsActionStatus); } if (attee.role() == KCalendarCore::Attendee::OptParticipant) { - att.insert(QStringLiteral("optional"), true); + att.insert(attendeeOptionalParam, true); } if (!attee.uid().isEmpty()) { - att.insert(QStringLiteral("id"), attee.uid()); + att.insert(idParam, attee.uid()); } atts.append(att); } if (!atts.isEmpty()) { - data.insert(QStringLiteral("attendees"), atts); + data.insert(eventAttendeesParam, atts); /* According to RFC, event without attendees should not have * any organizer. */ - KCalendarCore::Person organizer = event->organizer(); + const auto organizer = event->organizer(); if (!organizer.isEmpty()) { - QVariantMap org; - org.insert(QStringLiteral("displayName"), organizer.fullName()); - org.insert(QStringLiteral("email"), organizer.email()); - data.insert(QStringLiteral("organizer"), org); + data.insert(eventOrganizerParam, + QVariantMap{{organizerDisplayNameParam, organizer.fullName()}, + {organizerEmailParam, organizer.email()}}); } } - /* Reminders */ QVariantList overrides; - Q_FOREACH(const KCalendarCore::Alarm::Ptr &alarm, event->alarms()) { - QVariantMap override; - + const auto alarms = event->alarms(); + for (const auto &alarm : alarms) { + QVariantMap reminderOverride; if (alarm->type() == KCalendarCore::Alarm::Display) { - override.insert(QStringLiteral("method"), QLatin1String("popup")); + reminderOverride.insert(reminderMethodParam, popupMethod); } else if (alarm->type() == KCalendarCore::Alarm::Email) { - override.insert(QStringLiteral("method"), QLatin1String("email")); + reminderOverride.insert(reminderMethodParam, emailMethod); } else { continue; } + reminderOverride.insert(reminderMinutesParam, (int)(alarm->startOffset().asSeconds() / -60)); - override.insert(QStringLiteral("minutes"), (int)(alarm->startOffset().asSeconds() / -60)); - - overrides << override; + overrides.push_back(reminderOverride); } - QVariantMap reminders; - reminders.insert(QStringLiteral("useDefault"), false); - reminders.insert(QStringLiteral("overrides"), overrides); - data.insert(QStringLiteral("reminders"), reminders); + data.insert(eventRemindersParam, + QVariantMap{{reminderUseDefaultParam, false}, + {reminderOverridesParam, overrides}}); - /* Store categories */ if (!event->categories().isEmpty()) { - QVariantMap extendedProperties; - QVariantMap sharedProperties; - sharedProperties.insert(QStringLiteral("categories"), event->categoriesStr()); - extendedProperties.insert(QStringLiteral("shared"), sharedProperties); - data.insert(QStringLiteral("extendedProperties"), extendedProperties); + data.insert(eventExtendedPropertiesParam, + QVariantMap{{propertySharedParam, QVariantMap{{categoriesProperty, event->categoriesStr()}}}}); } /* TODO: Implement support for additional features: * http://code.google.com/apis/gdata/docs/2.0/elements.html */ - QJsonDocument document = QJsonDocument::fromVariant(data); + const auto document = QJsonDocument::fromVariant(data); return document.toJson(QJsonDocument::Compact); } ObjectsList parseEventJSONFeed(const QByteArray& jsonFeed, FeedData& feedData) { - QJsonDocument document = QJsonDocument::fromJson(jsonFeed); - QVariantMap data = document.toVariant().toMap(); + const auto document = QJsonDocument::fromJson(jsonFeed); + const auto data = document.toVariant().toMap(); QString timezone; - if (data.value(QStringLiteral("kind")) == QLatin1String("calendar#events")) { - if (data.contains(QLatin1String("nextPageToken"))) { + if (data.value(kindParam) == eventsKind) { + if (data.contains(nextPageTokenParam)) { QString calendarId = feedData.requestUrl.toString().remove(QStringLiteral("https://www.googleapis.com/calendar/v3/calendars/")); calendarId = calendarId.left(calendarId.indexOf(QLatin1Char('/'))); feedData.nextPageUrl = feedData.requestUrl; // replace the old pageToken with a new one QUrlQuery query(feedData.nextPageUrl); - query.removeQueryItem(QStringLiteral("pageToken")); - query.addQueryItem(QStringLiteral("pageToken"), data.value(QStringLiteral("nextPageToken")).toString()); + query.removeQueryItem(pageTokenParam); + query.addQueryItem(pageTokenParam, data.value(nextPageTokenParam).toString()); feedData.nextPageUrl.setQuery(query); } - if (data.contains(QLatin1String("timeZone"))) { + if (data.contains(timeZoneParam)) { // This should always be in Olson format - timezone = data.value(QStringLiteral("timeZone")).toString(); + timezone = data.value(timeZoneParam).toString(); } } else { - return ObjectsList(); + return {}; } ObjectsList list; - const QVariantList items = data.value(QStringLiteral("items")).toList(); + const auto items = data.value(itemsParam).toList(); list.reserve(items.size()); - for (const QVariant &i : items) { - list.append(Private::JSONToEvent(i.toMap(), timezone)); + for (const auto &i : items) { + list.push_back(Private::JSONToEvent(i.toMap(), timezone)); } return list; } /******************************** PRIVATE ***************************************/ KCalendarCore::DateList Private::parseRDate(const QString& rule) { KCalendarCore::DateList list; - QString value; + QStringRef value; QTimeZone tz; - QString left = rule.left(rule.indexOf(QLatin1Char(':'))); - const QStringList params = left.split(QLatin1Char(';')); - for (const QString ¶m : params) { + const auto left = rule.leftRef(rule.indexOf(QLatin1Char(':'))); + const auto params = left.split(QLatin1Char(';')); + for (const auto ¶m : params) { if (param.startsWith(QLatin1String("VALUE"))) { value = param.mid(param.indexOf(QLatin1Char('=')) + 1); } else if (param.startsWith(QLatin1String("TZID"))) { - QString _name = param.mid(param.indexOf(QLatin1Char('=')) + 1); + auto _name = param.mid(param.indexOf(QLatin1Char('=')) + 1); tz = QTimeZone(_name.toUtf8()); } } - QString datesStr = rule.mid(rule.lastIndexOf(QLatin1Char(':')) + 1); - const QStringList dates = datesStr.split(QLatin1Char(',')); - for (const QString &date : dates) { + const auto datesStr = rule.midRef(rule.lastIndexOf(QLatin1Char(':')) + 1); + const auto dates = datesStr.split(QLatin1Char(',')); + for (const auto &date : dates) { QDate dt; if (value == QLatin1String("DATE")) { - dt = QDate::fromString(date, QStringLiteral("yyyyMMdd")); + dt = QDate::fromString(date.toString(), QStringLiteral("yyyyMMdd")); } else if (value == QLatin1String("PERIOD")) { - QString start = date.left(date.indexOf(QLatin1Char('/'))); - QDateTime kdt = Utils::rfc3339DateFromString(start); + const auto start = date.left(date.indexOf(QLatin1Char('/'))); + QDateTime kdt = Utils::rfc3339DateFromString(start.toString()); if (tz.isValid()) { kdt.setTimeZone(tz); } dt = kdt.date(); } else { - QDateTime kdt = Utils::rfc3339DateFromString(date); + QDateTime kdt = Utils::rfc3339DateFromString(date.toString()); if (tz.isValid()) { kdt.setTimeZone(tz); } dt = kdt.date(); } - list << dt; + list.push_back(dt); } return list; } +namespace { -static QMap initMSCDOTZIDTable() -{ - QMap map; - - /* Based on "Time Zone to CdoTimeZoneId Map" - * http://msdn.microsoft.com/en-us/library/aa563018%28loband%29.aspx - * - * The mapping is not exact, since the CdoTimeZoneId usually refers to a - * region of multiple countries, so I always picked one of the countries - * in the specified region and used it's TZID. - */ - map.insert(0, QStringLiteral("UTC")); - map.insert(1, QStringLiteral("Europe/London")); /* GMT Greenwich Mean Time; Dublin, Edinburgh, London */ +/* Based on "Time Zone to CdoTimeZoneId Map" + * http://msdn.microsoft.com/en-us/library/aa563018%28loband%29.aspx + * + * The mapping is not exact, since the CdoTimeZoneId usually refers to a + * region of multiple countries, so I always picked one of the countries + * in the specified region and used it's TZID. + */ +static const std::map MSCDOTZIDTable = { + {0, QLatin1String("UTC")}, + {1, QLatin1String("Europe/London")}, /* GMT Greenwich Mean Time; Dublin, Edinburgh, London */ /* Seriously? *sigh* Let's handle these two in checkAndConvertCDOTZID() */ - //map.insertMulti(2, QStringLiteral("Europe/Lisbon")); /* GMT Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London */ - //map.insertMulti(2, QStringLiteral("Europe/Sarajevo")); /* GMT+01:00 Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb */ - map.insert(3, QStringLiteral("Europe/Paris")); /* GMT+01:00 Paris, Madrid, Brussels, Copenhagen */ - map.insert(4, QStringLiteral("Europe/Berlin")); /* GMT+01:00 Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna */ - map.insert(5, QStringLiteral("Europe/Bucharest")); /* GMT+02:00 Bucharest */ - map.insert(6, QStringLiteral("Europe/Prague")); /* GMT+01:00 Prague, Central Europe */ - map.insert(7, QStringLiteral("Europe/Athens")); /* GMT+02:00 Athens, Istanbul, Minsk */ - map.insert(8, QStringLiteral("America/Brazil")); /* GMT-03:00 Brasilia */ - map.insert(9, QStringLiteral("America/Halifax")); /* GMT-04:00 Atlantic time (Canada) */ - map.insert(10, QStringLiteral("America/New_York")); /* GMT-05:00 Eastern Time (US & Canada) */ - map.insert(11, QStringLiteral("America/Chicago")); /* GMT-06:00 Central Time (US & Canada) */ - map.insert(12, QStringLiteral("America/Denver")); /* GMT-07:00 Mountain Time (US & Canada) */ - map.insert(13, QStringLiteral("America/Los_Angeles")); /* GMT-08:00 Pacific Time (US & Canada); Tijuana */ - map.insert(14, QStringLiteral("America/Anchorage")); /* GMT-09:00 Alaska */ - map.insert(15, QStringLiteral("Pacific/Honolulu")); /* GMT-10:00 Hawaii */ - map.insert(16, QStringLiteral("Pacific/Apia")); /* GMT-11:00 Midway Island, Samoa */ - map.insert(17, QStringLiteral("Pacific/Auckland")); /* GMT+12:00 Auckland, Wellington */ - map.insert(18, QStringLiteral("Australia/Brisbane")); /* GMT+10:00 Brisbane, East Australia */ - map.insert(19, QStringLiteral("Australia/Adelaide")); /* GMT+09:30 Adelaide, Central Australia */ - map.insert(20, QStringLiteral("Asia/Tokyo")); /* GMT+09:00 Osaka, Sapporo, Tokyo */ - map.insert(21, QStringLiteral("Asia/Singapore")); /* GMT+08:00 Kuala Lumpur, Singapore */ - map.insert(22, QStringLiteral("Asia/Bangkok")); /* GMT+07:00 Bangkok, Hanoi, Jakarta */ - map.insert(23, QStringLiteral("Asia/Calcutta")); /* GMT+05:30 Kolkata, Chennai, Mumbai, New Delhi, India Standard Time */ - map.insert(24, QStringLiteral("Asia/Dubai")); /* GMT+04:00 Abu Dhabi, Muscat */ - map.insert(25, QStringLiteral("Asia/Tehran")); /* GMT+03:30 Tehran */ - map.insert(26, QStringLiteral("Asia/Baghdad")); /* GMT+03:00 Baghdad */ - map.insert(27, QStringLiteral("Asia/Jerusalem")); /* GMT+02:00 Israel, Jerusalem Standard Time */ - map.insert(28, QStringLiteral("America/St_Johns")); /* GMT-03:30 Newfoundland */ - map.insert(29, QStringLiteral("Atlantic/Portugal")); /* GMT-01:00 Azores */ - map.insert(30, QStringLiteral("America/Noronha")); /* GMT-02:00 Mid-Atlantic */ - map.insert(31, QStringLiteral("Africa/Monrovia")); /* GMT Casablanca, Monrovia */ - map.insert(32, QStringLiteral("America/Argentina/Buenos_Aires")); /* GMT-03:00 Buenos Aires, Georgetown */ - map.insert(33, QStringLiteral("America/La_Paz")); /* GMT-04:00 Caracas, La Paz */ - map.insert(34, QStringLiteral("America/New_York")); /* GMT-05:00 Indiana (East) */ - map.insert(35, QStringLiteral("America/Bogota")); /* GMT-05:00 Bogota, Lima, Quito */ - map.insert(36, QStringLiteral("America/Winnipeg")); /* GMT-06:00 Saskatchewan */ - map.insert(37, QStringLiteral("America/Mexico_City")); /* GMT-06:00 Mexico City, Tegucigalpa */ - map.insert(38, QStringLiteral("America/Phoenix")); /* GMT-07:00 Arizona */ - map.insert(39, QStringLiteral("Pacific/Kwajalein")); /* GMT-12:00 Eniwetok, Kwajalein, Dateline Time */ - map.insert(40, QStringLiteral("Pacific/Fiji")); /* GMT+12:00 Fušál, Kamchatka, Mashall Is. */ - map.insert(41, QStringLiteral("Pacific/Noumea")); /* GMT+11:00 Magadan, Solomon Is., New Caledonia */ - map.insert(42, QStringLiteral("Australia/Hobart")); /* GMT+10:00 Hobart, Tasmania */ - map.insert(43, QStringLiteral("Pacific/Guam")); /* GMT+10:00 Guam, Port Moresby */ - map.insert(44, QStringLiteral("Australia/Darwin")); /* GMT+09:30 Darwin */ - map.insert(45, QStringLiteral("Asia/Shanghai")); /* GMT+08:00 Beijing, Chongqing, Hong Kong SAR, Urumqi */ - map.insert(46, QStringLiteral("Asia/Omsk")); /* GMT+06:00 Almaty, Novosibirsk, North Central Asia */ - map.insert(47, QStringLiteral("Asia/Karachi")); /* GMT+05:00 Islamabad, Karachi, Tashkent */ - map.insert(48, QStringLiteral("Asia/Kabul")); /* GMT+04:30 Kabul */ - map.insert(49, QStringLiteral("Africa/Cairo")); /* GMT+02:00 Cairo */ - map.insert(50, QStringLiteral("Africa/Harare")); /* GMT+02:00 Harare, Pretoria */ - map.insert(51, QStringLiteral("Europe/Moscow")); /* GMT+03:00 Moscow, St. Petersburg, Volgograd */ - map.insert(53, QStringLiteral("Atlantic/Cape_Verde")); /* GMT-01:00 Cape Verde Is. */ - map.insert(54, QStringLiteral("Asia/Tbilisi")); /* GMT+04:00 Baku, Tbilisi, Yerevan */ - map.insert(55, QStringLiteral("America/Tegucigalpa")); /* GMT-06:00 Central America */ - map.insert(56, QStringLiteral("Africa/Nairobi")); /* GMT+03:00 East Africa, Nairobi */ - map.insert(58, QStringLiteral("Asia/Yekaterinburg")); /* GMT+05:00 Ekaterinburg */ - map.insert(59, QStringLiteral("Europe/Helsinki")); /* GMT+02:00 Helsinki, Riga, Tallinn */ - map.insert(60, QStringLiteral("America/Greenland")); /* GMT-03:00 Greenland */ - map.insert(61, QStringLiteral("Asia/Rangoon")); /* GMT+06:30 Yangon (Rangoon) */ - map.insert(62, QStringLiteral("Asia/Katmandu")); /* GMT+05:45 Kathmandu, Nepal */ - map.insert(63, QStringLiteral("Asia/Irkutsk")); /* GMT+08:00 Irkutsk, Ulaan Bataar */ - map.insert(64, QStringLiteral("Asia/Krasnoyarsk")); /* GMT+07:00 Krasnoyarsk */ - map.insert(65, QStringLiteral("America/Santiago")); /* GMT-04:00 Santiago */ - map.insert(66, QStringLiteral("Asia/Colombo")); /* GMT+06:00 Sri Jayawardenepura, Sri Lanka */ - map.insert(67, QStringLiteral("Pacific/Tongatapu")); /* GMT+13:00 Nuku'alofa, Tonga */ - map.insert(68, QStringLiteral("Asia/Vladivostok")); /* GMT+10:00 Vladivostok */ - map.insert(69, QStringLiteral("Africa/Bangui")); /* GMT+01:00 West Central Africa */ - map.insert(70, QStringLiteral("Asia/Yakutsk")); /* GMT+09:00 Yakutsk */ - map.insert(71, QStringLiteral("Asia/Dhaka")); /* GMT+06:00 Astana, Dhaka */ - map.insert(72, QStringLiteral("Asia/Seoul")); /* GMT+09:00 Seoul, Korea Standard time */ - map.insert(73, QStringLiteral("Australia/Perth")); /* GMT+08:00 Perth, Western Australia */ - map.insert(74, QStringLiteral("Asia/Kuwait")); /* GMT+03:00 Arab, Kuwait, Riyadh */ - map.insert(75, QStringLiteral("Asia/Taipei")); /* GMT+08:00 Taipei */ - map.insert(76, QStringLiteral("Australia/Sydney")); /* GMT+10:00 Canberra, Melbourne, Sydney */ - - return map; -} - -static QMap initMSStandardTimeTZTable() -{ - QMap map; - - - /* Based on "Microsoft Time Zone Index Values" - * http://support.microsoft.com/kb/973627 - * - * The mapping is not exact, since the TZID usually refers to a - * region of multiple countries, so I always picked one of the countries - * in the specified region and used it's TZID. - * - * The Olson timezones are taken from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - */ - map.insert(QStringLiteral("Dateline Standard Time"), QStringLiteral("Pacific/Kwajalein")); /* (GMT-12:00) International Date Line West */ - map.insert(QStringLiteral("Samoa Standard Time"), QStringLiteral("Pacific/Apia")); /* (GMT-11:00) Midway Island, Samoa */ - map.insert(QStringLiteral("Hawaiian Standard Time"), QStringLiteral("Pacific/Honolulu")); /* (GMT-10:00) Hawaii */ - map.insert(QStringLiteral("Alaskan Standard Time"), QStringLiteral("America/Anchorage")); /* (GMT-09:00) Alaska */ - map.insert(QStringLiteral("Pacific Standard Time"), QStringLiteral("America/Los_Angeles")); /* (GMT-08:00) Pacific Time (US and Canada); Tijuana */ - map.insert(QStringLiteral("Mountain Standard Time"), QStringLiteral("America/Denver")); /* (GMT-07:00) Mountain Time (US and Canada) */ - map.insert(QStringLiteral("Mexico Standard Time 2"), QStringLiteral("America/Chihuahua")); /* (GMT-07:00) Chihuahua, La Paz, Mazatlan */ - map.insert(QStringLiteral("U.S. Mountain Standard Time"), QStringLiteral("America/Phoenix")); /* (GMT-07:00) Arizona */ - map.insert(QStringLiteral("Central Standard Time"), QStringLiteral("America/Chicago")); /* (GMT-06:00) Central Time (US and Canada */ - map.insert(QStringLiteral("Canada Central Standard Time"), QStringLiteral("America/Winnipeg")); /* (GMT-06:00) Saskatchewan */ - map.insert(QStringLiteral("Mexico Standard Time"), QStringLiteral("America/Mexico_City")); /* (GMT-06:00) Guadalajara, Mexico City, Monterrey */ - map.insert(QStringLiteral("Central America Standard Time"), QStringLiteral("America/Chicago")); /* (GMT-06:00) Central America */ - map.insert(QStringLiteral("Eastern Standard Time"), QStringLiteral("America/New_York")); /* (GMT-05:00) Eastern Time (US and Canada) */ - map.insert(QStringLiteral("U.S. Eastern Standard Time"), QStringLiteral("America/New_York")); /* (GMT-05:00) Indiana (East) */ - map.insert(QStringLiteral("S.A. Pacific Standard Time"), QStringLiteral("America/Bogota")); /* (GMT-05:00) Bogota, Lima, Quito */ - map.insert(QStringLiteral("Atlantic Standard Time"), QStringLiteral("America/Halifax")); /* (GMT-04:00) Atlantic Time (Canada) */ - map.insert(QStringLiteral("S.A. Western Standard Time"), QStringLiteral("America/La_Paz")); /* (GMT-04:00) Caracas, La Paz */ - map.insert(QStringLiteral("Pacific S.A. Standard Time"), QStringLiteral("America/Santiago")); /* (GMT-04:00) Santiago */ - map.insert(QStringLiteral("Newfoundland and Labrador Standard Time"), QStringLiteral("America/St_Johns")); /* (GMT-03:30) Newfoundland and Labrador */ - map.insert(QStringLiteral("E. South America Standard Time"), QStringLiteral("America/Brazil")); /* (GMT-03:00) Brasilia */ - map.insert(QStringLiteral("S.A. Eastern Standard Time"), QStringLiteral("America/Argentina/Buenos_Aires")); /* (GMT-03:00) Buenos Aires, Georgetown */ - map.insert(QStringLiteral("Greenland Standard Time"), QStringLiteral("America/Greenland")); /* (GMT-03:00) Greenland */ - map.insert(QStringLiteral("Mid-Atlantic Standard Time"), QStringLiteral("America/Noronha")); /* (GMT-02:00) Mid-Atlantic */ - map.insert(QStringLiteral("Azores Standard Time"), QStringLiteral("Atlantic/Portugal")); /* (GMT-01:00) Azores */ - map.insert(QStringLiteral("Cape Verde Standard Time"), QStringLiteral("Atlantic/Cape_Verde")); /* (GMT-01:00) Cape Verde Islands */ - map.insert(QStringLiteral("GMT Standard Time"), QStringLiteral("Europe/London")); /* (GMT) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London */ - map.insert(QStringLiteral("Greenwich Standard Time"), QStringLiteral("Africa/Casablanca")); /* (GMT) Casablanca, Monrovia */ - map.insert(QStringLiteral("Central Europe Standard Time"), QStringLiteral("Europe/Prague")); /* (GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague */ - map.insert(QStringLiteral("Central European Standard Time"), QStringLiteral("Europe/Sarajevo")); /* (GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb */ - map.insert(QStringLiteral("Romance Standard Time"), QStringLiteral("Europe/Brussels")); /* (GMT+01:00) Brussels, Copenhagen, Madrid, Paris */ - map.insert(QStringLiteral("W. Europe Standard Time"), QStringLiteral("Europe/Amsterdam")); /* (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna */ - map.insert(QStringLiteral("W. Central Africa Standard Time"), QStringLiteral("Africa/Bangui")); /* (GMT+01:00) West Central Africa */ - map.insert(QStringLiteral("E. Europe Standard Time"), QStringLiteral("Europe/Bucharest")); /* (GMT+02:00) Bucharest */ - map.insert(QStringLiteral("Egypt Standard Time"), QStringLiteral("Africa/Cairo")); /* (GMT+02:00) Cairo */ - map.insert(QStringLiteral("FLE Standard Time"), QStringLiteral("Europe/Helsinki")); /* (GMT+02:00) Helsinki, Kiev, Riga, Sofia, Tallinn, Vilnius */ - map.insert(QStringLiteral("GTB Standard Time"), QStringLiteral("Europe/Athens")); /* (GMT+02:00) Athens, Istanbul, Minsk */ - map.insert(QStringLiteral("Israel Standard Time"), QStringLiteral("Europe/Athens")); /* (GMT+02:00) Jerusalem */ - map.insert(QStringLiteral("South Africa Standard Time"), QStringLiteral("Africa/Harare")); /* (GMT+02:00) Harare, Pretoria */ - map.insert(QStringLiteral("Russian Standard Time"), QStringLiteral("Europe/Moscow")); /* (GMT+03:00) Moscow, St. Petersburg, Volgograd */ - map.insert(QStringLiteral("Arab Standard Time"), QStringLiteral("Asia/Kuwait")); /* (GMT+03:00) Kuwait, Riyadh */ - map.insert(QStringLiteral("E. Africa Standard Time"), QStringLiteral("Africa/Nairobi")); /* (GMT+03:00) Nairobi */ - map.insert(QStringLiteral("Arabic Standard Time"), QStringLiteral("Asia/Baghdad")); /* (GMT+03:00) Baghdad */ - map.insert(QStringLiteral("Iran Standard Time"), QStringLiteral("Asia/Tehran")); /* (GMT+03:30) Tehran */ - map.insert(QStringLiteral("Arabian Standard Time"), QStringLiteral("Asia/Dubai")); /* (GMT+04:00) Abu Dhabi, Muscat */ - map.insert(QStringLiteral("Caucasus Standard Time"), QStringLiteral("Asia/Tbilisi")); /* (GMT+04:00) Baku, Tbilisi, Yerevan */ - map.insert(QStringLiteral("Transitional Islamic State of Afghanistan Standard Time"), QStringLiteral("Asia/Kabul")); /* (GMT+04:30) Kabul */ - map.insert(QStringLiteral("Ekaterinburg Standard Time"), QStringLiteral("Asia/Yekaterinburg")); /* (GMT+05:00) Ekaterinburg */ - map.insert(QStringLiteral("West Asia Standard Time"), QStringLiteral("Asia/Karachi")); /* (GMT+05:00) Islamabad, Karachi, Tashkent */ - map.insert(QStringLiteral("India Standard Time"), QStringLiteral("Asia/Calcutta")); /* (GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi */ - map.insert(QStringLiteral("Nepal Standard Time"), QStringLiteral("Asia/Calcutta")); /* (GMT+05:45) Kathmandu */ - map.insert(QStringLiteral("Central Asia Standard Time"), QStringLiteral("Asia/Dhaka")); /* (GMT+06:00) Astana, Dhaka */ - map.insert(QStringLiteral("Sri Lanka Standard Time"), QStringLiteral("Asia/Colombo")); /* (GMT+06:00) Sri Jayawardenepura */ - map.insert(QStringLiteral("N. Central Asia Standard Time"), QStringLiteral("Asia/Omsk")); /* (GMT+06:00) Almaty, Novosibirsk */ - map.insert(QStringLiteral("Myanmar Standard Time"), QStringLiteral("Asia/Rangoon")); /* (GMT+06:30) Yangon Rangoon */ - map.insert(QStringLiteral("S.E. Asia Standard Time"), QStringLiteral("Asia/Bangkok")); /* (GMT+07:00) Bangkok, Hanoi, Jakarta */ - map.insert(QStringLiteral("North Asia Standard Time"), QStringLiteral("Asia/Krasnoyarsk")); /* (GMT+07:00) Krasnoyarsk */ - map.insert(QStringLiteral("China Standard Time"), QStringLiteral("Asia/Shanghai")); /* (GMT+08:00) Beijing, Chongqing, Hong Kong SAR, Urumqi */ - map.insert(QStringLiteral("Singapore Standard Time"), QStringLiteral("Asia/Singapore")); /* (GMT+08:00) Kuala Lumpur, Singapore */ - map.insert(QStringLiteral("Taipei Standard Time"), QStringLiteral("Asia/Taipei")); /* (GMT+08:00) Taipei */ - map.insert(QStringLiteral("W. Australia Standard Time"), QStringLiteral("Australia/Perth")); /* (GMT+08:00) Perth */ - map.insert(QStringLiteral("North Asia East Standard Time"), QStringLiteral("Asia/Irkutsk")); /* (GMT+08:00) Irkutsk, Ulaanbaatar */ - map.insert(QStringLiteral("Korea Standard Time"), QStringLiteral("Asia/Seoul")); /* (GMT+09:00) Seoul */ - map.insert(QStringLiteral("Tokyo Standard Time"), QStringLiteral("Asia/Tokyo")); /* (GMT+09:00) Osaka, Sapporo, Tokyo */ - map.insert(QStringLiteral("Yakutsk Standard Time"), QStringLiteral("Asia/Yakutsk")); /* (GMT+09:00) Yakutsk */ - map.insert(QStringLiteral("A.U.S. Central Standard Time"), QStringLiteral("Australia/Darwin")); /* (GMT+09:30) Darwin */ - map.insert(QStringLiteral("Cen. Australia Standard Time"), QStringLiteral("Australia/Adelaide")); /* (GMT+09:30) Adelaide */ - map.insert(QStringLiteral("A.U.S. Eastern Standard Time"), QStringLiteral("Australia/Sydney")); /* (GMT+10:00) Canberra, Melbourne, Sydney */ - map.insert(QStringLiteral("E. Australia Standard Time"), QStringLiteral("Australia/Brisbane")); /* (GMT+10:00) Brisbane */ - map.insert(QStringLiteral("Tasmania Standard Time"), QStringLiteral("Australia/Hobart")); /* (GMT+10:00) Hobart */ - map.insert(QStringLiteral("Vladivostok Standard Time"), QStringLiteral("Asia/Vladivostok")); /* (GMT+10:00) Vladivostok */ - map.insert(QStringLiteral("West Pacific Standard Time"), QStringLiteral("Pacific/Guam")); /* (GMT+10:00) Guam, Port Moresby */ - map.insert(QStringLiteral("Central Pacific Standard Time"), QStringLiteral("Pacific/Noumea")); /* (GMT+11:00) Magadan, Solomon Islands, New Caledonia */ - map.insert(QStringLiteral("Fiji Islands Standard Time"), QStringLiteral("Pacific/Fiji")); /* (GMT+12:00) Fiji Islands, Kamchatka, Marshall Islands */ - map.insert(QStringLiteral("New Zealand Standard Time"), QStringLiteral("Pacific/Auckland")); /* (GMT+12:00) Auckland, Wellington */ - map.insert(QStringLiteral("Tonga Standard Time"), QStringLiteral("Pacific/Tongatapu")); /* (GMT+13:00) Nuku'alofa */ - map.insert(QStringLiteral("Azerbaijan Standard Time"), QStringLiteral("America/Argentina/Buenos_Aires")); /* (GMT-03:00) Buenos Aires */ - map.insert(QStringLiteral("Middle East Standard Time"), QStringLiteral("Asia/Beirut")); /* (GMT+02:00) Beirut */ - map.insert(QStringLiteral("Jordan Standard Time"), QStringLiteral("Asia/Amman")); /* (GMT+02:00) Amman */ - map.insert(QStringLiteral("Central Standard Time (Mexico)"), QStringLiteral("America/Mexico_City")); /* (GMT-06:00) Guadalajara, Mexico City, Monterrey - New */ - map.insert(QStringLiteral("Mountain Standard Time (Mexico)"), QStringLiteral("America/Ojinaga")); /* (GMT-07:00) Chihuahua, La Paz, Mazatlan - New */ - map.insert(QStringLiteral("Pacific Standard Time (Mexico)"), QStringLiteral("America/Tijuana")); /* (GMT-08:00) Tijuana, Baja California */ - map.insert(QStringLiteral("Namibia Standard Time"), QStringLiteral("Africa/Windhoek")); /* (GMT+02:00) Windhoek */ - map.insert(QStringLiteral("Georgian Standard Time"), QStringLiteral("Asia/Tbilisi")); /* (GMT+03:00) Tbilisi */ - map.insert(QStringLiteral("Central Brazilian Standard Time"), QStringLiteral("America/Manaus")); /*(GMT-04:00) Manaus */ - map.insert(QStringLiteral("Montevideo Standard Time"), QStringLiteral("America/Montevideo")); /* (GMT-03:00) Montevideo */ - map.insert(QStringLiteral("Armenian Standard Time"), QStringLiteral("Asia/Yerevan")); /* (GMT+04:00) Yerevan */ - map.insert(QStringLiteral("Venezuela Standard Time"), QStringLiteral("America/Caracas")); /* (GMT-04:30) Caracas */ - map.insert(QStringLiteral("Argentina Standard Time"), QStringLiteral("America/Argentina/Buenos_Aires")); /* (GMT-03:00) Buenos Aires */ - map.insert(QStringLiteral("Morocco Standard Time"), QStringLiteral("Africa/Casablanca")); /* (GMT) Casablanca */ - map.insert(QStringLiteral("Pakistan Standard Time"), QStringLiteral("Asia/Karachi")); /* (GMT+05:00) Islamabad, Karachi */ - map.insert(QStringLiteral("Mauritius Standard Time"), QStringLiteral("Indian/Mauritius")); /* (GMT+04:00) Port Louis */ - map.insert(QStringLiteral("UTC"), QStringLiteral("UTC")); /* (GMT) Coordinated Universal Time */ - map.insert(QStringLiteral("Paraguay Standard Time"), QStringLiteral("America/Asuncion")); /* (GMT-04:00) Asuncion */ - map.insert(QStringLiteral("Kamchatka Standard Time"), QStringLiteral("Asia/Kamchatka")); /* (GMT+12:00) Petropavlovsk-Kamchatsky */ - - return map; -} + //{2, QLatin1String("Europe/Lisbon")}, /* GMT Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London */ + //{2, QLatin1String("Europe/Sarajevo")}, /* GMT+01:00 Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb */ + {3, QLatin1String("Europe/Paris")}, /* GMT+01:00 Paris, Madrid, Brussels, Copenhagen */ + {4, QLatin1String("Europe/Berlin")}, /* GMT+01:00 Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna */ + {5, QLatin1String("Europe/Bucharest")}, /* GMT+02:00 Bucharest */ + {6, QLatin1String("Europe/Prague")}, /* GMT+01:00 Prague, Central Europe */ + {7, QLatin1String("Europe/Athens")}, /* GMT+02:00 Athens, Istanbul, Minsk */ + {8, QLatin1String("America/Brazil")}, /* GMT-03:00 Brasilia */ + {9, QLatin1String("America/Halifax")}, /* GMT-04:00 Atlantic time (Canada) */ + {10, QLatin1String("America/New_York")}, /* GMT-05:00 Eastern Time (US & Canada) */ + {11, QLatin1String("America/Chicago")}, /* GMT-06:00 Central Time (US & Canada) */ + {12, QLatin1String("America/Denver")}, /* GMT-07:00 Mountain Time (US & Canada) */ + {13, QLatin1String("America/Los_Angeles")}, /* GMT-08:00 Pacific Time (US & Canada); Tijuana */ + {14, QLatin1String("America/Anchorage")}, /* GMT-09:00 Alaska */ + {15, QLatin1String("Pacific/Honolulu")}, /* GMT-10:00 Hawaii */ + {16, QLatin1String("Pacific/Apia")}, /* GMT-11:00 Midway Island, Samoa */ + {17, QLatin1String("Pacific/Auckland")}, /* GMT+12:00 Auckland, Wellington */ + {18, QLatin1String("Australia/Brisbane")}, /* GMT+10:00 Brisbane, East Australia */ + {19, QLatin1String("Australia/Adelaide")}, /* GMT+09:30 Adelaide, Central Australia */ + {20, QLatin1String("Asia/Tokyo")}, /* GMT+09:00 Osaka, Sapporo, Tokyo */ + {21, QLatin1String("Asia/Singapore")}, /* GMT+08:00 Kuala Lumpur, Singapore */ + {22, QLatin1String("Asia/Bangkok")}, /* GMT+07:00 Bangkok, Hanoi, Jakarta */ + {23, QLatin1String("Asia/Calcutta")}, /* GMT+05:30 Kolkata, Chennai, Mumbai, New Delhi, India Standard Time */ + {24, QLatin1String("Asia/Dubai")}, /* GMT+04:00 Abu Dhabi, Muscat */ + {25, QLatin1String("Asia/Tehran")}, /* GMT+03:30 Tehran */ + {26, QLatin1String("Asia/Baghdad")}, /* GMT+03:00 Baghdad */ + {27, QLatin1String("Asia/Jerusalem")}, /* GMT+02:00 Israel, Jerusalem Standard Time */ + {28, QLatin1String("America/St_Johns")}, /* GMT-03:30 Newfoundland */ + {29, QLatin1String("Atlantic/Portugal")}, /* GMT-01:00 Azores */ + {30, QLatin1String("America/Noronha")}, /* GMT-02:00 Mid-Atlantic */ + {31, QLatin1String("Africa/Monrovia")}, /* GMT Casablanca, Monrovia */ + {32, QLatin1String("America/Argentina/Buenos_Aires")}, /* GMT-03:00 Buenos Aires, Georgetown */ + {33, QLatin1String("America/La_Paz")}, /* GMT-04:00 Caracas, La Paz */ + {34, QLatin1String("America/New_York")}, /* GMT-05:00 Indiana (East) */ + {35, QLatin1String("America/Bogota")}, /* GMT-05:00 Bogota, Lima, Quito */ + {36, QLatin1String("America/Winnipeg")}, /* GMT-06:00 Saskatchewan */ + {37, QLatin1String("America/Mexico_City")}, /* GMT-06:00 Mexico City, Tegucigalpa */ + {38, QLatin1String("America/Phoenix")}, /* GMT-07:00 Arizona */ + {39, QLatin1String("Pacific/Kwajalein")}, /* GMT-12:00 Eniwetok, Kwajalein, Dateline Time */ + {40, QLatin1String("Pacific/Fiji")}, /* GMT+12:00 Fušál, Kamchatka, Mashall Is. */ + {41, QLatin1String("Pacific/Noumea")}, /* GMT+11:00 Magadan, Solomon Is., New Caledonia */ + {42, QLatin1String("Australia/Hobart")}, /* GMT+10:00 Hobart, Tasmania */ + {43, QLatin1String("Pacific/Guam")}, /* GMT+10:00 Guam, Port Moresby */ + {44, QLatin1String("Australia/Darwin")}, /* GMT+09:30 Darwin */ + {45, QLatin1String("Asia/Shanghai")}, /* GMT+08:00 Beijing, Chongqing, Hong Kong SAR, Urumqi */ + {46, QLatin1String("Asia/Omsk")}, /* GMT+06:00 Almaty, Novosibirsk, North Central Asia */ + {47, QLatin1String("Asia/Karachi")}, /* GMT+05:00 Islamabad, Karachi, Tashkent */ + {48, QLatin1String("Asia/Kabul")}, /* GMT+04:30 Kabul */ + {49, QLatin1String("Africa/Cairo")}, /* GMT+02:00 Cairo */ + {50, QLatin1String("Africa/Harare")}, /* GMT+02:00 Harare, Pretoria */ + {51, QLatin1String("Europe/Moscow")}, /* GMT+03:00 Moscow, St. Petersburg, Volgograd */ + {53, QLatin1String("Atlantic/Cape_Verde")}, /* GMT-01:00 Cape Verde Is. */ + {54, QLatin1String("Asia/Tbilisi")}, /* GMT+04:00 Baku, Tbilisi, Yerevan */ + {55, QLatin1String("America/Tegucigalpa")}, /* GMT-06:00 Central America */ + {56, QLatin1String("Africa/Nairobi")}, /* GMT+03:00 East Africa, Nairobi */ + {58, QLatin1String("Asia/Yekaterinburg")}, /* GMT+05:00 Ekaterinburg */ + {59, QLatin1String("Europe/Helsinki")}, /* GMT+02:00 Helsinki, Riga, Tallinn */ + {60, QLatin1String("America/Greenland")}, /* GMT-03:00 Greenland */ + {61, QLatin1String("Asia/Rangoon")}, /* GMT+06:30 Yangon (Rangoon) */ + {62, QLatin1String("Asia/Katmandu")}, /* GMT+05:45 Kathmandu, Nepal */ + {63, QLatin1String("Asia/Irkutsk")}, /* GMT+08:00 Irkutsk, Ulaan Bataar */ + {64, QLatin1String("Asia/Krasnoyarsk")}, /* GMT+07:00 Krasnoyarsk */ + {65, QLatin1String("America/Santiago")}, /* GMT-04:00 Santiago */ + {66, QLatin1String("Asia/Colombo")}, /* GMT+06:00 Sri Jayawardenepura, Sri Lanka */ + {67, QLatin1String("Pacific/Tongatapu")}, /* GMT+13:00 Nuku'alofa, Tonga */ + {68, QLatin1String("Asia/Vladivostok")}, /* GMT+10:00 Vladivostok */ + {69, QLatin1String("Africa/Bangui")}, /* GMT+01:00 West Central Africa */ + {70, QLatin1String("Asia/Yakutsk")}, /* GMT+09:00 Yakutsk */ + {71, QLatin1String("Asia/Dhaka")}, /* GMT+06:00 Astana, Dhaka */ + {72, QLatin1String("Asia/Seoul")}, /* GMT+09:00 Seoul, Korea Standard time */ + {73, QLatin1String("Australia/Perth")}, /* GMT+08:00 Perth, Western Australia */ + {74, QLatin1String("Asia/Kuwait")}, /* GMT+03:00 Arab, Kuwait, Riyadh */ + {75, QLatin1String("Asia/Taipei")}, /* GMT+08:00 Taipei */ + {76, QLatin1String("Australia/Sydney")} /* GMT+10:00 Canberra, Melbourne, Sydney */ +}; -static const QMap MSCDOTZIDTable = initMSCDOTZIDTable(); -static const QMap MSSTTZTable = initMSStandardTimeTZTable(); +/* Based on "Microsoft Time Zone Index Values" + * http://support.microsoft.com/kb/973627 + * + * The mapping is not exact, since the TZID usually refers to a + * region of multiple countries, so I always picked one of the countries + * in the specified region and used it's TZID. + * + * The Olson timezones are taken from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + * + * Note: using std::map, because it allows heterogeneous lookup, i.e. I can lookup the QLatin1String + * keys by using QString value, which is not possible with Qt containers. + */ +static const std::map> MSSTTZTable = { + {QLatin1String("Dateline Standard Time"), QLatin1String("Pacific/Kwajalein")}, /* (GMT-12:00) International Date Line West */ + {QLatin1String("Samoa Standard Time"), QLatin1String("Pacific/Apia")}, /* (GMT-11:00) Midway Island, Samoa */ + {QLatin1String("Hawaiian Standard Time"), QLatin1String("Pacific/Honolulu")}, /* (GMT-10:00) Hawaii */ + {QLatin1String("Alaskan Standard Time"), QLatin1String("America/Anchorage")}, /* (GMT-09:00) Alaska */ + {QLatin1String("Pacific Standard Time"), QLatin1String("America/Los_Angeles")}, /* (GMT-08:00) Pacific Time (US and Canada); Tijuana */ + {QLatin1String("Mountain Standard Time"), QLatin1String("America/Denver")}, /* (GMT-07:00) Mountain Time (US and Canada) */ + {QLatin1String("Mexico Standard Time 2"), QLatin1String("America/Chihuahua")}, /* (GMT-07:00) Chihuahua, La Paz, Mazatlan */ + {QLatin1String("U.S. Mountain Standard Time"), QLatin1String("America/Phoenix")}, /* (GMT-07:00) Arizona */ + {QLatin1String("Central Standard Time"), QLatin1String("America/Chicago")}, /* (GMT-06:00) Central Time (US and Canada */ + {QLatin1String("Canada Central Standard Time"), QLatin1String("America/Winnipeg")}, /* (GMT-06:00) Saskatchewan */ + {QLatin1String("Mexico Standard Time"), QLatin1String("America/Mexico_City")}, /* (GMT-06:00) Guadalajara, Mexico City, Monterrey */ + {QLatin1String("Central America Standard Time"), QLatin1String("America/Chicago")}, /* (GMT-06:00) Central America */ + {QLatin1String("Eastern Standard Time"), QLatin1String("America/New_York")}, /* (GMT-05:00) Eastern Time (US and Canada) */ + {QLatin1String("U.S. Eastern Standard Time"), QLatin1String("America/New_York")}, /* (GMT-05:00) Indiana (East) */ + {QLatin1String("S.A. Pacific Standard Time"), QLatin1String("America/Bogota")}, /* (GMT-05:00) Bogota, Lima, Quito */ + {QLatin1String("Atlantic Standard Time"), QLatin1String("America/Halifax")}, /* (GMT-04:00) Atlantic Time (Canada) */ + {QLatin1String("S.A. Western Standard Time"), QLatin1String("America/La_Paz")}, /* (GMT-04:00) Caracas, La Paz */ + {QLatin1String("Pacific S.A. Standard Time"), QLatin1String("America/Santiago")}, /* (GMT-04:00) Santiago */ + {QLatin1String("Newfoundland and Labrador Standard Time"), QLatin1String("America/St_Johns")}, /* (GMT-03:30) Newfoundland and Labrador */ + {QLatin1String("E. South America Standard Time"), QLatin1String("America/Brazil")}, /* (GMT-03:00) Brasilia */ + {QLatin1String("S.A. Eastern Standard Time"), QLatin1String("America/Argentina/Buenos_Aires")}, /* (GMT-03:00) Buenos Aires, Georgetown */ + {QLatin1String("Greenland Standard Time"), QLatin1String("America/Greenland")}, /* (GMT-03:00) Greenland */ + {QLatin1String("Mid-Atlantic Standard Time"), QLatin1String("America/Noronha")}, /* (GMT-02:00) Mid-Atlantic */ + {QLatin1String("Azores Standard Time"), QLatin1String("Atlantic/Portugal")}, /* (GMT-01:00) Azores */ + {QLatin1String("Cape Verde Standard Time"), QLatin1String("Atlantic/Cape_Verde")}, /* (GMT-01:00) Cape Verde Islands */ + {QLatin1String("GMT Standard Time"), QLatin1String("Europe/London")}, /* (GMT) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London */ + {QLatin1String("Greenwich Standard Time"), QLatin1String("Africa/Casablanca")}, /* (GMT) Casablanca, Monrovia */ + {QLatin1String("Central Europe Standard Time"), QLatin1String("Europe/Prague")}, /* (GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague */ + {QLatin1String("Central European Standard Time"), QLatin1String("Europe/Sarajevo")}, /* (GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb */ + {QLatin1String("Romance Standard Time"), QLatin1String("Europe/Brussels")}, /* (GMT+01:00) Brussels, Copenhagen, Madrid, Paris */ + {QLatin1String("W. Europe Standard Time"), QLatin1String("Europe/Amsterdam")}, /* (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna */ + {QLatin1String("W. Central Africa Standard Time"), QLatin1String("Africa/Bangui")}, /* (GMT+01:00) West Central Africa */ + {QLatin1String("E. Europe Standard Time"), QLatin1String("Europe/Bucharest")}, /* (GMT+02:00) Bucharest */ + {QLatin1String("Egypt Standard Time"), QLatin1String("Africa/Cairo")}, /* (GMT+02:00) Cairo */ + {QLatin1String("FLE Standard Time"), QLatin1String("Europe/Helsinki")}, /* (GMT+02:00) Helsinki, Kiev, Riga, Sofia, Tallinn, Vilnius */ + {QLatin1String("GTB Standard Time"), QLatin1String("Europe/Athens")}, /* (GMT+02:00) Athens, Istanbul, Minsk */ + {QLatin1String("Israel Standard Time"), QLatin1String("Europe/Athens")}, /* (GMT+02:00) Jerusalem */ + {QLatin1String("South Africa Standard Time"), QLatin1String("Africa/Harare")}, /* (GMT+02:00) Harare, Pretoria */ + {QLatin1String("Russian Standard Time"), QLatin1String("Europe/Moscow")}, /* (GMT+03:00) Moscow, St. Petersburg, Volgograd */ + {QLatin1String("Arab Standard Time"), QLatin1String("Asia/Kuwait")}, /* (GMT+03:00) Kuwait, Riyadh */ + {QLatin1String("E. Africa Standard Time"), QLatin1String("Africa/Nairobi")}, /* (GMT+03:00) Nairobi */ + {QLatin1String("Arabic Standard Time"), QLatin1String("Asia/Baghdad")}, /* (GMT+03:00) Baghdad */ + {QLatin1String("Iran Standard Time"), QLatin1String("Asia/Tehran")}, /* (GMT+03:30) Tehran */ + {QLatin1String("Arabian Standard Time"), QLatin1String("Asia/Dubai")}, /* (GMT+04:00) Abu Dhabi, Muscat */ + {QLatin1String("Caucasus Standard Time"), QLatin1String("Asia/Tbilisi")}, /* (GMT+04:00) Baku, Tbilisi, Yerevan */ + {QLatin1String("Transitional Islamic State of Afghanistan Standard Time"), QLatin1String("Asia/Kabul")}, /* (GMT+04:30) Kabul */ + {QLatin1String("Ekaterinburg Standard Time"), QLatin1String("Asia/Yekaterinburg")}, /* (GMT+05:00) Ekaterinburg */ + {QLatin1String("West Asia Standard Time"), QLatin1String("Asia/Karachi")}, /* (GMT+05:00) Islamabad, Karachi, Tashkent */ + {QLatin1String("India Standard Time"), QLatin1String("Asia/Calcutta")}, /* (GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi */ + {QLatin1String("Nepal Standard Time"), QLatin1String("Asia/Calcutta")}, /* (GMT+05:45) Kathmandu */ + {QLatin1String("Central Asia Standard Time"), QLatin1String("Asia/Dhaka")}, /* (GMT+06:00) Astana, Dhaka */ + {QLatin1String("Sri Lanka Standard Time"), QLatin1String("Asia/Colombo")}, /* (GMT+06:00) Sri Jayawardenepura */ + {QLatin1String("N. Central Asia Standard Time"), QLatin1String("Asia/Omsk")}, /* (GMT+06:00) Almaty, Novosibirsk */ + {QLatin1String("Myanmar Standard Time"), QLatin1String("Asia/Rangoon")}, /* (GMT+06:30) Yangon Rangoon */ + {QLatin1String("S.E. Asia Standard Time"), QLatin1String("Asia/Bangkok")}, /* (GMT+07:00) Bangkok, Hanoi, Jakarta */ + {QLatin1String("North Asia Standard Time"), QLatin1String("Asia/Krasnoyarsk")}, /* (GMT+07:00) Krasnoyarsk */ + {QLatin1String("China Standard Time"), QLatin1String("Asia/Shanghai")}, /* (GMT+08:00) Beijing, Chongqing, Hong Kong SAR, Urumqi */ + {QLatin1String("Singapore Standard Time"), QLatin1String("Asia/Singapore")}, /* (GMT+08:00) Kuala Lumpur, Singapore */ + {QLatin1String("Taipei Standard Time"), QLatin1String("Asia/Taipei")}, /* (GMT+08:00) Taipei */ + {QLatin1String("W. Australia Standard Time"), QLatin1String("Australia/Perth")}, /* (GMT+08:00) Perth */ + {QLatin1String("North Asia East Standard Time"), QLatin1String("Asia/Irkutsk")}, /* (GMT+08:00) Irkutsk, Ulaanbaatar */ + {QLatin1String("Korea Standard Time"), QLatin1String("Asia/Seoul")}, /* (GMT+09:00) Seoul */ + {QLatin1String("Tokyo Standard Time"), QLatin1String("Asia/Tokyo")}, /* (GMT+09:00) Osaka, Sapporo, Tokyo */ + {QLatin1String("Yakutsk Standard Time"), QLatin1String("Asia/Yakutsk")}, /* (GMT+09:00) Yakutsk */ + {QLatin1String("A.U.S. Central Standard Time"), QLatin1String("Australia/Darwin")}, /* (GMT+09:30) Darwin */ + {QLatin1String("Cen. Australia Standard Time"), QLatin1String("Australia/Adelaide")}, /* (GMT+09:30) Adelaide */ + {QLatin1String("A.U.S. Eastern Standard Time"), QLatin1String("Australia/Sydney")}, /* (GMT+10:00) Canberra, Melbourne, Sydney */ + {QLatin1String("E. Australia Standard Time"), QLatin1String("Australia/Brisbane")}, /* (GMT+10:00) Brisbane */ + {QLatin1String("Tasmania Standard Time"), QLatin1String("Australia/Hobart")}, /* (GMT+10:00) Hobart */ + {QLatin1String("Vladivostok Standard Time"), QLatin1String("Asia/Vladivostok")}, /* (GMT+10:00) Vladivostok */ + {QLatin1String("West Pacific Standard Time"), QLatin1String("Pacific/Guam")}, /* (GMT+10:00) Guam, Port Moresby */ + {QLatin1String("Central Pacific Standard Time"), QLatin1String("Pacific/Noumea")}, /* (GMT+11:00) Magadan, Solomon Islands, New Caledonia */ + {QLatin1String("Fiji Islands Standard Time"), QLatin1String("Pacific/Fiji")}, /* (GMT+12:00) Fiji Islands, Kamchatka, Marshall Islands */ + {QLatin1String("New Zealand Standard Time"), QLatin1String("Pacific/Auckland")}, /* (GMT+12:00) Auckland, Wellington */ + {QLatin1String("Tonga Standard Time"), QLatin1String("Pacific/Tongatapu")}, /* (GMT+13:00) Nuku'alofa */ + {QLatin1String("Azerbaijan Standard Time"), QLatin1String("America/Argentina/Buenos_Aires")}, /* (GMT-03:00) Buenos Aires */ + {QLatin1String("Middle East Standard Time"), QLatin1String("Asia/Beirut")}, /* (GMT+02:00) Beirut */ + {QLatin1String("Jordan Standard Time"), QLatin1String("Asia/Amman")}, /* (GMT+02:00) Amman */ + {QLatin1String("Central Standard Time (Mexico)"), QLatin1String("America/Mexico_City")}, /* (GMT-06:00) Guadalajara, Mexico City, Monterrey - New */ + {QLatin1String("Mountain Standard Time (Mexico)"), QLatin1String("America/Ojinaga")}, /* (GMT-07:00) Chihuahua, La Paz, Mazatlan - New */ + {QLatin1String("Pacific Standard Time (Mexico)"), QLatin1String("America/Tijuana")}, /* (GMT-08:00) Tijuana, Baja California */ + {QLatin1String("Namibia Standard Time"), QLatin1String("Africa/Windhoek")}, /* (GMT+02:00) Windhoek */ + {QLatin1String("Georgian Standard Time"), QLatin1String("Asia/Tbilisi")}, /* (GMT+03:00) Tbilisi */ + {QLatin1String("Central Brazilian Standard Time"), QLatin1String("America/Manaus")}, /*(GMT-04:00) Manaus */ + {QLatin1String("Montevideo Standard Time"), QLatin1String("America/Montevideo")}, /* (GMT-03:00) Montevideo */ + {QLatin1String("Armenian Standard Time"), QLatin1String("Asia/Yerevan")}, /* (GMT+04:00) Yerevan */ + {QLatin1String("Venezuela Standard Time"), QLatin1String("America/Caracas")}, /* (GMT-04:30) Caracas */ + {QLatin1String("Argentina Standard Time"), QLatin1String("America/Argentina/Buenos_Aires")}, /* (GMT-03:00) Buenos Aires */ + {QLatin1String("Morocco Standard Time"), QLatin1String("Africa/Casablanca")}, /* (GMT) Casablanca */ + {QLatin1String("Pakistan Standard Time"), QLatin1String("Asia/Karachi")}, /* (GMT+05:00) Islamabad, Karachi */ + {QLatin1String("Mauritius Standard Time"), QLatin1String("Indian/Mauritius")}, /* (GMT+04:00) Port Louis */ + {QLatin1String("UTC"), QLatin1String("UTC")}, /* (GMT) Coordinated Universal Time */ + {QLatin1String("Paraguay Standard Time"), QLatin1String("America/Asuncion")}, /* (GMT-04:00) Asuncion */ + {QLatin1String("Kamchatka Standard Time"), QLatin1String("Asia/Kamchatka")}, /* (GMT+12:00) Petropavlovsk-Kamchatsky */ +}; +} // namespace -QString Private::checkAndConverCDOTZID(const QString& tzid, const EventPtr& event) +QString Private::checkAndConverCDOTZID(const QString &tzid, const EventPtr& event) { /* Try to match the @tzid to any valid timezone we know. */ - QTimeZone tz(tzid.toUtf8()); + QTimeZone tz(tzid.toLatin1()); if (tz.isValid()) { /* Yay, @tzid is a valid TZID in Olson format */ return tzid; } /* Damn, no match. Parse the iCal and try to find X-MICROSOFT-CDO-TZID * property that we can match against the MSCDOTZIDTable */ KCalendarCore::ICalFormat format; /* Use a copy of @event, otherwise it would be deleted when ptr is destroyed */ KCalendarCore::Incidence::Ptr incidence = event.dynamicCast(); const QString vcard = format.toICalString(incidence); const QStringList properties = vcard.split(QLatin1Char('\n')); int CDOId = -1; for (const QString &property : properties) { - if (property.startsWith(QLatin1String("X-MICROSOFT-CDO-TZID"))) { + if (property.startsWith(u"X-MICROSOFT-CDO-TZID")) { QStringList parsed = property.split(QLatin1Char(':')); if (parsed.length() != 2) { break; } CDOId = parsed.at(1).toInt(); break; } } /* Wheeee, we have X-MICROSOFT-CDO-TZID, try to map it to Olson format */ if (CDOId > -1) { /* *sigh* Some expert in MS assigned the same ID to two different timezones... */ if (CDOId == 2) { /* GMT Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London */ if (tzid.contains(QLatin1String("Dublin")) || tzid.contains(QLatin1String("Edinburgh")) || tzid.contains(QLatin1String("Lisbon")) || tzid.contains(QLatin1String("London"))) { return QStringLiteral("Europe/London"); } /* GMT+01:00 Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb */ else if (tzid.contains(QLatin1String("Sarajevo")) || tzid.contains(QLatin1String("Skopje")) || tzid.contains(QLatin1String("Sofija")) || tzid.contains(QLatin1String("Vilnius")) || tzid.contains(QLatin1String("Warsaw")) || tzid.contains(QLatin1String("Zagreb"))) { return QStringLiteral("Europe/Sarajevo"); } } - if (MSCDOTZIDTable.contains(CDOId)) { - return MSCDOTZIDTable.value(CDOId); + const auto it = MSCDOTZIDTable.find(CDOId); + if (it != MSCDOTZIDTable.cend()) { + return it->second; } } /* We failed to map to X-MICROSOFT-CDO-TZID. Let's try mapping the TZID * onto the Microsoft Standard Time Zones */ - if (MSSTTZTable.contains(tzid)) { - return MSSTTZTable.value(tzid); + const auto it = MSSTTZTable.find(tzid); + if (it != MSSTTZTable.cend()) { + return it->second; } /* Fail/ Just return the original TZID and hope Google will accept it * (though we know it won't) */ return tzid; } } // namespace CalendarService } // namespace KGAPI2 diff --git a/src/calendar/calendarservice.h b/src/calendar/calendarservice.h index 95eb23e..caa0107 100644 --- a/src/calendar/calendarservice.h +++ b/src/calendar/calendarservice.h @@ -1,191 +1,200 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_CALENDARSERVICE_H #define LIBKGAPI2_CALENDARSERVICE_H #include "types.h" #include "enums.h" #include "kgapicalendar_export.h" #include +class QNetworkRequest; + namespace KGAPI2 { /** * @brief Additional methods for implementing support for Google Calendar service * * You should never need to use these methods, unless implementing your own Job */ namespace CalendarService { enum class EventSerializeFlag { Default = 0, NoID = 1 << 0 }; using EventSerializeFlags = QFlags; + /** + * @vrief Preparse a QNetworkRequest for given URL + * + * @param url + */ + KGAPICALENDAR_EXPORT QNetworkRequest prepareRequest(const QUrl &url); + /** * @brief Parses calendar JSON data into Calendar object * * @param jsonData */ KGAPICALENDAR_EXPORT CalendarPtr JSONToCalendar(const QByteArray& jsonData); /** * @brief Serializes calendar into JSON * * @param calendar */ KGAPICALENDAR_EXPORT QByteArray calendarToJSON(const CalendarPtr& calendar); /** * @brief Parses JSON feed into list of Calendars * * @param jsonFeed * @param feedData The structure will be filled with additional information about * the feed, including URL for next page (if any) */ KGAPICALENDAR_EXPORT ObjectsList parseCalendarJSONFeed(const QByteArray& jsonFeed, FeedData& feedData); /** * @brief Parses event JSON into Event object * * @param jsonData */ KGAPICALENDAR_EXPORT EventPtr JSONToEvent(const QByteArray& jsonData); /** * @brief Serializes Event into JSON * * @param event */ KGAPICALENDAR_EXPORT QByteArray eventToJSON(const EventPtr& event, EventSerializeFlags flags = EventSerializeFlag::Default); /** * @brief Parses JSON feed into list of Events * * @param jsonFeed * @param feedData The structure will be filled with additional information about * the feed, including URL for next page (if any) */ KGAPICALENDAR_EXPORT ObjectsList parseEventJSONFeed(const QByteArray& jsonFeed, FeedData& feedData); /** * @brief Supported API version */ KGAPICALENDAR_EXPORT QString APIVersion(); /** * @brief Returns URL for fetching calendars list. */ KGAPICALENDAR_EXPORT QUrl fetchCalendarsUrl(); /** * @brief Returns URL for fetching single calendar. * * @param calendarID calendar ID */ KGAPICALENDAR_EXPORT QUrl fetchCalendarUrl(const QString &calendarID); /** * @brief Returns URL for updating existing calendar. * * @param calendarID ID of calendar to modify */ KGAPICALENDAR_EXPORT QUrl updateCalendarUrl(const QString &calendarID); /** * @brief Returns URL for creating a new calendar. */ KGAPICALENDAR_EXPORT QUrl createCalendarUrl(); /** * @brief Returns URL for removing an existing calendar. * * @param calendarID ID of calendar to remove */ KGAPICALENDAR_EXPORT QUrl removeCalendarUrl(const QString &calendarID); /** * @brief Returns URL for fetching all events from a specific calendar * * @param calendarID ID of calendar from which to fetch events */ KGAPICALENDAR_EXPORT QUrl fetchEventsUrl(const QString &calendarID); /** * @brief Returns URL for fetching a single event from a specific calendar. * * @param calendarID ID of calendar from which to fetch the event * @param eventID ID of event to fetch */ KGAPICALENDAR_EXPORT QUrl fetchEventUrl(const QString &calendarID, const QString &eventID); /** * @brief Returns URL for updating a single event * * @param calendarID ID of calendar in which the event is * @param eventID ID of event to update * @param updatesPolicy Whether to send notification to participants */ KGAPICALENDAR_EXPORT QUrl updateEventUrl(const QString &calendarID, const QString &eventID, SendUpdatesPolicy updatesPolicy); /** * @brief Returns URL creating new events. * * @param calendarID ID of calendar in which to create the event * @param updatesPolicy Whether to send notification to participants */ KGAPICALENDAR_EXPORT QUrl createEventUrl(const QString &calendarID, SendUpdatesPolicy updatesPolicy); /** * @brief Returns URL for removing events * * @param calendarID ID of parent calendar * @param eventID ID of event to remove. */ KGAPICALENDAR_EXPORT QUrl removeEventUrl(const QString &calendarID, const QString &eventID); /** * @brief Returns URL for moving event between calendars. * * @param sourceCalendar ID of calendar from which to remove the event * @param destCalendar ID of calendar to which to move the even * @param eventID ID of event in the \p sourceCalendar to move */ KGAPICALENDAR_EXPORT QUrl moveEventUrl(const QString &sourceCalendar, const QString &destCalendar, const QString &eventID); /** * @brief Returns URL for freebusy queries. */ KGAPICALENDAR_EXPORT QUrl freeBusyQueryUrl(); } // namespace CalendarService } // namespace KGAPI Q_DECLARE_OPERATORS_FOR_FLAGS(KGAPI2::CalendarService::EventSerializeFlags) #endif // LIBKGAPI2_CALENDARSERVICE_H diff --git a/src/calendar/event.cpp b/src/calendar/event.cpp index 44b810d..49f3e59 100644 --- a/src/calendar/event.cpp +++ b/src/calendar/event.cpp @@ -1,133 +1,118 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "event.h" #include "../debug.h" using namespace KGAPI2; +namespace { +static constexpr const char *EventIdProperty = "EventId"; +} + class Q_DECL_HIDDEN Event::Private { public: - explicit Private(); - Private(const Private &other); - QString id; - bool deleted; - bool useDefaultReminders; + bool deleted = false; + bool useDefaultReminders = false; }; -Event::Private::Private(): - deleted(false), - useDefaultReminders(false) -{ -} - -Event::Private::Private(const Private &other): - id(other.id), - deleted(other.deleted), - useDefaultReminders(other.useDefaultReminders) -{ -} - Event::Event(): Object(), KCalendarCore::Event(), d(new Private) { } Event::Event(const Event &other): Object(other), KCalendarCore::Event(other), d(new Private(*(other.d))) { } Event::Event(const KCalendarCore::Event &other): Object(), KCalendarCore::Event(other), d(new Private) { } -Event::~Event() -{ - delete d; -} +Event::~Event()= default; bool Event::operator==(const Event &other) const { if (!Object::operator==(other)) { return false; } if (!KCalendarCore::Event::operator==(other)) { return false; } if (d->deleted != other.d->deleted) { qCDebug(KGAPIDebug) << "Deleted does not match"; return false; } if (d->useDefaultReminders != other.d->useDefaultReminders) { qCDebug(KGAPIDebug) << "UseDefaultReminders does not match"; return false; } return true; } bool Event::deleted() const { return d->deleted; } bool Event::useDefaultReminders() const { return d->useDefaultReminders; } void Event::setDeleted(bool deleted) { d->deleted = deleted; } void Event::setUseDefaultReminders(bool useDefault) { d->useDefaultReminders = useDefault; } QString Event::id() const { - QString val = customProperty("LIBKGAPI", "EventId"); + const QString val = customProperty("LIBKGAPI", EventIdProperty); if (val.isEmpty()) { // Backwards compatibility: prior to introducing "id", UID was used for // remote identification: use it return KCalendarCore::Incidence::uid(); } return val; } void Event::setId(const QString &id) { - setCustomProperty("LIBKGAPI", "EventId", id); + setCustomProperty("LIBKGAPI", EventIdProperty, id); } diff --git a/src/calendar/event.h b/src/calendar/event.h index aba1da8..85d6f4d 100644 --- a/src/calendar/event.h +++ b/src/calendar/event.h @@ -1,111 +1,113 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_EVENT_H #define LIBKGAPI2_EVENT_H #include "object.h" #include "types.h" #include "kgapicalendar_export.h" #include +#include + namespace KGAPI2 { /** * @brief Represents a single event from Google Calendar * * @author Daniel Vrátil * @since 0.1 */ class KGAPICALENDAR_EXPORT Event: public KGAPI2::Object, - public KCalendarCore::Event + public KCalendarCore::Event { public: /** * @brief Constructor */ Event(); /** * @brief Copy constructor */ Event(const Event& other); /** * @brief Copy constructor */ explicit Event(const KCalendarCore::Event &event); /** * @brief Destructor */ ~Event(); bool operator==(const Event &other) const; /** * @brief Marks the event as deleted * * @param deleted */ void setDeleted(bool deleted); /** * @brief Returns whether the event was removed */ bool deleted() const; /** * @brief Sets whether the event should use calendar's default reminders. * * @param useDefault */ void setUseDefaultReminders(bool useDefault); /** * @brief Returns whether the event should use calendar's default reminders. */ bool useDefaultReminders() const; /** * @brief Returns ID used by Google to identify the event in calendar. * * This is not the same as UID. */ QString id() const; /** * @brief Sets event ID used by Google to identify the event in calendar. */ void setId(const QString &id); private: class Private; - Private * const d; + QScopedPointer const d; }; } // namespace KGAPI #endif // LIBKGAPI2_EVENT_H diff --git a/src/calendar/eventcreatejob.cpp b/src/calendar/eventcreatejob.cpp index 59ef9fe..70ce659 100644 --- a/src/calendar/eventcreatejob.cpp +++ b/src/calendar/eventcreatejob.cpp @@ -1,124 +1,111 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "eventcreatejob.h" #include "calendarservice.h" #include "account.h" #include "../debug.h" #include "event.h" #include "utils.h" #include "private/queuehelper_p.h" #include #include using namespace KGAPI2; class Q_DECL_HIDDEN EventCreateJob::Private { public: QueueHelper events; QString calendarId; SendUpdatesPolicy updatesPolicy = SendUpdatesPolicy::All; }; EventCreateJob::EventCreateJob(const EventPtr& event, const QString &calendarId, const AccountPtr& account, QObject* parent): CreateJob(account, parent), d(new Private) { d->events << event; d->calendarId = calendarId; } EventCreateJob::EventCreateJob(const EventsList& events, const QString& calendarId, const AccountPtr& account, QObject* parent): CreateJob(account, parent), d(new Private) { d->events = events; d->calendarId = calendarId; } -EventCreateJob::~EventCreateJob() -{ - delete d; -} +EventCreateJob::~EventCreateJob() = default; void EventCreateJob::setSendUpdates(SendUpdatesPolicy policy) { if (d->updatesPolicy != policy) { d->updatesPolicy = policy; Q_EMIT sendUpdatesChanged(d->updatesPolicy); } } SendUpdatesPolicy EventCreateJob::sendUpdates() const { return d->updatesPolicy; } void EventCreateJob::start() { if (d->events.atEnd()) { emitFinished(); return; } const EventPtr event = d->events.current(); - const QUrl url = CalendarService::createEventUrl(d->calendarId, d->updatesPolicy); - QNetworkRequest request(url); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); - + const auto request = CalendarService::prepareRequest(CalendarService::createEventUrl(d->calendarId, d->updatesPolicy)); const QByteArray rawData = CalendarService::eventToJSON(event, CalendarService::EventSerializeFlag::NoID); - QStringList headers; - auto rawHeaderList = request.rawHeaderList(); - headers.reserve(rawHeaderList.size()); - for (const QByteArray &str : qAsConst(rawHeaderList)) { - headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); - } - enqueueRequest(request, rawData, QStringLiteral("application/json")); } ObjectsList EventCreateJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); ObjectsList items; if (ct != KGAPI2::JSON) { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } items << CalendarService::JSONToEvent(rawData).dynamicCast(); d->events.currentProcessed(); // Enqueue next item or finish start(); return items; } diff --git a/src/calendar/eventcreatejob.h b/src/calendar/eventcreatejob.h index 9ff0803..7e5a81f 100644 --- a/src/calendar/eventcreatejob.h +++ b/src/calendar/eventcreatejob.h @@ -1,106 +1,108 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_EVENTCREATEJOB_H #define LIBKGAPI2_EVENTCREATEJOB_H #include "createjob.h" #include "enums.h" #include "kgapicalendar_export.h" +#include + namespace KGAPI2 { /** * @brief A job to create one or more new events in given calendar * * @author Daniel Vrátil * @since 2.0 */ class KGAPICALENDAR_EXPORT EventCreateJob : public KGAPI2::CreateJob { Q_OBJECT Q_PROPERTY(KGAPI2::SendUpdatesPolicy sendUpdates READ sendUpdates WRITE setSendUpdates NOTIFY sendUpdatesChanged) public: /** * @brief Constructs a job that will create given @p event in a calendar * with given @p calendarID * * @param event Event to create * @param calendarId ID of calendar in which to store the event * @param account Account to authenticate the request * @param parent */ explicit EventCreateJob(const EventPtr &event, const QString &calendarId, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Constructs a job that will create given @p events in a calendar * with given @p calendarID * * @param events Events to create * @param calendarId ID of calendar in which to store the event * @param account Account to authenticate the request * @param parent */ explicit EventCreateJob(const EventsList &events, const QString &calendarId, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Destructor */ ~EventCreateJob() override; KGAPI2::SendUpdatesPolicy sendUpdates() const; void setSendUpdates(KGAPI2::SendUpdatesPolicy updatePolicy); Q_SIGNALS: void sendUpdatesChanged(KGAPI2::SendUpdatesPolicy policy); protected: /** * @brief KGAPI2::Job::start implementation */ void start() override; /** * @brief KGAPI2::CreateJob::handleReplyWithItems implementation * * @param reply * @param rawData */ ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } // namespace KGAPI2 #endif // LIBKGAPI2_EVENTCREATEJOB_H diff --git a/src/calendar/eventdeletejob.cpp b/src/calendar/eventdeletejob.cpp index 5173dfb..33d45ff 100644 --- a/src/calendar/eventdeletejob.cpp +++ b/src/calendar/eventdeletejob.cpp @@ -1,111 +1,99 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "eventdeletejob.h" #include "calendarservice.h" #include "account.h" #include "../debug.h" #include "event.h" #include "private/queuehelper_p.h" #include using namespace KGAPI2; class Q_DECL_HIDDEN EventDeleteJob::Private { public: QueueHelper eventsIds; QString calendarId; }; EventDeleteJob::EventDeleteJob(const EventPtr& event, const QString &calendarId, const AccountPtr& account, QObject* parent): DeleteJob(account, parent), d(new Private) { d->eventsIds << event->id(); d->calendarId = calendarId; } EventDeleteJob::EventDeleteJob(const EventsList& events, const QString& calendarId, const AccountPtr& account, QObject* parent): DeleteJob(account, parent), d(new Private) { for (const EventPtr &event : events) { d->eventsIds << event->id(); } d->calendarId = calendarId; } EventDeleteJob::EventDeleteJob(const QString &eventId, const QString &calendarId, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private) { d->eventsIds << eventId; d->calendarId = calendarId; } EventDeleteJob::EventDeleteJob(const QStringList &eventIds, const QString &calendarId, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private) { d->eventsIds = eventIds; d->calendarId = calendarId; } -EventDeleteJob::~EventDeleteJob() -{ - delete d; -} +EventDeleteJob::~EventDeleteJob() = default; void EventDeleteJob::start() { if (d->eventsIds.atEnd()) { emitFinished(); return; } const QString eventId = d->eventsIds.current(); - const QUrl url = CalendarService::removeEventUrl(d->calendarId, eventId); - QNetworkRequest request(url); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); - - QStringList headers; - auto rawHeaderList = request.rawHeaderList(); - headers.reserve(rawHeaderList.size()); - for (const QByteArray &str : qAsConst(rawHeaderList)) { - headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); - } + const auto request = CalendarService::prepareRequest(CalendarService::removeEventUrl(d->calendarId, eventId)); enqueueRequest(request); } void EventDeleteJob::handleReply(const QNetworkReply* reply, const QByteArray& rawData) { d->eventsIds.currentProcessed(); KGAPI2::DeleteJob::handleReply(reply, rawData); } diff --git a/src/calendar/eventdeletejob.h b/src/calendar/eventdeletejob.h index e1785ac..4a050cd 100644 --- a/src/calendar/eventdeletejob.h +++ b/src/calendar/eventdeletejob.h @@ -1,123 +1,125 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_EVENTDELETEJOB_H #define LIBKGAPI2_EVENTDELETEJOB_H #include "deletejob.h" #include "kgapicalendar_export.h" +#include + namespace KGAPI2 { /** * @brief A job to delete one or more events from calendar in user's Google * Calendar account. * * Note that operation is irreversible. * * @author Daniel Vrátil * @since 2.0 */ class KGAPICALENDAR_EXPORT EventDeleteJob : public KGAPI2::DeleteJob { Q_OBJECT public: /** * @brief Constructs a new job that will delete given @p event from a * calendar with given @p calendarId * * @param event Event to delete * @param calendarId ID of calendar in which the event is stored * @param account Account to authenticate the request * @param parent */ explicit EventDeleteJob(const EventPtr &event, const QString &calendarId, const AccountPtr &account, QObject* parent); /** * @brief Constructs a new job that will delete given @p events from a * calendar with given @p calendarId * * @param events Events to delete * @param calendarId ID of calendar in which the event is stored * @param account Account to authenticate the request * @param parent */ explicit EventDeleteJob(const EventsList &events, const QString &calendarId, const AccountPtr &account, QObject* parent); /** * @brief Constructs a new job that will delete an event with given * @p eventId from a calendar with given @p calendarId * * @param eventId ID of event to delete * @param calendarId ID of calendar in which the events is stored * @param account Account to authenticate the request * @param parent */ explicit EventDeleteJob(const QString &eventId, const QString &calendarId, const AccountPtr &account, QObject* parent); /** * @brief Constructs a new job that will delete all events with given * @p eventsIds from a calendar with given @p calendarId * * @param eventIds IDs of events to delete * @param calendarId ID of calendar in which the events is stored * @param account Account to authenticate the request * @param parent */ explicit EventDeleteJob(const QStringList &eventIds, const QString &calendarId, const AccountPtr &account, QObject *parent); /** * @brief Destructor */ ~EventDeleteJob() override; protected: /** * @brief KGAPI2::Job::start implementation */ void start() override; /** * @brief KGAPI2::Job::handleReply implementation * * @param reply * @param rawData */ void handleReply(const QNetworkReply* reply, const QByteArray& rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } // namespace KGAPI2 #endif // LIBKGAPI2_EVENTDELETEJOB_H diff --git a/src/calendar/eventfetchjob.cpp b/src/calendar/eventfetchjob.cpp index 41889b5..f868636 100644 --- a/src/calendar/eventfetchjob.cpp +++ b/src/calendar/eventfetchjob.cpp @@ -1,228 +1,195 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "eventfetchjob.h" #include "calendarservice.h" #include "account.h" #include "../debug.h" #include "event.h" #include "utils.h" #include #include #include using namespace KGAPI2; class Q_DECL_HIDDEN EventFetchJob::Private { public: - Private(EventFetchJob *parent); - QNetworkRequest createRequest(const QUrl &url); - QString calendarId; QString eventId; QString filter; - bool fetchDeleted; - quint64 updatedTimestamp; - quint64 timeMin; - quint64 timeMax; - - private: - EventFetchJob * const q; + bool fetchDeleted = true; + quint64 updatedTimestamp = 0; + quint64 timeMin = 0; + quint64 timeMax = 0; }; -EventFetchJob::Private::Private(EventFetchJob* parent): - fetchDeleted(true), - updatedTimestamp(0), - timeMin(0), - timeMax(0), - q(parent) -{ -} - -QNetworkRequest EventFetchJob::Private::createRequest(const QUrl& url) -{ - QNetworkRequest request(url); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); - - QStringList headers; - auto rawHeaderList = request.rawHeaderList(); - headers.reserve(rawHeaderList.size()); - for (const QByteArray &str : qAsConst(rawHeaderList)) { - headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); - } - - return request; -} - EventFetchJob::EventFetchJob(const QString& calendarId, const AccountPtr& account, QObject* parent): FetchJob(account, parent), - d(new Private(this)) + d(new Private) { d->calendarId = calendarId; } EventFetchJob::EventFetchJob(const QString& eventId, const QString& calendarId, const AccountPtr& account, QObject* parent): FetchJob(account, parent), - d(new Private(this)) + d(new Private) { d->calendarId = calendarId; d->eventId = eventId; } -EventFetchJob::~EventFetchJob() -{ - delete d; -} +EventFetchJob::~EventFetchJob() = default; void EventFetchJob::setFetchDeleted(bool fetchDeleted) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify fetchDeleted property when job is running"; return; } d->fetchDeleted = fetchDeleted; } bool EventFetchJob::fetchDeleted() { return d->fetchDeleted; } void EventFetchJob::setFetchOnlyUpdated(quint64 timestamp) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify setFetchOnlyUpdated property when job is running"; return; } d->updatedTimestamp = timestamp; } quint64 EventFetchJob::fetchOnlyUpdated() { return d->updatedTimestamp; } void EventFetchJob::setTimeMax(quint64 timestamp) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify timeMax property when job is running"; return; } d->timeMax = timestamp; } quint64 EventFetchJob::timeMax() const { return d->timeMax; } void EventFetchJob::setTimeMin(quint64 timestamp) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify timeMin property when job is running"; return; } d->timeMin = timestamp; } quint64 EventFetchJob::timeMin() const { return d->timeMin; } void EventFetchJob::setFilter(const QString &query) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify filter property when job is running"; return; } d->filter = query; } QString EventFetchJob::filter() const { return d->filter; } void EventFetchJob::start() { QUrl url; if (d->eventId.isEmpty()) { url = CalendarService::fetchEventsUrl(d->calendarId); QUrlQuery query(url); query.addQueryItem(QStringLiteral("showDeleted"), Utils::bool2Str(d->fetchDeleted)); if (!d->filter.isEmpty()) { query.addQueryItem(QStringLiteral("q"), d->filter); } if (d->updatedTimestamp > 0) { query.addQueryItem(QStringLiteral("updatedMin"), Utils::ts2Str(d->updatedTimestamp)); } if (d->timeMin > 0) { query.addQueryItem(QStringLiteral("timeMin"), Utils::ts2Str(d->timeMin)); } if (d->timeMax > 0) { query.addQueryItem(QStringLiteral("timeMax"), Utils::ts2Str(d->timeMax)); } url.setQuery(query); } else { url = CalendarService::fetchEventUrl(d->calendarId, d->eventId); } - const QNetworkRequest request = d->createRequest(url); + const QNetworkRequest request = CalendarService::prepareRequest(url); enqueueRequest(request); } ObjectsList EventFetchJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) { FeedData feedData; feedData.requestUrl = reply->url(); ObjectsList items; const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); if (ct == KGAPI2::JSON) { if (d->eventId.isEmpty()) { items = CalendarService::parseEventJSONFeed(rawData, feedData); } else { items << CalendarService::JSONToEvent(rawData).dynamicCast(); } } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } if (feedData.nextPageUrl.isValid()) { - const QNetworkRequest request = d->createRequest(feedData.nextPageUrl); + const auto request = CalendarService::prepareRequest(feedData.nextPageUrl); enqueueRequest(request); } return items; } diff --git a/src/calendar/eventfetchjob.h b/src/calendar/eventfetchjob.h index e4e47d6..bab3546 100644 --- a/src/calendar/eventfetchjob.h +++ b/src/calendar/eventfetchjob.h @@ -1,240 +1,242 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_EVENTFETCHJOB_H #define LIBKGAPI2_EVENTFETCHJOB_H #include "fetchjob.h" #include "kgapicalendar_export.h" +#include + namespace KGAPI2 { /** * @brief A job to fetch all events from given calendar in user's Google * Calendar account. * * @author Daniel Vrátil * @since 2.0 */ class KGAPICALENDAR_EXPORT EventFetchJob : public KGAPI2::FetchJob { Q_OBJECT /** * @brief Whether to fetch deleted events as well * * When an event is deleted from Google Calendar, it's stored as a placeholder * on Google server and can still be retrieved. Such event will have * KGAPI2::Event::deleted set to @p true. * * By default, the job will fetch deleted events. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. * * @see setFetchDeleted, fetchDeleted */ Q_PROPERTY(bool fetchDeleted READ fetchDeleted WRITE setFetchDeleted) /** * @brief Timestamp to fetch only events modified since then * * When set, this job will only fetch events that have been modified since * given timestamp. * * By default the timestamp is 0 and all events are fetched. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. * * @see setFetchOnlyUpdated, fetchOnlyUpdated */ Q_PROPERTY(quint64 fetchOnlyUpdated READ fetchOnlyUpdated WRITE setFetchOnlyUpdated) /** * @brief Timestamp of the newest event that will be fetched * * Only events occurring before or precisely at the time indicated by this * property will be fetched. * * By default the timestamp is 0 and no limit is applied. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. * * @see setMaxTime, maxTime */ Q_PROPERTY(quint64 timeMax READ timeMax WRITE setTimeMax) /** * @brief Timestamp of the oldest event that will be fetched * * Only events occurring after or precisely at the time indicated by this * property will be fetched. * * By default the timestamp is 0 and no limit is applied. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. * * @see setMinTime, minTime */ Q_PROPERTY(quint64 timeMin READ timeMin WRITE setTimeMin) /** * @brief A filter to fetch only events matching fulltext filter * * By default the property is empty and no filter is applied. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. * * @see setFilter, filter */ Q_PROPERTY(QString filter READ filter WRITE setFilter) public: /** * @brief Constructs a job that will fetch all events from a calendar with * given @p calendarId * * Result of this job might not contain all events, depending on configured * filters. * * @param calendarId ID of calendar from which to fetch events * @param account Account to authenticate the request * @param parent */ explicit EventFetchJob(const QString &calendarId, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Constructs a job that will fetch an event with given @p eventId * from a calendar with given @p calendarId * * Note that none of the filter, fetchOnlyUpdated, timeMax or timeMin properties * is applied in this case. * * @param eventId ID of event to fetch * @param calendarId ID of calendar in which the event is * @param account Account to authenticate the request * @param parent */ explicit EventFetchJob(const QString &eventId, const QString &calendarId, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Destructor */ ~EventFetchJob() override; /** * @brief Sets fulltext filter. * * @param query */ void setFilter(const QString &query); /** * @brief Returns fulltext filter string */ QString filter() const; /** * @brief Sets whether to fetch deleted events * * @param fetchDeleted */ void setFetchDeleted(bool fetchDeleted = true); /** * @brief Returns whether deleted events are fetched. */ bool fetchDeleted(); /** * @brief Sets the job to fetch only events modified since @p timestamp * * @param timestamp */ void setFetchOnlyUpdated(quint64 timestamp); /** * @brief Returns whether the job will fetch only modified events * * @return 0 when all events will be fetched, a timestamp of since when the * modified events will be fetched. */ quint64 fetchOnlyUpdated(); /** * @brief Sets timestamp of newest event that can be fetched. * * @param timestamp */ void setTimeMax(quint64 timestamp); /** * @brief Returns upper limit for event occurrence */ quint64 timeMax() const; /** * @brief Sets timestamp of older events that can be fetched. * * @param timestamp */ void setTimeMin(quint64 timestamp); /** * @brief Returns lower boundary for events occurrence */ quint64 timeMin() const; protected: /** * @brief KGAPI2::Job::start implementation */ void start() override; /** * @brief KGAPI2::FetchJob::handleReplyWithItems implementation * * @param reply * @param rawData */ ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } // namespace KGAPI2 #endif // LIBKGAPI2_EVENTFETCHJOB_H diff --git a/src/calendar/eventmodifyjob.cpp b/src/calendar/eventmodifyjob.cpp index 7d36144..e273fc0 100644 --- a/src/calendar/eventmodifyjob.cpp +++ b/src/calendar/eventmodifyjob.cpp @@ -1,123 +1,110 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "eventmodifyjob.h" #include "calendarservice.h" #include "account.h" #include "../debug.h" #include "event.h" #include "utils.h" #include "private/queuehelper_p.h" #include #include using namespace KGAPI2; class Q_DECL_HIDDEN EventModifyJob::Private { public: QueueHelper events; QString calendarId; SendUpdatesPolicy updatesPolicy = SendUpdatesPolicy::All; }; EventModifyJob::EventModifyJob(const EventPtr& event, const QString& calendarId, const AccountPtr& account, QObject* parent): ModifyJob(account, parent), d(new Private) { d->events << event; d->calendarId = calendarId; } EventModifyJob::EventModifyJob(const EventsList& events, const QString& calendarId, const AccountPtr& account, QObject* parent): ModifyJob(account, parent), d(new Private) { d->events = events; d->calendarId = calendarId; } -EventModifyJob::~EventModifyJob() -{ - delete d; -} +EventModifyJob::~EventModifyJob() = default; void EventModifyJob::setSendUpdates(KGAPI2::SendUpdatesPolicy updatesPolicy) { if (d->updatesPolicy != updatesPolicy) { d->updatesPolicy = updatesPolicy; Q_EMIT sendUpdatesChanged(d->updatesPolicy); } } SendUpdatesPolicy EventModifyJob::sendUpdates() const { return d->updatesPolicy; } void EventModifyJob::start() { if (d->events.atEnd()) { emitFinished(); return; } const EventPtr event = d->events.current(); - const QUrl url = CalendarService::updateEventUrl(d->calendarId, event->id(), d->updatesPolicy); - QNetworkRequest request(url); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); - + const auto request = CalendarService::prepareRequest(CalendarService::updateEventUrl(d->calendarId, event->id(), d->updatesPolicy)); const QByteArray rawData = CalendarService::eventToJSON(event); - QStringList headers; - auto rawHeaderList = request.rawHeaderList(); - headers.reserve(rawHeaderList.size()); - for (const QByteArray &str : qAsConst(rawHeaderList)) { - headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); - } - enqueueRequest(request, rawData, QStringLiteral("application/json")); } ObjectsList EventModifyJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); ObjectsList items; if (ct != KGAPI2::JSON) { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } items << CalendarService::JSONToEvent(rawData).dynamicCast(); d->events.currentProcessed(); // Enqueue next item or finish start(); return items; } diff --git a/src/calendar/eventmodifyjob.h b/src/calendar/eventmodifyjob.h index 7a5250e..8785467 100644 --- a/src/calendar/eventmodifyjob.h +++ b/src/calendar/eventmodifyjob.h @@ -1,107 +1,109 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_EVENTMODIFYJOB_H #define LIBKGAPI2_EVENTMODIFYJOB_H #include "modifyjob.h" #include "enums.h" #include "kgapicalendar_export.h" +#include + namespace KGAPI2 { /** * @brief A job to modify events in a calendar on user's Google Calendar account. * * @author Daniel Vrátil * @since 2.0 */ class KGAPICALENDAR_EXPORT EventModifyJob : public KGAPI2::ModifyJob { Q_OBJECT Q_PROPERTY(KGAPI2::SendUpdatesPolicy sendUpdates READ sendUpdates WRITE setSendUpdates NOTIFY sendUpdatesChanged) public: /** * @brief Constructs a job that will write changes in given @p event to * corresponding event in calendar with given @p calendarId * * @param event Event to modify * @param calendarId ID of calendar where the event is stored * @param account Account to authenticate the request * @param parent */ explicit EventModifyJob(const EventPtr &event, const QString &calendarId, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Constructs a job that will write changes in given @p events to * corresponding events in calendar with given @p calendarId * * @param events Events to modify * @param calendarId ID of calendar where the event is stored * @param account Account to authenticate the request * @param parent */ explicit EventModifyJob(const EventsList &events, const QString &calendarId, const AccountPtr &account, QObject* parent = nullptr); /** * @brief Destructor */ ~EventModifyJob() override; KGAPI2::SendUpdatesPolicy sendUpdates() const; void setSendUpdates(KGAPI2::SendUpdatesPolicy updatesPolicy); Q_SIGNALS: void sendUpdatesChanged(KGAPI2::SendUpdatesPolicy policy); protected: /** * @brief KGAPI2::Job::start implementation */ void start() override; /** * @brief KGAPI2::ModifyJob::handleReplyWithItems implementation * * @param reply * @param rawData */ ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray& rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } // namespace KGAPI #endif // LIBKGAPI2_EVENTMODIFYJOB_H diff --git a/src/calendar/eventmovejob.cpp b/src/calendar/eventmovejob.cpp index f0915c9..23d11ef 100644 --- a/src/calendar/eventmovejob.cpp +++ b/src/calendar/eventmovejob.cpp @@ -1,163 +1,135 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "eventmovejob.h" #include "account.h" #include "calendarservice.h" #include "../debug.h" #include "event.h" #include "utils.h" #include "private/queuehelper_p.h" #include #include using namespace KGAPI2; class Q_DECL_HIDDEN EventMoveJob::Private { - public: - explicit Private(EventMoveJob *parent); - void processNextEvent(); - +public: QueueHelper eventsIds; QString source; QString destination; - - private: - EventMoveJob * const q; }; -EventMoveJob::Private::Private(EventMoveJob *parent): - q(parent) -{ -} - -void EventMoveJob::Private::processNextEvent() -{ - if (eventsIds.atEnd()) { - q->emitFinished(); - return; - } - - const QString eventId = eventsIds.current(); - const QUrl url = CalendarService::moveEventUrl(source, destination, eventId); - QNetworkRequest request(url); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); - - QStringList headers; - auto rawHeaderList = request.rawHeaderList(); - headers.reserve(rawHeaderList.size()); - for (const QByteArray &str : qAsConst(rawHeaderList)) { - headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); - } - - q->enqueueRequest(request); -} - EventMoveJob::EventMoveJob(const EventPtr &event, const QString &sourceCalendarId, const QString &destinationCalendarId, const AccountPtr &account, QObject *parent): ModifyJob(account, parent), - d(new Private(this)) + d(new Private()) { d->eventsIds << event->id(); d->source = sourceCalendarId; d->destination = destinationCalendarId; } EventMoveJob::EventMoveJob(const EventsList &events, const QString &sourceCalendarId, const QString &destinationCalendarId, const AccountPtr &account, QObject *parent): ModifyJob(account, parent), - d(new Private(this)) + d(new Private()) { for (const EventPtr &event : events) { d->eventsIds << event->id(); } d->source = sourceCalendarId; d->destination = destinationCalendarId; } EventMoveJob::EventMoveJob(const QString &eventId, const QString &sourceCalendarId, const QString &destinationCalendarId, const AccountPtr &account, QObject *parent): ModifyJob(account, parent), - d(new Private(this)) + d(new Private()) { d->eventsIds << eventId; d->source = sourceCalendarId; d->destination = destinationCalendarId; } EventMoveJob::EventMoveJob(const QStringList &eventsIds, const QString &sourceCalendarId, const QString &destinationCalendarId, const AccountPtr &account, QObject *parent): ModifyJob(account, parent), - d(new Private(this)) + d(new Private()) { d->eventsIds = eventsIds; d->source = sourceCalendarId; d->destination = destinationCalendarId; } -EventMoveJob::~EventMoveJob() -{ - delete d; -} +EventMoveJob::~EventMoveJob() = default; void EventMoveJob::start() { - d->processNextEvent(); + if (d->eventsIds.atEnd()) { + emitFinished(); + return; + } + + const QString eventId = d->eventsIds.current(); + const auto request = CalendarService::prepareRequest(CalendarService::moveEventUrl(d->source, d->destination, eventId)); + + enqueueRequest(request); } void EventMoveJob::dispatchRequest(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data, const QString &contentType) { Q_UNUSED(data) Q_UNUSED(contentType) accessManager->post(request, QByteArray()); } KGAPI2::ObjectsList EventMoveJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); ObjectsList items; if (ct != KGAPI2::JSON) { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } items << CalendarService::JSONToEvent(rawData).dynamicCast(); d->eventsIds.currentProcessed(); // Enqueue next item or finish - d->processNextEvent(); + start(); return items; } diff --git a/src/calendar/eventmovejob.h b/src/calendar/eventmovejob.h index 8a0ebc9..747460b 100644 --- a/src/calendar/eventmovejob.h +++ b/src/calendar/eventmovejob.h @@ -1,146 +1,148 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KGAPI2_EVENTMOVEJOB_H #define KGAPI2_EVENTMOVEJOB_H #include "modifyjob.h" #include "kgapicalendar_export.h" +#include + namespace KGAPI2 { /** * @brief A job that moves events between given calendars * * @author Daniel Vrátil * @since 2.0 */ class KGAPICALENDAR_EXPORT EventMoveJob : public KGAPI2::ModifyJob { Q_OBJECT public: /** * @brief Constructs a job that will move given \p event from a calendar * with \p sourceCalendarId to calendar with \p destinationCalendarId * * @param event Event to move * @param sourceCalendarId ID of calendar where the event is currently stored * @param destinationCalendarId ID of calendar where to move the event * @param account Account to authenticate the request * @param parent */ explicit EventMoveJob(const EventPtr &event, const QString &sourceCalendarId, const QString &destinationCalendarId, const AccountPtr &account, QObject *parent = nullptr); /** * @brief Constructs a job that will move given \p events from a calendar * with \p sourceCalendarId to calendar with \p destinationCalendarId * * @param events Events to move * @param sourceCalendarId ID of calendar where the events are currently stored * @param destinationCalendarId ID of calendar where to move the events * @param account Account to authenticate the request * @param parent */ explicit EventMoveJob(const EventsList &events, const QString &sourceCalendarId, const QString &destinationCalendarId, const AccountPtr &account, QObject *parent = nullptr); /** * @brief Constructs a job that will move event with given \p eventId from a * calendar with \p sourceCalendarId to calendar * with \p destinationCalendarId * * @param eventId ID of event to move * @param sourceCalendarId ID of calendar where the event is currently stored * @param destinationCalendarId ID of calendar where to move the event * @param account Account to authenticate the request * @param parent */ explicit EventMoveJob(const QString &eventId, const QString &sourceCalendarId, const QString &destinationCalendarId, const AccountPtr &account, QObject *parent = nullptr); /** * @brief Constructs a job that will move events with given \p eventsIds * from a calendar with \p sourceCalendarId to calendar * with \p destinationCalendarId * * @param eventsIds IDs of events to move * @param sourceCalendarId ID of calendar where the events are currently stored * @param destinationCalendarId ID of calendar where to move the events * @param account Account to authenticate the request * @param parent */ explicit EventMoveJob(const QStringList &eventsIds, const QString &sourceCalendarId, const QString &destinationCalendarId, const AccountPtr &account, QObject *parent = nullptr); /** * @brief Destructor */ ~EventMoveJob() override; protected: /** * @brief KGAPI2::Job::start implementation */ void start() override; /** * @brief KGAPI2::Job::dispatchRequest implementation * * @param accessManager * @param request * @param data * @param contentType */ void dispatchRequest(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data, const QString &contentType) override; /** * @brief KGAPI2::Job::handleReplyWithItems implementation * * @param reply * @param rawData */ KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } // namespace KGAPI2 #endif // KGAPI2_EVENTMOVEJOB_H diff --git a/src/calendar/freebusyqueryjob.cpp b/src/calendar/freebusyqueryjob.cpp index 3ed2f66..79dc71b 100644 --- a/src/calendar/freebusyqueryjob.cpp +++ b/src/calendar/freebusyqueryjob.cpp @@ -1,141 +1,137 @@ /* * Copyright 2015 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "freebusyqueryjob.h" #include "calendarservice.h" #include "utils.h" #include "account.h" #include #include #include #include #include using namespace KGAPI2; class Q_DECL_HIDDEN FreeBusyQueryJob::Private { public: Private(const QString &id, const QDateTime &timeMin, const QDateTime &timeMax) : id(id) , timeMin(timeMin) , timeMax(timeMax) {} QString id; QDateTime timeMin; QDateTime timeMax; FreeBusyQueryJob::BusyRangeList busy; }; FreeBusyQueryJob::FreeBusyQueryJob(const QString &id, const QDateTime &timeMin, const QDateTime &timeMax, const AccountPtr &account, QObject *parent) : FetchJob(account, parent) , d(new FreeBusyQueryJob::Private(id, timeMin, timeMax)) { } -FreeBusyQueryJob::~FreeBusyQueryJob() -{ - delete d; -} +FreeBusyQueryJob::~FreeBusyQueryJob() = default; FreeBusyQueryJob::BusyRangeList FreeBusyQueryJob::busy() const { return d->busy; } QString FreeBusyQueryJob::id() const { return d->id; } QDateTime FreeBusyQueryJob::timeMin() const { return d->timeMin; } QDateTime FreeBusyQueryJob::timeMax() const { return d->timeMax; } void FreeBusyQueryJob::start() { QVariantMap requestData({ { QStringLiteral("timeMin"), Utils::rfc3339DateToString(d->timeMin) }, { QStringLiteral("timeMax"), Utils::rfc3339DateToString(d->timeMax) }, - { QStringLiteral("items"), + { QStringLiteral("items"), QVariantList({ QVariantMap({ { QStringLiteral("id"), d->id } }) }) }}); QJsonDocument document = QJsonDocument::fromVariant(requestData); const QByteArray json = document.toJson(QJsonDocument::Compact); - QNetworkRequest request(CalendarService::freeBusyQueryUrl()); - request.setRawHeader("GData-Version", CalendarService::APIVersion().toLatin1()); + const auto request = CalendarService::prepareRequest(CalendarService::freeBusyQueryUrl()); enqueueRequest(request, json, QStringLiteral("application/json")); } void FreeBusyQueryJob::dispatchRequest(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data, const QString &contentType) { QNetworkRequest r = request; if (!r.hasRawHeader("Content-Type")) { r.setHeader(QNetworkRequest::ContentTypeHeader, contentType); } accessManager->post(r, data); } void FreeBusyQueryJob::handleReply(const QNetworkReply *reply, const QByteArray &rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); if (ct == KGAPI2::JSON) { const QJsonDocument document = QJsonDocument::fromJson(rawData); const QVariantMap data = document.toVariant().toMap(); const QVariantMap cals = data[QStringLiteral("calendars")].toMap(); const QVariantMap cal = cals[d->id].toMap(); if (cal.contains(QLatin1String("errors"))) { setError(KGAPI2::NotFound); setErrorString(tr("FreeBusy information is not available")); } else { const QVariantList busyList = cal[QStringLiteral("busy")].toList(); for (const QVariant &busyV : busyList) { const QVariantMap busy = busyV.toMap(); - d->busy << BusyRange{ + d->busy << BusyRange{ Utils::rfc3339DateFromString(busy[QStringLiteral("start")].toString()), Utils::rfc3339DateFromString(busy[QStringLiteral("end")].toString()) }; } } } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); } emitFinished(); } diff --git a/src/calendar/freebusyqueryjob.h b/src/calendar/freebusyqueryjob.h index 31b5952..c86ca48 100644 --- a/src/calendar/freebusyqueryjob.h +++ b/src/calendar/freebusyqueryjob.h @@ -1,79 +1,80 @@ /* * Copyright 2015 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KGAPI2_CALENDAR_FREEBUSYQUERYJOB_H #define KGAPI2_CALENDAR_FREEBUSYQUERYJOB_H #include "fetchjob.h" #include "kgapicalendar_export.h" #include #include +#include namespace KGAPI2 { class KGAPICALENDAR_EXPORT FreeBusyQueryJob : public KGAPI2::FetchJob { Q_OBJECT public: struct BusyRange { - BusyRange() {}; + BusyRange() = default; BusyRange(const QDateTime &busyStart, const QDateTime &busyEnd) : busyStart(busyStart), busyEnd(busyEnd) {} bool operator==(const BusyRange &other) const { return busyStart == other.busyStart && busyEnd == other.busyEnd; } QDateTime busyStart; QDateTime busyEnd; }; typedef QVector BusyRangeList; - explicit FreeBusyQueryJob(const QString &id, + explicit FreeBusyQueryJob(const QString &id, const QDateTime &timeMin, const QDateTime &timeMax, const AccountPtr &account, QObject* parent = nullptr); - ~FreeBusyQueryJob(); + ~FreeBusyQueryJob() override; QString id() const; QDateTime timeMin() const; QDateTime timeMax() const; BusyRangeList busy() const; protected: void start() override; void dispatchRequest(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data, const QString &contentType) override; void handleReply(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; - Private * const d; + QScopedPointer const d; friend class Private; }; } #endif // KGAPI2_CALENDAR_FREEBUSYQUERYJOB_H diff --git a/src/calendar/reminder.cpp b/src/calendar/reminder.cpp index 939710e..c471dd8 100644 --- a/src/calendar/reminder.cpp +++ b/src/calendar/reminder.cpp @@ -1,118 +1,97 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "reminder.h" #include "../debug.h" using namespace KGAPI2; using namespace KCalendarCore; class Q_DECL_HIDDEN Reminder::Private { - public: - Private(); - Private(const Private &other); - ~Private() {} - - Alarm::Type type; +public: + Alarm::Type type = Alarm::Invalid; Duration offset; }; -Reminder::Private::Private(): - type(Alarm::Invalid) -{ -} - -Reminder::Private::Private(const Private &other): - type(other.type), - offset(other.offset) -{ -} - Reminder::Reminder(): d(new Private) { } -Reminder::Reminder (const Alarm::Type &type, const Duration& startOffset): +Reminder::Reminder(const Alarm::Type &type, const Duration& startOffset): d(new Private) { d->type = type; d->offset = startOffset; } -Reminder::Reminder (const Reminder& other): +Reminder::Reminder(const Reminder& other): d(new Private(*(other.d))) { } -Reminder::~Reminder() -{ - delete d; -} +Reminder::~Reminder() = default; bool Reminder::operator==(const Reminder &other) const { if (d->type != other.d->type) { qCDebug(KGAPIDebug) << "Types don't match"; return false; } if (d->offset != other.d->offset) { qCDebug(KGAPIDebug) << "Offsets don't match"; return false; } return true; } - -void Reminder::setType (Alarm::Type type) +void Reminder::setType(Alarm::Type type) { d->type = type; } Alarm::Type Reminder::type() const { return d->type; } -void Reminder::setStartOffset (const Duration& startOffset) +void Reminder::setStartOffset(const Duration &startOffset) { d->offset = startOffset; } Duration Reminder::startOffset() const { return d->offset; } // In LibKGAPI1 we return AlarmPtr -Alarm* Reminder::toAlarm (Incidence* incidence) const +Alarm *Reminder::toAlarm(Incidence *incidence) const { - Alarm* alarm = new Alarm(incidence); - + auto alarm = new Alarm(incidence); alarm->setType(d->type); alarm->setStartOffset(d->offset); - return alarm; } diff --git a/src/calendar/reminder.h b/src/calendar/reminder.h index 1fdef88..137272b 100644 --- a/src/calendar/reminder.h +++ b/src/calendar/reminder.h @@ -1,109 +1,111 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 6 of version 3 of the license. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_REMINDER_H #define LIBKGAPI2_REMINDER_H #include "object.h" #include "types.h" #include "kgapicalendar_export.h" #include #include +#include + namespace KGAPI2 { /** * @brief Represents a default calendar reminder. * * @author Daniel Vrátil * @since 0.4 */ class KGAPICALENDAR_EXPORT Reminder { public: /** * @brief Constructor */ explicit Reminder(); /** * @brief Constructor * * @param type Type of the reminder (email, notification, etc.) * @param startOffset How long before the event should the reminder be shown */ - explicit Reminder( const KCalendarCore::Alarm::Type &type, - const KCalendarCore::Duration &startOffset = KCalendarCore::Duration( 0 ) ); + explicit Reminder(const KCalendarCore::Alarm::Type &type, + const KCalendarCore::Duration &startOffset = KCalendarCore::Duration(0)); /** * @brief Copy constructor */ - Reminder( const Reminder &other ); + Reminder(const Reminder &other); /** * @brief Destructor */ virtual ~Reminder(); bool operator==(const Reminder &other) const; /** * @brief Returns type of the reminder */ KCalendarCore::Alarm::Type type() const; /** * @brief Sets type of the reminder * * @param type */ - void setType(KCalendarCore::Alarm::Type type ); + void setType(KCalendarCore::Alarm::Type type); /** * @brief Returns how long before the event should reminder be shown */ KCalendarCore::Duration startOffset() const; /** * @brief Sets how long before the event should reminder be shown */ - void setStartOffset( const KCalendarCore::Duration &startOffset ); + void setStartOffset(const KCalendarCore::Duration &startOffset); /** * @brief Converts the reminder to a KCalendarCore::Alarm * * @param incidence An incidence on which the reminder should be applied * @return Returns a new KCalendarCore::Alarm */ - KCalendarCore::Alarm *toAlarm( KCalendarCore::Incidence *incidence ) const; + KCalendarCore::Alarm *toAlarm(KCalendarCore::Incidence *incidence) const; private: class Private; - Private *const d; + QScopedPointer const d; }; } // namespace KGAPI2 #endif // LIBKGAPI2_REMINDER_H