aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2014-09-05 14:12:14 +0000
committerCI bot <ps-jenkins@lists.canonical.com>2014-09-05 14:12:14 +0000
commit7affbfb591fe0d5b68bdf5023eae2aba5e727dd2 (patch)
tree55976fcc4f23debe01bb18ef9a9f2a8260f756b8 /src
parentd006b8d390004e03c2cd27d67c80f4fb767f35d5 (diff)
parent593c16de05fe3806edeeb3bc105ce63b71b8b545 (diff)
downloadayatana-indicator-datetime-7affbfb591fe0d5b68bdf5023eae2aba5e727dd2.tar.gz
ayatana-indicator-datetime-7affbfb591fe0d5b68bdf5023eae2aba5e727dd2.tar.bz2
ayatana-indicator-datetime-7affbfb591fe0d5b68bdf5023eae2aba5e727dd2.zip
Add the snooze feature Fixes: 1354400
Approved by: Jussi Pakkanen, PS Jenkins bot
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/exporter.cpp1
-rw-r--r--src/main.cpp32
-rw-r--r--src/planner-aggregate.cpp106
-rw-r--r--src/planner-snooze.cpp115
-rw-r--r--src/planner.cpp54
-rw-r--r--src/settings-live.cpp12
-rw-r--r--src/snap.cpp24
8 files changed, 318 insertions, 29 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e583334..512cc5c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -25,6 +25,9 @@ set (SERVICE_CXX_SOURCES
locations-settings.cpp
menu.cpp
notifications.cpp
+ planner.cpp
+ planner-aggregate.cpp
+ planner-snooze.cpp
planner-month.cpp
planner-range.cpp
planner-upcoming.cpp
diff --git a/src/exporter.cpp b/src/exporter.cpp
index 1d45705..05b21eb 100644
--- a/src/exporter.cpp
+++ b/src/exporter.cpp
@@ -145,6 +145,7 @@ private:
bind_uint_property(m_alarm_props, "default-volume", m_settings->alarm_volume);
bind_string_property(m_alarm_props, "default-sound", m_settings->alarm_sound);
bind_string_property(m_alarm_props, "haptic-feedback", m_settings->alarm_haptic);
+ bind_uint_property(m_alarm_props, "snooze-duration", m_settings->snooze_duration);
}
/***
diff --git a/src/main.cpp b/src/main.cpp
index 48d3d20..54517c9 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -25,6 +25,8 @@
#include <datetime/exporter.h>
#include <datetime/locations-settings.h>
#include <datetime/menu.h>
+#include <datetime/planner-aggregate.h>
+#include <datetime/planner-snooze.h>
#include <datetime/planner-range.h>
#include <datetime/settings-live.h>
#include <datetime/snap.h>
@@ -37,8 +39,6 @@
#include <glib/gi18n.h> // bindtextdomain()
#include <gio/gio.h>
-#include <url-dispatcher.h>
-
#include <locale.h>
#include <cstdlib> // exit()
@@ -90,6 +90,7 @@ namespace
}
std::shared_ptr<AlarmQueue> create_simple_alarm_queue(const std::shared_ptr<Clock>& clock,
+ const std::shared_ptr<Planner>& snooze_planner,
const std::shared_ptr<Engine>& engine,
const std::shared_ptr<Timezone>& tz)
{
@@ -102,8 +103,14 @@ namespace
upcoming_planner->date().set(now);
});
+ // create an aggregate planner that folds together the above
+ // upcoming-events planner and locally-generated snooze events
+ std::shared_ptr<AggregatePlanner> planner = std::make_shared<AggregatePlanner>();
+ planner->add(upcoming_planner);
+ planner->add(snooze_planner);
+
auto wakeup_timer = std::make_shared<PowerdWakeupTimer>(clock);
- return std::make_shared<SimpleAlarmQueue>(clock, upcoming_planner, wakeup_timer);
+ return std::make_shared<SimpleAlarmQueue>(clock, planner, wakeup_timer);
}
}
@@ -126,21 +133,14 @@ main(int /*argc*/, char** /*argv*/)
MenuFactory factory(actions, state);
// set up the snap decisions
+ auto snooze_planner = std::make_shared<SnoozePlanner>(state->settings, state->clock);
auto notification_engine = std::make_shared<uin::Engine>("indicator-datetime-service");
std::unique_ptr<Snap> snap (new Snap(notification_engine, state->settings));
- auto alarm_queue = create_simple_alarm_queue(state->clock, engine, timezone);
- alarm_queue->alarm_reached().connect([&snap](const Appointment& appt){
- auto snap_show = [](const Appointment& a){
- const char* url;
- if(!a.url.empty())
- url = a.url.c_str();
- else // alarm doesn't have a URl associated with it; use a fallback
- url = "appid://com.ubuntu.clock/clock/current-user-version";
- url_dispatch_send(url, nullptr, nullptr);
- };
- auto snap_dismiss = [](const Appointment&){};
- (*snap)(appt, snap_show, snap_dismiss);
- });
+ auto alarm_queue = create_simple_alarm_queue(state->clock, snooze_planner, engine, timezone);
+ auto on_snooze = [snooze_planner](const Appointment& a) {snooze_planner->add(a);};
+ auto on_ok = [](const Appointment&){};
+ auto on_alarm_reached = [&snap, &on_snooze, &on_ok](const Appointment& a) {(*snap)(a, on_snooze, on_ok);};
+ alarm_queue->alarm_reached().connect(on_alarm_reached);
// create the menus
std::vector<std::shared_ptr<Menu>> menus;
diff --git a/src/planner-aggregate.cpp b/src/planner-aggregate.cpp
new file mode 100644
index 0000000..7458f0c
--- /dev/null
+++ b/src/planner-aggregate.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2014 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ */
+
+#include <datetime/planner-aggregate.h>
+
+namespace unity {
+namespace indicator {
+namespace datetime {
+
+/***
+****
+***/
+
+class AggregatePlanner::Impl
+{
+public:
+ Impl(AggregatePlanner* owner):
+ m_owner(owner)
+ {
+ }
+
+ ~Impl() =default;
+
+ core::Property<std::vector<Appointment>>& appointments()
+ {
+ return m_appointments;
+ }
+
+ void add(const std::shared_ptr<Planner>& planner)
+ {
+ m_planners.push_back(planner);
+
+ auto on_changed = [this](const std::vector<Appointment>&){rebuild();};
+ auto connection = planner->appointments().changed().connect(on_changed);
+ m_connections.push_back(connection);
+ }
+
+private:
+
+ void rebuild()
+ {
+ // use a sorted aggregate vector of all our planners
+ std::vector<Appointment> all;
+ for (const auto& planner : m_planners) {
+ const auto& walk = planner->appointments().get();
+ all.insert(std::end(all), std::begin(walk), std::end(walk));
+ }
+ m_owner->sort(all);
+ m_appointments.set(all);
+ }
+
+ const AggregatePlanner* m_owner = nullptr;
+ core::Property<std::vector<Appointment>> m_appointments;
+ std::vector<std::shared_ptr<Planner>> m_planners;
+ std::vector<core::ScopedConnection> m_connections;
+};
+
+/***
+****
+***/
+
+AggregatePlanner::AggregatePlanner():
+ impl(new Impl{this})
+{
+}
+
+AggregatePlanner::~AggregatePlanner()
+{
+}
+
+core::Property<std::vector<Appointment>>&
+AggregatePlanner::appointments()
+{
+ return impl->appointments();
+}
+
+void
+AggregatePlanner::add(const std::shared_ptr<Planner>& planner)
+{
+ return impl->add(planner);
+}
+
+/***
+****
+***/
+
+} // namespace datetime
+} // namespace indicator
+} // namespace unity
+
diff --git a/src/planner-snooze.cpp b/src/planner-snooze.cpp
new file mode 100644
index 0000000..51ad0d2
--- /dev/null
+++ b/src/planner-snooze.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2014 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ */
+
+#include <datetime/planner-snooze.h>
+
+#include <libedataserver/libedataserver.h> // e_uid_new()
+
+namespace unity {
+namespace indicator {
+namespace datetime {
+
+/***
+****
+***/
+
+class SnoozePlanner::Impl
+{
+public:
+
+ Impl(SnoozePlanner* owner,
+ const std::shared_ptr<Settings>& settings,
+ const std::shared_ptr<Clock>& clock):
+ m_owner(owner),
+ m_settings(settings),
+ m_clock(clock)
+ {
+ }
+
+ ~Impl()
+ {
+ }
+
+ virtual core::Property<std::vector<Appointment>>& appointments()
+ {
+ return m_appointments;
+ }
+
+ void add(const Appointment& appt_in)
+ {
+ Appointment appt = appt_in;
+
+ // reschedule the alarm to go off N minutes from now
+ const auto alarm_duration_secs = appt.end - appt.begin;
+ appt.begin = m_clock->localtime().add_full(0,0,0,0,m_settings->snooze_duration.get(),0);
+ appt.end = appt.begin.add_full(0,0,0,0,0,alarm_duration_secs);
+
+ // give it a new ID
+ gchar* uid = e_uid_new();
+ appt.uid = uid;
+ g_free(uid);
+
+ // add it to our appointment list
+ auto tmp = appointments().get();
+ tmp.push_back(appt);
+ m_owner->sort(tmp);
+ m_appointments.set(tmp);
+ }
+
+private:
+
+ const SnoozePlanner* const m_owner;
+ const std::shared_ptr<Settings> m_settings;
+ const std::shared_ptr<Clock> m_clock;
+ core::Property<std::vector<Appointment>> m_appointments;
+};
+
+/***
+****
+***/
+
+SnoozePlanner::SnoozePlanner(const std::shared_ptr<Settings>& settings,
+ const std::shared_ptr<Clock>& clock):
+ impl(new Impl{this, settings, clock})
+{
+}
+
+SnoozePlanner::~SnoozePlanner()
+{
+}
+
+void
+SnoozePlanner::add(const Appointment& appointment)
+{
+ impl->add(appointment);
+}
+
+core::Property<std::vector<Appointment>>&
+SnoozePlanner::appointments()
+{
+ return impl->appointments();
+}
+
+/***
+****
+***/
+
+} // namespace datetime
+} // namespace indicator
+} // namespace unity
diff --git a/src/planner.cpp b/src/planner.cpp
new file mode 100644
index 0000000..6ca9ca7
--- /dev/null
+++ b/src/planner.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2014 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ */
+
+#include <datetime/planner.h>
+
+#include <algorithm>
+
+namespace unity {
+namespace indicator {
+namespace datetime {
+
+/***
+****
+***/
+
+Planner::Planner()
+{
+}
+
+Planner::~Planner()
+{
+}
+
+void
+Planner::sort(std::vector<Appointment>& appts)
+{
+ std::sort(std::begin(appts),
+ std::end(appts),
+ [](const Appointment& a, const Appointment& b){return a.begin < b.begin;});
+}
+
+/***
+****
+***/
+
+} // namespace datetime
+} // namespace indicator
+} // namespace unity
diff --git a/src/settings-live.cpp b/src/settings-live.cpp
index a8338ed..8ea06a4 100644
--- a/src/settings-live.cpp
+++ b/src/settings-live.cpp
@@ -56,6 +56,7 @@ LiveSettings::LiveSettings():
update_alarm_volume();
update_alarm_duration();
update_alarm_haptic();
+ update_snooze_duration();
// now listen for clients to change the properties s.t. we can sync update GSettings
@@ -135,6 +136,10 @@ LiveSettings::LiveSettings():
alarm_haptic.changed().connect([this](const std::string& value){
g_settings_set_string(m_settings, SETTINGS_ALARM_HAPTIC_S, value.c_str());
});
+
+ snooze_duration.changed().connect([this](unsigned int value){
+ g_settings_set_uint(m_settings, SETTINGS_SNOOZE_DURATION_S, value);
+ });
}
/***
@@ -249,6 +254,11 @@ void LiveSettings::update_alarm_haptic()
g_free(val);
}
+void LiveSettings::update_snooze_duration()
+{
+ snooze_duration.set(g_settings_get_uint(m_settings, SETTINGS_SNOOZE_DURATION_S));
+}
+
/***
****
***/
@@ -298,6 +308,8 @@ void LiveSettings::update_key(const std::string& key)
update_alarm_duration();
else if (key == SETTINGS_ALARM_HAPTIC_S)
update_alarm_haptic();
+ else if (key == SETTINGS_SNOOZE_DURATION_S)
+ update_snooze_duration();
}
/***
diff --git a/src/snap.cpp b/src/snap.cpp
index 0b2322a..505980c 100644
--- a/src/snap.cpp
+++ b/src/snap.cpp
@@ -59,12 +59,12 @@ public:
}
void operator()(const Appointment& appointment,
- appointment_func show,
- appointment_func dismiss)
+ appointment_func snooze,
+ appointment_func ok)
{
if (!appointment.has_alarms)
{
- dismiss(appointment);
+ ok(appointment);
return;
}
@@ -98,26 +98,24 @@ public:
g_free (title);
b.set_timeout (std::chrono::duration_cast<std::chrono::seconds>(minutes));
if (interactive) {
- b.add_action ("show", _("Show"));
- b.add_action ("dismiss", _("Dismiss"));
+ b.add_action ("ok", _("OK"));
+ b.add_action ("snooze", _("Snooze"));
}
// add 'sound', 'haptic', and 'awake' objects to the capture so
// they stay alive until the closed callback is called; i.e.,
// for the lifespan of the notficiation
- b.set_closed_callback([appointment, show, dismiss, sound, awake, haptic]
+ b.set_closed_callback([appointment, snooze, ok, sound, awake, haptic]
(const std::string& action){
- if (action == "show")
- show(appointment);
+ if (action == "snooze")
+ snooze(appointment);
else
- dismiss(appointment);
+ ok(appointment);
});
const auto key = m_engine->show(b);
if (key)
m_notifications.insert (key);
- else
- show(appointment);
}
private:
@@ -177,9 +175,9 @@ Snap::~Snap()
void
Snap::operator()(const Appointment& appointment,
appointment_func show,
- appointment_func dismiss)
+ appointment_func ok)
{
- (*impl)(appointment, show, dismiss);
+ (*impl)(appointment, show, ok);
}
/***