[Commits] [SCM] claws branch, master, updated. 3.17.0-16-g5783d2a

Colin colin at claws-mail.org
Fri Aug 24 13:52:13 CEST 2018


The branch, master has been updated
       via  5783d2a913dfd980d77c0be13557a54ad5c75e6a (commit)
       via  ba29a2031c9c04cdbaa21ab15f195147ed50d85e (commit)
       via  eee41ab09d8ab73a9cb70c1444c5c6ba463949e3 (commit)
       via  0314475ba605a707740f7e818d04a8ce66f619e8 (commit)
      from  f6016ef46503a7bac437a3f2ada7d9d0cde60edc (commit)

Summary of changes:
 src/advsearch.c                          |    2 +
 src/gtk/gtkutils.c                       |   97 ++++++++++++++++++
 src/gtk/gtkutils.h                       |    6 ++
 src/gtk/quicksearch.c                    |    4 +
 src/matcher.c                            |   48 +++++++++
 src/matcher.h                            |    1 +
 src/matcher_parser_parse.y               |   24 +++++
 src/plugins/vcalendar/vcal_meeting_gtk.c |  161 +++++-------------------------
 src/prefs_matcher.c                      |  124 ++++++++++++++++++++---
 9 files changed, 314 insertions(+), 153 deletions(-)


- Log -----------------------------------------------------------------
commit 5783d2a913dfd980d77c0be13557a54ad5c75e6a
Author: Colin Leroy <colin at colino.net>
Date:   Fri Aug 24 13:51:32 2018 +0200

    Better GUI (with calendar) for date filtering condition.

diff --git a/src/gtk/gtkutils.c b/src/gtk/gtkutils.c
index 53c2a97..4b70c58 100644
--- a/src/gtk/gtkutils.c
+++ b/src/gtk/gtkutils.c
@@ -2119,3 +2119,14 @@ gboolean gtkut_time_select_get_time(GtkComboBox *combo, int *hour, int *minute)
 
 	return TRUE;
 }
+
+void gtk_calendar_select_today(GtkCalendar *calendar)
+{
+	time_t t = time (NULL);
+	struct tm buft;
+ 	struct tm *lt = localtime_r (&t, &buft);
+
+	mktime(lt);
+	gtk_calendar_select_day(calendar, lt->tm_mday);
+	gtk_calendar_select_month(calendar, lt->tm_mon, lt->tm_year + 1900);
+}
diff --git a/src/gtk/gtkutils.h b/src/gtk/gtkutils.h
index 9a7f6c6..c40320b 100644
--- a/src/gtk/gtkutils.h
+++ b/src/gtk/gtkutils.h
@@ -192,6 +192,8 @@ GtkWidget *gtkut_time_select_combo_new();
 void gtkut_time_select_select_by_time(GtkComboBox *combo, int hour, int minute);
 gboolean gtkut_time_select_get_time(GtkComboBox *combo, int *hour, int *minute);
 
