Example #1
0
void CImage::EditApplyAll( BOOL fApplyData, BOOL fApplyAlpha )
{
LPOBJECT lpObject;

lpObject = NULL;
while ( lpObject = GetNextObject(lpObject, YES, NO) )
	ObjEditApply( lpObject, fApplyData, fApplyAlpha, NO );
}
Example #2
0
void ImgEditApplyAll( LPIMAGE lpImage, BOOL fApplyData, BOOL fApplyAlpha )
/************************************************************************/
{
LPOBJECT lpObject;

lpObject = NULL;
while ( lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO) )
	ObjEditApply( lpImage, lpObject, fApplyData, fApplyAlpha, NO );
}
Example #3
0
void ImgEditApply( LPIMAGE lpImage )
/************************************************************************/
{
LPOBJECT lpObject;

lpObject = NULL;
while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO))
	{
	if (Control.UndoObjects && !ImgIsSelectedObject(lpImage, lpObject))
		continue;
	ObjEditApply( lpImage, lpObject, YES, YES, NO );
	}
}
Example #4
0
BOOL CImage::EditRecoverObj( LPOBJECT lpObject,
					BOOL fEditUndo, BOOL fMaskUndo)
{
	// if manual apply we can't do anything to recover
	if (Control.UseApply)
		return(FALSE);

	if (fEditUndo)
		lpObject->DataDirty = TRUE;
	if (fMaskUndo)
		lpObject->AlphaDirty = TRUE;
	ObjEditUndo(lpObject, fEditUndo, fMaskUndo);
	ObjEditApply(lpObject, fEditUndo, fMaskUndo, FALSE);
	return( TRUE );
}
Example #5
0
BOOL CImage::EditRecoverSelObj( BOOL fEditUndo, BOOL fMaskUndo)
{
	LPOBJECT lpObject;

	// if manual apply we can't do anything to recover
	if (Control.UseApply)
		return(FALSE);

	lpObject = NULL;
	while ( lpObject = GetSelObject(lpObject) )
	{
		if (fEditUndo)
			lpObject->DataDirty = TRUE;
		if (fMaskUndo)
			lpObject->AlphaDirty = TRUE;
		ObjEditUndo(lpObject, fEditUndo, fMaskUndo);
		ObjEditApply(lpObject, fEditUndo, fMaskUndo, FALSE);
	}
	return( TRUE );
}
Example #6
0
void CImage::ObjEditUndo(LPOBJECT lpObject, BOOL fUndoData, BOOL fUndoAlpha)
{
RECT rTemp;
BOOL fSelected, Resolution, fDeleted, fBase, bLocked;
LPALPHA lpAlpha, lpTemp;
LPOBJECT lpNext;
int XSize, YSize;
int tempDataType;
LPCOLORMAP lpColorMap;
int        GroupID;

lpAlpha = lpObject->lpAlpha;
fBase = lpObject == GetBase();
if (fUndoData && lpObject->DataDirty)
	{
	if (lpObject->DataUndoType & UT_RESOLUTION)
		Resolution = FrameResolution(lpObject->Pixmap.EditFrame);
	if (lpObject->DataUndoType & UT_COLORMAP)
		{
		if (lpColorMap = FrameGetColorMap(ObjGetEditFrame(lpObject)))
			lpColorMap = FrameCopyColorMap(lpColorMap);
		else
			lpColorMap = NULL;
		}
	if (lpObject->DataUndoType & (UT_DATA|UT_NEWDATA))
		{
		PixmapEditUndo(&lpObject->Pixmap);
		if (fBase)
			{
			npix = FrameXSize(ObjGetEditFrame(lpObject));
			nlin = FrameYSize(ObjGetEditFrame(lpObject));
			if (lpObject->DataUndoType & UT_NEWDATA)
				{
				tempDataType = DataType;
				DataType = UndoDataType;
				UndoDataType = tempDataType;
				}
			}
		}
	if (lpObject->DataUndoType & UT_OBJECTRECT)
		{
		rTemp = lpObject->rObject;
		lpObject->rObject = lpObject->rUndoObject;
		lpObject->rUndoObject = rTemp;
		}
	if (lpObject->DataUndoType & UT_RESOLUTION)
		{
		FrameSetResolution( lpObject->Pixmap.EditFrame,
							lpObject->UndoResolution);
		lpObject->UndoResolution = Resolution;
		}
	if (lpObject->DataUndoType & UT_UNDOTEXTDATA)
		{
      	if (lpObject->lpUndoText)
      		{
      		CTextObject *pTmp    = lpObject->lpUndoText;
      		lpObject->lpUndoText = lpObject->lpText;
      		lpObject->lpText     = pTmp;
      		}
    	}
	if (lpObject->DataUndoType & UT_COLORMAP)
		{
		if (lpObject->UndoColorMap)
			{
			FrameSetColorMap( ObjGetEditFrame(lpObject), lpObject->UndoColorMap);
			FrameDestroyColorMap(lpObject->UndoColorMap);
			}
		lpObject->UndoColorMap = lpColorMap;
		}
	if (lpObject->DataUndoType & UT_SELECTION)
		{
		fSelected = lpObject->fSelected;
		lpObject->fSelected = lpObject->fUndoSelected;
		lpObject->fUndoSelected = fSelected;
		}
	if (lpObject->DataUndoType & UT_LOCKOBJECTS)
		{
		bLocked = lpObject->bLocked;
		lpObject->bLocked = lpObject->bUndoLocked;
		lpObject->bUndoLocked = bLocked;
		}
	if (lpObject->DataUndoType & UT_GROUPOBJECTS)
		{
		GroupID = lpObject->wGroupID;
		lpObject->wGroupID = lpObject->UndoGroupID;
		lpObject->UndoGroupID = GroupID;
		}
	if (lpObject->DataUndoType & UT_DELETEOBJECTS)
		{
		lpNext = lpObject;
		while (lpNext = GetNextObject(lpNext, YES, NO, YES))
			{
			if (lpNext->fUndoDeleted || lpNext->fDeleted)
				{
				fDeleted = lpNext->fDeleted;
				lpNext->fDeleted = lpNext->fUndoDeleted;
				lpNext->fUndoDeleted = fDeleted;
				}
			}
		}
	if (fBase && lpObject->DataUndoType & UT_MOVEOBJECTS)
		{
		lpNext = lpObject;
		while (lpNext = GetNextObject(lpNext, YES, NO, NO))
			{
			rTemp = lpNext->rObject;
			lpNext->rObject = lpNext->rUndoObject;
			lpNext->rUndoObject = rTemp;
			}
		}
	lpObject->DataUndoNotRedo = !lpObject->DataUndoNotRedo;
	if (!fUndoAlpha)
		fUndoAlpha = lpObject->fBothDirty;
	}
else if (fUndoAlpha && lpObject->fBothDirty)
	fUndoAlpha = NO;

if (fUndoAlpha && lpObject->AlphaDirty)
	{
	if (lpAlpha)
		{
		if (lpObject->AlphaUndoType & (UT_ALPHA|UT_NEWALPHA))
			{
			PixmapEditUndo(&lpAlpha->Pixmap);
			rTemp = lpAlpha->rMask;
			lpAlpha->rMask = lpAlpha->rUndoMask;
			lpAlpha->rUndoMask = rTemp;
			}
		}
	if (lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK))
		{
		lpTemp = lpObject->lpAlpha;
		lpObject->lpAlpha = lpObject->lpUndoAlpha;
		lpObject->lpUndoAlpha = lpTemp;
		}
	lpObject->AlphaUndoNotRedo = !lpObject->AlphaUndoNotRedo;
	}
