1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * Anjuta
4 * Copyright (C) 2002 Dave Camp
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 /**
22 * SECTION:anjuta-preferences-dialog
23 * @short_description: Preferences dialog
24 * @see_also: #AnjutaPreferences
25 * @stability: Unstable
26 * @include: libanjuta/anjuta-preferences-dialog.h
27 *
28 * Plugins can added preferences page with anjuta_preferences_dialog_add_page().
29 * However, read #AnjutaPreferences for adding proper preferences pages.
30 */
31
32 #include <config.h>
33
34 #include <string.h>
35 #include <glib.h>
36 #include <glib/gi18n.h>
37 #include <gtk/gtk.h>
38 #include <gdk-pixbuf/gdk-pixbuf.h>
39
40
41 #include <libanjuta/anjuta-cell-renderer-captioned-image.h>
42 #include <libanjuta/anjuta-preferences-dialog.h>
43
44 #define PREFERENCES_DEFAULT_WIDTH 800
45 #define PREFERENCES_DEFAULT_HEIGHT 400
46
47 struct _AnjutaPreferencesDialogPrivate {
48 GtkWidget *treeview;
49 GtkListStore *store;
50
51 GtkWidget *notebook;
52 };
53
54 enum {
55 COL_NAME,
56 COL_TITLE,
57 COL_PIXBUF,
58 COL_WIDGET,
59 LAST_COL
60 };
61
62 static void anjuta_preferences_dialog_class_init (AnjutaPreferencesDialogClass *class);
63 static void anjuta_preferences_dialog_init (AnjutaPreferencesDialog *dlg);
64
G_DEFINE_TYPE(AnjutaPreferencesDialog,anjuta_preferences_dialog,GTK_TYPE_DIALOG)65 G_DEFINE_TYPE (AnjutaPreferencesDialog, anjuta_preferences_dialog,
66 GTK_TYPE_DIALOG)
67
68 static void
69 anjuta_preferences_dialog_finalize (GObject *obj)
70 {
71 AnjutaPreferencesDialog *dlg = ANJUTA_PREFERENCES_DIALOG (obj);
72
73 if (dlg->priv->store) {
74 g_object_unref (dlg->priv->store);
75 dlg->priv->store = NULL;
76 }
77
78 g_free (dlg->priv);
79
80 ((GObjectClass *) anjuta_preferences_dialog_parent_class)->finalize (obj);
81 }
82
83 static void
anjuta_preferences_dialog_class_init(AnjutaPreferencesDialogClass * class)84 anjuta_preferences_dialog_class_init (AnjutaPreferencesDialogClass *class)
85 {
86 GObjectClass *object_class = G_OBJECT_CLASS (class);
87
88 object_class->finalize = anjuta_preferences_dialog_finalize;
89 }
90
91 static void
add_category_columns(AnjutaPreferencesDialog * dlg)92 add_category_columns (AnjutaPreferencesDialog *dlg)
93 {
94 GtkCellRenderer *renderer;
95 GtkTreeViewColumn *column;
96
97 renderer = anjuta_cell_renderer_captioned_image_new ();
98 g_object_ref_sink (renderer);
99 column = gtk_tree_view_column_new_with_attributes (_("Category"),
100 renderer,
101 "text",
102 COL_TITLE,
103 "pixbuf",
104 COL_PIXBUF,
105 NULL);
106
107 gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->treeview),
108 column);
109 }
110
111 static void
selection_changed_cb(GtkTreeSelection * selection,AnjutaPreferencesDialog * dlg)112 selection_changed_cb (GtkTreeSelection *selection,
113 AnjutaPreferencesDialog *dlg)
114 {
115 GtkTreeIter iter;
116
117 if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
118 GtkWidget *widget;
119
120 gtk_tree_model_get (GTK_TREE_MODEL (dlg->priv->store), &iter,
121 COL_WIDGET, &widget, -1);
122
123 gtk_notebook_set_current_page
124 (GTK_NOTEBOOK (dlg->priv->notebook),
125 gtk_notebook_page_num (GTK_NOTEBOOK (dlg->priv->notebook),
126 widget));
127
128 }
129 }
130
131 static gint
compare_pref_page_func(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer user_data)132 compare_pref_page_func (GtkTreeModel *model,
133 GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
134 {
135 gint val;
136 gchar *name1, *name2;
137
138 gtk_tree_model_get (model, a, COL_TITLE, &name1, -1);
139 gtk_tree_model_get (model, b, COL_TITLE, &name2, -1);
140
141 /* FIXME: Make the general page first */
142 if (strcmp (name1, _("General")) == 0)
143 return -1;
144
145 if (strcmp (name2, _("General")) == 0)
146 return 1;
147
148 val = strcmp (name1, name2);
149 g_free (name1);
150 g_free (name2);
151
152 return val;
153 }
154
155 static void
anjuta_preferences_dialog_init(AnjutaPreferencesDialog * dlg)156 anjuta_preferences_dialog_init (AnjutaPreferencesDialog *dlg)
157 {
158 GtkWidget *hbox;
159 GtkWidget *scrolled_window;
160 GtkTreeSelection *selection;
161 GtkTreeSortable *sortable;
162
163 dlg->priv = g_new0 (AnjutaPreferencesDialogPrivate, 1);
164
165 gtk_container_set_border_width (GTK_CONTAINER(dlg), 6);
166
167 hbox = g_object_new(GTK_TYPE_BOX,
168 "border-width", 6,
169 "spacing", 6,
170 "visible", TRUE,
171 NULL);
172
173 dlg->priv->treeview = gtk_tree_view_new ();
174 gtk_widget_show (dlg->priv->treeview);
175 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (dlg->priv->treeview),
176 FALSE);
177 dlg->priv->store = gtk_list_store_new (LAST_COL,
178 G_TYPE_STRING,
179 G_TYPE_STRING,
180 GDK_TYPE_PIXBUF,
181 GTK_TYPE_WIDGET,
182 G_TYPE_INT);
183 sortable = GTK_TREE_SORTABLE (dlg->priv->store);
184 gtk_tree_sortable_set_sort_column_id (sortable, COL_TITLE,
185 GTK_SORT_ASCENDING);
186 gtk_tree_sortable_set_sort_func (sortable, COL_TITLE,
187 compare_pref_page_func,
188 NULL, NULL);
189
190 gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->treeview),
191 GTK_TREE_MODEL (dlg->priv->store));
192
193 add_category_columns (dlg);
194
195 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
196 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
197 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
198 gtk_scrolled_window_set_shadow_type
199 (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
200
201 gtk_widget_show (scrolled_window);
202 gtk_container_add (GTK_CONTAINER (scrolled_window),
203 dlg->priv->treeview);
204 gtk_box_pack_start (GTK_BOX (hbox), scrolled_window,
205 FALSE, FALSE, 0);
206
207 dlg->priv->notebook = gtk_notebook_new ();
208 gtk_widget_show (dlg->priv->notebook);
209 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (dlg->priv->notebook), FALSE);
210 gtk_notebook_set_show_border (GTK_NOTEBOOK (dlg->priv->notebook),
211 FALSE);
212
213 gtk_box_pack_start (GTK_BOX (hbox), dlg->priv->notebook,
214 TRUE, TRUE, 0);
215
216
217 selection = gtk_tree_view_get_selection
218 (GTK_TREE_VIEW (dlg->priv->treeview));
219
220 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
221
222 g_signal_connect (selection, "changed",
223 G_CALLBACK (selection_changed_cb), dlg);
224
225 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), hbox,
226 TRUE, TRUE, 0);
227
228 gtk_dialog_add_button (GTK_DIALOG (dlg), GTK_STOCK_CLOSE, -7);
229
230 gtk_widget_show (hbox);
231 }
232
233 /**
234 * anjuta_preferences_dialog_new:
235 *
236 * Creates a new #AnjutaPreferencesDialog object.
237 *
238 * Return value: a new #AnjutaPreferencesDialog object.
239 */
240 GtkWidget *
anjuta_preferences_dialog_new(void)241 anjuta_preferences_dialog_new (void)
242 {
243 return g_object_new (ANJUTA_TYPE_PREFERENCES_DIALOG,
244 "title", _("Anjuta Preferences"),
245 "default-width", PREFERENCES_DEFAULT_WIDTH,
246 "default-height", PREFERENCES_DEFAULT_HEIGHT,
247 NULL);
248 }
249
250 /**
251 * anjuta_preferences_dialog_add_page:
252 * @dlg: A #AnjutaPreferencesDialog object.
253 * @name: Name of the preferences page.
254 * @title: Title of the page
255 * @icon: Icon file name.
256 * @page: page widget.
257 *
258 * Adds a widget page in preferences dialog. Name and icon appears
259 * on the left icon list where differnt pages are selected.
260 */
261 void
anjuta_preferences_dialog_add_page(AnjutaPreferencesDialog * dlg,const gchar * name,const gchar * title,GdkPixbuf * icon,GtkWidget * page)262 anjuta_preferences_dialog_add_page (AnjutaPreferencesDialog *dlg,
263 const gchar *name,
264 const gchar *title,
265 GdkPixbuf *icon,
266 GtkWidget *page)
267 {
268 GtkTreeIter iter;
269 GtkTreeSelection* selection =
270 gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->treeview));
271 GtkTreeIter first;
272 gtk_widget_show (page);
273
274 gtk_notebook_append_page (GTK_NOTEBOOK (dlg->priv->notebook), page, NULL);
275
276 gtk_list_store_append (dlg->priv->store, &iter);
277
278 gtk_list_store_set (dlg->priv->store, &iter,
279 COL_NAME, name,
280 COL_TITLE, title,
281 COL_PIXBUF, icon,
282 COL_WIDGET, page,
283 -1);
284
285 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dlg->priv->store),
286 &first);
287 gtk_tree_selection_select_iter (selection, &first);
288 }
289
290 /**
291 * anjuta_preferences_dialog_remove_page:
292 * @dlg: A #AnjutaPreferencesDialog object.g_signal_handler
293 * @title: Name of the preferences page.
294 *
295 * Removes a preferences page.
296 */
297 void
anjuta_preferences_dialog_remove_page(AnjutaPreferencesDialog * dlg,const char * title)298 anjuta_preferences_dialog_remove_page (AnjutaPreferencesDialog *dlg,
299 const char *title)
300 {
301 GtkTreeModel* model = GTK_TREE_MODEL(dlg->priv->store);
302 GtkTreeIter iter;
303 GtkWidget *page;
304
305 if (gtk_tree_model_get_iter_first(model, &iter))
306 {
307 do
308 {
309 gchar* page_title;
310 GObject* page_widget;
311
312 gtk_tree_model_get(model, &iter,
313 COL_TITLE, &page_title,
314 COL_WIDGET, &page_widget,
315 -1);
316
317 if (g_str_equal(page_title, title))
318 {
319 int page_num;
320
321 page_num = gtk_notebook_page_num (
322 GTK_NOTEBOOK(dlg->priv->notebook),
323 GTK_WIDGET (page_widget));
324
325 page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (dlg->priv->notebook),
326 page_num);
327
328 gtk_notebook_remove_page(
329 GTK_NOTEBOOK(dlg->priv->notebook), page_num);
330
331 gtk_widget_destroy (page);
332
333 gtk_list_store_remove(dlg->priv->store, &iter);
334 return;
335 }
336 }
337 while (gtk_tree_model_iter_next(model, &iter));
338 }
339 g_warning("Could not find page to remove");
340 }
341