From 6d922b21dc9181fb9b8f573fe3fc23b35378d548 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Wed, 19 Jul 2006 06:50:34 +0000 Subject: [PATCH] Make message dialogs transient for the progress window. Addresses bug 2006-07-19 Sven Neumann Make message dialogs transient for the progress window. Addresses bug #347214. * app/core/gimp-gui.[ch]: added a progress parameter to gimp_message(). Let gimp_message() deal with optionally delegating the message to gimp_progress_message(). * app/errors.c: changed accordingly. * app/core/gimpprogress.[ch] (gimp_progress_message): return a boolean indicating whether the message was handled. * app/gui/Makefile.am * app/gui/gui-message.[ch] * app/gui/gui-vtable.c: moved message handling to a new file. Only use the global error dialog for messages without a progress. Otherwise attach an error dialog to the progress and try to make it transient to the progress window. * tools/pdbgen/pdb/message.pdb: * app/plug-in/gimpplugin-progress.[ch]: don't delegate messages to the progress interface, this is handled by gimp_message() now. * app/pdb/message_cmds.c: regenerated. * app/plug-in/gimpplugin.c * app/actions/documents-commands.c: formatting. --- ChangeLog | 30 ++++ app/actions/documents-commands.c | 5 +- app/core/gimp-gui.c | 28 ++-- app/core/gimp-gui.h | 2 + app/core/gimpprogress.c | 12 +- app/core/gimpprogress.h | 2 +- app/errors.c | 2 +- app/file/file-open.c | 2 + app/gui/Makefile.am | 2 + app/gui/gui-message.c | 221 ++++++++++++++++++++++++++++++ app/gui/gui-message.h | 29 ++++ app/gui/gui-vtable.c | 68 +-------- app/pdb/message_cmds.c | 11 +- app/plug-in/gimpplugin-progress.c | 27 ---- app/plug-in/gimpplugin-progress.h | 3 - app/plug-in/gimpplugin.c | 4 +- po/POTFILES.in | 1 + tools/pdbgen/pdb/message.pdb | 11 +- 18 files changed, 331 insertions(+), 129 deletions(-) create mode 100644 app/gui/gui-message.c create mode 100644 app/gui/gui-message.h diff --git a/ChangeLog b/ChangeLog index 2c49be0d44..f8dca2f810 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2006-07-19 Sven Neumann + + Make message dialogs transient for the progress window. Addresses + bug #347214. + + * app/core/gimp-gui.[ch]: added a progress parameter to + gimp_message(). Let gimp_message() deal with optionally + delegating the message to gimp_progress_message(). + + * app/errors.c: changed accordingly. + + * app/core/gimpprogress.[ch] (gimp_progress_message): return a + boolean indicating whether the message was handled. + + * app/gui/Makefile.am + * app/gui/gui-message.[ch] + * app/gui/gui-vtable.c: moved message handling to a new file. Only + use the global error dialog for messages without a progress. + Otherwise attach an error dialog to the progress and try to make + it transient to the progress window. + + * tools/pdbgen/pdb/message.pdb: + * app/plug-in/gimpplugin-progress.[ch]: don't delegate messages to + the progress interface, this is handled by gimp_message() now. + + * app/pdb/message_cmds.c: regenerated. + + * app/plug-in/gimpplugin.c + * app/actions/documents-commands.c: formatting. + 2006-07-18 Kevin Cozens * INSTALL: Document --enable-profile, --disable-python, and diff --git a/app/actions/documents-commands.c b/app/actions/documents-commands.c index 198a71190e..62d9a0853e 100644 --- a/app/actions/documents-commands.c +++ b/app/actions/documents-commands.c @@ -310,15 +310,14 @@ documents_open_image (GimpContext *context, uri = gimp_object_get_name (GIMP_OBJECT (imagefile)); image = file_open_with_display (context->gimp, context, NULL, - uri, &status, &error); + uri, &status, &error); if (! image && status != GIMP_PDB_CANCEL) { gchar *filename; filename = file_utils_uri_display_name (uri); - g_message (_("Opening '%s' failed:\n\n%s"), - filename, error->message); + g_message (_("Opening '%s' failed:\n\n%s"), filename, error->message); g_clear_error (&error); g_free (filename); diff --git a/app/core/gimp-gui.c b/app/core/gimp-gui.c index 8207ae3fbb..392d967824 100644 --- a/app/core/gimp-gui.c +++ b/app/core/gimp-gui.c @@ -139,24 +139,30 @@ gimp_unset_busy (Gimp *gimp) } void -gimp_message (Gimp *gimp, - const gchar *domain, - const gchar *message) +gimp_message (Gimp *gimp, + GimpProgress *progress, + const gchar *domain, + const gchar *message) { - gchar *message2 = gimp_any_to_utf8 (message, -1, - "Cannot convert message to utf8."); - g_return_if_fail (GIMP_IS_GIMP (gimp)); + g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); + g_return_if_fail (message != NULL); if (! domain) domain = GIMP_ACRONYM; - if (! gimp->console_messages && gimp->gui.message) - gimp->gui.message (gimp, domain, message2); + if (progress && gimp_progress_message (progress, gimp, domain, message)) + { + /* message has already been handled by GimpProgress */ + } + else if (gimp->gui.message && ! gimp->console_messages) + { + gimp->gui.message (gimp, progress, domain, message); + } else - g_printerr ("%s: %s\n\n", domain, message2); - - g_free (message2); + { + g_printerr ("%s: %s\n\n", domain, message); + } } void diff --git a/app/core/gimp-gui.h b/app/core/gimp-gui.h index 2d1ca9f1b5..cb1d006694 100644 --- a/app/core/gimp-gui.h +++ b/app/core/gimp-gui.h @@ -31,6 +31,7 @@ struct _GimpGui void (* unset_busy) (Gimp *gimp); void (* message) (Gimp *gimp, + GimpProgress *progress, const gchar *domain, const gchar *message); void (* help) (Gimp *gimp, @@ -104,6 +105,7 @@ void gimp_set_busy_until_idle (Gimp *gimp); void gimp_unset_busy (Gimp *gimp); void gimp_message (Gimp *gimp, + GimpProgress *progress, const gchar *domain, const gchar *message); void gimp_help (Gimp *gimp, diff --git a/app/core/gimpprogress.c b/app/core/gimpprogress.c index 5229b8caf4..40b5c8d64d 100644 --- a/app/core/gimpprogress.c +++ b/app/core/gimpprogress.c @@ -218,7 +218,7 @@ gimp_progress_get_window (GimpProgress *progress) return 0; } -void +gboolean gimp_progress_message (GimpProgress *progress, Gimp *gimp, const gchar *domain, @@ -231,9 +231,13 @@ gimp_progress_message (GimpProgress *progress, progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress); if (progress_iface->message) - progress_iface->message (progress, gimp, domain, message); - else - gimp_message (gimp, domain, message); + { + progress_iface->message (progress, gimp, domain, message); + + return TRUE; + } + + return FALSE; } void diff --git a/app/core/gimpprogress.h b/app/core/gimpprogress.h index 0b72c3cff5..a3c9f50fff 100644 --- a/app/core/gimpprogress.h +++ b/app/core/gimpprogress.h @@ -78,7 +78,7 @@ void gimp_progress_pulse (GimpProgress *progress); guint32 gimp_progress_get_window (GimpProgress *progress); -void gimp_progress_message (GimpProgress *progress, +gboolean gimp_progress_message (GimpProgress *progress, Gimp *gimp, const gchar *domain, const gchar *message); diff --git a/app/errors.c b/app/errors.c index 472e86c31c..7bd581efb3 100644 --- a/app/errors.c +++ b/app/errors.c @@ -91,7 +91,7 @@ gimp_message_log_func (const gchar *log_domain, if (gimp && GIMP_IS_GIMP (*gimp)) { - gimp_message (*gimp, NULL, message); + gimp_message (*gimp, NULL, NULL, message); return; } diff --git a/app/file/file-open.c b/app/file/file-open.c index af86f38689..021bd1166f 100644 --- a/app/file/file-open.c +++ b/app/file/file-open.c @@ -250,8 +250,10 @@ file_open_thumbnail (Gimp *gimp, *mime_type = file_proc->mime_type; +#ifdef GIMP_UNSTABLE g_printerr ("opened thumbnail at %d x %d\n", image->width, image->height); +#endif } } diff --git a/app/gui/Makefile.am b/app/gui/Makefile.am index 600a4fcaf0..cf026d95d5 100644 --- a/app/gui/Makefile.am +++ b/app/gui/Makefile.am @@ -19,6 +19,8 @@ libappgui_a_SOURCES = \ color-history.h \ gui.c \ gui.h \ + gui-message.c \ + gui-message.h \ gui-vtable.c \ gui-vtable.h \ gui-types.h \ diff --git a/app/gui/gui-message.c b/app/gui/gui-message.c new file mode 100644 index 0000000000..b7ef4aebe5 --- /dev/null +++ b/app/gui/gui-message.c @@ -0,0 +1,221 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (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 + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include + +#include "libgimpwidgets/gimpwidgets.h" + +#include "gui-types.h" + +#include "config/gimpguiconfig.h" + +#include "core/gimp.h" +#include "core/gimpprogress.h" + +#include "plug-in/gimpplugin.h" + +#include "widgets/gimpdialogfactory.h" +#include "widgets/gimpdockable.h" +#include "widgets/gimperrorconsole.h" +#include "widgets/gimperrordialog.h" + +#include "dialogs/dialogs.h" + +#include "gimp-intl.h" + + +static gboolean gui_message_error_console (const gchar *domain, + const gchar *message); +static gboolean gui_message_error_dialog (GimpProgress *progress, + const gchar *domain, + const gchar *message); +static void gui_message_console (const gchar *domain, + const gchar *message); + +static void gimp_window_set_transient_for (GtkWindow *window, + guint32 parent_ID); + + +void +gui_message (Gimp *gimp, + GimpProgress *progress, + const gchar *domain, + const gchar *message) +{ + switch (gimp->message_handler) + { + case GIMP_ERROR_CONSOLE: + if (gui_message_error_console (domain, message)) + return; + + gimp->message_handler = GIMP_MESSAGE_BOX; + /* fallthru */ + + case GIMP_MESSAGE_BOX: + if (gui_message_error_dialog (progress, domain, message)) + return; + + gimp->message_handler = GIMP_CONSOLE; + /* fallthru */ + + case GIMP_CONSOLE: + gui_message_console (domain, message); + break; + } +} + +static gboolean +gui_message_error_console (const gchar *domain, + const gchar *message) +{ + GtkWidget *dockable; + + dockable = gimp_dialog_factory_dialog_raise (global_dock_factory, + gdk_screen_get_default (), + "gimp-error-console", -1); + + if (dockable) + { + gimp_error_console_add (GIMP_ERROR_CONSOLE (GTK_BIN (dockable)->child), + GIMP_STOCK_WARNING, domain, message); + + return TRUE; + } + + return FALSE; +} + +static void +progress_error_dialog_unset (GimpProgress *progress) +{ + g_object_set_data (G_OBJECT (progress), "gimp-error-dialog", NULL); +} + +static GtkWidget * +progress_error_dialog (GimpProgress *progress) +{ + GtkWidget *dialog; + + g_return_val_if_fail (GIMP_IS_PROGRESS (progress), NULL); + + dialog = g_object_get_data (G_OBJECT (progress), "gimp-error-dialog"); + + if (! dialog) + { + dialog = gimp_error_dialog_new (_("GIMP Message")); + + g_object_set_data (G_OBJECT (progress), "gimp-error-dialog", dialog); + + g_signal_connect_object (dialog, "destroy", + G_CALLBACK (progress_error_dialog_unset), + progress, G_CONNECT_SWAPPED); + + if (GTK_IS_WIDGET (progress)) + { + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (progress)); + + if (GTK_IS_WINDOW (toplevel)) + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (toplevel)); + } + else + { + guint32 window = gimp_progress_get_window (progress); + + if (window) + gimp_window_set_transient_for (GTK_WINDOW (dialog), window); + } + } + + return dialog; +} + +static GtkWidget * +global_error_dialog (void) +{ + return gimp_dialog_factory_dialog_new (global_dialog_factory, + gdk_screen_get_default (), + "gimp-error-dialog", -1, + FALSE); +} + +static gboolean +gui_message_error_dialog (GimpProgress *progress, + const gchar *domain, + const gchar *message) +{ + GtkWidget *dialog; + + dialog = progress ? progress_error_dialog (progress) : global_error_dialog (); + + if (dialog) + { + gimp_error_dialog_add (GIMP_ERROR_DIALOG (dialog), + GIMP_STOCK_WARNING, domain, message); + gtk_window_present (GTK_WINDOW (dialog)); + + return TRUE; + } + + return FALSE; +} + +static void +gui_message_console (const gchar *domain, + const gchar *message) +{ + g_printerr ("%s: %s\n\n", domain, message); +} + + +/* utility functions, similar to what we have in libgimp/gimpui.c */ + +static void +gimp_window_transient_realized (GtkWidget *window, + GdkWindow *parent) +{ + if (GTK_WIDGET_REALIZED (window)) + gdk_window_set_transient_for (window->window, parent); +} + +static void +gimp_window_set_transient_for (GtkWindow *window, + guint32 parent_ID) +{ + GdkWindow *parent; + + parent = gdk_window_foreign_new_for_display (gdk_display_get_default (), + parent_ID); + + if (! parent) + return; + + if (GTK_WIDGET_REALIZED (window)) + gdk_window_set_transient_for (GTK_WIDGET (window)->window, parent); + + g_signal_connect_object (window, "realize", + G_CALLBACK (gimp_window_transient_realized), + parent, 0); + + g_object_unref (parent); +} + diff --git a/app/gui/gui-message.h b/app/gui/gui-message.h new file mode 100644 index 0000000000..dbd3e9cbf1 --- /dev/null +++ b/app/gui/gui-message.h @@ -0,0 +1,29 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (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 + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GUI_MESSAGE_H__ +#define __GUI_MESSAGE_H__ + + +void gui_message (Gimp *gimp, + GimpProgress *progress, + const gchar *domain, + const gchar *message); + + +#endif /* __GUI_VTABLE_H__ */ diff --git a/app/gui/gui-vtable.c b/app/gui/gui-vtable.c index b8b980caa4..099fd7cec1 100644 --- a/app/gui/gui-vtable.c +++ b/app/gui/gui-vtable.c @@ -45,8 +45,6 @@ #include "widgets/gimpbrushselect.h" #include "widgets/gimpdialogfactory.h" #include "widgets/gimpdocked.h" -#include "widgets/gimperrorconsole.h" -#include "widgets/gimperrordialog.h" #include "widgets/gimpfontselect.h" #include "widgets/gimpgradientselect.h" #include "widgets/gimphelp.h" @@ -66,8 +64,7 @@ #include "menus/menus.h" -#include "dialogs/dialogs.h" - +#include "gui-message.h" #include "themes.h" @@ -77,9 +74,6 @@ static void gui_threads_enter (Gimp *gimp); static void gui_threads_leave (Gimp *gimp); static void gui_set_busy (Gimp *gimp); static void gui_unset_busy (Gimp *gimp); -static void gui_message (Gimp *gimp, - const gchar *domain, - const gchar *message); static void gui_help (Gimp *gimp, const gchar *help_domain, const gchar *help_id); @@ -183,66 +177,6 @@ gui_unset_busy (Gimp *gimp) } static void -gui_message (Gimp *gimp, - const gchar *domain, - const gchar *message) -{ - switch (gimp->message_handler) - { - case GIMP_ERROR_CONSOLE: - { - GtkWidget *dockable; - - dockable = gimp_dialog_factory_dialog_raise (global_dock_factory, - gdk_screen_get_default (), - "gimp-error-console", -1); - - if (dockable) - { - GimpErrorConsole *console; - - console = GIMP_ERROR_CONSOLE (GTK_BIN (dockable)->child); - - gimp_error_console_add (console, - GIMP_STOCK_WARNING, domain, message); - - return; - } - - gimp->message_handler = GIMP_MESSAGE_BOX; - } - /* fallthru */ - - case GIMP_MESSAGE_BOX: - { - GtkWidget *dialog; - - dialog = gimp_dialog_factory_dialog_new (global_dialog_factory, - gdk_screen_get_default (), - "gimp-error-dialog", -1, - FALSE); - - if (dialog) - { - gimp_error_dialog_add (GIMP_ERROR_DIALOG (dialog), - GIMP_STOCK_WARNING, domain, message); - - gtk_window_present (GTK_WINDOW (dialog)); - - return; - } - - gimp->message_handler = GIMP_CONSOLE; - } - /* fallthru */ - - case GIMP_CONSOLE: - g_printerr ("%s: %s\n\n", domain, message); - break; - } -} - -void gui_help (Gimp *gimp, const gchar *help_domain, const gchar *help_id) diff --git a/app/pdb/message_cmds.c b/app/pdb/message_cmds.c index 39dd75d325..907a72e077 100644 --- a/app/pdb/message_cmds.c +++ b/app/pdb/message_cmds.c @@ -31,7 +31,6 @@ #include "core/gimp.h" #include "gimp-intl.h" -#include "plug-in/gimpplugin-progress.h" #include "plug-in/gimpplugin.h" #include "plug-in/gimppluginmanager.h" @@ -50,11 +49,13 @@ message_invoker (GimpProcedure *procedure, if (success) { + gchar *domain = NULL; + if (gimp->plug_in_manager->current_plug_in) - gimp_plug_in_progress_message (gimp->plug_in_manager->current_plug_in, - message); - else - gimp_message (gimp, NULL, message); + domain = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in); + gimp_message (gimp, progress, domain, message); + + g_free (domain); } return gimp_procedure_get_return_values (procedure, success); diff --git a/app/plug-in/gimpplugin-progress.c b/app/plug-in/gimpplugin-progress.c index 7e5ec38d4a..ab714d3472 100644 --- a/app/plug-in/gimpplugin-progress.c +++ b/app/plug-in/gimpplugin-progress.c @@ -273,33 +273,6 @@ gimp_plug_in_progress_cancel (GimpPlugIn *plug_in, return FALSE; } -void -gimp_plug_in_progress_message (GimpPlugIn *plug_in, - const gchar *message) -{ - GimpPlugInProcFrame *proc_frame; - gchar *domain; - - g_return_if_fail (GIMP_IS_PLUG_IN (plug_in)); - g_return_if_fail (message != NULL); - - proc_frame = gimp_plug_in_get_proc_frame (plug_in); - - domain = gimp_plug_in_get_undo_desc (plug_in); - - if (proc_frame->progress) - { - gimp_progress_message (proc_frame->progress, - plug_in->manager->gimp, domain, message); - } - else - { - gimp_message (plug_in->manager->gimp, domain, message); - } - - g_free (domain); -} - /* private functions */ diff --git a/app/plug-in/gimpplugin-progress.h b/app/plug-in/gimpplugin-progress.h index 25df47a5b5..81f4ad0993 100644 --- a/app/plug-in/gimpplugin-progress.h +++ b/app/plug-in/gimpplugin-progress.h @@ -40,8 +40,5 @@ gboolean gimp_plug_in_progress_uninstall (GimpPlugIn *plug_in, gboolean gimp_plug_in_progress_cancel (GimpPlugIn *plug_in, const gchar *progress_callback); -void gimp_plug_in_progress_message (GimpPlugIn *plug_in, - const gchar *message); - #endif /* __GIMP_PLUG_IN_PROGRESS_H__ */ diff --git a/app/plug-in/gimpplugin.c b/app/plug-in/gimpplugin.c index 1c5bd64924..ec4d8f89e0 100644 --- a/app/plug-in/gimpplugin.c +++ b/app/plug-in/gimpplugin.c @@ -921,8 +921,8 @@ gimp_plug_in_remove_temp_proc (GimpPlugIn *plug_in, g_return_if_fail (GIMP_IS_PLUG_IN (plug_in)); g_return_if_fail (GIMP_IS_TEMPORARY_PROCEDURE (proc)); - plug_in->temp_procedures = g_slist_remove (plug_in->temp_procedures, - proc); + plug_in->temp_procedures = g_slist_remove (plug_in->temp_procedures, proc); + gimp_plug_in_manager_remove_temp_proc (plug_in->manager, proc); g_object_unref (proc); } diff --git a/po/POTFILES.in b/po/POTFILES.in index b7dd257cf3..d1e88ee3c7 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -196,6 +196,7 @@ app/file/file-save.c app/file/file-utils.c app/gui/gui.c +app/gui/gui-message.c app/gui/session.c app/gui/splash.c app/gui/themes.c diff --git a/tools/pdbgen/pdb/message.pdb b/tools/pdbgen/pdb/message.pdb index 0b5d62b9c8..1002171ed6 100644 --- a/tools/pdbgen/pdb/message.pdb +++ b/tools/pdbgen/pdb/message.pdb @@ -35,11 +35,13 @@ HELP %invoke = ( code => <<'CODE' { + gchar *domain = NULL; + if (gimp->plug_in_manager->current_plug_in) - gimp_plug_in_progress_message (gimp->plug_in_manager->current_plug_in, - message); - else - gimp_message (gimp, NULL, message); + domain = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in); + gimp_message (gimp, progress, domain, message); + + g_free (domain); } CODE ); @@ -99,7 +101,6 @@ CODE @headers = qw( "core/gimp.h" "plug-in/gimpplugin.h" - "plug-in/gimpplugin-progress.h" "plug-in/gimppluginmanager.h" "gimp-intl.h");