lpAlpha = lpObject->lpAlpha;
// check to make sure the mask is still the same size
if (fUndoData && fBase && lpObject->Pixmap.fNewFrame)
	{
	// we just undid to a different size frame bag mask delete undo
	if (lpObject->lpUndoAlpha && !lpObject->fBothDirty)
		ObjEditApply(lpObject, NO, YES, NO);
	if (lpAlpha)
		{
		XSize = FrameXSize(lpAlpha->Pixmap.EditFrame);
		YSize = FrameYSize(lpAlpha->Pixmap.EditFrame);
		if (XSize != FrameXSize(lpObject->Pixmap.EditFrame) ||
			YSize != FrameYSize(lpObject->Pixmap.EditFrame))
			{
			ObjEditInit(lpObject, UT_DELETEMASK);
			// dont free mask if it was stored for later undo/redo
			if (!lpObject->lpUndoAlpha)
				MaskClose(lpObject->lpAlpha);
			lpObject->fBothDirty = YES;
			lpObject->AlphaDirty = lpObject->DataDirty;
			lpObject->lpAlpha = NULL;
			}
		}
	}
}
Example #7
0
BOOL CImage::ObjEditInit(LPOBJECT lpObject, UNDO_TYPE UndoType)
{
LPALPHA lpAlpha;
LPOBJECT lpNext;
BOOL fBase, fDataInit, fAlphaInit;
LPCOLORMAP lpColorMap;

// See if this objects the base, and get alpha channel of object
fBase = (lpObject == GetBase());
lpAlpha = lpObject->lpAlpha;

//
// HANDLE INITIALIZATION OF OBJECT DATA
//

fDataInit = (UndoType & UT_DATAUNDO) != 0;
if (fDataInit && !(Control.NoUndo || fDisableUndos))
	{
	// Apply any changes that have been made if in auto apply mode
	// or if in manual apply mode and changes have been undone
	// the init flag is set only if we are doing an edit in place change
	// to the data so we get rid of any useless undo's
	if (!Control.UseApply || ( Control.UseApply && !lpObject->DataUndoNotRedo ) )
		ObjEditApply(lpObject, YES, !fBase, (UndoType & UT_DATA) != 0);

	// Save undo information for the specific type of operation
 	if (UndoType & UT_UNDOTEXTDATA && !(lpObject->DataUndoType & UT_UNDOTEXTDATA))
		lpObject->lpUndoText = new CTextObject(*lpObject->lpText);
	if (UndoType & UT_OBJECTRECT && !(lpObject->DataUndoType & UT_OBJECTRECT))
		lpObject->rUndoObject = lpObject->rObject;
	if (UndoType & UT_RESOLUTION && !(lpObject->DataUndoType & UT_RESOLUTION))
		lpObject->UndoResolution = FrameResolution(ObjGetEditFrame(lpObject));
	if (UndoType & UT_COLORMAP && !(lpObject->DataUndoType & UT_COLORMAP))
		{
		if (lpColorMap = FrameGetColorMap(ObjGetEditFrame(lpObject)))
			lpObject->UndoColorMap = FrameCopyColorMap(lpColorMap);
		else
			lpObject->UndoColorMap = NULL;
		}
	if (UndoType & UT_SELECTION && !(lpObject->DataUndoType & UT_SELECTION))
		lpObject->fUndoSelected = lpObject->fSelected;
	// Size base is a special case for the base and base only
	if (UndoType & UT_DATA)
		{
		// init the data pixmap for editing
		if (!lpObject->Pixmap.UndoFrame)
			if (!PixmapInitUndo(&lpObject->Pixmap))
				return(FALSE);
		}
	if (UndoType & UT_NEWDATA)
		{
		if (fBase)
			UndoDataType = DataType;
		}
	if (fBase && UndoType & UT_MOVEOBJECTS &&
		!(lpObject->DataUndoType & UT_MOVEOBJECTS))
		{
		lpNext = lpObject;
		while (lpNext = GetNextObject(lpNext, YES, NO, NO))
			{
			ObjEditApply(lpNext, TRUE, TRUE, FALSE);
			lpNext->rUndoObject = lpNext->rObject;
			}
		}
	// Delete objects is a special case for the base and base only
	if (fBase && UndoType & UT_DELETEOBJECTS &&
		!(lpObject->DataUndoType & UT_DELETEOBJECTS))
		{
		lpNext = lpObject;
		while (lpNext = GetNextObject(lpNext, YES, NO, YES))
			lpNext->fUndoDeleted = NO;
		}
	if (UndoType & UT_GROUPOBJECTS && !(lpObject->DataUndoType & UT_GROUPOBJECTS))
		lpObject->UndoGroupID = lpObject->wGroupID;
	if (UndoType & UT_LOCKOBJECTS &&	!(lpObject->DataUndoType & UT_LOCKOBJECTS))
		lpObject->bUndoLocked = lpObject->bLocked;
	}

// now that we have successfully initialized everything set UndoTypes
if (fDataInit)
	{
	lpObject->DataUndoNotRedo = YES;
	lpObject->DataUndoType |= (UndoType & UT_DATAUNDO);
	}

//
// HANDLE INITIALIZATION OF OBJECT ALPHA
//
fAlphaInit = (UndoType & UT_ALPHAUNDO) != 0;
if (fAlphaInit && !(Control.NoUndo  || fDisableUndos) && (!fBase || Control.UndoMasks))
	{
	// Apply any changes that have been made if in auto apply mode
	// or if in manual apply mode and changes have been undone or
	// apply any changes only to the mask
	// or if it is a change to both data and mask and
	// both were not dirty before
	// Initialize the data undo if the object is not the base and we didn't
	// already do a data init
	// the init flag is set only if we are doing an edit in place change
	// to the alpha so we get rid of any useless undo's
	if (!Control.UseApply ||
		(Control.UseApply && !lpObject->AlphaUndoNotRedo) ||
		(fBase && (!fDataInit || !lpObject->fBothDirty)))
		ObjEditApply(lpObject, fDataInit ? NO : !fBase, YES,
					(UndoType & UT_ALPHA) != 0);

	// Save undo information for the specific type of operation
	if (lpAlpha)
		{
		if (!lpObject->AlphaUndoType)
			{
			if (UndoType & UT_ALPHA)
				{
				// init the data pixmap for editing
				if (!lpAlpha->Pixmap.UndoFrame)
					if (!PixmapInitUndo(&lpAlpha->Pixmap))
						return(FALSE);
				lpAlpha->rUndoMask = lpAlpha->rMask;
				}
			if (UndoType & UT_NEWALPHA)
				lpAlpha->rUndoMask = lpAlpha->rMask;
			if (fBase && UndoType & UT_CREATEMASK)
				lpObject->lpUndoAlpha = NULL;
			if (fBase && UndoType & UT_DELETEMASK)
				lpObject->lpUndoAlpha = lpAlpha;
			if (UndoType & UT_ALPHAUNDO)
				{
				lpObject->AlphaUndoNotRedo = YES;
				lpObject->AlphaUndoType |= (UndoType & UT_ALPHAUNDO);
				}
			}
		}
	}

return(TRUE);
}
Example #8
0
BOOL CImage::EditInit( EDIT_TARGET Target, UNDO_TYPE UndoType,
				LPOBJECT lpTargetObject)
{
LPOBJECT lpObject, lpBase;
int retc;
BOOL fDiscardUndo = NO;
BOOL fUndoFailed;
BOOL fMaskEdit;
EDIT_TARGET OldTarget;

lpBase = GetBase();

// the InitUndoType flag is kept separately from the
// DataUndoType and AlphaUndoType so that if the initialization
// of the undo fails we still know what was edited when
// EditedObject and EditedObjectFrame are called
lpObject = NULL;
while (lpObject = GetNextObject(lpObject, YES, NO))
	lpObject->InitUndoType = 0;

// No mask undo's are allowed - so apply any that we have now
if (!Control.UndoMasks)
	ObjEditApply(lpBase, NO, YES, NO);

// No undo's are allowed - so apply any that we have now
if (Control.NoUndo || fDisableUndos)
	{
	lpObject = NULL;
	while (lpObject = GetNextObject(lpObject, YES, NO))
		ObjEditApply(lpObject, YES, lpObject != lpBase, NO);
	}

// if we have don't have multiple objects, strip off the delete objects flag
if (!Control.MultipleObjects)
	UndoType &= ~UT_DELETEOBJECTS;

// find out whether we are in mask edit mode
fMaskEdit = (Target == ET_OBJECT) && (lpTargetObject == lpBase) &&
			((UndoType & UT_ALPHAUNDO) != 0);

// see if any objects cannot have their undos freed without
// asking the user first, if so ask the user and get the response
// This is only a manual apply thing
if (UndoType & (UT_NEWDATA|UT_NEWALPHA) && Control.UseApply)
	{
	lpObject = NULL;
	fDiscardUndo = YES;
	while (lpObject = GetNextObject(lpObject, YES, NO))
		{
		// see if this is an object we are not editing
		if ((Target == ET_SELOBJECTS &&
			!IsSelectedObject(lpObject)) ||
			(Target == ET_OBJECT && lpObject != lpTargetObject))
			continue;
		if (!ObjEditUndoDiscardable(lpObject, (UndoType & UT_NEWDATA) != 0,
											(UndoType & UT_NEWALPHA) != 0))
			{
			if (lpCmdList->fPlayback)
				{
				fDiscardUndo = fDiscardUndo;
				}
			else
				{
				DISCARDUNDO_PARMS parms;

				retc = AstralConfirm( IDS_OKTOAPPLY );
				if (retc == IDCANCEL)
					return(FALSE);
				fDiscardUndo = retc == IDYES;
				parms.fDiscardUndo = fDiscardUndo;

				PostCommand(lpCmdList, IDS_CMD_DISCARDUNDO, &parms);
				}
			break;
			}
		}
	}

OldTarget = EditTarget;
EditTarget = Target;

// now loop through the objects initializing their undos
lpObject = NULL;
while (lpObject = GetNextObject(lpObject, YES, NO))
	{
	// if our last edit involved editing all objects then
	// make sure we apply for all objects
	if (OldTarget == ET_ALLOBJECTS)
		{
		ObjEditApply(lpObject, !fMaskEdit,
 				(lpObject != lpBase) && !fMaskEdit, NO);
		}

	// see if this is an object we are not editing
	if ((Target == ET_SELOBJECTS && !IsSelectedObject(lpObject)) ||
		(Target == ET_OBJECT && lpObject != lpTargetObject))
		{
		// if no individual undo's, wack any undo buffers
		// if in auto apply or in manual apply and state is redo
		// Objects that are not the base need to also have
		// their alphas wacked if this is not a mask edit 
		if (!Control.UndoObjects && (!Control.UseApply ||
				( Control.UseApply && !lpObject->DataUndoNotRedo ) ) )
			ObjEditApply(lpObject, !fMaskEdit,
 				(lpObject != lpBase) && !fMaskEdit, NO);
		continue;
		}

	// Discard it's undo if possible
	if (fDiscardUndo)
		ObjEditFreeUndo(lpObject, (UndoType & UT_NEWDATA) != 0,
						(UndoType & UT_NEWALPHA) != 0);

	// save state of undo failed flag
	fUndoFailed = lpObject->fUndoFailed;

	// Initialize the undo for this object
	if (!ObjEditInit(lpObject, UndoType))
		{
		// Undo initialization failed, so apply all objects that
		// were going to be initialized
		lpObject = NULL;
		while (lpObject = GetNextObject(lpObject, YES, NO))
			{
			// see if this is an object we are not editing
			if ((Target == ET_SELOBJECTS &&
				!IsSelectedObject(lpObject)) ||
				(Target == ET_OBJECT && lpObject != lpTargetObject))
				{
				continue;
				}
			lpObject->fUndoFailed = YES;
			lpObject->InitUndoType = 0;
			if (lpObject == lpBase)
				ObjEditApply(lpObject,
							(UndoType & UT_DATAUNDO) != 0,
							(UndoType & UT_ALPHAUNDO) != 0, NO);
			else
				ObjEditApply(lpObject, YES, YES, NO);
			}
		// if we have failed before
		if (fUndoFailed)
			return(TRUE);
		else
			{
			Message(IDS_NOUNDO);
			return(FALSE);
			}
		}
	lpObject->fUndoFailed = NO;
	lpObject->InitUndoType = UndoType;
	}
return( TRUE );
}
Example #9
0
static void ObjEditUndo(LPIMAGE lpImage, LPOBJECT lpObject, BOOL fUndoData, BOOL fUndoAlpha)
/***********************************************************************/
{
RECT rTemp;
BOOL fSelected, Resolution, fDeleted, fBase;
LPALPHA lpAlpha, lpTemp;
LPOBJECT lpNext;
int XSize, YSize;
int tempDataType;

lpAlpha = lpObject->lpAlpha;
fBase = lpObject == ImgGetBase(lpImage);
if (fUndoData && lpObject->DataDirty)
	{
	if (lpObject->DataUndoType & UT_RESOLUTION)
		Resolution = FrameResolution(lpObject->Pixmap.EditFrame);
	if (lpObject->DataUndoType & (UT_DATA|UT_NEWDATA))
		{
		PixmapEditUndo(&lpObject->Pixmap);
		if (fBase)
			{
			lpImage->npix = FrameXSize(ObjGetEditFrame(lpObject));
			lpImage->nlin = FrameYSize(ObjGetEditFrame(lpObject));
			if (lpObject->DataUndoType & UT_NEWDATA)
				{
				tempDataType = lpImage->DataType;
				lpImage->DataType = lpImage->UndoDataType;
				lpImage->UndoDataType = tempDataType;
				}
			}
		}
	if (lpObject->DataUndoType & UT_OBJECTRECT)
		{
		rTemp = lpObject->rObject;
		lpObject->rObject = lpObject->rUndoObject;
		lpObject->rUndoObject = rTemp;
		}
	if (lpObject->DataUndoType & UT_RESOLUTION)
		{
		FrameSetResolution( lpObject->Pixmap.EditFrame,
							lpObject->UndoResolution);
		lpObject->UndoResolution = Resolution;
		}
	if (lpObject->DataUndoType & UT_SELECTION)
		{
		fSelected = lpObject->fSelected;
		lpObject->fSelected = lpObject->fUndoSelected;
		lpObject->fUndoSelected = fSelected;
		}
	if (lpObject->DataUndoType & UT_DELETEOBJECTS)
		{
		lpNext = lpObject;
		while (lpNext = ImgGetNextObjectEx(lpImage, lpNext, YES, NO, YES))
			{
			if (lpNext->fUndoDeleted || lpNext->fDeleted)
				{
				fDeleted = lpNext->fDeleted;
				lpNext->fDeleted = lpNext->fUndoDeleted;
				lpNext->fUndoDeleted = fDeleted;
				}
			}
		}
	if (fBase && lpObject->DataUndoType & UT_MOVEOBJECTS)
		{
		lpNext = lpObject;
		while (lpNext = ImgGetNextObjectEx(lpImage, lpNext, YES, NO, NO))
			{
			rTemp = lpNext->rObject;
			lpNext->rObject = lpNext->rUndoObject;
			lpNext->rUndoObject = rTemp;
			}
		}
	lpObject->DataUndoNotRedo = !lpObject->DataUndoNotRedo;
	if (!fUndoAlpha)
		fUndoAlpha = lpObject->fBothDirty;
	}
else if (fUndoAlpha && lpObject->fBothDirty)
	fUndoAlpha = NO;

if (fUndoAlpha && lpObject->AlphaDirty)
	{
	if (lpAlpha)
		{
		if (lpObject->AlphaUndoType & (UT_ALPHA|UT_NEWALPHA))
			{
			PixmapEditUndo(&lpAlpha->Pixmap);
			rTemp = lpAlpha->rMask;
			lpAlpha->rMask = lpAlpha->rUndoMask;
			lpAlpha->rUndoMask = rTemp;
			}
		}
	if (lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK))
		{
		lpTemp = lpObject->lpAlpha;
		lpObject->lpAlpha = lpObject->lpUndoAlpha;
		lpObject->lpUndoAlpha = lpTemp;
		}
	lpObject->AlphaUndoNotRedo = !lpObject->AlphaUndoNotRedo;
	}
