Skip to content
Snippets Groups Projects
Commit 51f1f321 authored by Florian Hölzl's avatar Florian Hölzl
Browse files

implemented close editors on delete feature

renamed ProjectRootElementUtils -> ModelElementUtils
refs 309
parent e9f1964c
No related branches found
No related tags found
No related merge requests found
Showing
with 152 additions and 25 deletions
...@@ -19,19 +19,31 @@ package org.fortiss.tooling.kernel.ui.internal; ...@@ -19,19 +19,31 @@ package org.fortiss.tooling.kernel.ui.internal;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.EventObject;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.conqat.lib.commons.collections.CollectionUtils; import org.conqat.lib.commons.collections.CollectionUtils;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EObject;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException; import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI; import org.eclipse.ui.PlatformUI;
import org.fortiss.tooling.kernel.ToolingKernelActivator; import org.fortiss.tooling.kernel.ToolingKernelActivator;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.service.ICommandStackService;
import org.fortiss.tooling.kernel.service.IPersistencyService;
import org.fortiss.tooling.kernel.service.base.EObjectAwareServiceBase; import org.fortiss.tooling.kernel.service.base.EObjectAwareServiceBase;
import org.fortiss.tooling.kernel.ui.extension.IModelEditorBinding; import org.fortiss.tooling.kernel.ui.extension.IModelEditorBinding;
import org.fortiss.tooling.kernel.ui.internal.editor.ExtendableMultiPageEditor; import org.fortiss.tooling.kernel.ui.internal.editor.ExtendableMultiPageEditor;
import org.fortiss.tooling.kernel.ui.internal.editor.ModelElementEditorInput; import org.fortiss.tooling.kernel.ui.internal.editor.ModelElementEditorInput;
import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService; import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService;
import org.fortiss.tooling.kernel.utils.LoggingUtils; import org.fortiss.tooling.kernel.utils.LoggingUtils;
import org.fortiss.tooling.kernel.utils.ModelElementUtils;
/** /**
* This class implements the {@link IModelEditorBindingService} interface. * This class implements the {@link IModelEditorBindingService} interface.
...@@ -43,7 +55,7 @@ import org.fortiss.tooling.kernel.utils.LoggingUtils; ...@@ -43,7 +55,7 @@ import org.fortiss.tooling.kernel.utils.LoggingUtils;
*/ */
public class ModelEditorBindingService extends public class ModelEditorBindingService extends
EObjectAwareServiceBase<IModelEditorBinding<EObject>> implements EObjectAwareServiceBase<IModelEditorBinding<EObject>> implements
IModelEditorBindingService { IModelEditorBindingService, IPartListener, CommandStackListener {
/** The compositor extension point ID. */ /** The compositor extension point ID. */
private static final String EXTENSION_POINT_NAME = "org.fortiss.tooling.kernel.ui.modelEditorBinding"; private static final String EXTENSION_POINT_NAME = "org.fortiss.tooling.kernel.ui.modelEditorBinding";
...@@ -54,6 +66,12 @@ public class ModelEditorBindingService extends ...@@ -54,6 +66,12 @@ public class ModelEditorBindingService extends
/** The handler class attribute name. */ /** The handler class attribute name. */
private static final String HANDLER_CLASS_ATTRIBUTE_NAME = "binding"; private static final String HANDLER_CLASS_ATTRIBUTE_NAME = "binding";
/** Stores the currently opened editors and their model elements. */
private final Map<IEditorPart, EObject> currentEditors = new HashMap<IEditorPart, EObject>();
/** Stores the command stack registrations. */
private final Map<EObject, ITopLevelElement> currentCommandStacks = new HashMap<EObject, ITopLevelElement>();
/** Constructor. */ /** Constructor. */
public ModelEditorBindingService() { public ModelEditorBindingService() {
super(); super();
...@@ -71,15 +89,26 @@ public class ModelEditorBindingService extends ...@@ -71,15 +89,26 @@ public class ModelEditorBindingService extends
return; return;
} }
try { try {
PlatformUI IEditorPart part = PlatformUI
.getWorkbench() .getWorkbench()
.getActiveWorkbenchWindow() .getActiveWorkbenchWindow()
.getActivePage() .getActivePage()
.openEditor(new ModelElementEditorInput(element), .openEditor(new ModelElementEditorInput(element),
ExtendableMultiPageEditor.ID); ExtendableMultiPageEditor.ID);
currentEditors.put(part, element);
// ensure registration with part service
IPartService service = (IPartService) part.getSite().getService(
IPartService.class);
service.addPartListener(this);
// ensure registration with command stack service
ITopLevelElement top = IPersistencyService.INSTANCE
.getTopLevelElementFor(element);
ICommandStackService.INSTANCE.addCommandStackListener(top, this);
currentCommandStacks.put(element, top);
} catch (final PartInitException e) { } catch (final PartInitException e) {
LoggingUtils.error(ToolingKernelActivator.getDefault(), LoggingUtils.error(ToolingKernelActivator.getDefault(),
"Could not open editor with ID " + ExtendableMultiPageEditor.ID, e); "Could not open editor with ID "
+ ExtendableMultiPageEditor.ID, e);
} }
} }
...@@ -126,16 +155,78 @@ public class ModelEditorBindingService extends ...@@ -126,16 +155,78 @@ public class ModelEditorBindingService extends
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void closeEditors(EObject rootElement) { public void closeEditors(EObject parentElement) {
// TODO (FH): implement for (IEditorPart editor : currentEditors.keySet()) {
EObject editedElement = currentEditors.get(editor);
// for (final IEditorPart editor : editors) { if (ModelElementUtils
// editor.getSite().getShell().getDisplay().asyncExec(new Runnable() { .isChildElementOf(editedElement, parentElement)) {
// @Override closeEditor(editor);
// public void run() { }
// editor.getSite().getPage().closeEditor(editor, false); }
// } }
// });
// } /** Closes the given editor. */
private void closeEditor(final IEditorPart editor) {
editor.getSite().getShell().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
editor.getSite().getPage().closeEditor(editor, false);
}
});
}
/** {@inheritDoc} */
@Override
public void partActivated(IWorkbenchPart part) {
// ignore
}
/** {@inheritDoc} */
@Override
public void partBroughtToTop(IWorkbenchPart part) {
// ignore
}
/** {@inheritDoc} */
@Override
public void partClosed(IWorkbenchPart part) {
if (currentEditors.containsKey(part)) {
EObject eo = currentEditors.get(part);
ITopLevelElement top = currentCommandStacks.get(eo);
currentCommandStacks.remove(eo);
currentEditors.remove(part);
// clean up command stack registration
for (IEditorPart other : currentEditors.keySet()) {
if (top == currentCommandStacks.get(currentEditors.get(other))) {
return;
}
}
// no other editor references the command stack of top anymore
ICommandStackService.INSTANCE.removeCommandStackListener(top, this);
}
}
/** {@inheritDoc} */
@Override
public void partDeactivated(IWorkbenchPart part) {
// ignore
}
/** {@inheritDoc} */
@Override
public void partOpened(IWorkbenchPart part) {
// can be ignored
}
/** {@inheritDoc} */
@Override
public void commandStackChanged(EventObject event) {
for (IEditorPart part : currentEditors.keySet()) {
ITopLevelElement top = IPersistencyService.INSTANCE
.getTopLevelElementFor(currentEditors.get(part));
if (top == null) {
closeEditor(part);
}
}
} }
} }
...@@ -114,6 +114,10 @@ public class NavigatorService implements INavigatorService, ...@@ -114,6 +114,10 @@ public class NavigatorService implements INavigatorService,
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void topLevelElementRemoved(final ITopLevelElement element) { public void topLevelElementRemoved(final ITopLevelElement element) {
if (element == null) {
return;
}
new UIJob("NavigatorServiceSafeableRefresh") { new UIJob("NavigatorServiceSafeableRefresh") {
@Override @Override
public IStatus runInUIThread(IProgressMonitor monitor) { public IStatus runInUIThread(IProgressMonitor monitor) {
...@@ -153,7 +157,9 @@ public class NavigatorService implements INavigatorService, ...@@ -153,7 +157,9 @@ public class NavigatorService implements INavigatorService,
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void refresh() { public void refresh() {
navigatorViewPart.refresh(); if (navigatorViewPart != null) {
navigatorViewPart.refresh();
}
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
...@@ -251,7 +257,7 @@ public class NavigatorService implements INavigatorService, ...@@ -251,7 +257,7 @@ public class NavigatorService implements INavigatorService,
private void saveablesChanged(int event, ITopLevelElement element, private void saveablesChanged(int event, ITopLevelElement element,
boolean force) { boolean force) {
Saveable saveable = saveables.get(element); Saveable saveable = saveables.get(element);
if (saveable != null) { if (saveable != null && navigatorViewPart != null) {
ISaveablesLifecycleListener listener = (ISaveablesLifecycleListener) PlatformUI ISaveablesLifecycleListener listener = (ISaveablesLifecycleListener) PlatformUI
.getWorkbench().getService( .getWorkbench().getService(
ISaveablesLifecycleListener.class); ISaveablesLifecycleListener.class);
......
...@@ -32,7 +32,7 @@ import org.fortiss.tooling.kernel.ui.internal.ModelEditorBindingService; ...@@ -32,7 +32,7 @@ import org.fortiss.tooling.kernel.ui.internal.ModelEditorBindingService;
* @author hoelzl * @author hoelzl
* @author $Author$ * @author $Author$
* @version $Rev$ * @version $Rev$
* @ConQAT.Rating GREEN Hash: 820B5843566C65139914E39B21E01710 * @ConQAT.Rating GREEN Hash: 6A80D8ED088608C52D21BC3F4B73BE8B
*/ */
public interface IModelEditorBindingService { public interface IModelEditorBindingService {
...@@ -43,7 +43,7 @@ public interface IModelEditorBindingService { ...@@ -43,7 +43,7 @@ public interface IModelEditorBindingService {
void openInEditor(EObject element); void openInEditor(EObject element);
/** Closes editors which depend on the given element or a sub-element. */ /** Closes editors which depend on the given element or a sub-element. */
void closeEditors(EObject rootElement); void closeEditors(EObject parentElement);
/** Returns registered editor bindings for the given {@link EObject}. */ /** Returns registered editor bindings for the given {@link EObject}. */
List<IModelEditorBinding<EObject>> getBindings(EObject element); List<IModelEditorBinding<EObject>> getBindings(EObject element);
......
...@@ -40,7 +40,7 @@ import org.fortiss.tooling.kernel.extension.IStorageProvider; ...@@ -40,7 +40,7 @@ import org.fortiss.tooling.kernel.extension.IStorageProvider;
* @author hoelzl * @author hoelzl
* @author $Author$ * @author $Author$
* @version $Rev$ * @version $Rev$
* @ConQAT.Rating GREEN Hash: 85B4A36E3F052F4BED404969E3CDB7B0 * @ConQAT.Rating GREEN Hash: 627F8F0B59A57FB8FE9CD20F70C02C7F
*/ */
public interface ITopLevelElement { public interface ITopLevelElement {
...@@ -50,7 +50,10 @@ public interface ITopLevelElement { ...@@ -50,7 +50,10 @@ public interface ITopLevelElement {
/** Executes the given {@link Runnable} as model changing command. */ /** Executes the given {@link Runnable} as model changing command. */
void runAsCommand(Runnable runner); void runAsCommand(Runnable runner);
/** Adds a command stack listener. */ /**
* Adds a command stack listener. Has no effect if an identical listener is
* already registered.
*/
void addCommandStackListener(CommandStackListener listener); void addCommandStackListener(CommandStackListener listener);
/** Removes the command stack listener. */ /** Removes the command stack listener. */
......
...@@ -41,14 +41,23 @@ public class CommandStackService implements ICommandStackService { ...@@ -41,14 +41,23 @@ public class CommandStackService implements ICommandStackService {
@Override @Override
public void addCommandStackListener(ITopLevelElement target, public void addCommandStackListener(ITopLevelElement target,
CommandStackListener listener) { CommandStackListener listener) {
target.addCommandStackListener(listener); if (target != null) {
target.addCommandStackListener(listener);
}
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void removeCommandStackListener(ITopLevelElement target, public void removeCommandStackListener(ITopLevelElement target,
CommandStackListener listener) { CommandStackListener listener) {
target.removeCommandStackListener(listener); if (target != null) {
target.removeCommandStackListener(listener);
} else {
for (ITopLevelElement top : IPersistencyService.INSTANCE
.getTopLevelElements()) {
top.removeCommandStackListener(listener);
}
}
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
......
...@@ -109,7 +109,9 @@ class ModelContext implements ITopLevelElement, CommandStackListener { ...@@ -109,7 +109,9 @@ class ModelContext implements ITopLevelElement, CommandStackListener {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void addCommandStackListener(CommandStackListener listener) { public void addCommandStackListener(CommandStackListener listener) {
listeners.add(listener); if (!listeners.contains(listener)) {
listeners.add(listener);
}
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
......
...@@ -46,7 +46,8 @@ public interface ICommandStackService { ...@@ -46,7 +46,8 @@ public interface ICommandStackService {
/** /**
* Removes the command stack listener from the stack of the given target * Removes the command stack listener from the stack of the given target
* element. * element. If the target element is <code>null</code> the listener is
* removed from all current command stacks.
*/ */
void removeCommandStackListener(ITopLevelElement target, void removeCommandStackListener(ITopLevelElement target,
CommandStackListener listener); CommandStackListener listener);
......
...@@ -36,7 +36,7 @@ import org.fortiss.tooling.kernel.service.IPersistencyService; ...@@ -36,7 +36,7 @@ import org.fortiss.tooling.kernel.service.IPersistencyService;
* @version $Rev$ * @version $Rev$
* @ConQAT.Rating GREEN Hash: AA5BFF29ABFE9DEB170DB51BDB3B5427 * @ConQAT.Rating GREEN Hash: AA5BFF29ABFE9DEB170DB51BDB3B5427
*/ */
public final class ProjectRootElementUtils { public final class ModelElementUtils {
/** /**
* Returns the instance of a project root element corresponding to the given * Returns the instance of a project root element corresponding to the given
...@@ -103,4 +103,19 @@ public final class ProjectRootElementUtils { ...@@ -103,4 +103,19 @@ public final class ProjectRootElementUtils {
} }
return null; return null;
} }
/**
* Determines if the given element is an indirect child of the given parent
* element.
*/
public static boolean isChildElementOf(EObject element,
EObject parentElement) {
while (element.eContainer() != null) {
if (element.eContainer() == parentElement) {
return true;
}
element = element.eContainer();
}
return false;
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment