dialogs.c 17.7 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7 8 9 10 11 12 13 14
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 17 18 19 20 21
 */

#include "config.h"

#include <gtk/gtk.h>

22 23
#include "libgimpbase/gimpbase.h"
#include "libgimpconfig/gimpconfig.h"
24 25
#include "libgimpwidgets/gimpwidgets.h"

26
#include "dialogs-types.h"
27

Michael Natterer's avatar
Michael Natterer committed
28
#include "core/gimp.h"
29
#include "core/gimpcontext.h"
30
#include "core/gimplist.h"
31

32
#include "widgets/gimpdialogfactory.h"
33
#include "widgets/gimphelp-ids.h"
34
#include "widgets/gimpmenufactory.h"
35
#include "widgets/gimpsessioninfo.h"
36

37 38 39
#include "dialogs.h"
#include "dialogs-constructors.h"

40 41
#include "gimp-intl.h"

42

43 44 45
GimpDialogFactory *global_dialog_factory  = NULL;
GimpDialogFactory *global_dock_factory    = NULL;
GimpDialogFactory *global_toolbox_factory = NULL;
46
GimpDialogFactory *global_display_factory = NULL;
47

48 49
GimpContainer     *global_recent_docks    = NULL;

50

51
#define FOREIGN(id, singleton, remember_size) \
52
  { id, NULL, NULL, NULL, NULL, \
53
    NULL, 0, singleton,  TRUE, remember_size, FALSE, FALSE }
54

55
#define TOPLEVEL(id, new_func, singleton, session_managed, remember_size) \
56
  { id, NULL, NULL, NULL, NULL, \
57
    new_func, 0, singleton, session_managed, remember_size, FALSE, FALSE }
58 59


60
static const GimpDialogFactoryEntry toplevel_entries[] =
61
{
62
  /*  foreign toplevels without constructor  */
63
  FOREIGN ("gimp-brightness-contrast-tool-dialog", TRUE,  FALSE),
64
  FOREIGN ("gimp-color-balance-tool-dialog",       TRUE,  FALSE),
65 66 67 68
  FOREIGN ("gimp-color-picker-tool-dialog",        TRUE,  TRUE),
  FOREIGN ("gimp-colorize-tool-dialog",            TRUE,  FALSE),
  FOREIGN ("gimp-crop-tool-dialog",                TRUE,  FALSE),
  FOREIGN ("gimp-curves-tool-dialog",              TRUE,  TRUE),
69
  FOREIGN ("gimp-desaturate-tool-dialog",          TRUE,  FALSE),
70
  FOREIGN ("gimp-gegl-tool-dialog",                TRUE,  FALSE),
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
  FOREIGN ("gimp-hue-saturation-tool-dialog",      TRUE,  FALSE),
  FOREIGN ("gimp-levels-tool-dialog",              TRUE,  TRUE),
  FOREIGN ("gimp-measure-tool-dialog",             TRUE,  FALSE),
  FOREIGN ("gimp-posterize-tool-dialog",           TRUE,  FALSE),
  FOREIGN ("gimp-rotate-tool-dialog",              TRUE,  FALSE),
  FOREIGN ("gimp-scale-tool-dialog",               TRUE,  FALSE),
  FOREIGN ("gimp-shear-tool-dialog",               TRUE,  FALSE),
  FOREIGN ("gimp-text-tool-dialog",                TRUE,  TRUE),
  FOREIGN ("gimp-threshold-tool-dialog",           TRUE,  FALSE),
  FOREIGN ("gimp-perspective-tool-dialog",         TRUE,  FALSE),

  FOREIGN ("gimp-toolbox-color-dialog",            TRUE,  FALSE),
  FOREIGN ("gimp-gradient-editor-color-dialog",    TRUE,  FALSE),
  FOREIGN ("gimp-palette-editor-color-dialog",     TRUE,  FALSE),
  FOREIGN ("gimp-colormap-editor-color-dialog",    TRUE,  FALSE),

  FOREIGN ("gimp-controller-editor-dialog",        FALSE, TRUE),
  FOREIGN ("gimp-controller-action-dialog",        FALSE, TRUE),
89

90
  /*  ordinary toplevels  */
91 92 93 94 95 96 97 98
  TOPLEVEL ("gimp-image-new-dialog",
            dialogs_image_new_new,          FALSE, TRUE, FALSE),
  TOPLEVEL ("gimp-file-open-dialog",
            dialogs_file_open_new,          TRUE,  TRUE, TRUE),
  TOPLEVEL ("gimp-file-open-location-dialog",
            dialogs_file_open_location_new, FALSE, TRUE, FALSE),
  TOPLEVEL ("gimp-file-save-dialog",
            dialogs_file_save_new,          FALSE, TRUE, TRUE),
99 100
  TOPLEVEL ("gimp-file-export-dialog",
            dialogs_file_export_new,        FALSE, TRUE, TRUE),
101 102

  /*  singleton toplevels  */
103
  TOPLEVEL ("gimp-preferences-dialog",
104 105 106
            dialogs_preferences_get,        TRUE, TRUE,  FALSE),
  TOPLEVEL ("gimp-keyboard-shortcuts-dialog",
            dialogs_keyboard_shortcuts_get, TRUE, TRUE,  TRUE),
107
  TOPLEVEL ("gimp-module-dialog",
108
            dialogs_module_get,             TRUE, TRUE,  TRUE),
109 110
  TOPLEVEL ("gimp-palette-import-dialog",
            dialogs_palette_import_get,     TRUE, TRUE,  TRUE),
111
  TOPLEVEL ("gimp-tips-dialog",
112
            dialogs_tips_get,               TRUE, FALSE, FALSE),
113
  TOPLEVEL ("gimp-about-dialog",
114
            dialogs_about_get,              TRUE, FALSE, FALSE),
115
  TOPLEVEL ("gimp-error-dialog",
116
            dialogs_error_get,              TRUE, FALSE, FALSE),
117
  TOPLEVEL ("gimp-close-all-dialog",
118
            dialogs_close_all_get,          TRUE, FALSE, FALSE),
119
  TOPLEVEL ("gimp-quit-dialog",
120
            dialogs_quit_get,               TRUE, FALSE, FALSE)
121 122
};