+void gtk_calendar_select_today(GtkCalendar *calendar);
+
 typedef void (*ClawsIOFunc)(gpointer data, gint source, GIOCondition condition);
 gint
 claws_input_add    (gint	      source,
diff --git a/src/prefs_matcher.c b/src/prefs_matcher.c
index f80d2b1..8db0d79 100644
--- a/src/prefs_matcher.c
+++ b/src/prefs_matcher.c
@@ -39,6 +39,7 @@
 #include "prefs_gtk.h"
 #include "prefs_matcher.h"
 #include "prefs_common.h"
+#include "procheader.h"
 #include "mainwindow.h"
 #include "foldersel.h"
 #include "manage_window.h"
@@ -101,6 +102,9 @@ static struct Matcher {
 #if !GTK_CHECK_VERSION(3, 0, 0)
 	GtkWidget *color_optmenu;
 #endif
+	GtkWidget *calendar;
+	GtkWidget *time_label;
+	GtkWidget *time_entry;
 
 	GtkWidget *test_btn;
 	GtkWidget *addressbook_select_btn;
@@ -554,6 +558,11 @@ static void prefs_matcher_create(void)
 #if !GTK_CHECK_VERSION(3, 0, 0)
 	GtkWidget *color_optmenu;
 #endif
+	GtkWidget *calendar;
+	GtkWidget *time_label;
+	GtkWidget *time_entry;
+	GtkWidget *date_hbox;
+	GtkWidget *date_vbox;
 
 	static GdkGeometry geometry;
 	GtkSizeGroup *size_group;
@@ -754,6 +763,21 @@ static void prefs_matcher_create(void)
 	gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 2, 3,
 			 GTK_FILL, GTK_SHRINK, 4, 0);
 
+	/* Date widgets */
+	date_vbox = gtk_vbox_new(FALSE, VSPACING_NARROW);
+	calendar = gtk_calendar_new();
+	gtk_box_pack_start(GTK_BOX(hbox), calendar, TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(lower_hbox), date_vbox, FALSE, FALSE, 0);
+
+	date_hbox = gtk_hbox_new(FALSE, HSPACING_NARROW);
+	gtk_box_pack_start(GTK_BOX(date_vbox), date_hbox, FALSE, FALSE, 0);
+
+	time_entry = gtkut_time_select_combo_new();
+	gtk_box_pack_start(GTK_BOX(date_hbox), time_entry, FALSE, FALSE, 0);
+	time_label = gtk_label_new(_("on:"));
+	gtk_misc_set_alignment(GTK_MISC(time_label), 0, 0.5);
+	gtk_box_pack_start(GTK_BOX(date_hbox), time_label, FALSE, FALSE, 0);
+	
 	/* test info button */
 	test_btn = gtk_button_new_from_stock(GTK_STOCK_INFO);
 	gtk_box_pack_start(GTK_BOX(lower_hbox), test_btn, FALSE, FALSE, 0);
@@ -866,6 +890,9 @@ static void prefs_matcher_create(void)
 	matcher.regexp_checkbtn = regexp_checkbtn;
 	matcher.bool_op_combo = bool_op_combo;
 	matcher.test_btn = test_btn;
+	matcher.calendar = calendar;
+	matcher.time_label = time_label;
+	matcher.time_entry = time_entry;
 #ifndef USE_ALT_ADDRBOOK
 	matcher.addressbook_select_btn = addressbook_select_btn;
 #endif
@@ -971,6 +998,9 @@ static void prefs_matcher_reset_condition(void)
 	gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher.addressbook_folder_combo)))), "");
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_checkbtn), FALSE);
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_checkbtn), FALSE);
+
+	gtk_calendar_select_today(GTK_CALENDAR(matcher.calendar));
+	gtkut_time_select_select_by_time(GTK_COMBO_BOX(matcher.time_entry), 0, 0);
 }
 
 /*!
@@ -1489,6 +1519,7 @@ static MatcherProp *prefs_matcher_dialog_to_matcher(void)
 	const gchar *header;
 	const gchar *expr;
 	gint value, sel;
+	gint year, month, day, hour, minute;
 
 	if (value_criteria == -1)
 		return NULL;
@@ -1544,8 +1575,6 @@ static MatcherProp *prefs_matcher_dialog_to_matcher(void)
 	case CRITERIA_HEADERS_PART:
 	case CRITERIA_HEADERS_CONT:
 	case CRITERIA_BODY_PART:
-	case CRITERIA_DATE_AFTER:
-	case CRITERIA_DATE_BEFORE:
 	case CRITERIA_MESSAGE:
 		expr = gtk_entry_get_text(GTK_ENTRY(matcher.string_entry));
 		
@@ -1555,6 +1584,20 @@ static MatcherProp *prefs_matcher_dialog_to_matcher(void)
 		}
 		break;
 
+	case CRITERIA_DATE_AFTER:
+	case CRITERIA_DATE_BEFORE:
+		expr = NULL;
+		gtk_calendar_get_date(GTK_CALENDAR(matcher.calendar), &year, &month, &day);
+		if (gtkut_time_select_get_time(GTK_COMBO_BOX(matcher.time_entry), &hour, &minute))
+			expr = g_strdup_printf("%4d-%02d-%02d %02d:%02d:00",
+				year, month + 1, day, hour, minute);
+
+		if (expr == NULL) {
+			alertpanel_error(_("Invalid hour."));
+			return NULL;
+		}
+		break;
+
 	case CRITERIA_TEST:
 		expr = gtk_entry_get_text(GTK_ENTRY(matcher.string_entry));
 		
@@ -1949,7 +1992,13 @@ static void prefs_matcher_criteria_select(GtkWidget *widget,
 				    (value == MATCH_ABOOK));
 	prefs_matcher_enable_widget(matcher.string_entry,
 				    (MATCH_CASE_REGEXP(value) ||
-				     value == MATCH_TEST || value == MATCH_DATE));
+				     value == MATCH_TEST));
+	prefs_matcher_enable_widget(matcher.calendar,
+				    (value == MATCH_DATE));
+	prefs_matcher_enable_widget(matcher.time_label,
+				    (value == MATCH_DATE));
+	prefs_matcher_enable_widget(matcher.time_entry,
+				    (value == MATCH_DATE));
 	prefs_matcher_enable_widget(matcher.numeric_entry,
 				    MATCH_NUMERIC(value));
 	prefs_matcher_enable_widget(matcher.numeric_label,
@@ -1990,6 +2039,8 @@ static void prefs_matcher_criteria_select(GtkWidget *widget,
 	case MATCH_DATE:
 		prefs_matcher_set_model(matcher.match_combo, matcher.model_date);
 		gtk_label_set_text(GTK_LABEL(matcher.match_label), _("Date is"));
+		gtk_calendar_select_today(GTK_CALENDAR(matcher.calendar));
+		gtkut_time_select_select_by_time(GTK_COMBO_BOX(matcher.time_entry), 0, 0);
 		break;
 	case MATCH_AGE:
 		prefs_matcher_set_model(matcher.match_combo, matcher.model_age);
@@ -2431,6 +2482,8 @@ static gboolean prefs_matcher_selected(GtkTreeSelection *selector,
 	GtkWidget *menu;
 	GtkTreeIter iter;
 	gboolean is_valid;
+	struct tm lt;
+	char  zone[6];
 
 	if (currently_selected)
 		return TRUE;
@@ -2531,9 +2584,17 @@ static gboolean prefs_matcher_selected(GtkTreeSelection *selector,
 	case MATCHCRITERIA_BODY_PART:
 	case MATCHCRITERIA_MESSAGE:
 	case MATCHCRITERIA_TEST:
+		gtk_entry_set_text(GTK_ENTRY(matcher.string_entry), prop->expr);
+		break;
+
 	case MATCHCRITERIA_DATE_AFTER:
 	case MATCHCRITERIA_DATE_BEFORE:
-		gtk_entry_set_text(GTK_ENTRY(matcher.string_entry), prop->expr);
+		zone[0] = '\0';
+		procheader_date_parse_to_tm(prop->expr, &lt, zone);
+		gtk_calendar_select_day(GTK_CALENDAR(matcher.calendar), lt.tm_mday);
+		gtk_calendar_select_month(GTK_CALENDAR(matcher.calendar), lt.tm_mon, lt.tm_year + 1900);
+		gtkut_time_select_select_by_time(GTK_COMBO_BOX(matcher.time_entry), lt.tm_hour, lt.tm_min);
+
 		break;
 
 	case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK:

commit ba29a2031c9c04cdbaa21ab15f195147ed50d85e
Author: Colin Leroy <colin at colino.net>
Date:   Fri Aug 24 11:07:06 2018 +0200

    Move time selector from vCalendar to gtkutils

diff --git a/src/gtk/gtkutils.c b/src/gtk/gtkutils.c
index 89d092c..53c2a97 100644
--- a/src/gtk/gtkutils.c
+++ b/src/gtk/gtkutils.c
@@ -2033,3 +2033,89 @@ gpointer gtkut_tree_view_get_selected_pointer(GtkTreeView *view,
 
 	return ptr;
 }
+
+static GList *get_predefined_times(void)
+{
+	int h,m;
+	GList *times = NULL;
+	for (h = 0; h < 24; h++) {
+		for (m = 0; m < 60; m += 15) {
+			gchar *tmp = g_strdup_printf("%02d:%02d", h, m);
+			times = g_list_append(times, tmp);
+		}
+	}
+	return times;
+}
+
+static int get_list_item_num(int h, int m)
+{
+	if (m % 15 != 0)
+		return -1;
+
+	return (h*4 + m/15);
+}
+
+GtkWidget *gtkut_time_select_combo_new()
+{
+	GtkWidget *combo = gtk_combo_box_text_new_with_entry();
+	GList *times = get_predefined_times();
+
+	gtk_combo_box_set_active(GTK_COMBO_BOX(combo), -1);
+	combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(combo), times);
+
+	list_free_strings_full(times);
+
+	return combo;
+}
+
+
+void gtkut_time_select_select_by_time(GtkComboBox *combo, int hour, int minute)
+{
+	gchar *time_text = g_strdup_printf("%02d:%02d", hour, minute);
+	gint num = get_list_item_num(hour, minute);
+
+	if (num > -1)
+		combobox_select_by_text(combo, time_text);
+	else
+		gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo))), time_text);
+
+	g_free(time_text);
+}
+
+static void get_time_from_combo(GtkComboBox *combo, int *h, int *m)
+{
+	gchar *tmp;
+	gchar **parts;
+
+	if (!h || !m) 
+		return;
+
+	tmp = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(combo))), 0, -1);
+	parts = g_strsplit(tmp, ":", 2);
+	if (parts[0] && parts[1] && *parts[0] && *parts[1]) {
+		*h = atoi(parts[0]);
+		*m = atoi(parts[1]);
+	}
+	g_strfreev(parts);
+	g_free(tmp);
+}
+
+gboolean gtkut_time_select_get_time(GtkComboBox *combo, int *hour, int *minute)
+{
+	const gchar *value = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo))));
+
+	if (value == NULL || strlen(value) != 5)
+		return FALSE;
+
+	if (hour == NULL || minute == NULL)
+		return FALSE;
+
+	get_time_from_combo(combo, hour, minute);
+
+	if (*hour < 0 || *hour > 23)
+		return FALSE;
+	if (*minute < 0 || *minute > 59)
+		return FALSE;
+
+	return TRUE;
+}
diff --git a/src/gtk/gtkutils.h b/src/gtk/gtkutils.h
index b290bb6..9a7f6c6 100644
--- a/src/gtk/gtkutils.h
+++ b/src/gtk/gtkutils.h
@@ -188,6 +188,10 @@ GtkUIManager *gtkut_ui_manager(void);
 GdkPixbuf *claws_load_pixbuf_fitting(GdkPixbuf *pixbuf, int box_width,
 				     int box_height);
 
+GtkWidget *gtkut_time_select_combo_new();
+void gtkut_time_select_select_by_time(GtkComboBox *combo, int hour, int minute);
+gboolean gtkut_time_select_get_time(GtkComboBox *combo, int *hour, int *minute);
+
 typedef void (*ClawsIOFunc)(gpointer data, gint source, GIOCondition condition);
 gint
 claws_input_add    (gint	      source,
diff --git a/src/plugins/vcalendar/vcal_meeting_gtk.c b/src/plugins/vcalendar/vcal_meeting_gtk.c
index 5b2dc26..d0ea92f 100644
--- a/src/plugins/vcalendar/vcal_meeting_gtk.c
+++ b/src/plugins/vcalendar/vcal_meeting_gtk.c
@@ -384,24 +384,6 @@ static gchar *get_organizer_name(VCalMeeting *meet)
 		return g_strdup("");
 }
 
-static void get_time_from_combo(GtkWidget *combo, int *h, int *m)
-{
-	gchar *tmp;
-	gchar **parts;
-
-	if (!h || !m) 
-		return;
-
-	tmp = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(combo))), 0, -1);
-	parts = g_strsplit(tmp, ":", 2);
-	if (parts[0] && parts[1] && *parts[0] && *parts[1]) {
-		*h = atoi(parts[0]);
-		*m = atoi(parts[1]);
-	}
-	g_strfreev(parts);
-	g_free(tmp);
-}
-
 static int get_current_gmt_offset(void)
 {
 	time_t now = time(NULL);
@@ -465,9 +447,9 @@ static gchar *get_date(VCalMeeting *meet, int start)
 	lt->tm_sec  = 0;
 
 	if (start) {
-		get_time_from_combo(meet->start_time, &lt->tm_hour, &lt->tm_min);
+		gtkut_time_select_get_time(GTK_COMBO_BOX(meet->start_time), &lt->tm_hour, &lt->tm_min);
 	} else {
-		get_time_from_combo(meet->end_time, &lt->tm_hour, &lt->tm_min);
+		gtkut_time_select_get_time(GTK_COMBO_BOX(meet->end_time), &lt->tm_hour, &lt->tm_min);
 	}
 
 	debug_print("%d %d %d, %d:%d\n", lt->tm_mday, lt->tm_mon, lt->tm_year, lt->tm_hour, lt->tm_min);
@@ -535,14 +517,6 @@ static gboolean meeting_key_pressed(GtkWidget *widget,
 	return FALSE;
 }
 
-static int get_list_item_num(int h, int m)
-{
-	if (m % 15 != 0)
-		return -1;
-
-	return (h*4 + m/15);
-}
-
 static void meeting_end_changed(GtkWidget *widget, gpointer data);
 
 static void meeting_start_changed(GtkWidget *widget, gpointer data)
@@ -552,9 +526,8 @@ static void meeting_start_changed(GtkWidget *widget, gpointer data)
 	struct tm end_lt;
 	time_t start_t, end_t;
 	guint d, m, y;
-	int num = -1;
 
-	if (strlen(gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(meet->start_time))))) < 5)
+	if (!gtkut_time_select_get_time(GTK_COMBO_BOX(meet->start_time), &start_lt.tm_hour, &start_lt.tm_min))
 		return;
 	tzset();
 
@@ -571,7 +544,6 @@ static void meeting_start_changed(GtkWidget *widget, gpointer data)
 
 	gtk_calendar_get_date(GTK_CALENDAR(meet->start_c), &y, &m, &d);
 	start_lt.tm_mday = d; start_lt.tm_mon  = m; start_lt.tm_year = y - 1900;
-	get_time_from_combo(meet->start_time, &start_lt.tm_hour, &start_lt.tm_min);
 
 	start_t = mktime(&start_lt);
 	debug_print("start %s\n", ctime(&start_t));
@@ -579,7 +551,8 @@ static void meeting_start_changed(GtkWidget *widget, gpointer data)
 	gtk_calendar_get_date(GTK_CALENDAR(meet->end_c), &y, &m, &d);
 	end_lt.tm_mday = d; end_lt.tm_mon  = m; end_lt.tm_year = y - 1900;
 
-	get_time_from_combo(meet->end_time, &end_lt.tm_hour, &end_lt.tm_min);
+	gtkut_time_select_get_time(GTK_COMBO_BOX(meet->end_time), &end_lt.tm_hour, &end_lt.tm_min);
+
 	end_t = mktime(&end_lt);
 
 	debug_print("end   %s\n", ctime(&end_t));
@@ -606,19 +579,8 @@ static void meeting_start_changed(GtkWidget *widget, gpointer data)
 				end_lt.tm_mon,
 				end_lt.tm_year + 1900);
 
-	num = get_list_item_num(end_lt.tm_hour, end_lt.tm_min);
-	if (num > -1) {
-		gchar *time_text = g_strdup_printf("%02d:%02d", end_lt.tm_hour, end_lt.tm_min);
-		combobox_select_by_text(GTK_COMBO_BOX(meet->end_time), time_text);
-		g_free(time_text);
-	} else {
-		gchar *tmp = g_strdup_printf("%02d:%02d",
-				end_lt.tm_hour, 
-				end_lt.tm_min);
-		gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(meet->end_time))),
-				   tmp);
-		g_free(tmp);
-	}
+	gtkut_time_select_select_by_time(GTK_COMBO_BOX(meet->end_time), end_lt.tm_hour, end_lt.tm_min);
+
 	g_signal_handlers_unblock_by_func(gtk_bin_get_child(GTK_BIN(meet->end_time)), meeting_end_changed, meet);
 	g_signal_handlers_unblock_by_func(meet->end_c, meeting_end_changed, meet);
 }
@@ -630,9 +592,8 @@ static void meeting_end_changed(GtkWidget *widget, gpointer data)
 	struct tm end_lt;
 	time_t start_t, end_t;
 	guint d, m, y;
-	int num = -1;
 
-	if (strlen(gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(meet->end_time))))) < 5)
+	if (!gtkut_time_select_get_time(GTK_COMBO_BOX(meet->end_time), &end_lt.tm_hour, &end_lt.tm_min))
 		return;
 	start_t = time(NULL);
 	end_t = time(NULL);
@@ -650,14 +611,13 @@ static void meeting_end_changed(GtkWidget *widget, gpointer data)
 	
 	gtk_calendar_get_date(GTK_CALENDAR(meet->start_c), &y, &m, &d);
 	start_lt.tm_mday = d; start_lt.tm_mon  = m; start_lt.tm_year = y - 1900;
-	get_time_from_combo(meet->start_time, &start_lt.tm_hour, &start_lt.tm_min);
+	gtkut_time_select_get_time(GTK_COMBO_BOX(meet->start_time), &start_lt.tm_hour, &start_lt.tm_min);
 
 	start_t = mktime(&start_lt);
 	debug_print("start %s\n", ctime(&start_t));
 
 	gtk_calendar_get_date(GTK_CALENDAR(meet->end_c), &y, &m, &d);
 	end_lt.tm_mday = d; end_lt.tm_mon  = m; end_lt.tm_year = y - 1900;
-	get_time_from_combo(meet->end_time, &end_lt.tm_hour, &end_lt.tm_min);
 
 	end_t = mktime(&end_lt);
 
@@ -687,19 +647,7 @@ static void meeting_end_changed(GtkWidget *widget, gpointer data)
 				start_lt.tm_mon,
 				start_lt.tm_year + 1900);
 
-	num = get_list_item_num(start_lt.tm_hour, start_lt.tm_min);
-	if (num > -1) {
-		gchar *time_text = g_strdup_printf("%02d:%02d", start_lt.tm_hour, start_lt.tm_min);
-		combobox_select_by_text(GTK_COMBO_BOX(meet->start_time), time_text);
-		g_free(time_text);
-	} else {
-		gchar *tmp = g_strdup_printf("%02d:%02d",
-				start_lt.tm_hour, 
-				start_lt.tm_min);
-		gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(meet->start_time))),
-				   tmp);
-		g_free(tmp);
-	}
+	gtkut_time_select_select_by_time(GTK_COMBO_BOX(meet->start_time), start_lt.tm_hour, start_lt.tm_min);
 
 	g_signal_handlers_unblock_by_func(gtk_bin_get_child(GTK_BIN(meet->start_time)), meeting_start_changed, meet);
 	g_signal_handlers_unblock_by_func(meet->start_c, meeting_start_changed, meet);
@@ -1358,19 +1306,6 @@ static gboolean send_meeting_cb(GtkButton *widget, gpointer data)
 	return res;
 }
 
-static GList *get_predefined_times(void)
-{
-	int h,m;
-	GList *times = NULL;
-	for (h = 0; h < 24; h++) {
-		for (m = 0; m < 60; m += 15) {
-			gchar *tmp = g_strdup_printf("%02d:%02d", h, m);
-			times = g_list_append(times, tmp);
-		}
-	}
-	return times;
-}
-
 static VCalMeeting *vcal_meeting_create_real(VCalEvent *event, gboolean visible)
 {
 	VCalMeeting *meet = g_new0(VCalMeeting, 1);
@@ -1379,9 +1314,7 @@ static VCalMeeting *vcal_meeting_create_real(VCalEvent *event, gboolean visible)
 	gchar *s = NULL;
 	int i = 0, num = 0;
 	GtkWidget *scrolledwin;
-	GList *times = NULL;
 	GList *accounts;
-	gchar *time_text = NULL;
 #ifdef GENERIC_UMPC
 	GtkWidget *notebook;
 	GtkWidget *maemo_vbox0;
@@ -1408,17 +1341,9 @@ static VCalMeeting *vcal_meeting_create_real(VCalEvent *event, gboolean visible)
 	meet->avail_img	= gtk_image_new_from_stock
                         (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
 
-	times = get_predefined_times();
-
-	meet->start_time = gtk_combo_box_text_new_with_entry();
-	gtk_combo_box_set_active(GTK_COMBO_BOX(meet->start_time), -1);
-	combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(meet->start_time), times);
+	meet->start_time = gtkut_time_select_combo_new();
 	
-	meet->end_time = gtk_combo_box_text_new_with_entry();
-	gtk_combo_box_set_active(GTK_COMBO_BOX(meet->end_time), -1);
-	combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(meet->end_time), times);
-
-	list_free_strings_full(times);
+	meet->end_time = gtkut_time_select_combo_new();
 
 	meet->location  	= gtk_entry_new();
 	meet->summary		= gtk_entry_new();
@@ -1484,9 +1409,7 @@ static VCalMeeting *vcal_meeting_create_real(VCalEvent *event, gboolean visible)
 		gtk_calendar_select_month(GTK_CALENDAR(meet->start_c),
 					lt->tm_mon, lt->tm_year + 1900);
 	
-		time_text = g_strdup_printf("%02d:%02d", lt->tm_hour, 0);
-		combobox_select_by_text(GTK_COMBO_BOX(meet->start_time), time_text);
-		g_free(time_text);
+		gtkut_time_select_select_by_time(GTK_COMBO_BOX(meet->start_time), lt->tm_hour, 0);
 
 		t += 3600;
 		lt = localtime_r(&t, &buft2);
@@ -1496,10 +1419,7 @@ static VCalMeeting *vcal_meeting_create_real(VCalEvent *event, gboolean visible)
 		gtk_calendar_select_month(GTK_CALENDAR(meet->end_c),
 					lt->tm_mon, lt->tm_year + 1900);
 
-		time_text = g_strdup_printf("%02d:%02d", lt->tm_hour, 0);
-		combobox_select_by_text(GTK_COMBO_BOX(meet->end_time), time_text);
-		g_free(time_text);
-
+		gtkut_time_select_select_by_time(GTK_COMBO_BOX(meet->end_time), lt->tm_hour, 0);
 	} else {
 		gtk_calendar_select_day(GTK_CALENDAR(meet->start_c),
 					get_dtdate(event->dtstart, DAY));
@@ -1513,37 +1433,13 @@ static VCalMeeting *vcal_meeting_create_real(VCalEvent *event, gboolean visible)
 					get_dtdate(event->dtend, MONTH)-1,
 					get_dtdate(event->dtend, YEAR));
 
-		num = get_list_item_num(get_dtdate(event->dtstart, HOUR), 
-					get_dtdate(event->dtstart, MINUTE));
-		if (num > -1) {
-			time_text = g_strdup_printf("%02d:%02d", get_dtdate(event->dtstart, HOUR), 
-								 get_dtdate(event->dtstart, MINUTE));
-			combobox_select_by_text(GTK_COMBO_BOX(meet->start_time), time_text);
-			g_free(time_text);
-		} else {
-			gchar *tmp = g_strdup_printf("%02d:%02d",
+		gtkut_time_select_select_by_time(GTK_COMBO_BOX(meet->start_time),
 					get_dtdate(event->dtstart, HOUR), 
 					get_dtdate(event->dtstart, MINUTE));
-			gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(meet->start_time))),
-					   tmp);
-			g_free(tmp);
-		}
 
-		num = get_list_item_num(get_dtdate(event->dtend, HOUR), 
-					get_dtdate(event->dtend, MINUTE));
-		if (num > -1) {
-			time_text = g_strdup_printf("%02d:%02d", get_dtdate(event->dtend, HOUR), 
-								 get_dtdate(event->dtend, MINUTE));
-			combobox_select_by_text(GTK_COMBO_BOX(meet->end_time), time_text);
-			g_free(time_text);
-		} else {
-			gchar *tmp = g_strdup_printf("%02d:%02d",
+		gtkut_time_select_select_by_time(GTK_COMBO_BOX(meet->end_time),
 					get_dtdate(event->dtend, HOUR), 
 					get_dtdate(event->dtend, MINUTE));
-			gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(meet->end_time))),
-					   tmp);
-			g_free(tmp);
-		}
 	}
 
 	g_signal_connect(G_OBJECT(meet->start_c), "day-selected",
@@ -1750,7 +1646,7 @@ VCalMeeting *vcal_meeting_create(VCalEvent *event)
 VCalMeeting *vcal_meeting_create_with_start(VCalEvent *event, struct tm *sdate)
 {
 	VCalMeeting *meet = vcal_meeting_create(event);
-	int num = -1;
+
 	gtk_calendar_select_day(GTK_CALENDAR(meet->start_c),
 				sdate->tm_mday);
 	gtk_calendar_select_day(GTK_CALENDAR(meet->end_c),
@@ -1762,22 +1658,13 @@ VCalMeeting *vcal_meeting_create_with_start(VCalEvent *event, struct tm *sdate)
 				sdate->tm_mon, sdate->tm_year+1900);
 
 	if (sdate->tm_hour != 0) {
-		num = get_list_item_num(sdate->tm_hour, 0);
-		if (num > -1) {
-			gchar *time_text = g_strdup_printf("%02d:%02d", sdate->tm_hour, 0);
-			combobox_select_by_text(GTK_COMBO_BOX(meet->start_time), time_text);
-			g_free(time_text);
-		} 
+		gtkut_time_select_select_by_time(GTK_COMBO_BOX(meet->start_time), sdate->tm_hour, 0);
+
 		if (sdate->tm_hour < 23) {
-			num = get_list_item_num(sdate->tm_hour+1, 0);
-			if (num > -1) {
-				gchar *time_text = g_strdup_printf("%02d:%02d", sdate->tm_hour+1, 0);
-				combobox_select_by_text(GTK_COMBO_BOX(meet->end_time), time_text);
-				g_free(time_text);
-			} 
+			gtkut_time_select_select_by_time(GTK_COMBO_BOX(meet->end_time), sdate->tm_hour+1, 0);
 		} else {
 			struct tm tm_tomorrow;
-			gchar *time_text;
+
 			tm_tomorrow.tm_mday = sdate->tm_mday;
 			tm_tomorrow.tm_mon = sdate->tm_mon;
 			tm_tomorrow.tm_wday = sdate->tm_wday;
@@ -1789,9 +1676,7 @@ VCalMeeting *vcal_meeting_create_with_start(VCalEvent *event, struct tm *sdate)
 			gtk_calendar_select_month(GTK_CALENDAR(meet->end_c),
 						tm_tomorrow.tm_mon, tm_tomorrow.tm_year);
 			
-			time_text = g_strdup_printf("%02d:%02d", 0, 0);
-			combobox_select_by_text(GTK_COMBO_BOX(meet->end_time), time_text);
-			g_free(time_text);
+			gtkut_time_select_select_by_time(GTK_COMBO_BOX(meet->end_time), 0, 0);
 		}
 	}
 	return meet;
@@ -2157,7 +2042,7 @@ gboolean vcal_meeting_export_freebusy(const gchar *path, const gchar *user,
 	icalcomponent_add_property(tzc,
 		icalproperty_new_tzname("Greenwich meridian time"));
 
-        icalcomponent_add_component(timezone, tzc);
+	icalcomponent_add_component(timezone, tzc);
 
 	icalcomponent_add_component(calendar, timezone);
 

commit eee41ab09d8ab73a9cb70c1444c5c6ba463949e3
Author: Colin Leroy <colin at colino.net>
Date:   Fri Aug 24 10:17:27 2018 +0200

    Filtering: simple GUI for date_after/before

diff --git a/src/prefs_matcher.c b/src/prefs_matcher.c
index 874cc4f..f80d2b1 100644
--- a/src/prefs_matcher.c
+++ b/src/prefs_matcher.c
@@ -106,6 +106,7 @@ static struct Matcher {
 	GtkWidget *addressbook_select_btn;
 
 	GtkTreeModel *model_age;
+	GtkTreeModel *model_date;
 	GtkTreeModel *model_age_units;
 	GtkTreeModel *model_contain;
 	GtkTreeModel *model_found;
@@ -186,7 +187,10 @@ enum {
 	CRITERIA_AGE_LOWER_HOURS = 40,
 
 	CRITERIA_MESSAGEID = 41,
-	CRITERIA_HEADERS_CONT = 42
+	CRITERIA_HEADERS_CONT = 42,
+
+	CRITERIA_DATE_AFTER = 43,
+	CRITERIA_DATE_BEFORE = 44
 };
 
 enum {
@@ -202,7 +206,8 @@ enum {
 	MATCH_PARTIAL	= 9,
 	MATCH_ABOOK	= 10,
 	MATCH_TAGS	= 11,
-	MATCH_TEST	= 12
+	MATCH_TEST	= 12,
+	MATCH_DATE	= 13
 };
 
 enum {
@@ -338,6 +343,11 @@ static void prefs_matcher_models_create(void)
 	matcher.model_age_units = GTK_TREE_MODEL(store);
 
 	store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN);
+	COMBOBOX_ADD(store, _("after"), CRITERIA_DATE_AFTER);
+	COMBOBOX_ADD(store, _("before"), CRITERIA_DATE_BEFORE);
+	matcher.model_date = GTK_TREE_MODEL(store);
+
+	store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN);
 	COMBOBOX_ADD(store, _("higher than"), CRITERIA_SCORE_GREATER);
 	COMBOBOX_ADD(store, _("lower than"), CRITERIA_SCORE_LOWER);
 	COMBOBOX_ADD(store, _("exactly"), CRITERIA_SCORE_EQUAL);
@@ -618,19 +628,20 @@ static void prefs_matcher_create(void)
 	criteria_combo = gtkut_sc_combobox_create(NULL, FALSE);
 	store = GTK_LIST_STORE(gtk_combo_box_get_model(
 				GTK_COMBO_BOX(criteria_combo)));
-	COMBOBOX_ADD(store, _("All messages"), 0);
-	COMBOBOX_ADD(store, _("Header"), 1);
-	COMBOBOX_ADD(store, _("Age"), 2);
-	COMBOBOX_ADD(store, _("Phrase"), 3);
-	COMBOBOX_ADD(store, _("Flags"), 4);
-	COMBOBOX_ADD(store, _("Color labels"), 5);
-	COMBOBOX_ADD(store, _("Thread"), 6);
-	COMBOBOX_ADD(store, _("Score"), 7);
-	COMBOBOX_ADD(store, _("Size"), 8);
-	COMBOBOX_ADD(store, _("Partially downloaded"), 9);
-	COMBOBOX_ADD(store, _("Address book"), 10);
-	COMBOBOX_ADD(store, _("Tags"), 11);
-	COMBOBOX_ADD(store, _("External program test"), 12);
+	COMBOBOX_ADD(store, _("All messages"), MATCH_ALL);
+	COMBOBOX_ADD(store, _("Header"), MATCH_HEADER);
+	COMBOBOX_ADD(store, _("Age"), MATCH_AGE);
+	COMBOBOX_ADD(store, _("Phrase"), MATCH_PHRASE);
+	COMBOBOX_ADD(store, _("Flags"), MATCH_FLAG);
+	COMBOBOX_ADD(store, _("Color labels"), MATCH_LABEL);
+	COMBOBOX_ADD(store, _("Thread"), MATCH_THREAD);
+	COMBOBOX_ADD(store, _("Score"), MATCH_SCORE);
+	COMBOBOX_ADD(store, _("Size"), MATCH_SIZE);
+	COMBOBOX_ADD(store, _("Partially downloaded"), MATCH_PARTIAL);
+	COMBOBOX_ADD(store, _("Address book"), MATCH_ABOOK);
+	COMBOBOX_ADD(store, _("Tags"), MATCH_TAGS);
+	COMBOBOX_ADD(store, _("External program test"), MATCH_TEST);
+	COMBOBOX_ADD(store, _("Date"), MATCH_DATE);
 
 	gtk_widget_set_size_request(criteria_combo, 150, -1);
 	gtk_combo_box_set_active(GTK_COMBO_BOX(criteria_combo), MATCH_ALL);
@@ -1160,6 +1171,10 @@ static gint prefs_matcher_get_criteria_from_matching(gint matching_id)
 		return CRITERIA_AGE_GREATER;
 	case MATCHCRITERIA_AGE_LOWER:
 		return CRITERIA_AGE_LOWER;
+	case MATCHCRITERIA_DATE_AFTER:
+		return CRITERIA_DATE_AFTER;
+	case MATCHCRITERIA_DATE_BEFORE:
+		return CRITERIA_DATE_BEFORE;
 	case MATCHCRITERIA_SCORE_GREATER:
 		return CRITERIA_SCORE_GREATER;
 	case MATCHCRITERIA_SCORE_LOWER:
@@ -1256,6 +1271,10 @@ static gint prefs_matcher_get_matching_from_criteria(gint criteria_id)
 		return MATCHCRITERIA_AGE_GREATER_HOURS;
 	case CRITERIA_AGE_LOWER_HOURS:
 		return MATCHCRITERIA_AGE_LOWER_HOURS;
+	case CRITERIA_DATE_AFTER:
+		return MATCHCRITERIA_DATE_AFTER;
+	case CRITERIA_DATE_BEFORE:
+		return MATCHCRITERIA_DATE_BEFORE;
 	case CRITERIA_SCORE_GREATER:
 		return MATCHCRITERIA_SCORE_GREATER;
 	case CRITERIA_SCORE_LOWER:
@@ -1381,6 +1400,7 @@ static gint prefs_matcher_get_criteria(void)
 	case MATCH_ALL:
 		return CRITERIA_ALL;
 	case MATCH_AGE:
+	case MATCH_DATE:
 	case MATCH_SCORE:
 	case MATCH_SIZE:
 	case MATCH_FLAG:
@@ -1524,6 +1544,8 @@ static MatcherProp *prefs_matcher_dialog_to_matcher(void)
 	case CRITERIA_HEADERS_PART:
 	case CRITERIA_HEADERS_CONT:
 	case CRITERIA_BODY_PART:
+	case CRITERIA_DATE_AFTER:
+	case CRITERIA_DATE_BEFORE:
 	case CRITERIA_MESSAGE:
 		expr = gtk_entry_get_text(GTK_ENTRY(matcher.string_entry));
 		
@@ -1927,7 +1949,7 @@ static void prefs_matcher_criteria_select(GtkWidget *widget,
 				    (value == MATCH_ABOOK));
 	prefs_matcher_enable_widget(matcher.string_entry,
 				    (MATCH_CASE_REGEXP(value) ||
-				     value == MATCH_TEST));
+				     value == MATCH_TEST || value == MATCH_DATE));
 	prefs_matcher_enable_widget(matcher.numeric_entry,
 				    MATCH_NUMERIC(value));
 	prefs_matcher_enable_widget(matcher.numeric_label,
@@ -1965,6 +1987,10 @@ static void prefs_matcher_criteria_select(GtkWidget *widget,
 		gtk_label_set_text(GTK_LABEL(matcher.match_label), _("Header"));
 		gtk_label_set_text(GTK_LABEL(matcher.match_label2), _("content is"));
 		break;
+	case MATCH_DATE:
+		prefs_matcher_set_model(matcher.match_combo, matcher.model_date);
+		gtk_label_set_text(GTK_LABEL(matcher.match_label), _("Date is"));
+		break;
 	case MATCH_AGE:
 		prefs_matcher_set_model(matcher.match_combo, matcher.model_age);
 		prefs_matcher_set_model(matcher.match_combo2, matcher.model_age_units);
@@ -2301,6 +2327,10 @@ static void prefs_matcher_set_criteria(const gint criteria)
 	case CRITERIA_AGE_LOWER_HOURS:
 		match_criteria = MATCH_AGE;
 		break;
+	case CRITERIA_DATE_AFTER:
+	case CRITERIA_DATE_BEFORE:
+		match_criteria = MATCH_DATE;
+		break;
 	case CRITERIA_SCORE_GREATER:
 	case CRITERIA_SCORE_LOWER:
 	case CRITERIA_SCORE_EQUAL:
@@ -2373,6 +2403,7 @@ static void prefs_matcher_set_criteria(const gint criteria)
 						criteria);
 		break;
 	case MATCH_AGE:
+	case MATCH_DATE:
 	case MATCH_SCORE:
 	case MATCH_SIZE:
 	case MATCH_FLAG:
@@ -2500,6 +2531,8 @@ static gboolean prefs_matcher_selected(GtkTreeSelection *selector,
 	case MATCHCRITERIA_BODY_PART:
 	case MATCHCRITERIA_MESSAGE:
 	case MATCHCRITERIA_TEST:
+	case MATCHCRITERIA_DATE_AFTER:
+	case MATCHCRITERIA_DATE_BEFORE:
 		gtk_entry_set_text(GTK_ENTRY(matcher.string_entry), prop->expr);
 		break;
 

commit 0314475ba605a707740f7e818d04a8ce66f619e8
Author: Colin Leroy <colin at colino.net>
Date:   Fri Aug 24 09:58:09 2018 +0200

    Filtering: add date_before and date_after

diff --git a/src/advsearch.c b/src/advsearch.c
index 3abbeaa..ecd3acd 100644
--- a/src/advsearch.c
+++ b/src/advsearch.c
@@ -157,6 +157,8 @@ gchar *advsearch_expand_search_string(const gchar *search_string)
 		{ "c",	"cc",				1,	TRUE,	TRUE  },
 		{ "C",	"to_or_cc",			1,	TRUE,	TRUE  },
 		{ "D",	"deleted",			0,	FALSE,	FALSE },
+		{ "da", "date_after",			1,	FALSE,	TRUE  },
+		{ "db", "date_before",			1,	FALSE,	TRUE  },
 		{ "e",	"header \"Sender\"",		1,	TRUE,	TRUE  },
 		{ "E",	"execute",			1,	FALSE,	TRUE  },
 		{ "f",	"from",				1,	TRUE,	TRUE  },
diff --git a/src/gtk/quicksearch.c b/src/gtk/quicksearch.c
index 33c883e..ca01473 100644
--- a/src/gtk/quicksearch.c
+++ b/src/gtk/quicksearch.c
@@ -485,6 +485,10 @@ static gchar *search_descr_strings[] = {
 	"c S",	 N_("messages carbon-copied to S"),
 	"C S",	 N_("message is either To: or Cc: to S"),
 	"D",	 N_("deleted messages"), /** how I can filter deleted messages **/
