Merge lp:~ghugesss/xpad/code_refactor into lp:xpad
- code_refactor
- Merge into trunk
Proposed by
Sagar Ghuge
Status: | Needs review |
---|---|
Proposed branch: | lp:~ghugesss/xpad/code_refactor |
Merge into: | lp:xpad |
Diff against target: |
8138 lines (+3350/-3252) 21 files modified
src/fio.h (+7/-3) src/help.c (+3/-1) src/help.h (+3/-3) src/prefix.h (+3/-3) src/xpad-app.c (+239/-232) src/xpad-grip-tool-item.c (+38/-39) src/xpad-pad-group.c (+15/-11) src/xpad-pad-properties.c (+144/-143) src/xpad-pad.c (+1200/-1203) src/xpad-periodic.c (+230/-207) src/xpad-periodic.h (+7/-3) src/xpad-preferences.c (+477/-491) src/xpad-session-manager.c (+60/-57) src/xpad-session-manager.h (+4/-0) src/xpad-settings.c (+225/-210) src/xpad-text-buffer.c (+137/-124) src/xpad-text-view.c (+99/-100) src/xpad-toolbar.c (+279/-269) src/xpad-tray.c (+85/-75) src/xpad-tray.h (+4/-0) src/xpad-undo.c (+91/-78) |
To merge this branch: | bzr merge lp:~ghugesss/xpad/code_refactor |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Arthur Borsboom | code review no testing | Needs Fixing | |
Review via email: mp+233722@code.launchpad.net |
Commit message
Description of the change
https:/
As our app is under GNOME so we need to follow the global coding style and also follow the header includes for .c files.
I have tested a code and working fine. As I know you will going to see lot of changes, so from onwards before accepting any patch from other contributors we ask him to also follow the standard coding style.
To post a comment you must log in.
Revision history for this message
Arthur Borsboom (arthurborsboom) wrote : | # |
review:
Needs Fixing
(code review no testing)
Unmerged revisions
- 705. By Sagar Ghuge
-
Typo corrected.
- 704. By Sagar Ghuge
-
Code refactoring done.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/fio.h' | |||
2 | --- src/fio.h 2014-06-15 10:02:50 +0000 | |||
3 | +++ src/fio.h 2014-09-08 13:22:52 +0000 | |||
4 | @@ -19,11 +19,13 @@ | |||
5 | 19 | 19 | ||
6 | 20 | */ | 20 | */ |
7 | 21 | 21 | ||
10 | 22 | #ifndef _FIO_H_ | 22 | #ifndef __FIO_H__ |
11 | 23 | #define _FIO_H_ | 23 | #define __FIO_H__ |
12 | 24 | 24 | ||
13 | 25 | #include <glib.h> | 25 | #include <glib.h> |
14 | 26 | 26 | ||
15 | 27 | G_BEGIN_DECLS | ||
16 | 28 | |||
17 | 27 | gchar *fio_get_file (const gchar *name); | 29 | gchar *fio_get_file (const gchar *name); |
18 | 28 | gboolean fio_set_file (const gchar *name, const gchar *value); | 30 | gboolean fio_set_file (const gchar *name, const gchar *value); |
19 | 29 | void fio_remove_file (const gchar *filename); | 31 | void fio_remove_file (const gchar *filename); |
20 | @@ -35,4 +37,6 @@ | |||
21 | 35 | 37 | ||
22 | 36 | gchar *fio_unique_name (const gchar *prefix); | 38 | gchar *fio_unique_name (const gchar *prefix); |
23 | 37 | 39 | ||
25 | 38 | #endif /* _FIO_H_ */ | 40 | G_END_DECLS |
26 | 41 | |||
27 | 42 | #endif /* __FIO_H__ */ | ||
28 | 39 | 43 | ||
29 | === modified file 'src/help.c' | |||
30 | --- src/help.c 2014-06-21 11:03:38 +0000 | |||
31 | +++ src/help.c 2014-09-08 13:22:52 +0000 | |||
32 | @@ -20,10 +20,12 @@ | |||
33 | 20 | */ | 20 | */ |
34 | 21 | 21 | ||
35 | 22 | #include "../config.h" | 22 | #include "../config.h" |
36 | 23 | |||
37 | 23 | #include "help.h" | 24 | #include "help.h" |
38 | 25 | #include "xpad-app.h" | ||
39 | 24 | #include <gtk/gtk.h> | 26 | #include <gtk/gtk.h> |
40 | 25 | #include <glib/gi18n.h> | 27 | #include <glib/gi18n.h> |
42 | 26 | #include "xpad-app.h" | 28 | |
43 | 27 | 29 | ||
44 | 28 | GtkWindow *help_window = NULL; | 30 | GtkWindow *help_window = NULL; |
45 | 29 | 31 | ||
46 | 30 | 32 | ||
47 | === modified file 'src/help.h' | |||
48 | --- src/help.h 2014-06-10 20:55:56 +0000 | |||
49 | +++ src/help.h 2014-09-08 13:22:52 +0000 | |||
50 | @@ -19,9 +19,9 @@ | |||
51 | 19 | 19 | ||
52 | 20 | */ | 20 | */ |
53 | 21 | 21 | ||
56 | 22 | #ifndef HELP_H | 22 | #ifndef __HELP_H__ |
57 | 23 | #define HELP_H | 23 | #define __HELP_H__ |
58 | 24 | 24 | ||
59 | 25 | void show_help (void); | 25 | void show_help (void); |
60 | 26 | 26 | ||
62 | 27 | #endif | 27 | #endif /* __HELP_H__ */ |
63 | 28 | 28 | ||
64 | === modified file 'src/prefix.h' | |||
65 | --- src/prefix.h 2008-09-21 00:03:40 +0000 | |||
66 | +++ src/prefix.h 2014-09-08 13:22:52 +0000 | |||
67 | @@ -26,8 +26,8 @@ | |||
68 | 26 | * to br_*", try renaming prefix.c to prefix.cpp | 26 | * to br_*", try renaming prefix.c to prefix.cpp |
69 | 27 | */ | 27 | */ |
70 | 28 | 28 | ||
73 | 29 | #ifndef _PREFIX_H_ | 29 | #ifndef __PREFIX_H__ |
74 | 30 | #define _PREFIX_H_ | 30 | #define __PREFIX_H__ |
75 | 31 | 31 | ||
76 | 32 | #ifdef __cplusplus | 32 | #ifdef __cplusplus |
77 | 33 | extern "C" { | 33 | extern "C" { |
78 | @@ -126,4 +126,4 @@ | |||
79 | 126 | } | 126 | } |
80 | 127 | #endif /* __cplusplus */ | 127 | #endif /* __cplusplus */ |
81 | 128 | 128 | ||
83 | 129 | #endif /* _PREFIX_H_ */ | 129 | #endif /* __PREFIX_H__ */ |
84 | 130 | 130 | ||
85 | === modified file 'src/xpad-app.c' | |||
86 | --- src/xpad-app.c 2014-07-23 10:03:02 +0000 | |||
87 | +++ src/xpad-app.c 2014-09-08 13:22:52 +0000 | |||
88 | @@ -25,15 +25,8 @@ | |||
89 | 25 | Unfortunately, we lose portability... */ | 25 | Unfortunately, we lose portability... */ |
90 | 26 | 26 | ||
91 | 27 | #include "../config.h" | 27 | #include "../config.h" |
92 | 28 | |||
93 | 28 | #include "xpad-app.h" | 29 | #include "xpad-app.h" |
94 | 29 | #include <glib.h> | ||
95 | 30 | #include <glib/gi18n.h> | ||
96 | 31 | #include <glib/gstdio.h> | ||
97 | 32 | #include <string.h> | ||
98 | 33 | #include <sys/socket.h> | ||
99 | 34 | #include <sys/un.h> | ||
100 | 35 | #include <stdio.h> | ||
101 | 36 | #include <stdlib.h> | ||
102 | 37 | #include "help.h" | 30 | #include "help.h" |
103 | 38 | #include "xpad-pad.h" | 31 | #include "xpad-pad.h" |
104 | 39 | #include "xpad-pad-group.h" | 32 | #include "xpad-pad-group.h" |
105 | @@ -41,6 +34,16 @@ | |||
106 | 41 | #include "xpad-session-manager.h" | 34 | #include "xpad-session-manager.h" |
107 | 42 | #include "xpad-tray.h" | 35 | #include "xpad-tray.h" |
108 | 43 | 36 | ||
109 | 37 | #include <string.h> | ||
110 | 38 | #include <sys/socket.h> | ||
111 | 39 | #include <sys/un.h> | ||
112 | 40 | #include <stdio.h> | ||
113 | 41 | #include <stdlib.h> | ||
114 | 42 | |||
115 | 43 | #include <glib.h> | ||
116 | 44 | #include <glib/gi18n.h> | ||
117 | 45 | #include <glib/gstdio.h> | ||
118 | 46 | |||
119 | 44 | /* Seems that some systems (sun-sparc-solaris2.8 at least), need the following three #defines. | 47 | /* Seems that some systems (sun-sparc-solaris2.8 at least), need the following three #defines. |
120 | 45 | These were provided by Alan Mizrahi <alan@cesma.usb.ve>. | 48 | These were provided by Alan Mizrahi <alan@cesma.usb.ve>. |
121 | 46 | */ | 49 | */ |
122 | @@ -76,137 +79,36 @@ | |||
123 | 76 | static gint pads_loaded_on_start = 0; | 79 | static gint pads_loaded_on_start = 0; |
124 | 77 | static XpadSettings *settings; | 80 | static XpadSettings *settings; |
125 | 78 | 81 | ||
251 | 79 | static gboolean process_local_args (gint *argc, gchar **argv[]); | 82 | /** |
252 | 80 | static gboolean process_remote_args (gint *argc, gchar **argv[], gboolean have_gtk, XpadSettings *xpad_settings); | 83 | * Here are the functions called when arguments are passed to us. |
253 | 81 | 84 | */ | |
254 | 82 | static gboolean config_dir_exists (void); | 85 | |
255 | 83 | static gchar *make_config_dir (void); | 86 | static GOptionEntry local_options[] = |
256 | 84 | static void register_stock_icons (void); | 87 | { |
257 | 85 | static gint xpad_app_load_pads (void); | 88 | {"version", 'v', 0, G_OPTION_ARG_NONE, &option_version, N_("Show version number and quit"), NULL}, |
258 | 86 | static gboolean xpad_app_quit_if_no_pads (XpadPadGroup *group); | 89 | {"no-new", 'N', 0, G_OPTION_ARG_NONE, &option_nonew, N_("Don't create a new pad on startup if no previous pads exist"), NULL}, |
259 | 87 | static gboolean xpad_app_first_idle_check (XpadPadGroup *group); | 90 | {NULL} |
260 | 88 | static gboolean xpad_app_pass_args (void); | 91 | }; |
261 | 89 | static gboolean xpad_app_open_proc_file (void); | 92 | |
262 | 90 | 93 | static GOptionEntry remote_options[] = | |
263 | 91 | static void | 94 | { |
264 | 92 | xpad_app_init (int argc, char **argv) | 95 | {"new", 'n', 0, G_OPTION_ARG_NONE, &option_new, N_("Create a new pad on startup even if pads already exist"), NULL}, |
265 | 93 | { | 96 | {"hide", 'h', 0, G_OPTION_ARG_NONE, &option_hide, N_("Hide all pads"), NULL}, |
266 | 94 | gboolean first_time; | 97 | {"show", 's', 0, G_OPTION_ARG_NONE, &option_show, N_("Show all pads"), NULL}, |
267 | 95 | gboolean have_gtk; | 98 | {"toggle", 't', 0, G_OPTION_ARG_NONE, &option_toggle, N_("Toggle between show and hide all pads"), NULL}, |
268 | 96 | 99 | {"new-from-file", 'f', 0, G_OPTION_ARG_FILENAME_ARRAY, &option_files, N_("Create a new pad with the contents of a file"), N_("FILE")}, | |
269 | 97 | /* Set up support different languages */ | 100 | {"quit", 'q', 0, G_OPTION_ARG_NONE, &option_quit, N_("Close all pads"), NULL}, |
270 | 98 | #ifdef ENABLE_NLS | 101 | {"sm-client-id", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &option_smid, NULL, NULL}, |
271 | 99 | bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); | 102 | {NULL} |
272 | 100 | bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); | 103 | }; |
148 | 101 | textdomain (GETTEXT_PACKAGE); | ||
149 | 102 | #endif | ||
150 | 103 | |||
151 | 104 | have_gtk = gtk_init_check (&argc, &argv); | ||
152 | 105 | xpad_argc = argc; | ||
153 | 106 | xpad_argv = argv; | ||
154 | 107 | output = stdout; | ||
155 | 108 | |||
156 | 109 | /* Set up config directory. */ | ||
157 | 110 | first_time = !config_dir_exists (); | ||
158 | 111 | config_dir = make_config_dir (); | ||
159 | 112 | |||
160 | 113 | /* create master socket name */ | ||
161 | 114 | server_filename = g_build_filename (xpad_app_get_config_dir (), "server", NULL); | ||
162 | 115 | |||
163 | 116 | if (!have_gtk) | ||
164 | 117 | { | ||
165 | 118 | /* We don't have GTK+, but we can still do | ||
166 | 119 | --version or --help and such. Plus, we | ||
167 | 120 | can pass commands to a remote instance. */ | ||
168 | 121 | process_local_args (&xpad_argc, &xpad_argv); | ||
169 | 122 | if (!xpad_app_pass_args ()) | ||
170 | 123 | { | ||
171 | 124 | process_remote_args (&xpad_argc, &xpad_argv, FALSE, settings); | ||
172 | 125 | fprintf (output, "%s\n", _("Xpad is a graphical program. Please run it from your desktop.")); | ||
173 | 126 | } | ||
174 | 127 | exit (0); | ||
175 | 128 | } | ||
176 | 129 | |||
177 | 130 | g_set_application_name (_("Xpad")); | ||
178 | 131 | gdk_set_program_class (PACKAGE); | ||
179 | 132 | |||
180 | 133 | /* Set up program path. */ | ||
181 | 134 | if (xpad_argc > 0) | ||
182 | 135 | program_path = g_find_program_in_path (xpad_argv[0]); | ||
183 | 136 | else | ||
184 | 137 | program_path = NULL; | ||
185 | 138 | |||
186 | 139 | process_local_args (&xpad_argc, &xpad_argv); | ||
187 | 140 | |||
188 | 141 | if (xpad_app_pass_args ()) | ||
189 | 142 | exit (0); | ||
190 | 143 | |||
191 | 144 | /* Race condition here, between calls */ | ||
192 | 145 | xpad_app_open_proc_file (); | ||
193 | 146 | |||
194 | 147 | register_stock_icons (); | ||
195 | 148 | gtk_window_set_default_icon_name (PACKAGE); | ||
196 | 149 | |||
197 | 150 | /* Read the Xpad configuration file from disk (if exists) */ | ||
198 | 151 | settings = xpad_settings_new (); | ||
199 | 152 | |||
200 | 153 | /* Delay program startup, if user configured it, to wait for example for the loading of the systray. */ | ||
201 | 154 | guint autostart_delay; | ||
202 | 155 | g_object_get (settings, "autostart-delay", &autostart_delay, NULL); | ||
203 | 156 | |||
204 | 157 | if (autostart_delay) | ||
205 | 158 | sleep(autostart_delay); | ||
206 | 159 | |||
207 | 160 | pad_group = xpad_pad_group_new(); | ||
208 | 161 | process_remote_args (&xpad_argc, &xpad_argv, TRUE, settings); | ||
209 | 162 | |||
210 | 163 | xpad_tray_init (settings); | ||
211 | 164 | xpad_session_manager_init (); | ||
212 | 165 | |||
213 | 166 | /* Initialize Xpad-periodic module */ | ||
214 | 167 | xpad_periodic_init (); | ||
215 | 168 | xpad_periodic_set_callback ("save-content", (XpadPeriodicFunc) xpad_pad_save_content); | ||
216 | 169 | xpad_periodic_set_callback ("save-info", (XpadPeriodicFunc) xpad_pad_save_info); | ||
217 | 170 | |||
218 | 171 | /* load all pads */ | ||
219 | 172 | pads_loaded_on_start = xpad_app_load_pads (); | ||
220 | 173 | if (pads_loaded_on_start == 0 && !option_new) { | ||
221 | 174 | if (!option_nonew) { | ||
222 | 175 | GtkWidget *pad = xpad_pad_new (pad_group, settings); | ||
223 | 176 | gtk_widget_show (pad); | ||
224 | 177 | } | ||
225 | 178 | } | ||
226 | 179 | |||
227 | 180 | /* Since all pads have been loaded, reprocess the show/hide/toggle option for all pads */ | ||
228 | 181 | if (have_gtk && (option_show)) | ||
229 | 182 | xpad_pad_group_show_all (pad_group); | ||
230 | 183 | if (have_gtk && (option_hide)) | ||
231 | 184 | xpad_pad_group_close_all (pad_group); | ||
232 | 185 | if (have_gtk && option_toggle) | ||
233 | 186 | xpad_pad_group_toggle_hide (pad_group); | ||
234 | 187 | |||
235 | 188 | g_idle_add ((GSourceFunc)xpad_app_first_idle_check, pad_group); | ||
236 | 189 | |||
237 | 190 | if (first_time) | ||
238 | 191 | show_help (); | ||
239 | 192 | |||
240 | 193 | g_free (server_filename); | ||
241 | 194 | server_filename = NULL; | ||
242 | 195 | } | ||
243 | 196 | |||
244 | 197 | gint main (gint argc, gchar **argv) | ||
245 | 198 | { xpad_app_init (argc, argv); | ||
246 | 199 | |||
247 | 200 | gtk_main (); | ||
248 | 201 | |||
249 | 202 | return 0; | ||
250 | 203 | } | ||
273 | 204 | 104 | ||
274 | 205 | /* parent and secondary may be NULL. | 105 | /* parent and secondary may be NULL. |
275 | 206 | * Returns when user dismisses error. | 106 | * Returns when user dismisses error. |
276 | 207 | */ | 107 | */ |
277 | 208 | void | 108 | void |
279 | 209 | xpad_app_error (GtkWindow *parent, const gchar *primary, const gchar *secondary) | 109 | xpad_app_error (GtkWindow *parent, |
280 | 110 | const gchar *primary, | ||
281 | 111 | const gchar *secondary) | ||
282 | 210 | { | 112 | { |
283 | 211 | GtkWidget *dialog; | 113 | GtkWidget *dialog; |
284 | 212 | 114 | ||
285 | @@ -215,7 +117,7 @@ | |||
286 | 215 | 117 | ||
287 | 216 | g_printerr ("%s\n", primary); | 118 | g_printerr ("%s\n", primary); |
288 | 217 | 119 | ||
290 | 218 | dialog = xpad_app_alert_dialog (parent, "dialog-error", primary, secondary); | 120 | dialog = xpad_app_alert_dialog (parent, "dialog-error", primary, secondary); |
291 | 219 | gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Ok"), GTK_RESPONSE_OK, NULL); | 121 | gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Ok"), GTK_RESPONSE_OK, NULL); |
292 | 220 | gtk_dialog_run (GTK_DIALOG (dialog)); | 122 | gtk_dialog_run (GTK_DIALOG (dialog)); |
293 | 221 | gtk_widget_destroy (dialog); | 123 | gtk_widget_destroy (dialog); |
294 | @@ -349,7 +251,10 @@ | |||
295 | 349 | * secondary text of 'secondary'. No buttons are added. | 251 | * secondary text of 'secondary'. No buttons are added. |
296 | 350 | */ | 252 | */ |
297 | 351 | GtkWidget * | 253 | GtkWidget * |
299 | 352 | xpad_app_alert_dialog (GtkWindow *parent, const gchar *icon_name, const gchar *primary, const gchar *secondary) | 254 | xpad_app_alert_dialog (GtkWindow *parent, |
300 | 255 | const gchar *icon_name, | ||
301 | 256 | const gchar *primary, | ||
302 | 257 | const gchar *secondary) | ||
303 | 353 | { | 258 | { |
304 | 354 | GtkWidget *dialog, *hbox, *image, *label; | 259 | GtkWidget *dialog, *hbox, *image, *label; |
305 | 355 | gchar *buf; | 260 | gchar *buf; |
306 | @@ -360,7 +265,7 @@ | |||
307 | 360 | gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); | 265 | gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); |
308 | 361 | 266 | ||
309 | 362 | hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); | 267 | hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); |
311 | 363 | image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DIALOG); | 268 | image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DIALOG); |
312 | 364 | label = gtk_label_new (NULL); | 269 | label = gtk_label_new (NULL); |
313 | 365 | 270 | ||
314 | 366 | if (secondary) | 271 | if (secondary) |
315 | @@ -440,13 +345,13 @@ | |||
316 | 440 | } | 345 | } |
317 | 441 | 346 | ||
318 | 442 | static void | 347 | static void |
320 | 443 | xpad_app_pad_added (XpadPadGroup *group, XpadPad *pad) | 348 | xpad_app_pad_added (XpadPadGroup *group, |
321 | 349 | XpadPad *pad) | ||
322 | 444 | { | 350 | { |
323 | 445 | g_signal_connect_swapped (pad, "closed", G_CALLBACK (xpad_app_quit_if_no_pads), group); | 351 | g_signal_connect_swapped (pad, "closed", G_CALLBACK (xpad_app_quit_if_no_pads), group); |
324 | 446 | g_signal_connect_swapped (pad, "destroy", G_CALLBACK (xpad_app_quit_if_no_pads), group); | 352 | g_signal_connect_swapped (pad, "destroy", G_CALLBACK (xpad_app_quit_if_no_pads), group); |
325 | 447 | } | 353 | } |
326 | 448 | 354 | ||
327 | 449 | |||
328 | 450 | /* Scans config directory for pad files and loads them. */ | 355 | /* Scans config directory for pad files and loads them. */ |
329 | 451 | static gint | 356 | static gint |
330 | 452 | xpad_app_load_pads (void) | 357 | xpad_app_load_pads (void) |
331 | @@ -499,7 +404,9 @@ | |||
332 | 499 | puts allocated string in dest, and returns size | 404 | puts allocated string in dest, and returns size |
333 | 500 | */ | 405 | */ |
334 | 501 | static guint | 406 | static guint |
336 | 502 | args_to_string (int argc, char **argv, char **dest) | 407 | args_to_string (int argc, |
337 | 408 | char **argv, | ||
338 | 409 | char **dest) | ||
339 | 503 | { | 410 | { |
340 | 504 | gint i = 0; | 411 | gint i = 0; |
341 | 505 | guint size = 0; | 412 | guint size = 0; |
342 | @@ -541,7 +448,8 @@ | |||
343 | 541 | returns number of strings in newly allocated argv | 448 | returns number of strings in newly allocated argv |
344 | 542 | */ | 449 | */ |
345 | 543 | static guint | 450 | static guint |
347 | 544 | string_to_args (const char *string, char ***argv) | 451 | string_to_args (const char *string, |
348 | 452 | char ***argv) | ||
349 | 545 | { | 453 | { |
350 | 546 | guint num, i; | 454 | guint num, i; |
351 | 547 | const gchar *tmp; | 455 | const gchar *tmp; |
352 | @@ -589,6 +497,82 @@ | |||
353 | 589 | return num; | 497 | return num; |
354 | 590 | } | 498 | } |
355 | 591 | 499 | ||
356 | 500 | static gboolean | ||
357 | 501 | process_remote_args (gint *argc, | ||
358 | 502 | gchar **argv[], | ||
359 | 503 | gboolean have_gtk, | ||
360 | 504 | XpadSettings *xpad_settings) | ||
361 | 505 | { | ||
362 | 506 | GError *error = NULL; | ||
363 | 507 | GOptionContext *context; | ||
364 | 508 | |||
365 | 509 | option_new = FALSE; | ||
366 | 510 | option_files = NULL; | ||
367 | 511 | option_quit = FALSE; | ||
368 | 512 | option_smid = NULL; | ||
369 | 513 | option_hide = FALSE; | ||
370 | 514 | option_show = FALSE; | ||
371 | 515 | option_toggle = FALSE; | ||
372 | 516 | |||
373 | 517 | context = g_option_context_new (NULL); | ||
374 | 518 | g_option_context_set_ignore_unknown_options (context, TRUE); | ||
375 | 519 | g_option_context_set_help_enabled (context, FALSE); | ||
376 | 520 | g_option_context_add_main_entries (context, remote_options, GETTEXT_PACKAGE); | ||
377 | 521 | if (g_option_context_parse (context, argc, argv, &error)) | ||
378 | 522 | { | ||
379 | 523 | if (have_gtk && option_smid) | ||
380 | 524 | xpad_session_manager_set_id (option_smid); | ||
381 | 525 | |||
382 | 526 | if (!option_new) | ||
383 | 527 | g_object_get (settings, "autostart-new-pad", &option_new, NULL); | ||
384 | 528 | |||
385 | 529 | if (have_gtk && option_new) | ||
386 | 530 | { | ||
387 | 531 | GtkWidget *pad = xpad_pad_new (pad_group, settings); | ||
388 | 532 | gtk_widget_show (pad); | ||
389 | 533 | } | ||
390 | 534 | |||
391 | 535 | if (!option_hide && !option_show) { | ||
392 | 536 | guint display_pads; | ||
393 | 537 | g_object_get (xpad_settings, "autostart-display-pads", &display_pads, NULL); | ||
394 | 538 | if (display_pads == 0) | ||
395 | 539 | option_show = TRUE; | ||
396 | 540 | else if (display_pads == 1) | ||
397 | 541 | option_hide = TRUE; | ||
398 | 542 | } | ||
399 | 543 | |||
400 | 544 | if (have_gtk && option_files) | ||
401 | 545 | { | ||
402 | 546 | int i; | ||
403 | 547 | for (i = 0; option_files[i]; i++) | ||
404 | 548 | { | ||
405 | 549 | GtkWidget *pad = xpad_pad_new_from_file (pad_group, settings, option_files[i]); | ||
406 | 550 | if (pad) | ||
407 | 551 | gtk_widget_show (pad); | ||
408 | 552 | } | ||
409 | 553 | } | ||
410 | 554 | |||
411 | 555 | if (option_quit) | ||
412 | 556 | { | ||
413 | 557 | if (have_gtk && gtk_main_level () > 0) | ||
414 | 558 | xpad_app_quit (); | ||
415 | 559 | else | ||
416 | 560 | exit (0); | ||
417 | 561 | } | ||
418 | 562 | } | ||
419 | 563 | else | ||
420 | 564 | { | ||
421 | 565 | fprintf (output, "%s\n", error->message); | ||
422 | 566 | /* Don't quit. Bad options passed to the main xpad program by other | ||
423 | 567 | iterations shouldn't close the main one. */ | ||
424 | 568 | } | ||
425 | 569 | |||
426 | 570 | g_option_context_free (context); | ||
427 | 571 | |||
428 | 572 | return(option_new || option_quit || option_smid || option_files || | ||
429 | 573 | option_hide || option_show || option_toggle); | ||
430 | 574 | } | ||
431 | 575 | |||
432 | 592 | /* This reads a line from the proc file. This line will contain arguments to process. */ | 576 | /* This reads a line from the proc file. This line will contain arguments to process. */ |
433 | 593 | static void | 577 | static void |
434 | 594 | xpad_app_read_from_proc_file (void) | 578 | xpad_app_read_from_proc_file (void) |
435 | @@ -661,7 +645,9 @@ | |||
436 | 661 | } | 645 | } |
437 | 662 | 646 | ||
438 | 663 | static gboolean | 647 | static gboolean |
440 | 664 | can_read_from_server_fd (GIOChannel *source, GIOCondition condition, gpointer data) | 648 | can_read_from_server_fd (GIOChannel *source, |
441 | 649 | GIOCondition condition, | ||
442 | 650 | gpointer data) | ||
443 | 665 | { | 651 | { |
444 | 666 | /* A dirty way to silence the compiler for these unused variables. */ | 652 | /* A dirty way to silence the compiler for these unused variables. */ |
445 | 667 | (void) source; | 653 | (void) source; |
446 | @@ -702,7 +688,6 @@ | |||
447 | 702 | return TRUE; | 688 | return TRUE; |
448 | 703 | } | 689 | } |
449 | 704 | 690 | ||
450 | 705 | |||
451 | 706 | static gboolean | 691 | static gboolean |
452 | 707 | xpad_app_pass_args (void) | 692 | xpad_app_pass_args (void) |
453 | 708 | { | 693 | { |
454 | @@ -770,31 +755,9 @@ | |||
455 | 770 | return connected; | 755 | return connected; |
456 | 771 | } | 756 | } |
457 | 772 | 757 | ||
458 | 773 | /** | ||
459 | 774 | * Here are the functions called when arguments are passed to us. | ||
460 | 775 | */ | ||
461 | 776 | |||
462 | 777 | static GOptionEntry local_options[] = | ||
463 | 778 | { | ||
464 | 779 | {"version", 'v', 0, G_OPTION_ARG_NONE, &option_version, N_("Show version number and quit"), NULL}, | ||
465 | 780 | {"no-new", 'N', 0, G_OPTION_ARG_NONE, &option_nonew, N_("Don't create a new pad on startup if no previous pads exist"), NULL}, | ||
466 | 781 | {NULL} | ||
467 | 782 | }; | ||
468 | 783 | |||
469 | 784 | static GOptionEntry remote_options[] = | ||
470 | 785 | { | ||
471 | 786 | {"new", 'n', 0, G_OPTION_ARG_NONE, &option_new, N_("Create a new pad on startup even if pads already exist"), NULL}, | ||
472 | 787 | {"hide", 'h', 0, G_OPTION_ARG_NONE, &option_hide, N_("Hide all pads"), NULL}, | ||
473 | 788 | {"show", 's', 0, G_OPTION_ARG_NONE, &option_show, N_("Show all pads"), NULL}, | ||
474 | 789 | {"toggle", 't', 0, G_OPTION_ARG_NONE, &option_toggle, N_("Toggle between show and hide all pads"), NULL}, | ||
475 | 790 | {"new-from-file", 'f', 0, G_OPTION_ARG_FILENAME_ARRAY, &option_files, N_("Create a new pad with the contents of a file"), N_("FILE")}, | ||
476 | 791 | {"quit", 'q', 0, G_OPTION_ARG_NONE, &option_quit, N_("Close all pads"), NULL}, | ||
477 | 792 | {"sm-client-id", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &option_smid, NULL, NULL}, | ||
478 | 793 | {NULL} | ||
479 | 794 | }; | ||
480 | 795 | |||
481 | 796 | static gboolean | 758 | static gboolean |
483 | 797 | process_local_args (gint *argc, gchar **argv[]) | 759 | process_local_args (gint *argc, |
484 | 760 | gchar **argv[]) | ||
485 | 798 | { | 761 | { |
486 | 799 | GError *error = NULL; | 762 | GError *error = NULL; |
487 | 800 | GOptionContext *context; | 763 | GOptionContext *context; |
488 | @@ -836,75 +799,119 @@ | |||
489 | 836 | return (option_version || option_nonew); | 799 | return (option_version || option_nonew); |
490 | 837 | } | 800 | } |
491 | 838 | 801 | ||
494 | 839 | static gboolean | 802 | static void |
495 | 840 | process_remote_args (gint *argc, gchar **argv[], gboolean have_gtk, XpadSettings *xpad_settings) | 803 | xpad_app_init (int argc, |
496 | 804 | char **argv) | ||
497 | 841 | { | 805 | { |
514 | 842 | GError *error = NULL; | 806 | gboolean first_time; |
515 | 843 | GOptionContext *context; | 807 | gboolean have_gtk; |
516 | 844 | 808 | ||
517 | 845 | option_new = FALSE; | 809 | /* Set up support different languages */ |
518 | 846 | option_files = NULL; | 810 | #ifdef ENABLE_NLS |
519 | 847 | option_quit = FALSE; | 811 | bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); |
520 | 848 | option_smid = NULL; | 812 | bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); |
521 | 849 | option_hide = FALSE; | 813 | textdomain (GETTEXT_PACKAGE); |
522 | 850 | option_show = FALSE; | 814 | #endif |
523 | 851 | option_toggle = FALSE; | 815 | |
524 | 852 | 816 | have_gtk = gtk_init_check (&argc, &argv); | |
525 | 853 | context = g_option_context_new (NULL); | 817 | xpad_argc = argc; |
526 | 854 | g_option_context_set_ignore_unknown_options (context, TRUE); | 818 | xpad_argv = argv; |
527 | 855 | g_option_context_set_help_enabled (context, FALSE); | 819 | output = stdout; |
528 | 856 | g_option_context_add_main_entries (context, remote_options, GETTEXT_PACKAGE); | 820 | |
529 | 857 | if (g_option_context_parse (context, argc, argv, &error)) | 821 | /* Set up config directory. */ |
530 | 822 | first_time = !config_dir_exists (); | ||
531 | 823 | config_dir = make_config_dir (); | ||
532 | 824 | |||
533 | 825 | /* create master socket name */ | ||
534 | 826 | server_filename = g_build_filename (xpad_app_get_config_dir (), "server", NULL); | ||
535 | 827 | |||
536 | 828 | if (!have_gtk) | ||
537 | 858 | { | 829 | { |
545 | 859 | if (have_gtk && option_smid) | 830 | /* We don't have GTK+, but we can still do |
546 | 860 | xpad_session_manager_set_id (option_smid); | 831 | --version or --help and such. Plus, we |
547 | 861 | 832 | can pass commands to a remote instance. */ | |
548 | 862 | if (!option_new) | 833 | process_local_args (&xpad_argc, &xpad_argv); |
549 | 863 | g_object_get (settings, "autostart-new-pad", &option_new, NULL); | 834 | if (!xpad_app_pass_args ()) |
543 | 864 | |||
544 | 865 | if (have_gtk && option_new) | ||
550 | 866 | { | 835 | { |
551 | 836 | process_remote_args (&xpad_argc, &xpad_argv, FALSE, settings); | ||
552 | 837 | fprintf (output, "%s\n", _("Xpad is a graphical program. Please run it from your desktop.")); | ||
553 | 838 | } | ||
554 | 839 | exit (0); | ||
555 | 840 | } | ||
556 | 841 | |||
557 | 842 | g_set_application_name (_("Xpad")); | ||
558 | 843 | gdk_set_program_class (PACKAGE); | ||
559 | 844 | |||
560 | 845 | /* Set up program path. */ | ||
561 | 846 | if (xpad_argc > 0) | ||
562 | 847 | program_path = g_find_program_in_path (xpad_argv[0]); | ||
563 | 848 | else | ||
564 | 849 | program_path = NULL; | ||
565 | 850 | |||
566 | 851 | process_local_args (&xpad_argc, &xpad_argv); | ||
567 | 852 | |||
568 | 853 | if (xpad_app_pass_args ()) | ||
569 | 854 | exit (0); | ||
570 | 855 | |||
571 | 856 | /* Race condition here, between calls */ | ||
572 | 857 | xpad_app_open_proc_file (); | ||
573 | 858 | |||
574 | 859 | register_stock_icons (); | ||
575 | 860 | gtk_window_set_default_icon_name (PACKAGE); | ||
576 | 861 | |||
577 | 862 | /* Read the Xpad configuration file from disk (if exists) */ | ||
578 | 863 | settings = xpad_settings_new (); | ||
579 | 864 | |||
580 | 865 | /* Delay program startup, if user configured it, to wait for example for the loading of the systray. */ | ||
581 | 866 | guint autostart_delay; | ||
582 | 867 | g_object_get (settings, "autostart-delay", &autostart_delay, NULL); | ||
583 | 868 | |||
584 | 869 | if (autostart_delay) | ||
585 | 870 | sleep(autostart_delay); | ||
586 | 871 | |||
587 | 872 | pad_group = xpad_pad_group_new(); | ||
588 | 873 | process_remote_args (&xpad_argc, &xpad_argv, TRUE, settings); | ||
589 | 874 | |||
590 | 875 | xpad_tray_init (settings); | ||
591 | 876 | xpad_session_manager_init (); | ||
592 | 877 | |||
593 | 878 | /* Initialize Xpad-periodic module */ | ||
594 | 879 | xpad_periodic_init (); | ||
595 | 880 | xpad_periodic_set_callback ("save-content", (XpadPeriodicFunc) xpad_pad_save_content); | ||
596 | 881 | xpad_periodic_set_callback ("save-info", (XpadPeriodicFunc) xpad_pad_save_info); | ||
597 | 882 | |||
598 | 883 | /* load all pads */ | ||
599 | 884 | pads_loaded_on_start = xpad_app_load_pads (); | ||
600 | 885 | if (pads_loaded_on_start == 0 && !option_new) { | ||
601 | 886 | if (!option_nonew) { | ||
602 | 867 | GtkWidget *pad = xpad_pad_new (pad_group, settings); | 887 | GtkWidget *pad = xpad_pad_new (pad_group, settings); |
603 | 868 | gtk_widget_show (pad); | 888 | gtk_widget_show (pad); |
604 | 869 | } | 889 | } |
645 | 870 | 890 | } | |
646 | 871 | if (!option_hide && !option_show) { | 891 | |
647 | 872 | guint display_pads; | 892 | /* Since all pads have been loaded, reprocess the show/hide/toggle option for all pads */ |
648 | 873 | g_object_get (xpad_settings, "autostart-display-pads", &display_pads, NULL); | 893 | if (have_gtk && (option_show)) |
649 | 874 | if (display_pads == 0) | 894 | xpad_pad_group_show_all (pad_group); |
650 | 875 | option_show = TRUE; | 895 | if (have_gtk && (option_hide)) |
651 | 876 | else if (display_pads == 1) | 896 | xpad_pad_group_close_all (pad_group); |
652 | 877 | option_hide = TRUE; | 897 | if (have_gtk && option_toggle) |
653 | 878 | } | 898 | xpad_pad_group_toggle_hide (pad_group); |
654 | 879 | 899 | ||
655 | 880 | if (have_gtk && option_files) | 900 | g_idle_add ((GSourceFunc)xpad_app_first_idle_check, pad_group); |
656 | 881 | { | 901 | |
657 | 882 | int i; | 902 | if (first_time) |
658 | 883 | for (i = 0; option_files[i]; i++) | 903 | show_help (); |
659 | 884 | { | 904 | |
660 | 885 | GtkWidget *pad = xpad_pad_new_from_file (pad_group, settings, option_files[i]); | 905 | g_free (server_filename); |
661 | 886 | if (pad) | 906 | server_filename = NULL; |
662 | 887 | gtk_widget_show (pad); | 907 | } |
663 | 888 | } | 908 | |
664 | 889 | } | 909 | gint main (gint argc, |
665 | 890 | 910 | gchar **argv) | |
666 | 891 | if (option_quit) | 911 | { |
667 | 892 | { | 912 | xpad_app_init (argc, argv); |
668 | 893 | if (have_gtk && gtk_main_level () > 0) | 913 | |
669 | 894 | xpad_app_quit (); | 914 | gtk_main (); |
670 | 895 | else | 915 | |
671 | 896 | exit (0); | 916 | return 0; |
632 | 897 | } | ||
633 | 898 | } | ||
634 | 899 | else | ||
635 | 900 | { | ||
636 | 901 | fprintf (output, "%s\n", error->message); | ||
637 | 902 | /* Don't quit. Bad options passed to the main xpad program by other | ||
638 | 903 | iterations shouldn't close the main one. */ | ||
639 | 904 | } | ||
640 | 905 | |||
641 | 906 | g_option_context_free (context); | ||
642 | 907 | |||
643 | 908 | return(option_new || option_quit || option_smid || option_files || | ||
644 | 909 | option_hide || option_show || option_toggle); | ||
672 | 910 | } | 917 | } |
673 | 911 | 918 | ||
674 | === modified file 'src/xpad-grip-tool-item.c' | |||
675 | --- src/xpad-grip-tool-item.c 2014-06-17 18:22:49 +0000 | |||
676 | +++ src/xpad-grip-tool-item.c 2014-09-08 13:22:52 +0000 | |||
677 | @@ -20,6 +20,7 @@ | |||
678 | 20 | */ | 20 | */ |
679 | 21 | 21 | ||
680 | 22 | #include "../config.h" | 22 | #include "../config.h" |
681 | 23 | |||
682 | 23 | #include "xpad-grip-tool-item.h" | 24 | #include "xpad-grip-tool-item.h" |
683 | 24 | 25 | ||
684 | 25 | struct XpadGripToolItemPrivate | 26 | struct XpadGripToolItemPrivate |
685 | @@ -29,45 +30,9 @@ | |||
686 | 29 | 30 | ||
687 | 30 | G_DEFINE_TYPE_WITH_PRIVATE(XpadGripToolItem, xpad_grip_tool_item, GTK_TYPE_TOOL_ITEM) | 31 | G_DEFINE_TYPE_WITH_PRIVATE(XpadGripToolItem, xpad_grip_tool_item, GTK_TYPE_TOOL_ITEM) |
688 | 31 | 32 | ||
689 | 32 | static gboolean xpad_grip_tool_item_event_box_draw (GtkWidget *widget, cairo_t *cr); | ||
690 | 33 | static void xpad_grip_tool_item_event_box_realize (GtkWidget *widget); | ||
691 | 34 | static gboolean xpad_grip_tool_item_button_pressed_event (GtkWidget *widget, GdkEventButton *event); | ||
692 | 35 | |||
693 | 36 | GtkToolItem * | ||
694 | 37 | xpad_grip_tool_item_new (void) | ||
695 | 38 | { | ||
696 | 39 | return GTK_TOOL_ITEM (g_object_new (XPAD_TYPE_GRIP_TOOL_ITEM, NULL)); | ||
697 | 40 | } | ||
698 | 41 | |||
699 | 42 | static void | ||
700 | 43 | xpad_grip_tool_item_class_init (XpadGripToolItemClass *klass) | ||
701 | 44 | { | ||
702 | 45 | } | ||
703 | 46 | |||
704 | 47 | static void | ||
705 | 48 | xpad_grip_tool_item_init (XpadGripToolItem *grip) | ||
706 | 49 | { | ||
707 | 50 | GtkWidget *alignment; | ||
708 | 51 | gboolean right; | ||
709 | 52 | |||
710 | 53 | grip->priv = xpad_grip_tool_item_get_instance_private(grip); | ||
711 | 54 | |||
712 | 55 | grip->priv->drawbox = gtk_drawing_area_new (); | ||
713 | 56 | gtk_widget_add_events (grip->priv->drawbox, GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK); | ||
714 | 57 | g_signal_connect (grip->priv->drawbox, "button-press-event", G_CALLBACK (xpad_grip_tool_item_button_pressed_event), NULL); | ||
715 | 58 | g_signal_connect (grip->priv->drawbox, "realize", G_CALLBACK (xpad_grip_tool_item_event_box_realize), NULL); | ||
716 | 59 | g_signal_connect (grip->priv->drawbox, "draw", G_CALLBACK (xpad_grip_tool_item_event_box_draw), NULL); | ||
717 | 60 | gtk_widget_set_size_request (grip->priv->drawbox, 18, 18); | ||
718 | 61 | |||
719 | 62 | right = gtk_widget_get_direction (grip->priv->drawbox) == GTK_TEXT_DIR_LTR; | ||
720 | 63 | alignment = gtk_alignment_new (right ? 1 : 0, 1, 0, 0); | ||
721 | 64 | |||
722 | 65 | gtk_container_add (GTK_CONTAINER (alignment), grip->priv->drawbox); | ||
723 | 66 | gtk_container_add (GTK_CONTAINER (grip), alignment); | ||
724 | 67 | } | ||
725 | 68 | |||
726 | 69 | static gboolean | 33 | static gboolean |
728 | 70 | xpad_grip_tool_item_button_pressed_event (GtkWidget *widget, GdkEventButton *event) | 34 | xpad_grip_tool_item_button_pressed_event (GtkWidget *widget, |
729 | 35 | GdkEventButton *event) | ||
730 | 71 | { | 36 | { |
731 | 72 | if (event->button == 1) | 37 | if (event->button == 1) |
732 | 73 | { | 38 | { |
733 | @@ -105,7 +70,8 @@ | |||
734 | 105 | } | 70 | } |
735 | 106 | 71 | ||
736 | 107 | static gboolean | 72 | static gboolean |
738 | 108 | xpad_grip_tool_item_event_box_draw (GtkWidget *widget, cairo_t *cr) | 73 | xpad_grip_tool_item_event_box_draw (GtkWidget *widget, |
739 | 74 | cairo_t *cr) | ||
740 | 109 | { | 75 | { |
741 | 110 | gtk_render_handle(gtk_widget_get_style_context(widget), | 76 | gtk_render_handle(gtk_widget_get_style_context(widget), |
742 | 111 | cr, | 77 | cr, |
743 | @@ -115,3 +81,36 @@ | |||
744 | 115 | 81 | ||
745 | 116 | return FALSE; | 82 | return FALSE; |
746 | 117 | } | 83 | } |
747 | 84 | |||
748 | 85 | static void | ||
749 | 86 | xpad_grip_tool_item_class_init (XpadGripToolItemClass *klass) | ||
750 | 87 | { | ||
751 | 88 | } | ||
752 | 89 | |||
753 | 90 | static void | ||
754 | 91 | xpad_grip_tool_item_init (XpadGripToolItem *grip) | ||
755 | 92 | { | ||
756 | 93 | GtkWidget *alignment; | ||
757 | 94 | gboolean right; | ||
758 | 95 | |||
759 | 96 | grip->priv = xpad_grip_tool_item_get_instance_private(grip); | ||
760 | 97 | |||
761 | 98 | grip->priv->drawbox = gtk_drawing_area_new (); | ||
762 | 99 | gtk_widget_add_events (grip->priv->drawbox, GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK); | ||
763 | 100 | g_signal_connect (grip->priv->drawbox, "button-press-event", G_CALLBACK (xpad_grip_tool_item_button_pressed_event), NULL); | ||
764 | 101 | g_signal_connect (grip->priv->drawbox, "realize", G_CALLBACK (xpad_grip_tool_item_event_box_realize), NULL); | ||
765 | 102 | g_signal_connect (grip->priv->drawbox, "draw", G_CALLBACK (xpad_grip_tool_item_event_box_draw), NULL); | ||
766 | 103 | gtk_widget_set_size_request (grip->priv->drawbox, 18, 18); | ||
767 | 104 | |||
768 | 105 | right = gtk_widget_get_direction (grip->priv->drawbox) == GTK_TEXT_DIR_LTR; | ||
769 | 106 | alignment = gtk_alignment_new (right ? 1 : 0, 1, 0, 0); | ||
770 | 107 | |||
771 | 108 | gtk_container_add (GTK_CONTAINER (alignment), grip->priv->drawbox); | ||
772 | 109 | gtk_container_add (GTK_CONTAINER (grip), alignment); | ||
773 | 110 | } | ||
774 | 111 | |||
775 | 112 | GtkToolItem * | ||
776 | 113 | xpad_grip_tool_item_new (void) | ||
777 | 114 | { | ||
778 | 115 | return GTK_TOOL_ITEM (g_object_new (XPAD_TYPE_GRIP_TOOL_ITEM, NULL)); | ||
779 | 116 | } | ||
780 | 118 | 117 | ||
781 | === modified file 'src/xpad-pad-group.c' | |||
782 | --- src/xpad-pad-group.c 2014-07-23 10:03:02 +0000 | |||
783 | +++ src/xpad-pad-group.c 2014-09-08 13:22:52 +0000 | |||
784 | @@ -21,6 +21,7 @@ | |||
785 | 21 | */ | 21 | */ |
786 | 22 | 22 | ||
787 | 23 | #include "../config.h" | 23 | #include "../config.h" |
788 | 24 | |||
789 | 24 | #include "xpad-pad-group.h" | 25 | #include "xpad-pad-group.h" |
790 | 25 | #include "xpad-pad.h" | 26 | #include "xpad-pad.h" |
791 | 26 | 27 | ||
792 | @@ -31,8 +32,6 @@ | |||
793 | 31 | 32 | ||
794 | 32 | G_DEFINE_TYPE_WITH_PRIVATE (XpadPadGroup, xpad_pad_group, G_TYPE_OBJECT) | 33 | G_DEFINE_TYPE_WITH_PRIVATE (XpadPadGroup, xpad_pad_group, G_TYPE_OBJECT) |
795 | 33 | 34 | ||
796 | 34 | static void xpad_pad_group_save_unsaved_all (XpadPadGroup *group); | ||
797 | 35 | |||
798 | 36 | enum { | 35 | enum { |
799 | 37 | PROP_0 | 36 | PROP_0 |
800 | 38 | }; | 37 | }; |
801 | @@ -75,7 +74,7 @@ | |||
802 | 75 | G_TYPE_NONE, | 74 | G_TYPE_NONE, |
803 | 76 | 1, | 75 | 1, |
804 | 77 | GTK_TYPE_WIDGET); | 76 | GTK_TYPE_WIDGET); |
806 | 78 | 77 | ||
807 | 79 | signals[PAD_REMOVED] = | 78 | signals[PAD_REMOVED] = |
808 | 80 | g_signal_new ("pad_removed", | 79 | g_signal_new ("pad_removed", |
809 | 81 | G_OBJECT_CLASS_TYPE (object_class), | 80 | G_OBJECT_CLASS_TYPE (object_class), |
810 | @@ -96,10 +95,11 @@ | |||
811 | 96 | 95 | ||
812 | 97 | /* Add a pad to this group */ | 96 | /* Add a pad to this group */ |
813 | 98 | void | 97 | void |
815 | 99 | xpad_pad_group_add (XpadPadGroup *group, GtkWidget *pad) | 98 | xpad_pad_group_add (XpadPadGroup *group, |
816 | 99 | GtkWidget *pad) | ||
817 | 100 | { | 100 | { |
818 | 101 | g_object_ref(pad); | 101 | g_object_ref(pad); |
820 | 102 | 102 | ||
821 | 103 | group->priv->pads = g_slist_append (group->priv->pads, XPAD_PAD (pad)); | 103 | group->priv->pads = g_slist_append (group->priv->pads, XPAD_PAD (pad)); |
822 | 104 | g_signal_connect_swapped (pad, "destroy", G_CALLBACK (xpad_pad_group_remove), group); | 104 | g_signal_connect_swapped (pad, "destroy", G_CALLBACK (xpad_pad_group_remove), group); |
823 | 105 | 105 | ||
824 | @@ -108,7 +108,8 @@ | |||
825 | 108 | 108 | ||
826 | 109 | /* Remove a pad from this group */ | 109 | /* Remove a pad from this group */ |
827 | 110 | void | 110 | void |
829 | 111 | xpad_pad_group_remove (XpadPadGroup *group, GtkWidget *pad) | 111 | xpad_pad_group_remove (XpadPadGroup *group, |
830 | 112 | GtkWidget *pad) | ||
831 | 112 | { | 113 | { |
832 | 113 | group->priv->pads = g_slist_remove (group->priv->pads, XPAD_PAD (pad)); | 114 | group->priv->pads = g_slist_remove (group->priv->pads, XPAD_PAD (pad)); |
833 | 114 | g_object_unref(pad); | 115 | g_object_unref(pad); |
834 | @@ -117,6 +118,13 @@ | |||
835 | 117 | g_signal_emit (group, signals[PAD_REMOVED], 0, pad); | 118 | g_signal_emit (group, signals[PAD_REMOVED], 0, pad); |
836 | 118 | } | 119 | } |
837 | 119 | 120 | ||
838 | 121 | static void | ||
839 | 122 | xpad_pad_group_save_unsaved_all (XpadPadGroup *group) | ||
840 | 123 | { | ||
841 | 124 | if (group) | ||
842 | 125 | g_slist_foreach (group->priv->pads, (GFunc) xpad_pad_save_unsaved, NULL); | ||
843 | 126 | } | ||
844 | 127 | |||
845 | 120 | /* Delete all the current pads in the group */ | 128 | /* Delete all the current pads in the group */ |
846 | 121 | void | 129 | void |
847 | 122 | xpad_pad_group_destroy_pads (XpadPadGroup *group) | 130 | xpad_pad_group_destroy_pads (XpadPadGroup *group) |
848 | @@ -146,14 +154,10 @@ | |||
849 | 146 | } | 154 | } |
850 | 147 | g_slist_free(i); | 155 | g_slist_free(i); |
851 | 148 | } | 156 | } |
852 | 157 | |||
853 | 149 | return num; | 158 | return num; |
854 | 150 | } | 159 | } |
855 | 151 | 160 | ||
856 | 152 | static void xpad_pad_group_save_unsaved_all (XpadPadGroup *group) { | ||
857 | 153 | if (group) | ||
858 | 154 | g_slist_foreach (group->priv->pads, (GFunc) xpad_pad_save_unsaved, NULL); | ||
859 | 155 | } | ||
860 | 156 | |||
861 | 157 | void | 161 | void |
862 | 158 | xpad_pad_group_close_all (XpadPadGroup *group) | 162 | xpad_pad_group_close_all (XpadPadGroup *group) |
863 | 159 | { | 163 | { |
864 | 160 | 164 | ||
865 | === modified file 'src/xpad-pad-properties.c' | |||
866 | --- src/xpad-pad-properties.c 2014-06-19 12:35:19 +0000 | |||
867 | +++ src/xpad-pad-properties.c 2014-09-08 13:22:52 +0000 | |||
868 | @@ -21,44 +21,35 @@ | |||
869 | 21 | 21 | ||
870 | 22 | #include "../config.h" | 22 | #include "../config.h" |
871 | 23 | #include "xpad-pad-properties.h" | 23 | #include "xpad-pad-properties.h" |
872 | 24 | #include <gtk/gtk.h> | ||
873 | 24 | #include <glib/gi18n.h> | 25 | #include <glib/gi18n.h> |
874 | 25 | #include <gtk/gtk.h> | ||
875 | 26 | 26 | ||
876 | 27 | struct XpadPadPropertiesPrivate | 27 | struct XpadPadPropertiesPrivate |
877 | 28 | { | 28 | { |
878 | 29 | GtkWidget *fontcheck; | 29 | GtkWidget *fontcheck; |
879 | 30 | GtkWidget *colorcheck; | 30 | GtkWidget *colorcheck; |
880 | 31 | GtkWidget *colorbox; | 31 | GtkWidget *colorbox; |
882 | 32 | 32 | ||
883 | 33 | GtkWidget *textbutton; | 33 | GtkWidget *textbutton; |
884 | 34 | GdkRGBA texttmp; | 34 | GdkRGBA texttmp; |
886 | 35 | 35 | ||
887 | 36 | GtkWidget *backbutton; | 36 | GtkWidget *backbutton; |
888 | 37 | GdkRGBA backtmp; | 37 | GdkRGBA backtmp; |
890 | 38 | 38 | ||
891 | 39 | GtkWidget *fontbutton; | 39 | GtkWidget *fontbutton; |
892 | 40 | }; | 40 | }; |
893 | 41 | 41 | ||
894 | 42 | G_DEFINE_TYPE_WITH_PRIVATE (XpadPadProperties, xpad_pad_properties, GTK_TYPE_DIALOG) | 42 | G_DEFINE_TYPE_WITH_PRIVATE (XpadPadProperties, xpad_pad_properties, GTK_TYPE_DIALOG) |
895 | 43 | 43 | ||
896 | 44 | static void xpad_pad_properties_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); | ||
897 | 45 | static void xpad_pad_properties_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); | ||
898 | 46 | static void xpad_pad_properties_response (GtkDialog *dialog, gint response); | ||
899 | 47 | static void change_color_check (GtkToggleButton *button, XpadPadProperties *prop); | ||
900 | 48 | static void change_font_check (GtkToggleButton *button, XpadPadProperties *prop); | ||
901 | 49 | static void change_text_color (XpadPadProperties *prop); | ||
902 | 50 | static void change_back_color (XpadPadProperties *prop); | ||
903 | 51 | static void change_font_face (XpadPadProperties *prop); | ||
904 | 52 | |||
905 | 53 | enum | 44 | enum |
906 | 54 | { | 45 | { |
914 | 55 | PROP_0, | 46 | PROP_0, |
915 | 56 | PROP_FOLLOW_FONT_STYLE, | 47 | PROP_FOLLOW_FONT_STYLE, |
916 | 57 | PROP_FOLLOW_COLOR_STYLE, | 48 | PROP_FOLLOW_COLOR_STYLE, |
917 | 58 | PROP_BACK_COLOR, | 49 | PROP_BACK_COLOR, |
918 | 59 | PROP_TEXT_COLOR, | 50 | PROP_TEXT_COLOR, |
919 | 60 | PROP_FONTNAME, | 51 | PROP_FONTNAME, |
920 | 61 | N_PROPERTIES | 52 | N_PROPERTIES |
921 | 62 | }; | 53 | }; |
922 | 63 | 54 | ||
923 | 64 | static GParamSpec *obj_prop[N_PROPERTIES] = { NULL, }; | 55 | static GParamSpec *obj_prop[N_PROPERTIES] = { NULL, }; |
924 | @@ -69,6 +60,125 @@ | |||
925 | 69 | return g_object_new (XPAD_TYPE_PAD_PROPERTIES, NULL); | 60 | return g_object_new (XPAD_TYPE_PAD_PROPERTIES, NULL); |
926 | 70 | } | 61 | } |
927 | 71 | 62 | ||
928 | 63 | |||
929 | 64 | static void | ||
930 | 65 | xpad_pad_properties_response (GtkDialog *dialog, | ||
931 | 66 | gint response) | ||
932 | 67 | { | ||
933 | 68 | if (response == GTK_RESPONSE_CLOSE) | ||
934 | 69 | gtk_widget_destroy (GTK_WIDGET (dialog)); | ||
935 | 70 | } | ||
936 | 71 | |||
937 | 72 | static void | ||
938 | 73 | change_font_check (GtkToggleButton *button, | ||
939 | 74 | XpadPadProperties *prop) | ||
940 | 75 | { | ||
941 | 76 | gtk_widget_set_sensitive (prop->priv->fontbutton, gtk_toggle_button_get_active (button)); | ||
942 | 77 | |||
943 | 78 | g_object_notify (G_OBJECT (prop), "follow-font-style"); | ||
944 | 79 | } | ||
945 | 80 | |||
946 | 81 | static void | ||
947 | 82 | change_color_check (GtkToggleButton *button, | ||
948 | 83 | XpadPadProperties *prop) | ||
949 | 84 | { | ||
950 | 85 | gtk_widget_set_sensitive (prop->priv->colorbox, gtk_toggle_button_get_active (button)); | ||
951 | 86 | |||
952 | 87 | g_object_notify (G_OBJECT (prop), "follow-color-style"); | ||
953 | 88 | } | ||
954 | 89 | |||
955 | 90 | static void | ||
956 | 91 | change_text_color (XpadPadProperties *prop) | ||
957 | 92 | { | ||
958 | 93 | g_object_notify (G_OBJECT (prop), "text-color"); | ||
959 | 94 | } | ||
960 | 95 | |||
961 | 96 | static void | ||
962 | 97 | change_back_color (XpadPadProperties *prop) | ||
963 | 98 | { | ||
964 | 99 | g_object_notify (G_OBJECT (prop), "back-color"); | ||
965 | 100 | } | ||
966 | 101 | |||
967 | 102 | static void | ||
968 | 103 | change_font_face (XpadPadProperties *prop) | ||
969 | 104 | { | ||
970 | 105 | g_object_notify (G_OBJECT (prop), "fontname"); | ||
971 | 106 | } | ||
972 | 107 | |||
973 | 108 | static void | ||
974 | 109 | xpad_pad_properties_set_property (GObject *object, | ||
975 | 110 | guint prop_id, | ||
976 | 111 | const GValue *value, | ||
977 | 112 | GParamSpec *pspec) | ||
978 | 113 | { | ||
979 | 114 | XpadPadProperties *prop = XPAD_PAD_PROPERTIES (object); | ||
980 | 115 | |||
981 | 116 | switch (prop_id) | ||
982 | 117 | { | ||
983 | 118 | case PROP_FOLLOW_FONT_STYLE: | ||
984 | 119 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop->priv->fontcheck), !g_value_get_boolean (value)); | ||
985 | 120 | break; | ||
986 | 121 | |||
987 | 122 | case PROP_FOLLOW_COLOR_STYLE: | ||
988 | 123 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop->priv->colorcheck), !g_value_get_boolean (value)); | ||
989 | 124 | break; | ||
990 | 125 | |||
991 | 126 | case PROP_BACK_COLOR: | ||
992 | 127 | gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (prop->priv->backbutton), g_value_get_boxed (value)); | ||
993 | 128 | break; | ||
994 | 129 | |||
995 | 130 | case PROP_TEXT_COLOR: | ||
996 | 131 | gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (prop->priv->textbutton), g_value_get_boxed (value)); | ||
997 | 132 | break; | ||
998 | 133 | |||
999 | 134 | case PROP_FONTNAME: | ||
1000 | 135 | gtk_font_button_set_font_name (GTK_FONT_BUTTON (prop->priv->fontbutton), g_value_get_string (value)); | ||
1001 | 136 | break; | ||
1002 | 137 | |||
1003 | 138 | default: | ||
1004 | 139 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
1005 | 140 | break; | ||
1006 | 141 | } | ||
1007 | 142 | } | ||
1008 | 143 | |||
1009 | 144 | static void | ||
1010 | 145 | xpad_pad_properties_get_property (GObject *object, | ||
1011 | 146 | guint prop_id, | ||
1012 | 147 | GValue *value, | ||
1013 | 148 | GParamSpec *pspec) | ||
1014 | 149 | { | ||
1015 | 150 | XpadPadProperties *prop = XPAD_PAD_PROPERTIES (object); | ||
1016 | 151 | |||
1017 | 152 | switch (prop_id) | ||
1018 | 153 | { | ||
1019 | 154 | case PROP_FOLLOW_FONT_STYLE: | ||
1020 | 155 | g_value_set_boolean (value, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop->priv->fontcheck))); | ||
1021 | 156 | break; | ||
1022 | 157 | |||
1023 | 158 | case PROP_FOLLOW_COLOR_STYLE: | ||
1024 | 159 | g_value_set_boolean (value, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop->priv->colorcheck))); | ||
1025 | 160 | break; | ||
1026 | 161 | |||
1027 | 162 | case PROP_BACK_COLOR: | ||
1028 | 163 | gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (prop->priv->backbutton), &prop->priv->backtmp); | ||
1029 | 164 | g_value_set_static_boxed (value, &prop->priv->backtmp); | ||
1030 | 165 | break; | ||
1031 | 166 | |||
1032 | 167 | case PROP_TEXT_COLOR: | ||
1033 | 168 | gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (prop->priv->textbutton), &prop->priv->texttmp); | ||
1034 | 169 | g_value_set_static_boxed (value, &prop->priv->texttmp); | ||
1035 | 170 | break; | ||
1036 | 171 | |||
1037 | 172 | case PROP_FONTNAME: | ||
1038 | 173 | g_value_set_string (value, gtk_font_button_get_font_name (GTK_FONT_BUTTON (prop->priv->fontbutton))); | ||
1039 | 174 | break; | ||
1040 | 175 | |||
1041 | 176 | default: | ||
1042 | 177 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
1043 | 178 | break; | ||
1044 | 179 | } | ||
1045 | 180 | } | ||
1046 | 181 | |||
1047 | 72 | static void | 182 | static void |
1048 | 73 | xpad_pad_properties_class_init (XpadPadPropertiesClass *klass) | 183 | xpad_pad_properties_class_init (XpadPadPropertiesClass *klass) |
1049 | 74 | { | 184 | { |
1050 | @@ -93,9 +203,9 @@ | |||
1051 | 93 | GtkBox *hbox, *font_hbox, *vbox, *appearance_vbox; | 203 | GtkBox *hbox, *font_hbox, *vbox, *appearance_vbox; |
1052 | 94 | GtkWidget *font_radio, *color_radio, *label, *appearance_frame, *alignment; | 204 | GtkWidget *font_radio, *color_radio, *label, *appearance_frame, *alignment; |
1053 | 95 | GtkSizeGroup *size_group_labels = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); | 205 | GtkSizeGroup *size_group_labels = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); |
1055 | 96 | 206 | ||
1056 | 97 | prop->priv = xpad_pad_properties_get_instance_private (prop); | 207 | prop->priv = xpad_pad_properties_get_instance_private (prop); |
1058 | 98 | 208 | ||
1059 | 99 | text = g_strconcat ("<b>", _("Appearance"), "</b>", NULL); | 209 | text = g_strconcat ("<b>", _("Appearance"), "</b>", NULL); |
1060 | 100 | label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL, | 210 | label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL, |
1061 | 101 | "label", text, | 211 | "label", text, |
1062 | @@ -119,7 +229,7 @@ | |||
1063 | 119 | "child", alignment, | 229 | "child", alignment, |
1064 | 120 | "border-width", 6, | 230 | "border-width", 6, |
1065 | 121 | NULL)); | 231 | NULL)); |
1067 | 122 | 232 | ||
1068 | 123 | prop->priv->fontbutton = gtk_font_button_new (); | 233 | prop->priv->fontbutton = gtk_font_button_new (); |
1069 | 124 | prop->priv->textbutton = gtk_color_button_new (); | 234 | prop->priv->textbutton = gtk_color_button_new (); |
1070 | 125 | prop->priv->backbutton = gtk_color_button_new (); | 235 | prop->priv->backbutton = gtk_color_button_new (); |
1071 | @@ -133,7 +243,7 @@ | |||
1072 | 133 | 243 | ||
1073 | 134 | gtk_box_pack_start (font_hbox, prop->priv->fontcheck, FALSE, FALSE, 0); | 244 | gtk_box_pack_start (font_hbox, prop->priv->fontcheck, FALSE, FALSE, 0); |
1074 | 135 | gtk_box_pack_start (font_hbox, prop->priv->fontbutton, TRUE, TRUE, 0); | 245 | gtk_box_pack_start (font_hbox, prop->priv->fontbutton, TRUE, TRUE, 0); |
1076 | 136 | 246 | ||
1077 | 137 | prop->priv->colorbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); | 247 | prop->priv->colorbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); |
1078 | 138 | 248 | ||
1079 | 139 | hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12)); | 249 | hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12)); |
1080 | @@ -143,7 +253,7 @@ | |||
1081 | 143 | gtk_box_pack_start (hbox, label, FALSE, FALSE, 0); | 253 | gtk_box_pack_start (hbox, label, FALSE, FALSE, 0); |
1082 | 144 | gtk_box_pack_start (hbox, prop->priv->textbutton, TRUE, TRUE, 0); | 254 | gtk_box_pack_start (hbox, prop->priv->textbutton, TRUE, TRUE, 0); |
1083 | 145 | g_object_set (G_OBJECT (prop->priv->colorbox), "child", hbox, NULL); | 255 | g_object_set (G_OBJECT (prop->priv->colorbox), "child", hbox, NULL); |
1085 | 146 | 256 | ||
1086 | 147 | hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12)); | 257 | hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12)); |
1087 | 148 | label = gtk_label_new_with_mnemonic (_("Background:")); | 258 | label = gtk_label_new_with_mnemonic (_("Background:")); |
1088 | 149 | gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); | 259 | gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); |
1089 | @@ -151,22 +261,22 @@ | |||
1090 | 151 | gtk_box_pack_start (hbox, label, FALSE, FALSE, 0); | 261 | gtk_box_pack_start (hbox, label, FALSE, FALSE, 0); |
1091 | 152 | gtk_box_pack_start (hbox, prop->priv->backbutton, TRUE, TRUE, 0); | 262 | gtk_box_pack_start (hbox, prop->priv->backbutton, TRUE, TRUE, 0); |
1092 | 153 | g_object_set (G_OBJECT (prop->priv->colorbox), "child", hbox, NULL); | 263 | g_object_set (G_OBJECT (prop->priv->colorbox), "child", hbox, NULL); |
1094 | 154 | 264 | ||
1095 | 155 | alignment = gtk_alignment_new (1, 1, 1, 1); | 265 | alignment = gtk_alignment_new (1, 1, 1, 1); |
1096 | 156 | gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0); | 266 | gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0); |
1097 | 157 | gtk_container_add (GTK_CONTAINER (alignment), prop->priv->colorbox); | 267 | gtk_container_add (GTK_CONTAINER (alignment), prop->priv->colorbox); |
1099 | 158 | 268 | ||
1100 | 159 | gtk_dialog_add_button (GTK_DIALOG (prop), "gtk-close", GTK_RESPONSE_CLOSE); | 269 | gtk_dialog_add_button (GTK_DIALOG (prop), "gtk-close", GTK_RESPONSE_CLOSE); |
1101 | 160 | gtk_dialog_set_default_response (GTK_DIALOG (prop), GTK_RESPONSE_CLOSE); | 270 | gtk_dialog_set_default_response (GTK_DIALOG (prop), GTK_RESPONSE_CLOSE); |
1102 | 161 | g_signal_connect (prop, "response", G_CALLBACK (xpad_pad_properties_response), NULL); | 271 | g_signal_connect (prop, "response", G_CALLBACK (xpad_pad_properties_response), NULL); |
1104 | 162 | 272 | ||
1105 | 163 | gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (prop->priv->textbutton), FALSE); | 273 | gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (prop->priv->textbutton), FALSE); |
1106 | 164 | gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (prop->priv->backbutton), TRUE); | 274 | gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (prop->priv->backbutton), TRUE); |
1108 | 165 | 275 | ||
1109 | 166 | gtk_color_button_set_title (GTK_COLOR_BUTTON (prop->priv->textbutton), _("Set Foreground Color")); | 276 | gtk_color_button_set_title (GTK_COLOR_BUTTON (prop->priv->textbutton), _("Set Foreground Color")); |
1110 | 167 | gtk_color_button_set_title (GTK_COLOR_BUTTON (prop->priv->backbutton), _("Set Background Color")); | 277 | gtk_color_button_set_title (GTK_COLOR_BUTTON (prop->priv->backbutton), _("Set Background Color")); |
1111 | 168 | gtk_font_button_set_title (GTK_FONT_BUTTON (prop->priv->fontbutton), _("Set Font")); | 278 | gtk_font_button_set_title (GTK_FONT_BUTTON (prop->priv->fontbutton), _("Set Font")); |
1113 | 169 | 279 | ||
1114 | 170 | vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6)); | 280 | vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6)); |
1115 | 171 | hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12)); | 281 | hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12)); |
1116 | 172 | 282 | ||
1117 | @@ -180,131 +290,22 @@ | |||
1118 | 180 | gtk_box_pack_start (vbox, prop->priv->colorcheck, FALSE, FALSE, 0); | 290 | gtk_box_pack_start (vbox, prop->priv->colorcheck, FALSE, FALSE, 0); |
1119 | 181 | gtk_box_pack_start (vbox, alignment, FALSE, FALSE, 0); | 291 | gtk_box_pack_start (vbox, alignment, FALSE, FALSE, 0); |
1120 | 182 | gtk_box_pack_start (appearance_vbox, GTK_WIDGET (vbox), FALSE, FALSE, 0); | 292 | gtk_box_pack_start (appearance_vbox, GTK_WIDGET (vbox), FALSE, FALSE, 0); |
1122 | 183 | 293 | ||
1123 | 184 | g_signal_connect (prop->priv->fontcheck, "toggled", G_CALLBACK (change_font_check), prop); | 294 | g_signal_connect (prop->priv->fontcheck, "toggled", G_CALLBACK (change_font_check), prop); |
1124 | 185 | g_signal_connect (prop->priv->colorcheck, "toggled", G_CALLBACK (change_color_check), prop); | 295 | g_signal_connect (prop->priv->colorcheck, "toggled", G_CALLBACK (change_color_check), prop); |
1125 | 186 | g_signal_connect_swapped (prop->priv->fontbutton, "font-set", G_CALLBACK (change_font_face), prop); | 296 | g_signal_connect_swapped (prop->priv->fontbutton, "font-set", G_CALLBACK (change_font_face), prop); |
1126 | 187 | g_signal_connect_swapped (prop->priv->textbutton, "color-set", G_CALLBACK (change_text_color), prop); | 297 | g_signal_connect_swapped (prop->priv->textbutton, "color-set", G_CALLBACK (change_text_color), prop); |
1127 | 188 | g_signal_connect_swapped (prop->priv->backbutton, "color-set", G_CALLBACK (change_back_color), prop); | 298 | g_signal_connect_swapped (prop->priv->backbutton, "color-set", G_CALLBACK (change_back_color), prop); |
1129 | 189 | 299 | ||
1130 | 190 | /* Setup initial state, which should never be seen, but just in case client doesn't set them itself, we'll be consistent. */ | 300 | /* Setup initial state, which should never be seen, but just in case client doesn't set them itself, we'll be consistent. */ |
1131 | 191 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (font_radio), TRUE); | 301 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (font_radio), TRUE); |
1132 | 192 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (color_radio), TRUE); | 302 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (color_radio), TRUE); |
1133 | 193 | gtk_widget_set_sensitive (prop->priv->colorbox, FALSE); | 303 | gtk_widget_set_sensitive (prop->priv->colorbox, FALSE); |
1134 | 194 | gtk_widget_set_sensitive (prop->priv->fontbutton, FALSE); | 304 | gtk_widget_set_sensitive (prop->priv->fontbutton, FALSE); |
1136 | 195 | 305 | ||
1137 | 196 | g_object_unref (size_group_labels); | 306 | g_object_unref (size_group_labels); |
1139 | 197 | 307 | ||
1140 | 198 | gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (prop))), appearance_frame); | 308 | gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (prop))), appearance_frame); |
1141 | 199 | 309 | ||
1142 | 200 | gtk_widget_show_all (gtk_dialog_get_content_area (GTK_DIALOG (prop))); | 310 | gtk_widget_show_all (gtk_dialog_get_content_area (GTK_DIALOG (prop))); |
1143 | 201 | } | 311 | } |
1144 | 202 | |||
1145 | 203 | static void | ||
1146 | 204 | xpad_pad_properties_response (GtkDialog *dialog, gint response) | ||
1147 | 205 | { | ||
1148 | 206 | if (response == GTK_RESPONSE_CLOSE) | ||
1149 | 207 | gtk_widget_destroy (GTK_WIDGET (dialog)); | ||
1150 | 208 | } | ||
1151 | 209 | |||
1152 | 210 | static void | ||
1153 | 211 | change_font_check (GtkToggleButton *button, XpadPadProperties *prop) | ||
1154 | 212 | { | ||
1155 | 213 | gtk_widget_set_sensitive (prop->priv->fontbutton, gtk_toggle_button_get_active (button)); | ||
1156 | 214 | |||
1157 | 215 | g_object_notify (G_OBJECT (prop), "follow-font-style"); | ||
1158 | 216 | } | ||
1159 | 217 | |||
1160 | 218 | static void | ||
1161 | 219 | change_color_check (GtkToggleButton *button, XpadPadProperties *prop) | ||
1162 | 220 | { | ||
1163 | 221 | gtk_widget_set_sensitive (prop->priv->colorbox, gtk_toggle_button_get_active (button)); | ||
1164 | 222 | |||
1165 | 223 | g_object_notify (G_OBJECT (prop), "follow-color-style"); | ||
1166 | 224 | } | ||
1167 | 225 | |||
1168 | 226 | static void | ||
1169 | 227 | change_text_color (XpadPadProperties *prop) | ||
1170 | 228 | { | ||
1171 | 229 | g_object_notify (G_OBJECT (prop), "text-color"); | ||
1172 | 230 | } | ||
1173 | 231 | |||
1174 | 232 | static void | ||
1175 | 233 | change_back_color (XpadPadProperties *prop) | ||
1176 | 234 | { | ||
1177 | 235 | g_object_notify (G_OBJECT (prop), "back-color"); | ||
1178 | 236 | } | ||
1179 | 237 | |||
1180 | 238 | static void | ||
1181 | 239 | change_font_face (XpadPadProperties *prop) | ||
1182 | 240 | { | ||
1183 | 241 | g_object_notify (G_OBJECT (prop), "fontname"); | ||
1184 | 242 | } | ||
1185 | 243 | |||
1186 | 244 | static void | ||
1187 | 245 | xpad_pad_properties_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) | ||
1188 | 246 | { | ||
1189 | 247 | XpadPadProperties *prop = XPAD_PAD_PROPERTIES (object); | ||
1190 | 248 | |||
1191 | 249 | switch (prop_id) | ||
1192 | 250 | { | ||
1193 | 251 | case PROP_FOLLOW_FONT_STYLE: | ||
1194 | 252 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop->priv->fontcheck), !g_value_get_boolean (value)); | ||
1195 | 253 | break; | ||
1196 | 254 | |||
1197 | 255 | case PROP_FOLLOW_COLOR_STYLE: | ||
1198 | 256 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop->priv->colorcheck), !g_value_get_boolean (value)); | ||
1199 | 257 | break; | ||
1200 | 258 | |||
1201 | 259 | case PROP_BACK_COLOR: | ||
1202 | 260 | gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (prop->priv->backbutton), g_value_get_boxed (value)); | ||
1203 | 261 | break; | ||
1204 | 262 | |||
1205 | 263 | case PROP_TEXT_COLOR: | ||
1206 | 264 | gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (prop->priv->textbutton), g_value_get_boxed (value)); | ||
1207 | 265 | break; | ||
1208 | 266 | |||
1209 | 267 | case PROP_FONTNAME: | ||
1210 | 268 | gtk_font_button_set_font_name (GTK_FONT_BUTTON (prop->priv->fontbutton), g_value_get_string (value)); | ||
1211 | 269 | break; | ||
1212 | 270 | |||
1213 | 271 | default: | ||
1214 | 272 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
1215 | 273 | break; | ||
1216 | 274 | } | ||
1217 | 275 | } | ||
1218 | 276 | |||
1219 | 277 | static void | ||
1220 | 278 | xpad_pad_properties_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) | ||
1221 | 279 | { | ||
1222 | 280 | XpadPadProperties *prop = XPAD_PAD_PROPERTIES (object); | ||
1223 | 281 | |||
1224 | 282 | switch (prop_id) | ||
1225 | 283 | { | ||
1226 | 284 | case PROP_FOLLOW_FONT_STYLE: | ||
1227 | 285 | g_value_set_boolean (value, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop->priv->fontcheck))); | ||
1228 | 286 | break; | ||
1229 | 287 | |||
1230 | 288 | case PROP_FOLLOW_COLOR_STYLE: | ||
1231 | 289 | g_value_set_boolean (value, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop->priv->colorcheck))); | ||
1232 | 290 | break; | ||
1233 | 291 | |||
1234 | 292 | case PROP_BACK_COLOR: | ||
1235 | 293 | gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (prop->priv->backbutton), &prop->priv->backtmp); | ||
1236 | 294 | g_value_set_static_boxed (value, &prop->priv->backtmp); | ||
1237 | 295 | break; | ||
1238 | 296 | |||
1239 | 297 | case PROP_TEXT_COLOR: | ||
1240 | 298 | gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (prop->priv->textbutton), &prop->priv->texttmp); | ||
1241 | 299 | g_value_set_static_boxed (value, &prop->priv->texttmp); | ||
1242 | 300 | break; | ||
1243 | 301 | |||
1244 | 302 | case PROP_FONTNAME: | ||
1245 | 303 | g_value_set_string (value, gtk_font_button_get_font_name (GTK_FONT_BUTTON (prop->priv->fontbutton))); | ||
1246 | 304 | break; | ||
1247 | 305 | |||
1248 | 306 | default: | ||
1249 | 307 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
1250 | 308 | break; | ||
1251 | 309 | } | ||
1252 | 310 | } | ||
1253 | 311 | 312 | ||
1254 | === modified file 'src/xpad-pad.c' | |||
1255 | --- src/xpad-pad.c 2014-08-30 18:36:57 +0000 | |||
1256 | +++ src/xpad-pad.c 2014-09-08 13:22:52 +0000 | |||
1257 | @@ -24,9 +24,8 @@ | |||
1258 | 24 | */ | 24 | */ |
1259 | 25 | 25 | ||
1260 | 26 | #include "../config.h" | 26 | #include "../config.h" |
1261 | 27 | |||
1262 | 27 | #include "xpad-pad.h" | 28 | #include "xpad-pad.h" |
1263 | 28 | #include <gtk/gtk.h> | ||
1264 | 29 | #include <glib/gi18n.h> | ||
1265 | 30 | #include "fio.h" | 29 | #include "fio.h" |
1266 | 31 | #include "help.h" | 30 | #include "help.h" |
1267 | 32 | #include "xpad-app.h" | 31 | #include "xpad-app.h" |
1268 | @@ -38,6 +37,9 @@ | |||
1269 | 38 | #include "xpad-toolbar.h" | 37 | #include "xpad-toolbar.h" |
1270 | 39 | #include "xpad-tray.h" | 38 | #include "xpad-tray.h" |
1271 | 40 | 39 | ||
1272 | 40 | #include <gtk/gtk.h> | ||
1273 | 41 | #include <glib/gi18n.h> | ||
1274 | 42 | |||
1275 | 41 | struct XpadPadPrivate | 43 | struct XpadPadPrivate |
1276 | 42 | { | 44 | { |
1277 | 43 | /* saved values */ | 45 | /* saved values */ |
1278 | @@ -97,509 +99,105 @@ | |||
1279 | 97 | static GParamSpec *obj_prop[N_PROPERTIES] = { NULL, }; | 99 | static GParamSpec *obj_prop[N_PROPERTIES] = { NULL, }; |
1280 | 98 | static guint signals[LAST_SIGNAL] = { 0 }; | 100 | static guint signals[LAST_SIGNAL] = { 0 }; |
1281 | 99 | 101 | ||
1282 | 100 | static void xpad_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); | ||
1283 | 101 | static void xpad_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); | ||
1284 | 102 | static void xpad_pad_constructed (GObject *object); | ||
1285 | 103 | static void xpad_pad_dispose (GObject *object); | ||
1286 | 104 | static void xpad_pad_finalize (GObject *object); | ||
1287 | 105 | static void xpad_pad_load_info (XpadPad *pad, gboolean *show); | ||
1288 | 106 | static GtkWidget *menu_get_popup_highlight (XpadPad *pad, GtkAccelGroup *accel_group); | ||
1289 | 107 | static GtkWidget *menu_get_popup_no_highlight (XpadPad *pad, GtkAccelGroup *accel_group); | ||
1290 | 108 | static void xpad_pad_show (XpadPad *pad); | ||
1291 | 109 | static gboolean xpad_pad_configure_event (XpadPad *pad, GdkEventConfigure *event); | ||
1292 | 110 | static gboolean xpad_pad_toolbar_size_allocate (XpadPad *pad, GtkAllocation *event); | ||
1293 | 111 | static gboolean xpad_pad_delete_event (XpadPad *pad, GdkEvent *event); | ||
1294 | 112 | static gboolean xpad_pad_popup_menu (XpadPad *pad); | ||
1295 | 113 | static void menu_popup (XpadPad *pad); | ||
1296 | 114 | static void menu_popdown (XpadPad *pad); | ||
1297 | 115 | static gboolean xpad_pad_button_press_event (XpadPad *pad, GdkEventButton *event); | ||
1298 | 116 | static void xpad_pad_text_changed (XpadPad *pad, GtkTextBuffer *buffer); | ||
1299 | 117 | static void xpad_pad_notify_has_scrollbar (XpadPad *pad); | ||
1300 | 118 | static void xpad_pad_notify_has_decorations (XpadPad *pad); | ||
1301 | 119 | static void xpad_pad_notify_has_toolbar (XpadPad *pad); | ||
1302 | 120 | static void xpad_pad_notify_autohide_toolbar (XpadPad *pad); | ||
1303 | 121 | static void xpad_pad_hide_toolbar (XpadPad *pad); | ||
1304 | 122 | static void xpad_pad_show_toolbar (XpadPad *pad); | ||
1305 | 123 | static void xpad_pad_popup (XpadPad *pad, GdkEventButton *event); | ||
1306 | 124 | static void xpad_pad_spawn (XpadPad *pad); | ||
1307 | 125 | static void xpad_pad_clear (XpadPad *pad); | ||
1308 | 126 | static void xpad_pad_undo (XpadPad *pad); | ||
1309 | 127 | static void xpad_pad_redo (XpadPad *pad); | ||
1310 | 128 | static void xpad_pad_cut (XpadPad *pad); | ||
1311 | 129 | static void xpad_pad_copy (XpadPad *pad); | ||
1312 | 130 | static void xpad_pad_paste (XpadPad *pad); | ||
1313 | 131 | static void xpad_pad_delete (XpadPad *pad); | ||
1314 | 132 | static void xpad_pad_open_properties (XpadPad *pad); | ||
1315 | 133 | static void xpad_pad_open_preferences (XpadPad *pad); | ||
1316 | 134 | static void xpad_pad_close_all (XpadPad *pad); | ||
1317 | 135 | static void xpad_pad_sync_title (XpadPad *pad); | ||
1318 | 136 | static gboolean xpad_pad_leave_notify_event (GtkWidget *pad, GdkEventCrossing *event); | ||
1319 | 137 | static gboolean xpad_pad_enter_notify_event (GtkWidget *pad, GdkEventCrossing *event); | ||
1320 | 138 | |||
1321 | 139 | /* Create a new empty pad. */ | 102 | /* Create a new empty pad. */ |
1322 | 140 | GtkWidget * | 103 | GtkWidget * |
1324 | 141 | xpad_pad_new (XpadPadGroup *group, XpadSettings *settings) | 104 | xpad_pad_new (XpadPadGroup *group, |
1325 | 105 | XpadSettings *settings) | ||
1326 | 142 | { | 106 | { |
1327 | 143 | return GTK_WIDGET (g_object_new (XPAD_TYPE_PAD, "group", group, "settings", settings, NULL)); | 107 | return GTK_WIDGET (g_object_new (XPAD_TYPE_PAD, "group", group, "settings", settings, NULL)); |
1328 | 144 | } | 108 | } |
1329 | 145 | 109 | ||
1544 | 146 | /* Create a new pad based on the provided info-xxxxx file from the config directory and return this pad */ | 110 | static void |
1545 | 147 | GtkWidget * | 111 | xpad_pad_sync_title (XpadPad *pad) |
1546 | 148 | xpad_pad_new_with_info (XpadPadGroup *group, XpadSettings *settings, const gchar *info_filename, gboolean *show) | 112 | { |
1547 | 149 | { | 113 | GtkTextBuffer *buffer; |
1548 | 150 | GtkWidget *pad = xpad_pad_new (group, settings); | 114 | GtkTextIter s, e; |
1549 | 151 | 115 | gchar *content, *end; | |
1550 | 152 | XPAD_PAD (pad)->priv->infoname = g_strdup (info_filename); | 116 | |
1551 | 153 | xpad_pad_load_info (XPAD_PAD (pad), show); | 117 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); |
1552 | 154 | xpad_pad_load_content (XPAD_PAD (pad)); | 118 | gtk_text_buffer_get_bounds (buffer, &s, &e); |
1553 | 155 | gtk_window_set_role (GTK_WINDOW (pad), XPAD_PAD (pad)->priv->infoname); | 119 | content = gtk_text_buffer_get_text (buffer, &s, &e, FALSE); |
1554 | 156 | 120 | end = g_utf8_strchr (content, -1, '\n'); | |
1555 | 157 | return pad; | 121 | if (end) |
1556 | 158 | } | 122 | *end = '\0'; |
1557 | 159 | 123 | ||
1558 | 160 | /* Create a new pad based on the provided filename from the command line */ | 124 | gtk_window_set_title (GTK_WINDOW (pad), g_strstrip (content)); |
1559 | 161 | GtkWidget * | 125 | |
1560 | 162 | xpad_pad_new_from_file (XpadPadGroup *group, XpadSettings *settings, const gchar *filename) | 126 | g_free (content); |
1561 | 163 | { | 127 | } |
1562 | 164 | GtkWidget *pad = NULL; | 128 | |
1563 | 165 | gchar *content; | 129 | static void |
1564 | 166 | 130 | xpad_pad_text_changed (XpadPad *pad, | |
1565 | 167 | content = fio_get_file (filename); | 131 | GtkTextBuffer *buffer) |
1566 | 168 | 132 | { | |
1567 | 169 | if (!content) | 133 | /* A dirty way to silence the compiler for these unused variables. */ |
1568 | 170 | { | 134 | (void) buffer; |
1569 | 171 | gchar *usertext = g_strdup_printf (_("Could not read file %s."), filename); | 135 | |
1570 | 172 | xpad_app_error (NULL, usertext, NULL); | 136 | /* set title */ |
1357 | 173 | g_free (usertext); | ||
1358 | 174 | } | ||
1359 | 175 | else | ||
1360 | 176 | { | ||
1361 | 177 | GtkTextBuffer *buffer; | ||
1362 | 178 | |||
1363 | 179 | xpad_periodic_init (); | ||
1364 | 180 | xpad_periodic_set_callback ("save-content", (XpadPeriodicFunc) xpad_pad_save_content); | ||
1365 | 181 | |||
1366 | 182 | pad = xpad_pad_new (group, settings); | ||
1367 | 183 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (XPAD_PAD (pad)->priv->textview)); | ||
1368 | 184 | |||
1369 | 185 | xpad_text_buffer_freeze_undo (XPAD_TEXT_BUFFER (buffer)); | ||
1370 | 186 | g_signal_handlers_block_by_func (buffer, xpad_pad_text_changed, pad); | ||
1371 | 187 | |||
1372 | 188 | xpad_text_buffer_set_text_with_tags (XPAD_TEXT_BUFFER (buffer), content ? content : ""); | ||
1373 | 189 | g_free (content); | ||
1374 | 190 | |||
1375 | 191 | g_signal_handlers_unblock_by_func (buffer, xpad_pad_text_changed, pad); | ||
1376 | 192 | xpad_text_buffer_thaw_undo (XPAD_TEXT_BUFFER (buffer)); | ||
1377 | 193 | |||
1378 | 194 | xpad_pad_text_changed(XPAD_PAD(pad), buffer); | ||
1379 | 195 | } | ||
1380 | 196 | |||
1381 | 197 | return pad; | ||
1382 | 198 | } | ||
1383 | 199 | |||
1384 | 200 | /* Class pad - constructor */ | ||
1385 | 201 | static void | ||
1386 | 202 | xpad_pad_class_init (XpadPadClass *klass) | ||
1387 | 203 | { | ||
1388 | 204 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||
1389 | 205 | |||
1390 | 206 | gobject_class->constructed = xpad_pad_constructed; | ||
1391 | 207 | gobject_class->set_property = xpad_pad_set_property; | ||
1392 | 208 | gobject_class->get_property = xpad_pad_get_property; | ||
1393 | 209 | gobject_class->dispose = xpad_pad_dispose; | ||
1394 | 210 | gobject_class->finalize = xpad_pad_finalize; | ||
1395 | 211 | |||
1396 | 212 | signals[CLOSED] = | ||
1397 | 213 | g_signal_new ("closed", | ||
1398 | 214 | G_OBJECT_CLASS_TYPE (gobject_class), | ||
1399 | 215 | G_SIGNAL_RUN_FIRST, | ||
1400 | 216 | G_STRUCT_OFFSET (XpadPadClass, closed), | ||
1401 | 217 | NULL, NULL, | ||
1402 | 218 | g_cclosure_marshal_VOID__VOID, | ||
1403 | 219 | G_TYPE_NONE, | ||
1404 | 220 | 0); | ||
1405 | 221 | |||
1406 | 222 | /* Properties */ | ||
1407 | 223 | obj_prop[PROP_GROUP] = g_param_spec_pointer ("group", "Pad group", "Pad group for this pad", G_PARAM_READWRITE | G_PARAM_CONSTRUCT); | ||
1408 | 224 | obj_prop[PROP_SETTINGS] = g_param_spec_pointer ("settings", "Xpad settings", "Xpad global settings", G_PARAM_READWRITE | G_PARAM_CONSTRUCT); | ||
1409 | 225 | |||
1410 | 226 | g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_prop); | ||
1411 | 227 | } | ||
1412 | 228 | |||
1413 | 229 | static void | ||
1414 | 230 | xpad_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) | ||
1415 | 231 | { | ||
1416 | 232 | XpadPad *pad = XPAD_PAD (object); | ||
1417 | 233 | |||
1418 | 234 | switch (prop_id) | ||
1419 | 235 | { | ||
1420 | 236 | case PROP_GROUP: | ||
1421 | 237 | pad->priv->group = g_value_get_pointer (value); | ||
1422 | 238 | g_object_ref (pad->priv->group); | ||
1423 | 239 | if (pad->priv->group) | ||
1424 | 240 | xpad_pad_group_add (pad->priv->group, GTK_WIDGET (pad)); | ||
1425 | 241 | break; | ||
1426 | 242 | |||
1427 | 243 | case PROP_SETTINGS: | ||
1428 | 244 | pad->priv->settings = g_value_get_pointer (value); | ||
1429 | 245 | g_object_ref (pad->priv->settings); | ||
1430 | 246 | break; | ||
1431 | 247 | |||
1432 | 248 | default: | ||
1433 | 249 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
1434 | 250 | break; | ||
1435 | 251 | } | ||
1436 | 252 | } | ||
1437 | 253 | |||
1438 | 254 | static void | ||
1439 | 255 | xpad_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) | ||
1440 | 256 | { | ||
1441 | 257 | XpadPad *pad = XPAD_PAD (object); | ||
1442 | 258 | |||
1443 | 259 | switch (prop_id) | ||
1444 | 260 | { | ||
1445 | 261 | case PROP_GROUP: | ||
1446 | 262 | g_value_set_pointer (value, pad->priv->group); | ||
1447 | 263 | break; | ||
1448 | 264 | |||
1449 | 265 | case PROP_SETTINGS: | ||
1450 | 266 | g_value_set_pointer (value, pad->priv->settings); | ||
1451 | 267 | break; | ||
1452 | 268 | |||
1453 | 269 | default: | ||
1454 | 270 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
1455 | 271 | break; | ||
1456 | 272 | } | ||
1457 | 273 | } | ||
1458 | 274 | |||
1459 | 275 | /* Class pad - initializer */ | ||
1460 | 276 | static void | ||
1461 | 277 | xpad_pad_init (XpadPad *pad) | ||
1462 | 278 | { | ||
1463 | 279 | pad->priv = xpad_pad_get_instance_private (pad); | ||
1464 | 280 | |||
1465 | 281 | pad->priv->x = 0; | ||
1466 | 282 | pad->priv->y = 0; | ||
1467 | 283 | pad->priv->location_valid = FALSE; | ||
1468 | 284 | pad->priv->infoname = NULL; | ||
1469 | 285 | pad->priv->contentname = NULL; | ||
1470 | 286 | pad->priv->textview = NULL; | ||
1471 | 287 | pad->priv->scrollbar = NULL; | ||
1472 | 288 | pad->priv->toolbar = NULL; | ||
1473 | 289 | pad->priv->toolbar_timeout = 0; | ||
1474 | 290 | pad->priv->toolbar_height = 0; | ||
1475 | 291 | pad->priv->toolbar_expanded = FALSE; | ||
1476 | 292 | pad->priv->toolbar_pad_resized = TRUE; | ||
1477 | 293 | pad->priv->properties = NULL; | ||
1478 | 294 | pad->priv->unsaved_content = FALSE; | ||
1479 | 295 | pad->priv->unsaved_info = FALSE; | ||
1480 | 296 | } | ||
1481 | 297 | |||
1482 | 298 | static void xpad_pad_constructed (GObject *object) | ||
1483 | 299 | { | ||
1484 | 300 | XpadPad *pad = XPAD_PAD (object); | ||
1485 | 301 | |||
1486 | 302 | gboolean decorations; | ||
1487 | 303 | GtkBox *vbox; | ||
1488 | 304 | |||
1489 | 305 | g_object_get (pad->priv->settings, | ||
1490 | 306 | "width", &pad->priv->width, | ||
1491 | 307 | "height", &pad->priv->height, | ||
1492 | 308 | "autostart-sticky", &pad->priv->sticky, NULL); | ||
1493 | 309 | |||
1494 | 310 | GtkWindow *pad_window = GTK_WINDOW (pad); | ||
1495 | 311 | |||
1496 | 312 | pad->priv->textview = GTK_WIDGET (XPAD_TEXT_VIEW (xpad_text_view_new (pad->priv->settings, pad))); | ||
1497 | 313 | |||
1498 | 314 | pad->priv->scrollbar = GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW, | ||
1499 | 315 | "hadjustment", NULL, | ||
1500 | 316 | "hscrollbar-policy", GTK_POLICY_NEVER, | ||
1501 | 317 | "shadow-type", GTK_SHADOW_NONE, | ||
1502 | 318 | "vadjustment", NULL, | ||
1503 | 319 | "vscrollbar-policy", GTK_POLICY_NEVER, | ||
1504 | 320 | "child", pad->priv->textview, | ||
1505 | 321 | NULL)); | ||
1506 | 322 | |||
1507 | 323 | pad->priv->toolbar = GTK_WIDGET (xpad_toolbar_new (pad)); | ||
1508 | 324 | |||
1509 | 325 | pad->priv->accel_group = gtk_accel_group_new (); | ||
1510 | 326 | gtk_window_add_accel_group (pad_window, pad->priv->accel_group); | ||
1511 | 327 | pad->priv->menu = menu_get_popup_no_highlight (pad, pad->priv->accel_group); | ||
1512 | 328 | pad->priv->highlight_menu = menu_get_popup_highlight (pad, pad->priv->accel_group); | ||
1513 | 329 | gtk_accel_group_connect (pad->priv->accel_group, GDK_KEY_Q, GDK_CONTROL_MASK, 0, g_cclosure_new_swap (G_CALLBACK (xpad_app_quit), pad, NULL)); | ||
1514 | 330 | |||
1515 | 331 | vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); | ||
1516 | 332 | gtk_box_set_homogeneous (vbox, FALSE); | ||
1517 | 333 | gtk_box_pack_start (vbox, pad->priv->scrollbar, TRUE, TRUE, 0); | ||
1518 | 334 | gtk_box_pack_start (vbox, pad->priv->toolbar, FALSE, FALSE, 0); | ||
1519 | 335 | |||
1520 | 336 | gtk_container_child_set (GTK_CONTAINER (vbox), pad->priv->toolbar, "expand", FALSE, NULL); | ||
1521 | 337 | |||
1522 | 338 | g_object_get (pad->priv->settings, "has-decorations", &decorations, NULL); | ||
1523 | 339 | gtk_window_set_decorated (pad_window, decorations); | ||
1524 | 340 | gtk_window_set_default_size (pad_window, (gint) pad->priv->width, (gint) pad->priv->height); | ||
1525 | 341 | gtk_window_set_gravity (pad_window, GDK_GRAVITY_STATIC); /* static gravity makes saving pad x,y work */ | ||
1526 | 342 | gtk_window_set_skip_pager_hint (pad_window, decorations); | ||
1527 | 343 | gtk_window_set_skip_taskbar_hint (pad_window, !decorations); | ||
1528 | 344 | gtk_window_set_position (pad_window, GTK_WIN_POS_MOUSE); | ||
1529 | 345 | |||
1530 | 346 | g_object_set (G_OBJECT (pad), "child", vbox, NULL); | ||
1531 | 347 | |||
1532 | 348 | xpad_pad_notify_has_scrollbar (pad); | ||
1533 | 349 | xpad_pad_notify_has_selection (pad); | ||
1534 | 350 | xpad_pad_notify_clipboard_owner_changed (pad); | ||
1535 | 351 | xpad_pad_notify_undo_redo_changed (pad); | ||
1536 | 352 | |||
1537 | 353 | pad->priv->clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); | ||
1538 | 354 | |||
1539 | 355 | if (pad->priv->sticky) | ||
1540 | 356 | gtk_window_stick (pad_window); | ||
1541 | 357 | else | ||
1542 | 358 | gtk_window_unstick (pad_window); | ||
1543 | 359 | |||
1571 | 360 | xpad_pad_sync_title (pad); | 137 | xpad_pad_sync_title (pad); |
1814 | 361 | 138 | ||
1815 | 362 | gtk_widget_show_all (GTK_WIDGET (vbox)); | 139 | /* record change */ |
1816 | 363 | 140 | xpad_pad_save_content_delayed(pad); | |
1817 | 364 | gtk_widget_hide (pad->priv->toolbar); | 141 | } |
1818 | 365 | xpad_pad_notify_has_toolbar (pad); | 142 | |
1819 | 366 | 143 | void | |
1820 | 367 | /* Set up signals */ | 144 | xpad_pad_load_content (XpadPad *pad) |
1821 | 368 | gtk_widget_add_events (GTK_WIDGET (pad), GDK_BUTTON_PRESS_MASK | GDK_PROPERTY_CHANGE_MASK); | 145 | { |
1822 | 369 | gtk_widget_add_events (pad->priv->toolbar, GDK_ALL_EVENTS_MASK); | 146 | g_return_if_fail (pad); |
1823 | 370 | g_signal_connect_swapped (pad->priv->textview, "button-press-event", G_CALLBACK (xpad_pad_button_press_event), pad); | 147 | |
1824 | 371 | g_signal_connect_swapped (pad->priv->textview, "popup-menu", G_CALLBACK (xpad_pad_popup_menu), pad); | 148 | gchar *content; |
1825 | 372 | g_signal_connect_swapped (pad->priv->toolbar, "size-allocate", G_CALLBACK (xpad_pad_toolbar_size_allocate), pad); | 149 | GtkTextBuffer *buffer; |
1826 | 373 | g_signal_connect (pad, "button-press-event", G_CALLBACK (xpad_pad_button_press_event), NULL); | 150 | |
1827 | 374 | g_signal_connect (pad, "configure-event", G_CALLBACK (xpad_pad_configure_event), NULL); | 151 | if (!pad->priv->contentname) |
1828 | 375 | g_signal_connect (pad, "delete-event", G_CALLBACK (xpad_pad_delete_event), NULL); | 152 | return; |
1829 | 376 | g_signal_connect (pad, "popup-menu", G_CALLBACK (xpad_pad_popup_menu), NULL); | 153 | |
1830 | 377 | g_signal_connect (pad, "show", G_CALLBACK (xpad_pad_show), NULL); | 154 | content = fio_get_file (pad->priv->contentname); |
1831 | 378 | g_signal_connect_swapped (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)), "changed", G_CALLBACK (xpad_pad_text_changed), pad); | 155 | |
1832 | 379 | 156 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | |
1833 | 380 | g_signal_connect (pad, "enter-notify-event", G_CALLBACK (xpad_pad_enter_notify_event), NULL); | 157 | |
1834 | 381 | g_signal_connect (pad, "leave-notify-event", G_CALLBACK (xpad_pad_leave_notify_event), NULL); | 158 | xpad_text_buffer_freeze_undo (XPAD_TEXT_BUFFER (buffer)); |
1835 | 382 | 159 | g_signal_handlers_block_by_func (buffer, xpad_pad_text_changed, pad); | |
1836 | 383 | g_signal_connect_swapped (pad->priv->settings, "notify::has-decorations", G_CALLBACK (xpad_pad_notify_has_decorations), pad); | 160 | |
1837 | 384 | g_signal_connect_swapped (pad->priv->settings, "notify::has-toolbar", G_CALLBACK (xpad_pad_notify_has_toolbar), pad); | 161 | xpad_text_buffer_set_text_with_tags (XPAD_TEXT_BUFFER (buffer), content ? content : ""); |
1838 | 385 | g_signal_connect_swapped (pad->priv->settings, "notify::autohide-toolbar", G_CALLBACK (xpad_pad_notify_autohide_toolbar), pad); | 162 | g_free (content); |
1839 | 386 | g_signal_connect_swapped (pad->priv->settings, "notify::has-scrollbar", G_CALLBACK (xpad_pad_notify_has_scrollbar), pad); | 163 | |
1840 | 387 | g_signal_connect_swapped (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)), "notify::has-selection", G_CALLBACK (xpad_pad_notify_has_selection), pad); | 164 | g_signal_handlers_unblock_by_func (buffer, xpad_pad_text_changed, pad); |
1841 | 388 | g_signal_connect_swapped (pad->priv->clipboard, "owner-change", G_CALLBACK (xpad_pad_notify_clipboard_owner_changed), pad); | 165 | xpad_text_buffer_thaw_undo (XPAD_TEXT_BUFFER (buffer)); |
1842 | 389 | 166 | ||
1843 | 390 | g_signal_connect_swapped (pad->priv->toolbar, "activate-new", G_CALLBACK (xpad_pad_spawn), pad); | 167 | xpad_pad_text_changed(pad, buffer); |
1844 | 391 | g_signal_connect_swapped (pad->priv->toolbar, "activate-clear", G_CALLBACK (xpad_pad_clear), pad); | 168 | pad->priv->unsaved_content = FALSE; |
1845 | 392 | g_signal_connect_swapped (pad->priv->toolbar, "activate-close", G_CALLBACK (xpad_pad_close), pad); | 169 | } |
1846 | 393 | g_signal_connect_swapped (pad->priv->toolbar, "activate-undo", G_CALLBACK (xpad_pad_undo), pad); | 170 | |
1847 | 394 | g_signal_connect_swapped (pad->priv->toolbar, "activate-redo", G_CALLBACK (xpad_pad_redo), pad); | 171 | void |
1848 | 395 | g_signal_connect_swapped (pad->priv->toolbar, "activate-cut", G_CALLBACK (xpad_pad_cut), pad); | 172 | xpad_pad_save_content (XpadPad *pad) |
1849 | 396 | g_signal_connect_swapped (pad->priv->toolbar, "activate-copy", G_CALLBACK (xpad_pad_copy), pad); | 173 | { |
1850 | 397 | g_signal_connect_swapped (pad->priv->toolbar, "activate-paste", G_CALLBACK (xpad_pad_paste), pad); | 174 | g_return_if_fail (pad); |
1851 | 398 | g_signal_connect_swapped (pad->priv->toolbar, "activate-delete", G_CALLBACK (xpad_pad_delete), pad); | 175 | |
1852 | 399 | g_signal_connect_swapped (pad->priv->toolbar, "activate-properties", G_CALLBACK (xpad_pad_open_properties), pad); | 176 | gchar *content; |
1853 | 400 | g_signal_connect_swapped (pad->priv->toolbar, "activate-preferences", G_CALLBACK (xpad_pad_open_preferences), pad); | 177 | GtkTextBuffer *buffer; |
1854 | 401 | g_signal_connect_swapped (pad->priv->toolbar, "activate-quit", G_CALLBACK (xpad_pad_close_all), pad); | 178 | |
1855 | 402 | 179 | if (!pad->priv->unsaved_content) | |
1856 | 403 | g_signal_connect_swapped (pad->priv->toolbar, "popup", G_CALLBACK (menu_popup), pad); | 180 | return; |
1857 | 404 | g_signal_connect_swapped (pad->priv->toolbar, "popdown", G_CALLBACK (menu_popdown), pad); | 181 | |
1858 | 405 | 182 | /* create content file if it doesn't exist yet */ | |
1859 | 406 | g_signal_connect_swapped (pad->priv->menu, "deactivate", G_CALLBACK (menu_popdown), pad); | 183 | if (!pad->priv->contentname) |
1860 | 407 | g_signal_connect_swapped (pad->priv->highlight_menu, "deactivate", G_CALLBACK (menu_popdown), pad); | 184 | { |
1861 | 408 | } | 185 | pad->priv->contentname = fio_unique_name ("content-"); |
1862 | 409 | 186 | if (!pad->priv->contentname) | |
1863 | 410 | static void | 187 | return; |
1864 | 411 | xpad_pad_dispose (GObject *object) | 188 | } |
1865 | 412 | { | 189 | |
1866 | 413 | XpadPad *pad = XPAD_PAD (object); | 190 | if (GTK_IS_TEXT_VIEW(pad->priv->textview)) { |
1867 | 414 | 191 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | |
1868 | 415 | if (pad->priv->group) { | 192 | content = xpad_text_buffer_get_text_with_tags (XPAD_TEXT_BUFFER (buffer)); |
1869 | 416 | g_object_unref(pad->priv->group); | 193 | } |
1870 | 417 | pad->priv->group = NULL; | 194 | else |
1871 | 418 | } | 195 | g_warning("There is a problem in the program Xpad. In function 'xpad_pad_save_content' the variable 'pad->priv->textview' is not of type textview. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad."); |
1872 | 419 | 196 | ||
1873 | 420 | if (GTK_IS_WIDGET(pad->priv->menu)) { | 197 | fio_set_file (pad->priv->contentname, content); |
1874 | 421 | gtk_widget_destroy (pad->priv->menu); | 198 | |
1875 | 422 | pad->priv->menu = NULL; | 199 | pad->priv->unsaved_content = FALSE; |
1876 | 423 | } | 200 | g_free (content); |
1635 | 424 | |||
1636 | 425 | if (GTK_IS_WIDGET(pad->priv->highlight_menu)) { | ||
1637 | 426 | gtk_widget_destroy (pad->priv->highlight_menu); | ||
1638 | 427 | pad->priv->highlight_menu = NULL; | ||
1639 | 428 | } | ||
1640 | 429 | |||
1641 | 430 | if (XPAD_IS_PAD_PROPERTIES (pad->priv->properties)) { | ||
1642 | 431 | gtk_widget_destroy (pad->priv->properties); | ||
1643 | 432 | pad->priv->properties = NULL; | ||
1644 | 433 | } | ||
1645 | 434 | |||
1646 | 435 | gtk_clipboard_clear (pad->priv->clipboard); | ||
1647 | 436 | |||
1648 | 437 | /* For some reason the toolbar handler does not get automatically disconnected (or not at the right moment), leading to errors after deleting a pad. This manual disconnect prevents this error. */ | ||
1649 | 438 | if (XPAD_IS_TOOLBAR (pad->priv->toolbar)) { | ||
1650 | 439 | g_signal_handlers_disconnect_matched (pad->priv->toolbar, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pad); | ||
1651 | 440 | gtk_widget_destroy(pad->priv->toolbar); | ||
1652 | 441 | pad->priv->toolbar = NULL; | ||
1653 | 442 | } | ||
1654 | 443 | |||
1655 | 444 | G_OBJECT_CLASS (xpad_pad_parent_class)->dispose (object); | ||
1656 | 445 | } | ||
1657 | 446 | |||
1658 | 447 | static void | ||
1659 | 448 | xpad_pad_finalize (GObject *object) | ||
1660 | 449 | { | ||
1661 | 450 | XpadPad *pad = XPAD_PAD (object); | ||
1662 | 451 | |||
1663 | 452 | if (pad->priv->settings) { | ||
1664 | 453 | g_signal_handlers_disconnect_matched (pad->priv->settings, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pad); | ||
1665 | 454 | g_object_unref(pad->priv->settings); | ||
1666 | 455 | pad->priv->settings = NULL; | ||
1667 | 456 | } | ||
1668 | 457 | |||
1669 | 458 | g_free (pad->priv->infoname); | ||
1670 | 459 | g_free (pad->priv->contentname); | ||
1671 | 460 | |||
1672 | 461 | G_OBJECT_CLASS (xpad_pad_parent_class)->finalize (object); | ||
1673 | 462 | } | ||
1674 | 463 | |||
1675 | 464 | static void | ||
1676 | 465 | xpad_pad_show (XpadPad *pad) | ||
1677 | 466 | { | ||
1678 | 467 | /* | ||
1679 | 468 | * Some wm's might not acknowledge our request for a specific | ||
1680 | 469 | * location before we are shown. What we do here is a little gimpy | ||
1681 | 470 | * and not very respectful of wms' sovereignty, but it has the effect | ||
1682 | 471 | * of making pads' locations very dependable. We just move the pad | ||
1683 | 472 | * again here after being shown. This may create a visual effect if | ||
1684 | 473 | * the wm did ignore us, but is better than being in the wrong | ||
1685 | 474 | * place, I guess. | ||
1686 | 475 | */ | ||
1687 | 476 | if (pad->priv->location_valid) | ||
1688 | 477 | gtk_window_move (GTK_WINDOW (pad), pad->priv->x, pad->priv->y); | ||
1689 | 478 | |||
1690 | 479 | if (pad->priv->sticky) | ||
1691 | 480 | gtk_window_stick (GTK_WINDOW (pad)); | ||
1692 | 481 | else | ||
1693 | 482 | gtk_window_unstick (GTK_WINDOW (pad)); | ||
1694 | 483 | } | ||
1695 | 484 | |||
1696 | 485 | static gboolean toolbar_timeout (XpadPad *pad) | ||
1697 | 486 | { | ||
1698 | 487 | if (!pad || !pad->priv || !pad->priv->toolbar_timeout) | ||
1699 | 488 | return FALSE; | ||
1700 | 489 | |||
1701 | 490 | gboolean has_toolbar, autohide_toolbar; | ||
1702 | 491 | g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL); | ||
1703 | 492 | |||
1704 | 493 | if (pad->priv->toolbar_timeout && autohide_toolbar && has_toolbar) | ||
1705 | 494 | xpad_pad_hide_toolbar (pad); | ||
1706 | 495 | |||
1707 | 496 | pad->priv->toolbar_timeout = 0; | ||
1708 | 497 | |||
1709 | 498 | return FALSE; | ||
1710 | 499 | } | ||
1711 | 500 | |||
1712 | 501 | static void | ||
1713 | 502 | xpad_pad_notify_has_decorations (XpadPad *pad) | ||
1714 | 503 | { | ||
1715 | 504 | GtkWidget *pad_widget = GTK_WIDGET (pad); | ||
1716 | 505 | GtkWindow *pad_window = GTK_WINDOW (pad); | ||
1717 | 506 | gboolean decorations; | ||
1718 | 507 | g_object_get (pad->priv->settings, "has-decorations", &decorations, NULL); | ||
1719 | 508 | |||
1720 | 509 | /* Update pad menu with the new status */ | ||
1721 | 510 | GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-decorations"); | ||
1722 | 511 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), decorations); | ||
1723 | 512 | |||
1724 | 513 | /* | ||
1725 | 514 | * There are two modes of operation: a normal mode and a 'stealth' mode. | ||
1726 | 515 | * If decorations are disabled, we also don't show up in the taskbar or pager. | ||
1727 | 516 | */ | ||
1728 | 517 | gtk_window_set_decorated (pad_window, decorations); | ||
1729 | 518 | gtk_window_set_skip_taskbar_hint (pad_window, !decorations); | ||
1730 | 519 | gtk_window_set_skip_pager_hint (pad_window, !decorations); | ||
1731 | 520 | |||
1732 | 521 | /* | ||
1733 | 522 | * reshow_with_initial_size() seems to set the window back to a never-shown state. | ||
1734 | 523 | * This is good, as some WMs don't like us changing the above parameters mid-run, | ||
1735 | 524 | * even if we do a hide/show cycle. | ||
1736 | 525 | */ | ||
1737 | 526 | gtk_window_set_default_size (pad_window, (gint) pad->priv->width, (gint) pad->priv->height); | ||
1738 | 527 | gtk_widget_hide (pad_widget); | ||
1739 | 528 | gtk_widget_unrealize (pad_widget); | ||
1740 | 529 | gtk_widget_show (pad_widget); | ||
1741 | 530 | } | ||
1742 | 531 | |||
1743 | 532 | static void | ||
1744 | 533 | xpad_pad_notify_has_toolbar (XpadPad *pad) | ||
1745 | 534 | { | ||
1746 | 535 | gboolean has_toolbar, autohide_toolbar; | ||
1747 | 536 | g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL); | ||
1748 | 537 | |||
1749 | 538 | /* Update pad menu with the new status */ | ||
1750 | 539 | GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-toolbar"); | ||
1751 | 540 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), has_toolbar); | ||
1752 | 541 | menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-autohide-toolbar"); | ||
1753 | 542 | gtk_widget_set_sensitive (menu_item, has_toolbar); | ||
1754 | 543 | |||
1755 | 544 | if (has_toolbar && !autohide_toolbar) | ||
1756 | 545 | xpad_pad_show_toolbar (pad); | ||
1757 | 546 | else | ||
1758 | 547 | xpad_pad_hide_toolbar (pad); | ||
1759 | 548 | } | ||
1760 | 549 | |||
1761 | 550 | static void | ||
1762 | 551 | xpad_pad_notify_autohide_toolbar (XpadPad *pad) | ||
1763 | 552 | { | ||
1764 | 553 | gboolean autohide_toolbar; | ||
1765 | 554 | g_object_get (pad->priv->settings, "autohide-toolbar", &autohide_toolbar, NULL); | ||
1766 | 555 | |||
1767 | 556 | /* Update pad menu with the new status */ | ||
1768 | 557 | GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-autohide-toolbar"); | ||
1769 | 558 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), autohide_toolbar); | ||
1770 | 559 | |||
1771 | 560 | if (autohide_toolbar) | ||
1772 | 561 | { | ||
1773 | 562 | /* Likely not to be in pad when turning setting on */ | ||
1774 | 563 | if (!pad->priv->toolbar_timeout) | ||
1775 | 564 | pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad); | ||
1776 | 565 | } | ||
1777 | 566 | else | ||
1778 | 567 | { | ||
1779 | 568 | gboolean has_toolbar; | ||
1780 | 569 | g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, NULL); | ||
1781 | 570 | |||
1782 | 571 | if (has_toolbar) | ||
1783 | 572 | xpad_pad_show_toolbar(pad); | ||
1784 | 573 | } | ||
1785 | 574 | } | ||
1786 | 575 | |||
1787 | 576 | static void | ||
1788 | 577 | xpad_pad_notify_has_scrollbar (XpadPad *pad) | ||
1789 | 578 | { | ||
1790 | 579 | gboolean has_scrollbar; | ||
1791 | 580 | g_object_get (pad->priv->settings, "has-scrollbar", &has_scrollbar, NULL); | ||
1792 | 581 | |||
1793 | 582 | /* Update pad menu with the new status */ | ||
1794 | 583 | GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-scrollbar"); | ||
1795 | 584 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), has_scrollbar); | ||
1796 | 585 | |||
1797 | 586 | if (has_scrollbar) | ||
1798 | 587 | gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pad->priv->scrollbar), | ||
1799 | 588 | GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | ||
1800 | 589 | else | ||
1801 | 590 | { | ||
1802 | 591 | GtkAdjustment *v, *h; | ||
1803 | 592 | |||
1804 | 593 | gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pad->priv->scrollbar), | ||
1805 | 594 | GTK_POLICY_NEVER, GTK_POLICY_NEVER); | ||
1806 | 595 | |||
1807 | 596 | /* now we need to adjust view so that user can see whole pad */ | ||
1808 | 597 | h = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (pad->priv->scrollbar)); | ||
1809 | 598 | v = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (pad->priv->scrollbar)); | ||
1810 | 599 | |||
1811 | 600 | gtk_adjustment_set_value (h, 0); | ||
1812 | 601 | gtk_adjustment_set_value (v, 0); | ||
1813 | 602 | } | ||
1877 | 603 | } | 201 | } |
1878 | 604 | 202 | ||
1879 | 605 | static guint | 203 | static guint |
1880 | @@ -629,6 +227,28 @@ | |||
1881 | 629 | } | 227 | } |
1882 | 630 | 228 | ||
1883 | 631 | static void | 229 | static void |
1884 | 230 | xpad_pad_hide_toolbar (XpadPad *pad) | ||
1885 | 231 | { | ||
1886 | 232 | if (gtk_widget_get_visible (pad->priv->toolbar)) | ||
1887 | 233 | { | ||
1888 | 234 | GtkWidget *pad_widget = GTK_WIDGET (pad); | ||
1889 | 235 | if (gtk_widget_get_window (pad_widget)) | ||
1890 | 236 | gdk_window_freeze_updates (gtk_widget_get_window (pad_widget)); | ||
1891 | 237 | gtk_widget_hide (pad->priv->toolbar); | ||
1892 | 238 | |||
1893 | 239 | if (pad->priv->toolbar_expanded || | ||
1894 | 240 | (pad->priv->toolbar_pad_resized && xpad_pad_text_and_toolbar_height (pad) >= pad->priv->height)) | ||
1895 | 241 | { | ||
1896 | 242 | pad->priv->height -= pad->priv->toolbar_height; | ||
1897 | 243 | gtk_window_resize (GTK_WINDOW (pad), (gint) pad->priv->width, (gint) pad->priv->height); | ||
1898 | 244 | pad->priv->toolbar_expanded = FALSE; | ||
1899 | 245 | } | ||
1900 | 246 | if (gtk_widget_get_window (pad_widget)) | ||
1901 | 247 | gdk_window_thaw_updates (gtk_widget_get_window (pad_widget)); | ||
1902 | 248 | } | ||
1903 | 249 | } | ||
1904 | 250 | |||
1905 | 251 | static void | ||
1906 | 632 | xpad_pad_show_toolbar (XpadPad *pad) | 252 | xpad_pad_show_toolbar (XpadPad *pad) |
1907 | 633 | { | 253 | { |
1908 | 634 | if (!gtk_widget_get_visible (pad->priv->toolbar)) | 254 | if (!gtk_widget_get_visible (pad->priv->toolbar)) |
1909 | @@ -669,558 +289,10 @@ | |||
1910 | 669 | } | 289 | } |
1911 | 670 | } | 290 | } |
1912 | 671 | 291 | ||
1913 | 672 | static void | ||
1914 | 673 | xpad_pad_hide_toolbar (XpadPad *pad) | ||
1915 | 674 | { | ||
1916 | 675 | if (gtk_widget_get_visible (pad->priv->toolbar)) | ||
1917 | 676 | { | ||
1918 | 677 | GtkWidget *pad_widget = GTK_WIDGET (pad); | ||
1919 | 678 | if (gtk_widget_get_window (pad_widget)) | ||
1920 | 679 | gdk_window_freeze_updates (gtk_widget_get_window (pad_widget)); | ||
1921 | 680 | gtk_widget_hide (pad->priv->toolbar); | ||
1922 | 681 | |||
1923 | 682 | if (pad->priv->toolbar_expanded || | ||
1924 | 683 | (pad->priv->toolbar_pad_resized && xpad_pad_text_and_toolbar_height (pad) >= pad->priv->height)) | ||
1925 | 684 | { | ||
1926 | 685 | pad->priv->height -= pad->priv->toolbar_height; | ||
1927 | 686 | gtk_window_resize (GTK_WINDOW (pad), (gint) pad->priv->width, (gint) pad->priv->height); | ||
1928 | 687 | pad->priv->toolbar_expanded = FALSE; | ||
1929 | 688 | } | ||
1930 | 689 | if (gtk_widget_get_window (pad_widget)) | ||
1931 | 690 | gdk_window_thaw_updates (gtk_widget_get_window (pad_widget)); | ||
1932 | 691 | } | ||
1933 | 692 | } | ||
1934 | 693 | |||
1935 | 694 | void | ||
1936 | 695 | xpad_pad_notify_has_selection (XpadPad *pad) | ||
1937 | 696 | { | ||
1938 | 697 | g_return_if_fail (pad); | ||
1939 | 698 | |||
1940 | 699 | GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
1941 | 700 | gboolean has_selection = gtk_text_buffer_get_has_selection (buffer); | ||
1942 | 701 | |||
1943 | 702 | XpadToolbar *toolbar = XPAD_TOOLBAR (pad->priv->toolbar); | ||
1944 | 703 | if (toolbar == NULL) | ||
1945 | 704 | return; | ||
1946 | 705 | |||
1947 | 706 | xpad_toolbar_enable_cut_button (toolbar, has_selection); | ||
1948 | 707 | xpad_toolbar_enable_copy_button (toolbar, has_selection); | ||
1949 | 708 | } | ||
1950 | 709 | |||
1951 | 710 | void | ||
1952 | 711 | xpad_pad_notify_clipboard_owner_changed (XpadPad *pad) | ||
1953 | 712 | { | ||
1954 | 713 | g_return_if_fail (pad); | ||
1955 | 714 | |||
1956 | 715 | /* safe cast to toolbar */ | ||
1957 | 716 | if (XPAD_IS_TOOLBAR (pad->priv->toolbar)) { | ||
1958 | 717 | XpadToolbar *toolbar = XPAD_TOOLBAR (pad->priv->toolbar); | ||
1959 | 718 | g_return_if_fail (toolbar); | ||
1960 | 719 | |||
1961 | 720 | GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); | ||
1962 | 721 | xpad_toolbar_enable_paste_button (toolbar, gtk_clipboard_wait_is_text_available (clipboard)); | ||
1963 | 722 | } | ||
1964 | 723 | } | ||
1965 | 724 | |||
1966 | 725 | void | ||
1967 | 726 | xpad_pad_notify_undo_redo_changed (XpadPad *pad) | ||
1968 | 727 | { | ||
1969 | 728 | g_return_if_fail (pad); | ||
1970 | 729 | |||
1971 | 730 | XpadTextBuffer *buffer = NULL; | ||
1972 | 731 | buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview))); | ||
1973 | 732 | g_return_if_fail (buffer); | ||
1974 | 733 | |||
1975 | 734 | XpadToolbar *toolbar = NULL; | ||
1976 | 735 | toolbar = XPAD_TOOLBAR (pad->priv->toolbar); | ||
1977 | 736 | g_return_if_fail (toolbar); | ||
1978 | 737 | |||
1979 | 738 | xpad_toolbar_enable_undo_button (toolbar, xpad_text_buffer_undo_available (buffer)); | ||
1980 | 739 | xpad_toolbar_enable_redo_button (toolbar, xpad_text_buffer_redo_available (buffer)); | ||
1981 | 740 | } | ||
1982 | 741 | |||
1983 | 742 | static gboolean | ||
1984 | 743 | xpad_pad_enter_notify_event (GtkWidget *pad, GdkEventCrossing *event) | ||
1985 | 744 | { | ||
1986 | 745 | gboolean has_toolbar, autohide_toolbar; | ||
1987 | 746 | g_object_get (XPAD_PAD (pad)->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL); | ||
1988 | 747 | |||
1989 | 748 | if (has_toolbar && autohide_toolbar && | ||
1990 | 749 | event->detail != GDK_NOTIFY_INFERIOR && | ||
1991 | 750 | event->mode == GDK_CROSSING_NORMAL) | ||
1992 | 751 | { | ||
1993 | 752 | XPAD_PAD (pad)->priv->toolbar_timeout = 0; | ||
1994 | 753 | xpad_pad_show_toolbar (XPAD_PAD (pad)); | ||
1995 | 754 | } | ||
1996 | 755 | |||
1997 | 756 | return FALSE; | ||
1998 | 757 | } | ||
1999 | 758 | |||
2000 | 759 | static gboolean | ||
2001 | 760 | xpad_pad_leave_notify_event (GtkWidget *pad, GdkEventCrossing *event) | ||
2002 | 761 | { | ||
2003 | 762 | gboolean has_toolbar, autohide_toolbar; | ||
2004 | 763 | g_object_get (XPAD_PAD (pad)->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL); | ||
2005 | 764 | |||
2006 | 765 | if (has_toolbar && autohide_toolbar && | ||
2007 | 766 | event->detail != GDK_NOTIFY_INFERIOR && | ||
2008 | 767 | event->mode == GDK_CROSSING_NORMAL) | ||
2009 | 768 | { | ||
2010 | 769 | if (!XPAD_PAD (pad)->priv->toolbar_timeout) | ||
2011 | 770 | XPAD_PAD (pad)->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad); | ||
2012 | 771 | } | ||
2013 | 772 | |||
2014 | 773 | return FALSE; | ||
2015 | 774 | } | ||
2016 | 775 | |||
2017 | 776 | static void | ||
2018 | 777 | xpad_pad_spawn (XpadPad *pad) | ||
2019 | 778 | { | ||
2020 | 779 | GtkWidget *newpad = xpad_pad_new (pad->priv->group, pad->priv->settings); | ||
2021 | 780 | gtk_widget_show (newpad); | ||
2022 | 781 | } | ||
2023 | 782 | |||
2024 | 783 | static void | ||
2025 | 784 | xpad_pad_clear (XpadPad *pad) | ||
2026 | 785 | { | ||
2027 | 786 | GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
2028 | 787 | gtk_text_buffer_set_text (buffer, "", -1); | ||
2029 | 788 | } | ||
2030 | 789 | |||
2031 | 790 | void | ||
2032 | 791 | xpad_pad_close (XpadPad *pad) | ||
2033 | 792 | { | ||
2034 | 793 | gtk_widget_hide (GTK_WIDGET (pad)); | ||
2035 | 794 | |||
2036 | 795 | /* | ||
2037 | 796 | * If no tray and this is the last pad, we don't want to record this | ||
2038 | 797 | * pad as closed, we want to start with just this pad next open. So | ||
2039 | 798 | * quit before we record. | ||
2040 | 799 | */ | ||
2041 | 800 | if (!xpad_tray_is_open () && | ||
2042 | 801 | xpad_pad_group_num_visible_pads (pad->priv->group) == 0) | ||
2043 | 802 | { | ||
2044 | 803 | xpad_app_quit (); | ||
2045 | 804 | return; | ||
2046 | 805 | } | ||
2047 | 806 | |||
2048 | 807 | if (pad->priv->properties) | ||
2049 | 808 | gtk_widget_destroy (pad->priv->properties); | ||
2050 | 809 | |||
2051 | 810 | xpad_pad_save_info (pad); | ||
2052 | 811 | |||
2053 | 812 | g_signal_emit (pad, signals[CLOSED], 0); | ||
2054 | 813 | } | ||
2055 | 814 | |||
2056 | 815 | void | ||
2057 | 816 | xpad_pad_toggle(XpadPad *pad) | ||
2058 | 817 | { | ||
2059 | 818 | if (gtk_widget_get_visible (GTK_WIDGET(pad))) | ||
2060 | 819 | xpad_pad_close (pad); | ||
2061 | 820 | else | ||
2062 | 821 | gtk_widget_show (GTK_WIDGET (pad)); | ||
2063 | 822 | } | ||
2064 | 823 | |||
2065 | 824 | static gboolean | ||
2066 | 825 | should_confirm_delete (XpadPad *pad) | ||
2067 | 826 | { | ||
2068 | 827 | GtkTextBuffer *buffer; | ||
2069 | 828 | GtkTextIter s, e; | ||
2070 | 829 | gchar *content; | ||
2071 | 830 | gboolean confirm; | ||
2072 | 831 | |||
2073 | 832 | g_object_get (pad->priv->settings, "confirm-destroy", &confirm, NULL); | ||
2074 | 833 | if (!confirm) | ||
2075 | 834 | return FALSE; | ||
2076 | 835 | |||
2077 | 836 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
2078 | 837 | gtk_text_buffer_get_bounds (buffer, &s, &e); | ||
2079 | 838 | content = gtk_text_buffer_get_text (buffer, &s, &e, FALSE); | ||
2080 | 839 | |||
2081 | 840 | confirm = strcmp (g_strstrip (content), "") != 0; | ||
2082 | 841 | |||
2083 | 842 | g_free (content); | ||
2084 | 843 | |||
2085 | 844 | return confirm; | ||
2086 | 845 | } | ||
2087 | 846 | |||
2088 | 847 | static void | ||
2089 | 848 | xpad_pad_delete (XpadPad *pad) | ||
2090 | 849 | { | ||
2091 | 850 | g_return_if_fail (pad); | ||
2092 | 851 | |||
2093 | 852 | /* With the delayed saving functionality, it is necessary to clear the unsaved flags to prevent usage of non-existing object information. */ | ||
2094 | 853 | pad->priv->unsaved_info = FALSE; | ||
2095 | 854 | pad->priv->unsaved_content = FALSE; | ||
2096 | 855 | |||
2097 | 856 | if (should_confirm_delete (pad)) | ||
2098 | 857 | { | ||
2099 | 858 | GtkWidget *dialog; | ||
2100 | 859 | gint response; | ||
2101 | 860 | |||
2102 | 861 | dialog = xpad_app_alert_dialog (GTK_WINDOW (pad), "dialog-warning", _("Delete this pad?"), _("All text of this pad will be irrevocably lost.")); | ||
2103 | 862 | |||
2104 | 863 | if (!dialog) | ||
2105 | 864 | return; | ||
2106 | 865 | |||
2107 | 866 | gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Delete"), GTK_RESPONSE_ACCEPT, _("_Cancel"), GTK_RESPONSE_REJECT, NULL); | ||
2108 | 867 | |||
2109 | 868 | response = gtk_dialog_run (GTK_DIALOG (dialog)); | ||
2110 | 869 | |||
2111 | 870 | gtk_widget_destroy (dialog); | ||
2112 | 871 | |||
2113 | 872 | if (response != GTK_RESPONSE_ACCEPT) | ||
2114 | 873 | return; | ||
2115 | 874 | } | ||
2116 | 875 | |||
2117 | 876 | /* These two if statements actually erase the pad on the harddisk. */ | ||
2118 | 877 | if (pad->priv->infoname) | ||
2119 | 878 | fio_remove_file (pad->priv->infoname); | ||
2120 | 879 | if (pad->priv->contentname) | ||
2121 | 880 | fio_remove_file (pad->priv->contentname); | ||
2122 | 881 | |||
2123 | 882 | /* Remove the pad from the group and destroy it. */ | ||
2124 | 883 | gtk_widget_destroy (GTK_WIDGET (pad)); | ||
2125 | 884 | } | ||
2126 | 885 | |||
2127 | 886 | static void | ||
2128 | 887 | pad_properties_sync_title (XpadPad *pad) | ||
2129 | 888 | { | ||
2130 | 889 | gchar *title; | ||
2131 | 890 | |||
2132 | 891 | if (!pad->priv->properties) | ||
2133 | 892 | return; | ||
2134 | 893 | |||
2135 | 894 | title = g_strdup_printf (_("'%s' Properties"), gtk_window_get_title (GTK_WINDOW (pad))); | ||
2136 | 895 | gtk_window_set_title (GTK_WINDOW (pad->priv->properties), title); | ||
2137 | 896 | g_free (title); | ||
2138 | 897 | } | ||
2139 | 898 | |||
2140 | 899 | static void | ||
2141 | 900 | pad_properties_destroyed (XpadPad *pad) | ||
2142 | 901 | { | ||
2143 | 902 | if (!pad->priv->properties) | ||
2144 | 903 | return; | ||
2145 | 904 | |||
2146 | 905 | g_signal_handlers_disconnect_by_func (pad, (gpointer) pad_properties_sync_title, NULL); | ||
2147 | 906 | pad->priv->properties = NULL; | ||
2148 | 907 | } | ||
2149 | 908 | |||
2150 | 909 | static void | ||
2151 | 910 | prop_notify_font (XpadPad *pad) | ||
2152 | 911 | { | ||
2153 | 912 | XpadPadProperties *prop = XPAD_PAD_PROPERTIES (pad->priv->properties); | ||
2154 | 913 | |||
2155 | 914 | gboolean follow_font_style; | ||
2156 | 915 | g_object_get (prop, "follow-font-style", &follow_font_style, NULL); | ||
2157 | 916 | g_object_set (XPAD_TEXT_VIEW (pad->priv->textview), "follow-font-style", follow_font_style, NULL); | ||
2158 | 917 | |||
2159 | 918 | if (!follow_font_style) | ||
2160 | 919 | { | ||
2161 | 920 | const gchar *font; | ||
2162 | 921 | g_object_get (prop, "fontname", &font, NULL); | ||
2163 | 922 | PangoFontDescription *fontdesc; | ||
2164 | 923 | |||
2165 | 924 | fontdesc = font ? pango_font_description_from_string (font) : NULL; | ||
2166 | 925 | gtk_widget_override_font (pad->priv->textview, fontdesc); | ||
2167 | 926 | if (fontdesc) | ||
2168 | 927 | pango_font_description_free (fontdesc); | ||
2169 | 928 | } | ||
2170 | 929 | |||
2171 | 930 | xpad_pad_save_info_delayed (pad); | ||
2172 | 931 | } | ||
2173 | 932 | |||
2174 | 933 | static void | ||
2175 | 934 | prop_notify_colors (XpadPad *pad) | ||
2176 | 935 | { | ||
2177 | 936 | XpadPadProperties *prop = XPAD_PAD_PROPERTIES (pad->priv->properties); | ||
2178 | 937 | |||
2179 | 938 | gboolean follow_color_style; | ||
2180 | 939 | const GdkRGBA *text_color, *back_color; | ||
2181 | 940 | |||
2182 | 941 | g_object_get (prop, "follow-color-style", &follow_color_style, NULL); | ||
2183 | 942 | g_object_set (XPAD_TEXT_VIEW (pad->priv->textview), "follow-color-style", follow_color_style, NULL); | ||
2184 | 943 | |||
2185 | 944 | if (follow_color_style) | ||
2186 | 945 | /* Set the colors to the global preferences colors */ | ||
2187 | 946 | g_object_get (pad->priv->settings, "text-color", &text_color, "back-color", &back_color, NULL); | ||
2188 | 947 | else | ||
2189 | 948 | /* Set the color to the individual pad properties colors */ | ||
2190 | 949 | g_object_get (prop, "text-color", &text_color, "back-color", &back_color, NULL); | ||
2191 | 950 | |||
2192 | 951 | gtk_widget_override_cursor (pad->priv->textview, text_color, text_color); | ||
2193 | 952 | gtk_widget_override_color (pad->priv->textview, GTK_STATE_FLAG_NORMAL, text_color); | ||
2194 | 953 | gtk_widget_override_background_color (pad->priv->textview, GTK_STATE_FLAG_NORMAL, back_color); | ||
2195 | 954 | |||
2196 | 955 | /* Inverse the text and background colors for selected text, so it is likely to be visible by any choice of the colors. */ | ||
2197 | 956 | gtk_widget_override_color (pad->priv->textview, GTK_STATE_FLAG_SELECTED, back_color); | ||
2198 | 957 | gtk_widget_override_background_color (pad->priv->textview, GTK_STATE_FLAG_SELECTED, text_color); | ||
2199 | 958 | |||
2200 | 959 | xpad_pad_save_info_delayed (pad); | ||
2201 | 960 | } | ||
2202 | 961 | |||
2203 | 962 | static void | ||
2204 | 963 | xpad_pad_open_properties (XpadPad *pad) | ||
2205 | 964 | { | ||
2206 | 965 | gboolean follow_font_style, follow_color_style; | ||
2207 | 966 | GtkStyleContext *style = NULL; | ||
2208 | 967 | PangoFontDescription *font; | ||
2209 | 968 | GdkRGBA widget_text_color = {0, 0, 0, 0}; | ||
2210 | 969 | GdkRGBA widget_background_color = {0, 0, 0, 0}; | ||
2211 | 970 | |||
2212 | 971 | if (pad->priv->properties) | ||
2213 | 972 | { | ||
2214 | 973 | gtk_window_present (GTK_WINDOW (pad->priv->properties)); | ||
2215 | 974 | return; | ||
2216 | 975 | } | ||
2217 | 976 | |||
2218 | 977 | pad->priv->properties = xpad_pad_properties_new (); | ||
2219 | 978 | |||
2220 | 979 | gtk_window_set_transient_for (GTK_WINDOW (pad->priv->properties), GTK_WINDOW (pad)); | ||
2221 | 980 | gtk_window_set_resizable (GTK_WINDOW (pad->priv->properties), FALSE); | ||
2222 | 981 | |||
2223 | 982 | g_signal_connect_swapped (pad->priv->properties, "destroy", G_CALLBACK (pad_properties_destroyed), pad); | ||
2224 | 983 | g_signal_connect (pad, "notify::title", G_CALLBACK (pad_properties_sync_title), NULL); | ||
2225 | 984 | |||
2226 | 985 | style = gtk_widget_get_style_context (pad->priv->textview); | ||
2227 | 986 | gtk_style_context_get(style, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font, NULL); | ||
2228 | 987 | gtk_style_context_get_color (style, GTK_STATE_FLAG_NORMAL, &widget_text_color); | ||
2229 | 988 | gtk_style_context_get_background_color (style, GTK_STATE_FLAG_NORMAL, &widget_background_color); | ||
2230 | 989 | |||
2231 | 990 | g_object_get (XPAD_TEXT_VIEW (pad->priv->textview), "follow-font-style", &follow_font_style, "follow-color-style", &follow_color_style, NULL); | ||
2232 | 991 | g_object_set (G_OBJECT (pad->priv->properties), | ||
2233 | 992 | "follow-font-style", follow_font_style, | ||
2234 | 993 | "follow-color-style", follow_color_style, | ||
2235 | 994 | "text-color", &widget_text_color, | ||
2236 | 995 | "back-color", &widget_background_color, | ||
2237 | 996 | "fontname", pango_font_description_to_string(font), | ||
2238 | 997 | NULL); | ||
2239 | 998 | pango_font_description_free (font); | ||
2240 | 999 | |||
2241 | 1000 | g_signal_connect_swapped (pad->priv->properties, "notify::follow-font-style", G_CALLBACK (prop_notify_font), pad); | ||
2242 | 1001 | g_signal_connect_swapped (pad->priv->properties, "notify::follow-color-style", G_CALLBACK (prop_notify_colors), pad); | ||
2243 | 1002 | g_signal_connect_swapped (pad->priv->properties, "notify::text-color", G_CALLBACK (prop_notify_colors), pad); | ||
2244 | 1003 | g_signal_connect_swapped (pad->priv->properties, "notify::back-color", G_CALLBACK (prop_notify_colors), pad); | ||
2245 | 1004 | g_signal_connect_swapped (pad->priv->properties, "notify::fontname", G_CALLBACK (prop_notify_font), pad); | ||
2246 | 1005 | |||
2247 | 1006 | pad_properties_sync_title (pad); | ||
2248 | 1007 | |||
2249 | 1008 | gtk_widget_show (pad->priv->properties); | ||
2250 | 1009 | } | ||
2251 | 1010 | |||
2252 | 1011 | static void | ||
2253 | 1012 | xpad_pad_open_preferences (XpadPad *pad) | ||
2254 | 1013 | { | ||
2255 | 1014 | xpad_preferences_open (pad->priv->settings); | ||
2256 | 1015 | } | ||
2257 | 1016 | |||
2258 | 1017 | static void | ||
2259 | 1018 | xpad_pad_text_changed (XpadPad *pad, GtkTextBuffer *buffer) | ||
2260 | 1019 | { | ||
2261 | 1020 | /* A dirty way to silence the compiler for these unused variables. */ | ||
2262 | 1021 | (void) buffer; | ||
2263 | 1022 | |||
2264 | 1023 | /* set title */ | ||
2265 | 1024 | xpad_pad_sync_title (pad); | ||
2266 | 1025 | |||
2267 | 1026 | /* record change */ | ||
2268 | 1027 | xpad_pad_save_content_delayed(pad); | ||
2269 | 1028 | } | ||
2270 | 1029 | |||
2271 | 1030 | static gboolean | ||
2272 | 1031 | xpad_pad_toolbar_size_allocate (XpadPad *pad, GtkAllocation *event) | ||
2273 | 1032 | { | ||
2274 | 1033 | /* safe cast from gint to guint */ | ||
2275 | 1034 | if (event->height >= 0) { | ||
2276 | 1035 | pad->priv->toolbar_height = (guint) event->height; | ||
2277 | 1036 | } | ||
2278 | 1037 | else { | ||
2279 | 1038 | g_warning("There is a problem in the program Xpad. In function 'xpad_pad_toolbar_size_allocate' the variable 'event->height' is not a postive number. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad."); | ||
2280 | 1039 | pad->priv->toolbar_height = 0; | ||
2281 | 1040 | } | ||
2282 | 1041 | return FALSE; | ||
2283 | 1042 | } | ||
2284 | 1043 | |||
2285 | 1044 | static gboolean | ||
2286 | 1045 | xpad_pad_configure_event (XpadPad *pad, GdkEventConfigure *event) | ||
2287 | 1046 | { | ||
2288 | 1047 | if (!gtk_widget_get_visible (GTK_WIDGET(pad))) | ||
2289 | 1048 | return FALSE; | ||
2290 | 1049 | |||
2291 | 1050 | int eWidth = event->width; | ||
2292 | 1051 | int eHeight = event->height; | ||
2293 | 1052 | |||
2294 | 1053 | /* safe cast from gint to guint */ | ||
2295 | 1054 | if (eWidth >= 0 && eHeight >=0 ) { | ||
2296 | 1055 | if (pad->priv->width != (guint) eWidth || pad->priv->height != (guint) eHeight) | ||
2297 | 1056 | pad->priv->toolbar_pad_resized = TRUE; | ||
2298 | 1057 | |||
2299 | 1058 | pad->priv->width = (guint) event->width; | ||
2300 | 1059 | pad->priv->height = (guint) event->height; | ||
2301 | 1060 | } | ||
2302 | 1061 | else { | ||
2303 | 1062 | g_warning("There is a problem in the program Xpad. In function 'xpad_pad_configure_event' the variable 'event->width' or 'event->height' is not a postive number. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad."); | ||
2304 | 1063 | } | ||
2305 | 1064 | |||
2306 | 1065 | pad->priv->x = event->x; | ||
2307 | 1066 | pad->priv->y = event->y; | ||
2308 | 1067 | pad->priv->location_valid = TRUE; | ||
2309 | 1068 | |||
2310 | 1069 | xpad_pad_save_info_delayed(pad); | ||
2311 | 1070 | |||
2312 | 1071 | /* | ||
2313 | 1072 | * Sometimes when moving, if the toolbar tries to hide itself, | ||
2314 | 1073 | * the window manager will not resize it correctly. So, we make | ||
2315 | 1074 | * sure not to end the timeout while moving. | ||
2316 | 1075 | */ | ||
2317 | 1076 | if (pad->priv->toolbar_timeout) | ||
2318 | 1077 | { | ||
2319 | 1078 | g_source_remove (pad->priv->toolbar_timeout); | ||
2320 | 1079 | pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad); | ||
2321 | 1080 | } | ||
2322 | 1081 | |||
2323 | 1082 | return FALSE; | ||
2324 | 1083 | } | ||
2325 | 1084 | |||
2326 | 1085 | static gboolean | ||
2327 | 1086 | xpad_pad_delete_event (XpadPad *pad, GdkEvent *event) | ||
2328 | 1087 | { | ||
2329 | 1088 | /* A dirty way to silence the compiler for these unused variables. */ | ||
2330 | 1089 | (void) event; | ||
2331 | 1090 | |||
2332 | 1091 | xpad_pad_close (pad); | ||
2333 | 1092 | |||
2334 | 1093 | return TRUE; | ||
2335 | 1094 | } | ||
2336 | 1095 | |||
2337 | 1096 | static gboolean | ||
2338 | 1097 | xpad_pad_popup_menu (XpadPad *pad) | ||
2339 | 1098 | { | ||
2340 | 1099 | xpad_pad_popup (pad, NULL); | ||
2341 | 1100 | |||
2342 | 1101 | return TRUE; | ||
2343 | 1102 | } | ||
2344 | 1103 | |||
2345 | 1104 | static gboolean | ||
2346 | 1105 | xpad_pad_button_press_event (XpadPad *pad, GdkEventButton *event) | ||
2347 | 1106 | { | ||
2348 | 1107 | if (event->type == GDK_BUTTON_PRESS) | ||
2349 | 1108 | { | ||
2350 | 1109 | switch (event->button) | ||
2351 | 1110 | { | ||
2352 | 1111 | case 1: | ||
2353 | 1112 | if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_CONTROL_MASK) | ||
2354 | 1113 | { | ||
2355 | 1114 | gtk_window_begin_move_drag (GTK_WINDOW (pad), (gint) event->button, (gint) event->x_root, (gint) event->y_root, event->time); | ||
2356 | 1115 | return TRUE; | ||
2357 | 1116 | } | ||
2358 | 1117 | break; | ||
2359 | 1118 | |||
2360 | 1119 | case 3: | ||
2361 | 1120 | if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_CONTROL_MASK) | ||
2362 | 1121 | { | ||
2363 | 1122 | GdkWindowEdge edge; | ||
2364 | 1123 | |||
2365 | 1124 | if (gtk_widget_get_direction (GTK_WIDGET (pad)) == GTK_TEXT_DIR_LTR) | ||
2366 | 1125 | edge = GDK_WINDOW_EDGE_SOUTH_EAST; | ||
2367 | 1126 | else | ||
2368 | 1127 | edge = GDK_WINDOW_EDGE_SOUTH_WEST; | ||
2369 | 1128 | |||
2370 | 1129 | gtk_window_begin_resize_drag (GTK_WINDOW (pad), edge, (gint) event->button, (gint) event->x_root, (gint) event->y_root, event->time); | ||
2371 | 1130 | } | ||
2372 | 1131 | else | ||
2373 | 1132 | { | ||
2374 | 1133 | xpad_pad_popup (pad, event); | ||
2375 | 1134 | } | ||
2376 | 1135 | return TRUE; | ||
2377 | 1136 | } | ||
2378 | 1137 | } | ||
2379 | 1138 | |||
2380 | 1139 | return FALSE; | ||
2381 | 1140 | } | ||
2382 | 1141 | |||
2383 | 1142 | static void | ||
2384 | 1143 | xpad_pad_sync_title (XpadPad *pad) | ||
2385 | 1144 | { | ||
2386 | 1145 | GtkTextBuffer *buffer; | ||
2387 | 1146 | GtkTextIter s, e; | ||
2388 | 1147 | gchar *content, *end; | ||
2389 | 1148 | |||
2390 | 1149 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
2391 | 1150 | gtk_text_buffer_get_bounds (buffer, &s, &e); | ||
2392 | 1151 | content = gtk_text_buffer_get_text (buffer, &s, &e, FALSE); | ||
2393 | 1152 | end = g_utf8_strchr (content, -1, '\n'); | ||
2394 | 1153 | if (end) | ||
2395 | 1154 | *end = '\0'; | ||
2396 | 1155 | |||
2397 | 1156 | gtk_window_set_title (GTK_WINDOW (pad), g_strstrip (content)); | ||
2398 | 1157 | |||
2399 | 1158 | g_free (content); | ||
2400 | 1159 | } | ||
2401 | 1160 | |||
2402 | 1161 | void | ||
2403 | 1162 | xpad_pad_load_content (XpadPad *pad) | ||
2404 | 1163 | { | ||
2405 | 1164 | g_return_if_fail (pad); | ||
2406 | 1165 | |||
2407 | 1166 | gchar *content; | ||
2408 | 1167 | GtkTextBuffer *buffer; | ||
2409 | 1168 | |||
2410 | 1169 | if (!pad->priv->contentname) | ||
2411 | 1170 | return; | ||
2412 | 1171 | |||
2413 | 1172 | content = fio_get_file (pad->priv->contentname); | ||
2414 | 1173 | |||
2415 | 1174 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
2416 | 1175 | |||
2417 | 1176 | xpad_text_buffer_freeze_undo (XPAD_TEXT_BUFFER (buffer)); | ||
2418 | 1177 | g_signal_handlers_block_by_func (buffer, xpad_pad_text_changed, pad); | ||
2419 | 1178 | |||
2420 | 1179 | xpad_text_buffer_set_text_with_tags (XPAD_TEXT_BUFFER (buffer), content ? content : ""); | ||
2421 | 1180 | g_free (content); | ||
2422 | 1181 | |||
2423 | 1182 | g_signal_handlers_unblock_by_func (buffer, xpad_pad_text_changed, pad); | ||
2424 | 1183 | xpad_text_buffer_thaw_undo (XPAD_TEXT_BUFFER (buffer)); | ||
2425 | 1184 | |||
2426 | 1185 | xpad_pad_text_changed(pad, buffer); | ||
2427 | 1186 | pad->priv->unsaved_content = FALSE; | ||
2428 | 1187 | } | ||
2429 | 1188 | |||
2430 | 1189 | void | ||
2431 | 1190 | xpad_pad_save_content (XpadPad *pad) | ||
2432 | 1191 | { | ||
2433 | 1192 | g_return_if_fail (pad); | ||
2434 | 1193 | |||
2435 | 1194 | gchar *content; | ||
2436 | 1195 | GtkTextBuffer *buffer; | ||
2437 | 1196 | |||
2438 | 1197 | if (!pad->priv->unsaved_content) | ||
2439 | 1198 | return; | ||
2440 | 1199 | |||
2441 | 1200 | /* create content file if it doesn't exist yet */ | ||
2442 | 1201 | if (!pad->priv->contentname) | ||
2443 | 1202 | { | ||
2444 | 1203 | pad->priv->contentname = fio_unique_name ("content-"); | ||
2445 | 1204 | if (!pad->priv->contentname) | ||
2446 | 1205 | return; | ||
2447 | 1206 | } | ||
2448 | 1207 | |||
2449 | 1208 | if (GTK_IS_TEXT_VIEW(pad->priv->textview)) { | ||
2450 | 1209 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
2451 | 1210 | content = xpad_text_buffer_get_text_with_tags (XPAD_TEXT_BUFFER (buffer)); | ||
2452 | 1211 | } | ||
2453 | 1212 | else | ||
2454 | 1213 | g_warning("There is a problem in the program Xpad. In function 'xpad_pad_save_content' the variable 'pad->priv->textview' is not of type textview. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad."); | ||
2455 | 1214 | |||
2456 | 1215 | fio_set_file (pad->priv->contentname, content); | ||
2457 | 1216 | |||
2458 | 1217 | pad->priv->unsaved_content = FALSE; | ||
2459 | 1218 | g_free (content); | ||
2460 | 1219 | } | ||
2461 | 1220 | |||
2462 | 1221 | /* Extract all the metadata of a single pad from its info-xxxxx file and store it in the pad object */ | 292 | /* Extract all the metadata of a single pad from its info-xxxxx file and store it in the pad object */ |
2463 | 1222 | static void | 293 | static void |
2465 | 1223 | xpad_pad_load_info (XpadPad *pad, gboolean *show) | 294 | xpad_pad_load_info (XpadPad *pad, |
2466 | 295 | gboolean *show) | ||
2467 | 1224 | { | 296 | { |
2468 | 1225 | gboolean locked = FALSE, follow_font = TRUE, follow_color = TRUE, hidden = FALSE; | 297 | gboolean locked = FALSE, follow_font = TRUE, follow_color = TRUE, hidden = FALSE; |
2469 | 1226 | gboolean has_toolbar, autohide_toolbar; | 298 | gboolean has_toolbar, autohide_toolbar; |
2470 | @@ -1406,29 +478,142 @@ | |||
2471 | 1406 | pad->priv->unsaved_info = FALSE; | 478 | pad->priv->unsaved_info = FALSE; |
2472 | 1407 | } | 479 | } |
2473 | 1408 | 480 | ||
2497 | 1409 | static void | 481 | /* Create a new pad based on the provided info-xxxxx file from the config directory and return this pad */ |
2498 | 1410 | menu_about (XpadPad *pad) | 482 | GtkWidget * |
2499 | 1411 | { | 483 | xpad_pad_new_with_info (XpadPadGroup *group, |
2500 | 1412 | const gchar *artists[] = {"Michael Terry <mike@mterry.name>", NULL}; | 484 | XpadSettings *settings, |
2501 | 1413 | const gchar *authors[] = {"Arthur Borsboom <arthurborsboom@gmail.com>", "Jeroen Vermeulen <jtv@xs4all.nl>", "Michael Terry <mike@mterry.name>", "Paul Ivanov <pivanov@berkeley.edu>", "Sachin Raut <great.sachin@gmail.com>", NULL}; | 485 | const gchar *info_filename, |
2502 | 1414 | const gchar *comments = _("Sticky notes"); | 486 | gboolean *show) |
2503 | 1415 | const gchar *copyright = "© 2001-2014 Michael Terry"; | 487 | { |
2504 | 1416 | /* Translators: please translate this as your own name and optionally email | 488 | GtkWidget *pad = xpad_pad_new (group, settings); |
2505 | 1417 | like so: "Your Name <your@email.com>" */ | 489 | |
2506 | 1418 | const gchar *translator_credits = _("translator-credits"); | 490 | XPAD_PAD (pad)->priv->infoname = g_strdup (info_filename); |
2507 | 1419 | const gchar *website = "https://launchpad.net/xpad"; | 491 | xpad_pad_load_info (XPAD_PAD (pad), show); |
2508 | 1420 | 492 | xpad_pad_load_content (XPAD_PAD (pad)); | |
2509 | 1421 | gtk_show_about_dialog (GTK_WINDOW (pad), | 493 | gtk_window_set_role (GTK_WINDOW (pad), XPAD_PAD (pad)->priv->infoname); |
2510 | 1422 | "artists", artists, | 494 | |
2511 | 1423 | "authors", authors, | 495 | return pad; |
2512 | 1424 | "comments", comments, | 496 | } |
2513 | 1425 | "copyright", copyright, | 497 | |
2514 | 1426 | "license-type", GTK_LICENSE_GPL_3_0, | 498 | /* Create a new pad based on the provided filename from the command line */ |
2515 | 1427 | "logo-icon-name", PACKAGE, | 499 | GtkWidget * |
2516 | 1428 | "translator-credits", translator_credits, | 500 | xpad_pad_new_from_file (XpadPadGroup *group, |
2517 | 1429 | "version", VERSION, | 501 | XpadSettings *settings, |
2518 | 1430 | "website", website, | 502 | const gchar *filename) |
2519 | 1431 | NULL); | 503 | { |
2520 | 504 | GtkWidget *pad = NULL; | ||
2521 | 505 | gchar *content; | ||
2522 | 506 | |||
2523 | 507 | content = fio_get_file (filename); | ||
2524 | 508 | |||
2525 | 509 | if (!content) | ||
2526 | 510 | { | ||
2527 | 511 | gchar *usertext = g_strdup_printf (_("Could not read file %s."), filename); | ||
2528 | 512 | xpad_app_error (NULL, usertext, NULL); | ||
2529 | 513 | g_free (usertext); | ||
2530 | 514 | } | ||
2531 | 515 | else | ||
2532 | 516 | { | ||
2533 | 517 | GtkTextBuffer *buffer; | ||
2534 | 518 | |||
2535 | 519 | xpad_periodic_init (); | ||
2536 | 520 | xpad_periodic_set_callback ("save-content", (XpadPeriodicFunc) xpad_pad_save_content); | ||
2537 | 521 | |||
2538 | 522 | pad = xpad_pad_new (group, settings); | ||
2539 | 523 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (XPAD_PAD (pad)->priv->textview)); | ||
2540 | 524 | |||
2541 | 525 | xpad_text_buffer_freeze_undo (XPAD_TEXT_BUFFER (buffer)); | ||
2542 | 526 | g_signal_handlers_block_by_func (buffer, xpad_pad_text_changed, pad); | ||
2543 | 527 | |||
2544 | 528 | xpad_text_buffer_set_text_with_tags (XPAD_TEXT_BUFFER (buffer), content ? content : ""); | ||
2545 | 529 | g_free (content); | ||
2546 | 530 | |||
2547 | 531 | g_signal_handlers_unblock_by_func (buffer, xpad_pad_text_changed, pad); | ||
2548 | 532 | xpad_text_buffer_thaw_undo (XPAD_TEXT_BUFFER (buffer)); | ||
2549 | 533 | |||
2550 | 534 | xpad_pad_text_changed(XPAD_PAD(pad), buffer); | ||
2551 | 535 | } | ||
2552 | 536 | |||
2553 | 537 | return pad; | ||
2554 | 538 | } | ||
2555 | 539 | |||
2556 | 540 | static void | ||
2557 | 541 | xpad_pad_set_property (GObject *object, | ||
2558 | 542 | guint prop_id, | ||
2559 | 543 | const GValue *value, | ||
2560 | 544 | GParamSpec *pspec) | ||
2561 | 545 | { | ||
2562 | 546 | XpadPad *pad = XPAD_PAD (object); | ||
2563 | 547 | |||
2564 | 548 | switch (prop_id) | ||
2565 | 549 | { | ||
2566 | 550 | case PROP_GROUP: | ||
2567 | 551 | pad->priv->group = g_value_get_pointer (value); | ||
2568 | 552 | g_object_ref (pad->priv->group); | ||
2569 | 553 | if (pad->priv->group) | ||
2570 | 554 | xpad_pad_group_add (pad->priv->group, GTK_WIDGET (pad)); | ||
2571 | 555 | break; | ||
2572 | 556 | |||
2573 | 557 | case PROP_SETTINGS: | ||
2574 | 558 | pad->priv->settings = g_value_get_pointer (value); | ||
2575 | 559 | g_object_ref (pad->priv->settings); | ||
2576 | 560 | break; | ||
2577 | 561 | |||
2578 | 562 | default: | ||
2579 | 563 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
2580 | 564 | break; | ||
2581 | 565 | } | ||
2582 | 566 | } | ||
2583 | 567 | |||
2584 | 568 | static void | ||
2585 | 569 | xpad_pad_get_property (GObject *object, | ||
2586 | 570 | guint prop_id, | ||
2587 | 571 | GValue *value, | ||
2588 | 572 | GParamSpec *pspec) | ||
2589 | 573 | { | ||
2590 | 574 | XpadPad *pad = XPAD_PAD (object); | ||
2591 | 575 | |||
2592 | 576 | switch (prop_id) | ||
2593 | 577 | { | ||
2594 | 578 | case PROP_GROUP: | ||
2595 | 579 | g_value_set_pointer (value, pad->priv->group); | ||
2596 | 580 | break; | ||
2597 | 581 | |||
2598 | 582 | case PROP_SETTINGS: | ||
2599 | 583 | g_value_set_pointer (value, pad->priv->settings); | ||
2600 | 584 | break; | ||
2601 | 585 | |||
2602 | 586 | default: | ||
2603 | 587 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
2604 | 588 | break; | ||
2605 | 589 | } | ||
2606 | 590 | } | ||
2607 | 591 | |||
2608 | 592 | static void | ||
2609 | 593 | xpad_pad_spawn (XpadPad *pad) | ||
2610 | 594 | { | ||
2611 | 595 | GtkWidget *newpad = xpad_pad_new (pad->priv->group, pad->priv->settings); | ||
2612 | 596 | gtk_widget_show (newpad); | ||
2613 | 597 | } | ||
2614 | 598 | |||
2615 | 599 | static void | ||
2616 | 600 | xpad_pad_undo (XpadPad *pad) | ||
2617 | 601 | { | ||
2618 | 602 | g_return_if_fail (pad->priv->textview); | ||
2619 | 603 | XpadTextBuffer *buffer = NULL; | ||
2620 | 604 | buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview))); | ||
2621 | 605 | g_return_if_fail (buffer); | ||
2622 | 606 | xpad_text_buffer_undo (buffer); | ||
2623 | 607 | } | ||
2624 | 608 | |||
2625 | 609 | static void | ||
2626 | 610 | xpad_pad_redo (XpadPad *pad) | ||
2627 | 611 | { | ||
2628 | 612 | g_return_if_fail (pad->priv->textview); | ||
2629 | 613 | XpadTextBuffer *buffer = NULL; | ||
2630 | 614 | buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview))); | ||
2631 | 615 | g_return_if_fail (buffer); | ||
2632 | 616 | xpad_text_buffer_redo (buffer); | ||
2633 | 1432 | } | 617 | } |
2634 | 1433 | 618 | ||
2635 | 1434 | static void | 619 | static void |
2636 | @@ -1459,26 +644,6 @@ | |||
2637 | 1459 | } | 644 | } |
2638 | 1460 | 645 | ||
2639 | 1461 | static void | 646 | static void |
2640 | 1462 | xpad_pad_undo (XpadPad *pad) | ||
2641 | 1463 | { | ||
2642 | 1464 | g_return_if_fail (pad->priv->textview); | ||
2643 | 1465 | XpadTextBuffer *buffer = NULL; | ||
2644 | 1466 | buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview))); | ||
2645 | 1467 | g_return_if_fail (buffer); | ||
2646 | 1468 | xpad_text_buffer_undo (buffer); | ||
2647 | 1469 | } | ||
2648 | 1470 | |||
2649 | 1471 | static void | ||
2650 | 1472 | xpad_pad_redo (XpadPad *pad) | ||
2651 | 1473 | { | ||
2652 | 1474 | g_return_if_fail (pad->priv->textview); | ||
2653 | 1475 | XpadTextBuffer *buffer = NULL; | ||
2654 | 1476 | buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview))); | ||
2655 | 1477 | g_return_if_fail (buffer); | ||
2656 | 1478 | xpad_text_buffer_redo (buffer); | ||
2657 | 1479 | } | ||
2658 | 1480 | |||
2659 | 1481 | static void | ||
2660 | 1482 | xpad_pad_show_all (XpadPad *pad) | 647 | xpad_pad_show_all (XpadPad *pad) |
2661 | 1483 | { | 648 | { |
2662 | 1484 | xpad_pad_group_show_all (pad->priv->group); | 649 | xpad_pad_group_show_all (pad->priv->group); |
2663 | @@ -1502,8 +667,202 @@ | |||
2664 | 1502 | xpad_app_quit (); | 667 | xpad_app_quit (); |
2665 | 1503 | } | 668 | } |
2666 | 1504 | 669 | ||
2669 | 1505 | static void | 670 | static gboolean |
2670 | 1506 | menu_toggle_tag (XpadPad *pad, const gchar *name) | 671 | should_confirm_delete (XpadPad *pad) |
2671 | 672 | { | ||
2672 | 673 | GtkTextBuffer *buffer; | ||
2673 | 674 | GtkTextIter s, e; | ||
2674 | 675 | gchar *content; | ||
2675 | 676 | gboolean confirm; | ||
2676 | 677 | |||
2677 | 678 | g_object_get (pad->priv->settings, "confirm-destroy", &confirm, NULL); | ||
2678 | 679 | if (!confirm) | ||
2679 | 680 | return FALSE; | ||
2680 | 681 | |||
2681 | 682 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
2682 | 683 | gtk_text_buffer_get_bounds (buffer, &s, &e); | ||
2683 | 684 | content = gtk_text_buffer_get_text (buffer, &s, &e, FALSE); | ||
2684 | 685 | |||
2685 | 686 | confirm = strcmp (g_strstrip (content), "") != 0; | ||
2686 | 687 | |||
2687 | 688 | g_free (content); | ||
2688 | 689 | |||
2689 | 690 | return confirm; | ||
2690 | 691 | } | ||
2691 | 692 | |||
2692 | 693 | static void | ||
2693 | 694 | xpad_pad_delete (XpadPad *pad) | ||
2694 | 695 | { | ||
2695 | 696 | g_return_if_fail (pad); | ||
2696 | 697 | |||
2697 | 698 | /* With the delayed saving functionality, it is necessary to clear the unsaved flags to prevent usage of non-existing object information. */ | ||
2698 | 699 | pad->priv->unsaved_info = FALSE; | ||
2699 | 700 | pad->priv->unsaved_content = FALSE; | ||
2700 | 701 | |||
2701 | 702 | if (should_confirm_delete (pad)) | ||
2702 | 703 | { | ||
2703 | 704 | GtkWidget *dialog; | ||
2704 | 705 | gint response; | ||
2705 | 706 | |||
2706 | 707 | dialog = xpad_app_alert_dialog (GTK_WINDOW (pad), "dialog-warning", _("Delete this pad?"), _("All text of this pad will be irrevocably lost.")); | ||
2707 | 708 | |||
2708 | 709 | if (!dialog) | ||
2709 | 710 | return; | ||
2710 | 711 | |||
2711 | 712 | gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Delete"), GTK_RESPONSE_ACCEPT, _("_Cancel"), GTK_RESPONSE_REJECT, NULL); | ||
2712 | 713 | |||
2713 | 714 | response = gtk_dialog_run (GTK_DIALOG (dialog)); | ||
2714 | 715 | |||
2715 | 716 | gtk_widget_destroy (dialog); | ||
2716 | 717 | |||
2717 | 718 | if (response != GTK_RESPONSE_ACCEPT) | ||
2718 | 719 | return; | ||
2719 | 720 | } | ||
2720 | 721 | |||
2721 | 722 | /* These two if statements actually erase the pad on the harddisk. */ | ||
2722 | 723 | if (pad->priv->infoname) | ||
2723 | 724 | fio_remove_file (pad->priv->infoname); | ||
2724 | 725 | if (pad->priv->contentname) | ||
2725 | 726 | fio_remove_file (pad->priv->contentname); | ||
2726 | 727 | |||
2727 | 728 | /* Remove the pad from the group and destroy it. */ | ||
2728 | 729 | gtk_widget_destroy (GTK_WIDGET (pad)); | ||
2729 | 730 | } | ||
2730 | 731 | |||
2731 | 732 | static void | ||
2732 | 733 | pad_properties_sync_title (XpadPad *pad) | ||
2733 | 734 | { | ||
2734 | 735 | gchar *title; | ||
2735 | 736 | |||
2736 | 737 | if (!pad->priv->properties) | ||
2737 | 738 | return; | ||
2738 | 739 | |||
2739 | 740 | title = g_strdup_printf (_("'%s' Properties"), gtk_window_get_title (GTK_WINDOW (pad))); | ||
2740 | 741 | gtk_window_set_title (GTK_WINDOW (pad->priv->properties), title); | ||
2741 | 742 | g_free (title); | ||
2742 | 743 | } | ||
2743 | 744 | |||
2744 | 745 | static void | ||
2745 | 746 | pad_properties_destroyed (XpadPad *pad) | ||
2746 | 747 | { | ||
2747 | 748 | if (!pad->priv->properties) | ||
2748 | 749 | return; | ||
2749 | 750 | |||
2750 | 751 | g_signal_handlers_disconnect_by_func (pad, (gpointer) pad_properties_sync_title, NULL); | ||
2751 | 752 | pad->priv->properties = NULL; | ||
2752 | 753 | } | ||
2753 | 754 | |||
2754 | 755 | static void | ||
2755 | 756 | prop_notify_font (XpadPad *pad) | ||
2756 | 757 | { | ||
2757 | 758 | XpadPadProperties *prop = XPAD_PAD_PROPERTIES (pad->priv->properties); | ||
2758 | 759 | |||
2759 | 760 | gboolean follow_font_style; | ||
2760 | 761 | g_object_get (prop, "follow-font-style", &follow_font_style, NULL); | ||
2761 | 762 | g_object_set (XPAD_TEXT_VIEW (pad->priv->textview), "follow-font-style", follow_font_style, NULL); | ||
2762 | 763 | |||
2763 | 764 | if (!follow_font_style) | ||
2764 | 765 | { | ||
2765 | 766 | const gchar *font; | ||
2766 | 767 | g_object_get (prop, "fontname", &font, NULL); | ||
2767 | 768 | PangoFontDescription *fontdesc; | ||
2768 | 769 | |||
2769 | 770 | fontdesc = font ? pango_font_description_from_string (font) : NULL; | ||
2770 | 771 | gtk_widget_override_font (pad->priv->textview, fontdesc); | ||
2771 | 772 | if (fontdesc) | ||
2772 | 773 | pango_font_description_free (fontdesc); | ||
2773 | 774 | } | ||
2774 | 775 | |||
2775 | 776 | xpad_pad_save_info_delayed (pad); | ||
2776 | 777 | } | ||
2777 | 778 | |||
2778 | 779 | static void | ||
2779 | 780 | prop_notify_colors (XpadPad *pad) | ||
2780 | 781 | { | ||
2781 | 782 | XpadPadProperties *prop = XPAD_PAD_PROPERTIES (pad->priv->properties); | ||
2782 | 783 | |||
2783 | 784 | gboolean follow_color_style; | ||
2784 | 785 | const GdkRGBA *text_color, *back_color; | ||
2785 | 786 | |||
2786 | 787 | g_object_get (prop, "follow-color-style", &follow_color_style, NULL); | ||
2787 | 788 | g_object_set (XPAD_TEXT_VIEW (pad->priv->textview), "follow-color-style", follow_color_style, NULL); | ||
2788 | 789 | |||
2789 | 790 | if (follow_color_style) | ||
2790 | 791 | /* Set the colors to the global preferences colors */ | ||
2791 | 792 | g_object_get (pad->priv->settings, "text-color", &text_color, "back-color", &back_color, NULL); | ||
2792 | 793 | else | ||
2793 | 794 | /* Set the color to the individual pad properties colors */ | ||
2794 | 795 | g_object_get (prop, "text-color", &text_color, "back-color", &back_color, NULL); | ||
2795 | 796 | |||
2796 | 797 | gtk_widget_override_cursor (pad->priv->textview, text_color, text_color); | ||
2797 | 798 | gtk_widget_override_color (pad->priv->textview, GTK_STATE_FLAG_NORMAL, text_color); | ||
2798 | 799 | gtk_widget_override_background_color (pad->priv->textview, GTK_STATE_FLAG_NORMAL, back_color); | ||
2799 | 800 | |||
2800 | 801 | /* Inverse the text and background colors for selected text, so it is likely to be visible by any choice of the colors. */ | ||
2801 | 802 | gtk_widget_override_color (pad->priv->textview, GTK_STATE_FLAG_SELECTED, back_color); | ||
2802 | 803 | gtk_widget_override_background_color (pad->priv->textview, GTK_STATE_FLAG_SELECTED, text_color); | ||
2803 | 804 | |||
2804 | 805 | xpad_pad_save_info_delayed (pad); | ||
2805 | 806 | } | ||
2806 | 807 | |||
2807 | 808 | static void | ||
2808 | 809 | xpad_pad_open_properties (XpadPad *pad) | ||
2809 | 810 | { | ||
2810 | 811 | gboolean follow_font_style, follow_color_style; | ||
2811 | 812 | GtkStyleContext *style = NULL; | ||
2812 | 813 | PangoFontDescription *font; | ||
2813 | 814 | GdkRGBA widget_text_color = {0, 0, 0, 0}; | ||
2814 | 815 | GdkRGBA widget_background_color = {0, 0, 0, 0}; | ||
2815 | 816 | |||
2816 | 817 | if (pad->priv->properties) | ||
2817 | 818 | { | ||
2818 | 819 | gtk_window_present (GTK_WINDOW (pad->priv->properties)); | ||
2819 | 820 | return; | ||
2820 | 821 | } | ||
2821 | 822 | |||
2822 | 823 | pad->priv->properties = xpad_pad_properties_new (); | ||
2823 | 824 | |||
2824 | 825 | gtk_window_set_transient_for (GTK_WINDOW (pad->priv->properties), GTK_WINDOW (pad)); | ||
2825 | 826 | gtk_window_set_resizable (GTK_WINDOW (pad->priv->properties), FALSE); | ||
2826 | 827 | |||
2827 | 828 | g_signal_connect_swapped (pad->priv->properties, "destroy", G_CALLBACK (pad_properties_destroyed), pad); | ||
2828 | 829 | g_signal_connect (pad, "notify::title", G_CALLBACK (pad_properties_sync_title), NULL); | ||
2829 | 830 | |||
2830 | 831 | style = gtk_widget_get_style_context (pad->priv->textview); | ||
2831 | 832 | gtk_style_context_get(style, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font, NULL); | ||
2832 | 833 | gtk_style_context_get_color (style, GTK_STATE_FLAG_NORMAL, &widget_text_color); | ||
2833 | 834 | gtk_style_context_get_background_color (style, GTK_STATE_FLAG_NORMAL, &widget_background_color); | ||
2834 | 835 | |||
2835 | 836 | g_object_get (XPAD_TEXT_VIEW (pad->priv->textview), "follow-font-style", &follow_font_style, "follow-color-style", &follow_color_style, NULL); | ||
2836 | 837 | g_object_set (G_OBJECT (pad->priv->properties), | ||
2837 | 838 | "follow-font-style", follow_font_style, | ||
2838 | 839 | "follow-color-style", follow_color_style, | ||
2839 | 840 | "text-color", &widget_text_color, | ||
2840 | 841 | "back-color", &widget_background_color, | ||
2841 | 842 | "fontname", pango_font_description_to_string(font), | ||
2842 | 843 | NULL); | ||
2843 | 844 | pango_font_description_free (font); | ||
2844 | 845 | |||
2845 | 846 | g_signal_connect_swapped (pad->priv->properties, "notify::follow-font-style", G_CALLBACK (prop_notify_font), pad); | ||
2846 | 847 | g_signal_connect_swapped (pad->priv->properties, "notify::follow-color-style", G_CALLBACK (prop_notify_colors), pad); | ||
2847 | 848 | g_signal_connect_swapped (pad->priv->properties, "notify::text-color", G_CALLBACK (prop_notify_colors), pad); | ||
2848 | 849 | g_signal_connect_swapped (pad->priv->properties, "notify::back-color", G_CALLBACK (prop_notify_colors), pad); | ||
2849 | 850 | g_signal_connect_swapped (pad->priv->properties, "notify::fontname", G_CALLBACK (prop_notify_font), pad); | ||
2850 | 851 | |||
2851 | 852 | pad_properties_sync_title (pad); | ||
2852 | 853 | |||
2853 | 854 | gtk_widget_show (pad->priv->properties); | ||
2854 | 855 | } | ||
2855 | 856 | |||
2856 | 857 | static void | ||
2857 | 858 | xpad_pad_open_preferences (XpadPad *pad) | ||
2858 | 859 | { | ||
2859 | 860 | xpad_preferences_open (pad->priv->settings); | ||
2860 | 861 | } | ||
2861 | 862 | |||
2862 | 863 | static void | ||
2863 | 864 | menu_toggle_tag (XpadPad *pad, | ||
2864 | 865 | const gchar *name) | ||
2865 | 1507 | { | 866 | { |
2866 | 1508 | g_return_if_fail (pad->priv->textview); | 867 | g_return_if_fail (pad->priv->textview); |
2867 | 1509 | XpadTextBuffer *buffer = NULL; | 868 | XpadTextBuffer *buffer = NULL; |
2868 | @@ -1541,7 +900,8 @@ | |||
2869 | 1541 | * because this function has been probably been called, because of a menu toggle. | 900 | * because this function has been probably been called, because of a menu toggle. |
2870 | 1542 | */ | 901 | */ |
2871 | 1543 | static void | 902 | static void |
2873 | 1544 | menu_sticky (GtkCheckMenuItem *check, XpadPad *pad) | 903 | menu_sticky (GtkCheckMenuItem *check, |
2874 | 904 | XpadPad *pad) | ||
2875 | 1545 | { | 905 | { |
2876 | 1546 | pad->priv->sticky = gtk_check_menu_item_get_active (check); | 906 | pad->priv->sticky = gtk_check_menu_item_get_active (check); |
2877 | 1547 | if (pad->priv->sticky) | 907 | if (pad->priv->sticky) |
2878 | @@ -1552,31 +912,36 @@ | |||
2879 | 1552 | } | 912 | } |
2880 | 1553 | 913 | ||
2881 | 1554 | static void | 914 | static void |
2883 | 1555 | menu_toolbar (GtkCheckMenuItem *check, XpadPad *pad) | 915 | menu_toolbar (GtkCheckMenuItem *check, |
2884 | 916 | XpadPad *pad) | ||
2885 | 1556 | { | 917 | { |
2886 | 1557 | g_object_set (pad->priv->settings, "has-toolbar", gtk_check_menu_item_get_active (check), NULL); | 918 | g_object_set (pad->priv->settings, "has-toolbar", gtk_check_menu_item_get_active (check), NULL); |
2887 | 1558 | } | 919 | } |
2888 | 1559 | 920 | ||
2889 | 1560 | static void | 921 | static void |
2891 | 1561 | menu_scrollbar (GtkCheckMenuItem *check, XpadPad *pad) | 922 | menu_scrollbar (GtkCheckMenuItem *check, |
2892 | 923 | XpadPad *pad) | ||
2893 | 1562 | { | 924 | { |
2894 | 1563 | g_object_set (pad->priv->settings, "has-scrollbar", gtk_check_menu_item_get_active (check), NULL); | 925 | g_object_set (pad->priv->settings, "has-scrollbar", gtk_check_menu_item_get_active (check), NULL); |
2895 | 1564 | } | 926 | } |
2896 | 1565 | 927 | ||
2897 | 1566 | static void | 928 | static void |
2899 | 1567 | menu_autohide (GtkCheckMenuItem *check, XpadPad *pad) | 929 | menu_autohide (GtkCheckMenuItem *check, |
2900 | 930 | XpadPad *pad) | ||
2901 | 1568 | { | 931 | { |
2902 | 1569 | g_object_set (pad->priv->settings, "autohide-toolbar", gtk_check_menu_item_get_active (check), NULL); | 932 | g_object_set (pad->priv->settings, "autohide-toolbar", gtk_check_menu_item_get_active (check), NULL); |
2903 | 1570 | } | 933 | } |
2904 | 1571 | 934 | ||
2905 | 1572 | static void | 935 | static void |
2907 | 1573 | menu_decorated (GtkCheckMenuItem *check, XpadPad *pad) | 936 | menu_decorated (GtkCheckMenuItem *check, |
2908 | 937 | XpadPad *pad) | ||
2909 | 1574 | { | 938 | { |
2910 | 1575 | g_object_set (pad->priv->settings, "has-decorations", gtk_check_menu_item_get_active (check), NULL); | 939 | g_object_set (pad->priv->settings, "has-decorations", gtk_check_menu_item_get_active (check), NULL); |
2911 | 1576 | } | 940 | } |
2912 | 1577 | 941 | ||
2913 | 1578 | static gint | 942 | static gint |
2915 | 1579 | menu_title_compare (GtkWindow *a, GtkWindow *b) | 943 | menu_title_compare (GtkWindow *a, |
2916 | 944 | GtkWindow *b) | ||
2917 | 1580 | { | 945 | { |
2918 | 1581 | gchar *title_a = g_utf8_casefold (gtk_window_get_title (a), -1); | 946 | gchar *title_a = g_utf8_casefold (gtk_window_get_title (a), -1); |
2919 | 1582 | gchar *title_b = g_utf8_casefold (gtk_window_get_title (b), -1); | 947 | gchar *title_b = g_utf8_casefold (gtk_window_get_title (b), -1); |
2920 | @@ -1589,6 +954,31 @@ | |||
2921 | 1589 | return rv; | 954 | return rv; |
2922 | 1590 | } | 955 | } |
2923 | 1591 | 956 | ||
2924 | 957 | static void | ||
2925 | 958 | menu_about (XpadPad *pad) | ||
2926 | 959 | { | ||
2927 | 960 | const gchar *artists[] = {"Michael Terry <mike@mterry.name>", NULL}; | ||
2928 | 961 | const gchar *authors[] = {"Arthur Borsboom <arthurborsboom@gmail.com>", "Jeroen Vermeulen <jtv@xs4all.nl>", "Michael Terry <mike@mterry.name>", "Paul Ivanov <pivanov@berkeley.edu>", "Sachin Raut <great.sachin@gmail.com>", NULL}; | ||
2929 | 962 | const gchar *comments = _("Sticky notes"); | ||
2930 | 963 | const gchar *copyright = "© 2001-2014 Michael Terry"; | ||
2931 | 964 | /* Translators: please translate this as your own name and optionally email | ||
2932 | 965 | like so: "Your Name <your@email.com>" */ | ||
2933 | 966 | const gchar *translator_credits = _("translator-credits"); | ||
2934 | 967 | const gchar *website = "https://launchpad.net/xpad"; | ||
2935 | 968 | |||
2936 | 969 | gtk_show_about_dialog (GTK_WINDOW (pad), | ||
2937 | 970 | "artists", artists, | ||
2938 | 971 | "authors", authors, | ||
2939 | 972 | "comments", comments, | ||
2940 | 973 | "copyright", copyright, | ||
2941 | 974 | "license-type", GTK_LICENSE_GPL_3_0, | ||
2942 | 975 | "logo-icon-name", PACKAGE, | ||
2943 | 976 | "translator-credits", translator_credits, | ||
2944 | 977 | "version", VERSION, | ||
2945 | 978 | "website", website, | ||
2946 | 979 | NULL); | ||
2947 | 980 | } | ||
2948 | 981 | |||
2949 | 1592 | /* FIXME: Accelerators are working but not visible for menu items with an image (icon). */ | 982 | /* FIXME: Accelerators are working but not visible for menu items with an image (icon). */ |
2950 | 1593 | #define MENU_ADD(mnemonic, image, key, mask, callback) {\ | 983 | #define MENU_ADD(mnemonic, image, key, mask, callback) {\ |
2951 | 1594 | if (image) {\ | 984 | if (image) {\ |
2952 | @@ -1621,7 +1011,32 @@ | |||
2953 | 1621 | } | 1011 | } |
2954 | 1622 | 1012 | ||
2955 | 1623 | static GtkWidget * | 1013 | static GtkWidget * |
2957 | 1624 | menu_get_popup_no_highlight (XpadPad *pad, GtkAccelGroup *accel_group) | 1014 | menu_get_popup_highlight (XpadPad *pad, |
2958 | 1015 | GtkAccelGroup *accel_group) | ||
2959 | 1016 | { | ||
2960 | 1017 | GtkWidget *menu, *item; | ||
2961 | 1018 | |||
2962 | 1019 | menu = gtk_menu_new (); | ||
2963 | 1020 | gtk_menu_set_accel_group (GTK_MENU (menu), accel_group); | ||
2964 | 1021 | |||
2965 | 1022 | MENU_ADD (_("Cu_t"), "edit-cut", 0, 0, xpad_pad_cut); | ||
2966 | 1023 | MENU_ADD (_("_Copy"), "edit-copy", 0, 0, xpad_pad_copy); | ||
2967 | 1024 | MENU_ADD (_("_Paste"), "edit-paste", 0, 0, xpad_pad_paste); | ||
2968 | 1025 | g_object_set_data (G_OBJECT (menu), "paste", item); | ||
2969 | 1026 | MENU_ADD_SEP (); | ||
2970 | 1027 | MENU_ADD (_("_Bold"), "format-text-bold", GDK_KEY_b, GDK_CONTROL_MASK, menu_bold); | ||
2971 | 1028 | MENU_ADD (_("_Italic"), "format-text-italic", GDK_KEY_i, GDK_CONTROL_MASK, menu_italic); | ||
2972 | 1029 | MENU_ADD (_("_Underline"), "format-text-underline", GDK_KEY_u, GDK_CONTROL_MASK, menu_underline); | ||
2973 | 1030 | MENU_ADD (_("_Strikethrough"), "format-text-strikethrough", 0, 0, menu_strikethrough); | ||
2974 | 1031 | |||
2975 | 1032 | gtk_widget_show_all (menu); | ||
2976 | 1033 | |||
2977 | 1034 | return menu; | ||
2978 | 1035 | } | ||
2979 | 1036 | |||
2980 | 1037 | static GtkWidget * | ||
2981 | 1038 | menu_get_popup_no_highlight (XpadPad *pad, | ||
2982 | 1039 | GtkAccelGroup *accel_group) | ||
2983 | 1625 | { | 1040 | { |
2984 | 1626 | GtkWidget *uppermenu, *menu, *item; | 1041 | GtkWidget *uppermenu, *menu, *item; |
2985 | 1627 | gboolean has_toolbar, autohide_toolbar, has_scrollbar, decorations; | 1042 | gboolean has_toolbar, autohide_toolbar, has_scrollbar, decorations; |
2986 | @@ -1693,7 +1108,7 @@ | |||
2987 | 1693 | gtk_container_add (GTK_CONTAINER (uppermenu), item); | 1108 | gtk_container_add (GTK_CONTAINER (uppermenu), item); |
2988 | 1694 | menu = gtk_menu_new (); | 1109 | menu = gtk_menu_new (); |
2989 | 1695 | gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu); | 1110 | gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu); |
2991 | 1696 | MENU_ADD (_("_Help"), "help-browser", GDK_KEY_F1, 0, show_help); | 1111 | MENU_ADD (_("_Help"), "help-browser", GDK_KEY_F1, 0, show_help); |
2992 | 1697 | MENU_ADD (_("_About"), "help-about", 0, 0, menu_about); | 1112 | MENU_ADD (_("_About"), "help-about", 0, 0, menu_about); |
2993 | 1698 | 1113 | ||
2994 | 1699 | gtk_widget_show_all (uppermenu); | 1114 | gtk_widget_show_all (uppermenu); |
2995 | @@ -1702,7 +1117,139 @@ | |||
2996 | 1702 | } | 1117 | } |
2997 | 1703 | 1118 | ||
2998 | 1704 | static void | 1119 | static void |
3000 | 1705 | menu_prep_popup_no_highlight (XpadPad *pad, GtkWidget *uppermenu) | 1120 | xpad_pad_show (XpadPad *pad) |
3001 | 1121 | { | ||
3002 | 1122 | /* | ||
3003 | 1123 | * Some wm's might not acknowledge our request for a specific | ||
3004 | 1124 | * location before we are shown. What we do here is a little gimpy | ||
3005 | 1125 | * and not very respectful of wms' sovereignty, but it has the effect | ||
3006 | 1126 | * of making pads' locations very dependable. We just move the pad | ||
3007 | 1127 | * again here after being shown. This may create a visual effect if | ||
3008 | 1128 | * the wm did ignore us, but is better than being in the wrong | ||
3009 | 1129 | * place, I guess. | ||
3010 | 1130 | */ | ||
3011 | 1131 | if (pad->priv->location_valid) | ||
3012 | 1132 | gtk_window_move (GTK_WINDOW (pad), pad->priv->x, pad->priv->y); | ||
3013 | 1133 | |||
3014 | 1134 | if (pad->priv->sticky) | ||
3015 | 1135 | gtk_window_stick (GTK_WINDOW (pad)); | ||
3016 | 1136 | else | ||
3017 | 1137 | gtk_window_unstick (GTK_WINDOW (pad)); | ||
3018 | 1138 | } | ||
3019 | 1139 | |||
3020 | 1140 | static gboolean toolbar_timeout (XpadPad *pad) | ||
3021 | 1141 | { | ||
3022 | 1142 | if (!pad || !pad->priv || !pad->priv->toolbar_timeout) | ||
3023 | 1143 | return FALSE; | ||
3024 | 1144 | |||
3025 | 1145 | gboolean has_toolbar, autohide_toolbar; | ||
3026 | 1146 | g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL); | ||
3027 | 1147 | |||
3028 | 1148 | if (pad->priv->toolbar_timeout && autohide_toolbar && has_toolbar) | ||
3029 | 1149 | xpad_pad_hide_toolbar (pad); | ||
3030 | 1150 | |||
3031 | 1151 | pad->priv->toolbar_timeout = 0; | ||
3032 | 1152 | |||
3033 | 1153 | return FALSE; | ||
3034 | 1154 | } | ||
3035 | 1155 | |||
3036 | 1156 | static gboolean | ||
3037 | 1157 | xpad_pad_configure_event (XpadPad *pad, | ||
3038 | 1158 | GdkEventConfigure *event) | ||
3039 | 1159 | { | ||
3040 | 1160 | if (!gtk_widget_get_visible (GTK_WIDGET(pad))) | ||
3041 | 1161 | return FALSE; | ||
3042 | 1162 | |||
3043 | 1163 | int eWidth = event->width; | ||
3044 | 1164 | int eHeight = event->height; | ||
3045 | 1165 | |||
3046 | 1166 | /* safe cast from gint to guint */ | ||
3047 | 1167 | if (eWidth >= 0 && eHeight >=0 ) { | ||
3048 | 1168 | if (pad->priv->width != (guint) eWidth || pad->priv->height != (guint) eHeight) | ||
3049 | 1169 | pad->priv->toolbar_pad_resized = TRUE; | ||
3050 | 1170 | |||
3051 | 1171 | pad->priv->width = (guint) event->width; | ||
3052 | 1172 | pad->priv->height = (guint) event->height; | ||
3053 | 1173 | } | ||
3054 | 1174 | else { | ||
3055 | 1175 | g_warning("There is a problem in the program Xpad. In function 'xpad_pad_configure_event' the variable 'event->width' or 'event->height' is not a postive number. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad."); | ||
3056 | 1176 | } | ||
3057 | 1177 | |||
3058 | 1178 | pad->priv->x = event->x; | ||
3059 | 1179 | pad->priv->y = event->y; | ||
3060 | 1180 | pad->priv->location_valid = TRUE; | ||
3061 | 1181 | |||
3062 | 1182 | xpad_pad_save_info_delayed(pad); | ||
3063 | 1183 | |||
3064 | 1184 | /* | ||
3065 | 1185 | * Sometimes when moving, if the toolbar tries to hide itself, | ||
3066 | 1186 | * the window manager will not resize it correctly. So, we make | ||
3067 | 1187 | * sure not to end the timeout while moving. | ||
3068 | 1188 | */ | ||
3069 | 1189 | if (pad->priv->toolbar_timeout) | ||
3070 | 1190 | { | ||
3071 | 1191 | g_source_remove (pad->priv->toolbar_timeout); | ||
3072 | 1192 | pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad); | ||
3073 | 1193 | } | ||
3074 | 1194 | |||
3075 | 1195 | return FALSE; | ||
3076 | 1196 | } | ||
3077 | 1197 | |||
3078 | 1198 | static gboolean | ||
3079 | 1199 | xpad_pad_toolbar_size_allocate (XpadPad *pad, | ||
3080 | 1200 | GtkAllocation *event) | ||
3081 | 1201 | { | ||
3082 | 1202 | /* safe cast from gint to guint */ | ||
3083 | 1203 | if (event->height >= 0) { | ||
3084 | 1204 | pad->priv->toolbar_height = (guint) event->height; | ||
3085 | 1205 | } | ||
3086 | 1206 | else { | ||
3087 | 1207 | g_warning("There is a problem in the program Xpad. In function 'xpad_pad_toolbar_size_allocate' the variable 'event->height' is not a postive number. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad."); | ||
3088 | 1208 | pad->priv->toolbar_height = 0; | ||
3089 | 1209 | } | ||
3090 | 1210 | return FALSE; | ||
3091 | 1211 | } | ||
3092 | 1212 | |||
3093 | 1213 | static gboolean | ||
3094 | 1214 | xpad_pad_delete_event (XpadPad *pad, | ||
3095 | 1215 | GdkEvent *event) | ||
3096 | 1216 | { | ||
3097 | 1217 | /* A dirty way to silence the compiler for these unused variables. */ | ||
3098 | 1218 | (void) event; | ||
3099 | 1219 | |||
3100 | 1220 | xpad_pad_close (pad); | ||
3101 | 1221 | |||
3102 | 1222 | return TRUE; | ||
3103 | 1223 | } | ||
3104 | 1224 | |||
3105 | 1225 | static gboolean | ||
3106 | 1226 | xpad_pad_leave_notify_event (GtkWidget *pad, | ||
3107 | 1227 | GdkEventCrossing *event) | ||
3108 | 1228 | { | ||
3109 | 1229 | gboolean has_toolbar, autohide_toolbar; | ||
3110 | 1230 | g_object_get (XPAD_PAD (pad)->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL); | ||
3111 | 1231 | |||
3112 | 1232 | if (has_toolbar && autohide_toolbar && | ||
3113 | 1233 | event->detail != GDK_NOTIFY_INFERIOR && | ||
3114 | 1234 | event->mode == GDK_CROSSING_NORMAL) | ||
3115 | 1235 | { | ||
3116 | 1236 | if (!XPAD_PAD (pad)->priv->toolbar_timeout) | ||
3117 | 1237 | XPAD_PAD (pad)->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad); | ||
3118 | 1238 | } | ||
3119 | 1239 | |||
3120 | 1240 | return FALSE; | ||
3121 | 1241 | } | ||
3122 | 1242 | |||
3123 | 1243 | static void | ||
3124 | 1244 | menu_popup (XpadPad *pad) | ||
3125 | 1245 | { | ||
3126 | 1246 | g_signal_handlers_block_matched (pad, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer) xpad_pad_leave_notify_event, NULL); | ||
3127 | 1247 | pad->priv->toolbar_timeout = 0; | ||
3128 | 1248 | } | ||
3129 | 1249 | |||
3130 | 1250 | static void | ||
3131 | 1251 | menu_prep_popup_no_highlight (XpadPad *pad, | ||
3132 | 1252 | GtkWidget *uppermenu) | ||
3133 | 1706 | { | 1253 | { |
3134 | 1707 | GtkWidget *menu, *item; | 1254 | GtkWidget *menu, *item; |
3135 | 1708 | 1255 | ||
3136 | @@ -1747,6 +1294,495 @@ | |||
3137 | 1747 | gtk_widget_show_all (menu); | 1294 | gtk_widget_show_all (menu); |
3138 | 1748 | } | 1295 | } |
3139 | 1749 | 1296 | ||
3140 | 1297 | static void | ||
3141 | 1298 | menu_prep_popup_highlight (XpadPad *pad, | ||
3142 | 1299 | GtkWidget *menu) | ||
3143 | 1300 | { | ||
3144 | 1301 | /* A dirty way to silence the compiler for these unused variables. */ | ||
3145 | 1302 | (void) pad; | ||
3146 | 1303 | |||
3147 | 1304 | GtkWidget *item; | ||
3148 | 1305 | GtkClipboard *clipboard; | ||
3149 | 1306 | |||
3150 | 1307 | clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); | ||
3151 | 1308 | |||
3152 | 1309 | item = g_object_get_data (G_OBJECT (menu), "paste"); | ||
3153 | 1310 | if (item) | ||
3154 | 1311 | gtk_widget_set_sensitive (item, gtk_clipboard_wait_is_text_available (clipboard)); | ||
3155 | 1312 | } | ||
3156 | 1313 | |||
3157 | 1314 | static void | ||
3158 | 1315 | xpad_pad_popup (XpadPad *pad, | ||
3159 | 1316 | GdkEventButton *event) | ||
3160 | 1317 | { | ||
3161 | 1318 | GtkTextBuffer *buffer; | ||
3162 | 1319 | GtkWidget *menu; | ||
3163 | 1320 | |||
3164 | 1321 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
3165 | 1322 | |||
3166 | 1323 | if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL)) | ||
3167 | 1324 | { | ||
3168 | 1325 | menu = pad->priv->highlight_menu; | ||
3169 | 1326 | menu_prep_popup_highlight (pad, menu); | ||
3170 | 1327 | } | ||
3171 | 1328 | else | ||
3172 | 1329 | { | ||
3173 | 1330 | menu = pad->priv->menu; | ||
3174 | 1331 | menu_prep_popup_no_highlight (pad, menu); | ||
3175 | 1332 | } | ||
3176 | 1333 | |||
3177 | 1334 | if (!menu) | ||
3178 | 1335 | return; | ||
3179 | 1336 | |||
3180 | 1337 | menu_popup (pad); | ||
3181 | 1338 | |||
3182 | 1339 | if (event) | ||
3183 | 1340 | gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time); | ||
3184 | 1341 | else | ||
3185 | 1342 | gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ()); | ||
3186 | 1343 | } | ||
3187 | 1344 | |||
3188 | 1345 | static gboolean | ||
3189 | 1346 | xpad_pad_popup_menu (XpadPad *pad) | ||
3190 | 1347 | { | ||
3191 | 1348 | xpad_pad_popup (pad, NULL); | ||
3192 | 1349 | |||
3193 | 1350 | return TRUE; | ||
3194 | 1351 | } | ||
3195 | 1352 | |||
3196 | 1353 | static void | ||
3197 | 1354 | menu_popdown (XpadPad *pad) | ||
3198 | 1355 | { | ||
3199 | 1356 | cairo_rectangle_int_t rect; | ||
3200 | 1357 | |||
3201 | 1358 | /* We must check if we disabled off of pad and start the timeout if so. */ | ||
3202 | 1359 | rect.x = 10; | ||
3203 | 1360 | rect.y = 10; | ||
3204 | 1361 | rect.width = 1; | ||
3205 | 1362 | rect.height = 1; | ||
3206 | 1363 | |||
3207 | 1364 | if (!pad->priv->toolbar_timeout && !gtk_widget_intersect (GTK_WIDGET (pad), &rect, NULL)) | ||
3208 | 1365 | pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad); | ||
3209 | 1366 | |||
3210 | 1367 | g_signal_handlers_unblock_matched (pad, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer) xpad_pad_leave_notify_event, NULL); | ||
3211 | 1368 | } | ||
3212 | 1369 | |||
3213 | 1370 | static gboolean | ||
3214 | 1371 | xpad_pad_button_press_event (XpadPad *pad, | ||
3215 | 1372 | GdkEventButton *event) | ||
3216 | 1373 | { | ||
3217 | 1374 | if (event->type == GDK_BUTTON_PRESS) | ||
3218 | 1375 | { | ||
3219 | 1376 | switch (event->button) | ||
3220 | 1377 | { | ||
3221 | 1378 | case 1: | ||
3222 | 1379 | if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_CONTROL_MASK) | ||
3223 | 1380 | { | ||
3224 | 1381 | gtk_window_begin_move_drag (GTK_WINDOW (pad), (gint) event->button, (gint) event->x_root, (gint) event->y_root, event->time); | ||
3225 | 1382 | return TRUE; | ||
3226 | 1383 | } | ||
3227 | 1384 | break; | ||
3228 | 1385 | |||
3229 | 1386 | case 3: | ||
3230 | 1387 | if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_CONTROL_MASK) | ||
3231 | 1388 | { | ||
3232 | 1389 | GdkWindowEdge edge; | ||
3233 | 1390 | |||
3234 | 1391 | if (gtk_widget_get_direction (GTK_WIDGET (pad)) == GTK_TEXT_DIR_LTR) | ||
3235 | 1392 | edge = GDK_WINDOW_EDGE_SOUTH_EAST; | ||
3236 | 1393 | else | ||
3237 | 1394 | edge = GDK_WINDOW_EDGE_SOUTH_WEST; | ||
3238 | 1395 | |||
3239 | 1396 | gtk_window_begin_resize_drag (GTK_WINDOW (pad), edge, (gint) event->button, (gint) event->x_root, (gint) event->y_root, event->time); | ||
3240 | 1397 | } | ||
3241 | 1398 | else | ||
3242 | 1399 | { | ||
3243 | 1400 | xpad_pad_popup (pad, event); | ||
3244 | 1401 | } | ||
3245 | 1402 | return TRUE; | ||
3246 | 1403 | } | ||
3247 | 1404 | } | ||
3248 | 1405 | |||
3249 | 1406 | return FALSE; | ||
3250 | 1407 | } | ||
3251 | 1408 | |||
3252 | 1409 | static void | ||
3253 | 1410 | xpad_pad_notify_has_scrollbar (XpadPad *pad) | ||
3254 | 1411 | { | ||
3255 | 1412 | gboolean has_scrollbar; | ||
3256 | 1413 | g_object_get (pad->priv->settings, "has-scrollbar", &has_scrollbar, NULL); | ||
3257 | 1414 | |||
3258 | 1415 | /* Update pad menu with the new status */ | ||
3259 | 1416 | GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-scrollbar"); | ||
3260 | 1417 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), has_scrollbar); | ||
3261 | 1418 | |||
3262 | 1419 | if (has_scrollbar) | ||
3263 | 1420 | gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pad->priv->scrollbar), | ||
3264 | 1421 | GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | ||
3265 | 1422 | else | ||
3266 | 1423 | { | ||
3267 | 1424 | GtkAdjustment *v, *h; | ||
3268 | 1425 | |||
3269 | 1426 | gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pad->priv->scrollbar), | ||
3270 | 1427 | GTK_POLICY_NEVER, GTK_POLICY_NEVER); | ||
3271 | 1428 | |||
3272 | 1429 | /* now we need to adjust view so that user can see whole pad */ | ||
3273 | 1430 | h = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (pad->priv->scrollbar)); | ||
3274 | 1431 | v = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (pad->priv->scrollbar)); | ||
3275 | 1432 | |||
3276 | 1433 | gtk_adjustment_set_value (h, 0); | ||
3277 | 1434 | gtk_adjustment_set_value (v, 0); | ||
3278 | 1435 | } | ||
3279 | 1436 | } | ||
3280 | 1437 | |||
3281 | 1438 | static void | ||
3282 | 1439 | xpad_pad_notify_has_decorations (XpadPad *pad) | ||
3283 | 1440 | { | ||
3284 | 1441 | GtkWidget *pad_widget = GTK_WIDGET (pad); | ||
3285 | 1442 | GtkWindow *pad_window = GTK_WINDOW (pad); | ||
3286 | 1443 | gboolean decorations; | ||
3287 | 1444 | g_object_get (pad->priv->settings, "has-decorations", &decorations, NULL); | ||
3288 | 1445 | |||
3289 | 1446 | /* Update pad menu with the new status */ | ||
3290 | 1447 | GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-decorations"); | ||
3291 | 1448 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), decorations); | ||
3292 | 1449 | |||
3293 | 1450 | /* | ||
3294 | 1451 | * There are two modes of operation: a normal mode and a 'stealth' mode. | ||
3295 | 1452 | * If decorations are disabled, we also don't show up in the taskbar or pager. | ||
3296 | 1453 | */ | ||
3297 | 1454 | gtk_window_set_decorated (pad_window, decorations); | ||
3298 | 1455 | gtk_window_set_skip_taskbar_hint (pad_window, !decorations); | ||
3299 | 1456 | gtk_window_set_skip_pager_hint (pad_window, !decorations); | ||
3300 | 1457 | |||
3301 | 1458 | /* | ||
3302 | 1459 | * reshow_with_initial_size() seems to set the window back to a never-shown state. | ||
3303 | 1460 | * This is good, as some WMs don't like us changing the above parameters mid-run, | ||
3304 | 1461 | * even if we do a hide/show cycle. | ||
3305 | 1462 | */ | ||
3306 | 1463 | gtk_window_set_default_size (pad_window, (gint) pad->priv->width, (gint) pad->priv->height); | ||
3307 | 1464 | gtk_widget_hide (pad_widget); | ||
3308 | 1465 | gtk_widget_unrealize (pad_widget); | ||
3309 | 1466 | gtk_widget_show (pad_widget); | ||
3310 | 1467 | } | ||
3311 | 1468 | |||
3312 | 1469 | static void | ||
3313 | 1470 | xpad_pad_notify_has_toolbar (XpadPad *pad) | ||
3314 | 1471 | { | ||
3315 | 1472 | gboolean has_toolbar, autohide_toolbar; | ||
3316 | 1473 | g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL); | ||
3317 | 1474 | |||
3318 | 1475 | /* Update pad menu with the new status */ | ||
3319 | 1476 | GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-toolbar"); | ||
3320 | 1477 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), has_toolbar); | ||
3321 | 1478 | menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-autohide-toolbar"); | ||
3322 | 1479 | gtk_widget_set_sensitive (menu_item, has_toolbar); | ||
3323 | 1480 | |||
3324 | 1481 | if (has_toolbar && !autohide_toolbar) | ||
3325 | 1482 | xpad_pad_show_toolbar (pad); | ||
3326 | 1483 | else | ||
3327 | 1484 | xpad_pad_hide_toolbar (pad); | ||
3328 | 1485 | } | ||
3329 | 1486 | |||
3330 | 1487 | static void | ||
3331 | 1488 | xpad_pad_notify_autohide_toolbar (XpadPad *pad) | ||
3332 | 1489 | { | ||
3333 | 1490 | gboolean autohide_toolbar; | ||
3334 | 1491 | g_object_get (pad->priv->settings, "autohide-toolbar", &autohide_toolbar, NULL); | ||
3335 | 1492 | |||
3336 | 1493 | /* Update pad menu with the new status */ | ||
3337 | 1494 | GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-autohide-toolbar"); | ||
3338 | 1495 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), autohide_toolbar); | ||
3339 | 1496 | |||
3340 | 1497 | if (autohide_toolbar) | ||
3341 | 1498 | { | ||
3342 | 1499 | /* Likely not to be in pad when turning setting on */ | ||
3343 | 1500 | if (!pad->priv->toolbar_timeout) | ||
3344 | 1501 | pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad); | ||
3345 | 1502 | } | ||
3346 | 1503 | else | ||
3347 | 1504 | { | ||
3348 | 1505 | gboolean has_toolbar; | ||
3349 | 1506 | g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, NULL); | ||
3350 | 1507 | |||
3351 | 1508 | if (has_toolbar) | ||
3352 | 1509 | xpad_pad_show_toolbar(pad); | ||
3353 | 1510 | } | ||
3354 | 1511 | } | ||
3355 | 1512 | |||
3356 | 1513 | static void | ||
3357 | 1514 | xpad_pad_clear (XpadPad *pad) | ||
3358 | 1515 | { | ||
3359 | 1516 | GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
3360 | 1517 | gtk_text_buffer_set_text (buffer, "", -1); | ||
3361 | 1518 | } | ||
3362 | 1519 | |||
3363 | 1520 | static gboolean | ||
3364 | 1521 | xpad_pad_enter_notify_event (GtkWidget *pad, | ||
3365 | 1522 | GdkEventCrossing *event) | ||
3366 | 1523 | { | ||
3367 | 1524 | gboolean has_toolbar, autohide_toolbar; | ||
3368 | 1525 | g_object_get (XPAD_PAD (pad)->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL); | ||
3369 | 1526 | |||
3370 | 1527 | if (has_toolbar && autohide_toolbar && | ||
3371 | 1528 | event->detail != GDK_NOTIFY_INFERIOR && | ||
3372 | 1529 | event->mode == GDK_CROSSING_NORMAL) | ||
3373 | 1530 | { | ||
3374 | 1531 | XPAD_PAD (pad)->priv->toolbar_timeout = 0; | ||
3375 | 1532 | xpad_pad_show_toolbar (XPAD_PAD (pad)); | ||
3376 | 1533 | } | ||
3377 | 1534 | |||
3378 | 1535 | return FALSE; | ||
3379 | 1536 | } | ||
3380 | 1537 | |||
3381 | 1538 | static void xpad_pad_constructed (GObject *object) | ||
3382 | 1539 | { | ||
3383 | 1540 | XpadPad *pad = XPAD_PAD (object); | ||
3384 | 1541 | |||
3385 | 1542 | gboolean decorations; | ||
3386 | 1543 | GtkBox *vbox; | ||
3387 | 1544 | |||
3388 | 1545 | g_object_get (pad->priv->settings, | ||
3389 | 1546 | "width", &pad->priv->width, | ||
3390 | 1547 | "height", &pad->priv->height, | ||
3391 | 1548 | "autostart-sticky", &pad->priv->sticky, NULL); | ||
3392 | 1549 | |||
3393 | 1550 | GtkWindow *pad_window = GTK_WINDOW (pad); | ||
3394 | 1551 | |||
3395 | 1552 | pad->priv->textview = GTK_WIDGET (XPAD_TEXT_VIEW (xpad_text_view_new (pad->priv->settings, pad))); | ||
3396 | 1553 | |||
3397 | 1554 | pad->priv->scrollbar = GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW, | ||
3398 | 1555 | "hadjustment", NULL, | ||
3399 | 1556 | "hscrollbar-policy", GTK_POLICY_NEVER, | ||
3400 | 1557 | "shadow-type", GTK_SHADOW_NONE, | ||
3401 | 1558 | "vadjustment", NULL, | ||
3402 | 1559 | "vscrollbar-policy", GTK_POLICY_NEVER, | ||
3403 | 1560 | "child", pad->priv->textview, | ||
3404 | 1561 | NULL)); | ||
3405 | 1562 | |||
3406 | 1563 | pad->priv->toolbar = GTK_WIDGET (xpad_toolbar_new (pad)); | ||
3407 | 1564 | |||
3408 | 1565 | pad->priv->accel_group = gtk_accel_group_new (); | ||
3409 | 1566 | gtk_window_add_accel_group (pad_window, pad->priv->accel_group); | ||
3410 | 1567 | pad->priv->menu = menu_get_popup_no_highlight (pad, pad->priv->accel_group); | ||
3411 | 1568 | pad->priv->highlight_menu = menu_get_popup_highlight (pad, pad->priv->accel_group); | ||
3412 | 1569 | gtk_accel_group_connect (pad->priv->accel_group, GDK_KEY_Q, GDK_CONTROL_MASK, 0, g_cclosure_new_swap (G_CALLBACK (xpad_app_quit), pad, NULL)); | ||
3413 | 1570 | |||
3414 | 1571 | vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); | ||
3415 | 1572 | gtk_box_set_homogeneous (vbox, FALSE); | ||
3416 | 1573 | gtk_box_pack_start (vbox, pad->priv->scrollbar, TRUE, TRUE, 0); | ||
3417 | 1574 | gtk_box_pack_start (vbox, pad->priv->toolbar, FALSE, FALSE, 0); | ||
3418 | 1575 | |||
3419 | 1576 | gtk_container_child_set (GTK_CONTAINER (vbox), pad->priv->toolbar, "expand", FALSE, NULL); | ||
3420 | 1577 | |||
3421 | 1578 | g_object_get (pad->priv->settings, "has-decorations", &decorations, NULL); | ||
3422 | 1579 | gtk_window_set_decorated (pad_window, decorations); | ||
3423 | 1580 | gtk_window_set_default_size (pad_window, (gint) pad->priv->width, (gint) pad->priv->height); | ||
3424 | 1581 | gtk_window_set_gravity (pad_window, GDK_GRAVITY_STATIC); /* static gravity makes saving pad x,y work */ | ||
3425 | 1582 | gtk_window_set_skip_pager_hint (pad_window, decorations); | ||
3426 | 1583 | gtk_window_set_skip_taskbar_hint (pad_window, !decorations); | ||
3427 | 1584 | gtk_window_set_position (pad_window, GTK_WIN_POS_MOUSE); | ||
3428 | 1585 | |||
3429 | 1586 | g_object_set (G_OBJECT (pad), "child", vbox, NULL); | ||
3430 | 1587 | |||
3431 | 1588 | xpad_pad_notify_has_scrollbar (pad); | ||
3432 | 1589 | xpad_pad_notify_has_selection (pad); | ||
3433 | 1590 | xpad_pad_notify_clipboard_owner_changed (pad); | ||
3434 | 1591 | xpad_pad_notify_undo_redo_changed (pad); | ||
3435 | 1592 | |||
3436 | 1593 | pad->priv->clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); | ||
3437 | 1594 | |||
3438 | 1595 | if (pad->priv->sticky) | ||
3439 | 1596 | gtk_window_stick (pad_window); | ||
3440 | 1597 | else | ||
3441 | 1598 | gtk_window_unstick (pad_window); | ||
3442 | 1599 | |||
3443 | 1600 | xpad_pad_sync_title (pad); | ||
3444 | 1601 | |||
3445 | 1602 | gtk_widget_show_all (GTK_WIDGET (vbox)); | ||
3446 | 1603 | |||
3447 | 1604 | gtk_widget_hide (pad->priv->toolbar); | ||
3448 | 1605 | xpad_pad_notify_has_toolbar (pad); | ||
3449 | 1606 | |||
3450 | 1607 | /* Set up signals */ | ||
3451 | 1608 | gtk_widget_add_events (GTK_WIDGET (pad), GDK_BUTTON_PRESS_MASK | GDK_PROPERTY_CHANGE_MASK); | ||
3452 | 1609 | gtk_widget_add_events (pad->priv->toolbar, GDK_ALL_EVENTS_MASK); | ||
3453 | 1610 | g_signal_connect_swapped (pad->priv->textview, "button-press-event", G_CALLBACK (xpad_pad_button_press_event), pad); | ||
3454 | 1611 | g_signal_connect_swapped (pad->priv->textview, "popup-menu", G_CALLBACK (xpad_pad_popup_menu), pad); | ||
3455 | 1612 | g_signal_connect_swapped (pad->priv->toolbar, "size-allocate", G_CALLBACK (xpad_pad_toolbar_size_allocate), pad); | ||
3456 | 1613 | g_signal_connect (pad, "button-press-event", G_CALLBACK (xpad_pad_button_press_event), NULL); | ||
3457 | 1614 | g_signal_connect (pad, "configure-event", G_CALLBACK (xpad_pad_configure_event), NULL); | ||
3458 | 1615 | g_signal_connect (pad, "delete-event", G_CALLBACK (xpad_pad_delete_event), NULL); | ||
3459 | 1616 | g_signal_connect (pad, "popup-menu", G_CALLBACK (xpad_pad_popup_menu), NULL); | ||
3460 | 1617 | g_signal_connect (pad, "show", G_CALLBACK (xpad_pad_show), NULL); | ||
3461 | 1618 | g_signal_connect_swapped (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)), "changed", G_CALLBACK (xpad_pad_text_changed), pad); | ||
3462 | 1619 | |||
3463 | 1620 | g_signal_connect (pad, "enter-notify-event", G_CALLBACK (xpad_pad_enter_notify_event), NULL); | ||
3464 | 1621 | g_signal_connect (pad, "leave-notify-event", G_CALLBACK (xpad_pad_leave_notify_event), NULL); | ||
3465 | 1622 | |||
3466 | 1623 | g_signal_connect_swapped (pad->priv->settings, "notify::has-decorations", G_CALLBACK (xpad_pad_notify_has_decorations), pad); | ||
3467 | 1624 | g_signal_connect_swapped (pad->priv->settings, "notify::has-toolbar", G_CALLBACK (xpad_pad_notify_has_toolbar), pad); | ||
3468 | 1625 | g_signal_connect_swapped (pad->priv->settings, "notify::autohide-toolbar", G_CALLBACK (xpad_pad_notify_autohide_toolbar), pad); | ||
3469 | 1626 | g_signal_connect_swapped (pad->priv->settings, "notify::has-scrollbar", G_CALLBACK (xpad_pad_notify_has_scrollbar), pad); | ||
3470 | 1627 | g_signal_connect_swapped (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)), "notify::has-selection", G_CALLBACK (xpad_pad_notify_has_selection), pad); | ||
3471 | 1628 | g_signal_connect_swapped (pad->priv->clipboard, "owner-change", G_CALLBACK (xpad_pad_notify_clipboard_owner_changed), pad); | ||
3472 | 1629 | |||
3473 | 1630 | g_signal_connect_swapped (pad->priv->toolbar, "activate-new", G_CALLBACK (xpad_pad_spawn), pad); | ||
3474 | 1631 | g_signal_connect_swapped (pad->priv->toolbar, "activate-clear", G_CALLBACK (xpad_pad_clear), pad); | ||
3475 | 1632 | g_signal_connect_swapped (pad->priv->toolbar, "activate-close", G_CALLBACK (xpad_pad_close), pad); | ||
3476 | 1633 | g_signal_connect_swapped (pad->priv->toolbar, "activate-undo", G_CALLBACK (xpad_pad_undo), pad); | ||
3477 | 1634 | g_signal_connect_swapped (pad->priv->toolbar, "activate-redo", G_CALLBACK (xpad_pad_redo), pad); | ||
3478 | 1635 | g_signal_connect_swapped (pad->priv->toolbar, "activate-cut", G_CALLBACK (xpad_pad_cut), pad); | ||
3479 | 1636 | g_signal_connect_swapped (pad->priv->toolbar, "activate-copy", G_CALLBACK (xpad_pad_copy), pad); | ||
3480 | 1637 | g_signal_connect_swapped (pad->priv->toolbar, "activate-paste", G_CALLBACK (xpad_pad_paste), pad); | ||
3481 | 1638 | g_signal_connect_swapped (pad->priv->toolbar, "activate-delete", G_CALLBACK (xpad_pad_delete), pad); | ||
3482 | 1639 | g_signal_connect_swapped (pad->priv->toolbar, "activate-properties", G_CALLBACK (xpad_pad_open_properties), pad); | ||
3483 | 1640 | g_signal_connect_swapped (pad->priv->toolbar, "activate-preferences", G_CALLBACK (xpad_pad_open_preferences), pad); | ||
3484 | 1641 | g_signal_connect_swapped (pad->priv->toolbar, "activate-quit", G_CALLBACK (xpad_pad_close_all), pad); | ||
3485 | 1642 | |||
3486 | 1643 | g_signal_connect_swapped (pad->priv->toolbar, "popup", G_CALLBACK (menu_popup), pad); | ||
3487 | 1644 | g_signal_connect_swapped (pad->priv->toolbar, "popdown", G_CALLBACK (menu_popdown), pad); | ||
3488 | 1645 | |||
3489 | 1646 | g_signal_connect_swapped (pad->priv->menu, "deactivate", G_CALLBACK (menu_popdown), pad); | ||
3490 | 1647 | g_signal_connect_swapped (pad->priv->highlight_menu, "deactivate", G_CALLBACK (menu_popdown), pad); | ||
3491 | 1648 | } | ||
3492 | 1649 | |||
3493 | 1650 | static void | ||
3494 | 1651 | xpad_pad_dispose (GObject *object) | ||
3495 | 1652 | { | ||
3496 | 1653 | XpadPad *pad = XPAD_PAD (object); | ||
3497 | 1654 | |||
3498 | 1655 | if (pad->priv->group) { | ||
3499 | 1656 | g_object_unref(pad->priv->group); | ||
3500 | 1657 | pad->priv->group = NULL; | ||
3501 | 1658 | } | ||
3502 | 1659 | |||
3503 | 1660 | if (GTK_IS_WIDGET(pad->priv->menu)) { | ||
3504 | 1661 | gtk_widget_destroy (pad->priv->menu); | ||
3505 | 1662 | pad->priv->menu = NULL; | ||
3506 | 1663 | } | ||
3507 | 1664 | |||
3508 | 1665 | if (GTK_IS_WIDGET(pad->priv->highlight_menu)) { | ||
3509 | 1666 | gtk_widget_destroy (pad->priv->highlight_menu); | ||
3510 | 1667 | pad->priv->highlight_menu = NULL; | ||
3511 | 1668 | } | ||
3512 | 1669 | |||
3513 | 1670 | if (XPAD_IS_PAD_PROPERTIES (pad->priv->properties)) { | ||
3514 | 1671 | gtk_widget_destroy (pad->priv->properties); | ||
3515 | 1672 | pad->priv->properties = NULL; | ||
3516 | 1673 | } | ||
3517 | 1674 | |||
3518 | 1675 | gtk_clipboard_clear (pad->priv->clipboard); | ||
3519 | 1676 | |||
3520 | 1677 | /* For some reason the toolbar handler does not get automatically disconnected (or not at the right moment), leading to errors after deleting a pad. This manual disconnect prevents this error. */ | ||
3521 | 1678 | if (XPAD_IS_TOOLBAR (pad->priv->toolbar)) { | ||
3522 | 1679 | g_signal_handlers_disconnect_matched (pad->priv->toolbar, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pad); | ||
3523 | 1680 | gtk_widget_destroy(pad->priv->toolbar); | ||
3524 | 1681 | pad->priv->toolbar = NULL; | ||
3525 | 1682 | } | ||
3526 | 1683 | |||
3527 | 1684 | G_OBJECT_CLASS (xpad_pad_parent_class)->dispose (object); | ||
3528 | 1685 | } | ||
3529 | 1686 | |||
3530 | 1687 | static void | ||
3531 | 1688 | xpad_pad_finalize (GObject *object) | ||
3532 | 1689 | { | ||
3533 | 1690 | XpadPad *pad = XPAD_PAD (object); | ||
3534 | 1691 | |||
3535 | 1692 | if (pad->priv->settings) { | ||
3536 | 1693 | g_signal_handlers_disconnect_matched (pad->priv->settings, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pad); | ||
3537 | 1694 | g_object_unref(pad->priv->settings); | ||
3538 | 1695 | pad->priv->settings = NULL; | ||
3539 | 1696 | } | ||
3540 | 1697 | |||
3541 | 1698 | g_free (pad->priv->infoname); | ||
3542 | 1699 | g_free (pad->priv->contentname); | ||
3543 | 1700 | |||
3544 | 1701 | G_OBJECT_CLASS (xpad_pad_parent_class)->finalize (object); | ||
3545 | 1702 | } | ||
3546 | 1703 | |||
3547 | 1704 | void | ||
3548 | 1705 | xpad_pad_notify_has_selection (XpadPad *pad) | ||
3549 | 1706 | { | ||
3550 | 1707 | g_return_if_fail (pad); | ||
3551 | 1708 | |||
3552 | 1709 | GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
3553 | 1710 | gboolean has_selection = gtk_text_buffer_get_has_selection (buffer); | ||
3554 | 1711 | |||
3555 | 1712 | XpadToolbar *toolbar = XPAD_TOOLBAR (pad->priv->toolbar); | ||
3556 | 1713 | if (toolbar == NULL) | ||
3557 | 1714 | return; | ||
3558 | 1715 | |||
3559 | 1716 | xpad_toolbar_enable_cut_button (toolbar, has_selection); | ||
3560 | 1717 | xpad_toolbar_enable_copy_button (toolbar, has_selection); | ||
3561 | 1718 | } | ||
3562 | 1719 | |||
3563 | 1720 | void | ||
3564 | 1721 | xpad_pad_notify_clipboard_owner_changed (XpadPad *pad) | ||
3565 | 1722 | { | ||
3566 | 1723 | g_return_if_fail (pad); | ||
3567 | 1724 | |||
3568 | 1725 | /* safe cast to toolbar */ | ||
3569 | 1726 | if (XPAD_IS_TOOLBAR (pad->priv->toolbar)) { | ||
3570 | 1727 | XpadToolbar *toolbar = XPAD_TOOLBAR (pad->priv->toolbar); | ||
3571 | 1728 | g_return_if_fail (toolbar); | ||
3572 | 1729 | |||
3573 | 1730 | GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); | ||
3574 | 1731 | xpad_toolbar_enable_paste_button (toolbar, gtk_clipboard_wait_is_text_available (clipboard)); | ||
3575 | 1732 | } | ||
3576 | 1733 | } | ||
3577 | 1734 | |||
3578 | 1735 | void | ||
3579 | 1736 | xpad_pad_notify_undo_redo_changed (XpadPad *pad) | ||
3580 | 1737 | { | ||
3581 | 1738 | g_return_if_fail (pad); | ||
3582 | 1739 | |||
3583 | 1740 | XpadTextBuffer *buffer = NULL; | ||
3584 | 1741 | buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview))); | ||
3585 | 1742 | g_return_if_fail (buffer); | ||
3586 | 1743 | |||
3587 | 1744 | XpadToolbar *toolbar = NULL; | ||
3588 | 1745 | toolbar = XPAD_TOOLBAR (pad->priv->toolbar); | ||
3589 | 1746 | g_return_if_fail (toolbar); | ||
3590 | 1747 | |||
3591 | 1748 | xpad_toolbar_enable_undo_button (toolbar, xpad_text_buffer_undo_available (buffer)); | ||
3592 | 1749 | xpad_toolbar_enable_redo_button (toolbar, xpad_text_buffer_redo_available (buffer)); | ||
3593 | 1750 | } | ||
3594 | 1751 | |||
3595 | 1752 | void | ||
3596 | 1753 | xpad_pad_close (XpadPad *pad) | ||
3597 | 1754 | { | ||
3598 | 1755 | gtk_widget_hide (GTK_WIDGET (pad)); | ||
3599 | 1756 | |||
3600 | 1757 | /* | ||
3601 | 1758 | * If no tray and this is the last pad, we don't want to record this | ||
3602 | 1759 | * pad as closed, we want to start with just this pad next open. So | ||
3603 | 1760 | * quit before we record. | ||
3604 | 1761 | */ | ||
3605 | 1762 | if (!xpad_tray_is_open () && | ||
3606 | 1763 | xpad_pad_group_num_visible_pads (pad->priv->group) == 0) | ||
3607 | 1764 | { | ||
3608 | 1765 | xpad_app_quit (); | ||
3609 | 1766 | return; | ||
3610 | 1767 | } | ||
3611 | 1768 | |||
3612 | 1769 | if (pad->priv->properties) | ||
3613 | 1770 | gtk_widget_destroy (pad->priv->properties); | ||
3614 | 1771 | |||
3615 | 1772 | xpad_pad_save_info (pad); | ||
3616 | 1773 | |||
3617 | 1774 | g_signal_emit (pad, signals[CLOSED], 0); | ||
3618 | 1775 | } | ||
3619 | 1776 | |||
3620 | 1777 | void | ||
3621 | 1778 | xpad_pad_toggle(XpadPad *pad) | ||
3622 | 1779 | { | ||
3623 | 1780 | if (gtk_widget_get_visible (GTK_WIDGET(pad))) | ||
3624 | 1781 | xpad_pad_close (pad); | ||
3625 | 1782 | else | ||
3626 | 1783 | gtk_widget_show (GTK_WIDGET (pad)); | ||
3627 | 1784 | } | ||
3628 | 1785 | |||
3629 | 1750 | void xpad_pad_append_pad_titles_to_menu (GtkWidget *menu) | 1786 | void xpad_pad_append_pad_titles_to_menu (GtkWidget *menu) |
3630 | 1751 | { | 1787 | { |
3631 | 1752 | GSList *pads, *l; | 1788 | GSList *pads, *l; |
3632 | @@ -1782,114 +1818,75 @@ | |||
3633 | 1782 | g_slist_free (pads); | 1818 | g_slist_free (pads); |
3634 | 1783 | } | 1819 | } |
3635 | 1784 | 1820 | ||
3636 | 1785 | static GtkWidget * | ||
3637 | 1786 | menu_get_popup_highlight (XpadPad *pad, GtkAccelGroup *accel_group) | ||
3638 | 1787 | { | ||
3639 | 1788 | GtkWidget *menu, *item; | ||
3640 | 1789 | |||
3641 | 1790 | menu = gtk_menu_new (); | ||
3642 | 1791 | gtk_menu_set_accel_group (GTK_MENU (menu), accel_group); | ||
3643 | 1792 | |||
3644 | 1793 | MENU_ADD (_("Cu_t"), "edit-cut", 0, 0, xpad_pad_cut); | ||
3645 | 1794 | MENU_ADD (_("_Copy"), "edit-copy", 0, 0, xpad_pad_copy); | ||
3646 | 1795 | MENU_ADD (_("_Paste"), "edit-paste", 0, 0, xpad_pad_paste); | ||
3647 | 1796 | g_object_set_data (G_OBJECT (menu), "paste", item); | ||
3648 | 1797 | MENU_ADD_SEP (); | ||
3649 | 1798 | MENU_ADD (_("_Bold"), "format-text-bold", GDK_KEY_b, GDK_CONTROL_MASK, menu_bold); | ||
3650 | 1799 | MENU_ADD (_("_Italic"), "format-text-italic", GDK_KEY_i, GDK_CONTROL_MASK, menu_italic); | ||
3651 | 1800 | MENU_ADD (_("_Underline"), "format-text-underline", GDK_KEY_u, GDK_CONTROL_MASK, menu_underline); | ||
3652 | 1801 | MENU_ADD (_("_Strikethrough"), "format-text-strikethrough", 0, 0, menu_strikethrough); | ||
3653 | 1802 | |||
3654 | 1803 | gtk_widget_show_all (menu); | ||
3655 | 1804 | |||
3656 | 1805 | return menu; | ||
3657 | 1806 | } | ||
3658 | 1807 | |||
3659 | 1808 | static void | ||
3660 | 1809 | menu_prep_popup_highlight (XpadPad *pad, GtkWidget *menu) | ||
3661 | 1810 | { | ||
3662 | 1811 | /* A dirty way to silence the compiler for these unused variables. */ | ||
3663 | 1812 | (void) pad; | ||
3664 | 1813 | |||
3665 | 1814 | GtkWidget *item; | ||
3666 | 1815 | GtkClipboard *clipboard; | ||
3667 | 1816 | |||
3668 | 1817 | clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); | ||
3669 | 1818 | |||
3670 | 1819 | item = g_object_get_data (G_OBJECT (menu), "paste"); | ||
3671 | 1820 | if (item) | ||
3672 | 1821 | gtk_widget_set_sensitive (item, gtk_clipboard_wait_is_text_available (clipboard)); | ||
3673 | 1822 | } | ||
3674 | 1823 | |||
3675 | 1824 | static void | ||
3676 | 1825 | menu_popup (XpadPad *pad) | ||
3677 | 1826 | { | ||
3678 | 1827 | g_signal_handlers_block_matched (pad, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer) xpad_pad_leave_notify_event, NULL); | ||
3679 | 1828 | pad->priv->toolbar_timeout = 0; | ||
3680 | 1829 | } | ||
3681 | 1830 | |||
3682 | 1831 | static void | ||
3683 | 1832 | menu_popdown (XpadPad *pad) | ||
3684 | 1833 | { | ||
3685 | 1834 | cairo_rectangle_int_t rect; | ||
3686 | 1835 | |||
3687 | 1836 | /* We must check if we disabled off of pad and start the timeout if so. */ | ||
3688 | 1837 | rect.x = 10; | ||
3689 | 1838 | rect.y = 10; | ||
3690 | 1839 | rect.width = 1; | ||
3691 | 1840 | rect.height = 1; | ||
3692 | 1841 | |||
3693 | 1842 | if (!pad->priv->toolbar_timeout && !gtk_widget_intersect (GTK_WIDGET (pad), &rect, NULL)) | ||
3694 | 1843 | pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad); | ||
3695 | 1844 | |||
3696 | 1845 | g_signal_handlers_unblock_matched (pad, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer) xpad_pad_leave_notify_event, NULL); | ||
3697 | 1846 | } | ||
3698 | 1847 | |||
3699 | 1848 | static void | ||
3700 | 1849 | xpad_pad_popup (XpadPad *pad, GdkEventButton *event) | ||
3701 | 1850 | { | ||
3702 | 1851 | GtkTextBuffer *buffer; | ||
3703 | 1852 | GtkWidget *menu; | ||
3704 | 1853 | |||
3705 | 1854 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)); | ||
3706 | 1855 | |||
3707 | 1856 | if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL)) | ||
3708 | 1857 | { | ||
3709 | 1858 | menu = pad->priv->highlight_menu; | ||
3710 | 1859 | menu_prep_popup_highlight (pad, menu); | ||
3711 | 1860 | } | ||
3712 | 1861 | else | ||
3713 | 1862 | { | ||
3714 | 1863 | menu = pad->priv->menu; | ||
3715 | 1864 | menu_prep_popup_no_highlight (pad, menu); | ||
3716 | 1865 | } | ||
3717 | 1866 | |||
3718 | 1867 | if (!menu) | ||
3719 | 1868 | return; | ||
3720 | 1869 | |||
3721 | 1870 | menu_popup (pad); | ||
3722 | 1871 | |||
3723 | 1872 | if (event) | ||
3724 | 1873 | gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time); | ||
3725 | 1874 | else | ||
3726 | 1875 | gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ()); | ||
3727 | 1876 | } | ||
3728 | 1877 | |||
3729 | 1878 | /* These functions below are used to reduce the amounts of writes, hence improve the performance. */ | 1821 | /* These functions below are used to reduce the amounts of writes, hence improve the performance. */ |
3730 | 1879 | void xpad_pad_save_content_delayed (XpadPad *pad) | 1822 | void xpad_pad_save_content_delayed (XpadPad *pad) |
3731 | 1880 | { | 1823 | { |
3734 | 1881 | pad->priv->unsaved_content = TRUE; | 1824 | pad->priv->unsaved_content = TRUE; |
3735 | 1882 | xpad_periodic_save_content_delayed (pad); | 1825 | xpad_periodic_save_content_delayed (pad); |
3736 | 1883 | } | 1826 | } |
3737 | 1827 | |||
3738 | 1884 | void xpad_pad_save_info_delayed (XpadPad *pad) | 1828 | void xpad_pad_save_info_delayed (XpadPad *pad) |
3739 | 1885 | { | 1829 | { |
3742 | 1886 | pad->priv->unsaved_info = TRUE; | 1830 | pad->priv->unsaved_info = TRUE; |
3743 | 1887 | xpad_periodic_save_info_delayed (pad); | 1831 | xpad_periodic_save_info_delayed (pad); |
3744 | 1888 | } | 1832 | } |
3745 | 1833 | |||
3746 | 1889 | void xpad_pad_save_unsaved (XpadPad *pad) | 1834 | void xpad_pad_save_unsaved (XpadPad *pad) |
3747 | 1890 | { | 1835 | { |
3752 | 1891 | if (pad->priv->unsaved_content) | 1836 | if (pad->priv->unsaved_content) |
3753 | 1892 | xpad_pad_save_content (pad); | 1837 | xpad_pad_save_content (pad); |
3754 | 1893 | if (pad->priv->unsaved_info) | 1838 | if (pad->priv->unsaved_info) |
3755 | 1894 | xpad_pad_save_info (pad); | 1839 | xpad_pad_save_info (pad); |
3756 | 1840 | } | ||
3757 | 1841 | |||
3758 | 1842 | /* Class pad - constructor */ | ||
3759 | 1843 | static void | ||
3760 | 1844 | xpad_pad_class_init (XpadPadClass *klass) | ||
3761 | 1845 | { | ||
3762 | 1846 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||
3763 | 1847 | |||
3764 | 1848 | gobject_class->constructed = xpad_pad_constructed; | ||
3765 | 1849 | gobject_class->set_property = xpad_pad_set_property; | ||
3766 | 1850 | gobject_class->get_property = xpad_pad_get_property; | ||
3767 | 1851 | gobject_class->dispose = xpad_pad_dispose; | ||
3768 | 1852 | gobject_class->finalize = xpad_pad_finalize; | ||
3769 | 1853 | |||
3770 | 1854 | signals[CLOSED] = | ||
3771 | 1855 | g_signal_new ("closed", | ||
3772 | 1856 | G_OBJECT_CLASS_TYPE (gobject_class), | ||
3773 | 1857 | G_SIGNAL_RUN_FIRST, | ||
3774 | 1858 | G_STRUCT_OFFSET (XpadPadClass, closed), | ||
3775 | 1859 | NULL, NULL, | ||
3776 | 1860 | g_cclosure_marshal_VOID__VOID, | ||
3777 | 1861 | G_TYPE_NONE, | ||
3778 | 1862 | 0); | ||
3779 | 1863 | |||
3780 | 1864 | /* Properties */ | ||
3781 | 1865 | obj_prop[PROP_GROUP] = g_param_spec_pointer ("group", "Pad group", "Pad group for this pad", G_PARAM_READWRITE | G_PARAM_CONSTRUCT); | ||
3782 | 1866 | obj_prop[PROP_SETTINGS] = g_param_spec_pointer ("settings", "Xpad settings", "Xpad global settings", G_PARAM_READWRITE | G_PARAM_CONSTRUCT); | ||
3783 | 1867 | |||
3784 | 1868 | g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_prop); | ||
3785 | 1869 | } | ||
3786 | 1870 | |||
3787 | 1871 | /* Class pad - initializer */ | ||
3788 | 1872 | static void | ||
3789 | 1873 | xpad_pad_init (XpadPad *pad) | ||
3790 | 1874 | { | ||
3791 | 1875 | pad->priv = xpad_pad_get_instance_private (pad); | ||
3792 | 1876 | |||
3793 | 1877 | pad->priv->x = 0; | ||
3794 | 1878 | pad->priv->y = 0; | ||
3795 | 1879 | pad->priv->location_valid = FALSE; | ||
3796 | 1880 | pad->priv->infoname = NULL; | ||
3797 | 1881 | pad->priv->contentname = NULL; | ||
3798 | 1882 | pad->priv->textview = NULL; | ||
3799 | 1883 | pad->priv->scrollbar = NULL; | ||
3800 | 1884 | pad->priv->toolbar = NULL; | ||
3801 | 1885 | pad->priv->toolbar_timeout = 0; | ||
3802 | 1886 | pad->priv->toolbar_height = 0; | ||
3803 | 1887 | pad->priv->toolbar_expanded = FALSE; | ||
3804 | 1888 | pad->priv->toolbar_pad_resized = TRUE; | ||
3805 | 1889 | pad->priv->properties = NULL; | ||
3806 | 1890 | pad->priv->unsaved_content = FALSE; | ||
3807 | 1891 | pad->priv->unsaved_info = FALSE; | ||
3808 | 1895 | } | 1892 | } |
3809 | 1896 | 1893 | ||
3810 | === modified file 'src/xpad-periodic.c' | |||
3811 | --- src/xpad-periodic.c 2014-06-19 09:08:49 +0000 | |||
3812 | +++ src/xpad-periodic.c 2014-09-08 13:22:52 +0000 | |||
3813 | @@ -20,246 +20,269 @@ | |||
3814 | 20 | */ | 20 | */ |
3815 | 21 | 21 | ||
3816 | 22 | #include "../config.h" | 22 | #include "../config.h" |
3817 | 23 | |||
3818 | 23 | #include "xpad-periodic.h" | 24 | #include "xpad-periodic.h" |
3820 | 24 | #include <glib/gi18n.h> | 25 | |
3821 | 25 | #include <stdlib.h> | 26 | #include <stdlib.h> |
3822 | 26 | #include <string.h> | 27 | #include <string.h> |
3823 | 27 | 28 | ||
3824 | 29 | #include <glib/gi18n.h> | ||
3825 | 30 | |||
3826 | 28 | #ifdef SHOW_DEBUG | 31 | #ifdef SHOW_DEBUG |
3827 | 29 | # define G_PRINT_DBG g_print | 32 | # define G_PRINT_DBG g_print |
3828 | 30 | #else | 33 | #else |
3829 | 31 | # define G_PRINT_DBG gprint_ignore | 34 | # define G_PRINT_DBG gprint_ignore |
3830 | 32 | #endif | 35 | #endif |
3831 | 33 | 36 | ||
3833 | 34 | #define TIMEOUT_SECONDS 4 | 37 | #define TIMEOUT_SECONDS 4 |
3834 | 35 | 38 | ||
3835 | 36 | struct sigref_ { | 39 | struct sigref_ { |
3839 | 37 | const char * signame; | 40 | const char *signame; |
3840 | 38 | XpadPeriodicFunc func_ptr; | 41 | XpadPeriodicFunc func_ptr; |
3841 | 39 | gpointer data; | 42 | gpointer data; |
3842 | 40 | }; | 43 | }; |
3843 | 41 | 44 | ||
3844 | 42 | typedef struct sigref_ Xpadsigref; | 45 | typedef struct sigref_ Xpadsigref; |
3845 | 43 | 46 | ||
3846 | 44 | typedef struct { | 47 | typedef struct { |
3853 | 45 | /************************ | 48 | /************************ |
3854 | 46 | count = a clock tick count | 49 | count = a clock tick count |
3855 | 47 | after_id = the timeout id | 50 | after_id = the timeout id |
3856 | 48 | ************************/ | 51 | ************************/ |
3857 | 49 | int count; | 52 | int count; |
3858 | 50 | int after_id; | 53 | int after_id; |
3859 | 51 | 54 | ||
3870 | 52 | /************************ | 55 | /************************ |
3871 | 53 | template = a list of signal names and function pointers | 56 | template = a list of signal names and function pointers |
3872 | 54 | template_len = the length of 'template' | 57 | template_len = the length of 'template' |
3873 | 55 | sigs = a list of signal names, function pointers and data | 58 | sigs = a list of signal names, function pointers and data |
3874 | 56 | sigs_len = the length of 'sigs' | 59 | sigs_len = the length of 'sigs' |
3875 | 57 | ************************/ | 60 | ************************/ |
3876 | 58 | Xpadsigref * template; | 61 | Xpadsigref *template; |
3877 | 59 | int template_len; | 62 | int template_len; |
3878 | 60 | Xpadsigref * sigs; | 63 | Xpadsigref *sigs; |
3879 | 61 | int sigs_len; | 64 | int sigs_len; |
3880 | 62 | } XpadPeriodic; | 65 | } XpadPeriodic; |
3881 | 63 | 66 | ||
3882 | 64 | |||
3883 | 65 | /* prototypes */ | ||
3884 | 66 | static gint xppd_intercept (gpointer); | ||
3885 | 67 | static gint gprint_ignore(const char *, ...); | 67 | static gint gprint_ignore(const char *, ...); |
3886 | 68 | static void xpad_periodic_signal (const char * cbname, void * xpad_pad); | ||
3887 | 69 | static void xpad_periodic_error_exit (const char *, ...); | ||
3888 | 70 | |||
3889 | 71 | static gboolean str_equal (const char *, const char *); | ||
3890 | 72 | 68 | ||
3891 | 73 | /* global variables */ | 69 | /* global variables */ |
3892 | 74 | static XpadPeriodic xpptr [1]; | 70 | static XpadPeriodic xpptr [1]; |
3893 | 75 | 71 | ||
3894 | 76 | /* Functions start here */ | 72 | /* Functions start here */ |
3895 | 77 | 73 | ||
3932 | 78 | gboolean xpad_periodic_init (void) | 74 | void |
3933 | 79 | { | 75 | xpad_periodic_close (void) |
3934 | 80 | memset(xpptr, 0, sizeof(*xpptr)); | 76 | { |
3935 | 81 | xpptr->after_id = (gint) g_timeout_add_seconds(TIMEOUT_SECONDS, xppd_intercept, xpptr); | 77 | if (xpptr->after_id) { g_source_remove((guint) xpptr->after_id); } |
3936 | 82 | 78 | /* Free the signal references memory. */ | |
3937 | 83 | /* Allocate space for the signal references. */ | 79 | g_free(xpptr->template); |
3938 | 84 | int tlen = xpptr->template_len = 5; | 80 | g_free(xpptr->sigs); |
3939 | 85 | int slen = xpptr->sigs_len = 20; | 81 | /* Signal that this structure is now cleared. */ |
3940 | 86 | xpptr->template = g_malloc0((gsize) tlen * sizeof(Xpadsigref)); | 82 | memset(xpptr, 0, sizeof(*xpptr)); |
3941 | 87 | xpptr->sigs = g_malloc0((gsize) slen * sizeof(Xpadsigref)); | 83 | } |
3942 | 88 | 84 | ||
3943 | 89 | return TRUE; | 85 | /************************ |
3944 | 90 | } | 86 | xppd_intercept - intercepts a timer tick |
3945 | 91 | 87 | ||
3946 | 92 | void xpad_periodic_close (void) | 88 | This function intercepts a timer tick and iterates |
3947 | 93 | { | 89 | over the signal references. Any signal references that |
3948 | 94 | if (xpptr->after_id) { g_source_remove((guint) xpptr->after_id); } | 90 | are fully stocked with signal names, function pointers |
3949 | 95 | /* Free the signal references memory. */ | 91 | and data pointers are invoked. |
3950 | 96 | g_free(xpptr->template); | 92 | |
3951 | 97 | g_free(xpptr->sigs); | 93 | IOW (In other words), the function pointer is called with the |
3952 | 98 | /* Signal that this structure is now cleared. */ | 94 | right data pointer. |
3953 | 99 | memset(xpptr, 0, sizeof(*xpptr)); | 95 | ************************/ |
3954 | 100 | } | 96 | gint |
3955 | 101 | 97 | xppd_intercept (gpointer cdata) | |
3920 | 102 | /************************ | ||
3921 | 103 | xppd_intercept - intercepts a timer tick | ||
3922 | 104 | |||
3923 | 105 | This function intercepts a timer tick and iterates | ||
3924 | 106 | over the signal references. Any signal references that | ||
3925 | 107 | are fully stocked with signal names, function pointers | ||
3926 | 108 | and data pointers are invoked. | ||
3927 | 109 | |||
3928 | 110 | IOW (In other words), the function pointer is called with the | ||
3929 | 111 | right data pointer. | ||
3930 | 112 | ************************/ | ||
3931 | 113 | gint xppd_intercept (gpointer cdata) | ||
3956 | 114 | { | 98 | { |
3957 | 115 | /* A dirty way to silence the compiler for these unused variables. */ | 99 | /* A dirty way to silence the compiler for these unused variables. */ |
3958 | 116 | (void) cdata; | 100 | (void) cdata; |
3959 | 117 | 101 | ||
4094 | 118 | int cnt=0; | 102 | int cnt=0; |
4095 | 119 | XpadPeriodicFunc fnptr=0; | 103 | XpadPeriodicFunc fnptr=0; |
4096 | 120 | xpptr->count++; /* increment tick count */ | 104 | xpptr->count++; /* increment tick count */ |
4097 | 121 | 105 | ||
4098 | 122 | G_PRINT_DBG("xppd tick: %4d\n", xpptr->count); | 106 | G_PRINT_DBG ("xppd tick: %4d\n", xpptr->count); |
4099 | 123 | 107 | ||
4100 | 124 | for (cnt = 0; cnt < xpptr->sigs_len; ++cnt) { | 108 | for (cnt = 0; cnt < xpptr->sigs_len; ++cnt) |
4101 | 125 | Xpadsigref * sig_item = xpptr->sigs + cnt; | 109 | { |
4102 | 126 | if (sig_item->signame && sig_item->func_ptr && sig_item->data) { | 110 | Xpadsigref * sig_item = xpptr->sigs + cnt; |
4103 | 127 | fnptr = sig_item->func_ptr; | 111 | if (sig_item->signame && sig_item->func_ptr && sig_item->data) |
4104 | 128 | (*fnptr)(sig_item->data); | 112 | { |
4105 | 129 | G_PRINT_DBG("invoked %s : %p : %p\n", sig_item->signame, | 113 | fnptr = sig_item->func_ptr; |
4106 | 130 | sig_item->func_ptr, sig_item->data); | 114 | (*fnptr)(sig_item->data); |
4107 | 131 | memset(sig_item, 0, sizeof(*sig_item)); | 115 | G_PRINT_DBG ("invoked %s : %p : %p\n", sig_item->signame, |
4108 | 132 | } | 116 | sig_item->func_ptr, sig_item->data); |
4109 | 133 | } | 117 | memset(sig_item, 0, sizeof(*sig_item)); |
4110 | 134 | 118 | } | |
4111 | 135 | return TRUE; | 119 | } |
4112 | 136 | } | 120 | |
4113 | 137 | 121 | return TRUE; | |
4114 | 138 | /************************ | 122 | } |
4115 | 139 | Xpad_periodic_set_callback(): | 123 | |
4116 | 140 | This function prepares a callback function to be invoked | 124 | /************************ |
4117 | 141 | for an event name such as "save-content" or "save-info". | 125 | Xpad_periodic_set_callback(): |
4118 | 142 | 126 | This function prepares a callback function to be invoked | |
4119 | 143 | cbname : event name (or callback function name) | 127 | for an event name such as "save-content" or "save-info". |
4120 | 144 | func : function address | 128 | |
4121 | 145 | 129 | cbname : event name (or callback function name) | |
4122 | 146 | Returns true if a callback was registered. | 130 | func : function address |
4123 | 147 | ************************/ | 131 | |
4124 | 148 | gboolean xpad_periodic_set_callback ( | 132 | Returns true if a callback was registered. |
4125 | 149 | const char * cbname, | 133 | ************************/ |
4126 | 150 | XpadPeriodicFunc func) | 134 | gboolean |
4127 | 151 | { | 135 | xpad_periodic_set_callback (const char * cbname, |
4128 | 152 | int index = 0; | 136 | XpadPeriodicFunc func) |
4129 | 153 | gboolean isdone=FALSE; | 137 | { |
4130 | 154 | if (0 == func) { return FALSE; } | 138 | int index = 0; |
4131 | 155 | if (0 == cbname || 0==*cbname) { return FALSE; } | 139 | gboolean isdone=FALSE; |
4132 | 156 | 140 | if (0 == func) { return FALSE; } | |
4133 | 157 | /* Find an open slot for signal (callback) references and | 141 | if (0 == cbname || 0==*cbname) { return FALSE; } |
4134 | 158 | insert this one. */ | 142 | |
4135 | 159 | for (index = 0; index < xpptr->template_len; ++index) { | 143 | /* Find an open slot for signal (callback) references and |
4136 | 160 | /* Store a pointer to the current signal item. */ | 144 | insert this one. */ |
4137 | 161 | Xpadsigref * sig_item = xpptr->template + index; | 145 | for (index = 0; index < xpptr->template_len; ++index) |
4138 | 162 | 146 | { | |
4139 | 163 | /* If it's empty, set it. */ | 147 | /* Store a pointer to the current signal item. */ |
4140 | 164 | if (0 == sig_item->signame) { | 148 | Xpadsigref * sig_item = xpptr->template + index; |
4141 | 165 | sig_item->signame = cbname; | 149 | |
4142 | 166 | sig_item->func_ptr = func; | 150 | /* If it's empty, set it. */ |
4143 | 167 | isdone = TRUE; | 151 | if (0 == sig_item->signame) |
4144 | 168 | break; | 152 | { |
4145 | 169 | } | 153 | sig_item->signame = cbname; |
4146 | 170 | } | 154 | sig_item->func_ptr = func; |
4147 | 171 | 155 | isdone = TRUE; | |
4148 | 172 | if (! isdone) { | 156 | break; |
4149 | 173 | g_print("Failed to install signal callback: %s\n", cbname); | 157 | } |
4150 | 174 | exit(1); | 158 | } |
4151 | 175 | } | 159 | |
4152 | 176 | 160 | if (! isdone) | |
4153 | 177 | return isdone; | 161 | { |
4154 | 178 | } | 162 | g_print ("Failed to install signal callback: %s\n", cbname); |
4155 | 179 | 163 | exit (1); | |
4156 | 180 | void xpad_periodic_save_info_delayed (void * xpad_pad) | 164 | } |
4157 | 181 | { | 165 | |
4158 | 182 | xpad_periodic_signal("save-info", xpad_pad); | 166 | return isdone; |
4159 | 183 | } | 167 | } |
4160 | 184 | 168 | ||
4161 | 185 | void xpad_periodic_save_content_delayed (void * xpad_pad) | 169 | gboolean |
4162 | 186 | { | 170 | xpad_periodic_init (void) |
4163 | 187 | xpad_periodic_signal("save-content", xpad_pad); | 171 | { |
4164 | 188 | } | 172 | memset(xpptr, 0, sizeof(*xpptr)); |
4165 | 189 | 173 | xpptr->after_id = (gint) g_timeout_add_seconds(TIMEOUT_SECONDS, xppd_intercept, xpptr); | |
4166 | 190 | static void xpad_periodic_signal (const char * cbname, void * xpad_pad) { | 174 | |
4167 | 191 | int isdone = 0; | 175 | /* Allocate space for the signal references. */ |
4168 | 192 | int tnx=0, snx=0; | 176 | int tlen = xpptr->template_len = 5; |
4169 | 193 | XpadPeriodicFunc func_ptr = 0; | 177 | int slen = xpptr->sigs_len = 20; |
4170 | 194 | Xpadsigref * sig_item = 0; | 178 | xpptr->template = g_malloc0((gsize) tlen * sizeof(Xpadsigref)); |
4171 | 195 | 179 | xpptr->sigs = g_malloc0((gsize) slen * sizeof(Xpadsigref)); | |
4172 | 196 | if (0 == cbname || 0==*cbname) { return; } | 180 | |
4173 | 197 | if (0 == xpad_pad) { return; } | 181 | return TRUE; |
4174 | 198 | 182 | } | |
4175 | 199 | /* Get the callback function address */ | 183 | |
4176 | 200 | for (tnx = 0; tnx < xpptr->template_len; ++tnx) { | 184 | static void |
4177 | 201 | if (str_equal(xpptr->template[tnx].signame, cbname)) { | 185 | xpad_periodic_error_exit (const char * fmt, ...) |
4178 | 202 | func_ptr = xpptr->template[tnx].func_ptr; | 186 | { |
4179 | 203 | break; | 187 | va_list app; |
4180 | 204 | } | 188 | va_start (app, fmt); |
4181 | 205 | } | 189 | g_print (fmt, app); |
4182 | 206 | 190 | va_end (app); | |
4183 | 207 | /* If there is no callback address, we can't continue. */ | 191 | exit (1); |
4184 | 208 | if (! func_ptr) { | 192 | } |
4185 | 209 | xpad_periodic_error_exit("Can't find signal function address: %s\n", cbname); | 193 | |
4186 | 210 | } | 194 | static void |
4187 | 211 | 195 | xpad_periodic_signal (const char * cbname, | |
4188 | 212 | /* Check that this event is not already present. | 196 | void * xpad_pad) |
4189 | 213 | If it is present, don't do anything more. */ | 197 | { |
4190 | 214 | for (snx = 0; snx < xpptr->sigs_len; ++snx) { | 198 | int isdone = 0; |
4191 | 215 | sig_item = xpptr->sigs + snx; | 199 | int tnx=0, snx=0; |
4192 | 216 | if (str_equal(sig_item->signame,cbname) && | 200 | XpadPeriodicFunc func_ptr = 0; |
4193 | 217 | (xpad_pad == sig_item->data)) { | 201 | Xpadsigref * sig_item = 0; |
4194 | 218 | G_PRINT_DBG("Already got signal: %s\n", cbname); | 202 | |
4195 | 219 | return; | 203 | if (0 == cbname || 0==*cbname) { return; } |
4196 | 220 | } | 204 | if (0 == xpad_pad) { return; } |
4197 | 221 | } | 205 | |
4198 | 222 | 206 | /* Get the callback function address */ | |
4199 | 223 | /* Find a suitable slot for the signal reference and set it. */ | 207 | for (tnx = 0; tnx < xpptr->template_len; ++tnx) |
4200 | 224 | for (snx = 0; snx < xpptr->sigs_len; ++snx) { | 208 | { |
4201 | 225 | gint doadd = 0; | 209 | if (str_equal (xpptr->template[tnx].signame, cbname)) |
4202 | 226 | sig_item = xpptr->sigs + snx; | 210 | { |
4203 | 227 | 211 | func_ptr = xpptr->template[tnx].func_ptr; | |
4204 | 228 | doadd += (str_equal(sig_item->signame, cbname)); | 212 | break; |
4205 | 229 | doadd += (0 == sig_item->signame); | 213 | } |
4206 | 230 | 214 | } | |
4207 | 231 | if (doadd) { | 215 | |
4208 | 232 | sig_item->signame = cbname; | 216 | /* If there is no callback address, we can't continue. */ |
4209 | 233 | sig_item->func_ptr = func_ptr; | 217 | if (! func_ptr) |
4210 | 234 | sig_item->data = xpad_pad; | 218 | { |
4211 | 235 | isdone = TRUE; | 219 | xpad_periodic_error_exit ("Can't find signal function address: %s\n", cbname); |
4212 | 236 | break; | 220 | } |
4213 | 237 | } | 221 | |
4214 | 238 | } | 222 | /* Check that this event is not already present. |
4215 | 239 | 223 | If it is present, don't do anything more. */ | |
4216 | 240 | if (! isdone) { | 224 | for (snx = 0; snx < xpptr->sigs_len; ++snx) |
4217 | 241 | xpad_periodic_error_exit("Could not schedule event: %s\n", cbname); | 225 | { |
4218 | 242 | } | 226 | sig_item = xpptr->sigs + snx; |
4219 | 243 | } | 227 | if (str_equal(sig_item->signame,cbname) && |
4220 | 244 | 228 | (xpad_pad == sig_item->data)) | |
4221 | 245 | gboolean str_equal (const char * s1, const char * s2) { | 229 | { |
4222 | 246 | if (0 == s1 || 0==s2) { return FALSE; } | 230 | G_PRINT_DBG ("Already got signal: %s\n", cbname); |
4223 | 247 | if (s1 == s2) { return TRUE; } | 231 | return; |
4224 | 248 | return (0 == strcmp(s1, s2)); | 232 | } |
4225 | 249 | } | 233 | } |
4226 | 250 | 234 | ||
4227 | 251 | gint gprint_ignore (const char * fmt, ...) | 235 | /* Find a suitable slot for the signal reference and set it. */ |
4228 | 236 | for (snx = 0; snx < xpptr->sigs_len; ++snx) | ||
4229 | 237 | { | ||
4230 | 238 | gint doadd = 0; | ||
4231 | 239 | sig_item = xpptr->sigs + snx; | ||
4232 | 240 | |||
4233 | 241 | doadd += (str_equal (sig_item->signame, cbname)); | ||
4234 | 242 | doadd += (0 == sig_item->signame); | ||
4235 | 243 | |||
4236 | 244 | if (doadd) | ||
4237 | 245 | { | ||
4238 | 246 | sig_item->signame = cbname; | ||
4239 | 247 | sig_item->func_ptr = func_ptr; | ||
4240 | 248 | sig_item->data = xpad_pad; | ||
4241 | 249 | isdone = TRUE; | ||
4242 | 250 | break; | ||
4243 | 251 | } | ||
4244 | 252 | } | ||
4245 | 253 | |||
4246 | 254 | if (! isdone) | ||
4247 | 255 | { | ||
4248 | 256 | xpad_periodic_error_exit ("Could not schedule event: %s\n", cbname); | ||
4249 | 257 | } | ||
4250 | 258 | } | ||
4251 | 259 | |||
4252 | 260 | void | ||
4253 | 261 | xpad_periodic_save_info_delayed (void * xpad_pad) | ||
4254 | 262 | { | ||
4255 | 263 | xpad_periodic_signal ("save-info", xpad_pad); | ||
4256 | 264 | } | ||
4257 | 265 | |||
4258 | 266 | void | ||
4259 | 267 | xpad_periodic_save_content_delayed (void * xpad_pad) | ||
4260 | 268 | { | ||
4261 | 269 | xpad_periodic_signal ("save-content", xpad_pad); | ||
4262 | 270 | } | ||
4263 | 271 | |||
4264 | 272 | gboolean | ||
4265 | 273 | str_equal (const char * s1, | ||
4266 | 274 | const char * s2) | ||
4267 | 275 | { | ||
4268 | 276 | if (0 == s1 || 0==s2) { return FALSE; } | ||
4269 | 277 | if (s1 == s2) { return TRUE; } | ||
4270 | 278 | return (0 == strcmp(s1, s2)); | ||
4271 | 279 | } | ||
4272 | 280 | |||
4273 | 281 | gint | ||
4274 | 282 | gprint_ignore (const char * fmt, ...) | ||
4275 | 252 | { | 283 | { |
4276 | 253 | /* A dirty way to silence the compiler for these unused variables. */ | 284 | /* A dirty way to silence the compiler for these unused variables. */ |
4277 | 254 | (void) fmt; | 285 | (void) fmt; |
4278 | 255 | 286 | ||
4288 | 256 | return 0; | 287 | return 0; |
4280 | 257 | } | ||
4281 | 258 | |||
4282 | 259 | static void xpad_periodic_error_exit (const char * fmt, ...) { | ||
4283 | 260 | va_list app; | ||
4284 | 261 | va_start(app, fmt); | ||
4285 | 262 | g_print(fmt, app); | ||
4286 | 263 | va_end(app); | ||
4287 | 264 | exit(1); | ||
4289 | 265 | } | 288 | } |
4290 | 266 | 289 | ||
4291 | === modified file 'src/xpad-periodic.h' | |||
4292 | --- src/xpad-periodic.h 2014-06-19 09:08:49 +0000 | |||
4293 | +++ src/xpad-periodic.h 2014-09-08 13:22:52 +0000 | |||
4294 | @@ -19,11 +19,13 @@ | |||
4295 | 19 | 19 | ||
4296 | 20 | */ | 20 | */ |
4297 | 21 | 21 | ||
4300 | 22 | #ifndef XPAD_PERIODIC_H | 22 | #ifndef __XPAD_PERIODIC_H__ |
4301 | 23 | #define XPAD_PERIODIC_H | 23 | #define __XPAD_PERIODIC_H__ |
4302 | 24 | 24 | ||
4303 | 25 | #include <glib.h> | 25 | #include <glib.h> |
4304 | 26 | 26 | ||
4305 | 27 | G_BEGIN_DECLS | ||
4306 | 28 | |||
4307 | 27 | typedef void (*XpadPeriodicFunc)(void *); | 29 | typedef void (*XpadPeriodicFunc)(void *); |
4308 | 28 | 30 | ||
4309 | 29 | /* Callback function codes: save-content, save-info */ | 31 | /* Callback function codes: save-content, save-info */ |
4310 | @@ -51,4 +53,6 @@ | |||
4311 | 51 | void xpad_periodic_save_content_delayed (void * xpad_pad); | 53 | void xpad_periodic_save_content_delayed (void * xpad_pad); |
4312 | 52 | void xpad_periodic_save_info_delayed (void * xpad_pad); | 54 | void xpad_periodic_save_info_delayed (void * xpad_pad); |
4313 | 53 | 55 | ||
4315 | 54 | #endif /* XPAD_PERIODIC_H */ | 56 | G_END_DECLS |
4316 | 57 | |||
4317 | 58 | #endif /* __XPAD_PERIODIC_H__ */ | ||
4318 | 55 | 59 | ||
4319 | === modified file 'src/xpad-preferences.c' | |||
4320 | --- src/xpad-preferences.c 2014-07-20 16:36:07 +0000 | |||
4321 | +++ src/xpad-preferences.c 2014-09-08 13:22:52 +0000 | |||
4322 | @@ -20,10 +20,12 @@ | |||
4323 | 20 | */ | 20 | */ |
4324 | 21 | 21 | ||
4325 | 22 | #include "../config.h" | 22 | #include "../config.h" |
4326 | 23 | |||
4327 | 23 | #include "xpad-preferences.h" | 24 | #include "xpad-preferences.h" |
4328 | 25 | #include "xpad-app.h" | ||
4329 | 26 | |||
4330 | 24 | #include <glib/gi18n.h> | 27 | #include <glib/gi18n.h> |
4331 | 25 | #include <gtk/gtk.h> | 28 | #include <gtk/gtk.h> |
4332 | 26 | #include "xpad-app.h" | ||
4333 | 27 | 29 | ||
4334 | 28 | struct XpadPreferencesPrivate | 30 | struct XpadPreferencesPrivate |
4335 | 29 | { | 31 | { |
4336 | @@ -36,12 +38,12 @@ | |||
4337 | 36 | GtkWidget *fontbutton; | 38 | GtkWidget *fontbutton; |
4338 | 37 | GtkWidget *colorcheck; | 39 | GtkWidget *colorcheck; |
4339 | 38 | GtkWidget *anticolorcheck; | 40 | GtkWidget *anticolorcheck; |
4341 | 39 | GtkWidget *colorbox; | 41 | GtkWidget *colorbox; |
4342 | 40 | GtkWidget *textbutton; | 42 | GtkWidget *textbutton; |
4343 | 41 | GtkWidget *backbutton; | 43 | GtkWidget *backbutton; |
4344 | 42 | GtkWidget *autostart_xpad; | 44 | GtkWidget *autostart_xpad; |
4345 | 43 | GtkWidget *autostart_wait_systray; | 45 | GtkWidget *autostart_wait_systray; |
4347 | 44 | GtkWidget *autostart_delay; | 46 | GtkWidget *autostart_delay; |
4348 | 45 | GtkWidget *autostart_new_pad; | 47 | GtkWidget *autostart_new_pad; |
4349 | 46 | GtkWidget *autostart_sticky; | 48 | GtkWidget *autostart_sticky; |
4350 | 47 | GtkWidget *autostart_display_pads; | 49 | GtkWidget *autostart_display_pads; |
4351 | @@ -50,7 +52,7 @@ | |||
4352 | 50 | GtkWidget *editcheck; | 52 | GtkWidget *editcheck; |
4353 | 51 | GtkWidget *confirmcheck; | 53 | GtkWidget *confirmcheck; |
4354 | 52 | 54 | ||
4356 | 53 | gulong fontcheck_handler; | 55 | gulong fontcheck_handler; |
4357 | 54 | gulong font_handler; | 56 | gulong font_handler; |
4358 | 55 | gulong colorcheck_handler; | 57 | gulong colorcheck_handler; |
4359 | 56 | gulong text_handler; | 58 | gulong text_handler; |
4360 | @@ -60,7 +62,7 @@ | |||
4361 | 60 | gulong autostart_delay_handler; | 62 | gulong autostart_delay_handler; |
4362 | 61 | gulong autostart_new_pad_handler; | 63 | gulong autostart_new_pad_handler; |
4363 | 62 | gulong autostart_sticky_handler; | 64 | gulong autostart_sticky_handler; |
4365 | 63 | gulong autostart_display_pads_handler; | 65 | gulong autostart_display_pads_handler; |
4366 | 64 | gulong tray_enabled_handler; | 66 | gulong tray_enabled_handler; |
4367 | 65 | gulong tray_click_handler; | 67 | gulong tray_click_handler; |
4368 | 66 | gulong editcheck_handler; | 68 | gulong editcheck_handler; |
4369 | @@ -83,51 +85,13 @@ | |||
4370 | 83 | 85 | ||
4371 | 84 | G_DEFINE_TYPE_WITH_PRIVATE (XpadPreferences, xpad_preferences, GTK_TYPE_DIALOG) | 86 | G_DEFINE_TYPE_WITH_PRIVATE (XpadPreferences, xpad_preferences, GTK_TYPE_DIALOG) |
4372 | 85 | 87 | ||
4373 | 86 | static void xpad_preferences_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); | ||
4374 | 87 | static void xpad_preferences_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); | ||
4375 | 88 | static void xpad_preferences_constructed (GObject *object); | ||
4376 | 89 | static void xpad_preferences_finalize (GObject *object); | ||
4377 | 90 | static void xpad_preferences_response (GtkDialog *dialog, gint response); | ||
4378 | 91 | |||
4379 | 92 | static void change_font_check (GtkToggleButton *button, XpadPreferences *pref); | ||
4380 | 93 | static void change_font_face (GtkFontButton *button, XpadPreferences *pref); | ||
4381 | 94 | static void change_color_check (GtkToggleButton *button, XpadPreferences *pref); | ||
4382 | 95 | static void change_text_color (GtkColorChooser *chooser, XpadPreferences *pref); | ||
4383 | 96 | static void change_back_color (GtkColorChooser *chooser, XpadPreferences *pref); | ||
4384 | 97 | static void change_autostart_xpad (GtkToggleButton *button, XpadPreferences *pref); | ||
4385 | 98 | static void change_autostart_wait_systray (GtkToggleButton *button, XpadPreferences *pref); | ||
4386 | 99 | static void change_autostart_delay (GtkComboBox *box, XpadPreferences *pref); | ||
4387 | 100 | static void change_autostart_new_pad (GtkToggleButton *button, XpadPreferences *pref); | ||
4388 | 101 | static void change_autostart_sticky (GtkToggleButton *button, XpadPreferences *pref); | ||
4389 | 102 | static void change_autostart_display_pads (GtkComboBox *box, XpadPreferences *pref); | ||
4390 | 103 | static void change_tray_enabled (GtkToggleButton *button, XpadPreferences *pref); | ||
4391 | 104 | static void change_tray_click (GtkComboBox *box, XpadPreferences *pref); | ||
4392 | 105 | static void change_edit_check (GtkToggleButton *button, XpadPreferences *pref); | ||
4393 | 106 | static void change_confirm_check (GtkToggleButton *button, XpadPreferences *pref); | ||
4394 | 107 | |||
4395 | 108 | static void notify_fontname (XpadPreferences *pref); | ||
4396 | 109 | static void notify_text_color (XpadPreferences *pref); | ||
4397 | 110 | static void notify_back_color (XpadPreferences *pref); | ||
4398 | 111 | static void notify_autostart_xpad (XpadPreferences *pref); | ||
4399 | 112 | static void notify_autostart_wait_systray (XpadPreferences *pref); | ||
4400 | 113 | static void notify_autostart_delay (XpadPreferences *pref); | ||
4401 | 114 | static void notify_autostart_new_pad (XpadPreferences *pref); | ||
4402 | 115 | static void notify_autostart_sticky (XpadPreferences *pref); | ||
4403 | 116 | static void notify_autostart_display_pads (XpadPreferences *pref); | ||
4404 | 117 | static void notify_tray_enabled (XpadPreferences *pref); | ||
4405 | 118 | static void notify_tray_click (XpadPreferences *pref); | ||
4406 | 119 | static void notify_edit (XpadPreferences *pref); | ||
4407 | 120 | static void notify_confirm (XpadPreferences *pref); | ||
4408 | 121 | |||
4409 | 122 | static GtkWidget * create_label (const gchar *label_text); | ||
4410 | 123 | |||
4411 | 124 | static GtkWidget *_xpad_preferences = NULL; | 88 | static GtkWidget *_xpad_preferences = NULL; |
4412 | 125 | 89 | ||
4413 | 126 | enum | 90 | enum |
4414 | 127 | { | 91 | { |
4418 | 128 | PROP_0, | 92 | PROP_0, |
4419 | 129 | PROP_SETTINGS, | 93 | PROP_SETTINGS, |
4420 | 130 | N_PROPERTIES | 94 | N_PROPERTIES |
4421 | 131 | }; | 95 | }; |
4422 | 132 | 96 | ||
4423 | 133 | static GParamSpec *obj_prop[N_PROPERTIES] = { NULL, }; | 97 | static GParamSpec *obj_prop[N_PROPERTIES] = { NULL, }; |
4424 | @@ -144,25 +108,447 @@ | |||
4425 | 144 | gtk_window_present (GTK_WINDOW (_xpad_preferences)); | 108 | gtk_window_present (GTK_WINDOW (_xpad_preferences)); |
4426 | 145 | } | 109 | } |
4427 | 146 | 110 | ||
4447 | 147 | static void | 111 | static GtkWidget * create_label (const gchar *label_text) |
4448 | 148 | xpad_preferences_class_init (XpadPreferencesClass *klass) | 112 | { |
4449 | 149 | { | 113 | GtkWidget *label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL, |
4450 | 150 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | 114 | "label", g_strconcat ("<b>", label_text, "</b>", NULL), |
4451 | 151 | 115 | "use-markup", TRUE, | |
4452 | 152 | gobject_class->constructed = xpad_preferences_constructed; | 116 | "xalign", 0.0, |
4453 | 153 | gobject_class->set_property = xpad_preferences_set_property; | 117 | NULL)); |
4454 | 154 | gobject_class->get_property = xpad_preferences_get_property; | 118 | return label; |
4455 | 155 | gobject_class->finalize = xpad_preferences_finalize; | 119 | } |
4456 | 156 | 120 | ||
4457 | 157 | obj_prop[PROP_SETTINGS] = g_param_spec_pointer ("settings", "Xpad settings", "Xpad global settings", G_PARAM_READWRITE | G_PARAM_CONSTRUCT); | 121 | static void |
4458 | 158 | 122 | xpad_preferences_set_property (GObject *object, | |
4459 | 159 | g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_prop); | 123 | guint prop_id, |
4460 | 160 | } | 124 | const GValue *value, |
4461 | 161 | 125 | GParamSpec *pspec) | |
4462 | 162 | static void | 126 | { |
4463 | 163 | xpad_preferences_init (XpadPreferences *pref) | 127 | XpadPreferences *pref = XPAD_PREFERENCES (object); |
4464 | 164 | { | 128 | |
4465 | 165 | pref->priv = xpad_preferences_get_instance_private (pref); | 129 | switch (prop_id) |
4466 | 130 | { | ||
4467 | 131 | case PROP_SETTINGS: | ||
4468 | 132 | pref->priv->settings = g_value_get_pointer (value); | ||
4469 | 133 | g_object_ref (pref->priv->settings); | ||
4470 | 134 | break; | ||
4471 | 135 | |||
4472 | 136 | default: | ||
4473 | 137 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
4474 | 138 | break; | ||
4475 | 139 | } | ||
4476 | 140 | } | ||
4477 | 141 | |||
4478 | 142 | static void | ||
4479 | 143 | xpad_preferences_get_property (GObject *object, | ||
4480 | 144 | guint prop_id, | ||
4481 | 145 | GValue *value, | ||
4482 | 146 | GParamSpec *pspec) | ||
4483 | 147 | { | ||
4484 | 148 | XpadPreferences *pref = XPAD_PREFERENCES (object); | ||
4485 | 149 | |||
4486 | 150 | switch (prop_id) | ||
4487 | 151 | { | ||
4488 | 152 | case PROP_SETTINGS: | ||
4489 | 153 | g_value_set_pointer (value, pref->priv->settings); | ||
4490 | 154 | break; | ||
4491 | 155 | |||
4492 | 156 | default: | ||
4493 | 157 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
4494 | 158 | break; | ||
4495 | 159 | } | ||
4496 | 160 | } | ||
4497 | 161 | |||
4498 | 162 | static void | ||
4499 | 163 | xpad_preferences_finalize (GObject *object) | ||
4500 | 164 | { | ||
4501 | 165 | XpadPreferences *pref = XPAD_PREFERENCES (object); | ||
4502 | 166 | |||
4503 | 167 | if (pref->priv->settings) | ||
4504 | 168 | g_signal_handlers_disconnect_matched (pref->priv->settings, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pref); | ||
4505 | 169 | |||
4506 | 170 | G_OBJECT_CLASS (xpad_preferences_parent_class)->finalize (object); | ||
4507 | 171 | } | ||
4508 | 172 | |||
4509 | 173 | static void | ||
4510 | 174 | xpad_preferences_response (GtkDialog *dialog, | ||
4511 | 175 | gint response) | ||
4512 | 176 | { | ||
4513 | 177 | if (response == GTK_RESPONSE_CLOSE) | ||
4514 | 178 | gtk_widget_destroy (GTK_WIDGET (dialog)); | ||
4515 | 179 | } | ||
4516 | 180 | |||
4517 | 181 | static void | ||
4518 | 182 | change_font_check (GtkToggleButton *button, | ||
4519 | 183 | XpadPreferences *pref) | ||
4520 | 184 | { | ||
4521 | 185 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_font_handler); | ||
4522 | 186 | if (!gtk_toggle_button_get_active (button)) | ||
4523 | 187 | g_object_set (pref->priv->settings, "fontname", NULL, NULL); | ||
4524 | 188 | else | ||
4525 | 189 | g_object_set (pref->priv->settings, "fontname", gtk_font_button_get_font_name (GTK_FONT_BUTTON (pref->priv->fontbutton)), NULL); | ||
4526 | 190 | gtk_widget_set_sensitive (pref->priv->fontbutton, gtk_toggle_button_get_active (button)); | ||
4527 | 191 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_font_handler); | ||
4528 | 192 | } | ||
4529 | 193 | |||
4530 | 194 | static void | ||
4531 | 195 | change_font_face (GtkFontButton *button, | ||
4532 | 196 | XpadPreferences *pref) | ||
4533 | 197 | { | ||
4534 | 198 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_font_handler); | ||
4535 | 199 | g_object_set (pref->priv->settings, "fontname", gtk_font_button_get_font_name (button), NULL); | ||
4536 | 200 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_font_handler); | ||
4537 | 201 | } | ||
4538 | 202 | |||
4539 | 203 | static void | ||
4540 | 204 | change_color_check (GtkToggleButton *button, | ||
4541 | 205 | XpadPreferences *pref) | ||
4542 | 206 | { | ||
4543 | 207 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_text_handler); | ||
4544 | 208 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_back_handler); | ||
4545 | 209 | |||
4546 | 210 | if (!gtk_toggle_button_get_active (button)) | ||
4547 | 211 | g_object_set (pref->priv->settings, "text-color", NULL, "back-color", NULL, NULL); | ||
4548 | 212 | else | ||
4549 | 213 | { | ||
4550 | 214 | GdkRGBA text_color, back_color; | ||
4551 | 215 | gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (pref->priv->textbutton), &text_color); | ||
4552 | 216 | gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (pref->priv->backbutton), &back_color); | ||
4553 | 217 | g_object_set (pref->priv->settings, "text-color", &text_color, "back-color", &back_color, NULL); | ||
4554 | 218 | } | ||
4555 | 219 | |||
4556 | 220 | gtk_widget_set_sensitive (pref->priv->colorbox, gtk_toggle_button_get_active (button)); | ||
4557 | 221 | |||
4558 | 222 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_text_handler); | ||
4559 | 223 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_back_handler); | ||
4560 | 224 | } | ||
4561 | 225 | |||
4562 | 226 | static void | ||
4563 | 227 | change_text_color (GtkColorChooser *chooser, | ||
4564 | 228 | XpadPreferences *pref) | ||
4565 | 229 | { | ||
4566 | 230 | GdkRGBA text_color = {0, 0, 0, 0}; | ||
4567 | 231 | gtk_color_chooser_get_rgba (chooser, &text_color); | ||
4568 | 232 | |||
4569 | 233 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_text_handler); | ||
4570 | 234 | g_object_set (pref->priv->settings, "text-color", &text_color, NULL); | ||
4571 | 235 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_text_handler); | ||
4572 | 236 | } | ||
4573 | 237 | |||
4574 | 238 | static void | ||
4575 | 239 | change_back_color (GtkColorChooser *chooser, | ||
4576 | 240 | XpadPreferences *pref) | ||
4577 | 241 | { | ||
4578 | 242 | GdkRGBA back_color = {0, 0, 0, 0}; | ||
4579 | 243 | gtk_color_chooser_get_rgba (chooser, &back_color); | ||
4580 | 244 | |||
4581 | 245 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_back_handler); | ||
4582 | 246 | g_object_set (pref->priv->settings, "back-color", &back_color, NULL); | ||
4583 | 247 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_back_handler); | ||
4584 | 248 | } | ||
4585 | 249 | |||
4586 | 250 | static void | ||
4587 | 251 | change_autostart_xpad (GtkToggleButton *button, | ||
4588 | 252 | XpadPreferences *pref) | ||
4589 | 253 | { | ||
4590 | 254 | g_object_set (pref->priv->settings, "autostart-xpad", gtk_toggle_button_get_active (button), NULL); | ||
4591 | 255 | } | ||
4592 | 256 | |||
4593 | 257 | static void | ||
4594 | 258 | change_autostart_wait_systray (GtkToggleButton *button, | ||
4595 | 259 | XpadPreferences *pref) | ||
4596 | 260 | { | ||
4597 | 261 | GKeyFile *keyfile; | ||
4598 | 262 | GKeyFileFlags flags; | ||
4599 | 263 | GError *error = NULL; | ||
4600 | 264 | char *filename; | ||
4601 | 265 | gboolean wait_systray; | ||
4602 | 266 | |||
4603 | 267 | wait_systray = gtk_toggle_button_get_active (button); | ||
4604 | 268 | |||
4605 | 269 | /* Create a new GKeyFile object and a bitwise list of flags. */ | ||
4606 | 270 | keyfile = g_key_file_new (); | ||
4607 | 271 | filename = g_strdup_printf ("%s/.config/autostart/xpad.desktop", g_get_home_dir()); | ||
4608 | 272 | flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS; | ||
4609 | 273 | |||
4610 | 274 | /* Load the GKeyFile from xpad.desktop or show an error message. */ | ||
4611 | 275 | if (!g_key_file_load_from_file (keyfile, filename, flags, &error)) { | ||
4612 | 276 | gchar *errtext; | ||
4613 | 277 | errtext = g_strdup_printf (_("Could not load %s\n%s"), filename, error->message); | ||
4614 | 278 | xpad_app_error (NULL, _("Error changing wait for systray setting"), errtext); | ||
4615 | 279 | g_free (errtext); | ||
4616 | 280 | |||
4617 | 281 | gtk_toggle_button_set_active (button, !wait_systray); | ||
4618 | 282 | return; | ||
4619 | 283 | } | ||
4620 | 284 | |||
4621 | 285 | g_key_file_set_boolean (keyfile, "Desktop Entry", "X-LXQt-Need-Tray", wait_systray); | ||
4622 | 286 | |||
4623 | 287 | if (!g_key_file_save_to_file (keyfile, filename, &error)) { | ||
4624 | 288 | gchar *errtext; | ||
4625 | 289 | errtext = g_strdup_printf (_("Could not save %s\n%s"), filename, error->message); | ||
4626 | 290 | xpad_app_error (NULL, _("Error changing wait for systray setting"), errtext); | ||
4627 | 291 | g_free (errtext); | ||
4628 | 292 | |||
4629 | 293 | gtk_toggle_button_set_active (button, !wait_systray); | ||
4630 | 294 | return; | ||
4631 | 295 | } | ||
4632 | 296 | |||
4633 | 297 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_autostart_wait_systray_handler); | ||
4634 | 298 | g_object_set (pref->priv->settings, "autostart-wait-systray", wait_systray, NULL); | ||
4635 | 299 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_autostart_wait_systray_handler); | ||
4636 | 300 | } | ||
4637 | 301 | |||
4638 | 302 | static void | ||
4639 | 303 | change_autostart_new_pad (GtkToggleButton *button, | ||
4640 | 304 | XpadPreferences *pref) | ||
4641 | 305 | { | ||
4642 | 306 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_autostart_new_pad_handler); | ||
4643 | 307 | g_object_set (pref->priv->settings, "autostart-new-pad", gtk_toggle_button_get_active (button), NULL); | ||
4644 | 308 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_autostart_new_pad_handler); | ||
4645 | 309 | } | ||
4646 | 310 | |||
4647 | 311 | static void | ||
4648 | 312 | change_autostart_sticky (GtkToggleButton *button, | ||
4649 | 313 | XpadPreferences *pref) | ||
4650 | 314 | { | ||
4651 | 315 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_autostart_sticky_handler); | ||
4652 | 316 | g_object_set (pref->priv->settings, "autostart-sticky", gtk_toggle_button_get_active (button), NULL); | ||
4653 | 317 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_autostart_sticky_handler); | ||
4654 | 318 | } | ||
4655 | 319 | |||
4656 | 320 | static void | ||
4657 | 321 | change_autostart_delay (GtkComboBox *box, | ||
4658 | 322 | XpadPreferences *pref) | ||
4659 | 323 | { | ||
4660 | 324 | g_signal_handler_block(pref->priv->settings, pref->priv->notify_autostart_delay_handler); | ||
4661 | 325 | g_object_set (pref->priv->settings, "autostart-delay", (guint) gtk_combo_box_get_active (box), NULL); | ||
4662 | 326 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_autostart_delay_handler); | ||
4663 | 327 | } | ||
4664 | 328 | |||
4665 | 329 | static void | ||
4666 | 330 | change_autostart_display_pads (GtkComboBox *box, | ||
4667 | 331 | XpadPreferences *pref) | ||
4668 | 332 | { | ||
4669 | 333 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_autostart_display_pads_handler); | ||
4670 | 334 | g_object_set (pref->priv->settings, "autostart-display-pads", (guint) gtk_combo_box_get_active (box), NULL); | ||
4671 | 335 | g_signal_handler_unblock(pref->priv->settings, pref->priv->notify_autostart_display_pads_handler); | ||
4672 | 336 | } | ||
4673 | 337 | |||
4674 | 338 | static void | ||
4675 | 339 | change_tray_enabled (GtkToggleButton *button, | ||
4676 | 340 | XpadPreferences *pref) | ||
4677 | 341 | { | ||
4678 | 342 | g_object_set (pref->priv->settings, "tray-enabled", gtk_toggle_button_get_active (button), NULL); | ||
4679 | 343 | } | ||
4680 | 344 | |||
4681 | 345 | static void | ||
4682 | 346 | change_tray_click (GtkComboBox *box, | ||
4683 | 347 | XpadPreferences *pref) | ||
4684 | 348 | { | ||
4685 | 349 | g_signal_handler_block(pref->priv->settings, pref->priv->notify_tray_click_handler); | ||
4686 | 350 | g_object_set (pref->priv->settings, "tray-click-configuration", (guint) gtk_combo_box_get_active (box), NULL); | ||
4687 | 351 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_tray_click_handler); | ||
4688 | 352 | } | ||
4689 | 353 | |||
4690 | 354 | static void | ||
4691 | 355 | change_edit_check (GtkToggleButton *button, XpadPreferences *pref) | ||
4692 | 356 | { | ||
4693 | 357 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_edit_handler); | ||
4694 | 358 | g_object_set (pref->priv->settings, "edit-lock", gtk_toggle_button_get_active (button), NULL); | ||
4695 | 359 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_edit_handler); | ||
4696 | 360 | } | ||
4697 | 361 | |||
4698 | 362 | static void | ||
4699 | 363 | change_confirm_check (GtkToggleButton *button, | ||
4700 | 364 | XpadPreferences *pref) | ||
4701 | 365 | { | ||
4702 | 366 | g_signal_handler_block (pref->priv->settings, pref->priv->notify_confirm_handler); | ||
4703 | 367 | g_object_set (pref->priv->settings, "confirm-destroy", gtk_toggle_button_get_active (button), NULL); | ||
4704 | 368 | g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_confirm_handler); | ||
4705 | 369 | } | ||
4706 | 370 | |||
4707 | 371 | static void | ||
4708 | 372 | notify_fontname (XpadPreferences *pref) | ||
4709 | 373 | { | ||
4710 | 374 | const gchar *fontname; | ||
4711 | 375 | g_object_get (pref->priv->settings, "fontname", &fontname, NULL); | ||
4712 | 376 | |||
4713 | 377 | g_signal_handler_block (pref->priv->fontbutton, pref->priv->font_handler); | ||
4714 | 378 | g_signal_handler_block (pref->priv->fontcheck, pref->priv->fontcheck_handler); | ||
4715 | 379 | |||
4716 | 380 | if (fontname) | ||
4717 | 381 | { | ||
4718 | 382 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->fontcheck), TRUE); | ||
4719 | 383 | gtk_widget_set_sensitive (pref->priv->fontbutton, TRUE); | ||
4720 | 384 | gtk_font_button_set_font_name (GTK_FONT_BUTTON (pref->priv->fontbutton), fontname); | ||
4721 | 385 | } | ||
4722 | 386 | else | ||
4723 | 387 | { | ||
4724 | 388 | gtk_widget_set_sensitive (pref->priv->fontbutton, FALSE); | ||
4725 | 389 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->antifontcheck), TRUE); | ||
4726 | 390 | } | ||
4727 | 391 | |||
4728 | 392 | g_signal_handler_unblock (pref->priv->fontcheck, pref->priv->fontcheck_handler); | ||
4729 | 393 | g_signal_handler_unblock (pref->priv->fontbutton, pref->priv->font_handler); | ||
4730 | 394 | } | ||
4731 | 395 | |||
4732 | 396 | static void | ||
4733 | 397 | notify_text_color (XpadPreferences *pref) | ||
4734 | 398 | { | ||
4735 | 399 | const GdkRGBA *text_color; | ||
4736 | 400 | g_object_get (pref->priv->settings, "text-color", &text_color, NULL); | ||
4737 | 401 | |||
4738 | 402 | g_signal_handler_block (pref->priv->textbutton, pref->priv->text_handler); | ||
4739 | 403 | g_signal_handler_block (pref->priv->colorcheck, pref->priv->colorcheck_handler); | ||
4740 | 404 | |||
4741 | 405 | if (text_color) | ||
4742 | 406 | { | ||
4743 | 407 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->colorcheck), TRUE); | ||
4744 | 408 | gtk_widget_set_sensitive (pref->priv->colorbox, TRUE); | ||
4745 | 409 | gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (pref->priv->textbutton), text_color); | ||
4746 | 410 | |||
4747 | 411 | } | ||
4748 | 412 | else | ||
4749 | 413 | { | ||
4750 | 414 | gtk_widget_set_sensitive (pref->priv->colorbox, FALSE); | ||
4751 | 415 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->anticolorcheck), TRUE); | ||
4752 | 416 | } | ||
4753 | 417 | |||
4754 | 418 | g_signal_handler_unblock (pref->priv->colorcheck, pref->priv->colorcheck_handler); | ||
4755 | 419 | g_signal_handler_unblock (pref->priv->textbutton, pref->priv->text_handler); | ||
4756 | 420 | } | ||
4757 | 421 | |||
4758 | 422 | static void | ||
4759 | 423 | notify_back_color (XpadPreferences *pref) | ||
4760 | 424 | { | ||
4761 | 425 | const GdkRGBA *back_color; | ||
4762 | 426 | g_object_get (pref->priv->settings, "back-color", &back_color, NULL); | ||
4763 | 427 | |||
4764 | 428 | g_signal_handler_block (pref->priv->backbutton, pref->priv->back_handler); | ||
4765 | 429 | g_signal_handler_block (pref->priv->colorcheck, pref->priv->colorcheck_handler); | ||
4766 | 430 | |||
4767 | 431 | if (back_color) | ||
4768 | 432 | { | ||
4769 | 433 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->colorcheck), TRUE); | ||
4770 | 434 | gtk_widget_set_sensitive (pref->priv->colorbox, TRUE); | ||
4771 | 435 | gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (pref->priv->backbutton), back_color); | ||
4772 | 436 | } | ||
4773 | 437 | else | ||
4774 | 438 | { | ||
4775 | 439 | gtk_widget_set_sensitive (pref->priv->colorbox, FALSE); | ||
4776 | 440 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->anticolorcheck), TRUE); | ||
4777 | 441 | } | ||
4778 | 442 | |||
4779 | 443 | g_signal_handler_unblock (pref->priv->colorcheck, pref->priv->colorcheck_handler); | ||
4780 | 444 | g_signal_handler_unblock (pref->priv->backbutton, pref->priv->back_handler); | ||
4781 | 445 | } | ||
4782 | 446 | |||
4783 | 447 | static void | ||
4784 | 448 | notify_autostart_xpad (XpadPreferences *pref) | ||
4785 | 449 | { | ||
4786 | 450 | gboolean value; | ||
4787 | 451 | g_object_get (pref->priv->settings, "autostart-xpad", &value, NULL); | ||
4788 | 452 | g_signal_handler_block (pref->priv->autostart_xpad, pref->priv->autostart_xpad_handler); | ||
4789 | 453 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_xpad), value); | ||
4790 | 454 | gtk_widget_set_sensitive (pref->priv->autostart_wait_systray, value); | ||
4791 | 455 | if (value) | ||
4792 | 456 | change_autostart_wait_systray (GTK_TOGGLE_BUTTON (pref->priv->autostart_wait_systray), pref); | ||
4793 | 457 | g_signal_handler_unblock (pref->priv->autostart_xpad, pref->priv->autostart_xpad_handler); | ||
4794 | 458 | } | ||
4795 | 459 | |||
4796 | 460 | static void | ||
4797 | 461 | notify_autostart_wait_systray (XpadPreferences *pref) | ||
4798 | 462 | { | ||
4799 | 463 | gboolean value; | ||
4800 | 464 | g_object_get (pref->priv->settings, "autostart-wait-systray", &value, NULL); | ||
4801 | 465 | g_signal_handler_block (pref->priv->autostart_wait_systray, pref->priv->autostart_wait_systray_handler); | ||
4802 | 466 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_wait_systray), value); | ||
4803 | 467 | g_signal_handler_unblock (pref->priv->autostart_wait_systray, pref->priv->autostart_wait_systray_handler); | ||
4804 | 468 | } | ||
4805 | 469 | |||
4806 | 470 | static void | ||
4807 | 471 | notify_autostart_new_pad (XpadPreferences *pref) | ||
4808 | 472 | { | ||
4809 | 473 | gboolean value; | ||
4810 | 474 | g_object_get (pref->priv->settings, "autostart-new-pad", &value, NULL); | ||
4811 | 475 | g_signal_handler_block (pref->priv->autostart_new_pad, pref->priv->autostart_new_pad_handler); | ||
4812 | 476 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_new_pad), value); | ||
4813 | 477 | g_signal_handler_unblock (pref->priv->autostart_new_pad, pref->priv->autostart_new_pad_handler); | ||
4814 | 478 | } | ||
4815 | 479 | |||
4816 | 480 | static void | ||
4817 | 481 | notify_autostart_sticky (XpadPreferences *pref) | ||
4818 | 482 | { | ||
4819 | 483 | gboolean value; | ||
4820 | 484 | g_object_get (pref->priv->settings, "autostart-sticky", &value, NULL); | ||
4821 | 485 | g_signal_handler_block (pref->priv->autostart_sticky, pref->priv->autostart_sticky_handler); | ||
4822 | 486 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_sticky), value); | ||
4823 | 487 | g_signal_handler_unblock (pref->priv->autostart_sticky, pref->priv->autostart_sticky_handler); | ||
4824 | 488 | } | ||
4825 | 489 | |||
4826 | 490 | static void | ||
4827 | 491 | notify_autostart_delay (XpadPreferences *pref) | ||
4828 | 492 | { | ||
4829 | 493 | guint value; | ||
4830 | 494 | g_object_get (pref->priv->settings, "autostart-delay", &value, NULL); | ||
4831 | 495 | g_signal_handler_block (pref->priv->autostart_delay, pref->priv->autostart_delay_handler); | ||
4832 | 496 | gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->autostart_delay), value); | ||
4833 | 497 | g_signal_handler_unblock (pref->priv->autostart_delay, pref->priv->autostart_delay_handler); | ||
4834 | 498 | } | ||
4835 | 499 | |||
4836 | 500 | static void | ||
4837 | 501 | notify_autostart_display_pads (XpadPreferences *pref) | ||
4838 | 502 | { | ||
4839 | 503 | guint value; | ||
4840 | 504 | g_object_get (pref->priv->settings, "autostart-display-pads", &value, NULL); | ||
4841 | 505 | g_signal_handler_block (pref->priv->autostart_display_pads, pref->priv->autostart_display_pads_handler); | ||
4842 | 506 | gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->autostart_display_pads), value); | ||
4843 | 507 | g_signal_handler_unblock (pref->priv->autostart_display_pads, pref->priv->autostart_display_pads_handler); | ||
4844 | 508 | } | ||
4845 | 509 | |||
4846 | 510 | static void | ||
4847 | 511 | notify_tray_enabled (XpadPreferences *pref) | ||
4848 | 512 | { | ||
4849 | 513 | gboolean value; | ||
4850 | 514 | g_object_get (pref->priv->settings, "tray-enabled", &value, NULL); | ||
4851 | 515 | g_signal_handler_block (pref->priv->tray_enabled, pref->priv->tray_enabled_handler); | ||
4852 | 516 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->tray_enabled), value); | ||
4853 | 517 | gtk_widget_set_sensitive (pref->priv->tray_click_configuration, value); | ||
4854 | 518 | gtk_widget_set_sensitive (pref->priv->autostart_display_pads, value); | ||
4855 | 519 | if (!value) | ||
4856 | 520 | g_object_set (pref->priv->settings, "autostart-display-pads", 0, NULL); | ||
4857 | 521 | g_signal_handler_unblock (pref->priv->tray_enabled, pref->priv->tray_enabled_handler); | ||
4858 | 522 | } | ||
4859 | 523 | |||
4860 | 524 | static void | ||
4861 | 525 | notify_tray_click (XpadPreferences *pref) | ||
4862 | 526 | { | ||
4863 | 527 | guint value; | ||
4864 | 528 | g_object_get (pref->priv->settings, "tray-click-configuration", &value, NULL); | ||
4865 | 529 | g_signal_handler_block (pref->priv->tray_click_configuration, pref->priv->tray_click_handler); | ||
4866 | 530 | gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->tray_click_configuration), value); | ||
4867 | 531 | g_signal_handler_unblock (pref->priv->tray_click_configuration, pref->priv->tray_click_handler); | ||
4868 | 532 | } | ||
4869 | 533 | |||
4870 | 534 | static void | ||
4871 | 535 | notify_edit (XpadPreferences *pref) | ||
4872 | 536 | { | ||
4873 | 537 | gboolean value; | ||
4874 | 538 | g_object_get (pref->priv->settings, "edit-lock", &value, NULL); | ||
4875 | 539 | g_signal_handler_block (pref->priv->editcheck, pref->priv->editcheck_handler); | ||
4876 | 540 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->editcheck), value); | ||
4877 | 541 | g_signal_handler_unblock (pref->priv->editcheck, pref->priv->editcheck_handler); | ||
4878 | 542 | } | ||
4879 | 543 | |||
4880 | 544 | static void | ||
4881 | 545 | notify_confirm (XpadPreferences *pref) | ||
4882 | 546 | { | ||
4883 | 547 | gboolean value; | ||
4884 | 548 | g_object_get (pref->priv->settings, "confirm-destroy", &value, NULL); | ||
4885 | 549 | g_signal_handler_block (pref->priv->confirmcheck, pref->priv->confirmcheck_handler); | ||
4886 | 550 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->confirmcheck), value); | ||
4887 | 551 | g_signal_handler_unblock (pref->priv->confirmcheck, pref->priv->confirmcheck_handler); | ||
4888 | 166 | } | 552 | } |
4889 | 167 | 553 | ||
4890 | 168 | static void xpad_preferences_constructed (GObject *object) | 554 | static void xpad_preferences_constructed (GObject *object) |
4891 | @@ -263,10 +649,10 @@ | |||
4892 | 263 | else | 649 | else |
4893 | 264 | { | 650 | { |
4894 | 265 | PangoFontDescription *font; | 651 | PangoFontDescription *font; |
4896 | 266 | 652 | ||
4897 | 267 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->antifontcheck), TRUE); | 653 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->antifontcheck), TRUE); |
4898 | 268 | gtk_widget_set_sensitive (pref->priv->fontbutton, FALSE); | 654 | gtk_widget_set_sensitive (pref->priv->fontbutton, FALSE); |
4900 | 269 | 655 | ||
4901 | 270 | gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font, NULL); | 656 | gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font, NULL); |
4902 | 271 | gtk_font_button_set_font_name (GTK_FONT_BUTTON (pref->priv->fontbutton), pango_font_description_to_string(font)); | 657 | gtk_font_button_set_font_name (GTK_FONT_BUTTON (pref->priv->fontbutton), pango_font_description_to_string(font)); |
4903 | 272 | pango_font_description_free (font); | 658 | pango_font_description_free (font); |
4904 | @@ -288,17 +674,17 @@ | |||
4905 | 288 | gtk_widget_set_sensitive (pref->priv->colorbox, FALSE); | 674 | gtk_widget_set_sensitive (pref->priv->colorbox, FALSE); |
4906 | 289 | gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (pref->priv->backbutton), &theme_background_color); | 675 | gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (pref->priv->backbutton), &theme_background_color); |
4907 | 290 | } | 676 | } |
4909 | 291 | 677 | ||
4910 | 292 | alignment = gtk_alignment_new (1, 1, 1, 1); | 678 | alignment = gtk_alignment_new (1, 1, 1, 1); |
4911 | 293 | gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0); | 679 | gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0); |
4912 | 294 | gtk_container_add (GTK_CONTAINER (alignment), pref->priv->colorbox); | 680 | gtk_container_add (GTK_CONTAINER (alignment), pref->priv->colorbox); |
4914 | 295 | 681 | ||
4915 | 296 | vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6)); | 682 | vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6)); |
4916 | 297 | 683 | ||
4917 | 298 | gtk_box_pack_start (vbox, pref->priv->antifontcheck, FALSE, FALSE, 0); | 684 | gtk_box_pack_start (vbox, pref->priv->antifontcheck, FALSE, FALSE, 0); |
4918 | 299 | gtk_box_pack_start (vbox, GTK_WIDGET (font_hbox), FALSE, FALSE, 0); | 685 | gtk_box_pack_start (vbox, GTK_WIDGET (font_hbox), FALSE, FALSE, 0); |
4919 | 300 | gtk_box_pack_start (appearance_vbox, GTK_WIDGET (vbox), FALSE, FALSE, 0); | 686 | gtk_box_pack_start (appearance_vbox, GTK_WIDGET (vbox), FALSE, FALSE, 0); |
4921 | 301 | 687 | ||
4922 | 302 | vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6)); | 688 | vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6)); |
4923 | 303 | 689 | ||
4924 | 304 | gtk_box_pack_start (vbox, pref->priv->anticolorcheck, FALSE, FALSE, 0); | 690 | gtk_box_pack_start (vbox, pref->priv->anticolorcheck, FALSE, FALSE, 0); |
4925 | @@ -358,7 +744,7 @@ | |||
4926 | 358 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_sticky), autostart_sticky); | 744 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_sticky), autostart_sticky); |
4927 | 359 | 745 | ||
4928 | 360 | label = gtk_label_new (_("Delay in seconds")); | 746 | label = gtk_label_new (_("Delay in seconds")); |
4930 | 361 | pref->priv->autostart_delay = gtk_combo_box_text_new(); | 747 | pref->priv->autostart_delay = gtk_combo_box_text_new(); |
4931 | 362 | guint i; | 748 | guint i; |
4932 | 363 | for (i=0; i<15; i++) | 749 | for (i=0; i<15; i++) |
4933 | 364 | gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pref->priv->autostart_delay), g_strdup_printf ("%i", i)); | 750 | gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pref->priv->autostart_delay), g_strdup_printf ("%i", i)); |
4934 | @@ -482,7 +868,7 @@ | |||
4935 | 482 | pref->priv->notify_confirm_handler = g_signal_connect_swapped (pref->priv->settings, "notify::confirm-destroy", G_CALLBACK (notify_confirm), pref); | 868 | pref->priv->notify_confirm_handler = g_signal_connect_swapped (pref->priv->settings, "notify::confirm-destroy", G_CALLBACK (notify_confirm), pref); |
4936 | 483 | pref->priv->notify_tray_enabled_handler = g_signal_connect_swapped (pref->priv->settings, "notify::tray-enabled", G_CALLBACK (notify_tray_enabled), pref); | 869 | pref->priv->notify_tray_enabled_handler = g_signal_connect_swapped (pref->priv->settings, "notify::tray-enabled", G_CALLBACK (notify_tray_enabled), pref); |
4937 | 484 | pref->priv->notify_tray_click_handler = g_signal_connect_swapped (pref->priv->settings, "notify::tray-click-configuration", G_CALLBACK(notify_tray_click), pref); | 870 | pref->priv->notify_tray_click_handler = g_signal_connect_swapped (pref->priv->settings, "notify::tray-click-configuration", G_CALLBACK(notify_tray_click), pref); |
4939 | 485 | 871 | ||
4940 | 486 | g_object_unref (size_group_labels); | 872 | g_object_unref (size_group_labels); |
4941 | 487 | 873 | ||
4942 | 488 | /* Initiliaze the GUI logic */ | 874 | /* Initiliaze the GUI logic */ |
4943 | @@ -498,423 +884,23 @@ | |||
4944 | 498 | g_object_set (G_OBJECT (pref), "default-width", (gint) (req.height * 0.8), NULL); | 884 | g_object_set (G_OBJECT (pref), "default-width", (gint) (req.height * 0.8), NULL); |
4945 | 499 | } | 885 | } |
4946 | 500 | 886 | ||
4947 | 501 | static GtkWidget * create_label (const gchar *label_text) { | ||
4948 | 502 | GtkWidget *label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL, | ||
4949 | 503 | "label", g_strconcat ("<b>", label_text, "</b>", NULL), | ||
4950 | 504 | "use-markup", TRUE, | ||
4951 | 505 | "xalign", 0.0, | ||
4952 | 506 | NULL)); | ||
4953 | 507 | return label; | ||
4954 | 508 | } | ||
4955 | 509 | |||
4956 | 510 | static void | ||
4957 | 511 | xpad_preferences_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) | ||
4958 | 512 | { | ||
4959 | 513 | XpadPreferences *pref = XPAD_PREFERENCES (object); | ||
4960 | 514 | |||
4961 | 515 | switch (prop_id) | ||
4962 | 516 | { | ||
4963 | 517 | case PROP_SETTINGS: | ||
4964 | 518 | pref->priv->settings = g_value_get_pointer (value); | ||
4965 | 519 | g_object_ref (pref->priv->settings); | ||
4966 | 520 | break; | ||
4967 | 521 | |||
4968 | 522 | default: | ||
4969 | 523 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
4970 | 524 | break; | ||
4971 | 525 | } | ||
4972 | 526 | } | ||
4973 | 527 | |||
4974 | 528 | static void | ||
4975 | 529 | xpad_preferences_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) | ||
4976 | 530 | { | ||
4977 | 531 | XpadPreferences *pref = XPAD_PREFERENCES (object); | ||
4978 | 532 | |||
4979 | 533 | switch (prop_id) | ||
4980 | 534 | { | ||
4981 | 535 | case PROP_SETTINGS: | ||
4982 | 536 | g_value_set_pointer (value, pref->priv->settings); | ||
4983 | 537 | break; | ||
4984 | 538 | |||
4985 | 539 | default: | ||
4986 | 540 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
4987 | 541 | break; | ||
4988 | 542 | } | ||
4989 | 543 | } | ||
4990 | 544 | |||
4991 | 545 | static void | ||
4992 | 546 | xpad_preferences_finalize (GObject *object) | ||
4993 | 547 | { | ||
4994 | 548 | XpadPreferences *pref = XPAD_PREFERENCES (object); | ||
4995 | 549 | |||
4996 | 550 | if (pref->priv->settings) | ||
4997 | 551 | g_signal_handlers_disconnect_matched (pref->priv->settings, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pref); | ||
4998 | 552 | |||
4999 | 553 | G_OBJECT_CLASS (xpad_preferences_parent_class)->finalize (object); | ||
5000 | 554 | } |
The diff has been truncated for viewing.
Hi Sagar,
I went through most of the code changes.
Some things I dislike, some things I like.
Let's see if we can agree on the parts.
I summarize below what I would like to see different.
Feel free to disagree and explain,
1. Split and group changes (and merge requests)
When working with other developers, in general it is better to produce small changes.
And if the changes are bigger, than at least group the different changes together.
In this merge proposal there are many different changes, with some I agree (which I would like to merge) and some I disagree, which I would like to request fixing.
Splitting the changes also makes it easier to find issues introduced by changes. It also makes it easier to undo a change.
So my request is to split the different changes. Below I try to do a start, since I discuss each group of changes by subject.
2. Order of includes
Agree totally. I would like to merge this directly.
3. Improving head guards
I Agree totally. I would like to merge this directly.
4. Improving function declarations by G_BEGIN_DECLS and G_END_DECLS
I Agree totally. I would like to merge this directly.
5. Removal of function prototypes by reordering functions
I am in a split here.
I agree that it is nicer and easier to maintain if these are removed.
I disagree since it sometimes make readability and therefore maintainability harder.
So, only if the readability of the code stays more or less the same, I am in favor of this. Two examples:
I do like the removal of the forward declaration in xpad-pad-group.c
I dislike reading the xpad-pad.c and xpad-app.c from the bottom to the top (instead of the other way around), and therefore I don't like this to be changed.
6. Reformatting of function parameters, each parameter on a new line.
I strongly dislike this. In my opinion this makes reading the code much harder.
I guess it comes from the old-fashioned Linux kernel coding rule: 80 character limit. I used to dislike it and I still dislike it. These days almost each developer has a screen with at least 200 characters if not 500.
Only when the function declaration becomes extremely long, breaking this line in two or three pieces might be better.
7. Reformatting of function and return type on a new line.
I guess this is better. This might be my Java coding habit from the old days.
/* good */ class_init (XpadUndoClass *klass)
static void
xpad_undo_
/* bad */ class_init (XpadUndoClass *klass)
static void xpad_undo_
I prefer the one defined by me as 'bad', but I don't think it changes readability a lot and the code conforms to the best practice.
***
In general, best practices are good, but are not the law. In my opinion if you have a good reason to disagree with the best practice, it is okay.
For me, most of the disagreements above have to do with readability and maintainability. And since I (we) are maintaining the software, I like to do this as easy as possible.
Again, everything is open for discussing.
Nevertheless, I would like you to start with discussion point 1.
Then I can merge all the subjects we agree on and we can discuss the others after that.
Cheers,
Arthur.