Commit 25b81b15 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer
Browse files

Fixed lots of QuickMask brokenness by letting the image adjust its

2004-02-14  Michael Natterer  <mitch@gimp.org>

	Fixed lots of QuickMask brokenness by letting the image adjust
	its qmask_state automatically:

	* app/core/gimpimage-qmask.h: #define GIMP_IMAGE_QMASK_NAME "Qmask".
	Use the define in all files below.

	* app/core/gimpimage.[ch]: split gimp_image_drawable_add,_remove()
	into separate handlers for layers and channels. Added a
	"name_changed" handler for all channels. In the channel "add",
	"remove" and "name_changed" handlers, check if it was a channel
	named "Qmask" that was added, removed or renamed and call
	gimp_image_set_qmask_state() accordingly.

	* app/core/core-enums.[ch]
	* app/core/gimpimage-undo-push.[ch]
	* app/core/gimpundo.c: removed all Qmask undo code because the image
	does the right thing without undo interaction now.

	* app/core/gimpimage-qmask.c (gimp_image_set_qmask_state): set
	gimage->qmask_state early so we can return early when called
	recursively. Removed calls to gimp_image_undo_push_image_qmask().
	Returned "removed" callback (it was utterly broken the way it was
	implemented).

	* app/display/gimpdisplayshell-callbacks.c
	(gimp_display_shell_qmask_toggled): check if the image's
	qmask state needs to be changed before changing it.

	* app/xcf/xcf-load.c (xcf_load_channel): removed code which
	recognized the qmask. GimpImage does this automatically now.

	* app/gui/qmask-commands.c: cleanup.

	* app/widgets/gimpimagedock.c (gimp_image_dock_constructor):
	destroy the "/Select/By Color" and "/Select/Toggle QuickMask" menu
	items.

	* app/widgets/image-menu.c (image_menu_update): changed accordingly.
parent 8672dbf3
2004-02-14 Michael Natterer <mitch@gimp.org>
Fixed lots of QuickMask brokenness by letting the image adjust
its qmask_state automatically:
* app/core/gimpimage-qmask.h: #define GIMP_IMAGE_QMASK_NAME "Qmask".
Use the define in all files below.
* app/core/gimpimage.[ch]: split gimp_image_drawable_add,_remove()
into separate handlers for layers and channels. Added a
"name_changed" handler for all channels. In the channel "add",
"remove" and "name_changed" handlers, check if it was a channel
named "Qmask" that was added, removed or renamed and call
gimp_image_set_qmask_state() accordingly.
* app/core/core-enums.[ch]
* app/core/gimpimage-undo-push.[ch]
* app/core/gimpundo.c: removed all Qmask undo code because the image
does the right thing without undo interaction now.
* app/core/gimpimage-qmask.c (gimp_image_set_qmask_state): set
gimage->qmask_state early so we can return early when called
recursively. Removed calls to gimp_image_undo_push_image_qmask().
Returned "removed" callback (it was utterly broken the way it was
implemented).
* app/display/gimpdisplayshell-callbacks.c
(gimp_display_shell_qmask_toggled): check if the image's
qmask state needs to be changed before changing it.
* app/xcf/xcf-load.c (xcf_load_channel): removed code which
recognized the qmask. GimpImage does this automatically now.
* app/gui/qmask-commands.c: cleanup.
* app/widgets/gimpimagedock.c (gimp_image_dock_constructor):
destroy the "/Select/By Color" and "/Select/Toggle QuickMask" menu
items.
* app/widgets/image-menu.c (image_menu_update): changed accordingly.
2004-02-13 Manish Singh <yosh@gimp.org>
 
