X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Factions%2FAssignSymbolGroup.java;h=1c5dea754acb55454e629926a67fe1e790f3f391;hb=refs%2Fchanges%2F26%2F2526%2F3;hp=18317084c2b2b977eef102abe5c86d2980159c32;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/AssignSymbolGroup.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/AssignSymbolGroup.java index 18317084c..1c5dea754 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/AssignSymbolGroup.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/AssignSymbolGroup.java @@ -1,410 +1,409 @@ -/******************************************************************************* - * Copyright (c) 2012 Association for Decentralized Information Management - * in Industry THTH ry. - * 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: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.modeling.ui.actions; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IInputValidator; -import org.eclipse.jface.dialogs.InputDialog; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ICheckStateProvider; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PlatformUI; -import org.simantics.Simantics; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.request.PossibleIndexRoot; -import org.simantics.db.common.request.UniqueRead; -import org.simantics.db.common.request.WriteRequest; -import org.simantics.db.common.utils.NameUtils; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.adapter.ActionFactory; -import org.simantics.db.layer0.adapter.ActionFactory2; -import org.simantics.db.request.Read; -import org.simantics.diagram.stubs.DiagramResource; -import org.simantics.modeling.AssignSymbolGroupRequest; -import org.simantics.modeling.GetSymbolGroups; -import org.simantics.modeling.NewSymbolGroupRequest; -import org.simantics.utils.strings.AlphanumComparator; -import org.simantics.utils.ui.ErrorLogger; -import org.simantics.utils.ui.dialogs.ShowMessage; - -/** - * @author Hannu Niemistö - * @author Tuukka Lehtonen - */ -public class AssignSymbolGroup implements ActionFactory, ActionFactory2 { - - @Override - public Runnable create(Collection targets) { - final ArrayList resources = new ArrayList(); - for (Object target : targets) { - if (!(target instanceof Resource)) - return null; - resources.add((Resource) target); - } - return new Runnable() { - @Override - public void run() { - assignGroups(resources); - - } - }; - } - - @Override - public Runnable create(Object target) { - if(!(target instanceof Resource)) - return null; - final Resource symbol = (Resource)target; - return new Runnable() { - @Override - public void run() { - assignGroups(Collections.singletonList(symbol)); - } - }; - } - - private static final SymbolGroup[] NO_SYMBOL_GROUPS = new SymbolGroup[0]; - - static enum Tristate { - NONE, SOME, ALL; - - public static Tristate add(Tristate current, boolean next) { - if (current == null) - return next ? ALL : NONE; - switch (current) { - case ALL: return next ? ALL : SOME; - case SOME: return next ? SOME : SOME; - case NONE: return next ? SOME : NONE; - default: return NONE; - } - } - } - - private static class SymbolGroup implements Comparable { - Resource resource; - String name; - Tristate originallySelected; - Tristate selected; - - public SymbolGroup(Resource resource, String name, Tristate originallySelected, Tristate selected) { - super(); - this.resource = resource; - this.name = name; - this.originallySelected = originallySelected; - this.selected = selected; - } - - @Override - public int compareTo(SymbolGroup o) { - return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(name, o.name); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[name=" + name - + ", originally selected=" + originallySelected - + ", selected=" + selected + "]"; - } - } - - private static class ContentProviderImpl implements IStructuredContentProvider { - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public void dispose() { - } - - @Override - public Object[] getElements(Object inputElement) { - return (Object[])inputElement; - } - }; - - private static class LabelProviderImpl extends LabelProvider { - @Override - public String getText(Object element) { - return ((SymbolGroup)element).name; - } - } - - private static class CheckStateProviderImpl implements ICheckStateProvider { - @Override - public boolean isChecked(Object element) { - return ((SymbolGroup) element).selected != Tristate.NONE; - } - @Override - public boolean isGrayed(Object element) { - return ((SymbolGroup) element).selected == Tristate.SOME; - } - } - - private static Resource getCommonModel(final Collection symbols) { - try { - return Simantics.sync(new UniqueRead() { - @Override - public Resource perform(ReadGraph graph) throws DatabaseException { - return getPossibleIndexRoot(graph, symbols); - } - }); - } catch (DatabaseException e) { - ErrorLogger.defaultLogError(e); - return null; - } - } - - private static Resource getPossibleIndexRoot(ReadGraph g, Collection symbols) throws DatabaseException { - Resource model = null; - for (Resource symbol : symbols) { - Resource m = getIndexRootOf(g, symbol); - if (m == null) - return null; - if (model == null) - model = m; - else if (!model.equals(m)) - return null; - } - return model; - } - - private static Resource getIndexRootOf(ReadGraph g, Resource symbol) throws DatabaseException { - return g.syncRequest(new PossibleIndexRoot(symbol)); - } - - private static SymbolGroup[] getSymbolGroups(final Collection symbols) { - try { - return Simantics.getSession().syncRequest(new Read() { - @Override - public SymbolGroup[] perform(ReadGraph g) throws DatabaseException { - return getSymbolGroups(g, symbols); - } - }); - } catch(DatabaseException e) { - e.printStackTrace(); - return NO_SYMBOL_GROUPS; - } - } - - private static SymbolGroup[] getSymbolGroups(ReadGraph g, Collection symbols) throws DatabaseException { - Resource model = getPossibleIndexRoot(g, symbols); - if (model == null) - return NO_SYMBOL_GROUPS; - // All symbols have same model. - // Resolve the symbol group selection states now. - ArrayList result = new ArrayList(); - DiagramResource DIA = DiagramResource.getInstance(g); - for (Resource library : GetSymbolGroups.getSymbolGroups(g, model)) { - Tristate selected = getLibrarySelectionState(g, library, symbols, DIA); - selected = selected != null ? selected : Tristate.NONE; - result.add( new SymbolGroup( - library, - NameUtils.getSafeLabel(g, library), - selected, - selected) ); - } - //System.out.println("result: " + EString.implode(result)); - Collections.sort(result); - //System.out.println("sorted result: " + EString.implode(result)); - return result.toArray(new SymbolGroup[result.size()]); - } - - protected static Tristate getLibrarySelectionState(ReadGraph graph, Resource library, - Collection symbols, DiagramResource DIA) throws DatabaseException { - Tristate selected = null; - for (Resource symbol : symbols) { - selected = Tristate.add(selected, graph.hasStatement(library, DIA.HasSymbol, symbol)); - } - return selected != null ? selected : Tristate.NONE; - } - - private static SymbolGroup[] selectedElements(SymbolGroup[] symbolGroups) { - int count = 0; - for(SymbolGroup g : symbolGroups) - if(g.selected != Tristate.NONE) - ++count; - SymbolGroup[] result = new SymbolGroup[count]; - count = 0; - for(SymbolGroup g : symbolGroups) - if(g.selected != Tristate.NONE) - result[count++] = g; - return result; - } - - public void assignGroups(final Collection symbols) { - if (symbols.isEmpty()) - return; - - final Resource model = getCommonModel(symbols); - if (model == null) { - ShowMessage.showInformation("Same Model Required", "All the selected symbols must be from within the same model."); - return; - } - - final AtomicReference groups = - new AtomicReference( getSymbolGroups(symbols) ); - - StringBuilder message = new StringBuilder(); - message.append("Select symbol groups the selected "); - if (symbols.size() > 1) - message.append(symbols.size()).append(" symbols are shown in."); - else - message.append("symbol is shown in."); - - AssignSymbolGroupsDialog dialog = new AssignSymbolGroupsDialog( - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - groups.get(), - new ContentProviderImpl(), - new LabelProviderImpl(), - new CheckStateProviderImpl(), - message.toString()) { - - @Override - protected void checkStateChanged(Object[] elements, boolean checked) { - for (Object _g : elements) { - SymbolGroup g = (SymbolGroup) _g; - g.selected = checked ? Tristate.ALL : Tristate.NONE; - // Refresh checked states through provider. - listViewer.refresh(); - } - } - - @Override - protected void newAction() { - SymbolGroup newGroup = newSymbolGroup(getShell(), model, (SymbolGroup[])inputElement); - if (newGroup != null) { - // Select the new library by default. - newGroup.selected = Tristate.ALL; - - SymbolGroup[] newGroups = (SymbolGroup[]) inputElement; - newGroups = Arrays.copyOf(newGroups, newGroups.length+1); - newGroups[newGroups.length-1] = newGroup; - Arrays.sort(newGroups); - listViewer.setInput(newGroups); - inputElement = newGroups; - groups.set(newGroups); - } - } - - @Override - protected void deleteAction(Object[] array) { - SymbolGroup[] groupsToRemove = Arrays.copyOf(array, array.length, SymbolGroup[].class); - if (removeSymbolGroups(getShell(), groupsToRemove)) { - listViewer.remove(groupsToRemove); - Set removedGroups = new HashSet(); - for (SymbolGroup removed : groupsToRemove) - removedGroups.add(removed); - List newGroups = new ArrayList(groups.get().length); - for (SymbolGroup old : groups.get()) { - if (!removedGroups.contains(old)) - newGroups.add(old); - } - groups.set( newGroups.toArray(NO_SYMBOL_GROUPS) ); - } - } - }; - dialog.setTitle("Symbol Group Assignments"); - dialog.setInitialSelections(selectedElements(groups.get())); - if (dialog.open() == Dialog.OK) { - final ArrayList added = new ArrayList(); - final ArrayList removed = new ArrayList(); - for (SymbolGroup g : groups.get()) { - if (g.selected != g.originallySelected && g.selected == Tristate.ALL) - added.add(g); - if (g.selected != g.originallySelected && g.selected == Tristate.NONE) - removed.add(g); - } - if (!added.isEmpty() || !removed.isEmpty()) { - ArrayList addedSymbolGroups = new ArrayList(); - ArrayList removedSymbolGroups = new ArrayList(); - for (SymbolGroup group : added) - addedSymbolGroups.add(group.resource); - for (SymbolGroup group : removed) - removedSymbolGroups.add(group.resource); - Simantics.getSession().asyncRequest(new AssignSymbolGroupRequest(addedSymbolGroups, removedSymbolGroups, symbols)); - } - } - } - - private static SymbolGroup newSymbolGroup(Shell shell, Resource model, final SymbolGroup[] oldGroups) { - InputDialog dialog = new InputDialog(shell, - "New Symbol Group", - "Write the name of the new symbol group.", - "NewSymbolGroup", - new IInputValidator() { - @Override - public String isValid(String newText) { - newText = newText.trim(); - if (newText.isEmpty()) - return "The name must be non-empty."; - for (SymbolGroup g : oldGroups) - if (newText.equals(g.name)) - return "A symbol group with that name already exists."; - return null; - } - } - ); - if (dialog.open() == Dialog.OK) { - String name = dialog.getValue(); - try { - NewSymbolGroupRequest request = new NewSymbolGroupRequest(name, model); - Resource symbolGroup = Simantics.getSession().syncRequest(request); - if (symbolGroup == null) - return null; - return new SymbolGroup(symbolGroup, name, Tristate.NONE, Tristate.NONE); - } catch (DatabaseException e) { - ErrorLogger.defaultLogError(e); - return null; - } - } - return null; - } - - private boolean removeSymbolGroups(Shell shell, final SymbolGroup[] groups) { - if (groups.length == 0) - return false; - String message; - if (groups.length == 1) - message = "Are you sure you want to remove symbol group '" + groups[0].name + "' ?"; - else - message = "Are you sure you want to remove " + groups.length + " symbol groups?"; - MessageDialog dialog = - new MessageDialog(shell, "Confirm removal", null, message, MessageDialog.QUESTION, new String[] { "OK", "Cancel" }, 0); - if (dialog.open() == Dialog.OK) { - Simantics.getSession().asyncRequest(new WriteRequest() { - @Override - public void perform(WriteGraph graph) throws DatabaseException { - for (SymbolGroup group : groups) - graph.deny(group.resource); - } - }); - return true; - } - else - return false; - } - -} +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management + * in Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modeling.ui.actions; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ICheckStateProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.db.layer0.adapter.ActionFactory2; +import org.simantics.db.request.Read; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.modeling.AssignSymbolGroupRequest; +import org.simantics.modeling.GetSymbolGroups; +import org.simantics.modeling.NewSymbolGroupRequest; +import org.simantics.utils.strings.AlphanumComparator; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.dialogs.ShowMessage; + +/** + * @author Hannu Niemistö + * @author Tuukka Lehtonen + */ +public class AssignSymbolGroup implements ActionFactory, ActionFactory2 { + + @Override + public Runnable create(Collection targets) { + final ArrayList resources = new ArrayList(); + for (Object target : targets) { + if (!(target instanceof Resource)) + return null; + resources.add((Resource) target); + } + return new Runnable() { + @Override + public void run() { + assignGroups(resources); + + } + }; + } + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource symbol = (Resource)target; + return new Runnable() { + @Override + public void run() { + assignGroups(Collections.singletonList(symbol)); + } + }; + } + + private static final SymbolGroup[] NO_SYMBOL_GROUPS = new SymbolGroup[0]; + + static enum Tristate { + NONE, SOME, ALL; + + public static Tristate add(Tristate current, boolean next) { + if (current == null) + return next ? ALL : NONE; + switch (current) { + case ALL: return next ? ALL : SOME; + case SOME: return next ? SOME : SOME; + case NONE: return next ? SOME : NONE; + default: return NONE; + } + } + } + + private static class SymbolGroup implements Comparable { + Resource resource; + String name; + Tristate originallySelected; + Tristate selected; + + public SymbolGroup(Resource resource, String name, Tristate originallySelected, Tristate selected) { + super(); + this.resource = resource; + this.name = name; + this.originallySelected = originallySelected; + this.selected = selected; + } + + @Override + public int compareTo(SymbolGroup o) { + return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(name, o.name); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[name=" + name //$NON-NLS-1$ + + ", originally selected=" + originallySelected //$NON-NLS-1$ + + ", selected=" + selected + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + private static class ContentProviderImpl implements IStructuredContentProvider { + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public void dispose() { + } + + @Override + public Object[] getElements(Object inputElement) { + return (Object[])inputElement; + } + }; + + private static class LabelProviderImpl extends LabelProvider { + @Override + public String getText(Object element) { + return ((SymbolGroup)element).name; + } + } + + private static class CheckStateProviderImpl implements ICheckStateProvider { + @Override + public boolean isChecked(Object element) { + return ((SymbolGroup) element).selected != Tristate.NONE; + } + @Override + public boolean isGrayed(Object element) { + return ((SymbolGroup) element).selected == Tristate.SOME; + } + } + + private static Resource getCommonModel(final Collection symbols) { + try { + return Simantics.sync(new UniqueRead() { + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return getPossibleIndexRoot(graph, symbols); + } + }); + } catch (DatabaseException e) { + ErrorLogger.defaultLogError(e); + return null; + } + } + + private static Resource getPossibleIndexRoot(ReadGraph g, Collection symbols) throws DatabaseException { + Resource model = null; + for (Resource symbol : symbols) { + Resource m = getIndexRootOf(g, symbol); + if (m == null) + return null; + if (model == null) + model = m; + else if (!model.equals(m)) + return null; + } + return model; + } + + private static Resource getIndexRootOf(ReadGraph g, Resource symbol) throws DatabaseException { + return g.syncRequest(new PossibleIndexRoot(symbol)); + } + + private static SymbolGroup[] getSymbolGroups(final Collection symbols) { + try { + return Simantics.getSession().syncRequest(new Read() { + @Override + public SymbolGroup[] perform(ReadGraph g) throws DatabaseException { + return getSymbolGroups(g, symbols); + } + }); + } catch(DatabaseException e) { + e.printStackTrace(); + return NO_SYMBOL_GROUPS; + } + } + + private static SymbolGroup[] getSymbolGroups(ReadGraph g, Collection symbols) throws DatabaseException { + Resource model = getPossibleIndexRoot(g, symbols); + if (model == null) + return NO_SYMBOL_GROUPS; + // All symbols have same model. + // Resolve the symbol group selection states now. + ArrayList result = new ArrayList(); + DiagramResource DIA = DiagramResource.getInstance(g); + for (Resource library : GetSymbolGroups.getSymbolGroups(g, model)) { + Tristate selected = getLibrarySelectionState(g, library, symbols, DIA); + selected = selected != null ? selected : Tristate.NONE; + result.add( new SymbolGroup( + library, + NameUtils.getSafeLabel(g, library), + selected, + selected) ); + } + //System.out.println("result: " + EString.implode(result)); + Collections.sort(result); + //System.out.println("sorted result: " + EString.implode(result)); + return result.toArray(new SymbolGroup[result.size()]); + } + + protected static Tristate getLibrarySelectionState(ReadGraph graph, Resource library, + Collection symbols, DiagramResource DIA) throws DatabaseException { + Tristate selected = null; + for (Resource symbol : symbols) { + selected = Tristate.add(selected, graph.hasStatement(library, DIA.HasSymbol, symbol)); + } + return selected != null ? selected : Tristate.NONE; + } + + private static SymbolGroup[] selectedElements(SymbolGroup[] symbolGroups) { + int count = 0; + for(SymbolGroup g : symbolGroups) + if(g.selected != Tristate.NONE) + ++count; + SymbolGroup[] result = new SymbolGroup[count]; + count = 0; + for(SymbolGroup g : symbolGroups) + if(g.selected != Tristate.NONE) + result[count++] = g; + return result; + } + + public void assignGroups(final Collection symbols) { + if (symbols.isEmpty()) + return; + + final Resource model = getCommonModel(symbols); + if (model == null) { + ShowMessage.showInformation(Messages.AssignSymbolGroup_SameModelRequired, Messages.AssignSymbolGroup_SameModelRequiredMsg); + return; + } + + final AtomicReference groups = + new AtomicReference( getSymbolGroups(symbols) ); + + String message = symbols.size() > 1 + ? NLS.bind(Messages.AssignSymbolGroup_SelectSymbolGroupsTheSelectedSymbolsAreShownIn, symbols.size()) + : Messages.AssignSymbolGroup_SelectSymbolGroupsTheSelectedSymbolIsShownIn; + + AssignSymbolGroupsDialog dialog = new AssignSymbolGroupsDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), + groups.get(), + new ContentProviderImpl(), + new LabelProviderImpl(), + new CheckStateProviderImpl(), + message.toString()) { + + @Override + protected void checkStateChanged(Object[] elements, boolean checked) { + for (Object _g : elements) { + SymbolGroup g = (SymbolGroup) _g; + g.selected = checked ? Tristate.ALL : Tristate.NONE; + // Refresh checked states through provider. + listViewer.refresh(); + } + } + + @Override + protected void newAction() { + SymbolGroup newGroup = newSymbolGroup(getShell(), model, (SymbolGroup[])inputElement); + if (newGroup != null) { + // Select the new library by default. + newGroup.selected = Tristate.ALL; + + SymbolGroup[] newGroups = (SymbolGroup[]) inputElement; + newGroups = Arrays.copyOf(newGroups, newGroups.length+1); + newGroups[newGroups.length-1] = newGroup; + Arrays.sort(newGroups); + listViewer.setInput(newGroups); + inputElement = newGroups; + groups.set(newGroups); + } + } + + @Override + protected void deleteAction(Object[] array) { + SymbolGroup[] groupsToRemove = Arrays.copyOf(array, array.length, SymbolGroup[].class); + if (removeSymbolGroups(getShell(), groupsToRemove)) { + listViewer.remove(groupsToRemove); + Set removedGroups = new HashSet(); + for (SymbolGroup removed : groupsToRemove) + removedGroups.add(removed); + List newGroups = new ArrayList(groups.get().length); + for (SymbolGroup old : groups.get()) { + if (!removedGroups.contains(old)) + newGroups.add(old); + } + groups.set( newGroups.toArray(NO_SYMBOL_GROUPS) ); + } + } + }; + dialog.setTitle(Messages.AssignSymbolGroup_SymbolGroupAssignments); + dialog.setInitialSelections(selectedElements(groups.get())); + if (dialog.open() == Dialog.OK) { + final ArrayList added = new ArrayList(); + final ArrayList removed = new ArrayList(); + for (SymbolGroup g : groups.get()) { + if (g.selected != g.originallySelected && g.selected == Tristate.ALL) + added.add(g); + if (g.selected != g.originallySelected && g.selected == Tristate.NONE) + removed.add(g); + } + if (!added.isEmpty() || !removed.isEmpty()) { + ArrayList addedSymbolGroups = new ArrayList(); + ArrayList removedSymbolGroups = new ArrayList(); + for (SymbolGroup group : added) + addedSymbolGroups.add(group.resource); + for (SymbolGroup group : removed) + removedSymbolGroups.add(group.resource); + Simantics.getSession().asyncRequest(new AssignSymbolGroupRequest(addedSymbolGroups, removedSymbolGroups, symbols)); + } + } + } + + private static SymbolGroup newSymbolGroup(Shell shell, Resource model, final SymbolGroup[] oldGroups) { + InputDialog dialog = new InputDialog(shell, + Messages.AssignSymbolGroup_NewSymbolGroup, + Messages.AssignSymbolGroup_WriteSymbolGroupName, + "NewSymbolGroup", //$NON-NLS-1$ + new IInputValidator() { + @Override + public String isValid(String newText) { + newText = newText.trim(); + if (newText.isEmpty()) + return Messages.AssignSymbolGroup_NameMustNotBeEmpty; + for (SymbolGroup g : oldGroups) + if (newText.equals(g.name)) + return Messages.AssignSymbolGroup_GroupSymbolAlreadyExists; + return null; + } + } + ); + if (dialog.open() == Dialog.OK) { + String name = dialog.getValue(); + try { + NewSymbolGroupRequest request = new NewSymbolGroupRequest(name, model); + Resource symbolGroup = Simantics.getSession().syncRequest(request); + if (symbolGroup == null) + return null; + return new SymbolGroup(symbolGroup, name, Tristate.NONE, Tristate.NONE); + } catch (DatabaseException e) { + ErrorLogger.defaultLogError(e); + return null; + } + } + return null; + } + + private boolean removeSymbolGroups(Shell shell, final SymbolGroup[] groups) { + if (groups.length == 0) + return false; + String message; + if (groups.length == 1) + message = NLS.bind(Messages.AssignSymbolGroup_AreYouSureToRemoveSymbolGroup, groups[0].name ); + else + message = NLS.bind(Messages.AssignSymbolGroup_AreYouSureToRemoveSymbolGroup1, groups.length ); + MessageDialog dialog = + new MessageDialog(shell, Messages.AssignSymbolGroup_ConfirmRemoval, null, message, MessageDialog.QUESTION, new String[] { IDialogConstants.OK_LABEL , IDialogConstants.CANCEL_LABEL }, 0); + if (dialog.open() == Dialog.OK) { + Simantics.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + for (SymbolGroup group : groups) + graph.deny(group.resource); + } + }); + return true; + } + else + return false; + } + +}