Beispiel #1
0
int CImage::GetDirtyState()
{
LPOBJECT lpObject = NULL;
int dirty = NO;
int ObjDirty;

while (lpObject = GetNextObject(lpObject, YES, NO))
    {
    if (Control.UndoObjects && !IsSelectedObject(lpObject))
        continue;
    if (lpObject->DataDirty)
        ObjDirty = lpObject->DataDirty;
    else if ((lpObject != GetBase()) && lpObject->lpAlpha &&
            lpObject->AlphaDirty)
        ObjDirty = lpObject->AlphaDirty;
    else
        continue;
    if (!dirty)
        dirty = ObjDirty;
    else if (ObjDirty != dirty)
        return(IDS_EDITS);
    }
return(dirty);
}
Beispiel #2
0
BOOL CImage::GetUndoState()
{
LPOBJECT lpObject = NULL;
BOOL ObjUndoNotRedo;
int UndoNotRedo = -1;

while (lpObject = GetNextObject(lpObject, YES, NO))
    {
    if (Control.UndoObjects && !IsSelectedObject(lpObject))
        continue;
    if (lpObject->DataDirty)
        ObjUndoNotRedo = lpObject->DataUndoNotRedo;
    else if ((lpObject != GetBase()) && lpObject->lpAlpha &&
            lpObject->AlphaDirty)
        ObjUndoNotRedo = lpObject->AlphaUndoNotRedo;
    else
        continue;
    if (UndoNotRedo < 0)
        UndoNotRedo = ObjUndoNotRedo;
    else if (ObjUndoNotRedo != UndoNotRedo)
        return(TRUE);
    }
return(UndoNotRedo);
}
Beispiel #3
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 );
}
Beispiel #4
0
void CImage::EditUndo( BOOL fEditUndo, BOOL fMaskUndo,
					LPUPDATE_TYPE lpUpdateType, LPRECT lpUpdateRect)
{
RECT rUndo, rUndoMask, rTemp;
LPOBJECT lpBase, lpObject, lpNext;
BOOL fNewSize, fSetupMiniViews, fRemoveMarquee, fUndoDelete, fColorMapChanged;
BOOL fUndoAlpha, fUndoData;
int nDeleted;
LPMASK lpMask;
EDIT_TARGET Target;

AstralSetRectEmpty(lpUpdateRect);

// Initialize things for updating the display
fNewSize = fSetupMiniViews = fUndoDelete = fColorMapChanged = NO;
AstralSetRectEmpty(&rUndo);
AstralSetRectEmpty(&rUndoMask);

// loop through objects doing undo
lpBase = GetBase();
lpObject = NULL;
// get the target of the last edit
Target = EditTarget;
while (lpObject = GetNextObject(lpObject, NO, NO, fEditUndo))
	{
	// See if this is an object we are undoing
	if (fEditUndo)
		{
		// check for special undo processing of a deleted object
		if (lpObject->fDeleted) 
			continue; // do no undo processing for a deleted object
//			{
//			if (Control.UndoObjects && !IsSelectedObject(lpBase))
//				continue;
//			}
		else
		// if target is not the entire image and we are in undo
		// object mode and the object is not selected then
		// skip this object
		if (Target != ET_ALLOBJECTS && Control.UndoObjects && !IsSelectedObject(lpObject))
			continue;
		}
	// Only handle mask undo for the base object
	if (fMaskUndo)
		{
		if (lpObject != lpBase || lpObject->fBothDirty ||
			!lpObject->AlphaDirty)
		continue;
		}

	fUndoData = fUndoAlpha = NO;

	// Do preprocess for doing a data undo
	if (fEditUndo)
		{
		if (lpObject->DataDirty)
			fUndoData = YES;
		// See if we need to undo the alpha for this object
		if ((lpObject != lpBase) && lpObject->lpAlpha && lpObject->AlphaDirty)
			fUndoAlpha = YES;
		if (!fUndoData && !fUndoAlpha)
			continue;
	
		// check to see and undoing/redoing deleted objects will change
		// the select state, if so undraw the object marquee
		if (lpObject == lpBase &&
			lpObject->DataUndoType & UT_DELETEOBJECTS)
			{
			fUndoDelete = YES;
			fRemoveMarquee = NO;
			nDeleted = 0;
			lpNext = lpObject;
			while (lpNext = GetNextObject(lpNext, YES, NO, YES))
				{
				if (lpNext->fUndoDeleted)
					++nDeleted;
				else
				if (lpNext->fDeleted && lpNext->fSelected)
					{
					fRemoveMarquee = YES;
					break;
					}
				}
			if (GetSelObject(NULL) == lpBase && !fRemoveMarquee)
				{
				if (CountObjects() - nDeleted <= 1)
					fRemoveMarquee = YES;
				}
			if (fRemoveMarquee)
				{
				GetObjectMarqueeRect(this, &rTemp);
				AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp);
				}
			}
		}
	else // fMaskUndo
	if (!lpObject->AlphaDirty)
		continue;
	else
		fUndoAlpha = YES;

	// do a preprocess for undoing the mask caused either by
	// a mask undo or by an edit function that also edits the mask
	if (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) ||
		fMaskUndo)
		{
		if ( lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) )
			{
			// if the undo is going to delete the mask,
			// we need to undraw the mask
			if (GetMask())
				{
				GetMaskMarqueeRect(this, &rTemp);
				AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp);
				if (GetMaskUpdateRect(YES, NO, &rTemp))
					AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp);
				}
			// if the undo is going to create the mask,
			// we need to undraw the object marquees if
			// not in mask and object marquee mode
			else
				{
				if (!Control.UseMaskAndObjects)
					{
					GetObjectMarqueeRect(this, &rTemp);
					AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp);
					}
				}
			}
		}

	// Actually do the undo
	ObjEditUndo(lpObject, fUndoData, fUndoAlpha);

	// do a postprocess for undoing the mask
	if ((lpMask = GetMask()) &&
		(((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) ||
		fMaskUndo))
		{
		// if the undo is going to add the mask, we need to redraw the mask
		if (lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) )
			{
			if (GetMaskUpdateRect(YES, NO, &rTemp))
				AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp);
			}
		else
			// just redraw the undo area for the mask
			AstralUnionRect(&rUndoMask, &rUndoMask, &lpMask->Pixmap.UndoRect);
		}

	// Setup rectangle for undoing deletion of objects
	// Handled specially so that moved objects will still undo
	// and redo properly
	if (fEditUndo)
		{
		if (lpObject == lpBase &&
			lpObject->DataUndoType & UT_DELETEOBJECTS)
			{
			lpNext = lpObject;
			while (lpNext = GetNextObject(lpNext, YES, NO, YES))
				{
				if (lpNext->fDeleted || lpNext->fUndoDeleted)
					AstralUnionRect(&rUndo, &rUndo, &lpNext->rObject);
				}
			fSetupMiniViews = YES;
			}
		if (lpObject->DataUndoType & UT_COLORMAP)
			fColorMapChanged = YES;

		if (lpObject->Pixmap.fNewFrame)
			{
			/* if new frame, cause window to be redisplayed */
			if (lpObject == lpBase)
				fNewSize = YES;
			else
				{
				if (!fNewSize)
					{
					AstralUnionRect(&rUndo, &rUndo, &lpObject->rObject);
					AstralUnionRect(&rUndo, &rUndo, &lpObject->rUndoObject);
					}
				}
			}
		else
			{
			AstralSetRectEmpty(&rTemp);
			if (fUndoData)
				AstralUnionRect(&rTemp, &rTemp, &lpObject->Pixmap.UndoRect);
			if (fUndoAlpha)
				AstralUnionRect(&rTemp, &rTemp,
						&lpObject->lpAlpha->Pixmap.UndoRect);
			if (rTemp.right >= rTemp.left)
				{
				if (!fNewSize)
					{
					OffsetRect(&rTemp, lpObject->rObject.left,
							lpObject->rObject.top);
					AstralUnionRect(&rUndo, &rUndo, &rTemp);
					}
				}
			if( lpObject->DataUndoType & UT_OBJECTRECT )
				{
				AstralUnionRect( &rUndo, &rUndo,	&lpObject->rObject );
				AstralUnionRect( &rUndo, &rUndo,	&lpObject->rUndoObject );
				}
			}
		}
	}

