Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc) » [EEF] Recipe for incorporating related views
| | | | |
Re: [EEF] Recipe for incorporating related views [message #516694 is a reply to message #513731] |
Wed, 24 February 2010 19:50 |
Miles Parker Messages: 1341 Registered: July 2009 |
Senior Member |
|
|
OK, thanks Goulwen, that was exactly what I needed and gave me the confidence that I was headed in the right direction. I spent yesterday getting this up and running and so here's the more involved recipe. Ce n'est pas de la tarte! But not too difficult either..
- In Repository for Library, add a Custom Element editor for "bookDetail".
- In Properties Edition for "Library", added a "bookDetail" that uses that view. I set the model to "books" because it needs to be bound to something, I think.
- Generated the code.
- Changed a bunch of code. (I'm only covering the forms stuff here as I don't need the regular parts for my usage.) My basic strategy was to delegate to the corresponding Book classes rather than copy the code whenever possible.
- In In LibraryPropertiesEditionPartForm
- protected void createBooksTableComposition(FormToolkit widgetFactory, Composite parent) {
// Start of user code for additional ui definition
this.attributes.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
if (e.item != null) {
Object data = e.item.getData();
if (data instanceof Book) {
if (e.item != null && e.item.getData() instanceof EObject) {
EObject attr = attributesEditUtil.foundCorrespondingEObject((EObject) e.item.getData());
setCurrentAttribute((Book) attr);
return;
}
}
}
setCurrentAttribute(null);
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
// End of user code
This was my biggest hangup, because I didn't know that I needed to use the utility to find a different corresponding eObject. If I'd have figured that out, it would have been much quicker. Also, I think that I may not be doing this in the best way. I noticed in the Tarot example that you used a fireProperties instead of setting the values explicitly, but I couldn't easily make that work.
- Instead I created this method:
private void setCurrentAttribute(Book book) {
((LibraryPropertiesEditionComponent) propertiesEditionComponent).setbook(book);
attributesComponent.setLiveEditingDomain(((LibraryPropertiesEditionComponent) propertiesEditionComponent)
.getLiveDomain());
((LibraryPropertiesEditionComponent) propertiesEditionComponent).setbookProps(attributesComponent);
attributesComponent.setPropertiesEditionPart(MetaabmViewsRepository.Book.class, 0, attributesForm);
attributesComponent.addListener(attributesForm);
attributesComponent.addListener(this);
attributesComponent.setAttribute(book);
if (book != null) {
attributesComponent.initPart(MetaabmViewsRepository.Book.class, 0, book, resourceSet);
} else {
attributesComponent.initPart(MetaabmViewsRepository.Book.class, 0, null, resourceSet);
}
}
protected void createBooksGroup(FormToolkit widgetFactory, final Composite view) {
// Start of user code for attributeDetail widgets implementation
GridData attributesGroupData2 = new GridData(SWT.FILL, SWT.TOP, true, false);
attributesForm.createDetailsGroup(widgetFactory, attributesGroup, Section.TITLE_BAR | Section.TWISTIE
| Section.EXPANDED);
attributesForm.getDetailsSection().setLayoutData(attributesGroupData2);
attributesComponent = new BookPropertiesEditionComponent(null, IPropertiesEditionComponent.LIVE_MODE);
// End of user code
- In In BookPropertiesEditionPartForm:
- Changed the constructor to break out the book setting to a seperate setter, like so:
/**
* Default constructor
*/
public BookPropertiesEditionComponent(EObject book, String editing_mode) {
this.editing_mode = editing_mode;
setAttribute((Book) book);
}
public void setAttribute(Book attr) {
if (book != null) {
this.book.eAdapters().remove(semanticAdapter);
}
this.book = attr;
if (book != null) {
if (IPropertiesEditionComponent.LIVE_MODE.equals(editing_mode)) {
if (semanticAdapter == null) {
semanticAdapter = initializeSemanticAdapter();
}
this.book.eAdapters().add(semanticAdapter);
}
}
}
. This let's me use it to set domain object independently. Perhaps there is a better way to do this, but the issue is that I want to be able to reuse the component if possible.
- In LibraryPropertiesEditionComponent -- these are the most important!
- Added the following fields and methods:
// Start of user code for attributeDetail properties
private Book book;
private BookPropertiesEditionComponent bookProps;
/**
* @param book the book to set
*/
public void setbook(Book book) {
this.book = book;
}
/**
* @param bookProps the bookProps to set
*/
public void setbookProps(BookPropertiesEditionComponent bookProps) {
this.bookProps = bookProps;
}
public EditingDomain getLiveDomain() {
return liveEditingDomain;
}
// End of user code
(The generator is not protecting my user code here for some reason, so I need to figure that out..) The point of this is that I need to keep a reference to the detail component and the detail domain object in the parent component. Or at least I think I do, perhaps there is a more clever way to do this.
- In protected void runUpdateRunnable(final Notification msg) {
// Start of user code for attributeDetail live update
if (msg.getNotifier() == book) {
bookProps.runUpdateRunnable(msg);
basePart.updateAttributes(library);
}
// End of user code
- In public CompoundCommand getPropertiesEditionCommand(EditingDomain editingDomain) {
// Start of user code for attributeDetail update command
if (book != null) {
CompoundCommand attrEditionCommand = bookProps.getPropertiesEditionCommand(editingDomain);
cc.append(attrEditionCommand);
}
// End of user code
- In public EObject getPropertiesEditionObject(EObject source) {
// Start of user code for attributeDetail part update
if (book != null) {
bookProps.getPropertiesEditionObject(book);
}
// End of user code
- In public void firePropertiesChanged(IPropertiesEditionEvent event) {
// Start of user code for attributeDetail live command update
if (book != null && event.getAffectedEditor().startsWith("metaabm::Book")) {
bookProps.firePropertiesChanged(event);
}
// End of user code
That's it! But I have probably missed something here..also there is much still to do, like making the add button not open the seperate part editor but instead allow users to enter it in the detail. Anyway, I hope it helps some other folks who might need to do this.
BTW, something that could be a translation issue, or may just be my not understanding all of the design yet, but does "Edition" in this context mean "a particular version / instantiation of something" or "something that is used for editing"? If the latter then the word doesn't quite mean that. It might be more clear as "Editing" or simply "Edit", so for example we would have "Property Editing Component" and "LibraryPropertiesEditPartForm".
[Updated on: Wed, 24 February 2010 19:52] Report message to a moderator
|
|
|
Re: [EEF] Recipe for incorporating related views [message #516807 is a reply to message #516694] |
Thu, 25 February 2010 09:01 |
Goulwen Le Fur Messages: 125 Registered: July 2009 |
Senior Member |
|
|
Hi Miles,
Miles Parker a écrit :
> OK, thanks Goulwen, that was exactly what I needed and gave me the
> confidence that I was headed in the right direction. I spent yesterday
> getting this up and running and so here's the more involved recipe. Ce
> n'est pas de la tarte! But not too difficult either..
>
huhu, I like your phrase ;)
>
> In Repository for Library, add a Custom Element editor for "bookDetail".
> In Properties Edition for "Library", added a "bookDetail" that uses that
> view. I set the model to "books" because it needs to be bound to
> something, I think.
> Generated the code.
> Changed a bunch of code. (I'm only covering the forms stuff here as I
> don't need the regular parts for my usage.) My basic strategy was to
> delegate to the corresponding Book classes rather than copy the code
> whenever possible.
> In In LibraryPropertiesEditionPartForm
>
> protected void createBooksTableComposition(FormToolkit widgetFactory,
> Composite parent) {
> // Start of user code for additional ui definition
> this.attributes.addSelectionListener(new SelectionListener() {
>
> public void widgetSelected(SelectionEvent e) {
> if (e.item != null) {
> Object data = e.item.getData();
> if (data instanceof Book) {
> if (e.item != null && e.item.getData() instanceof
> EObject) {
> EObject attr =
> attributesEditUtil.foundCorrespondingEObject((EObject) e.item.getData());
> setCurrentAttribute((Book) attr);
> return;
> }
> }
> }
> setCurrentAttribute(null);
> }
>
> public void widgetDefaultSelected(SelectionEvent e) {
> }
> });
> // End of user code
> This was my biggest hangup, because I didn't know that I needed to use
> the utility to find a different corresponding eObject. If I'd have
> figured that out, it would have been much quicker. Also, I think that I
> may not be doing this in the best way. I noticed in the Tarot example
> that you used a fireProperties instead of setting the values explicitly,
> but I couldn't easily make that work.
> Instead I created this method:
>
> private void setCurrentAttribute(Book book) {
> ((LibraryPropertiesEditionComponent)
> propertiesEditionComponent).setbook(book);
>
> attributesComponent.setLiveEditingDomain(((LibraryProperties EditionComponent)
> propertiesEditionComponent)
> .getLiveDomain());
> ((LibraryPropertiesEditionComponent)
> propertiesEditionComponent).setbookProps(attributesComponent );
>
> attributesComponent.setPropertiesEditionPart(MetaabmViewsRep ository.Book.class,
> 0, attributesForm);
> attributesComponent.addListener(attributesForm);
> attributesComponent.addListener(this);
> attributesComponent.setAttribute(book);
> if (book != null) {
>
> attributesComponent.initPart(MetaabmViewsRepository.Book.cla ss, 0, book,
> resourceSet);
> } else {
>
> attributesComponent.initPart(MetaabmViewsRepository.Book.cla ss, 0, null,
> resourceSet);
> }
> }
>
> protected void createBooksGroup(FormToolkit widgetFactory, final
> Composite view) {
>
> // Start of user code for attributeDetail widgets implementation
> GridData attributesGroupData2 = new GridData(SWT.FILL, SWT.TOP,
> true, false);
> attributesForm.createDetailsGroup(widgetFactory, attributesGroup,
> Section.TITLE_BAR | Section.TWISTIE
> | Section.EXPANDED);
>
> attributesForm.getDetailsSection().setLayoutData(attributesG roupData2);
> attributesComponent = new BookPropertiesEditionComponent(null,
> IPropertiesEditionComponent.LIVE_MODE);
> // End of user code
>
>
>
> In In BookPropertiesEditionPartForm:
>
> Changed the constructor to break out the book setting to a seperate
> setter, like so:
>
>
> /**
> * Default constructor
> */
> public BookPropertiesEditionComponent(EObject book, String
> editing_mode) {
> this.editing_mode = editing_mode;
> setAttribute((Book) book);
> }
>
> public void setAttribute(Book attr) {
> if (book != null) {
> this.book.eAdapters().remove(semanticAdapter);
> }
> this.book = attr;
> if (book != null) {
> if (IPropertiesEditionComponent.LIVE_MODE.equals(editing_mode)) {
> if (semanticAdapter == null) {
> semanticAdapter = initializeSemanticAdapter();
> }
> this.book.eAdapters().add(semanticAdapter);
> }
> }
> }
> This let's me use it to set domain object independently. Perhaps there
> is a better way to do this, but the issue is that I want to be able to
> reuse the component if possible.
>
> In LibraryPropertiesEditionComponent -- these are the most important!
>
> Added the following fields and methods:
> // Start of user code for attributeDetail properties
>
> private Book book;
>
> private BookPropertiesEditionComponent bookProps;
> /**
> * @param book the book to set
> */
> public void setbook(Book book) {
> this.book = book;
> }
>
> /**
> * @param bookProps the bookProps to set
> */
> public void setbookProps(BookPropertiesEditionComponent bookProps) {
> this.bookProps = bookProps;
> }
>
> public EditingDomain getLiveDomain() {
> return liveEditingDomain;
> }
>
> // End of user code
>
> (The generator is not protecting my user code here for some reason, so I
> need to figure that out..) The point of this is that I need to keep a
> reference to the detail component and the detail domain object in the
> parent component. Or at least I think I do, perhaps there is a more
> clever way to do this.
> In protected void runUpdateRunnable(final Notification msg) {
> // Start of user code for attributeDetail live update
> if (msg.getNotifier() == book) {
> bookProps.runUpdateRunnable(msg);
> basePart.updateAttributes(library);
> }
> // End of user code
>
> In public CompoundCommand getPropertiesEditionCommand(EditingDomain
> editingDomain) {
>
> // Start of user code for attributeDetail update command
> if (book != null) {
> CompoundCommand attrEditionCommand =
> bookProps.getPropertiesEditionCommand(editingDomain);
> cc.append(attrEditionCommand);
> }
>
> // End of user code
>
> In public EObject getPropertiesEditionObject(EObject source) {
>
> // Start of user code for attributeDetail part update
> if (book != null) {
> bookProps.getPropertiesEditionObject(book);
> }
> // End of user code
>
> In public void firePropertiesChanged(IPropertiesEditionEvent event) {
>
> // Start of user code for attributeDetail live command update
> if (book != null &&
> event.getAffectedEditor().startsWith("metaabm::Book")) {
> bookProps.firePropertiesChanged(event);
> }
>
> // End of user code
>
>
>
>
>
>
> That's it! :) But I have probably missed something here.. hope it helps
> some other folks who might need to do this.
>
It's great ! Can you put this process on the Eclipse Wiki ?
> BTW, something that could be a translation issue, or may just be my not
> understanding all of the design yet, but does "Edition" in this context
> mean "a particular version / instantiation of something" or "something
> that is used for editing"? If the latter then the word doesn't quite
> mean that. It might be more clear as "Editing" or simply "Edit", so for
> example we would have "Property Editing Component" and
> "LibraryPropertiesEditPartForm".
You're right, It's a translation issue but I'm not sure of the way to
fix it ! :) If we change the EEF metamodels we have to create a
migration tool for older version, the problem is the same for changes in
API (the User Code problem !). And if we just change labelProvider we
don't solve the problem. We just hide it ! ;)
--
Goulwen Le Fur - goulwen.lefur@obeo.fr
|
|
|
Re: [EEF] Recipe for incorporating related views [message #517018 is a reply to message #516807] |
Thu, 25 February 2010 18:38 |
Miles Parker Messages: 1341 Registered: July 2009 |
Senior Member |
|
|
Goulwen Le Fur wrote on Thu, 25 February 2010 04:01 |
>
> That's it! But I have probably missed something here.. hope it helps
> some other folks who might need to do this.
>
It's great ! Can you put this process on the Eclipse Wiki ?
|
Yes, I will try to do it soon. There are still some bits I'm working out to have generation not overwrite any of the changes. I have one bug request in and prob. one more to come re: that. Also, I know I messed something things up. Do you think the idea of setting the attribute for the component and form manually is ok, or would it be better to fire the property change for some reason?
Quote: |
> BTW, something that could be a translation issue, or may just be my not
> understanding all of the design yet, but does "Edition" in this context
> mean "a particular version / instantiation of something" or "something
> that is used for editing"? If the latter then the word doesn't quite
> mean that. It might be more clear as "Editing" or simply "Edit", so for
> example we would have "Property Editing Component" and
> "LibraryPropertiesEditPartForm".
You're right, It's a translation issue but I'm not sure of the way to
fix it ! If we change the EEF metamodels we have to create a
migration tool for older version, the problem is the same for changes in
API (the User Code problem !). And if we just change labelProvider we
don't solve the problem. We just hide it !
|
Yes, that is why I hesitated to bring it up! You could simply change the plugin.properties entries and leave the underlying meta-model the same. Perhaps there is a simple way to add an xsd mapping for legacy. But I don't see anyway around the issue of requiring people to reweave their code generation. Perhaps in version 0.9.0 or 2.0.
|
|
| |
Re: [EEF] Recipe for incorporating related views [message #622239 is a reply to message #516807] |
Thu, 25 February 2010 18:38 |
Miles Parker Messages: 1341 Registered: July 2009 |
Senior Member |
|
|
Goulwen Le Fur wrote on Thu, 25 February 2010 04:01
> >
> > That's it! :) But I have probably missed something here.. hope it helps
> > some other folks who might need to do this.
> >
>
> It's great ! Can you put this process on the Eclipse Wiki ?
Yes, I will try to do it soon. There are still some bits I'm working out to have generation not overwrite any of the changes. I have one bug request in and prob. one more to come re: that. Also, I know I messed something things up. Do you think the idea of setting the attribute for the component and form manually is ok, or would it be better to fire the property change for some reason?
Quote:
> > BTW, something that could be a translation issue, or may just be my not
> > understanding all of the design yet, but does "Edition" in this context
> > mean "a particular version / instantiation of something" or "something
> > that is used for editing"? If the latter then the word doesn't quite
> > mean that. It might be more clear as "Editing" or simply "Edit", so for
> > example we would have "Property Editing Component" and
> > "LibraryPropertiesEditPartForm".
>
> You're right, It's a translation issue but I'm not sure of the way to
> fix it ! :) If we change the EEF metamodels we have to create a
> migration tool for older version, the problem is the same for changes in
> API (the User Code problem !). And if we just change labelProvider we
> don't solve the problem. We just hide it ! ;)
Yes, that is why I hesitated to bring it up! You could simply change the plugin.properties entries and leave the underlying meta-model the same. Perhaps there is a simple way to add an xsd mapping for legacy. But I don't see anyway around the issue of requiring people to reweave their code generation. Perhaps in version 0.9.0 or 2.0. :)
|
|
| |
Goto Forum:
Current Time: Thu Apr 25 05:46:47 GMT 2024
Powered by FUDForum. Page generated in 0.03830 seconds
|