diff options
author | Chenthill Palanisamy <pchen@src.gnome.org> | 2007-06-04 09:43:27 +0800 |
---|---|---|
committer | Chenthill Palanisamy <pchen@src.gnome.org> | 2007-06-04 09:43:27 +0800 |
commit | faad8a01e1a4fc4d425ed2ff850158339fb6bd37 (patch) | |
tree | b8be0cb43801b31d3573e5b0968d9e252dedb239 /calendar/gui | |
parent | 8bebb05056fd093d0302546fc65edb130c3c136a (diff) | |
download | gsoc2013-evolution-faad8a01e1a4fc4d425ed2ff850158339fb6bd37.tar.gz gsoc2013-evolution-faad8a01e1a4fc4d425ed2ff850158339fb6bd37.tar.zst gsoc2013-evolution-faad8a01e1a4fc4d425ed2ff850158339fb6bd37.zip |
Added advanced search options.
svn path=/trunk/; revision=33648
Diffstat (limited to 'calendar/gui')
-rw-r--r-- | calendar/gui/Makefile.am | 10 | ||||
-rw-r--r-- | calendar/gui/cal-search-bar.c | 521 | ||||
-rw-r--r-- | calendar/gui/cal-search-bar.h | 8 | ||||
-rw-r--r-- | calendar/gui/caltypes.xml | 278 | ||||
-rw-r--r-- | calendar/gui/e-cal-model.c | 31 | ||||
-rw-r--r-- | calendar/gui/e-cal-model.h | 1 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 67 | ||||
-rw-r--r-- | calendar/gui/memotypes.xml | 233 | ||||
-rw-r--r-- | calendar/gui/tasktypes.xml | 311 |
9 files changed, 1351 insertions, 109 deletions
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am index efb573ebce..2fa778b85c 100644 --- a/calendar/gui/Makefile.am +++ b/calendar/gui/Makefile.am @@ -51,6 +51,11 @@ ecalendarincludedir = $(privincludedir)/calendar/gui ecalendarinclude_HEADERS = \ e-cal-config.h +search_files = tasktypes.xml memotypes.xml caltypes.xml + +ruledir = $(privdatadir) +rule_DATA = $(search_files) + INCLUDES = \ -DG_LOG_DOMAIN=\"calendar-gui\" \ -I$(top_builddir)/shell \ @@ -60,6 +65,7 @@ INCLUDES = \ -I$(top_srcdir)/widgets \ -I$(top_srcdir)/widgets/misc \ -I$(top_srcdir)/a11y/calendar \ + -DSEARCH_RULE_DIR=\"$(ruledir)\" \ -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \ -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \ @@ -235,6 +241,7 @@ libevolution_calendar_la_LIBADD = \ $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \ $(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ + $(top_builddir)/filter/libfilter.la \ $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la \ $(LIBSOUP_LIBS) \ @@ -261,7 +268,8 @@ EXTRA_DIST = \ $(glade_DATA) \ $(schema_in_files) \ $(etspec_DATA) \ - $(server_in_files) + $(server_in_files) \ + $(search_files) BUILT_SOURCES = $(IDL_GENERATED) $(server_DATA) CLEANFILES = $(BUILT_SOURCES) diff --git a/calendar/gui/cal-search-bar.c b/calendar/gui/cal-search-bar.c index 7b2efc5de2..75e0d819ad 100644 --- a/calendar/gui/cal-search-bar.c +++ b/calendar/gui/cal-search-bar.c @@ -31,23 +31,39 @@ #include <gtk/gtksignal.h> #include <glib/gi18n.h> #include <libedataserver/e-categories.h> +#include <libecal/e-cal-time-util.h> #include <e-util/e-icon-factory.h> #include <libedataserver/e-categories.h> +#include <filter/rule-editor.h> #include "cal-search-bar.h" +#include "e-util/e-error.h" +#include "e-util/e-util-private.h" + typedef struct CALSearchBarItem { ESearchBarItem search; - char *image; -}CALSearchBarItem; + const char *image; +} CALSearchBarItem; + +static ESearchBarItem calendar_search_items[] = { + E_FILTERBAR_ADVANCED, + {NULL, 0, 0}, + E_FILTERBAR_SAVE, + E_FILTERBAR_EDIT, + {NULL, -1, 0} +}; + /* IDs and option items for the ESearchBar */ enum { SEARCH_SUMMARY_CONTAINS, SEARCH_DESCRIPTION_CONTAINS, + SEARCH_ANY_FIELD_CONTAINS, SEARCH_CATEGORY_IS, SEARCH_COMMENT_CONTAINS, SEARCH_LOCATION_CONTAINS, - SEARCH_ANY_FIELD_CONTAINS + SEARCH_ATTENDEE_CONTAINS + }; /* Comments are disabled because they are kind of useless right now, see bug 33247 */ @@ -61,14 +77,44 @@ static ESearchBarItem search_option_items[] = { }; /* IDs for the categories suboptions */ -#define CATEGORIES_ALL 0 -#define CATEGORIES_UNMATCHED 1 -#define CATEGORIES_OFFSET 3 + +typedef enum { + CATEGORIES_ALL, + CATEGORIES_UNMATCHED, + LAST_FIELD +} common_search_options; + +typedef enum { + N_DAY_TASK = LAST_FIELD, + ACTIVE_TASK, + OVERDUE_TASK, + COMPLETED_TASK, + TASK_WITH_ATTACHMENT, + TASK_LAST_FIELD +} task_search_options; + +typedef enum { + ACTIVE_APPONTMENT = LAST_FIELD, + N_DAY_APPOINTMENT, + CAL_LAST_FIELD +} cal_search_options; + +/* We add 2 to the offset to include the separators used to differenciate the quick search queries. */ +#define CATEGORIES_TASKS_OFFSET (TASK_LAST_FIELD + 2) +#define CATEGORIES_MEMOS_OFFSET (LAST_FIELD + 1) +#define CATEGORIES_CALENDAR_OFFSET (CAL_LAST_FIELD + 2) /* Private part of the CalSearchBar structure */ struct CalSearchBarPrivate { /* Array of categories */ GPtrArray *categories; + + RuleContext *search_context; + FilterRule *search_rule; + guint32 view_flag; + + time_t start; + time_t end; }; static void cal_search_bar_destroy (GtkObject *object); @@ -84,16 +130,17 @@ enum { static guint cal_search_bar_signals[LAST_SIGNAL] = { 0 }; -G_DEFINE_TYPE (CalSearchBar, cal_search_bar, E_SEARCH_BAR_TYPE) + +G_DEFINE_TYPE (CalSearchBar, cal_search_bar, E_FILTER_BAR_TYPE) /* Class initialization function for the calendar search bar */ static void cal_search_bar_class_init (CalSearchBarClass *class) { - ESearchBarClass *e_search_bar_class; - GtkObjectClass *object_class; - e_search_bar_class = (ESearchBarClass *) class; + EFilterBarClass *e_search_bar_class; + GtkObjectClass *object_class; + e_search_bar_class = (EFilterBarClass *) class; object_class = (GtkObjectClass *) class; cal_search_bar_signals[SEXP_CHANGED] = @@ -116,9 +163,7 @@ cal_search_bar_class_init (CalSearchBarClass *class) class->sexp_changed = NULL; class->category_changed = NULL; - - e_search_bar_class->search_activated = cal_search_bar_search_activated; - + ((ESearchBarClass *) e_search_bar_class)->search_activated = cal_search_bar_search_activated; object_class->destroy = cal_search_bar_destroy; } @@ -133,6 +178,9 @@ cal_search_bar_init (CalSearchBar *cal_search) priv->categories = g_ptr_array_new (); g_ptr_array_set_size (priv->categories, 0); + + priv->start = -1; + priv->end = -1; } /* Frees an array of categories */ @@ -168,6 +216,17 @@ cal_search_bar_destroy (GtkObject *object) priv->categories = NULL; } + if (priv->search_rule) { + g_object_unref (priv->search_rule); + priv->search_rule = NULL; + } + + /* FIXME + if (priv->search_context) { + g_object_unref (priv->search_context); + priv->search_context = NULL; + }*/ + g_free (priv); cal_search->priv = NULL; } @@ -186,14 +245,13 @@ notify_sexp_changed (CalSearchBar *cal_search, const char *sexp) sexp); } -/* Returns the string of the currently selected category, NULL for "Unmatched", - * or (const char *) 1 for "All". - */ +/* Returns the string of the currently selected category, NULL for "Unmatched" and "All +*/ static const char * get_current_category (CalSearchBar *cal_search) { CalSearchBarPrivate *priv; - gint viewid; + gint viewid, i; priv = cal_search->priv; @@ -201,18 +259,20 @@ get_current_category (CalSearchBar *cal_search) viewid = e_search_bar_get_viewitem_id (E_SEARCH_BAR (cal_search)); - if (viewid == CATEGORIES_ALL) - return (const char *) 1; - else if (viewid == CATEGORIES_UNMATCHED) + if (viewid == CATEGORIES_ALL || viewid == CATEGORIES_UNMATCHED) return NULL; - else { - int i; - - i = viewid - CATEGORIES_OFFSET; - g_assert (i >= 0 && i < priv->categories->len); + if (priv->view_flag == CAL_SEARCH_TASKS_DEFAULT) + i = viewid - CATEGORIES_TASKS_OFFSET; + else if (priv->view_flag == CAL_SEARCH_MEMOS_DEFAULT) + i = viewid - CATEGORIES_MEMOS_OFFSET; + else if (priv->view_flag == CAL_SEARCH_CALENDAR_DEFAULT) + i = viewid - CATEGORIES_CALENDAR_OFFSET; + + if (i >= 0 && i < priv->categories->len) return priv->categories->pdata[i]; - } + else + return NULL; } @@ -221,22 +281,123 @@ get_current_category (CalSearchBar *cal_search) * as NULL. */ static char * -get_category_sexp (CalSearchBar *cal_search) +get_show_option_sexp (CalSearchBar *cal_search) { - const char *category; + CalSearchBarPrivate *priv ; + gint viewid ; + char *start, *end, *due, *ret = NULL; + const char *category = NULL ; + time_t start_range, end_range; - category = get_current_category (cal_search); + priv = cal_search->priv; + viewid = e_search_bar_get_viewitem_id (E_SEARCH_BAR (cal_search)); - if (category == NULL) + if (viewid == CATEGORIES_UNMATCHED) return g_strdup ("(has-categories? #f)"); /* Unfiled items */ - else if (category == (const char *) 1) { + else if (viewid == CATEGORIES_ALL) return NULL; /* All items */ + + switch (priv->view_flag) { + case CAL_SEARCH_TASKS_DEFAULT: + if (viewid == N_DAY_TASK) { + start_range = time(NULL); + end_range = time_add_day(start_range, 7); + start = isodate_from_time_t (start_range); + due = isodate_from_time_t (end_range); + + ret = g_strdup_printf ("(due-in-time-range? (make-time \"%s\")" + " (make-time \"%s\"))", + start, due); + + g_free (start); + g_free (due); + + return ret; + } else if (viewid == ACTIVE_TASK) { + /* Shows the tasks due for an year from now which are not completed yet*/ + start_range = time(NULL); + end_range = time_add_day(start_range, 365); + start = isodate_from_time_t (start_range); + due = isodate_from_time_t (end_range); + + ret = g_strdup_printf ("(and (due-in-time-range? (make-time \"%s\")" + " (make-time \"%s\")) (not (is-completed?)))", + start, due); + + g_free (start); + g_free (due); + + return ret; + } else if (viewid == OVERDUE_TASK) { + /* Shows the tasks which are overdue from lower limit 1970 to the current time */ + start_range = 0; + end_range = time (NULL); + start = isodate_from_time_t (start_range); + due = isodate_from_time_t (end_range); + + ret = g_strdup_printf ("(and (due-in-time-range? (make-time \"%s\")" + " (make-time \"%s\")) (not (is-completed?)))", + start, due); + + g_free (start); + g_free (due); + + return ret; + } else if (viewid == COMPLETED_TASK) + return g_strdup ("(is-completed?)"); + else if (viewid == TASK_WITH_ATTACHMENT) + return g_strdup ("(has-attachments?)"); + break; + case CAL_SEARCH_CALENDAR_DEFAULT: + if (viewid == ACTIVE_APPONTMENT) { + /* Shows next one year's Appointments */ + start_range = time (NULL); + end_range = time_add_day (start_range, 365); + start = isodate_from_time_t (start_range); + end = isodate_from_time_t (end_range); + + ret = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\")" + " (make-time \"%s\"))", + start, end); + + cal_search->priv->start = start_range; + cal_search->priv->end = end_range; + + g_free (start); + g_free (end); + + return ret; + } else if (viewid == N_DAY_APPOINTMENT) { + start_range = time (NULL); + end_range = time_add_day (start_range, 7); + start = isodate_from_time_t (start_range); + end = isodate_from_time_t (end_range); + + ret = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\")" + " (make-time \"%s\"))", + start, end); + + cal_search->priv->start = start_range; + cal_search->priv->end = end_range; + + g_free (start); + g_free (end); + + return ret; + } + break; + default: + break; } + + category = get_current_category (cal_search); + + if (category != NULL) + return g_strdup_printf ("(has-categories? \"%s\")", category); else - return g_strdup_printf ("(has-categories? \"%s\")", category); /* Specific category */ + return NULL; } - /* Sets the query string to be (contains? "field" "text") */ static void notify_e_cal_view_contains (CalSearchBar *cal_search, const char *field, const char *view) @@ -257,11 +418,12 @@ notify_e_cal_view_contains (CalSearchBar *cal_search, const char *field, const c /* Apply the selected view on search */ - view = get_category_sexp (cal_search); - if (view && *view) + if (view && *view){ sexp = g_strconcat ("(and ",sexp, view, ")", NULL); - + } + notify_sexp_changed (cal_search, sexp); + g_free (sexp); } @@ -272,7 +434,7 @@ notify_category_is (CalSearchBar *cal_search) { char *sexp; - sexp = get_category_sexp (cal_search); + sexp = get_show_option_sexp (cal_search); if (!sexp) notify_sexp_changed (cal_search, "#t"); /* Match all */ @@ -289,39 +451,62 @@ static void regen_query (CalSearchBar *cal_search) { int id; - const char *category_sexp; + char *show_option_sexp = NULL; + char *sexp = NULL; + GString *out = NULL; + EFilterBar *efb = (EFilterBar *) cal_search; /* Fetch the data from the ESearchBar's entry widgets */ id = e_search_bar_get_item_id (E_SEARCH_BAR (cal_search)); + cal_search->priv->start = -1; + cal_search->priv->end = -1; + /* Get the selected view */ - category_sexp = get_category_sexp (cal_search); + show_option_sexp = get_show_option_sexp (cal_search); /* Generate the different types of queries */ switch (id) { case SEARCH_ANY_FIELD_CONTAINS: - notify_e_cal_view_contains (cal_search, "any", category_sexp); + notify_e_cal_view_contains (cal_search, "any", show_option_sexp); break; case SEARCH_SUMMARY_CONTAINS: - notify_e_cal_view_contains (cal_search, "summary", category_sexp); + notify_e_cal_view_contains (cal_search, "summary", show_option_sexp); break; case SEARCH_DESCRIPTION_CONTAINS: - notify_e_cal_view_contains (cal_search, "description", category_sexp); + notify_e_cal_view_contains (cal_search, "description", show_option_sexp); break; case SEARCH_COMMENT_CONTAINS: - notify_e_cal_view_contains (cal_search, "comment", category_sexp); + notify_e_cal_view_contains (cal_search, "comment", show_option_sexp); break; case SEARCH_LOCATION_CONTAINS: - notify_e_cal_view_contains (cal_search, "location", category_sexp); + notify_e_cal_view_contains (cal_search, "location", show_option_sexp); + break; + case SEARCH_ATTENDEE_CONTAINS: + notify_e_cal_view_contains (cal_search, "attendee", show_option_sexp); + break; + case E_FILTERBAR_ADVANCED_ID: + out = g_string_new (""); + filter_rule_build_code (efb->current_query, out); + + if (show_option_sexp && *show_option_sexp) + sexp = g_strconcat ("(and ", out->str, show_option_sexp, ")", NULL); + + notify_sexp_changed (cal_search, sexp ? sexp : out->str); + + g_string_free (out, TRUE); + g_free(sexp); break; default: g_assert_not_reached (); } + + g_free (show_option_sexp); } #if 0 @@ -407,13 +592,44 @@ generate_viewoption_menu (CALSearchBarItem *subitems) return menu; } +static void +setup_category_options (CalSearchBar *cal_search, CALSearchBarItem *subitems, gint index, gint offset) +{ + CalSearchBarPrivate *priv; + gint i; + + priv = cal_search->priv; + + if (priv->categories->len > 0) { + subitems[index].search.text = NULL; /* separator */ + subitems[index].search.id = 0; + subitems[index].image = NULL; + + for (i = 0; i < priv->categories->len; i++) { + const char *category; + + category = priv->categories->pdata[i] ? priv->categories->pdata [i] : ""; + + /* The search.text field should not be free'd */ + subitems[i + offset].search.text = (char *) category; + subitems[i + offset].search.id = i + offset; + subitems[i + offset].image = e_categories_get_icon_file_for (category); + } + index = i + offset; + } + + subitems[index].search.id = -1; /* terminator */ + subitems[index].search.text = NULL; + subitems[index].image = NULL; +} + + /* Creates the suboptions menu for the ESearchBar with the list of categories */ static void make_suboptions (CalSearchBar *cal_search) { CalSearchBarPrivate *priv; - CALSearchBarItem *subitems; - int i; + CALSearchBarItem *subitems = NULL; GtkWidget *menu; priv = cal_search->priv; @@ -421,56 +637,110 @@ make_suboptions (CalSearchBar *cal_search) g_assert (priv->categories != NULL); /* Categories plus "all", "unmatched", separator, terminator */ - subitems = g_new (CALSearchBarItem, priv->categories->len + 3 + 1); /* All, unmatched, separator */ - subitems[0].search.text = _("Any Category"); - subitems[0].search.id = CATEGORIES_ALL; - subitems[0].image = NULL; + if (priv->view_flag == CAL_SEARCH_TASKS_DEFAULT) { + subitems = g_new (CALSearchBarItem, priv->categories->len + CATEGORIES_TASKS_OFFSET + 1); - subitems[1].search.text = _("Unmatched"); - subitems[1].search.id = CATEGORIES_UNMATCHED; - subitems[1].image = NULL; - - /* All the other items */ + subitems[0].search.text = _("Any Category"); + subitems[0].search.id = CATEGORIES_ALL; + subitems[0].image = NULL; - if (priv->categories->len > 0) { - subitems[2].search.text = NULL; /* separator */ - subitems[2].search.id = 0; - subitems[2].image = 0; - - for (i = 0; i < priv->categories->len; i++) { - const char *category; - char *str; - - category = priv->categories->pdata[i]; - str = g_strdup (category ? category : ""); - - subitems[i + CATEGORIES_OFFSET].search.text = str; - subitems[i + CATEGORIES_OFFSET].search.id = i + CATEGORIES_OFFSET; - subitems[i + CATEGORIES_OFFSET].image = g_strdup (e_categories_get_icon_file_for(str)); - } - - subitems[i + CATEGORIES_OFFSET].search.id = -1; /* terminator */ - subitems[2].search.text = NULL; - subitems[2].image = NULL; - } else { - - subitems[2].search.id = -1; /* terminator */ - subitems[2].search.text = NULL; - subitems[2].image = NULL; - } - - menu = generate_viewoption_menu (subitems); - e_search_bar_set_viewoption_menu ((ESearchBar *)cal_search, menu); - - /* Free the strings */ - for (i = 0; i < priv->categories->len; i++) { - g_free (subitems[i + CATEGORIES_OFFSET].search.text); - g_free (subitems[i + CATEGORIES_OFFSET].image); + subitems[1].search.text = _("Unmatched"); + subitems[1].search.id = CATEGORIES_UNMATCHED; + subitems[1].image = NULL; + + subitems[2].search.text = NULL; + subitems[2].search.id = 0; + subitems[2].image = 0; + + subitems[3].search.text = _("Next 7 days Tasks"); + subitems[3].search.id = N_DAY_TASK; + subitems[3].image = NULL; + + subitems[4].search.text = _("Active Tasks"); + subitems[4].search.id = ACTIVE_TASK; + subitems[4].image = NULL; + + subitems[5].search.text = _("Over Due Tasks"); + subitems[5].search.id = OVERDUE_TASK; + subitems[5].image = NULL; + + subitems[6].search.text = _("Completed Tasks"); + subitems[6].search.id = COMPLETED_TASK; + subitems[6].image = NULL; + + subitems[7].search.text = _("Tasks With Attachments"); + subitems[7].search.id = TASK_WITH_ATTACHMENT; + subitems[7].image = NULL; + + /* All the other items */ + setup_category_options (cal_search, subitems, 8, CATEGORIES_TASKS_OFFSET); + + menu = generate_viewoption_menu (subitems); + e_search_bar_set_viewoption_menu ((ESearchBar *)cal_search, menu); + + } else if (priv->view_flag == CAL_SEARCH_MEMOS_DEFAULT) { + subitems = g_new (CALSearchBarItem, priv->categories->len + CATEGORIES_MEMOS_OFFSET + 1); + + /* All, unmatched, separator */ + + subitems[0].search.text = _("Any Category"); + subitems[0].search.id = CATEGORIES_ALL; + subitems[0].image = NULL; + + subitems[1].search.text = _("Unmatched"); + subitems[1].search.id = CATEGORIES_UNMATCHED; + subitems[1].image = NULL; + + /* All the other items */ + setup_category_options (cal_search, subitems, 2, CATEGORIES_MEMOS_OFFSET); + + menu = generate_viewoption_menu (subitems); + e_search_bar_set_viewoption_menu ((ESearchBar *)cal_search, menu); + + } else if (priv->view_flag == CAL_SEARCH_CALENDAR_DEFAULT) { + subitems = g_new (CALSearchBarItem, priv->categories->len + CATEGORIES_CALENDAR_OFFSET + 1); + + /* All, unmatched, separator */ + + subitems[0].search.text = _("Any Category"); + subitems[0].search.id = CATEGORIES_ALL; + subitems[0].image = NULL; + + subitems[1].search.text = _("Unmatched"); + subitems[1].search.id = CATEGORIES_UNMATCHED; + subitems[1].image = NULL; + + subitems[2].search.text = NULL; + subitems[2].search.id = 0; + subitems[2].image = 0; + + subitems[3].search.text = _("Active Appointments"); + subitems[3].search.id = ACTIVE_APPONTMENT; + subitems[3].image = NULL; + + subitems[4].search.text = _("Next 7 Day Appointments"); + subitems[4].search.id = N_DAY_APPOINTMENT; + subitems[4].image = NULL; + + /* All the other items */ + setup_category_options (cal_search, subitems, 5, CATEGORIES_CALENDAR_OFFSET); + + menu = generate_viewoption_menu (subitems); + e_search_bar_set_viewoption_menu ((ESearchBar *)cal_search, menu); } - g_free (subitems); + + if(subitems != NULL) + g_free (subitems); +} + +static void +search_menu_activated (ESearchBar *esb, int id) +{ + if (id == E_FILTERBAR_ADVANCED_ID) + e_search_bar_set_item_id (esb, id); } /** @@ -488,6 +758,11 @@ cal_search_bar_construct (CalSearchBar *cal_search, guint32 flags) ESearchBarItem *items; guint32 bit = 0x1; int i, j; + char *xmlfile = NULL; + char *userfile = NULL; + FilterPart *part; + RuleContext *search_context; + FilterRule *search_rule; g_return_val_if_fail (IS_CAL_SEARCH_BAR (cal_search), NULL); @@ -503,10 +778,51 @@ cal_search_bar_construct (CalSearchBar *cal_search, guint32 flags) items[j].text = NULL; items[j].id = -1; + search_context = rule_context_new (); + cal_search->priv->view_flag = flags; + + rule_context_add_part_set (search_context, "partset", filter_part_get_type (), + rule_context_add_part, rule_context_next_part); + rule_context_add_rule_set (search_context, "ruleset", filter_rule_get_type (), + rule_context_add_rule, rule_context_next_rule); + + if (flags == CAL_SEARCH_MEMOS_DEFAULT) { + userfile = g_build_filename (g_get_home_dir (), ".evolution/memos/searches.xml", NULL); + xmlfile = g_build_filename (SEARCH_RULE_DIR, "memotypes.xml", NULL); + } else if (flags == CAL_SEARCH_TASKS_DEFAULT) { + userfile = g_build_filename (g_get_home_dir (), ".evolution/tasks/searches.xml", NULL); + xmlfile = g_build_filename (SEARCH_RULE_DIR, "tasktypes.xml", NULL); + } else { + userfile = g_build_filename (g_get_home_dir (), ".evolution/calendar/searches.xml", NULL); + xmlfile = g_build_filename (SEARCH_RULE_DIR, "caltypes.xml", NULL); + } + + g_object_set_data_full (G_OBJECT (search_context), "user", userfile, g_free); + g_object_set_data_full (G_OBJECT (search_context), "system", xmlfile, g_free); + + rule_context_load (search_context, xmlfile, userfile); + search_rule = filter_rule_new (); + part = rule_context_next_part (search_context, NULL); - e_search_bar_construct (E_SEARCH_BAR (cal_search), NULL, items); + if (part == NULL) + g_warning ("Could not load calendar search; no parts."); + else + filter_rule_add_part (search_rule, filter_part_clone (part)); + + e_filter_bar_new_construct (search_context, xmlfile, userfile, NULL, cal_search, + (EFilterBar*) cal_search ); + e_search_bar_set_menu ((ESearchBar *) cal_search, calendar_search_items); + + g_signal_connect ((ESearchBar *) cal_search, "menu_activated", G_CALLBACK (search_menu_activated), cal_search); + make_suboptions (cal_search); + cal_search->priv->search_rule = search_rule; + cal_search->priv->search_context = search_context; + + g_free (xmlfile); + g_free (userfile); + return cal_search; } @@ -514,9 +830,9 @@ cal_search_bar_construct (CalSearchBar *cal_search, guint32 flags) * cal_search_bar_new: * flags: bitfield of items to appear in the search menu * - * Creates a new calendar search bar. + * creates a new calendar search bar. * - * Return value: A newly-created calendar search bar. You should connect to the + * return value: a newly-created calendar search bar. you should connect to the * "sexp_changed" signal to monitor changes in the generated sexps. **/ GtkWidget * @@ -605,8 +921,19 @@ cal_search_bar_get_category (CalSearchBar *cal_search) category = get_current_category (cal_search); - if (!category || category == (const char *) 1) - return NULL; - else - return category; + return category; +} + +void +cal_search_bar_get_time_range (CalSearchBar *cal_search, time_t *start, time_t *end) +{ + CalSearchBarPrivate *priv; + + g_return_if_fail (IS_CAL_SEARCH_BAR (cal_search)); + + priv = cal_search->priv; + + *start = priv->start; + *end = priv->end; } + diff --git a/calendar/gui/cal-search-bar.h b/calendar/gui/cal-search-bar.h index dfb235a378..53b8a346ad 100644 --- a/calendar/gui/cal-search-bar.h +++ b/calendar/gui/cal-search-bar.h @@ -48,18 +48,18 @@ enum { #define CAL_SEARCH_ALL (0xff) #define CAL_SEARCH_CALENDAR_DEFAULT (0x33) -#define CAL_SEARCH_TASKS_DEFAULT (0x23) +#define CAL_SEARCH_TASKS_DEFAULT (0xE3) #define CAL_SEARCH_MEMOS_DEFAULT (0x23) typedef struct { - ESearchBar search_bar; + EFilterBar search_bar; /* Private data */ CalSearchBarPrivate *priv; } CalSearchBar; typedef struct { - ESearchBarClass parent_class; + EFilterBarClass parent_class; /* Notification signals */ @@ -77,6 +77,8 @@ void cal_search_bar_set_categories (CalSearchBar *cal_search, GPtrArray *categor const char *cal_search_bar_get_category (CalSearchBar *cal_search); +void cal_search_bar_get_time_range (CalSearchBar *cal_search, time_t *start, time_t *end); + G_END_DECLS diff --git a/calendar/gui/caltypes.xml b/calendar/gui/caltypes.xml new file mode 100644 index 0000000000..73038d2600 --- /dev/null +++ b/calendar/gui/caltypes.xml @@ -0,0 +1,278 @@ +<?xml version="1.0"?> +<filterdescription> +<partset> + <part name="summary"> + <title>Summary</title> + <input type="optionlist" name="summary-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "summary" ${summary})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "summary" ${summary}))</code> + </option> + </input> + <input type="string" name="summary"/> + </part> + + <part name="description"> + <title>Description</title> + <input type="optionlist" name="description-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "description" ${description})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "description" ${description}))</code> + </option> + </input> + <input type="string" name="description"/> + </part> + <part name="anyfield"> + <title>Any Field</title> + <input type="optionlist" name="anyfield-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "any" ${anyfield})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "any" ${anyfield}))</code> + </option> + </input> + <input type="string" name="anyfield"/> + </part> + + <part name="name5"> + <title>Classification</title> + <input type="optionlist" name="name-type"> + <option value="is"> + <title>is</title> + <code>(contains? "classification" ${classification})</code> + </option> + <option value="is not"> + <title>is not</title> + <code>(not(contains? "classification" ${classification}))</code> + </option> + </input> + <input type="optionlist" name="classification"> + <option value="Public"> + <title>Public</title> + </option> + <option value="Private"> + <title>Private</title> + </option> + <option value="Confidential"> + <title>Confidential</title> + </option> + </input> + </part> + + + <part name="name2"> + <title>Organizer</title> + <input type="optionlist" name="name-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "organizer" ${name})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "organizer" ${name}))</code> + </option> + </input> + <input type="string" name="name"/> + </part> + + <part name="name3"> + <title>Attendee</title> + <input type="optionlist" name="name-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "attendee" ${name})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "attendee" ${name}))</code> + </option> + </input> + <input type="string" name="name"/> + </part> + + <part name="name4"> + <title>Loaction</title> + <input type="optionlist" name="name-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "location" ${name})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "location" ${name}))</code> + </option> + </input> + <input type="string" name="name"/> + </part> + + <part name="category"> + <title>Category</title> + <input type="optionlist" name="category-type"> + <option value="is"> + <title>is</title> + <code>(has-categories? ${category})</code> + </option> + <option value="is not"> + <title>is not</title> + <code>(not(has-categories? ${category}))</code> + </option> + </input> + <input type="optionlist" name="category"> + <option value="Anniversary"> + <title>Anniversary</title> + </option> + <option value="Holiday"> + <title>Holiday</title> + </option> + <option value="Ideas"> + <title>Ideas</title> + </option> + <option value="Status"> + <title>Status</title> + </option> + <option value="Holiday Cards"> + <title>Holiday Cards</title> + </option> + <option value="Hot Contacts"> + <title>Hot Contacts</title> + </option> + <option value="International"> + <title>International</title> + </option> + <option value="Next 7 days"> + <title>Next 7 days</title> + </option> + <option value="Birthday"> + <title>Birthday</title> + </option> + <option value="VIP"> + <title>VIP</title> + </option> + <option value="Gifts"> + <title>Gifts</title> + </option> + <option value="Waiting"> + <title>Waiting</title> + </option> + <option value="Key Customer"> + <title>Key Customer</title> + </option> + <option value="Time & Expenses"> + <title>Time & Expenses </title> + </option> + <option value="Miscellaneous"> + <title>Miscellaneous</title> + </option> + <option value="Business"> + <title>Business</title> + </option> + <option value="Personal"> + <title>Personal</title> + </option> + <option value="Suppliers"> + <title>Suppliers</title> + </option> + <option value="Goals/Objectives"> + <title>Goals/Objectives</title> + </option> + <option value="Strategies"> + <title>Strategies</title> + </option> + <option value="Competition"> + <title>Competition</title> + </option> + <option value="Favourites"> + <title>Favourites</title> + </option> + <option value="Phone Calls"> + <title>Phone Calls</title> + </option> + </input> + </part> + + <part name="attachments"> + <title>Attachments</title> + <input type="optionlist" name="match-type"> + <option value="exist"> + <title>Exist</title> + <code> + (has-attachments?) + </code> + </option> + <option value="not exist"> + <title>Do Not Exist</title> + <code> + (not(has-attachments?)) + </code> + </option> + </input> + </part> + + <part name="recurrences"> + <title>Recurrence</title> + <input type="optionlist" name="match-type"> + <option value="exist"> + <title>Exist</title> + <code> + (has-recurrences?) + </code> + </option> + <option value="not exist"> + <title>Do Not Exist</title> + <code> + (not (has-recurrences?)) + </code> + </option> + </input> + </part> + </partset> + +<ruleset> + <rule grouping="any" source="demand"> + <_title>Summary Contain</_title> + <partset> + <part name="summary"> + <value name="summary-type" type="option" value="contains"/> + <value name="summary" type="string"/> + </part> + </partset> + + <sources/> + </rule> + + <rule grouping="any" source="demand"> + <_title>Description Contain</_title> + <partset> + <part name="description"> + <value name="description-type" type="option" value="contains"/> + <value name="description" type="string"/> + </part> + </partset> + <sources/> + </rule> + + <rule grouping="any" source="demand"> + <_title>Any field contains</_title> + <partset> + <part name="anyfield"> + <value name="anyfield-type" type="option" value="contains"/> + <value name="anyfield" type="string"/> + </part> + </partset> + <sources/> + </rule> + + </ruleset> + + </filterdescription> diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index 78afb704a3..5cdc412a54 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -1812,6 +1812,37 @@ e_cal_model_set_search_query (ECalModel *model, const char *sexp) } /** + * e_cal_model_set_query + */ +void +e_cal_model_set_search_query_with_time_range (ECalModel *model, const char *sexp, time_t start, time_t end) +{ + ECalModelPrivate *priv; + gboolean do_query = FALSE; + + g_return_if_fail (E_IS_CAL_MODEL (model)); + + priv = model->priv; + + if (strcmp (sexp ? sexp : "", priv->search_sexp ? priv->search_sexp : "")) { + if (priv->search_sexp) + g_free (priv->search_sexp); + + priv->search_sexp = g_strdup (sexp); + do_query = TRUE; + } + + if (!(priv->start == start && priv->end == end)) { + priv->start = start; + priv->end = end; + do_query = TRUE; + } + + if (do_query) + redo_queries (model); +} + +/** * e_cal_model_create_component_with_defaults */ icalcomponent * diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h index 5fcef40a29..46418d9f80 100644 --- a/calendar/gui/e-cal-model.h +++ b/calendar/gui/e-cal-model.h @@ -154,6 +154,7 @@ void e_cal_model_generate_instances (ECalModel gpointer cb_data); GPtrArray * e_cal_model_get_object_array (ECalModel *model); void e_cal_model_set_instance_times (ECalModelComponent *comp_data, const icaltimezone *zone); +void e_cal_model_set_search_query_with_time_range (ECalModel *model, const char *sexp, time_t start, time_t end); diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 3c27eb3fe2..864cc064fa 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -185,6 +185,10 @@ struct _GnomeCalendarPrivate { time_t visible_start; time_t visible_end; gboolean updating; + + /* If this is true list view uses range of showing the events as the dates selected in date navigator which is one month, else + it uses the date range set in search bar */ + gboolean lview_select_daten_range; }; /* Signal IDs */ @@ -883,6 +887,7 @@ set_search_query (GnomeCalendar *gcal, const char *sexp) { GnomeCalendarPrivate *priv; int i; + time_t start, end; g_return_if_fail (gcal != NULL); g_return_if_fail (GNOME_IS_CALENDAR (gcal)); @@ -900,8 +905,23 @@ set_search_query (GnomeCalendar *gcal, const char *sexp) update_query (gcal); /* Set the query on the views */ - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) - e_cal_model_set_search_query (e_calendar_view_get_model (priv->views[i]), sexp); + for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { + if (i == GNOME_CAL_LIST_VIEW) { + if (!priv->lview_select_daten_range) { + cal_search_bar_get_time_range ((CalSearchBar *)priv->search_bar, &start, &end); + e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end); + } else { + start = priv->base_view_time; + get_times_for_views (gcal, GNOME_CAL_LIST_VIEW, &start, &end); + + e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end); + + if (priv->current_view_type == GNOME_CAL_LIST_VIEW) + gnome_calendar_update_date_navigator (gcal); + } + } else + e_cal_model_set_search_query (e_calendar_view_get_model (priv->views[i]), sexp); + } /* Set the query on the task pad */ update_todo_view (gcal); @@ -932,8 +952,20 @@ static void search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer data) { GnomeCalendar *gcal; + const char *d_sexp = "occur-in-time-range?"; gcal = GNOME_CALENDAR (data); + + /* Choose List view if the search made in the search bar is based on date */ + if(sexp != NULL && strstr (sexp, d_sexp ) != NULL) { + gcal->priv->lview_select_daten_range = FALSE; + gtk_widget_hide (GTK_WIDGET (gcal->priv->date_navigator)); + gnome_calendar_set_view (gcal, GNOME_CAL_LIST_VIEW); + } else { + gcal->priv->lview_select_daten_range = TRUE; + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); + } + set_search_query (gcal, sexp); } @@ -1209,10 +1241,6 @@ update_memo_view (GnomeCalendar *gcal) priv = gcal->priv; /* Set the query on the memo pad*/ - if (priv->memo_sexp) { - g_free (priv->memo_sexp); - } - model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo)); view_model = e_calendar_view_get_model(priv->views[priv->current_view_type]); e_cal_model_get_time_range (view_model, &start, &end); @@ -1221,6 +1249,10 @@ update_memo_view (GnomeCalendar *gcal) iso_start = isodate_from_time_t (start); iso_end = isodate_from_time_t (end); + if (priv->memo_sexp) { + g_free (priv->memo_sexp); + } + priv->memo_sexp = g_strdup_printf ("(and (occur-in-time-range? (make-time \"%s\")" " (make-time \"%s\"))" " %s)", @@ -1692,6 +1724,7 @@ gnome_calendar_init (GnomeCalendar *gcal) priv->current_view_type = GNOME_CAL_DAY_VIEW; priv->range_selected = FALSE; + priv->lview_select_daten_range = TRUE; setup_config (gcal); setup_widgets (gcal); @@ -1997,7 +2030,10 @@ update_view_times (GnomeCalendar *gcal, time_t start_time) model = e_calendar_view_get_model (priv->views[i]); get_times_for_views (gcal, i, &real_start_time, &end_time); - e_cal_model_set_time_range (model, real_start_time, end_time); + if (i == GNOME_CAL_LIST_VIEW && !priv->lview_select_daten_range) + continue; + + e_cal_model_set_time_range (model, real_start_time, end_time); } } @@ -2183,15 +2219,18 @@ display_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean gra case GNOME_CAL_DAY_VIEW: if (!priv->range_selected) e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), 1); - + + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); break; case GNOME_CAL_WORK_WEEK_VIEW: preserve_day = TRUE; + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); break; case GNOME_CAL_WEEK_VIEW: preserve_day = TRUE; + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); break; case GNOME_CAL_MONTH_VIEW: @@ -2199,9 +2238,14 @@ display_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean gra e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), 6); preserve_day = TRUE; + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); break; case GNOME_CAL_LIST_VIEW: + if (!priv->lview_select_daten_range) + gtk_widget_hide (GTK_WIDGET (gcal->priv->date_navigator)); + else + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); break; default: @@ -2267,6 +2311,10 @@ display_view_cb (GalViewInstance *view_instance, GalView *view, gpointer data) display_view (gcal, view_type, TRUE); gnome_calendar_update_date_navigator (gcal); gnome_calendar_notify_dates_shown_changed (gcal); + + if (!priv->lview_select_daten_range && priv->current_view_type != GNOME_CAL_LIST_VIEW) + update_query (gcal); + } /** @@ -3255,6 +3303,9 @@ gnome_calendar_update_date_navigator (GnomeCalendar *gcal) if (!GTK_WIDGET_VISIBLE (priv->date_navigator)) return; + if (priv->current_view_type == GNOME_CAL_LIST_VIEW && !priv->lview_select_daten_range) + return; + model = e_calendar_view_get_model (priv->views[priv->current_view_type]); e_cal_model_get_time_range (model, &start, &end); diff --git a/calendar/gui/memotypes.xml b/calendar/gui/memotypes.xml new file mode 100644 index 0000000000..20a60529f7 --- /dev/null +++ b/calendar/gui/memotypes.xml @@ -0,0 +1,233 @@ +<?xml version="1.0"?> +<filterdescription> +<partset> + <part name="summary"> + <title>Summary</title> + <input type="optionlist" name="summary-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "summary" ${summary})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "summary" ${summary}))</code> + </option> + </input> + <input type="string" name="summary"/> + </part> + + <part name="description"> + <title>Description</title> + <input type="optionlist" name="description-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "description" ${description})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "description" ${description}))</code> + </option> + </input> + <input type="string" name="description"/> + </part> + + <part name="anyfield"> + <title>Any Field</title> + <input type="optionlist" name="anyfield-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "any" ${anyfield})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "any" ${anyfield}))</code> + </option> + </input> + <input type="string" name="anyfield"/> + </part> + + <part name="name2"> + <title>Organizer</title> + <input type="optionlist" name="name-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "organizer" ${name})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "organizer" ${name}))</code> + </option> + </input> + <input type="string" name="name"/> + </part> + +<part name="name2"> + <title>Classification</title> + <input type="optionlist" name="name-type"> + <option value="is"> + <title>is</title> + <code>(contains? "classification" ${classification})</code> + </option> + <option value="is not"> + <title>is not</title> + <code>(not(contains? "classification" ${classification}))</code> + </option> + </input> + <input type="optionlist" name="classification"> + <option value="Public"> + <title>Public</title> + </option> + <option value="Private"> + <title>Private</title> + </option> + <option value="Confidential"> + <title>Confidential</title> + </option> + </input> + </part> + + <part name="category"> + <title>Category</title> + <input type="optionlist" name="category-type"> + <option value="is"> + <title>is</title> + <code>(has-categories? ${category})</code> + </option> + <option value="is not"> + <title>is not</title> + <code>(not(has-categories? ${category}))</code> + </option> + </input> + <input type="optionlist" name="category"> + <option value="Anniversary"> + <title>Anniversary</title> + </option> + <option value="Holiday"> + <title>Holiday</title> + </option> + <option value="Ideas"> + <title>Ideas</title> + </option> + <option value="Status"> + <title>Status</title> + </option> + <option value="Holiday Cards"> + <title>Holiday Cards</title> + </option> + <option value="Hot Contacts"> + <title>Hot Contacts</title> + </option> + <option value="International"> + <title>International</title> + </option> + <option value="Next 7 days"> + <title>Next 7 days</title> + </option> + <option value="Birthday"> + <title>Birthday</title> + </option> + <option value="VIP"> + <title>VIP</title> + </option> + <option value="Gifts"> + <title>Gifts</title> + </option> + <option value="Waiting"> + <title>Waiting</title> + </option> + <option value="Key Customer"> + <title>Key Customer</title> + </option> + <option value="Time & Expenses"> + <title>Time & Expenses </title> + </option> + <option value="Miscellaneous"> + <title>Miscellaneous</title> + </option> + <option value="Business"> + <title>Business</title> + </option> + <option value="Personal"> + <title>Personal</title> + </option> + <option value="Suppliers"> + <title>Suppliers</title> + </option> + <option value="Goals/Objectives"> + <title>Goals/Objectives</title> + </option> + <option value="Strategies"> + <title>Strategies</title> + </option> + <option value="Competition"> + <title>Competition</title> + </option> + <option value="Favourites"> + <title>Favourites</title> + </option> + <option value="Phone Calls"> + <title>Phone Calls</title> + </option> + </input> + </part> + +<part name="attachments"> + <title>Attachments</title> + <input type="optionlist" name="match-type"> + <option value="exist"> + <title>Exist</title> + <code> + (has-attachments?) + + </code> + </option> + <option value="not exist"> + <title>Do Not Exist</title> + <code> + (not(has-attachments?)) + </code> + </option> + </input> + </part> + + +</partset> + +<ruleset> + + <rule grouping="any" source="demand"> + <_title>Summary Contain</_title> + <partset> + <part name="summary"> + <value name="summary-type" type="option" value="contains"/> + <value name="summary" type="string"/> + </part> + </partset> + <sources/> + </rule> + + <rule grouping="any" source="demand"> + <_title>Description Contain</_title> + <partset> + <part name="description"> + <value name="description-type" type="option" value="contains"/> + <value name="description" type="string"/> + </part> + </partset> + <sources/> + </rule> + + <rule grouping="any" source="demand"> + <_title>Any field contains</_title> + <partset> + <part name="anyfield"> + <value name="anyfield-type" type="option" value="contains"/> + <value name="anyfield" type="string"/> + </part> + </partset> + <sources/> + </rule> + + </ruleset> + + </filterdescription> diff --git a/calendar/gui/tasktypes.xml b/calendar/gui/tasktypes.xml new file mode 100644 index 0000000000..5871a3abbf --- /dev/null +++ b/calendar/gui/tasktypes.xml @@ -0,0 +1,311 @@ +<?xml version="1.0"?> +<filterdescription> + <partset> + <part name="summary"> + <title>Summary</title> + <input type="optionlist" name="summary-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "summary" ${summary})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "summary" ${summary}))</code> + </option> + </input> + <input type="string" name="summary"/> + </part> + + <part name="description"> + <title>Description</title> + <input type="optionlist" name="description-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "description" ${description})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "description" ${description}))</code> + </option> + </input> + <input type="string" name="description"/> + </part> + + <part name="name2"> + <title>Organizer</title> + <input type="optionlist" name="name-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "organizer" ${name})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "organizer" ${name}))</code> + </option> + </input> + <input type="string" name="name"/> + </part> + + <part name="name3"> + <title>Attendee</title> + <input type="optionlist" name="name-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "attendee" ${name})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "attendee" ${name}))</code> + </option> + </input> + <input type="string" name="name"/> + </part> + + <part name="anyfield"> + <title>Any Field</title> + <input type="optionlist" name="anyfield-type"> + <option value="contains"> + <title>contains</title> + <code>(contains? "any" ${anyfield})</code> + </option> + <option value="not contains"> + <title>does not contain</title> + <code>(not (contains? "any" ${anyfield}))</code> + </option> + </input> + <input type="string" name="anyfield"/> + </part> + + <part name="status"> + <title>Status</title> + <input type="optionlist" name="status-type"> + <option value="is"> + <title>is</title> + <code>(contains? "status" ${status})</code> + </option> + <option value="is not"> + <title>is not</title> + <code>(not(contains? "status" ${status}))</code> + </option> + </input> + <input type="optionlist" name="status"> + <option value="NOT STARTED"> + <title>Not Started</title> + </option> + <option value="IN PROGRESS"> + <title>In progress</title> + </option> + <option value="COMPLETED"> + <title>Completed</title> + </option> + <option value="CANCELLED"> + <title>Cancelled</title> + </option> + + </input> + </part> + + <part name="attachments"> + <title>Attachments</title> + <input type="optionlist" name="match-type"> + <option value="exist"> + <title>Exist</title> + <code> + (has-attachments?) + </code> + </option> + <option value="not exist"> + <title>Do Not Exist</title> + <code> + (not(has-attachments?)) + </code> + </option> + </input> + </part> + + <part name="priority"> + <title>Priority</title> + <input type="optionlist" name="priority-type"> + <option value="is"> + <title>is</title> + <code>(contains? "priority" ${priority})</code> + </option> + <option value="is not"> + <title>is not</title> + <code>(not(contains? "priority" ${priority}))</code> + </option> + </input> + <input type="optionlist" name="priority"> + <option value="HIGH"> + <title>High</title> + </option> + <option value="NORMAL"> + <title>Normal</title> + </option> + <option value="LOW"> + <title>Low</title> + </option> + <option value="UNDEFINED"> + <title>Undefined</title> + </option> + + </input> + </part> + + <part name="category"> + <title>Category</title> + <input type="optionlist" name="category-type"> + <option value="is"> + <title>is</title> + <code>(has-categories? ${category})</code> + </option> + <option value="is not"> + <title>is not</title> + <code>(not(has-categories? ${category}))</code> + </option> + </input> + <input type="optionlist" name="category"> + <option value="Anniversary"> + <title>Anniversary</title> + </option> + <option value="Holiday"> + <title>Holiday</title> + </option> + <option value="Ideas"> + <title>Ideas</title>ke + </option> + <option value="Status"> + <title>Status</title> + </option> + <option value="Holiday Cards"> + <title>Holiday Cards</title> + </option> + <option value="Hot Contacts"> + <title>Hot Contacts</title> + </option> + <option value="International"> + <title>International</title> + </option> + <option value="Next 7 days"> + <title>Next 7 days</title> + </option> + <option value="Birthday"> + <title>Birthday</title> + </option> + <option value="VIP"> + <title>VIP</title> + </option> + <option value="Gifts"> + <title>Gifts</title> + </option> + <option value="Waiting"> + <title>Waiting</title> + </option> + <option value="Key Customer"> + <title>Key Customer</title> + </option> + <option value="Time & Expenses"> + <title>Time & Expenses </title> + </option> + <option value="Miscellaneous"> + <title>Miscellaneous</title> + </option> + <option value="Business"> + <title>Business</title> + </option> + <option value="Personal"> + ke + <title>Personal</title> + </option> + <option value="Suppliers"> + <title>Suppliers</title> + </option> + <option value="Goals/Objectives"> + <title>Goals/Objectives</title> + </option> + <option value="Strategies"> + <title>Strategies</title> + </option> + <option value="Competition"> + <title>Competition</title> + </option> + <option value="Favourites"> + <title>Favourites</title> + </option> + <option value="Phone Calls"> + <title>Phone Calls</title> + </option> + </input> + </part> + + <part name="completed"> + <title>% Completed</title> + <input type="optionlist" name="completed-type"> + <option value="is"> + <title>is</title> + <code> + (= (percent-complete?) ${versus} ) + </code> + </option> + <option value="is-not"> + <title>is not</title> + <code> + (not(= (percent-complete?) ${versus} )) + </code> + </option> + <option value="greater-than"> + <title>is greater than</title> + <code> + (> (percent-complete?) ${versus} ) + </code> + </option> + <option value="less-than"> + <title>is less than</title> + <code> + (< (percent-complete?) ${versus} ) + </code> + </option> + </input> + <input type="completedpercent" name="versus"/> + </part> + + </partset> + <ruleset> + <rule grouping="any" source="demand"> + <_title>Summary Contain</_title> + <partset> + <part name="summary"> + <value name="summary-type" type="option" value="contains"/> + <value name="summary" type="string"/> + </part> + </partset> + + <sources/> + </rule> + + <rule grouping="any" source="demand"> + <_title>Description Contain</_title> + <partset> + <part name="description"> + <value name="description-type" type="option" value="contains"/> + <value name="description" type="string"/> + </part> + </partset> + + <sources/> + </rule> + + <rule grouping="any" source="demand"> + <_title>Any field contains</_title> + <partset> + <part name="anyfield"> + <value name="anyfield-type" type="option" value="contains"/> + <value name="anyfield" type="string"/> + </part> + </partset> + + <sources/> + </rule> + </ruleset> + +</filterdescription> |