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.
This commit is contained in:
Michael Natterer 2004-02-14 15:37:23 +00:00 committed by Michael Natterer
parent 8672dbf34c
commit 25b81b1570
21 changed files with 235 additions and 268 deletions

View File

@ -1,3 +1,44 @@
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> 2004-02-13 Manish Singh <yosh@gimp.org>
* plug-ins/common/psd.c (load_image): Initialize dest to NULL, * plug-ins/common/psd.c (load_image): Initialize dest to NULL,

View File

@ -73,11 +73,10 @@ qmask_toggle_cmd_callback (GtkWidget *widget,
gpointer data, gpointer data,
guint action) guint action)
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data); if (GTK_CHECK_MENU_ITEM (widget)->active !=
gimp_image_get_qmask_state (shell->gdisp->gimage))
if (GTK_CHECK_MENU_ITEM (widget)->active != shell->gdisp->gimage->qmask_state)
{ {
gimp_image_set_qmask_state (shell->gdisp->gimage, gimp_image_set_qmask_state (shell->gdisp->gimage,
GTK_CHECK_MENU_ITEM (widget)->active); GTK_CHECK_MENU_ITEM (widget)->active);
@ -91,9 +90,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
gpointer data, gpointer data,
guint action) guint action)
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data);
if (GTK_CHECK_MENU_ITEM (widget)->active) if (GTK_CHECK_MENU_ITEM (widget)->active)
{ {
@ -101,7 +98,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
{ {
gimp_image_qmask_invert (shell->gdisp->gimage); 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); gimp_image_flush (shell->gdisp->gimage);
} }
} }
@ -112,9 +109,7 @@ qmask_configure_cmd_callback (GtkWidget *widget,
gpointer data, gpointer data,
guint action) guint action)
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data);
qmask_channel_query (shell); qmask_channel_query (shell);
} }
@ -221,7 +216,8 @@ qmask_query_response (GtkWidget *widget,
GimpChannel *channel; GimpChannel *channel;
GimpRGB color; 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) if (options->gimage && channel)
{ {

View File

@ -73,11 +73,10 @@ qmask_toggle_cmd_callback (GtkWidget *widget,
gpointer data, gpointer data,
guint action) guint action)
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data); if (GTK_CHECK_MENU_ITEM (widget)->active !=
gimp_image_get_qmask_state (shell->gdisp->gimage))
if (GTK_CHECK_MENU_ITEM (widget)->active != shell->gdisp->gimage->qmask_state)
{ {
gimp_image_set_qmask_state (shell->gdisp->gimage, gimp_image_set_qmask_state (shell->gdisp->gimage,
GTK_CHECK_MENU_ITEM (widget)->active); GTK_CHECK_MENU_ITEM (widget)->active);
@ -91,9 +90,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
gpointer data, gpointer data,
guint action) guint action)
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data);
if (GTK_CHECK_MENU_ITEM (widget)->active) if (GTK_CHECK_MENU_ITEM (widget)->active)
{ {
@ -101,7 +98,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
{ {
gimp_image_qmask_invert (shell->gdisp->gimage); 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); gimp_image_flush (shell->gdisp->gimage);
} }
} }
@ -112,9 +109,7 @@ qmask_configure_cmd_callback (GtkWidget *widget,
gpointer data, gpointer data,
guint action) guint action)
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data);
qmask_channel_query (shell); qmask_channel_query (shell);
} }
@ -221,7 +216,8 @@ qmask_query_response (GtkWidget *widget,
GimpChannel *channel; GimpChannel *channel;
GimpRGB color; 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) if (options->gimage && channel)
{ {

View File

@ -617,7 +617,6 @@ static const GEnumValue gimp_undo_type_enum_values[] =
{ GIMP_UNDO_IMAGE_TYPE, N_("Image Type"), "image-type" }, { GIMP_UNDO_IMAGE_TYPE, N_("Image Type"), "image-type" },
{ GIMP_UNDO_IMAGE_SIZE, N_("Image Size"), "image-size" }, { GIMP_UNDO_IMAGE_SIZE, N_("Image Size"), "image-size" },
{ GIMP_UNDO_IMAGE_RESOLUTION, N_("Resolution Change"), "image-resolution" }, { 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_GRID, N_("Grid"), "image-grid" },
{ GIMP_UNDO_IMAGE_GUIDE, N_("Guide"), "image-guide" }, { GIMP_UNDO_IMAGE_GUIDE, N_("Guide"), "image-guide" },
{ GIMP_UNDO_IMAGE_COLORMAP, N_("Change Indexed Palette"), "image-colormap" }, { GIMP_UNDO_IMAGE_COLORMAP, N_("Change Indexed Palette"), "image-colormap" },

View File

@ -452,7 +452,6 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_IMAGE_TYPE, /*< desc="Image Type" >*/ GIMP_UNDO_IMAGE_TYPE, /*< desc="Image Type" >*/
GIMP_UNDO_IMAGE_SIZE, /*< desc="Image Size" >*/ GIMP_UNDO_IMAGE_SIZE, /*< desc="Image Size" >*/
GIMP_UNDO_IMAGE_RESOLUTION, /*< desc="Resolution Change" >*/ GIMP_UNDO_IMAGE_RESOLUTION, /*< desc="Resolution Change" >*/
GIMP_UNDO_IMAGE_QMASK, /*< desc="QuickMask" >*/
GIMP_UNDO_IMAGE_GRID, /*< desc="Grid" >*/ GIMP_UNDO_IMAGE_GRID, /*< desc="Grid" >*/
GIMP_UNDO_IMAGE_GUIDE, /*< desc="Guide" >*/ GIMP_UNDO_IMAGE_GUIDE, /*< desc="Guide" >*/
GIMP_UNDO_IMAGE_COLORMAP, /*< desc="Change Indexed Palette" >*/ GIMP_UNDO_IMAGE_COLORMAP, /*< desc="Change Indexed Palette" >*/

View File

@ -18,8 +18,6 @@
#include "config.h" #include "config.h"
#include <stdlib.h>
#include <glib-object.h> #include <glib-object.h>
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
@ -28,7 +26,6 @@
#include "gimp.h" #include "gimp.h"
#include "gimpchannel.h" #include "gimpchannel.h"
#include "gimpcontext.h"
#include "gimpimage.h" #include "gimpimage.h"
#include "gimpimage-qmask.h" #include "gimpimage-qmask.h"
#include "gimpimage-undo.h" #include "gimpimage-undo.h"
@ -39,12 +36,6 @@
#include "gimp-intl.h" #include "gimp-intl.h"
/* local function prototypes */
static void gimp_image_qmask_removed_callback (GObject *qmask,
GimpImage *gimage);
/* public functions */ /* public functions */
void void
@ -53,22 +44,22 @@ gimp_image_set_qmask_state (GimpImage *gimage,
{ {
GimpChannel *selection; GimpChannel *selection;
GimpChannel *mask; GimpChannel *mask;
GimpRGB color;
g_return_if_fail (GIMP_IS_IMAGE (gimage)); g_return_if_fail (GIMP_IS_IMAGE (gimage));
if (qmask_state == gimage->qmask_state) if (qmask_state == gimage->qmask_state)
return; 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); selection = gimp_image_get_mask (gimage);
mask = gimp_image_get_channel_by_name (gimage, GIMP_IMAGE_QMASK_NAME);
if (qmask_state) if (qmask_state)
{ {
/* Set the defaults */
color = gimage->qmask_color;
mask = gimp_image_get_channel_by_name (gimage, "Qmask");
if (! mask) if (! mask)
{ {
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK, 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 */ /* if no selection */
GimpLayer *layer; GimpLayer *floating_sel = gimp_image_floating_sel (gimage);
if ((layer = gimp_image_floating_sel (gimage))) if (floating_sel)
{ floating_sel_to_layer (floating_sel);
floating_sel_to_layer (layer);
}
mask = gimp_channel_new (gimage, mask = gimp_channel_new (gimage,
gimage->width, gimage->width,
gimage->height, gimage->height,
"Qmask", GIMP_IMAGE_QMASK_NAME,
&color); &gimage->qmask_color);
gimp_drawable_fill_by_type (GIMP_DRAWABLE (mask), /* Clear the mask */
gimp_get_current_context (gimage->gimp), gimp_channel_clear (mask, NULL, FALSE);
GIMP_TRANSPARENT_FILL);
} }
else else
{ {
@ -106,40 +94,25 @@ gimp_image_set_qmask_state (GimpImage *gimage,
/* Clear the selection */ /* Clear the selection */
gimp_channel_clear (selection, NULL, TRUE); gimp_channel_clear (selection, NULL, TRUE);
gimp_channel_set_color (mask, &color, FALSE); gimp_channel_set_color (mask, &gimage->qmask_color, FALSE);
gimp_item_rename (GIMP_ITEM (mask), "Qmask"); gimp_item_rename (GIMP_ITEM (mask), GIMP_IMAGE_QMASK_NAME);
} }
if (gimage->qmask_inverted)
gimp_channel_invert (mask, FALSE);
gimp_image_add_channel (gimage, mask, 0); gimp_image_add_channel (gimage, mask, 0);
if (gimage->qmask_inverted)
gimp_channel_invert (mask, TRUE);
gimp_image_undo_push_image_qmask (gimage, NULL);
gimp_image_undo_group_end (gimage); 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 else
{ {
mask = gimp_image_get_channel_by_name (gimage, "Qmask");
if (mask) if (mask)
{ {
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK, gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK,
_("Disable QuickMask")); _("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) if (gimage->qmask_inverted)
gimp_channel_invert (mask, TRUE); 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); gimp_image_qmask_changed (gimage);
} }
@ -172,7 +143,7 @@ gimp_image_qmask_invert (GimpImage *gimage)
{ {
GimpChannel *qmask; 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) if (qmask)
{ {
@ -187,13 +158,3 @@ gimp_image_qmask_invert (GimpImage *gimage)
gimage->qmask_inverted = ! gimage->qmask_inverted; 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);
}

View File

@ -20,6 +20,9 @@
#define __GIMP_IMAGE_QMASK_H__ #define __GIMP_IMAGE_QMASK_H__
#define GIMP_IMAGE_QMASK_NAME "Qmask"
void gimp_image_set_qmask_state (GimpImage *gimage, void gimp_image_set_qmask_state (GimpImage *gimage,
gboolean qmask_state); gboolean qmask_state);
gboolean gimp_image_get_qmask_state (const GimpImage *gimage); gboolean gimp_image_get_qmask_state (const GimpImage *gimage);

View File

@ -18,8 +18,6 @@
#include "config.h" #include "config.h"
#include <stdlib.h>
#include <glib-object.h> #include <glib-object.h>
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
@ -28,7 +26,6 @@
#include "gimp.h" #include "gimp.h"
#include "gimpchannel.h" #include "gimpchannel.h"
#include "gimpcontext.h"
#include "gimpimage.h" #include "gimpimage.h"
#include "gimpimage-qmask.h" #include "gimpimage-qmask.h"
#include "gimpimage-undo.h" #include "gimpimage-undo.h"
@ -39,12 +36,6 @@
#include "gimp-intl.h" #include "gimp-intl.h"
/* local function prototypes */
static void gimp_image_qmask_removed_callback (GObject *qmask,
GimpImage *gimage);
/* public functions */ /* public functions */
void void
@ -53,22 +44,22 @@ gimp_image_set_qmask_state (GimpImage *gimage,
{ {
GimpChannel *selection; GimpChannel *selection;
GimpChannel *mask; GimpChannel *mask;
GimpRGB color;
g_return_if_fail (GIMP_IS_IMAGE (gimage)); g_return_if_fail (GIMP_IS_IMAGE (gimage));
if (qmask_state == gimage->qmask_state) if (qmask_state == gimage->qmask_state)
return; 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); selection = gimp_image_get_mask (gimage);
mask = gimp_image_get_channel_by_name (gimage, GIMP_IMAGE_QMASK_NAME);
if (qmask_state) if (qmask_state)
{ {
/* Set the defaults */
color = gimage->qmask_color;
mask = gimp_image_get_channel_by_name (gimage, "Qmask");
if (! mask) if (! mask)
{ {
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK, 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 */ /* if no selection */
GimpLayer *layer; GimpLayer *floating_sel = gimp_image_floating_sel (gimage);
if ((layer = gimp_image_floating_sel (gimage))) if (floating_sel)
{ floating_sel_to_layer (floating_sel);
floating_sel_to_layer (layer);
}
mask = gimp_channel_new (gimage, mask = gimp_channel_new (gimage,
gimage->width, gimage->width,
gimage->height, gimage->height,
"Qmask", GIMP_IMAGE_QMASK_NAME,
&color); &gimage->qmask_color);
gimp_drawable_fill_by_type (GIMP_DRAWABLE (mask), /* Clear the mask */
gimp_get_current_context (gimage->gimp), gimp_channel_clear (mask, NULL, FALSE);
GIMP_TRANSPARENT_FILL);
} }
else else
{ {
@ -106,40 +94,25 @@ gimp_image_set_qmask_state (GimpImage *gimage,
/* Clear the selection */ /* Clear the selection */
gimp_channel_clear (selection, NULL, TRUE); gimp_channel_clear (selection, NULL, TRUE);
gimp_channel_set_color (mask, &color, FALSE); gimp_channel_set_color (mask, &gimage->qmask_color, FALSE);
gimp_item_rename (GIMP_ITEM (mask), "Qmask"); gimp_item_rename (GIMP_ITEM (mask), GIMP_IMAGE_QMASK_NAME);
} }
if (gimage->qmask_inverted)
gimp_channel_invert (mask, FALSE);
gimp_image_add_channel (gimage, mask, 0); gimp_image_add_channel (gimage, mask, 0);
if (gimage->qmask_inverted)
gimp_channel_invert (mask, TRUE);
gimp_image_undo_push_image_qmask (gimage, NULL);
gimp_image_undo_group_end (gimage); 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 else
{ {
mask = gimp_image_get_channel_by_name (gimage, "Qmask");
if (mask) if (mask)
{ {
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK, gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK,
_("Disable QuickMask")); _("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) if (gimage->qmask_inverted)
gimp_channel_invert (mask, TRUE); 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); gimp_image_qmask_changed (gimage);
} }
@ -172,7 +143,7 @@ gimp_image_qmask_invert (GimpImage *gimage)
{ {
GimpChannel *qmask; 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) if (qmask)
{ {
@ -187,13 +158,3 @@ gimp_image_qmask_invert (GimpImage *gimage)
gimage->qmask_inverted = ! gimage->qmask_inverted; 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);
}

View File

@ -20,6 +20,9 @@
#define __GIMP_IMAGE_QMASK_H__ #define __GIMP_IMAGE_QMASK_H__
#define GIMP_IMAGE_QMASK_NAME "Qmask"
void gimp_image_set_qmask_state (GimpImage *gimage, void gimp_image_set_qmask_state (GimpImage *gimage,
gboolean qmask_state); gboolean qmask_state);
gboolean gimp_image_get_qmask_state (const GimpImage *gimage); gboolean gimp_image_get_qmask_state (const GimpImage *gimage);

View File

@ -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 */ /* Grid Undo */
/****************/ /****************/

View File

@ -44,8 +44,6 @@ gboolean gimp_image_undo_push_image_size (GimpImage *gimage,
const gchar *undo_desc); const gchar *undo_desc);
gboolean gimp_image_undo_push_image_resolution (GimpImage *gimage, gboolean gimp_image_undo_push_image_resolution (GimpImage *gimage,
const gchar *undo_desc); 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, gboolean gimp_image_undo_push_image_grid (GimpImage *gimage,
const gchar *undo_desc, const gchar *undo_desc,
GimpGrid *grid); GimpGrid *grid);

View File

@ -46,6 +46,7 @@
#include "gimpimage-guides.h" #include "gimpimage-guides.h"
#include "gimpimage-preview.h" #include "gimpimage-preview.h"
#include "gimpimage-projection.h" #include "gimpimage-projection.h"
#include "gimpimage-qmask.h"
#include "gimpimage-undo.h" #include "gimpimage-undo.h"
#include "gimpimage-undo-push.h" #include "gimpimage-undo-push.h"
#include "gimplayer.h" #include "gimplayer.h"
@ -134,11 +135,19 @@ static void gimp_image_drawable_update (GimpDrawable *drawable,
GimpImage *gimage); GimpImage *gimage);
static void gimp_image_drawable_visibility (GimpItem *item, static void gimp_image_drawable_visibility (GimpItem *item,
GimpImage *gimage); GimpImage *gimage);
static void gimp_image_drawable_add (GimpContainer *container, static void gimp_image_layer_add (GimpContainer *container,
GimpItem *item, GimpLayer *layer,
GimpImage *gimage); GimpImage *gimage);
static void gimp_image_drawable_remove (GimpContainer *container, static void gimp_image_layer_remove (GimpContainer *container,
GimpItem *item, GimpLayer *layer,
GimpImage *gimage);
static void gimp_image_channel_add (GimpContainer *container,
GimpChannel *channel,
GimpImage *gimage);
static void gimp_image_channel_remove (GimpContainer *container,
GimpChannel *channel,
GimpImage *gimage);
static void gimp_image_channel_name_changed (GimpChannel *channel,
GimpImage *gimage); GimpImage *gimage);
@ -507,18 +516,23 @@ gimp_image_init (GimpImage *gimage)
G_CALLBACK (gimp_image_drawable_visibility), G_CALLBACK (gimp_image_drawable_visibility),
gimage); gimage);
g_signal_connect (gimage->layers, "add", gimage->channel_name_changed_handler =
G_CALLBACK (gimp_image_drawable_add), gimp_container_add_handler (gimage->channels, "name_changed",
gimage); G_CALLBACK (gimp_image_channel_name_changed),
g_signal_connect (gimage->channels, "add",
G_CALLBACK (gimp_image_drawable_add),
gimage); gimage);
g_signal_connect (gimage->layers, "add",
G_CALLBACK (gimp_image_layer_add),
gimage);
g_signal_connect (gimage->layers, "remove", g_signal_connect (gimage->layers, "remove",
G_CALLBACK (gimp_image_drawable_remove), G_CALLBACK (gimp_image_layer_remove),
gimage);
g_signal_connect (gimage->channels, "add",
G_CALLBACK (gimp_image_channel_add),
gimage); gimage);
g_signal_connect (gimage->channels, "remove", g_signal_connect (gimage->channels, "remove",
G_CALLBACK (gimp_image_drawable_remove), G_CALLBACK (gimp_image_channel_remove),
gimage); gimage);
gimage->active_layer = NULL; gimage->active_layer = NULL;
@ -568,18 +582,22 @@ gimp_image_dispose (GObject *object)
gimp_container_remove_handler (gimage->channels, gimp_container_remove_handler (gimage->channels,
gimage->channel_visible_handler); gimage->channel_visible_handler);
g_signal_handlers_disconnect_by_func (gimage->layers, gimp_container_remove_handler (gimage->channels,
gimp_image_drawable_add, gimage->channel_name_changed_handler);
gimage);
g_signal_handlers_disconnect_by_func (gimage->channels,
gimp_image_drawable_add,
gimage);
g_signal_handlers_disconnect_by_func (gimage->layers, g_signal_handlers_disconnect_by_func (gimage->layers,
gimp_image_drawable_remove, gimp_image_layer_add,
gimage); gimage);
g_signal_handlers_disconnect_by_func (gimage->layers,
gimp_image_layer_remove,
gimage);
g_signal_handlers_disconnect_by_func (gimage->channels, g_signal_handlers_disconnect_by_func (gimage->channels,
gimp_image_drawable_remove, gimp_image_channel_add,
gimage);
g_signal_handlers_disconnect_by_func (gimage->channels,
gimp_image_channel_remove,
gimage); gimage);
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
@ -899,23 +917,78 @@ gimp_image_drawable_visibility (GimpItem *item,
} }
static void static void
gimp_image_drawable_add (GimpContainer *container, gimp_image_layer_add (GimpContainer *container,
GimpItem *item, GimpLayer *layer,
GimpImage *gimage) GimpImage *gimage)
{ {
GimpItem *item = GIMP_ITEM (layer);
if (gimp_item_get_visible (item)) if (gimp_item_get_visible (item))
gimp_image_drawable_visibility (item, gimage); gimp_image_drawable_visibility (item, gimage);
} }
static void static void
gimp_image_drawable_remove (GimpContainer *container, gimp_image_layer_remove (GimpContainer *container,
GimpItem *item, GimpLayer *layer,
GimpImage *gimage) GimpImage *gimage)
{ {
GimpItem *item = GIMP_ITEM (layer);
if (gimp_item_get_visible (item)) if (gimp_item_get_visible (item))
gimp_image_drawable_visibility (item, gimage); gimp_image_drawable_visibility (item, gimage);
} }
static void
gimp_image_channel_add (GimpContainer *container,
GimpChannel *channel,
GimpImage *gimage)
{
GimpItem *item = GIMP_ITEM (channel);
if (gimp_item_get_visible (item))
gimp_image_drawable_visibility (item, gimage);
if (! strcmp (GIMP_IMAGE_QMASK_NAME,
gimp_object_get_name (GIMP_OBJECT (channel))))
{
gimp_image_set_qmask_state (gimage, TRUE);
}
}
static void
gimp_image_channel_remove (GimpContainer *container,
GimpChannel *channel,
GimpImage *gimage)
{
GimpItem *item = GIMP_ITEM (channel);
if (gimp_item_get_visible (item))
gimp_image_drawable_visibility (item, gimage);
if (! strcmp (GIMP_IMAGE_QMASK_NAME,
gimp_object_get_name (GIMP_OBJECT (channel))))
{
gimp_image_set_qmask_state (gimage, FALSE);
}
}
static void
gimp_image_channel_name_changed (GimpChannel *channel,
GimpImage *gimage)
{
if (! strcmp (GIMP_IMAGE_QMASK_NAME,
gimp_object_get_name (GIMP_OBJECT (channel))))
{
gimp_image_set_qmask_state (gimage, TRUE);
}
else if (gimp_image_get_qmask_state (gimage) &&
! gimp_container_get_child_by_name (gimage->channels,
GIMP_IMAGE_QMASK_NAME))
{
gimp_image_set_qmask_state (gimage, FALSE);
}
}
/* public functions */ /* public functions */

View File

@ -143,6 +143,7 @@ struct _GimpImage
GQuark channel_update_handler; GQuark channel_update_handler;
GQuark layer_visible_handler; GQuark layer_visible_handler;
GQuark channel_visible_handler; GQuark channel_visible_handler;
GQuark channel_name_changed_handler;
GimpLayer *active_layer; /* the active layer */ GimpLayer *active_layer; /* the active layer */
GimpChannel *active_channel; /* the active channel */ GimpChannel *active_channel; /* the active channel */

View File

@ -381,7 +381,6 @@ gimp_undo_create_preview_private (GimpUndo *undo)
{ {
case GIMP_UNDO_GROUP_IMAGE_QMASK: case GIMP_UNDO_GROUP_IMAGE_QMASK:
case GIMP_UNDO_GROUP_MASK: case GIMP_UNDO_GROUP_MASK:
case GIMP_UNDO_IMAGE_QMASK:
case GIMP_UNDO_MASK: case GIMP_UNDO_MASK:
preview_viewable = GIMP_VIEWABLE (gimp_image_get_mask (undo->gimage)); preview_viewable = GIMP_VIEWABLE (gimp_image_get_mask (undo->gimage));
break; break;

View File

@ -1480,12 +1480,16 @@ gimp_display_shell_qmask_button_press (GtkWidget *widget,
void void
gimp_display_shell_qmask_toggled (GtkWidget *widget, gimp_display_shell_qmask_toggled (GtkWidget *widget,
GimpDisplayShell *shell) GimpDisplayShell *shell)
{
if (GTK_TOGGLE_BUTTON (widget)->active !=
gimp_image_get_qmask_state (shell->gdisp->gimage))
{ {
gimp_image_set_qmask_state (shell->gdisp->gimage, gimp_image_set_qmask_state (shell->gdisp->gimage,
GTK_TOGGLE_BUTTON (widget)->active); GTK_TOGGLE_BUTTON (widget)->active);
gimp_image_flush (shell->gdisp->gimage); gimp_image_flush (shell->gdisp->gimage);
} }
}
gboolean gboolean
gimp_display_shell_nav_button_press (GtkWidget *widget, gimp_display_shell_nav_button_press (GtkWidget *widget,

View File

@ -1491,6 +1491,8 @@ image_menu_update (GtkItemFactory *item_factory,
SET_SENSITIVE ("/Select/None", lp && sel); SET_SENSITIVE ("/Select/None", lp && sel);
SET_SENSITIVE ("/Select/Invert", lp && sel); SET_SENSITIVE ("/Select/Invert", lp && sel);
SET_SENSITIVE ("/Select/Float", lp && sel); SET_SENSITIVE ("/Select/Float", lp && sel);
if (display_items)
SET_SENSITIVE ("/Select/By Color", lp); SET_SENSITIVE ("/Select/By Color", lp);
SET_SENSITIVE ("/Select/Feather...", lp && sel); SET_SENSITIVE ("/Select/Feather...", lp && sel);
@ -1499,7 +1501,9 @@ image_menu_update (GtkItemFactory *item_factory,
SET_SENSITIVE ("/Select/Grow...", lp && sel); SET_SENSITIVE ("/Select/Grow...", lp && sel);
SET_SENSITIVE ("/Select/Border...", lp && sel); SET_SENSITIVE ("/Select/Border...", lp && sel);
if (display_items)
SET_SENSITIVE ("/Select/Toggle QuickMask", gdisp); SET_SENSITIVE ("/Select/Toggle QuickMask", gdisp);
SET_SENSITIVE ("/Select/Save to Channel", sel && !fs); SET_SENSITIVE ("/Select/Save to Channel", sel && !fs);
SET_SENSITIVE ("/Select/To Path", sel && !fs); SET_SENSITIVE ("/Select/To Path", sel && !fs);

View File

@ -73,11 +73,10 @@ qmask_toggle_cmd_callback (GtkWidget *widget,
gpointer data, gpointer data,
guint action) guint action)
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data); if (GTK_CHECK_MENU_ITEM (widget)->active !=
gimp_image_get_qmask_state (shell->gdisp->gimage))
if (GTK_CHECK_MENU_ITEM (widget)->active != shell->gdisp->gimage->qmask_state)
{ {
gimp_image_set_qmask_state (shell->gdisp->gimage, gimp_image_set_qmask_state (shell->gdisp->gimage,
GTK_CHECK_MENU_ITEM (widget)->active); GTK_CHECK_MENU_ITEM (widget)->active);
@ -91,9 +90,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
gpointer data, gpointer data,
guint action) guint action)
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data);
if (GTK_CHECK_MENU_ITEM (widget)->active) if (GTK_CHECK_MENU_ITEM (widget)->active)
{ {
@ -101,7 +98,7 @@ qmask_invert_cmd_callback (GtkWidget *widget,
{ {
gimp_image_qmask_invert (shell->gdisp->gimage); 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); gimp_image_flush (shell->gdisp->gimage);
} }
} }
@ -112,9 +109,7 @@ qmask_configure_cmd_callback (GtkWidget *widget,
gpointer data, gpointer data,
guint action) guint action)
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
shell = GIMP_DISPLAY_SHELL (data);
qmask_channel_query (shell); qmask_channel_query (shell);
} }
@ -221,7 +216,8 @@ qmask_query_response (GtkWidget *widget,
GimpChannel *channel; GimpChannel *channel;
GimpRGB color; 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) if (options->gimage && channel)
{ {

View File

@ -1491,6 +1491,8 @@ image_menu_update (GtkItemFactory *item_factory,
SET_SENSITIVE ("/Select/None", lp && sel); SET_SENSITIVE ("/Select/None", lp && sel);
SET_SENSITIVE ("/Select/Invert", lp && sel); SET_SENSITIVE ("/Select/Invert", lp && sel);
SET_SENSITIVE ("/Select/Float", lp && sel); SET_SENSITIVE ("/Select/Float", lp && sel);
if (display_items)
SET_SENSITIVE ("/Select/By Color", lp); SET_SENSITIVE ("/Select/By Color", lp);
SET_SENSITIVE ("/Select/Feather...", lp && sel); SET_SENSITIVE ("/Select/Feather...", lp && sel);
@ -1499,7 +1501,9 @@ image_menu_update (GtkItemFactory *item_factory,
SET_SENSITIVE ("/Select/Grow...", lp && sel); SET_SENSITIVE ("/Select/Grow...", lp && sel);
SET_SENSITIVE ("/Select/Border...", lp && sel); SET_SENSITIVE ("/Select/Border...", lp && sel);
if (display_items)
SET_SENSITIVE ("/Select/Toggle QuickMask", gdisp); SET_SENSITIVE ("/Select/Toggle QuickMask", gdisp);
SET_SENSITIVE ("/Select/Save to Channel", sel && !fs); SET_SENSITIVE ("/Select/Save to Channel", sel && !fs);
SET_SENSITIVE ("/Select/To Path", sel && !fs); SET_SENSITIVE ("/Select/To Path", sel && !fs);

View File

@ -277,6 +277,9 @@ gimp_image_dock_constructor (GType type,
DESTROY ("/Layer/Stack/Layer to Top"); DESTROY ("/Layer/Stack/Layer to Top");
DESTROY ("/Layer/Stack/Layer to Bottom"); DESTROY ("/Layer/Stack/Layer to Bottom");
DESTROY ("/Select/By Color");
DESTROY ("/Select/Toggle QuickMask");
DESTROY ("/Tools/Toolbox"); DESTROY ("/Tools/Toolbox");
DESTROY ("/Tools/Default Colors"); DESTROY ("/Tools/Default Colors");
DESTROY ("/Tools/Swap Colors"); DESTROY ("/Tools/Swap Colors");

View File

@ -277,6 +277,9 @@ gimp_image_dock_constructor (GType type,
DESTROY ("/Layer/Stack/Layer to Top"); DESTROY ("/Layer/Stack/Layer to Top");
DESTROY ("/Layer/Stack/Layer to Bottom"); DESTROY ("/Layer/Stack/Layer to Bottom");
DESTROY ("/Select/By Color");
DESTROY ("/Select/Toggle QuickMask");
DESTROY ("/Tools/Toolbox"); DESTROY ("/Tools/Toolbox");
DESTROY ("/Tools/Default Colors"); DESTROY ("/Tools/Default Colors");
DESTROY ("/Tools/Swap Colors"); DESTROY ("/Tools/Swap Colors");

View File

@ -894,7 +894,6 @@ xcf_load_channel (XcfInfo *info,
gint width; gint width;
gint height; gint height;
gboolean is_fs_drawable; gboolean is_fs_drawable;
gboolean is_qmask = FALSE;
gchar *name; gchar *name;
GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE }; GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
@ -908,9 +907,6 @@ xcf_load_channel (XcfInfo *info,
info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1); info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
info->cp += xcf_read_string (info->fp, &name, 1); info->cp += xcf_read_string (info->fp, &name, 1);
if (name)
is_qmask = (strcmp (name, "Qmask") == 0);
/* create a new channel */ /* create a new channel */
channel = gimp_channel_new (gimage, width, height, name, &color); channel = gimp_channel_new (gimage, width, height, name, &color);
g_free (name); g_free (name);
@ -934,9 +930,6 @@ xcf_load_channel (XcfInfo *info,
if (is_fs_drawable) if (is_fs_drawable)
info->floating_sel_drawable = GIMP_DRAWABLE (channel); info->floating_sel_drawable = GIMP_DRAWABLE (channel);
if (is_qmask)
gimage->qmask_state = TRUE;
return channel; return channel;
error: error: