Code

peeled back the gboolean code as it hit on some complexity theory principles...
[inkscape.git] / src / dialogs / input.cpp
1 #define __SP_INPUT_C__
3 /*
4  * Extended input devices dialog
5  *
6  * Authors:
7  *   Nicklas Lindgren <nili@lysator.liu.se>
8  *
9  * Copyright (C) 2005 Authors
10  *
11  * Released under GNU GPL, read the file 'COPYING' for more information
12  */
14 #ifdef HAVE_CONFIG_H
15 # include "config.h"
16 #endif
17 #include <gtk/gtksignal.h>
18 #include <gtk/gtkinputdialog.h>
19 #include <glibmm/ustring.h>
21 #include "../inkscape.h"
22 #include "../macros.h"
23 #include "../verbs.h"
24 #include "../interface.h"
25 #include "../xml/repr.h"
27 #include "dialog-events.h"
28 #include "../prefs-utils.h"
31 static GtkWidget *dlg = NULL;
32 static win_data wd;
34 // impossible original values to make sure they are read from prefs
35 static gint x = -1000, y = -1000, w = 0, h = 0;
36 static gchar *prefs_path = "dialogs.input";
38 static void
39 sp_input_dialog_destroy (GtkObject *object, gpointer data)
40 {
41     sp_signal_disconnect_by_data (INKSCAPE, dlg);
42     wd.win = dlg = NULL;
43     wd.stop = 0;
44 }
46 static gboolean
47 sp_input_dialog_delete (GtkObject *object, GdkEvent *event, gpointer data)
48 {
49     gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
50     gtk_window_get_size ((GtkWindow *) dlg, &w, &h);
52     if (x<0) x=0;
53     if (y<0) y=0;
55     prefs_set_int_attribute (prefs_path, "x", x);
56     prefs_set_int_attribute (prefs_path, "y", y);
57     prefs_set_int_attribute (prefs_path, "w", w);
58     prefs_set_int_attribute (prefs_path, "h", h);
60     return FALSE; // which means, go ahead and destroy it
62 }
64 static gchar *axis_use_strings[GDK_AXIS_LAST] = {
65     "ignore", "x", "y", "pressure", "xtilt", "ytilt", "wheel"
66 };
68 void
69 sp_input_load_from_preferences (void)
70 {
71     Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices");
72     if (devices == NULL)
73         return;
75     Inkscape::XML::Node *repr;
76     GList *list_ptr;
78     for (list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
79         GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
80         repr = sp_repr_lookup_child(devices, "id", device->name);
81         if (repr != NULL) {
82             GdkInputMode mode;
83             const gchar *attribute = repr->attribute("mode");
85             if (attribute == NULL)
86                 mode = GDK_MODE_DISABLED;
87             else if (!strcmp(attribute, "screen"))
88                 mode = GDK_MODE_SCREEN;
89             else if (!strcmp(attribute, "window"))
90                 mode = GDK_MODE_WINDOW;
91             else
92                 mode = GDK_MODE_DISABLED;
94             if (device->mode != mode) {
95                 gdk_device_set_mode(device, mode);
96             }
98             const gchar *temp_ptr;
99             Glib::ustring::size_type pos0;
100             Glib::ustring::size_type pos1;
101             gint i;
102             gint j;
104             GdkAxisUse axis_use;
106             temp_ptr = repr->attribute("axes");
107             if (temp_ptr != NULL) {
108                 const Glib::ustring temp_str = temp_ptr;
109                 pos0 = pos1 = 0;
110                 for (i=0; i < device->num_axes; i++) {
111                     pos1 = temp_str.find(";", pos0);
112                     if (pos1 == Glib::ustring::npos)
113                         break;  // Too few axis specifications
115                     axis_use = GDK_AXIS_IGNORE;
116                     for (j=0; j < GDK_AXIS_LAST; j++)
117                         if (!strcmp(temp_str.substr(pos0, pos1-pos0).c_str(), axis_use_strings[j])) {
118                             axis_use = static_cast<GdkAxisUse>(j);
119                             break;
120                         }
121                     gdk_device_set_axis_use(device, i, axis_use);
122                     pos0 = pos1 + 1;
123                 }
124             }
126             guint keyval;
127             GdkModifierType modifier;
129             temp_ptr = repr->attribute("keys");
130             if (temp_ptr != NULL) {
131                 const Glib::ustring temp_str = temp_ptr;
132                 pos0 = pos1 = 0;
133                 for (i=0; i < device->num_keys; i++) {
134                     pos1 = temp_str.find(";", pos0);
135                     if (pos1 == Glib::ustring::npos)
136                         break;  // Too few key specifications
138                     gtk_accelerator_parse(temp_str.substr(pos0, pos1-pos0).c_str(), &keyval, &modifier);
139                     gdk_device_set_key(device, i, keyval, modifier);
140                     pos0 = pos1 + 1;
141                 }
142             }
143         }
144     }
147 void
148 sp_input_save_to_preferences (void)
150     Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices");
151     if (devices == NULL)
152         // TODO: find a clean way to add a node to the preferences root, or
153         // give an error message
154         return;
156     Inkscape::XML::Node *repr;
157     GList *list_ptr;
159     for (list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
160         gint i;
161         Glib::ustring temp_attribute;
162         GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
164         repr = sp_repr_lookup_child(devices, "id", device->name);
165         if (repr == NULL) {
166             repr = sp_repr_new("group");
167             repr->setAttribute("id", device->name);
168             devices->appendChild(repr);
169             Inkscape::GC::release(repr);
170         }
171         switch (device->mode) {
172             default:
173             case GDK_MODE_DISABLED: {
174                 repr->setAttribute("mode", "disabled");
175                 break;
176             }
177             case GDK_MODE_SCREEN: {
178                 repr->setAttribute("mode", "screen");
179                 break;
180             }
181             case GDK_MODE_WINDOW: {
182                 repr->setAttribute("mode", "window");
183                 break;
184             }
185         }
187         temp_attribute = "";
188         for (i=0; i < device->num_axes; i++) {
189             temp_attribute += axis_use_strings[device->axes[i].use];
190             temp_attribute += ";";
191         }
192         repr->setAttribute("axes", temp_attribute.c_str());
194         temp_attribute = "";
195         for (i=0; i < device->num_keys; i++) {
196             temp_attribute += gtk_accelerator_name(device->keys[i].keyval, device->keys[i].modifiers);
197             temp_attribute += ";";
198         }
199         repr->setAttribute("keys", temp_attribute.c_str());
200     }
203 static void
204 sp_input_save_button (GtkObject *object, gpointer data)
206     sp_input_save_to_preferences();
209 /**
210  * \brief  Dialog
211  *
212  */
213 void
214 sp_input_dialog (void)
216     if (dlg == NULL) {
218         gchar title[500];
219         sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_INPUT), title);
221         dlg = gtk_input_dialog_new();
223         if (x == -1000 || y == -1000) {
224             x = prefs_get_int_attribute (prefs_path, "x", 0);
225             y = prefs_get_int_attribute (prefs_path, "y", 0);
226         }
228         if (w ==0 || h == 0) {
229             w = prefs_get_int_attribute (prefs_path, "w", 0);
230             h = prefs_get_int_attribute (prefs_path, "h", 0);
231         }
233         if (x<0) x=0;
234         if (y<0) y=0;
236         if (x != 0 || y != 0) {
237             gtk_window_move ((GtkWindow *) dlg, x, y);
238         } else {
239             gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
240         }
242         if (w && h) {
243             gtk_window_resize ((GtkWindow *) dlg, w, h);
244         }
246         sp_transientize (dlg);
247         wd.win = dlg;
248         wd.stop = 0;
250         g_signal_connect   ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd);
251         gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg);
252         gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_input_dialog_destroy), dlg);
253         gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_input_dialog_delete), dlg);
254         g_signal_connect   ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_input_dialog_delete), dlg);
255         g_signal_connect   ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg);
256         g_signal_connect   ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg);
258         // Dialog-specific stuff
259         gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->close_button),
260                                    "clicked",
261                                    (GtkSignalFunc)gtk_widget_destroy,
262                                    GTK_OBJECT(dlg));
263         gtk_signal_connect (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->save_button),
264                             "clicked",
265                             (GtkSignalFunc)sp_input_save_button, NULL);
266     }
268     gtk_window_present ((GtkWindow *) dlg);
272 /*
273   Local Variables:
274   mode:c++
275   c-file-style:"stroustrup"
276   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
277   indent-tabs-mode:nil
278   fill-column:99
279   End:
280 */
281 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :