Home » Modeling » GMF (Graphical Modeling Framework) » [GMF-Runtime] Custom initialization in the default creation tools
|
Re: [GMF-Runtime] Custom initialization in the default creation tools [message #71626 is a reply to message #71459] |
Mon, 30 October 2006 15:45 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Linda Damus![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=ldamus%40ca.ibm.com) Messages: 85 Registered: July 2009 |
Member |
|
|
Hi Michael,
Did you consider creating a specialization type (in the elementTypes
extension point) for your tool? That way you could contribute an
IEditHelperAdvice that sets the name to "MGolubevClass" after the class
is created (by implementing #getAfterConfigureCommand()). The
UnspecifiedTypeCreationTool would be initialized with this
specialization type as one of the choices it presents to the user.
The advantage to creating a specialization type is that you will be able
to reuse the extended semantic behaviour if you later decide to support
the same element creation from a popup toolbar, a context menu, a
dialog, etc. Creating a custom tool to extend the semantic behaviour
limits that extension to the tool palette.
Hope that helps,
Linda
Michael Golubev wrote:
> Hi,
>
> I would like to implement custom creation tool that setup some properties of
> just created element.
>
> I am well aware of the ElementInitializer's that allow me to generate some
> initialization logic, but it is not my case, because I want to set up
> unrelated properties. (As an example of what I am going to achieve, consider
> the element type for uml Class with all its constraints and initializers and
> additional creation tool that creates classes with my preferred name
> "MGolubevClass").
>
> I would like to reuse UnspecifiedTypeCreationTool /
> UnspecifiedTypeConnectionTool but execute additional tool-specific command
> after default one from SemanticEditPolicy is successfully executed.
>
> Is it the correct way to do it? The problem is that actually the
> UnspecifiedTypeCreationTool (via super class) has following code:
>
> protected void performCreation(int button) {
> antiScroll = true;
>
> EditPartViewer viewer = getCurrentViewer();
> Command c = getCurrentCommand();
> executeCurrentCommand();
> selectAddedObject(viewer, DiagramCommandStack.getReturnValues(c));
>
> antiScroll = false;
> }
>
> It looks like I have to copy-paste the whole method into my custom tool
> class to access new object.
> It would be helpful if this code would be refactored as follows:
>
> protected void performCreation(int button) {
> antiScroll = true;
>
> Command c = getCurrentCommand();
> executeCurrentCommand();
> hookElementsCreated(DiagramCommandStack.getReturnValues(c));
>
> antiScroll = false;
> }
>
> protected void hookElementsCreated(Collection justCreated) {
> selectAddedObject(getCurrentViewer(), justCreated);
> }
>
> The things are far more complicated in the link creation tool that contains
> 2 different paths that creates new elements (createConnection() and
> handleCreateConnection()). It seems that in the actual state, I need to
> copy-paste more than 70 of not trivial LOCs to access new created object.
> The single hook method would be really helpful.
>
> Regards,
> Michael
>
>
|
|
|
Re: [GMF-Runtime] Custom initialization in the default creation tools [message #71645 is a reply to message #71459] |
Mon, 30 October 2006 15:53 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Eclipse User![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=) |
|
|
|
Originally posted by: vcciubot.uwaterloo.ca
> I would like to implement custom creation tool that setup some properties of
> just created element.
>
> I am well aware of the ElementInitializer's that allow me to generate some
> initialization logic, but it is not my case, because I want to set up
> unrelated properties. (As an example of what I am going to achieve, consider
> the element type for uml Class with all its constraints and initializers and
> additional creation tool that creates classes with my preferred name
> "MGolubevClass").
>
> I would like to reuse UnspecifiedTypeCreationTool /
> UnspecifiedTypeConnectionTool but execute additional tool-specific command
> after default one from SemanticEditPolicy is successfully executed.
You can create a specialization type your uml Class model type. And
associate with it a AbstractEditHelperAdvice. In the advice you can bind
a command post-configuration command that sets up your desired properties
of the element.
/*
* (non-Javadoc)
*
* @see org.eclipse.gmf.runtime.emf.type.core.edithelper.IEditHelper Advice#getAfterEditCommand(org.eclipse.gmf.runtime.emf.type. core.edithelper.IEditCommandRequest)
*/
public ICommand getAfterEditCommand(IEditCommandRequest request) {
if (request instanceof CreateRelationshipRequest) {
return getAfterCreateRelationshipCommand((CreateRelationshipRequest ) request);
} else if (request instanceof CreateElementRequest) {
return getAfterCreateCommand((CreateElementRequest) request);
} else if (request instanceof ConfigureRequest) {
return getAfterConfigureCommand((ConfigureRequest) request);
It's done in the logic example, also documented in the GMF Programmer's
manual: runtime -> Use of the Extensible Type Registry in GMF
You can use a creation tool with this specialization type, don't need to
override any tool behaviour.
> The things are far more complicated in the link creation tool that contains
> 2 different paths that creates new elements (createConnection() and
> handleCreateConnection()). It seems that in the actual state, I need to
> copy-paste more than 70 of not trivial LOCs to access new created object.
> The single hook method would be really helpful.
The above idea works for connections too.
If you need to create arbitrary connection elements with one 'Create
connection gesture' the easiest way is to override the graphical node edit
policy on the target of the connection. You can return there an arbitrary
semantic command that does more than one thing. If you have a canonical
policy for connections, you don't have to worry about creating edges:
//copy & paste from super, comment out the notational command and return
//custom semantic command
protected Command getConnectionAndRelationshipCompleteCommand(
CreateConnectionViewAndElementRequest request) {
// get the element descriptor
CreateElementRequestAdapter requestAdapter = request
.getConnectionViewAndElementDescriptor().getCreateElementReq uestAdapter();
// get the semantic request
CreateRelationshipRequest createElementRequest = (CreateRelationshipRequest) requestAdapter
.getAdapter(CreateRelationshipRequest.class);
createElementRequest.setPrompt(!request.isUISupressed());
// complete the semantic request by filling in the source and
// destination
INodeEditPart targetEP = getConnectionCompleteEditPart(request);
View sourceView = (View)request.getSourceEditPart().getModel();
View targetView = (View)targetEP.getModel();
// resolve the source
EObject source = ViewUtil.resolveSemanticElement(sourceView);
if (source == null) {
source = sourceView;
}
createElementRequest.setSource(source);
// resolve the target
EObject target = ViewUtil.resolveSemanticElement(targetView);
if (target == null) {
target = targetView;
}
createElementRequest.setTarget(target);
// get the create element request based on the elementdescriptor's
// request
Command createElementCommand = /* targetEP
.getCommand(new EditCommandRequestWrapper(
(CreateRelationshipRequest) requestAdapter
.getAdapter(CreateRelationshipRequest.class), request.getExtendedData()));*/
new ICommandProxy (new CreateSegmentsCommand((End) source, (End) target));
// create the create semantic element wrapper command
if (null == createElementCommand)
return null;
SemanticCreateCommand semanticCommand = new SemanticCreateCommand(
requestAdapter, createElementCommand);
// get the view command
Command viewCommand = getConnectionCompleteCommand(request);
if (null == viewCommand)
return null;
// form the compound command and return
CompositeCommand cc = new CompositeCommand(semanticCommand.getLabel());
cc.compose( semanticCommand );
//cc.compose( new CommandProxy(viewCommand) );
return new ICommandProxy(cc);
}
|
|
|
Re: [GMF-Runtime] Custom initialization in the default creation tools [message #71681 is a reply to message #71626] |
Mon, 30 October 2006 16:51 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Michael Golubev![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=borlander%40gmail.com) Messages: 383 Registered: July 2009 |
Senior Member |
|
|
Hi,
Yes, I understand that new specialization type would solve my problem.
But I am intentionally trying to avoid the usage of the new element type (or
specialization type), intentionally limiting the initialization logic to
invocation from this particular toolbar.
I used the imaginary use case with "MGolubevClass" to highlight the fact
that this kind of element represent exactly the same concept in the semantic
model as just-the-normal-class. The only difference between them is the
initial name that may be changed in future. After all, I do not want to have
some code that listens for the renaming to determine the possible change
from specialization type (with its fixed gmf visual id) to the common
metamodel type.
Probably the better imaginary usecase would be requirement to show
configuration dialog just after creation of the new element by this
particular tool. It is definitely related to the tool itself, not to the
element type created by this tool.
In any case, thank you for help,
Michael,
"Linda Damus" <ldamus@ca.ibm.com> wrote in message
news:ei56ne$oup$1@utils.eclipse.org...
> Hi Michael,
>
> Did you consider creating a specialization type (in the elementTypes
> extension point) for your tool? That way you could contribute an
> IEditHelperAdvice that sets the name to "MGolubevClass" after the class is
> created (by implementing #getAfterConfigureCommand()). The
> UnspecifiedTypeCreationTool would be initialized with this specialization
> type as one of the choices it presents to the user.
>
> The advantage to creating a specialization type is that you will be able
> to reuse the extended semantic behaviour if you later decide to support
> the same element creation from a popup toolbar, a context menu, a dialog,
> etc. Creating a custom tool to extend the semantic behaviour limits that
> extension to the tool palette.
>
> Hope that helps,
> Linda
>
> Michael Golubev wrote:
>> Hi,
>>
>> I would like to implement custom creation tool that setup some properties
>> of just created element.
>>
>> I am well aware of the ElementInitializer's that allow me to generate
>> some initialization logic, but it is not my case, because I want to set
>> up unrelated properties. (As an example of what I am going to achieve,
>> consider the element type for uml Class with all its constraints and
>> initializers and additional creation tool that creates classes with my
>> preferred name "MGolubevClass").
>>
>> I would like to reuse UnspecifiedTypeCreationTool /
>> UnspecifiedTypeConnectionTool but execute additional tool-specific
>> command after default one from SemanticEditPolicy is successfully
>> executed.
>>
>> Is it the correct way to do it? The problem is that actually the
>> UnspecifiedTypeCreationTool (via super class) has following code:
>>
>> protected void performCreation(int button) {
>> antiScroll = true;
>>
>> EditPartViewer viewer = getCurrentViewer();
>> Command c = getCurrentCommand();
>> executeCurrentCommand();
>> selectAddedObject(viewer, DiagramCommandStack.getReturnValues(c));
>>
>> antiScroll = false;
>> }
>>
>> It looks like I have to copy-paste the whole method into my custom tool
>> class to access new object.
>> It would be helpful if this code would be refactored as follows:
>>
>> protected void performCreation(int button) {
>> antiScroll = true;
>>
>> Command c = getCurrentCommand();
>> executeCurrentCommand();
>> hookElementsCreated(DiagramCommandStack.getReturnValues(c));
>>
>> antiScroll = false;
>> }
>>
>> protected void hookElementsCreated(Collection justCreated) {
>> selectAddedObject(getCurrentViewer(), justCreated);
>> }
>>
>> The things are far more complicated in the link creation tool that
>> contains 2 different paths that creates new elements (createConnection()
>> and handleCreateConnection()). It seems that in the actual state, I need
>> to copy-paste more than 70 of not trivial LOCs to access new created
>> object. The single hook method would be really helpful.
>>
>> Regards,
>> Michael
|
|
|
Re: [GMF-Runtime] Custom initialization in the default creation tools [message #72073 is a reply to message #71681] |
Tue, 31 October 2006 14:18 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Cherie Revells![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=crevells%40ca.ibm.com) Messages: 299 Registered: July 2009 |
Senior Member |
|
|
Michael,
If Linda's solution is not suitable in your case, you could use an
editpolicy to contribute the command that will popup a configuration
dialog. You could subclass the CreationTool to create a request with a
flag set indicating you would like to popup a configuration dialog.
Your CreationEditPolicy or GraphicalNodeEditPolicy (in the case of
connection creation) could add a command to popup the dialog, similar to
how the CreationEditPolicy.getUnspecifiedTypeCreateCommand() adds a
command that will popup a dialog for the user to select which type of
element they wish to create.
Speaking from experience, we have learned that customizing the
CreationTool is not the best approach. At this point, you say that this
is the only place you want to be able to create this type, but if you
change your mind in the future it will be much simpler to reuse this
behavior if it is accessible via a request.
I hope this helps.
- Cherie
Michael Golubev wrote:
> Hi,
>
> Yes, I understand that new specialization type would solve my problem.
>
> But I am intentionally trying to avoid the usage of the new element type (or
> specialization type), intentionally limiting the initialization logic to
> invocation from this particular toolbar.
>
> I used the imaginary use case with "MGolubevClass" to highlight the fact
> that this kind of element represent exactly the same concept in the semantic
> model as just-the-normal-class. The only difference between them is the
> initial name that may be changed in future. After all, I do not want to have
> some code that listens for the renaming to determine the possible change
> from specialization type (with its fixed gmf visual id) to the common
> metamodel type.
>
> Probably the better imaginary usecase would be requirement to show
> configuration dialog just after creation of the new element by this
> particular tool. It is definitely related to the tool itself, not to the
> element type created by this tool.
>
> In any case, thank you for help,
> Michael,
>
> "Linda Damus" <ldamus@ca.ibm.com> wrote in message
> news:ei56ne$oup$1@utils.eclipse.org...
>> Hi Michael,
>>
>> Did you consider creating a specialization type (in the elementTypes
>> extension point) for your tool? That way you could contribute an
>> IEditHelperAdvice that sets the name to "MGolubevClass" after the class is
>> created (by implementing #getAfterConfigureCommand()). The
>> UnspecifiedTypeCreationTool would be initialized with this specialization
>> type as one of the choices it presents to the user.
>>
>> The advantage to creating a specialization type is that you will be able
>> to reuse the extended semantic behaviour if you later decide to support
>> the same element creation from a popup toolbar, a context menu, a dialog,
>> etc. Creating a custom tool to extend the semantic behaviour limits that
>> extension to the tool palette.
>>
>> Hope that helps,
>> Linda
>>
>> Michael Golubev wrote:
>>> Hi,
>>>
>>> I would like to implement custom creation tool that setup some properties
>>> of just created element.
>>>
>>> I am well aware of the ElementInitializer's that allow me to generate
>>> some initialization logic, but it is not my case, because I want to set
>>> up unrelated properties. (As an example of what I am going to achieve,
>>> consider the element type for uml Class with all its constraints and
>>> initializers and additional creation tool that creates classes with my
>>> preferred name "MGolubevClass").
>>>
>>> I would like to reuse UnspecifiedTypeCreationTool /
>>> UnspecifiedTypeConnectionTool but execute additional tool-specific
>>> command after default one from SemanticEditPolicy is successfully
>>> executed.
>>>
>>> Is it the correct way to do it? The problem is that actually the
>>> UnspecifiedTypeCreationTool (via super class) has following code:
>>>
>>> protected void performCreation(int button) {
>>> antiScroll = true;
>>>
>>> EditPartViewer viewer = getCurrentViewer();
>>> Command c = getCurrentCommand();
>>> executeCurrentCommand();
>>> selectAddedObject(viewer, DiagramCommandStack.getReturnValues(c));
>>>
>>> antiScroll = false;
>>> }
>>>
>>> It looks like I have to copy-paste the whole method into my custom tool
>>> class to access new object.
>>> It would be helpful if this code would be refactored as follows:
>>>
>>> protected void performCreation(int button) {
>>> antiScroll = true;
>>>
>>> Command c = getCurrentCommand();
>>> executeCurrentCommand();
>>> hookElementsCreated(DiagramCommandStack.getReturnValues(c));
>>>
>>> antiScroll = false;
>>> }
>>>
>>> protected void hookElementsCreated(Collection justCreated) {
>>> selectAddedObject(getCurrentViewer(), justCreated);
>>> }
>>>
>>> The things are far more complicated in the link creation tool that
>>> contains 2 different paths that creates new elements (createConnection()
>>> and handleCreateConnection()). It seems that in the actual state, I need
>>> to copy-paste more than 70 of not trivial LOCs to access new created
>>> object. The single hook method would be really helpful.
>>>
>>> Regards,
>>> Michael
>
>
|
|
|
Re: [GMF-Runtime] Custom initialization in the default creation tools [message #72665 is a reply to message #71681] |
Wed, 01 November 2006 14:34 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Linda Damus![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=ldamus%40ca.ibm.com) Messages: 85 Registered: July 2009 |
Member |
|
|
One more thing to think about is that if you edit the model when the
configuration dialog is applied by your custom tool, you can end up with
two operations on the undo stack. The user may expect to be able to
undo the tool gesture in a single step.
--Linda
Michael Golubev wrote:
> Hi,
>
> Yes, I understand that new specialization type would solve my problem.
>
> But I am intentionally trying to avoid the usage of the new element type (or
> specialization type), intentionally limiting the initialization logic to
> invocation from this particular toolbar.
>
> I used the imaginary use case with "MGolubevClass" to highlight the fact
> that this kind of element represent exactly the same concept in the semantic
> model as just-the-normal-class. The only difference between them is the
> initial name that may be changed in future. After all, I do not want to have
> some code that listens for the renaming to determine the possible change
> from specialization type (with its fixed gmf visual id) to the common
> metamodel type.
>
> Probably the better imaginary usecase would be requirement to show
> configuration dialog just after creation of the new element by this
> particular tool. It is definitely related to the tool itself, not to the
> element type created by this tool.
>
> In any case, thank you for help,
> Michael,
>
> "Linda Damus" <ldamus@ca.ibm.com> wrote in message
> news:ei56ne$oup$1@utils.eclipse.org...
>> Hi Michael,
>>
>> Did you consider creating a specialization type (in the elementTypes
>> extension point) for your tool? That way you could contribute an
>> IEditHelperAdvice that sets the name to "MGolubevClass" after the class is
>> created (by implementing #getAfterConfigureCommand()). The
>> UnspecifiedTypeCreationTool would be initialized with this specialization
>> type as one of the choices it presents to the user.
>>
>> The advantage to creating a specialization type is that you will be able
>> to reuse the extended semantic behaviour if you later decide to support
>> the same element creation from a popup toolbar, a context menu, a dialog,
>> etc. Creating a custom tool to extend the semantic behaviour limits that
>> extension to the tool palette.
>>
>> Hope that helps,
>> Linda
>>
>> Michael Golubev wrote:
>>> Hi,
>>>
>>> I would like to implement custom creation tool that setup some properties
>>> of just created element.
>>>
>>> I am well aware of the ElementInitializer's that allow me to generate
>>> some initialization logic, but it is not my case, because I want to set
>>> up unrelated properties. (As an example of what I am going to achieve,
>>> consider the element type for uml Class with all its constraints and
>>> initializers and additional creation tool that creates classes with my
>>> preferred name "MGolubevClass").
>>>
>>> I would like to reuse UnspecifiedTypeCreationTool /
>>> UnspecifiedTypeConnectionTool but execute additional tool-specific
>>> command after default one from SemanticEditPolicy is successfully
>>> executed.
>>>
>>> Is it the correct way to do it? The problem is that actually the
>>> UnspecifiedTypeCreationTool (via super class) has following code:
>>>
>>> protected void performCreation(int button) {
>>> antiScroll = true;
>>>
>>> EditPartViewer viewer = getCurrentViewer();
>>> Command c = getCurrentCommand();
>>> executeCurrentCommand();
>>> selectAddedObject(viewer, DiagramCommandStack.getReturnValues(c));
>>>
>>> antiScroll = false;
>>> }
>>>
>>> It looks like I have to copy-paste the whole method into my custom tool
>>> class to access new object.
>>> It would be helpful if this code would be refactored as follows:
>>>
>>> protected void performCreation(int button) {
>>> antiScroll = true;
>>>
>>> Command c = getCurrentCommand();
>>> executeCurrentCommand();
>>> hookElementsCreated(DiagramCommandStack.getReturnValues(c));
>>>
>>> antiScroll = false;
>>> }
>>>
>>> protected void hookElementsCreated(Collection justCreated) {
>>> selectAddedObject(getCurrentViewer(), justCreated);
>>> }
>>>
>>> The things are far more complicated in the link creation tool that
>>> contains 2 different paths that creates new elements (createConnection()
>>> and handleCreateConnection()). It seems that in the actual state, I need
>>> to copy-paste more than 70 of not trivial LOCs to access new created
>>> object. The single hook method would be really helpful.
>>>
>>> Regards,
>>> Michael
>
>
|
|
|
Re: [GMF-Runtime] Custom initialization in the default creation tools [message #72885 is a reply to message #72665] |
Wed, 01 November 2006 17:16 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Michael Golubev![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=borlander%40gmail.com) Messages: 383 Registered: July 2009 |
Senior Member |
|
|
Hi,
Ok. You have convinced me that usage of EditHelper's infrastructure is the
only correct way to do it :).
Unfortunately there are still some problems while going this way.
Again, I know how to solve this problems (see below) but I don't like the
resulting code and hope that it may be improved.
I still do not want to create different element/specialization types for my
scenario (trust me, it is not really an option for my scenario, I am
actually forced to use single element type).
Instead of executing the command from the tool, I added the following code
into the generated MyEditHelper class:
public static final PARAM_NAME = "MyParam";
/**
* @generated NOT
*/
protected ICommand getConfigureCommand(ConfigureRequest req) {
if (req.getParameter(PARAM_NAME) != null) {
EObject justCreated = req.getElementToConfigure();
Object toolSpecificValue = req.getParameter(PARAM_NAME);
SetRequest request = new SetRequest(justCreated, myEStructuralFeature,
toolSpecificValue);
return new SetValueCommand(request);
}
return super.getConfigureCommand(req);
}
and have modified tool class as follows
public MyTool extends UnspecifiedTypeConnectionTool {
private final Object myValue;
public MyTool(Object value){
myValue = value;
}
protected Request createTargetRequest() {
Request request = super.createTargetRequest();
setToolSpecificParameter(request, myValue);
return request;
}
}
In this scenario, the custom tool specifies the value for custom
initialziation code that is executed via edit helper handling any
ConfigureRequest. It seems to be natural way and I like it.
The only remaining part is to implement setToolSpecificParameter()
IMHO, the most logical way to do it is:
private void setToolSpecificParameter(Request request, Object value){
//DOES NOT WORK
request.getExtendedData().put(MyEditHelper.PARAM_NAME, value);
}
Unfortunately, it does not work. The problem is that IEditCommandRequest
that is passed to EditHelper and CreateUnspecifiedTypeConnectionRequest
created by tool are absolutely diifferent instances. That does not share
parameters. Below is the only working way I found looking at the code.
private setToolSpecificParameter(Request req, Object toolValue){
//WORKS, but seems to be an ugly hack
CreateUnspecifiedTypeConnectionRequest request =
(CreateUnspecifiedTypeConnectionRequest)req;
//below is the only way to propagate extended data into
IEditCommandRequest#parameters
HashMap extendedData = new HashMap();
extendedData.putAll(request.getExtendedData());
extendedData.put(MyEditHelper.PARAM_NAME, toolValue);
for (CreateRequest next : (List<CreateRequest>)request.getAllRequests()){
next.setExtendedData(extendedData);
}
}
It works due to the code from CreateConnectionViewAndElementRequest, lines
230-251, that handles setExtendedData() and pushes the parameters map into
the underlying IEditCommandRequest.
Note that it handles only setExtendedData() not the changes into the
existing map via getExtendedData().put(...);
Also note that the composite request
(CreateUnspecifiedTypeConnectionRequest) does not handle changes of
parameters pushing them into concrete CreateRequest's like it is done, say,
for setLocation() method.
Probably it makes sense to change the both requests code to push this
changes automatically. That will allow my first attempt (that is, the code
marked with //DOES NOT WORK) to work.
I have complete patch for this change, if you are interested, please let me
know, I will submit Bugzilla and attach patch to it.
Regards,
Michael
"Linda Damus" <ldamus@ca.ibm.com> wrote in message
news:eiab92$9g4$1@utils.eclipse.org...
> One more thing to think about is that if you edit the model when the
> configuration dialog is applied by your custom tool, you can end up with
> two operations on the undo stack. The user may expect to be able to undo
> the tool gesture in a single step.
>
> --Linda
>
> Michael Golubev wrote:
>> Hi,
>>
>> Yes, I understand that new specialization type would solve my problem.
>>
>> But I am intentionally trying to avoid the usage of the new element type
>> (or specialization type), intentionally limiting the initialization logic
>> to invocation from this particular toolbar.
>>
>> I used the imaginary use case with "MGolubevClass" to highlight the fact
>> that this kind of element represent exactly the same concept in the
>> semantic model as just-the-normal-class. The only difference between them
>> is the initial name that may be changed in future. After all, I do not
>> want to have some code that listens for the renaming to determine the
>> possible change from specialization type (with its fixed gmf visual id)
>> to the common metamodel type.
>>
>> Probably the better imaginary usecase would be requirement to show
>> configuration dialog just after creation of the new element by this
>> particular tool. It is definitely related to the tool itself, not to the
>> element type created by this tool.
>>
>> In any case, thank you for help,
>> Michael,
>>
>> "Linda Damus" <ldamus@ca.ibm.com> wrote in message
>> news:ei56ne$oup$1@utils.eclipse.org...
>>> Hi Michael,
>>>
>>> Did you consider creating a specialization type (in the elementTypes
>>> extension point) for your tool? That way you could contribute an
>>> IEditHelperAdvice that sets the name to "MGolubevClass" after the class
>>> is created (by implementing #getAfterConfigureCommand()). The
>>> UnspecifiedTypeCreationTool would be initialized with this
>>> specialization type as one of the choices it presents to the user.
>>>
>>> The advantage to creating a specialization type is that you will be able
>>> to reuse the extended semantic behaviour if you later decide to support
>>> the same element creation from a popup toolbar, a context menu, a
>>> dialog, etc. Creating a custom tool to extend the semantic behaviour
>>> limits that extension to the tool palette.
>>>
>>> Hope that helps,
>>> Linda
>>>
>>> Michael Golubev wrote:
>>>> Hi,
>>>>
>>>> I would like to implement custom creation tool that setup some
>>>> properties of just created element.
>>>>
>>>> I am well aware of the ElementInitializer's that allow me to generate
>>>> some initialization logic, but it is not my case, because I want to set
>>>> up unrelated properties. (As an example of what I am going to achieve,
>>>> consider the element type for uml Class with all its constraints and
>>>> initializers and additional creation tool that creates classes with my
>>>> preferred name "MGolubevClass").
>>>>
>>>> I would like to reuse UnspecifiedTypeCreationTool /
>>>> UnspecifiedTypeConnectionTool but execute additional tool-specific
>>>> command after default one from SemanticEditPolicy is successfully
>>>> executed.
>>>>
>>>> Is it the correct way to do it? The problem is that actually the
>>>> UnspecifiedTypeCreationTool (via super class) has following code:
>>>>
>>>> protected void performCreation(int button) {
>>>> antiScroll = true;
>>>>
>>>> EditPartViewer viewer = getCurrentViewer();
>>>> Command c = getCurrentCommand();
>>>> executeCurrentCommand();
>>>> selectAddedObject(viewer, DiagramCommandStack.getReturnValues(c));
>>>>
>>>> antiScroll = false;
>>>> }
>>>>
>>>> It looks like I have to copy-paste the whole method into my custom tool
>>>> class to access new object.
>>>> It would be helpful if this code would be refactored as follows:
>>>>
>>>> protected void performCreation(int button) {
>>>> antiScroll = true;
>>>>
>>>> Command c = getCurrentCommand();
>>>> executeCurrentCommand();
>>>> hookElementsCreated(DiagramCommandStack.getReturnValues(c));
>>>>
>>>> antiScroll = false;
>>>> }
>>>>
>>>> protected void hookElementsCreated(Collection justCreated) {
>>>> selectAddedObject(getCurrentViewer(), justCreated);
>>>> }
>>>>
>>>> The things are far more complicated in the link creation tool that
>>>> contains 2 different paths that creates new elements
>>>> (createConnection() and handleCreateConnection()). It seems that in the
>>>> actual state, I need to copy-paste more than 70 of not trivial LOCs to
>>>> access new created object. The single hook method would be really
>>>> helpful.
>>>>
>>>> Regards,
>>>> Michael
>>
|
|
|
Re: [GMF-Runtime] Custom initialization in the default creation tools [message #72907 is a reply to message #72885] |
Wed, 01 November 2006 17:44 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
Linda Damus![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=ldamus%40ca.ibm.com) Messages: 85 Registered: July 2009 |
Member |
|
|
Hi Michael,
Thank you for the thorough analysis and offer of a patch! Sorry about
the bugs and yes, please do open a bugzilla. The request parameters
should certainly be propagated throughout.
Doubtless there are other correct solutions, but I do like the one that
you have proposed :-)
Regards,
Linda
Michael Golubev wrote:
> Hi,
>
> Ok. You have convinced me that usage of EditHelper's infrastructure is the
> only correct way to do it :).
>
> Unfortunately there are still some problems while going this way.
> Again, I know how to solve this problems (see below) but I don't like the
> resulting code and hope that it may be improved.
>
> I still do not want to create different element/specialization types for my
> scenario (trust me, it is not really an option for my scenario, I am
> actually forced to use single element type).
>
> Instead of executing the command from the tool, I added the following code
> into the generated MyEditHelper class:
>
> public static final PARAM_NAME = "MyParam";
>
> /**
> * @generated NOT
> */
> protected ICommand getConfigureCommand(ConfigureRequest req) {
> if (req.getParameter(PARAM_NAME) != null) {
> EObject justCreated = req.getElementToConfigure();
> Object toolSpecificValue = req.getParameter(PARAM_NAME);
> SetRequest request = new SetRequest(justCreated, myEStructuralFeature,
> toolSpecificValue);
> return new SetValueCommand(request);
> }
> return super.getConfigureCommand(req);
> }
>
> and have modified tool class as follows
>
> public MyTool extends UnspecifiedTypeConnectionTool {
> private final Object myValue;
>
> public MyTool(Object value){
> myValue = value;
> }
>
> protected Request createTargetRequest() {
> Request request = super.createTargetRequest();
> setToolSpecificParameter(request, myValue);
> return request;
> }
>
> }
>
> In this scenario, the custom tool specifies the value for custom
> initialziation code that is executed via edit helper handling any
> ConfigureRequest. It seems to be natural way and I like it.
>
> The only remaining part is to implement setToolSpecificParameter()
>
> IMHO, the most logical way to do it is:
>
> private void setToolSpecificParameter(Request request, Object value){
> //DOES NOT WORK
> request.getExtendedData().put(MyEditHelper.PARAM_NAME, value);
> }
>
> Unfortunately, it does not work. The problem is that IEditCommandRequest
> that is passed to EditHelper and CreateUnspecifiedTypeConnectionRequest
> created by tool are absolutely diifferent instances. That does not share
> parameters. Below is the only working way I found looking at the code.
>
> private setToolSpecificParameter(Request req, Object toolValue){
> //WORKS, but seems to be an ugly hack
> CreateUnspecifiedTypeConnectionRequest request =
> (CreateUnspecifiedTypeConnectionRequest)req;
> //below is the only way to propagate extended data into
> IEditCommandRequest#parameters
> HashMap extendedData = new HashMap();
> extendedData.putAll(request.getExtendedData());
> extendedData.put(MyEditHelper.PARAM_NAME, toolValue);
> for (CreateRequest next : (List<CreateRequest>)request.getAllRequests()){
> next.setExtendedData(extendedData);
> }
>
> }
>
> It works due to the code from CreateConnectionViewAndElementRequest, lines
> 230-251, that handles setExtendedData() and pushes the parameters map into
> the underlying IEditCommandRequest.
>
> Note that it handles only setExtendedData() not the changes into the
> existing map via getExtendedData().put(...);
> Also note that the composite request
> (CreateUnspecifiedTypeConnectionRequest) does not handle changes of
> parameters pushing them into concrete CreateRequest's like it is done, say,
> for setLocation() method.
>
> Probably it makes sense to change the both requests code to push this
> changes automatically. That will allow my first attempt (that is, the code
> marked with //DOES NOT WORK) to work.
>
> I have complete patch for this change, if you are interested, please let me
> know, I will submit Bugzilla and attach patch to it.
>
> Regards,
> Michael
>
> "Linda Damus" <ldamus@ca.ibm.com> wrote in message
> news:eiab92$9g4$1@utils.eclipse.org...
>> One more thing to think about is that if you edit the model when the
>> configuration dialog is applied by your custom tool, you can end up with
>> two operations on the undo stack. The user may expect to be able to undo
>> the tool gesture in a single step.
>>
>> --Linda
>>
>> Michael Golubev wrote:
>>> Hi,
>>>
>>> Yes, I understand that new specialization type would solve my problem.
>>>
>>> But I am intentionally trying to avoid the usage of the new element type
>>> (or specialization type), intentionally limiting the initialization logic
>>> to invocation from this particular toolbar.
>>>
>>> I used the imaginary use case with "MGolubevClass" to highlight the fact
>>> that this kind of element represent exactly the same concept in the
>>> semantic model as just-the-normal-class. The only difference between them
>>> is the initial name that may be changed in future. After all, I do not
>>> want to have some code that listens for the renaming to determine the
>>> possible change from specialization type (with its fixed gmf visual id)
>>> to the common metamodel type.
>>>
>>> Probably the better imaginary usecase would be requirement to show
>>> configuration dialog just after creation of the new element by this
>>> particular tool. It is definitely related to the tool itself, not to the
>>> element type created by this tool.
>>>
>>> In any case, thank you for help,
>>> Michael,
>>>
>>> "Linda Damus" <ldamus@ca.ibm.com> wrote in message
>>> news:ei56ne$oup$1@utils.eclipse.org...
>>>> Hi Michael,
>>>>
>>>> Did you consider creating a specialization type (in the elementTypes
>>>> extension point) for your tool? That way you could contribute an
>>>> IEditHelperAdvice that sets the name to "MGolubevClass" after the class
>>>> is created (by implementing #getAfterConfigureCommand()). The
>>>> UnspecifiedTypeCreationTool would be initialized with this
>>>> specialization type as one of the choices it presents to the user.
>>>>
>>>> The advantage to creating a specialization type is that you will be able
>>>> to reuse the extended semantic behaviour if you later decide to support
>>>> the same element creation from a popup toolbar, a context menu, a
>>>> dialog, etc. Creating a custom tool to extend the semantic behaviour
>>>> limits that extension to the tool palette.
>>>>
>>>> Hope that helps,
>>>> Linda
>>>>
>>>> Michael Golubev wrote:
>>>>> Hi,
>>>>>
>>>>> I would like to implement custom creation tool that setup some
>>>>> properties of just created element.
>>>>>
>>>>> I am well aware of the ElementInitializer's that allow me to generate
>>>>> some initialization logic, but it is not my case, because I want to set
>>>>> up unrelated properties. (As an example of what I am going to achieve,
>>>>> consider the element type for uml Class with all its constraints and
>>>>> initializers and additional creation tool that creates classes with my
>>>>> preferred name "MGolubevClass").
>>>>>
>>>>> I would like to reuse UnspecifiedTypeCreationTool /
>>>>> UnspecifiedTypeConnectionTool but execute additional tool-specific
>>>>> command after default one from SemanticEditPolicy is successfully
>>>>> executed.
>>>>>
>>>>> Is it the correct way to do it? The problem is that actually the
>>>>> UnspecifiedTypeCreationTool (via super class) has following code:
>>>>>
>>>>> protected void performCreation(int button) {
>>>>> antiScroll = true;
>>>>>
>>>>> EditPartViewer viewer = getCurrentViewer();
>>>>> Command c = getCurrentCommand();
>>>>> executeCurrentCommand();
>>>>> selectAddedObject(viewer, DiagramCommandStack.getReturnValues(c));
>>>>>
>>>>> antiScroll = false;
>>>>> }
>>>>>
>>>>> It looks like I have to copy-paste the whole method into my custom tool
>>>>> class to access new object.
>>>>> It would be helpful if this code would be refactored as follows:
>>>>>
>>>>> protected void performCreation(int button) {
>>>>> antiScroll = true;
>>>>>
>>>>> Command c = getCurrentCommand();
>>>>> executeCurrentCommand();
>>>>> hookElementsCreated(DiagramCommandStack.getReturnValues(c));
>>>>>
>>>>> antiScroll = false;
>>>>> }
>>>>>
>>>>> protected void hookElementsCreated(Collection justCreated) {
>>>>> selectAddedObject(getCurrentViewer(), justCreated);
>>>>> }
>>>>>
>>>>> The things are far more complicated in the link creation tool that
>>>>> contains 2 different paths that creates new elements
>>>>> (createConnection() and handleCreateConnection()). It seems that in the
>>>>> actual state, I need to copy-paste more than 70 of not trivial LOCs to
>>>>> access new created object. The single hook method would be really
>>>>> helpful.
>>>>>
>>>>> Regards,
>>>>> Michael
>
|
|
|
Goto Forum:
Current Time: Sat Aug 17 00:10:35 GMT 2024
Powered by FUDForum. Page generated in 0.04914 seconds
|