|
|
Undo / Redo with custom paste operation
Last post 05-12-2008, 9:32 AM by ZenRhapsody. 9 replies.
-
05-09-2008, 12:05 PM |
-
ZenRhapsody
-
-
-
Joined on 01-19-2007
-
-
Posts 54
-
-
|
Undo / Redo with custom paste operation
I have implemented a custom replicating paste operation that emulates Excel's repeating paste. For example, if you copy 1 cell and select multiple cells to paste, the 1 cell is replicated. If you select 2 rows, then paste over 10 rows, the pattern is repeated 5 times. i catch the OnClipboardPasting event to override default spread processing IF the clipboard contains CellInfoRange. If not a spread copy, I let spread's default paste handling work.
This all works fine.
Now i want to add undo/redo support to this custom paste action. I have figured out how to implement this by subclassing UndoAction, but when stepping through my code, I see that the OnClipboardPasting event is called by ClipboardPasteUndoAction.PerformUndoAction(). This makes sense, but now I'm concerned with the nested calls to UndoManager.PerformUndoAction().
I still want CNTL-V to work as a paste, as well as menu paste commands.
So, could you provide some guidance? Can I integrate with Spread's default processing of paste commands, or must I redirect CNTL-V to another action with the action maps (I'm not real familiar with the action maps yet) and take full control away from spread on all pastes?
|
|
-
05-09-2008, 2:29 PM |
-
BobM
-
-
-
Joined on 03-06-2003
-
-
Posts 6,310
-
-
|
Re: Undo / Redo with custom paste operation
ZenRhapsody -
I am not sure about this. I have solicited the insight of a few others to see what would be the appropriate course of action in this case.
Bob M. FarPoint Technologies, Inc.
|
|
-
05-09-2008, 3:09 PM |
-
ZenRhapsody
-
-
-
Joined on 01-19-2007
-
-
Posts 54
-
-
|
Re: Undo / Redo with custom paste operation
I think I've figured this out - see how this seems to you and your team:
I created a new CustomPasteUndoAction and set ActionMap for CNTL-V to this; taking control away from spread completely for paste and not tryng to catch OnPasting event.
In CustomPasteUndoAction.PerformUndoAction(object sender) I first check to see if the copied data on the clipboard is CellInfoRange data. If it is, I do my state save and perform operation as usual. If the data is not CellInfoRange data, I want FpSpread to handle it instead of me. In this case, I create a instance of ClipboardPasteUndoAction() and call it's PerformUndoAction() method.
In my Undo() method, I first check if my ClipboardPasteUndoAction variable is null. If not, I just call it's Undo method and return.
So essentially, I wrapped ClipboardPasteUndoAction with a new customPasteUndoAction. Subclassing ClipboardPasteUndoAction could have worked also I guess.
I'm beginning to test this all out now. How does this approach sound ?
|
|
-
05-09-2008, 3:28 PM |
-
seanl
-
-
-
Joined on 02-13-2003
-
Morrisville, NC, USA
-
Posts 253
-
-
|
Re: Undo / Redo with custom paste operation
Hi,
If you want to make your action undoable, you will need to create a custom UndoAction class which implements SaveUndoState, PerformAction, and Undo to make your paste work. Then you can put an instance of that action into the action map for the CTRL+V key handling. You can also use your action directly in code by creating an instance of it and passing it into the FpSpread.UndoManager.PerformUndoAction method.
To make your action work correctly in the action map, you should leave the object uninitialized when it is added to the action map, and make the class cloneable by implementing the ICloneable interface. The SpreadView will automatically clone UndoAction objects which are ICloneable before performing the action, since each UndoAction instance needs to track its action separately in order to correctly preserve the undo state information.
The UndoAction.PerformUndoAction and Undo methods are passed a sender parameter, which will be a SpreadView object on which the operation is happening. The code to implement the methods should use this SpreadView to determine everything required for the action. You will probably need to change your code handling OnClipboardPasting to make it undoable when you implement PerformUndoAction. If you have .Net Reflector, you can use that to look at the way we have implemeneted the ClipboardPasteUndoAction to get an idea of what is needed to make a clipboard paste operation undoable. The SaveUndoState method should determine the SheetView, CellRange, and data which should be pasted, and store those values in fields, and also get the CellInfoRange (and ColumnClipInfoRange and RowClipInfoRange, if applicable) for the target CellRange, so that this too can be stored in a field and used to undo the operation. The PerformUndoAction method should use the SheetView, CellRange, and CellInfoRange fields (and ColumnClipInfoRange and RowClipInfoRange, if applicable) to call ClipboardPaste on the SheetView using the appropriate overload that takes all those arguments. The Undo method should reverse the operation by selecting the original cell range in the sheet and calling SheetView.ClipboardPaste using the CellInfoRange (and ColumnClipInfoRange and RowClipInfoRange, if applicable) containing the original values that was saved in SaveUndoState.
seanl
FarPoint Technologies, Inc.
|
|
-
05-09-2008, 3:37 PM |
-
seanl
-
-
-
Joined on 02-13-2003
-
Morrisville, NC, USA
-
Posts 253
-
-
|
Re: Undo / Redo with custom paste operation
I meant to go into a bit more detail about the ColumnClipInfoRange and RowClipInfoRange classes, because they can be a little confusing. The work just like CellInfoRange, except they store column and row information when a clipboard operation is performed on a range of columns, or a range or rows, or on an entire sheet. When the CellRange specifies -1 for row and rowCount, the range consists of entire columns, and when it specifies -1 for column and columnCount, the range consists of entire rows, and when the CellRange specifies -1 for row and rowCount and column and columnCount, the range consists of the entire sheet. Clipboard operations performed on ranges of rows or columns will also copy row or column settings. CellInfoRange.FromCellRange will create the CellInfoRange for the specified CellRange in the specified SheetView, and if you want to get row and column clip information too, you must also pass in a ColumnClipInfoRange and RowClipInfoRange as reference parameters for the method to initialize when the CellRange specifies -1 somewhere.
seanl
FarPoint Technologies, Inc.
|
|
-
05-09-2008, 3:44 PM |
-
seanl
-
-
-
Joined on 02-13-2003
-
Morrisville, NC, USA
-
Posts 253
-
-
|
Re: Undo / Redo with custom paste operation
ZenRhapsody:I think I've figured this out - see how this seems to you and your team:
I created a new CustomPasteUndoAction and set ActionMap for CNTL-V to this; taking control away from spread completely for paste and not tryng to catch OnPasting event.
In CustomPasteUndoAction.PerformUndoAction(object sender) I first check to see if the copied data on the clipboard is CellInfoRange data. If it is, I do my state save and perform operation as usual. If the data is not CellInfoRange data, I want FpSpread to handle it instead of me. In this case, I create a instance of ClipboardPasteUndoAction() and call it's PerformUndoAction() method.
In my Undo() method, I first check if my ClipboardPasteUndoAction variable is null. If not, I just call it's Undo method and return.
So essentially, I wrapped ClipboardPasteUndoAction with a new customPasteUndoAction. Subclassing ClipboardPasteUndoAction could have worked also I guess.
I'm beginning to test this all out now. How does this approach sound ?
As long as your Undo method can put everything back the way it was before the paste when your PerformUndoAction code is handling it instead of our ClipboardPasteUndoAction, and the PerformUndoAction code is not overwriting the saved state information when it is called again to redo the action, that should be fine. And you need to make sure that your undo action is cloneable if you are going to put it into the action map.
seanl
FarPoint Technologies, Inc.
|
|
-
05-09-2008, 4:03 PM |
-
ZenRhapsody
-
-
-
Joined on 01-19-2007
-
-
Posts 54
-
-
|
Re: Undo / Redo with custom paste operation
I did forget about redo when delegating to your ClipboardPasteUndoAction, but that should be easy enough to fix.
Thanks for the heads up on the situation on selecting entire rows and columns; I hadn't gotten that far with my code.
On the IClonable issue; I didn't do any special code to support it since Action base class implements it. As I've stepped into PerformUndoAction() method each time, all my member variables are null or default, so I assume Action base class just does a Memberwise copy of each variable from the class passed into the action map. If I'm wrong on this, please let me know.
The basic concept seems to be working ok; thanks for the help (and for such an extensible product!).
|
|
-
05-09-2008, 6:27 PM |
-
ZenRhapsody
-
-
-
Joined on 01-19-2007
-
-
Posts 54
-
-
|
Re: Undo / Redo with custom paste operation
Another question -
My custom action classes modify the sheet data due to customer interaction. I need to know when user changes any data, so I catch the FpSpread.Change event. Calling SheetView.SetValue() doesn't fire this event (correctly, I agree).
However, I need to also flag changes due to my custom actions. I do call SheetView.RaiseCellChanged() in order for spread to redraw the cells. However, I cannot find a way to fire an event that I can catch to flag that user has changed data.
I am aware of DataModel.Changed event, but doesn't that fire for every code change of data?
|
|
-
05-12-2008, 7:22 AM |
-
scotts
-
-
-
Joined on 02-20-2003
-
-
Posts 17,303
-
-
|
Re: Undo / Redo with custom paste operation
Hello,
The DataModel's Changed event will fire every time there is a change in the DataModel, whethr it is by the user or done programatically. However, if it is done programatically, you can set a global flag that you check in this event, before calling the code to cause this event to fire. Then, you know the event is being fired because of your code.
Scott S. FarPoint Technologies, Inc.
|
|
-
05-12-2008, 9:32 AM |
-
ZenRhapsody
-
-
-
Joined on 01-19-2007
-
-
Posts 54
-
-
|
Re: Undo / Redo with custom paste operation
Thanks Scott, that's what I figured I'd have to do. Just wanted to avoid the rework :)
|
|
FarPoint Forums Home
|
|