No issues found
1 /*
2 * e-task-shell-view.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 *
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19 *
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "e-task-shell-view-private.h"
27
28 enum {
29 PROP_0,
30 PROP_CONFIRM_PURGE
31 };
32
33 static gpointer parent_class;
34 static GType task_shell_view_type;
35
36 static void
37 task_shell_view_set_property (GObject *object,
38 guint property_id,
39 const GValue *value,
40 GParamSpec *pspec)
41 {
42 switch (property_id) {
43 case PROP_CONFIRM_PURGE:
44 e_task_shell_view_set_confirm_purge (
45 E_TASK_SHELL_VIEW (object),
46 g_value_get_boolean (value));
47 return;
48 }
49
50 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
51 }
52
53 static void
54 task_shell_view_get_property (GObject *object,
55 guint property_id,
56 GValue *value,
57 GParamSpec *pspec)
58 {
59 switch (property_id) {
60 case PROP_CONFIRM_PURGE:
61 g_value_set_boolean (
62 value, e_task_shell_view_get_confirm_purge (
63 E_TASK_SHELL_VIEW (object)));
64 return;
65 }
66
67 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
68 }
69
70 static void
71 task_shell_view_dispose (GObject *object)
72 {
73 e_task_shell_view_private_dispose (E_TASK_SHELL_VIEW (object));
74
75 /* Chain up to parent's dispose() method. */
76 G_OBJECT_CLASS (parent_class)->dispose (object);
77 }
78
79 static void
80 task_shell_view_finalize (GObject *object)
81 {
82 e_task_shell_view_private_finalize (E_TASK_SHELL_VIEW (object));
83
84 /* Chain up to parent's finalize() method. */
85 G_OBJECT_CLASS (parent_class)->finalize (object);
86 }
87
88 static void
89 task_shell_view_constructed (GObject *object)
90 {
91 /* Chain up to parent's constructed() method. */
92 G_OBJECT_CLASS (parent_class)->constructed (object);
93
94 e_task_shell_view_private_constructed (E_TASK_SHELL_VIEW (object));
95 }
96
97 static void
98 task_shell_view_execute_search (EShellView *shell_view)
99 {
100 ETaskShellContent *task_shell_content;
101 EShellWindow *shell_window;
102 EShellContent *shell_content;
103 EShellSearchbar *searchbar;
104 EActionComboBox *combo_box;
105 GtkRadioAction *action;
106 ECalComponentPreview *task_preview;
107 EPreviewPane *preview_pane;
108 ETaskTable *task_table;
109 EWebView *web_view;
110 ECalModel *model;
111 icaltimezone *timezone;
112 struct icaltimetype current_time;
113 time_t start_range;
114 time_t end_range;
115 time_t now_time;
116 gchar *start, *end;
117 gchar *query;
118 gchar *temp;
119 gint value;
120
121 shell_window = e_shell_view_get_shell_window (shell_view);
122 shell_content = e_shell_view_get_shell_content (shell_view);
123
124 task_shell_content = E_TASK_SHELL_CONTENT (shell_content);
125 searchbar = e_task_shell_content_get_searchbar (task_shell_content);
126
127 task_shell_content = E_TASK_SHELL_CONTENT (shell_content);
128 task_table = e_task_shell_content_get_task_table (task_shell_content);
129 model = e_task_table_get_model (task_table);
130 timezone = e_cal_model_get_timezone (model);
131 current_time = icaltime_current_time_with_zone (timezone);
132 now_time = time_day_begin (icaltime_as_timet (current_time));
133
134 action = GTK_RADIO_ACTION (ACTION (TASK_SEARCH_ANY_FIELD_CONTAINS));
135 value = gtk_radio_action_get_current_value (action);
136
137 if (value == TASK_SEARCH_ADVANCED) {
138 query = e_shell_view_get_search_query (shell_view);
139
140 if (!query)
141 query = g_strdup ("");
142 } else {
143 const gchar *format;
144 const gchar *text;
145 GString *string;
146
147 text = e_shell_searchbar_get_search_text (searchbar);
148
149 if (text == NULL || *text == '\0') {
150 text = "";
151 value = TASK_SEARCH_SUMMARY_CONTAINS;
152 }
153
154 switch (value) {
155 default:
156 text = "";
157 /* fall through */
158
159 case TASK_SEARCH_SUMMARY_CONTAINS:
160 format = "(contains? \"summary\" %s)";
161 break;
162
163 case TASK_SEARCH_DESCRIPTION_CONTAINS:
164 format = "(contains? \"description\" %s)";
165 break;
166
167 case TASK_SEARCH_ANY_FIELD_CONTAINS:
168 format = "(contains? \"any\" %s)";
169 break;
170 }
171
172 /* Build the query. */
173 string = g_string_new ("");
174 e_sexp_encode_string (string, text);
175 query = g_strdup_printf (format, string->str);
176 g_string_free (string, TRUE);
177 }
178
179 /* Apply selected filter. */
180 combo_box = e_shell_searchbar_get_filter_combo_box (searchbar);
181 value = e_action_combo_box_get_current_value (combo_box);
182 switch (value) {
183 case TASK_FILTER_ANY_CATEGORY:
184 break;
185
186 case TASK_FILTER_UNMATCHED:
187 temp = g_strdup_printf (
188 "(and (has-categories? #f) %s)", query);
189 g_free (query);
190 query = temp;
191 break;
192
193 case TASK_FILTER_NEXT_7_DAYS_TASKS:
194 start_range = now_time;
195 end_range = time_day_end (time_add_day (start_range, 7));
196 start = isodate_from_time_t (start_range);
197 end = isodate_from_time_t (end_range);
198
199 temp = g_strdup_printf (
200 "(and %s (due-in-time-range? "
201 "(make-time \"%s\") (make-time \"%s\")))",
202 query, start, end);
203 g_free (query);
204 query = temp;
205 break;
206
207 case TASK_FILTER_ACTIVE_TASKS:
208 start_range = now_time;
209 end_range = time_day_end (time_add_day (start_range, 365));
210 start = isodate_from_time_t (start_range);
211 end = isodate_from_time_t (end_range);
212
213 temp = g_strdup_printf (
214 "(and %s (due-in-time-range? "
215 "(make-time \"%s\") (make-time \"%s\")) "
216 "(not (is-completed?)))",
217 query, start, end);
218 g_free (query);
219 query = temp;
220 break;
221
222 case TASK_FILTER_OVERDUE_TASKS:
223 start_range = 0;
224 end_range = time_day_end (now_time);
225 start = isodate_from_time_t (start_range);
226 end = isodate_from_time_t (end_range);
227
228 temp = g_strdup_printf (
229 "(and %s (due-in-time-range? "
230 "(make-time \"%s\") (make-time \"%s\")) "
231 "(not (is-completed?)))",
232 query, start, end);
233 g_free (query);
234 query = temp;
235 break;
236
237 case TASK_FILTER_COMPLETED_TASKS:
238 temp = g_strdup_printf (
239 "(and (is-completed?) %s)", query);
240 g_free (query);
241 query = temp;
242 break;
243
244 case TASK_FILTER_TASKS_WITH_ATTACHMENTS:
245 temp = g_strdup_printf (
246 "(and (has-attachments?) %s)", query);
247 g_free (query);
248 query = temp;
249 break;
250
251 default:
252 {
253 GList *categories;
254 const gchar *category_name;
255
256 categories = e_util_get_searchable_categories ();
257 category_name = g_list_nth_data (categories, value);
258 g_list_free (categories);
259
260 temp = g_strdup_printf (
261 "(and (has-categories? \"%s\") %s)",
262 category_name, query);
263 g_free (query);
264 query = temp;
265 break;
266 }
267 }
268
269 /* Honor the user's preference to hide completed tasks. */
270 temp = calendar_config_get_hide_completed_tasks_sexp (FALSE);
271 if (temp != NULL) {
272 gchar *temp2;
273
274 temp2 = g_strdup_printf ("(and %s %s)", temp, query);
275 g_free (query);
276 g_free (temp);
277 query = temp2;
278 }
279
280 /* Submit the query. */
281 e_cal_model_set_search_query (model, query);
282 g_free (query);
283
284 preview_pane =
285 e_task_shell_content_get_preview_pane (task_shell_content);
286
287 web_view = e_preview_pane_get_web_view (preview_pane);
288 task_preview = E_CAL_COMPONENT_PREVIEW (web_view);
289 e_cal_component_preview_clear (task_preview);
290 }
291
292 static void
293 task_shell_view_update_actions (EShellView *shell_view)
294 {
295 EShellContent *shell_content;
296 EShellSidebar *shell_sidebar;
297 EShellWindow *shell_window;
298 GtkAction *action;
299 const gchar *label;
300 gboolean sensitive;
301 guint32 state;
302
303 /* Be descriptive. */
304 gboolean any_tasks_selected;
305 gboolean has_primary_source;
306 gboolean multiple_tasks_selected;
307 gboolean primary_source_is_writable;
308 gboolean primary_source_is_removable;
309 gboolean primary_source_is_remote_deletable;
310 gboolean primary_source_in_collection;
311 gboolean selection_has_url;
312 gboolean selection_is_assignable;
313 gboolean single_task_selected;
314 gboolean some_tasks_complete;
315 gboolean some_tasks_incomplete;
316 gboolean sources_are_editable;
317 gboolean refresh_supported;
318
319 /* Chain up to parent's update_actions() method. */
320 E_SHELL_VIEW_CLASS (parent_class)->update_actions (shell_view);
321
322 shell_window = e_shell_view_get_shell_window (shell_view);
323
324 shell_content = e_shell_view_get_shell_content (shell_view);
325 state = e_shell_content_check_state (shell_content);
326
327 single_task_selected =
328 (state & E_TASK_SHELL_CONTENT_SELECTION_SINGLE);
329 multiple_tasks_selected =
330 (state & E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE);
331 selection_is_assignable =
332 (state & E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN);
333 sources_are_editable =
334 (state & E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT);
335 some_tasks_complete =
336 (state & E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE);
337 some_tasks_incomplete =
338 (state & E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE);
339 selection_has_url =
340 (state & E_TASK_SHELL_CONTENT_SELECTION_HAS_URL);
341
342 shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
343 state = e_shell_sidebar_check_state (shell_sidebar);
344
345 has_primary_source =
346 (state & E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE);
347 primary_source_is_writable =
348 (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE);
349 primary_source_is_removable =
350 (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE);
351 primary_source_is_remote_deletable =
352 (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOTE_DELETABLE);
353 primary_source_in_collection =
354 (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION);
355 refresh_supported =
356 (state & E_TASK_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH);
357
358 any_tasks_selected =
359 (single_task_selected || multiple_tasks_selected);
360
361 action = ACTION (TASK_ASSIGN);
362 sensitive =
363 single_task_selected && sources_are_editable &&
364 selection_is_assignable;
365 gtk_action_set_sensitive (action, sensitive);
366
367 action = ACTION (TASK_DELETE);
368 sensitive = any_tasks_selected && sources_are_editable;
369 gtk_action_set_sensitive (action, sensitive);
370 if (multiple_tasks_selected)
371 label = _("Delete Tasks");
372 else
373 label = _("Delete Task");
374 gtk_action_set_label (action, label);
375
376 action = ACTION (TASK_FIND);
377 sensitive = single_task_selected;
378 gtk_action_set_sensitive (action, sensitive);
379
380 action = ACTION (TASK_FORWARD);
381 sensitive = single_task_selected;
382 gtk_action_set_sensitive (action, sensitive);
383
384 action = ACTION (TASK_LIST_COPY);
385 sensitive = has_primary_source;
386 gtk_action_set_sensitive (action, sensitive);
387
388 action = ACTION (TASK_LIST_DELETE);
389 sensitive =
390 primary_source_is_removable ||
391 primary_source_is_remote_deletable;
392 gtk_action_set_sensitive (action, sensitive);
393
394 action = ACTION (TASK_LIST_PROPERTIES);
395 sensitive = primary_source_is_writable;
396 gtk_action_set_sensitive (action, sensitive);
397
398 action = ACTION (TASK_LIST_REFRESH);
399 sensitive = refresh_supported;
400 gtk_action_set_sensitive (action, sensitive);
401
402 action = ACTION (TASK_LIST_RENAME);
403 sensitive =
404 primary_source_is_writable &&
405 !primary_source_in_collection;
406 gtk_action_set_sensitive (action, sensitive);
407
408 action = ACTION (TASK_MARK_COMPLETE);
409 sensitive =
410 any_tasks_selected &&
411 sources_are_editable &&
412 some_tasks_incomplete;
413 gtk_action_set_sensitive (action, sensitive);
414
415 action = ACTION (TASK_MARK_INCOMPLETE);
416 sensitive =
417 any_tasks_selected &&
418 sources_are_editable &&
419 some_tasks_complete;
420 gtk_action_set_sensitive (action, sensitive);
421
422 action = ACTION (TASK_OPEN);
423 sensitive = single_task_selected;
424 gtk_action_set_sensitive (action, sensitive);
425
426 action = ACTION (TASK_OPEN_URL);
427 sensitive = single_task_selected && selection_has_url;
428 gtk_action_set_sensitive (action, sensitive);
429
430 action = ACTION (TASK_PRINT);
431 sensitive = single_task_selected;
432 gtk_action_set_sensitive (action, sensitive);
433
434 action = ACTION (TASK_PURGE);
435 sensitive = sources_are_editable;
436 gtk_action_set_sensitive (action, sensitive);
437
438 action = ACTION (TASK_SAVE_AS);
439 sensitive = single_task_selected;
440 gtk_action_set_sensitive (action, sensitive);
441 }
442
443 static void
444 task_shell_view_class_init (ETaskShellViewClass *class,
445 GTypeModule *type_module)
446 {
447 GObjectClass *object_class;
448 EShellViewClass *shell_view_class;
449
450 parent_class = g_type_class_peek_parent (class);
451 g_type_class_add_private (class, sizeof (ETaskShellViewPrivate));
452
453 object_class = G_OBJECT_CLASS (class);
454 object_class->set_property = task_shell_view_set_property;
455 object_class->get_property = task_shell_view_get_property;
456 object_class->dispose = task_shell_view_dispose;
457 object_class->finalize = task_shell_view_finalize;
458 object_class->constructed = task_shell_view_constructed;
459
460 shell_view_class = E_SHELL_VIEW_CLASS (class);
461 shell_view_class->label = _("Tasks");
462 shell_view_class->icon_name = "evolution-tasks";
463 shell_view_class->ui_definition = "evolution-tasks.ui";
464 shell_view_class->ui_manager_id = "org.gnome.evolution.tasks";
465 shell_view_class->search_options = "/task-search-options";
466 shell_view_class->search_rules = "tasktypes.xml";
467 shell_view_class->new_shell_content = e_task_shell_content_new;
468 shell_view_class->new_shell_sidebar = e_task_shell_sidebar_new;
469 shell_view_class->execute_search = task_shell_view_execute_search;
470 shell_view_class->update_actions = task_shell_view_update_actions;
471
472 g_object_class_install_property (
473 object_class,
474 PROP_CONFIRM_PURGE,
475 g_param_spec_boolean (
476 "confirm-purge",
477 "Confirm Purge",
478 NULL,
479 TRUE,
480 G_PARAM_READWRITE));
481 }
482
483 static void
484 task_shell_view_init (ETaskShellView *task_shell_view,
485 EShellViewClass *shell_view_class)
486 {
487 task_shell_view->priv =
488 E_TASK_SHELL_VIEW_GET_PRIVATE (task_shell_view);
489
490 e_task_shell_view_private_init (task_shell_view, shell_view_class);
491 }
492
493 GType
494 e_task_shell_view_get_type (void)
495 {
496 return task_shell_view_type;
497 }
498
499 void
500 e_task_shell_view_register_type (GTypeModule *type_module)
501 {
502 const GTypeInfo type_info = {
503 sizeof (ETaskShellViewClass),
504 (GBaseInitFunc) NULL,
505 (GBaseFinalizeFunc) NULL,
506 (GClassInitFunc) task_shell_view_class_init,
507 (GClassFinalizeFunc) NULL,
508 type_module,
509 sizeof (ETaskShellView),
510 0, /* n_preallocs */
511 (GInstanceInitFunc) task_shell_view_init,
512 NULL /* value_table */
513 };
514
515 task_shell_view_type = g_type_module_register_type (
516 type_module, E_TYPE_SHELL_VIEW,
517 "ETaskShellView", &type_info, 0);
518 }
519
520 gboolean
521 e_task_shell_view_get_confirm_purge (ETaskShellView *task_shell_view)
522 {
523 g_return_val_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view), FALSE);
524
525 return task_shell_view->priv->confirm_purge;
526 }
527
528 void
529 e_task_shell_view_set_confirm_purge (ETaskShellView *task_shell_view,
530 gboolean confirm_purge)
531 {
532 g_return_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view));
533
534 if (task_shell_view->priv->confirm_purge == confirm_purge)
535 return;
536
537 task_shell_view->priv->confirm_purge = confirm_purge;
538
539 g_object_notify (G_OBJECT (task_shell_view), "confirm-purge");
540 }