org.opentcs.modeleditor.application.OpenTCSView Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) The openTCS Authors.
*
* This program is free software and subject to the MIT license. (For details,
* see the licensing information (LICENSE.txt) you should have received with
* this copy of the software.)
*/
package org.opentcs.modeleditor.application;
import static java.util.Objects.requireNonNull;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.SingleCDockable;
import bibliothek.gui.dock.common.event.CVetoClosingEvent;
import bibliothek.gui.dock.common.event.CVetoClosingListener;
import jakarta.annotation.Nullable;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.EtchedBorder;
import org.jhotdraw.app.AbstractView;
import org.jhotdraw.draw.Drawing;
import org.jhotdraw.draw.DrawingView;
import org.jhotdraw.draw.Figure;
import org.jhotdraw.gui.URIChooser;
import org.jhotdraw.util.ReversedList;
import org.opentcs.access.Kernel;
import org.opentcs.access.KernelRuntimeException;
import org.opentcs.access.KernelServicePortal;
import org.opentcs.access.SharedKernelServicePortal;
import org.opentcs.access.SharedKernelServicePortalProvider;
import org.opentcs.components.kernel.services.ServiceUnavailableException;
import org.opentcs.components.plantoverview.PlantModelExporter;
import org.opentcs.components.plantoverview.PlantModelImporter;
import org.opentcs.components.plantoverview.PluggablePanel;
import org.opentcs.components.plantoverview.PluggablePanelFactory;
import org.opentcs.customizations.ApplicationEventBus;
import org.opentcs.customizations.plantoverview.ApplicationFrame;
import org.opentcs.guing.base.components.properties.event.AttributesChangeEvent;
import org.opentcs.guing.base.components.properties.event.AttributesChangeListener;
import org.opentcs.guing.base.components.properties.type.AbstractProperty;
import org.opentcs.guing.base.components.properties.type.LengthProperty;
import org.opentcs.guing.base.event.BlockChangeEvent;
import org.opentcs.guing.base.event.BlockChangeListener;
import org.opentcs.guing.base.model.ModelComponent;
import org.opentcs.guing.base.model.PropertiesCollection;
import org.opentcs.guing.base.model.elements.BlockModel;
import org.opentcs.guing.base.model.elements.LayoutModel;
import org.opentcs.guing.base.model.elements.LinkModel;
import org.opentcs.guing.base.model.elements.LocationModel;
import org.opentcs.guing.base.model.elements.LocationTypeModel;
import org.opentcs.guing.base.model.elements.PathModel;
import org.opentcs.guing.base.model.elements.PointModel;
import org.opentcs.guing.base.model.elements.VehicleModel;
import org.opentcs.guing.common.application.ApplicationState;
import org.opentcs.guing.common.application.ComponentsManager;
import org.opentcs.guing.common.application.GuiManager;
import org.opentcs.guing.common.application.GuiManagerModeling;
import org.opentcs.guing.common.application.ModelRestorationProgressStatus;
import org.opentcs.guing.common.application.OperationMode;
import org.opentcs.guing.common.application.PluginPanelManager;
import org.opentcs.guing.common.application.ProgressIndicator;
import org.opentcs.guing.common.application.StartupProgressStatus;
import org.opentcs.guing.common.application.StatusPanel;
import org.opentcs.guing.common.components.dockable.DrawingViewFocusHandler;
import org.opentcs.guing.common.components.drawing.DrawingViewScrollPane;
import org.opentcs.guing.common.components.drawing.OpenTCSDrawingEditor;
import org.opentcs.guing.common.components.drawing.OpenTCSDrawingView;
import org.opentcs.guing.common.components.drawing.course.Origin;
import org.opentcs.guing.common.components.drawing.course.OriginChangeListener;
import org.opentcs.guing.common.components.drawing.figures.FigureConstants;
import org.opentcs.guing.common.components.drawing.figures.LabeledFigure;
import org.opentcs.guing.common.components.drawing.figures.SimpleLineConnection;
import org.opentcs.guing.common.components.drawing.figures.TCSFigure;
import org.opentcs.guing.common.components.layer.LayerManager;
import org.opentcs.guing.common.components.properties.SelectionPropertiesComponent;
import org.opentcs.guing.common.components.properties.panel.PropertiesPanelFactory;
import org.opentcs.guing.common.components.tree.BlocksTreeViewManager;
import org.opentcs.guing.common.components.tree.ComponentsTreeViewManager;
import org.opentcs.guing.common.components.tree.TreeViewManager;
import org.opentcs.guing.common.components.tree.elements.ContextObject;
import org.opentcs.guing.common.components.tree.elements.UserObject;
import org.opentcs.guing.common.components.tree.elements.UserObjectContext;
import org.opentcs.guing.common.components.tree.elements.UserObjectContext.ContextType;
import org.opentcs.guing.common.components.tree.elements.UserObjectUtil;
import org.opentcs.guing.common.event.DrawingEditorEvent;
import org.opentcs.guing.common.event.DrawingEditorListener;
import org.opentcs.guing.common.event.ModelNameChangeEvent;
import org.opentcs.guing.common.event.OperationModeChangeEvent;
import org.opentcs.guing.common.event.ResetInteractionToolCommand;
import org.opentcs.guing.common.event.SystemModelTransitionEvent;
import org.opentcs.guing.common.model.SystemModel;
import org.opentcs.guing.common.persistence.ModelManager;
import org.opentcs.guing.common.util.ModelComponentFactory;
import org.opentcs.guing.common.util.PanelRegistry;
import org.opentcs.guing.common.util.UserMessageHelper;
import org.opentcs.modeleditor.application.action.ToolBarManager;
import org.opentcs.modeleditor.application.action.ViewActionMap;
import org.opentcs.modeleditor.components.dockable.DockingManagerModeling;
import org.opentcs.modeleditor.components.drawing.DrawingViewFactory;
import org.opentcs.modeleditor.components.layer.LayerEditorEventHandler;
import org.opentcs.modeleditor.persistence.ModelManagerModeling;
import org.opentcs.modeleditor.util.Colors;
import org.opentcs.modeleditor.util.I18nPlantOverviewModeling;
import org.opentcs.modeleditor.util.UniqueNameGenerator;
import org.opentcs.thirdparty.guing.common.jhotdraw.application.action.edit.UndoRedoManager;
import org.opentcs.thirdparty.guing.common.jhotdraw.application.toolbar.PaletteToolBarBorder;
import org.opentcs.thirdparty.guing.common.jhotdraw.components.drawing.AbstractOpenTCSDrawingView;
import org.opentcs.thirdparty.guing.common.jhotdraw.util.ResourceBundleUtil;
import org.opentcs.thirdparty.modeleditor.jhotdraw.application.action.file.CloseFileAction;
import org.opentcs.thirdparty.modeleditor.jhotdraw.components.drawing.OpenTCSDrawingViewModeling;
import org.opentcs.util.event.EventBus;
import org.opentcs.util.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Visualizes the driving course and other kernel objects as well as messages
* received by the kernel.
* (Contains everything underneath the tool bars.)
*/
public class OpenTCSView
extends
AbstractView
implements
GuiManager,
GuiManagerModeling,
ComponentsManager,
PluginPanelManager,
EventHandler {
/**
* The name/title of this application.
*/
public static final String NAME
= ResourceBundleUtil.getBundle(I18nPlantOverviewModeling.MISC_PATH)
.getString("openTcsView.applicationName.text");
/**
* Property key for the currently loaded driving course model.
* The corresponding value contains a "*" if the model has been modified.
*/
public static final String MODELNAME_PROPERTY = "modelName";
/**
* This class's logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(OpenTCSView.class);
/**
* This instance's resource bundle.
*/
private final ResourceBundleUtil bundle
= ResourceBundleUtil.getBundle(I18nPlantOverviewModeling.MISC_PATH);
/**
* Provides/manages the application's current state.
*/
private final ApplicationState appState;
/**
* Allows for undoing and redoing actions.
*/
private final UndoRedoManager fUndoRedoManager;
/**
* The drawing editor.
*/
private final OpenTCSDrawingEditor fDrawingEditor;
/**
* The JFrame.
*/
private final JFrame fFrame;
/**
* Utility to manage the views.
*/
private final ViewManagerModeling viewManager;
/**
* A manager for the components tree view.
*/
private final TreeViewManager fComponentsTreeManager;
/**
* A manager for the blocks tree view.
*/
private final TreeViewManager fBlocksTreeManager;
/**
* Displays properties of the currently selected model component(s).
*/
private final SelectionPropertiesComponent fPropertiesComponent;
/**
* Manages driving course models.
*/
private final ModelManagerModeling fModelManager;
/**
* Indicates the progress for lengthy operations.
*/
private final ProgressIndicator progressIndicator;
/**
* Manages docking frames.
*/
private final DockingManagerModeling dockingManager;
/**
* Registry for plugin panels.
*/
private final PanelRegistry panelRegistry;
/**
* Provides access to a portal.
*/
private final SharedKernelServicePortalProvider portalProvider;
/**
* A panel for mouse position/status.
*/
private final StatusPanel statusPanel;
/**
* The model component factory to be used.
*/
private final ModelComponentFactory modelComponentFactory;
/**
* Shows messages to the user.
*/
private final UserMessageHelper userMessageHelper;
/**
* A factory for drawing views.
*/
private final DrawingViewFactory drawingViewFactory;
/**
* Handles block events.
*/
private final BlockChangeListener blockEventHandler = new BlockEventHandler();
/**
* Handles events for changes of properties.
*/
private final AttributesChangeListener attributesEventHandler = new AttributesEventHandler();
/**
* Generates names for model objects.
*/
private final UniqueNameGenerator modelCompNameGen;
/**
* A factory for UserObject instances.
*/
private final UserObjectUtil userObjectUtil;
/**
* A provider for ActionMaps.
*/
private final Provider actionMapProvider;
/**
* A provider for the tool bar manager.
*/
private final Provider toolBarManagerProvider;
/**
* A factory for properties-related panels.
*/
private final PropertiesPanelFactory propertiesPanelFactory;
/**
* The application's event bus.
*/
private final EventBus eventBus;
/**
* Handles focussing of dockables.
*/
private final DrawingViewFocusHandler drawingViewFocusHandler;
/**
* The layer manager.
*/
private final LayerManager layerManager;
/**
* Handles drawing editor events that the layer editor needs to know about.
*/
private final LayerEditorEventHandler layerEditorEventHandler;
/**
* Provides the application's tool bars.
*/
private ToolBarManager toolBarManager;
/**
* Creates a new instance.
*
* @param appState Provides/manages the application's current state.
* @param appFrame The JFrame
this view is wrapped in.
* @param progressIndicator The progress indicator to be used.
* @param portalProvider Provides a access to a portal.
* @param viewManager The view manager to be used.
* @param tcsDrawingEditor The drawing editor to be used.
* @param modelManager The model manager to be used.
* @param statusPanel The status panel to be used.
* @param panelRegistry The plugin panel registry to be used.
* @param modelComponentFactory The model component factory to be used.
* @param userMessageHelper An UserMessageHelper
* @param drawingViewFactory A factory for drawing views.
* @param modelCompNameGen A generator for model components' names.
* @param undoRedoManager Allows for undoing and redoing actions.
* @param componentsTreeManager Manages the components tree view.
* @param blocksTreeManager Manages the blocks tree view.
* @param propertiesComponent Displays properties of the currently selected model component(s).
* @param userObjectUtil A factory for UserObject instances.
* @param actionMapProvider A provider for ActionMaps.
* @param toolBarManagerProvider A provider for the tool bar manager.
* @param propertiesPanelFactory A factory for properties-related panels.
* @param eventBus The application's event bus.
* @param dockingManager Manages docking frames.
* @param drawingViewFocusHandler Handles focussing of dockables.
* @param layerManager The layer manager.
* @param layerEditorEventHandler Handles drawing editor events that the layer editor needs to
* know about.
*/
@Inject
public OpenTCSView(
ApplicationState appState,
@ApplicationFrame
JFrame appFrame,
ProgressIndicator progressIndicator,
SharedKernelServicePortalProvider portalProvider,
ViewManagerModeling viewManager,
OpenTCSDrawingEditor tcsDrawingEditor,
ModelManagerModeling modelManager,
StatusPanel statusPanel,
PanelRegistry panelRegistry,
ModelComponentFactory modelComponentFactory,
UserMessageHelper userMessageHelper,
DrawingViewFactory drawingViewFactory,
UniqueNameGenerator modelCompNameGen,
UndoRedoManager undoRedoManager,
ComponentsTreeViewManager componentsTreeManager,
BlocksTreeViewManager blocksTreeManager,
SelectionPropertiesComponent propertiesComponent,
UserObjectUtil userObjectUtil,
Provider actionMapProvider,
Provider toolBarManagerProvider,
PropertiesPanelFactory propertiesPanelFactory,
@ApplicationEventBus
EventBus eventBus,
DockingManagerModeling dockingManager,
DrawingViewFocusHandler drawingViewFocusHandler,
LayerManager layerManager,
LayerEditorEventHandler layerEditorEventHandler
) {
this.appState = requireNonNull(appState, "appState");
this.fFrame = requireNonNull(appFrame, "appFrame");
this.progressIndicator = requireNonNull(progressIndicator, "progressIndicator");
this.portalProvider = requireNonNull(portalProvider, "portalProvider");
this.viewManager = requireNonNull(viewManager, "viewManager");
this.fDrawingEditor = requireNonNull(tcsDrawingEditor, "tcsDrawingEditor");
this.fModelManager = requireNonNull(modelManager, "modelManager");
this.statusPanel = requireNonNull(statusPanel, "statusPanel");
this.panelRegistry = requireNonNull(panelRegistry, "panelRegistry");
this.modelComponentFactory = requireNonNull(modelComponentFactory, "modelComponentFactory");
this.userMessageHelper = requireNonNull(userMessageHelper, "userMessageHelper");
this.drawingViewFactory = requireNonNull(drawingViewFactory, "drawingViewFactory");
this.modelCompNameGen = requireNonNull(modelCompNameGen, "modelCompNameGen");
this.fUndoRedoManager = requireNonNull(undoRedoManager, "undoRedoManager");
this.fComponentsTreeManager = requireNonNull(componentsTreeManager, "componentsTreeManager");
this.fBlocksTreeManager = requireNonNull(blocksTreeManager, "blocksTreeManager");
this.fPropertiesComponent = requireNonNull(propertiesComponent, "propertiesComponent");
this.userObjectUtil = requireNonNull(userObjectUtil, "userObjectUtil");
this.actionMapProvider = requireNonNull(actionMapProvider, "actionMapProvider");
this.toolBarManagerProvider = requireNonNull(toolBarManagerProvider, "toolBarManagerProvider");
this.propertiesPanelFactory = requireNonNull(propertiesPanelFactory, "propertiesPanelFactory");
this.eventBus = requireNonNull(eventBus, "eventBus");
this.dockingManager = requireNonNull(dockingManager, "dockingManager");
this.drawingViewFocusHandler = requireNonNull(
drawingViewFocusHandler,
"drawingViewFocusHandler"
);
this.layerManager = requireNonNull(layerManager, "layerManager");
this.layerEditorEventHandler = requireNonNull(
layerEditorEventHandler,
"layerEditorEventHandler"
);
}
@Override // AbstractView
public void init() {
eventBus.subscribe(this);
progressIndicator.setProgress(StartupProgressStatus.INITIALIZED);
fDrawingEditor.addDrawingEditorListener(layerEditorEventHandler);
fDrawingEditor.addDrawingEditorListener(new DrawingEditorEventHandler(fModelManager));
eventBus.subscribe(fComponentsTreeManager);
progressIndicator.setProgress(StartupProgressStatus.INITIALIZE_MODEL);
setSystemModel(fModelManager.getModel());
// Properties view (lower left corner)
fPropertiesComponent.setPropertiesContent(
propertiesPanelFactory.createPropertiesTableContent(this)
);
setActionMap(actionMapProvider.get());
this.toolBarManager = toolBarManagerProvider.get();
eventBus.subscribe(toolBarManager);
eventBus.subscribe(fPropertiesComponent);
eventBus.subscribe(fUndoRedoManager);
eventBus.subscribe(fDrawingEditor);
layerManager.initialize();
initializeFrame();
viewManager.init();
createEmptyModel();
setModelingState();
}
@Override // AbstractView
public void stop() {
LOG.info("GUI terminating...");
eventBus.unsubscribe(this);
System.exit(0);
}
@Override // AbstractView
public void clear() {
}
@Override
public void onEvent(Object event) {
if (event instanceof SystemModelTransitionEvent) {
handleSystemModelTransition((SystemModelTransitionEvent) event);
}
}
private void handleSystemModelTransition(SystemModelTransitionEvent evt) {
switch (evt.getStage()) {
case LOADED:
setHasUnsavedChanges(false);
// Update model name in title
setModelNameProperty(fModelManager.getModel().getName());
break;
default:
// Do nada.
}
}
@Override
public void showPluginPanel(PluggablePanelFactory factory, boolean visible) {
String id = factory.getClass().getName();
SingleCDockable dockable = dockingManager.getCControl().getSingleDockable(id);
if (dockable != null) {
// dockable is not null at this point when the user hides the plugin
// panel by clicking on its menu entry
PluggablePanel panel = (PluggablePanel) dockable.getFocusComponent();
panel.terminate();
if (!dockingManager.getCControl().removeDockable(dockable)) {
LOG.warn("Couldn't remove dockable for plugin panel factory '{}'", factory);
return;
}
}
if (!visible) {
return;
}
if (factory.providesPanel(Kernel.State.MODELLING)) {
PluggablePanel panel = factory.createPanel(Kernel.State.MODELLING);
DefaultSingleCDockable factoryDockable = dockingManager.createFloatingDockable(
factory.getClass().getName(),
factory.getPanelDescription(),
panel
);
factoryDockable.addVetoClosingListener(new CVetoClosingListener() {
@Override
public void closing(CVetoClosingEvent event) {
}
@Override
public void closed(CVetoClosingEvent event) {
panel.terminate();
dockingManager.getCControl().removeDockable(factoryDockable);
}
});
panel.initialize();
}
}
/**
* Adds a new drawing view to the tabbed wrappingPanel.
*
* @return The newly created Dockable.
*/
public DefaultSingleCDockable addDrawingView() {
DrawingViewScrollPane newScrollPane
= drawingViewFactory.createDrawingView(
fModelManager.getModel(),
toolBarManager.getSelectionToolButton(),
toolBarManager.getDragToolButton(),
toolBarManager.getButtonCreateLink(),
toolBarManager.getButtonCreatePath()
);
int drawingViewIndex = viewManager.getNextDrawingViewIndex();
String title
= bundle.getString("openTcsView.panel_operatingDrawingView.title") + " " + drawingViewIndex;
DefaultSingleCDockable newDockable
= dockingManager.createDockable(
"drivingCourse" + drawingViewIndex,
title,
newScrollPane,
true
);
viewManager.addDrawingView(newDockable, newScrollPane);
int lastIndex = Math.max(0, drawingViewIndex - 1);
dockingManager.addTabTo(newDockable, DockingManagerModeling.COURSE_TAB_PANE_ID, lastIndex);
newDockable.addVetoClosingListener(new DrawingViewClosingListener(newDockable));
newDockable.addFocusListener(drawingViewFocusHandler);
newScrollPane.getDrawingView().getComponent().dispatchEvent(
new FocusEvent(this, FocusEvent.FOCUS_GAINED)
);
firePropertyChange(AbstractOpenTCSDrawingView.FOCUS_GAINED, null, newDockable);
return newDockable;
}
/**
* Restores the layout to default.
*/
public void resetWindowArrangement() {
for (DefaultSingleCDockable dock : new ArrayList<>(viewManager.getDrawingViewMap().keySet())) {
removeDrawingView(dock);
}
dockingManager.reset();
closeOpenedPluginPanels();
viewManager.reset();
initializeFrame();
viewManager.init();
// Depending on the current kernel state there may exist panels, now, that shouldn't be visible.
new Thread(() -> setModelingState()).start();
}
@Override // GuiManager
public void createEmptyModel() {
CloseFileAction action = (CloseFileAction) getActionMap().get(CloseFileAction.ID);
if (action != null) {
action.actionPerformed(
new ActionEvent(
this,
ActionEvent.ACTION_PERFORMED,
CloseFileAction.ID_MODEL_CLOSING
)
);
if (action.getFileSavedStatus() == JOptionPane.CANCEL_OPTION) {
return;
}
}
// Clean up first...
eventBus.onEvent(
new SystemModelTransitionEvent(
this,
SystemModelTransitionEvent.Stage.UNLOADING,
fModelManager.getModel()
)
);
eventBus.onEvent(
new SystemModelTransitionEvent(
this,
SystemModelTransitionEvent.Stage.UNLOADED,
fModelManager.getModel()
)
);
// Create the new, empty model.
LOG.debug("Creating new driving course model...");
fModelManager.createEmptyModel();
eventBus.onEvent(
new SystemModelTransitionEvent(
this,
SystemModelTransitionEvent.Stage.LOADING,
fModelManager.getModel()
)
);
// Now let components set themselves up for the new model.
setSystemModel(fModelManager.getModel());
eventBus.onEvent(
new SystemModelTransitionEvent(
this,
SystemModelTransitionEvent.Stage.LOADED,
fModelManager.getModel()
)
);
// makes sure the origin is on the lower left side and the ruler
// are correctly drawn
fDrawingEditor.initializeViewport();
}
public void downloadModelFromKernel() {
try (SharedKernelServicePortal sharedPortal = portalProvider.register()) {
downloadModelFromKernel(sharedPortal.getPortal());
}
catch (ServiceUnavailableException exc) {
LOG.info("Kernel unavailable, aborting.", exc);
}
}
/**
* Loads the current kernel model.
*/
private void downloadModelFromKernel(KernelServicePortal portal) {
if (hasUnsavedChanges()) {
if (!showUnsavedChangesDialog()) {
return;
}
}
restoreModel(portal);
}
/**
* Initializes the model stored in the kernel or in the model manager.
*
* @param portal If not null, the model from the given kernel will be loaded, else the model from
* the model manager
*/
private void restoreModel(
@Nullable
KernelServicePortal portal
) {
progressIndicator.initialize();
progressIndicator.setProgress(ModelRestorationProgressStatus.CLEANUP);
eventBus.onEvent(
new SystemModelTransitionEvent(
this,
SystemModelTransitionEvent.Stage.UNLOADING,
fModelManager.getModel()
)
);
progressIndicator.setProgress(ModelRestorationProgressStatus.START_LOADING_MODEL);
eventBus.onEvent(
new SystemModelTransitionEvent(
this,
SystemModelTransitionEvent.Stage.UNLOADED,
fModelManager.getModel()
)
);
if (portal == null) {
fModelManager.restoreModel();
}
else {
fModelManager.restoreModel(portal);
statusPanel.setLogMessage(
Level.INFO,
bundle.getFormatted(
"openTcsView.message_modelDownloaded.text",
fModelManager.getModel().getName()
)
);
}
progressIndicator.setProgress(ModelRestorationProgressStatus.SET_UP_MODEL_VIEW);
eventBus.onEvent(
new SystemModelTransitionEvent(
this,
SystemModelTransitionEvent.Stage.LOADING,
fModelManager.getModel()
)
);
setSystemModel(fModelManager.getModel());
progressIndicator.setProgress(ModelRestorationProgressStatus.SET_UP_DIRECTORY_TREE);
progressIndicator.setProgress(ModelRestorationProgressStatus.SET_UP_WORKING_AREA);
ModelComponent layoutComponent
= fModelManager.getModel().getMainFolder(SystemModel.FolderKey.LAYOUT);
layoutComponent.addAttributesChangeListener(attributesEventHandler);
eventBus.onEvent(
new SystemModelTransitionEvent(
this, SystemModelTransitionEvent.Stage.LOADED,
fModelManager.getModel()
)
);
updateModelName();
progressIndicator.terminate();
}
private void setModelNameProperty(String modelName) {
fModelManager.getModel().setName(modelName);
eventBus.onEvent(new ModelNameChangeEvent(this, modelName));
}
public void updateModelName() {
String newName = fModelManager.getModel().getName();
eventBus.onEvent(new ModelNameChangeEvent(this, newName));
}
/**
* Adds a background image to the currently active drawing view.
*
* @param file The file with the image.
*/
public void addBackgroundBitmap(File file) {
viewManager.setBitmapToModellingView(file);
}
@Override
public List restoreModelComponents(List userObjects) {
List restoredUserObjects = new ArrayList<>();
for (UserObject userObject : userObjects) {
ModelComponent modelComponent = userObject.getModelComponent();
ModelComponent folder = fModelManager.getModel().getFolder(modelComponent);
if (folder == null) {
// Workaround: No folders should be selected in the tree!
return null;
}
if (folder.contains(modelComponent)) {
try {
// Paste after Copy: Create clones of tree components (and figures)
Figure figure = fModelManager.getModel().getFigure(modelComponent);
if (figure != null) {
if (figure instanceof LabeledFigure) {
// Point, Location
// Create new Figure with a "cloned" model
final LabeledFigure clonedFigure = (LabeledFigure) figure.clone();
// Place the figure relative to the position of the prototype
AffineTransform tx = new AffineTransform();
// TODO: Make the duplicate's distance configurable.
// TODO: With multiple pastes, place the inserted figure relative
// to the predecessor, not the original.
tx.translate(50, 50);
clonedFigure.transform(tx);
getActiveDrawingView().getDrawing().add(clonedFigure);
// The new tree component will be created by "figureAdded()"
modelComponent = clonedFigure.get(FigureConstants.MODEL);
}
else if (figure instanceof TCSFigure) {
// Vehicle, ...
TCSFigure clonedFigure = (TCSFigure) figure.clone();
modelComponent = clonedFigure.getModel();
}
}
else {
// LocationType, Block, Group
modelComponent = modelComponent.clone();
}
}
catch (CloneNotSupportedException ex) {
LOG.warn("clone() not supported for {}", modelComponent.getName());
}
}
Figure figure = fModelManager.getModel().getFigure(modelComponent);
if (figure != null
&& !getActiveDrawingView().getDrawing().contains(figure)) {
getActiveDrawingView().getDrawing().add(figure);
}
addModelComponent(folder, modelComponent);
ContextType type = null;
if (userObject instanceof ContextObject) {
ContextObject co = (ContextObject) userObject;
type = co.getContextType();
}
UserObjectContext context = userObjectUtil.createContext(type);
restoredUserObjects.add(userObjectUtil.createUserObject(modelComponent, context));
}
return restoredUserObjects;
}
@Override // View
public void write(URI f, URIChooser chooser)
throws IOException {
}
@Override // View
public void read(URI f, URIChooser chooser)
throws IOException {
}
@Override // AbstractView
public boolean canSaveTo(URI file) {
return new File(file).getName().endsWith(".xml");
}
@Override // AbstractView
public URI getURI() {
String modelName = fModelManager.getModel().getName();
try {
uri = new URI(modelName);
}
catch (URISyntaxException ex) {
LOG.warn("URISyntaxException in getURI({})", modelName, ex);
}
return uri;
}
/**
* Returns all drawing views (including the modelling view).
*
* @return List with all known OpenTCSDrawingViews
.
*/
private List getDrawingViews() {
List views = new ArrayList<>();
for (DrawingViewScrollPane scrollPane : viewManager.getDrawingViewMap().values()) {
views.add(scrollPane.getDrawingView());
}
return views;
}
@Override
public void selectModelComponent(ModelComponent modelComponent) {
fPropertiesComponent.setModel(modelComponent);
DrawingView drawingView = fDrawingEditor.getActiveView();
drawingView.clearSelection();
Figure figure = findFigure(modelComponent);
// LocationTypes don't have a figure.
if (figure != null) {
drawingView.toggleSelection(figure);
}
}
@Override// GuiManager
public void addSelectedModelComponent(ModelComponent modelComponent) {
Set components = fComponentsTreeManager.getSelectedItems();
if (components.size() > 1) {
components.add(modelComponent);
DrawingView drawingView = fDrawingEditor.getActiveView();
drawingView.clearSelection();
Collection