1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include <gdk/gdkkeysyms.h>
22 #include <glib/gi18n-lib.h>
24 #include <libedataserver/libedataserver.h>
26 #include "e-categories-editor.h"
27 #include "e-categories-selector.h"
28 #include "e-category-completion.h"
29 #include "e-category-editor.h"
30 #include "e-dialog-widgets.h"
32 #define E_CATEGORIES_EDITOR_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE \
34 ((obj), E_TYPE_CATEGORIES_EDITOR, ECategoriesEditorPrivate))
36 struct _ECategoriesEditorPrivate
{
37 ECategoriesSelector
*categories_list
;
38 GtkWidget
*categories_entry
;
39 GtkWidget
*categories_entry_label
;
40 GtkWidget
*new_button
;
41 GtkWidget
*edit_button
;
42 GtkWidget
*delete_button
;
44 guint ignore_category_changes
: 1;
64 static gint signals
[LAST_SIGNAL
] = {0};
66 G_DEFINE_TYPE (ECategoriesEditor
, e_categories_editor
, GTK_TYPE_GRID
)
69 entry_changed_cb (GtkEntry
*entry
,
70 ECategoriesEditor
*editor
)
72 g_signal_emit (editor
, signals
[ENTRY_CHANGED
], 0);
76 categories_editor_selection_changed_cb (ECategoriesEditor
*editor
,
77 GtkTreeSelection
*selection
)
82 n_rows
= gtk_tree_selection_count_selected_rows (selection
);
84 widget
= editor
->priv
->edit_button
;
85 gtk_widget_set_sensitive (widget
, n_rows
== 1);
87 widget
= editor
->priv
->delete_button
;
88 gtk_widget_set_sensitive (widget
, n_rows
>= 1);
92 category_checked_cb (ECategoriesSelector
*selector
,
93 const gchar
*category
,
94 const gboolean checked
,
95 ECategoriesEditor
*editor
)
100 entry
= GTK_ENTRY (editor
->priv
->categories_entry
);
101 categories
= e_categories_selector_get_checked (selector
);
103 gtk_entry_set_text (entry
, categories
);
109 new_button_clicked_cb (GtkButton
*button
,
110 ECategoriesEditor
*editor
)
112 ECategoryEditor
*cat_editor
= e_category_editor_new ();
114 e_category_editor_create_category (cat_editor
);
116 gtk_widget_destroy (GTK_WIDGET (cat_editor
));
120 edit_button_clicked_cb (GtkButton
*button
,
121 ECategoriesEditor
*editor
)
123 ECategoryEditor
*cat_editor
= e_category_editor_new ();
126 category
= e_categories_selector_get_selected (
127 editor
->priv
->categories_list
);
129 e_category_editor_edit_category (cat_editor
, category
);
131 gtk_widget_destroy (GTK_WIDGET (cat_editor
));
136 categories_editor_set_property (GObject
*object
,
141 switch (property_id
) {
142 case PROP_ENTRY_VISIBLE
:
143 e_categories_editor_set_entry_visible (
144 E_CATEGORIES_EDITOR (object
),
145 g_value_get_boolean (value
));
149 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
153 categories_editor_get_property (GObject
*object
,
158 switch (property_id
) {
159 case PROP_ENTRY_VISIBLE
:
160 g_value_set_boolean (
161 value
, e_categories_editor_get_entry_visible (
162 E_CATEGORIES_EDITOR (object
)));
166 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
170 e_categories_editor_class_init (ECategoriesEditorClass
*class)
172 GObjectClass
*object_class
;
174 g_type_class_add_private (class, sizeof (ECategoriesEditorPrivate
));
176 object_class
= G_OBJECT_CLASS (class);
177 object_class
->set_property
= categories_editor_set_property
;
178 object_class
->get_property
= categories_editor_get_property
;
180 g_object_class_install_property (
183 g_param_spec_boolean (
190 signals
[ENTRY_CHANGED
] = g_signal_new (
192 G_TYPE_FROM_CLASS (class),
194 G_STRUCT_OFFSET (ECategoriesEditorClass
, entry_changed
),
196 g_cclosure_marshal_VOID__VOID
,
201 e_categories_editor_init (ECategoriesEditor
*editor
)
203 GtkEntryCompletion
*completion
;
205 GtkWidget
*entry_categories
;
206 GtkWidget
*label_header
;
208 GtkWidget
*scrolledwindow1
;
209 GtkWidget
*categories_list
;
210 GtkWidget
*hbuttonbox1
;
211 GtkWidget
*button_new
;
212 GtkWidget
*button_edit
;
213 GtkWidget
*button_delete
;
215 gtk_widget_set_size_request (GTK_WIDGET (editor
), -1, 400);
217 grid
= GTK_GRID (editor
);
219 gtk_grid_set_row_spacing (grid
, 6);
220 gtk_grid_set_column_spacing (grid
, 6);
222 label_header
= gtk_label_new_with_mnemonic (
223 _("Currently _used categories:"));
224 gtk_widget_set_halign (label_header
, GTK_ALIGN_FILL
);
225 gtk_grid_attach (grid
, label_header
, 0, 0, 1, 1);
226 gtk_label_set_justify (GTK_LABEL (label_header
), GTK_JUSTIFY_CENTER
);
227 gtk_misc_set_alignment (GTK_MISC (label_header
), 0, 0.5);
229 entry_categories
= gtk_entry_new ();
230 gtk_widget_set_hexpand (entry_categories
, TRUE
);
231 gtk_widget_set_halign (entry_categories
, GTK_ALIGN_FILL
);
232 gtk_grid_attach (grid
, entry_categories
, 0, 1, 1, 1);
234 label2
= gtk_label_new_with_mnemonic (_("_Available Categories:"));
235 gtk_widget_set_halign (label2
, GTK_ALIGN_FILL
);
236 gtk_grid_attach (grid
, label2
, 0, 2, 1, 1);
237 gtk_label_set_justify (GTK_LABEL (label2
), GTK_JUSTIFY_CENTER
);
238 gtk_misc_set_alignment (GTK_MISC (label2
), 0, 0.5);
240 scrolledwindow1
= gtk_scrolled_window_new (NULL
, NULL
);
242 G_OBJECT (scrolledwindow1
),
244 "halign", GTK_ALIGN_FILL
,
246 "valign", GTK_ALIGN_FILL
,
248 gtk_grid_attach (grid
, scrolledwindow1
, 0, 3, 1, 1);
249 gtk_scrolled_window_set_policy (
250 GTK_SCROLLED_WINDOW (scrolledwindow1
),
251 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
252 gtk_scrolled_window_set_shadow_type (
253 GTK_SCROLLED_WINDOW (scrolledwindow1
), GTK_SHADOW_IN
);
255 categories_list
= GTK_WIDGET (e_categories_selector_new ());
256 gtk_container_add (GTK_CONTAINER (scrolledwindow1
), categories_list
);
257 gtk_widget_set_size_request (categories_list
, -1, 350);
258 gtk_tree_view_set_headers_visible (
259 GTK_TREE_VIEW (categories_list
), FALSE
);
260 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (categories_list
), TRUE
);
262 G_OBJECT (categories_list
), "category-checked",
263 G_CALLBACK (category_checked_cb
), editor
);
265 hbuttonbox1
= gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL
);
267 G_OBJECT (hbuttonbox1
),
269 "halign", GTK_ALIGN_FILL
,
271 gtk_grid_attach (grid
, hbuttonbox1
, 0, 4, 1, 1);
272 gtk_box_set_spacing (GTK_BOX (hbuttonbox1
), 6);
274 button_new
= e_dialog_button_new_with_icon ("document-new", C_("category", "_New"));
275 gtk_container_add (GTK_CONTAINER (hbuttonbox1
), button_new
);
276 gtk_widget_set_can_default (button_new
, TRUE
);
278 button_edit
= gtk_button_new_with_mnemonic (C_("category", "_Edit"));
279 gtk_container_add (GTK_CONTAINER (hbuttonbox1
), button_edit
);
280 gtk_widget_set_can_default (button_edit
, TRUE
);
282 button_delete
= e_dialog_button_new_with_icon ("edit-delete", C_("category", "_Delete"));
283 gtk_container_add (GTK_CONTAINER (hbuttonbox1
), button_delete
);
284 gtk_widget_set_can_default (button_delete
, TRUE
);
286 gtk_label_set_mnemonic_widget (
287 GTK_LABEL (label_header
), entry_categories
);
288 gtk_label_set_mnemonic_widget (
289 GTK_LABEL (label2
), categories_list
);
291 editor
->priv
= E_CATEGORIES_EDITOR_GET_PRIVATE (editor
);
293 editor
->priv
->categories_list
= E_CATEGORIES_SELECTOR (categories_list
);
294 editor
->priv
->categories_entry
= entry_categories
;
295 editor
->priv
->categories_entry_label
= label_header
;
297 g_signal_connect_swapped (
298 editor
->priv
->categories_list
, "selection-changed",
299 G_CALLBACK (categories_editor_selection_changed_cb
), editor
);
301 completion
= e_category_completion_new ();
302 gtk_entry_set_completion (
303 GTK_ENTRY (editor
->priv
->categories_entry
), completion
);
304 g_object_unref (completion
);
306 editor
->priv
->new_button
= button_new
;
308 editor
->priv
->new_button
, "clicked",
309 G_CALLBACK (new_button_clicked_cb
), editor
);
311 editor
->priv
->edit_button
= button_edit
;
313 editor
->priv
->edit_button
, "clicked",
314 G_CALLBACK (edit_button_clicked_cb
), editor
);
316 editor
->priv
->delete_button
= button_delete
;
317 g_signal_connect_swapped (
318 editor
->priv
->delete_button
, "clicked",
319 G_CALLBACK (e_categories_selector_delete_selection
),
320 editor
->priv
->categories_list
);
323 editor
->priv
->categories_entry
, "changed",
324 G_CALLBACK (entry_changed_cb
), editor
);
326 gtk_widget_show_all (GTK_WIDGET (editor
));
330 * e_categories_editor_new:
332 * Creates a new #ECategoriesEditor widget.
334 * Returns: a new #ECategoriesEditor
339 e_categories_editor_new (void)
341 return g_object_new (E_TYPE_CATEGORIES_EDITOR
, NULL
);
345 * e_categories_editor_get_categories:
346 * @editor: an #ECategoriesEditor
348 * Gets a comma-separated list of the categories currently selected
351 * Returns: a comma-separated list of categories. Free returned
352 * pointer with g_free().
357 e_categories_editor_get_categories (ECategoriesEditor
*editor
)
359 ECategoriesSelector
*categories_list
;
361 g_return_val_if_fail (E_IS_CATEGORIES_EDITOR (editor
), NULL
);
363 categories_list
= editor
->priv
->categories_list
;
365 return e_categories_selector_get_checked (categories_list
);
369 * e_categories_editor_set_categories:
370 * @editor: an #ECategoriesEditor
371 * @categories: comma-separated list of categories
373 * Sets the list of categories selected on the editor.
378 e_categories_editor_set_categories (ECategoriesEditor
*editor
,
379 const gchar
*categories
)
381 ECategoriesSelector
*categories_list
;
383 g_return_if_fail (E_IS_CATEGORIES_EDITOR (editor
));
385 categories_list
= editor
->priv
->categories_list
;
387 e_categories_selector_set_checked (categories_list
, categories
);
388 category_checked_cb (categories_list
, NULL
, FALSE
, editor
);
392 * e_categories_editor_get_entry_visible:
393 * @editor: an #ECategoriesEditor
395 * Return the visibility of the category input entry.
397 * Returns: whether the entry is visible
402 e_categories_editor_get_entry_visible (ECategoriesEditor
*editor
)
404 g_return_val_if_fail (E_IS_CATEGORIES_EDITOR (editor
), TRUE
);
406 return gtk_widget_get_visible (editor
->priv
->categories_entry
);
410 * e_categories_editor_set_entry_visible:
411 * @editor: an #ECategoriesEditor
412 * @entry_visible: whether to make the entry visible
414 * Sets the visibility of the category input entry.
419 e_categories_editor_set_entry_visible (ECategoriesEditor
*editor
,
420 gboolean entry_visible
)
422 g_return_if_fail (E_IS_CATEGORIES_EDITOR (editor
));
424 if ((gtk_widget_get_visible (editor
->priv
->categories_entry
) ? 1 : 0) ==
425 (entry_visible
? 1 : 0))
428 gtk_widget_set_visible (
429 editor
->priv
->categories_entry
, entry_visible
);
430 gtk_widget_set_visible (
431 editor
->priv
->categories_entry_label
, entry_visible
);
432 e_categories_selector_set_items_checkable (
433 editor
->priv
->categories_list
, entry_visible
);
435 g_object_notify (G_OBJECT (editor
), "entry-visible");