lpAlpha = lpObject->lpAlpha;
// check to make sure the mask is still the same size
if (fUndoData && fBase && lpObject->Pixmap.fNewFrame)
	{
	// we just undid to a different size frame bag mask delete undo
	if (lpObject->lpUndoAlpha && !lpObject->fBothDirty)
		ObjEditApply(lpImage, lpObject, NO, YES, NO);
	if (lpAlpha)
		{
		XSize = FrameXSize(lpAlpha->Pixmap.EditFrame);
		YSize = FrameYSize(lpAlpha->Pixmap.EditFrame);
		if (XSize != FrameXSize(lpObject->Pixmap.EditFrame) ||
			YSize != FrameYSize(lpObject->Pixmap.EditFrame))
			{
			ObjEditInit(lpImage, lpObject, UT_DELETEMASK);
			lpObject->fBothDirty = YES;
			lpObject->AlphaDirty = lpObject->DataDirty;
			lpObject->lpAlpha = NULL;
			}
		}
	}
}
Example #10
0
BOOL ImgEditInit( LPIMAGE lpImage, EDIT_TARGET Target, UNDO_TYPE UndoType,
				LPOBJECT lpTargetObject)
/***********************************************************************/
{
LPOBJECT lpObject, lpBase;
int retc;
BOOL fDiscardUndo = NO;
BOOL fUndoFailed;
BOOL fMaskEdit;

lpBase = ImgGetBase(lpImage);

lpObject = NULL;
while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO))
	lpObject->InitUndoType = 0;

