X-Git-Url: https://dev.e-taxonomy.eu/gitweb/taxeditor.git/blobdiff_plain/e9958b2a7e7d2bfcd011ee94bd9a36187942cf0c..66889a4215d74759957fbf7a08733210a5ebe7e1:/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/matrix/CharacterMatrix.java diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/matrix/CharacterMatrix.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/matrix/CharacterMatrix.java index b8ec197e1..17bd0adf7 100644 --- a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/matrix/CharacterMatrix.java +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/matrix/CharacterMatrix.java @@ -11,6 +11,7 @@ package eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix; import java.io.File; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -32,6 +33,8 @@ import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.di.UIEventTopic; import org.eclipse.e4.ui.di.UISynchronize; import org.eclipse.e4.ui.services.EMenuService; import org.eclipse.jface.layout.GridDataFactory; @@ -56,32 +59,26 @@ import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedList import org.eclipse.nebula.widgets.nattable.freeze.CompositeFreezeLayer; import org.eclipse.nebula.widgets.nattable.freeze.FreezeHelper; import org.eclipse.nebula.widgets.nattable.freeze.FreezeLayer; -import org.eclipse.nebula.widgets.nattable.grid.GridRegion; import org.eclipse.nebula.widgets.nattable.grid.command.ClientAreaResizeCommand; import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider; import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider; import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider; -import org.eclipse.nebula.widgets.nattable.grid.data.FixedSummaryRowHeaderLayer; import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer; import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer; import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer; import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer; +import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer; import org.eclipse.nebula.widgets.nattable.group.ColumnGroupGroupHeaderLayer; import org.eclipse.nebula.widgets.nattable.group.ColumnGroupHeaderLayer; import org.eclipse.nebula.widgets.nattable.group.ColumnGroupModel; import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer; -import org.eclipse.nebula.widgets.nattable.layer.CompositeLayer; import org.eclipse.nebula.widgets.nattable.layer.DataLayer; import org.eclipse.nebula.widgets.nattable.layer.ILayer; -import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator; import org.eclipse.nebula.widgets.nattable.persistence.gui.PersistenceDialog; import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer; import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer; import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration; -import org.eclipse.nebula.widgets.nattable.style.HorizontalAlignmentEnum; import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration; -import org.eclipse.nebula.widgets.nattable.summaryrow.FixedSummaryRowLayer; -import org.eclipse.nebula.widgets.nattable.summaryrow.SummaryRowLayer; import org.eclipse.nebula.widgets.nattable.tree.ITreeRowModel; import org.eclipse.nebula.widgets.nattable.tree.TreeLayer; import org.eclipse.nebula.widgets.nattable.tree.command.TreeExpandToLevelCommand; @@ -103,19 +100,28 @@ import ca.odell.glazedlists.SortedList; import ca.odell.glazedlists.TreeList; import eu.etaxonomy.cdm.api.application.CdmApplicationState; import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService; +import eu.etaxonomy.cdm.api.service.IOccurrenceService; +import eu.etaxonomy.cdm.api.service.UpdateResult; +import eu.etaxonomy.cdm.api.service.config.RemoveDescriptionsFromDescriptiveDataSetConfigurator; +import eu.etaxonomy.cdm.api.service.dto.FieldUnitDTO; import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO; import eu.etaxonomy.cdm.api.service.dto.SpecimenRowWrapperDTO; import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor; +import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.model.description.DescriptionBase; import eu.etaxonomy.cdm.model.description.DescriptiveDataSet; -import eu.etaxonomy.cdm.model.description.Feature; -import eu.etaxonomy.cdm.model.description.MeasurementUnit; -import eu.etaxonomy.cdm.model.term.TermNode; -import eu.etaxonomy.cdm.model.term.TermTree; +import eu.etaxonomy.cdm.model.description.SpecimenDescription; +import eu.etaxonomy.cdm.model.occurrence.FieldUnit; +import eu.etaxonomy.cdm.persistence.dto.DescriptiveDataSetBaseDto; +import eu.etaxonomy.cdm.persistence.dto.FeatureDto; import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper; import eu.etaxonomy.cdm.persistence.dto.TermDto; +import eu.etaxonomy.cdm.persistence.dto.TermNodeDto; +import eu.etaxonomy.cdm.persistence.dto.TermTreeDto; +import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache; import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin; import eu.etaxonomy.taxeditor.editor.l10n.Messages; +import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants; import eu.etaxonomy.taxeditor.model.MessagingUtils; import eu.etaxonomy.taxeditor.session.ICdmEntitySession; import eu.etaxonomy.taxeditor.store.CdmStore; @@ -155,11 +161,12 @@ public class CharacterMatrix extends Composite { private NatTable natTable; - private Collection> rowsToSave = new HashSet<>(); +// private Collection> rowsToSave = new HashSet<>(); + private HashMap> rowsToMerge = new HashMap<>(); - private Map indexToFeatureMap = new HashMap<>(); + private Map indexToFeatureMap = new HashMap<>(); - private Map> categoricalFeatureToStateMap = new HashMap<>(); + private Map> categoricalFeatureToStateMap = new HashMap<>(); private LinkedMap propertyToLabelMap = new LinkedMap<>(); @@ -167,22 +174,18 @@ public class CharacterMatrix extends Composite { private Collection specimenCache = null; - private Map featureToHistogramMap = new HashMap<>(); - - private Map featureToQuantDataStatisticsMap = new HashMap<>(); + private Map featureToHistogramMap = new HashMap<>(); private ListDataProvider bodyDataProvider; private FreezeLayer freezeLayer; - private List features; + private List features; private CharacterMatrixPart part; private AbstractLayer topMostLayer; - private FixedSummaryRowLayer summaryRowLayer; - private ConfigRegistry configRegistry; private MatrixBodyLayerStack bodyLayer; @@ -191,9 +194,15 @@ public class CharacterMatrix extends Composite { private CharacterMatrixToolbar toolbar; - private boolean isShowTooltips = true; - private DescriptionTreeFormat treeFormat; +// private List descriptionUuidsToDelete; + Map> descriptionUuidsToDelete; + + private List specimenToAdd; + + private MouseEventMatcher mouseEventMatcher = null; + + private Set descriptionsToSave = new HashSet<>(); public CharacterMatrix(Composite parent, CharacterMatrixPart part) { super(parent, SWT.NONE); @@ -204,7 +213,7 @@ public class CharacterMatrix extends Composite { natTable = new NatTable(this, false); - createBottomToolbar(); +// createBottomToolbar(); } @@ -220,7 +229,6 @@ public class CharacterMatrix extends Composite { private void applyStyles(){ ModernNatTableThemeConfiguration configuration = new ModernNatTableThemeConfiguration(); - configuration.summaryRowHAlign = HorizontalAlignmentEnum.CENTER; // NOTE: Getting the colors and fonts from the GUIHelper ensures that // they are disposed properly (required by SWT) configuration.cHeaderBgColor = GUIHelper.getColor(211, 211, 211); @@ -231,18 +239,19 @@ public class CharacterMatrix extends Composite { void toggleTreeFlat(boolean isTree, Button btnToggleFlat, Button btnToggleTree, Button btnCollapseAll, Button btnExpandAll, Button btnFreezeSuppInfo) { isTreeView = isTree; - createTable(isTree, freezeLayer.isFrozen()); + createTable(isTree, freezeLayer.isFrozen(), true); btnToggleFlat.setEnabled(isTree); btnToggleTree.setEnabled(!isTree); btnCollapseAll.setEnabled(isTree); btnExpandAll.setEnabled(isTree); + } public boolean isTreeView() { return isTreeView; } - public void createTable(boolean treeView, boolean freezeSupplementalColumns){ + public void createTable(boolean treeView, boolean freezeSupplementalColumns, boolean isInitialExpandToDeepestTaxonLevel){ /** * layers */ @@ -251,7 +260,8 @@ public class CharacterMatrix extends Composite { /** * configuration */ - configureNatTable(treeView, configRegistry, topMostLayer, summaryRowLayer); + + configureNatTable(treeView, configRegistry, topMostLayer); /** * handlers and listeners @@ -261,8 +271,8 @@ public class CharacterMatrix extends Composite { //grab all space GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable); - //update label to current data set - toolbar.getWsLabel().setText(getDescriptiveDataSet().getLabel()); + //update label to current dataset + toolbar.getWsLabel().setText(getDescriptiveDataSet().getTitleCache()); toolbar.getWsLabel().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); toolbar.getWsLabel().getParent().layout(); @@ -279,9 +289,11 @@ public class CharacterMatrix extends Composite { natTable.doCommand(new ClientAreaResizeCommand(natTable)); // expand all taxa - Integer deepestTaxonLevel = treeFormat.getDeepestTaxonLevel(); - if(deepestTaxonLevel!=null){ - natTable.doCommand(new TreeExpandToLevelCommand(deepestTaxonLevel-2)); + if(isInitialExpandToDeepestTaxonLevel){ + Integer deepestTaxonLevel = treeFormat.getDeepestTaxonLevel(); + if(deepestTaxonLevel!=null){ + natTable.doCommand(new TreeExpandToLevelCommand(deepestTaxonLevel-2)); + } } // clean up table state @@ -289,45 +301,65 @@ public class CharacterMatrix extends Composite { getNatTableState().remove(PersistenceDialog.ACTIVE_VIEW_CONFIGURATION_KEY); } - private List initFeatureList(TermNode node){ - List features = new ArrayList<>(); - node.getChildNodes().forEach(childNode-> - { - features.add(childNode.getTerm()); - features.addAll(initFeatureList(childNode)); - }); + private List initFeatureList(TermNodeDto node){ + List features = new ArrayList<>(); + List childNodes = node.getChildren(); + for (TermNodeDto childNode : childNodes) { + if (childNode != null){ + features.add((FeatureDto) childNode.getTerm()); + features.addAll(initFeatureList(childNode)); + } + } return features; } public void initDescriptiveDataSet(){ - //get features/columns stored in descriptive data set - TermTree tree = getDescriptiveDataSet().getDescriptiveSystem(); + //get features/columns stored in descriptive dataset + TermTreeDto tree = getDescriptiveDataSet().getDescriptiveSystem(); features = initFeatureList(tree.getRoot()); + Set duplicateFeatures = features.stream().filter(i -> Collections.frequency(features, i) >1) + .collect(Collectors.toSet()); + + if (!duplicateFeatures.isEmpty()) { + throw new IllegalArgumentException("Duplicate features found: " + + duplicateFeatures.stream().map(feature -> feature.getRepresentation_L10n()).collect(Collectors.joining(","))); + } + //init state data for categorical features - features.forEach(feature->fetchSupportedStates(feature)); +// features.forEach(feature->fetchSupportedStates(feature)); + fetchSupportedStates(features); descriptions = new BasicEventList<>(); } - private void fetchSupportedStates(Feature feature) { - List supportedStates = CdmStore.getService(IDescriptiveDataSetService.class).getSupportedStatesForFeature(feature.getUuid()); - categoricalFeatureToStateMap.put(feature, supportedStates); + private void fetchSupportedStates(List features) { + Set featureUuids = new HashSet<>(); + features.forEach(i->featureUuids.add(i.getUuid())); + categoricalFeatureToStateMap = CdmStore.getService(IDescriptiveDataSetService.class).getSupportedStatesForFeature(featureUuids); + } + + private void createLayers(boolean treeView) { + SortedList sortedList = new SortedList<>(descriptions, new MatrixRowComparator()); // wrap the SortedList with the TreeList treeFormat = new DescriptionTreeFormat(getDescriptiveDataSet()); TreeList treeList = new TreeList(sortedList, treeFormat, TreeList.NODES_START_COLLAPSED); + // wrap the SortedList with the TreeList +// treeFormat = new DescriptionTreeFormat(getDescriptiveDataSet()); + /** * data provider */ SpecimenColumnPropertyAccessor columnPropertyAccessor = new SpecimenColumnPropertyAccessor(this); bodyDataProvider = treeView?new ListDataProvider<>(treeList, columnPropertyAccessor):new ListDataProvider<>(sortedList, columnPropertyAccessor); - configRegistry = new ConfigRegistry(); + DataLayer bodyDataLayer = new DataLayer(bodyDataProvider); + bodyDataLayer.registerCommandHandler(new CopyPasteUpdateDataCommandHandler(bodyDataLayer)); /** @@ -335,11 +367,6 @@ public class CharacterMatrix extends Composite { * * - CompositeLayer - - (top) SummaryRowLayer - - (bottom) ViewportLayer - - ^ ViewportLayer ^ @@ -360,18 +387,14 @@ public class CharacterMatrix extends Composite { ^ ColumnHideShowLayer - ^ - ColumnReorderLayer - ^ DataLayer * */ - DataLayer bodyDataLayer = new DataLayer(bodyDataProvider); - bodyDataLayer.registerCommandHandler(new CopyPasteUpdateDataCommandHandler(bodyDataLayer)); + configRegistry = new ConfigRegistry(); //register labels CharacterMatrixConfigLabelAccumulator labelAccumulator = new CharacterMatrixConfigLabelAccumulator(this); bodyDataLayer.setConfigLabelAccumulator(labelAccumulator); @@ -382,7 +405,7 @@ public class CharacterMatrix extends Composite { propertyToLabelMap.put(IDENTIFIER_COLUMN, Messages.CharacterMatrix_IDENTIFIER); propertyToLabelMap.put(COUNTRY_COLUMN, Messages.CharacterMatrix_COUNTRY); for(int i=0;i columnGroups = new LinkedList<>(); - List> rootChildren = getDescriptiveDataSet().getDescriptiveSystem().getRootChildren(); + List rootChildren = getDescriptiveDataSet().getDescriptiveSystem().getRoot().getChildren(); buildHeader(rootChildren, columnGroups); bodyLayer = new MatrixBodyLayerStack(eventLayer, columnGroups); @@ -402,27 +425,12 @@ public class CharacterMatrix extends Composite { freezeLayer = new FreezeLayer(selectionLayer); final CompositeFreezeLayer compositeFreezeLayer = new CompositeFreezeLayer( freezeLayer, bodyLayer.getViewportLayer(), selectionLayer); - TreeLayer treeLayer = new TreeLayer(compositeFreezeLayer, treeRowModel); - - topMostLayer = treeView?treeLayer:compositeFreezeLayer; - - summaryRowLayer = new FixedSummaryRowLayer(bodyDataLayer, topMostLayer, configRegistry, false); - //regoster labels with summary prefix for summary layer - ColumnOverrideLabelAccumulator summaryColumnLabelAccumulator =new ColumnOverrideLabelAccumulator(bodyDataLayer); - summaryRowLayer.setConfigLabelAccumulator(summaryColumnLabelAccumulator); - for(int i=0;i, TreeSet> entry: groupLevel1.getColumnGroupToIndexMap().entrySet()) { - TermNode group = entry.getKey(); + for (Entry> entry: groupLevel1.getColumnGroupToIndexMap().entrySet()) { + TermNodeDto group = entry.getKey(); TreeSet indexList = entry.getValue(); int[] intArray = indexList.stream().mapToInt(Integer::intValue).toArray(); groupLayerLevel1.addColumnsIndexesToGroup(group.getTerm().getTitleCache(), intArray); @@ -454,8 +462,8 @@ public class CharacterMatrix extends Composite { if(columnGroups.size()>1){ ColumnGroupWrapper groupLevel2 = columnGroups.get(1); groupLayerLevel2 = new ColumnGroupGroupHeaderLayer(groupLayerLevel1, selectionLayer, groupLevel2.getModel()); - for (Entry, TreeSet> entry: groupLevel2.getColumnGroupToIndexMap().entrySet()) { - TermNode group = entry.getKey(); + for (Entry> entry: groupLevel2.getColumnGroupToIndexMap().entrySet()) { + TermNodeDto group = entry.getKey(); TreeSet indexList = entry.getValue(); int[] intArray = indexList.stream().mapToInt(Integer::intValue).toArray(); groupLayerLevel2.addColumnsIndexesToGroup(group.getTerm().getTitleCache(), intArray); @@ -483,9 +491,8 @@ public class CharacterMatrix extends Composite { */ IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider); DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider); - FixedSummaryRowHeaderLayer fixedSummaryRowHeaderLayer = new FixedSummaryRowHeaderLayer(rowHeaderDataLayer, - composite, selectionLayer); - fixedSummaryRowHeaderLayer.setSummaryRowLabel("\u2211"); //$NON-NLS-1$ + RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, + topMostLayer, selectionLayer); /** @@ -493,40 +500,44 @@ public class CharacterMatrix extends Composite { */ ILayer cornerLayer = new CornerLayer( new DataLayer(new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider)), - fixedSummaryRowHeaderLayer, sortHeaderLayer); + rowHeaderLayer, sortHeaderLayer); /** * GRID layer (composition of all other layers) */ - GridLayer gridLayer = new GridLayer(composite, sortHeaderLayer, fixedSummaryRowHeaderLayer, cornerLayer); + GridLayer gridLayer = new GridLayer(topMostLayer, sortHeaderLayer, rowHeaderLayer, cornerLayer); natTable.setLayer(gridLayer); } - private TreeSet recurseChildIndexes(TermNode node){ + private TreeSet recurseChildIndexes(TermNodeDto node){ TreeSet childIndexes = new TreeSet<>(); - if(node.getChildCount()>0){ - List> childNodes = node.getChildNodes(); - for (TermNode childNode: childNodes) { - childIndexes.addAll(recurseChildIndexes(childNode)); + if(node.getChildren().size() >0){ + List childNodes = node.getChildren(); + for (TermNodeDto childNode: childNodes) { + if (childNode != null){ + childIndexes.addAll(recurseChildIndexes(childNode)); + } } } childIndexes.add(features.indexOf(node.getTerm())+LEADING_COLUMN_COUNT); return childIndexes; } - private void buildHeader(List> nodes, LinkedList columnGroups){ - Map, TreeSet> columnGroupToIndexMap = new HashMap<>(); - List> childNodes = new ArrayList<>(); - for (TermNode node : nodes) { - TreeSet childIndexes = recurseChildIndexes(node); - if(childIndexes.size()>1){ - // filter out groups that only have one member - columnGroupToIndexMap.put(node, childIndexes); + private void buildHeader(List nodes, LinkedList columnGroups){ + Map> columnGroupToIndexMap = new HashMap<>(); + List childNodes = new ArrayList<>(); + for (TermNodeDto node : nodes) { + if (node != null){ + TreeSet childIndexes = recurseChildIndexes(node); + if(childIndexes.size()>1){ + // filter out groups that only have one member + columnGroupToIndexMap.put(node, childIndexes); + } + childNodes.addAll(node.getChildren()); } - childNodes.addAll(node.getChildNodes()); } if(!columnGroupToIndexMap.isEmpty()){ columnGroups.addFirst(new ColumnGroupWrapper(new ColumnGroupModel(), columnGroupToIndexMap)); @@ -557,11 +568,15 @@ public class CharacterMatrix extends Composite { private void configureNatTable(boolean treeView, ConfigRegistry configRegistry, - AbstractLayer topMostLayer, - FixedSummaryRowLayer summaryRowLayer) { + AbstractLayer topMostLayer) { /** * CONFIGURATION */ + //+++CONTEXT MENU+++ + menuService.registerContextMenu(natTable, "eu.etaxonomy.taxeditor.editor.popupmenu.charactermatrix"); //$NON-NLS-1$ + // get the menu registered by EMenuService + final Menu e4Menu = natTable.getMenu(); + natTable.setConfigRegistry(configRegistry); applyStyles(); @@ -570,7 +585,7 @@ public class CharacterMatrix extends Composite { natTable.addConfiguration(new DefaultNatTableStyleConfiguration()); // this is for DEBUG ONLY - // natTable.addConfiguration(new DebugMenuConfiguration(natTable)); +// natTable.addConfiguration(new DebugMenuConfiguration(natTable)); // override the default sort configuration and change the mouse bindings // to sort on a single click @@ -582,78 +597,91 @@ public class CharacterMatrix extends Composite { // add the header menu configuration for adding the column header menu // with hide/show actions - natTable.addConfiguration(new CharacterMatrixHeaderMenuConfiguration(natTable)); +// natTable.addConfiguration(new CharacterMatrixHeaderMenuConfiguration(natTable)); // add custom configuration for data conversion and add column labels to viewport layer topMostLayer.addConfiguration(new CellEditorDataConversionConfiguration(this)); - //register aggregation configuration - summaryRowLayer.addConfiguration(new AggregationConfiguration(this)); - //copy&paste configuration natTable.addConfiguration(new CopyPasteEditBindings(bodyLayer.getSelectionLayer(), natTable.getInternalCellClipboard())); - //+++CONTEXT MENU+++ - menuService.registerContextMenu(natTable, "eu.etaxonomy.taxeditor.editor.popupmenu.charactermatrix"); //$NON-NLS-1$ - // get the menu registered by EMenuService - final Menu e4Menu = natTable.getMenu(); + // remove the menu reference from NatTable instance natTable.setMenu(null); + + +// natTable.addConfiguration(new CharacterMatrixHeaderMenuConfiguration(natTable)); + + + natTable.configure(); + + natTable.addConfiguration( - new AbstractUiBindingConfiguration() { - @Override - public void configureUiBindings( - UiBindingRegistry uiBindingRegistry) { - // add e4 menu to NatTable - new PopupMenuBuilder(natTable, e4Menu) + new AbstractUiBindingConfiguration() { + @Override + public void configureUiBindings( + UiBindingRegistry uiBindingRegistry) { + // add e4 menu to NatTable + + + uiBindingRegistry.unregisterMouseDownBinding(mouseEventMatcher); + new PopupMenuBuilder(natTable, e4Menu) + .withHideColumnMenuItem() + .withShowAllColumnsMenuItem() .build(); - // register the UI binding for header, corner and body region - uiBindingRegistry.registerMouseDownBinding( - new MouseEventMatcher( - SWT.NONE, - null, - MouseEventMatcher.RIGHT_BUTTON), - new PopupMenuAction(e4Menu)); - } - }); + // register the UI binding for header, corner and body region + mouseEventMatcher = new MouseEventMatcher( + SWT.NONE, + null, + MouseEventMatcher.RIGHT_BUTTON); + uiBindingRegistry.registerMouseDownBinding(mouseEventMatcher, + new PopupMenuAction(e4Menu)); + } + }); - natTable.configure(); } void freezeSupplementalColumns(boolean freeze){ + int rightMostFreezeColumIndex = LEADING_COLUMN_COUNT-1; + Collection hiddenColumnIndexes = bodyLayer.getColumnHideShowLayer().getHiddenColumnIndexes(); + for (Integer integer : hiddenColumnIndexes) { + if(integer recommendedMeasurementUnits = feature.getRecommendedMeasurementUnits(); - if(recommendedMeasurementUnits.size()>1){ - MessagingUtils.warningDialog(Messages.CharacterMatrix_INIT_PROBLEM, CharacterMatrix.class, - String.format(Messages.CharacterMatrix_INIT_PROBLEM_MESSAGE, feature.getLabel())); - } + Set recommendedMeasurementUnits = feature.getRecommendedMeasurementUnits(); +// if(recommendedMeasurementUnits.size()>1){ +// MessagingUtils.warningDialog(Messages.CharacterMatrix_INIT_PROBLEM, CharacterMatrix.class, +// String.format(Messages.CharacterMatrix_INIT_PROBLEM_MESSAGE, feature.getLabel())); +// } if(recommendedMeasurementUnits.size()==1){ - MeasurementUnit unit = recommendedMeasurementUnits.iterator().next(); + TermDto unit = recommendedMeasurementUnits.iterator().next(); label += " ["+unit.getIdInVocabulary()+"]"; //$NON-NLS-1$ //$NON-NLS-2$ } } propertyToLabelMap.put(property, label); } - public void loadDescriptions(UUID descriptiveDataSetUuid) { - UUID monitorUuid = CdmApplicationState.getLongRunningTasksService().monitGetRowWrapper(descriptiveDataSetUuid); + public void loadDescriptions(boolean isInitialExpandToDeepestTaxonLevel, boolean initialLoading) { + UUID monitorUuid = CdmApplicationState.getLongRunningTasksService().monitGetRowWrapper(this.getDescriptiveDataSet().getUuid()); final Collection wrappers = new ArrayList<>(); String jobLabel = Messages.CharacterMatrix_LOAD_CHARACTER_DATA; @@ -704,7 +732,10 @@ public class CharacterMatrix extends Composite { } descriptions.clear(); wrappers.stream().filter(row->row.getTaxonNode()!=null).forEach(wrapper->CharacterMatrix.this.descriptions.add(wrapper)); - loadingDone(); + if(initialLoading){ + loadingDone(isInitialExpandToDeepestTaxonLevel); + } + }); } }); @@ -722,16 +753,25 @@ public class CharacterMatrix extends Composite { return new StructuredSelection(selectedObjects); } - private void loadingDone() { + private void loadingDone(boolean isInitialExpandToDeepestTaxonLevel) { this.part.loadingDone(); - createTable(isTreeView, freezeLayer.isFrozen()); + createTable(isTreeView, freezeLayer.isFrozen(), isInitialExpandToDeepestTaxonLevel); + + } + + public List getSupportedStatesForCategoricalFeature(UUID featureUuid){ + return categoricalFeatureToStateMap.get(featureUuid); } - public List getSupportedStatesForCategoricalFeature(Feature feature){ - return categoricalFeatureToStateMap.get(feature); + public Set getDescriptionsToSave() { + return descriptionsToSave; } - public Map getIndexToFeatureMap() { + public void addDescriptionToSave(DescriptionBase descriptionToSave) { + this.descriptionsToSave.add(descriptionToSave); + } + + public Map getIndexToFeatureMap() { return indexToFeatureMap; } @@ -743,6 +783,46 @@ public class CharacterMatrix extends Composite { part.setDirty(); } + public Map> getDescriptionsToDelete() { + return descriptionUuidsToDelete; + } + + public void addDescriptionToDelete(UUID descriptionToDelete, RemoveDescriptionsFromDescriptiveDataSetConfigurator config) { + if (descriptionUuidsToDelete == null){ + descriptionUuidsToDelete = new HashMap<>(); + } + if (descriptionUuidsToDelete.get(config) != null){ + descriptionUuidsToDelete.get(config).add(descriptionToDelete); + }else{ + List uuidList = new ArrayList<>(); + uuidList.add(descriptionToDelete); + this.descriptionUuidsToDelete.put(config, uuidList); + } + + + } + + public List getSpecimenToAdd() { + return specimenToAdd; + } + + public void addSpecimenToAdd(Collection specimenToAdd) { + if (this.specimenToAdd == null){ + this.specimenToAdd = new ArrayList(); + } + + this.specimenToAdd.addAll(specimenToAdd); + this.specimenCache.removeAll(specimenToAdd); + } + public void addSpecimenToAdd(SpecimenRowWrapperDTO specimenToAdd) { + if (this.specimenToAdd == null){ + this.specimenToAdd = new ArrayList(); + } + + this.specimenToAdd.add(specimenToAdd); + this.specimenCache.remove(specimenToAdd); + } + public CharacterMatrixPart getPart() { return part; } @@ -755,16 +835,16 @@ public class CharacterMatrix extends Composite { return descriptions; } - public DescriptiveDataSet getDescriptiveDataSet() { + public DescriptiveDataSetBaseDto getDescriptiveDataSet() { return part.getDescriptiveDataSet(); } - public void setDescriptiveDataSet(DescriptiveDataSet dataSet) { + public void setDescriptiveDataSet(DescriptiveDataSetBaseDto dataSet) { part.setDescriptiveDataSet(dataSet); } public Collection getSpecimenCache() { - return specimenCache; + return specimenCache; } public void setSpecimenCache(Collection specimenCache) { @@ -773,7 +853,7 @@ public class CharacterMatrix extends Composite { //map descriptions on a list of uuids of the described specimen !this.descriptions.stream() .filter(rowWrapper->rowWrapper instanceof SpecimenRowWrapperDTO) - .map(specimenRowWrapper->((SpecimenRowWrapperDTO) specimenRowWrapper).getSpecimen().getUuid()) + .map(specimenRowWrapper->((SpecimenRowWrapperDTO) specimenRowWrapper).getSpecimenDto().getUuid()) .collect(Collectors.toList()) //and check if the specimen to add is already contained .contains(wrapper.getUuidAndTitleCache().getUuid()) @@ -781,12 +861,23 @@ public class CharacterMatrix extends Composite { .collect(Collectors.toList()); } - public void addRowToSave(RowWrapperDTO row){ - rowsToSave.add(row); +// public void addRowToSave(RowWrapperDTO row){ +// rowsToMerge.put(row.getDescription().getDescription().getUuid(), row); +// } +// +// public HashMap> getRowsToSave() { +// return rowsToMerge; +// } + + public HashMap> getRowsToMerge() { + return rowsToMerge; } - public Collection> getRowsToSave() { - return rowsToSave; + public void putRowToMerge(RowWrapperDTO rowToMerge) { + if (this.rowsToMerge == null){ + this.rowsToMerge = new HashMap<>(); + } + this.rowsToMerge.put(rowToMerge.getDescription().getDescriptionUuid(), rowToMerge); } public Properties getNatTableState() { @@ -805,28 +896,132 @@ public class CharacterMatrix extends Composite { return new File(WorkbenchUtility.getBaseLocation(), CHARACTER_MATRIX_STATE_PROPERTIES); } - public List getFeatures() { + public List getFeatures() { return features; } - public Map getFeatureToHistogramMap() { + public Map getFeatureToHistogramMap() { return featureToHistogramMap; } - public Map getFeatureToQuantDataStatisticsMap() { - return featureToQuantDataStatisticsMap; + + + public ICdmEntitySession getCdmEntitiySession(){ + return part.getCdmEntitySession(); + } + + @Inject + @Optional + private void updateSpecimenList(@UIEventTopic(WorkbenchEventConstants.REFRESH_DESCRIPTIVE_DATASET)UUID uuid){ + if(uuid!= null && uuid.equals(part.getDescriptiveDataSet().getUuid())){ + this.specimenCache = null; + + } } - public void toogleIsShowTooltips() { - this.isShowTooltips = !this.isShowTooltips; + public void addRowsToMatrix(Collection wrappers){ + + List specimenUuids = new ArrayList(); + wrappers.forEach(wrapper -> specimenUuids.add(wrapper.getUuidAndTitleCache().getUuid())); +// List specimens = CdmStore.getService(IOccurrenceService.class).load(specimenUuids, null); + Map> specimenMap = new HashMap(); + + for (UUID specimenUuid: specimenUuids ){ + try{ + FieldUnitDTO fieldUnitDto = CdmStore.getService(IOccurrenceService.class).loadFieldUnitDTO(specimenUuid); + if (fieldUnitDto != null){ + UuidAndTitleCache fieldUnit = new UuidAndTitleCache(FieldUnit.class, fieldUnitDto.getUuid(), null, fieldUnitDto.getLabel()); + specimenMap.put(specimenUuid, fieldUnit); + } + }catch(Exception e){ + e.printStackTrace(); + } + + } + for (SpecimenNodeWrapper wrapper: wrappers){ + SpecimenRowWrapperDTO rowWrapper = CdmStore.getService(IDescriptiveDataSetService.class).createSpecimenRowWrapper(wrapper.getUuidAndTitleCache().getUuid(), wrapper.getTaxonNode().getUuid(), getDescriptiveDataSet().getUuid()); + addSpecimenToAdd(rowWrapper); +// SpecimenRowWrapperDTO rowWrapper = new SpecimenRowWrapperDTO(wrapper.getUuidAndTitleCache(), wrapper.getType(), wrapper.getTaxonNode(), specimenMap.get(wrapper.getUuidAndTitleCache().getUuid()), null, null); + descriptions.add(rowWrapper); + } + + + setDirty(); } - public boolean isShowTooltips() { - return isShowTooltips; + public HashMap addSpecimensToDescriptiveDataSet(){ + if (specimenToAdd == null || specimenToAdd.isEmpty()){ + return new HashMap<>(); + } + UpdateResult result = CdmStore.getService(IDescriptiveDataSetService.class).addRowWrapperToDataset(specimenToAdd, getDescriptiveDataSet().getUuid()); + if(!result.getExceptions().isEmpty()){ + MessagingUtils.warningDialog(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_TITLE, this, + String.format(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_MESSAGE, result.getExceptions() + .stream().map(ex->ex.toString()) + .collect(Collectors.joining("\n")))); + } + DescriptiveDataSet dataSet = (DescriptiveDataSet) result.getCdmEntity(); + HashMap resultMap = new HashMap<>(); + for (CdmBase updated: result.getUpdatedObjects()){ + if (updated instanceof SpecimenDescription){ + resultMap.put(updated.getUuid(), (DescriptionBase)updated); + } + + + } + dataSet = this.getCdmEntitiySession().load(dataSet, true); + // update local dataset + DescriptiveDataSetBaseDto dto = DescriptiveDataSetBaseDto.fromDescriptiveDataSet(dataSet); + this.setDescriptiveDataSet(dto); + + //these descriptions are already updated + for (SpecimenRowWrapperDTO row: specimenToAdd){ + this.rowsToMerge.remove(row.getDescription().getDescriptionUuid()); + } + specimenToAdd.clear(); + return resultMap; + } - public ICdmEntitySession getCdmEntitiySession(){ - return part.getCdmEntitySession(); + @Inject + @Optional + private void updateView(@UIEventTopic(WorkbenchEventConstants.ADD_TO_MERGE_ROWS) UUID uuid) { + + } + + @Override + public void dispose () { + super.dispose(); + descriptions.dispose(); + descriptions = null; + this.natTable.dispose(); + this.natTable = null; + categoricalFeatureToStateMap = null; + rowsToMerge.clear(); + rowsToMerge = null; + indexToFeatureMap = null; + propertyToLabelMap = null; + specimenCache = null; + featureToHistogramMap = null; + bodyDataProvider = null; + freezeLayer = null; + features = null; + topMostLayer.dispose(); + topMostLayer = null; + configRegistry = null; + bodyLayer.dispose(); + bodyLayer = null; + toolbar.dispose(); + toolbar = null; + treeFormat = null; + descriptionUuidsToDelete = null; + specimenToAdd = null; + mouseEventMatcher = null; + descriptionsToSave = null; + menuService = null; + sync = null; + part = null; + } }