Files
gimp/app/gui/gui.c
Michael Natterer 05e15eb1cc Cleanup weekend...
2001-10-29  Michael Natterer  <mitch@gimp.org>

	Cleanup weekend...

	* app/app_procs.c: pass "no_interface" to gimp_new().

	* app/core/gimp.[ch]: added "gboolean no_interface" and the
	load_procs and save_procs GSLists.

	* app/core/gimptoolinfo.[ch]: added a "Gimp" pointer to the
	GimpToolInfo object so more functions find their context without
	accessing the global "the_gimp" variable.

	* app/display/display-types.h: removed the GDisplay -> GimpDisplay
	typedef.

	* app/display/gimpdisplay.c: look at gimp->no_interface, don't
	include "appenv.h".

	* app/file/file-open.[ch]
	* app/file/file-save.[ch]: don't use "the_gimp" any more. Instead,
	pass around lots of "Gimp" pointers. Removed the global load_procs
	and save_procs variables here. Use access() to find out whether a
	file is readable/writable, removed the manual voodoo and it's
	Win32 wrappers. Added an optional (can be NULL) "PlunInProcDef"
	parameter to file_save(), removed file_save_with_proc().

	* app/gui/menus.c: Use the unused "gpointer data" parameter of the
	GtkItemFactory callbacks to pass a "Gimp" pointer to all of them.
	This reduces the usage of the global "the_gimp" hack to zero
	in app/gui/... yeah.

	* app/gui/channels-commands.c
	* app/gui/edit-commands.c
	* app/gui/file-commands.c
	* app/gui/image-commands.c
	* app/gui/layers-commands.c
	* app/gui/palettes-commands.c
	* app/gui/select-commands.c
	* app/gui/test-commands.c
	* app/gui/tools-commands.c
	* app/gui/view-commands.c: use the passed "Gimp" pointer.

	* app/gui/color-area.[ch]
	* app/gui/convert-dialog.c
	* app/gui/dialogs-constructors.c
	* app/gui/file-new-dialog.[ch]
	* app/gui/file-open-dialog.[ch]
	* app/gui/file-save-dialog.[ch]
	* app/gui/gui.c
	* app/gui/info-window.[ch]
	* app/gui/module-browser.[ch]
	* app/gui/palette-editor.c
	* app/gui/palette-import-dialog.[ch]
	* app/gui/paths-dialog.c
	* app/gui/preferences-dialog.[ch]
	* app/gui/resize-dialog.[ch]
	* app/gui/tool-options-dialog.[ch]
	* app/gui/toolbox.c: pass around lots more "Gimp" and
	"GimpContext" pointers and don't use "the_gimp" any more.

	* app/tools/gimptool.h: added a pointer to the corresponding
	GimpToolInfo object (which in turn has a pointer to a Gimp).

	* app/tools/tool_manager.[ch]: set the pointer after creating the
	tool object. Removed tool_manager_get_info_by_tool() as there is a
	tool->tool_info pointer now.

	* app/tools/gimpbezierselecttool.c
	* app/tools/gimpblendtool.c
	* app/tools/gimpbrightnesscontrasttool.c
	* app/tools/gimpclonetool.c
	* app/tools/gimpcolorbalancetool.c
	* app/tools/gimpcolorpickertool.c
	* app/tools/gimpconvolvetool.c
	* app/tools/gimpcroptool.c
	* app/tools/gimpcurvestool.c
	* app/tools/gimpdodgeburntool.c
	* app/tools/gimpdrawtool.c
	* app/tools/gimpeditselectiontool.c
	* app/tools/gimpellipseselecttool.c
	* app/tools/gimperasertool.c
	* app/tools/gimpfliptool.c
	* app/tools/gimphistogramtool.c
	* app/tools/gimphuesaturationtool.c
	* app/tools/gimpinktool.c
	* app/tools/gimplevelstool.c
	* app/tools/gimpmagnifytool.c
	* app/tools/gimpmeasuretool.c
	* app/tools/gimpmovetool.c
	* app/tools/gimppainttool.c
	* app/tools/gimppathtool.c
	* app/tools/gimpperspectivetool.c
	* app/tools/gimpposterizetool.c
	* app/tools/gimprectselecttool.c
	* app/tools/gimprotatetool.c
	* app/tools/gimpscaletool.c
	* app/tools/gimpsheartool.c
	* app/tools/gimptexttool.c
	* app/tools/gimpthresholdtool.c
	* app/tools/path_tool.c
	* app/tools/xinput_airbrush.c: s/GDisplay/GimpDisplay/g.
	Use tool->tool_info and tool_info->gimp in some places to get
	rid of using "the_gimp".

	Removing the remaining ones involves changing the tool options
	system and is scheduled next...

	* app/widgets/gimpdnd.c
	* app/widgets/gimpdocumentview.c: pass a "Gimp" pointer to all
	file_open_*() functions.

	* app/gdisplay_color.[ch]
	* app/gdisplay_color_ui.[ch]
	* app/image_map.[ch]
	* app/nav_window.[ch]
	* app/path.c
	* app/path_bezier.c
	* app/path_transform.h
	* app/qmask.[ch]: s/GDisplay/GimpDisplay/g

	* tools/pdbgen/pdb/fileops.pdb: load_procs and save_procs are
	members of the "Gimp" object now.

	* tools/pdbgen/pdb/plug_in.pdb: use gimp->no_interface, don't
	include "appenv.h".

	* app/pdb/fileops_cmds.c
	* app/pdb/plug_in_cmds.c: regenerated.
