home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-11 | 80.7 KB | 2,751 lines | [TEXT/MPS ] |
- /*
- File: ShapeCommands.cpp
-
- Contains: Shape command Classes Implementation
-
- Written by: Dave Stafford
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
- */
-
- // -- Compiler/Preprocessor Switches --
-
- #ifndef _COMPILERDEFS_
- #include "CompDefs.h"
- #endif
-
- // -- DrawEditor Includes --
-
- #ifndef _PROMISE_
- #include "Promise.h"
- #endif
-
- #ifndef _SHAPECOMMANDS_
- #include "ShapeCommands.h"
- #endif
-
- #ifndef _SHAPES_
- #include "Shapes.h"
- #endif
-
- #ifndef _SELECTION_
- #include "Selection.h"
- #endif
-
- #ifndef _DRAWEDITORGLOBALS_
- #include "DrawEditorGlobals.h"
- #endif
-
- #ifndef _DRAWEDITOR_
- #include "DrawEditor.h"
- #endif
-
- #ifndef _DRAWEDITORUTILS_
- #include "DrawEditorUtils.h"
- #endif
-
- #ifndef _PALETTE_
- #include "Palette.h"
- #endif
-
- #ifndef _LINK_
- #include "Link.h"
- #endif
-
- // -- OpenDoc Includes --
-
- // for ODName and ODByteArray
- #ifndef _ODTYPES_
- #include <ODTypes.h>
- #endif
-
- #ifndef SOM_ODClipboard_xh
- #include <Clipbd.xh>
- #endif
-
- #ifndef SOM_ODCMDDefs_xh
- #include <CMDDefs.xh>
- #endif
-
- #ifndef SOM_ODDragAndDrop_xh
- #include <DragDrp.xh>
- #endif
-
- #ifndef SOM_ODDragItemIterator_xh
- #include <DgItmIt.xh>
- #endif
-
- #ifndef SOM_ODUndo_xh
- #include <Undo.xh>
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODLinkSpec_xh
- #include <LinkSpec.xh>
- #endif
-
- #ifndef SOM_ODLink_xh
- #include <Link.xh>
- #endif
-
- // -- OpenDoc Utilities --
-
- #ifndef _ODUTILS_
- #include "ODUtils.h"
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #ifndef _ITEXT_
- #include "IText.h"
- #endif
-
- #ifndef _ORDCOLL_
- #include "OrdColl.h"
- #endif
-
- #ifndef _FOCUSLIB_
- #include "FocusLib.h"
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef _ODMEMORY_
- #include "ODMemory.h" // ODDisposePtr
- #endif
-
- #ifndef _ISOSTR_
- #include "ISOStr.h" // ODISOStrFromCStr
- #endif
-
- // -- Toolbox Includes --
-
- #ifndef mathRoutinesIncludes
- #include <math routines.h>
- #endif
-
- #ifndef __MEMORY__
- #include <memory.h>
- #endif
-
- #ifndef __OSUTILS__
- #include <OSUtils.h>
- #endif
-
-
-
- // **************************** Need to improve Handling of Failure **********************
-
- //=============================================================================
- // CModifySelectionCommand
- //=============================================================================
- CModifySelectionCommand::CModifySelectionCommand( DrawEditor* theEditor,
- CSelection* selection,
- ODBoolean canUndo,
- ODBoolean changesContent,
- ODID undoTextIndex,
- ODID redoTextIndex) :
- CCommand(theEditor, canUndo, changesContent, undoTextIndex, redoTextIndex)
- {
- fSelection = selection;
- fSavedShapes = kODNULL;
- fSubscribeLinks = kODNULL;
- }
-
-
- //=============================================================================
- // CModifySelectionCommand
- //=============================================================================
- CModifySelectionCommand::~CModifySelectionCommand()
- {
- if (fSavedShapes)
- {
- delete fSavedShapes;
- fSavedShapes = kODNULL;
- }
-
- if (fSubscribeLinks)
- {
- delete fSubscribeLinks;
- fSubscribeLinks = kODNULL;
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CModifySelectionCommand::CaptureCommandState
- //
- // Here you want to make a copy of the selection so that derivative commands can
- // handle undo/redo correctly.
- //-----------------------------------------------------------------------------
-
- void CModifySelectionCommand::CaptureCommandState(Environment* ev)
- {
- // A move to another part is the only Undo-able drag action,
- // So save undo state here in that case.
-
- // Only a cut is undo-able, but a copy needs to make the shape and subscribe link lists
- // available to the pending publish link.
-
- fSavedShapes = new COrderedList;
- COrdListIterator iter(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- if (!shape->IsSubscribed())
- fSavedShapes->AddLast(shape);
- }
-
- fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
- }
-
- //-----------------------------------------------------------------------------
- // CModifySelectionCommand::UndoCommand
- //-----------------------------------------------------------------------------
-
- void CModifySelectionCommand::UndoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::UndoCommand(ev);
-
- // Add the saved shapes to the selection
- this->SelectModifiedShapes(ev);
-
- // Call selection changed before adding back any publishers. That way,
- // They won't be updated. Publishers that are entirely contained in content
- // being removed should not propagate updates, therefore don't need to when they
- // are added back in again.
-
- fSelection->SelectedContentUpdated(ev);
-
- }
-
-
- //-----------------------------------------------------------------------------
- // CModifySelectionCommand::RedoCommand
- //-----------------------------------------------------------------------------
-
- void CModifySelectionCommand::RedoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::RedoCommand(ev);
-
- // Select saved shapes
- this->SelectModifiedShapes(ev);
- }
-
- //-----------------------------------------------------------------------------
- // CModifySelectionCommand::SelectModifiedShapes
- //-----------------------------------------------------------------------------
-
- void CModifySelectionCommand::SelectModifiedShapes(Environment* ev)
- {
- fSelection->CloseSelection(ev);
-
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- fSelection->AddToSelection(ev, shape, kODFalse);
- }
-
- COrdListIterator iter2(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
- iter2.IsNotComplete();
- link = (CSubscribeLink*)iter2.Next())
- {
- link->AddToSelection(ev, kODFalse);
- }
- }
-
-
- //=============================================================================
- // CNewShapeCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CNewShapeCommand::CNewShapeCommand
- //-----------------------------------------------------------------------------
-
- CNewShapeCommand::CNewShapeCommand( DrawEditor* theEditor,
- ODFacet* sourceFacet,
- Rect& bounds,
- CRGBColor& color,
- ODSShort shapeType,
- CSelection* selection) :
- CCommand(theEditor, kODTrue, kODTrue, kUndoNewShapeIndex, kRedoNewShapeIndex)
- {
- fShapeColor = color;
- fShapeBounds = bounds;
- fShape = kODNULL;
- fSelection = selection;
- fShapeType = shapeType;
- fSourceFacet = sourceFacet;
- }
-
-
- //-----------------------------------------------------------------------------
- // CNewShapeCommand::~CNewShapeCommand
- //-----------------------------------------------------------------------------
-
- CNewShapeCommand::~CNewShapeCommand()
- {
- fDrawEditor = kODNULL;
- fSourceFacet = kODNULL;
- }
-
- //-----------------------------------------------------------------------------
- // CNewShapeCommand::DoCommand
- //-----------------------------------------------------------------------------
-
- void CNewShapeCommand::DoCommand(Environment* ev)
- {
- // Call inherited
- CCommand::DoCommand(ev);
-
- // We are creating a new shape. The new shape
- // should be the only thing selected afterwards
- fSelection->CloseSelection(ev);
-
- // If the shapetype is kEmbeddingShape then
- // construct on of those,
- if (fShapeType==kEmbeddingShape)
- {
- // The user is requesting a text shape
- // Call the draft to create a part of the kind we are interested in
- ODPart* textPart = fDrawEditor->GetDraft(ev)->CreatePart(ev, gGlobals->fCurrentTextPartKind, kODNULL);
- THROW_IF_NULL(textPart);
-
- // We must externalize the newly created part, so that it will have
- // a valid contents property
- textPart->Externalize(ev);
-
- // Create a content shape
- fShape = fDrawEditor->CreateShape(ev, fShapeType, fShapeBounds);
-
- // Embed the part, CEmbeddingShape::Embed will release the part passed to it.
- ((CEmbeddingShape*)fShape)->Embed(ev, textPart, fSourceFacet->GetFrame(ev), kODNULL);
-
- // Release the newly created part
- ODReleaseObject(ev, textPart);
- }
- else
- {
- // Otherwise, Create a regular shape.
- fShape = fDrawEditor->CreateShape(ev, fShapeType, fShapeBounds);
- THROW_IF_NULL(fShape);
-
- fShape->SetColor(fShapeColor);
- }
-
- // Add the shape to the content list
- fDrawEditor->AddShape(ev, fShape);
-
- // Add the shape to the selection
- fSelection->AddToSelection(ev, fShape, kODTrue);
-
- fDrawEditor->ContentUpdated(ev, kODNULL);
- }
-
-
- //-----------------------------------------------------------------------------
- // CNewShapeCommand::UndoCommand
- //-----------------------------------------------------------------------------
-
- void CNewShapeCommand::UndoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::UndoCommand(ev);
-
- fSelection->RemoveFromSelection(ev, fShape, kODTrue);
- fDrawEditor->RemoveShape(ev, fShape);
-
- fDrawEditor->ContentUpdated(ev, kODNULL);
- }
-
-
- //-----------------------------------------------------------------------------
- // CNewShapeCommand::RedoCommand
- //-----------------------------------------------------------------------------
-
- void CNewShapeCommand::RedoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::RedoCommand(ev);
-
- // Add the shape to the selection
- fSelection->AddToSelection(ev, fShape, kODTrue);
- fDrawEditor->AddShape(ev, fShape);
-
- fDrawEditor->ContentUpdated(ev, kODNULL);
- }
-
-
- //-----------------------------------------------------------------------------
- // CNewShapeCommand::Commit
- //
- // Here you want to clean up command specific structures depnding on the value of state.
- // For example, if a command creates a new piece of content and is comitted after being undone
- // then it should delete the structure representing the new content. Otherwise, it should not
- // deleted.
- //-----------------------------------------------------------------------------
-
- void CNewShapeCommand::Commit(Environment* ev, ODDoneState state)
- {
- CCommand::Commit(ev, state);
-
- // Create temp list to pass to CheckAndResolvePromisedShapes
- COrderedList tList;
- tList.AddLast(fShape);
- CheckAndResolvePromisedShapes(ev, &tList, fDrawEditor->GetSession(ev));
-
- // If the command was undone, then delete the shape
- if ((state==kODUndone)&&(fShape))
- {
- fShape->SetInLimbo(ev, kODTrue);
- fShape->Removed(ev, kCommit);
- delete fShape;
- }
- fShape = kODNULL;
- }
-
-
- //-----------------------------------------------------------------------------
- // CNewShapeCommand::CaptureCommandState
- //
- // Here you want to save off any state info necessary for the command to be able to undo/redo.
- // Example: You might make a copy of a list of references to content that is being operated on
- // by the command.
- //-----------------------------------------------------------------------------
-
- void CNewShapeCommand::CaptureCommandState(Environment* ev)
- {
-
- }
-
- //=============================================================================
- // CMoveShapeCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CMoveShapeCommand::CMoveShapeCommand
- //
- // Since this command is used for four different actions, we pass zeroes to
- // the base class for undo/redo string IDs and set them to the correct values
- // later.
- //-----------------------------------------------------------------------------
-
- CMoveShapeCommand::CMoveShapeCommand(DrawEditor* theEditor,
- ODFrame* sourceFrame,
- ODCommandID moveType,
- CSelection* selection) :
- CCommand(theEditor, kODTrue, kODTrue,
- 0, 0)
- {
- fMoveType = moveType;
- fSelection = selection;
- fSourceFrame = sourceFrame;
- fSavedShapes = kODNULL;
-
- // Set up the correct undo/redo strings for this instance of the command
- switch ( fMoveType )
- {
- // Drawing Commands
- case kMoveForwardCmd:
- this->SetMenuTextIDs(kUndoMoveForwardIndex, kRedoMoveForwardIndex);
- break;
-
- case kMoveFrontCmd:
- this->SetMenuTextIDs(kUndoMoveFrontIndex, kRedoMoveFrontIndex);
- break;
-
- case kMoveBackwardCmd:
- this->SetMenuTextIDs(kUndoMoveBackwardIndex, kRedoMoveBackwardIndex);
- break;
-
- case kMoveBackCmd:
- this->SetMenuTextIDs(kUndoMoveBackIndex, kRedoMoveBackIndex);
- break;
-
- default:
- THROW(kODErrInvalidParameter, "Passed invalid move type to move shape command!");
- }
-
- }
-
-
- //-----------------------------------------------------------------------------
- // CMoveShapeCommand::~CMoveShapeCommand
- //-----------------------------------------------------------------------------
-
- CMoveShapeCommand::~CMoveShapeCommand()
- {
- fDrawEditor = NULL;
- fSourceFrame = NULL;
-
- if (fSavedShapes)
- {
- delete fSavedShapes;
- fSavedShapes = kODNULL;
- }
- }
-
- //-----------------------------------------------------------------------------
- // CMoveShapeCommand::MoveShape
- //-----------------------------------------------------------------------------
-
- void CMoveShapeCommand::MoveShape(Environment* ev, CShape* moveShape, CShape* shape)
- {
- switch ( fMoveType )
- {
- // Drawing Commands
- case kMoveForwardCmd:
- case kMoveFrontCmd:
- fDrawEditor->MoveShapeBefore(ev, moveShape, shape);
- break;
-
- case kMoveBackwardCmd:
- case kMoveBackCmd:
- fDrawEditor->MoveShapeAfter(ev, moveShape, shape);
- break;
-
- default:
- THROW(kODErrInvalidParameter, "Passed invalid move type to move shape command!");
- }
- }
-
- //-----------------------------------------------------------------------------
- // CMoveShapeCommand::FindReferenceShape
- //-----------------------------------------------------------------------------
-
- CShape* CMoveShapeCommand::FindReferenceShape(Environment* ev, CShape* moveShape)
- {
- COrderedList* tShapeList = fDrawEditor->GetShapeList();
-
- switch ( fMoveType )
- {
- // Drawing Commands
- case kMoveForwardCmd:
- return (CShape*)tShapeList->Before(moveShape);
- break;
-
- case kMoveFrontCmd:
- return (CShape*)tShapeList->First();
- break;
-
- case kMoveBackwardCmd:
- return (CShape*)tShapeList->After(moveShape);
- break;
-
- case kMoveBackCmd:
- return (CShape*)tShapeList->Last();
- break;
-
- default:
- THROW(kODErrInvalidParameter, "Passed invalid move type to move shape command!");
- }
-
- return kODNULL;
- }
-
- //-----------------------------------------------------------------------------
- // CMoveShapeCommand::DoCommand
- //-----------------------------------------------------------------------------
-
- void CMoveShapeCommand::DoCommand(Environment* ev)
- {
- // Call inherited
- CCommand::DoCommand(ev);
-
- // If any of the shapes in the selection we are operating on have
- // already been promised t othe clipboard, then we need to resolve
- // the promise on the clipoard to ensure that it will not be corrupted.
- if (fSelection->IsPromisedToClipboard())
- {
- ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
- }
-
- COrdListIterator ite(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- CShape* tShape = this->FindReferenceShape(ev, shape);
-
- // The way the MoveShape method actually moves a shape is to first remove
- // it from the list, then add it back to the list relative to the ref
- // shape. Well, obviously, if the ref & move shapes are the same shape
- // this will *not* work.
- if (shape!=tShape)
- this->MoveShape(ev, shape, tShape);
- }
-
- fSelection->InvalidateSelection(ev, fSourceFrame);
- fSelection->SelectedContentUpdated(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CMoveShapeCommand::UndoCommand
- //-----------------------------------------------------------------------------
-
- void CMoveShapeCommand::UndoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::UndoCommand(ev);
-
- // Get the first saved shape and reset the iter
- COrdListIterator savedShapeIter(fSavedShapes);
- CShape* tShape = (CShape*)savedShapeIter.First();
-
- COrdListIterator ite(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- if (tShape!=kODNULL)
- fDrawEditor->MoveShapeBefore(ev, shape, tShape);
-
- CShape* tShape = (CShape*)savedShapeIter.Next();
- }
-
- fSelection->InvalidateSelection(ev, fSourceFrame);
- fSelection->SelectedContentUpdated(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CMoveShapeCommand::RedoCommand
- //-----------------------------------------------------------------------------
-
- void CMoveShapeCommand::RedoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::RedoCommand(ev);
-
- COrdListIterator ite(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- CShape* tShape = this->FindReferenceShape(ev, shape);
-
- // The way the MoveShape method actually moves a shape is to first remove
- // it from the list, then add it back to the list relative to the ref
- // shape. Well, obviously, if the ref & move shapes are the same shape
- // this will *not* work.
- if (shape!=tShape)
- this->MoveShape(ev, shape, tShape);
- }
-
- fSelection->InvalidateSelection(ev, fSourceFrame);
- fSelection->SelectedContentUpdated(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CMoveShapeCommand::Commit
- //
- // Here you want to clean up command specific structures depending on the value of state.
- // For example, if a command creates a new piece of content and is comitted after being undone
- // then it should delete the structure representing the new content. Otherwise, it should not
- // deleted.
- //-----------------------------------------------------------------------------
-
- void CMoveShapeCommand::Commit(Environment* ev, ODDoneState state)
- {
- CCommand::Commit(ev, state);
- }
-
-
- //-----------------------------------------------------------------------------
- // CMoveShapeCommand::CaptureCommandState
- //
- // Here you want to save off any state info necessary for the command to be able to undo/redo.
- // Example: You might make a copy of a list of references to content that is being operated on
- // by the command.
- //-----------------------------------------------------------------------------
-
- void CMoveShapeCommand::CaptureCommandState(Environment* ev)
- {
- // List of shapes being operated on
- COrderedList* tShapeList = fDrawEditor->GetShapeList();
-
- // Allocate a list to store shapes for undo/redo
- fSavedShapes = new COrderedList;
-
- // Save off the "after" shape of each shape in the selection
- // so we can reconstitute the correct order when a "redo" occurs.
- COrdListIterator ite(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- CShape* tShape = (CShape*)tShapeList->After(shape);
- fSavedShapes->AddFirst(tShape);
- }
-
- }
-
-
- //=============================================================================
- // CResizeSelectionCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CResizeSelectionCommand::CResizeSelectionCommand
- //-----------------------------------------------------------------------------
-
- CResizeSelectionCommand::CResizeSelectionCommand(DrawEditor* theEditor,
- ODFacet* sourceFacet,
- CSelection* selection,
- Rect& baseRect,
- Rect& resizeRect) :
- CModifySelectionCommand(theEditor, selection, kODTrue, kODTrue, kUndoResizeIndex, kRedoResizeIndex)
- {
- fBaseRect = baseRect;
- fResizeRect = resizeRect;
-
- fSourceFacet = sourceFacet;
- fDrawEditor = theEditor;
- }
-
-
- //-----------------------------------------------------------------------------
- // CResizeSelectionCommand::~CResizeSelectionCommand
- //-----------------------------------------------------------------------------
-
- CResizeSelectionCommand::~CResizeSelectionCommand()
- {
- }
-
-
- //-----------------------------------------------------------------------------
- // CResizeSelectionCommand::DoCommand
- //-----------------------------------------------------------------------------
-
- void CResizeSelectionCommand::DoCommand(Environment* ev)
- {
- // Call inherited
- CCommand::DoCommand(ev);
-
- // If any of the shapes in the selection we are operating on have
- // already been promised t othe clipboard, then we need to resolve
- // the promise on the clipoard to ensure that it will not be corrupted.
- if (fSelection->IsPromisedToClipboard())
- {
- ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
- }
-
- fSelection->ResizeSelection(ev, fSourceFacet->GetFrame(ev), fBaseRect, fResizeRect);
- fSelection->SelectedContentUpdated(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CResizeSelectionCommand::UndoCommand
- //-----------------------------------------------------------------------------
-
- void CResizeSelectionCommand::UndoCommand(Environment* ev)
- {
- // Call Inherited
- CModifySelectionCommand::UndoCommand(ev);
-
- fSelection->ResizeSelection(ev, fSourceFacet->GetFrame(ev), fResizeRect, fBaseRect);
- fSelection->SelectedContentUpdated(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CResizeSelectionCommand::RedoCommand
- //-----------------------------------------------------------------------------
-
- void CResizeSelectionCommand::RedoCommand(Environment* ev)
- {
- // Call Inherited
- CModifySelectionCommand::RedoCommand(ev);
-
- fSelection->ResizeSelection(ev, fSourceFacet->GetFrame(ev), fBaseRect, fResizeRect);
- fSelection->SelectedContentUpdated(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CResizeSelectionCommand::Commit
- //
- // Here you want to clean up command specific structures depnding on the value of state.
- // For example, if a command creates a new piece of content and is comitted after being undone
- // then it should delete the structure representing the new content. Otherwise, it should not
- // deleted.
- //-----------------------------------------------------------------------------
-
- void CResizeSelectionCommand::Commit(Environment* ev, ODDoneState state)
- {
- CCommand::Commit(ev, state);
- }
-
-
- //-----------------------------------------------------------------------------
- // CResizeSelectionCommand::CaptureCommandState
- //
- // Here you want to save off any state info necessary for the command to be able to undo/redo.
- // Example: You might make a copy of a list of references to content that is being operated on
- // by the command.
- //-----------------------------------------------------------------------------
-
- void CResizeSelectionCommand::CaptureCommandState(Environment* ev)
- {
- CModifySelectionCommand::CaptureCommandState(ev);
- }
-
-
- //=============================================================================
- // CColorSelectionCommand::CColorSelectionCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CColorSelectionCommand::CColorSelectionCommand
- //-----------------------------------------------------------------------------
-
- CColorSelectionCommand::CColorSelectionCommand(DrawEditor* theEditor,
- CSelection* selection,
- CRGBColor& newColor) :
- CCommand(theEditor, kODTrue, kODTrue, kUndoColorChangeIndex, kRedoColorChangeIndex)
- {
- fColor = newColor;
-
- fSavedColors = new COrderedList;
- fDrawEditor = theEditor;
- fSelection = selection;
- }
-
-
- //-----------------------------------------------------------------------------
- // CColorSelectionCommand::~CRGBColorSelectionCommand
- //-----------------------------------------------------------------------------
-
- CColorSelectionCommand::~CColorSelectionCommand()
- {
- if (fSavedColors)
- {
- fSavedColors->DeleteAllLinks();
- delete fSavedColors;
- }
- }
-
-
- //-----------------------------------------------------------------------------
- //CColorSelectionCommand::DoCommand
- //-----------------------------------------------------------------------------
-
- void CColorSelectionCommand::DoCommand(Environment* ev)
- {
- // Call inherited
- CCommand::DoCommand(ev);
-
- // If any of the shapes in the selection we are operating on have
- // already been promised t othe clipboard, then we need to resolve
- // the promise on the clipoard to ensure that it will not be corrupted.
- if (fSelection->IsPromisedToClipboard())
- {
- ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
- }
-
- COrdListIterator iter(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
- {
- // Save the old rectangle for undo
- CRGBColor* savedColor = new CRGBColor(*shape->GetColor());
- fSavedColors->AddLast(savedColor);
-
- // Invalidate old shape
- fDrawEditor->InvalidateShape(ev, shape);
-
- // Recolor the shape
- shape->SetColor(fColor);
-
- // Draw new shape
- fDrawEditor->InvalidateShape(ev, shape);
- }
- fSelection->SelectedContentUpdated(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CColorSelectionCommand::UndoCommand
- //-----------------------------------------------------------------------------
-
- void CColorSelectionCommand::UndoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::UndoCommand(ev);
-
-
- COrdListIterator iter2(fSavedColors);
- CRGBColor* saved = (CRGBColor*)iter2.First();
-
- COrdListIterator iter(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- // Reset the shapes bounds to the pre-resized rectangle
- shape->SetColor(*saved);
-
- // Redraw shape
- fDrawEditor->InvalidateShape(ev, shape);
-
- saved = (CRGBColor*)iter2.Next();
- }
- fSelection->SelectedContentUpdated(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CColorSelectionCommand::RedoCommand
- //-----------------------------------------------------------------------------
-
- void CColorSelectionCommand::RedoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::RedoCommand(ev);
-
- COrdListIterator iter(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
- {
- // Don't need to save off the rects here because we already did in the DoCommand method
-
- // Restore shape color
- shape->SetColor(fColor);
-
- // Redraw shape
- fDrawEditor->InvalidateShape(ev, shape);
- }
- fSelection->SelectedContentUpdated(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CColorSelectionCommand::Commit
- //
- // Here you want to clean up command specific structures depnding on the value of state.
- // For example, if a command creates a new piece of content and is comitted after being undone
- // then it should delete the structure representing the new content. Otherwise, it should not
- // deleted.
- //-----------------------------------------------------------------------------
-
- void CColorSelectionCommand::Commit(Environment* ev, ODDoneState state)
- {
- CCommand::Commit(ev, state);
- }
-
-
- //-----------------------------------------------------------------------------
- //CColorSelectionCommand::CaptureCommandState
- //
- // Here you want to save off any state info necessary for the command to be able to undo/redo.
- // Example: You might make a copy of a list of references to content that is being operated on
- // by the command.
- //-----------------------------------------------------------------------------
-
- void CColorSelectionCommand::CaptureCommandState(Environment* ev)
- {
-
- }
-
-
- //=============================================================================
- // CDragShapeCommand::CDragShapeCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::CDragShapeCommand
- //-----------------------------------------------------------------------------
-
- CDragShapeCommand::CDragShapeCommand(DrawEditor* theEditor,
- ODFacet* sourceFacet,
- CSelection* selection,
- ODEventData* event,
- ODBoolean showFeedBack,
- ODBoolean canUndo) :
- // CCommand(theEditor, canUndo, kODFalse, kUndoCommandIndex, kRedoCommandIndex)
- CCommand(theEditor, kODTrue, kODFalse, kUndoDragIndex, kRedoDragIndex)
- {
- fEventData = event;
- fShowDragFeedback = showFeedBack;
- fDragResult = kODDropCopy;
- fDragRegion = kODNULL;
-
- fSavedShapes = kODNULL;
- fPublishLinks = kODNULL;
- fSubscribeLinks = kODNULL;
-
- fSelection = selection;
- fSourceFacet = sourceFacet;
-
- fDestinationPart = kODNULL;
- fDrawEditor = theEditor;
-
- this->SetActionType(kODBeginAction);
-
- fPublishLink = kODNULL;
- }
-
-
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::~CDragShapeCommand
- //-----------------------------------------------------------------------------
-
- CDragShapeCommand::~CDragShapeCommand()
- {
- if (fDragRegion)
- {
- ::DisposeRgn(fDragRegion);
- fDragRegion = kODNULL;
- }
-
- if (fSavedShapes)
- delete fSavedShapes;
-
- if (fPublishLinks)
- delete fPublishLinks;
-
- if (fSubscribeLinks)
- delete fSubscribeLinks;
- }
-
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::CreateDragShape
- //-----------------------------------------------------------------------------
-
- ODShape* CDragShapeCommand::CreateDragShape(Environment* ev, ODFacet* facet)
- {
- return fSelection->CreateDragShape(ev, facet, fFrame);
- }
-
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::SelectDraggedShapes
- //-----------------------------------------------------------------------------
-
- void CDragShapeCommand::SelectDraggedShapes(Environment* ev)
- {
- fSelection->CloseSelection(ev);
-
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- fSelection->AddToSelection(ev, shape, kODFalse);
- }
-
- COrdListIterator iter2(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
- iter2.IsNotComplete();
- link = (CSubscribeLink*)iter2.Next())
- {
- link->AddToSelection(ev, kODFalse);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::Drag
- //-----------------------------------------------------------------------------
-
- ODBoolean CDragShapeCommand::Drag(Environment* ev, ODEventData* event)
- {
- ODPart* destination;
- ODDragAndDrop* drag;
- ODStorageUnit* dragSU;
-
- // Assume fSourceFacet is not null
- THROW_IF_NULL(fSourceFacet);
-
- // Fill the command's frame field
- fFrame = fSourceFacet->GetFrame(ev);
-
- // Get the Drag Shape & Transform it to window coordinates
- ODShape* dragShape = this->CreateDragShape(ev, fSourceFacet);
-
- // Get the drag region
- TRY
- fDragRegion = (RgnHandle)::ODCopyHandle((Handle)dragShape->GetQDRegion(ev));
- CATCH_ALL
- ODSafeReleaseObject(dragShape);
- return kODFalse;
- ENDTRY
-
- // Release ref counted geometry
- ODReleaseObject(ev, dragShape);
-
- // Focus for drawing
- {
- CFocus focus(ev, fSourceFacet);
-
- // Put the drag region into screen coordinates
- GrafPtr port;
- GetPort(&port);
- Point offset = {0, 0};
- ::LocalToGlobal(&offset);
- ::OffsetRgn(fDragRegion, offset.h, offset.v);
- }
-
- // Populate the drag & drop storage unit with drag data
- drag = fDrawEditor->GetSession(ev)->GetDragAndDrop(ev);
- drag->Clear(ev);
- dragSU = drag->GetContentStorageUnit(ev);
-
- // Determine clone kind by whether the selection can be moved or only copied
- ODCloneKind cloneKind = fSelection->CanMoveSelectedContent() ? kODCloneCut : kODCloneCopy;
-
- // If we are dragging a single embedded shape then externalize
- // as per that recipe
- CEmbeddingShape* tShape = fSelection->IsOneEmbeddedShape(ev);
- if (tShape!=kODNULL)
- {
- // Must find the embedded frame, so we can externalize it
- ODFrame* embeddedFrame = tShape->GetEmbeddedFacet(ev, fSourceFacet)->GetFrame(ev);
-
- // Build clone information
- CCloneInfo cloneInfo(0, fDrawEditor->GetDraft(ev),
- fSourceFacet->GetFrame(ev), kODCloneCut);
-
- // Externalize the frame
- fSelection->ExternalizeSingleEmbeddedFrame(ev, dragSU, &cloneInfo, embeddedFrame);
- }
- else
- // Otherwise, promise some data
- {
- // Focus to the content property
- ODSUForceFocus(ev, dragSU, kODPropContents, kDrawEditorKind);
-
- CCloneInfo cloneInfo(0, fDrawEditor->GetDraft(ev),
- fSourceFacet->GetFrame(ev), cloneKind);
-
- CPromise* promise = new CPromise(fDrawEditor, fSourceFacet->GetFrame(ev), fSelection, cloneKind );
- promise->Promise(ev, dragSU);
- }
-
- // Possible opportunity for factoring much of this and much of parallel code
- // in CCutCopyCommand into CPublishLink, but there are a few differences.
-
- ODBoolean doPublish = fSelection->CanPublish();
-
- if (doPublish)
- {
- // If current selection is already published, just re-use its publisher
- CPublishLink* publishLink = fSelection->FindPublisher();
-
- ODUpdateID updateID;
-
- // the publisher is the same one already spec'd on the clipboard then we have to
- // preserve the id, cuz otherwise, the next pasteAs with link from the clipboard
- // will fail. So we'll just always re-use the existing pendingID always.
-
- if (publishLink && (publishLink == fDrawEditor->GetPendingPublish()))
- updateID = publishLink->GetPendingID();
- else
- {
- updateID = fDrawEditor->GetSession(ev)->UniqueUpdateID(ev);
- if (publishLink)
- publishLink->SetPendingID(updateID); // otherwise done in constructor later.
- }
-
- ODLinkSpec* linkSpec = kODNULL;
- ODVolatile(linkSpec);
-
- // New recipe recommends that in the event that a link is created for the spec in the drag,
- // the undo/redo of the drag becomes responsible for undo/redo of the link creation
- // We were already using the updateID as a tag to determine which link is being created.
- // We'll add a reference to this command. CreateLink, when it finds this reference, instead
- // of creating a CCreateLinkCommand which adds a kODSingleAction, for a copy/pasteAs link,
- // will pass the CPublishLink ref to this command so that it can control the undoing/redoing
- // of the link.
-
- LinkSpecData specData = {updateID, this};
-
- TRY
- ODByteArray data;
- data._buffer = (octet*)&specData;
- data._length = sizeof(specData);
- data._maximum = sizeof(specData);
-
- linkSpec = fDrawEditor->GetDraft(ev)->CreateLinkSpec(ev, fDrawEditor->GetODPart(), &data);
-
- dragSU->AddProperty(ev, kODPropLinkSpec);
- linkSpec->WriteLinkSpec(ev, dragSU);
- delete linkSpec;
- CATCH_ALL
- if (linkSpec)
- delete linkSpec;
- doPublish = kODFalse;
- ENDTRY
-
- if (doPublish)
- {
- if (publishLink)
- publishLink->SetPendingID(updateID);
- else
- {
-
- // Have to provide copies of shape and subscribe link lists to the new publisher
- // because if this turns out to be a move, we'll need the lists in our undo an redo code.
-
- publishLink = new CPublishLink( updateID, fSelection,
- new COrderedList(fSavedShapes),
- new COrderedList(fSubscribeLinks));
-
- }
-
- fDrawEditor->SetPendingDragPublish(publishLink);
- }
- }
-
-
- // ----- Write id of source frame in case the drop occurs in the same frame.
- ODID frameID = fFrame->GetID(ev);
- dragSU->AddProperty(ev, kPropFrameInfo)->AddValue(ev, kODULong);
- StorageUnitSetValue(dragSU, ev, sizeof(ODID), &frameID);
-
- // We must notify all frames that we are dragging that they *are* being dragged.
- // This will prevent the frame being dragged from getting called for DragEnter, etc.
- fSelection->Dragging(ev, kODTrue);
-
- // Create structures for the StartDrag call
- ODByteArray dragByteArray;
- dragByteArray._length = sizeof(RgnHandle);
- dragByteArray._maximum = sizeof(RgnHandle);
- dragByteArray._buffer = (octet*)&fDragRegion;
-
- ODByteArray eventByteArray;
- eventByteArray._length = sizeof(ODEventData*);
- eventByteArray._maximum = sizeof(ODEventData*);
- eventByteArray._buffer = (octet*)&event;
-
- // Set the limbo status of any embedded frames in the current selection.
- fSelection->SetInLimbo(ev, kODTrue);
-
- // Start drag assumes that root facet is focused
- fDragResult = drag->StartDrag(ev, fFrame, kODDragImageRegionHandle, &dragByteArray, &destination, &eventByteArray);
-
-
- fDestinationPart = destination;
-
- // Release the destination part, if there was one
- // since it is returned to us with a bumped ref count.
- ODReleaseObject(ev, destination);
-
- return kODTrue;
- }
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::DragCompleted
- //-----------------------------------------------------------------------------
-
- void CDragShapeCommand::DragCompleted(Environment* ev)
- {
- // We must notify all frames that we are dragging that dragging has completed since
- // notified them earlier that they were being dragged. See earlier comment for
- // explanation.
- fSelection->Dragging(ev, kODFalse);
-
- // If the destination was somewhere else AND the drag was a move
- // then get rid of the dragged shapes
- if (fDestinationPart != fDrawEditor->GetODPart()&&fDragResult == kODDropMove)
- {
- ODBoolean tBoolean = fSelection->ClearSelection(ev, fSourceFacet->GetFrame(ev));
- if (!tBoolean)
- {
- DebugStr("\pClearSelection Failed!");
- }
- }
- else
- // If the drag was a copy, then any embedded frames that were put in limbo before
- // StartDrag should now be removed from limbo since they will remain in the current
- // document.
- if (fDragResult == kODDropCopy)
- {
- fSelection->SetInLimbo(ev, kODFalse);
- }
-
- // This is where we need to create an EndAction command, as per the
- // progammer's guide, the "dragger" is reponsible for both the begin
- // and end actions.
- if (fDragResult == kODDropUnfinished || fDragResult == kODDropFail)
- {
- this->AbortCommand(ev);
- }
- else
- {
- this->WriteAction(ev, kODEndAction);
- fTransactionClosed = kODTrue;
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::DoCommand
- //-----------------------------------------------------------------------------
-
- void CDragShapeCommand::DoCommand(Environment* ev)
- {
- // Call inherited
- CCommand::DoCommand(ev);
-
- // If any of the shapes in the selection we are operating on have
- // already been promised t othe clipboard, then we need to resolve
- // the promise on the clipoard to ensure that it will not be corrupted.
- if (fSelection->IsPromisedToClipboard())
- {
- ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
- }
-
- if (fShowDragFeedback)
- this->Drag(ev, fEventData);
- // else
- // Need to set up structures to simulate drag for scripting. $$$$$.
-
- this->DragCompleted(ev);
-
- if (fDragRegion)
- {
- ::DisposeRgn(fDragRegion);
- fDragRegion = kODNULL;
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::UndoCommand
- //-----------------------------------------------------------------------------
-
- void CDragShapeCommand::UndoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::UndoCommand(ev);
-
- if (fDestinationPart != fDrawEditor->GetODPart()&&fDragResult == kODDropMove)
- {
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- fDrawEditor->AddShape(ev, shape);
- }
-
- COrdListIterator iter2(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
- iter2.IsNotComplete();
- link = (CSubscribeLink*)iter2.Next())
- {
- link->AddToPart(ev);
- }
-
- // Add the saved shapes to the selection
- this->SelectDraggedShapes(ev);
-
- // Call selection changed before adding back any publishers. That way,
- // They won't be updated. Publishers that are entirely contained in content
- // being removed should not propagate updates, therefore don't need to when they
- // are added back in again.
-
- // fFrame->GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
- fSelection->SelectedContentUpdated(ev);
-
- COrdListIterator iter3(fPublishLinks);
- for (CPublishLink* plink = (CPublishLink*)iter3.First();
- iter3.IsNotComplete();
- plink = (CPublishLink*)iter3.Next())
- {
- plink->AddToPart(ev);
- }
- }
- else if (fPublishLink)
- {
- fPublishLink->Unpublish(ev);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::RedoCommand
- //-----------------------------------------------------------------------------
-
- void CDragShapeCommand::RedoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::RedoCommand(ev);
-
- if (fDestinationPart != fDrawEditor->GetODPart()&&fDragResult == kODDropMove)
- {
- // Select saved shapes
- this->SelectDraggedShapes(ev);
-
- // Put them back in limbo
- fSelection->SetInLimbo(ev, kODTrue);
-
- // clear them, again
- fSelection->ClearSelection(ev, fSourceFacet->GetFrame(ev));
- }
- else if (fPublishLink)
- {
- fPublishLink->Publish(ev);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::Commit
- //
- // Here you want to clean up command specific structures depnding on the value of state.
- // For example, if a command creates a new piece of content and is comitted after being undone
- // then it should delete the structure representing the new content. Otherwise, it should not
- // deleted.
- //-----------------------------------------------------------------------------
-
- void CDragShapeCommand::Commit(Environment* ev, ODDoneState state)
- {
- CCommand::Commit(ev, state);
-
- if ( state != kODUndone &&
- fDragResult == kODDropMove &&
- fDestinationPart != fDrawEditor->GetODPart())
- {
- // Before removing / deleting shapes check to see if they
- // are promised to the clipboard.
- ::CheckAndResolvePromisedShapes(ev, fSavedShapes, fDrawEditor->GetSession(ev));
-
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- shape->Removed(ev, kCommit);
- delete shape;
- }
-
- while (fSubscribeLinks->Count() != 0)
- {
- CSubscribeLink* link = (CSubscribeLink*)fSubscribeLinks->RemoveFirst();
- link->RemoveShapes(ev, kCommit);
- delete link;
- }
-
- while (fPublishLinks->Count() != 0)
- {
- CPublishLink* link = (CPublishLink*)fPublishLinks->RemoveFirst();
- delete link;
- }
- }
-
- // If a link was created, then undone, then we may have to dispose of it .
- else if (fPublishLink && state == kODUndone )
- {
- fPublishLink->SetHasCommandOutstanding(kODFalse);
-
- if (fDrawEditor->GetPendingPublish() != fPublishLink && fDrawEditor->GetPendingDragPublish() != fPublishLink)
- delete fPublishLink;
- }
-
- }
-
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::CaptureCommandState
- //
- // Here you want to save off any state info necessary for the command to be able to undo/redo.
- // Example: You might make a copy of a list of references to content that is being operated on
- // by the command.
- //-----------------------------------------------------------------------------
-
- void CDragShapeCommand::CaptureCommandState(Environment* ev)
- {
- // A move to another part is the only Undo-able drag action,
- // So save undo state here in that case.
-
- // Only a cut is undo-able, but a copy needs to make the shape and subscribe link lists
- // available to the pending publish link.
-
- fSavedShapes = new COrderedList;
- COrdListIterator iter(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- if (!shape->IsSubscribed())
- fSavedShapes->AddLast(shape);
- }
-
- fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
-
- // This data is only needed for an undoable move. However, at this time,
- // we don't know what were going to get!
-
- fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
- }
-
- //-----------------------------------------------------------------------------
- // CDragShapeCommand::CreateLink
- //
- // Grab a CPublishLink reference for later undoing and redoing, and publish the link
- // Does what a CCreateLinkCommand would do, but includes the link creation in the
- // Drag/Drop undo/redo action.
- //-----------------------------------------------------------------------------
- void CDragShapeCommand::CreateLink(Environment* ev, CPublishLink* pLink)
- {
- TRY
- pLink->Publish(ev);
- pLink->ContentUpdated(ev, fDrawEditor->GetSession(ev)->UniqueUpdateID(ev));
- CATCH_ALL
- if (!fTransactionClosed)
- this->AbortCommand(ev);
-
- RERAISE;
- ENDTRY
-
- pLink->SetHasCommandOutstanding(kODTrue);
- fPublishLink = pLink;
-
- }
-
-
- //=============================================================================
- // CDropShapeCommand::CDropShapeCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::CDropShapeCommand
- //-----------------------------------------------------------------------------
-
- CDropShapeCommand::CDropShapeCommand(DrawEditor* theEditor,
- ODFacet* sourceFacet,
- ODDragItemIterator* dropInfo,
- CSelection* selection,
- ODPoint& dropPoint,
- ODBoolean canUndo) :
- CCommand(theEditor, canUndo, kODTrue, kUndoDropIndex, kRedoDropIndex)
- {
- fDroppedInSameFrame = FALSE;
- fDropResult = kODDropFail;
- fDropPoint = dropPoint;
- fDropInfo = dropInfo;
-
- fSelection = selection;
- fSourceFacet = sourceFacet;
-
- fSavedShapes = kODNULL;
- fPublishLinks = kODNULL;
- fSubscribeLinks = kODNULL;
- }
-
-
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::~CDropShapeCommand
- //-----------------------------------------------------------------------------
-
- CDropShapeCommand::~CDropShapeCommand()
- {
- if (fSavedShapes)
- delete fSavedShapes;
-
- if (fPublishLinks)
- delete fPublishLinks;
-
- if (fSubscribeLinks)
- delete fSubscribeLinks;
-
- }
-
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::GetDropResult
- //-----------------------------------------------------------------------------
-
- ODDropResult CDropShapeCommand::GetDropResult()
- {
- return fDropResult;
- }
-
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::GetDropOrigin
- //-----------------------------------------------------------------------------
-
- void CDropShapeCommand::GetDropOrigin(Environment* ev, ODPoint* originPoint)
- {
- // ----- Calculate originPoint (in content coordinate)
- Point dragOrigin;
-
- ODDragAndDrop* drag = fDrawEditor->GetSession(ev)->GetDragAndDrop(ev);
-
- DragReference theDrag = drag->GetDragReference(ev);
- ::GetDragOrigin(theDrag, &dragOrigin);
- ::GlobalToLocal(&dragOrigin);
-
- *originPoint = dragOrigin;
-
- ODTransform* tTransform = fSourceFacet->AcquireWindowContentTransform(ev, NULL);
- tTransform->InvertPoint(ev, originPoint); // originPoint is modified in place
-
- ODReleaseObject(ev, tTransform);
- }
-
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::DoCommand
- //-----------------------------------------------------------------------------
-
- void CDropShapeCommand::DoCommand(Environment* ev)
- {
- TRY
- if (!fSourceFacet->GetFrame(ev)->IsDroppable(ev))
- fDropResult = kODDropFail;
- else
- {
- this->ExecuteDrop(ev);
- }
-
- this->AdjustUndo(ev);
-
- // Resolve the drop before we set the action history
- CCommand::DoCommand(ev);
-
- // if this was not a move within the same frame, then we have to add the subscribers and register them now.
- if (!fDroppedInSameFrame || (fDropResult == kODDropCopy))
- {
- COrdListIterator iter(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter.First();
- iter.IsNotComplete();
- link = (CSubscribeLink*)iter.Next())
- {
- link->AddToPart(ev);
- }
- }
- CATCH_ALL
- // ----- If we failed to drop, set the drop result to kODDropFail
- fDropResult = kODDropFail;
- ENDTRY
- }
-
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::AdjustUndo
- //-----------------------------------------------------------------------------
-
- void CDropShapeCommand::AdjustUndo(Environment* ev)
- {
- if (fDropResult == kODDropFail) // Drop failed--can't Undo
- {
- fCanUndo = FALSE; // Don't call AddActionToHistory
- fChangesContent = FALSE; // Don't call fPart->Changed()
- }
- else
- // According to Programmer's guide Drop is always a single action. Drag
- // should specify both begin & end.
- this->SetActionType(kODSingleAction);
- }
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::Commit
- //
- // Here you want to clean up command specific structures depnding on the value of state.
- // For example, if a command creates a new piece of content and is comitted after being undone
- // then it should delete the structure representing the new content. Otherwise, it should not
- // deleted.
- //-----------------------------------------------------------------------------
-
- void CDropShapeCommand::Commit(Environment* ev, ODDoneState state)
- {
- CCommand::Commit(ev, state);
-
- // If the command was Done or Redone and it was not a drop move
- // ( shapes were dragged out of document ) then we should delete the
- // shapes in the saved shape list.
- if (((state==kODUndone)&&fDropResult!=kODDropMove))
- {
- // Before removing / deleting shapes check to see if they
- // are promised to the clipboard.
- ::CheckAndResolvePromisedShapes(ev, fSavedShapes, fDrawEditor->GetSession(ev));
-
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- shape->SetInLimbo(ev, kODTrue);
- shape->Removed(ev, kCommit);
- delete shape;
-
- while (fSubscribeLinks->Count() != 0)
- {
- CSubscribeLink* link = (CSubscribeLink*)fSubscribeLinks->RemoveFirst();
- link->RemoveShapes(ev, kCommit);
- delete link;
- }
-
- while (fPublishLinks->Count() != 0)
- {
- CPublishLink* link = (CPublishLink*)fPublishLinks->RemoveFirst();
- delete link;
- }
- }
- }
-
- }
-
-
- //----------------------------------------------------------------------------------------
- // CDropShapeCommand::DoDroppedInSameFrame
- //----------------------------------------------------------------------------------------
-
- ODBoolean CDropShapeCommand::DoDroppedInSameFrame(Environment* ev,
- ODStorageUnit* dropSU,
- ODPoint& originPoint,
- ODPoint& dropPoint)
- {
- fDropOffset = dropPoint;
- fDropOffset -= originPoint;
-
- TRY
- // Offset the selection
- fSelection->OffsetSelection(ev, fSourceFacet->GetFrame(ev), fDropOffset.x, fDropOffset.y);
- CATCH_ALL
- return kODFalse;
- ENDTRY
-
- return kODTrue;
- }
-
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::CaptureCommandState
- //
- //-----------------------------------------------------------------------------
-
- void CDropShapeCommand::CaptureCommandState(Environment* ev)
- {
- // Create a new list
- fSavedShapes = new COrderedList;
-
- // Save shapes that were just dropped
- COrdListIterator ite(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- if (!shape->IsSubscribed())
- fSavedShapes->AddLast(shape);
- }
-
- fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
- fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
- }
-
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::UndoCommand
- //-----------------------------------------------------------------------------
-
- void CDropShapeCommand::UndoCommand(Environment* ev)
- {
- if (fDroppedInSameFrame && fDropResult == kODDropMove) // it's a drag-move
- {
- // select dropped shapes and move them back to the original position
- this->SelectDroppedShapes(ev);
- fSelection->OffsetSelection(ev, fSourceFacet->GetFrame(ev), -fDropOffset.x, -fDropOffset.y);
-
- fSelection->SelectedContentUpdated(ev);
- }
- else
- {
- // select dropped shapes and remove them from the document
- this->SelectDroppedShapes(ev);
- fSelection->SetInLimbo(ev, kODTrue);
- fSelection->ClearSelection(ev, fSourceFacet->GetFrame(ev));
- }
- }
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::RedoCommand
- //-----------------------------------------------------------------------------
-
- void CDropShapeCommand::RedoCommand(Environment* ev)
- {
- if (fDroppedInSameFrame && fDropResult == kODDropMove) // it's a drag-move
- {
- // select dropped shapes and move them to new position
- this->SelectDroppedShapes(ev);
- fSelection->OffsetSelection(ev, fSourceFacet->GetFrame(ev), fDropOffset.x, fDropOffset.y);
- fSelection->SelectedContentUpdated(ev);
- }
- else // dropped shapes are copies
- {
- // add dropped shapes back into document
- COrdListIterator ite(fSavedShapes);
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- // Add the shape to the content list
- fDrawEditor->AddShape(ev, shape);
-
- // Then, add back into selection
- fSelection->AddToSelection(ev, shape, kODTrue);
- }
-
- COrdListIterator iter2(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
- iter2.IsNotComplete();
- link = (CSubscribeLink*)iter2.Next())
- {
- link->AddToPart(ev);
- link->AddToSelection(ev, kODFalse);
- }
-
- COrdListIterator iter3(fPublishLinks);
- for (CPublishLink* plink = (CPublishLink*)iter3.First();
- iter3.IsNotComplete();
- plink = (CPublishLink*)iter3.Next())
- {
- plink->AddToPart(ev);
- }
-
- fDrawEditor->ContentUpdated(ev, kODNULL);
- }
-
- }
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::SelectDroppedShapes
- //-----------------------------------------------------------------------------
-
- void CDropShapeCommand::SelectDroppedShapes(Environment* ev)
- {
- fSelection->CloseSelection(ev);
-
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- fSelection->AddToSelection(ev, shape, kODFalse);
- }
-
- COrdListIterator iter2(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
- iter2.IsNotComplete();
- link = (CSubscribeLink*)iter2.Next())
- {
- link->AddToSelection(ev, kODFalse);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CDropShapeCommand::ExecuteDrop
- //-----------------------------------------------------------------------------
-
- void CDropShapeCommand::ExecuteDrop(Environment* ev)
- {
- ODStorageUnit *dropSU;
- ODPoint originPoint;
-
- ODDragAndDrop* drag = fDrawEditor->GetSession(ev)->GetDragAndDrop(ev);
- ODULong attributes = drag->GetDragAttributes(ev);
-
- // Get the drop result from D&D
- fDropResult = ((attributes & kODDropIsMove) ? kODDropMove : kODDropCopy);
-
- fDroppedInSameFrame = attributes & kODDropIsInSourceFrame;
-
- this->GetDropOrigin(ev, &originPoint);
-
- // ----- Iterate thru dropped items
- for (dropSU = fDropInfo->First(ev); dropSU && fDropResult!=kODDropFail;
- dropSU = fDropInfo->Next(ev))
- {
- // The drop originated within our frame, so we can be smart
- // and just offset the selection
- if (fDroppedInSameFrame && (fDropResult == kODDropMove))
- {
- if (!this->DoDroppedInSameFrame(ev, dropSU, originPoint, fDropPoint))
- fDropResult = kODDropFail;
-
- // Actually, this causes source links that are moved in their entirety to update
- // unecessarily. We need a parameter to SelectedContentUpdated that determines
- // whether or not a change should affect fully selected source links.
-
- fSelection->SelectedContentUpdated(ev);
- }
- else
- {
- // Ok, the drop came from somewhere else..
-
- // So, Empty the selection
- fSelection->CloseSelection(ev);
-
- // Determine the clone kind based on the drop result
- ODCloneKind kind = (GetDropResult() == kODDropMove) ? kODCloneDropMove : kODCloneDropCopy;
-
- // D&D storage is in the from draft
- ODDraft* fromDraft = dropSU->GetDraft(ev);
-
- // Build clone info to pass to internalize
- CCloneInfo info(0, fromDraft, fSourceFacet->GetFrame(ev), kind);
-
- // If we internalization fails, DoCommand will set drop result to fail.
- fSelection->HandleInternalizeContent(ev, dropSU, &info);
-
- // Adjust the selection for the drop
- ODPoint newPosition(fDropPoint.x, fDropPoint.y);
-
- ODRect box;
- fSelection->GetSelectionRectangle(&box);
-
- fSelection->OffsetSelection(ev,
- fSourceFacet->GetFrame(ev),
- newPosition.x - box.left,
- newPosition.y - box.top);
-
- fDrawEditor->ContentUpdated(ev, kODNULL);
- }
- }
-
- // ----- Notify DrawEditor that the drop has completed so that
- // the drag hilite will be erased.
- fDrawEditor->DropCompleted(ev, fDrawEditor->GetODPart(), fDropResult);
- }
-
- //=============================================================================
- // CDropAsCommand::CDropAsCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CDropAsCommand::CDropAsCommand
- //-----------------------------------------------------------------------------
-
- CDropAsCommand::CDropAsCommand(DrawEditor* theEditor,
- ODFacet* sourceFacet,
- ODDragItemIterator* dropInfo,
- CSelection* selection,
- ODPoint& dropPoint,
- ODBoolean doEmbed) :
- CDropShapeCommand(theEditor, sourceFacet, dropInfo, selection, dropPoint, kODTrue)
- {
- fDoEmbed = doEmbed;
- }
-
-
-
- //-----------------------------------------------------------------------------
- // CDropAsCommand::~CDropAsCommand
- //-----------------------------------------------------------------------------
-
- CDropAsCommand::~CDropAsCommand()
- {
- }
-
- //-----------------------------------------------------------------------------
- // CDropAsCommand::ExecuteDrop
- //-----------------------------------------------------------------------------
-
- void CDropAsCommand::ExecuteDrop(Environment* ev)
- {
- ODStorageUnit *dropSU;
- ODPoint originPoint;
-
- ODDragAndDrop* drag = fDrawEditor->GetSession(ev)->GetDragAndDrop(ev);
- ODULong attributes = drag->GetDragAttributes(ev);
-
- // Get the drop result from D&D
- fDropResult = ((attributes & kODDropIsMove) ? kODDropMove : kODDropCopy);
-
- fDroppedInSameFrame = attributes & kODDropIsInSourceFrame;
-
- this->GetDropOrigin(ev, &originPoint);
-
- // ----- Iterate thru dropped items
- for (dropSU = fDropInfo->First(ev); dropSU && fDropResult!=kODDropFail;
- dropSU = fDropInfo->Next(ev))
- {
- // So, Empty the selection
- fSelection->CloseSelection(ev);
-
- // Determine the clone kind based on the drop result
- ODCloneKind kind = (GetDropResult() == kODDropMove) ? kODCloneDropMove : kODCloneDropCopy;
-
- // D&D storage is in the from draft
- ODDraft* fromDraft = dropSU->GetDraft(ev);
-
- // Build clone info to pass to internalize
- CCloneInfo info(0, fromDraft, fSourceFacet->GetFrame(ev), kind);
-
- // If we internalization fails, DoCommand will set drop result to fail.
- fSelection->HandleTranslateContent(ev, dropSU, &info, fDoEmbed);
-
- // Adjust the selection for the drop
- ODPoint newPosition(fDropPoint.x, fDropPoint.y);
-
- ODRect box;
- fSelection->GetSelectionRectangle(&box);
-
- fSelection->OffsetSelection(ev,
- fSourceFacet->GetFrame(ev),
- newPosition.x - box.left,
- newPosition.y - box.top);
-
- fDrawEditor->ContentUpdated(ev, kODNULL);
- }
-
- // ----- Notify DrawEditor that the drop has completed so that
- // the drag hilite will be erased.
- fDrawEditor->DropCompleted(ev, fDrawEditor->GetODPart(), fDropResult);
- }
-
-
-
- //=============================================================================
- // CCutCopyClearShapeCommand::CCutCopyClearShapeCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CCutCopyClearShapeCommand::CCutCopyClearShapeCommand
- //-----------------------------------------------------------------------------
-
- CCutCopyClearShapeCommand::CCutCopyClearShapeCommand(DrawEditor* theEditor,
- ODFrame* sourceFrame,
- CSelection* selection,
- ODCommandID command) :
- CCommand(theEditor, kODFalse, kODFalse, kUndoCopyIndex, kRedoCopyIndex)
- {
- fSavedShapes = kODNULL;
- fPublishLinks = kODNULL;
- fSubscribeLinks = kODNULL;
-
- fSelection = selection;
- fSourceFrame = sourceFrame;
- fCommandID = command;
-
- fUpdateID = kODNULLID;
-
- // Cut operations are undoable and change content
- if (fCommandID!=kODCommandCopy)
- {
- fCanUndo = kODTrue;
- fChangesContent = kODTrue;
- }
-
- // Create clone info
- if (fCommandID==kODCommandCopy)
- fCloneKind = kODCloneCopy;
- else
- fCloneKind = kODCloneCut;
- }
-
-
-
- //-----------------------------------------------------------------------------
- // CCutCopyClearShapeCommand::~CCutCopyClearShapeCommand
- //-----------------------------------------------------------------------------
-
- CCutCopyClearShapeCommand::~CCutCopyClearShapeCommand()
- {
- if (fSavedShapes)
- delete fSavedShapes;
-
- delete fPublishLinks;
- delete fSubscribeLinks;
- }
-
-
- //-----------------------------------------------------------------------------
- // CCutCopyClearShapeCommand::SelectCutShapes
- //-----------------------------------------------------------------------------
-
- void CCutCopyClearShapeCommand::SelectCutShapes(Environment* ev)
- {
- fSelection->CloseSelection(ev);
-
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- fSelection->AddToSelection(ev, shape, kODFalse);
- }
-
- COrdListIterator iter2(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
- iter2.IsNotComplete();
- link = (CSubscribeLink*)iter2.Next())
- {
- link->AddToSelection(ev, kODFalse);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CCutCopyClearShapeCommand::DoCommand
- //-----------------------------------------------------------------------------
-
- void CCutCopyClearShapeCommand::DoCommand(Environment* ev)
- {
- // Call inherited
- CCommand::DoCommand(ev);
-
- // If any of the shapes in the selection we are operating on have
- // already been promised t othe clipboard, then we need to resolve
- // the promise on the clipoard to ensure that it will not be corrupted.
- if (fSelection->IsPromisedToClipboard())
- {
- ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
- }
-
- // Capture the update id, to be checked in redo, undo
- if (fCommandID!=kODCommandClear)
- this->WriteShapesToClipboard(ev);
-
- // If this is a cut/clear operation then cut away the shapes
- if (fCommandID!=kODCommandCopy)
- {
- // Mark any embedded content as removed ( "Limbo" )
- fSelection->SetInLimbo(ev, kODTrue);
-
- // Clear the selection
- fSelection->ClearSelection(ev, fSourceFrame);
- }
-
- // notify clipboard of action done status
- ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
- fUpdateID = clip->ActionDone(ev, fCloneKind);
- }
-
-
- //-----------------------------------------------------------------------------
- // CCutCopyClearShapeCommand::WriteShapesToClipboard
- //-----------------------------------------------------------------------------
-
- void CCutCopyClearShapeCommand::WriteShapesToClipboard(Environment* ev)
- {
- ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
-
- // Remove existing clipboard data
- clip->Clear(ev);
-
- // Get the clipboard content storage unit
- ODStorageUnit* clipSU = clip->GetContentStorageUnit(ev);
-
- CCloneInfo info(0, fDrawEditor->GetDraft(ev), fSourceFrame, fCloneKind);
- ODUpdateID updateID = clip->GetUpdateID(ev);
- ODLinkSpec* linkSpec = NULL;
- ODBoolean doPublish = (fCommandID == kODCommandCopy) && fSelection->CanPublish();
-
- ODVolatile(linkSpec);
-
- TRY
-
- CEmbeddingShape* tShape = fSelection->IsOneEmbeddedShape(ev);
- if (tShape)
- {
- ODFrame* embeddedFrame = tShape->
- GetEmbeddedFacet(ev, fSourceFrame)->GetFrame(ev);
-
- fSelection->ExternalizeSingleEmbeddedFrame( ev,
- clipSU,
- &info,
- embeddedFrame);
- }
- else
- {
- // Focus to the content property
- ODSUForceFocus(ev, clipSU, kODPropContents, kDrawEditorKind);
-
- CClipboardPromise* promise = new CClipboardPromise(fDrawEditor,
- fSourceFrame, fSelection, fCloneKind, updateID );
-
- // Promise the data
- promise->Promise(ev, clipSU);
- }
-
- if (doPublish)
- {
- // See the comment in CDragShapeCommand::Drag for complete explanation. In this case
- // a null command pointer in the spec will trigger CreateLink to create a CCreateLinkCommand
- // for undo/redo.
- LinkSpecData specData = {updateID, (CDragShapeCommand*)kODNULL};
-
- ODByteArray data;
- data._buffer = (octet*)&specData;
- data._length = sizeof(specData);
- data._maximum = sizeof(specData);
-
- linkSpec = fDrawEditor->GetDraft(ev)->CreateLinkSpec(ev, fDrawEditor->GetODPart(), &data);
-
- clipSU->AddProperty(ev, kODPropLinkSpec);
- linkSpec->WriteLinkSpec(ev, clipSU);
- delete linkSpec;
- }
-
- CATCH_ALL
- // If an exception was raised then clear the clipboard.
- // The previous contents of the clipboard are lost.
- clip->Clear(ev);
-
- if (linkSpec)
- delete linkSpec;
-
- doPublish = kODFalse;
- ENDTRY
-
- if (doPublish)
- {
- // If current selection is already published, just re-use its publisher
- CPublishLink* publishLink = fSelection->FindPublisher();
-
- if (publishLink)
- publishLink->SetPendingID(updateID);
- else
- {
- // since never create a publisher for a cut, we can let the new publish links have
- // our shape and subscribe link lists without copying them. (Copy is not undoable)
- publishLink = new CPublishLink(updateID, fSelection, fSavedShapes, fSubscribeLinks);
-
- // The new link is now responsible for these.
- fSavedShapes = kODNULL;
- fSubscribeLinks = kODNULL;
- }
-
- fDrawEditor->SetPendingPublish(publishLink);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CCutCopyClearShapeCommand::UndoCommand
- //-----------------------------------------------------------------------------
-
- void CCutCopyClearShapeCommand::UndoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::UndoCommand(ev);
-
- // We should never get here unless this is a cut operation
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- fDrawEditor->AddShape(ev, shape);
- }
-
- COrdListIterator iter2(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
- iter2.IsNotComplete();
- link = (CSubscribeLink*)iter2.Next())
- {
- link->AddToPart(ev);
- }
-
- this->SelectCutShapes(ev);
-
- // Call selection changed before adding back any publishers. That way,
- // They won't be updated. Publishers that are entirely contained in content
- // being removed should not propagate updates, therefore don't need to when they
- // are added back in again.
-
- // fFrame->GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
- fSelection->SelectedContentUpdated(ev);
-
- COrdListIterator iter3(fPublishLinks);
- for (CPublishLink* plink = (CPublishLink*)iter3.First();
- iter3.IsNotComplete();
- plink = (CPublishLink*)iter3.Next())
- {
- plink->AddToPart(ev);
- }
-
- fDrawEditor->ContentUpdated(ev, kODNULL);
-
- // notify clipboard of action done status
- ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
- clip->ActionUndone(ev, fUpdateID, fCloneKind);
- }
-
-
- //-----------------------------------------------------------------------------
- // CCutCopyClearShapeCommand::RedoCommand
- //-----------------------------------------------------------------------------
-
- void CCutCopyClearShapeCommand::RedoCommand(Environment* ev)
- {
- // Call Inherited
- CCommand::RedoCommand(ev);
-
- this->SelectCutShapes(ev);
-
- // If this is a cut operation then cut away the shapes
- if (fCommandID!=kODCommandCopy)
- {
- // Mark any embedded content as removed ( "Limbo" )
- fSelection->SetInLimbo(ev, kODTrue);
-
- // Clear the selection
- fSelection->ClearSelection(ev, fSourceFrame);
- }
-
- // notify clipboard of action done status
- ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
- clip->ActionRedone(ev, fUpdateID, fCloneKind);
- }
-
-
- //-----------------------------------------------------------------------------
- // CCutCopyClearShapeCommand::Commit
- //
- // Here you want to clean up command specific structures depnding on the value of state.
- // For example, if a command creates a new piece of content and is comitted after being undone
- // then it should delete the structure representing the new content. Otherwise, it should not
- // deleted.
- //-----------------------------------------------------------------------------
-
- void CCutCopyClearShapeCommand::Commit(Environment* ev, ODDoneState state)
- {
- CCommand::Commit(ev, state);
-
- if ( (state != kODUndone) && (fCommandID != kODCommandCopy) )
- {
-
- // Before removing / deleting shapes check to see if they
- // are promised to the clipboard.
- ::CheckAndResolvePromisedShapes(ev, fSavedShapes, fDrawEditor->GetSession(ev));
-
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- shape->Removed(ev, kCommit);
- delete shape;
- }
-
- while (fSubscribeLinks->Count() != 0)
- {
- CSubscribeLink* link = (CSubscribeLink*)fSubscribeLinks->RemoveFirst();
- link->RemoveShapes(ev, kCommit);
- delete link;
- }
-
- while (fPublishLinks->Count() != 0)
- {
- CPublishLink* link = (CPublishLink*)fPublishLinks->RemoveFirst();
- delete link;
- }
-
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CCutCopyClearShapeCommand::CaptureCommandState
- //
- // Here you want to save off any state info necessary for the command to be able to undo/redo.
- // Example: You might make a copy of a list of references to content that is being operated on
- // by the command.
- //-----------------------------------------------------------------------------
-
- void CCutCopyClearShapeCommand::CaptureCommandState(Environment* ev)
- {
- // Only a cut/clear is undo-able, but a copy needs to make the shape and subscribe
- // link lists available to the pending publish link.
- fSavedShapes = new COrderedList;
- COrdListIterator iter(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- if (!shape->IsSubscribed())
- fSavedShapes->AddLast(shape);
- }
-
- fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
-
- // Set the menu text IDs for the right command
- if (fCommandID != kODCommandCopy)
- {
- fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
- if (fCommandID==kODCommandCut)
- this->SetMenuTextIDs(kUndoCutIndex, kRedoCutIndex);
- else
- this->SetMenuTextIDs(kUndoClearIndex, kRedoClearIndex);
- }
- else
- this->SetMenuTextIDs(kUndoCopyIndex, kRedoCopyIndex);
- }
-
-
- //=============================================================================
- // CPasteCommand::CPasteCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CPasteCommand::CPasteCommand
- //-----------------------------------------------------------------------------
-
- CPasteCommand::CPasteCommand(DrawEditor* theEditor,
- ODFrame* sourceFrame,
- CSelection* selection) :
- CCommand(theEditor, kODTrue, kODTrue, kUndoPasteIndex, kRedoPasteIndex)
- {
- fSelection = selection;
- fSourceFrame = sourceFrame;
-
- fUpdateID = kODNULLID;
-
- fSavedShapes = kODNULL;
- fPublishLinks = kODNULL;
- fSubscribeLinks = kODNULL;
- }
-
- //-----------------------------------------------------------------------------
- // CPasteCommand::~CPasteCommand
- //-----------------------------------------------------------------------------
-
- CPasteCommand::~CPasteCommand()
- {
- if (fSavedShapes)
- delete fSavedShapes;
-
- delete fPublishLinks;
- delete fSubscribeLinks;
- }
-
-
- //-----------------------------------------------------------------------------
- // CPasteCommand::HandlePaste
- //-----------------------------------------------------------------------------
-
- void CPasteCommand::HandlePaste(Environment* ev)
- {
- // Get the clipboard storage unit and internalize it
- ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
-
- // Get the clipboard content storage unit
- ODStorageUnit* contentSU = clip->GetContentStorageUnit(ev);
-
- // The clone kind is paste
- ODCloneKind kind = kODClonePaste;
-
- // D&D storage is in the from draft
- ODDraft* fromDraft = contentSU->GetDraft(ev);
-
- // Build clone info to pass to internalize
- CCloneInfo info(0, fromDraft, fSourceFrame, kind);
-
- TRY
- fSelection->HandleInternalizeContent(ev, contentSU, &info);
- CATCH_ALL
- DebugStr("\pFailure to internlalize paste!");
- ENDTRY
-
- // Transform the shape for the paste
- ODPoint newPosition(100, 100); // DCS $$$$$ Change to constant/function
-
- fSelection->OffsetSelection(ev, fSourceFrame, newPosition.x, newPosition.y);
-
- // Save shapes that were just dropped
- COrdListIterator ite(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- if (!shape->IsSubscribed())
- fSavedShapes->AddLast(shape);
- }
-
- fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
- fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
-
- // Here we actually add any just internalized subscribe links to the part. Doing so
- // may cause the some links to be immediately updated. That would be bad if done while
- // on directly by the selection on it's list of links, because the update closes the
- // current selection, thus clearing the list in the process.
-
- COrdListIterator iter(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter.First();
- iter.IsNotComplete();
- link = (CSubscribeLink*)iter.Next())
- {
- link->AddToPart(ev);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CPasteCommand::DoCommand
- //-----------------------------------------------------------------------------
-
- void CPasteCommand::DoCommand(Environment* ev)
- {
-
- // Resolve the drop before we set the action history
- CCommand::DoCommand(ev);
-
- // Empty the selection
- fSelection->CloseSelection(ev);
-
- // Do the paste
- this->HandlePaste(ev);
-
- // notify clipboard of action done status
- ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
- fUpdateID = clip->ActionDone(ev, kODClonePaste);
- }
-
-
- //-----------------------------------------------------------------------------
- // CPasteCommand::Commit
- //
- // Here you want to clean up command specific structures depending on the value of state.
- // For example, if a command creates a new piece of content and is comitted after being undone
- // then it should delete the structure representing the new content. Otherwise, it should not
- // deleted.
- //-----------------------------------------------------------------------------
-
- void CPasteCommand::Commit(Environment* ev, ODDoneState state)
- {
- CCommand::Commit(ev, state);
-
- // If the command was Done or Redone and it was not a drop move
- // ( shapes were dragged out of document ) then we should delete the
- // shapes in the saved shape list.
- if ((state==kODUndone))
- {
- // Before removing / deleting shapes check to see if they
- // are promised to the clipboard.
- ::CheckAndResolvePromisedShapes(ev, fSavedShapes, fDrawEditor->GetSession(ev));
-
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- shape->Removed(ev, kCommit);
- delete shape;
- }
-
- while (fSubscribeLinks->Count() != 0)
- {
- CSubscribeLink* link = (CSubscribeLink*)fSubscribeLinks->RemoveFirst();
- link->RemoveShapes(ev, kCommit);
- delete link;
- }
-
- while (fPublishLinks->Count() != 0)
- {
- CPublishLink* link = (CPublishLink*)fPublishLinks->RemoveFirst();
- delete link;
- }
-
- }
-
- }
-
-
- //-----------------------------------------------------------------------------
- // CPasteCommand::CaptureCommandState
- //
- //-----------------------------------------------------------------------------
-
- void CPasteCommand::CaptureCommandState(Environment* ev)
- {
- // Create a new list
- fSavedShapes = new COrderedList;
- }
-
-
- //-----------------------------------------------------------------------------
- // CPasteCommand::UndoCommand
- //-----------------------------------------------------------------------------
-
- void CPasteCommand::UndoCommand(Environment* ev)
- {
- // select pasted shapes and remove them from the document
- this->SelectPastedShapes(ev);
-
- fSelection->SetInLimbo(ev, kODTrue);
- fSelection->ClearSelection(ev, fSourceFrame);
-
- // Clear selection calls ContentUpdated.
-
- // notify clipboard of action done status
- ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
- clip->ActionUndone(ev, fUpdateID, kODClonePaste);
- }
-
- //-----------------------------------------------------------------------------
- // CPasteCommand::RedoCommand
- //-----------------------------------------------------------------------------
-
- void CPasteCommand::RedoCommand(Environment* ev)
- {
- // add dropped shapes back into document
- COrdListIterator ite(fSavedShapes);
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- // Add the shape to the content list
- fDrawEditor->AddShape(ev, shape);
- fSelection->AddToSelection(ev, shape, kODTrue);
- }
-
- COrdListIterator iter2(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
- iter2.IsNotComplete();
- link = (CSubscribeLink*)iter2.Next())
- {
- link->AddToPart(ev);
- link->AddToSelection(ev, kODFalse);
- }
-
- // (MH) Call selection changed before adding back any publishers. That way,
- // They won't be updated. Publishers that are entirely contained in content
- // being removed/replaced don't need to propagate any updates.
-
- // fFrame->GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
- fSelection->SelectedContentUpdated(ev);
-
- COrdListIterator iter3(fPublishLinks);
- for (CPublishLink* plink = (CPublishLink*)iter3.First();
- iter3.IsNotComplete();
- plink = (CPublishLink*)iter3.Next())
- {
- plink->AddToPart(ev);
- }
-
- fDrawEditor->ContentUpdated(ev, kODNULL);
-
- // notify clipboard of action done status
- ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
- clip->ActionRedone(ev, fUpdateID, kODClonePaste);
- }
-
- //-----------------------------------------------------------------------------
- // CPasteCommand::SelectPastedShapes
- //-----------------------------------------------------------------------------
-
- void CPasteCommand::SelectPastedShapes(Environment* ev)
- {
- fSelection->CloseSelection(ev);
-
- COrdListIterator iter(fSavedShapes);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- fSelection->AddToSelection(ev, shape, kODFalse);
- }
-
- COrdListIterator iter2(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
- iter2.IsNotComplete();
- link = (CSubscribeLink*)iter2.Next())
- {
- link->AddToSelection(ev, kODFalse);
- }
- }
-
- //=============================================================================
- // CPasteAsCommand::CPasteAsCommand
- //=============================================================================
-
- //-----------------------------------------------------------------------------
- // CPasteAsCommand::CPasteAsCommand
- //-----------------------------------------------------------------------------
-
- CPasteAsCommand::CPasteAsCommand(DrawEditor* theEditor,
- ODFrame* sourceFrame,
- CSelection* selection,
- ODBoolean embedOrMerge) :
- CPasteCommand(theEditor, sourceFrame, selection)
- {
- fDoEmbed = embedOrMerge;
- }
-
- //-----------------------------------------------------------------------------
- // CPasteAsCommand::~CPasteAsCommand
- //-----------------------------------------------------------------------------
-
- CPasteAsCommand::~CPasteAsCommand()
- {
- }
-
-
- //-----------------------------------------------------------------------------
- // CPasteAsCommand::HandlePaste
- //-----------------------------------------------------------------------------
-
- void CPasteAsCommand::HandlePaste(Environment* ev)
- {
- // Get the clipboard storage unit and internalize it
- ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
-
- // Get the clipboard content storage unit
- ODStorageUnit* contentSU = clip->GetContentStorageUnit(ev);
-
- // The clone kind is paste
- ODCloneKind kind = kODClonePaste;
-
- // D&D storage is in the from draft
- ODDraft* fromDraft = contentSU->GetDraft(ev);
-
- // Build clone info to pass to internalize
- CCloneInfo info(0, fromDraft, fSourceFrame, kind);
-
- TRY
- fSelection->HandleTranslateContent(ev, contentSU, &info, fDoEmbed);
- CATCH_ALL
- DebugStr("\pFailure to internlalize paste!");
- ENDTRY
-
- // Transform the shape for the paste
- ODPoint newPosition(100, 100); // DCS $$$$$ Change to constant/function
-
- fSelection->OffsetSelection(ev, fSourceFrame, newPosition.x, newPosition.y);
-
- // Save shapes that were just pasted
- COrdListIterator ite(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- if (!shape->IsSubscribed())
- fSavedShapes->AddLast(shape);
- }
-
- fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
- fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
-
- // Here we actually add any just internalzied subscribe links to the part. Doing so
- // may cause the some links to be immediately updated. That would be bad if done while
- // on directly by the selection on it's list of links, because the update closes the
- // current selection, thus clearing the list in the process.
-
- COrdListIterator iter(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter.First();
- iter.IsNotComplete();
- link = (CSubscribeLink*)iter.Next())
- {
- link->AddToPart(ev);
- }
- }
-
-
-
-
-