From df0581fc5c479ab0555bcb1abc900ecd6b21890d Mon Sep 17 00:00:00 2001 From: Eike Stepper Date: Mon, 9 May 2022 06:24:16 +0200 Subject: [579862] Provide a way to contribute "Browse Xyz..." buttons to the "Load Resource" dialog https://bugs.eclipse.org/bugs/show_bug.cgi?id=579862--- .../org.eclipse.net4j.util.ui-feature/feature.xml | 2 +- features/org.eclipse.net4j.util.ui-feature/pom.xml | 2 +- plugins/org.eclipse.emf.cdo.ui/CDOClient1.launch | 1 + plugins/org.eclipse.emf.cdo.ui/CDOClient2.launch | 5 +- .../org.eclipse.emf.cdo.ui/META-INF/MANIFEST.MF | 36 ++--- plugins/org.eclipse.emf.cdo.ui/plugin.xml | 1 + plugins/org.eclipse.emf.cdo.ui/pom.xml | 2 +- .../ui/CDOAdapterFactoryContentProvider.java | 61 ++++++++ .../emf/cdo/internal/ui/CDOContentProvider.java | 40 ++++++ .../ui/editor/CDOActionBarContributor.java | 3 +- .../emf/cdo/internal/ui/editor/CDOEditor.java | 123 ++-------------- .../internal/ui/editor/CDOLoadResourceAction.java | 159 +++++++++++++++++++++ .../emf/cdo/ui/CDOLoadResourceProvider.java | 64 +++++++++ plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF | 52 +++---- plugins/org.eclipse.emf.cdo/pom.xml | 2 +- .../.settings/.api_filters | 8 ++ .../org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF | 34 ++--- plugins/org.eclipse.net4j.util.ui/pom.xml | 2 +- .../org/eclipse/net4j/util/ui/SafeTreeViewer.java | 90 ++++++++++++ 19 files changed, 505 insertions(+), 182 deletions(-) create mode 100644 plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/CDOAdapterFactoryContentProvider.java create mode 100644 plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOLoadResourceAction.java create mode 100644 plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOLoadResourceProvider.java create mode 100644 plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/SafeTreeViewer.java diff --git a/features/org.eclipse.net4j.util.ui-feature/feature.xml b/features/org.eclipse.net4j.util.ui-feature/feature.xml index 241dbe33ec..3fac147110 100644 --- a/features/org.eclipse.net4j.util.ui-feature/feature.xml +++ b/features/org.eclipse.net4j.util.ui-feature/feature.xml @@ -12,7 +12,7 @@ org.eclipse.emf.cdo.features org.eclipse.net4j.util.ui - 4.17.1-SNAPSHOT + 4.18.0-SNAPSHOT eclipse-feature diff --git a/plugins/org.eclipse.emf.cdo.ui/CDOClient1.launch b/plugins/org.eclipse.emf.cdo.ui/CDOClient1.launch index 698de05b35..5e1fcc81fc 100644 --- a/plugins/org.eclipse.emf.cdo.ui/CDOClient1.launch +++ b/plugins/org.eclipse.emf.cdo.ui/CDOClient1.launch @@ -55,6 +55,7 @@ + diff --git a/plugins/org.eclipse.emf.cdo.ui/CDOClient2.launch b/plugins/org.eclipse.emf.cdo.ui/CDOClient2.launch index 3f953b41ba..f4b0def6b1 100644 --- a/plugins/org.eclipse.emf.cdo.ui/CDOClient2.launch +++ b/plugins/org.eclipse.emf.cdo.ui/CDOClient2.launch @@ -5,11 +5,11 @@ - + - + @@ -55,6 +55,7 @@ + diff --git a/plugins/org.eclipse.emf.cdo.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.ui/META-INF/MANIFEST.MF index 7db4d1f2e5..111a655eab 100644 --- a/plugins/org.eclipse.emf.cdo.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.emf.cdo.ui;singleton:=true -Bundle-Version: 4.12.0.qualifier +Bundle-Version: 4.13.0.qualifier Bundle-Activator: org.eclipse.emf.cdo.internal.ui.bundle.OM$Activator Bundle-Vendor: %providerName Bundle-ClassPath: . @@ -29,7 +29,7 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)";reso org.eclipse.emf.ecp.ui.view.swt;bundle-version="[1.5.0,2.0.0)";resolution:=optional;x-installation:=greedy, org.eclipse.jdt.ui;bundle-version="[3.5.0,4.0.0)";resolution:=optional, org.eclipse.ui.editors;bundle-version="[3.5.0,4.0.0)";resolution:=optional -Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; +Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -38,7 +38,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.actions;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.actions;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -47,7 +47,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.handlers;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.handlers;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -56,9 +56,9 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.actions.delegates;version="4.12.0";x-internal:=true, - org.eclipse.emf.cdo.internal.ui.bundle;version="4.12.0";x-internal:=true, - org.eclipse.emf.cdo.internal.ui.dialogs;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.actions.delegates;version="4.13.0";x-internal:=true, + org.eclipse.emf.cdo.internal.ui.bundle;version="4.13.0";x-internal:=true, + org.eclipse.emf.cdo.internal.ui.dialogs;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -67,7 +67,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.dnd;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.dnd;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -76,7 +76,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.editor;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.editor;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -85,7 +85,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.filters;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.filters;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -94,7 +94,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.history;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.history;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -103,7 +103,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.messages;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.messages;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -112,7 +112,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.perspectives;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.perspectives;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -121,7 +121,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.preferences;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.preferences;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -130,7 +130,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.transfer;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.transfer;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -139,7 +139,7 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.internal.ui.views;version="4.12.0"; + org.eclipse.emf.cdo.internal.ui.views;version="4.13.0"; x-friends:="org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.ui.location, org.eclipse.emf.cdo.tests.ui, @@ -148,6 +148,6 @@ Export-Package: org.eclipse.emf.cdo.internal.ui;version="4.12.0"; org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.ui.team, org.eclipse.emf.cdo.ui.compare", - org.eclipse.emf.cdo.ui;version="4.12.0", - org.eclipse.emf.cdo.ui.widgets;version="4.12.0" + org.eclipse.emf.cdo.ui;version="4.13.0", + org.eclipse.emf.cdo.ui.widgets;version="4.13.0" Automatic-Module-Name: org.eclipse.emf.cdo.ui diff --git a/plugins/org.eclipse.emf.cdo.ui/plugin.xml b/plugins/org.eclipse.emf.cdo.ui/plugin.xml index 3fde41070e..5793223abb 100644 --- a/plugins/org.eclipse.emf.cdo.ui/plugin.xml +++ b/plugins/org.eclipse.emf.cdo.ui/plugin.xml @@ -17,6 +17,7 @@ + diff --git a/plugins/org.eclipse.emf.cdo.ui/pom.xml b/plugins/org.eclipse.emf.cdo.ui/pom.xml index 8f829f8741..8ddb2cc05a 100644 --- a/plugins/org.eclipse.emf.cdo.ui/pom.xml +++ b/plugins/org.eclipse.emf.cdo.ui/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo org.eclipse.emf.cdo.ui - 4.12.0-SNAPSHOT + 4.13.0-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/CDOAdapterFactoryContentProvider.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/CDOAdapterFactoryContentProvider.java new file mode 100644 index 0000000000..1b63726595 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/CDOAdapterFactoryContentProvider.java @@ -0,0 +1,61 @@ +package org.eclipse.emf.cdo.internal.ui; + +import org.eclipse.emf.cdo.internal.ui.bundle.OM; + +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; + +import org.eclipse.jface.viewers.Viewer; + +/** + * @author Eike Stepper + */ +public class CDOAdapterFactoryContentProvider extends AdapterFactoryContentProvider +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDOAdapterFactoryContentProvider.class); + + public CDOAdapterFactoryContentProvider(AdapterFactory adapterFactory) + { + super(adapterFactory); + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) + { + super.inputChanged(viewer, oldInput, newInput); + + if (viewer != null) + { + viewerRefresh = new RunnableViewerRefresh(viewer); + } + else + { + viewerRefresh = null; + } + } + + public RunnableViewerRefresh getViewerRefresh() + { + return (RunnableViewerRefresh)viewerRefresh; + } + + @Override + public boolean hasChildren(Object object) + { + try + { + return super.hasChildren(object); + } + catch (Exception ex) + { + if (TRACER.isEnabled()) + { + TRACER.trace(ex); + } + + return false; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/CDOContentProvider.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/CDOContentProvider.java index e7e6975495..fac93d8ecf 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/CDOContentProvider.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/CDOContentProvider.java @@ -741,4 +741,44 @@ public abstract class CDOContentProvider implements ITreeContentProvide { Opening, Open, Closed } + + /** + * @author Eike Stepper + */ + public static abstract class ContextFree extends CDOContentProvider + { + public ContextFree() + { + } + + @Override + protected boolean isContext(Object object) + { + return false; + } + + @Override + protected ContextState getContextState(Object context) + { + throw new UnsupportedOperationException(); + } + + @Override + protected void openContext(Object context) + { + throw new UnsupportedOperationException(); + } + + @Override + protected void closeContext(Object context) + { + throw new UnsupportedOperationException(); + } + + @Override + protected Object getRootObject(Object context) + { + throw new UnsupportedOperationException(); + } + } } diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOActionBarContributor.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOActionBarContributor.java index d15953de9e..54a5b3b965 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOActionBarContributor.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOActionBarContributor.java @@ -22,7 +22,6 @@ import org.eclipse.emf.edit.ui.action.ControlAction; import org.eclipse.emf.edit.ui.action.CreateChildAction; import org.eclipse.emf.edit.ui.action.CreateSiblingAction; import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor; -import org.eclipse.emf.edit.ui.action.LoadResourceAction; import org.eclipse.emf.edit.ui.action.ValidateAction; import org.eclipse.jface.action.Action; @@ -177,7 +176,7 @@ public class CDOActionBarContributor extends EditingDomainActionBarContributor i public CDOActionBarContributor() { super(ADDITIONS_LAST_STYLE); - loadResourceAction = new LoadResourceAction(); + loadResourceAction = new CDOLoadResourceAction(); loadResourceAction.setId(LOAD_RESOURCE_ID); importRootsAction = new ImportRootsAction(); diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java index e38288ca8e..cca2b0df67 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java @@ -24,6 +24,7 @@ import org.eclipse.emf.cdo.common.model.CDOPackageUnit; import org.eclipse.emf.cdo.common.model.EMFUtil; import org.eclipse.emf.cdo.common.util.CDOCommonUtil; import org.eclipse.emf.cdo.eresource.CDOResource; +import org.eclipse.emf.cdo.internal.ui.CDOAdapterFactoryContentProvider; import org.eclipse.emf.cdo.internal.ui.CDOContentProvider; import org.eclipse.emf.cdo.internal.ui.RunnableViewerRefresh; import org.eclipse.emf.cdo.internal.ui.ViewerUtil; @@ -58,6 +59,7 @@ import org.eclipse.net4j.util.collection.ConcurrentArray; import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.net4j.util.om.OMPlatform; import org.eclipse.net4j.util.om.trace.ContextTracer; +import org.eclipse.net4j.util.ui.SafeTreeViewer; import org.eclipse.net4j.util.ui.UIUtil; import org.eclipse.net4j.util.ui.actions.LongRunningAction; import org.eclipse.net4j.util.ui.actions.SafeAction; @@ -157,12 +159,10 @@ import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; @@ -1267,13 +1267,15 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv { editingDomain = (AdapterFactoryEditingDomain)domainProvider.getEditingDomain(); commandStack = editingDomain.getCommandStack(); - if (editingDomain.getAdapterFactory() instanceof ComposedAdapterFactory) + + AdapterFactory editingDomainAdapterFactory = editingDomain.getAdapterFactory(); + if (editingDomainAdapterFactory instanceof ComposedAdapterFactory) { - adapterFactory = (ComposedAdapterFactory)editingDomain.getAdapterFactory(); + adapterFactory = (ComposedAdapterFactory)editingDomainAdapterFactory; } else { - adapterFactory.addAdapterFactory(editingDomain.getAdapterFactory()); + adapterFactory.addAdapterFactory(editingDomainAdapterFactory); } } else @@ -1346,7 +1348,7 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv } Tree tree = new Tree(getContainer(), SWT.MULTI); - selectionViewer = new SafeTreeViewer(tree); + selectionViewer = new SafeTreeViewer(tree, ex -> handleException(ex)); setCurrentViewer(selectionViewer); selectionViewer.setContentProvider(createContentProvider()); @@ -1551,56 +1553,10 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv */ protected IContentProvider createContentProvider() { - class DelegateContentProvider extends AdapterFactoryContentProvider - { - public DelegateContentProvider(AdapterFactory adapterFactory) - { - super(adapterFactory); - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) - { - super.inputChanged(viewer, oldInput, newInput); - - if (viewer != null) - { - viewerRefresh = new RunnableViewerRefresh(viewer); - } - else - { - viewerRefresh = null; - } - } - - public RunnableViewerRefresh getViewerRefresh() - { - return (RunnableViewerRefresh)viewerRefresh; - } - - @Override - public boolean hasChildren(Object object) - { - try - { - return super.hasChildren(object); - } - catch (Exception ex) - { - if (TRACER.isEnabled()) - { - TRACER.trace(ex); - } - - return false; - } - } - } - - DelegateContentProvider delegate = new DelegateContentProvider(adapterFactory); - return new CDOContentProvider() { + private final CDOAdapterFactoryContentProvider delegate = new CDOAdapterFactoryContentProvider(adapterFactory); + @Override public void inputChanged(Viewer newViewer, Object oldInput, Object newInput) { @@ -3101,7 +3057,7 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv } else { - TreeViewer treeViewer = new SafeTreeViewer(parent, getTreeStyle()); + TreeViewer treeViewer = new SafeTreeViewer(parent, getTreeStyle(), ex -> handleException(ex)); treeViewer.addSelectionChangedListener(this); ReflectUtil.setValue(CONTENT_OUTLINE_PAGE_VIEWER_FIELD, this, treeViewer); } @@ -3163,63 +3119,6 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv } } - /** - * @author Eike Stepper - */ - private final class SafeTreeViewer extends TreeViewer - { - public SafeTreeViewer(Tree tree) - { - super(tree); - } - - public SafeTreeViewer(Composite parent, int style) - { - super(parent, style); - } - - @Override - protected void doUpdateItem(Widget widget, Object element, boolean fullMap) - { - try - { - super.doUpdateItem(widget, element, fullMap); - } - catch (Exception ex) - { - handleException(ex); - } - } - - @Override - protected void doUpdateItem(final Item item, Object element) - { - try - { - super.doUpdateItem(item, element); - } - catch (Exception ex) - { - handleException(ex); - } - } - - @Override - public boolean isExpandable(Object element) - { - try - { - return super.isExpandable(element); - } - catch (Exception ex) - { - - handleException(ex); - return false; - } - } - } - /** * @author Eike Stepper */ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOLoadResourceAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOLoadResourceAction.java new file mode 100644 index 0000000000..e94420568d --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOLoadResourceAction.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2022 Eike Stepper (Loehne, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.internal.ui.editor; + +import org.eclipse.emf.cdo.ui.CDOLoadResourceProvider; + +import org.eclipse.net4j.util.ObjectUtil; +import org.eclipse.net4j.util.container.IPluginContainer; + +import org.eclipse.emf.common.EMFPlugin; +import org.eclipse.emf.common.ui.CommonUIPlugin; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.edit.ui.action.LoadResourceAction; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.widgets.WidgetFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; + +import java.util.List; + +/** + * @author Eike Stepper + */ +public class CDOLoadResourceAction extends LoadResourceAction +{ + public CDOLoadResourceAction() + { + } + + public CDOLoadResourceAction(EditingDomain domain) + { + super(domain); + } + + @Override + public void run() + { + LoadResourceDialog dialog = new CDOLoadResourceDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), domain); + dialog.open(); + } + + /** + * @author Eike Stepper + */ + public static class CDOLoadResourceDialog extends LoadResourceDialog + { + public CDOLoadResourceDialog(Shell parent, EditingDomain domain) + { + super(parent, domain); + } + + @Override + protected Control createDialogArea(Composite parent) + { + Shell shell = getShell(); + boolean multi = isMulti(); + + ResourceSet resourceSet = domain.getResourceSet(); + List providers = CDOLoadResourceProvider.Factory.getProviders(IPluginContainer.INSTANCE, resourceSet); + + // Create a composite with standard margins and spacing. + GridLayout areaLayout = new GridLayout(); + areaLayout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); + areaLayout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); + areaLayout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); + areaLayout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); + areaLayout.numColumns = 1 // resourceURILabel + + 1 // browseFileSystemButton + + (EMFPlugin.IS_RESOURCES_BUNDLE_AVAILABLE ? 1 : 0) // browseWorkspaceButton + + providers.size(); // Provider buttons + + Composite composite = WidgetFactory.composite(SWT.NONE).layout(areaLayout).layoutData(new GridData(GridData.FILL_BOTH)).create(parent); + applyDialogFont(composite); + + Label resourceURILabel = new Label(composite, SWT.LEFT); + resourceURILabel.setText(CommonUIPlugin.INSTANCE.getString(multi ? "_UI_ResourceURIs_label" : "_UI_ResourceURI_label")); + resourceURILabel.setLayoutData(GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).create()); + + Button browseFileSystemButton = new Button(composite, SWT.PUSH); + browseFileSystemButton.setText(CommonUIPlugin.INSTANCE.getString("_UI_BrowseFileSystem_label")); + browseFileSystemButton.setLayoutData(GridDataFactory.fillDefaults().create()); + prepareBrowseFileSystemButton(browseFileSystemButton); + + if (EMFPlugin.IS_RESOURCES_BUNDLE_AVAILABLE) + { + Button browseWorkspaceButton = new Button(composite, SWT.PUSH); + browseWorkspaceButton.setText(CommonUIPlugin.INSTANCE.getString("_UI_BrowseWorkspace_label")); + browseWorkspaceButton.setLayoutData(GridDataFactory.fillDefaults().create()); + prepareBrowseWorkspaceButton(browseWorkspaceButton); + } + + for (CDOLoadResourceProvider provider : providers) + { + Button button = new Button(composite, SWT.PUSH); + button.setText(provider.getButtonText(resourceSet)); + button.setLayoutData(GridDataFactory.fillDefaults().create()); + button.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + List uris = provider.browseResources(resourceSet, shell, multi); + if (ObjectUtil.isEmpty(uris)) + { + return; + } + + if (multi) + { + StringBuilder builder = new StringBuilder(); + + for (URI uri : uris) + { + builder.append(uri.toString()); + builder.append(" "); + } + + uriField.setText((uriField.getText() + " " + builder.toString()).trim()); + } + else + { + uriField.setText(uris.get(0).toString()); + } + } + }); + } + + uriField = new Text(composite, SWT.BORDER); + uriField.setLayoutData(GridDataFactory.fillDefaults().span(areaLayout.numColumns, 1).grab(true, false).create()); + + Label separatorLabel = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + separatorLabel.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); + + return composite; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOLoadResourceProvider.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOLoadResourceProvider.java new file mode 100644 index 0000000000..9bf4ef0ad3 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOLoadResourceProvider.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Eike Stepper (Loehne, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.ui; + +import org.eclipse.net4j.util.container.IManagedContainer; +import org.eclipse.net4j.util.factory.ProductCreationException; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.ResourceSet; + +import org.eclipse.swt.widgets.Shell; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Eike Stepper + * @since 4.13 + */ +public interface CDOLoadResourceProvider +{ + public String getButtonText(ResourceSet resourceSet); + + public boolean canHandle(ResourceSet resourceSet); + + public List browseResources(ResourceSet resourceSet, Shell shell, boolean multi); + + /** + * @author Eike Stepper + */ + public static abstract class Factory extends org.eclipse.net4j.util.factory.Factory + { + public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.ui.loadResourceProviders"; + + public Factory(String type) + { + super(PRODUCT_GROUP, type); + } + + @Override + public abstract CDOLoadResourceProvider create(String description) throws ProductCreationException; + + public static List getProviders(IManagedContainer container, ResourceSet resourceSet) + { + List providers = new ArrayList<>(); + container.forEachElement(PRODUCT_GROUP, CDOLoadResourceProvider.class, provider -> { + if (provider.canHandle(resourceSet)) + { + providers.add(provider); + } + }); + + return providers; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF index d544aa9f9f..715c2295e3 100644 --- a/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.emf.cdo; singleton:=true -Bundle-Version: 4.17.0.qualifier +Bundle-Version: 4.17.1.qualifier Bundle-ClassPath: . Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -10,28 +10,28 @@ Bundle-Activator: org.eclipse.emf.internal.cdo.bundle.Activator$Implementation Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)";resolution:=optional, org.eclipse.emf.cdo.common;bundle-version="[4.0.0,5.0.0)";visibility:=reexport -Export-Package: org.eclipse.emf.cdo;version="4.17.0", - org.eclipse.emf.cdo.eresource;version="4.17.0", - org.eclipse.emf.cdo.eresource.impl;version="4.17.0", - org.eclipse.emf.cdo.eresource.util;version="4.17.0", - org.eclipse.emf.cdo.eresource.validation;version="4.17.0", - org.eclipse.emf.cdo.etypes;version="4.17.0", - org.eclipse.emf.cdo.etypes.impl;version="4.17.0", - org.eclipse.emf.cdo.etypes.util;version="4.17.0", - org.eclipse.emf.cdo.session;version="4.17.0", - org.eclipse.emf.cdo.session.remote;version="4.17.0", - org.eclipse.emf.cdo.transaction;version="4.17.0", - org.eclipse.emf.cdo.util;version="4.17.0", - org.eclipse.emf.cdo.view;version="4.17.0", - org.eclipse.emf.internal.cdo;version="4.17.0", - org.eclipse.emf.internal.cdo.analyzer;version="4.17.0"; +Export-Package: org.eclipse.emf.cdo;version="4.17.1", + org.eclipse.emf.cdo.eresource;version="4.17.1", + org.eclipse.emf.cdo.eresource.impl;version="4.17.1", + org.eclipse.emf.cdo.eresource.util;version="4.17.1", + org.eclipse.emf.cdo.eresource.validation;version="4.17.1", + org.eclipse.emf.cdo.etypes;version="4.17.1", + org.eclipse.emf.cdo.etypes.impl;version="4.17.1", + org.eclipse.emf.cdo.etypes.util;version="4.17.1", + org.eclipse.emf.cdo.session;version="4.17.1", + org.eclipse.emf.cdo.session.remote;version="4.17.1", + org.eclipse.emf.cdo.transaction;version="4.17.1", + org.eclipse.emf.cdo.util;version="4.17.1", + org.eclipse.emf.cdo.view;version="4.17.1", + org.eclipse.emf.internal.cdo;version="4.17.1", + org.eclipse.emf.internal.cdo.analyzer;version="4.17.1"; x-friends:="org.eclipse.emf.cdo.net4j, org.eclipse.emf.cdo.server, org.eclipse.emf.cdo.tests, org.eclipse.emf.cdo.ui", - org.eclipse.emf.internal.cdo.bundle;version="4.17.0";x-friends:="org.eclipse.emf.cdo.ui", - org.eclipse.emf.internal.cdo.messages;version="4.17.0";x-internal:=true, - org.eclipse.emf.internal.cdo.object;version="4.17.0"; + org.eclipse.emf.internal.cdo.bundle;version="4.17.1";x-friends:="org.eclipse.emf.cdo.ui", + org.eclipse.emf.internal.cdo.messages;version="4.17.1";x-internal:=true, + org.eclipse.emf.internal.cdo.object;version="4.17.1"; x-friends:="org.eclipse.emf.cdo.net4j, org.eclipse.emf.cdo.server, org.eclipse.emf.cdo.tests, @@ -40,12 +40,12 @@ Export-Package: org.eclipse.emf.cdo;version="4.17.0", org.eclipse.emf.cdo.explorer, org.eclipse.emf.cdo.explorer.ui, org.eclipse.emf.cdo.edit", - org.eclipse.emf.internal.cdo.query;version="4.17.0"; + org.eclipse.emf.internal.cdo.query;version="4.17.1"; x-friends:="org.eclipse.emf.cdo.net4j, org.eclipse.emf.cdo.server, org.eclipse.emf.cdo.tests, org.eclipse.emf.cdo.ui", - org.eclipse.emf.internal.cdo.session;version="4.17.0"; + org.eclipse.emf.internal.cdo.session;version="4.17.1"; x-friends:="org.eclipse.emf.cdo.net4j, org.eclipse.emf.cdo.server, org.eclipse.emf.cdo.tests, @@ -55,23 +55,23 @@ Export-Package: org.eclipse.emf.cdo;version="4.17.0", org.eclipse.emf.cdo.security.ui, org.eclipse.emf.cdo.explorer, org.eclipse.emf.cdo.explorer.ui", - org.eclipse.emf.internal.cdo.session.remote;version="4.17.0"; + org.eclipse.emf.internal.cdo.session.remote;version="4.17.1"; x-friends:="org.eclipse.emf.cdo.net4j, org.eclipse.emf.cdo.server, org.eclipse.emf.cdo.tests, org.eclipse.emf.cdo.ui", - org.eclipse.emf.internal.cdo.transaction;version="4.17.0"; + org.eclipse.emf.internal.cdo.transaction;version="4.17.1"; x-friends:="org.eclipse.emf.cdo.net4j, org.eclipse.emf.cdo.server, org.eclipse.emf.cdo.tests, org.eclipse.emf.cdo.ui, org.eclipse.emf.cdo.explorer.ui", - org.eclipse.emf.internal.cdo.util;version="4.17.0"; + org.eclipse.emf.internal.cdo.util;version="4.17.1"; x-friends:="org.eclipse.emf.cdo.net4j, org.eclipse.emf.cdo.server, org.eclipse.emf.cdo.tests, org.eclipse.emf.cdo.ui", - org.eclipse.emf.internal.cdo.view;version="4.17.0"; + org.eclipse.emf.internal.cdo.view;version="4.17.1"; x-friends:="org.eclipse.emf.cdo.net4j, org.eclipse.emf.cdo.server, org.eclipse.emf.cdo.tests, @@ -79,6 +79,6 @@ Export-Package: org.eclipse.emf.cdo;version="4.17.0", org.eclipse.emf.cdo.ui.ide, org.eclipse.emf.cdo.explorer, org.eclipse.emf.cdo.explorer.ui", - org.eclipse.emf.spi.cdo;version="4.17.0" + org.eclipse.emf.spi.cdo;version="4.17.1" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.emf.cdo diff --git a/plugins/org.eclipse.emf.cdo/pom.xml b/plugins/org.eclipse.emf.cdo/pom.xml index b8f89557c8..7f550cb9e2 100644 --- a/plugins/org.eclipse.emf.cdo/pom.xml +++ b/plugins/org.eclipse.emf.cdo/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo org.eclipse.emf.cdo - 4.17.0-SNAPSHOT + 4.17.1-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.net4j.util.ui/.settings/.api_filters b/plugins/org.eclipse.net4j.util.ui/.settings/.api_filters index 83594dfcb7..759d464e22 100644 --- a/plugins/org.eclipse.net4j.util.ui/.settings/.api_filters +++ b/plugins/org.eclipse.net4j.util.ui/.settings/.api_filters @@ -100,6 +100,14 @@ + + + + + + + + diff --git a/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF index 5b7f09a212..8ae693a98a 100644 --- a/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.net4j.util.ui;singleton:=true -Bundle-Version: 3.14.0.qualifier +Bundle-Version: 3.15.0.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-ActivationPolicy: lazy @@ -15,20 +15,20 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui;bundle-version="[3.5.0,4.0.0)";visibility:=reexport, org.eclipse.net4j.util;bundle-version="[3.0.0,4.0.0)";visibility:=reexport, org.eclipse.net4j.ui.shared;bundle-version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.net4j.util.internal.ui;version="3.14.0";x-internal:=true, - org.eclipse.net4j.util.internal.ui.actions;version="3.14.0";x-internal:=true, - org.eclipse.net4j.util.internal.ui.bundle;version="3.14.0";x-internal:=true, - org.eclipse.net4j.util.internal.ui.messages;version="3.14.0";x-internal:=true, - org.eclipse.net4j.util.internal.ui.views;version="3.14.0";x-internal:=true, - org.eclipse.net4j.util.ui;version="3.14.0", - org.eclipse.net4j.util.ui.actions;version="3.14.0", - org.eclipse.net4j.util.ui.confirmation;version="3.14.0", - org.eclipse.net4j.util.ui.container;version="3.14.0", - org.eclipse.net4j.util.ui.dnd;version="3.14.0", - org.eclipse.net4j.util.ui.handlers;version="3.14.0", - org.eclipse.net4j.util.ui.prefs;version="3.14.0", - org.eclipse.net4j.util.ui.proposals;version="3.14.0", - org.eclipse.net4j.util.ui.security;version="3.14.0", - org.eclipse.net4j.util.ui.views;version="3.14.0", - org.eclipse.net4j.util.ui.widgets;version="3.14.0" +Export-Package: org.eclipse.net4j.util.internal.ui;version="3.15.0";x-internal:=true, + org.eclipse.net4j.util.internal.ui.actions;version="3.15.0";x-internal:=true, + org.eclipse.net4j.util.internal.ui.bundle;version="3.15.0";x-internal:=true, + org.eclipse.net4j.util.internal.ui.messages;version="3.15.0";x-internal:=true, + org.eclipse.net4j.util.internal.ui.views;version="3.15.0";x-internal:=true, + org.eclipse.net4j.util.ui;version="3.15.0", + org.eclipse.net4j.util.ui.actions;version="3.15.0", + org.eclipse.net4j.util.ui.confirmation;version="3.15.0", + org.eclipse.net4j.util.ui.container;version="3.15.0", + org.eclipse.net4j.util.ui.dnd;version="3.15.0", + org.eclipse.net4j.util.ui.handlers;version="3.15.0", + org.eclipse.net4j.util.ui.prefs;version="3.15.0", + org.eclipse.net4j.util.ui.proposals;version="3.15.0", + org.eclipse.net4j.util.ui.security;version="3.15.0", + org.eclipse.net4j.util.ui.views;version="3.15.0", + org.eclipse.net4j.util.ui.widgets;version="3.15.0" Automatic-Module-Name: org.eclipse.net4j.util.ui diff --git a/plugins/org.eclipse.net4j.util.ui/pom.xml b/plugins/org.eclipse.net4j.util.ui/pom.xml index 7fd227eda2..5d061df521 100644 --- a/plugins/org.eclipse.net4j.util.ui/pom.xml +++ b/plugins/org.eclipse.net4j.util.ui/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo org.eclipse.net4j.util.ui - 3.14.0-SNAPSHOT + 3.15.0-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/SafeTreeViewer.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/SafeTreeViewer.java new file mode 100644 index 0000000000..b7b0d832f5 --- /dev/null +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/SafeTreeViewer.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2022 Eike Stepper (Loehne, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.net4j.util.ui; + +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.Widget; + +import java.util.function.Consumer; + +/** + * @author Eike Stepper + * @since 3.15 + */ +public class SafeTreeViewer extends TreeViewer +{ + private final Consumer exceptionHandler; + + public SafeTreeViewer(Tree tree, Consumer exceptionHandler) + { + super(tree); + this.exceptionHandler = exceptionHandler; + } + + public SafeTreeViewer(Composite parent, int style, Consumer exceptionHandler) + { + super(parent, style); + this.exceptionHandler = exceptionHandler; + } + + @Override + protected void doUpdateItem(Widget widget, Object element, boolean fullMap) + { + try + { + super.doUpdateItem(widget, element, fullMap); + } + catch (Exception ex) + { + if (exceptionHandler != null) + { + exceptionHandler.accept(ex); + } + } + } + + @Override + protected void doUpdateItem(Item item, Object element) + { + try + { + super.doUpdateItem(item, element); + } + catch (Exception ex) + { + if (exceptionHandler != null) + { + exceptionHandler.accept(ex); + } + } + } + + @Override + public boolean isExpandable(Object element) + { + try + { + return super.isExpandable(element); + } + catch (Exception ex) + { + if (exceptionHandler != null) + { + exceptionHandler.accept(ex); + } + + return false; + } + } +} -- cgit v1.2.3