* plug-ins/common/psd.c (load_image): Initialize dest to NULL,
......@@ -73,11 +73,10 @@ qmask_toggle_cmd_callback (GtkWidget *widget,
gpointer data,
guint action)
{
GimpDisplayShell *shell;
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data);
if (GTK_CHECK_MENU_ITEM (widget)->active != shell->gdisp->gimage->qmask_state)
if (GTK_CHECK_MENU_ITEM (widget)->active !=
gimp_image_get_qmask_state (shell->gdisp->gimage))
{
gimp_image_set_qmask_state (shell->gdisp->gimage,
GTK_CHECK_MENU_ITEM (widget)->active);
......@@ -91,9 +90,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
gpointer data,
guint action)
{
GimpDisplayShell *shell;
shell = GIMP_DISPLAY_SHELL (data);
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
if (GTK_CHECK_MENU_ITEM (widget)->active)
{
......@@ -101,7 +98,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
{
gimp_image_qmask_invert (shell->gdisp->gimage);
if (shell->gdisp->gimage->qmask_state)
if (gimp_image_get_qmask_state (shell->gdisp->gimage))
gimp_image_flush (shell->gdisp->gimage);
}
}
......@@ -112,9 +109,7 @@ qmask_configure_cmd_callback (GtkWidget *widget,
gpointer data,
guint action)
{
GimpDisplayShell *shell;
shell = GIMP_DISPLAY_SHELL (data);
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
qmask_channel_query (shell);
}
......@@ -221,7 +216,8 @@ qmask_query_response (GtkWidget *widget,
GimpChannel *channel;
GimpRGB color;
channel = gimp_image_get_channel_by_name (options->gimage, "Qmask");
channel = gimp_image_get_channel_by_name (options->gimage,
GIMP_IMAGE_QMASK_NAME);
if (options->gimage && channel)
{
......@@ -247,7 +243,7 @@ static void
qmask_query_scale_update (GtkAdjustment *adjustment,
gpointer data)
{
GimpRGB color;
GimpRGB color;
gimp_color_button_get_color (GIMP_COLOR_BUTTON (data), &color);
gimp_rgb_set_alpha (&color, adjustment->value / 100.0);
......
......@@ -73,11 +73,10 @@ qmask_toggle_cmd_callback (GtkWidget *widget,
gpointer data,
guint action)
{
GimpDisplayShell *shell;
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data);
if (GTK_CHECK_MENU_ITEM (widget)->active != shell->gdisp->gimage->qmask_state)
if (GTK_CHECK_MENU_ITEM (widget)->active !=
gimp_image_get_qmask_state (shell->gdisp->gimage))
{
gimp_image_set_qmask_state (shell->gdisp->gimage,
GTK_CHECK_MENU_ITEM (widget)->active);
......@@ -91,9 +90,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
gpointer data,
guint action)
{
GimpDisplayShell *shell;
shell = GIMP_DISPLAY_SHELL (data);
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
if (GTK_CHECK_MENU_ITEM (widget)->active)
{
......@@ -101,7 +98,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
{
gimp_image_qmask_invert (shell->gdisp->gimage);
if (shell->gdisp->gimage->qmask_state)
if (gimp_image_get_qmask_state (shell->gdisp->gimage))
gimp_image_flush (shell->gdisp->gimage);
}
}
......@@ -112,9 +109,7 @@ qmask_configure_cmd_callback (GtkWidget *widget,
gpointer data,
guint action)
{
GimpDisplayShell *shell;
shell = GIMP_DISPLAY_SHELL (data);
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
qmask_channel_query (shell);
}
......@@ -221,7 +216,8 @@ qmask_query_response (GtkWidget *widget,
GimpChannel *channel;
GimpRGB color;
channel = gimp_image_get_channel_by_name (options->gimage, "Qmask");
channel = gimp_image_get_channel_by_name (options->gimage,
GIMP_IMAGE_QMASK_NAME);
if (options->gimage && channel)
{
......@@ -247,7 +243,7 @@ static void
qmask_query_scale_update (GtkAdjustment *adjustment,
gpointer data)
{
GimpRGB color;
GimpRGB color;
gimp_color_button_get_color (GIMP_COLOR_BUTTON (data), &color);
gimp_rgb_set_alpha (&color, adjustment->value / 100.0);
......
......@@ -617,7 +617,6 @@ static const GEnumValue gimp_undo_type_enum_values[] =
{ GIMP_UNDO_IMAGE_TYPE, N_("Image Type"), "image-type" },
{ GIMP_UNDO_IMAGE_SIZE, N_("Image Size"), "image-size" },
{ GIMP_UNDO_IMAGE_RESOLUTION, N_("Resolution Change"), "image-resolution" },
{ GIMP_UNDO_IMAGE_QMASK, N_("QuickMask"), "image-qmask" },
{ GIMP_UNDO_IMAGE_GRID, N_("Grid"), "image-grid" },
{ GIMP_UNDO_IMAGE_GUIDE, N_("Guide"), "image-guide" },
{ GIMP_UNDO_IMAGE_COLORMAP, N_("Change Indexed Palette"), "image-colormap" },
......
......@@ -452,7 +452,6 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_IMAGE_TYPE, /*< desc="Image Type" >*/
GIMP_UNDO_IMAGE_SIZE, /*< desc="Image Size" >*/
GIMP_UNDO_IMAGE_RESOLUTION, /*< desc="Resolution Change" >*/
GIMP_UNDO_IMAGE_QMASK, /*< desc="QuickMask" >*/
GIMP_UNDO_IMAGE_GRID, /*< desc="Grid" >*/
GIMP_UNDO_IMAGE_GUIDE, /*< desc="Guide" >*/
GIMP_UNDO_IMAGE_COLORMAP, /*< desc="Change Indexed Palette" >*/
......
......@@ -18,8 +18,6 @@
#include "config.h"
#include <stdlib.h>
#include <glib-object.h>
#include "libgimpcolor/gimpcolor.h"
......@@ -28,7 +26,6 @@
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpcontext.h"
#include "gimpimage.h"
#include "gimpimage-qmask.h"
#include "gimpimage-undo.h"
......@@ -39,12 +36,6 @@
#include "gimp-intl.h"
/* local function prototypes */
static void gimp_image_qmask_removed_callback (GObject *qmask,
GimpImage *gimage);
/* public functions */
void
......@@ -53,22 +44,22 @@ gimp_image_set_qmask_state (GimpImage *gimage,
{
GimpChannel *selection;
GimpChannel *mask;
GimpRGB color;
g_return_if_fail (GIMP_IS_IMAGE (gimage));
if (qmask_state == gimage->qmask_state)
return;
/* set image->qmask_state early so we can return early when
* being called recursively
*/
gimage->qmask_state = qmask_state ? TRUE : FALSE;
selection = gimp_image_get_mask (gimage);
mask = gimp_image_get_channel_by_name (gimage, GIMP_IMAGE_QMASK_NAME);
if (qmask_state)
{
/* Set the defaults */
color = gimage->qmask_color;
mask = gimp_image_get_channel_by_name (gimage, "Qmask");
if (! mask)
{
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK,
......@@ -78,22 +69,19 @@ gimp_image_set_qmask_state (GimpImage *gimage,
{
/* if no selection */
GimpLayer *layer;
GimpLayer *floating_sel = gimp_image_floating_sel (gimage);
if ((layer = gimp_image_floating_sel (gimage)))
{
floating_sel_to_layer (layer);
}
if (floating_sel)
floating_sel_to_layer (floating_sel);
mask = gimp_channel_new (gimage,
gimage->width,
gimage->height,
"Qmask",
&color);
GIMP_IMAGE_QMASK_NAME,
&gimage->qmask_color);
gimp_drawable_fill_by_type (GIMP_DRAWABLE (mask),
gimp_get_current_context (gimage->gimp),
GIMP_TRANSPARENT_FILL);
/* Clear the mask */
gimp_channel_clear (mask, NULL, FALSE);
}
else
{
......@@ -106,40 +94,25 @@ gimp_image_set_qmask_state (GimpImage *gimage,
/* Clear the selection */
gimp_channel_clear (selection, NULL, TRUE);
gimp_channel_set_color (mask, &color, FALSE);
gimp_item_rename (GIMP_ITEM (mask), "Qmask");
gimp_channel_set_color (mask, &gimage->qmask_color, FALSE);
gimp_item_rename (GIMP_ITEM (mask), GIMP_IMAGE_QMASK_NAME);
}
gimp_image_add_channel (gimage, mask, 0);
if (gimage->qmask_inverted)
gimp_channel_invert (mask, TRUE);
gimp_channel_invert (mask, FALSE);
gimp_image_undo_push_image_qmask (gimage, NULL);
gimp_image_add_channel (gimage, mask, 0);
gimp_image_undo_group_end (gimage);
/* connect to the removed signal, so the buttons get updated */
g_signal_connect (mask, "removed",
G_CALLBACK (gimp_image_qmask_removed_callback),
gimage);
}
}
else
{
mask = gimp_image_get_channel_by_name (gimage, "Qmask");
if (mask)
{
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK,
_("Disable QuickMask"));
/* push the undo here since removing the mask will
* call the qmask_removed_callback() which will set
* the qmask_state to FALSE
*/
gimp_image_undo_push_image_qmask (gimage, NULL);
if (gimage->qmask_inverted)
gimp_channel_invert (mask, TRUE);
......@@ -150,8 +123,6 @@ gimp_image_set_qmask_state (GimpImage *gimage,
}
}
gimage->qmask_state = qmask_state ? TRUE : FALSE;
gimp_image_qmask_changed (gimage);
}
......@@ -172,7 +143,7 @@ gimp_image_qmask_invert (GimpImage *gimage)
{
GimpChannel *qmask;
qmask = gimp_image_get_channel_by_name (gimage, "Qmask");
qmask = gimp_image_get_channel_by_name (gimage, GIMP_IMAGE_QMASK_NAME);
if (qmask)
{
......@@ -187,13 +158,3 @@ gimp_image_qmask_invert (GimpImage *gimage)
gimage->qmask_inverted = ! gimage->qmask_inverted;
}
/* private functions */
static void
gimp_image_qmask_removed_callback (GObject *qmask,
GimpImage *gimage)
{
gimp_image_set_qmask_state (gimage, FALSE);
}
......@@ -20,6 +20,9 @@
#define __GIMP_IMAGE_QMASK_H__
#define GIMP_IMAGE_QMASK_NAME "Qmask"
void gimp_image_set_qmask_state (GimpImage *gimage,
gboolean qmask_state);
gboolean gimp_image_get_qmask_state (const GimpImage *gimage);
......
......@@ -18,8 +18,6 @@
#include "config.h"
#include <stdlib.h>
#include <glib-object.h>
#include "libgimpcolor/gimpcolor.h"
......@@ -28,7 +26,6 @@
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpcontext.h"
#include "gimpimage.h"
#include "gimpimage-qmask.h"
#include "gimpimage-undo.h"
......@@ -39,12 +36,6 @@
#include "gimp-intl.h"
/* local function prototypes */
static void gimp_image_qmask_removed_callback (GObject *qmask,
GimpImage *gimage);
/* public functions */
void
......@@ -53,22 +44,22 @@ gimp_image_set_qmask_state (GimpImage *gimage,
{
GimpChannel *selection;
GimpChannel *mask;
GimpRGB color;
g_return_if_fail (GIMP_IS_IMAGE (gimage));
if (qmask_state == gimage->qmask_state)
return;
/* set image->qmask_state early so we can return early when
* being called recursively
*/
gimage->qmask_state = qmask_state ? TRUE : FALSE;
selection = gimp_image_get_mask (gimage);
mask = gimp_image_get_channel_by_name (gimage, GIMP_IMAGE_QMASK_NAME);
if (qmask_state)
{
/* Set the defaults */
color = gimage->qmask_color;
mask = gimp_image_get_channel_by_name (gimage, "Qmask");
if (! mask)
{
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK,
......@@ -78,22 +69,19 @@ gimp_image_set_qmask_state (GimpImage *gimage,
{
/* if no selection */
GimpLayer *layer;
GimpLayer *floating_sel = gimp_image_floating_sel (gimage);
if ((layer = gimp_image_floating_sel (gimage)))
{
floating_sel_to_layer (layer);
}
if (floating_sel)
floating_sel_to_layer (floating_sel);
mask = gimp_channel_new (gimage,
gimage->width,
gimage->height,
"Qmask",
&color);
GIMP_IMAGE_QMASK_NAME,
&gimage->qmask_color);
gimp_drawable_fill_by_type (GIMP_DRAWABLE (mask),
gimp_get_current_context (gimage->gimp),
GIMP_TRANSPARENT_FILL);
/* Clear the mask */
gimp_channel_clear (mask, NULL, FALSE);
}
else
{
......@@ -106,40 +94,25 @@ gimp_image_set_qmask_state (GimpImage *gimage,
/* Clear the selection */
gimp_channel_clear (selection, NULL, TRUE);
gimp_channel_set_color (mask, &color, FALSE);
gimp_item_rename (GIMP_ITEM (mask), "Qmask");
gimp_channel_set_color (mask, &gimage->qmask_color, FALSE);
gimp_item_rename (GIMP_ITEM (mask), GIMP_IMAGE_QMASK_NAME);
}
gimp_image_add_channel (gimage, mask, 0);
if (gimage->qmask_inverted)
gimp_channel_invert (mask, TRUE);
gimp_channel_invert (mask, FALSE);
gimp_image_undo_push_image_qmask (gimage, NULL);
gimp_image_add_channel (gimage, mask, 0);
gimp_image_undo_group_end (gimage);
/* connect to the removed signal, so the buttons get updated */
g_signal_connect (mask, "removed",
G_CALLBACK (gimp_image_qmask_removed_callback),
gimage);
}
}
else
{
mask = gimp_image_get_channel_by_name (gimage, "Qmask");
if (mask)
{
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK,
_("Disable QuickMask"));
/* push the undo here since removing the mask will
* call the qmask_removed_callback() which will set
* the qmask_state to FALSE
*/
gimp_image_undo_push_image_qmask (gimage, NULL);
if (gimage->qmask_inverted)
gimp_channel_invert (mask, TRUE);
......@@ -150,8 +123,6 @@ gimp_image_set_qmask_state (GimpImage *gimage,
}
}
gimage->qmask_state = qmask_state ? TRUE : FALSE;
gimp_image_qmask_changed (gimage);
}
......@@ -172,7 +143,7 @@ gimp_image_qmask_invert (GimpImage *gimage)
{
GimpChannel *qmask;
qmask = gimp_image_get_channel_by_name (gimage, "Qmask");
qmask = gimp_image_get_channel_by_name (gimage, GIMP_IMAGE_QMASK_NAME);
if (qmask)
{
......@@ -187,13 +158,3 @@ gimp_image_qmask_invert (GimpImage *gimage)
gimage->qmask_inverted = ! gimage->qmask_inverted;
}
/* private functions */
static void
gimp_image_qmask_removed_callback (GObject *qmask,
GimpImage *gimage)
{
gimp_image_set_qmask_state (gimage, FALSE);
}
......@@ -20,6 +20,9 @@
#define __GIMP_IMAGE_QMASK_H__
#define GIMP_IMAGE_QMASK_NAME "Qmask"
void gimp_image_set_qmask_state (GimpImage *gimage,
gboolean qmask_state);
gboolean gimp_image_get_qmask_state (const GimpImage *gimage);
......
......@@ -560,76 +560,6 @@ undo_free_image_resolution (GimpUndo *undo,
}
/****************/
/* Qmask Undo */
/****************/
typedef struct _QmaskUndo QmaskUndo;
struct _QmaskUndo
{
gboolean qmask_state;
};
static gboolean undo_pop_image_qmask (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_image_qmask (GimpUndo *undo,
GimpUndoMode undo_mode);
gboolean
gimp_image_undo_push_image_qmask (GimpImage *gimage,
const gchar *undo_desc)
{
GimpUndo *new;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
if ((new = gimp_image_undo_push (gimage,
sizeof (QmaskUndo),
sizeof (QmaskUndo),
GIMP_UNDO_IMAGE_QMASK, undo_desc,
TRUE,
undo_pop_image_qmask,
undo_free_image_qmask)))
{
QmaskUndo *qu;
qu = new->data;
qu->qmask_state = gimage->qmask_state;
return TRUE;
}
return FALSE;
}
static gboolean
undo_pop_image_qmask (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
QmaskUndo *qu = undo->data;
gboolean tmp;
tmp = undo->gimage->qmask_state;
undo->gimage->qmask_state = qu->qmask_state;
qu->qmask_state = tmp;
accum->qmask_changed = TRUE;
return TRUE;
}
static void
undo_free_image_qmask (GimpUndo *undo,
GimpUndoMode undo_mode)
{
g_free (undo->data);
}
/****************/
/* Grid Undo */
/****************/
......
......@@ -44,8 +44,6 @@ gboolean gimp_image_undo_push_image_size (GimpImage *gimage,
const gchar *undo_desc);
gboolean gimp_image_undo_push_image_resolution (GimpImage *gimage,
const gchar *undo_desc);
gboolean gimp_image_undo_push_image_qmask (GimpImage *gimage,
const gchar *undo_desc);
gboolean gimp_image_undo_push_image_grid (GimpImage *gimage,
const gchar *undo_desc,
GimpGrid *grid);
......
......@@ -46,6 +46,7 @@
#include "gimpimage-guides.h"
#include "gimpimage-preview.h"
#include "gimpimage-projection.h"
#include "gimpimage-qmask.h"
#include "gimpimage-undo.h"
#include "gimpimage-undo-push.h"
#include "gimplayer.h"
......@@ -134,11 +135,19 @@ static void gimp_image_drawable_update (GimpDrawable *drawable,
GimpImage *gimage);