1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * This is a plug-in for GIMP.
5 *
6 * Copyright (C) 2000 Michael Natterer <mitch@gimp.org>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include <string.h>
25
26 #include <libgimp/gimp.h>
27 #include <libgimp/gimpui.h>
28
29 #include "libgimp/stdplugins-intl.h"
30
31
32 #define PLUG_IN_PROC "plug-in-unit-editor"
33 #define PLUG_IN_BINARY "unit-editor"
34 #define PLUG_IN_ROLE "gimp-unit-editor"
35 #define RESPONSE_REFRESH 1
36
37 enum
38 {
39 SAVE,
40 IDENTIFIER,
41 FACTOR,
42 DIGITS,
43 SYMBOL,
44 ABBREVIATION,
45 SINGULAR,
46 PLURAL,
47 UNIT,
48 USER_UNIT,
49 BG_COLOR,
50 NUM_COLUMNS
51 };
52
53 typedef struct
54 {
55 const gchar *title;
56 const gchar *help;
57
58 } UnitColumn;
59
60
61 static void query (void);
62 static void run (const gchar *name,
63 gint n_params,
64 const GimpParam *param,
65 gint *n_return_vals,
66 GimpParam **return_vals);
67
68 static GimpUnit new_unit_dialog (GtkWidget *main_dialog,
69 GimpUnit template);
70 static void unit_editor_dialog (void);
71 static void unit_editor_response (GtkWidget *widget,
72 gint response_id,
73 gpointer data);
74 static void new_callback (GtkAction *action,
75 GtkTreeView *tv);
76 static void duplicate_callback (GtkAction *action,
77 GtkTreeView *tv);
78 static void saved_toggled_callback (GtkCellRendererToggle *celltoggle,
79 gchar *path_string,
80 GtkListStore *list_store);
81 static void unit_list_init (GtkTreeView *tv);
82
83
84 const GimpPlugInInfo PLUG_IN_INFO =
85 {
86 NULL, /* init_proc */
87 NULL, /* quit_proc */
88 query, /* query_proc */
89 run, /* run_proc */
90 };
91
92 static const UnitColumn columns[] =
93 {
94 { N_("Saved"), N_("A unit definition will only be saved before "
95 "GIMP exits if this column is checked.") },
96 { N_("ID"), N_("This string will be used to identify a "
97 "unit in GIMP's configuration files.") },
98 { N_("Factor"), N_("How many units make up an inch.") },
99 { N_("Digits"), N_("This field is a hint for numerical input "
100 "fields. It specifies how many decimal digits "
101 "the input field should provide to get "
102 "approximately the same accuracy as an "
103 "\"inch\" input field with two decimal digits.") },
104 { N_("Symbol"), N_("The unit's symbol if it has one (e.g. \" "
105 "for inches). The unit's abbreviation is used "
106 "if doesn't have a symbol.") },
107 { N_("Abbreviation"), N_("The unit's abbreviation (e.g. \"cm\" for "
108 "centimeters).") },
109 { N_("Singular"), N_("The unit's singular form.") },
110 { N_("Plural"), N_("The unit's plural form.") }
111 };
112
113 static GtkActionEntry actions[] =
114 {
115 { "unit-editor-toolbar", NULL,
116 "Unit Editor Toolbar", NULL, NULL, NULL
117 },
118
119 { "unit-editor-new", GIMP_ICON_DOCUMENT_NEW,
120 NULL, "<control>N",
121 N_("Create a new unit from scratch"),
122 G_CALLBACK (new_callback)
123 },
124
125 { "unit-editor-duplicate", GIMP_ICON_OBJECT_DUPLICATE,
126 NULL, "<control>D",
127 N_("Create a new unit using the currently selected unit as template"),
128 G_CALLBACK (duplicate_callback)
129 }
130 };
131
132
MAIN()133 MAIN ()
134
135
136 static void
137 query (void)
138 {
139 static const GimpParamDef args[] =
140 {
141 { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0) }" }
142 };
143
144 gimp_install_procedure (PLUG_IN_PROC,
145 N_("Create or alter units used in GIMP"),
146 "The GIMP unit editor",
147 "Michael Natterer <mitch@gimp.org>",
148 "Michael Natterer <mitch@gimp.org>",
149 "2000",
150 N_("U_nits"),
151 "",
152 GIMP_PLUGIN,
153 G_N_ELEMENTS (args), 0,
154 args, NULL);
155
156 gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Edit/Preferences");
157 gimp_plugin_icon_register (PLUG_IN_PROC, GIMP_ICON_TYPE_ICON_NAME,
158 (const guint8 *) GIMP_ICON_TOOL_MEASURE);
159 }
160
161 static void
run(const gchar * name,gint nparams,const GimpParam * param,gint * nreturn_vals,GimpParam ** return_vals)162 run (const gchar *name,
163 gint nparams,
164 const GimpParam *param,
165 gint *nreturn_vals,
166 GimpParam **return_vals)
167 {
168 static GimpParam values[2];
169
170 INIT_I18N ();
171
172 *nreturn_vals = 1;
173 *return_vals = values;
174
175 values[0].type = GIMP_PDB_STATUS;
176 values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
177
178 if (strcmp (name, PLUG_IN_PROC) == 0)
179 {
180 values[0].data.d_status = GIMP_PDB_SUCCESS;
181
182 unit_editor_dialog ();
183 }
184 }
185
186 static GimpUnit
new_unit_dialog(GtkWidget * main_dialog,GimpUnit template)187 new_unit_dialog (GtkWidget *main_dialog,
188 GimpUnit template)
189 {
190 GtkWidget *dialog;
191 GtkWidget *table;
192 GtkWidget *entry;
193 GtkWidget *spinbutton;
194
195 GtkWidget *identifier_entry;
196 GtkAdjustment *factor_adj;
197 GtkAdjustment *digits_adj;
198 GtkWidget *symbol_entry;
199 GtkWidget *abbreviation_entry;
200 GtkWidget *singular_entry;
201 GtkWidget *plural_entry;
202
203 GimpUnit unit = GIMP_UNIT_PIXEL;
204
205 dialog = gimp_dialog_new (_("Add a New Unit"), PLUG_IN_ROLE,
206 main_dialog, GTK_DIALOG_MODAL,
207 gimp_standard_help_func, PLUG_IN_PROC,
208
209 _("_Cancel"), GTK_RESPONSE_CANCEL,
210 _("_Add"), GTK_RESPONSE_OK,
211
212 NULL);
213
214 gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
215 GTK_RESPONSE_OK,
216 GTK_RESPONSE_CANCEL,
217 -1);
218
219 table = gtk_table_new (7, 2, FALSE);
220 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
221 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
222 gtk_container_set_border_width (GTK_CONTAINER (table), 12);
223 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
224 table, FALSE, FALSE, 0);
225 gtk_widget_show (table);
226
227 entry = identifier_entry = gtk_entry_new ();
228 if (template != GIMP_UNIT_PIXEL)
229 {
230 gtk_entry_set_text (GTK_ENTRY (entry),
231 gimp_unit_get_identifier (template));
232 }
233 gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
234 _("_ID:"), 0.0, 0.5,
235 entry, 1, FALSE);
236
237 gimp_help_set_help_data (entry, gettext (columns[IDENTIFIER].help), NULL);
238
239 factor_adj = (GtkAdjustment *)
240 gtk_adjustment_new ((template != GIMP_UNIT_PIXEL) ?
241 gimp_unit_get_factor (template) : 1.0,
242 GIMP_MIN_RESOLUTION, GIMP_MAX_RESOLUTION,
243 0.01, 0.1, 0.0);
244 spinbutton = gimp_spin_button_new (factor_adj, 0.01, 5);
245 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
246 gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
247 _("_Factor:"), 0.0, 0.5,
248 spinbutton, 1, TRUE);
249
250 gimp_help_set_help_data (spinbutton, gettext (columns[FACTOR].help), NULL);
251
252 digits_adj = (GtkAdjustment *)
253 gtk_adjustment_new ((template != GIMP_UNIT_PIXEL) ?
254 gimp_unit_get_digits (template) : 2.0,
255 0, 5, 1, 1, 0);
256 spinbutton = gimp_spin_button_new (digits_adj, 0, 0);
257 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
258 gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
259 _("_Digits:"), 0.0, 0.5,
260 spinbutton, 1, TRUE);
261
262 gimp_help_set_help_data (spinbutton, gettext (columns[DIGITS].help), NULL);
263
264 entry = symbol_entry = gtk_entry_new ();
265 if (template != GIMP_UNIT_PIXEL)
266 {
267 gtk_entry_set_text (GTK_ENTRY (entry),
268 gimp_unit_get_symbol (template));
269 }
270 gimp_table_attach_aligned (GTK_TABLE (table), 0, 3,
271 _("_Symbol:"), 0.0, 0.5,
272 entry, 1, FALSE);
273
274 gimp_help_set_help_data (entry, gettext (columns[SYMBOL].help), NULL);
275
276 entry = abbreviation_entry = gtk_entry_new ();
277 if (template != GIMP_UNIT_PIXEL)
278 {
279 gtk_entry_set_text (GTK_ENTRY (entry),
280 gimp_unit_get_abbreviation (template));
281 }
282 gimp_table_attach_aligned (GTK_TABLE (table), 0, 4,
283 _("_Abbreviation:"), 0.0, 0.5,
284 entry, 1, FALSE);
285
286 gimp_help_set_help_data (entry, gettext (columns[ABBREVIATION].help), NULL);
287
288 entry = singular_entry = gtk_entry_new ();
289 if (template != GIMP_UNIT_PIXEL)
290 {
291 gtk_entry_set_text (GTK_ENTRY (entry),
292 gimp_unit_get_singular (template));
293 }
294 gimp_table_attach_aligned (GTK_TABLE (table), 0, 5,
295 _("Si_ngular:"), 0.0, 0.5,
296 entry, 1, FALSE);
297
298 gimp_help_set_help_data (entry, gettext (columns[SINGULAR].help), NULL);
299
300 entry = plural_entry = gtk_entry_new ();
301 if (template != GIMP_UNIT_PIXEL)
302 {
303 gtk_entry_set_text (GTK_ENTRY (entry),
304 gimp_unit_get_plural (template));
305 }
306 gimp_table_attach_aligned (GTK_TABLE (table), 0, 6,
307 _("_Plural:"), 0.0, 0.5,
308 entry, 1, FALSE);
309
310 gimp_help_set_help_data (entry, gettext (columns[PLURAL].help), NULL);
311
312 gtk_widget_show (dialog);
313
314 while (TRUE)
315 {
316 gchar *identifier;
317 gdouble factor;
318 gint digits;
319 gchar *symbol;
320 gchar *abbreviation;
321 gchar *singular;
322 gchar *plural;
323
324 if (gimp_dialog_run (GIMP_DIALOG (dialog)) != GTK_RESPONSE_OK)
325 break;
326
327 identifier = g_strdup (gtk_entry_get_text (GTK_ENTRY (identifier_entry)));
328 factor = gtk_adjustment_get_value (GTK_ADJUSTMENT (factor_adj));
329 digits = gtk_adjustment_get_value (GTK_ADJUSTMENT (digits_adj));
330 symbol = g_strdup (gtk_entry_get_text (GTK_ENTRY (symbol_entry)));
331 abbreviation = g_strdup (gtk_entry_get_text (GTK_ENTRY (abbreviation_entry)));
332 singular = g_strdup (gtk_entry_get_text (GTK_ENTRY (singular_entry)));
333 plural = g_strdup (gtk_entry_get_text (GTK_ENTRY (plural_entry)));
334
335 identifier = g_strstrip (identifier);
336 symbol = g_strstrip (symbol);
337 abbreviation = g_strstrip (abbreviation);
338 singular = g_strstrip (singular);
339 plural = g_strstrip (plural);
340
341 if (! strlen (identifier) ||
342 ! strlen (symbol) ||
343 ! strlen (abbreviation) ||
344 ! strlen (singular) ||
345 ! strlen (plural))
346 {
347 GtkWidget *msg = gtk_message_dialog_new (GTK_WINDOW (dialog), 0,
348 GTK_MESSAGE_ERROR,
349 GTK_BUTTONS_OK,
350 _("Incomplete input"));
351
352 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (msg),
353 _("Please fill in all text fields."));
354 gtk_dialog_run (GTK_DIALOG (msg));
355 gtk_widget_destroy (msg);
356
357 continue;
358 }
359
360 unit = gimp_unit_new (identifier,
361 factor, digits,
362 symbol, abbreviation, singular, plural);
363
364 g_free (identifier);
365 g_free (symbol);
366 g_free (abbreviation);
367 g_free (singular);
368 g_free (plural);
369
370 break;
371 }
372
373 gtk_widget_destroy (dialog);
374
375 return unit;
376 }
377
378 static void
unit_editor_dialog(void)379 unit_editor_dialog (void)
380 {
381 GtkWidget *dialog;
382 GtkWidget *scrolled_win;
383 GtkUIManager *ui_manager;
384 GtkActionGroup *group;
385 GtkWidget *toolbar;
386 GtkListStore *list_store;
387 GtkWidget *tv;
388 GtkTreeViewColumn *col;
389 GtkWidget *col_widget;
390 GtkWidget *button;
391 GtkCellRenderer *rend;
392 gint i;
393
394 gimp_ui_init (PLUG_IN_BINARY, FALSE);
395
396 list_store = gtk_list_store_new (NUM_COLUMNS,
397 G_TYPE_BOOLEAN, /* SAVE */
398 G_TYPE_STRING, /* IDENTIFIER */
399 G_TYPE_DOUBLE, /* FACTOR */
400 G_TYPE_INT, /* DIGITS */
401 G_TYPE_STRING, /* SYMBOL */
402 G_TYPE_STRING, /* ABBREVIATION */
403 G_TYPE_STRING, /* SINGULAR */
404 G_TYPE_STRING, /* PLURAL */
405 GIMP_TYPE_UNIT, /* UNIT */
406 G_TYPE_BOOLEAN, /* USER_UNIT */
407 GDK_TYPE_COLOR); /* BG_COLOR */
408
409 tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
410 g_object_unref (list_store);
411
412 dialog = gimp_dialog_new (_("Unit Editor"), PLUG_IN_ROLE,
413 NULL, 0,
414 gimp_standard_help_func, PLUG_IN_PROC,
415
416 _("_Refresh"), RESPONSE_REFRESH,
417 _("_Close"), GTK_RESPONSE_CLOSE,
418
419 NULL);
420
421 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
422
423 g_signal_connect (dialog, "response",
424 G_CALLBACK (unit_editor_response),
425 tv);
426 g_signal_connect (dialog, "destroy",
427 G_CALLBACK (gtk_main_quit),
428 NULL);
429
430 /* the toolbar */
431 ui_manager = gtk_ui_manager_new ();
432
433 group = gtk_action_group_new ("unit-editor");
434
435 gtk_action_group_set_translation_domain (group, NULL);
436 gtk_action_group_add_actions (group, actions, G_N_ELEMENTS (actions), tv);
437
438 gtk_window_add_accel_group (GTK_WINDOW (dialog),
439 gtk_ui_manager_get_accel_group (ui_manager));
440 gtk_accel_group_lock (gtk_ui_manager_get_accel_group (ui_manager));
441
442 gtk_ui_manager_insert_action_group (ui_manager, group, -1);
443 g_object_unref (group);
444
445 gtk_ui_manager_add_ui_from_string
446 (ui_manager,
447 "<ui>\n"
448 " <toolbar action=\"unit-editor-toolbar\">\n"
449 " <toolitem action=\"unit-editor-new\" />\n"
450 " <toolitem action=\"unit-editor-duplicate\" />\n"
451 " </toolbar>\n"
452 "</ui>\n",
453 -1, NULL);
454
455 toolbar = gtk_ui_manager_get_widget (ui_manager, "/unit-editor-toolbar");
456 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
457 toolbar, FALSE, FALSE, 0);
458 gtk_widget_show (toolbar);
459
460 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
461 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
462 GTK_SHADOW_IN);
463 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
464 GTK_POLICY_NEVER,
465 GTK_POLICY_ALWAYS);
466 gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 12);
467 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
468 scrolled_win, TRUE, TRUE, 0);
469 gtk_widget_show (scrolled_win);
470
471 gtk_widget_set_size_request (tv, -1, 220);
472 gtk_container_add (GTK_CONTAINER (scrolled_win), tv);
473 gtk_widget_show (tv);
474
475 rend = gtk_cell_renderer_toggle_new ();
476 col =
477 gtk_tree_view_column_new_with_attributes (gettext (columns[SAVE].title),
478 rend,
479 "active", SAVE,
480 "activatable", USER_UNIT,
481 "cell-background-gdk", BG_COLOR,
482 NULL);
483
484 gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
485
486 col_widget = gtk_tree_view_column_get_widget (col);
487 if (col_widget)
488 {
489 button = gtk_widget_get_ancestor (col_widget, GTK_TYPE_BUTTON);
490
491 if (button)
492 gimp_help_set_help_data (button,
493 gettext (columns[SAVE].help), NULL);
494 }
495
496 g_signal_connect (rend, "toggled",
497 G_CALLBACK (saved_toggled_callback),
498 list_store);
499
500 for (i = 0; i < G_N_ELEMENTS (columns); i++)
501 {
502 if (i == SAVE)
503 continue;
504
505 col =
506 gtk_tree_view_column_new_with_attributes (gettext (columns[i].title),
507 gtk_cell_renderer_text_new (),
508 "text", i,
509 "cell-background-gdk", BG_COLOR,
510 NULL);
511
512 gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
513
514 col_widget = gtk_tree_view_column_get_widget (col);
515 if (col_widget)
516 {
517 button = gtk_widget_get_ancestor (col_widget, GTK_TYPE_BUTTON);
518
519 if (button)
520 gimp_help_set_help_data (button, gettext (columns[i].help), NULL);
521 }
522 }
523
524 unit_list_init (GTK_TREE_VIEW (tv));
525
526 gtk_widget_show (dialog);
527
528 gtk_main ();
529 }
530
531 static void
unit_editor_response(GtkWidget * widget,gint response_id,gpointer data)532 unit_editor_response (GtkWidget *widget,
533 gint response_id,
534 gpointer data)
535 {
536 switch (response_id)
537 {
538 case RESPONSE_REFRESH:
539 unit_list_init (GTK_TREE_VIEW (data));
540 break;
541
542 default:
543 gtk_widget_destroy (widget);
544 break;
545 }
546 }
547
548 static void
new_callback(GtkAction * action,GtkTreeView * tv)549 new_callback (GtkAction *action,
550 GtkTreeView *tv)
551 {
552 GimpUnit unit;
553
554 unit = new_unit_dialog (gtk_widget_get_toplevel (GTK_WIDGET (tv)),
555 GIMP_UNIT_PIXEL);
556
557 if (unit != GIMP_UNIT_PIXEL)
558 {
559 GtkTreeModel *model;
560 GtkTreeIter iter;
561
562 unit_list_init (tv);
563
564 model = gtk_tree_view_get_model (tv);
565
566 if (gtk_tree_model_get_iter_first (model, &iter) &&
567 gtk_tree_model_iter_nth_child (model, &iter,
568 NULL, unit - GIMP_UNIT_INCH))
569 {
570 GtkAdjustment *adj;
571
572 gtk_tree_selection_select_iter (gtk_tree_view_get_selection (tv),
573 &iter);
574
575 adj = gtk_tree_view_get_vadjustment (tv);
576 gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
577 }
578 }
579 }
580
581 static void
duplicate_callback(GtkAction * action,GtkTreeView * tv)582 duplicate_callback (GtkAction *action,
583 GtkTreeView *tv)
584 {
585 GtkTreeModel *model;
586 GtkTreeSelection *sel;
587 GtkTreeIter iter;
588
589 model = gtk_tree_view_get_model (tv);
590 sel = gtk_tree_view_get_selection (tv);
591
592 if (gtk_tree_selection_get_selected (sel, NULL, &iter))
593 {
594 GimpUnit unit;
595
596 gtk_tree_model_get (model, &iter,
597 UNIT, &unit,
598 -1);
599
600 unit = new_unit_dialog (gtk_widget_get_toplevel (GTK_WIDGET (tv)),
601 unit);
602
603 if (unit != GIMP_UNIT_PIXEL)
604 {
605 GtkTreeIter iter;
606
607 unit_list_init (tv);
608
609 if (gtk_tree_model_get_iter_first (model, &iter) &&
610 gtk_tree_model_iter_nth_child (model, &iter,
611 NULL, unit - GIMP_UNIT_INCH))
612 {
613 GtkAdjustment *adj;
614
615 gtk_tree_selection_select_iter (sel, &iter);
616
617 adj = gtk_tree_view_get_vadjustment (tv);
618 gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
619 }
620 }
621 }
622 }
623
624 static void
saved_toggled_callback(GtkCellRendererToggle * celltoggle,gchar * path_string,GtkListStore * list_store)625 saved_toggled_callback (GtkCellRendererToggle *celltoggle,
626 gchar *path_string,
627 GtkListStore *list_store)
628 {
629 GtkTreePath *path;
630 GtkTreeIter iter;
631 gboolean saved;
632 GimpUnit unit;
633
634 path = gtk_tree_path_new_from_string (path_string);
635
636 if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store), &iter, path))
637 {
638 g_warning ("%s: bad tree path?", G_STRLOC);
639 return;
640 }
641 gtk_tree_path_free (path);
642
643 gtk_tree_model_get (GTK_TREE_MODEL (list_store), &iter,
644 SAVE, &saved,
645 UNIT, &unit,
646 -1);
647
648 if (unit >= gimp_unit_get_number_of_built_in_units ())
649 {
650 gimp_unit_set_deletion_flag (unit, saved);
651 gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
652 SAVE, ! saved,
653 -1);
654 }
655 }
656
657 static void
unit_list_init(GtkTreeView * tv)658 unit_list_init (GtkTreeView *tv)
659 {
660 GtkListStore *list_store;
661 GtkTreeIter iter;
662 gint num_units;
663 GimpUnit unit;
664 GdkColor color;
665
666 list_store = GTK_LIST_STORE (gtk_tree_view_get_model (tv));
667
668 gtk_list_store_clear (list_store);
669
670 num_units = gimp_unit_get_number_of_units ();
671
672 color.red = 0xdddd;
673 color.green = 0xdddd;
674 color.blue = 0xffff;
675
676 for (unit = GIMP_UNIT_INCH; unit < num_units; unit++)
677 {
678 gboolean user_unit = (unit >= gimp_unit_get_number_of_built_in_units ());
679
680 gtk_list_store_append (list_store, &iter);
681 gtk_list_store_set (list_store, &iter,
682 SAVE, ! gimp_unit_get_deletion_flag (unit),
683 IDENTIFIER, gimp_unit_get_identifier (unit),
684 FACTOR, gimp_unit_get_factor (unit),
685 DIGITS, gimp_unit_get_digits (unit),
686 SYMBOL, gimp_unit_get_symbol (unit),
687 ABBREVIATION, gimp_unit_get_abbreviation (unit),
688 SINGULAR, gimp_unit_get_singular (unit),
689 PLURAL, gimp_unit_get_plural (unit),
690 UNIT, unit,
691 USER_UNIT, user_unit,
692
693 user_unit ? -1 : BG_COLOR, &color,
694
695 -1);
696 }
697
698 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter))
699 gtk_tree_selection_select_iter (gtk_tree_view_get_selection (tv), &iter);
700 }
701