From ebe483c0584c839a2890db1e4a43b0526ed738d8 Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <lfleischer@calcurse.org>
Date: Wed, 27 Jan 2016 08:03:09 +0100
Subject: Support sending notifications for all appointments

In 45417bc (Add configuration option to notify all appointments,
2011-07-31), we added an option that allows for choosing whether the
user receives notifications only for flagged or only for unflagged
appointments. Convert this setting into a three-state option and allow
the user to additionally enable notifications for *all* appointments.

Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
---
 src/calcurse.h |  4 ++++
 src/config.c   | 30 +++++++++++++++++++++++++++++-
 src/notify.c   | 55 ++++++++++++++++++++++++++++++++-----------------------
 3 files changed, 65 insertions(+), 24 deletions(-)

(limited to 'src')

diff --git a/src/calcurse.h b/src/calcurse.h
index 5d8c9e4..b569d8d 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -598,6 +598,10 @@ struct pad {
 };
 
 /* Notification bar definition. */
+#define NOTIFY_FLAGGED_ONLY    0
+#define NOTIFY_UNFLAGGED_ONLY  1
+#define NOTIFY_ALL             2
+
 struct nbar {
 	unsigned show;		/* display or hide the notify-bar */
 	int cntdwn;		/* warn when time left before next app
diff --git a/src/config.c b/src/config.c
index 8b65740..86277e8 100644
--- a/src/config.c
+++ b/src/config.c
@@ -75,6 +75,8 @@ static int config_parse_output_datefmt(void *, const char *);
 static int config_serialize_output_datefmt(char **, void *);
 static int config_parse_input_datefmt(void *, const char *);
 static int config_serialize_input_datefmt(char **, void *);
+static int config_parse_notifyall(void *, const char *);
+static int config_serialize_notifyall(char **, void *);
 
 #define CONFIG_HANDLER_BOOL(var) (config_fn_parse_t) config_parse_bool, \
   (config_fn_serialize_t) config_serialize_bool, &(var)
@@ -109,7 +111,7 @@ static const struct confvar confmap[] = {
 	{"general.progressbar", CONFIG_HANDLER_BOOL(conf.progress_bar)},
 	{"general.systemdialogs", CONFIG_HANDLER_BOOL(conf.system_dialogs)},
 	{"notification.command", CONFIG_HANDLER_STR(nbar.cmd)},
-	{"notification.notifyall", CONFIG_HANDLER_BOOL(nbar.notify_all)},
+	{"notification.notifyall", config_parse_notifyall, config_serialize_notifyall, NULL},
 	{"notification.warning", CONFIG_HANDLER_INT(nbar.cntdwn)}
 };
 
@@ -291,6 +293,19 @@ static int config_parse_input_datefmt(void *dummy, const char *val)
 	}
 }
 
+static int config_parse_notifyall(void *dummy, const char *val)
+{
+	if (strcmp(val, "flagged-only") == 0)
+		nbar.notify_all = NOTIFY_FLAGGED_ONLY;
+	else if (strcmp(val, "unflagged-only") == 0)
+		nbar.notify_all = NOTIFY_UNFLAGGED_ONLY;
+	else if (strcmp(val, "all") == 0)
+		nbar.notify_all = NOTIFY_ALL;
+	else
+		return config_parse_bool(&nbar.notify_all, val);
+	return 1;
+}
+
 /* Set a configuration variable. */
 static int config_set_conf(const char *key, const char *value)
 {
@@ -453,6 +468,19 @@ static int config_serialize_input_datefmt(char **buf, void *dummy)
 	return config_serialize_int(buf, &conf.input_datefmt);
 }
 
+static int config_serialize_notifyall(char **buf, void *dummy)
+{
+	if (nbar.notify_all == NOTIFY_FLAGGED_ONLY)
+		*buf = mem_strdup("flagged-only");
+	else if (nbar.notify_all == NOTIFY_UNFLAGGED_ONLY)
+		*buf = mem_strdup("unflagged-only");
+	else if (nbar.notify_all == NOTIFY_ALL)
+		*buf = mem_strdup("all");
+	else
+		return 0;
+	return 1;
+}
+
 /* Serialize the value of a configuration variable. */
 static int
 config_serialize_conf(char **buf, const char *key,
diff --git a/src/notify.c b/src/notify.c
index 78c8484..a5b46d7 100644
--- a/src/notify.c
+++ b/src/notify.c
@@ -71,18 +71,27 @@ int notify_time_left(void)
 	return left > 0 ? left : 0;
 }
 
+static unsigned notify_trigger(void)
+{
+	int flagged = notify_app.state & APOINT_NOTIFY;
+
+	if (!notify_app.got_app)
+		return 0;
+	if (nbar.notify_all == NOTIFY_ALL)
+		return 1;
+	if (nbar.notify_all == NOTIFY_UNFLAGGED_ONLY)
+		flagged = !flagged;
+	return flagged;
+}
+
 /*
- * Return 1 if the reminder was not sent already for the upcoming
- * appointment.
+ * Return 1 if the reminder was not sent already for the upcoming appointment.
  */
 unsigned notify_needs_reminder(void)
 {
-	if (notify_app.got_app
-	    && (((notify_app.state & APOINT_NOTIFY) && !nbar.notify_all) ||
-		(!(notify_app.state & APOINT_NOTIFY) && nbar.notify_all))
-	    && !(notify_app.state & APOINT_NOTIFIED))
-		return 1;
-	return 0;
+	if (notify_app.state & APOINT_NOTIFIED)
+		return 0;
+	return notify_trigger();
 }
 
 /*
@@ -274,14 +283,7 @@ void notify_update_bar(void)
 			     hours_left * HOURINSEC) / MININSEC;
 			pthread_mutex_lock(&nbar.mutex);
 
-			if (time_left < nbar.cntdwn &&
-			    (((notify_app.state & APOINT_NOTIFY)
-			      && !nbar.notify_all)
-			     || (!(notify_app.state & APOINT_NOTIFY)
-				 && nbar.notify_all)))
-				blinking = 1;
-			else
-				blinking = 0;
+			blinking = time_left < nbar.cntdwn && notify_trigger();
 
 			WINS_NBAR_LOCK;
 			if (blinking)
@@ -599,7 +601,7 @@ print_option(WINDOW * win, unsigned x, unsigned y, char *name,
 /* Print options related to the notify-bar. */
 static void print_config_option(int i, WINDOW *win, int y, int hilt, void *cb_data)
 {
-	enum { SHOW, DATE, CLOCK, WARN, CMD, NOTIFY_ALL, DMON, DMON_LOG,
+	enum { SHOW, DATE, CLOCK, WARN, CMD, NOTIFYALL, DMON, DMON_LOG,
 		    NB_OPT };
 
 	struct opt_s {
@@ -629,8 +631,8 @@ static void print_config_option(int i, WINDOW *win, int y, int hilt, void *cb_da
 	opt[CMD].desc =
 	    _("(Command used to notify user of an upcoming appointment)");
 
-	opt[NOTIFY_ALL].name = "notification.notifyall = ";
-	opt[NOTIFY_ALL].desc =
+	opt[NOTIFYALL].name = "notification.notifyall = ";
+	opt[NOTIFYALL].desc =
 	    _("(Notify all appointments instead of flagged ones only)");
 
 	opt[DMON].name = "daemon.enable = ";
@@ -651,14 +653,21 @@ static void print_config_option(int i, WINDOW *win, int y, int hilt, void *cb_da
 
 	/* Boolean options */
 	opt[SHOW].valnum = nbar.show;
-	opt[NOTIFY_ALL].valnum = nbar.notify_all;
 	pthread_mutex_unlock(&nbar.mutex);
 
 	opt[DMON].valnum = dmon.enable;
 	opt[DMON_LOG].valnum = dmon.log;
 
-	opt[SHOW].valstr[0] = opt[NOTIFY_ALL].valstr[0] =
-	    opt[DMON].valstr[0] = opt[DMON_LOG].valstr[0] = '\0';
+	opt[SHOW].valstr[0] = opt[DMON].valstr[0] =
+		opt[DMON_LOG].valstr[0] = '\0';
+
+	opt[NOTIFYALL].valnum = nbar.notify_all;
+	if (opt[NOTIFYALL].valnum == NOTIFY_FLAGGED_ONLY)
+		strcpy(opt[NOTIFYALL].valstr, "flagged-only");
+	else if (opt[NOTIFYALL].valnum == NOTIFY_UNFLAGGED_ONLY)
+		strcpy(opt[NOTIFYALL].valstr, "unflagged-only");
+	else if (opt[NOTIFYALL].valnum == NOTIFY_ALL)
+		strcpy(opt[NOTIFYALL].valstr, "all");
 
 	if (hilt)
 		custom_apply_attr(win, ATTR_HIGHEST);
@@ -757,7 +766,7 @@ static void config_option_edit(int i)
 		break;
 	case 5:
 		pthread_mutex_lock(&nbar.mutex);
-		nbar.notify_all = !nbar.notify_all;
+		nbar.notify_all = (nbar.notify_all + 1) % 3;
 		pthread_mutex_unlock(&nbar.mutex);
 		notify_check_next_app(1);
 		break;
-- 
cgit v1.2.3-70-g09d2