Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpguilet2017-02-10 16:02:22 +0000
committerpguilet2017-03-24 14:17:53 +0000
commit071c53c1e669f700d799fd5fca9dd7ceac968779 (patch)
tree24f75f3d7c59d156bc3f96688f330722c0a0aaf7
parent47ed885a5666d0b8c1e597eee865dc0cfbe0ce53 (diff)
downloadorg.eclipse.sirius-071c53c1e669f700d799fd5fca9dd7ceac968779.tar.gz
org.eclipse.sirius-071c53c1e669f700d799fd5fca9dd7ceac968779.tar.xz
org.eclipse.sirius-071c53c1e669f700d799fd5fca9dd7ceac968779.zip
[512104] Fix Sirius table editor not working after external aird changes
- Update editors' tree viewer's components with new DRepresentation replacing the used one when manual aird modification is done so they can work after. - Add tests. Bug: 512104 Change-Id: If4a865c659fd0bac98f1223ed680db3268d5c00a Signed-off-by: pguilet <pierre.guilet@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/AbstractDTableEditor.java36
-rw-r--r--plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableMenuListener.java34
-rw-r--r--plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java175
-rw-r--r--plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/listeners/DTableViewerListener.java15
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.aird88
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.ecore7
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.odesign36
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/ManualAirdModificationTest.java250
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java3
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeEditor.java30
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java30
-rw-r--r--plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTableViewerManager.java16
-rw-r--r--plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTreeEditor.java46
13 files changed, 631 insertions, 135 deletions
diff --git a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/AbstractDTableEditor.java b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/AbstractDTableEditor.java
index 7dd977733b..3df862f271 100644
--- a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/AbstractDTableEditor.java
+++ b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/AbstractDTableEditor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2015 THALES GLOBAL SERVICES and others.
+ * Copyright (c) 2008, 2017 THALES GLOBAL SERVICES and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -111,10 +111,9 @@ public abstract class AbstractDTableEditor extends AbstractDTreeEditor implement
if (isDeleted(getEditorInput())) {
if (isSaveAsAllowed()) {
/*
- * 1GEUSSR: ITPUI:ALL - User should never loose changes made in
- * the editors. Changed Behavior to make sure that if called
- * inside a regular save (because of deletion of input element)
- * there is a way to report back to the caller.
+ * 1GEUSSR: ITPUI:ALL - User should never loose changes made in the editors. Changed Behavior to make
+ * sure that if called inside a regular save (because of deletion of input element) there is a way to
+ * report back to the caller.
*/
performSaveAs(progressMonitor);
} else {
@@ -286,9 +285,8 @@ public abstract class AbstractDTableEditor extends AbstractDTreeEditor implement
}
/**
- * Overridden to update the UI part when the {@link DTable} model is changed
- * outside of a EMF Command (which notify DTableContentAdapter) in case of
- * collab model.
+ * Overridden to update the UI part when the {@link DTable} model is changed outside of a EMF Command (which notify
+ * DTableContentAdapter) in case of collab model.
*
* {@inheritDoc}
*/
@@ -351,10 +349,9 @@ public abstract class AbstractDTableEditor extends AbstractDTreeEditor implement
* @param uri
* the URI to resolve.
* @param loadOnDemand
- * whether to create and load the resource, if it doesn't already
- * exists.
- * @return the DTable resource resolved by the URI, or <code>null</code> if
- * there isn't one and it's not being demand loaded.
+ * whether to create and load the resource, if it doesn't already exists.
+ * @return the DTable resource resolved by the URI, or <code>null</code> if there isn't one and it's not being
+ * demand loaded.
*/
private DTable getDTable(final URI uri, final boolean loadOnDemand) {
DTable result = null;
@@ -415,8 +412,7 @@ public abstract class AbstractDTableEditor extends AbstractDTreeEditor implement
}
/**
- * Sets the cursor and selection state for an editor to reveal the position
- * of the given marker.
+ * Sets the cursor and selection state for an editor to reveal the position of the given marker.
*
* @param marker
* the marker to go to
@@ -498,4 +494,16 @@ public abstract class AbstractDTableEditor extends AbstractDTreeEditor implement
refreshAtOpeningActivator = null;
}
}
+
+ @Override
+ protected void updateEditorAfterAirdResourceReload() {
+ // We update all components that keeps Aird proxified element after an
+ // Aird resource reload.
+ treeViewerManager.updateDRepresentation(getTableModel());
+ getSite().getPage().removePartListener(refreshAtOpeningActivator);
+ refreshAtOpeningActivator = new RefreshAtOpeningActivator(session, this);
+ getSite().getPage().addPartListener(refreshAtOpeningActivator);
+ treeViewerManager.getTreeViewer().refresh();
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableMenuListener.java b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableMenuListener.java
index 14dd24750b..2f622d2353 100644
--- a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableMenuListener.java
+++ b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableMenuListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2016 THALES GLOBAL SERVICES and others.
+ * Copyright (c) 2007, 2017 THALES GLOBAL SERVICES and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -115,7 +115,7 @@ public class DTableMenuListener implements IMenuListener {
private final AdapterFactory adapterFactory;
- private final DTable dTable;
+ private DTable dTable;
private final DTableViewerManager treeViewManager;
@@ -155,15 +155,11 @@ public class DTableMenuListener implements IMenuListener {
* @param treeViewManager
* The manager of the TreeView
* @param mappingToCreateActions
- * A map which associates {@link TableMapping} with the
- * corresponding list of {@link AbstractToolAction} (
- * {@link org.eclipse.sirius.table.ui.tools.internal.editor.action.CreateLineAction}
- * or
- * {@link org.eclipse.sirius.table.ui.tools.internal.editor.action.CreateTargetColumnAction}
- * )
+ * A map which associates {@link TableMapping} with the corresponding list of {@link AbstractToolAction}
+ * ( {@link org.eclipse.sirius.table.ui.tools.internal.editor.action.CreateLineAction} or
+ * {@link org.eclipse.sirius.table.ui.tools.internal.editor.action.CreateTargetColumnAction} )
* @param mappingToDeleteColumnActions
- * A map which associates {@link TableMapping} with the
- * corresponding
+ * A map which associates {@link TableMapping} with the corresponding
* {@link org.eclipse.sirius.table.ui.tools.internal.editor.action.DeleteTargetColumnAction}
* @param createActionsForTable
* A list of the actions for create lines under the table.
@@ -615,15 +611,14 @@ public class DTableMenuListener implements IMenuListener {
}
/**
- * Tests whether a representation description belongs to a viewpoint which
- * is currently active in the session.
+ * Tests whether a representation description belongs to a viewpoint which is currently active in the session.
*
* @param session
* the current session.
* @param representationDescription
* the representation description to check.
- * @return <code>true</code> if the representation description belongs to a
- * viewpoint which is currently active in the session.
+ * @return <code>true</code> if the representation description belongs to a viewpoint which is currently active in
+ * the session.
*/
private boolean isFromActiveViewpoint(final Session session, final RepresentationDescription representationDescription) {
final Viewpoint vp = ViewpointRegistry.getInstance().getViewpoint(representationDescription);
@@ -631,15 +626,13 @@ public class DTableMenuListener implements IMenuListener {
}
/**
- * Tests whether a representation belongs to a viewpoint which is currently
- * active in the session.
+ * Tests whether a representation belongs to a viewpoint which is currently active in the session.
*
* @param session
* the current session.
* @param representation
* the representation to check.
- * @return <code>true</code> if the representation belongs to a viewpoint
- * which is currently active in the session.
+ * @return <code>true</code> if the representation belongs to a viewpoint which is currently active in the session.
*/
private boolean isFromActiveViewpoint(final Session session, final DRepresentation representation) {
final RepresentationDescription description = DialectManager.INSTANCE.getDescription(representation);
@@ -669,4 +662,9 @@ public class DTableMenuListener implements IMenuListener {
public void setCreateActionsForTable(final List<AbstractToolAction> createActionsForTable) {
this.createActionsForTable = createActionsForTable;
}
+
+ public void setTable(DTable newDRepresentation) {
+ this.dTable = newDRepresentation;
+
+ }
}
diff --git a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java
index 3a3532ce3f..1395d7d836 100644
--- a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java
+++ b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2015 THALES GLOBAL SERVICES and others.
+ * Copyright (c) 2008, 2017 THALES GLOBAL SERVICES and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -74,6 +74,7 @@ import org.eclipse.sirius.ui.tools.internal.editor.DTableTreeFocusListener;
import org.eclipse.sirius.ui.tools.internal.editor.DescriptionFileChangedNotifier;
import org.eclipse.sirius.ui.tools.internal.editor.SelectDRepresentationElementsListener;
import org.eclipse.sirius.ui.tools.internal.views.common.navigator.adapters.ModelDragTargetAdapter;
+import org.eclipse.sirius.viewpoint.DRepresentation;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.DND;
@@ -157,6 +158,11 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
}
/**
+ * True if the dRepresentation has just been replaced.
+ */
+ protected boolean dRepresentationReplaced;
+
+ /**
* the current active column.
*/
private int activeColumn = -1;
@@ -179,6 +185,10 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
private SelectDRepresentationElementsListener selectTableElementsListener;
+ private TreeColumnLayout treeLayout;
+
+ private Composite composite;
+
/**
* The constructor.
*
@@ -212,49 +222,76 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
/**
* Create the TreeViewer.
*
- * Problem for action on column header :
- * https://bugs.eclipse.org/bugs/show_bug.cgi?id=23103
+ * Problem for action on column header : https://bugs.eclipse.org/bugs/show_bug.cgi?id=23103
*
- * @param composite
+ * @param theComposite
* the parent composite
*/
@Override
- protected void createTreeViewer(final Composite composite) {
+ protected void createTreeViewer(final Composite theComposite) {
+ this.composite = theComposite;
// Create a composite to hold the children
final GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_BOTH);
- composite.setLayoutData(gridData);
- final TreeColumnLayout treeLayout = new TreeColumnLayout();
- composite.setLayout(treeLayout);
+ theComposite.setLayoutData(gridData);
+ treeLayout = new TreeColumnLayout();
+ theComposite.setLayout(treeLayout);
// Create and setup the TreeViewer
final int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI;
- treeViewer = new DTableTreeViewer(composite, style, this);
+ treeViewer = new DTableTreeViewer(theComposite, style, this);
+ treeViewer.addTreeListener(tableViewerListener);
+ initializeDragSupport();
+ treeViewer.setUseHashlookup(true);
// Add a focus listener to deactivate the EMF actions on the Tree
treeViewer.getTree().addFocusListener(new DTableTreeFocusListener(treeEditor, treeViewer.getTree()));
- initializeDragSupport();
+ descriptionFileChangedNotifier = new DescriptionFileChangedNotifier(this);
+ dTableContentProvider = new DTableContentProvider();
+ treeViewer.setContentProvider(dTableContentProvider);
+ ColumnViewerToolTipSupport.enableFor(treeViewer);
+ treeViewer.getTree().setLinesVisible(true);
+ treeViewer.getTree().setHeaderVisible(true);
+ // Manage height of the lines, selected colors,
+ triggerCustomDrawingTreeItems();
+ // Create a new CellFocusManager
+ final TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(treeViewer, new FocusCellOwnerDrawHighlighter(treeViewer));
+ // Create a TreeViewerEditor with focusable cell
+ TreeViewerEditor.create(treeViewer, focusCellManager, new DTableColumnViewerEditorActivationStrategy(treeViewer),
+ ColumnViewerEditor.TABBING_HORIZONTAL | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION);
+ initializeKeyBindingSupport();
+ triggerColumnSelectedColumn();
+ initializeColumnsAndComponentsRelatedToDRepresentation(treeLayout);
+ }
+
+ /**
+ * Initialize the columns and everything initialized according to DRepresentation.
+ *
+ * @param theTreeLayout
+ * the tree layout used to layout the columns.
+ */
+ private void initializeColumnsAndComponentsRelatedToDRepresentation(final TreeColumnLayout theTreeLayout) {
+
sortListener = new DLinesSorter(getEditingDomain(), getEditor().getTableModel());
// 1st column with line labels
- TreeViewerColumn headerTreeColumn = addFirstColumn(treeLayout);
+ TreeViewerColumn headerTreeColumn = addFirstColumn(theTreeLayout);
// Next columns
int index = 1;
for (final DColumn column : ((DTable) dRepresentation).getColumns()) {
addNewColumn(column, index++);
}
- treeViewer.setUseHashlookup(true);
+
// TableUIUpdater must be called before {@link
// SelectDRepresentationElementsListener} to have TreeItem created
tableUIUpdater = new TableUIUpdater(this, dRepresentation);
+
+ if (selectTableElementsListener != null) {
+ selectTableElementsListener.dispose();
+ }
selectTableElementsListener = new SelectDRepresentationElementsListener(treeEditor, true);
- descriptionFileChangedNotifier = new DescriptionFileChangedNotifier(this);
- dTableContentProvider = new DTableContentProvider();
- treeViewer.setContentProvider(dTableContentProvider);
+
// The input for the table viewer is the instance of DTable
treeViewer.setInput(dRepresentation);
- ColumnViewerToolTipSupport.enableFor(treeViewer);
- treeViewer.getTree().setLinesVisible(true);
- treeViewer.getTree().setHeaderVisible(true);
+
fillMenu();
- triggerColumnSelectedColumn();
// Expands the line according to the model
treeViewer.setExpandedElements(TableHelper.getExpandedLines((DTable) dRepresentation).toArray());
@@ -267,22 +304,14 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
treeViewer.getTree().getColumn(i).pack();
}
}
- treeViewer.addTreeListener(tableViewerListener);
- // Manage height of the lines, selected colors,
- triggerCustomDrawingTreeItems();
- // Create a new CellFocusManager
- final TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(treeViewer, new FocusCellOwnerDrawHighlighter(treeViewer));
- // Create a TreeViewerEditor with focusable cell
- TreeViewerEditor.create(treeViewer, focusCellManager, new DTableColumnViewerEditorActivationStrategy(treeViewer),
- ColumnViewerEditor.TABBING_HORIZONTAL | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION);
// Set after the setInput to avoid layout call it several time for
// nothing at opening
headerTreeColumn.getColumn().addControlListener(tableViewerListener);
- initializeKeyBindingSupport();
+
}
- private TreeViewerColumn addFirstColumn(TreeColumnLayout treeLayout) {
+ private TreeViewerColumn addFirstColumn(TreeColumnLayout theTreeLayout) {
DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.ADD_SWT_COLUMN_KEY);
final TreeViewerColumn headerTreeColumn = new TreeViewerColumn(treeViewer, SWT.CENTER, 0);
DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.SET_COLUMN_NAME_KEY);
@@ -306,12 +335,12 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
headerTreeColumn.setLabelProvider(lineheaderColumnLabelProvider);
int headerColumnWidth = ((DTable) dRepresentation).getHeaderColumnWidth();
if (headerColumnWidth != 0) {
- treeLayout.setColumnData(headerTreeColumn.getColumn(), new ColumnPixelData(headerColumnWidth));
+ theTreeLayout.setColumnData(headerTreeColumn.getColumn(), new ColumnPixelData(headerColumnWidth));
if (headerTreeColumn.getColumn().getWidth() != headerColumnWidth) {
headerTreeColumn.getColumn().setWidth(headerColumnWidth);
}
} else {
- treeLayout.setColumnData(headerTreeColumn.getColumn(), new ColumnWeightData(1));
+ theTreeLayout.setColumnData(headerTreeColumn.getColumn(), new ColumnWeightData(1));
if (IS_GTK_OS) {
// Do not launch treeViewerColumn.getColumn().pack() here
// for windows because the size is computed only with the
@@ -358,29 +387,26 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
}
/**
- * Initialize a cache and add, if needed, the contextual menu for the table.
- * <BR>
- * Cached the actions of creation and deletion in order to increase
- * performance and not calculate it on each contextual menu.<BR>
- * Problem for action on column header :
- * https://bugs.eclipse.org/bugs/show_bug.cgi?id=23103 <BR>
+ * Initialize a cache and add, if needed, the contextual menu for the table. <BR>
+ * Cached the actions of creation and deletion in order to increase performance and not calculate it on each
+ * contextual menu.<BR>
+ * Problem for action on column header : https://bugs.eclipse.org/bugs/show_bug.cgi?id=23103 <BR>
*/
@Override
public void fillMenu() {
- if (descriptionFileChanged) {
+ if (descriptionFileChanged || dRepresentationReplaced) {
descriptionFileChanged = false;
+
final Map<TableMapping, DeleteTargetColumnAction> mappingToDeleteActions = Maps.newHashMap();
final Map<TableMapping, List<AbstractToolAction>> mappingToCreateActions = Maps.newHashMap();
final List<AbstractToolAction> createActionsForTable = Lists.newArrayList();
calculateAvailableMenus(mappingToDeleteActions, mappingToCreateActions, createActionsForTable);
mgr.setRemoveAllWhenShown(true);
- if (actualMenuListener != null) {
- mgr.removeAll();
- actualMenuListener.setMappingToCreateActions(mappingToCreateActions);
- actualMenuListener.setMappingToDeleteActions(mappingToDeleteActions);
- actualMenuListener.setCreateActionsForTable(createActionsForTable);
- } else {
+ if (dRepresentationReplaced || actualMenuListener == null) {
+ if (dRepresentationReplaced) {
+ mgr.removeMenuListener(actualMenuListener);
+ }
actualMenuListener = new DTableMenuListener((DTable) dRepresentation, this, mappingToCreateActions, mappingToDeleteActions, createActionsForTable);
mgr.addMenuListener(actualMenuListener);
@@ -388,23 +414,27 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
treeViewer.getControl().setMenu(menu);
// Add this line to have others contextual menus
treeEditor.getSite().registerContextMenu(mgr, treeViewer);
+ } else {
+ mgr.removeAll();
+ actualMenuListener.setMappingToCreateActions(mappingToCreateActions);
+ actualMenuListener.setMappingToDeleteActions(mappingToDeleteActions);
+ actualMenuListener.setCreateActionsForTable(createActionsForTable);
}
getCreateLineMenu().update(createActionsForTable);
getCreateTargetColumnMenu().update(createActionsForTable);
+ dRepresentationReplaced = false;
}
}
/**
- * Create the menus according to the {@link TableMapping} and the associated
- * {@link CreateTool} and {@link DeleteTool}.
+ * Create the menus according to the {@link TableMapping} and the associated {@link CreateTool} and
+ * {@link DeleteTool}.
*
* @param mappingToDeleteActions
- * A map which associates {@link TableMapping} with the
- * corresponding {@link DeleteTargetColumnAction}
+ * A map which associates {@link TableMapping} with the corresponding {@link DeleteTargetColumnAction}
* @param mappingToCreateActions
- * A map which associates {@link TableMapping} with the
- * corresponding list of {@link AbstractToolAction} (
- * {@link CreateLineAction} or {@link CreateTargetColumnAction})
+ * A map which associates {@link TableMapping} with the corresponding list of {@link AbstractToolAction}
+ * ( {@link CreateLineAction} or {@link CreateTargetColumnAction})
* @param createActionsForTable
* A list of the actions for create lines under the table.
*/
@@ -441,18 +471,16 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
}
/**
- * Create the menus according to the {@link ElementColumnMapping} and the
- * associated {@link CreateTool} and {@link DeleteTool}.
+ * Create the menus according to the {@link ElementColumnMapping} and the associated {@link CreateTool} and
+ * {@link DeleteTool}.
*
* @param columnMappings
* List of {@link ElementColumnMapping}
* @param mappingToDeleteActions
- * A map which associates {@link TableMapping} with the
- * corresponding {@link DeleteTargetColumnAction}
+ * A map which associates {@link TableMapping} with the corresponding {@link DeleteTargetColumnAction}
* @param mappingToCreateActions
- * A map which associates {@link TableMapping} with the
- * corresponding list of {@link AbstractToolAction} (
- * {@link CreateLineAction} or {@link CreateTargetColumnAction})
+ * A map which associates {@link TableMapping} with the corresponding list of {@link AbstractToolAction}
+ * ( {@link CreateLineAction} or {@link CreateTargetColumnAction})
*/
private void calculateAvailableMenusForColumn(final EList<ElementColumnMapping> columnMappings, final Map<TableMapping, DeleteTargetColumnAction> mappingToDeleteActions,
final Map<TableMapping, List<AbstractToolAction>> mappingToCreateActions) {
@@ -476,15 +504,14 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
}
/**
- * Create the menus according to the {@link LineMapping} and the associated
- * {@link CreateTool} and {@link DeleteTool}.
+ * Create the menus according to the {@link LineMapping} and the associated {@link CreateTool} and
+ * {@link DeleteTool}.
*
* @param lineMappings
* List of {@link LineMapping}
* @param mappingToCreateActions
- * A map which associates {@link TableMapping} with the
- * corresponding list of {@link AbstractToolAction} (
- * {@link CreateLineAction} or {@link CreateTargetColumnAction})
+ * A map which associates {@link TableMapping} with the corresponding list of {@link AbstractToolAction}
+ * ( {@link CreateLineAction} or {@link CreateTargetColumnAction})
*/
private void calculateAvailableMenusForLine(final EList<LineMapping> lineMappings, final Map<TableMapping, List<AbstractToolAction>> mappingToCreateActions,
final List<LineMapping> processedLineMappings) {
@@ -516,8 +543,7 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
}
/**
- * Add a listener on the tree to listen the mouseDouwn or the key left-right
- * arrows and store the activeColumn.
+ * Add a listener on the tree to listen the mouseDouwn or the key left-right arrows and store the activeColumn.
*/
protected void triggerColumnSelectedColumn() {
treeViewer.getTree().addMouseListener(new MouseAdapter() {
@@ -611,8 +637,7 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
* @param index
* the index at which to place the newly created column
* @param changeInput
- * true if we must change the input of the SWT tree to null
- * before adding the SWT column, false otherwise
+ * true if we must change the input of the SWT tree to null before adding the SWT column, false otherwise
*/
public void addNewColumn(final DColumn newColumn, final int index, final boolean changeInput) {
DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.ADD_SWT_COLUMN_KEY);
@@ -750,4 +775,20 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
createTargetColumnMenu = null;
}
+ @Override
+ public void updateDRepresentation(DRepresentation newDRepresentation) {
+ this.dRepresentation = newDRepresentation;
+ tableViewerListener.resetDTable();
+
+ getTreeViewer().getTree().removeAll();
+ getTreeViewer().getTree().clearAll(true);
+ while (getTreeViewer().getTree().getColumnCount() > 0) {
+ getTreeViewer().getTree().getColumns()[0].dispose();
+ }
+ treeLayout = new TreeColumnLayout();
+ composite.setLayout(treeLayout);
+ dRepresentationReplaced = true;
+ initializeColumnsAndComponentsRelatedToDRepresentation(treeLayout);
+
+ }
}
diff --git a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/listeners/DTableViewerListener.java b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/listeners/DTableViewerListener.java
index 626cfb61d5..78caf321c6 100644
--- a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/listeners/DTableViewerListener.java
+++ b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/listeners/DTableViewerListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2015 THALES GLOBAL SERVICES.
+ * Copyright (c) 2011, 2017 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -36,9 +36,8 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TreeColumn;
/**
- * A {@link ITreeViewerListener} and {@link ControlListener} to update the
- * DTable model when a SWT TreeItem is collapsed/expanded and
- * {@link TreeColumn#getWidth()} change.
+ * A {@link ITreeViewerListener} and {@link ControlListener} to update the DTable model when a SWT TreeItem is
+ * collapsed/expanded and {@link TreeColumn#getWidth()} change.
*
* @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
*/
@@ -150,4 +149,12 @@ public class DTableViewerListener implements ITreeViewerListener, ControlListene
}
}
+ /**
+ * Replace the current DTable used with the given one.
+ *
+ */
+ public void resetDTable() {
+ this.dTable = (DTable) this.dTableViewerManager.getEditor().getRepresentation();
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.aird b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.aird
new file mode 100644
index 0000000000..8f22f5ffb3
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.aird
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:description="http://www.eclipse.org/sirius/description/1.1.0" xmlns:description_1="http://www.eclipse.org/sirius/tree/description/1.0.0" xmlns:description_2="http://www.eclipse.org/sirius/table/description/1.1.0" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:table="http://www.eclipse.org/sirius/table/1.1.0" xmlns:tree="http://www.eclipse.org/sirius/tree/1.0.0" xmlns:viewpoint="http://www.eclipse.org/sirius/1.1.0" xsi:schemaLocation="http://www.eclipse.org/sirius/description/1.1.0 http://www.eclipse.org/sirius/1.1.0#//description http://www.eclipse.org/sirius/tree/description/1.0.0 http://www.eclipse.org/sirius/tree/1.0.0#//description http://www.eclipse.org/sirius/table/description/1.1.0 http://www.eclipse.org/sirius/table/1.1.0#//description">
+ <viewpoint:DAnalysis xmi:id="_59Je0PIJEea1GeqoRSXufw" selectedViews="_BJd7kPIKEeaCXtca9wOvKA" version="11.1.0.201608251200">
+ <semanticResources>manualAird.ecore</semanticResources>
+ <ownedViews xmi:type="viewpoint:DView" xmi:id="_BJd7kPIKEeaCXtca9wOvKA">
+ <viewpoint xmi:type="description:Viewpoint" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']"/>
+ <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" xmi:id="_9qLDwPLFEeaQMeHKkdbtDQ" name="manualAirdTree" representation="_9qLDwfLFEeaQMeHKkdbtDQ">
+ <description xmi:type="description_1:TreeDescription" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTree']"/>
+ <target xmi:type="ecore:EPackage" href="manualAird.ecore#/"/>
+ </ownedRepresentationDescriptors>
+ <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" xmi:id="_-Rh-sPLFEeaQMeHKkdbtDQ" name="manualAirdTable" representation="_-RilwPLFEeaQMeHKkdbtDQ">
+ <description xmi:type="description_2:EditionTableDescription" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTable']"/>
+ <target xmi:type="ecore:EPackage" href="manualAird.ecore#/"/>
+ </ownedRepresentationDescriptors>
+ </ownedViews>
+ </viewpoint:DAnalysis>
+ <tree:DTree xmi:id="_9qLDwfLFEeaQMeHKkdbtDQ" name="manualAirdTree">
+ <target xmi:type="ecore:EPackage" href="manualAird.ecore#/"/>
+ <ownedTreeItems xmi:type="tree:DTreeItem" xmi:id="_9qLDwvLFEeaQMeHKkdbtDQ" name="C1">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C1"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C1"/>
+ <ownedStyle xmi:type="tree:TreeItemStyle" xmi:id="_9qLDw_LFEeaQMeHKkdbtDQ"/>
+ <actualMapping xmi:type="description_1:TreeItemMapping" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTree']/@subItemMappings[name='eclass2']"/>
+ </ownedTreeItems>
+ <ownedTreeItems xmi:type="tree:DTreeItem" xmi:id="_9qLDxPLFEeaQMeHKkdbtDQ" name="C2">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C2"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C2"/>
+ <ownedStyle xmi:type="tree:TreeItemStyle" xmi:id="_9qLDxfLFEeaQMeHKkdbtDQ"/>
+ <actualMapping xmi:type="description_1:TreeItemMapping" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTree']/@subItemMappings[name='eclass2']"/>
+ </ownedTreeItems>
+ <ownedTreeItems xmi:type="tree:DTreeItem" xmi:id="_9qLDxvLFEeaQMeHKkdbtDQ" name="C3">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C3"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C3"/>
+ <ownedStyle xmi:type="tree:TreeItemStyle" xmi:id="_9qLDx_LFEeaQMeHKkdbtDQ"/>
+ <actualMapping xmi:type="description_1:TreeItemMapping" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTree']/@subItemMappings[name='eclass2']"/>
+ </ownedTreeItems>
+ <description xmi:type="description_1:TreeDescription" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTree']"/>
+ </tree:DTree>
+ <table:DTable xmi:id="_-RilwPLFEeaQMeHKkdbtDQ" name="manualAirdTable" headerColumnWidth="59">
+ <target xmi:type="ecore:EPackage" href="manualAird.ecore#/"/>
+ <lines xmi:type="table:DLine" xmi:id="_-RilwfLFEeaQMeHKkdbtDQ" label="C1">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C1"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C1"/>
+ <originMapping xmi:type="description_2:LineMapping" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTable']/@ownedLineMappings[name='Classes']"/>
+ <cells xmi:type="table:DCell" xmi:id="_-RilwvLFEeaQMeHKkdbtDQ" label="true" column="_-RilyvLFEeaQMeHKkdbtDQ">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C1"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C1"/>
+ </cells>
+ <cells xmi:type="table:DCell" xmi:id="_-Rilw_LFEeaQMeHKkdbtDQ" label="DC1" column="_-Rily_LFEeaQMeHKkdbtDQ">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C1"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C1"/>
+ </cells>
+ </lines>
+ <lines xmi:type="table:DLine" xmi:id="_-RilxPLFEeaQMeHKkdbtDQ" label="C2">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C2"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C2"/>
+ <originMapping xmi:type="description_2:LineMapping" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTable']/@ownedLineMappings[name='Classes']"/>
+ <cells xmi:type="table:DCell" xmi:id="_-RilxfLFEeaQMeHKkdbtDQ" label="false" column="_-RilyvLFEeaQMeHKkdbtDQ">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C2"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C2"/>
+ </cells>
+ <cells xmi:type="table:DCell" xmi:id="_-RilxvLFEeaQMeHKkdbtDQ" label="DC2" column="_-Rily_LFEeaQMeHKkdbtDQ">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C2"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C2"/>
+ </cells>
+ </lines>
+ <lines xmi:type="table:DLine" xmi:id="_-Rilx_LFEeaQMeHKkdbtDQ" label="C3">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C3"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C3"/>
+ <originMapping xmi:type="description_2:LineMapping" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTable']/@ownedLineMappings[name='Classes']"/>
+ <cells xmi:type="table:DCell" xmi:id="_-RilyPLFEeaQMeHKkdbtDQ" label="false" column="_-RilyvLFEeaQMeHKkdbtDQ">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C3"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C3"/>
+ </cells>
+ <cells xmi:type="table:DCell" xmi:id="_-RilyfLFEeaQMeHKkdbtDQ" label="DC3" column="_-Rily_LFEeaQMeHKkdbtDQ">
+ <target xmi:type="ecore:EClass" href="manualAird.ecore#//C3"/>
+ <semanticElements xmi:type="ecore:EClass" href="manualAird.ecore#//C3"/>
+ </cells>
+ </lines>
+ <columns xmi:type="table:DFeatureColumn" xmi:id="_-RilyvLFEeaQMeHKkdbtDQ" label="Is Abstract?" cells="_-RilwvLFEeaQMeHKkdbtDQ _-RilxfLFEeaQMeHKkdbtDQ _-RilyPLFEeaQMeHKkdbtDQ" width="75" featureName="abstract">
+ <originMapping xmi:type="description_2:FeatureColumnMapping" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTable']/@ownedColumnMappings[name='IsAbstractColumn']"/>
+ </columns>
+ <columns xmi:type="table:DFeatureColumn" xmi:id="_-Rily_LFEeaQMeHKkdbtDQ" label="Label" cells="_-Rilw_LFEeaQMeHKkdbtDQ _-RilxvLFEeaQMeHKkdbtDQ _-RilyfLFEeaQMeHKkdbtDQ" width="43" featureName="name">
+ <originMapping xmi:type="description_2:FeatureColumnMapping" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTable']/@ownedColumnMappings[name='Class%20label']"/>
+ </columns>
+ <description xmi:type="description_2:EditionTableDescription" href="manualAird.odesign#//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTable']"/>
+ </table:DTable>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.ecore b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.ecore
new file mode 100644
index 0000000000..b49eda855b
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.ecore
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="root">
+ <eClassifiers xsi:type="ecore:EClass" name="C1" abstract="true"/>
+ <eClassifiers xsi:type="ecore:EClass" name="C2"/>
+ <eClassifiers xsi:type="ecore:EClass" name="C3"/>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.odesign b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.odesign
new file mode 100644
index 0000000000..02ab416438
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/refresh/manualAirdModification/manualAird.odesign
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description:Group xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:description="http://www.eclipse.org/sirius/description/1.1.0" xmlns:description_1="http://www.eclipse.org/sirius/table/description/1.1.0" xmlns:description_2="http://www.eclipse.org/sirius/tree/description/1.0.0" xmlns:tool="http://www.eclipse.org/sirius/description/tool/1.1.0" name="manualAird" version="11.1.1.201610211630">
+ <ownedViewpoints name="manualAird" modelFileExtension="ecore">
+ <ownedRepresentations xsi:type="description_1:EditionTableDescription" name="manualAirdTable" domainClass="EPackage">
+ <ownedLineMappings name="Classes" domainClass="EClass" semanticCandidatesExpression="feature:eClassifiers"/>
+ <ownedColumnMappings name="IsAbstractColumn" headerLabelExpression="Is Abstract?" featureName="abstract" labelExpression="feature:abstract"/>
+ <ownedColumnMappings name="Class label" headerLabelExpression="Label" featureName="name" labelExpression="aql:'D'+self.name">
+ <directEdit>
+ <variables name="element" documentation="The semantic currently edited element."/>
+ <variables name="lineSemantic" documentation="The semantic element corresponding to the line."/>
+ <variables name="root" documentation="The semantic root element of the table."/>
+ <firstModelOperation xsi:type="tool:ChangeContext" browseExpression="var:element">
+ <subModelOperations xsi:type="tool:SetValue" featureName="name" valueExpression="var:arg0"/>
+ </firstModelOperation>
+ <mask mask="{0}"/>
+ </directEdit>
+ </ownedColumnMappings>
+ </ownedRepresentations>
+ <ownedRepresentations xsi:type="description_2:TreeDescription" name="manualAirdTree" domainClass="EPackage">
+ <subItemMappings name="eclass2" domainClass="ecore.EClass" semanticCandidatesExpression="feature:eAllContents">
+ <defaultStyle>
+ <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/>
+ <backgroundColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='white']"/>
+ </defaultStyle>
+ <directEdit name="directEdit" mapping="//@ownedViewpoints[name='manualAird']/@ownedRepresentations[name='manualAirdTree']/@subItemMappings[name='eclass2']">
+ <firstModelOperation xsi:type="tool:ChangeContext" browseExpression="var:element">
+ <subModelOperations xsi:type="tool:SetValue" featureName="name" valueExpression="var:arg0"/>
+ </firstModelOperation>
+ <mask mask="{0}"/>
+ <element name="element"/>
+ <root name="root"/>
+ </directEdit>
+ </subItemMappings>
+ </ownedRepresentations>
+ </ownedViewpoints>
+</description:Group>
diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/ManualAirdModificationTest.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/ManualAirdModificationTest.java
new file mode 100644
index 0000000000..edfea0214e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/ManualAirdModificationTest.java
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tests.swtbot;
+
+import static org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable.syncExec;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionStatus;
+import org.eclipse.sirius.table.metamodel.table.DTable;
+import org.eclipse.sirius.tests.swtbot.support.api.AbstractSiriusSwtBotGefTestCase;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIResource;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.results.IntResult;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Tests behavior of table and tree editors when the aird is manually modified
+ * whereas editors are already opened.
+ *
+ * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a>
+ *
+ */
+public class ManualAirdModificationTest extends AbstractSiriusSwtBotGefTestCase {
+
+ private static final String PATH = "data/unit/refresh/manualAirdModification/";
+
+ private static final String SEMANTIC_RESOURCE_NAME = "manualAird.ecore";
+
+ private static final String REPRESENTATIONS_RESOURCE_NAME = "manualAird.aird";
+
+ private static final String MODELER_RESOURCE_NAME = "manualAird.odesign";
+
+ private SWTBotTree tableTree;
+
+ private SWTBotEditor tableEditor;
+
+ private SWTBotEditor treeEditor;
+
+ private Session session;
+
+ private URI airdResourceUri;
+
+ @Override
+ protected void onSetUpAfterOpeningDesignerPerspective() throws Exception {
+ sessionAirdResource = new UIResource(designerProject, "/", REPRESENTATIONS_RESOURCE_NAME);
+ localSession = designerPerspective.openSessionFromFile(sessionAirdResource, true);
+ session = localSession.getOpenedSession();
+
+ tableEditor = openRepresentation(localSession.getOpenedSession(), "manualAirdTable", "manualAirdTable", DTable.class);
+ tableTree = tableEditor.bot().tree();
+
+ treeEditor = openRepresentation(localSession.getOpenedSession(), "manualAirdTree", "manualAirdTree", DTree.class);
+
+ airdResourceUri = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(sessionAirdResource.getFullPath())).getRawLocationURI();
+
+ }
+
+ @Override
+ protected void onSetUpBeforeClosingWelcomePage() throws Exception {
+ copyFileToTestProject(Activator.PLUGIN_ID, PATH, SEMANTIC_RESOURCE_NAME, REPRESENTATIONS_RESOURCE_NAME, MODELER_RESOURCE_NAME);
+ }
+
+ /**
+ * Test that modifications made outside of the session does not break
+ * current opened table and tree editors.
+ *
+ * @throws IOException
+ * if a problem occurs when modifying representations file
+ * outside of the session.
+ * @throws CoreException
+ * if a problem occurs when refreshing workspace project.
+ */
+ public void testManualAirdModificationBehavior() throws IOException, CoreException {
+ // check original header column width
+ assertEquals("The original table header column width is not the expected one.", (Integer) 59, syncExec(new IntResult() {
+ @Override
+ public Integer run() {
+ return tableTree.widget.getColumns()[0].getWidth();
+ }
+ }));
+ // We replace the header column width from 59 to 100 in the aird.
+ modifyRepresentationsFileOutsideOfTheSession("headerColumnWidth=\"59\"", "headerColumnWidth=\"100\"");
+
+ // refresh workspace projects
+ ResourcesPlugin.getWorkspace().getRoot().getProject(getProjectName()).refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
+
+ SWTBotUtils.waitAllUiEvents();
+ tableEditor.show();
+ SWTBotUtils.waitAllUiEvents();
+
+ // check original header column width
+ assertEquals("The table header column width has not been updated after modification of representations file outside of the session.", (Integer) 100, syncExec(new IntResult() {
+ @Override
+ public Integer run() {
+ return tableTree.widget.getColumns()[0].getWidth();
+ }
+ }));
+
+ assertEquals("The session should not be dirty.", SessionStatus.SYNC, session.getStatus());
+
+ // We check property view is still linked to table selection
+ changeNameByUsingPropertyView(tableEditor, "C3", "C4");
+ tableEditor.setFocus();
+ assertEquals("The session should be dirty.", SessionStatus.DIRTY, session.getStatus());
+
+ // We check direct edit tool works for the table
+ directEditLabel(tableEditor, "C2", 'E');
+ treeEditor.show();
+ try {
+ treeEditor.bot().tree().getTreeItem("C4");
+ } catch (WidgetNotFoundException e) {
+ fail("Tree cell has not been updated grapically.");
+ }
+ try {
+ treeEditor.bot().tree().getTreeItem("E");
+ } catch (WidgetNotFoundException e) {
+ fail("Tree cell has not been updated grapically.");
+ }
+ session.save(new NullProgressMonitor());
+ assertEquals("The session should not be dirty.", SessionStatus.SYNC, session.getStatus());
+
+ // We check property view is still linked to tree selection
+ changeNameByUsingPropertyView(treeEditor, "C1", "C7");
+ treeEditor.setFocus();
+ assertEquals("The session should be dirty.", SessionStatus.DIRTY, session.getStatus());
+
+ // We check direct edit tool works for the tree
+ directEditLabel(treeEditor, "E", 'F');
+ tableEditor.show();
+ treeEditor.show();
+
+ try {
+ treeEditor.bot().tree().getTreeItem("F");
+ } catch (WidgetNotFoundException e) {
+ fail("Tree cell has not been updated grapically.");
+ }
+ try {
+ treeEditor.bot().tree().getTreeItem("C7");
+ } catch (WidgetNotFoundException e) {
+ fail("Tree cell has not been updated grapically.");
+ }
+ }
+
+ /**
+ * Replace the value in the aird matching the given reg exp oldValue by the
+ * new value.
+ *
+ * @param newValue
+ * the value used to replace mathing value in the aird.
+ * @param oldValue
+ * the reg exp used to find content in aird that will be replaced
+ * by the new value.
+ * @throws IOException
+ * if any problem occurs when modifying the aird.
+ *
+ */
+ protected void modifyRepresentationsFileOutsideOfTheSession(String oldValue, String newValue) throws IOException {
+ java.nio.file.Path representationsFilePath = Paths.get(airdResourceUri);
+ // Read the content of the file
+ Optional<String> newContent = Optional.empty();
+ try (BufferedReader br = Files.newBufferedReader(representationsFilePath)) {
+ // Replace the content
+ Stream<String> newContentStream = br.lines().map(line -> line.replace(oldValue, newValue));
+ newContent = newContentStream.reduce((concatenatedLines, lineToConcat) -> concatenatedLines.concat(lineToConcat));
+ }
+ if (newContent.isPresent()) {
+ // Write the new content
+ try (BufferedWriter bw = Files.newBufferedWriter(representationsFilePath, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
+ bw.write(newContent.get());
+ }
+ }
+ }
+
+ /**
+ * Direct edit the text cell with the given old value and replace the
+ * content with the given char.
+ *
+ * @param editor
+ * editor containing the text cell to edit.
+ * @param oldValue
+ * the value that should be changed.
+ * @param newChar
+ * the new value.
+ */
+ protected void directEditLabel(SWTBotEditor editor, String oldValue, char newChar) {
+ SWTBotTreeItem tableItem = editor.bot().tree().getTreeItem(oldValue);
+ tableItem.select();
+ tableItem.click(2);
+ SWTBotUtils.directEditWithKeyboard(tableTree.widget, newChar + "");
+ }
+
+ /**
+ * Change the value of the cell text containing the old value to the new one
+ * by clicking on it on the given editor and modifying it using the
+ * properties view. This tests that properties views are linked to editor
+ * selections.
+ *
+ * @param editor
+ * editor used to do the modification
+ * @param oldValue
+ * the EClass name old value to update
+ * @param newValue
+ * the EClass name new value.
+ */
+ protected void changeNameByUsingPropertyView(SWTBotEditor editor, String oldValue, String newValue) {
+ editor.bot().tree().select(oldValue);
+ SWTBotUtils.waitAllUiEvents();
+ bot.viewByTitle("Properties").setFocus();
+ SWTBot propertiesBot = bot.viewByTitle("Properties").bot();
+ try {
+ SWTBotTreeItem treeItem = propertiesBot.tree().getTreeItem(oldValue).getNode("Name");
+ treeItem.select();
+ treeItem.click();
+ SWTBotText propertyText = propertiesBot.text(oldValue);
+ propertyText.setText(newValue);
+ } catch (WidgetNotFoundException e) {
+ fail("The properties view is not linked anymore to editor selection.");
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java
index f64de73bc4..25da22f11b 100644
--- a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java
+++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2016 THALES GLOBAL SERVICES.
+ * Copyright (c) 2010, 2017 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -162,6 +162,7 @@ public class AllTestSuite extends TestCase {
suite.addTestSuite(EdgeLabelsMoveFromEdgeMoveTest.class);
suite.addTestSuite(OpeningContextTest.class);
suite.addTestSuite(NodeWithDecoratorSelectionTest.class);
+ suite.addTestSuite(ManualAirdModificationTest.class);
}
/**
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeEditor.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeEditor.java
index 23d43d61e0..552ef66f18 100644
--- a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeEditor.java
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeEditor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2015 THALES GLOBAL SERVICES and others.
+ * Copyright (c) 2010, 2017 THALES GLOBAL SERVICES and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -248,9 +248,8 @@ public class DTreeEditor extends AbstractDTreeEditor implements org.eclipse.siri
}
/**
- * Overridden to update the UI part when the {@link DTree} model is changed
- * outside of a EMF Command (which notify DTreeContentAdapter) in case of
- * collab model.
+ * Overridden to update the UI part when the {@link DTree} model is changed outside of a EMF Command (which notify
+ * DTreeContentAdapter) in case of collab model.
*
* {@inheritDoc}
*/
@@ -320,10 +319,9 @@ public class DTreeEditor extends AbstractDTreeEditor implements org.eclipse.siri
* @param uri
* the URI to resolve.
* @param loadOnDemand
- * whether to create and load the resource, if it doesn't already
- * exists.
- * @return the DTree resource resolved by the URI, or <code>null</code> if
- * there isn't one and it's not being demand loaded.
+ * whether to create and load the resource, if it doesn't already exists.
+ * @return the DTree resource resolved by the URI, or <code>null</code> if there isn't one and it's not being demand
+ * loaded.
*/
private DTree getDTree(final URI uri, final boolean loadOnDemand) {
DTree result = null;
@@ -378,8 +376,7 @@ public class DTreeEditor extends AbstractDTreeEditor implements org.eclipse.siri
}
/**
- * Sets the cursor and selection state for an editor to reveal the position
- * of the given marker.
+ * Sets the cursor and selection state for an editor to reveal the position of the given marker.
*
* @param marker
* the marker to go to
@@ -494,4 +491,17 @@ public class DTreeEditor extends AbstractDTreeEditor implements org.eclipse.siri
}
return initialTitleImage;
}
+
+ @Override
+ protected void updateEditorAfterAirdResourceReload() {
+ // We update all components that keep Aird proxified element after an
+ // Aird resource reload.
+ treeViewerManager.updateDRepresentation(getTreeModel());
+ getSite().getPage().removePartListener(refreshAtOpeningActivator);
+ refreshAtOpeningActivator = new RefreshAtOpeningActivator(this);
+ getSite().getPage().addPartListener(refreshAtOpeningActivator);
+ treeViewerManager.getTreeViewer().refresh();
+
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java
index d021f20141..3c042c7ab4 100644
--- a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2015 THALES GLOBAL SERVICES and others.
+ * Copyright (c) 2010, 2017 THALES GLOBAL SERVICES and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -67,6 +67,7 @@ import org.eclipse.sirius.ui.tools.internal.editor.DTableTreeFocusListener;
import org.eclipse.sirius.ui.tools.internal.editor.DescriptionFileChangedNotifier;
import org.eclipse.sirius.ui.tools.internal.editor.SelectDRepresentationElementsListener;
import org.eclipse.sirius.ui.tools.internal.views.common.navigator.adapters.ModelDragTargetAdapter;
+import org.eclipse.sirius.viewpoint.DRepresentation;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.DND;
@@ -116,6 +117,10 @@ public class DTreeViewerManager extends AbstractDTableViewerManager {
private SelectDRepresentationElementsListener selectTableElementsListener;
+ private TreeColumnLayout treeLayout;
+
+ private Composite composite;
+
/**
* The constructor.
*
@@ -152,12 +157,13 @@ public class DTreeViewerManager extends AbstractDTableViewerManager {
* the Container of the TreeViewer to create
*/
@Override
- protected void createTreeViewer(final Composite composite) {
+ protected void createTreeViewer(final Composite theComposite) {
+ this.composite = theComposite;
// Create a composite to hold the children
final GridData gridData = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(gridData);
- final TreeColumnLayout treeLayout = new TreeColumnLayout();
+ treeLayout = new TreeColumnLayout();
composite.setLayout(treeLayout);
// Create and setup the TreeViewer
@@ -461,4 +467,22 @@ public class DTreeViewerManager extends AbstractDTableViewerManager {
createTreeItemMenu.dispose();
}
+ @Override
+ public void updateDRepresentation(DRepresentation newDRepresentation) {
+ this.dRepresentation = newDRepresentation;
+ treeUIUpdater.dispose();
+ treeUIUpdater = new TreeUIUpdater((DTreeViewer) treeViewer, dRepresentation);
+
+ getTreeViewer().getTree().removeAll();
+ getTreeViewer().getTree().clearAll(true);
+
+ treeLayout = new TreeColumnLayout();
+ composite.setLayout(treeLayout);
+
+ treeViewer.setInput(dRepresentation);
+
+ // Expands the line according to the model
+ treeViewer.setExpandedElements(TreeHelper.getExpandedItems((DTree) dRepresentation).toArray());
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTableViewerManager.java b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTableViewerManager.java
index d4d7f5eedc..62ee0653b9 100644
--- a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTableViewerManager.java
+++ b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTableViewerManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2015 THALES GLOBAL SERVICES and others.
+ * Copyright (c) 2010, 2017 THALES GLOBAL SERVICES and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -62,7 +62,7 @@ public abstract class AbstractDTableViewerManager {
/**
* the model editing by this Viewer.
*/
- protected final DRepresentation dRepresentation;
+ protected DRepresentation dRepresentation;
/**
* The model accessor.
@@ -148,7 +148,8 @@ public abstract class AbstractDTableViewerManager {
protected abstract void createTreeViewer(Composite composite);
/**
- * Initialize a cache and add, if needed, the contextual menu for the table. <BR>
+ * Initialize a cache and add, if needed, the contextual menu for the table.
+ * <BR>
* Cached the actions of creation and deletion in order to increase
* performance and not calculate it on each contextual menu.<BR>
* Problem for action on column header :
@@ -230,4 +231,13 @@ public abstract class AbstractDTableViewerManager {
descriptionFileChanged = modified;
}
+ /**
+ * Update this viewer manager representation with the new given
+ * {@link DRepresentation}. It replaces all references to the old used one.
+ *
+ * @param newDRepresentation
+ * the representation that will replace the current one used.
+ */
+ public abstract void updateDRepresentation(final DRepresentation newDRepresentation);
+
}
diff --git a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTreeEditor.java b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTreeEditor.java
index 26a22d6ea3..7b1d82c547 100644
--- a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTreeEditor.java
+++ b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/editor/AbstractDTreeEditor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2015 THALES GLOBAL SERVICES and others.
+ * Copyright (c) 2008, 2017 THALES GLOBAL SERVICES and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -433,22 +433,11 @@ public abstract class AbstractDTreeEditor extends EditorPart
@Override
public void setFocus() {
if (treeViewerManager != null) {
- /*
- * A regression in Kepler can cause an NPE inside the
- * treeViewerManager.getControl().setFocus() below. The guard
- * condition is a workaround, which seems to fix the problem (or at
- * least the symptom) in our tests. See
- * https://bugs.eclipse.org/bugs/show_bug.cgi?id=378846#c16
- */
- AbstractDTreeViewer viewer = treeViewerManager.getTreeViewer();
- if (viewer != null && viewer.getTree() != null && viewer.getTree().getTopItem() != null) {
- treeViewerManager.getControl().setFocus();
- }
- setEclipseWindowTitle();
-
// Resolve proxy model after aird reload.
DRepresentation representation = getRepresentation();
+ boolean representationProxyDetected = false;
if (representation != null && representation.eIsProxy() && session != null) {
+ representationProxyDetected = true;
IEditorInput editorInput = getEditorInput();
if (editorInput instanceof URIEditorInput) {
URIEditorInput sessionEditorInput = (URIEditorInput) editorInput;
@@ -475,12 +464,36 @@ public abstract class AbstractDTreeEditor extends EditorPart
}
checkSemanticAssociation();
+
+ if (representationProxyDetected) {
+ updateEditorAfterAirdResourceReload();
+ }
+ /*
+ * A regression in Kepler can cause an NPE inside the
+ * treeViewerManager.getControl().setFocus() below. The guard
+ * condition is a workaround, which seems to fix the problem (or at
+ * least the symptom) in our tests. See
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=378846#c16
+ */
+ AbstractDTreeViewer viewer = treeViewerManager.getTreeViewer();
+ if (viewer != null && viewer.getTree() != null && viewer.getTree().getTopItem() != null) {
+ treeViewerManager.getControl().setFocus();
+ }
+ setEclipseWindowTitle();
+
} else if (control != null) {
control.setFocus();
}
}
/**
+ * Update all needed editor elements after an Aird resource reload like
+ * {@link Tree} or {@link AbstractDTableViewerManager} referencing previous
+ * Aird elements as proxies.
+ */
+ protected abstract void updateEditorAfterAirdResourceReload();
+
+ /**
* Retrieve and set the representation from the given URI.
*
* @param uri
@@ -491,7 +504,10 @@ public abstract class AbstractDTreeEditor extends EditorPart
*/
protected abstract void setRepresentation(URI uri, boolean loadOnDemand);
- private void checkSemanticAssociation() {
+ /**
+ * Close this editor if root element has been removed.
+ */
+ protected void checkSemanticAssociation() {
DRepresentation representation = getRepresentation();
boolean shouldClose = representation == null || representation.eResource() == null;
if (!shouldClose && representation instanceof DSemanticDecorator) {

Back to the top