+	"da \"YYYY-MM-dd HH:mm:ss\"",  N_("messages whose date is after requested date "
+					  "(time is optional)"),
+	"db \"YYYY-MM-dd HH:mm:ss\"",  N_("messages whose date is before requested date "
+					  "(time is optional)"),
 	"e S",	 N_("messages which contain S in the Sender field"),
 	"E S",	 N_("true if execute \"S\" succeeds"),
 	"f S",	 N_("messages originating from user S"),
diff --git a/src/matcher.c b/src/matcher.c
index a0d8ab7..29581e9 100644
--- a/src/matcher.c
+++ b/src/matcher.c
@@ -112,6 +112,8 @@ static const MatchParser matchparser_tab[] = {
 	{MATCHCRITERIA_AGE_LOWER, "age_lower"},
 	{MATCHCRITERIA_AGE_GREATER_HOURS, "age_greater_hours"},
 	{MATCHCRITERIA_AGE_LOWER_HOURS, "age_lower_hours"},
+	{MATCHCRITERIA_DATE_AFTER, "date_after"},
+	{MATCHCRITERIA_DATE_BEFORE, "date_before"},
 	{MATCHCRITERIA_NEWSGROUPS, "newsgroups"},
 	{MATCHCRITERIA_NOT_NEWSGROUPS, "~newsgroups"},
 	{MATCHCRITERIA_MESSAGEID, "messageid"},
@@ -932,6 +934,27 @@ static gboolean matcherprop_match(MatcherProp *prop,
 		}
 		return ret;
 	}
