Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Sapphire » Apply read.only to cells at runtime
Apply read.only to cells at runtime [message #1232138] Thu, 16 January 2014 04:52 Go to next message
Andreas Weise is currently offline Andreas Weise
Messages: 37
Registered: January 2014
Member
I have a table representation of a list property ListFoo, that contains 2 columns ColA and ColB. The cells should be editable in the table which of course works out of the box with sapphire and is great.

ListFoo contains 2 default entries, which must not be removed. I think this can be achieved using a SapphireActionHandlerFilter in conjunction with ListSelectionService for disabling the Remove Action when one of the entry is selected.

Now ColA of both entries should not be editable.

I'm trying to figure out how to implement that. I know that the read.only hint is available in the sdef, but is that applicable to instance elements at runtime somehow? Or do you know another approach. I could not find anything similar in the Sapphire Samples.

Thanks in advance.
Re: Apply read.only to cells at runtime [message #1232309 is a reply to message #1232138] Thu, 16 January 2014 11:51 Go to previous messageGo to next message
Konstantin Komissarchik is currently offline Konstantin Komissarchik
Messages: 940
Registered: July 2009
Senior Member
There is not a way to do this today. The read.only hint applies to all cells in the column. The @ReadOnly annotation for the model is also static and applies to all instances of the property.

One thing that you could do is use a custom list binding to separate ListFoo into two lists, which you can control independently.
Re: Apply read.only to cells at runtime [message #1239068 is a reply to message #1232309] Mon, 03 February 2014 04:06 Go to previous messageGo to next message
Andreas Weise is currently offline Andreas Weise
Messages: 37
Registered: January 2014
Member
So the custom binding approach would be something like:

- Create 2 lists each containing a dedicated but similar element (because one of the 2 elements has the property ColA annotated with @ReadOnly)
- Create a 3rd list with custom list binding (something like AggregatedListBinding which extends org.eclipse.sapphire.ListPropertyBinding)
- Create a AggregatedResource that is managed within AggregatedListBinding and contains both lists from step 1. Each AggregatedResource references the base element of the corresponding list from step 1, and it does not have a parent resource.
- Bind the UI on the 3rd list.

Checking out the samples, this would be a mix of two samples:
So the AggregatedResource will be similar to org.eclipse.sapphire.samples.calendar.integrated.internal.CalendarResource.
And AggregatedListBinding will be similar to org.eclipse.sapphire.samples.catalog.CategoriesBinding

Which methods are important to overwrite on the AggregatedResource or AggregatedListBinding.
Is it required that the AggregatedListBinding extends org.eclipse.sapphire.LayeredListPropertyBinding or even org.eclipse.sapphire.modeling.xml.StandardXmlListBindingImpl? What's the purpose of LayeredListPropertyBinding.

Thanks again.
Re: Apply read.only to cells at runtime [message #1239217 is a reply to message #1239068] Mon, 03 February 2014 12:08 Go to previous messageGo to next message
Konstantin Komissarchik is currently offline Konstantin Komissarchik
Messages: 940
Registered: July 2009
Senior Member
I was suggesting that you show the two lists separately on the form, but I think there is a better solution. The @ReadOnly annotation is static, but you can have a heterogeneous list with two element types, such that the property is @ReadOnly in one. Something like this...

public interface ListEntry extends Element
{
    ElementType TYPE = new ElementType( ListEntry.class );

    // *** Value ***

    ValueProperty PROP_VALUE = new ValueProperty( TYPE, "Value" );

    Value<String> getValue();
    void setValue( String value );
}

public interface ListEntryReadOnly extends ListEntry
{
    ElementType TYPE = new ElementType( ListEntry.class );

    // *** Value ***

    @ReadOnly

    ValueProperty PROP_VALUE = new ValueProperty( TYPE, ListEntry.PROP_VALUE );
}

// *** List ***
    
@Type( base = ListEntry.class, possible = { ListEntry.class, ListEntryReadOnly.class } )
@CustomXmlListBinding( impl = YourCustomBinding.class )
@XmlElementBinding
( 
    mappings = 
    {
        @XmlElementBinding.Mapping( element = "entry", type = ListEntry.class ),
        @XmlElementBinding.Mapping( element = "entry", type = ListEntryReadOnly.class ),
    }
)

ListProperty PROP_LIST = new ListProperty( TYPE, "List" );

ElementList<ListEntry> getList();


You'd have to implement a custom binding for this list property since the standard binding can only assign different element types based on different XML element names and you'd have a custom heuristic. If you extend StandardXmlListBindingImpl, you should only need to override the type(Resource) method.
Re: Apply read.only to cells at runtime [message #1239291 is a reply to message #1239217] Mon, 03 February 2014 16:34 Go to previous messageGo to next message
Andreas Weise is currently offline Andreas Weise
Messages: 37
Registered: January 2014
Member
Nice and easy approach.

The downside now is, that the Sapphire.Add action now contains a Submenu for both the ListEntryReadOnly and the ListEntry.

As the ReadOnly items can neither be deleted nor added (in my use case), is there a chance to suppress this behavior on the add action button. I've already disabled the Sapphire.Delete action for ListEntryReadOnly items using the ListSelection service and a listener.

final SapphireAction deleteAction = action.getActionSet().getAction("Sapphire.Delete");
final ListSelectionService listService = action.getPart().service(ListSelectionService.class);
final Listener selectionListener = new FilteredListener<ListSelectionChangedEvent>() {
	@Override
	public void handleTypedEvent(final ListSelectionChangedEvent event) {
		if (listService.selection().size() == 1 && ListEntryReadOnly.TYPE == listService.selection().get(0).type()) {
			deleteAction.setEnabled(true);
			return;
		}
		deleteAction.setEnabled(false);
	}
};
listService.attach(selectionListener);


Of course I can filter the Sapphire.Add action using a SapphireActionHandlerFilter, but whats the most suitable way then to build the add-functionality only for the default ListEntry.
Re: Apply read.only to cells at runtime [message #1239306 is a reply to message #1239291] Mon, 03 February 2014 17:34 Go to previous messageGo to next message
Konstantin Komissarchik is currently offline Konstantin Komissarchik
Messages: 940
Registered: July 2009
Senior Member
Removing the undesired add action handler using SapphireActionHandlerFilter is the way to go.
Re: Apply read.only to cells at runtime [message #1239314 is a reply to message #1239306] Mon, 03 February 2014 18:08 Go to previous messageGo to next message
Andreas Weise is currently offline Andreas Weise
Messages: 37
Registered: January 2014
Member
Ok. Unfortunatly a Filter added on the Property Editor of the List with the following code, does not filter it out:

@Override
public boolean check(SapphireActionHandler handler) {
	return !handler.getAction().getId().equals("Sapphire.Add");
}


I also debugged, and it did not even invoke the check method. Adding it programmatically however works.

And another issue came up, but that more seems like a bug. After disabling the delete button (like described in the last reply) entries can still be deleted using the DEL key on the keyboard.

[Updated on: Mon, 03 February 2014 18:24]

Report message to a moderator

Re: Apply read.only to cells at runtime [message #1239362 is a reply to message #1239314] Mon, 03 February 2014 21:32 Go to previous messageGo to next message
Konstantin Komissarchik is currently offline Konstantin Komissarchik
Messages: 940
Registered: July 2009
Senior Member
Quote:
I also debugged, and it did not even invoke the check method.


That sounds like a filter registration issue. How are you registering it?

Quote:
And another issue came up, but that more seems like a bug. After disabling the delete button (like described in the last reply) entries can still be deleted using the DEL key on the keyboard.


Please open a bug report.
Re: Apply read.only to cells at runtime [message #1239437 is a reply to message #1239362] Tue, 04 February 2014 02:50 Go to previous message
Andreas Weise is currently offline Andreas Weise
Messages: 37
Registered: January 2014
Member
Quote:
That sounds like a filter registration issue. How are you registering it?


<action-handler-filter>
	<impl>com.foo.MyAddActionFilter</impl>
</action-handler-filter>


And I can't tell you why: Today it is working. So nevermind.

Bug Report for the Key-Binding Issue is here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=427341
That might be a general issue for all Key Bindings, when disabling the corresponding action.
Previous Topic:Enforce Rendering of Instance based PossibleValuesService like with Context Metamodel
Next Topic:Disable Sapphire.Restore.Defaults on section
Goto Forum:
  


Current Time: Thu Aug 21 04:21:24 EDT 2014

Powered by FUDForum. Page generated in 0.01878 seconds