123
#define DOCKABLE(id,name,blurb,stock_id,help_id,\
124
                 new_func,view_size,singleton) \
125
  { id, name, blurb, stock_id, help_id, \
126
    new_func, view_size, singleton, FALSE, FALSE, TRUE, TRUE }
127 128

#define LISTGRID(id,name,blurb,stock_id,help_id,\
129
                 view_size) \
130
  { "gimp-"#id"-list", name, blurb, stock_id, help_id, \
131
    dialogs_##id##_list_view_new, view_size, FALSE, FALSE, FALSE, TRUE, TRUE }, \
132
  { "gimp-"#id"-grid", name, blurb, stock_id, help_id, \
133
    dialogs_##id##_grid_view_new, view_size, FALSE, FALSE, FALSE, TRUE, TRUE }
134

135 136 137 138 139
#define LIST(id,name,blurb,stock_id,help_id,\
             view_size) \
  { "gimp-"#id"-list", name, blurb, stock_id, help_id, \
    dialogs_##id##_list_view_new, view_size, FALSE, FALSE, FALSE, TRUE, TRUE }

140
static const GimpDialogFactoryEntry dock_entries[] =
141
{
142
  /*  singleton dockables  */
143 144 145
  DOCKABLE ("gimp-tool-options",
            N_("Tool Options"), NULL, GIMP_STOCK_TOOL_OPTIONS,
            GIMP_HELP_TOOL_OPTIONS_DIALOG,
146
            dialogs_tool_options_new, 0, TRUE),
147 148 149
  DOCKABLE ("gimp-device-status",
            N_("Devices"), N_("Device Status"), GIMP_STOCK_DEVICE_STATUS,
            GIMP_HELP_DEVICE_STATUS_DIALOG,
150
            dialogs_device_status_new, 0, TRUE),
151 152 153
  DOCKABLE ("gimp-error-console",
            N_("Errors"), N_("Error Console"), GIMP_STOCK_WARNING,
            GIMP_HELP_ERRORS_DIALOG,
154 155
            dialogs_error_console_new, 0, TRUE),
  DOCKABLE ("gimp-cursor-view",
156 157
            N_("Pointer"), N_("Pointer Information"), GIMP_STOCK_CURSOR,
            GIMP_HELP_POINTER_INFO_DIALOG,
158
            dialogs_cursor_view_new, 0, TRUE),
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174

  /*  list & grid views  */
  LISTGRID (image, N_("Images"), NULL, GIMP_STOCK_IMAGES,
            GIMP_HELP_IMAGE_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
  LISTGRID (brush, N_("Brushes"), NULL, GIMP_STOCK_BRUSH,
            GIMP_HELP_BRUSH_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
  LISTGRID (pattern, N_("Patterns"), NULL, GIMP_STOCK_PATTERN,
            GIMP_HELP_PATTERN_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
  LISTGRID (gradient, N_("Gradients"), NULL, GIMP_STOCK_GRADIENT,
            GIMP_HELP_GRADIENT_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
  LISTGRID (palette, N_("Palettes"), NULL, GIMP_STOCK_PALETTE,
            GIMP_HELP_PALETTE_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
  LISTGRID (font, N_("Fonts"), NULL, GIMP_STOCK_FONT,
            GIMP_HELP_FONT_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
  LISTGRID (buffer, N_("Buffers"), NULL, GIMP_STOCK_BUFFER,
            GIMP_HELP_BUFFER_DIALOG, GIMP_VIEW_SIZE_MEDIUM),
175
  LISTGRID (document, N_("History"), N_("Document History"), "document-open-recent",
176 177 178
            GIMP_HELP_DOCUMENT_DIALOG, GIMP_VIEW_SIZE_LARGE),
  LISTGRID (template, N_("Templates"), N_("Image Templates"), GIMP_STOCK_TEMPLATE,
            GIMP_HELP_TEMPLATE_DIALOG, GIMP_VIEW_SIZE_SMALL),
179

180 181 182 183
  /* Some things do not have grids, so just list */
  LIST (dynamics, N_("Dynamics"), NULL, GIMP_STOCK_DYNAMICS,
        GIMP_HELP_DYNAMICS_DIALOG, GIMP_VIEW_SIZE_MEDIUM),

184
  /*  image related  */
185 186 187 188 189 190 191 192 193 194 195 196 197
  DOCKABLE ("gimp-layer-list",
            N_("Layers"), NULL, GIMP_STOCK_LAYERS,
            GIMP_HELP_LAYER_DIALOG,
            dialogs_layer_list_view_new, 0, FALSE),
  DOCKABLE ("gimp-channel-list",
            N_("Channels"), NULL, GIMP_STOCK_CHANNELS,
            GIMP_HELP_CHANNEL_DIALOG,
            dialogs_channel_list_view_new, 0, FALSE),
  DOCKABLE ("gimp-vectors-list",
            N_("Paths"), NULL, GIMP_STOCK_PATHS,
            GIMP_HELP_PATH_DIALOG,
            dialogs_vectors_list_view_new, 0, FALSE),
  DOCKABLE ("gimp-indexed-palette",
198
            N_("Colormap"), NULL, GIMP_STOCK_COLORMAP,
199 200 201 202 203 204 205 206 207 208 209 210 211 212
            GIMP_HELP_INDEXED_PALETTE_DIALOG,
            dialogs_colormap_editor_new, 0, FALSE),
  DOCKABLE ("gimp-histogram-editor",
            N_("Histogram"), NULL, GIMP_STOCK_HISTOGRAM,
            GIMP_HELP_HISTOGRAM_DIALOG,
            dialogs_histogram_editor_new, 0, FALSE),
  DOCKABLE ("gimp-selection-editor",
            N_("Selection"), N_("Selection Editor"), GIMP_STOCK_SELECTION,
            GIMP_HELP_SELECTION_DIALOG,
            dialogs_selection_editor_new, 0, FALSE),
  DOCKABLE ("gimp-undo-history",
            N_("Undo"), N_("Undo History"), GIMP_STOCK_UNDO_HISTORY,
            GIMP_HELP_UNDO_DIALOG,
            dialogs_undo_editor_new, 0, FALSE),
213 214 215 216
  DOCKABLE ("gimp-sample-point-editor",
            N_("Sample Points"), N_("Sample Points"), GIMP_STOCK_SAMPLE_POINT,
            GIMP_HELP_SAMPLE_POINT_DIALOG,
            dialogs_sample_point_editor_new, 0, FALSE),
217

218
  /*  display related  */
219 220 221 222
  DOCKABLE ("gimp-navigation-view",
            N_("Navigation"), N_("Display Navigation"), GIMP_STOCK_NAVIGATION,
            GIMP_HELP_NAVIGATION_DIALOG,
            dialogs_navigation_editor_new, 0, FALSE),
223

224
  /*  editors  */
225 226 227 228
  DOCKABLE ("gimp-color-editor",
            N_("FG/BG"), N_("FG/BG Color"), GIMP_STOCK_DEFAULT_COLORS,
            GIMP_HELP_COLOR_DIALOG,
            dialogs_color_editor_new, 0, FALSE),
229

230
  /*  singleton editors  */
231 232 233 234
  DOCKABLE ("gimp-brush-editor",
            N_("Brush Editor"), NULL, GIMP_STOCK_BRUSH,
            GIMP_HELP_BRUSH_EDITOR_DIALOG,
            dialogs_brush_editor_get, 0, TRUE),
235 236 237 238
  DOCKABLE ("gimp-dynamics-editor",
            N_("Dynamics Editor"), NULL, GIMP_STOCK_DYNAMICS,
            GIMP_HELP_DYNAMICS_EDITOR_DIALOG,
            dialogs_dynamics_editor_get, 0, TRUE),
239 240 241 242 243 244 245 246
  DOCKABLE ("gimp-gradient-editor",
            N_("Gradient Editor"), NULL, GIMP_STOCK_GRADIENT,
            GIMP_HELP_GRADIENT_EDITOR_DIALOG,
            dialogs_gradient_editor_get, 0, TRUE),
  DOCKABLE ("gimp-palette-editor",
            N_("Palette Editor"), NULL, GIMP_STOCK_PALETTE,
            GIMP_HELP_PALETTE_EDITOR_DIALOG,
            dialogs_palette_editor_get, 0, TRUE)
247 248 249 250 251
};


/*  public functions  */

252
void
253 254
dialogs_init (Gimp            *gimp,
              GimpMenuFactory *menu_factory)
255
{
256 257
  gint i;

258
  g_return_if_fail (GIMP_IS_GIMP (gimp));
259
  g_return_if_fail (GIMP_IS_MENU_FACTORY (menu_factory));
260

261
  /* Toplevel */
Michael Natterer's avatar
Michael Natterer committed
262
  global_dialog_factory = gimp_dialog_factory_new ("toplevel",
263 264
                                                   gimp_get_user_context (gimp),
                                                   menu_factory,
265 266
                                                   NULL,
                                                   TRUE);
267

268
  /* Toolbox */
269 270
  global_toolbox_factory = gimp_dialog_factory_new ("toolbox",
                                                    gimp_get_user_context (gimp),
271
                                                    menu_factory,
272 273
                                                    dialogs_toolbox_get,
                                                    TRUE);
274 275
  gimp_dialog_factory_set_constructor (global_toolbox_factory,
                                       dialogs_dockable_constructor);
276 277
  gimp_dialog_factory_set_dock_window_func (global_toolbox_factory,
                                            dialogs_toolbox_dock_window_new);
278

279
  /* Dock */
Michael Natterer's avatar
Michael Natterer committed
280
  global_dock_factory = gimp_dialog_factory_new ("dock",
281 282
                                                 gimp_get_user_context (gimp),
                                                 menu_factory,
283 284
                                                 dialogs_dock_new,
                                                 TRUE);
285 286
  gimp_dialog_factory_set_constructor (global_dock_factory,
                                       dialogs_dockable_constructor);
287 288
  gimp_dialog_factory_set_dock_window_func (global_dock_factory,
                                            dialogs_dock_window_new);
289

290
  /* Display */
291 292 293
  global_display_factory = gimp_dialog_factory_new ("display",
                                                    gimp_get_user_context (gimp),
                                                    menu_factory,
294 295
                                                    NULL,
                                                    FALSE);
296

297

Michael Natterer's avatar
Michael Natterer committed
298
  for (i = 0; i < G_N_ELEMENTS (toplevel_entries); i++)
299
    gimp_dialog_factory_register_entry (global_dialog_factory,
300 301 302 303 304 305 306 307 308 309 310
                                        toplevel_entries[i].identifier,
                                        gettext (toplevel_entries[i].name),
                                        gettext (toplevel_entries[i].blurb),
                                        toplevel_entries[i].stock_id,
                                        toplevel_entries[i].help_id,
                                        toplevel_entries[i].new_func,
                                        toplevel_entries[i].view_size,
                                        toplevel_entries[i].singleton,
                                        toplevel_entries[i].session_managed,
                                        toplevel_entries[i].remember_size,
                                        toplevel_entries[i].remember_if_open);
311

Michael Natterer's avatar
Michael Natterer committed
312
  for (i = 0; i < G_N_ELEMENTS (dock_entries); i++)
313
    gimp_dialog_factory_register_entry (global_dock_factory,
314 315 316 317 318 319 320 321 322 323 324
                                        dock_entries[i].identifier,
                                        gettext (dock_entries[i].name),
                                        gettext (dock_entries[i].blurb),
                                        dock_entries[i].stock_id,
                                        dock_entries[i].help_id,
                                        dock_entries[i].new_func,
                                        dock_entries[i].view_size,
                                        dock_entries[i].singleton,
                                        dock_entries[i].session_managed,
                                        dock_entries[i].remember_size,
                                        dock_entries[i].remember_if_open);
325 326

  gimp_dialog_factory_register_entry (global_display_factory,
327
                                      "gimp-empty-image-window",
328 329 330 331 332 333 334 335
                                      NULL, NULL,
                                      NULL, NULL,
                                      NULL,
                                      -1,
                                      TRUE,
                                      TRUE,
                                      TRUE,
                                      FALSE);
336 337

  global_recent_docks = gimp_list_new (GIMP_TYPE_SESSION_INFO, FALSE);
338
}
339 340

void
Michael Natterer's avatar
Michael Natterer committed
341
dialogs_exit (Gimp *gimp)
342
{
343 344
  g_return_if_fail (GIMP_IS_GIMP (gimp));

345 346
  if (global_dialog_factory)
    {
347
      g_object_unref (global_dialog_factory);
348 349 350
      global_dialog_factory = NULL;
    }

351 352 353 354 355 356 357 358
  /*  destroy the "global_toolbox_factory" _before_ destroying the
   *  "global_dock_factory" because the "global_toolbox_factory" owns
   *  dockables which were created by the "global_dock_factory".  This
   *  way they are properly removed from the "global_dock_factory", which
   *  would complain about stale entries otherwise.
   */
  if (global_toolbox_factory)
    {
359
      g_object_unref (global_toolbox_factory);
360 361 362
      global_toolbox_factory = NULL;
    }

363 364
  if (global_dock_factory)
    {
365
      g_object_unref (global_dock_factory);
366 367
      global_dock_factory = NULL;
    }
368 369 370 371 372 373

  if (global_display_factory)
    {
      g_object_unref (global_display_factory);
      global_display_factory = NULL;
    }
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399

  if (global_recent_docks)
    {
      g_object_unref (global_recent_docks);
      global_recent_docks = NULL;
    }
}

void
dialogs_load_recent_docks (Gimp *gimp)
{
  gchar  *filename;
  GError *error = NULL;

  g_return_if_fail (GIMP_IS_GIMP (gimp));

  filename = gimp_personal_rc_file ("dockrc");

  if (gimp->be_verbose)
    g_print ("Parsing '%s'\n", gimp_filename_to_utf8 (filename));

  if (! gimp_config_deserialize_file (GIMP_CONFIG (global_recent_docks),
                                      filename,
                                      NULL, &error))
    {
      if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT)
400
        gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
401 402 403 404

      g_clear_error (&error);
    }

405 406
  gimp_list_reverse (GIMP_LIST (global_recent_docks));

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
  g_free (filename);
}

void
dialogs_save_recent_docks (Gimp *gimp)
{
  gchar  *filename;
  GError *error = NULL;

  g_return_if_fail (GIMP_IS_GIMP (gimp));

  filename = gimp_personal_rc_file ("dockrc");

  if (gimp->be_verbose)
    g_print ("Writing '%s'\n", gimp_filename_to_utf8 (filename));

  if (! gimp_config_serialize_to_file (GIMP_CONFIG (global_recent_docks),
                                       filename,
                                       "recently closed docks",
                                       "end of recently closed docks",
                                       NULL, &error))
    {
429
      gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
430 431 432 433
      g_clear_error (&error);
    }

  g_free (filename);
434
}
435 436 437 438 439 440 441 442 443 444 445 446

GtkWidget *
dialogs_get_toolbox (void)
{
  GList *list;

  g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (global_toolbox_factory), NULL);

  for (list = global_toolbox_factory->open_dialogs;
       list;
       list = g_list_next (list))
    {
447
      if (gtk_widget_is_toplevel (list->data))
448 449 450 451 452
        return list->data;
    }

  return NULL;
}