+	case MATCHCRITERIA_DATE_AFTER:
+	{
+		gboolean ret;
+
+		ret = prop->value < info->date_t;
+
+		/* debug output */
+		if (debug_filtering_session
+				&& prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) {
+			if (ret) {
+				log_print(LOG_DEBUG_FILTERING,
+						"message date [ %ld ] is after [ %d ]\n",
+						info->date_t, prop->value);
+			} else {
+				log_print(LOG_DEBUG_FILTERING,
+						"message date [ %ld ] is not after [ %d ]\n",
+						info->date_t, prop->value);
+			}
+		}
+		return ret;
+	}
 	case MATCHCRITERIA_AGE_LOWER:
 		age_mult_hours = 24;
 		/* Fallthrough intended */
@@ -959,6 +982,27 @@ static gboolean matcherprop_match(MatcherProp *prop,
 		}
 		return ret;
 	}
+	case MATCHCRITERIA_DATE_BEFORE:
+	{
+		gboolean ret;
+
+		ret = prop->value > info->date_t;
+
+		/* debug output */
+		if (debug_filtering_session
+				&& prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) {
+			if (ret) {
+				log_print(LOG_DEBUG_FILTERING,
+						"message date [ %ld ] is before [ %d ]\n",
+						info->date_t, prop->value);
+			} else {
+				log_print(LOG_DEBUG_FILTERING,
+						"message date [ %ld ] is not before [ %d ]\n",
+						info->date_t, prop->value);
+			}
+		}
+		return ret;
+	}
 	case MATCHCRITERIA_SCORE_GREATER:
 	{
 		gboolean ret = (info->score > prop->value);
@@ -1912,6 +1956,8 @@ gboolean matcherlist_match(MatcherList *matchers, MsgInfo *info)
 		case MATCHCRITERIA_AGE_LOWER:
 		case MATCHCRITERIA_AGE_GREATER_HOURS:
 		case MATCHCRITERIA_AGE_LOWER_HOURS:
+		case MATCHCRITERIA_DATE_AFTER:
+		case MATCHCRITERIA_DATE_BEFORE:
 		case MATCHCRITERIA_NEWSGROUPS:
 		case MATCHCRITERIA_NOT_NEWSGROUPS:
 		case MATCHCRITERIA_MESSAGEID:
@@ -2104,6 +2150,8 @@ gchar *matcherprop_to_string(MatcherProp *matcher)
 		return g_strdup(criteria_str);
 	case MATCHCRITERIA_TEST:
 	case MATCHCRITERIA_NOT_TEST:
+	case MATCHCRITERIA_DATE_AFTER:
+	case MATCHCRITERIA_DATE_BEFORE:
 		quoted_expr = matcher_quote_str(matcher->expr);
 		matcher_str = g_strdup_printf("%s \"%s\"",
 					      criteria_str, quoted_expr);
diff --git a/src/matcher.h b/src/matcher.h
index e9c3239..392924d 100644
--- a/src/matcher.h
+++ b/src/matcher.h
@@ -88,6 +88,7 @@ enum {
 	MC_(TO_OR_CC), MC_(NOT_TO_AND_NOT_CC),
 	MC_(AGE_GREATER), MC_(AGE_LOWER),
 	MC_(AGE_GREATER_HOURS), MC_(AGE_LOWER_HOURS),
+	MC_(DATE_AFTER), MC_(DATE_BEFORE),
 	MC_(NEWSGROUPS), MC_(NOT_NEWSGROUPS),
 	MC_(MESSAGEID), MC_(NOT_MESSAGEID),
 	MC_(INREPLYTO), MC_(NOT_INREPLYTO),
diff --git a/src/matcher_parser_parse.y b/src/matcher_parser_parse.y
index ea37c44..19726de 100644
--- a/src/matcher_parser_parse.y
+++ b/src/matcher_parser_parse.y
@@ -25,6 +25,7 @@
 
 #include "utils.h"
 #include "filtering.h"
+#include "procheader.h"
 #include "matcher.h"
 #include "matcher_parser.h"
 #include "matcher_parser_lex.h"
@@ -326,6 +327,7 @@ int matcher_parserwrap(void)
 %token MATCHER_CC  MATCHER_NOT_CC  MATCHER_TO_OR_CC  MATCHER_NOT_TO_AND_NOT_CC
 %token MATCHER_AGE_GREATER  MATCHER_AGE_LOWER  MATCHER_NEWSGROUPS
 %token MATCHER_AGE_GREATER_HOURS  MATCHER_AGE_LOWER_HOURS
+%token MATCHER_DATE_AFTER  MATCHER_DATE_BEFORE
 %token MATCHER_NOT_NEWSGROUPS  MATCHER_INREPLYTO  MATCHER_NOT_INREPLYTO
 %token MATCHER_MESSAGEID MATCHER_NOT_MESSAGEID
 %token MATCHER_REFERENCES  MATCHER_NOT_REFERENCES  MATCHER_SCORE_GREATER
@@ -989,6 +991,28 @@ MATCHER_ALL
 	value = strtol($2, NULL, 0);
 	prop = matcherprop_new(criteria, NULL, 0, NULL, value);
 }
+| MATCHER_DATE_AFTER MATCHER_STRING
+{
+	gint criteria = 0;
+	gchar *expr = NULL;
+	time_t value;
+
+	criteria = MATCHCRITERIA_DATE_AFTER;
+	expr = $2;
+	value = procheader_date_parse(NULL, expr, 0);
+	prop = matcherprop_new(criteria, NULL, 0, expr, value);
+}
+| MATCHER_DATE_BEFORE MATCHER_STRING
+{
+	gint criteria = 0;
+	gchar *expr = NULL;
+	time_t value;
+
+	criteria = MATCHCRITERIA_DATE_BEFORE;
+	expr = $2;
+	value = procheader_date_parse(NULL, expr, 0);
+	prop = matcherprop_new(criteria, NULL, 0, expr, value);
+}
 | MATCHER_NEWSGROUPS match_type MATCHER_STRING
 {
 	gint criteria = 0;

-----------------------------------------------------------------------


hooks/post-receive
-- 
Claws Mail


More information about the Commits mailing list