diff options
Diffstat (limited to 'plugins/infra/nattable/org.eclipse.papyrus.infra.nattable/src/org/eclipse/papyrus/infra/nattable/provider/PasteEObjectTreeAxisInNattableCommandProvider.java')
-rw-r--r-- | plugins/infra/nattable/org.eclipse.papyrus.infra.nattable/src/org/eclipse/papyrus/infra/nattable/provider/PasteEObjectTreeAxisInNattableCommandProvider.java | 663 |
1 files changed, 356 insertions, 307 deletions
diff --git a/plugins/infra/nattable/org.eclipse.papyrus.infra.nattable/src/org/eclipse/papyrus/infra/nattable/provider/PasteEObjectTreeAxisInNattableCommandProvider.java b/plugins/infra/nattable/org.eclipse.papyrus.infra.nattable/src/org/eclipse/papyrus/infra/nattable/provider/PasteEObjectTreeAxisInNattableCommandProvider.java index eff5b124c5b..ae1afe0fd07 100644 --- a/plugins/infra/nattable/org.eclipse.papyrus.infra.nattable/src/org/eclipse/papyrus/infra/nattable/provider/PasteEObjectTreeAxisInNattableCommandProvider.java +++ b/plugins/infra/nattable/org.eclipse.papyrus.infra.nattable/src/org/eclipse/papyrus/infra/nattable/provider/PasteEObjectTreeAxisInNattableCommandProvider.java @@ -38,7 +38,6 @@ import org.eclipse.emf.ecore.EFactory; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.workspace.EMFCommandOperation; import org.eclipse.gmf.runtime.common.core.command.CommandResult; @@ -56,7 +55,6 @@ import org.eclipse.papyrus.infra.nattable.Activator; import org.eclipse.papyrus.infra.nattable.manager.cell.CellManagerFactory; import org.eclipse.papyrus.infra.nattable.manager.table.INattableModelManager; import org.eclipse.papyrus.infra.nattable.messages.Messages; -import org.eclipse.papyrus.infra.nattable.model.nattable.NattablePackage; import org.eclipse.papyrus.infra.nattable.model.nattable.Table; import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.AbstractHeaderAxisConfiguration; import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.IAxisConfiguration; @@ -69,7 +67,6 @@ import org.eclipse.papyrus.infra.nattable.parsers.CSVParser; import org.eclipse.papyrus.infra.nattable.parsers.CellIterator; import org.eclipse.papyrus.infra.nattable.parsers.RowIterator; import org.eclipse.papyrus.infra.nattable.paste.IValueSetter; -import org.eclipse.papyrus.infra.nattable.paste.PastePostActionRegistry; import org.eclipse.papyrus.infra.nattable.utils.AxisConfigurationUtils; import org.eclipse.papyrus.infra.nattable.utils.CSVPasteHelper; import org.eclipse.papyrus.infra.nattable.utils.Constants; @@ -92,21 +89,12 @@ import org.eclipse.ui.progress.UIJob; */ // TODO : refactor me to create common ancestor with normal paste // TODO : refactor me : This class should be in oep.infra.emf.nattable +// TODO Nicolas FAUVERGUE : This class must be refactor because the detached mode and the attached mode have some duplicated code. public class PasteEObjectTreeAxisInNattableCommandProvider { private static final int MIN_AXIS_FOR_PROGRESS_MONITOR = 5; /** - * the containment feature to use - */ - private EStructuralFeature containmentFeature; - - /** - * the type to create - */ - private IElementType typeToCreate; - - /** * the table manager */ private INattableModelManager tableManager; @@ -139,7 +127,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { /** * the converter map */ - private Map<Class<? extends AbstractStringValueConverter>, AbstractStringValueConverter> existingConverters; + private final Map<Class<? extends AbstractStringValueConverter>, AbstractStringValueConverter> existingConverters; private static final String PASTE_ACTION_TASK_NAME = Messages.PasteEObjectAxisInTableCommandProvider_PasteAction; @@ -159,9 +147,14 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { private final int nbOperationsToDo; + /** + * The character of the indentation for the single column. + */ + private static final char INDENTATION_CHARACTER = ' '; // $NON-NLS-1$ + // we refresh the dialog each X read char - private int refreshEachReadChar = 1000; + private final int refreshEachReadChar = 1000; /** * if <code>true</code> the command can't be created and executed @@ -176,11 +169,11 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { /** * the parser to use */ - private CSVParser parser; + private final CSVParser parser; int factor; - private Table table; + private final Table table; final TransactionalEditingDomain tableEditingDomain; @@ -195,11 +188,25 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { */ private final boolean isSingleHeaderColumnTreeTable; - public PasteEObjectTreeAxisInNattableCommandProvider(INattableModelManager tableManager, boolean pasteColumn, Reader reader, CSVPasteHelper pasteHelper2, long totalSize) { + /** + * Constructor. + * + * @param tableManager + * The table manager. + * @param pasteColumn + * Boolean to determinate if the column are pasted. + * @param reader + * The reader of the pasted text. + * @param pasteHelper + * The paste helper. + * @param totalSize + * The total size of element pasted. + */ + public PasteEObjectTreeAxisInNattableCommandProvider(final INattableModelManager tableManager, final boolean pasteColumn, final Reader reader, final CSVPasteHelper pasteHelper, final long totalSize) { this.tableManager = tableManager; // this.pasteMode = status; this.existingConverters = new HashMap<Class<? extends AbstractStringValueConverter>, AbstractStringValueConverter>(); - this.pasteHelper = pasteHelper2; + this.pasteHelper = pasteHelper; this.reader = reader; this.pasteColumn = pasteColumn; this.table = tableManager.getTable(); @@ -224,50 +231,65 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { init(); } - protected List<IPasteConfiguration> getPasteConfigurationFor(int depth) { - List<IPasteConfiguration> pasteConfs = new ArrayList<IPasteConfiguration>(); - for (TreeFillingConfiguration current : FillingConfigurationUtils.getAllTreeFillingConfiguration(table)) { + /** + * Get the paste configuration for the depth. + * + * @param depth + * The depth searched. + * @return The paste configuration for the depth. + */ + protected List<IPasteConfiguration> getPasteConfigurationFor(final int depth) { + final List<IPasteConfiguration> pasteConfs = new ArrayList<IPasteConfiguration>(); + if (depth == 0 && FillingConfigurationUtils.hasTreeFillingConfigurationForDepth(table, depth)) { + final IPasteConfiguration conf = (IPasteConfiguration) AxisConfigurationUtils.getIAxisConfigurationUsedInTable(tableManager.getTable(), NattableaxisconfigurationPackage.eINSTANCE.getPasteEObjectConfiguration(), false); + pasteConfs.add(conf); + } + for (final TreeFillingConfiguration current : FillingConfigurationUtils.getAllTreeFillingConfiguration(table)) { if (current.getDepth() == depth) { - IPasteConfiguration pasteConf = current.getPasteConfiguration(); + final IPasteConfiguration pasteConf = current.getPasteConfiguration(); Assert.isNotNull(pasteConf);// must not be null here! (so must be verified before pasteConfs.add(pasteConf); } } - if (depth == 0 && pasteConfs.size() == 0 && FillingConfigurationUtils.hasTreeFillingConfigurationForDepth(table, depth)) { - final IPasteConfiguration conf = (IPasteConfiguration) AxisConfigurationUtils.getIAxisConfigurationUsedInTable(tableManager.getTable(), NattableaxisconfigurationPackage.eINSTANCE.getPasteEObjectConfiguration(), false); - pasteConfs.add(conf); - } return pasteConfs; } - - protected IPasteConfiguration getPasteConfigurationsFor(int depth, String categoryName) { + /** + * Get the paste configuration for the depth and the category name. + * + * @param depth + * The depth searched. + * @param categoryName + * The category name searched. + * @returnThe paste configuration for the depth and the category name. + */ + protected IPasteConfiguration getPasteConfigurationsFor(final int depth, final String categoryName) { if (depth == 0 && !FillingConfigurationUtils.hasTreeFillingConfigurationForDepth(table, 0)) { AbstractHeaderAxisConfiguration conf = table.getLocalRowHeaderAxisConfiguration(); if (conf != null) { conf = table.getTableConfiguration().getRowHeaderAxisConfiguration(); } - List<TreeFillingConfiguration> filling = FillingConfigurationUtils.getAllTreeFillingConfigurationForDepth(table, depth); - List<IAxisConfiguration> referencedPasteConf = new ArrayList<IAxisConfiguration>(); - for (TreeFillingConfiguration tmp : filling) { + final List<TreeFillingConfiguration> filling = FillingConfigurationUtils.getAllTreeFillingConfigurationForDepth(table, depth); + final List<IAxisConfiguration> referencedPasteConf = new ArrayList<IAxisConfiguration>(); + for (final TreeFillingConfiguration tmp : filling) { if (tmp.getPasteConfiguration() != null) { referencedPasteConf.add(tmp.getPasteConfiguration()); } } - for (IAxisConfiguration axisConf : conf.getOwnedAxisConfigurations()) { + for (final IAxisConfiguration axisConf : conf.getOwnedAxisConfigurations()) { if (axisConf instanceof IPasteConfiguration && !referencedPasteConf.contains(axisConf)) { return (IPasteConfiguration) axisConf; } } } - for (TreeFillingConfiguration curr : FillingConfigurationUtils.getAllTreeFillingConfiguration(table)) { + for (final TreeFillingConfiguration curr : FillingConfigurationUtils.getAllTreeFillingConfiguration(table)) { if (curr.getDepth() == depth) { if (categoryName == null || categoryName.isEmpty()) { return curr.getPasteConfiguration(); } else { String featureName = curr.getAxisUsedAsAxisProvider().getAlias(); if (featureName == null || "".equals(featureName)) { - Object element = curr.getAxisUsedAsAxisProvider().getElement(); + final Object element = curr.getAxisUsedAsAxisProvider().getElement(); // TODO : doesn't work for stereotype propertyes // TODO : use label provider if (element instanceof EStructuralFeature) { @@ -275,7 +297,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { } } if (categoryName.equals(featureName)) { - return (IPasteConfiguration) curr.getPasteConfiguration(); + return curr.getPasteConfiguration(); } } @@ -285,9 +307,16 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { return null; } - protected boolean pasteInDetachedMode(Table table) { - List<IPasteConfiguration> confs = getPasteConfigurationFor(0); - for (IPasteConfiguration current : confs) { + /** + * Returns <code>true</code> if the configuration is in the detached mode, <code>false</code> otherwise. + * + * @param table + * The table. + * @return <code>true</code> if the configuration is in the detached mode, <code>false</code> otherwise. + */ + protected boolean isPasteInDetachedMode(final Table table) { + final List<IPasteConfiguration> confs = getPasteConfigurationFor(0); + for (final IPasteConfiguration current : confs) { if (current.isDetachedMode()) { return true; } @@ -295,34 +324,24 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { return false; } - /** - * inits the field of this class + * Initialize the fields of this class. */ private void init() { - this.detachedMode = pasteInDetachedMode(table); - // PasteEObjectConfiguration configuration = null; - // if (this.pasteColumn) { - // configuration = (PasteEObjectConfiguration) AxisConfigurationUtils.getIAxisConfigurationUsedInTable(this.table, NattableaxisconfigurationPackage.eINSTANCE.getPasteEObjectConfiguration(), true); - // this.secondAxis = tableManager.getRowElementsList(); - // } else { - // - // configuration = (PasteEObjectConfiguration) AxisConfigurationUtils.getIAxisConfigurationUsedInTable(this.table, NattableaxisconfigurationPackage.eINSTANCE.getPasteEObjectConfiguration(), false); + final boolean bool = isPasteInDetachedMode(this.table); + final PasteEObjectConfiguration configuration = (PasteEObjectConfiguration) AxisConfigurationUtils.getIAxisConfigurationUsedInTable(this.table, NattableaxisconfigurationPackage.eINSTANCE.getPasteEObjectConfiguration(), false); this.secondAxis = tableManager.getColumnElementsList(); - // } - // if (configuration != null) { - // this.containmentFeature = configuration.getPasteElementContainementFeature(); - // this.typeToCreate = ElementTypeRegistry.getInstance().getType(configuration.getPastedElementId()); - // this.postActions = configuration.getPostActions(); - // this.detachedMode = configuration.isDetachedMode(); - // } + if (configuration != null) { + this.postActions = configuration.getPostActions(); + this.detachedMode = configuration.isDetachedMode(); + } } /** + * This allows to execute the paste from string command. * * @param useProgressMonitor * boolean indicating that we must do the paste with a progress monitor - * TODO : post actions are not yet supported in the in the detached mode */ public void executePasteFromStringCommand(final boolean useProgressMonitor) { // if (this.pasteColumn) {// not yet supported @@ -337,18 +356,21 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { // } else { pasteJobName = PASTE_ROWS_JOB_NAME; // } - // if (this.detachedMode) { - // executePasteFromStringCommandInDetachedMode(useProgressMonitor, pasteJobName); - // } else { - executePasteFromStringCommandInAttachedMode(useProgressMonitor, pasteJobName); - // } + if (this.detachedMode) { + executePasteFromStringCommandInDetachedMode(useProgressMonitor, pasteJobName); + } else { + executePasteFromStringCommandInAttachedMode(useProgressMonitor, pasteJobName); + } } /** - * + * This allows to execute the paste from String command in the detached mode. + * * @param useProgressMonitor - * boolean indicating that we must do the paste with a progress monitor + * boolean indicating that we must do the paste with a progress monitor. + * @param pasteJobName + * The name of the paste job. */ private void executePasteFromStringCommandInDetachedMode(final boolean useProgressMonitor, final String pasteJobName) { // the map used to share objects between the paste action and the cell value managers @@ -367,7 +389,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { final ICommand pasteCommand = getPasteFromStringCommandInDetachedMode(contextEditingDomain, tableEditingDomain, new NullProgressMonitor(), sharedMap); try { CheckedOperationHistory.getInstance().execute(pasteCommand, new NullProgressMonitor(), null); - } catch (ExecutionException e) { + } catch (final ExecutionException e) { Activator.log.error(e); } sharedMap.clear(); @@ -376,7 +398,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { final UIJob job = new UIJob(pasteJobName) { @Override - public IStatus runInUIThread(IProgressMonitor monitor) { + public IStatus runInUIThread(final IProgressMonitor monitor) { final ICommand pasteCommand = getPasteFromStringCommandInDetachedMode(contextEditingDomain, tableEditingDomain, monitor, sharedMap); if (pasteCommand == null) { @@ -386,7 +408,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { if (pasteCommand.canExecute()) { try { CheckedOperationHistory.getInstance().execute(pasteCommand, monitor, null); - } catch (ExecutionException e) { + } catch (final ExecutionException e) { return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "An exception occured during the paste", e); //$NON-NLS-1$ } finally { sharedMap.clear(); @@ -405,16 +427,19 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { } /** + * This allows to execute the paste from String command in the attached mode. * * @param useProgressMonitor * boolean indicating that we must do the paste with a progress monitor + * @param pasteJobName + * The name of the paste job. */ private void executePasteFromStringCommandInAttachedMode(final boolean useProgressMonitor, final String pasteJobName) { if (!useProgressMonitor) { final ICommand pasteCommand = getPasteFromStringCommandInAttachedMode(contextEditingDomain, tableEditingDomain, new NullProgressMonitor()); try { CheckedOperationHistory.getInstance().execute(pasteCommand, new NullProgressMonitor(), null); - } catch (ExecutionException e) { + } catch (final ExecutionException e) { Activator.log.error(e); } } else { @@ -422,7 +447,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { final UIJob job = new UIJob(pasteJobName) { @Override - public IStatus runInUIThread(IProgressMonitor monitor) { + public IStatus runInUIThread(final IProgressMonitor monitor) { final ICommand pasteCommand = getPasteFromStringCommandInAttachedMode(contextEditingDomain, tableEditingDomain, monitor); if (pasteCommand == null) { @@ -433,10 +458,10 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { try { - EMFCommandOperation op = new EMFCommandOperation(contextEditingDomain, new GMFtoEMFCommandWrapper(pasteCommand)); + final EMFCommandOperation op = new EMFCommandOperation(contextEditingDomain, new GMFtoEMFCommandWrapper(pasteCommand)); // EMFOperationCommand c = new EMFOperationCommand(contextEditingDomain, pasteCommand); CheckedOperationHistory.getInstance().execute(op, monitor, null); - } catch (Exception e) { + } catch (final Exception e) { return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "An exception occured during the paste", e); //$NON-NLS-1$ } monitor.done(); @@ -451,217 +476,245 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { } } - private ICommand getPasteRowFromStringCommandInDetachedMode(final TransactionalEditingDomain contextEditingDomain, final TransactionalEditingDomain tableEditingDomain, final IProgressMonitor progressMonitor, final Map<Object, Object> sharedMap) { - if (progressMonitor != null) { - progressMonitor.beginTask(PASTE_ACTION_TASK_NAME, this.nbOperationsToDo);// +1 to add the created elements to the table + /** + * Create the paste row from string command for the detached mode. + * + * @param contextEditingDomain + * The context editing domain. + * @param tableEditingDomain + * The table editing domain. + * @param progressMonitor + * The progress monitor. + * @param sharedMap + * The shared map. + * @return The created command for the paste in detached mode. + */ + private ICommand getPasteRowFromStringInDetachedModeCommand(final TransactionalEditingDomain contextEditingDomain, final TransactionalEditingDomain tableEditingDomain, final IProgressMonitor progressMonitor, final Map<Object, Object> sharedMap) { + // initialize the progress monitor + if (null != progressMonitor) { + progressMonitor.beginTask(PASTE_ACTION_TASK_NAME, this.nbOperationsToDo); } - // the list of the created elements - final List<Object> createdElements = new ArrayList<Object>(); + + final boolean isSingleHeaderColumnTreeTable = TableHelper.isSingleColumnTreeTable(table); // 2.2 create the creation request and find the command provider - final EClass eClassToCreate = this.typeToCreate.getEClass(); - final EFactory eFactory = eClassToCreate.getEPackage().getEFactoryInstance(); - - // 2.3 create the axis - int nbCreatedElements = 0; - - // we refresh the dialog each X read char - long readChar = 0; - long previousreadChar = 0; - final RowIterator rowIter = this.parser.parse(); - while (rowIter.hasNext()) { - final CellIterator cellIter = rowIter.next(); - if (!cellIter.hasNext()) { - continue;// to avoid blank line - } - if ((progressMonitor != null) && progressMonitor.isCanceled()) { - // the user click on the cancel button - return null; - } + final ICommand pasteAllCommand = new AbstractTransactionalCommand(contextEditingDomain, PASTE_COMMAND_NAME, null) { - readChar = readChar + (parser.getReadCharacters() - previousreadChar); - previousreadChar = parser.getReadCharacters(); + /** + * + * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable) + * + * @param monitor + * @param info + * @return + * @throws ExecutionException + */ + @SuppressWarnings("unchecked") + @Override + protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException { + final List<IStatus> resultStatus = new ArrayList<IStatus>(); + long readChar = 0; + long previousreadChar = 0; - if (progressMonitor != null && readChar > refreshEachReadChar) { - readChar = 0; - progressMonitor.subTask(NLS.bind("{0} {1} have been created.", new Object[] { nbCreatedElements, typeToCreate.getEClass().getName() })); //$NON-NLS-1$ - progressMonitor.worked(refreshEachReadChar); - } - nbCreatedElements++; + // this map stores the last created object to a depth. + // its allows us to find easily the context to use for each created element + final Map<Integer, EObject> contextMap = new HashMap<Integer, EObject>(); + contextMap.put(Integer.valueOf(-1), table.getContext()); - // 2.3.3 we create the element itself - final EObject createdElement = eFactory.create(eClassToCreate); + // 2. create a map with the last paste configuration used by depth + final Map<Integer, PasteEObjectConfiguration> confMap = new HashMap<Integer, PasteEObjectConfiguration>(); - createdElements.add(createdElement); - nbCreatedElements++; - for (final String currentPostActions : this.postActions) { - PastePostActionRegistry.INSTANCE.doPostAction(this.tableManager, currentPostActions, tableContext, createdElement, sharedMap, null);// TODO : remove this parameter - } + final RowIterator rowIter = parser.parse(); + int nbReadLine = 0; + // Manage the rows paste + while (rowIter.hasNext()) { + final CellIterator cellIter = rowIter.next(); + nbReadLine++; + if (!cellIter.hasNext()) { + continue;// to avoid blank line + } + // Check if the progress monitor catch a cancel click + if (null != progressMonitor && progressMonitor.isCanceled()) { + progressMonitor.done(); + localDispose(); + return CommandResult.newCancelledCommandResult(); + } + readChar = readChar + (parser.getReadCharacters() - previousreadChar); + previousreadChar = parser.getReadCharacters(); - // 2.3.4 we set these properties values - final Iterator<Object> secondAxisIterator = secondAxis.iterator(); - while (secondAxisIterator.hasNext() && cellIter.hasNext()) { - final Object currentAxis = secondAxisIterator.next(); - final String valueAsString = cellIter.next(); - final Object columnObject; - final Object rowObject; - if (this.pasteColumn) { - columnObject = createdElement; - rowObject = currentAxis; - } else { - columnObject = currentAxis; - rowObject = createdElement; - } + if (null != progressMonitor && readChar > refreshEachReadChar) { + readChar = 0; + progressMonitor.worked(refreshEachReadChar); + } + // the iterator on columns + final Iterator<?> secondAxisIterator = secondAxis.iterator(); - boolean isEditable = CellManagerFactory.INSTANCE.isCellEditable(columnObject, rowObject, sharedMap); - if (isEditable) { - final AbstractStringValueConverter converter = CellManagerFactory.INSTANCE.getOrCreateStringValueConverterClass(columnObject, rowObject, tableManager, existingConverters, this.pasteHelper.getMultiValueSeparator()); - CellManagerFactory.INSTANCE.setStringValue(columnObject, rowObject, valueAsString, converter, tableManager, sharedMap); - } - } + // Manage the first column of the row + while (cellIter.hasNext()) { + String valueAsString = cellIter.next(); + int nbReadCell = 1; - // TODO : do something to say that the number of cell is not correct! - while (cellIter.hasNext()) { - cellIter.next();// required! - } - } + if (isSingleHeaderColumnTreeTable && !valueAsString.isEmpty()) { + // If the table is a single header column, parse the value string to manage the correct depth + // (manage each separator character as empty cell) + while (INDENTATION_CHARACTER == valueAsString.charAt(0)) { + nbReadCell++; + valueAsString = valueAsString.substring(1); + } + } else { + // test if the value is empty (we are in the tree header) + while (cellIter.hasNext() && valueAsString.isEmpty()) { + valueAsString = cellIter.next(); + nbReadCell++; + } + // Remove the whitespace on beginning + if (isSingleHeaderColumnTreeTable && !valueAsString.isEmpty()) { + while (INDENTATION_CHARACTER == valueAsString.charAt(0)) { + valueAsString = valueAsString.substring(1); + } + } + } - // 2.4 we add the created elements to the table - final AbstractTransactionalCommand pasteCommand = new AbstractTransactionalCommand(tableEditingDomain, PASTE_COMMAND_NAME, null) { + final int depth = getDepth(nbReadCell); + final boolean isCategory = isCategory(nbReadCell); - @Override - protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { - // initialize lists - final Collection<String> postActions = getPostActions(); - - // we add the post actions added by cell manager - // see bug 431691: [Table 2] Paste from Spreadsheet must be able to apply required stereotypes for column properties in all usecases - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=431691 - @SuppressWarnings("unchecked") - final Collection<String> postActionsAddedByCellManagers = (Collection<String>) sharedMap.get(Constants.ADDITIONAL_POST_ACTIONS_TO_CONCLUDE_PASTE_KEY); - postActions.addAll(postActionsAddedByCellManagers); - - @SuppressWarnings("unchecked") - final List<Cell> cells = (List<Cell>) sharedMap.get(Constants.CELLS_TO_ADD_KEY); - @SuppressWarnings("unchecked") - final List<IValueSetter> valueToSet = (List<IValueSetter>) sharedMap.get(Constants.REFERENCES_TO_SET_KEY); - - int nbTasks = 1; // to add created elements to the model - nbTasks = nbTasks + 1; // to add createds elements to the table - nbTasks = nbTasks + postActions.size();// to do post actions after the attachment to the model - nbTasks = nbTasks + 1; // to attach the cells to the model - nbTasks = nbTasks + valueToSet.size(); // to set the references values - - if (progressMonitor != null) { - if (progressMonitor.isCanceled()) { - localDispose(); - return CommandResult.newCancelledCommandResult(); - } - progressMonitor.beginTask(Messages.PasteEObjectAxisInTableCommandProvider_FinishingThePaste, nbTasks); - } + if (isCategory) { + confMap.put(Integer.valueOf(depth), (PasteEObjectConfiguration) getPasteConfigurationsFor(depth, valueAsString)); + // lastConfiguration = (PasteEObjectConfiguration) getPasteConfigurationsFor(depth, valueAsString); + while (cellIter.hasNext()) { + cellIter.next(); + } + break; + } - // 1. Add the elements to the context - AddCommand.create(contextEditingDomain, tableContext, containmentFeature, createdElements).execute(); + // we get the paste configuration to use + PasteEObjectConfiguration pasteConfToUse = confMap.get(Integer.valueOf(depth)); + if (null == pasteConfToUse) { + pasteConfToUse = (PasteEObjectConfiguration) getPasteConfigurationsFor(depth, null); + if (null != pasteConfToUse) { + confMap.put(Integer.valueOf(depth), pasteConfToUse); + } else { + final IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, PasteSeverityCode.PASTE_ERROR__NO_PASTE_CONFIGURATION, NLS.bind("No paste configuration found for the depth {0}", depth), null); + return new CommandResult(status); + } + } - if (progressMonitor != null) { - if (progressMonitor.isCanceled()) { - return CommandResult.newCancelledCommandResult(); - } - progressMonitor.worked(1); - progressMonitor.subTask(Messages.PasteEObjectAxisInTableCommandProvider_AddingElementToTheTable); - } + // get the element type to use to create the element + final IElementType typeToCreate = ElementTypeRegistry.getInstance().getType(pasteConfToUse.getPastedElementId()); - Command cmd = null; - if (pasteColumn) { - cmd = tableManager.getAddColumnElementCommand(createdElements); // TODO remove one of these 2 lines - } else { - cmd = tableManager.getAddRowElementCommand(createdElements); - } - if (cmd != null) {// could be null - cmd.execute(); - } + // Get the class type to create and get its factory + final EClass eClassToCreate = typeToCreate.getEClass(); + final EFactory eFactory = eClassToCreate.getEPackage().getEFactoryInstance(); - if (progressMonitor != null) { - if (progressMonitor.isCanceled()) { - return CommandResult.newCancelledCommandResult(); - } - progressMonitor.worked(1); - progressMonitor.subTask(Messages.PasteEObjectAxisInTableCommandProvider_DoingAdditionalActions); - } + // get the element type to use to create the element + final Object createdElement = eFactory.create(eClassToCreate); + // 4. we use the label to do a set name command on the created element + if (createdElement instanceof EObject) { + final EObject eobject = (EObject) createdElement; - for (final String currentPostActions : postActions) { - PastePostActionRegistry.INSTANCE.concludePostAction(tableManager, currentPostActions, sharedMap); - progressMonitor.worked(1); - } + // add the created element to the context map + contextMap.put(Integer.valueOf(depth), (EObject) createdElement); + // get the context to use + final EObject context = contextMap.get(depth - 1); + final EStructuralFeature containmentFeature = pasteConfToUse.getPasteElementContainementFeature(); + if (containmentFeature.isMany()) { + ((Collection<EObject>) context.eGet(containmentFeature)).add(eobject); + } else { + context.eSet(containmentFeature, createdElement); + } - if (progressMonitor != null) { - if (progressMonitor.isCanceled()) { - return CommandResult.newCancelledCommandResult(); - } - progressMonitor.worked(1); - progressMonitor.subTask(Messages.PasteEObjectAxisInTableCommandProvider_LinkingReferencesToTheModel); - } + // get the feature used as ID for the element + final EStructuralFeature nameFeature = ((EObject) createdElement).eClass().getEStructuralFeature("name"); //$NON-NLS-1$ + if (nameFeature != null) { + eobject.eSet(nameFeature, valueAsString); + } + // we add the created element to the table, only if its parent is the context of the table and if the table is filled by DnD + if (!FillingConfigurationUtils.hasTreeFillingConfigurationForDepth(table, 0) && ((EObject) createdElement).eContainer() == tableContext) { + final Command addCommand = tableManager.getAddRowElementCommand(Collections.singleton(createdElement)); + + if (addCommand != null) {// can be null + addCommand.execute(); + addCommand.dispose(); + } + } + } + + crossCellIteratorToFirstBodyCell(cellIter, nbReadCell); + + while (secondAxisIterator.hasNext() && cellIter.hasNext()) { + // we must exit of the header part! + valueAsString = cellIter.next(); + // Remove the whitespace on beginning + if (isSingleHeaderColumnTreeTable && !valueAsString.isEmpty()) { + while (INDENTATION_CHARACTER == valueAsString.charAt(0)) { + valueAsString = valueAsString.substring(1); + } + } - // we set the references + final Object currentAxis = secondAxisIterator.next(); + if (!valueAsString.isEmpty()) { + final Object columnObject = currentAxis; + final Object rowObject = createdElement; - if (valueToSet.size() > 0) { - for (final IValueSetter current : valueToSet) { - current.doSetValue(contextEditingDomain); - if (progressMonitor != null) { - if (progressMonitor.isCanceled()) { - return CommandResult.newCancelledCommandResult(); + final boolean isEditable = CellManagerFactory.INSTANCE.isCellEditable(columnObject, rowObject, sharedMap); + if (isEditable) { + final AbstractStringValueConverter converter = CellManagerFactory.INSTANCE.getOrCreateStringValueConverterClass(columnObject, rowObject, tableManager, existingConverters, pasteHelper.getMultiValueSeparator()); + CellManagerFactory.INSTANCE.setStringValue(columnObject, rowObject, valueAsString, converter, tableManager, sharedMap); + } } - progressMonitor.worked(1); } - } - } - // the cells must be attached at the end (in order to update properly the cell map in the table manager - if (progressMonitor != null) { - if (progressMonitor.isCanceled()) { - return CommandResult.newCancelledCommandResult(); + int tooManyCellOnRow = 0; + while (cellIter.hasNext()) { + cellIter.next();// required + tooManyCellOnRow++; + } + + if (tooManyCellOnRow != 0) { + final String message = NLS.bind("There are too many cells on the rows number {0}", nbReadLine); //$NON-NLS-1$ + final IStatus status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, PasteSeverityCode.PASTE_WARNING__TOO_MANY_CELLS_ON_ROWS, message, null); + resultStatus.add(status); + } } - progressMonitor.worked(1); } - // add the created cells to the table - AddCommand.create(tableEditingDomain, table, NattablePackage.eINSTANCE.getTable_Cells(), cells).execute(); - - if (progressMonitor != null) { - progressMonitor.done(); - } + progressMonitor.done(); localDispose(); - return CommandResult.newOKCommandResult(); + if (resultStatus.isEmpty()) { + return CommandResult.newOKCommandResult(); + } else { + final IStatus resultingStatus = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, resultStatus.toArray(new IStatus[resultStatus.size()]), "The paste has been done, but we found some problems", null); + return new CommandResult(resultingStatus); + } } }; - - return pasteCommand; + return pasteAllCommand; } - /** + * Get the paste command for the detached mode. * - * + * @param contextEditingDomain + * The context editing domain. + * @param tableEditingDomain + * The table editing domain. + * @param progressMonitor + * The progress monitor used. * @param sharedMap * a map used to share objects and informations during the paste between this class and the cell value manager - * @param commandCreationCancelProvider - * the creation command progress monitor - * @param commandExecutionProgressMonitor - * the command execution progress monitor * @return - * the command to use to finish the paste (the main part of the paste is directly done here) + * the command to use to finish the paste (the main part of the paste is directly done here) */ private ICommand getPasteFromStringCommandInDetachedMode(final TransactionalEditingDomain contextEditingDomain, final TransactionalEditingDomain tableEditingDomain, final IProgressMonitor progressMonitor, final Map<Object, Object> sharedMap) { - if (!this.pasteColumn) { - return getPasteRowFromStringCommandInDetachedMode(contextEditingDomain, tableEditingDomain, progressMonitor, sharedMap); + if (this.pasteColumn) { + return new UnexecutableCommand(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.PasteEObjectTreeAxisInNatTableCommandProvider_CantPasteColumnsInTreeTable)); } else { - // return getPasteColumnFromStringCommandInDetachedMode(contextEditingDomain, tableEditingDomain, progressMonitor, sharedMap); + return getPasteRowFromStringInDetachedModeCommand(contextEditingDomain, tableEditingDomain, progressMonitor, sharedMap); } - return null; } @@ -717,7 +770,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { // previousreadChar = parser.getReadCharacters(); // if (progressMonitor != null && readChar > refreshEachReadChar) { // readChar = 0; - // progressMonitor.subTask(NLS.bind("{0} {1} have been created.", new Object[] { typeToCreate.getEClass().getName(), nbCreatedElements })); //$NON-NLS-1$ + // progressMonitor.subTask(NLS.bind("{0} {1} have been created.", new Object[] { typeToCreate.getEClass().getName(), nbCreatedElements })); //$NON-NLS-1$ // progressMonitor.worked(refreshEachReadChar); // } // nbCreatedElements++; @@ -784,27 +837,36 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { // return pasteAllCommand; // } - - - - - private boolean isCategory(int nbReadCell) { + /** + * Check if this is a category. + * + * @param nbReadCell + * The number of cells read. + * @return <code>true</code> if this is a category, <code>false</code> otherwise. + */ + private boolean isCategory(final int nbReadCell) { return PasteTreeUtils.isCategory(nbReadCell, FillingConfigurationUtils.getMaxDepthForTree(table), StyleUtils.getHiddenDepths(table), FillingConfigurationUtils.hasTreeFillingConfigurationForDepth(table, 0)); } - - private int getDepth(int nbReadCell) { + /** + * Get the depth corresponding to the number of cells read + * + * @param nbReadCell + * The number of cell read. + * @return The depth number. + */ + private int getDepth(final int nbReadCell) { return PasteTreeUtils.getDepth(nbReadCell, FillingConfigurationUtils.getMaxDepthForTree(table), StyleUtils.getHiddenDepths(table), FillingConfigurationUtils.hasTreeFillingConfigurationForDepth(table, 0)); } /** * - * @param iterator - * the cellIterator + * @param cellIter + * The cellIterator * @param nbReadCell - * + * The number of cells read. */ - protected void crossCellIteratorToFirstBodyCell(CellIterator cellIter, int nbReadCell) { + protected void crossCellIteratorToFirstBodyCell(final CellIterator cellIter, int nbReadCell) { // If this is a single column header tree table, we don't need to do anything, only the first column is used for the header in the excel spearsheet if (!TableHelper.isSingleColumnTreeTable(table)) { int nbColumns = (FillingConfigurationUtils.getMaxDepthForTree(table) + 1) * 2; @@ -813,8 +875,8 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { } // exit of the header part - List<Integer> hiddenDepth = StyleUtils.getHiddenDepths(table); - int nbVisibleColumns = nbColumns - hiddenDepth.size(); + final List<Integer> hiddenDepth = StyleUtils.getHiddenDepths(table); + final int nbVisibleColumns = nbColumns - hiddenDepth.size(); while (nbReadCell < nbVisibleColumns) { cellIter.next(); @@ -826,11 +888,14 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { /** * - * @param commandCreationCancelProvider - * the creation command progress monitor - * @param commandExecutionProgressMonitor - * the command execution progress monitor - * @return + * + * @param contextEditingDomain + * The context editing domain. + * @param tableEditingDomain + * The table editing domain. + * @param progressMonitor + * The progress monitor. + * @return The paste command for the attached mode. */ private ICommand getPasteRowFromStringInAttachedModeCommand(final TransactionalEditingDomain contextEditingDomain, final TransactionalEditingDomain tableEditingDomain, final IProgressMonitor progressMonitor) { // initialize the progress monitor @@ -844,11 +909,6 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { final ICommand pasteAllCommand = new AbstractTransactionalCommand(contextEditingDomain, PASTE_COMMAND_NAME, null) { /** - * The character of the indentation for the single column. - */ - private static final char INDENTATION_CHARACTER = ' '; // $NON-NLS-1$ - - /** * * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable) * @@ -858,22 +918,21 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { * @throws ExecutionException */ @Override - protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { - List<IStatus> resultStatus = new ArrayList<IStatus>(); + protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException { + final List<IStatus> resultStatus = new ArrayList<IStatus>(); long readChar = 0; long previousreadChar = 0; // this map stores the last created object to a depth. // its allows us to find easily the context to use for each created element - Map<Integer, EObject> contextMap = new HashMap<Integer, EObject>(); + final Map<Integer, EObject> contextMap = new HashMap<Integer, EObject>(); contextMap.put(Integer.valueOf(-1), table.getContext()); // 2. create a map with the last paste configuration used by depth - Map<Integer, PasteEObjectConfiguration> confMap = new HashMap<Integer, PasteEObjectConfiguration>(); + final Map<Integer, PasteEObjectConfiguration> confMap = new HashMap<Integer, PasteEObjectConfiguration>(); final RowIterator rowIter = parser.parse(); - int nbCreatedElements = 0; int nbReadLine = 0; while (rowIter.hasNext()) { final CellIterator cellIter = rowIter.next(); @@ -918,7 +977,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { nbReadCell++; } // Remove the whitespace on beginning - if(isSingleHeaderColumnTreeTable && !valueAsString.isEmpty()){ + if (isSingleHeaderColumnTreeTable && !valueAsString.isEmpty()) { while (INDENTATION_CHARACTER == valueAsString.charAt(0)) { valueAsString = valueAsString.substring(1); } @@ -949,25 +1008,25 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { } // we get the paste configuration to use - PasteEObjectConfiguration pasteConfToUse = (PasteEObjectConfiguration) confMap.get(Integer.valueOf(depth)); + PasteEObjectConfiguration pasteConfToUse = confMap.get(Integer.valueOf(depth)); if (pasteConfToUse == null) { pasteConfToUse = (PasteEObjectConfiguration) getPasteConfigurationsFor(depth, null); if (pasteConfToUse != null) { confMap.put(Integer.valueOf(depth), pasteConfToUse); } else { - IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, PasteSeverityCode.PASTE_ERROR__NO_PASTE_CONFIGURATION, NLS.bind("No paste configuration found for the depth {0}", depth), null); + final IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, PasteSeverityCode.PASTE_ERROR__NO_PASTE_CONFIGURATION, NLS.bind("No paste configuration found for the depth {0}", depth), null); return new CommandResult(status); } } // get the paste configuration to use // get the element type to use to create the element - IElementType typeToCreate = ElementTypeRegistry.getInstance().getType(pasteConfToUse.getPastedElementId()); + final IElementType typeToCreate = ElementTypeRegistry.getInstance().getType(pasteConfToUse.getPastedElementId()); - EStructuralFeature containmentFeature = pasteConfToUse.getPasteElementContainementFeature(); + final EStructuralFeature containmentFeature = pasteConfToUse.getPasteElementContainementFeature(); // get the context to use - EObject context = contextMap.get(depth - 1); + final EObject context = contextMap.get(depth - 1); final CreateElementRequest createRequest1 = new CreateElementRequest(contextEditingDomain, context, typeToCreate, (EReference) containmentFeature); final IElementEditService creationContextCommandProvider = ElementEditServiceUtils.getCommandProvider(context); @@ -976,7 +1035,6 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { // 1. we create the element commandCreation.execute(monitor, info); - nbCreatedElements++; // 2. we get the result of the command final CommandResult res = commandCreation.getCommandResult(); @@ -991,14 +1049,14 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { // TODO : this class should be in oep.infra.emf.nattable if (createdElement instanceof EObject) { // TODO : this past must be specific for EMF AND for UML - EObject eobject = (EObject) createdElement; + final EObject eobject = (EObject) createdElement; // get the feature used as ID for the element - EStructuralFeature nameFeature = ((EObject) createdElement).eClass().getEStructuralFeature("name"); //$NON-NLS-1$ + final EStructuralFeature nameFeature = eobject.eClass().getEStructuralFeature("name"); //$NON-NLS-1$ if (nameFeature != null) { - SetRequest setNameRequest = new SetRequest(contextEditingDomain, (EObject) createdElement, nameFeature, valueAsString); + final SetRequest setNameRequest = new SetRequest(contextEditingDomain, eobject, nameFeature, valueAsString); final IElementEditService createdElementCommandProvider = ElementEditServiceUtils.getCommandProvider(createdElement); if (createdElementCommandProvider != null) { - ICommand setName = createdElementCommandProvider.getEditCommand(setNameRequest); + final ICommand setName = createdElementCommandProvider.getEditCommand(setNameRequest); if (setName != null && setName.canExecute()) { setName.execute(monitor, info); } @@ -1022,7 +1080,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { // we must exit of the header part! valueAsString = cellIter.next(); // Remove the whitespace on beginning - if(isSingleHeaderColumnTreeTable && !valueAsString.isEmpty()){ + if (isSingleHeaderColumnTreeTable && !valueAsString.isEmpty()) { while (INDENTATION_CHARACTER == valueAsString.charAt(0)) { valueAsString = valueAsString.substring(1); } @@ -1041,7 +1099,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { // } - boolean isEditable = CellManagerFactory.INSTANCE.isCellEditable(columnObject, rowObject); + final boolean isEditable = CellManagerFactory.INSTANCE.isCellEditable(columnObject, rowObject); if (isEditable) { final AbstractStringValueConverter converter = CellManagerFactory.INSTANCE.getOrCreateStringValueConverterClass(columnObject, rowObject, tableManager, existingConverters, pasteHelper.getMultiValueSeparator()); @@ -1049,7 +1107,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { if (setValueCommand != null && setValueCommand.canExecute()) { try { setValueCommand.execute(); - } catch (Exception e) { + } catch (final Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } @@ -1065,8 +1123,8 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { } if (tooManyCellOnRow != 0) { - String message = NLS.bind("There are too many cells on the rows number {0}", nbReadLine); - IStatus status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, PasteSeverityCode.PASTE_WARNING__TOO_MANY_CELLS_ON_ROWS, message, null); + final String message = NLS.bind("There are too many cells on the rows number {0}", nbReadLine); + final IStatus status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, PasteSeverityCode.PASTE_WARNING__TOO_MANY_CELLS_ON_ROWS, message, null); resultStatus.add(status); } } @@ -1077,8 +1135,7 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { if (resultStatus.isEmpty()) { return CommandResult.newOKCommandResult(); } else { - // TODO : use me - IStatus resultingStatus = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, resultStatus.toArray(new IStatus[resultStatus.size()]), "The paste has been done, but we found some problems", null); + final IStatus resultingStatus = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, resultStatus.toArray(new IStatus[resultStatus.size()]), "The paste has been done, but we found some problems", null); return new CommandResult(resultingStatus); } } @@ -1086,56 +1143,48 @@ public class PasteEObjectTreeAxisInNattableCommandProvider { return pasteAllCommand; } - protected boolean useDetachedMode() { - // TODO - return false; - } - - protected Command getSetNameCommandusingLabel(Object createdElement, String label) { - - return null; - } - /** + * Get the paste command for the attached mode. * - * @param commandCreationCancelProvider - * the creation command progress monitor - * @param commandExecutionProgressMonitor - * the command execution progress monitor - * @return + * @param contextEditingDomain + * The context editing domain + * @param tableEditingDomain + * The table editing domain + * @param progressMonitor + * The progress monitor + * @return the command to use to finish the paste (the main part of the paste is directly done here) */ private ICommand getPasteFromStringCommandInAttachedMode(final TransactionalEditingDomain contextEditingDomain, final TransactionalEditingDomain tableEditingDomain, final IProgressMonitor progressMonitor) { if (this.pasteColumn) { - return new UnexecutableCommand(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "We can't paste columns in a tree table")); + return new UnexecutableCommand(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.PasteEObjectTreeAxisInNatTableCommandProvider_CantPasteColumnsInTreeTable)); } else { return getPasteRowFromStringInAttachedModeCommand(contextEditingDomain, tableEditingDomain, progressMonitor); } } /** - * + * Get the post actions. + * * @return - * the list of the post actions to do + * the list of the post actions to do */ private Collection<String> getPostActions() { return this.postActions; } /** - * dispose fields of the class + * Dispose fields of the class */ private void localDispose() { this.isDisposed = true; this.tableManager = null; - this.typeToCreate = null; - this.containmentFeature = null; for (final AbstractStringValueConverter current : existingConverters.values()) { current.dispose(); } this.existingConverters.clear(); try { this.reader.close(); - } catch (IOException e) { + } catch (final IOException e) { Activator.log.error(e); } } |