// now redisplay whatever changes are necessary for the undo
if (fColorMapChanged)
	{
	ImgColorMapChanged(this);
	*lpUpdateType |= UT_DATATYPE;
	}

if (fNewSize)
	{
	*lpUpdateType |= UT_DATATYPE;
	if (lpBase->Pixmap.UndoFrame)
		{
		if ((FrameXSize(lpBase->Pixmap.UndoFrame) ==
			FrameXSize(lpBase->Pixmap.EditFrame)) &&
			(FrameYSize(lpBase->Pixmap.UndoFrame) ==
			FrameYSize(lpBase->Pixmap.EditFrame)))
			fNewSize = NO;
		}
	if (fNewSize)
		*lpUpdateType |= UT_SIZE;
	else
		{
		int dx, dy;

		GetInfo(&dx, &dy, NULL, NULL);
		SetRect(lpUpdateRect, 0, 0, dx-1, dy-1);
		}
	}
else
	{
	if (!AstralIsRectEmpty(lpUpdateRect))
		*lpUpdateType |= UT_ACTIVEAREA;
	if (rUndoMask.right >= rUndoMask.left)
		{
		*lpUpdateType |= UT_ACTIVEAREA;
		AstralUnionRect(lpUpdateRect, lpUpdateRect, &rUndoMask);
		}
	if (rUndo.right >= rUndo.left)
		{
		*lpUpdateType |= UT_AREA;
		AstralUnionRect(lpUpdateRect, lpUpdateRect, &rUndo);
		}
	}
}