Code

fix 198818
[inkscape.git] / src / widgets / spw-utilities.cpp
1 #define __SPW_UTILITIES_C__
3 /*
4  * Inkscape Widget Utilities
5  *
6  * Authors:
7  *   Bryce W. Harrington <brycehar@bryceharrington.com>
8  *   bulia byak <buliabyak@users.sf.net>
9  *
10  * Copyright (C) 2003 Bryce W. Harrington
11  *
12  * Released under GNU GPL, read the file 'COPYING' for more information
13  */
15 #ifdef HAVE_CONFIG_H
16 # include "config.h"
17 #endif
19 #include <cstring>
20 #include <string>
21 #include <gtk/gtk.h>
23 #include "selection.h"
25 #include "helper/unit-menu.h"
27 /**
28  * Creates a label widget with the given text, at the given col, row
29  * position in the table.
30  */
31 GtkWidget *
32 spw_label(GtkWidget * table, const gchar *label_text, int col, int row)
33 {
34   GtkWidget *label_widget;
36   label_widget = gtk_label_new (label_text);
37   g_assert(label_widget != NULL);
38   gtk_misc_set_alignment (GTK_MISC (label_widget), 1.0, 0.5);
39   gtk_widget_show (label_widget);
40   gtk_table_attach (GTK_TABLE (table), label_widget, col, col+1, row, row+1,
41                     (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
42   return label_widget;
43 }
45 /**
46  * Creates a horizontal layout manager with 4-pixel spacing between children
47  * and space for 'width' columns.
48  */
49 GtkWidget *
50 spw_hbox(GtkWidget * table, int width, int col, int row)
51 {
52   GtkWidget *hb;
53   /* Create a new hbox with a 4-pixel spacing between children */
54   hb = gtk_hbox_new (FALSE, 4);
55   g_assert(hb != NULL);
56   gtk_widget_show (hb);
57   gtk_table_attach (GTK_TABLE (table), hb, col, col+width, row, row+1,
58                     (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
59   return hb;
60 }
62 /**
63  * Creates a checkbutton widget and adds it to a vbox.
64  * This is a compound widget that includes a label.
65  */
66 GtkWidget *spw_vbox_checkbutton(GtkWidget *dialog, GtkWidget *vbox,
67                                         const gchar *label, const gchar *tip, gchar *key, GCallback cb)
68 {
69   g_assert (dialog != NULL);
70   g_assert (vbox != NULL);
72   GtkTooltips *tt = gtk_tooltips_new ();
74   GtkWidget *b = gtk_check_button_new_with_label (label);
75   gtk_tooltips_set_tip(tt, b, tip, NULL);
76   g_assert (b != NULL);
77   gtk_widget_show (b);
78   gtk_box_pack_start (GTK_BOX (vbox), b, FALSE, FALSE, 0);
79   gtk_object_set_data (GTK_OBJECT (b), "key", key);
80   gtk_object_set_data (GTK_OBJECT (dialog), key, b);
81   g_signal_connect (G_OBJECT (b), "toggled", cb, dialog);
82   return b;
83 }
86 /**
87  * Creates a checkbutton widget and adds it to a table.
88  * This is a compound widget that includes a label.
89  */
90 GtkWidget *
91 spw_checkbutton(GtkWidget * dialog, GtkWidget * table,
92                 const gchar * label, gchar * key, int col, int row,
93                 int insensitive, GCallback cb)
94 {
95   GtkWidget *b;
97   g_assert(dialog != NULL);
98   g_assert(table  != NULL);
100         GtkWidget *l = gtk_label_new (label);
101         gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
102         gtk_widget_show (l);
103   gtk_table_attach (GTK_TABLE (table), l, 0, 1, row, row+1,
104                     (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
106   b = gtk_check_button_new ();
107   gtk_widget_show (b);
108   gtk_table_attach (GTK_TABLE (table), b, 1, 2, row, row+1,
109                     (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
110   gtk_object_set_data (GTK_OBJECT (b), "key", key);
111   gtk_object_set_data (GTK_OBJECT (dialog), key, b);
112   g_signal_connect (G_OBJECT (b), "toggled", cb, dialog);
113   if (insensitive == 1) {
114     gtk_widget_set_sensitive (b, FALSE);
115   }
116   return b;
119 /**
120  * Creates a dropdown widget.  This is a compound widget that includes
121  * a label as well as the dropdown.
122  */
123 GtkWidget *
124 spw_dropdown(GtkWidget * dialog, GtkWidget * table,
125              const gchar * label_text, gchar * key, int row,
126              GtkWidget * selector
127              )
129   g_assert(dialog   != NULL);
130   g_assert(table    != NULL);
131   g_assert(selector != NULL);
133   spw_label(table, label_text, 0, row);
135   gtk_widget_show (selector);
136   gtk_table_attach (GTK_TABLE (table), selector, 1, 2, row, row+1,
137                     (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
138   gtk_object_set_data (GTK_OBJECT (dialog), key, selector);
139   return selector;
142 /**
143  * Creates a unit selector widget, used for selecting whether one wishes
144  * to measure screen elements in millimeters, points, etc.  This is a
145  * compound unit that includes a label as well as the dropdown selector.
146  */
147 GtkWidget *
148 spw_unit_selector(GtkWidget * dialog, GtkWidget * table,
149                   const gchar * label_text, gchar * key, int row,
150                 GtkWidget * us, GCallback cb, bool can_be_negative)
152   GtkWidget * sb;
153   GtkObject * a;
155   g_assert(dialog != NULL);
156   g_assert(table  != NULL);
157   g_assert(us     != NULL);
159   spw_label(table, label_text, 0, row);
161   a = gtk_adjustment_new (0.0, can_be_negative?-1e6:0, 1e6, 1.0, 10.0, 10.0);
162   g_assert(a != NULL);
163   gtk_object_set_data (GTK_OBJECT (a), "key", key);
164   gtk_object_set_data (GTK_OBJECT (a), "unit_selector", us);
165   gtk_object_set_data (GTK_OBJECT (dialog), key, a);
166   sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (us), GTK_ADJUSTMENT (a));
167   sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, 4);
168   g_assert(sb != NULL);
169   gtk_widget_show (sb);
170   gtk_table_attach (GTK_TABLE (table), sb, 1, 2, row, row+1,
171                     (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0);
172   g_signal_connect (G_OBJECT (a), "value_changed", cb, dialog);
173   return sb;
176 void
177 sp_set_font_size_recursive (GtkWidget *w, gpointer font)
179         guint size = GPOINTER_TO_UINT (font);
181         PangoFontDescription* pan = pango_font_description_new ();
182         pango_font_description_set_size (pan, size);
184         gtk_widget_modify_font (w, pan);
186         if (GTK_IS_CONTAINER(w)) {
187                 gtk_container_foreach (GTK_CONTAINER(w), (GtkCallback) sp_set_font_size_recursive, font);
188         }
190         pango_font_description_free (pan);
193 void
194 sp_set_font_size (GtkWidget *w, guint font)
196         sp_set_font_size_recursive (w, GUINT_TO_POINTER(font));
199 void
200 sp_set_font_size_smaller (GtkWidget *w)
202         PangoContext *pc = gtk_widget_get_pango_context (w);
203         PangoFontDescription* pfd = pango_context_get_font_description (pc);
204         guint size = pango_font_description_get_size (pfd);
205         sp_set_font_size_recursive (w, GUINT_TO_POINTER((int) (0.8*size)));
208 /**
209 \brief  Finds the descendant of w which has the data with the given key and returns the data, or NULL if there's none
210 */
211 gpointer
212 sp_search_by_data_recursive (GtkWidget *w, gpointer key)
214         gpointer r = NULL;
216         if (w && GTK_IS_OBJECT(w)) {
217                 r = gtk_object_get_data (GTK_OBJECT(w), (gchar *) key);
218         }
219         if (r) return r;
221         if (GTK_IS_CONTAINER(w)) {
222                 GList *ch = gtk_container_get_children (GTK_CONTAINER(w));
223                 for (GList *i = ch; i != NULL; i = i->next) {
224                         r = sp_search_by_data_recursive(GTK_WIDGET(i->data), key);
225                         if (r) return r;
226                 }
227         }
229         return NULL;
232 /**
233 \brief  Returns the descendant of w which has the given key and value pair, or NULL if there's none
234 */
235 GtkWidget *
236 sp_search_by_value_recursive (GtkWidget *w, gchar *key, gchar *value)
238         gchar *r = NULL;
239         GtkWidget *child;
241         if (w && GTK_IS_OBJECT(w)) {
242                 r = (gchar *) gtk_object_get_data (GTK_OBJECT(w), key);
243         }
244         if (r && !strcmp (r, value)) return w;
246         if (GTK_IS_CONTAINER(w)) {
247                 GList *ch = gtk_container_get_children (GTK_CONTAINER(w));
248                 for (GList *i = ch; i != NULL; i = i->next) {
249                         child = sp_search_by_value_recursive(GTK_WIDGET(i->data), key, value);
250                         if (child) return child;
251                 }
252         }
254         return NULL;