1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta-environment-editor.c
4 * Copyright (C) 2011 Sebastien Granjoux
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 #include "anjuta-environment-editor.h"
22 #include <glib/gi18n.h>
23
24 enum
25 {
26 CHANGED,
27 LAST_SIGNAL
28 };
29
30 enum {
31 ENV_NAME_COLUMN = 0,
32 ENV_VALUE_COLUMN,
33 ENV_DEFAULT_VALUE_COLUMN,
34 ENV_COLOR_COLUMN,
35 ENV_N_COLUMNS
36 };
37
38 #define ENV_USER_COLOR "black"
39 #define ENV_DEFAULT_COLOR "gray"
40
41
42 struct _AnjutaEnvironmentEditor
43 {
44 GtkBin parent;
45
46 gchar **variables;
47
48 GtkTreeModel *model;
49
50 GtkTreeView *treeview;
51 GtkWidget *edit_button;
52 GtkWidget *remove_button;
53 };
54
55
56 G_DEFINE_TYPE (AnjutaEnvironmentEditor, anjuta_environment_editor, GTK_TYPE_BIN);
57
58
59 /* Helpers functions
60 *---------------------------------------------------------------------------*/
61
62 #include <string.h>
63
64 static gboolean
anjuta_gtk_tree_model_find_string(GtkTreeModel * model,GtkTreeIter * parent,GtkTreeIter * iter,guint col,const gchar * value)65 anjuta_gtk_tree_model_find_string (GtkTreeModel *model, GtkTreeIter *parent,
66 GtkTreeIter *iter, guint col, const gchar *value)
67
68 {
69 gboolean valid;
70 gboolean found = FALSE;
71
72 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), FALSE);
73 g_return_val_if_fail (iter != NULL, FALSE);
74 g_return_val_if_fail (value != NULL, FALSE);
75
76 if (!parent)
77 {
78 valid = gtk_tree_model_get_iter_first (model, iter);
79 }
80 else
81 {
82 valid = gtk_tree_model_iter_children (model, iter, parent);
83 }
84
85 while (valid)
86 {
87 gchar *mvalue;
88
89 gtk_tree_model_get (model, iter, col, &mvalue, -1);
90 found = (mvalue != NULL) && (strcmp (mvalue, value) == 0);
91 g_free (mvalue);
92 if (found) break;
93
94 if (gtk_tree_model_iter_has_child (model, iter))
95 {
96 GtkTreeIter citer;
97
98 found = anjuta_gtk_tree_model_find_string (model, iter,
99 &citer, col, value);
100 if (found)
101 {
102 *iter = citer;
103 break;
104 }
105 }
106 valid = gtk_tree_model_iter_next (model, iter);
107 }
108
109 return found;
110 }
111
112 /* Private functions
113 *---------------------------------------------------------------------------*/
114
115 static void
load_environment_variables(AnjutaEnvironmentEditor * editor,GtkListStore * store)116 load_environment_variables (AnjutaEnvironmentEditor *editor, GtkListStore *store)
117 {
118 GtkTreeIter iter;
119 gchar **var;
120 gchar **list;
121
122 /* Load current environment variables */
123 list = g_listenv();
124 var = list;
125 if (var)
126 {
127 for (; *var != NULL; var++)
128 {
129 const gchar *value = g_getenv (*var);
130 gtk_list_store_prepend (store, &iter);
131 gtk_list_store_set (store, &iter,
132 ENV_NAME_COLUMN, *var,
133 ENV_VALUE_COLUMN, value,
134 ENV_DEFAULT_VALUE_COLUMN, value,
135 ENV_COLOR_COLUMN, ENV_DEFAULT_COLOR,
136 -1);
137 }
138 }
139 g_strfreev (list);
140
141 /* Load user environment variables */
142 var = editor->variables;
143 if (var)
144 {
145 for (; *var != NULL; var++)
146 {
147 gchar ** value;
148
149 value = g_strsplit (*var, "=", 2);
150 if (value)
151 {
152 if (anjuta_gtk_tree_model_find_string (GTK_TREE_MODEL (store),
153 NULL, &iter, ENV_NAME_COLUMN,
154 value[0]))
155 {
156 gtk_list_store_set (store, &iter,
157 ENV_VALUE_COLUMN, value[1],
158 ENV_COLOR_COLUMN, ENV_USER_COLOR,
159 -1);
160 }
161 else
162 {
163 gtk_list_store_prepend (store, &iter);
164 gtk_list_store_set (store, &iter,
165 ENV_NAME_COLUMN, value[0],
166 ENV_VALUE_COLUMN, value[1],
167 ENV_DEFAULT_VALUE_COLUMN, NULL,
168 ENV_COLOR_COLUMN, ENV_USER_COLOR,
169 -1);
170 }
171 g_strfreev (value);
172 }
173 }
174 }
175 }
176
177
178 /* Implement GtkWidget functions
179 *---------------------------------------------------------------------------*/
180
181 static void
anjuta_environment_editor_size_allocate(GtkWidget * widget,GtkAllocation * allocation)182 anjuta_environment_editor_size_allocate (GtkWidget *widget,
183 GtkAllocation *allocation)
184 {
185 GtkBin *bin;
186 GtkWidget *child;
187
188 bin = GTK_BIN (widget);
189 child = gtk_bin_get_child (bin);
190 if ((child != NULL) && gtk_widget_get_visible (child))
191 {
192 gtk_widget_set_allocation (widget, allocation);
193 gtk_widget_size_allocate (child, allocation);
194 }
195 }
196
197 static void
anjuta_environment_editor_get_preferred_width(GtkWidget * widget,gint * minimum_size,gint * natural_size)198 anjuta_environment_editor_get_preferred_width (GtkWidget *widget,
199 gint *minimum_size,
200 gint *natural_size)
201 {
202 GtkBin *bin;
203 GtkWidget *child;
204
205 bin = GTK_BIN (widget);
206 child = gtk_bin_get_child (bin);
207 gtk_widget_get_preferred_width (child, minimum_size, natural_size);
208 }
209
210 static void
anjuta_environment_editor_get_preferred_height(GtkWidget * widget,gint * minimum_size,gint * natural_size)211 anjuta_environment_editor_get_preferred_height (GtkWidget *widget,
212 gint *minimum_size,
213 gint *natural_size)
214 {
215 GtkBin *bin;
216 GtkWidget *child;
217
218 bin = GTK_BIN (widget);
219 child = gtk_bin_get_child (bin);
220 gtk_widget_get_preferred_height (child, minimum_size, natural_size);
221 }
222
223 static void
on_environment_selection_changed(GtkTreeSelection * selection,AnjutaEnvironmentEditor * editor)224 on_environment_selection_changed (GtkTreeSelection *selection, AnjutaEnvironmentEditor *editor)
225 {
226 GtkTreeIter iter;
227 GtkTreeModel *model;
228 gboolean selected;
229
230 if (selection == NULL)
231 {
232 selection = gtk_tree_view_get_selection (editor->treeview);
233 }
234
235 selected = gtk_tree_selection_get_selected (selection, &model, &iter);
236 if (selected)
237 {
238 gchar *color;
239 gchar *value;
240 gboolean restore;
241
242 gtk_tree_model_get (model, &iter,
243 ENV_DEFAULT_VALUE_COLUMN, &value,
244 ENV_COLOR_COLUMN, &color,
245 -1);
246
247 restore = (strcmp (color, ENV_USER_COLOR) == 0) && (value != NULL);
248 gtk_button_set_label (GTK_BUTTON (editor->remove_button), restore ? GTK_STOCK_REVERT_TO_SAVED : GTK_STOCK_DELETE);
249 g_free (color);
250 g_free (value);
251 }
252 gtk_widget_set_sensitive (editor->remove_button, selected);
253 gtk_widget_set_sensitive (editor->edit_button, selected);
254 }
255
256 static void
on_environment_add_button(GtkButton * button,GtkTreeView * view)257 on_environment_add_button (GtkButton *button, GtkTreeView *view)
258 {
259 GtkTreeIter iter;
260 GtkListStore *model;
261 GtkTreeViewColumn *column;
262 GtkTreePath *path;
263 GtkTreeSelection* sel;
264
265 model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
266
267 sel = gtk_tree_view_get_selection (view);
268 if (gtk_tree_selection_get_selected (sel, NULL, &iter))
269 {
270 GtkTreeIter niter;
271 gtk_list_store_insert_after (model, &niter, &iter);
272 iter = niter;
273 }
274 else
275 {
276 gtk_list_store_prepend (model, &iter);
277 }
278
279 gtk_list_store_set (model, &iter, ENV_NAME_COLUMN, "",
280 ENV_VALUE_COLUMN, "",
281 ENV_DEFAULT_VALUE_COLUMN, NULL,
282 ENV_COLOR_COLUMN, ENV_USER_COLOR,
283 -1);
284
285 path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
286 column = gtk_tree_view_get_column (view, ENV_NAME_COLUMN);
287 gtk_tree_view_scroll_to_cell (view, path, column, FALSE, 0, 0);
288 gtk_tree_view_set_cursor (view, path, column ,TRUE);
289 gtk_tree_path_free (path);
290 }
291
292 static void
on_environment_edit_button(GtkButton * button,GtkTreeView * view)293 on_environment_edit_button (GtkButton *button, GtkTreeView *view)
294 {
295 GtkTreeIter iter;
296 GtkTreeSelection* sel;
297
298 sel = gtk_tree_view_get_selection (view);
299 if (gtk_tree_selection_get_selected (sel, NULL, &iter))
300 {
301 GtkListStore *model;
302 GtkTreePath *path;
303 GtkTreeViewColumn *column;
304
305 model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
306 path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
307 column = gtk_tree_view_get_column (view, ENV_VALUE_COLUMN);
308 gtk_tree_view_scroll_to_cell (view, path, column, FALSE, 0, 0);
309 gtk_tree_view_set_cursor (view, path, column ,TRUE);
310 gtk_tree_path_free (path);
311 }
312 }
313
314 static void
on_environment_remove_button(GtkButton * button,AnjutaEnvironmentEditor * editor)315 on_environment_remove_button (GtkButton *button, AnjutaEnvironmentEditor *editor)
316 {
317 GtkTreeIter iter;
318 GtkTreeSelection* sel;
319 GtkTreeView *view = editor->treeview;
320
321 sel = gtk_tree_view_get_selection (view);
322 if (gtk_tree_selection_get_selected (sel, NULL, &iter))
323 {
324 GtkListStore *model;
325 GtkTreeViewColumn *column;
326 GtkTreePath *path;
327 gchar *color;
328
329 model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
330
331 /* Display variable */
332 path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
333 column = gtk_tree_view_get_column (view, ENV_NAME_COLUMN);
334 gtk_tree_view_scroll_to_cell (view, path, column, FALSE, 0, 0);
335 gtk_tree_path_free (path);
336
337 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
338 ENV_COLOR_COLUMN, &color,
339 -1);
340 if (strcmp(color, ENV_USER_COLOR) == 0)
341 {
342 /* Remove an user variable */
343 gchar *value;
344
345 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
346 ENV_DEFAULT_VALUE_COLUMN, &value,
347 -1);
348
349 if (value != NULL)
350 {
351 /* Restore default environment variable */
352 gtk_list_store_set (model, &iter, ENV_VALUE_COLUMN, value,
353 ENV_COLOR_COLUMN, ENV_DEFAULT_COLOR,
354 -1);
355 }
356 else
357 {
358 gtk_list_store_remove (model, &iter);
359 }
360 g_free (value);
361 }
362 else
363 {
364 /* Replace value with an empty one */
365 gtk_list_store_set (model, &iter, ENV_VALUE_COLUMN, NULL,
366 ENV_COLOR_COLUMN, ENV_USER_COLOR,
367 -1);
368 }
369 on_environment_selection_changed (sel, editor);
370 }
371 }
372
373 static gboolean
move_to_environment_value(gpointer data)374 move_to_environment_value (gpointer data)
375 {
376 GtkTreeView *view = GTK_TREE_VIEW (data);
377 GtkTreeSelection* sel;
378 GtkTreeModel *model;
379 GtkTreeIter iter;
380 GtkTreeViewColumn *column;
381
382 sel = gtk_tree_view_get_selection (view);
383 if (gtk_tree_selection_get_selected (sel, &model, &iter))
384 {
385 GtkTreePath *path;
386
387 path = gtk_tree_model_get_path (model, &iter);
388 column = gtk_tree_view_get_column (view, ENV_VALUE_COLUMN);
389 gtk_tree_view_set_cursor (view, path, column, TRUE);
390 gtk_tree_path_free (path);
391 }
392
393 return FALSE;
394 }
395
396 static void
on_environment_variable_edited(GtkCellRendererText * cell,gchar * path,gchar * text,AnjutaEnvironmentEditor * editor)397 on_environment_variable_edited (GtkCellRendererText *cell,
398 gchar *path,
399 gchar *text,
400 AnjutaEnvironmentEditor *editor)
401 {
402 GtkTreeIter iter;
403 GtkTreeIter niter;
404 GtkListStore *model;
405 gboolean valid;
406 GtkTreeView *view = editor->treeview;
407
408 text = g_strstrip (text);
409
410 model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
411
412 valid = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path);
413 if (valid)
414 {
415 gchar *name;
416 gchar *value;
417 gchar *def_value;
418
419 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
420 ENV_NAME_COLUMN, &name,
421 ENV_VALUE_COLUMN, &value,
422 ENV_DEFAULT_VALUE_COLUMN, &def_value,
423 -1);
424
425 if (strcmp(name, text) != 0)
426 {
427
428 if (def_value != NULL)
429 {
430 /* Remove current variable */
431 gtk_list_store_set (model, &iter, ENV_VALUE_COLUMN, NULL,
432 ENV_COLOR_COLUMN, ENV_USER_COLOR,
433 -1);
434 }
435
436 /* Search variable with new name */
437 if (anjuta_gtk_tree_model_find_string (GTK_TREE_MODEL (model),
438 NULL, &niter, ENV_NAME_COLUMN,
439 text))
440 {
441 if (def_value == NULL)
442 {
443 gtk_list_store_remove (model, &iter);
444 }
445 gtk_list_store_set (model, &niter,
446 ENV_VALUE_COLUMN, value,
447 ENV_COLOR_COLUMN, ENV_USER_COLOR,
448 -1);
449 }
450 else
451 {
452 if (def_value != NULL)
453 {
454 gtk_list_store_insert_after (model, &niter, &iter);
455 gtk_list_store_set (model, &niter, ENV_NAME_COLUMN, text,
456 ENV_VALUE_COLUMN, value,
457 ENV_DEFAULT_VALUE_COLUMN, NULL,
458 ENV_COLOR_COLUMN, ENV_USER_COLOR,
459 -1);
460 }
461 else
462 {
463 gtk_list_store_set (model, &iter, ENV_NAME_COLUMN, text,
464 -1);
465 }
466 }
467 g_idle_add (move_to_environment_value, view);
468 }
469 g_free (name);
470 g_free (def_value);
471 g_free (value);
472 }
473 }
474
475 static void
on_environment_value_edited(GtkCellRendererText * cell,gchar * path,gchar * text,AnjutaEnvironmentEditor * editor)476 on_environment_value_edited (GtkCellRendererText *cell,
477 gchar *path,
478 gchar *text,
479 AnjutaEnvironmentEditor *editor)
480 {
481 GtkTreeIter iter;
482 GtkListStore *model;
483 GtkTreeView *view = editor->treeview;
484
485 text = g_strstrip (text);
486
487 model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
488 if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
489 {
490 gtk_list_store_set (model, &iter, ENV_VALUE_COLUMN, text,
491 ENV_COLOR_COLUMN, ENV_USER_COLOR,
492 -1);
493 on_environment_selection_changed (NULL, editor);
494 }
495 }
496
497 /* Implement GtkWidget functions
498 *---------------------------------------------------------------------------*/
499
500 static void
anjuta_environment_editor_dispose(GObject * object)501 anjuta_environment_editor_dispose (GObject *object)
502 {
503 AnjutaEnvironmentEditor* editor = ANJUTA_ENVIRONMENT_EDITOR (object);
504
505 if (editor->model != NULL) g_object_unref (editor->model);
506
507 G_OBJECT_CLASS (anjuta_environment_editor_parent_class)->dispose (object);
508 }
509
510 static void
anjuta_environment_editor_finalize(GObject * object)511 anjuta_environment_editor_finalize (GObject *object)
512 {
513 AnjutaEnvironmentEditor* editor = ANJUTA_ENVIRONMENT_EDITOR (object);
514
515 g_strfreev (editor->variables);
516 editor->variables = NULL;
517
518 G_OBJECT_CLASS (anjuta_environment_editor_parent_class)->finalize (object);
519 }
520
521 static void
anjuta_environment_editor_init(AnjutaEnvironmentEditor * editor)522 anjuta_environment_editor_init (AnjutaEnvironmentEditor *editor)
523 {
524 GtkWidget *expander;
525 GtkWidget *hbox;
526 GtkWidget *scrolled;
527 GtkWidget *treeview;
528 GtkWidget *vbutton;
529 GtkWidget *add_button;
530 GtkWidget *edit_button;
531 GtkWidget *remove_button;
532 GtkTreeModel *model;
533 GtkTreeViewColumn* column;
534 GtkCellRenderer* renderer;
535 GtkTreeSelection *selection;
536
537 editor->variables = NULL;
538
539 gtk_widget_set_has_window (GTK_WIDGET (editor), FALSE);
540 gtk_widget_set_redraw_on_allocate (GTK_WIDGET (editor), FALSE);
541
542 /* Create all needed widgets */
543 expander = gtk_expander_new (_("Environment Variables:"));
544 gtk_container_add (GTK_CONTAINER (editor), expander);
545 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
546 gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
547 gtk_container_add (GTK_CONTAINER (expander), hbox);
548 scrolled = gtk_scrolled_window_new (NULL, NULL);
549 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_OUT);
550 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
551
552 gtk_box_pack_start (GTK_BOX (hbox), scrolled, TRUE, TRUE, 0);
553 treeview = gtk_tree_view_new ();
554 gtk_container_add (GTK_CONTAINER (scrolled), treeview);
555 editor->treeview = GTK_TREE_VIEW (treeview);
556
557 vbutton = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
558 gtk_button_box_set_layout (GTK_BUTTON_BOX (vbutton), GTK_BUTTONBOX_START);
559 gtk_box_set_spacing (GTK_BOX (vbutton), 6);
560 gtk_box_pack_start (GTK_BOX (hbox), vbutton, FALSE, FALSE, 0);
561 add_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
562 gtk_container_add (GTK_CONTAINER (vbutton), add_button);
563 edit_button = gtk_button_new_from_stock (GTK_STOCK_EDIT);
564 gtk_container_add (GTK_CONTAINER (vbutton), edit_button);
565 editor->edit_button = edit_button;
566 remove_button = gtk_button_new_from_stock (GTK_STOCK_DELETE);
567 gtk_container_add (GTK_CONTAINER (vbutton), remove_button);
568 editor->remove_button = remove_button;
569
570 gtk_widget_show_all (GTK_WIDGET (editor));
571
572 /* Fill environment variable list */
573 model = GTK_TREE_MODEL (gtk_list_store_new (ENV_N_COLUMNS,
574 G_TYPE_STRING,
575 G_TYPE_STRING,
576 G_TYPE_STRING,
577 G_TYPE_STRING,
578 G_TYPE_BOOLEAN));
579 gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), model);
580 load_environment_variables (editor, GTK_LIST_STORE (model));
581 editor->model = g_object_ref (model);
582
583 renderer = gtk_cell_renderer_text_new ();
584 g_signal_connect(renderer, "edited", (GCallback) on_environment_variable_edited, editor);
585 g_object_set(renderer, "editable", TRUE, NULL);
586 column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer,
587 "text", ENV_NAME_COLUMN,
588 "foreground", ENV_COLOR_COLUMN,
589 NULL);
590 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
591 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
592 renderer = gtk_cell_renderer_text_new ();
593 g_object_set(renderer, "editable", TRUE, NULL);
594 g_signal_connect(renderer, "edited", (GCallback) on_environment_value_edited, editor);
595 column = gtk_tree_view_column_new_with_attributes (_("Value"), renderer,
596 "text", ENV_VALUE_COLUMN,
597 "foreground", ENV_COLOR_COLUMN,
598 NULL);
599 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
600 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
601
602 /* Connect signals */
603 g_signal_connect (G_OBJECT (add_button), "clicked", G_CALLBACK (on_environment_add_button), editor->treeview);
604 g_signal_connect (G_OBJECT (edit_button), "clicked", G_CALLBACK (on_environment_edit_button), editor->treeview);
605 g_signal_connect (G_OBJECT (remove_button), "clicked", G_CALLBACK (on_environment_remove_button), editor);
606 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
607 g_signal_connect (selection, "changed", G_CALLBACK (on_environment_selection_changed), editor);
608
609 on_environment_selection_changed (NULL, editor);
610 }
611
612 static void
anjuta_environment_editor_class_init(AnjutaEnvironmentEditorClass * klass)613 anjuta_environment_editor_class_init (AnjutaEnvironmentEditorClass *klass)
614 {
615 GObjectClass* object_class = G_OBJECT_CLASS (klass);
616 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
617
618
619 /**
620 * AnjutaEnvironmentEditor::changed:
621 * @widget: the AnjutaEnvironmentEditor that received the signal
622 *
623 * The ::changed signal is emitted when an environment variable
624 * is changed (include deleted variables)
625 */
626 g_signal_new ("changed",
627 G_OBJECT_CLASS_TYPE (klass),
628 G_SIGNAL_RUN_LAST,
629 G_STRUCT_OFFSET (AnjutaEnvironmentEditorClass, changed),
630 NULL, NULL,
631 g_cclosure_marshal_VOID__VOID,
632 G_TYPE_NONE, 0);
633
634 object_class->dispose = anjuta_environment_editor_dispose;
635 object_class->finalize = anjuta_environment_editor_finalize;
636
637 widget_class->size_allocate = anjuta_environment_editor_size_allocate;
638 widget_class->get_preferred_width = anjuta_environment_editor_get_preferred_width;
639 widget_class->get_preferred_height = anjuta_environment_editor_get_preferred_height;
640 }
641
642 /* Public functions
643 *---------------------------------------------------------------------------*/
644
645 /*
646 * anjuta_environment_editor_new:
647 *
648 * Returns: A new AnjutaEnvironmentEditor widget
649 */
650 GtkWidget*
anjuta_environment_editor_new(void)651 anjuta_environment_editor_new (void)
652 {
653 return GTK_WIDGET (g_object_new (ANJUTA_TYPE_ENVIRONMENT_EDITOR, NULL));
654 }
655
656 /*
657 * anjuta_environment_editor_set_variable:
658 * @editor: A AnjutaEnvironmentEditor widget
659 * @variable: Environment variable name and value
660 *
661 * Set environment variable.
662 */
663 void
anjuta_environment_editor_set_variable(AnjutaEnvironmentEditor * editor,const gchar * variable)664 anjuta_environment_editor_set_variable (AnjutaEnvironmentEditor *editor, const gchar *variable)
665 {
666 GtkTreeIter iter;
667 GtkTreeModel *model;
668 gboolean valid;
669 gchar *name;
670 const gchar *equal;
671 guint len;
672
673 model = editor->model;
674
675 /* Check is variable is already existing */
676 equal = strchr (variable, '=');
677 len = equal != NULL ? equal - variable : 0;
678
679 for (valid = gtk_tree_model_get_iter_first (model, &iter); valid; valid = gtk_tree_model_iter_next (model, &iter))
680 {
681 gtk_tree_model_get (editor->model, &iter,
682 ENV_NAME_COLUMN, &name,
683 -1);
684 if (((len == 0) && (strcmp (name, variable) == 0)) ||
685 ((len != 0) && (strncmp (name, variable, len) == 0) && (name[len] == '\0')))
686 {
687 break;
688 }
689 g_free (name);
690 name = NULL;
691 }
692
693 if (!valid) gtk_list_store_insert_after (GTK_LIST_STORE (model), &iter, NULL);
694
695 if (name == NULL)
696 {
697 name = g_strdup (variable);
698 if (len != 0) name[len] = '\0';
699 }
700 if (equal != NULL)
701 {
702 equal++;
703 }
704 gtk_list_store_set (GTK_LIST_STORE (model), &iter, ENV_NAME_COLUMN, name,
705 ENV_VALUE_COLUMN, equal,
706 ENV_COLOR_COLUMN, ENV_USER_COLOR,
707 -1);
708 g_free (name);
709 }
710
711 /*
712 * anjuta_environment_editor_get_all_variables:
713 * @editor: A AnjutaEnvironmentEditor widget
714 *
715 * Returns: A list of all environment variables in a string array.
716 */
717 gchar**
anjuta_environment_editor_get_all_variables(AnjutaEnvironmentEditor * editor)718 anjuta_environment_editor_get_all_variables (AnjutaEnvironmentEditor *editor)
719 {
720 gchar **all_var;
721 gchar *var;
722 gboolean valid;
723 GtkTreeIter iter;
724
725 all_var = g_new (gchar *, gtk_tree_model_iter_n_children (editor->model, NULL) + 1);
726 var = *all_var;
727
728 for (valid = gtk_tree_model_get_iter_first (editor->model, &iter); valid; valid = gtk_tree_model_iter_next (editor->model, &iter))
729 {
730 gchar *name;
731 gchar *value;
732 gchar *color;
733
734 gtk_tree_model_get (editor->model, &iter,
735 ENV_NAME_COLUMN, &name,
736 ENV_VALUE_COLUMN, &value,
737 ENV_COLOR_COLUMN, &color,
738 -1);
739
740 var = g_strconcat(name, "=", value, NULL);
741 var++;
742 g_free (name);
743 g_free (value);
744 g_free (color);
745 }
746 var = NULL;
747
748 return all_var;
749 }
750
751 /*
752 * anjuta_environment_editor_get_modified_variables:
753 * @editor: A AnjutaEnvironmentEditor widget
754 *
755 * Returns: A list of modified environment variables in a string array.
756 */
757 gchar**
anjuta_environment_editor_get_modified_variables(AnjutaEnvironmentEditor * editor)758 anjuta_environment_editor_get_modified_variables (AnjutaEnvironmentEditor *editor)
759 {
760 gchar **mod_var;
761 gchar **var;
762 gboolean valid;
763 GtkTreeIter iter;
764
765 /* Allocated a too big array: able to save all environment variables
766 * while we need to save only variables modified by user but it
767 * shouldn't be that big anyway and checking exactly which variable
768 * need to be saved will take more time */
769 mod_var = g_new (gchar *, gtk_tree_model_iter_n_children (editor->model, NULL) + 1);
770 var = mod_var;
771
772 for (valid = gtk_tree_model_get_iter_first (editor->model, &iter); valid; valid = gtk_tree_model_iter_next (editor->model, &iter))
773 {
774 gchar *name;
775 gchar *value;
776 gchar *color;
777
778 gtk_tree_model_get (editor->model, &iter,
779 ENV_NAME_COLUMN, &name,
780 ENV_VALUE_COLUMN, &value,
781 ENV_COLOR_COLUMN, &color,
782 -1);
783
784 /* Save only variables modified by user */
785 if (strcmp(color, ENV_USER_COLOR) == 0)
786 {
787 *var = g_strconcat(name, "=", value, NULL);
788 var++;
789 }
790 g_free (name);
791 g_free (value);
792 g_free (color);
793 }
794 *var = NULL;
795
796 return mod_var;
797 }
798
799 /*
800 * anjuta_environment_editor_reset:
801 * @editor: A AnjutaEnvironmentEditor widget
802 *
803 * Remove all variables modified by the user
804 */
805 void
anjuta_environment_editor_reset(AnjutaEnvironmentEditor * editor)806 anjuta_environment_editor_reset (AnjutaEnvironmentEditor *editor)
807 {
808 gtk_list_store_clear (GTK_LIST_STORE (editor->model));
809 load_environment_variables (editor, GTK_LIST_STORE (editor->model));
810 }
811