2001-10-29 11:47:11 +00:00

615 lines
15 KiB
C

/* 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 <stdio.h>
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "gui-types.h"
#include "core/gimp.h"
#include "core/gimpcontainer.h"
#include "core/gimpcontext.h"
#include "core/gimpdatafiles.h"
#include "core/gimpimage.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplay-foreach.h"
#include "display/gimpdisplay-ops.h"
#include "display/gimpdisplay-render.h"
#include "display/gximage.h"
#include "widgets/gimpdialogfactory.h"
#include "brush-select.h"
#include "color-select.h"
#include "devices.h"
#include "dialogs.h"
#include "file-open-dialog.h"
#include "file-save-dialog.h"
#include "gradient-select.h"
#include "gui.h"
#include "menus.h"
#include "palette-select.h"
#include "palette-import-dialog.h"
#include "pattern-select.h"
#include "session.h"
#include "tool-options-dialog.h"
#include "toolbox.h"
#include "gimprc.h"
#include "libgimp/gimpintl.h"
#include "pixmaps/wilber2.xpm"
/* local function prototypes */
static void gui_set_busy (Gimp *gimp);
static void gui_unset_busy (Gimp *gimp);
static void gui_display_new (GimpImage *gimage);
static gint gui_rotate_the_shield_harmonics (GtkWidget *widget,
GdkEvent *eevent,
gpointer data);
static void gui_really_quit_callback (GtkWidget *button,
gboolean quit,
gpointer data);
static void gui_display_changed (GimpContext *context,
GimpDisplay *display,
gpointer data);
static void gui_image_disconnect (GimpImage *gimage,
gpointer data);
static void gui_image_mode_changed (GimpImage *gimage,
gpointer data);
static void gui_image_colormap_changed (GimpImage *gimage,
gint ncol,
gpointer data);
static void gui_image_name_changed (GimpImage *gimage,
gpointer data);
static void gui_image_size_changed (GimpImage *gimage,
gpointer data);
static void gui_image_alpha_changed (GimpImage *gimage,
gpointer data);
static void gui_image_update (GimpImage *gimage,
gint x,
gint y,
gint w,
gint h,
gpointer data);
static void gui_image_selection_control (GimpImage *gimage,
GimpSelectionControl control,
gpointer data);
/* private variables */
static GQuark image_disconnect_handler_id = 0;
static GQuark image_mode_changed_handler_id = 0;
static GQuark image_colormap_changed_handler_id = 0;
static GQuark image_name_changed_handler_id = 0;
static GQuark image_size_changed_handler_id = 0;
static GQuark image_alpha_changed_handler_id = 0;
static GQuark image_update_handler_id = 0;
static GQuark image_selection_control_handler_id = 0;
static GHashTable *themes_hash = NULL;
/* public functions */
static void
gui_themes_dir_foreach_func (const gchar *filename,
gpointer loader_data)
{
Gimp *gimp;
gchar *basename;
gimp = (Gimp *) loader_data;
basename = g_path_get_basename (filename);
if (gimp->be_verbose)
g_print (_("adding theme \"%s\" (%s)\n"), basename, filename);
g_hash_table_insert (themes_hash,
basename,
g_strdup (filename));
}
void
gui_libs_init (Gimp *gimp,
gint *argc,
gchar ***argv)
{
gchar *theme_dir;
gchar *gtkrc;
g_return_if_fail (GIMP_IS_GIMP (gimp));
gimp_stock_init ();
themes_hash = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_free);
if (gimprc.theme_path)
{
gimp_datafiles_read_directories (gimprc.theme_path,
TYPE_DIRECTORY,
gui_themes_dir_foreach_func,
gimp);
}
if (gimprc.theme)
theme_dir = g_hash_table_lookup (themes_hash, gimprc.theme);
else
theme_dir = g_hash_table_lookup (themes_hash, "Default");
if (theme_dir)
{
gtkrc = g_build_filename (theme_dir, "gtkrc", NULL);
}
else
{
/* get the hardcoded default theme gtkrc */
gtkrc = g_strdup (gimp_gtkrc ());
}
if (gimp->be_verbose)
g_print (_("parsing \"%s\"\n"), gtkrc);
gtk_rc_parse (gtkrc);
g_free (gtkrc);
/* parse the user gtkrc */
gtkrc = gimp_personal_rc_file ("gtkrc");
if (gimp->be_verbose)
g_print (_("parsing \"%s\"\n"), gtkrc);
gtk_rc_parse (gtkrc);
g_free (gtkrc);
}
void
gui_init (Gimp *gimp)
{
g_return_if_fail (GIMP_IS_GIMP (gimp));
gimp->create_display_func = gui_display_new;
gimp->gui_set_busy_func = gui_set_busy;
gimp->gui_unset_busy_func = gui_unset_busy;
image_disconnect_handler_id =
gimp_container_add_handler (gimp->images, "disconnect",
G_CALLBACK (gui_image_disconnect),
gimp);
image_mode_changed_handler_id =
gimp_container_add_handler (gimp->images, "mode_changed",
G_CALLBACK (gui_image_mode_changed),
gimp);
image_colormap_changed_handler_id =
gimp_container_add_handler (gimp->images, "colormap_changed",
G_CALLBACK (gui_image_colormap_changed),
gimp);
image_name_changed_handler_id =
gimp_container_add_handler (gimp->images, "name_changed",
G_CALLBACK (gui_image_name_changed),
gimp);
image_size_changed_handler_id =
gimp_container_add_handler (gimp->images, "size_changed",
G_CALLBACK (gui_image_size_changed),
gimp);
image_alpha_changed_handler_id =
gimp_container_add_handler (gimp->images, "alpha_changed",
G_CALLBACK (gui_image_alpha_changed),
gimp);
image_update_handler_id =
gimp_container_add_handler (gimp->images, "update",
G_CALLBACK (gui_image_update),
gimp);
image_selection_control_handler_id =
gimp_container_add_handler (gimp->images, "selection_control",
G_CALLBACK (gui_image_selection_control),
gimp);
g_signal_connect (G_OBJECT (gimp_get_user_context (gimp)), "display_changed",
G_CALLBACK (gui_display_changed),
gimp);
/* make sure the monitor resolution is valid */
if (gimprc.monitor_xres < GIMP_MIN_RESOLUTION ||
gimprc.monitor_yres < GIMP_MIN_RESOLUTION)
{
gdisplay_xserver_resolution (&gimprc.monitor_xres, &gimprc.monitor_yres);
gimprc.using_xserver_resolution = TRUE;
}
/* tooltips */
gimp_help_init ();
if (! gimprc.show_tool_tips)
gimp_help_disable_tooltips ();
menus_init (gimp);
gximage_init ();
render_setup (gimprc.transparency_type, gimprc.transparency_size);
dialogs_init (gimp);
devices_init ();
session_init (gimp);
}
void
gui_restore (Gimp *gimp,
gboolean restore_session)
{
g_return_if_fail (GIMP_IS_GIMP (gimp));
file_open_dialog_menu_init (gimp);
file_save_dialog_menu_init (gimp);
menus_restore (gimp);
gimp_dialog_factory_dialog_new (global_dialog_factory, "gimp:toolbox");
color_select_init ();
devices_restore ();
if (gimprc.always_restore_session || restore_session)
session_restore (gimp);
}
void
gui_post_init (Gimp *gimp)
{
g_return_if_fail (GIMP_IS_GIMP (gimp));
if (gimprc.show_tips)
{
gimp_dialog_factory_dialog_new (global_dialog_factory, "gimp:tips-dialog");
}
}
void
gui_shutdown (Gimp *gimp)
{
g_return_if_fail (GIMP_IS_GIMP (gimp));
session_save (gimp);
device_status_free ();
brush_dialog_free ();
pattern_dialog_free ();
palette_dialog_free ();
gradient_dialog_free ();
gdisplays_delete ();
}
void
gui_exit (Gimp *gimp)
{
g_return_if_fail (GIMP_IS_GIMP (gimp));
menus_exit (gimp);
gximage_free ();
render_free ();
dialogs_exit (gimp);
/* handle this in the dialog factory: */
tool_options_dialog_free (gimp);
toolbox_free (gimp);
gimp_help_free ();
gimp_container_remove_handler (gimp->images, image_disconnect_handler_id);
gimp_container_remove_handler (gimp->images, image_mode_changed_handler_id);
gimp_container_remove_handler (gimp->images, image_colormap_changed_handler_id);
gimp_container_remove_handler (gimp->images, image_name_changed_handler_id);
gimp_container_remove_handler (gimp->images, image_size_changed_handler_id);
gimp_container_remove_handler (gimp->images, image_alpha_changed_handler_id);
gimp_container_remove_handler (gimp->images, image_update_handler_id);
gimp_container_remove_handler (gimp->images, image_selection_control_handler_id);
image_disconnect_handler_id = 0;
image_mode_changed_handler_id = 0;
image_colormap_changed_handler_id = 0;
image_name_changed_handler_id = 0;
image_size_changed_handler_id = 0;
image_alpha_changed_handler_id = 0;
image_update_handler_id = 0;
image_selection_control_handler_id = 0;
if (themes_hash)
{
g_hash_table_destroy (themes_hash);
themes_hash = NULL;
}
}
void
gui_really_quit_dialog (GCallback quit_func)
{
GtkWidget *dialog;
menus_set_sensitive ("<Toolbox>/File/Quit", FALSE);
menus_set_sensitive ("<Image>/File/Quit", FALSE);
dialog = gimp_query_boolean_box (_("Really Quit?"),
gimp_standard_help_func,
"dialogs/really_quit.html",
TRUE,
_("Some files unsaved.\n\nQuit the GIMP?"),
GTK_STOCK_QUIT, GTK_STOCK_CANCEL,
NULL, NULL,
gui_really_quit_callback,
quit_func);
gtk_widget_show (dialog);
}
/* private functions */
gboolean double_speed = FALSE;
static void
gui_display_new (GimpImage *gimage)
{
GimpDisplay *gdisp;
gdisp = gdisplay_new (gimage, 0x0101);
gimp_context_set_display (gimp_get_user_context (gimage->gimp), gdisp);
if (double_speed)
g_signal_connect_after (G_OBJECT (gdisp->canvas), "expose_event",
G_CALLBACK (gui_rotate_the_shield_harmonics),
NULL);
}
static void
gui_set_busy (Gimp *gimp)
{
gdisplays_set_busy ();
gimp_dialog_factories_idle ();
}
static void
gui_unset_busy (Gimp *gimp)
{
gdisplays_unset_busy ();
gimp_dialog_factories_unidle ();
}
static gint
gui_rotate_the_shield_harmonics (GtkWidget *widget,
GdkEvent *eevent,
gpointer data)
{
GdkPixmap *pixmap = NULL;
GdkBitmap *mask = NULL;
gint width = 0;
gint height = 0;
g_signal_handlers_disconnect_by_func (G_OBJECT (widget),
gui_rotate_the_shield_harmonics,
data);
pixmap = gdk_pixmap_create_from_xpm_d (widget->window,
&mask,
NULL,
wilber2_xpm);
gdk_drawable_get_size (pixmap, &width, &height);
if (widget->allocation.width >= width &&
widget->allocation.height >= height)
{
gint x, y;
x = (widget->allocation.width - width) / 2;
y = (widget->allocation.height - height) / 2;
gdk_gc_set_clip_mask (widget->style->black_gc, mask);
gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
gdk_draw_drawable (widget->window,
widget->style->black_gc,
pixmap, 0, 0,
x, y,
width, height);
gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
}
gdk_drawable_unref (pixmap);
gdk_drawable_unref (mask);
return FALSE;
}
static void
gui_really_quit_callback (GtkWidget *button,
gboolean quit,
gpointer data)
{
GCallback quit_func;
quit_func = G_CALLBACK (data);
if (quit)
{
(* quit_func) ();
}
else
{
menus_set_sensitive ("<Toolbox>/File/Quit", TRUE);
menus_set_sensitive ("<Image>/File/Quit", TRUE);
}
}
/* FIXME: this junk should mostly go to the display subsystem */
static void
gui_display_changed (GimpContext *context,
GimpDisplay *display,
gpointer data)
{
Gimp *gimp;
gimp = (Gimp *) data;
gdisplay_set_menu_sensitivity (display);
}
static void
gui_image_disconnect (GimpImage *gimage,
gpointer data)
{
Gimp *gimp;
gimp = (Gimp *) data;
/* check if this is the last image */
if (gimp_container_num_children (gimp->images) == 1)
{
gimp_dialog_factory_dialog_raise (global_dialog_factory, "gimp:toolbox");
}
}
static void
gui_image_mode_changed (GimpImage *gimage,
gpointer data)
{
Gimp *gimp;
gimp = (Gimp *) data;
gimp_image_invalidate_layer_previews (gimage);
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gimage));
gdisplays_update_title (gimage);
gdisplays_update_full (gimage);
}
static void
gui_image_colormap_changed (GimpImage *gimage,
gint ncol,
gpointer data)
{
Gimp *gimp;
gimp = (Gimp *) data;
if (gimp_image_base_type (gimage) == INDEXED)
gdisplays_update_full (gimage);
}
static void
gui_image_name_changed (GimpImage *gimage,
gpointer data)
{
Gimp *gimp;
gimp = (Gimp *) data;
gdisplays_update_title (gimage);
palette_import_image_renamed (gimage);
}
static void
gui_image_size_changed (GimpImage *gimage,
gpointer data)
{
Gimp *gimp;
gimp = (Gimp *) data;
/* shrink wrap and update all views */
gdisplays_resize_cursor_label (gimage);
gdisplays_update_full (gimage);
gdisplays_shrink_wrap (gimage);
}
static void
gui_image_alpha_changed (GimpImage *gimage,
gpointer data)
{
Gimp *gimp;
gimp = (Gimp *) data;
gdisplays_update_title (gimage);
}
static void
gui_image_update (GimpImage *gimage,
gint x,
gint y,
gint w,
gint h,
gpointer data)
{
Gimp *gimp;
gimp = (Gimp *) data;
gdisplays_update_area (gimage, x, y, w, h);
}
static void
gui_image_selection_control (GimpImage *gimage,
GimpSelectionControl control,
gpointer data)
{
Gimp *gimp;
gimp = (Gimp *) data;
gdisplays_selection_visibility (gimage, control);
}