// No mask undo's are allowed - so apply any that we have now
if (!Control.UndoMasks)
	ObjEditApply(lpImage, lpBase, NO, YES, NO);

// No undo's are allowed - so apply any that we have now
if (Control.NoUndo)
	{
	lpObject = NULL;
	while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO))
		ObjEditApply(lpImage, lpObject, YES, lpObject != lpBase, NO);
	}

if (!Control.MultipleObjects)
	UndoType &= ~UT_DELETEOBJECTS;

fMaskEdit = (Target == ET_OBJECT) && (lpTargetObject == lpBase) &&
			((UndoType & UT_ALPHAUNDO) != 0);

// see if any objects cannot have their undos freed without
// asking the user first, if so ask the user and get the response
// This is only a manual apply thing
if (UndoType & (UT_NEWDATA|UT_NEWALPHA) && Control.UseApply)
	{
	lpObject = NULL;
	fDiscardUndo = YES;
	while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO))
		{
		// see if this is an object we are not editing
		if ((Target == ET_SELOBJECTS &&
			!ImgIsSelectedObject(lpImage, lpObject)) ||
			(Target == ET_OBJECT && lpObject != lpTargetObject))
			continue;
		if (!ObjEditUndoDiscardable(lpObject, (UndoType & UT_NEWDATA) != 0,
											(UndoType & UT_NEWALPHA) != 0))
			{
			retc = AstralConfirm( IDS_OKTOAPPLY );
			if (retc == IDCANCEL)
				return(FALSE);
			fDiscardUndo = retc == IDYES;
			break;
			}
		}
	}

