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 library is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU Lesser General Public
7 * License as published by the Free Software Foundation.
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 * General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
23 #include <gdk/gdkkeysyms.h>
24 #include <glib/gi18n-lib.h>
26 #include <libedataserver/libedataserver.h>
27 #include <libedataserver/libedataserver-private.h>
29 #include "e-categories-editor.h"
30 #include "e-categories-selector.h"
31 #include "e-category-completion.h"
32 #include "e-category-editor.h"
34 #define E_CATEGORIES_EDITOR_GET_PRIVATE(obj) \
35 (G_TYPE_INSTANCE_GET_PRIVATE \
36 ((obj), E_TYPE_CATEGORIES_EDITOR, ECategoriesEditorPrivate))
38 struct _ECategoriesEditorPrivate {
39 ECategoriesSelector *categories_list;
40 GtkWidget *categories_entry;
41 GtkWidget *categories_entry_label;
42 GtkWidget *new_button;
43 GtkWidget *edit_button;
44 GtkWidget *delete_button;
46 guint ignore_category_changes : 1;
66 static gint signals[LAST_SIGNAL] = {0};
68 G_DEFINE_TYPE (ECategoriesEditor, e_categories_editor, GTK_TYPE_GRID)
71 entry_changed_cb (GtkEntry *entry,
72 ECategoriesEditor *editor)
74 g_signal_emit (editor, signals[ENTRY_CHANGED], 0);
78 categories_editor_selection_changed_cb (ECategoriesEditor *editor,
79 GtkTreeSelection *selection)
84 n_rows = gtk_tree_selection_count_selected_rows (selection);
86 widget = editor->priv->edit_button;
87 gtk_widget_set_sensitive (widget, n_rows == 1);
89 widget = editor->priv->delete_button;
90 gtk_widget_set_sensitive (widget, n_rows >= 1);
94 category_checked_cb (ECategoriesSelector *selector,
95 const gchar *category,
96 const gboolean checked,
97 ECategoriesEditor *editor)
102 entry = GTK_ENTRY (editor->priv->categories_entry);
103 categories = e_categories_selector_get_checked (selector);
105 gtk_entry_set_text (entry, categories);
111 new_button_clicked_cb (GtkButton *button,
112 ECategoriesEditor *editor)
114 ECategoryEditor *cat_editor = e_category_editor_new ();
116 e_category_editor_create_category (cat_editor);
118 gtk_widget_destroy (GTK_WIDGET (cat_editor));
122 edit_button_clicked_cb (GtkButton *button,
123 ECategoriesEditor *editor)
125 ECategoryEditor *cat_editor = e_category_editor_new ();
128 category = e_categories_selector_get_selected (
129 editor->priv->categories_list);
131 e_category_editor_edit_category (cat_editor, category);
133 gtk_widget_destroy (GTK_WIDGET (cat_editor));
138 categories_editor_set_property (GObject *object,
143 switch (property_id) {
144 case PROP_ENTRY_VISIBLE:
145 e_categories_editor_set_entry_visible (
146 E_CATEGORIES_EDITOR (object),
147 g_value_get_boolean (value));
151 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
155 categories_editor_get_property (GObject *object,
160 switch (property_id) {
161 case PROP_ENTRY_VISIBLE:
162 g_value_set_boolean (
163 value, e_categories_editor_get_entry_visible (
164 E_CATEGORIES_EDITOR (object)));
168 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
172 e_categories_editor_class_init (ECategoriesEditorClass *class)
174 GObjectClass *object_class;
176 g_type_class_add_private (class, sizeof (ECategoriesEditorPrivate));
178 object_class = G_OBJECT_CLASS (class);
179 object_class->set_property = categories_editor_set_property;
180 object_class->get_property = categories_editor_get_property;
182 g_object_class_install_property (
185 g_param_spec_boolean (
192 signals[ENTRY_CHANGED] = g_signal_new (
194 G_TYPE_FROM_CLASS (class),
196 G_STRUCT_OFFSET (ECategoriesEditorClass, entry_changed),
198 g_cclosure_marshal_VOID__VOID,
203 e_categories_editor_init (ECategoriesEditor *editor)
205 GtkEntryCompletion *completion;
207 GtkWidget *entry_categories;
208 GtkWidget *label_header;
210 GtkWidget *scrolledwindow1;
211 GtkWidget *categories_list;
212 GtkWidget *hbuttonbox1;
213 GtkWidget *button_new;
214 GtkWidget *button_edit;
215 GtkWidget *button_delete;
217 gtk_widget_set_size_request (GTK_WIDGET (editor), -1, 400);
219 grid = GTK_GRID (editor);
221 gtk_grid_set_row_spacing (grid, 6);
222 gtk_grid_set_column_spacing (grid, 6);
224 label_header = gtk_label_new_with_mnemonic (
225 _("Currently _used categories:"));
226 gtk_widget_set_halign (label_header, GTK_ALIGN_FILL);
227 gtk_grid_attach (grid, label_header, 0, 0, 1, 1);
228 gtk_label_set_justify (GTK_LABEL (label_header), GTK_JUSTIFY_CENTER);
229 gtk_misc_set_alignment (GTK_MISC (label_header), 0, 0.5);
231 entry_categories = gtk_entry_new ();
232 gtk_widget_set_hexpand (entry_categories, TRUE);
233 gtk_widget_set_halign (entry_categories, GTK_ALIGN_FILL);
234 gtk_grid_attach (grid, entry_categories, 0, 1, 1, 1);
236 label2 = gtk_label_new_with_mnemonic (_("_Available Categories:"));
237 gtk_widget_set_halign (label2, GTK_ALIGN_FILL);
238 gtk_grid_attach (grid, label2, 0, 2, 1, 1);
239 gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER);
240 gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5);
242 scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
243 g_object_set (G_OBJECT (scrolledwindow1),
245 "halign", GTK_ALIGN_FILL,
247 "valign", GTK_ALIGN_FILL,
249 gtk_grid_attach (grid, scrolledwindow1, 0, 3, 1, 1);
250 gtk_scrolled_window_set_policy (
251 GTK_SCROLLED_WINDOW (scrolledwindow1),
252 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
253 gtk_scrolled_window_set_shadow_type (
254 GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_IN);
256 categories_list = GTK_WIDGET (e_categories_selector_new ());
257 gtk_container_add (GTK_CONTAINER (scrolledwindow1), categories_list);
258 gtk_widget_set_size_request (categories_list, -1, 350);
259 gtk_tree_view_set_headers_visible (
260 GTK_TREE_VIEW (categories_list), FALSE);
261 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (categories_list), TRUE);
263 G_OBJECT (categories_list), "category-checked",
264 G_CALLBACK (category_checked_cb), editor);
266 hbuttonbox1 = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
267 g_object_set (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 = gtk_button_new_from_stock (GTK_STOCK_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_from_stock (GTK_STOCK_EDIT);
279 gtk_container_add (GTK_CONTAINER (hbuttonbox1), button_edit);
280 gtk_widget_set_can_default (button_edit, TRUE);
282 button_delete = gtk_button_new_from_stock (GTK_STOCK_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");