From 38b878589ffb08d2272169d2529703e887933be9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 17 Dec 2013 22:03:12 -0600 Subject: add planner + tests --- src/planner-eds.cpp | 419 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 src/planner-eds.cpp (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp new file mode 100644 index 0000000..804d98e --- /dev/null +++ b/src/planner-eds.cpp @@ -0,0 +1,419 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Charles Kerr + */ + +#include + +#include + +#include +#include +#include +#include + +namespace unity { +namespace indicator { +namespace datetime { + +/**** +***** +****/ + +G_DEFINE_QUARK ("source-client", source_client) + + +class PlannerEds::Impl +{ +public: + + Impl (PlannerEds& owner): + owner_(owner), + cancellable_(g_cancellable_new()) + { + e_source_registry_new (cancellable_, on_source_registry_ready, this); + + owner_.time.changed().connect([this](const DateTime& dt) { + g_message ("planner's datetime property changed to %s; calling rebuildSoon()", g_date_time_format(dt.get(), "%F %T")); + rebuildSoon(); + }); + + rebuildSoon(); + } + + ~Impl() + { + g_cancellable_cancel (cancellable_); + g_clear_object (&cancellable_); + + if (rebuild_tag_) + g_source_remove (rebuild_tag_); + + if (source_registry_) + g_signal_handlers_disconnect_by_data (source_registry_, this); + g_clear_object (&source_registry_); + } + +private: + + static void on_source_registry_ready (GObject* /*source*/, GAsyncResult* res, gpointer gself) + { + GError * error = NULL; + auto r = e_source_registry_new_finish (res, &error); + if (error != NULL) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("indicator-datetime cannot show EDS appointments: %s", error->message); + + g_error_free (error); + } + else + { + auto self = static_cast(gself); + + g_signal_connect (r, "source-added", G_CALLBACK(on_source_added), self); + g_signal_connect (r, "source-removed", G_CALLBACK(on_source_removed), self); + g_signal_connect (r, "source-changed", G_CALLBACK(on_source_changed), self); + g_signal_connect (r, "source-disabled", G_CALLBACK(on_source_disabled), self); + g_signal_connect (r, "source-enabled", G_CALLBACK(on_source_enabled), self); + + self->source_registry_ = r; + + GList* sources = e_source_registry_list_sources (r, E_SOURCE_EXTENSION_CALENDAR); + for (auto l=sources; l!=nullptr; l=l->next) + on_source_added (r, E_SOURCE(l->data), gself); + g_list_free_full (sources, g_object_unref); + } + } + + static void on_source_added(ESourceRegistry* registry, ESource* source, gpointer gself) + { + auto self = static_cast(gself); + + self->sources_.insert(E_SOURCE(g_object_ref(source))); + + if (e_source_get_enabled(source)) + on_source_enabled(registry, source, gself); + } + + static void on_source_enabled (ESourceRegistry* /*registry*/, ESource* source, gpointer gself) + { + auto self = static_cast(gself); + + e_cal_client_connect (source, + E_CAL_CLIENT_SOURCE_TYPE_EVENTS, + self->cancellable_, + on_client_connected, + gself); + } + + static void on_client_connected (GObject* /*source*/, GAsyncResult * res, gpointer gself) + { + GError * error = nullptr; + EClient * client = e_cal_client_connect_finish (res, &error); + if (error) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("indicator-datetime cannot connect to EDS source: %s", error->message); + + g_error_free (error); + } + else + { + // we've got a new connected ECalClient, so store it & notify clients + g_object_set_qdata_full (G_OBJECT(e_client_get_source(client)), + source_client_quark(), + client, + g_object_unref); + + g_message ("client connected; calling rebuildSoon()"); + static_cast(gself)->rebuildSoon(); + } + } + + static void on_source_disabled (ESourceRegistry* /*registry*/, ESource* source, gpointer gself) + { + gpointer e_cal_client; + + // if this source has a connected ECalClient, remove it & notify clients + if ((e_cal_client = g_object_steal_qdata (G_OBJECT(source), source_client_quark()))) + { + g_object_unref (e_cal_client); + + g_message ("source disabled; calling rebuildSoon()"); + static_cast(gself)->rebuildSoon(); + } + } + + static void on_source_removed (ESourceRegistry* registry, ESource* source, gpointer gself) + { + auto self = static_cast(gself); + + on_source_disabled (registry, source, gself); + + self->sources_.erase (source); + g_object_unref (source); + } + + static void on_source_changed (ESourceRegistry* /*registry*/, ESource* /*source*/, gpointer gself) + { + g_message ("source changed; calling rebuildSoon()"); + static_cast(gself)->rebuildSoon(); + } + +private: + + typedef std::function&)> appointment_func; + + struct Task + { + Impl* impl_; + appointment_func func_; + std::vector appointments_; + Task (Impl* impl, const appointment_func& func): impl_(impl), func_(func) {} + }; + + struct AppointmentSubtask + { + std::shared_ptr task_; + ECalClient * client_; + std::string color_; + AppointmentSubtask (const std::shared_ptr& task, ECalClient* client, const char* color): + task_(task), client_(client), color_(color) {} + }; + + void rebuildSoon() + { + const static guint ARBITRARY_INTERVAL_SECS = 2; + + if (rebuild_tag_ == 0) + rebuild_tag_ = g_timeout_add_seconds (ARBITRARY_INTERVAL_SECS, rebuildNowStatic, this); + } + + static gboolean rebuildNowStatic (gpointer gself) + { + auto self = static_cast(gself); + self->rebuild_tag_ = 0; + self->rebuildNow(); + return G_SOURCE_REMOVE; + } + + void rebuildNow() + { + GDateTime* calendar_date = owner_.time.get().get(); + GDateTime* begin; + GDateTime* end; + int y, m, d; + g_message ("in rebuildNow"); + + // get all the appointments in the calendar month + g_date_time_get_ymd(calendar_date, &y, &m, &d); + begin = g_date_time_new_local(y, m, 1, 0, 0, 0.1); + end = g_date_time_new_local(y, m, g_date_get_days_in_month(GDateMonth(m),GDateYear(y)), 23, 59, 59.9); + if (begin && end) + { + getAppointments(begin, end, [this](const std::vector& appointments) { + g_message ("got %d appointments in this calendar month", (int)appointments.size()); + }); + } + g_clear_pointer(&begin, g_date_time_unref); + g_clear_pointer(&end, g_date_time_unref); + + // get the upcoming appointments + begin = g_date_time_ref(calendar_date); + end = g_date_time_add_months(begin, 1); + if (begin && end) + { + getAppointments(begin, end, [this](const std::vector& appointments) { + g_message ("got %d upcoming appointments", (int)appointments.size()); + }); + } + g_clear_pointer(&begin, g_date_time_unref); + g_clear_pointer(&end, g_date_time_unref); + g_clear_pointer(&calendar_date, g_date_time_unref); + } + + void getAppointments(GDateTime* begin_dt, GDateTime* end_dt, appointment_func func) + { + const auto begin = g_date_time_to_unix(begin_dt); + const auto end = g_date_time_to_unix(end_dt); + g_message ("getting all appointments from [%s ... %s]", g_date_time_format (begin_dt, "%F %T"), + g_date_time_format (end_dt, "%F %T")); + + /** + *** init the default timezone + **/ + + icaltimezone * default_timezone = nullptr; + + const auto tz = g_date_time_get_timezone_abbreviation (owner_.time.get().get()); + g_message ("%s tz is %s", G_STRLOC, tz); + if (tz && *tz) + { + default_timezone = icaltimezone_get_builtin_timezone (tz); + + if (default_timezone == nullptr) // maybe str is a tzid? + default_timezone = icaltimezone_get_builtin_timezone_from_tzid (tz); + + g_debug ("default_timezone is %p", default_timezone); + } + + /** + *** walk through the sources to build the appointment list + **/ + + std::shared_ptr main_task (new Task(this, func), [](Task* task){ + g_message("time to delete task %p", task); + task->func_(task->appointments_); + }); + + for (auto& source : sources_) + { + auto client = E_CAL_CLIENT (g_object_get_qdata (G_OBJECT(source), source_client_quark())); + if (client == nullptr) + continue; + + if (default_timezone != nullptr) + e_cal_client_set_default_timezone (client, default_timezone); + + // start a new subtask to enumerate all the components in this client. + auto extension = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR); + const auto color = e_source_selectable_get_color (E_SOURCE_SELECTABLE(extension)); + g_message ("calling e_cal_client_generate_instances for %p", client); + e_cal_client_generate_instances (client, + begin, + end, + cancellable_, + my_get_appointments_foreach, + new AppointmentSubtask (main_task, client, color), + [](gpointer g){delete static_cast(g);}); + } + } + + struct UrlSubtask + { + std::shared_ptr task_; + Appointment appointment_; + UrlSubtask (const std::shared_ptr& task, const Appointment& appointment): task_(task), appointment_(appointment) {} + }; + + static gboolean + my_get_appointments_foreach (ECalComponent* component, + time_t begin, + time_t end, + gpointer gsubtask) + { + const auto vtype = e_cal_component_get_vtype(component); + auto subtask = static_cast(gsubtask); + + if ((vtype == E_CAL_COMPONENT_EVENT) || (vtype == E_CAL_COMPONENT_TODO)) + { + const gchar* uid = NULL; + e_cal_component_get_uid (component, &uid); + + auto status = ICAL_STATUS_NONE; + e_cal_component_get_status (component, &status); + + if ((uid != NULL) && + (status != ICAL_STATUS_COMPLETED) && + (status != ICAL_STATUS_CANCELLED)) + { + Appointment appointment; + + /* Determine whether this is a recurring event. + NB: icalrecurrencetype supports complex recurrence patterns; + however, since design only allows daily recurrence, + that's all we support here. */ + GSList * recur_list; + e_cal_component_get_rrule_list (component, &recur_list); + for (auto l=recur_list; l!=NULL; l=l->next) + { + const auto recur = static_cast(l->data); + appointment.is_daily |= ((recur->freq == ICAL_DAILY_RECURRENCE) + && (recur->interval == 1)); + } + e_cal_component_free_recur_list (recur_list); + + ECalComponentText text; + text.value = ""; + e_cal_component_get_summary (component, &text); + + appointment.begin = g_date_time_new_from_unix_local (begin); + appointment.end = g_date_time_new_from_unix_local (end); + appointment.color = subtask->color_; + appointment.is_event = vtype == E_CAL_COMPONENT_EVENT; + appointment.summary = text.value; + appointment.uid = uid; + + GList * alarm_uids = e_cal_component_get_alarm_uids (component); + appointment.has_alarms = alarm_uids != nullptr; + cal_obj_uid_list_free (alarm_uids); + + e_cal_client_get_attachment_uris (subtask->client_, + uid, + NULL, + subtask->task_->impl_->cancellable_, + on_appointment_uris_ready, + new UrlSubtask(subtask->task_, appointment)); + } + } + + return G_SOURCE_CONTINUE; + } + + static void on_appointment_uris_ready (GObject* client, GAsyncResult* res, gpointer gsubtask) + { + auto subtask = static_cast(gsubtask); + + GSList * uris = nullptr; + GError * error = nullptr; + e_cal_client_get_attachment_uris_finish (E_CAL_CLIENT(client), res, &uris, &error); + if (error != NULL) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Error getting appointment uris: %s", error->message); + + g_error_free (error); + } + else if (uris != NULL) + { + subtask->appointment_.url = (const char*) uris->data; // copy the first URL + g_debug ("found url '%s' for appointment '%s'", subtask->appointment_.url.c_str(), subtask->appointment_.summary.c_str()); + e_client_util_free_string_slist (uris); + } + + g_message ("adding appointment '%s' '%s'", subtask->appointment_.summary.c_str(), subtask->appointment_.url.c_str()); + subtask->task_->appointments_.push_back (subtask->appointment_); + delete subtask; + } + +private: + + PlannerEds& owner_; + std::set sources_; + GCancellable * cancellable_ = nullptr; + ESourceRegistry * source_registry_ = nullptr; + guint rebuild_tag_ = 0; +}; + +PlannerEds::PlannerEds(): impl_(new Impl(*this)) {} + +PlannerEds::~PlannerEds() =default; + +} // namespace datetime +} // namespace indicator +} // namespace unity -- cgit v1.2.3 From ee64bb2698adfe27e55615a8856b0e2c78ad8469 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 14 Jan 2014 23:07:10 -0600 Subject: Function: add fully-tested ActionGroups, per-profile Menus, state object. Form: Add code annotations/comments. Remove dead code. Use Mir style guide. Todo: GSettings toggles, sync with new dbus-test-runner API, get GNOME Panel building again --- src/planner-eds.cpp | 283 ++++++++++++++++++++++++++-------------------------- 1 file changed, 142 insertions(+), 141 deletions(-) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index 804d98e..6abaf3e 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -34,21 +34,21 @@ namespace datetime { ***** ****/ -G_DEFINE_QUARK ("source-client", source_client) +G_DEFINE_QUARK("source-client", source_client) class PlannerEds::Impl { public: - Impl (PlannerEds& owner): - owner_(owner), - cancellable_(g_cancellable_new()) + Impl(PlannerEds& owner): + m_owner(owner), + m_cancellable(g_cancellable_new()) { - e_source_registry_new (cancellable_, on_source_registry_ready, this); + e_source_registry_new(m_cancellable, on_source_registry_ready, this); - owner_.time.changed().connect([this](const DateTime& dt) { - g_message ("planner's datetime property changed to %s; calling rebuildSoon()", g_date_time_format(dt.get(), "%F %T")); + m_owner.time.changed().connect([this](const DateTime& dt) { + g_message("planner's datetime property changed to %s; calling rebuildSoon()", g_date_time_format(dt.get(), "%F %T")); rebuildSoon(); }); @@ -57,46 +57,46 @@ public: ~Impl() { - g_cancellable_cancel (cancellable_); - g_clear_object (&cancellable_); + g_cancellable_cancel(m_cancellable); + g_clear_object(&m_cancellable); - if (rebuild_tag_) - g_source_remove (rebuild_tag_); + if (m_rebuild_tag) + g_source_remove(m_rebuild_tag); - if (source_registry_) - g_signal_handlers_disconnect_by_data (source_registry_, this); - g_clear_object (&source_registry_); + if (m_source_registry) + g_signal_handlers_disconnect_by_data(m_source_registry, this); + g_clear_object(&m_source_registry); } private: - static void on_source_registry_ready (GObject* /*source*/, GAsyncResult* res, gpointer gself) + static void on_source_registry_ready(GObject* /*source*/, GAsyncResult* res, gpointer gself) { - GError * error = NULL; - auto r = e_source_registry_new_finish (res, &error); - if (error != NULL) + GError * error = nullptr; + auto r = e_source_registry_new_finish(res, &error); + if (error != nullptr) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("indicator-datetime cannot show EDS appointments: %s", error->message); + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning("indicator-datetime cannot show EDS appointments: %s", error->message); - g_error_free (error); + g_error_free(error); } else { auto self = static_cast(gself); - g_signal_connect (r, "source-added", G_CALLBACK(on_source_added), self); - g_signal_connect (r, "source-removed", G_CALLBACK(on_source_removed), self); - g_signal_connect (r, "source-changed", G_CALLBACK(on_source_changed), self); - g_signal_connect (r, "source-disabled", G_CALLBACK(on_source_disabled), self); - g_signal_connect (r, "source-enabled", G_CALLBACK(on_source_enabled), self); + g_signal_connect(r, "source-added", G_CALLBACK(on_source_added), self); + g_signal_connect(r, "source-removed", G_CALLBACK(on_source_removed), self); + g_signal_connect(r, "source-changed", G_CALLBACK(on_source_changed), self); + g_signal_connect(r, "source-disabled", G_CALLBACK(on_source_disabled), self); + g_signal_connect(r, "source-enabled", G_CALLBACK(on_source_enabled), self); - self->source_registry_ = r; + self->m_source_registry = r; - GList* sources = e_source_registry_list_sources (r, E_SOURCE_EXTENSION_CALENDAR); + GList* sources = e_source_registry_list_sources(r, E_SOURCE_EXTENSION_CALENDAR); for (auto l=sources; l!=nullptr; l=l->next) - on_source_added (r, E_SOURCE(l->data), gself); - g_list_free_full (sources, g_object_unref); + on_source_added(r, E_SOURCE(l->data), gself); + g_list_free_full(sources, g_object_unref); } } @@ -104,74 +104,74 @@ private: { auto self = static_cast(gself); - self->sources_.insert(E_SOURCE(g_object_ref(source))); + self->m_sources.insert(E_SOURCE(g_object_ref(source))); if (e_source_get_enabled(source)) on_source_enabled(registry, source, gself); } - static void on_source_enabled (ESourceRegistry* /*registry*/, ESource* source, gpointer gself) + static void on_source_enabled(ESourceRegistry* /*registry*/, ESource* source, gpointer gself) { auto self = static_cast(gself); - e_cal_client_connect (source, - E_CAL_CLIENT_SOURCE_TYPE_EVENTS, - self->cancellable_, - on_client_connected, - gself); + e_cal_client_connect(source, + E_CAL_CLIENT_SOURCE_TYPE_EVENTS, + self->m_cancellable, + on_client_connected, + gself); } - static void on_client_connected (GObject* /*source*/, GAsyncResult * res, gpointer gself) + static void on_client_connected(GObject* /*source*/, GAsyncResult * res, gpointer gself) { GError * error = nullptr; - EClient * client = e_cal_client_connect_finish (res, &error); + EClient * client = e_cal_client_connect_finish(res, &error); if (error) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("indicator-datetime cannot connect to EDS source: %s", error->message); + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning("indicator-datetime cannot connect to EDS source: %s", error->message); - g_error_free (error); + g_error_free(error); } else { // we've got a new connected ECalClient, so store it & notify clients - g_object_set_qdata_full (G_OBJECT(e_client_get_source(client)), - source_client_quark(), - client, - g_object_unref); + g_object_set_qdata_full(G_OBJECT(e_client_get_source(client)), + source_client_quark(), + client, + g_object_unref); - g_message ("client connected; calling rebuildSoon()"); + g_message("client connected; calling rebuildSoon()"); static_cast(gself)->rebuildSoon(); } } - static void on_source_disabled (ESourceRegistry* /*registry*/, ESource* source, gpointer gself) + static void on_source_disabled(ESourceRegistry* /*registry*/, ESource* source, gpointer gself) { gpointer e_cal_client; // if this source has a connected ECalClient, remove it & notify clients - if ((e_cal_client = g_object_steal_qdata (G_OBJECT(source), source_client_quark()))) + if ((e_cal_client = g_object_steal_qdata(G_OBJECT(source), source_client_quark()))) { - g_object_unref (e_cal_client); + g_object_unref(e_cal_client); - g_message ("source disabled; calling rebuildSoon()"); + g_message("source disabled; calling rebuildSoon()"); static_cast(gself)->rebuildSoon(); } } - static void on_source_removed (ESourceRegistry* registry, ESource* source, gpointer gself) + static void on_source_removed(ESourceRegistry* registry, ESource* source, gpointer gself) { auto self = static_cast(gself); - on_source_disabled (registry, source, gself); + on_source_disabled(registry, source, gself); - self->sources_.erase (source); - g_object_unref (source); + self->m_sources.erase(source); + g_object_unref(source); } - static void on_source_changed (ESourceRegistry* /*registry*/, ESource* /*source*/, gpointer gself) + static void on_source_changed(ESourceRegistry* /*registry*/, ESource* /*source*/, gpointer gself) { - g_message ("source changed; calling rebuildSoon()"); + g_message("source changed; calling rebuildSoon()"); static_cast(gself)->rebuildSoon(); } @@ -181,44 +181,44 @@ private: struct Task { - Impl* impl_; - appointment_func func_; - std::vector appointments_; - Task (Impl* impl, const appointment_func& func): impl_(impl), func_(func) {} + Impl* p; + appointment_func func; + std::vector appointments; + Task(Impl* p_in, const appointment_func& func_in): p(p_in), func(func_in) {} }; struct AppointmentSubtask { - std::shared_ptr task_; - ECalClient * client_; - std::string color_; - AppointmentSubtask (const std::shared_ptr& task, ECalClient* client, const char* color): - task_(task), client_(client), color_(color) {} + std::shared_ptr task; + ECalClient* client; + std::string color; + AppointmentSubtask(const std::shared_ptr& task_in, ECalClient* client_in, const char* color_in): + task(task_in), client(client_in), color(color_in) {} }; void rebuildSoon() { const static guint ARBITRARY_INTERVAL_SECS = 2; - if (rebuild_tag_ == 0) - rebuild_tag_ = g_timeout_add_seconds (ARBITRARY_INTERVAL_SECS, rebuildNowStatic, this); + if (m_rebuild_tag == 0) + m_rebuild_tag = g_timeout_add_seconds(ARBITRARY_INTERVAL_SECS, rebuildNowStatic, this); } - static gboolean rebuildNowStatic (gpointer gself) + static gboolean rebuildNowStatic(gpointer gself) { auto self = static_cast(gself); - self->rebuild_tag_ = 0; + self->m_rebuild_tag = 0; self->rebuildNow(); return G_SOURCE_REMOVE; } void rebuildNow() { - GDateTime* calendar_date = owner_.time.get().get(); + auto calendar_date = m_owner.time.get().get(); GDateTime* begin; GDateTime* end; int y, m, d; - g_message ("in rebuildNow"); + g_message("in rebuildNow"); // get all the appointments in the calendar month g_date_time_get_ymd(calendar_date, &y, &m, &d); @@ -227,7 +227,7 @@ private: if (begin && end) { getAppointments(begin, end, [this](const std::vector& appointments) { - g_message ("got %d appointments in this calendar month", (int)appointments.size()); + g_message("got %d appointments in this calendar month", (int)appointments.size()); }); } g_clear_pointer(&begin, g_date_time_unref); @@ -239,7 +239,7 @@ private: if (begin && end) { getAppointments(begin, end, [this](const std::vector& appointments) { - g_message ("got %d upcoming appointments", (int)appointments.size()); + g_message("got %d upcoming appointments", (int)appointments.size()); }); } g_clear_pointer(&begin, g_date_time_unref); @@ -251,8 +251,8 @@ private: { const auto begin = g_date_time_to_unix(begin_dt); const auto end = g_date_time_to_unix(end_dt); - g_message ("getting all appointments from [%s ... %s]", g_date_time_format (begin_dt, "%F %T"), - g_date_time_format (end_dt, "%F %T")); + g_message("getting all appointments from [%s ... %s]", g_date_time_format(begin_dt, "%F %T"), + g_date_time_format(end_dt, "%F %T")); /** *** init the default timezone @@ -260,75 +260,76 @@ private: icaltimezone * default_timezone = nullptr; - const auto tz = g_date_time_get_timezone_abbreviation (owner_.time.get().get()); - g_message ("%s tz is %s", G_STRLOC, tz); + const auto tz = g_date_time_get_timezone_abbreviation(m_owner.time.get().get()); + g_message("%s tz is %s", G_STRLOC, tz); if (tz && *tz) { - default_timezone = icaltimezone_get_builtin_timezone (tz); + default_timezone = icaltimezone_get_builtin_timezone(tz); if (default_timezone == nullptr) // maybe str is a tzid? - default_timezone = icaltimezone_get_builtin_timezone_from_tzid (tz); + default_timezone = icaltimezone_get_builtin_timezone_from_tzid(tz); - g_debug ("default_timezone is %p", default_timezone); + g_debug("default_timezone is %p", default_timezone); } /** *** walk through the sources to build the appointment list **/ - std::shared_ptr main_task (new Task(this, func), [](Task* task){ + std::shared_ptr main_task(new Task(this, func), [](Task* task){ g_message("time to delete task %p", task); - task->func_(task->appointments_); + task->func(task->appointments); }); - for (auto& source : sources_) + for (auto& source : m_sources) { - auto client = E_CAL_CLIENT (g_object_get_qdata (G_OBJECT(source), source_client_quark())); + auto client = E_CAL_CLIENT(g_object_get_qdata(G_OBJECT(source), source_client_quark())); if (client == nullptr) continue; if (default_timezone != nullptr) - e_cal_client_set_default_timezone (client, default_timezone); + e_cal_client_set_default_timezone(client, default_timezone); // start a new subtask to enumerate all the components in this client. - auto extension = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR); - const auto color = e_source_selectable_get_color (E_SOURCE_SELECTABLE(extension)); - g_message ("calling e_cal_client_generate_instances for %p", client); - e_cal_client_generate_instances (client, - begin, - end, - cancellable_, - my_get_appointments_foreach, - new AppointmentSubtask (main_task, client, color), - [](gpointer g){delete static_cast(g);}); + auto extension = e_source_get_extension(source, E_SOURCE_EXTENSION_CALENDAR); + const auto color = e_source_selectable_get_color(E_SOURCE_SELECTABLE(extension)); + g_message("calling e_cal_client_generate_instances for %p", client); + e_cal_client_generate_instances(client, + begin, + end, + m_cancellable, + my_get_appointments_foreach, + new AppointmentSubtask (main_task, client, color), + [](gpointer g){delete static_cast(g);}); } } struct UrlSubtask { - std::shared_ptr task_; - Appointment appointment_; - UrlSubtask (const std::shared_ptr& task, const Appointment& appointment): task_(task), appointment_(appointment) {} + std::shared_ptr task; + Appointment appointment; + UrlSubtask(const std::shared_ptr& task_in, const Appointment& appointment_in): + task(task_in), appointment(appointment_in) {} }; static gboolean - my_get_appointments_foreach (ECalComponent* component, - time_t begin, - time_t end, - gpointer gsubtask) + my_get_appointments_foreach(ECalComponent* component, + time_t begin, + time_t end, + gpointer gsubtask) { const auto vtype = e_cal_component_get_vtype(component); auto subtask = static_cast(gsubtask); if ((vtype == E_CAL_COMPONENT_EVENT) || (vtype == E_CAL_COMPONENT_TODO)) { - const gchar* uid = NULL; - e_cal_component_get_uid (component, &uid); + const gchar* uid = nullptr; + e_cal_component_get_uid(component, &uid); auto status = ICAL_STATUS_NONE; - e_cal_component_get_status (component, &status); + e_cal_component_get_status(component, &status); - if ((uid != NULL) && + if ((uid != nullptr) && (status != ICAL_STATUS_COMPLETED) && (status != ICAL_STATUS_CANCELLED)) { @@ -339,78 +340,78 @@ private: however, since design only allows daily recurrence, that's all we support here. */ GSList * recur_list; - e_cal_component_get_rrule_list (component, &recur_list); - for (auto l=recur_list; l!=NULL; l=l->next) + e_cal_component_get_rrule_list(component, &recur_list); + for (auto l=recur_list; l!=nullptr; l=l->next) { const auto recur = static_cast(l->data); appointment.is_daily |= ((recur->freq == ICAL_DAILY_RECURRENCE) && (recur->interval == 1)); } - e_cal_component_free_recur_list (recur_list); + e_cal_component_free_recur_list(recur_list); ECalComponentText text; text.value = ""; - e_cal_component_get_summary (component, &text); + e_cal_component_get_summary(component, &text); - appointment.begin = g_date_time_new_from_unix_local (begin); - appointment.end = g_date_time_new_from_unix_local (end); - appointment.color = subtask->color_; + appointment.begin = g_date_time_new_from_unix_local(begin); + appointment.end = g_date_time_new_from_unix_local(end); + appointment.color = subtask->color; appointment.is_event = vtype == E_CAL_COMPONENT_EVENT; appointment.summary = text.value; appointment.uid = uid; - GList * alarm_uids = e_cal_component_get_alarm_uids (component); + GList * alarm_uids = e_cal_component_get_alarm_uids(component); appointment.has_alarms = alarm_uids != nullptr; - cal_obj_uid_list_free (alarm_uids); - - e_cal_client_get_attachment_uris (subtask->client_, - uid, - NULL, - subtask->task_->impl_->cancellable_, - on_appointment_uris_ready, - new UrlSubtask(subtask->task_, appointment)); + cal_obj_uid_list_free(alarm_uids); + + e_cal_client_get_attachment_uris(subtask->client, + uid, + nullptr, + subtask->task->p->m_cancellable, + on_appointment_uris_ready, + new UrlSubtask(subtask->task, appointment)); } } return G_SOURCE_CONTINUE; } - static void on_appointment_uris_ready (GObject* client, GAsyncResult* res, gpointer gsubtask) + static void on_appointment_uris_ready(GObject* client, GAsyncResult* res, gpointer gsubtask) { auto subtask = static_cast(gsubtask); GSList * uris = nullptr; GError * error = nullptr; - e_cal_client_get_attachment_uris_finish (E_CAL_CLIENT(client), res, &uris, &error); - if (error != NULL) + e_cal_client_get_attachment_uris_finish(E_CAL_CLIENT(client), res, &uris, &error); + if (error != nullptr) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("Error getting appointment uris: %s", error->message); + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning("Error getting appointment uris: %s", error->message); - g_error_free (error); + g_error_free(error); } - else if (uris != NULL) + else if (uris != nullptr) { - subtask->appointment_.url = (const char*) uris->data; // copy the first URL - g_debug ("found url '%s' for appointment '%s'", subtask->appointment_.url.c_str(), subtask->appointment_.summary.c_str()); - e_client_util_free_string_slist (uris); + subtask->appointment.url = (const char*) uris->data; // copy the first URL + g_debug("found url '%s' for appointment '%s'", subtask->appointment.url.c_str(), subtask->appointment.summary.c_str()); + e_client_util_free_string_slist(uris); } - g_message ("adding appointment '%s' '%s'", subtask->appointment_.summary.c_str(), subtask->appointment_.url.c_str()); - subtask->task_->appointments_.push_back (subtask->appointment_); + g_message("adding appointment '%s' '%s'", subtask->appointment.summary.c_str(), subtask->appointment.url.c_str()); + subtask->task->appointments.push_back(subtask->appointment); delete subtask; } private: - PlannerEds& owner_; - std::set sources_; - GCancellable * cancellable_ = nullptr; - ESourceRegistry * source_registry_ = nullptr; - guint rebuild_tag_ = 0; + PlannerEds& m_owner; + std::set m_sources; + GCancellable * m_cancellable = nullptr; + ESourceRegistry * m_source_registry = nullptr; + guint m_rebuild_tag = 0; }; -PlannerEds::PlannerEds(): impl_(new Impl(*this)) {} +PlannerEds::PlannerEds(): p(new Impl(*this)) {} PlannerEds::~PlannerEds() =default; -- cgit v1.2.3 From 83dcdd840483c9183fcd500b0f63d1d011da90bf Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 16 Jan 2014 21:21:55 -0600 Subject: fix minor -Wpedantic warnings --- src/planner-eds.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index 6abaf3e..275a29e 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -269,7 +269,7 @@ private: if (default_timezone == nullptr) // maybe str is a tzid? default_timezone = icaltimezone_get_builtin_timezone_from_tzid(tz); - g_debug("default_timezone is %p", default_timezone); + g_debug("default_timezone is %p", (void*)default_timezone); } /** @@ -277,7 +277,7 @@ private: **/ std::shared_ptr main_task(new Task(this, func), [](Task* task){ - g_message("time to delete task %p", task); + g_message("time to delete task %p", (void*)task); task->func(task->appointments); }); @@ -293,7 +293,7 @@ private: // start a new subtask to enumerate all the components in this client. auto extension = e_source_get_extension(source, E_SOURCE_EXTENSION_CALENDAR); const auto color = e_source_selectable_get_color(E_SOURCE_SELECTABLE(extension)); - g_message("calling e_cal_client_generate_instances for %p", client); + g_message("calling e_cal_client_generate_instances for %p", (void*)client); e_cal_client_generate_instances(client, begin, end, -- cgit v1.2.3 From f0fee18c0baf7ef0fb27351db716ee3708c021c6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 22 Jan 2014 00:41:16 -0600 Subject: copyediting: rename Service as Exporter & tweak comments --- src/planner-eds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index 275a29e..b3f751a 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -48,7 +48,7 @@ public: e_source_registry_new(m_cancellable, on_source_registry_ready, this); m_owner.time.changed().connect([this](const DateTime& dt) { - g_message("planner's datetime property changed to %s; calling rebuildSoon()", g_date_time_format(dt.get(), "%F %T")); + g_message("planner's datetime property changed to %s; calling rebuildSoon()", dt.format("%F %T").c_str()); rebuildSoon(); }); -- cgit v1.2.3 From 0ec1731c28ee208eab98f3ff53bc63cedb527b75 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 22 Jan 2014 07:57:21 -0600 Subject: in PlannerEds, wire in planner.thisMonth and planner.upcoming --- src/planner-eds.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index b3f751a..f7a1d17 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -228,6 +228,7 @@ private: { getAppointments(begin, end, [this](const std::vector& appointments) { g_message("got %d appointments in this calendar month", (int)appointments.size()); + m_owner.thisMonth.set(appointments); }); } g_clear_pointer(&begin, g_date_time_unref); @@ -240,6 +241,7 @@ private: { getAppointments(begin, end, [this](const std::vector& appointments) { g_message("got %d upcoming appointments", (int)appointments.size()); + m_owner.upcoming.set(appointments); }); } g_clear_pointer(&begin, g_date_time_unref); -- cgit v1.2.3 From bf30d05fa9220b3369734c74197ac149c3290af7 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 22 Jan 2014 07:59:05 -0600 Subject: in PlannerEds, replace g_message() console messages with g_debug() --- src/planner-eds.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index f7a1d17..54332ce 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -48,7 +48,7 @@ public: e_source_registry_new(m_cancellable, on_source_registry_ready, this); m_owner.time.changed().connect([this](const DateTime& dt) { - g_message("planner's datetime property changed to %s; calling rebuildSoon()", dt.format("%F %T").c_str()); + g_debug("planner's datetime property changed to %s; calling rebuildSoon()", dt.format("%F %T").c_str()); rebuildSoon(); }); @@ -140,7 +140,7 @@ private: client, g_object_unref); - g_message("client connected; calling rebuildSoon()"); + g_debug("client connected; calling rebuildSoon()"); static_cast(gself)->rebuildSoon(); } } @@ -154,7 +154,7 @@ private: { g_object_unref(e_cal_client); - g_message("source disabled; calling rebuildSoon()"); + g_debug("source disabled; calling rebuildSoon()"); static_cast(gself)->rebuildSoon(); } } @@ -171,7 +171,7 @@ private: static void on_source_changed(ESourceRegistry* /*registry*/, ESource* /*source*/, gpointer gself) { - g_message("source changed; calling rebuildSoon()"); + g_debug("source changed; calling rebuildSoon()"); static_cast(gself)->rebuildSoon(); } @@ -218,7 +218,6 @@ private: GDateTime* begin; GDateTime* end; int y, m, d; - g_message("in rebuildNow"); // get all the appointments in the calendar month g_date_time_get_ymd(calendar_date, &y, &m, &d); @@ -227,7 +226,7 @@ private: if (begin && end) { getAppointments(begin, end, [this](const std::vector& appointments) { - g_message("got %d appointments in this calendar month", (int)appointments.size()); + g_debug("got %d appointments in this calendar month", (int)appointments.size()); m_owner.thisMonth.set(appointments); }); } @@ -240,7 +239,7 @@ private: if (begin && end) { getAppointments(begin, end, [this](const std::vector& appointments) { - g_message("got %d upcoming appointments", (int)appointments.size()); + g_debug("got %d upcoming appointments", (int)appointments.size()); m_owner.upcoming.set(appointments); }); } @@ -253,7 +252,7 @@ private: { const auto begin = g_date_time_to_unix(begin_dt); const auto end = g_date_time_to_unix(end_dt); - g_message("getting all appointments from [%s ... %s]", g_date_time_format(begin_dt, "%F %T"), + g_debug("getting all appointments from [%s ... %s]", g_date_time_format(begin_dt, "%F %T"), g_date_time_format(end_dt, "%F %T")); /** @@ -263,7 +262,7 @@ private: icaltimezone * default_timezone = nullptr; const auto tz = g_date_time_get_timezone_abbreviation(m_owner.time.get().get()); - g_message("%s tz is %s", G_STRLOC, tz); + g_debug("%s tz is %s", G_STRLOC, tz); if (tz && *tz) { default_timezone = icaltimezone_get_builtin_timezone(tz); @@ -279,7 +278,7 @@ private: **/ std::shared_ptr main_task(new Task(this, func), [](Task* task){ - g_message("time to delete task %p", (void*)task); + g_debug("time to delete task %p", (void*)task); task->func(task->appointments); }); @@ -295,7 +294,7 @@ private: // start a new subtask to enumerate all the components in this client. auto extension = e_source_get_extension(source, E_SOURCE_EXTENSION_CALENDAR); const auto color = e_source_selectable_get_color(E_SOURCE_SELECTABLE(extension)); - g_message("calling e_cal_client_generate_instances for %p", (void*)client); + g_debug("calling e_cal_client_generate_instances for %p", (void*)client); e_cal_client_generate_instances(client, begin, end, @@ -399,7 +398,7 @@ private: e_client_util_free_string_slist(uris); } - g_message("adding appointment '%s' '%s'", subtask->appointment.summary.c_str(), subtask->appointment.url.c_str()); + g_debug("adding appointment '%s' '%s'", subtask->appointment.summary.c_str(), subtask->appointment.url.c_str()); subtask->task->appointments.push_back(subtask->appointment); delete subtask; } -- cgit v1.2.3 From 416e13070bc73824999ad430cb9f264192c76296 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 28 Jan 2014 18:37:14 -0600 Subject: fix free-memory-read bug found by valgrind testing --- src/planner-eds.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index 54332ce..db5d1ba 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -214,7 +214,7 @@ private: void rebuildNow() { - auto calendar_date = m_owner.time.get().get(); + const auto calendar_date = m_owner.time.get().get(); GDateTime* begin; GDateTime* end; int y, m, d; @@ -245,7 +245,6 @@ private: } g_clear_pointer(&begin, g_date_time_unref); g_clear_pointer(&end, g_date_time_unref); - g_clear_pointer(&calendar_date, g_date_time_unref); } void getAppointments(GDateTime* begin_dt, GDateTime* end_dt, appointment_func func) -- cgit v1.2.3 From 65b58035b31bde014bc206ae23a6fac83e9bf3b9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 28 Jan 2014 18:40:13 -0600 Subject: fix Task leak found by valgrind testing --- src/planner-eds.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index db5d1ba..1fb0bd1 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -279,6 +279,7 @@ private: std::shared_ptr main_task(new Task(this, func), [](Task* task){ g_debug("time to delete task %p", (void*)task); task->func(task->appointments); + delete task; }); for (auto& source : m_sources) -- cgit v1.2.3 From ae3ac73a1a8e5a8da7aa0e4f3a3031ba0ec2f192 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 28 Jan 2014 18:51:21 -0600 Subject: fix GDateTime leak found by valgrind testing --- src/planner-eds.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index 1fb0bd1..df62360 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -353,9 +353,9 @@ private: ECalComponentText text; text.value = ""; e_cal_component_get_summary(component, &text); - - appointment.begin = g_date_time_new_from_unix_local(begin); - appointment.end = g_date_time_new_from_unix_local(end); + + appointment.begin = DateTime(begin); + appointment.end = DateTime(end); appointment.color = subtask->color; appointment.is_event = vtype == E_CAL_COMPONENT_EVENT; appointment.summary = text.value; -- cgit v1.2.3 From a82d0fd7cbad9bff96fafae17b2922e1e9d99972 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 28 Jan 2014 18:51:56 -0600 Subject: fix g_date_time_format() leak found by valgrind testing --- src/planner-eds.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index df62360..98cfe0a 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -251,8 +251,12 @@ private: { const auto begin = g_date_time_to_unix(begin_dt); const auto end = g_date_time_to_unix(end_dt); - g_debug("getting all appointments from [%s ... %s]", g_date_time_format(begin_dt, "%F %T"), - g_date_time_format(end_dt, "%F %T")); + + auto begin_str = g_date_time_format(begin_dt, "%F %T"); + auto end_str = g_date_time_format(end_dt, "%F %T"); + g_debug("getting all appointments from [%s ... %s]", begin_str, end_str); + g_free(begin_str); + g_free(end_str); /** *** init the default timezone -- cgit v1.2.3 From a7a09a5ca5012fb1c48f259d2587542316e7349b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 30 Jan 2014 18:33:14 -0600 Subject: copyediting: as per review, use name_of_thing() instead of get_name_of_thing() or getNameOfThing() --- src/planner-eds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/planner-eds.cpp') diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp index 98cfe0a..cb42d6e 100644 --- a/src/planner-eds.cpp +++ b/src/planner-eds.cpp @@ -227,7 +227,7 @@ private: { getAppointments(begin, end, [this](const std::vector& appointments) { g_debug("got %d appointments in this calendar month", (int)appointments.size()); - m_owner.thisMonth.set(appointments); + m_owner.this_month.set(appointments); }); } g_clear_pointer(&begin, g_date_time_unref); -- cgit v1.2.3