Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » EMF Model Editor - Customized Copy/Paste Action
EMF Model Editor - Customized Copy/Paste Action [message #762654] Thu, 08 December 2011 13:01 Go to next message
Ralph P is currently offline Ralph PFriend
Messages: 30
Registered: September 2010
Location: Frankfurt, Germany
Member
Hello,

I'm trying to customize the Copy/Paste mechanism in my generated model editor.

My customization contains a dialog where the user must enter a new ID for the copied object.

I started by implementing a new EditingDomainViewerDropAdapter, which worked fine until I realized that my logic works only for drag & drop does not change the behavior of copy & paste (of course!).
Browsing through this forums, I read that overriding MyItemProvider#createInitializeCopyCommand(...) is the right approach. But when I found out, that this method is called every time I use "Copy" at runtime (not Paste), I extended the CopyCommand. In MyCopyCommand I've overridden the execute() method, because I thought "on "Copy" the CopyCommand is created, and on "Paste" it should be executed". But that's not true. The CopyCommand is created and executed when I only use "Copy". Obviously there must a difference when using "Copy" or "Paste" - and this is what I'm looking for!

My custom CopyCommand works fine, but I get the "Change ID"-Dialog two times (on Copy and on Paste).

MyItemProvider:
	@Override
	protected Command createCopyCommand(EditingDomain pDomain, EObject pOwner,
			Helper pHelper) {
		return new MyCopyCommand(pDomain, pOwner, pHelper);
	}


MyCopyCommand:
	@Override
	public void execute() {
		super.execute();
		// What I need is something like:
		// if(!_paste)
		// return;
		getNewObjectIDs(getResult());
		renameCopiedResources(getResult());
	}


Thanks in advance!
Ralph
Re: EMF Model Editor - Customized Copy/Paste Action [message #762666 is a reply to message #762654] Thu, 08 December 2011 13:23 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33142
Registered: July 2009
Senior Member
Ralph,

Comments below.

On 08/12/2011 5:01 AM, r.pakosch wrote:
> Hello,
>
> I'm trying to customize the Copy/Paste mechanism in my generated model
> editor.
>
> My customization contains a dialog where the user must enter a new ID
> for the copied object.
User interactions as part of a command are often rather tricky. After
all, the user can generally cancel an interaction...
>
> I started by implementing a new EditingDomainViewerDropAdapter, which
> worked fine until I realized that my logic works only for drag & drop
> does not change the behavior of copy & paste (of course!).
Yes, there are lots of fine grained things going on under the covers and
you generally need to focus on those...
> Browsing through this forums, I read that overriding
> MyItemProvider#createInitializeCopyCommand(...) is the right approach.
> But when I found out, that this method is called every time I use
> "Copy" at runtime (not Paste), I extended the CopyCommand.
Yes, commands are prepared and tested for excutability to populate menus.
> In MyCopyCommand I've overridden the execute() method, because I
> thought "on "Copy" the CopyCommand is created, and on "Paste" it
> should be executed". But that's not true. The CopyCommand is created
> and executed when I only use "Copy". Obviously there must a difference
> when using "Copy" or "Paste" - and this is what I'm looking for!
One can do a copy, which copies to the clipboard, and an hour later do
a paste, or perhaps never do a paste.
>
> My custom CopyCommand works fine, but I get the "Change ID"-Dialog two
> times (on Copy and on Paste).
If you think about it, if you copy something to the clipboard, you might
change the original, so you need a copy in the clipboard. Once you
paste from the clipboard, you might paste it a second time, so you
really need to paste a copy of what's in the clipboard, or at least put
a copy back in the clipboard...
>
> MyItemProvider:
> @Override
> protected Command createCopyCommand(EditingDomain pDomain, EObject
> pOwner,
> Helper pHelper) {
> return new MyCopyCommand(pDomain, pOwner, pHelper);
> }
>
> MyCopyCommand:
> @Override
> public void execute() {
> super.execute();
> // What I need is something like:
> // if(!_paste)
> // return;
> getNewObjectIDs(getResult());
> renameCopiedResources(getResult());
> }
Is there any way for the user to change the ID of an existing object?
If so, how do you deal with duplicates should they cause those?

Perhaps a better approach is to specialize copy not to copy the ID, and
to do something more general, like listen to the command stack and check
the command result to scan for objects without an ID and then present
the user with the option to set them.

If you do want to specialize paste itself, you should look at
specializing AdapterFactoryEditingDomain.createCommand and handle
PasteFromClipboardCommand in some special way.
>
> Thanks in advance!
> Ralph


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: EMF Model Editor - Customized Copy/Paste Action [message #762684 is a reply to message #762666] Thu, 08 December 2011 14:03 Go to previous messageGo to next message
Ralph P is currently offline Ralph PFriend
Messages: 30
Registered: September 2010
Location: Frankfurt, Germany
Member
Hello Ed,

thanks for the reply!

Your suggestions are interesting and both worth a try!

So am I right that there is no difference between the CopyCommands (and their results) when using Copy or Paste? Why does the CopyCommand not create any (visible) Objects when only using "Copy" in the editor?

Objects with same IDs are not a critical problem in our editor (since one can use the validation) but it happened that a user copied an object and edited the original one by mistake (which was referred by other objects).

Best regards,
Ralph
Re: EMF Model Editor - Customized Copy/Paste Action [message #762708 is a reply to message #762684] Thu, 08 December 2011 14:27 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33142
Registered: July 2009
Senior Member
Ralph,

Comments below.

On 08/12/2011 6:03 AM, r.pakosch wrote:
> Hello Ed,
>
> thanks for the reply!
>
> Your suggestions are interesting and both worth a try!
>
> So am I right that there is no difference between the CopyCommands
> (and their results) when using Copy or Paste?
Right.
> Why does the CopyCommand not create any (visible) Objects when only
> using "Copy" in the editor?
The clipboard isn't visible.
>
> Objects with same IDs are not a critical problem in our editor (since
> one can use the validation) but it happened that a user copied an
> object and edited the original one by mistake (which was referred by
> other objects).
Not sure how that happens. When you paste, that new things is generally
selected...
>
> Best regards,
> Ralph


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: EMF Model Editor - Customized Copy/Paste Action [message #763215 is a reply to message #762708] Fri, 09 December 2011 11:11 Go to previous messageGo to next message
Ralph P is currently offline Ralph PFriend
Messages: 30
Registered: September 2010
Location: Frankfurt, Germany
Member
Hello Ed,

I've successfully implemented a specialized PasteFromClipboardCommand (thanks again!).

There's one thing left that's not working how I want it:

CustomPasteFromClipboardCommand:
	@Override
	public void doExecute() {
		super.doExecute();
		try {
			getNewObjectIDs(getResult());
		} catch (OperationCanceledException e) {
			// User canceled the rename dialog
			// TODO undo does not work properly
			_editingDomain.getCommandStack().undo();
			return;
		}
		renameCopiedResources(getResult());
	}


The "undo" leads to strange results (in some cases to "phantom objects" which don't physically exist but are visible in the editor). What am I doing wrong here?

Thank you!
Ralph


For others: How I implemented a custom paste action:
Specialized AdapterFactoryEditingDomain:
public class CustomAdapterFactoryEditingDomain extends
		AdapterFactoryEditingDomain {

	public CustomAdapterFactoryEditingDomain(AdapterFactory pAdapterFactory,
			CommandStack pCommandStack,
			Map<Resource, Boolean> pResourceToReadOnlyMap) {
		super(pAdapterFactory, pCommandStack, pResourceToReadOnlyMap);
	}

	@Override
	public Command createCommand(Class<? extends Command> pCommandClass,
			CommandParameter pCommandParameter) {
		if (pCommandClass.equals(PasteFromClipboardCommand.class)) {
			return new CustomPasteFromClipboardCommand(this,
					pCommandParameter.getOwner(),
					pCommandParameter.getFeature(),
					pCommandParameter.getIndex(), getOptimizeCopy());
		}
		return super.createCommand(pCommandClass, pCommandParameter);
	}
}


Instantiated by the editor:
	protected void initializeEditingDomain() {
		<...>
		//
		// Create the editing domain with a special command stack.
		//
		editingDomain = new CustomAdapterFactoryEditingDomain(adapterFactory,
				commandStack, new HashMap<Resource, Boolean>());
	}


doExecute() method over
Re: EMF Model Editor - Customized Copy/Paste Action [message #763222 is a reply to message #763215] Fri, 09 December 2011 11:21 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33142
Registered: July 2009
Senior Member
Comments below.

On 09/12/2011 3:11 AM, r.pakosch wrote:
> Hello Ed,
>
> I've successfully implemented a specialized PasteFromClipboardCommand
> (thanks again!).
>
> There's one thing left that's not working how I want it:
>
> CustomPasteFromClipboardCommand:
> @Override
> public void doExecute() {
> super.doExecute();
> try {
> getNewObjectIDs(getResult());
> } catch (OperationCanceledException e) {
> // User canceled the rename dialog
> // TODO undo does not work properly
> _editingDomain.getCommandStack().undo();
Have a look to see what command stack execute is doing when you call
this and you'll see that you'll be making a complete mess of the command
stack. You'll also noticed you can throw AbortExecutionException.
> return;
> }
> renameCopiedResources(getResult());
> }
>
> The "undo" leads to strange results (in some cases to "phantom
> objects" which don't physically exist but are visible in the editor).
> What am I doing wrong here?
That's not surprising...
>
> Thank you!
> Ralph
>
>
> For others: How I implemented a custom paste action:
> Specialized AdapterFactoryEditingDomain:
> public class CustomAdapterFactoryEditingDomain extends
> AdapterFactoryEditingDomain {
>
> public CustomAdapterFactoryEditingDomain(AdapterFactory
> pAdapterFactory,
> CommandStack pCommandStack,
> Map<Resource, Boolean> pResourceToReadOnlyMap) {
> super(pAdapterFactory, pCommandStack, pResourceToReadOnlyMap);
> }
>
> @Override
> public Command createCommand(Class<? extends Command> pCommandClass,
> CommandParameter pCommandParameter) {
> if (pCommandClass.equals(PasteFromClipboardCommand.class)) {
> return new CustomPasteFromClipboardCommand(this,
> pCommandParameter.getOwner(),
> pCommandParameter.getFeature(),
> pCommandParameter.getIndex(), getOptimizeCopy());
> }
> return super.createCommand(pCommandClass, pCommandParameter);
> }
> }
>
>
> Instantiated by the editor:
> protected void initializeEditingDomain() {
> <...>
> //
> // Create the editing domain with a special command stack.
> //
> editingDomain = new
> CustomAdapterFactoryEditingDomain(adapterFactory,
> commandStack, new HashMap<Resource, Boolean>());
> }
>
>
> doExecute() method over


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: EMF Model Editor - Customized Copy/Paste Action [message #763301 is a reply to message #763222] Fri, 09 December 2011 14:36 Go to previous messageGo to next message
Ralph P is currently offline Ralph PFriend
Messages: 30
Registered: September 2010
Location: Frankfurt, Germany
Member
Hello Ed,

sorry for asking again!

1) Why do I mess up the command stack by undoing the paste command? Is there a way to do this correctly (obviously yes, because it's possible in the editor)?
doUndo() works as long as the copied object is visible in the editor. Otherwise: "phantom object"
	@Override
	public void doExecute() {
		super.doExecute();
		try {
			getNewObjectIDs(getResult());
		} catch (OperationCanceledException e) {
			doUndo();
			return;
		}
		renameCopiedResources(getResult());
	}


2) Before the execution of the PasteFromClipboardCommand I can get the corresponding EObjects by _editingDomain.getClipboard(). Unfortunately these don't contain their containers (eObj.eContainer() -> null). Is there a method to always find the container of an EObject? If yes, I don't need to undo the copy command (because I can get the new IDs before the execution).

Best regards,
Ralph
Re: EMF Model Editor - Customized Copy/Paste Action [message #763340 is a reply to message #763301] Fri, 09 December 2011 15:38 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33142
Registered: July 2009
Senior Member
COmments below.

On 09/12/2011 6:36 AM, r.pakosch wrote:
> Hello Ed,
>
> sorry for asking again!
>
> 1) Why do I mess up the command stack by undoing the paste command?
You can answer this yourself by setting a breakpoint in your excute
method, looking up the stack, and see what the command stack is
doing. (You'll see that you're undo the previously execute command,
not this one, and you'll still record this one.
> Is there a way to do this correctly (obviously yes, because it's
> possible in the editor)?
> doUndo() works as long as the copied object is visible in the editor.
> Otherwise: "phantom object"
> @Override
> public void doExecute() {
> super.doExecute();
> try {
> getNewObjectIDs(getResult());
> } catch (OperationCanceledException e) {
> doUndo();
You've changed what you showed before, but you still need to be sure
that this command is not recorded on the command stack. I already
suggested how to do that...
> return;
> }
> renameCopiedResources(getResult());
> }
>
> 2) Before the execution of the PasteFromClipboardCommand I can get the
> corresponding EObjects by _editingDomain.getClipboard(). Unfortunately
> these don't contain their containers (eObj.eContainer() -> null). Is
> there a method to always find the container of an EObject?
Yes, eContainer(), which is null when there isn't a container and then
nothing will find it because there isn't one. Of course the objects in
the clipboard is already a copy that's not contained anywhere and not
referenced by anything (but the clipboard).
> If yes, I don't need to undo the copy command (because I can get the
> new IDs before the execution).
You can look closely at what PasteFromClipboardCommand. prepare does.
It would certainly be possible to create the copy but avoid doing the
add until you're sure you want to go ahead with execution.
>
> Best regards,
> Ralph
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: EMF Model Editor - Customized Copy/Paste Action [message #764570 is a reply to message #763340] Mon, 12 December 2011 13:00 Go to previous message
Ralph P is currently offline Ralph PFriend
Messages: 30
Registered: September 2010
Location: Frankfurt, Germany
Member
Hello Ed,

thank you (for the 30th time maybe Smile)! Everything works fine now!

Just like in PasteFromClipboardCommand#prepare() I've created a WrappedCommand and specialized the createCommand() method. If the user cancels the rename dialog, the createCommand() method only returns the CopyCommand (without the AddCommand).

I also found out that a copied EObject still doesn't have an eContainer (not until the AddCommand was executed), but I can use the command its owner for the ID validation.

Best regards,
Ralph
Previous Topic:What is Resource and Resource set in EMF?
Next Topic:setting list contents (reference) via command stack with set/add/remove commands
Goto Forum:
  


Current Time: Fri Apr 26 15:17:52 GMT 2024

Powered by FUDForum. Page generated in 0.04052 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top