=General Presentation=
The Papyrus Table uses the NatTable widget. Its documentation is available [http://eclipse.org/nattable/documentation.php?page=getting_started http://eclipse.org/nattable/documentation.php?page=getting_started] and [http://eclipse.org/nattable/documentation.php?page=basics http://eclipse.org/nattable/documentation.php?page=basics]. This kind of table is available since the Papyrus Release 0.10 in June 2013.
The NatTable source code can be downloaded with git ([http://git.eclipse.org/gitroot/nattable/org.eclipse.nebula.widgets.nattable.git http://git.eclipse.org/gitroot/nattable/org.eclipse.nebula.widgets.nattable.git]).
Before continuing reading this document, we advise you to read the Table User documentation.
Papyrus provides tables to edit features of UML Elements. In general, UML Elements are displayed in rows and their features are displayed in columns.
These tables can be flat or hierarchical, and they can be filled by the user or synchronized with the context of the table.
The Papyrus integration should allow creating a Matrix, but Papyrus does not provide Matrix editors yet.
The Papyrus team created the nattable.ecore metamodel to describe the Tabular editor and to store it. This metamodel (also known as "the table metamodel") is provided by the plugin org.eclipse.papyrus.infra.nattable.model and declares all the elements used to manipulate the table concept. The next simplified diagram shows '''some''' key elements and relationships:
[[File:images/PartOfPapyrusNattableMM.png|frame|none]]
# NamedStyle
#* Named object to store information. Implementations of this element allow you to store boolean, int, list, string, etc. It works is the same way than in the GMF notation metamodel used by the Papyrus Diagram.
#StyledElement
#* Abstract element that allows to reference style NamedStyle. Each element provided by the table metamodel must inherit from this one, so developers can add easily information to element, without modifying the table metamodel.
#TableConfiguration
#* Element that contains all the information required to create a table. The user can't modify it.
#Table
#* Element that is created from a TableConfiguration. Users can modify it using the tabular editor. It always references a TableConfiguration.
# IAxis
#* Abstract object used to reference elements represented by columns and rows.
=Table Editor API=
In order to make easily the creation, destruction and search for table editors, Papyrus provides helpers to to that (since Papyrus 1.2/Eclispe Neon).
==Table Creation==
The class '''org.eclipse.papyrus.infra.nattable.common.api.TableEditorCreationHelper''' allows you to create a table editor easily, according to some required parameters:
*mandatory parameters:
**'''tableContext (EObject)''': the context used to create the new table,
**'''tableType (String)''': the type of table (also called implementationID in the viewpoint framework),
**'''tableName (String)''': the name for the created table,
**'''openCreatedEditor (boolean)''': if true
, the created editor will be opened,
*additional parameters:
**'''tableOwner (EObject)''': the owner of the table, if not defined, we will use the tableContext,
**'''tableDescription (String''': the description of the created table.
Methods provided by this class :
*public IStatus canCreateTable()
**check all fields given by the class constructors or the setter methods,
**from these fields, we determine others required properties to be able to create the table,
**return a IStatus
. the code of the IStatus
indicates if the table can be created or not and why. Possible code are defined in the class '''org.eclipse.papyrus.infra.nattable.common.api.ITableEditorStatusCode'''.
*public Table createTableEditor()
:
**call canCreateTable()
before to try to create the table,
**create the table if possible and return it or null
if a problem appears,
*public Command getCreateTableEditorCommand()
**call canCreateTable()
before to try to build the table creation command,
**create the command and return it or null
if a problem appears,
*all setter method for contructor parameters. These values are checked by each call to the previous method calling canCreateTable()
.
==Table destruction==
The class '''org.eclipse.papyrus.infra.nattable.common.api.TableEditorDeleteHelper.TableEditorDeleteHelper(Table)''' allows you to create a table editor easily.
*mandatory parameters:
**'''tableToDestroy (Table)''': the table to destroy.
Methods provides by this class:
*public IStatus canDeleteTableEditor()
**check all fields given by the class constructors or the setter methods,
**from these fields, we determine others required properties to be able to destroy the table,
**return a IStatus
. the code of the IStatus
indicates if the table can be destroyed or not and why. Possible code are defined in the class '''org.eclipse.papyrus.infra.nattable.common.api.ITableEditorStatusCode''',
*public void deleteTableEditor()
**call canDeleteTableEditor()
before to try to create the table,
**destroy the table if possible,
*public Command getDeleteTableEditorCommand()
**call canDeleteTableEditor()
before to try to build the table deletion command,
**create the command and return it or null
if a problem appears,
*all setter method for contructor parameters. These values are checked by each call to the previous method calling canDeleteTableEditor()
.
==Find existing tables==
The class '''org.eclipse.papyrus.infra.nattable.common.api.TableEditorFinderHelper''' allows you to find existing table easily. Intanciation of this class requires an EObject of the edited model. Several methods are provides to find a table using one or several of these values:
*the context of the table
*the owner of the table
*the type of the table
*the name of the table
==JUnits for this API==
The facilities described previously are tested by the plugin '''org.eclipse.papyrus.infra.nattable.common.tests'''.
=How to create your own table configuration to edit features of UML Elements=
==Introduction==
This section describes how to create types of tables. We assume that developers have already a good knowledge of the EMF framework. During this tutorial the developer could use any of the two main editors:
* The nattableconfiguration Model Editor (provided by Papyrus)
* The Sample Reflective Model Editor, provided by EMF.
We advice to use the Sample Reflective Model Editor because it allows you the load the UML Resource http://www.eclipse.org/uml2/5.0.0/UML
which is required to create a new table configuration.
However, there are two known problems with EMF editors that developers should keep in mind:
* Often, we don't have enough information in the Property View to edit reference, because the label doesn’t us give enough information to distinguish element. In the following tutorial you will need to create several instances of the same object. The only way to be sure of referencing the right one is to open the file with the text editor.
* The path of referenced element coming from external resource is ugly, for example, the EMF Editor will serialize (look at the href ):
BlockTableTester
implementing org.eclipse.papyrus.infra.nattable.tester.ITableTester
. If you have an 'unresolvable reference' error, add 'org.eclipse.papyrus.infra.nattable' to the list of required JARs and class folders in the Java build path or your plugin.
BlockTableTester
==Define Row Header Axis Configuration==
===Create Row Header Axis Configuration===
This object allows to:
* define the row header appearance
* store the configuration to use to manage rows
Click with the right mouse button on the Table Configuration item and create a New Child of type Table Header Axis Configuration. Once added, define its properties:
[[File:images/RowTableHeaderAxisConfiguration.png|frame|none]]
* '''Display Filter''' : value ignored for rows.
* '''Display Index''' : the Row Index Header will be hidden if false
.
* '''Display Label''' : the Row Label Header will be hidden if false
.
* '''Index Style''' : ALPHABETIC
or NUMERIC
. We often use Numeric for Rows (and Alphabetic for Columns).
===Define Label Provider Configuration for Row Label===
This object provides the configuration used to display Row Label in the Row Header Label Area. As the rows represent edited object, we will use an '''Object Label Provider Configuration'''.
Click with the right mouse button on your new created Table Header Axis Configuration item and create a New Child of type '''Object Label Provider Configuration'''. Once added, define its properties:
[[File:images/ObjectLabelProviderConfiguration.png|frame|none]]
* '''Display Icon''' : it true, an icon will be displayed at the left of the label in the Row Label Header area
* '''Display Label''' : if true, the label of the row will be displayed in the Row Label Header area
===Add specific configurations===
This is in this part than we will configure the paste and the synchronization of our tables.
====Define the Paste Configuration====
Create a new '''Paste EObject Configuration''' as children of your '''Table Header Axis Configuration'''. Once created define its properties
[[File:images/PasteBlockConfiguration.png|frame|none|PasteBlockConfiguration.png ]]
*'''Detached Mode''' : if true
:
** the paste will be done ignoring the Papyrus Edit Service
** less safe
** quicker
* '''Pasted Element Id''' : the Papyrus id used to described the pasted element, here to paste SysML Block:
** org.eclipse.papyrus.sysml.Block
if detached mode=false (if true, in fact, we will paste org.eclipse.papyrus.uml.Class)
** org.eclipse.papyrus.uml.Class
if detached mode = true (in fact org.eclipse.papyrus.sysml.Block will be interpreted as org.eclipse.papyrus.uml.Class)
These strings representing the element to paste do not come from the Eclipse UML2 Project. They are provided by Papyrus and used by the Papyrus Service Type. If you create your static profile, you can generate them and use them here. The generation of these elements is described in an other documentation page (TODO (not yet done)).
=====**********How to generate element id for a given profile**********=====
* Open your profile model
* In the ModelExplorer View, Right click on the Profile
* Select '''Generating Tool Model''', then '''Element Type...''', a dialog will be opened, press OK. A new file called '''model.elementtypesconfigurations''' has been created in your project.
[[File:images/ElementTypeGeneration.png|frame|none]]
* You should register this file in your plugin.xml file, using the extension point '''org.eclipse.papyrus.infra.elementtypesconfigurations.elementTypeSetConfiguration'''.
*Now you can use the generated id in the '''Pasted Element Id''' field of your paste configuration
=====*******************************************************************=====
* '''Paste Element Containment Feature''' : define the feature of the context of the table which will own the created element. Set it to http://www.eclipse.org/uml2/4.0.0/UML#//Namespace/ownedMember
*'''Post Actions''' : actions to do after the paste, like applied required stereotypes
** if detached mode=false
, there is nothing to do
** if detached mode=true
, a post action is required to apply the stereotype Block on the created elements. Set the value to applyStereotype:/SysML::Blocks::Block
to apply it.
====='''Paste Configuration for UMLDnDBlockTable and UMLSynchronizedBlockTable'''=====
There is nothing to add to the previous description. You should do it in the 2 nattableconfiguration file of these tables
====='''Paste Configuration for UMLSynchronizedBlockTreeTable '''=====
The previous description will works fine in a Tree Table but with 2 restrictions :
* It define the paste only for root element of the tree table
* It will be used only if your table is filled by DnD by the User.
So you need to complete the '''Table Header Axis Configuration''' in your file '''UMLSynchronizedBlockTreeTable.nattableconfiguration'''. You must create a new '''Paste Eobject Configuration''' for each category listen by the table. The configuration previously created to paste Block could be reused (but you can also duplicate it in your file), so you need to create 2 others '''Paste Eobject Configuration'''.
Set these values to paste UML Operation:
* '''Detached Mode''' : true
* '''Pasted Element Id''' : org.eclipse.papyrus.uml.Operation
* '''Paste Element Containment Feature''' : http://www.eclipse.org/uml2/5.0.0/UML#//BehavioralFeature/ownedParameter
*'''Post Actions''' : nothing to do
Set these values to paste UML Parameter:
* '''Detached Mode''' : true
* '''Pasted Element Id''' : org.eclipse.papyrus.uml.Parameter
* '''Paste Element Containment Feature''' : http://www.eclipse.org/uml2/5.0.0/UML#//Class/ownedOperation
*'''Post Actions''' : nothing to do
====Synchronization====
In this section, we will describe how to configure the synchronization of your table with the context of the table
====='''UMLDnDBlockTable'''=====
There is nothing to do, it is not a synchronized table.
====='''UMLSynchronizedBlockTable'''=====
We need to provide a FillingConfiguration to know which feature to listen to fill the table.
You must create an '''EStructural Feature Value Filling Configuration''' as child of the '''Table Header Axis Configuration'''
[[File:images/EStructuralFeatureValueFillingConfiguration.PNG|frame|none]]
* '''Listen Feature''': Set the value to http://www.eclipse.org/uml2/5.0.0/UML#//Namespace/ownedMember
====='''UMLSynchronizedBlockTreeTable'''=====
The Tree table listen several features (at least one be depth). Here, we call these features ''categories''.
* '''Step1''': Firstly, you need to declare an additional label configuration to know how to display the categories in the table. Often, we create a '''Feature Label Configuration'''.
If required, you could create an '''Object Label Configuration''' instead, but you get less possibilities of configuration (only '''Display Label''', restricited to the name of the object, and '''Display Icon''') instead of the 6 degrees described below.
Create a '''Feature Label provider Configuration''' as child of '''Table Header Axis Configuration''', then edit these properties:
[[File:images/FeaturelabelconfigurationForCategories.PNG|frame|none]]
** '''Display Icon''' : if true
, an icon will be displayed at the left of the label for the category
** '''Display Is Derived''' : if true
a / will be displayed in the label if the represented feature is derived
** '''Display Label''' : if true
, the label will be displayed, with this format:''[isDerived][name]:[type][multiplicity]''
** '''Display Multiplicity''', if true
, the multiplicity will be displayed for the category in the label
** '''Display Name''' : if true
, the name of the category will be displayed in the label
** '''Display Type''' : if true
, the type of the category will be displayed in the label
This '''Feature Label Configuration''' will be referenced by all '''Tree Filling Configuration''' created in the next steps.
* '''Step2''': Now you need to create 3 '''Tree Filling Configuration''', one by categories. So you need to create one with depth=0, one with depth=1 and one with depth=2.
[[File:images/TreeFillingConfiguration.PNG|frame|none]]
**'''Depth'''
***the depth on which the configuration is applied
***starts to 0, if there is no configuration declared with depth=0, the root of the tree table will be filled by DnD by the user
**'''Label provider''' : references a '''Label Provider Configuration''' declared as children of '''Row Header Axis Configuration'''. This label provider will be used to display the categories. Here, you must reference the '''Feature Label Provider Configuration''' that you came to define in the previous step.
**'''Label provider context''' : org.eclipse.papyrus.infra.nattable.header.treefilling.feature.labelprovider
** '''Paste Configuration''' : references the paste configuration to use to paste element in this category
* '''Step3''': Now you need to define the category (the feature) which is listen by each of these '''Tree Filling Configurations'''.
You must create an IAxis as child of each configuration. For this example, the '''IAxis''' must be an '''EStructural Feature Axis'''.
[[File:images/TreeFillingConfigurationIAxis.PNG|frame|none]]
** '''Alias''' : a string which will be displayed instead of the name of the referenced feature in the label of the categories
** '''Element''' : the feature to listen
** '''Manager''' : keep null for this usage
You should create one '''EStructural Feature Axis'' as child of each '''Tree Filling Configuration''' Once the Axis has been created, set these properties:
** For depth=0
*** the feature to listen is http://www.eclipse.org/uml2/5.0.0/UML#//Namespace/ownedMember
. This feature provides NamedElement
, but we will filter its contains in the java class which will manages the rows
*** set the alias to Blocks
** For depth=1
*** the feature to listen is http://www.eclipse.org/uml2/5.0.0/UML#//Class/ownedOperation
** For depth=2
*** the feature to listen is http://www.eclipse.org/uml2/5.0.0/UML#//BehavioralFeature/ownedParameter
===Define the Row Manager===
Now you need to create an '''Axis Manager Representation''' for Rows. You can declare one or several axis manager representation. This element allows to declare the java class to used to manage rows in the table. Moreover, it references the configuration to use for the rows and declare the context of the label provider.
Created an '''Axis Manager Representation''' item as child of your '''Table Header Axis Configuration'''. Once added, define its properties:
[[File:images/RowAxisManagerRepresentation.PNG|frame|none]]
* '''Axis Manager Id''':''' define the id of the java class which will manage your rows
* '''Header Label Configuration''' : the label configuration to use in the Row header Label area.
* '''Label Provider context''' : the id of the label provider context to use
* '''Specific Axis Configuration''' : Here, you should references all the '''Tree Filling Configuration''' previously created. '''Paste EObject Configuration''' are required too in only one usecase: if your Tree Table is filled by the user (DnD) (so you do not have '''Tree Filling Configuration''' on depth==0), you should reference the '''Paste EObject Configuration''' to use to create root elements. In others cases, it is not mandatory, because the '''Paste EObject Configuration''' are already referenced by the the '''Tree Filling Configuration'''.
====UMLDnDBlockTable====
# '''Axis Manager Id''': org.eclipse.papyrus.sysml.nattable.BlockAxisManager
# '''Header Label Configuration''': Your must reference your '''Object Label Configuration'''
# '''Label Provider context''': org.eclipse.papyrus.infra.nattable.header.labelprovider
# '''Specific Axis Configuration''': you must reference your '''Paste EObject Configuration'''
Now, you need to create a java class called for example BlockAxisManager
. This axis manager must implement org.eclipse.papyrus.infra.nattable.manager.axis.IAxisManager
, but we advice you to extends org.eclipse.papyrus.uml.nattable.manager.axis.UMLElementAxisManager
.
org.eclipse.papyrus.infra.nattable.axismanager
.
[[File:images/RegisterAxisManager.PNG|frame|none]]
* '''id''' : org.eclipse.papyrus.sysml.nattable.BlockAxisManager
. It must be the same id than in the '''Axis Manager Representation'''
* '''manager''' : The qualified Name of your created class
====UMLSynchronizedBlockTable====
# '''Axis Manager Id''': org.eclipse.papyrus.sysml.nattable.BlockSynchronizedAxisManager
# '''Header Label Configuration''': Your must reference your '''Object Label Configuration'''
# '''Label Provider context''': org.eclipse.papyrus.infra.nattable.header.labelprovider
# '''Specific Axis Configuration''': You must reference your '''EStructural Feature value Configuration''' and your '''Paste EObject Configuration'''.
Now, you need to create a java class, but before, you should add the following dependencies to your plugin (addapt bundle-version to your Papyrus version):
org.eclipse.emf.transaction;bundle-version="1.9.0",
org.eclipse.nebula.widgets.nattable.core;bundle-version="1.3.0",
org.eclipse.papyrus.infra.emf.nattable;bundle-version="1.1.3",
org.eclipse.papyrus.infra.nattable;bundle-version="1.1.3",
org.eclipse.papyrus.infra.nattable.model;bundle-version="1.1.3",
org.eclipse.papyrus.infra.widgets;bundle-version="1.1.3",
org.eclipse.papyrus.uml.nattable;bundle-version="1.1.3",
ca.odell.glazedlists;bundle-version="1.9.0"
Now, you can create a java class, called for example BlockSynchronizedAxisManager
. This axis manager must implement org.eclipse.papyrus.infra.nattable.manager.axis.IAxisManager
, but we advice you to extends org.eclipse.papyrus.uml.nattable.manager.axis.AbstractStereotypedElementUMLSynchronizedOnFeatureAxisManager
.
org.eclipse.papyrus.infra.nattable.axismanager
. See the description done for UMLDnDBlockTable
* '''id''' : org.eclipse.papyrus.sysml.nattable.BlockSynchronizedAxisManager
. It must be the same id than in the '''Axis Manager Representation'''
* '''manager''' : The qualified Name of your created class
====UMLSynchronizedBlockTreeTable====
# '''Axis Manager Id''': org.eclipse.papyrus.sysml.nattable.BlockTreeAxisManager
# '''Header Label Configuration''': Your must reference your '''Object Label Configuration'''
# '''Label Provider context''': org.eclipse.papyrus.infra.nattable.header.labelprovider
# '''Specific Axis Configuration''' : you must reference your '''Paste EObject Configuration''' allowing to paste Block and all your '''Tree Filling Configuration'''.
Now, you need to create a java class called for example BlockSynchronizedTreeAxisManager. This axis manager must implement org.eclipse.papyrus.infra.nattable.manager.axis.ITreeItemAxisManagerForEventList
but we advice you to extend org.eclipse.papyrus.uml.nattable.manager.axis.UMLElementTreeAxisManagerForEventList
org.eclipse.papyrus.infra.nattable.axismanager
. See the description done for UMLDnDBlockTable
* '''id''' : org.eclipse.papyrus.sysml.nattable.BlockTreeAxisManager
. It must be the same id than in the '''Axis Manager Representation'''.
* '''manager''' : The qualified Name of your created class
==Define Column Header Axis Configuration ==
===Create Column Header Axis Configuration===
This step is the same to build the 3 tables : UMLDnDBlockTable, UMLSynchronizedBlockTable and UMLSynchronizedBlockTreeTable.
This object allows to:
* define the row header appearance
* store the configuration to use to manage rows
Click with the right mouse button on the '''Table Configuration''' item and create a New Child of type '''Column Header Axis Configuration Table Header Axis Configuration'''. Once added, define its properties:
[[File:images/ColumnTableHeaderAxisConfiguration.png|frame|none]]
* '''Display Filter''' : if true
a row filter will be displayed at the bottom of the Column Header Area.
* '''Display Index''' : the Column Index Header will be hidden if false
.
* '''Display Label''' : the Column Label Header will be hidden if false
.
* '''Index Style''' : ALPHABETIC
or NUMERIC
. We often use Alphabetic for Columns (and Numeric for Rows)
===Define Label Provider Configuration for Column Label===
This step is the same to build the 3 tables : UMLDnDBlockTable, UMLSynchronizedBlockTable and UMLSynchronizedBlockTreeTable.
This object provides the configuration used to display Column Label in the Column Header Label Area. As the rows represent edited object, we will use a '''Feature Label Provider Configuration'''.
Click with the right mouse button on your new created '''Table Header Axis Configuration''' item and create a New Child of type '''Feature Label Provider Configuration'''. Once added, define its properties:
[[File:images/FeatureLabelProviderConfigurationForColumn.png|frame|none]]
* '''Display Icon''' : if true
, an icon will be displayed at the left of the label for the category
* '''Display Is Derived''' : if true
a / will be displayed in the label if the represented feature is derived
* '''Display Label''' : if true
, the label will be displayed
* '''Display Multiplicity''', if true
, the multiplicity will be displayed for the category in the label
* '''Display Name''' : if true
, the name of the category will be displayed in the label
* '''Display Type''' : if true
, the type of the category will be display in the label
===Define the Column Manager===
This step is the same to build the 3 tables : UMLDnDBlockTable, UMLSynchronizedBlockTable and UMLSynchronizedBlockTreeTable.
This element allows to declare the java class to used to manage rows in the table. Moreover, it references the configuration to use for the columns and declare the context of the label provider.
Here, you need to create two '''Axis Manager Representation''' to manage columns. The first one will be used to managed UML features and the second one will be used to manage properties of stereotypes applied on the row elements.
Click with the right mouse button on your '''Table Header Axis Configuration''' item and create a New Child of type '''Axis Manager Representation'''. Once added, define its properties:
[[File:images/AxisManagerRepresentation01.PNG|frame|none]]
* '''Axis Manager Id''': org.eclipse.papyrus.uml.nattable.feature.axis.manager
. It is an axis manager already declared in Papyrus.
* '''Header Label Configuration''': Your must reference your '''Feature Label Configuration'''
** Warning in UMLSynchronizedBlockTreeTable, there are now two '''Feature Label Configuration''', Select the right one.
* '''Label Provider context''': org.eclipse.papyrus.infra.nattable.header.labelprovider
* '''Specific Axis Configuration''': there is nothing to reference for columns
And again, create a second New Child of type Axis Manager Representation. Once added, define its properties:
[[File:images/AxisManagerRepresentation02.PNG|frame|none]]
* '''Axis Manager Id''': org.eclipse.papyrus.uml.nattable.stereotype.property.axis.manager
. It is an axis manager already declared in Papyrus.
* '''Header Label Configuration''': Your must reference your '''Feature Label Configuration'''
** Warning in UMLSynchronizedBlockTreeTable, there are now two '''Feature Label Configuration''', Select the right one.
* '''Label Provider context''': org.eclipse.papyrus.infra.nattable.header.labelprovider
* '''Specific Axis Configuration''': there is nothing to reference for columns
==Define Row Provider==
This step is the same to build the 3 tables : UMLDnDBlockTable, UMLSynchronizedBlockTable and UMLSynchronizedBlockTreeTable.
The row provider is the object used to store the axis (here the rows) visible in the table. In case of synchronized table. It always be empty. It exists 2 kinds of provider : Master and Slave.
For rows, we must take a Master. Click with the right mouse button on the '''Table Configuration''' item and create a New Child of type '''Row Axis Providers Master Object Axis Provider'''. Once added, define its properties:
[[File:images/MasterObjectAxisProvider.png|frame|none]]
* Description : field used in user dialog. Allows to describe the behavior of the axis manager
* Disconnect Slave : we advice to set it to true
.
** false
for each added row, the system will add columns axis for each features of the rows not yet represented by a column axis.
** true
the behavior described previously will be stopped
==Define Column Provider==
This step is the same to build the 3 tables : UMLDnDBlockTable, UMLSynchronizedBlockTable and UMLSynchronizedBlockTreeTable.
The column provider is the object used to store the column axis visible in the table. Here, we will take a Slave Axis Provider.
Click with the right mouse button on the '''Table Configuration''' item and create a New Child of type '''Column Axis Providers Slave Object Axis Provider'''. Once added, define its properties:
[[File:images/SlaveObjectAxisProvider.png|frame|none]]
===Define the default columns for your table===
Now you should declare here the default columns for your table.
====Define the Name Column====
Click with the right mouse button on your new created '''Slave Object Axis Provider''' item and create a New Child of type '''EStructural Feature Axis''' to define. Once added, define its properties:
[[File:images/EStructuralFeatureAxis.png|frame|none]]
* '''Alias''': this field allow to give an alias to the represented feature
* '''Element''' : set the value to http://www.eclipse.org/uml2/5.0.0/UML#//NamedElement/name
* '''Manager:''' set the reference to the column axis manager created previously. Warning, you have now 3 Axis Manager Representation in the model. You should reference the Axis Manager which have this id : org.eclipse.papyrus.uml.nattable.feature.axis.manager
====Define the IsEncapsulated Column====
IsEncapsulated is a property of stereotype, so you can not reference directly it. The table framework allows you to reference it using its qualified name.
Click with the right mouse button on your new created '''Slave Object Axis Provider''' item and create a New Child of type '''Feature Id Axis'''. Once added, define its properties:
[[File:images/FeatureIdAxis.png|frame|none]]
* '''Alias''' : this field allows to define an alias for the represented feature.
* '''Element:''' : the referenced element
** Set it to property_of_stereotype:/SysML::Blocks::Block::isEncapsulated
* '''Manager:''' set the reference to the column axis manager created previously. Warning, you have now 3 Axis Manager Representation in the model. You should reference the Axis Manager which have this id : org.eclipse.papyrus.uml.nattable.stereotype.property.axis.manager
==Configure Table Configuration==
This is the last step concerning the edition of the nattableconfiguration. Select the root of the model, that is to say the object '''Table Configuration''', to set its properties:
[[File:images/EditingTableConfiguration.png|frame|none]]
* '''Cell Editor Declaration''' : can be :
** COLUMN : all cells of the columns will use the same kind of editors (used here, because we have the feature in column, so the system needs to declare a Cell Editor by column.
** ROW : all cells of the rows will use the same kind of editors
** CELL : each cell uses a specific editor (provided, but not used)
* '''Default Column Axis Provider''':
** it is the default, because you could declare several axis provider for columns!
** Here, you must reference the Column Axis Provider to use by default, ie just after the table creation
* '''Default Row Axis Provider'''
** it is the default, because you could declare several axis provider for rows!
** Here, you must reference the Row Axis Provider to use by default, ie just after the table creation
* '''Description''' : a small description of your table. This text will be displayed in user dialog
* '''Icon path''' : an icon (16x16) used to represent this kind of table. This icon will be used in the Table Creation Menu, in the Model Explorer View, in the ShortCut displayed on the Diagram, ...
* '''Name''' : the initial name proposed to the user when it will create a table from your table configuration
* '''Type''' : the type of your table. It must be unique in Papyrus. It is used by the Papyrus Framework to identify each kind of editor for (save, open, create, ... actions)
===UMLDnDBlockTable===
* '''Cell Editor Declaration''' : COLUMN
* '''Default Column Axis Provider''': you must reference your Slave Object Axis Provider
* '''Default Row Axis Provider''' : you must reference your Master Object Axis Provider
* '''Description''' : This table allows to edit Block added by the user by DnD
* '''Icon path''' : an icon (16x16) used to represent this kind of table.
* '''Name''' : UMLDnDBlockTable
* '''Type''' : PapyrusExampleUMLDnDBlockTable
===UMLSynchronizedBlockTable===
* '''Cell Editor Declaration''' : COLUMN
* '''Default Column Axis Provider''': you must reference your Slave Object Axis Provider
* '''Default Row Axis Provider''' : you must reference your Master Object Axis Provider
* '''Description''' : This table allows to show and edit all Block owned by a Package. It is a synchronized Table
* '''Icon path''' : an icon (16x16) used to represent this kind of table.
* '''Name''' : UMLSynchronizedBlockTable
* '''Type''' : PapyrusExampleUMLSynchronizedBlockTable
===UMLSynchronizedBlockTreeTable===
* '''Cell Editor Declaration''' : COLUMN
* '''Default Column Axis Provider''': you must reference your Slave Object Axis Provider
* '''Default Row Axis Provider''' : you must reference your Master Object Axis Provider
* '''Description''' : This table allows to show and edit all Block owned by a Package. It is a tree synchronized Table. It allows to show the Block, with their Operations and them Parameters.
* '''Icon path''' : an icon (16x16) used to represent this kind of table.
* '''Name''' : UMLSynchronizedBlockTreeTable
* '''Type''' : PapyrusExampleUMLSynchronizedBlockTable
====How to hide categories in the TableConfiguration File====
* Create a new '''IntListValueStyle''' as child of the '''TableConfiguration'''
* Set it the name '''hiddenCategoriesByDepth'''
* Set it the depths of the categories to hide
==Register your new table configuration into Papyrus framework==
===Register your nattable configuration file===
Each Table Configuration File created previously must contribute to the Papyrus Extension Point org.eclipse.papyrus.infra.nattable.configuration
.
This extension point allows to contribute to the Table Configuration Catalogue provided by the Papyrus Framework.
[[File:images/ContributeToNattableConfigurationExtensionPoint.PNG|frame|none]]
* '''file''': the path for the file configuration
* '''type''': the type of the table, it must be the same string than the type field in the nattableconfiguration file.
====UMLDnDBlockTable====
* '''file''': the path for the file configuration
* '''type''': PapyrusExampleUMLDnDBlockTable
====UMLSynchronizedBlockTable====
* '''file''': the path for the file configuration
* '''type''': PapyrusExampleUMLSynchronizedBlockTable
====UMLSynchronizedBlockTreeTable====
* '''file''': the path for the file configuration
* '''type''': PapyrusExampleUMLSynchronizedBlockTreeTable
===Contribute to Viewpoint Framework===
Please, see Viewpoint documentation embedded in Eclipse.
This part is the same for the 3 kind of tables previously created. Here we choose to explain the viewpoint configuration for the UMLDnDBlockTable table. You should adapt this documentation to your usecase.
For this step, first of all, you have to create a new Viewpoints configuration in your plugin. Create the file UMLDnDBlockTableViewpoint.configuration
.
====Contribute to the Default Papyrus Viewpoint====
Using this way, you will able to contribute to the default Papyrus Viewpoint.
* Right Click in the Viewpoint editor, and select action '''Load Resource...''', paste this value platform:/plugin/org.eclipse.papyrus.infra.viewpoints.policy/builtin/default.configuration
[[File:images/ViewPointContribution_loadViewPointResource.png|frame|none]]
* Select the Papyrus Configuration and in the Property View, edit the field '''Default Stakeholder'''. Set it the value '''Default Modeler'''
[[File:images/ViewPointContribution_setDefaultStakeholder.png|frame|none]]
* Right Click in the Viewpoint editor, and select action '''Load Resource...''', paste this value platform:/plugin/org.eclipse.uml2.uml/model/UML.ecore
[[File:images/ViewPointContribution_loadUMLResource.png|frame|none]]
* Select the Papyrus Configuration and in the Property View, edit the field '''Metamodel'''. Set it the value '''http://www.eclipse.org/uml2/5.0.0/UML'''
[[File:images/ViewPointContribution_setMetamodel.png|frame|none]]
* Create a new child, Papyrus ViewPoint, set it its name : Default Papyrus Viewpoint
. You should not use an other name, because this name is used as id to contribute to an existing viewpoint (the Papyrus Default Viewpoint). We don't edit others fields.
[[File:images/ViewPointContribution_setName.png|frame|none]]
* Create a new child to Papyrus Viewpoint. You can create a '''Papyrus Sync Table''' or a '''Papyrus Table'''. The only difference is in the declaration of the contribution
**Creating a Papyrus Sync Table, you must fill:
***'''Categories''': the category of your contribution (UML, SysML, Profile, ...) It allows you to define in which context your contribution must be proposed in the creation menu.
***'''Implementation ID''': must have the same value than the field type defined in your table configuration file
***'''Icon''': the icon to display in the menu, it is a URL starting with '''platform:/plugin/PLUGIN_ID+PATH+ICON_NAME.EXT'''
***'''Name''': the name displayed in the menu, it could be the same than default name defined in the table configuration file
[[File:images/ViewPointConfiguration_setTableViewPointValues.png|frame|none]]
**Creation a Papyrus Table, you must fill:
***'''Categories''': the category of your contribution (UML, SysML, Profile, ...) It allows you to define in which context your contribution must be proposed in the creation menu. Here, we set SysML
.
***'''Configuration''':the path to your nattable configuration file, it is a URL starting with '''platform:/plugin/PLUGIN_ID+PATH+FILE_NAME.nattableconfiguration'''
***'''Icon''': the icon to display in the menu, it is a URL starting with '''platform:/plugin/PLUGIN_ID+PATH+ICON_NAME.EXT'''
***'''Implementation ID''': not mandatory in this case, must have the same value than the field type defined in your table configuration file. Here we set PapyrusUMLDnDBlockTableViewpoint
***'''Name''': the default name of your table, it should be the same than default name defined in the table configuration file. here we set UMLDnDBlockTable
***'''Profiles''': to indicate if your table requires some profile. Here we reference http://www.eclipse.org/papyrus/0.7.0/SysML/Blocks
[[File:images/ViewPointContribution_setViewPointValues.PNG|frame|none]]
*Now you can add '''Model Rule''' and '''Owning Rule''' as children of your Viewpoint. These properties define the allowed context of the table and its possible owner. The first one is the context used to create new items in the table, and the second to set the items below which we can view the table in the ModelExplorer. The multiplicities indicates how many table of this kind can references the root and the owner.
**As SysML Block can be created inside a Package or inside a Block, we will create 2 '''Model Rule''' and set these values:
***for the first '''Model Rule''', you must set the field '''Element''' to Package
from UML Package
[[File:images/viewPointContribution_firstModelRule.png|frame|none]]
***for the second '''Model Rule''', you must set the field '''Element''' to Class and the field '''Stereotypes''' to Blocks#Block
[[File:images/viewPointContribution_secondModelRule.png|frame|none]]
**We decide than only package can be displayed as parent of the table in the ModelExplorer.
***Create a new '''Owner Rule''' and set the field '''Element''' to Package
from UML Package
[[File:images/viewPointContribution_ownerRule.png|frame|none]]
Once you have finish to edit the configuration, you must register it using the extension point '''org.eclipse.papyrus.infra.viewpoints.policy.custom'''.
* In your plugin.xml file, contribute to the extension point '''org.eclipse.papyrus.infra.viewpoints.policy.custom'''. There are 2 possible children for this extension point. Take the '''contribution'''and edit the fields as described below:
**'''original''': platform:/plugin/org.eclipse.papyrus.infra.viewpoints.policy/builtin/default.configuration
**'''file''': references your file
[[File:images/UMLDnDBlockTableViewpoint_contribution_plugin_contribution.png|frame|none]]
====Contribute to a new Viewpoint for UML====
Using this way, you will be able to create your own Viewpoint. This is basically the same things, excepted for these points:
#you must create your own stakeholder
#you must contribute to the extension point using '''configuration''' instead of '''contribution'''
* Right Click, and select action Load Resource, paste this value platform:/plugin/org.eclipse.uml2.uml/model/UML.ecore
to load UML metamodel
* Create a new '''Stakeholder''' as child of the Papyrus Configuration and give it a name. Here, we call it New SysML Block StakeHolder
[[File:images/ViewPointConfiguration_newStakeholder.png|frame|none]]
* Select the viewpoint and in the Property View, edit the field :
**'''Default Stakeholder''', reference your stakeholder created in the previous step
**'''Metamodel''', set it the value '''http://www.eclipse.org/uml2/5.0.0/UML'''
[[File:images/ViewPointConfiguration_setViewPointValues.png|frame|none]]
* Create a Papyrus View Point as child of the Papyrus Configuration, and give it a name. Here we call it SysML Block ViewPoint
[[File:images/ViewPointConfiguration_createNewViewPoint.png|frame|none]]
* Select your stakeholder and edit its field '''Viewpoints''' to reference the viewpoint created in the previous step.
[[File:images/ViewPointConfiguration_referenceNewViewPoints.png|frame|none]]
* From here, you can continue the edition of the configuration, as described previously for the contribution to the Default Papyrus Viewpoint Configuration.
Once you have finish to edit the configuration, you must register it using the extension point '''org.eclipse.papyrus.infra.viewpoints.policy.custom'''.
* In your plugin.xml file, contribute to the extension point '''org.eclipse.papyrus.infra.viewpoints.policy.custom'''. There are 2 possible children for this extension point. Take the configuration and edit the fields as described below:
**'''file''': references your file
**'''priority''': set it a priority
[[File:images/UMLDnDBlockTableViewpoint_configuration_plugin_contribution.png|frame|none]]
Once your new plugin deployed, in your >Eclipse Runtime, you must go into The Eclipse Preferences -> Papyrus -> Viewpoints Configuration
* Select '''Deployed through the extension point'''
* Select your stakeholder
* Select your viewpoint
==Result==
===Creating a new Block Table===
[[File:images/CreateBlockTable03.png|frame|none]]
You can create the Block Table directly under a package:
[[File:images/ExampleBlockTable.png|frame|none]]
===Synchronization between table and model===
The illustration of the table sychronization when a block is added or removed:
[[File:images/SynchroTable01.png|frame|none]] After added Block2
[[File:images/SynchroTable02.png|frame|none]] Affter removed Block1
=Contribute to creation menu with a new Papyrus Table (must be completed)=
The contribution must be done using viewpoint with a file .configuration.
The viewpoint metamodel provides 2 ways to register new tables. the first one used the Element Papyrus Sync Table. You must fill the field :
* Categories
* Icon
* ImplementationID : the type of the table, with the same value than in the field type declared in the file .nattableConfiguration of your table
* Name : the name of the table
Then you can declare Rules to allow/forbid the creation of the table according to the selected element
The second way with viewpoint using Papyrus Table element
In this case you must fill the field configuration with the path of your table configuration file.
== Label Providers ==
For the label provider, we divided the tables into 2 areas :
#Headers
#Body
for each areas we declared a label provider context (using the Papyrus Label Provider extension point):
#org.eclipse.papyrus.infra.nattable.full.labelprovider : the context to use to find the label provider used in the table. This one calls the others label providers according to the region for which we are looking for the text/image to display.
#org.eclipse.papyrus.infra.nattable.body.labelprovider : the context to use to find the label provider used to get the text in the body of the table
#org.eclipse.papyrus.infra.nattable.header.labelprovider : the context to use to find the label provider used to get the text in the header of the table (display icon, display label)
#org.eclipse.papyrus.infra.nattable.header.feature.labelprovider : the context to use to find the label provider used to display feature in a header. This label provider allows to define the text to display according to the configuration of the axis ( display icon, display label, display multiciplicity, display type, display a "/" for the derived feature)
These contexts are declared into the plugin org.eclipse.papyrus.infra.nattable.
All label provider declared on these context must accept elements implementing ILabelProviderCellContextElement. This object encapsulate the cell for which we want display a text AND useful elements which can be used to define the text/image/color/... to display in the cell.
Papyrus Extension Point For Table :
#Axis Manager
#Cell Manager
#Cell Editor Configuration
== Selection synchronization ==
Some changes have been applied to the code in order to allow a selection synchronization between the tables and the model explorer. The affected classes are the following :
In these changes, IRevealSemanticElement and its associated method revealSemanticElement is at the core of the modifications.
* '''Step1''': org/eclipse/papyrus/infra/nattable/common/editor/AbstractEMFNattableEditor.java
**where we implement the interface and add the call for the newly created revealSemanticElement method in AbstractNattableWidgetManager and giving it the list of selected objects.
* '''Step2''': org/eclipse/papyrus/infra/nattable/manager/table/AbstractNattableWidgetManager.java
**the method goes through the lines and columns of the tables to find all the elements contained in the list and then proceed to select them graphically in the table.
**the method used for this is org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.doCommand(ILayerCommand command)
* '''Step3''': org/eclipse/papyrus/infra/gmfdiag/common/SynchronizableGmfDiagramEditor.java
**in the original method the selection only allowed the first selected element found to show. we now collect all found IGraphicalEditParts and proceed to set the selection in the graphicalViewer.
* '''Step4''': org/eclipse/papyrus/views/modelexplorer/ModelExplorerView.java
**in the handleSelectionChangedFromDiagramEditor method the principal problem was that, if revealSemanticElement was called, it shunned the model explorer as it was not an IEditPart and the redundacy of the IAdaptable verification crashed the process.
**when we are in an IIeditorPart, as we were interested in the Eobject for the contruction of the list of selected elements and that org.eclipse.papyrus.infra.emf.utils.EMFHelper.getEObject(Object source) already checked for the IAdaptability, the direct replacement of the verification was done.
**as for the selection in the model explorer, we went through org.eclipse.ui.navigator.LinkHelperService.getLinkHelpersFor(Object anObject) to get the list of LinkHelpers and used the LinkHelper in org.eclipse.papyrus.views.modelexplorer.LinkHelper.activateEditor(IWorkbenchPage aPage, IStructuredSelection aSelection) to handle the selection with revealSemantiElement.
== Modifying the graphical representation of the tables ==
=== Resizing Axis and Headers ===
Three listeners have been added to the AbstractNattableWidgetManager class in order to capture the graphical changes and edit the model.
#addAxisResizeListener(final BodyLayerStack bodyLayerStack) that listens to the BodyLayerStack
#addColumnHeaderResizeListener(final ColumnHeaderLayerStack columnHeaderLayerStack) that listens to the ColumnHeaderLayerStack
#addRowHeaderResizeListener(final RowHeaderLayerStack rowHeaderLayerStack) that listens to the RowHeaderLayerStack
Those methods verify the model in order to know if the graphical values are already present and if not create them and write them using a CompositeCommand and executing it.
The major change introduced in order to accomplish this is the modification of the table's model by adding new Styles, more particularly intValueStyles that are used to carry this specific information. These styles are introduced in the Axis elements, if the changes of size modify axis, or to a newly, or existing, LocalHeaderAxisConfiguration if the changes modify headers. Of course, both of them are now StyledElements and therefore can call on the method getNamedStyle().
*NamedStyle org.eclipse.papyrus.infra.nattable.model.nattable.nattablestyle.StyledElement.getNamedStyle(EClass eClass, String name)
Two init methods will also be called when refreshing or opening the table in order to show the modified table.
#initTableAxis() that gets the list of the displayed axis and check their styles
#initTableHeaders() that gets the AbstractHeaderAxisConfigurationUsedInTable, allowing the method to get around the invertAxis configuration, and check their styles
Both have a default behavior, in case no styles were attached to an element, to apply its default size to its graphical representation.
=== Merging cells inside their Axis ===
The merge is based on nebula's AutomaticSpanningDataProvider (org.eclipse.nebula.widgets.nattable.data.AutomaticSpanningDataProvider) allowing us to apply a spanProvider to the table's BodyLayerStack and, with minor modification of the method valuesNotEqual(), triggering the desired span (i.e. merge) throughout the layer. It is to be noted that the cells are merged using their values and not their types.
To accomplish this four new merge handlers were created, piloted by a menu constituted of exclusive choices.
#org.eclipse.papyrus.infra.nattable.handler.MergeColumnsHandler
#org.eclipse.papyrus.infra.nattable.handler.MergeRowsHandler
#org.eclipse.papyrus.infra.nattable.handler.MergeSelectedRowsHandler
#org.eclipse.papyrus.infra.nattable.handler.MergeSelectedColumnsHandler
The handlers' model modification behavior are similar to the resize listeners' one, where the style's value is researched in the model and created, or modified, depending on the case, set inside a CompositeCommand and executed inside the core AbstractMergeHandler. The merge boolean will then be carried by the LocalHeaderAxisConfiguration if the user chose to merge all the columns/rows inside the table or by the Axis if the user chose to merge only selected Axis.
To access these handlers, new extensions have been added in the form of a new menu to call on the handlers and a property tester to check the availability of the menu's options or not depending on the merge state of the table; and to update the toggles of each menu, new updateToggleCommandState() have also been added to NattableModelManager, calling on the getToggleState[...]() methods in AbstractNattableManager.
One init method and two Listeners, one for the resourceSet and another for the Layer, are used to update the graphical view throughout the changes.
#initTableMerge() in wich the list of the displayed axis is obtained and their styles checked
#resourceSetListener inside the updateCellMap() method in which the notifications due to the modification of the resourceSet are filtered to keep the styles we want to apply or unapply, depending on the user's choices, and enable the use of the undo/redo behavior
=== Editing merged cells ===
A PapyrusSpanningDataLayer has been added and @Overrides the setDataValue of nebula's org.eclipse.nebula.widgets.nattable.layer.SpanningDataLayer#setDataValue(int, int, java.lang.Object) to allow the edition of multiple cells inside a merged selection.
The edition will then verify if the value to be inputted can indeed be, see org.eclipse.papyrus.infra.nattable.manager.cell.AbstractCellManager.setValue(), and edit the cell accordingly. Of course, the merge selection is updated after this so that, inside a previuosly merged selection, only the cells of equal values are still merged.
= What is the difference between Slave and Master for AxisManager/AxisProvider=
We decided to introduce a difference between the Axis Manager used in the Table. There is Slave and Master.
==Master/Slave configuration==
For the tables which present an axis with Object (Rows) and an Axis with Features (Columns), like in UML Generic Table, the row axis provider is a Master and the Column axis provider is the slave.
Its means that the the column axis manager provides elements which depends on the elements provided by the rows axis. For UML Table, the columns axis provides the features for the object displayed as rows in the table.
As you can declare several AxisManagers for rows and several AxisManager for columns, we store them in CompositeAxisManager. So you must have a CompositeAxisManager Master for rows and a CompositeAxisManager slave for columns.
You can mix Master and Slave Axis Manager in a CompositeAxisManager.
==Master/Master configuration==
In case of Matrix, the Rows and the Columns Axis Manager must be master, because the twice provide Object.
=What is the difference between AxisManagerRepresentation and AxisManagerConfiguration?=
==AxisManagerRepresentation==
The axis manager representation provide the default configuration for an axis manager in the TableConfiguration.
This object contains the following field:
*'''axisManagerId:String''' the if of the configured axis manager,
*'''labelProviderContext:String''' the id of the context to use to find the label provider to use,
*'''headerLabelConfiguration:ILabelProviderConfiguration''' the label configuration to use (read by the label provider, to know how the header must be displayed). We read it, only if there is no AxisManagerConfiguration
referencing the AxisManagerRepresentation
and providing a localHeaderLabelConfiguration
,
*'''specificAxisConfiguration:IAxisConfiguration''' the configuration to apply to the axis (synchronization, paste configuration, ...).
==AxisManagerConfiguration==
*'''localHeaderLabelConfiguration:ILabelProviderConfiguration''' the label configuration to use (read by the label provider, to know how the header must be displayed). if null
, we read the field headerLabelConfiguration
from the referenced AxisManagerRepresentation
,
*'''axisManager:AxisManagerRepresentation''' the axis manager on which this configuration must be applied,
*'''localSpecificConfigurations''' the configurations to apply. it complete OR overrides AxisManagerRepresentation#specificAxisConfiguration
,
**override for configurations already existing in the AxisManagerRepresentation#specificAxisConfiguration,
**complete for configurations which do not exist in the AxisManagerRepresentation#specificAxisConfiguration.
=Filters=
The filters are located at the bottom of the Column Header.
In Papyrus, you can get cells displaying N/A
, it means than the columns is not available for the row element owning this cell. That's why declaring your own filter, you must think to manage this specific value.
Moreover, if you declare a specific comparator in your filter configuration, it should returns the value org.eclipse.papyrus.infra.nattable.filter.FilterPreferences.INCONSISTENT_VALUE
when the value in the cell is inconsistent vs the filter value. This specific returns will be used, according to the preference obtained with org.eclipse.papyrus.infra.nattable.filter.FilterPreferences.displayInconsistentValueWithFilter(Table)
to show/hide the rows with inconsistent values.
==How to activate filters==
To activate filter by default for your table, in your nattableconfiguration file, you must select your Table Header Axis Configuration
used for columns and set the value '''Display Filter''' to true
.
[[File:images/ActivateFilterInTableConfiguration.png|frame|none]]
==How to declare your own filter==
In your plugin.xml file, you must contribute to the Papyrus Extension Point '''org.eclipse.papyrus.infra.nattable.filter.configuration'''. You must fill the 2 fields of the extension:
*'''class''' : your java class implementing org.eclipse.papyrus.infra.nattable.filter.configuration.IFilterConfiguration
*'''order''' : the order to use for your configuration (smaller are more priority). Papyrus default configuration uses value near to 8000.
The interface IFilterConfiguration
provides 4 methods:
*public boolean handles(IConfigRegistry registry, final Object axis)
: Your must return true
if your configuration must be applied to the axis.
*public void configureFilter(IConfigRegistry configRegistry, final Object axis, final String configLabel)
here, you will configure nattable to use your filter configuration.
*public String getConfigurationId()
: You must return a unique id.
*public String getConfigurationDescription()
: You should return a description of your configuration. It will be use in user dialog to allow to the user to apply a specific configuration for a column.
In the method configureFilter
you can configure several elements, using these keys:
*'''org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes.CELL_EDITOR'''
**to declare the cell editor to use in the the filter cell for the column
*'''org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes.DISPLAY_CONVERTER'''
**to declare the display converter to use (conversion between real element in the cell and the label to use for this element)
*'''org.eclipse.papyrus.infra.nattable.utils.NattableConfigAttributes.MATCHER_EDITOR_FACTORY'''
**to declare the matcher factory which will create the matcher to use to compare the filter value and the cell value
*'''org.eclipse.papyrus.infra.nattable.filter.configuration.IFilterConfiguration.FILTER_VALUE_TO_MATCH_MANAGER'''
**to declare the class which will save the filter state in the model and which will read/convert the saved value to the value to use.
===Example to filter EEnumLiteral===
This example will allow you to filter EEnumLiteral (http://www.eclipse.org/uml2/5.0.0/UML#//NamedElement/visibility
for example)
org.eclipse.nebula.widgets.nattable.filterrow.combobox.FilterRowComboBoxCellEditor
), used in org.eclipse.papyrus.infra.emf.nattable.filter.configuration.EBooleanComboBoxCellEditorFilterConfiguration
[[File:images/ComboWithCheckBox.png|frame|none]]
* a combo without checkbox (class org.eclipse.nebula.widgets.nattable.edit.editor.ComboBoxCellEditor
), used in org.eclipse.papyrus.infra.emf.nattable.filter.configuration.EBooleanFilterRowComboBoxCellEditorFilterConfiguration
[[File:images/ComboWithoutCheckBox.png|frame|none]]
* a string editor with several mode used in org.eclipse.papyrus.infra.nattable.filter.PapyrusTextMatchingMode
:
** contains: (case by default)
** regex found: a substring of the text match the regex
** regex match: the full text match the regex
** start with: the text start with the wanted string
** numeric mode: This mode allows you to use comparison operators : <
, >
, <=
, >=
, =
and <>
for not equals.
So, to configure filter using a text cell editor, you should extends the class org.eclipse.papyrus.infra.nattable.filter.configuration.TextEditorFilterConfiguration
.
To configure integer comparison, with a text editor, you should look the class org.eclipse.papyrus.infra.nattable.filter.configuration.AbstractIntegerEditorFilterConfiguration
. In this class and its subclasses, in the method org.eclipse.papyrus.infra.nattable.filter.configuration.TextEditorFilterConfiguration.configureFilter(IConfigRegistry, Object, String)
:
* we declare a specific data validator: the user can only typed numerical values
* we declare a specific Comparator to compare numerical values
* we declare the matching mode to org.eclipse.papyrus.infra.nattable.filter.PapyrusTextMatchingMode.NUM
: to get numeric comparison and use the comparator declared previously
==Comparator used by filter==
If you need to declare your own comparator and you extend org.eclipse.papyrus.infra.nattable.filter.configuration.TextEditorFilterConfiguration.configureFilter(IConfigRegistry, Object, String)
, you should know these points.
* Your comparator must always manage String comparison to manage cells with N/A
value.
* In the case where the value to compare is inconsistent (String value to match a numerical value for example), Your comparator must returns the value org.eclipse.papyrus.infra.nattable.filter.FilterPreferences.INCONSISTENT_VALUE
. this value will be interpreted as an impossible comparison.
* The method org.eclipse.papyrus.infra.nattable.filter.FilterPreferences.displayInconsistentValueWithFilter(Table)
allow to know it the inconsistent row (impossible comparison) must be displayed or hidden. By default, Papyrus hides these rows.
===Filter Strategy===
* By default, the row with a cell contains is inconsistent with the column are hidden. There is 2 main cases in Papyrus:
** the cell display N/A for a value which is not a string
** the user uses num:
(see below) in the string editor, all values which are not numerical values will be hidden
* In case of filtering on several column in the same time, we will display only the rows matching all applied filters
* In case of collection in a cell, the row matches if the collection contains the wanted element
=Cell Editor=
Papyrus table provides several kinds of cell editors, for example, editors for ValueSpecification and UML NamedElement:
*textual editor
** textual editor for ValueSpecification
***This editor allows to edit/create ValueSpecification using a text field.
***The class of this cell editor is org.eclipse.papyrus.uml.nattable.xtext.valuespecification.celleditor.ValueSpecificationCellEditor.ValueSpecificationCellEditor
***The plugin org.eclipse.papyrus.uml.textual.editors.example
provide an example of integration in the table. Taking this plugin into your workspace will allow you to edit the column defaultValue using this editor.
***a video is available here https://www.youtube.com/watch?v=OERg0BUZmyU&feature=youtu.be
***for further information, please see the page [[Papyrus_Developer_Guide/Papyrus_Embedded_Editors_Documentation/Value_Specification_Xtext_editor]]
** textual editor for NamedElement (to edit references which are not containment)
*** This editor allows to edit references to named element.
*** The plugin org.eclipse.papyrus.uml.textual.editors.example
provides an example of integration in the table. Taking this plugin into your workspace will allow you to edit the precondition of an operation using a text field.
*** The class of this cell editor is org.eclipse.papyrus.uml.nattable.manager.cell.editor.UMLReferenceTextWithCompletionCellEditor
.
*** for further information, please see the page [[Papyrus Developer Guide/Papyrus Embedded Editors Documentation/Textual Editor For NamedElement]]
==How to declare a new Cell Editor==
In your plugin.xml file, you must contribute to the extension point '''org.eclipse.papyrus.infra.nattable.celleditor.configuration''', providing a '''cellAxisConfiguration'''.
Note: '''configuration''' is deprecated and must not be used.
This extension point has two fields :
*'''class''': the java class providing your cell editor configuration and implementing org.eclipse.papyrus.infra.nattable.celleditor.config.ICellAxisConfiguration
*'''order''': an integer value, more the order is small, more the contribution is prioritary (several cell editors can be declared to edit the same kind of value
Now you should create the java class, 4 methods must be implemented :
*'''String getConfigurationId()''': a unique id for this cell editor configuration
*'''String getConfigurationDescriptio()''': a description of the cell editor (will be used in dialog not yet implemented)
*'''boolean handles(Table table, Object axisElement)''': In this method you will be able to restrict your contribution to a specific table kind and a specific axisElement (a row or a column)
*'''void configureCellEditor(IConfigRegistry configRegistry, Object axisElement, String configLabel)''': here you register the cell editor to use for the axisElement and some others interesting things, like a value validator, a value convertor, a cell painter, ...
you should add these dependencies in your Manifest (adapt bundle-version to your Papyrus version):
org.eclipse.papyrus.infra.nattable;bundle-version="1.2.0",
org.eclipse.papyrus.infra.nattable.model;bundle-version="1.2.0",
org.eclipse.nebula.widgets.nattable.core;bundle-version="1.3.0"
The only way to restrict your cell editor to a kind of table is your implementation of the method '''ICellAxisConfiguration#handles(Table table, Object axisElement)'''.
There is not yet a way to force the usage of given cell editor in a nattable configuration file.
Example of code used in Papyrus:
true
if axisElement is a {@link EEnum} {@link EStructuralFeature}
*/
@Override
public boolean handles(Table table, Object axisElement) {
Object representedElement = AxisUtils.getRepresentedElement(axisElement);
if (representedElement instanceof EStructuralFeature) {
EStructuralFeature feature = (EStructuralFeature) representedElement;
if (!feature.isMany()) {
EClassifier eType = feature.getEType();
return eType instanceof EEnum;
}
}
return false;
}
/**
* @see org.eclipse.papyrus.infra.emf.nattable.celleditor.configuration.ICellAxisEditorConfiguration#configureCellEditor(org.eclipse.nebula.widgets.nattable.config.IConfigRegistry, java.lang.Object, java.lang.String)
*
* @param configRegistry
* @param axis
* @param configLabel
*/
@Override
public void configureCellEditor(final IConfigRegistry configRegistry, Object axis, String configLabel) {
Object representedElement = AxisUtils.getRepresentedElement(axis);
EEnum eenum = (EEnum) ((EStructuralFeature) representedElement).getEType();
IDisplayConverter displayConverter = new DisplayConverter() {
@Override
public Object displayToCanonicalValue(Object displayValue) {
return null;
}
@Override
public Object canonicalToDisplayValue(Object canonicalValue) {
// for others case
// LabelProviderService service = configRegistry.getConfigAttribute(NattableConfigAttributes.LABEL_PROVIDER_SERVICE_CONFIG_ATTRIBUTE, DisplayMode.NORMAL, NattableConfigAttributes.LABEL_PROVIDER_SERVICE_ID);
// return service.getLabelProvider(canonicalValue).getText(canonicalValue);
//
return new EMFLabelProvider().getText(canonicalValue);
}
};
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, new ComboBoxPainter(), DisplayMode.EDIT, configLabel);
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new ComboBoxCellEditor(new EEnumComboBoxDataProvider(eenum)), DisplayMode.EDIT, configLabel);
configRegistry.registerConfigAttribute(CellConfigAttributes.DISPLAY_CONVERTER, displayConverter, DisplayMode.EDIT, configLabel);
}
}
org.eclipse.papyrus.infra.nattable.provider.TableSelectionProvider
which manages the selection layer.
The table selection provider manage the selection as following specified:
{| class="wikitable" border="1"
! style="text-align: center;" | Selection in table
! style="text-align: center;" | Selection managed by provider
|-
! style="font-weight: bold;" | None
| Table context (The selection must the the table context to manage the properties view)
|-
! style="font-weight: bold;" | Rows
| The rows elements, features or operations
|-
! style="font-weight: bold;" | Columns
| The columns elements, features or operations
|-
! style="font-weight: bold;" | Cells
| The cells values
|}
This table selection provider manage the control and the shift mask and is managed by CellSelectionEvent
, RowSelectionEvent
or ColumnSelectionEvent
.
==TableStructuredSelection==
The getSelection()
managed in the NattableModelManager
returns a TableStructuredSelection
.
This one contains a reference to the wrapper for the table selection: TableSelectionWrapper
. To get this one: it is just needed to use the getAdapter(TableSelectionWrapper.class)
.
==TableSelectionWrapper==
The TableSelectionWrapper can allow to determinate the selected cells, the selected rows and the selected columns.
The rows and the columns selected only contains the entire rows or columns selected, not partial.
This can determinate if the cells, rows or columns are continous or not.
==Example of use==
This is an example how to use the table selection (enable an action when only rows are selected:
org.eclipse.papyrus.infra.nattable.manager.axis.IAxisManager
. Each Axis has a way to reference the managed object.
===Create an Axis Manager for EObject===
====Flat and not synchronized Axis Manager====
*We advice you to extend org.eclipse.papyrus.infra.emf.nattable.manager.axis.EObjectAxisManager
.
*The Eobject axis element is wrapped in a EObjectAxis.
====Flat and Synchronized on a EStructural Feature Axis Manager====
*We advice you to extends org.eclipse.papyrus.infra.emf.nattable.manager.axis.AbstractSynchronizedOnEStructuralFeatureAxisManager
.
*The EObject axis element is directly managed by the axis manager and not wrapped in a EObjectAxis.
===Create an Axis Manager for EStructuralFeature===
====Flat and not synchronized Axis Manager====
*for real EStructuralFeature:
**We advice you to extend org.eclipse.papyrus.infra.emf.nattable.manager.axis.EStructuralFeatureAxisManager
.
**The EStructuralFeature axis element are wrapped in a EStructuralFeatureAxis
*for properties of stereotypes:
**We advice you to extend org.eclipse.papyrus.uml.nattable.manager.axis.UMLStereotypePropertyAxisManager
.
**The stereotype properties are referenced in a FeatureIdAxis, using a string, starting by the string : properties_of_stereotype:/
and suffixed with the qualified name of the property of stereotype.
===Create Axis Manager for others kinds of objects/feature===
*We advice you to extends AbstractAxisManager.
*The best way to reference your object which is not a EObject, is to use an IdAxis to reference it using a string.
* You can choose ObjectIdAxis, FeatureObjectAxis or OperationIdAxis for flat AxisManager
* You can choose ObjectIdTreeItemAxis, FeatureIdObjectTreeItemAxis or OperationIdTreeItemAxis for tree AxisManager
* The choice between object, operation and feature must be done looking the possible informations to display in the axis header for your table:
** Object properties:
*** display icon: true or false
*** display label: true or false
**Feature properties
*** display icon: true or false
*** display label: true or false
*** display isDerived: true or false
*** display type: true or false
*** display multiplicity: true or false
*** display name: true or false
**Operation properties
*** display icon: true or false
*** display label: true or false
*** display type: true or false
*** display multiplicity: true or false
*** display name: true or false
==Create a new Axis Manager==
Now, you should know which class to extend and which kind of IAxis used to store axis provided by the axis manager (if the storage is required)
#Create a new plugin project with the required dependencies
#Create a new java class extenting the good class, we will complete it later
#Contribute to the papyrus extension point org.eclipse.papyrus.infra.nattable.axismanager
##'''id''': a unique id for the axis axis manager
##''class''': the java class
#Open a file *.nattableconfiguration
##Modify existing table configuration in order to be able to get new axis in existing table. In general case, you will contribute to the column Axis Manager, where the index are displayed as Alphbetic. In the good one Table Header Axis Configuration (Numeric for rows and Alphabetic for Column)
##Create a new Label Provider Configuration (Feature or Operation or Object)
##Create a new Axis Manager Representation
###'''Axis Manager Id''': the same value than in the plugin.xml
###'''Header Label Configuration''': you must reference the Label Provider Configuration created previously.
###'''Label Provider Context''': one of these three possibilities, according to your Header Label Configuration kind
####org.eclipse.papyrus.infra.nattable.header.feature.labelprovider
####org.eclipse.papyrus.infra.nattable.header.operation.labelprovider
####org.eclipse.papyrus.infra.nattable.header.object.labelprovider
###'''Specific Axis Configurations''': nothing for this usecase
##Add new default axis provided by our new Axis Manager
###If you want that new table created by our user provides by default some columns managed by our Axis Manager, you must create new IAxis in one of the 2 Object Axis Provider. In the general case, there is a slave for columns and a master for rows, and the default axis are defined for columns. So probably in the Slave Object Axis Provider, you can create new IAxis, probably an IdAxis or a IdTreeItemAxis, for Object, Feature or Operation, then you must fill these fields:
####'''Alias''': not mandatory, a name for the axis
####'''Element''': the object referenced by the axis, probably a string if you use an IdAxis
####'''Manager''': you must reference the Axis Manager Representation created previously
==Create a new Cell Manager==
It will allow you to get the contents of the cell and to save it after editing value.
#Create a new java class implementing org.eclipse.papyrus.infra.nattable.manager.cell.IUnsetValueCellManager
or extending org.eclipse.papyrus.infra.nattable.manager.cell.AbstractCellManager
or one of these subclasses and complete it.
#Register this class in the plugin.xml file, using the extension point org.eclipse.papyrus.infra.nattable.cellmanager
.
##'''id''': a unique id for your cell manager,
##'''manager''': tha java class,
##'''order''': an integer
==Create a new CellEditor Configuration==
It will allow you to edit the cell value.
#Create a new class implementing org.eclipse.papyrus.infra.nattable.celleditor.config.ICellAxisConfiguration
or one of these subclasses and complete it.
#Register the class in the plugin.xml file, using the extension point org.eclipse.papyrus.infra.nattable.celleditor.configuration
and the object cellAxisConfiguration
. (FYI, configuration
is deprecated since Eclipse Neon/Papyrus 1.2.0)
##'''class''': the java class for the cell editor configuration
##'''order''': an integer
==Create a new Label Provider Configuration==
It will allow you to display the contents of the cells returned by the CellManager. This steps is not mandatory, because it depends on the object displayed in our cells. Maybe your case is always managed by Papyrus, maybe not.
#Create a new class extending org.eclipse.papyrus.infra.nattable.provider.AbstractNattableCellLabelProvider
or one of these subclasses and complete it.
##Warning, in the context of Papyrus table, you never receive directly the object displayed on the cell, but you will receive a wrapper implementing org.eclipse.papyrus.infra.nattable.utils.ILabelProviderContextElementWrapper
#Register your class in the plugin.xml file, using the extension point org.eclipse.papyrus.infra.services.labelprovider.labelProvider
##'''priority''': an integer
##'''provider''': the java class
==Create a new Filter Configuration==
This step is not mandatory, by default, the string filter will be used.
#Create a new class, implementing org.eclipse.papyrus.infra.nattable.filter.configuration.IFilterConfiguration
or extending org.eclipse.papyrus.infra.nattable.filter.configuration.AbstractFilterConfiguration
or one of these subclasses.
#Register your class in the plugin.xml file, using the extension point org.eclipse.papyrus.infra.nattable.filter.configuration
##'''class''': the java class
##'''order''': an integer
=How to create your own post action for paste=
//TODO
=How to declare several axis configuration in the same table=
//TODO
=How to declare new actions in the Papyrus Table Context Menu=
==General Tricks about the menus in Eclipse ==
You can call the Eclipse Menu Service to fill your own MenuManager with contributions declared with the eclipse extension point ''org.eclipse.ui.menus''.
Here it is a code example for the Papyrus Table. (The final implementation doesn't use the IMenuService in the table, because it is already done upper in Papyrus Infra Core).
popup:org.eclipse.papyrus.infra.nattable.widget.menu?after=cell.separator
: insert your contribution after the separator called '''cell.separator'''
**popup:org.eclipse.papyrus.infra.nattable.widget.menu?before=cell.separator
: insert your contribution beforethe separator called '''cell.separator'''
The menu displayed for Tree Table:
[[File:images/TablehierarchiBodyMenu.png|frame|none|Body Popup Menu for the Tree Table]]
==Body Menu (Papyrus 1.1/Eclipse Mars)==
* In your plugin.xml file, you should add a new extension ''org.eclipse.ui.menus'', with a new menu contribution. The field '''locationURI''' must be set to '''popup:org.eclipse.ui.popup.any''' and the field '''allPopups''' should be set to true
.
* Doing this, your contributions will be displayed in all Eclipse Menus. To restrict is you must add a '''visibleWhen''' condition for each declared command. Here, we will restrict it using an existing PropertyTester (see this part of the documentation to create your own property tester:[[Table_Developer_Documentation#How_to_declare_a_menu_action_for_a_specific_kind_of_table.2C_using_PropertyTester | Table Developer Documentation/How to declare a menu action for a specific kind of table, using PropertyTester]] )
* In the '''visibleWhen''' condition, you must create a '''with''' child working on the Eclipse variable '''selection'''.
* In '''with''' condition, you must create a child '''test''', working on the property "org.eclipse.papyrus.infra.nattable.tester.isNattableWidget
and comparing the result value to true
. You should force the Plugin activation too.
The result in the xml file will be something like that :
org.eclipse.core.expressions.PropertyTester
**'''id''': the id of your tester. It must be unique and it will be used to declare the condition of activation of your action in the menu.
***'''namespace''': the namespace, you can use the same value than for id
***'''properties''': the list of properties provided by your tester. Properties are strings, separated with comma.
***'''type''': it is the type of the parameter used by your Property Tester. Often we use org.eclipse.jface.viewers.IStructuredSelection
Here, it is the declaration of the property tester used to know is the current Papyrus Editor is a table editor. This property tester provides several properties:
*isNattableWidget,
*hasFeatureRowHeaderConfiguration,
*hasFeatureColumnHeaderConfiguration,
*hasSlaveRowAxisProvider,
*hasSlaveColumnAxisProvider,
*canInvertAxis,
*isHierarchicTable
null
if not found
*/
protected INattableModelManager getNattableModelManager() {
final IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchPart current = null;
if (workbench != null) {
final IWorkbenchWindow activeWorkbench = workbench.getActiveWorkbenchWindow();
if (activeWorkbench != null) {
final IWorkbenchPage activePage = activeWorkbench.getActivePage();
if (activePage != null) {
current = activePage.getActivePart();
}
}
}
if (current != null) {
return (INattableModelManager) current.getAdapter(INattableModelManager.class);
}
return null;
}
}
org.eclipse.papyrus.infra.nattable.provider.NattableTopLabelProvider
**method getImage(Object)
: to be able to display the overlay in addition of the image
*org.eclipse.papyrus.infra.nattable.provider.PapyrusNatTableToolTipProvider
**allows to display validation messages in the tooltip
**allows to display validation icons in the tooltip
All these changes depends on the decoration service and not on the validation service because currently, validation marker are implemented as decorations.
The validation menu is available in the table popup menu, but we do not provide specific handler for validation in table. We use the handlers defined by Papyrus in others plugins.
The validation menu provides these actions (the same than in others views):
*Validate model
*Validate subtree
*Select constraints and Validate model
*Select constraints and Validate subtree
*Remove markers from model
*Remove markers from subtree
These actions works according to the table selection, with this behavior (Row, then Column, then Cell):
*if there is at least one row is fully selected
** we apply the chosen action on the object represented by this row (if the action is enabled)
*if there is no row selected, we take the first fully selected columns
** we apply the chosen action on the object represented by this column(if the action is enabled)
*if there is no row and no column selected, we take the first object from the first selected cell
** we apply the chosen action on the first object represented by this cell(if the action is enabled)
This order is given by the method calculating the selection of the table: org.eclipse.papyrus.infra.nattable.provider.TableSelectionProvider.calculateAndStoreNewSelection(ILayerEvent)
=Matrix=
The Papyrus tabular editor should allow to the developper to create matrix, we doesn't really try to do that. Here, we give some points which should allow you to create matrix :
# the column axis must manage object instead of manage features
# you must declare a cell manager specific to your table to get and edit the values in the cell
# you probably need to declare your own label provider
# others things to do?
# to conclude, don't forget to implements required methods to allow (or forbid) all features already supported by the table framework. The list of the supported feature is available [[Table_Documentation#Table_Features|here]].
=Which is the difference between TableHeader... and LocalHeader...=
//TODO
=Table embedded in the Property View=
The classes managing the NatTable widget in the property view are:
*org.eclipse.papyrus.uml.properties.widgets.NattablePropertyEditor
*org.eclipse.papyrus.uml.properties.widgets.TreeNattablePropertyEditor
These tables have some custom behaviors:
* the tree table is always expand all ath the beginning
*
the table will use percentage sizing for the columns display, excepted if you set a BooleanNamedStyle columnsWidthAsPercentage to false has a child of your TableConfiguration.* the table are not really persisted, but we keep the user configuration for a given table opened on an object of a given EClass. See
org.eclipse.papyrus.uml.properties.widgets.NattablePropertyEditor.createTableURI(EObject, TableConfiguration)
for further information.
* So during your table development, you need to clear your workspace each time to test your table configuration, or you need to remove your table instance from the location yourRuntimeWorkspace/.metadata.plugins/org.eclipse.papyrus.uml.properties/tables.=Enhancements to plan for a next table version= *allow to a user/developper to add a new AxisManager to an existing table. Currently it is not possible, because the java AxisManager are represented in the nattableconfiguration file by an AxisManagerRepresentation. This one provides several configuration to the AxisManager, like LabelProvider to use *remove the paste with detached mode *store all axis for synchronized table too or provide an easy way for the user to define if the contents must be stored or not **all tables must be able to be stored **some user actions could required a full storage of the table **wrap all rows/columns in IAxis *nattableConfiguration should be a table *store all customization information in the table just after its creation. Currently, when a table is created, we continue to look for these information in the tableconfiguration until the user modifies the default configuration *add supports for queries in table, queries could be used for several features in the table: *#specific columns *#specific categories *#could be used in the JavaTester class (allow to know if the table can be created on not for a given context) *#used as configuration for AxisManager to filter the elements *#used as configuration for AxisManager to get the element to display (like cateegories) *#the possible queries would be ocl queries, java queries, others ? We could start this feature integrating Papyrus Facet which already provides OCL and java queries. *hierarchical rows for all tables *hierarchical columns too (need to develop our own layer! *filter on rows to filter column (specific layer too) *invert layer (already exist in NatTable, but static and not dynamic (need a boolean) *feature "Rows Connect/Disconnect Columns Axis" must be reimplemented. Currently, this feature is linked to the composte Axis Manager, we should move it to each sub-axis manager. Moreover, this property must be a part of the Table metamodel. **an other possibility, all axis should be notified when one of the axis (opposite or same side) add/remove/move/... elements and must be able to chain a command if required. **this possibility is not incompatible with the connect/disconnect feature **master and slave should be a removed concept with this kind of solution *property master/slave of the axis must be a property of the metamodel and not a java implementation *property table about cell editor declaration must be improved. If we use "Cell" instead of "Column", we lose the possibility to add columns and declaring cell editor by columns for them. Maybe this property should be managed by the axis manager and not by the table. *cell configruation, axis manager, filter, ... and so on, shoudl be represented as EMF object in separate file, in order to be easily referenced by table. It will be more efficient than using String as id to identify them. Moreover dependency problem will be the same. We will get unresolved proxy instead of contribution to extension point unknown. *table must allow to use as TreeContentProvider the tree of the ModelExplorer, in order to be able to get the same hierarchy provided by Facet (+ custom ???) *table framework should allow to load axis/cell/labelprovider/celleditors... in the user workspace without launch a runtime