2 * Copyright (C) 2015 Red Hat, Inc. (www.redhat.com)
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by
6 * the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "evolution-config.h"
20 #include <glib/gi18n-lib.h>
23 #include <e-util/e-util.h>
25 #include "calendar-config.h"
26 #include "comp-util.h"
27 #include "e-comp-editor.h"
28 #include "e-comp-editor-page.h"
29 #include "e-comp-editor-page-attachments.h"
30 #include "e-comp-editor-page-general.h"
31 #include "e-comp-editor-page-recurrence.h"
32 #include "e-comp-editor-page-reminders.h"
33 #include "e-comp-editor-property-part.h"
34 #include "e-comp-editor-property-parts.h"
36 #include "e-comp-editor-task.h"
38 struct _ECompEditorTaskPrivate
{
39 ECompEditorPage
*page_general
;
40 ECompEditorPage
*recurrence_page
;
41 ECompEditorPage
*reminders_page
;
42 ECompEditorPropertyPart
*categories
;
43 ECompEditorPropertyPart
*dtstart
;
44 ECompEditorPropertyPart
*due_date
;
45 ECompEditorPropertyPart
*completed_date
;
46 ECompEditorPropertyPart
*percentcomplete
;
47 ECompEditorPropertyPart
*status
;
48 ECompEditorPropertyPart
*timezone
;
50 gpointer in_the_past_alert
;
51 gpointer insensitive_info_alert
;
54 G_DEFINE_TYPE (ECompEditorTask
, e_comp_editor_task
, E_TYPE_COMP_EDITOR
)
57 ece_task_get_timezone_from_property (ECompEditor
*comp_editor
,
58 icalproperty
*property
)
62 icaltimezone
*zone
= NULL
;
65 g_return_val_if_fail (E_IS_COMP_EDITOR (comp_editor
), NULL
);
70 param
= icalproperty_get_first_parameter (property
, ICAL_TZID_PARAMETER
);
74 tzid
= icalparameter_get_tzid (param
);
78 if (g_ascii_strcasecmp (tzid
, "UTC") == 0)
79 return icaltimezone_get_utc_timezone ();
81 client
= e_comp_editor_get_source_client (comp_editor
);
82 /* It should be already fetched for the UI, thus this should be non-blocking. */
83 if (client
&& e_cal_client_get_timezone_sync (client
, tzid
, &zone
, NULL
, NULL
) && zone
)
86 zone
= icaltimezone_get_builtin_timezone_from_tzid (tzid
);
88 zone
= icaltimezone_get_builtin_timezone (tzid
);
94 ece_task_update_timezone (ECompEditorTask
*task_editor
,
95 gboolean
*force_allday
)
97 const gint properties
[] = {
98 ICAL_DTSTART_PROPERTY
,
100 ICAL_COMPLETED_PROPERTY
102 ECompEditor
*comp_editor
;
103 icalcomponent
*component
;
104 icaltimezone
*zone
= NULL
;
107 g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor
));
110 *force_allday
= FALSE
;
112 comp_editor
= E_COMP_EDITOR (task_editor
);
114 component
= e_comp_editor_get_component (comp_editor
);
118 for (ii
= 0; !zone
&& ii
< G_N_ELEMENTS (properties
); ii
++) {
119 struct icaltimetype dt
;
120 if (icalcomponent_get_first_property (component
, properties
[ii
])) {
121 dt
= icalcomponent_get_dtstart (component
);
122 if (icaltime_is_valid_time (dt
)) {
123 if (force_allday
&& dt
.is_date
)
124 *force_allday
= TRUE
;
126 if (icaltime_is_utc (dt
))
127 zone
= icaltimezone_get_utc_timezone ();
129 zone
= ece_task_get_timezone_from_property (comp_editor
,
130 icalcomponent_get_first_property (component
, properties
[ii
]));
136 GtkWidget
*edit_widget
;
138 edit_widget
= e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->timezone
);
140 e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (edit_widget
), zone
);
142 if (zone
!= calendar_config_get_icaltimezone ()) {
143 /* Show timezone part */
146 action
= e_comp_editor_get_action (comp_editor
, "view-timezone");
147 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
), TRUE
);
153 ece_task_notify_source_client_cb (GObject
*object
,
157 g_return_if_fail (E_IS_COMP_EDITOR_TASK (object
));
159 ece_task_update_timezone (E_COMP_EDITOR_TASK (object
), NULL
);
163 ece_task_notify_target_client_cb (GObject
*object
,
167 ECompEditorTask
*task_editor
;
168 ECompEditor
*comp_editor
;
169 ECalClient
*cal_client
;
170 GtkWidget
*edit_widget
;
175 gboolean can_reminders
;
177 g_return_if_fail (E_IS_COMP_EDITOR_TASK (object
));
179 task_editor
= E_COMP_EDITOR_TASK (object
);
180 comp_editor
= E_COMP_EDITOR (task_editor
);
181 cal_client
= e_comp_editor_get_target_client (comp_editor
);
183 action
= e_comp_editor_get_action (comp_editor
, "all-day-task");
184 was_allday
= gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action
));
186 date_only
= !cal_client
|| e_client_check_capability (E_CLIENT (cal_client
), CAL_STATIC_CAPABILITY_TASK_DATE_ONLY
);
188 e_comp_editor_property_part_datetime_set_date_only (E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->dtstart
), date_only
);
189 e_comp_editor_property_part_datetime_set_date_only (E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->due_date
), date_only
);
190 e_comp_editor_property_part_datetime_set_date_only (E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->completed_date
), date_only
);
192 edit_widget
= e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->timezone
);
193 gtk_widget_set_sensitive (edit_widget
, !date_only
);
195 action
= e_comp_editor_get_action (comp_editor
, "view-timezone");
196 gtk_action_set_sensitive (action
, !date_only
);
198 action
= e_comp_editor_get_action (comp_editor
, "all-day-task");
199 gtk_action_set_visible (action
, !date_only
);
202 action
= e_comp_editor_get_action (comp_editor
, "all-day-task");
203 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
), TRUE
);
206 can_reminders
= !cal_client
|| !e_client_check_capability (E_CLIENT (cal_client
), CAL_STATIC_CAPABILITY_TASK_NO_ALARM
);
207 gtk_widget_set_visible (GTK_WIDGET (task_editor
->priv
->reminders_page
), can_reminders
);
209 can_recur
= !cal_client
|| e_client_check_capability (E_CLIENT (cal_client
), CAL_STATIC_CAPABILITY_TASK_CAN_RECUR
);
210 gtk_widget_set_visible (GTK_WIDGET (task_editor
->priv
->recurrence_page
), can_recur
);
214 ece_task_check_dates_in_the_past (ECompEditorTask
*task_editor
)
218 g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor
));
220 flags
= e_comp_editor_get_flags (E_COMP_EDITOR (task_editor
));
222 if (task_editor
->priv
->in_the_past_alert
)
223 e_alert_response (task_editor
->priv
->in_the_past_alert
, GTK_RESPONSE_OK
);
225 if ((flags
& E_COMP_EDITOR_FLAG_IS_NEW
) != 0) {
226 GString
*message
= NULL
;
227 struct icaltimetype dtstart_itt
, due_date_itt
;
229 dtstart_itt
= e_comp_editor_property_part_datetime_get_value (
230 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->dtstart
));
231 due_date_itt
= e_comp_editor_property_part_datetime_get_value (
232 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->due_date
));
234 if (cal_comp_util_compare_time_with_today (dtstart_itt
) < 0)
235 message
= g_string_new (_("Task’s start date is in the past"));
237 if (cal_comp_util_compare_time_with_today (due_date_itt
) < 0) {
239 g_string_append (message
, "\n");
241 message
= g_string_new ("");
243 g_string_append (message
, _("Task’s due date is in the past"));
249 alert
= e_comp_editor_add_warning (E_COMP_EDITOR (task_editor
), message
->str
, NULL
);
251 task_editor
->priv
->in_the_past_alert
= alert
;
254 g_object_add_weak_pointer (G_OBJECT (alert
), &task_editor
->priv
->in_the_past_alert
);
256 g_string_free (message
, TRUE
);
257 g_clear_object (&alert
);
263 ece_task_dtstart_changed_cb (EDateEdit
*date_edit
,
264 ECompEditorTask
*task_editor
)
266 ECompEditor
*comp_editor
;
268 g_return_if_fail (E_IS_DATE_EDIT (date_edit
));
269 g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor
));
271 comp_editor
= E_COMP_EDITOR (task_editor
);
273 if (e_comp_editor_get_updating (comp_editor
))
276 e_comp_editor_set_updating (comp_editor
, TRUE
);
278 e_comp_editor_ensure_start_before_end (E_COMP_EDITOR (task_editor
),
279 task_editor
->priv
->dtstart
, task_editor
->priv
->due_date
,
282 e_comp_editor_set_updating (comp_editor
, FALSE
);
284 ece_task_check_dates_in_the_past (task_editor
);
288 ece_task_due_date_changed_cb (EDateEdit
*date_edit
,
289 ECompEditorTask
*task_editor
)
291 ECompEditor
*comp_editor
;
293 g_return_if_fail (E_IS_DATE_EDIT (date_edit
));
294 g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor
));
296 comp_editor
= E_COMP_EDITOR (task_editor
);
298 if (e_comp_editor_get_updating (comp_editor
))
301 e_comp_editor_set_updating (comp_editor
, TRUE
);
303 e_comp_editor_ensure_start_before_end (E_COMP_EDITOR (task_editor
),
304 task_editor
->priv
->dtstart
, task_editor
->priv
->due_date
,
307 e_comp_editor_set_updating (comp_editor
, FALSE
);
309 ece_task_check_dates_in_the_past (task_editor
);
313 ece_task_completed_date_changed_cb (EDateEdit
*date_edit
,
314 ECompEditorTask
*task_editor
)
316 GtkSpinButton
*percent_spin
;
317 ECompEditor
*comp_editor
;
318 struct icaltimetype itt
;
321 g_return_if_fail (E_IS_DATE_EDIT (date_edit
));
322 g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor
));
324 comp_editor
= E_COMP_EDITOR (task_editor
);
326 if (e_comp_editor_get_updating (comp_editor
))
329 e_comp_editor_set_updating (comp_editor
, TRUE
);
331 status
= e_comp_editor_property_part_picker_with_map_get_selected (
332 E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (task_editor
->priv
->status
));
333 itt
= e_comp_editor_property_part_datetime_get_value (
334 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->completed_date
));
335 percent_spin
= GTK_SPIN_BUTTON (e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->percentcomplete
));
337 if (icaltime_is_null_time (itt
)) {
338 if (status
== ICAL_STATUS_COMPLETED
) {
339 e_comp_editor_property_part_picker_with_map_set_selected (
340 E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (task_editor
->priv
->status
),
343 gtk_spin_button_set_value (percent_spin
, 0);
346 if (status
!= ICAL_STATUS_COMPLETED
) {
347 e_comp_editor_property_part_picker_with_map_set_selected (
348 E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (task_editor
->priv
->status
),
349 ICAL_STATUS_COMPLETED
);
352 gtk_spin_button_set_value (percent_spin
, 100);
355 e_comp_editor_set_updating (comp_editor
, FALSE
);
359 ece_task_status_changed_cb (GtkComboBox
*combo_box
,
360 ECompEditorTask
*task_editor
)
362 ECompEditor
*comp_editor
;
363 GtkSpinButton
*percent_spin
;
364 EDateEdit
*completed_date
;
367 g_return_if_fail (GTK_IS_COMBO_BOX (combo_box
));
368 g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor
));
370 comp_editor
= E_COMP_EDITOR (task_editor
);
372 if (e_comp_editor_get_updating (comp_editor
))
375 e_comp_editor_set_updating (comp_editor
, TRUE
);
377 percent_spin
= GTK_SPIN_BUTTON (e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->percentcomplete
));
378 completed_date
= E_DATE_EDIT (e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->completed_date
));
379 status
= e_comp_editor_property_part_picker_with_map_get_selected (
380 E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (task_editor
->priv
->status
));
382 if (status
== ICAL_STATUS_NONE
) {
383 gtk_spin_button_set_value (percent_spin
, 0);
384 e_date_edit_set_time (completed_date
, (time_t) -1);
385 } else if (status
== ICAL_STATUS_INPROCESS
) {
386 gint percent_complete
= gtk_spin_button_get_value_as_int (percent_spin
);
388 if (percent_complete
<= 0 || percent_complete
>= 100)
389 gtk_spin_button_set_value (percent_spin
, 50);
391 e_date_edit_set_time (completed_date
, (time_t) -1);
392 } else if (status
== ICAL_STATUS_COMPLETED
) {
393 gtk_spin_button_set_value (percent_spin
, 100);
394 e_date_edit_set_time (completed_date
, time (NULL
));
397 e_comp_editor_set_updating (comp_editor
, FALSE
);
401 ece_task_percentcomplete_value_changed_cb (GtkSpinButton
*spin_button
,
402 ECompEditorTask
*task_editor
)
404 ECompEditor
*comp_editor
;
405 GtkSpinButton
*percent_spin
;
406 EDateEdit
*completed_date
;
407 gint status
, percent
;
410 g_return_if_fail (GTK_IS_SPIN_BUTTON (spin_button
));
411 g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor
));
413 comp_editor
= E_COMP_EDITOR (task_editor
);
415 if (e_comp_editor_get_updating (comp_editor
))
418 e_comp_editor_set_updating (comp_editor
, TRUE
);
420 percent_spin
= GTK_SPIN_BUTTON (e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->percentcomplete
));
421 completed_date
= E_DATE_EDIT (e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->completed_date
));
423 percent
= gtk_spin_button_get_value_as_int (percent_spin
);
424 if (percent
== 100) {
426 status
= ICAL_STATUS_COMPLETED
;
431 status
= ICAL_STATUS_NONE
;
433 status
= ICAL_STATUS_INPROCESS
;
436 e_comp_editor_property_part_picker_with_map_set_selected (
437 E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (task_editor
->priv
->status
), status
);
438 e_date_edit_set_time (completed_date
, ctime
);
440 e_comp_editor_set_updating (comp_editor
, FALSE
);
444 ece_task_sensitize_widgets (ECompEditor
*comp_editor
,
445 gboolean force_insensitive
)
447 ECompEditorTask
*task_editor
;
449 gboolean is_organizer
;
452 g_return_if_fail (E_IS_COMP_EDITOR_TASK (comp_editor
));
454 E_COMP_EDITOR_CLASS (e_comp_editor_task_parent_class
)->sensitize_widgets (comp_editor
, force_insensitive
);
456 flags
= e_comp_editor_get_flags (comp_editor
);
457 is_organizer
= (flags
& (E_COMP_EDITOR_FLAG_IS_NEW
| E_COMP_EDITOR_FLAG_ORGANIZER_IS_USER
)) != 0;
458 task_editor
= E_COMP_EDITOR_TASK (comp_editor
);
460 action
= e_comp_editor_get_action (comp_editor
, "all-day-task");
461 gtk_action_set_sensitive (action
, !force_insensitive
&& is_organizer
);
463 if (task_editor
->priv
->insensitive_info_alert
)
464 e_alert_response (task_editor
->priv
->insensitive_info_alert
, GTK_RESPONSE_OK
);
466 if (force_insensitive
|| !is_organizer
) {
468 const gchar
*message
= NULL
;
470 client
= e_comp_editor_get_target_client (comp_editor
);
472 message
= _("Task cannot be edited, because the selected task list could not be opened");
473 else if (e_client_is_readonly (E_CLIENT (client
)))
474 message
= _("Task cannot be edited, because the selected task list is read only");
475 else if (!is_organizer
)
476 message
= _("Task cannot be fully edited, because you are not the organizer");
481 alert
= e_comp_editor_add_information (comp_editor
, message
, NULL
);
483 task_editor
->priv
->insensitive_info_alert
= alert
;
486 g_object_add_weak_pointer (G_OBJECT (alert
), &task_editor
->priv
->insensitive_info_alert
);
488 g_clear_object (&alert
);
492 ece_task_check_dates_in_the_past (task_editor
);
496 ece_task_fill_widgets (ECompEditor
*comp_editor
,
497 icalcomponent
*component
)
499 gboolean force_allday
= FALSE
;
501 g_return_if_fail (E_IS_COMP_EDITOR_TASK (comp_editor
));
502 g_return_if_fail (component
!= NULL
);
504 E_COMP_EDITOR_CLASS (e_comp_editor_task_parent_class
)->fill_widgets (comp_editor
, component
);
506 ece_task_update_timezone (E_COMP_EDITOR_TASK (comp_editor
), &force_allday
);
511 action
= e_comp_editor_get_action (comp_editor
, "all-day-task");
512 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
), TRUE
);
517 ece_task_fill_component (ECompEditor
*comp_editor
,
518 icalcomponent
*component
)
520 ECompEditorTask
*task_editor
;
521 struct icaltimetype itt
;
523 g_return_val_if_fail (E_IS_COMP_EDITOR_TASK (comp_editor
), FALSE
);
525 task_editor
= E_COMP_EDITOR_TASK (comp_editor
);
527 if (!e_comp_editor_property_part_datetime_check_validity (
528 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->dtstart
), NULL
, NULL
)) {
530 e_comp_editor_set_validation_error (comp_editor
,
531 task_editor
->priv
->page_general
,
532 e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->dtstart
),
533 _("Start date is not a valid date"));
538 if (e_cal_util_component_has_recurrences (component
)) {
539 struct icaltimetype dtstart
;
541 dtstart
= e_comp_editor_property_part_datetime_get_value (E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->dtstart
));
543 if (icaltime_is_null_time (dtstart
) || !icaltime_is_valid_time (dtstart
)) {
544 e_comp_editor_set_validation_error (comp_editor
,
545 task_editor
->priv
->page_general
,
546 e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->dtstart
),
547 _("Start date is required for recurring tasks"));
553 if (!e_comp_editor_property_part_datetime_check_validity (
554 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->due_date
), NULL
, NULL
)) {
556 e_comp_editor_set_validation_error (comp_editor
,
557 task_editor
->priv
->page_general
,
558 e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->due_date
),
559 _("Due date is not a valid date"));
564 if (!e_comp_editor_property_part_datetime_check_validity (
565 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->completed_date
), NULL
, NULL
)) {
567 e_comp_editor_set_validation_error (comp_editor
,
568 task_editor
->priv
->page_general
,
569 e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->completed_date
),
570 _("Completed date is not a valid date"));
575 itt
= e_comp_editor_property_part_datetime_get_value (
576 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->completed_date
));
577 if (cal_comp_util_compare_time_with_today (itt
) > 0) {
578 e_comp_editor_set_validation_error (comp_editor
,
579 task_editor
->priv
->page_general
,
580 e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->completed_date
),
581 _("Completed date cannot be in the future"));
586 if (!E_COMP_EDITOR_CLASS (e_comp_editor_task_parent_class
)->fill_component (comp_editor
, component
))
589 if (e_cal_util_component_has_recurrences (component
)) {
590 ECalClient
*cal_client
;
592 cal_client
= e_comp_editor_get_source_client (comp_editor
);
594 cal_client
= e_comp_editor_get_target_client (comp_editor
);
597 if ((e_comp_editor_get_flags (comp_editor
) & E_COMP_EDITOR_FLAG_IS_NEW
) != 0) {
598 e_cal_util_init_recur_task_sync (component
, cal_client
, NULL
, NULL
);
599 } else if (icalcomponent_get_first_property (component
, ICAL_COMPLETED_PROPERTY
)) {
600 e_cal_util_mark_task_complete_sync (component
, (time_t) -1, cal_client
, NULL
, NULL
);
601 } else if (!icalcomponent_get_first_property (component
, ICAL_DUE_PROPERTY
)) {
602 e_cal_util_init_recur_task_sync (component
, cal_client
, NULL
, NULL
);
611 ece_task_setup_ui (ECompEditorTask
*task_editor
)
615 " <menubar action='main-menu'>"
616 " <menu action='view-menu'>"
617 " <placeholder name='parts'>"
618 " <menuitem action='view-timezone'/>"
619 " <menuitem action='view-categories'/>"
622 " <menu action='options-menu'>"
623 " <placeholder name='toggles'>"
624 " <menuitem action='all-day-task'/>"
628 " <toolbar name='main-toolbar'>"
629 " <placeholder name='content'>\n"
630 " <toolitem action='all-day-task'/>\n"
635 const GtkToggleActionEntry view_actions
[] = {
640 N_("Toggles whether to display categories"),
648 N_("Toggles whether the time zone is displayed"),
653 "stock_new-24h-appointment",
656 N_("Toggles whether to have All Day Task"),
661 ECompEditor
*comp_editor
;
663 GtkUIManager
*ui_manager
;
665 GtkActionGroup
*action_group
;
666 GtkWidget
*edit_widget
;
667 GError
*error
= NULL
;
669 g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor
));
671 comp_editor
= E_COMP_EDITOR (task_editor
);
672 settings
= e_comp_editor_get_settings (comp_editor
);
673 ui_manager
= e_comp_editor_get_ui_manager (comp_editor
);
674 action_group
= e_comp_editor_get_action_group (comp_editor
, "individual");
676 gtk_action_group_add_toggle_actions (action_group
,
677 view_actions
, G_N_ELEMENTS (view_actions
), task_editor
);
679 gtk_ui_manager_add_ui_from_string (ui_manager
, ui
, -1, &error
);
681 e_plugin_ui_register_manager (ui_manager
, "org.gnome.evolution.task-editor", task_editor
);
682 e_plugin_ui_enable_manager (ui_manager
, "org.gnome.evolution.task-editor");
685 g_critical ("%s: %s", G_STRFUNC
, error
->message
);
686 g_error_free (error
);
689 action
= e_comp_editor_get_action (comp_editor
, "view-timezone");
690 e_binding_bind_property (
691 task_editor
->priv
->timezone
, "visible",
693 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
695 settings
, "editor-show-timezone",
697 G_SETTINGS_BIND_DEFAULT
);
699 action
= e_comp_editor_get_action (comp_editor
, "view-categories");
700 e_binding_bind_property (
701 task_editor
->priv
->categories
, "visible",
703 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
705 settings
, "editor-show-categories",
707 G_SETTINGS_BIND_DEFAULT
);
709 action
= e_comp_editor_get_action (comp_editor
, "all-day-task");
711 edit_widget
= e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->dtstart
);
712 e_binding_bind_property (
714 edit_widget
, "show-time",
715 G_BINDING_INVERT_BOOLEAN
| G_BINDING_BIDIRECTIONAL
);
717 edit_widget
= e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->due_date
);
718 e_binding_bind_property (
720 edit_widget
, "show-time",
721 G_BINDING_INVERT_BOOLEAN
);
723 edit_widget
= e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->completed_date
);
724 e_binding_bind_property (
726 edit_widget
, "show-time",
727 G_BINDING_INVERT_BOOLEAN
);
731 e_comp_editor_task_constructed (GObject
*object
)
733 ECompEditorTask
*task_editor
;
734 ECompEditor
*comp_editor
;
735 ECompEditorPage
*page
;
736 ECompEditorPropertyPart
*part
, *summary
;
737 EFocusTracker
*focus_tracker
;
738 GtkWidget
*edit_widget
;
740 G_OBJECT_CLASS (e_comp_editor_task_parent_class
)->constructed (object
);
742 task_editor
= E_COMP_EDITOR_TASK (object
);
743 comp_editor
= E_COMP_EDITOR (task_editor
);
744 focus_tracker
= e_comp_editor_get_focus_tracker (comp_editor
);
746 page
= e_comp_editor_page_general_new (comp_editor
,
747 _("_List:"), E_SOURCE_EXTENSION_TASK_LIST
,
750 part
= e_comp_editor_property_part_summary_new (focus_tracker
);
751 e_comp_editor_page_add_property_part (page
, part
, 0, 2, 4, 1);
754 part
= e_comp_editor_property_part_dtstart_new (C_("ECompEditor", "Sta_rt date:"), TRUE
, TRUE
);
755 e_comp_editor_page_add_property_part (page
, part
, 0, 3, 2, 1);
756 task_editor
->priv
->dtstart
= part
;
758 edit_widget
= e_comp_editor_property_part_get_edit_widget (part
);
759 g_signal_connect (edit_widget
, "changed", G_CALLBACK (ece_task_dtstart_changed_cb
), task_editor
);
761 part
= e_comp_editor_property_part_status_new ();
762 e_comp_editor_page_add_property_part (page
, part
, 2, 3, 2, 1);
763 task_editor
->priv
->status
= part
;
765 edit_widget
= e_comp_editor_property_part_get_edit_widget (part
);
766 g_signal_connect (edit_widget
, "changed", G_CALLBACK (ece_task_status_changed_cb
), task_editor
);
768 part
= e_comp_editor_property_part_due_new (TRUE
, TRUE
);
769 e_comp_editor_page_add_property_part (page
, part
, 0, 4, 2, 1);
770 task_editor
->priv
->due_date
= part
;
772 edit_widget
= e_comp_editor_property_part_get_edit_widget (part
);
773 g_signal_connect (edit_widget
, "changed", G_CALLBACK (ece_task_due_date_changed_cb
), task_editor
);
775 part
= e_comp_editor_property_part_priority_new ();
776 e_comp_editor_page_add_property_part (page
, part
, 2, 4, 2, 1);
778 part
= e_comp_editor_property_part_completed_new (TRUE
, TRUE
);
779 e_comp_editor_page_add_property_part (page
, part
, 0, 5, 2, 1);
780 task_editor
->priv
->completed_date
= part
;
782 edit_widget
= e_comp_editor_property_part_get_edit_widget (part
);
783 g_signal_connect (edit_widget
, "changed", G_CALLBACK (ece_task_completed_date_changed_cb
), task_editor
);
785 part
= e_comp_editor_property_part_percentcomplete_new ();
786 e_comp_editor_page_add_property_part (page
, part
, 2, 5, 2, 1);
787 task_editor
->priv
->percentcomplete
= part
;
789 edit_widget
= e_comp_editor_property_part_get_edit_widget (part
);
790 g_signal_connect (edit_widget
, "value-changed", G_CALLBACK (ece_task_percentcomplete_value_changed_cb
), task_editor
);
792 part
= e_comp_editor_property_part_url_new (focus_tracker
);
793 e_comp_editor_page_add_property_part (page
, part
, 0, 6, 2, 1);
795 edit_widget
= e_comp_editor_property_part_get_edit_widget (part
);
796 gtk_widget_set_hexpand (edit_widget
, TRUE
);
798 part
= e_comp_editor_property_part_classification_new ();
799 e_comp_editor_page_add_property_part (page
, part
, 2, 6, 2, 1);
801 part
= e_comp_editor_property_part_timezone_new ();
802 e_comp_editor_page_add_property_part (page
, part
, 0, 7, 4, 1);
803 task_editor
->priv
->timezone
= part
;
805 part
= e_comp_editor_property_part_categories_new (focus_tracker
);
806 e_comp_editor_page_add_property_part (page
, part
, 0, 8, 4, 1);
807 task_editor
->priv
->categories
= part
;
809 part
= e_comp_editor_property_part_description_new (focus_tracker
);
810 e_comp_editor_page_add_property_part (page
, part
, 0, 9, 4, 1);
812 e_comp_editor_add_page (comp_editor
, C_("ECompEditorPage", "General"), page
);
813 task_editor
->priv
->page_general
= page
;
815 edit_widget
= e_comp_editor_property_part_get_edit_widget (task_editor
->priv
->timezone
);
816 e_comp_editor_property_part_datetime_attach_timezone_entry (
817 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->dtstart
),
818 E_TIMEZONE_ENTRY (edit_widget
));
819 e_comp_editor_property_part_datetime_attach_timezone_entry (
820 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->due_date
),
821 E_TIMEZONE_ENTRY (edit_widget
));
822 e_comp_editor_property_part_datetime_attach_timezone_entry (
823 E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor
->priv
->completed_date
),
824 E_TIMEZONE_ENTRY (edit_widget
));
826 e_comp_editor_set_time_parts (comp_editor
, task_editor
->priv
->dtstart
, task_editor
->priv
->due_date
);
828 page
= e_comp_editor_page_reminders_new (comp_editor
);
829 e_comp_editor_add_page (comp_editor
, C_("ECompEditorPage", "Reminders"), page
);
830 task_editor
->priv
->reminders_page
= page
;
832 page
= e_comp_editor_page_recurrence_new (comp_editor
);
833 e_comp_editor_add_page (comp_editor
, C_("ECompEditorPage", "Recurrence"), page
);
834 task_editor
->priv
->recurrence_page
= page
;
836 page
= e_comp_editor_page_attachments_new (comp_editor
);
837 e_comp_editor_add_page (comp_editor
, C_("ECompEditorPage", "Attachments"), page
);
839 ece_task_setup_ui (task_editor
);
841 edit_widget
= e_comp_editor_property_part_get_edit_widget (summary
);
842 e_binding_bind_property (edit_widget
, "text", comp_editor
, "title-suffix", 0);
843 gtk_widget_grab_focus (edit_widget
);
845 g_signal_connect (comp_editor
, "notify::source-client",
846 G_CALLBACK (ece_task_notify_source_client_cb
), NULL
);
847 g_signal_connect (comp_editor
, "notify::target-client",
848 G_CALLBACK (ece_task_notify_target_client_cb
), NULL
);
852 e_comp_editor_task_init (ECompEditorTask
*task_editor
)
854 task_editor
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (task_editor
, E_TYPE_COMP_EDITOR_TASK
, ECompEditorTaskPrivate
);
858 e_comp_editor_task_class_init (ECompEditorTaskClass
*klass
)
860 GObjectClass
*object_class
;
861 ECompEditorClass
*comp_editor_class
;
863 g_type_class_add_private (klass
, sizeof (ECompEditorTaskPrivate
));
865 object_class
= G_OBJECT_CLASS (klass
);
866 object_class
->constructed
= e_comp_editor_task_constructed
;
868 comp_editor_class
= E_COMP_EDITOR_CLASS (klass
);
869 comp_editor_class
->help_section
= "tasks-usage";
870 comp_editor_class
->title_format_with_attendees
= _("Assigned Task — %s");
871 comp_editor_class
->title_format_without_attendees
= _("Task — %s");
872 comp_editor_class
->icon_name
= "stock_task";
873 comp_editor_class
->sensitize_widgets
= ece_task_sensitize_widgets
;
874 comp_editor_class
->fill_widgets
= ece_task_fill_widgets
;
875 comp_editor_class
->fill_component
= ece_task_fill_component
;