aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2014-02-04 00:10:17 -0600
committerCharles Kerr <charles.kerr@canonical.com>2014-02-04 00:10:17 -0600
commit894c0c625ff1e2f2d031f48f157a3008302cb5a7 (patch)
treeccdfa8520159bb95555368aa9a7439c384e6bb1c
parent7d1ec01369d1c107cd42b0a7501f8cdb3c7e08ac (diff)
downloadayatana-indicator-datetime-894c0c625ff1e2f2d031f48f157a3008302cb5a7.tar.gz
ayatana-indicator-datetime-894c0c625ff1e2f2d031f48f157a3008302cb5a7.tar.bz2
ayatana-indicator-datetime-894c0c625ff1e2f2d031f48f157a3008302cb5a7.zip
pin the planner's upcoming appointments to the live clock time, rather than the calendar's time, so that they always update correctly in real-time
-rw-r--r--include/datetime/planner-eds.h5
-rw-r--r--src/main.cpp2
-rw-r--r--src/planner-eds.cpp117
-rw-r--r--tests/test-planner.cpp14
4 files changed, 82 insertions, 56 deletions
diff --git a/include/datetime/planner-eds.h b/include/datetime/planner-eds.h
index f3abce0..a99f611 100644
--- a/include/datetime/planner-eds.h
+++ b/include/datetime/planner-eds.h
@@ -20,9 +20,10 @@
#ifndef INDICATOR_DATETIME_PLANNER_EDS_H
#define INDICATOR_DATETIME_PLANNER_EDS_H
+#include <datetime/clock.h>
#include <datetime/planner.h>
-#include <memory> // unique_ptr
+#include <memory> // shared_ptr, unique_ptr
namespace unity {
namespace indicator {
@@ -34,7 +35,7 @@ namespace datetime {
class PlannerEds: public Planner
{
public:
- PlannerEds();
+ PlannerEds(const std::shared_ptr<Clock>& clock);
virtual ~PlannerEds();
private:
diff --git a/src/main.cpp b/src/main.cpp
index 3c17923..87bfed1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -64,7 +64,7 @@ main(int /*argc*/, char** /*argv*/)
state->settings = live_settings;
state->clock = live_clock;
state->locations.reset(new SettingsLocations(live_settings, live_timezones));
- state->planner.reset(new PlannerEds);
+ state->planner.reset(new PlannerEds(live_clock));
state->planner->time = live_clock->localtime();
std::shared_ptr<Actions> actions(new LiveActions(state));
MenuFactory factory(actions, state);
diff --git a/src/planner-eds.cpp b/src/planner-eds.cpp
index 9048f52..7d9416c 100644
--- a/src/planner-eds.cpp
+++ b/src/planner-eds.cpp
@@ -41,18 +41,24 @@ class PlannerEds::Impl
{
public:
- Impl(PlannerEds& owner):
+ Impl(PlannerEds& owner, const std::shared_ptr<Clock>& clock):
m_owner(owner),
+ m_clock(clock),
m_cancellable(g_cancellable_new())
{
e_source_registry_new(m_cancellable, on_source_registry_ready, this);
+ m_clock->minute_changed.connect([this](){
+ g_debug("rebuilding upcoming because the clock's minute_changed");
+ rebuild_soon(UPCOMING);
+ });
+
m_owner.time.changed().connect([this](const DateTime& dt) {
g_debug("planner's datetime property changed to %s; calling rebuild_soon()", dt.format("%F %T").c_str());
- rebuild_soon();
+ rebuild_soon(MONTH);
});
- rebuild_soon();
+ rebuild_soon(ALL);
}
~Impl()
@@ -164,7 +170,7 @@ private:
self);
g_debug("client connected; calling rebuild_soon()");
- self->rebuild_soon();
+ self->rebuild_soon(ALL);
}
}
@@ -185,7 +191,7 @@ private:
g_signal_connect(view, "objects-modified", G_CALLBACK(on_view_objects_modified), self);
g_signal_connect(view, "objects-removed", G_CALLBACK(on_view_objects_removed), self);
g_debug("view connected; calling rebuild_soon()");
- self->rebuild_soon();
+ self->rebuild_soon(ALL);
}
else if(error != nullptr)
{
@@ -199,17 +205,17 @@ private:
static void on_view_objects_added(ECalClientView* /*view*/, gpointer /*objects*/, gpointer gself)
{
g_debug("%s", G_STRFUNC);
- static_cast<Impl*>(gself)->rebuild_soon();
+ static_cast<Impl*>(gself)->rebuild_soon(ALL);
}
static void on_view_objects_modified(ECalClientView* /*view*/, gpointer /*objects*/, gpointer gself)
{
g_debug("%s", G_STRFUNC);
- static_cast<Impl*>(gself)->rebuild_soon();
+ static_cast<Impl*>(gself)->rebuild_soon(ALL);
}
static void on_view_objects_removed(ECalClientView* /*view*/, gpointer /*objects*/, gpointer gself)
{
g_debug("%s", G_STRFUNC);
- static_cast<Impl*>(gself)->rebuild_soon();
+ static_cast<Impl*>(gself)->rebuild_soon(ALL);
}
static void on_source_disabled(ESourceRegistry* /*registry*/, ESource* source, gpointer gself)
@@ -228,7 +234,7 @@ private:
g_warn_if_fail(n_disconnected == 3);
g_object_unref(view);
m_views.erase(vit);
- rebuild_soon();
+ rebuild_soon(ALL);
}
// if an ECalClient is associated with this source, remove it
@@ -238,7 +244,7 @@ private:
auto& client = cit->second;
g_object_unref(client);
m_clients.erase(cit);
- rebuild_soon();
+ rebuild_soon(ALL);
}
}
@@ -255,14 +261,14 @@ private:
{
g_object_unref(*sit);
m_sources.erase(sit);
- rebuild_soon();
+ rebuild_soon(ALL);
}
}
static void on_source_changed(ESourceRegistry* /*registry*/, ESource* /*source*/, gpointer gself)
{
g_debug("source changed; calling rebuild_soon()");
- static_cast<Impl*>(gself)->rebuild_soon();
+ static_cast<Impl*>(gself)->rebuild_soon(ALL);
}
private:
@@ -286,9 +292,11 @@ private:
task(task_in), client(client_in), color(color_in) {}
};
- void rebuild_soon()
+ void rebuild_soon(int rebuild_flags)
{
- const static guint ARBITRARY_INTERVAL_SECS = 2;
+ static const guint ARBITRARY_INTERVAL_SECS = 2;
+
+ m_rebuild_flags |= rebuild_flags;
if (m_rebuild_tag == 0)
m_rebuild_tag = g_timeout_add_seconds(ARBITRARY_INTERVAL_SECS, rebuild_now_static, this);
@@ -297,44 +305,56 @@ private:
static gboolean rebuild_now_static(gpointer gself)
{
auto self = static_cast<Impl*>(gself);
+ const auto flags = self->m_rebuild_flags;
self->m_rebuild_tag = 0;
- self->rebuild_now();
+ self->m_rebuild_flags = 0;
+ self->rebuild_now(flags);
return G_SOURCE_REMOVE;
}
- void rebuild_now()
+ void rebuild_now(int rebuild_flags)
{
- const auto calendar_date = m_owner.time.get().get();
- GDateTime* begin;
- GDateTime* end;
- int y, m, d;
-
- // 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)
- {
- get_appointments(begin, end, [this](const std::vector<Appointment>& appointments) {
- g_debug("got %d appointments in this calendar month", (int)appointments.size());
- m_owner.this_month.set(appointments);
- });
- }
- g_clear_pointer(&begin, g_date_time_unref);
- g_clear_pointer(&end, g_date_time_unref);
+ if (rebuild_flags & UPCOMING)
+ rebuild_upcoming();
- // get the upcoming appointments
- begin = g_date_time_ref(calendar_date);
- end = g_date_time_add_months(begin, 1);
- if (begin && end)
- {
- get_appointments(begin, end, [this](const std::vector<Appointment>& appointments) {
- g_debug("got %d upcoming appointments", (int)appointments.size());
- m_owner.upcoming.set(appointments);
- });
- }
- g_clear_pointer(&begin, g_date_time_unref);
- g_clear_pointer(&end, g_date_time_unref);
+ if (rebuild_flags & MONTH)
+ rebuild_month();
+ }
+
+ void rebuild_month()
+ {
+ const auto ref = m_owner.time.get().get();
+ auto month_begin = g_date_time_add_full(ref,
+ 0, // subtract no years
+ 0, // subtract no months
+ -(g_date_time_get_day_of_month(ref)-1),
+ -g_date_time_get_hour(ref),
+ -g_date_time_get_minute(ref),
+ -g_date_time_get_seconds(ref));
+ auto month_end = g_date_time_add_full(month_begin, 0, 1, 0, 0, 0, -0.1);
+
+ get_appointments(month_begin, month_end, [this](const std::vector<Appointment>& appointments) {
+ g_debug("got %d appointments in this calendar month", (int)appointments.size());
+ m_owner.this_month.set(appointments);
+ });
+
+ g_date_time_unref(month_end);
+ g_date_time_unref(month_begin);
+ }
+
+ void rebuild_upcoming()
+ {
+ const auto ref = m_clock->localtime();
+ const auto begin = g_date_time_add_minutes(ref.get(),-10);
+ const auto end = g_date_time_add_months(begin,1);
+
+ get_appointments(begin, end, [this](const std::vector<Appointment>& appointments) {
+ g_debug("got %d upcoming appointments", (int)appointments.size());
+ m_owner.upcoming.set(appointments);
+ });
+
+ g_date_time_unref(end);
+ g_date_time_unref(begin);
}
void get_appointments(GDateTime* begin_dt, GDateTime* end_dt, appointment_func func)
@@ -496,15 +516,18 @@ private:
}
PlannerEds& m_owner;
+ std::shared_ptr<Clock> m_clock;
std::set<ESource*> m_sources;
std::map<ESource*,ECalClient*> m_clients;
std::map<ESource*,ECalClientView*> m_views;
GCancellable* m_cancellable = nullptr;
ESourceRegistry* m_source_registry = nullptr;
guint m_rebuild_tag = 0;
+ guint m_rebuild_flags = 0;
+ enum { UPCOMING=(1<<0), MONTH=(1<<1), ALL=UPCOMING|MONTH };
};
-PlannerEds::PlannerEds(): p(new Impl(*this)) {}
+PlannerEds::PlannerEds(const std::shared_ptr<Clock>& clock): p(new Impl(*this, clock)) {}
PlannerEds::~PlannerEds() =default;
diff --git a/tests/test-planner.cpp b/tests/test-planner.cpp
index b476ee8..1923ba1 100644
--- a/tests/test-planner.cpp
+++ b/tests/test-planner.cpp
@@ -28,9 +28,7 @@
#include <langinfo.h>
#include <locale.h>
-using unity::indicator::datetime::Appointment;
-using unity::indicator::datetime::DateTime;
-using unity::indicator::datetime::PlannerEds;
+using namespace unity::indicator::datetime;
/***
****
@@ -40,11 +38,15 @@ typedef GlibFixture PlannerFixture;
TEST_F(PlannerFixture, EDS)
{
- PlannerEds planner;
+ auto tmp = g_date_time_new_now_local();
+ const auto now = DateTime(tmp);
+ g_date_time_unref(tmp);
+
+ std::shared_ptr<Clock> clock(new MockClock(now));
+ PlannerEds planner(clock);
wait_msec(100);
- auto now = g_date_time_new_now_local();
- planner.time.set(DateTime(now));
+ planner.time.set(now);
wait_msec(2500);
std::vector<Appointment> this_month = planner.this_month.get();