X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Factions%2FConfigureConnectionTypes.java;h=e392419c9a5ad71455a50eab51734e0c91f11a5c;hb=HEAD;hp=20bb053db057817ae9f901f72e6817b1e62333ff;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/ConfigureConnectionTypes.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/ConfigureConnectionTypes.java index 20bb053db..e392419c9 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/ConfigureConnectionTypes.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/ConfigureConnectionTypes.java @@ -1,307 +1,307 @@ -/******************************************************************************* - * 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.Collection; -import java.util.Collections; -import java.util.concurrent.atomic.AtomicReference; - -import org.eclipse.jface.dialogs.Dialog; -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.ui.PlatformUI; -import org.simantics.Simantics; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.common.request.PossibleIndexRoot; -import org.simantics.db.common.request.UniqueRead; -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.AssignConnectionTypesRequest; -import org.simantics.modeling.GetConnectionTypes; -import org.simantics.structural2.modelingRules.AllowedConnectionTypes; -import org.simantics.utils.strings.AlphanumComparator; -import org.simantics.utils.ui.ErrorLogger; -import org.simantics.utils.ui.dialogs.ShowMessage; - -/** - * @author Antti Villberg - */ -public class ConfigureConnectionTypes 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() { - assignTypes(resources); - } - }; - } - - @Override - public Runnable create(Object target) { - if(!(target instanceof Resource)) - return null; - final Resource connectionPoint = (Resource)target; - return new Runnable() { - @Override - public void run() { - assignTypes(Collections.singletonList(connectionPoint)); - } - }; - } - - private static final ConnectionType[] NO_CONNECTION_TYPES = new ConnectionType[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 ConnectionType implements Comparable { - Resource resource; - String name; - Tristate originallySelected; - Tristate selected; - - public ConnectionType(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(ConnectionType 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 ((ConnectionType)element).name; - } - } - - private static class CheckStateProviderImpl implements ICheckStateProvider { - @Override - public boolean isChecked(Object element) { - return ((ConnectionType) element).selected != Tristate.NONE; - } - @Override - public boolean isGrayed(Object element) { - return ((ConnectionType) element).selected == Tristate.SOME; - } - } - - private static Resource getCommonModel(final Collection connectionPoints) { - try { - return Simantics.sync(new UniqueRead() { - @Override - public Resource perform(ReadGraph graph) throws DatabaseException { - return getPossibleIndexRoot(graph, connectionPoints); - } - }); - } catch (DatabaseException e) { - ErrorLogger.defaultLogError(e); - return null; - } - } - - private static Resource getPossibleIndexRoot(ReadGraph g, Collection connectionPoints) throws DatabaseException { - Resource model = null; - for (Resource connectionPoint : connectionPoints) { - Resource m = getIndexRootOf(g, connectionPoint); - 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 connectionPoint) throws DatabaseException { - return g.syncRequest(new PossibleIndexRoot(connectionPoint)); - } - - private static ConnectionType[] getConnectionTypes(final Collection connectionPoints) { - try { - return Simantics.getSession().syncRequest(new Read() { - @Override - public ConnectionType[] perform(ReadGraph g) throws DatabaseException { - return getConnectionTypes(g, connectionPoints); - } - }); - } catch(DatabaseException e) { - e.printStackTrace(); - return NO_CONNECTION_TYPES; - } - } - - private static ConnectionType[] getConnectionTypes(ReadGraph g, Collection connectionPoints) throws DatabaseException { - Resource root = getPossibleIndexRoot(g, connectionPoints); - if (root == null) - return NO_CONNECTION_TYPES; - // All connection points have same index root. - // Resolve the connection type selection states now. - ArrayList result = new ArrayList(); - DiagramResource DIA = DiagramResource.getInstance(g); - for (Resource type : GetConnectionTypes.getConnectionTypes(g, root)) { - Tristate selected = getConnectionTypeSelectionState(g, type, connectionPoints, DIA); - selected = selected != null ? selected : Tristate.NONE; - result.add( new ConnectionType( - type, - NameUtils.getSafeLabel(g, type), - selected, - selected) ); - } - //System.out.println("result: " + EString.implode(result)); - Collections.sort(result); - //System.out.println("sorted result: " + EString.implode(result)); - return result.toArray(new ConnectionType[result.size()]); - } - - protected static Tristate getConnectionTypeSelectionState(ReadGraph graph, Resource connectionType, - Collection connectionPoints, DiagramResource DIA) throws DatabaseException { - Tristate selected = null; - for (Resource connectionPoint : connectionPoints) { - Collection allowed = graph.syncRequest(new AllowedConnectionTypes(connectionPoint)); - selected = Tristate.add(selected, allowed.contains(connectionType)); - } - return selected != null ? selected : Tristate.NONE; - } - - private static ConnectionType[] selectedElements(ConnectionType[] connectionTypes) { - int count = 0; - for(ConnectionType connectionType : connectionTypes) - if(connectionType.selected != Tristate.NONE) - ++count; - ConnectionType[] result = new ConnectionType[count]; - count = 0; - for(ConnectionType connectionType : connectionTypes) - if(connectionType.selected != Tristate.NONE) - result[count++] = connectionType; - return result; - } - - public void assignTypes(final Collection connectionPoints) { - if (connectionPoints.isEmpty()) - return; - - final Resource indexRoot = getCommonModel(connectionPoints); - if (indexRoot == null) { - ShowMessage.showInformation("Same Model Required", "All the selected connection points must be from within the same index root."); - return; - } - - final AtomicReference types = - new AtomicReference( getConnectionTypes(connectionPoints) ); - - StringBuilder message = new StringBuilder(); - if (connectionPoints.size() > 1) - message.append("Select connection types for the selected connection points"); - else - message.append("Select connection types for the selected connection point"); - - ConfigureConnectionTypesDialog dialog = new ConfigureConnectionTypesDialog( - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - types.get(), - new ContentProviderImpl(), - new LabelProviderImpl(), - new CheckStateProviderImpl(), - message.toString()) { - - @Override - protected void checkStateChanged(Object[] elements, boolean checked) { - for (Object _g : elements) { - ConnectionType g = (ConnectionType) _g; - g.selected = checked ? Tristate.ALL : Tristate.NONE; - // Refresh checked states through provider. - listViewer.refresh(); - } - } - - }; - dialog.setTitle("Connection Type Assignments"); - dialog.setInitialSelections(selectedElements(types.get())); - if (dialog.open() == Dialog.OK) { - final ArrayList added = new ArrayList(); - final ArrayList removed = new ArrayList(); - for (ConnectionType g : types.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 addedConnectionTypes = new ArrayList(); - ArrayList removedConnectionTypes = new ArrayList(); - for (ConnectionType type : added) - addedConnectionTypes.add(type.resource); - for (ConnectionType type : removed) - removedConnectionTypes.add(type.resource); - Simantics.getSession().asyncRequest(new AssignConnectionTypesRequest(addedConnectionTypes, removedConnectionTypes, connectionPoints)); - } - } - } - -} +/******************************************************************************* + * 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.Collection; +import java.util.Collections; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.jface.dialogs.Dialog; +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.ui.PlatformUI; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.request.UniqueRead; +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.AssignConnectionTypesRequest; +import org.simantics.modeling.GetConnectionTypes; +import org.simantics.structural2.modelingRules.AllowedConnectionTypes; +import org.simantics.utils.strings.AlphanumComparator; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.dialogs.ShowMessage; + +/** + * @author Antti Villberg + */ +public class ConfigureConnectionTypes 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() { + assignTypes(resources); + } + }; + } + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource connectionPoint = (Resource)target; + return new Runnable() { + @Override + public void run() { + assignTypes(Collections.singletonList(connectionPoint)); + } + }; + } + + private static final ConnectionType[] NO_CONNECTION_TYPES = new ConnectionType[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 ConnectionType implements Comparable { + Resource resource; + String name; + Tristate originallySelected; + Tristate selected; + + public ConnectionType(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(ConnectionType 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 ((ConnectionType)element).name; + } + } + + private static class CheckStateProviderImpl implements ICheckStateProvider { + @Override + public boolean isChecked(Object element) { + return ((ConnectionType) element).selected != Tristate.NONE; + } + @Override + public boolean isGrayed(Object element) { + return ((ConnectionType) element).selected == Tristate.SOME; + } + } + + private static Resource getCommonModel(final Collection connectionPoints) { + try { + return Simantics.sync(new UniqueRead() { + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return getPossibleIndexRoot(graph, connectionPoints); + } + }); + } catch (DatabaseException e) { + ErrorLogger.defaultLogError(e); + return null; + } + } + + private static Resource getPossibleIndexRoot(ReadGraph g, Collection connectionPoints) throws DatabaseException { + Resource model = null; + for (Resource connectionPoint : connectionPoints) { + Resource m = getIndexRootOf(g, connectionPoint); + 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 connectionPoint) throws DatabaseException { + return g.syncRequest(new PossibleIndexRoot(connectionPoint)); + } + + private static ConnectionType[] getConnectionTypes(final Collection connectionPoints) { + try { + return Simantics.getSession().syncRequest(new Read() { + @Override + public ConnectionType[] perform(ReadGraph g) throws DatabaseException { + return getConnectionTypes(g, connectionPoints); + } + }); + } catch(DatabaseException e) { + e.printStackTrace(); + return NO_CONNECTION_TYPES; + } + } + + private static ConnectionType[] getConnectionTypes(ReadGraph g, Collection connectionPoints) throws DatabaseException { + Resource root = getPossibleIndexRoot(g, connectionPoints); + if (root == null) + return NO_CONNECTION_TYPES; + // All connection points have same index root. + // Resolve the connection type selection states now. + ArrayList result = new ArrayList(); + DiagramResource DIA = DiagramResource.getInstance(g); + for (Resource type : GetConnectionTypes.getConnectionTypes(g, root)) { + Tristate selected = getConnectionTypeSelectionState(g, type, connectionPoints, DIA); + selected = selected != null ? selected : Tristate.NONE; + result.add( new ConnectionType( + type, + NameUtils.getSafeLabel(g, type), + selected, + selected) ); + } + //System.out.println("result: " + EString.implode(result)); + Collections.sort(result); + //System.out.println("sorted result: " + EString.implode(result)); + return result.toArray(new ConnectionType[result.size()]); + } + + protected static Tristate getConnectionTypeSelectionState(ReadGraph graph, Resource connectionType, + Collection connectionPoints, DiagramResource DIA) throws DatabaseException { + Tristate selected = null; + for (Resource connectionPoint : connectionPoints) { + Collection allowed = graph.syncRequest(new AllowedConnectionTypes(connectionPoint)); + selected = Tristate.add(selected, allowed.contains(connectionType)); + } + return selected != null ? selected : Tristate.NONE; + } + + private static ConnectionType[] selectedElements(ConnectionType[] connectionTypes) { + int count = 0; + for(ConnectionType connectionType : connectionTypes) + if(connectionType.selected != Tristate.NONE) + ++count; + ConnectionType[] result = new ConnectionType[count]; + count = 0; + for(ConnectionType connectionType : connectionTypes) + if(connectionType.selected != Tristate.NONE) + result[count++] = connectionType; + return result; + } + + public void assignTypes(final Collection connectionPoints) { + if (connectionPoints.isEmpty()) + return; + + final Resource indexRoot = getCommonModel(connectionPoints); + if (indexRoot == null) { + ShowMessage.showInformation(Messages.ConfigureConnectionTypes_SameModelRequired, Messages.ConfigureConnectionTypes_SameModelRequiredMsg); + return; + } + + final AtomicReference types = + new AtomicReference( getConnectionTypes(connectionPoints) ); + + StringBuilder message = new StringBuilder(); + if (connectionPoints.size() > 1) + message.append(Messages.ConfigureConnectionTypes_SelectConnectionTypeForSelectedConnectionPoints); + else + message.append(Messages.ConfigureConnectionTypes_SelectConnectionTypeForSelectedConnectionPoint); + + ConfigureConnectionTypesDialog dialog = new ConfigureConnectionTypesDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), + types.get(), + new ContentProviderImpl(), + new LabelProviderImpl(), + new CheckStateProviderImpl(), + message.toString()) { + + @Override + protected void checkStateChanged(Object[] elements, boolean checked) { + for (Object _g : elements) { + ConnectionType g = (ConnectionType) _g; + g.selected = checked ? Tristate.ALL : Tristate.NONE; + // Refresh checked states through provider. + listViewer.refresh(); + } + } + + }; + dialog.setTitle(Messages.ConfigureConnectionTypes_ConnectionTypeAssignments); + dialog.setInitialSelections(selectedElements(types.get())); + if (dialog.open() == Dialog.OK) { + final ArrayList added = new ArrayList(); + final ArrayList removed = new ArrayList(); + for (ConnectionType g : types.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 addedConnectionTypes = new ArrayList(); + ArrayList removedConnectionTypes = new ArrayList(); + for (ConnectionType type : added) + addedConnectionTypes.add(type.resource); + for (ConnectionType type : removed) + removedConnectionTypes.add(type.resource); + Simantics.getSession().asyncRequest(new AssignConnectionTypesRequest(addedConnectionTypes, removedConnectionTypes, connectionPoints)); + } + } + } + +}