1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * dialogs.c
5 * Copyright (C) 2010 Martin Nordholts <martinn@src.gnome.org>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include <gegl.h>
24 #include <gtk/gtk.h>
25
26 #include "libgimpbase/gimpbase.h"
27 #include "libgimpconfig/gimpconfig.h"
28 #include "libgimpwidgets/gimpwidgets.h"
29
30 #include "dialogs-types.h"
31
32 #include "config/gimpguiconfig.h"
33
34 #include "display/gimpdisplay.h"
35 #include "display/gimpdisplayshell.h"
36
37 #include "core/gimp.h"
38 #include "core/gimpcontext.h"
39 #include "core/gimplist.h"
40
41 #include "widgets/gimpdialogfactory.h"
42 #include "widgets/gimpdockwindow.h"
43 #include "widgets/gimphelp-ids.h"
44 #include "widgets/gimpmenufactory.h"
45 #include "widgets/gimpsessioninfo.h"
46 #include "widgets/gimpsessioninfo-aux.h"
47 #include "widgets/gimpsessionmanaged.h"
48 #include "widgets/gimptoolbox.h"
49
50 #include "dialogs.h"
51 #include "dialogs-constructors.h"
52
53 #include "gimp-log.h"
54
55 #include "gimp-intl.h"
56
57
58 GimpContainer *global_recent_docks = NULL;
59
60
61 #define FOREIGN(id, singleton, remember_size) \
62 { id /* identifier */, \
63 NULL /* name */, \
64 NULL /* blurb */, \
65 NULL /* icon_name */, \
66 NULL /* help_id */, \
67 NULL /* new_func */, \
68 dialogs_restore_dialog /* restore_func */, \
69 0 /* view_size */, \
70 singleton /* singleton */, \
71 TRUE /* session_managed */, \
72 remember_size /* remember_size */, \
73 FALSE /* remember_if_open */, \
74 TRUE /* hideable */, \
75 FALSE /* image_window */, \
76 FALSE /* dockable */}
77
78 #define IMAGE_WINDOW(id, singleton, remember_size) \
79 { id /* identifier */, \
80 NULL /* name */, \
81 NULL /* blurb */, \
82 NULL /* icon_name */, \
83 NULL /* help_id */, \
84 NULL /* new_func */, \
85 dialogs_restore_window /* restore_func */, \
86 0 /* view_size */, \
87 singleton /* singleton */, \
88 TRUE /* session_managed */, \
89 remember_size /* remember_size */, \
90 TRUE /* remember_if_open */, \
91 FALSE /* hideable */, \
92 TRUE /* image_window */, \
93 FALSE /* dockable */}
94
95 #define TOPLEVEL(id, new_func, singleton, session_managed, remember_size) \
96 { id /* identifier */, \
97 NULL /* name */, \
98 NULL /* blurb */, \
99 NULL /* icon_name */, \
100 NULL /* help_id */, \
101 new_func /* new_func */, \
102 dialogs_restore_dialog /* restore_func */, \
103 0 /* view_size */, \
104 singleton /* singleton */, \
105 session_managed /* session_managed */, \
106 remember_size /* remember_size */, \
107 FALSE /* remember_if_open */, \
108 TRUE /* hideable */, \
109 FALSE /* image_window */, \
110 FALSE /* dockable */}
111
112 #define DOCKABLE(id, name, blurb, icon_name, help_id, new_func, view_size, singleton) \
113 { id /* identifier */, \
114 name /* name */, \
115 blurb /* blurb */, \
116 icon_name /* icon_name */, \
117 help_id /* help_id */, \
118 new_func /* new_func */, \
119 NULL /* restore_func */, \
120 view_size /* view_size */, \
121 singleton /* singleton */, \
122 FALSE /* session_managed */, \
123 FALSE /* remember_size */, \
124 TRUE /* remember_if_open */, \
125 TRUE /* hideable */, \
126 FALSE /* image_window */, \
127 TRUE /* dockable */}
128
129 #define DOCK(id, new_func) \
130 { id /* identifier */, \
131 NULL /* name */, \
132 NULL /* blurb */, \
133 NULL /* icon_name */, \
134 NULL /* help_id */, \
135 new_func /* new_func */, \
136 dialogs_restore_dialog /* restore_func */, \
137 0 /* view_size */, \
138 FALSE /* singleton */, \
139 FALSE /* session_managed */, \
140 FALSE /* remember_size */, \
141 FALSE /* remember_if_open */, \
142 TRUE /* hideable */, \
143 FALSE /* image_window */, \
144 FALSE /* dockable */}
145
146 #define DOCK_WINDOW(id, new_func) \
147 { id /* identifier */, \
148 NULL /* name */, \
149 NULL /* blurb */, \
150 NULL /* icon_name */, \
151 NULL /* help_id */, \
152 new_func /* new_func */, \
153 dialogs_restore_dialog /* restore_func */, \
154 0 /* view_size */, \
155 FALSE /* singleton */, \
156 TRUE /* session_managed */, \
157 TRUE /* remember_size */, \
158 TRUE /* remember_if_open */, \
159 TRUE /* hideable */, \
160 FALSE /* image_window */, \
161 FALSE /* dockable */}
162
163 #define LISTGRID(id, new_func, name, blurb, icon_name, help_id, view_size) \
164 { "gimp-"#id"-list" /* identifier */, \
165 name /* name */, \
166 blurb /* blurb */, \
167 icon_name /* icon_name */, \
168 help_id /* help_id */, \
169 dialogs_##new_func##_list_view_new /* new_func */, \
170 NULL /* restore_func */, \
171 view_size /* view_size */, \
172 FALSE /* singleton */, \
173 FALSE /* session_managed */, \
174 FALSE /* remember_size */, \
175 TRUE /* remember_if_open */, \
176 TRUE /* hideable */, \
177 FALSE /* image_window */, \
178 TRUE /* dockable */}, \
179 { "gimp-"#id"-grid" /* identifier */, \
180 name /* name */, \
181 blurb /* blurb */, \
182 icon_name /* icon_name */, \
183 help_id /* help_id */, \
184 dialogs_##new_func##_grid_view_new /* new_func */, \
185 NULL /* restore_func */, \
186 view_size /* view_size */, \
187 FALSE /* singleton */, \
188 FALSE /* session_managed */, \
189 FALSE /* remember_size */, \
190 TRUE /* remember_if_open */, \
191 TRUE /* hideable */, \
192 FALSE /* image_window */, \
193 TRUE /* dockable */}
194
195 #define LIST(id, new_func, name, blurb, icon_name, help_id, view_size) \
196 { "gimp-"#id"-list" /* identifier */, \
197 name /* name */, \
198 blurb /* blurb */, \
199 icon_name /* icon_name */, \
200 help_id /* help_id */, \
201 dialogs_##new_func##_list_view_new /* new_func */, \
202 NULL /* restore_func */, \
203 view_size /* view_size */, \
204 FALSE /* singleton */, \
205 FALSE /* session_managed */, \
206 FALSE /* remember_size */, \
207 TRUE /* remember_if_open */, \
208 TRUE /* hideable */, \
209 FALSE /* image_window */, \
210 TRUE /* dockable */}
211
212
213 static GtkWidget * dialogs_restore_dialog (GimpDialogFactory *factory,
214 GdkScreen *screen,
215 gint monitor,
216 GimpSessionInfo *info);
217 static GtkWidget * dialogs_restore_window (GimpDialogFactory *factory,
218 GdkScreen *screen,
219 gint monitor,
220 GimpSessionInfo *info);
221
222
223 static const GimpDialogFactoryEntry entries[] =
224 {
225 /* foreign toplevels without constructor */
226 FOREIGN ("gimp-brightness-contrast-tool-dialog", TRUE, FALSE),
227 FOREIGN ("gimp-color-balance-tool-dialog", TRUE, FALSE),
228 FOREIGN ("gimp-color-picker-tool-dialog", TRUE, TRUE),
229 FOREIGN ("gimp-colorize-tool-dialog", TRUE, FALSE),
230 FOREIGN ("gimp-crop-tool-dialog", TRUE, FALSE),
231 FOREIGN ("gimp-curves-tool-dialog", TRUE, TRUE),
232 FOREIGN ("gimp-desaturate-tool-dialog", TRUE, FALSE),
233 FOREIGN ("gimp-foreground-select-tool-dialog", TRUE, FALSE),
234 FOREIGN ("gimp-gegl-tool-dialog", TRUE, FALSE),
235 FOREIGN ("gimp-gradient-tool-dialog", TRUE, FALSE),
236 FOREIGN ("gimp-hue-saturation-tool-dialog", TRUE, FALSE),
237 FOREIGN ("gimp-levels-tool-dialog", TRUE, TRUE),
238 FOREIGN ("gimp-measure-tool-dialog", TRUE, FALSE),
239 FOREIGN ("gimp-offset-tool-dialog", TRUE, FALSE),
240 FOREIGN ("gimp-operation-tool-dialog", TRUE, FALSE),
241 FOREIGN ("gimp-posterize-tool-dialog", TRUE, FALSE),
242 FOREIGN ("gimp-rotate-tool-dialog", TRUE, FALSE),
243 FOREIGN ("gimp-scale-tool-dialog", TRUE, FALSE),
244 FOREIGN ("gimp-shear-tool-dialog", TRUE, FALSE),
245 FOREIGN ("gimp-text-tool-dialog", TRUE, TRUE),
246 FOREIGN ("gimp-threshold-tool-dialog", TRUE, FALSE),
247 FOREIGN ("gimp-transform-3d-tool-dialog", TRUE, FALSE),
248 FOREIGN ("gimp-perspective-tool-dialog", TRUE, FALSE),
249 FOREIGN ("gimp-unified-transform-tool-dialog", TRUE, FALSE),
250 FOREIGN ("gimp-handle-transform-tool-dialog", TRUE, FALSE),
251
252 FOREIGN ("gimp-toolbox-color-dialog", TRUE, FALSE),
253 FOREIGN ("gimp-gradient-editor-color-dialog", TRUE, FALSE),
254 FOREIGN ("gimp-palette-editor-color-dialog", TRUE, FALSE),
255 FOREIGN ("gimp-colormap-editor-color-dialog", TRUE, FALSE),
256
257 FOREIGN ("gimp-controller-editor-dialog", FALSE, TRUE),
258 FOREIGN ("gimp-controller-action-dialog", FALSE, TRUE),
259
260 /* ordinary toplevels */
261 TOPLEVEL ("gimp-image-new-dialog",
262 dialogs_image_new_new, FALSE, TRUE, FALSE),
263 TOPLEVEL ("gimp-file-open-dialog",
264 dialogs_file_open_new, TRUE, TRUE, TRUE),
265 TOPLEVEL ("gimp-file-open-location-dialog",
266 dialogs_file_open_location_new, FALSE, TRUE, FALSE),
267 TOPLEVEL ("gimp-file-save-dialog",
268 dialogs_file_save_new, FALSE, TRUE, TRUE),
269 TOPLEVEL ("gimp-file-export-dialog",
270 dialogs_file_export_new, FALSE, TRUE, TRUE),
271
272 /* singleton toplevels */
273 TOPLEVEL ("gimp-preferences-dialog",
274 dialogs_preferences_get, TRUE, TRUE, TRUE),
275 TOPLEVEL ("gimp-input-devices-dialog",
276 dialogs_input_devices_get, TRUE, TRUE, FALSE),
277 TOPLEVEL ("gimp-keyboard-shortcuts-dialog",
278 dialogs_keyboard_shortcuts_get, TRUE, TRUE, TRUE),
279 TOPLEVEL ("gimp-module-dialog",
280 dialogs_module_get, TRUE, TRUE, TRUE),
281 TOPLEVEL ("gimp-palette-import-dialog",
282 dialogs_palette_import_get, TRUE, TRUE, TRUE),
283 TOPLEVEL ("gimp-tips-dialog",
284 dialogs_tips_get, TRUE, FALSE, FALSE),
285 TOPLEVEL ("gimp-about-dialog",
286 dialogs_about_get, TRUE, FALSE, FALSE),
287 TOPLEVEL ("gimp-action-search-dialog",
288 dialogs_action_search_get, TRUE, TRUE, TRUE),
289 TOPLEVEL ("gimp-error-dialog",
290 dialogs_error_get, TRUE, FALSE, FALSE),
291 TOPLEVEL ("gimp-critical-dialog",
292 dialogs_critical_get, TRUE, FALSE, FALSE),
293 TOPLEVEL ("gimp-close-all-dialog",
294 dialogs_close_all_get, TRUE, FALSE, FALSE),
295 TOPLEVEL ("gimp-quit-dialog",
296 dialogs_quit_get, TRUE, FALSE, FALSE),
297
298 /* docks */
299 DOCK ("gimp-dock",
300 dialogs_dock_new),
301 DOCK ("gimp-toolbox",
302 dialogs_toolbox_new),
303
304 /* dock windows */
305 DOCK_WINDOW ("gimp-dock-window",
306 dialogs_dock_window_new),
307 DOCK_WINDOW ("gimp-toolbox-window",
308 dialogs_toolbox_dock_window_new),
309
310 /* singleton dockables */
311 DOCKABLE ("gimp-tool-options",
312 N_("Tool Options"), NULL, GIMP_ICON_DIALOG_TOOL_OPTIONS,
313 GIMP_HELP_TOOL_OPTIONS_DIALOG,
314 dialogs_tool_options_new, 0, TRUE),
315 DOCKABLE ("gimp-device-status",
316 N_("Devices"), N_("Device Status"), GIMP_ICON_DIALOG_DEVICE_STATUS,
317 GIMP_HELP_DEVICE_STATUS_DIALOG,
318 dialogs_device_status_new, 0, TRUE),
319 DOCKABLE ("gimp-error-console",
320 N_("Errors"), N_("Error Console"), GIMP_ICON_DIALOG_WARNING,
321 GIMP_HELP_ERRORS_DIALOG,
322 dialogs_error_console_new, 0, TRUE),
323 DOCKABLE ("gimp-cursor-view",
324 N_("Pointer"), N_("Pointer Information"), GIMP_ICON_CURSOR,
325 GIMP_HELP_POINTER_INFO_DIALOG,
326 dialogs_cursor_view_new, 0, TRUE),
327 DOCKABLE ("gimp-dashboard",
328 N_("Dashboard"), N_("Dashboard"), GIMP_ICON_DIALOG_DASHBOARD,
329 GIMP_HELP_DASHBOARD_DIALOG,
330 dialogs_dashboard_new, 0, TRUE),
331
332 /* list & grid views */
333 LISTGRID (image, image,
334 N_("Images"), NULL, GIMP_ICON_DIALOG_IMAGES,
335 GIMP_HELP_IMAGE_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
336 LISTGRID (brush, brush,
337 N_("Brushes"), NULL, GIMP_ICON_BRUSH,
338 GIMP_HELP_BRUSH_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
339 LISTGRID (dynamics, dynamics,
340 N_("Paint Dynamics"), NULL, GIMP_ICON_DYNAMICS,
341 GIMP_HELP_DYNAMICS_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
342 LISTGRID (mypaint-brush, mypaint_brush,
343 N_("MyPaint Brushes"), NULL, GIMP_ICON_MYPAINT_BRUSH,
344 GIMP_HELP_MYPAINT_BRUSH_DIALOG, GIMP_VIEW_SIZE_LARGE),
345 LISTGRID (pattern, pattern,
346 N_("Patterns"), NULL, GIMP_ICON_PATTERN,
347 GIMP_HELP_PATTERN_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
348 LISTGRID (gradient, gradient,
349 N_("Gradients"), NULL, GIMP_ICON_GRADIENT,
350 GIMP_HELP_GRADIENT_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
351 LISTGRID (palette, palette,
352 N_("Palettes"), NULL, GIMP_ICON_PALETTE,
353 GIMP_HELP_PALETTE_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
354 LISTGRID (font, font,
355 N_("Fonts"), NULL, GIMP_ICON_FONT,
356 GIMP_HELP_FONT_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
357 LISTGRID (buffer, buffer,
358 N_("Buffers"), NULL, GIMP_ICON_BUFFER,
359 GIMP_HELP_BUFFER_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
360 LISTGRID (tool-preset, tool_preset,
361 N_("Tool Presets"), NULL, GIMP_ICON_TOOL_PRESET,
362 GIMP_HELP_TOOL_PRESET_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
363 LISTGRID (document, document,
364 N_("History"), N_("Document History"), GIMP_ICON_DOCUMENT_OPEN_RECENT,
365 GIMP_HELP_DOCUMENT_DIALOG, GIMP_VIEW_SIZE_LARGE),
366 LISTGRID (template, template,
367 N_("Templates"), N_("Image Templates"), GIMP_ICON_TEMPLATE,
368 GIMP_HELP_TEMPLATE_DIALOG, GIMP_VIEW_SIZE_SMALL),
369
370 /* image related */
371 DOCKABLE ("gimp-layer-list",
372 N_("Layers"), NULL, GIMP_ICON_DIALOG_LAYERS,
373 GIMP_HELP_LAYER_DIALOG,
374 dialogs_layer_list_view_new, 0, FALSE),
375 DOCKABLE ("gimp-channel-list",
376 N_("Channels"), NULL, GIMP_ICON_DIALOG_CHANNELS,
377 GIMP_HELP_CHANNEL_DIALOG,
378 dialogs_channel_list_view_new, 0, FALSE),
379 DOCKABLE ("gimp-vectors-list",
380 N_("Paths"), NULL, GIMP_ICON_DIALOG_PATHS,
381 GIMP_HELP_PATH_DIALOG,
382 dialogs_vectors_list_view_new, 0, FALSE),
383 DOCKABLE ("gimp-indexed-palette",
384 N_("Colormap"), NULL, GIMP_ICON_COLORMAP,
385 GIMP_HELP_INDEXED_PALETTE_DIALOG,
386 dialogs_colormap_editor_new, 0, FALSE),
387 DOCKABLE ("gimp-histogram-editor",
388 N_("Histogram"), NULL, GIMP_ICON_HISTOGRAM,
389 GIMP_HELP_HISTOGRAM_DIALOG,
390 dialogs_histogram_editor_new, 0, FALSE),
391 DOCKABLE ("gimp-selection-editor",
392 N_("Selection"), N_("Selection Editor"), GIMP_ICON_SELECTION,
393 GIMP_HELP_SELECTION_DIALOG,
394 dialogs_selection_editor_new, 0, FALSE),
395 DOCKABLE ("gimp-symmetry-editor",
396 N_("Symmetry Painting"), NULL, GIMP_ICON_SYMMETRY,
397 GIMP_HELP_SYMMETRY_DIALOG,
398 dialogs_symmetry_editor_new, 0, FALSE),
399 DOCKABLE ("gimp-undo-history",
400 N_("Undo"), N_("Undo History"), GIMP_ICON_DIALOG_UNDO_HISTORY,
401 GIMP_HELP_UNDO_DIALOG,
402 dialogs_undo_editor_new, 0, FALSE),
403 DOCKABLE ("gimp-sample-point-editor",
404 N_("Sample Points"), N_("Sample Points"), GIMP_ICON_SAMPLE_POINT,
405 GIMP_HELP_SAMPLE_POINT_DIALOG,
406 dialogs_sample_point_editor_new, 0, FALSE),
407
408 /* display related */
409 DOCKABLE ("gimp-navigation-view",
410 N_("Navigation"), N_("Display Navigation"), GIMP_ICON_DIALOG_NAVIGATION,
411 GIMP_HELP_NAVIGATION_DIALOG,
412 dialogs_navigation_editor_new, 0, FALSE),
413
414 /* editors */
415 DOCKABLE ("gimp-color-editor",
416 N_("FG/BG"), N_("FG/BG Color"), GIMP_ICON_COLORS_DEFAULT,
417 GIMP_HELP_COLOR_DIALOG,
418 dialogs_color_editor_new, 0, FALSE),
419
420 /* singleton editors */
421 DOCKABLE ("gimp-brush-editor",
422 N_("Brush Editor"), NULL, GIMP_ICON_BRUSH,
423 GIMP_HELP_BRUSH_EDITOR_DIALOG,
424 dialogs_brush_editor_get, 0, TRUE),
425 DOCKABLE ("gimp-dynamics-editor",
426 N_("Paint Dynamics Editor"), NULL, GIMP_ICON_DYNAMICS,
427 GIMP_HELP_DYNAMICS_EDITOR_DIALOG,
428 dialogs_dynamics_editor_get, 0, TRUE),
429 DOCKABLE ("gimp-gradient-editor",
430 N_("Gradient Editor"), NULL, GIMP_ICON_GRADIENT,
431 GIMP_HELP_GRADIENT_EDITOR_DIALOG,
432 dialogs_gradient_editor_get, 0, TRUE),
433 DOCKABLE ("gimp-palette-editor",
434 N_("Palette Editor"), NULL, GIMP_ICON_PALETTE,
435 GIMP_HELP_PALETTE_EDITOR_DIALOG,
436 dialogs_palette_editor_get, 0, TRUE),
437 DOCKABLE ("gimp-tool-preset-editor",
438 N_("Tool Preset Editor"), NULL, GIMP_ICON_TOOL_PRESET,
439 GIMP_HELP_TOOL_PRESET_EDITOR_DIALOG,
440 dialogs_tool_preset_editor_get, 0, TRUE),
441
442 /* image windows */
443 IMAGE_WINDOW ("gimp-empty-image-window",
444 TRUE, TRUE),
445 IMAGE_WINDOW ("gimp-single-image-window",
446 TRUE, TRUE)
447 };
448
449 /**
450 * dialogs_restore_dialog:
451 * @factory:
452 * @screen:
453 * @monitor:
454 * @info:
455 *
456 * Creates a top level widget based on the given session info object
457 * in which other widgets later can be be put, typically also restored
458 * from the same session info object.
459 *
460 * Returns:
461 **/
462 static GtkWidget *
dialogs_restore_dialog(GimpDialogFactory * factory,GdkScreen * screen,gint monitor,GimpSessionInfo * info)463 dialogs_restore_dialog (GimpDialogFactory *factory,
464 GdkScreen *screen,
465 gint monitor,
466 GimpSessionInfo *info)
467 {
468 GtkWidget *dialog;
469 GimpCoreConfig *config = gimp_dialog_factory_get_context (factory)->gimp->config;
470
471 GIMP_LOG (DIALOG_FACTORY, "restoring toplevel \"%s\" (info %p)",
472 gimp_session_info_get_factory_entry (info)->identifier,
473 info);
474
475 dialog =
476 gimp_dialog_factory_dialog_new (factory, screen, monitor,
477 NULL /*ui_manager*/,
478 gimp_session_info_get_factory_entry (info)->identifier,
479 gimp_session_info_get_factory_entry (info)->view_size,
480 ! GIMP_GUI_CONFIG (config)->hide_docks);
481
482 g_object_set_data (G_OBJECT (dialog), GIMP_DIALOG_VISIBILITY_KEY,
483 GINT_TO_POINTER (GIMP_GUI_CONFIG (config)->hide_docks ?
484 GIMP_DIALOG_VISIBILITY_HIDDEN :
485 GIMP_DIALOG_VISIBILITY_VISIBLE));
486
487 return dialog;
488 }
489
490 /**
491 * dialogs_restore_window:
492 * @factory:
493 * @screen:
494 * @monitor:
495 * @info:
496 *
497 * "restores" the image window. We don't really restore anything since
498 * the image window is created earlier, so we just look for and return
499 * the already-created image window.
500 *
501 * Returns:
502 **/
503 static GtkWidget *
dialogs_restore_window(GimpDialogFactory * factory,GdkScreen * screen,gint monitor,GimpSessionInfo * info)504 dialogs_restore_window (GimpDialogFactory *factory,
505 GdkScreen *screen,
506 gint monitor,
507 GimpSessionInfo *info)
508 {
509 Gimp *gimp = gimp_dialog_factory_get_context (factory)->gimp;
510 GimpDisplay *display = GIMP_DISPLAY (gimp_get_empty_display (gimp));
511 GimpDisplayShell *shell = gimp_display_get_shell (display);
512 GtkWidget *dialog;
513
514 dialog = GTK_WIDGET (gimp_display_shell_get_window (shell));
515
516 return dialog;
517 }
518
519
520 /* public functions */
521
522 void
dialogs_init(Gimp * gimp,GimpMenuFactory * menu_factory)523 dialogs_init (Gimp *gimp,
524 GimpMenuFactory *menu_factory)
525 {
526 GimpDialogFactory *factory = NULL;
527 gint i = 0;
528
529 g_return_if_fail (GIMP_IS_GIMP (gimp));
530 g_return_if_fail (GIMP_IS_MENU_FACTORY (menu_factory));
531
532 factory = gimp_dialog_factory_new ("toplevel",
533 gimp_get_user_context (gimp),
534 menu_factory);
535 gimp_dialog_factory_set_singleton (factory);
536
537 for (i = 0; i < G_N_ELEMENTS (entries); i++)
538 gimp_dialog_factory_register_entry (factory,
539 entries[i].identifier,
540 gettext (entries[i].name),
541 gettext (entries[i].blurb),
542 entries[i].icon_name,
543 entries[i].help_id,
544 entries[i].new_func,
545 entries[i].restore_func,
546 entries[i].view_size,
547 entries[i].singleton,
548 entries[i].session_managed,
549 entries[i].remember_size,
550 entries[i].remember_if_open,
551 entries[i].hideable,
552 entries[i].image_window,
553 entries[i].dockable);
554
555 global_recent_docks = gimp_list_new (GIMP_TYPE_SESSION_INFO, FALSE);
556 }
557
558 void
dialogs_exit(Gimp * gimp)559 dialogs_exit (Gimp *gimp)
560 {
561 g_return_if_fail (GIMP_IS_GIMP (gimp));
562
563 if (gimp_dialog_factory_get_singleton ())
564 {
565 /* run dispose manually so the factory destroys its dialogs, which
566 * might in turn directly or indirectly ref the factory
567 */
568 g_object_run_dispose (G_OBJECT (gimp_dialog_factory_get_singleton ()));
569
570 g_object_unref (gimp_dialog_factory_get_singleton ());
571 gimp_dialog_factory_set_singleton (NULL);
572 }
573
574 g_clear_object (&global_recent_docks);
575 }
576
577 static void
dialogs_ensure_factory_entry_on_recent_dock(GimpSessionInfo * info)578 dialogs_ensure_factory_entry_on_recent_dock (GimpSessionInfo *info)
579 {
580 if (! gimp_session_info_get_factory_entry (info))
581 {
582 GimpDialogFactoryEntry *entry = NULL;
583
584 /* The recent docks container only contains session infos for
585 * dock windows
586 */
587 entry = gimp_dialog_factory_find_entry (gimp_dialog_factory_get_singleton (),
588 "gimp-dock-window");
589
590 gimp_session_info_set_factory_entry (info, entry);
591 }
592 }
593
594 static GFile *
dialogs_get_dockrc_file(void)595 dialogs_get_dockrc_file (void)
596 {
597 const gchar *basename;
598
599 basename = g_getenv ("GIMP_TESTING_DOCKRC_NAME");
600 if (! basename)
601 basename = "dockrc";
602
603 return gimp_directory_file (basename, NULL);
604 }
605
606 void
dialogs_load_recent_docks(Gimp * gimp)607 dialogs_load_recent_docks (Gimp *gimp)
608 {
609 GFile *file;
610 GError *error = NULL;
611
612 g_return_if_fail (GIMP_IS_GIMP (gimp));
613
614 file = dialogs_get_dockrc_file ();
615
616 if (gimp->be_verbose)
617 g_print ("Parsing '%s'\n", gimp_file_get_utf8_name (file));
618
619 if (! gimp_config_deserialize_gfile (GIMP_CONFIG (global_recent_docks),
620 file,
621 NULL, &error))
622 {
623 if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT)
624 gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
625
626 g_clear_error (&error);
627 }
628
629 g_object_unref (file);
630
631 /* In GIMP 2.6 dockrc did not contain the factory entries for the
632 * session infos, so set that up manually if needed
633 */
634 gimp_container_foreach (global_recent_docks,
635 (GFunc) dialogs_ensure_factory_entry_on_recent_dock,
636 NULL);
637
638 gimp_list_reverse (GIMP_LIST (global_recent_docks));
639 }
640
641 void
dialogs_save_recent_docks(Gimp * gimp)642 dialogs_save_recent_docks (Gimp *gimp)
643 {
644 GFile *file;
645 GError *error = NULL;
646
647 g_return_if_fail (GIMP_IS_GIMP (gimp));
648
649 file = dialogs_get_dockrc_file ();
650
651 if (gimp->be_verbose)
652 g_print ("Writing '%s'\n", gimp_file_get_utf8_name (file));
653
654 if (! gimp_config_serialize_to_gfile (GIMP_CONFIG (global_recent_docks),
655 file,
656 "recently closed docks",
657 "end of recently closed docks",
658 NULL, &error))
659 {
660 gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
661 g_clear_error (&error);
662 }
663
664 g_object_unref (file);
665 }
666
667 GtkWidget *
dialogs_get_toolbox(void)668 dialogs_get_toolbox (void)
669 {
670 GList *list;
671
672 g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (gimp_dialog_factory_get_singleton ()), NULL);
673
674 for (list = gimp_dialog_factory_get_open_dialogs (gimp_dialog_factory_get_singleton ());
675 list;
676 list = g_list_next (list))
677 {
678 if (GIMP_IS_DOCK_WINDOW (list->data) &&
679 gimp_dock_window_has_toolbox (list->data))
680 return list->data;
681 }
682
683 return NULL;
684 }
685
686 GtkWidget *
dialogs_get_dialog(GObject * attach_object,const gchar * attach_key)687 dialogs_get_dialog (GObject *attach_object,
688 const gchar *attach_key)
689 {
690 g_return_val_if_fail (G_IS_OBJECT (attach_object), NULL);
691 g_return_val_if_fail (attach_key != NULL, NULL);
692
693 return g_object_get_data (attach_object, attach_key);
694 }
695
696 void
dialogs_attach_dialog(GObject * attach_object,const gchar * attach_key,GtkWidget * dialog)697 dialogs_attach_dialog (GObject *attach_object,
698 const gchar *attach_key,
699 GtkWidget *dialog)
700 {
701 g_return_if_fail (G_IS_OBJECT (attach_object));
702 g_return_if_fail (attach_key != NULL);
703 g_return_if_fail (GTK_IS_WIDGET (dialog));
704
705 g_object_set_data (attach_object, attach_key, dialog);
706 g_object_set_data (G_OBJECT (dialog), "gimp-dialogs-attach-key",
707 (gpointer) attach_key);
708
709 g_signal_connect_object (dialog, "destroy",
710 G_CALLBACK (dialogs_detach_dialog),
711 attach_object,
712 G_CONNECT_SWAPPED);
713 }
714
715 void
dialogs_detach_dialog(GObject * attach_object,GtkWidget * dialog)716 dialogs_detach_dialog (GObject *attach_object,
717 GtkWidget *dialog)
718 {
719 const gchar *attach_key;
720
721 g_return_if_fail (G_IS_OBJECT (attach_object));
722 g_return_if_fail (GTK_IS_WIDGET (dialog));
723
724 attach_key = g_object_get_data (G_OBJECT (dialog),
725 "gimp-dialogs-attach-key");
726
727 g_return_if_fail (attach_key != NULL);
728
729 g_object_set_data (attach_object, attach_key, NULL);
730
731 g_signal_handlers_disconnect_by_func (dialog,
732 dialogs_detach_dialog,
733 attach_object);
734 }
735
736 void
dialogs_destroy_dialog(GObject * attach_object,const gchar * attach_key)737 dialogs_destroy_dialog (GObject *attach_object,
738 const gchar *attach_key)
739 {
740 GtkWidget *dialog;
741
742 g_return_if_fail (G_IS_OBJECT (attach_object));
743 g_return_if_fail (attach_key != NULL);
744
745 dialog = g_object_get_data (attach_object, attach_key);
746
747 if (dialog)
748 gtk_widget_destroy (dialog);
749 }
750