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-object.h>
23 #include <e-util/e-util.h>
25 #include "comp-util.h"
26 #include "e-comp-editor-property-part.h"
28 struct _ECompEditorPropertyPartPrivate
{
29 GtkWidget
*label_widget
;
30 GtkWidget
*edit_widget
;
32 gboolean sensitize_handled
;
37 PROPERTY_PART_PROP_SENSITIZE_HANDLED
,
38 PROPERTY_PART_PROP_VISIBLE
42 PROPERTY_PART_CHANGED
,
43 PROPERTY_PART_LAST_SIGNAL
46 static guint property_part_signals
[PROPERTY_PART_LAST_SIGNAL
];
48 G_DEFINE_ABSTRACT_TYPE (ECompEditorPropertyPart
, e_comp_editor_property_part
, G_TYPE_OBJECT
)
51 e_comp_editor_property_part_set_property (GObject
*object
,
56 switch (property_id
) {
57 case PROPERTY_PART_PROP_SENSITIZE_HANDLED
:
58 e_comp_editor_property_part_set_sensitize_handled (
59 E_COMP_EDITOR_PROPERTY_PART (object
),
60 g_value_get_boolean (value
));
63 case PROPERTY_PART_PROP_VISIBLE
:
64 e_comp_editor_property_part_set_visible (
65 E_COMP_EDITOR_PROPERTY_PART (object
),
66 g_value_get_boolean (value
));
70 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
74 e_comp_editor_property_part_get_property (GObject
*object
,
79 switch (property_id
) {
80 case PROPERTY_PART_PROP_SENSITIZE_HANDLED
:
83 e_comp_editor_property_part_get_sensitize_handled (
84 E_COMP_EDITOR_PROPERTY_PART (object
)));
87 case PROPERTY_PART_PROP_VISIBLE
:
90 e_comp_editor_property_part_get_visible (
91 E_COMP_EDITOR_PROPERTY_PART (object
)));
95 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
99 e_comp_editor_property_part_constructed (GObject
*object
)
101 ECompEditorPropertyPart
*property_part
;
102 GtkWidget
*label_widget
= NULL
, *edit_widget
= NULL
;
104 G_OBJECT_CLASS (e_comp_editor_property_part_parent_class
)->constructed (object
);
106 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (object
));
108 property_part
= E_COMP_EDITOR_PROPERTY_PART (object
);
110 e_comp_editor_property_part_create_widgets (property_part
, &label_widget
, &edit_widget
);
113 property_part
->priv
->label_widget
= g_object_ref_sink (label_widget
);
115 e_binding_bind_property (
116 property_part
, "visible",
117 label_widget
, "visible",
118 G_BINDING_SYNC_CREATE
);
122 property_part
->priv
->edit_widget
= g_object_ref_sink (edit_widget
);
124 e_binding_bind_property (
125 property_part
, "visible",
126 edit_widget
, "visible",
127 G_BINDING_SYNC_CREATE
);
132 e_comp_editor_property_part_dispose (GObject
*object
)
134 ECompEditorPropertyPart
*property_part
;
136 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (object
));
138 property_part
= E_COMP_EDITOR_PROPERTY_PART (object
);
140 g_clear_object (&property_part
->priv
->label_widget
);
141 g_clear_object (&property_part
->priv
->edit_widget
);
143 G_OBJECT_CLASS (e_comp_editor_property_part_parent_class
)->dispose (object
);
147 e_comp_editor_property_part_init (ECompEditorPropertyPart
*property_part
)
149 property_part
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (property_part
,
150 E_TYPE_COMP_EDITOR_PROPERTY_PART
,
151 ECompEditorPropertyPartPrivate
);
152 property_part
->priv
->visible
= TRUE
;
153 property_part
->priv
->sensitize_handled
= FALSE
;
157 e_comp_editor_property_part_class_init (ECompEditorPropertyPartClass
*klass
)
159 GObjectClass
*object_class
;
161 g_type_class_add_private (klass
, sizeof (ECompEditorPropertyPartPrivate
));
163 object_class
= G_OBJECT_CLASS (klass
);
164 object_class
->set_property
= e_comp_editor_property_part_set_property
;
165 object_class
->get_property
= e_comp_editor_property_part_get_property
;
166 object_class
->constructed
= e_comp_editor_property_part_constructed
;
167 object_class
->dispose
= e_comp_editor_property_part_dispose
;
169 g_object_class_install_property (
171 PROPERTY_PART_PROP_VISIBLE
,
172 g_param_spec_boolean (
175 "Whether the part is visible",
178 G_PARAM_STATIC_STRINGS
));
180 g_object_class_install_property (
182 PROPERTY_PART_PROP_SENSITIZE_HANDLED
,
183 g_param_spec_boolean (
186 "Whether the part's sensitive property is handled by the owner of it",
189 G_PARAM_STATIC_STRINGS
));
191 property_part_signals
[PROPERTY_PART_CHANGED
] = g_signal_new (
193 G_TYPE_FROM_CLASS (klass
),
195 G_STRUCT_OFFSET (ECompEditorPropertyPartClass
, changed
),
202 e_comp_editor_property_part_get_visible (ECompEditorPropertyPart
*property_part
)
204 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
), FALSE
);
206 return property_part
->priv
->visible
;
210 e_comp_editor_property_part_set_visible (ECompEditorPropertyPart
*property_part
,
213 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
));
215 if ((property_part
->priv
->visible
? 1 : 0) == (visible
? 1 : 0))
218 property_part
->priv
->visible
= visible
;
220 g_object_notify (G_OBJECT (property_part
), "visible");
224 e_comp_editor_property_part_get_sensitize_handled (ECompEditorPropertyPart
*property_part
)
226 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
), FALSE
);
228 return property_part
->priv
->sensitize_handled
;
232 e_comp_editor_property_part_set_sensitize_handled (ECompEditorPropertyPart
*property_part
,
233 gboolean sensitize_handled
)
235 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
));
237 if ((property_part
->priv
->sensitize_handled
? 1 : 0) == (sensitize_handled
? 1 : 0))
240 property_part
->priv
->sensitize_handled
= sensitize_handled
;
242 g_object_notify (G_OBJECT (property_part
), "sensitize-handled");
246 e_comp_editor_property_part_create_widgets (ECompEditorPropertyPart
*property_part
,
247 GtkWidget
**out_label_widget
,
248 GtkWidget
**out_edit_widget
)
250 ECompEditorPropertyPartClass
*klass
;
252 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
));
254 g_return_if_fail (property_part
->priv
->label_widget
== NULL
);
255 g_return_if_fail (property_part
->priv
->edit_widget
== NULL
);
257 klass
= E_COMP_EDITOR_PROPERTY_PART_GET_CLASS (property_part
);
258 g_return_if_fail (klass
->create_widgets
!= NULL
);
260 klass
->create_widgets (property_part
, out_label_widget
, out_edit_widget
);
264 e_comp_editor_property_part_get_label_widget (ECompEditorPropertyPart
*property_part
)
266 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
), NULL
);
268 return property_part
->priv
->label_widget
;
272 e_comp_editor_property_part_get_edit_widget (ECompEditorPropertyPart
*property_part
)
274 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
), NULL
);
276 return property_part
->priv
->edit_widget
;
280 e_comp_editor_property_part_fill_widget (ECompEditorPropertyPart
*property_part
,
281 icalcomponent
*component
)
283 ECompEditorPropertyPartClass
*klass
;
285 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
));
287 klass
= E_COMP_EDITOR_PROPERTY_PART_GET_CLASS (property_part
);
288 g_return_if_fail (klass
->fill_widget
!= NULL
);
290 klass
->fill_widget (property_part
, component
);
294 e_comp_editor_property_part_fill_component (ECompEditorPropertyPart
*property_part
,
295 icalcomponent
*component
)
297 ECompEditorPropertyPartClass
*klass
;
299 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
));
301 klass
= E_COMP_EDITOR_PROPERTY_PART_GET_CLASS (property_part
);
302 g_return_if_fail (klass
->fill_component
!= NULL
);
304 klass
->fill_component (property_part
, component
);
308 e_comp_editor_property_part_emit_changed (ECompEditorPropertyPart
*property_part
)
310 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART (property_part
));
312 g_signal_emit (property_part
, property_part_signals
[PROPERTY_PART_CHANGED
], 0, NULL
);
315 /* ************************************************************************* */
317 struct _ECompEditorPropertyPartStringPrivate
{
318 gboolean is_multivalue
;
321 G_DEFINE_ABSTRACT_TYPE (ECompEditorPropertyPartString
, e_comp_editor_property_part_string
, E_TYPE_COMP_EDITOR_PROPERTY_PART
)
324 ecepp_string_create_widgets (ECompEditorPropertyPart
*property_part
,
325 GtkWidget
**out_label_widget
,
326 GtkWidget
**out_edit_widget
)
328 ECompEditorPropertyPartStringClass
*klass
;
330 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (property_part
));
331 g_return_if_fail (out_label_widget
!= NULL
);
332 g_return_if_fail (out_edit_widget
!= NULL
);
334 klass
= E_COMP_EDITOR_PROPERTY_PART_STRING_GET_CLASS (property_part
);
335 g_return_if_fail (klass
!= NULL
);
336 g_return_if_fail (g_type_is_a (klass
->entry_type
, GTK_TYPE_ENTRY
) ||
337 g_type_is_a (klass
->entry_type
, GTK_TYPE_TEXT_VIEW
));
339 /* The descendant sets the 'out_label_widget' parameter */
340 *out_edit_widget
= g_object_new (klass
->entry_type
, NULL
);
341 g_return_if_fail (*out_edit_widget
!= NULL
);
343 g_object_set (G_OBJECT (*out_edit_widget
),
345 "halign", GTK_ALIGN_FILL
,
347 "valign", GTK_ALIGN_START
,
350 gtk_widget_show (*out_edit_widget
);
352 if (g_type_is_a (klass
->entry_type
, GTK_TYPE_TEXT_VIEW
)) {
353 GtkScrolledWindow
*scrolled_window
;
354 GtkTextBuffer
*text_buffer
;
356 scrolled_window
= GTK_SCROLLED_WINDOW (gtk_scrolled_window_new (NULL
, NULL
));
357 gtk_scrolled_window_set_policy (scrolled_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
358 gtk_scrolled_window_set_shadow_type (scrolled_window
, GTK_SHADOW_IN
);
359 gtk_widget_show (GTK_WIDGET (scrolled_window
));
361 gtk_container_add (GTK_CONTAINER (scrolled_window
), *out_edit_widget
);
363 g_object_set (G_OBJECT (*out_edit_widget
),
365 "halign", GTK_ALIGN_FILL
,
367 "valign", GTK_ALIGN_FILL
,
370 g_object_set (G_OBJECT (scrolled_window
),
372 "halign", GTK_ALIGN_FILL
,
374 "valign", GTK_ALIGN_START
,
377 text_buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (*out_edit_widget
));
378 g_signal_connect_swapped (text_buffer
, "changed",
379 G_CALLBACK (e_comp_editor_property_part_emit_changed
), property_part
);
381 *out_edit_widget
= GTK_WIDGET (scrolled_window
);
383 g_signal_connect_swapped (*out_edit_widget
, "changed",
384 G_CALLBACK (e_comp_editor_property_part_emit_changed
), property_part
);
389 ecepp_string_fill_widget (ECompEditorPropertyPart
*property_part
,
390 icalcomponent
*component
)
392 ECompEditorPropertyPartStringClass
*klass
;
393 GtkWidget
*edit_widget
;
394 GString
*multivalue
= NULL
;
396 const gchar
*value
= NULL
;
398 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (property_part
));
399 g_return_if_fail (component
!= NULL
);
401 edit_widget
= e_comp_editor_property_part_get_edit_widget (property_part
);
402 g_return_if_fail (GTK_IS_ENTRY (edit_widget
) || GTK_IS_SCROLLED_WINDOW (edit_widget
));
404 klass
= E_COMP_EDITOR_PROPERTY_PART_STRING_GET_CLASS (property_part
);
405 g_return_if_fail (klass
!= NULL
);
406 g_return_if_fail (klass
->ical_prop_kind
!= ICAL_NO_PROPERTY
);
407 g_return_if_fail (klass
->ical_get_func
!= NULL
);
409 if (e_comp_editor_property_part_string_is_multivalue (E_COMP_EDITOR_PROPERTY_PART_STRING (property_part
))) {
410 for (prop
= icalcomponent_get_first_property (component
, klass
->ical_prop_kind
);
412 prop
= icalcomponent_get_next_property (component
, klass
->ical_prop_kind
)) {
413 value
= klass
->ical_get_func (prop
);
415 if (!value
|| !*value
)
419 multivalue
= g_string_new ("");
420 else if (multivalue
->len
)
421 g_string_append_c (multivalue
, ',');
423 g_string_append (multivalue
, value
);
427 value
= multivalue
->str
;
431 prop
= icalcomponent_get_first_property (component
, klass
->ical_prop_kind
);
433 value
= klass
->ical_get_func (prop
);
439 if (GTK_IS_ENTRY (edit_widget
)) {
440 gtk_entry_set_text (GTK_ENTRY (edit_widget
), value
);
441 } else /* if (GTK_IS_SCROLLED_WINDOW (edit_widget)) */ {
442 GtkTextBuffer
*buffer
;
444 buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_bin_get_child (GTK_BIN (edit_widget
))));
445 gtk_text_buffer_set_text (buffer
, value
, -1);
448 e_widget_undo_reset (edit_widget
);
451 g_string_free (multivalue
, TRUE
);
455 ecepp_string_fill_component (ECompEditorPropertyPart
*property_part
,
456 icalcomponent
*component
)
458 ECompEditorPropertyPartStringClass
*klass
;
459 GtkWidget
*edit_widget
;
463 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (property_part
));
464 g_return_if_fail (component
!= NULL
);
466 edit_widget
= e_comp_editor_property_part_get_edit_widget (property_part
);
467 g_return_if_fail (GTK_IS_ENTRY (edit_widget
) || GTK_IS_SCROLLED_WINDOW (edit_widget
));
469 klass
= E_COMP_EDITOR_PROPERTY_PART_STRING_GET_CLASS (property_part
);
470 g_return_if_fail (klass
!= NULL
);
471 g_return_if_fail (klass
->ical_prop_kind
!= ICAL_NO_PROPERTY
);
472 g_return_if_fail (klass
->ical_new_func
!= NULL
);
473 g_return_if_fail (klass
->ical_set_func
!= NULL
);
475 if (GTK_IS_ENTRY (edit_widget
)) {
476 value
= g_strdup (gtk_entry_get_text (GTK_ENTRY (edit_widget
)));
477 } else /* if (GTK_IS_SCROLLED_WINDOW (edit_widget)) */ {
478 GtkTextBuffer
*buffer
;
479 GtkTextIter text_iter_start
, text_iter_end
;
481 buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_bin_get_child (GTK_BIN (edit_widget
))));
482 gtk_text_buffer_get_start_iter (buffer
, &text_iter_start
);
483 gtk_text_buffer_get_end_iter (buffer
, &text_iter_end
);
484 value
= gtk_text_buffer_get_text (buffer
, &text_iter_start
, &text_iter_end
, FALSE
);
487 if (e_comp_editor_property_part_string_is_multivalue (E_COMP_EDITOR_PROPERTY_PART_STRING (property_part
))) {
488 /* Clear all multivalues first */
489 while (prop
= icalcomponent_get_first_property (component
, klass
->ical_prop_kind
), prop
) {
490 icalcomponent_remove_property (component
, prop
);
491 icalproperty_free (prop
);
495 prop
= icalcomponent_get_first_property (component
, klass
->ical_prop_kind
);
497 if (value
&& *value
) {
499 klass
->ical_set_func (prop
, value
);
501 prop
= klass
->ical_new_func (value
);
502 icalcomponent_add_property (component
, prop
);
505 icalcomponent_remove_property (component
, prop
);
506 icalproperty_free (prop
);
513 e_comp_editor_property_part_string_init (ECompEditorPropertyPartString
*part_string
)
515 part_string
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (part_string
,
516 E_TYPE_COMP_EDITOR_PROPERTY_PART_STRING
,
517 ECompEditorPropertyPartStringPrivate
);
518 part_string
->priv
->is_multivalue
= FALSE
;
522 e_comp_editor_property_part_string_class_init (ECompEditorPropertyPartStringClass
*klass
)
524 ECompEditorPropertyPartClass
*part_class
;
526 g_type_class_add_private (klass
, sizeof (ECompEditorPropertyPartStringPrivate
));
528 klass
->entry_type
= GTK_TYPE_ENTRY
;
530 klass
->ical_prop_kind
= ICAL_NO_PROPERTY
;
531 klass
->ical_new_func
= NULL
;
532 klass
->ical_set_func
= NULL
;
533 klass
->ical_get_func
= NULL
;
535 part_class
= E_COMP_EDITOR_PROPERTY_PART_CLASS (klass
);
536 part_class
->create_widgets
= ecepp_string_create_widgets
;
537 part_class
->fill_widget
= ecepp_string_fill_widget
;
538 part_class
->fill_component
= ecepp_string_fill_component
;
542 e_comp_editor_property_part_string_attach_focus_tracker (ECompEditorPropertyPartString
*part_string
,
543 EFocusTracker
*focus_tracker
)
545 GtkWidget
*edit_widget
;
547 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (part_string
));
552 g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker
));
554 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_string
));
556 if (GTK_IS_SCROLLED_WINDOW (edit_widget
))
557 e_widget_undo_attach (gtk_bin_get_child (GTK_BIN (edit_widget
)), focus_tracker
);
559 e_widget_undo_attach (edit_widget
, focus_tracker
);
564 e_comp_editor_property_part_string_set_is_multivalue (ECompEditorPropertyPartString
*part_string
,
565 gboolean is_multivalue
)
567 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (part_string
));
569 part_string
->priv
->is_multivalue
= is_multivalue
;
573 e_comp_editor_property_part_string_is_multivalue (ECompEditorPropertyPartString
*part_string
)
575 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (part_string
), FALSE
);
577 return part_string
->priv
->is_multivalue
;
580 /* ************************************************************************* */
582 struct _ECompEditorPropertyPartDatetimePrivate
{
583 GWeakRef timezone_entry
;
586 G_DEFINE_ABSTRACT_TYPE (ECompEditorPropertyPartDatetime
, e_comp_editor_property_part_datetime
, E_TYPE_COMP_EDITOR_PROPERTY_PART
)
589 ecepp_datetime_create_widgets (ECompEditorPropertyPart
*property_part
,
590 GtkWidget
**out_label_widget
,
591 GtkWidget
**out_edit_widget
)
593 ECompEditorPropertyPartDatetimeClass
*klass
;
595 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (property_part
));
596 g_return_if_fail (out_label_widget
!= NULL
);
597 g_return_if_fail (out_edit_widget
!= NULL
);
599 klass
= E_COMP_EDITOR_PROPERTY_PART_DATETIME_GET_CLASS (property_part
);
600 g_return_if_fail (klass
!= NULL
);
602 /* The descendant sets the 'out_label_widget' parameter */
603 *out_edit_widget
= e_date_edit_new ();
604 g_return_if_fail (*out_edit_widget
!= NULL
);
606 g_object_set (G_OBJECT (*out_edit_widget
),
608 "halign", GTK_ALIGN_START
,
610 "valign", GTK_ALIGN_START
,
613 gtk_widget_show (*out_edit_widget
);
615 g_signal_connect_swapped (*out_edit_widget
, "changed",
616 G_CALLBACK (e_comp_editor_property_part_emit_changed
), property_part
);
617 g_signal_connect_swapped (*out_edit_widget
, "notify::show-time",
618 G_CALLBACK (e_comp_editor_property_part_emit_changed
), property_part
);
622 ecepp_datetime_fill_widget (ECompEditorPropertyPart
*property_part
,
623 icalcomponent
*component
)
625 ECompEditorPropertyPartDatetime
*part_datetime
;
626 ECompEditorPropertyPartDatetimeClass
*klass
;
627 GtkWidget
*edit_widget
;
629 struct icaltimetype value
;
631 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (property_part
));
632 g_return_if_fail (component
!= NULL
);
634 edit_widget
= e_comp_editor_property_part_get_edit_widget (property_part
);
635 g_return_if_fail (E_IS_DATE_EDIT (edit_widget
));
637 klass
= E_COMP_EDITOR_PROPERTY_PART_DATETIME_GET_CLASS (property_part
);
638 g_return_if_fail (klass
!= NULL
);
639 g_return_if_fail (klass
->ical_prop_kind
!= ICAL_NO_PROPERTY
);
640 g_return_if_fail (klass
->ical_get_func
!= NULL
);
642 part_datetime
= E_COMP_EDITOR_PROPERTY_PART_DATETIME (property_part
);
644 prop
= icalcomponent_get_first_property (component
, klass
->ical_prop_kind
);
646 value
= klass
->ical_get_func (prop
);
648 value
= icaltime_null_time ();
650 e_comp_editor_property_part_datetime_set_value (part_datetime
, value
);
654 ecepp_datetime_fill_component (ECompEditorPropertyPart
*property_part
,
655 icalcomponent
*component
)
657 ECompEditorPropertyPartDatetime
*part_datetime
;
658 ECompEditorPropertyPartDatetimeClass
*klass
;
659 GtkWidget
*edit_widget
;
660 EDateEdit
*date_edit
;
662 struct icaltimetype value
;
665 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (property_part
));
666 g_return_if_fail (component
!= NULL
);
668 edit_widget
= e_comp_editor_property_part_get_edit_widget (property_part
);
669 g_return_if_fail (E_IS_DATE_EDIT (edit_widget
));
671 klass
= E_COMP_EDITOR_PROPERTY_PART_DATETIME_GET_CLASS (property_part
);
672 g_return_if_fail (klass
!= NULL
);
673 g_return_if_fail (klass
->ical_prop_kind
!= ICAL_NO_PROPERTY
);
674 g_return_if_fail (klass
->ical_new_func
!= NULL
);
675 g_return_if_fail (klass
->ical_set_func
!= NULL
);
677 part_datetime
= E_COMP_EDITOR_PROPERTY_PART_DATETIME (property_part
);
678 date_edit
= E_DATE_EDIT (edit_widget
);
679 tt
= e_date_edit_get_time (date_edit
);
681 prop
= icalcomponent_get_first_property (component
, klass
->ical_prop_kind
);
683 if (e_date_edit_get_allow_no_date_set (date_edit
) && tt
== (time_t) -1) {
685 icalcomponent_remove_property (component
, prop
);
686 icalproperty_free (prop
);
689 value
= e_comp_editor_property_part_datetime_get_value (part_datetime
);
692 klass
->ical_set_func (prop
, value
);
693 cal_comp_util_update_tzid_parameter (prop
, value
);
695 prop
= klass
->ical_new_func (value
);
696 cal_comp_util_update_tzid_parameter (prop
, value
);
697 icalcomponent_add_property (component
, prop
);
703 ecepp_datetime_finalize (GObject
*object
)
705 ECompEditorPropertyPartDatetime
*part_datetime
= E_COMP_EDITOR_PROPERTY_PART_DATETIME (object
);
707 g_weak_ref_clear (&part_datetime
->priv
->timezone_entry
);
709 G_OBJECT_CLASS (e_comp_editor_property_part_datetime_parent_class
)->finalize (object
);
713 e_comp_editor_property_part_datetime_init (ECompEditorPropertyPartDatetime
*part_datetime
)
715 part_datetime
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (part_datetime
,
716 E_TYPE_COMP_EDITOR_PROPERTY_PART_DATETIME
,
717 ECompEditorPropertyPartDatetimePrivate
);
719 g_weak_ref_init (&part_datetime
->priv
->timezone_entry
, NULL
);
723 e_comp_editor_property_part_datetime_class_init (ECompEditorPropertyPartDatetimeClass
*klass
)
725 ECompEditorPropertyPartClass
*part_class
;
726 GObjectClass
*object_class
;
728 g_type_class_add_private (klass
, sizeof (ECompEditorPropertyPartDatetimePrivate
));
730 klass
->ical_prop_kind
= ICAL_NO_PROPERTY
;
731 klass
->ical_new_func
= NULL
;
732 klass
->ical_set_func
= NULL
;
733 klass
->ical_get_func
= NULL
;
735 part_class
= E_COMP_EDITOR_PROPERTY_PART_CLASS (klass
);
736 part_class
->create_widgets
= ecepp_datetime_create_widgets
;
737 part_class
->fill_widget
= ecepp_datetime_fill_widget
;
738 part_class
->fill_component
= ecepp_datetime_fill_component
;
740 object_class
= G_OBJECT_CLASS (klass
);
741 object_class
->finalize
= ecepp_datetime_finalize
;
745 e_comp_editor_property_part_datetime_attach_timezone_entry (ECompEditorPropertyPartDatetime
*part_datetime
,
746 ETimezoneEntry
*timezone_entry
)
748 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (part_datetime
));
750 g_return_if_fail (E_IS_TIMEZONE_ENTRY (timezone_entry
));
752 g_weak_ref_set (&part_datetime
->priv
->timezone_entry
, timezone_entry
);
756 e_comp_editor_property_part_datetime_set_date_only (ECompEditorPropertyPartDatetime
*part_datetime
,
759 GtkWidget
*edit_widget
;
761 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (part_datetime
));
763 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_datetime
));
764 g_return_if_fail (E_IS_DATE_EDIT (edit_widget
));
766 if ((e_date_edit_get_show_time (E_DATE_EDIT (edit_widget
)) ? 1 : 0) == ((!date_only
) ? 1 : 0))
769 e_date_edit_set_show_time (E_DATE_EDIT (edit_widget
), !date_only
);
773 e_comp_editor_property_part_datetime_get_date_only (ECompEditorPropertyPartDatetime
*part_datetime
)
775 GtkWidget
*edit_widget
;
777 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (part_datetime
), FALSE
);
779 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_datetime
));
780 g_return_val_if_fail (E_IS_DATE_EDIT (edit_widget
), FALSE
);
782 return !e_date_edit_get_show_time (E_DATE_EDIT (edit_widget
));
786 e_comp_editor_property_part_datetime_set_allow_no_date_set (ECompEditorPropertyPartDatetime
*part_datetime
,
787 gboolean allow_no_date_set
)
789 GtkWidget
*edit_widget
;
791 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (part_datetime
));
793 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_datetime
));
794 g_return_if_fail (E_IS_DATE_EDIT (edit_widget
));
796 e_date_edit_set_allow_no_date_set (E_DATE_EDIT (edit_widget
), allow_no_date_set
);
800 e_comp_editor_property_part_datetime_get_allow_no_date_set (ECompEditorPropertyPartDatetime
*part_datetime
)
802 GtkWidget
*edit_widget
;
804 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (part_datetime
), FALSE
);
806 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_datetime
));
807 g_return_val_if_fail (E_IS_DATE_EDIT (edit_widget
), FALSE
);
809 return !e_date_edit_get_allow_no_date_set (E_DATE_EDIT (edit_widget
));
813 e_comp_editor_property_part_datetime_set_value (ECompEditorPropertyPartDatetime
*part_datetime
,
814 struct icaltimetype value
)
816 GtkWidget
*edit_widget
;
817 EDateEdit
*date_edit
;
819 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (part_datetime
));
821 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_datetime
));
822 g_return_if_fail (E_IS_DATE_EDIT (edit_widget
));
824 date_edit
= E_DATE_EDIT (edit_widget
);
826 if (!e_date_edit_get_allow_no_date_set (date_edit
) && (icaltime_is_null_time (value
) ||
827 !icaltime_is_valid_time (value
))) {
828 value
= icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
831 if (icaltime_is_null_time (value
) ||
832 !icaltime_is_valid_time (value
)) {
833 e_date_edit_set_time (date_edit
, (time_t) -1);
835 e_date_edit_set_date (date_edit
, value
.year
, value
.month
, value
.day
);
838 e_date_edit_set_time_of_day (date_edit
, value
.hour
, value
.minute
);
839 else if (e_date_edit_get_show_time (date_edit
))
840 e_date_edit_set_time_of_day (date_edit
, 0, 0);
841 else if (e_date_edit_get_allow_no_date_set (date_edit
))
842 e_date_edit_set_time_of_day (date_edit
, -1, -1);
844 e_comp_editor_property_part_datetime_set_date_only (part_datetime
, value
.is_date
);
849 e_comp_editor_property_part_datetime_get_value (ECompEditorPropertyPartDatetime
*part_datetime
)
851 ETimezoneEntry
*timezone_entry
= NULL
;
852 GtkWidget
*edit_widget
;
853 EDateEdit
*date_edit
;
854 struct icaltimetype value
= icaltime_null_time ();
856 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (part_datetime
), value
);
858 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_datetime
));
859 g_return_val_if_fail (E_IS_DATE_EDIT (edit_widget
), value
);
861 date_edit
= E_DATE_EDIT (edit_widget
);
863 if (!e_date_edit_get_date (date_edit
, &value
.year
, &value
.month
, &value
.day
))
864 return icaltime_null_time ();
866 if (!e_date_edit_get_show_time (date_edit
)) {
870 value
.is_date
= !e_date_edit_get_time_of_day (date_edit
, &value
.hour
, &value
.minute
);
872 if (!value
.is_date
) {
873 timezone_entry
= g_weak_ref_get (&part_datetime
->priv
->timezone_entry
);
875 value
.zone
= e_timezone_entry_get_timezone (timezone_entry
);
877 value
.zone
= icaltimezone_get_utc_timezone ();
881 g_clear_object (&timezone_entry
);
887 e_comp_editor_property_part_datetime_check_validity (ECompEditorPropertyPartDatetime
*part_datetime
,
888 gboolean
*out_date_is_valid
,
889 gboolean
*out_time_is_valid
)
891 GtkWidget
*edit_widget
;
892 EDateEdit
*date_edit
;
893 gboolean date_is_valid
= TRUE
, time_is_valid
= TRUE
;
895 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (part_datetime
), FALSE
);
897 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_datetime
));
898 g_return_val_if_fail (E_IS_DATE_EDIT (edit_widget
), FALSE
);
900 date_edit
= E_DATE_EDIT (edit_widget
);
902 if (!e_date_edit_get_allow_no_date_set (date_edit
) ||
903 e_date_edit_get_time (date_edit
) != (time_t) -1) {
904 date_is_valid
= e_date_edit_date_is_valid (date_edit
);
906 if (e_date_edit_get_show_time (date_edit
))
907 time_is_valid
= e_date_edit_time_is_valid (date_edit
);
910 if (out_date_is_valid
)
911 *out_date_is_valid
= date_is_valid
;
912 if (out_time_is_valid
)
913 *out_time_is_valid
= time_is_valid
;
915 return date_is_valid
&& time_is_valid
;
918 /* ************************************************************************* */
920 struct _ECompEditorPropertyPartSpinPrivate
{
924 G_DEFINE_ABSTRACT_TYPE (ECompEditorPropertyPartSpin
, e_comp_editor_property_part_spin
, E_TYPE_COMP_EDITOR_PROPERTY_PART
)
927 ecepp_spin_create_widgets (ECompEditorPropertyPart
*property_part
,
928 GtkWidget
**out_label_widget
,
929 GtkWidget
**out_edit_widget
)
931 ECompEditorPropertyPartSpinClass
*klass
;
933 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_SPIN (property_part
));
934 g_return_if_fail (out_label_widget
!= NULL
);
935 g_return_if_fail (out_edit_widget
!= NULL
);
937 klass
= E_COMP_EDITOR_PROPERTY_PART_SPIN_GET_CLASS (property_part
);
938 g_return_if_fail (klass
!= NULL
);
940 /* The descendant sets the 'out_label_widget' parameter */
941 *out_edit_widget
= gtk_spin_button_new_with_range (-10, 10, 1);
942 g_return_if_fail (*out_edit_widget
!= NULL
);
944 g_object_set (G_OBJECT (*out_edit_widget
),
946 "halign", GTK_ALIGN_FILL
,
948 "valign", GTK_ALIGN_START
,
951 gtk_spin_button_set_digits (GTK_SPIN_BUTTON (*out_edit_widget
), 0);
953 gtk_widget_show (*out_edit_widget
);
955 g_signal_connect_swapped (*out_edit_widget
, "value-changed",
956 G_CALLBACK (e_comp_editor_property_part_emit_changed
), property_part
);
960 ecepp_spin_fill_widget (ECompEditorPropertyPart
*property_part
,
961 icalcomponent
*component
)
963 ECompEditorPropertyPartSpinClass
*klass
;
964 GtkWidget
*edit_widget
;
968 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_SPIN (property_part
));
969 g_return_if_fail (component
!= NULL
);
971 edit_widget
= e_comp_editor_property_part_get_edit_widget (property_part
);
972 g_return_if_fail (GTK_IS_SPIN_BUTTON (edit_widget
));
974 klass
= E_COMP_EDITOR_PROPERTY_PART_SPIN_GET_CLASS (property_part
);
975 g_return_if_fail (klass
!= NULL
);
976 g_return_if_fail (klass
->ical_prop_kind
!= ICAL_NO_PROPERTY
);
977 g_return_if_fail (klass
->ical_get_func
!= NULL
);
979 prop
= icalcomponent_get_first_property (component
, klass
->ical_prop_kind
);
981 value
= klass
->ical_get_func (prop
);
983 gdouble d_min
, d_max
;
985 gtk_spin_button_get_range (GTK_SPIN_BUTTON (edit_widget
), &d_min
, &d_max
);
987 value
= (gint
) d_min
;
990 gtk_spin_button_set_value (GTK_SPIN_BUTTON (edit_widget
), value
);
994 ecepp_spin_fill_component (ECompEditorPropertyPart
*property_part
,
995 icalcomponent
*component
)
997 ECompEditorPropertyPartSpinClass
*klass
;
998 GtkWidget
*edit_widget
;
1002 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_SPIN (property_part
));
1003 g_return_if_fail (component
!= NULL
);
1005 edit_widget
= e_comp_editor_property_part_get_edit_widget (property_part
);
1006 g_return_if_fail (GTK_IS_SPIN_BUTTON (edit_widget
));
1008 klass
= E_COMP_EDITOR_PROPERTY_PART_SPIN_GET_CLASS (property_part
);
1009 g_return_if_fail (klass
!= NULL
);
1010 g_return_if_fail (klass
->ical_prop_kind
!= ICAL_NO_PROPERTY
);
1011 g_return_if_fail (klass
->ical_new_func
!= NULL
);
1012 g_return_if_fail (klass
->ical_set_func
!= NULL
);
1014 value
= gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (edit_widget
));
1015 prop
= icalcomponent_get_first_property (component
, klass
->ical_prop_kind
);
1018 klass
->ical_set_func (prop
, value
);
1020 prop
= klass
->ical_new_func (value
);
1021 icalcomponent_add_property (component
, prop
);
1026 e_comp_editor_property_part_spin_init (ECompEditorPropertyPartSpin
*part_spin
)
1028 part_spin
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (part_spin
,
1029 E_TYPE_COMP_EDITOR_PROPERTY_PART_SPIN
,
1030 ECompEditorPropertyPartSpinPrivate
);
1034 e_comp_editor_property_part_spin_class_init (ECompEditorPropertyPartSpinClass
*klass
)
1036 ECompEditorPropertyPartClass
*part_class
;
1038 g_type_class_add_private (klass
, sizeof (ECompEditorPropertyPartSpinPrivate
));
1040 klass
->ical_prop_kind
= ICAL_NO_PROPERTY
;
1041 klass
->ical_new_func
= NULL
;
1042 klass
->ical_set_func
= NULL
;
1043 klass
->ical_get_func
= NULL
;
1045 part_class
= E_COMP_EDITOR_PROPERTY_PART_CLASS (klass
);
1046 part_class
->create_widgets
= ecepp_spin_create_widgets
;
1047 part_class
->fill_widget
= ecepp_spin_fill_widget
;
1048 part_class
->fill_component
= ecepp_spin_fill_component
;
1052 e_comp_editor_property_part_spin_set_range (ECompEditorPropertyPartSpin
*part_spin
,
1056 GtkWidget
*edit_widget
;
1058 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_SPIN (part_spin
));
1060 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_spin
));
1061 g_return_if_fail (GTK_IS_SPIN_BUTTON (edit_widget
));
1063 gtk_spin_button_set_range (GTK_SPIN_BUTTON (edit_widget
), min_value
, max_value
);
1067 e_comp_editor_property_part_spin_get_range (ECompEditorPropertyPartSpin
*part_spin
,
1068 gint
*out_min_value
,
1069 gint
*out_max_value
)
1071 GtkWidget
*edit_widget
;
1072 gdouble d_min
= 0, d_max
= 0;
1074 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_SPIN (part_spin
));
1076 edit_widget
= e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_spin
));
1077 g_return_if_fail (GTK_IS_SPIN_BUTTON (edit_widget
));
1079 gtk_spin_button_get_range (GTK_SPIN_BUTTON (edit_widget
), &d_min
, &d_max
);
1082 *out_min_value
= (gint
) d_min
;
1084 *out_max_value
= (gint
) d_max
;
1087 /* ************************************************************************* */
1089 struct _ECompEditorPropertyPartPickerPrivate
{
1093 G_DEFINE_ABSTRACT_TYPE (ECompEditorPropertyPartPicker
, e_comp_editor_property_part_picker
, E_TYPE_COMP_EDITOR_PROPERTY_PART
)
1096 ecepp_picker_create_widgets (ECompEditorPropertyPart
*property_part
,
1097 GtkWidget
**out_label_widget
,
1098 GtkWidget
**out_edit_widget
)
1100 ECompEditorPropertyPartPickerClass
*klass
;
1101 GtkComboBoxText
*combo_box
;
1102 GSList
*ids
= NULL
, *display_names
= NULL
, *i_link
, *dn_link
;
1104 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER (property_part
));
1105 g_return_if_fail (out_label_widget
!= NULL
);
1106 g_return_if_fail (out_edit_widget
!= NULL
);
1108 klass
= E_COMP_EDITOR_PROPERTY_PART_PICKER_GET_CLASS (property_part
);
1109 g_return_if_fail (klass
!= NULL
);
1111 /* The descendant sets the 'out_label_widget' parameter */
1112 *out_edit_widget
= gtk_combo_box_text_new ();
1113 g_return_if_fail (*out_edit_widget
!= NULL
);
1115 g_object_set (G_OBJECT (*out_edit_widget
),
1117 "halign", GTK_ALIGN_FILL
,
1119 "valign", GTK_ALIGN_START
,
1122 gtk_widget_show (*out_edit_widget
);
1124 e_comp_editor_property_part_picker_get_values (E_COMP_EDITOR_PROPERTY_PART_PICKER (property_part
),
1125 &ids
, &display_names
);
1127 g_warn_if_fail (g_slist_length (ids
) == g_slist_length (display_names
));
1129 combo_box
= GTK_COMBO_BOX_TEXT (*out_edit_widget
);
1131 for (i_link
= ids
, dn_link
= display_names
; i_link
&& dn_link
; i_link
= g_slist_next (i_link
), dn_link
= g_slist_next (dn_link
)) {
1132 const gchar
*id
, *display_name
;
1135 display_name
= dn_link
->data
;
1137 g_warn_if_fail (id
!= NULL
);
1138 g_warn_if_fail (display_name
!= NULL
);
1140 if (!id
|| !display_name
)
1143 gtk_combo_box_text_append (combo_box
, id
, display_name
);
1146 g_slist_free_full (ids
, g_free
);
1147 g_slist_free_full (display_names
, g_free
);
1149 g_signal_connect_swapped (*out_edit_widget
, "changed",
1150 G_CALLBACK (e_comp_editor_property_part_emit_changed
), property_part
);
1154 ecepp_picker_fill_widget (ECompEditorPropertyPart
*property_part
,
1155 icalcomponent
*component
)
1157 GtkWidget
*edit_widget
;
1160 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER (property_part
));
1161 g_return_if_fail (component
!= NULL
);
1163 edit_widget
= e_comp_editor_property_part_get_edit_widget (property_part
);
1164 g_return_if_fail (GTK_IS_COMBO_BOX_TEXT (edit_widget
));
1166 if (e_comp_editor_property_part_picker_get_from_component (
1167 E_COMP_EDITOR_PROPERTY_PART_PICKER (property_part
),
1168 component
, &id
) && id
) {
1169 gtk_combo_box_set_active_id (GTK_COMBO_BOX (edit_widget
), id
);
1172 gtk_combo_box_set_active (GTK_COMBO_BOX (edit_widget
), 0);
1177 ecepp_picker_fill_component (ECompEditorPropertyPart
*property_part
,
1178 icalcomponent
*component
)
1180 GtkWidget
*edit_widget
;
1183 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER (property_part
));
1184 g_return_if_fail (component
!= NULL
);
1186 edit_widget
= e_comp_editor_property_part_get_edit_widget (property_part
);
1187 g_return_if_fail (GTK_IS_COMBO_BOX_TEXT (edit_widget
));
1189 id
= gtk_combo_box_get_active_id (GTK_COMBO_BOX (edit_widget
));
1191 e_comp_editor_property_part_picker_set_to_component (
1192 E_COMP_EDITOR_PROPERTY_PART_PICKER (property_part
),
1198 e_comp_editor_property_part_picker_init (ECompEditorPropertyPartPicker
*part_picker
)
1200 part_picker
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (part_picker
,
1201 E_TYPE_COMP_EDITOR_PROPERTY_PART_PICKER
,
1202 ECompEditorPropertyPartPickerPrivate
);
1206 e_comp_editor_property_part_picker_class_init (ECompEditorPropertyPartPickerClass
*klass
)
1208 ECompEditorPropertyPartClass
*part_class
;
1210 g_type_class_add_private (klass
, sizeof (ECompEditorPropertyPartPickerPrivate
));
1212 part_class
= E_COMP_EDITOR_PROPERTY_PART_CLASS (klass
);
1213 part_class
->create_widgets
= ecepp_picker_create_widgets
;
1214 part_class
->fill_widget
= ecepp_picker_fill_widget
;
1215 part_class
->fill_component
= ecepp_picker_fill_component
;
1218 /* Both out_ids and out_display_names contain newly allocated strings,
1219 where also n-th element of out_uids corresponds to n-th element of
1220 the out_display_names. */
1222 e_comp_editor_property_part_picker_get_values (ECompEditorPropertyPartPicker
*part_picker
,
1224 GSList
**out_display_names
)
1226 ECompEditorPropertyPartPickerClass
*klass
;
1228 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER (part_picker
));
1230 klass
= E_COMP_EDITOR_PROPERTY_PART_PICKER_GET_CLASS (part_picker
);
1231 g_return_if_fail (klass
!= NULL
);
1232 g_return_if_fail (klass
->get_values
!= NULL
);
1234 klass
->get_values (part_picker
, out_ids
, out_display_names
);
1238 e_comp_editor_property_part_picker_get_from_component (ECompEditorPropertyPartPicker
*part_picker
,
1239 icalcomponent
*component
,
1242 ECompEditorPropertyPartPickerClass
*klass
;
1244 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER (part_picker
), FALSE
);
1246 klass
= E_COMP_EDITOR_PROPERTY_PART_PICKER_GET_CLASS (part_picker
);
1247 g_return_val_if_fail (klass
!= NULL
, FALSE
);
1248 g_return_val_if_fail (klass
->get_from_component
!= NULL
, FALSE
);
1250 return klass
->get_from_component (part_picker
, component
, out_id
);
1254 e_comp_editor_property_part_picker_set_to_component (ECompEditorPropertyPartPicker
*part_picker
,
1256 icalcomponent
*component
)
1258 ECompEditorPropertyPartPickerClass
*klass
;
1260 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER (part_picker
));
1262 klass
= E_COMP_EDITOR_PROPERTY_PART_PICKER_GET_CLASS (part_picker
);
1263 g_return_if_fail (klass
!= NULL
);
1264 g_return_if_fail (klass
->set_to_component
!= NULL
);
1266 klass
->set_to_component (part_picker
, id
, component
);
1270 e_comp_editor_property_part_picker_get_selected_id (ECompEditorPropertyPartPicker
*part_picker
)
1272 GtkWidget
*edit_widget
;
1274 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER (part_picker
), NULL
);
1276 edit_widget
= e_comp_editor_property_part_get_edit_widget (
1277 E_COMP_EDITOR_PROPERTY_PART (part_picker
));
1278 g_return_val_if_fail (GTK_IS_COMBO_BOX_TEXT (edit_widget
), NULL
);
1280 return gtk_combo_box_get_active_id (GTK_COMBO_BOX (edit_widget
));
1284 e_comp_editor_property_part_picker_set_selected_id (ECompEditorPropertyPartPicker
*part_picker
,
1287 GtkWidget
*edit_widget
;
1289 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER (part_picker
));
1290 g_return_if_fail (id
!= NULL
);
1292 edit_widget
= e_comp_editor_property_part_get_edit_widget (
1293 E_COMP_EDITOR_PROPERTY_PART (part_picker
));
1294 g_return_if_fail (GTK_IS_COMBO_BOX_TEXT (edit_widget
));
1296 gtk_combo_box_set_active_id (GTK_COMBO_BOX (edit_widget
), id
);
1299 /* ************************************************************************* */
1301 struct _ECompEditorPropertyPartPickerWithMapPrivate
{
1302 ECompEditorPropertyPartPickerMap
*map
;
1306 icalproperty_kind ical_prop_kind
;
1307 ECompEditorPropertyPartPickerMapICalNewFunc ical_new_func
;
1308 ECompEditorPropertyPartPickerMapICalSetFunc ical_set_func
;
1309 ECompEditorPropertyPartPickerMapICalGetFunc ical_get_func
;
1313 PICKER_WITH_MAP_PROP_0
,
1314 PICKER_WITH_MAP_PROP_MAP
,
1315 PICKER_WITH_MAP_PROP_LABEL
1318 G_DEFINE_TYPE (ECompEditorPropertyPartPickerWithMap
, e_comp_editor_property_part_picker_with_map
, E_TYPE_COMP_EDITOR_PROPERTY_PART_PICKER
)
1321 ecepp_picker_with_map_get_values (ECompEditorPropertyPartPicker
*part_picker
,
1323 GSList
**out_display_names
)
1325 ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
;
1328 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (part_picker
));
1329 g_return_if_fail (out_ids
!= NULL
);
1330 g_return_if_fail (out_display_names
!= NULL
);
1332 part_picker_with_map
= E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (part_picker
);
1333 g_return_if_fail (part_picker_with_map
->priv
->map
!= NULL
);
1334 g_return_if_fail (part_picker_with_map
->priv
->n_map_elems
> 0);
1336 for (ii
= 0; ii
< part_picker_with_map
->priv
->n_map_elems
; ii
++) {
1337 *out_ids
= g_slist_prepend (*out_ids
, g_strdup_printf ("%d", ii
));
1338 *out_display_names
= g_slist_prepend (*out_display_names
,
1339 g_strdup (part_picker_with_map
->priv
->map
[ii
].description
));
1342 *out_ids
= g_slist_reverse (*out_ids
);
1343 *out_display_names
= g_slist_reverse (*out_display_names
);
1347 ecepp_picker_with_map_get_from_component (ECompEditorPropertyPartPicker
*part_picker
,
1348 icalcomponent
*component
,
1351 ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
;
1355 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (part_picker
), FALSE
);
1356 g_return_val_if_fail (component
!= NULL
, FALSE
);
1357 g_return_val_if_fail (out_id
!= NULL
, FALSE
);
1359 part_picker_with_map
= E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (part_picker
);
1360 g_return_val_if_fail (part_picker_with_map
->priv
->map
!= NULL
, FALSE
);
1361 g_return_val_if_fail (part_picker_with_map
->priv
->n_map_elems
> 0, FALSE
);
1362 g_return_val_if_fail (part_picker_with_map
->priv
->ical_prop_kind
!= ICAL_NO_PROPERTY
, FALSE
);
1363 g_return_val_if_fail (part_picker_with_map
->priv
->ical_get_func
!= NULL
, FALSE
);
1365 prop
= icalcomponent_get_first_property (component
, part_picker_with_map
->priv
->ical_prop_kind
);
1369 value
= part_picker_with_map
->priv
->ical_get_func (prop
);
1371 for (ii
= 0; ii
< part_picker_with_map
->priv
->n_map_elems
; ii
++) {
1374 if (part_picker_with_map
->priv
->map
[ii
].matches_func
) {
1375 matches
= part_picker_with_map
->priv
->map
[ii
].matches_func (part_picker_with_map
->priv
->map
[ii
].value
, value
);
1377 matches
= value
== part_picker_with_map
->priv
->map
[ii
].value
;
1381 *out_id
= g_strdup_printf ("%d", ii
);
1390 ecepp_picker_with_map_set_to_component (ECompEditorPropertyPartPicker
*part_picker
,
1392 icalcomponent
*component
)
1394 ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
;
1398 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (part_picker
));
1399 g_return_if_fail (id
!= NULL
);
1400 g_return_if_fail (component
!= NULL
);
1402 part_picker_with_map
= E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (part_picker
);
1403 g_return_if_fail (part_picker_with_map
->priv
->map
!= NULL
);
1404 g_return_if_fail (part_picker_with_map
->priv
->n_map_elems
> 0);
1405 g_return_if_fail (part_picker_with_map
->priv
->ical_prop_kind
!= ICAL_NO_PROPERTY
);
1406 g_return_if_fail (part_picker_with_map
->priv
->ical_new_func
!= NULL
);
1407 g_return_if_fail (part_picker_with_map
->priv
->ical_set_func
!= NULL
);
1409 ii
= (gint
) g_ascii_strtoll (id
, NULL
, 10);
1410 g_return_if_fail (ii
>= 0 && ii
< part_picker_with_map
->priv
->n_map_elems
);
1412 prop
= icalcomponent_get_first_property (component
, part_picker_with_map
->priv
->ical_prop_kind
);
1413 value
= part_picker_with_map
->priv
->map
[ii
].value
;
1415 if (part_picker_with_map
->priv
->map
[ii
].delete_prop
) {
1417 icalcomponent_remove_property (component
, prop
);
1418 icalproperty_free (prop
);
1421 part_picker_with_map
->priv
->ical_set_func (prop
, value
);
1423 prop
= part_picker_with_map
->priv
->ical_new_func (value
);
1424 icalcomponent_add_property (component
, prop
);
1429 ecepp_picker_with_map_create_widgets (ECompEditorPropertyPart
*property_part
,
1430 GtkWidget
**out_label_widget
,
1431 GtkWidget
**out_edit_widget
)
1433 ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
;
1434 ECompEditorPropertyPartClass
*part_class
;
1436 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (property_part
));
1437 g_return_if_fail (out_label_widget
!= NULL
);
1438 g_return_if_fail (out_edit_widget
!= NULL
);
1440 part_class
= E_COMP_EDITOR_PROPERTY_PART_CLASS (e_comp_editor_property_part_picker_with_map_parent_class
);
1441 g_return_if_fail (part_class
!= NULL
);
1442 g_return_if_fail (part_class
->create_widgets
!= NULL
);
1444 *out_label_widget
= NULL
;
1446 part_class
->create_widgets (property_part
, out_label_widget
, out_edit_widget
);
1447 g_return_if_fail (*out_label_widget
== NULL
);
1448 g_return_if_fail (*out_edit_widget
!= NULL
);
1450 part_picker_with_map
= E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (property_part
);
1452 *out_label_widget
= gtk_label_new_with_mnemonic (part_picker_with_map
->priv
->label
);
1453 gtk_label_set_mnemonic_widget (GTK_LABEL (*out_label_widget
), *out_edit_widget
);
1455 g_object_set (G_OBJECT (*out_label_widget
),
1457 "halign", GTK_ALIGN_END
,
1459 "valign", GTK_ALIGN_CENTER
,
1462 gtk_widget_show (*out_label_widget
);
1466 ecepp_picker_with_map_set_property (GObject
*object
,
1468 const GValue
*value
,
1471 ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
;
1474 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (object
));
1476 part_picker_with_map
= E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (object
);
1478 switch (property_id
) {
1479 case PICKER_WITH_MAP_PROP_MAP
:
1480 g_return_if_fail (part_picker_with_map
->priv
->map
== NULL
);
1482 part_picker_with_map
->priv
->map
= g_value_get_pointer (value
);
1483 for (ii
= 0; part_picker_with_map
->priv
->map
[ii
].description
; ii
++) {
1484 /* pre-count elements */
1487 part_picker_with_map
->priv
->n_map_elems
= ii
;
1490 case PICKER_WITH_MAP_PROP_LABEL
:
1491 g_free (part_picker_with_map
->priv
->label
);
1492 part_picker_with_map
->priv
->label
= g_value_dup_string (value
);
1496 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
1500 ecepp_picker_with_map_finalize (GObject
*object
)
1502 ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
=
1503 E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (object
);
1505 if (part_picker_with_map
->priv
->map
&& part_picker_with_map
->priv
->n_map_elems
> 0) {
1508 for (ii
= 0; ii
< part_picker_with_map
->priv
->n_map_elems
; ii
++) {
1509 g_free ((gchar
*) part_picker_with_map
->priv
->map
[ii
].description
);
1512 g_free (part_picker_with_map
->priv
->map
);
1513 part_picker_with_map
->priv
->map
= NULL
;
1516 g_free (part_picker_with_map
->priv
->label
);
1517 part_picker_with_map
->priv
->label
= NULL
;
1519 G_OBJECT_CLASS (e_comp_editor_property_part_picker_with_map_parent_class
)->finalize (object
);
1523 e_comp_editor_property_part_picker_with_map_init (ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
)
1525 part_picker_with_map
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (part_picker_with_map
,
1526 E_TYPE_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP
,
1527 ECompEditorPropertyPartPickerWithMapPrivate
);
1531 e_comp_editor_property_part_picker_with_map_class_init (ECompEditorPropertyPartPickerWithMapClass
*klass
)
1533 ECompEditorPropertyPartPickerClass
*part_picker_class
;
1534 ECompEditorPropertyPartClass
*part_class
;
1535 GObjectClass
*object_class
;
1537 g_type_class_add_private (klass
, sizeof (ECompEditorPropertyPartPickerWithMapPrivate
));
1539 part_picker_class
= E_COMP_EDITOR_PROPERTY_PART_PICKER_CLASS (klass
);
1540 part_picker_class
->get_values
= ecepp_picker_with_map_get_values
;
1541 part_picker_class
->get_from_component
= ecepp_picker_with_map_get_from_component
;
1542 part_picker_class
->set_to_component
= ecepp_picker_with_map_set_to_component
;
1544 part_class
= E_COMP_EDITOR_PROPERTY_PART_CLASS (klass
);
1545 part_class
->create_widgets
= ecepp_picker_with_map_create_widgets
;
1547 object_class
= G_OBJECT_CLASS (klass
);
1548 object_class
->set_property
= ecepp_picker_with_map_set_property
;
1549 object_class
->finalize
= ecepp_picker_with_map_finalize
;
1551 g_object_class_install_property (
1553 PICKER_WITH_MAP_PROP_MAP
,
1554 g_param_spec_pointer (
1557 "Map of values, .description-NULL-terminated",
1559 G_PARAM_CONSTRUCT_ONLY
|
1560 G_PARAM_STATIC_STRINGS
));
1562 g_object_class_install_property (
1564 PICKER_WITH_MAP_PROP_LABEL
,
1565 g_param_spec_string (
1568 "Label of the picker",
1571 G_PARAM_CONSTRUCT_ONLY
|
1572 G_PARAM_STATIC_STRINGS
));
1575 ECompEditorPropertyPart
*
1576 e_comp_editor_property_part_picker_with_map_new (const ECompEditorPropertyPartPickerMap map
[],
1577 gint n_map_elements
,
1579 icalproperty_kind ical_prop_kind
,
1580 ECompEditorPropertyPartPickerMapICalNewFunc ical_new_func
,
1581 ECompEditorPropertyPartPickerMapICalSetFunc ical_set_func
,
1582 ECompEditorPropertyPartPickerMapICalGetFunc ical_get_func
)
1584 ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
;
1585 ECompEditorPropertyPartPickerMap
*map_copy
;
1586 ECompEditorPropertyPart
*property_part
;
1589 g_return_val_if_fail (map
!= NULL
, NULL
);
1590 g_return_val_if_fail (n_map_elements
> 0, NULL
);
1591 g_return_val_if_fail (label
!= NULL
, NULL
);
1592 g_return_val_if_fail (ical_prop_kind
!= ICAL_NO_PROPERTY
, NULL
);
1593 g_return_val_if_fail (ical_new_func
!= NULL
, NULL
);
1594 g_return_val_if_fail (ical_set_func
!= NULL
, NULL
);
1595 g_return_val_if_fail (ical_get_func
!= NULL
, NULL
);
1597 map_copy
= g_new0 (ECompEditorPropertyPartPickerMap
, n_map_elements
+ 1);
1598 for (ii
= 0; ii
< n_map_elements
; ii
++) {
1599 map_copy
[ii
] = map
[ii
];
1600 map_copy
[ii
].description
= g_strdup (map
[ii
].description
);
1603 property_part
= g_object_new (E_TYPE_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP
,
1608 part_picker_with_map
= E_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (property_part
);
1610 part_picker_with_map
->priv
->ical_prop_kind
= ical_prop_kind
;
1611 part_picker_with_map
->priv
->ical_new_func
= ical_new_func
;
1612 part_picker_with_map
->priv
->ical_set_func
= ical_set_func
;
1613 part_picker_with_map
->priv
->ical_get_func
= ical_get_func
;
1615 return property_part
;
1619 e_comp_editor_property_part_picker_with_map_get_selected (ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
)
1624 g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (part_picker_with_map
), -1);
1625 g_return_val_if_fail (part_picker_with_map
->priv
->map
!= NULL
, -1);
1627 id
= e_comp_editor_property_part_picker_get_selected_id (E_COMP_EDITOR_PROPERTY_PART_PICKER (part_picker_with_map
));
1631 ii
= (gint
) g_ascii_strtoll (id
, NULL
, 10);
1632 if (ii
< 0 || ii
>= part_picker_with_map
->priv
->n_map_elems
)
1635 return part_picker_with_map
->priv
->map
[ii
].value
;
1639 e_comp_editor_property_part_picker_with_map_set_selected (ECompEditorPropertyPartPickerWithMap
*part_picker_with_map
,
1644 g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_PICKER_WITH_MAP (part_picker_with_map
));
1645 g_return_if_fail (part_picker_with_map
->priv
->map
!= NULL
);
1647 for (ii
= 0; ii
< part_picker_with_map
->priv
->n_map_elems
; ii
++) {
1648 if (part_picker_with_map
->priv
->map
[ii
].value
== value
) {
1651 id
= g_strdup_printf ("%d", ii
);
1652 e_comp_editor_property_part_picker_set_selected_id (
1653 E_COMP_EDITOR_PROPERTY_PART_PICKER (part_picker_with_map
), id
);
1660 g_warn_if_reached ();
1663 /* ************************************************************************* */