// now loop through the objects initializing their undos
lpObject = NULL;
while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO))
	{
	// see if this is an object we are not editing
	if ((Target == ET_SELOBJECTS && !ImgIsSelectedObject(lpImage, lpObject)) ||
		(Target == ET_OBJECT && lpObject != lpTargetObject))
		{
		// if no individual undo's, wack any undo buffers
		// if in auto apply or in manual apply and state is redo
		// Objects that are not the base need to also have
		// their alphas wacked if this is not a mask edit 
		if (!Control.UndoObjects && (!Control.UseApply ||
				( Control.UseApply && !lpObject->DataUndoNotRedo ) ) )
			ObjEditApply(lpImage, lpObject, !fMaskEdit,
 				(lpObject != lpBase) && !fMaskEdit, NO);
		continue;
		}

	// Discard it's undo if possible
	if (fDiscardUndo)
		ObjEditFreeUndo(lpObject, (UndoType & UT_NEWDATA) != 0,
						(UndoType & UT_NEWALPHA) != 0);

	// save state of undo failed flag
	fUndoFailed = lpObject->fUndoFailed;

	// Initialize the undo for this object
	if (!ObjEditInit(lpImage, lpObject, UndoType))
		{
		// Undo initialization failed, so apply all objects that
		// were going to be initialized
		lpObject = NULL;
		while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO))
			{
			// see if this is an object we are not editing
			if ((Target == ET_SELOBJECTS &&
				!ImgIsSelectedObject(lpImage, lpObject)) ||
				(Target == ET_OBJECT && lpObject != lpTargetObject))
				{
				continue;
				}
			lpObject->fUndoFailed = YES;
			lpObject->InitUndoType = 0;
			if (lpObject == lpBase)
				ObjEditApply(lpImage, lpObject,
							(UndoType & UT_DATAUNDO) != 0,
							(UndoType & UT_ALPHAUNDO) != 0, NO);
			else
				ObjEditApply(lpImage, lpObject, YES, YES, NO);
			}
		// if we have failed before
		if (fUndoFailed)
			return(TRUE);
		else
			{
			Message(IDS_NOUNDO);
			return(FALSE);
			}
		}
	lpObject->fUndoFailed = NO;
	lpObject->InitUndoType = UndoType;
	}
return( TRUE );
}