All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bidib.wizard.mvc.main.view.MainView Maven / Gradle / Ivy

There is a newer version: 2.0.29
Show newest version
package org.bidib.wizard.mvc.main.view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Properties;

import javax.swing.JButton;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.event.ListSelectionListener;

import org.apache.commons.lang3.StringUtils;
import org.bidib.api.json.types.ConnectionPhase;
import org.bidib.wizard.api.LookupService;
import org.bidib.wizard.api.locale.Resources;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.api.model.common.PreferencesPortType;
import org.bidib.wizard.api.model.listener.CvDefinitionRequestListener;
import org.bidib.wizard.api.model.listener.DefaultNodeListListener;
import org.bidib.wizard.client.common.uils.SwingUtils;
import org.bidib.wizard.client.common.view.BusyFrame;
import org.bidib.wizard.client.common.view.ButtonUtils;
import org.bidib.wizard.client.common.view.DefaultBusyFrame;
import org.bidib.wizard.client.common.view.WindowUtils;
import org.bidib.wizard.client.common.view.statusbar.StatusBar;
import org.bidib.wizard.common.context.DefaultApplicationContext;
import org.bidib.wizard.common.labels.WizardLabelWrapper;
import org.bidib.wizard.common.model.settings.ConnectionConfiguration;
import org.bidib.wizard.common.model.settings.GlobalSettingsInterface;
import org.bidib.wizard.common.model.settings.WizardSettingsInterface;
import org.bidib.wizard.common.service.SettingsService;
import org.bidib.wizard.common.utils.ImageUtils;
import org.bidib.wizard.config.DebugInterfaceControllerFactory;
import org.bidib.wizard.config.SimulationControllerFactory;
import org.bidib.wizard.config.WorkListControllerFactory;
import org.bidib.wizard.core.model.connection.ConnectionRegistry;
import org.bidib.wizard.core.model.settings.GlobalSettings;
import org.bidib.wizard.core.model.settings.SettingsWrapper;
import org.bidib.wizard.core.model.settings.WizardSettings;
import org.bidib.wizard.core.utils.AopUtils;
import org.bidib.wizard.mvc.debug.controller.DebugInterfaceController;
import org.bidib.wizard.mvc.main.controller.BidibPiController;
import org.bidib.wizard.mvc.main.model.ConnectionPhaseModel;
import org.bidib.wizard.mvc.main.model.MainModel;
import org.bidib.wizard.mvc.main.view.menu.MainMenuBar;
import org.bidib.wizard.mvc.main.view.menu.listener.MainMenuListener;
import org.bidib.wizard.mvc.main.view.panel.MainPanel;
import org.bidib.wizard.mvc.main.view.panel.listener.NodeListActionListener;
import org.bidib.wizard.nodescript.script.node.NodeScriptingSupportProvider;
import org.bidib.wizard.simulation.client.controller.SimulationController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import com.vlsolutions.swing.docking.DockingContext;
import com.vlsolutions.swing.docking.DockingDesktop;
import com.vlsolutions.swing.toolbars.ToolBarConstraints;
import com.vlsolutions.swing.toolbars.ToolBarContainer;
import com.vlsolutions.swing.toolbars.ToolBarPanel;
import com.vlsolutions.swing.toolbars.VLToolBar;

public class MainView implements BusyFrame {

    private static final Logger LOGGER = LoggerFactory.getLogger(MainView.class);

    private MainMenuBar mainMenuBar;

    private MainPanel mainPanel;

    private JButton connectButton;

    private JButton disconnectButton;

    private JButton listenNetBidibButton;

    private JButton allBoosterOffButton;

    private JButton allBoosterOnButton;

    private JButton savePendingChangesButton;

    private JButton simulationButton;

    private JButton simulationExportButton;

    private JButton comparisonExportButton;

    private JButton developerDebugInterfaceButton;

    private JButton developerDebugConsoleButton;

    private JButton developerRxTxLoggerViewButton;

    private JButton bidibPiResetButton;

    private JButton firmwareRepoButton;

    private JButton backupAllNodesButton;

    private JButton nodesClientButton;

    private JButton scriptClientButton;

    private JButton nodeScriptingButton;

    private JButton preferencesButton;

    private JButton locoDialogButton;

    private JButton carDialogButton;

    private JButton workListButton;

    @Autowired
    private DockingDesktop desktop;

    @Autowired
    private DockingContext dockingContext;

    private final MainModel mainModel;

    private VLToolBar toolbarSimulation;

    private VLToolBar toolbarDeveloper;

    private VLToolBar toolbarBidibPi;

    private ToolBarPanel topToolBarPanel;

    private final ConnectionPhaseModel connectionPhaseModel;

    private final NodeScriptingSupportProvider nodeScriptingSupportProvider;

    private DefaultBusyFrame frame;

    @Autowired
    private StatusBar statusBar;

    @Autowired
    private GlobalSettingsInterface globalSettings;

    @Autowired
    private WizardSettingsInterface wizardSettings;

    @Autowired
    private SettingsWrapper settingsWrapper;

    @Autowired
    private SettingsService settingsService;

    @Autowired
    private WizardLabelWrapper wizardLabelWrapper;

    private MainMenuListener mainMenuListener;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private LookupService lookupService;

    private final WorkListControllerFactory workListItemProvider;

    private WindowStateListener windowStateListener;

    private int extendedWindowState;

    public MainView(final MainModel model, final ConnectionPhaseModel connectionPhaseModel,
        final NodeScriptingSupportProvider nodeScriptingSupportProvider,
        WorkListControllerFactory workListItemProvider) {
        this.mainModel = model;
        this.connectionPhaseModel = connectionPhaseModel;
        this.nodeScriptingSupportProvider = nodeScriptingSupportProvider;
        this.workListItemProvider = workListItemProvider;
    }

    public void setMainMenuListener(final MainMenuListener mainMenuListener) {
        this.mainMenuListener = mainMenuListener;
    }

    public void createComponents() {

        this.frame = new DefaultBusyFrame();

        try {
            final Properties version = new Properties();
            version.load(getClass().getResourceAsStream("/META-INF/build-info.properties"));
            String projectVersion = version.getProperty("build.version");
            String buildNumber = version.getProperty("build.buildnumber-and-branch-info");

            LOGGER.info("Current buildNumber: {}", buildNumber);

            StringBuilder sb = new StringBuilder(Resources.getString(getClass(), "title"));
            sb.append(" ").append(projectVersion);
            if (!buildNumber.startsWith("${")) {
                if (buildNumber.indexOf(",") > -1) {
                    sb.append(" (").append(buildNumber.substring(0, buildNumber.indexOf(","))).append(")");
                }
                else {
                    sb.append(" (").append(buildNumber).append(")");
                }
            }
            frame.setTitle(sb.toString());
        }
        catch (Exception ex) {
            LOGGER.warn("Load version information failed.");
            frame.setTitle(Resources.getString(getClass(), "title"));
        }

        frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        frame.setIconImage(ImageUtils.createImageIcon(getClass(), "/icons/wizard-logo2-48x48.png").getImage());

        mainMenuBar =
            new MainMenuBar(mainModel, desktop, dockingContext, settingsService, connectionPhaseModel,
                this.mainMenuListener, this.wizardLabelWrapper);
        frame.setJMenuBar(mainMenuBar);

        // create and install the container
        ToolBarContainer container = ToolBarContainer.createDefaultContainer(true, false, false, false);
        topToolBarPanel = container.getToolBarPanelAt(BorderLayout.NORTH);

        DefaultApplicationContext
            .getInstance().register(DefaultApplicationContext.KEY_TOPTOOLBARPANEL, topToolBarPanel);
        DefaultApplicationContext.getInstance().register(DefaultApplicationContext.KEY_DESKTOP, desktop);

        // create and register the toolbars
        VLToolBar toolbarBidib = new VLToolBar("bidib");
        topToolBarPanel.add(toolbarBidib, new ToolBarConstraints(0, 0));
        addBidibButtons(toolbarBidib);

        VLToolBar toolbarTools = new VLToolBar("tools");
        topToolBarPanel.add(toolbarTools, new ToolBarConstraints(0, 1));
        addToolsButtons(toolbarTools, desktop);

        toolbarSimulation = new VLToolBar("simulation");
        topToolBarPanel.add(toolbarSimulation, new ToolBarConstraints(0, 2));
        addSimulationButtons(toolbarSimulation, desktop);

        // only show simulation toolbar in simulation mode
        PreferencesPortType portType =
            ConnectionConfiguration
                .toPreferencesPortType(globalSettings.getConnectionConfigurations(),
                    ConnectionRegistry.CONNECTION_ID_MAIN);
        boolean simulationMode = PreferencesPortType.isSimulation(portType);
        toolbarSimulation.setVisible(simulationMode);

        toolbarDeveloper = new VLToolBar("developer");
        topToolBarPanel.add(toolbarDeveloper, new ToolBarConstraints(0, 3));
        addDeveloperButtons(toolbarDeveloper, desktop);

        // only show developer toolbar in power user mode
        boolean powerUserMode = wizardSettings.isPowerUser();
        toolbarDeveloper.setVisible(powerUserMode);

        final org.bidib.wizard.api.context.ApplicationContext applicationContext =
            DefaultApplicationContext.getInstance();

        final BidibPiController bidibPiController =
            applicationContext
                .get(org.bidib.wizard.api.context.ApplicationContext.KEY_BIDIB_PI_CONTROLLER, BidibPiController.class);
        if (bidibPiController != null) {
            toolbarBidibPi = new VLToolBar("bidibpi");
            topToolBarPanel.add(toolbarBidibPi, new ToolBarConstraints(0, 4));
            addBidibPiButtons(toolbarBidibPi, desktop);

            toolbarBidibPi.setVisible(true);
        }

        // add the desktop to the center
        container.add(desktop, BorderLayout.CENTER);

        // toolbar container becomes the only one component
        frame.getContentPane().add(container);

        // create the main panel
        this.mainPanel =
            new MainPanel(mainModel, connectionPhaseModel, settingsService, wizardLabelWrapper,
                this.nodeScriptingSupportProvider, this.lookupService, this.statusBar);
        this.mainPanel
            .create(desktop, this.mainMenuListener, this.applicationContext,
                workListItemProvider
                    .createWorkListController(desktop, wizardSettings, settingsService.getMiscSettings(),
                        this.applicationContext));

        // Add the status bar.
        frame.getContentPane().add(statusBar.getComponent(), BorderLayout.AFTER_LAST_LINE);

        connectionPhaseModel.addPropertyChangeListener(evt -> {
            switch (evt.getPropertyName()) {
                case ConnectionPhaseModel.PROPERTY_CONNECTIONPHASE:
                    ConnectionPhase connectionPhase = connectionPhaseModel.getConnectionPhase();
                    switch (connectionPhase) {
                        case CONNECTING:
                            LOGGER.info("The port is opening. Disable the buttons.");

                            SwingUtils.executeInEDT(() -> {

                                connectButton.setEnabled(false);
                                disconnectButton.setEnabled(false);
                                listenNetBidibButton.setEnabled(false);

                                allBoosterOffButton.setEnabled(false);
                                allBoosterOnButton.setEnabled(false);

                                savePendingChangesButton.setEnabled(false);

                                mainMenuBar.opening();

                                setStatusText(Resources.getString(ConnectionPhaseModel.class, "opening-port"),
                                    StatusBar.DISPLAY_NORMAL);
                            });

                            break;
                        case CONNECTED:
                            SwingUtils.executeInEDT(() -> {
                                connectButton.setEnabled(false);
                                disconnectButton.setEnabled(true);
                                listenNetBidibButton.setEnabled(false);

                                allBoosterOffButton.setEnabled(true);
                                allBoosterOnButton.setEnabled(true);

                                savePendingChangesButton.setEnabled(true);

                                nodesClientButton.setEnabled(true);
                                simulationExportButton.setEnabled(true);
                                backupAllNodesButton.setEnabled(true);
                                comparisonExportButton.setEnabled(true);

                                locoDialogButton.setEnabled(true);
                                carDialogButton.setEnabled(true);

                                mainMenuBar.opened(connectionPhaseModel.getConnectionId());

                                setStatusText(Resources.getString(ConnectionPhaseModel.class, "open-port-passed") + " "
                                    + connectionPhaseModel.getConnectionId(), StatusBar.DISPLAY_NORMAL);
                            });

                            break;
                        case DISCONNECTED:
                            SwingUtils.executeInEDT(() -> {
                                connectButton.setEnabled(true);
                                disconnectButton.setEnabled(false);

                                allBoosterOffButton.setEnabled(false);
                                allBoosterOnButton.setEnabled(false);

                                savePendingChangesButton.setEnabled(false);

                                nodesClientButton.setEnabled(false);
                                simulationExportButton.setEnabled(false);
                                backupAllNodesButton.setEnabled(false);
                                comparisonExportButton.setEnabled(false);

                                locoDialogButton.setEnabled(false);
                                carDialogButton.setEnabled(false);

                                enableListenNetBidibItem();

                                mainMenuBar.closed(connectionPhaseModel.getConnectionId());

                                if (StringUtils.isNotBlank(connectionPhaseModel.getConnectionId())) {

                                    setStatusText(Resources.getString(ConnectionPhaseModel.class, "close-port-passed")
                                        + " " + connectionPhaseModel.getConnectionId(), StatusBar.DISPLAY_NORMAL);
                                }
                                else {
                                    setStatusText(null, StatusBar.DISPLAY_NORMAL);
                                }
                            });

                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
        });

        try {
            final GlobalSettings gs = AopUtils.getTargetObject(globalSettings);
            gs.addPropertyChangeListener(GlobalSettings.PROPERTY_SELECTED_PORTTYPE, new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {

                    if (toolbarSimulation != null) {
                        try {
                            PreferencesPortType portType =
                                ConnectionConfiguration
                                    .toPreferencesPortType(globalSettings.getConnectionConfigurations(),
                                        ConnectionRegistry.CONNECTION_ID_MAIN);
                            LOGGER
                                .info(
                                    "The selected port type has changed, enable/disable the simulation toolbar, portType: {}",
                                    portType);
                            if (portType != null) {
                                toolbarSimulation.setVisible(PreferencesPortType.isSimulation(portType));
                            }
                        }
                        catch (Exception ex) {
                            LOGGER.warn("Change visibility of simulation toolbar failed.", ex);
                        }
                    }
                }
            });
        }
        catch (Exception ex) {
            LOGGER.warn("Add property change listeners failed.", ex);
        }

        try {
            final WizardSettings ws = AopUtils.getTargetObject(wizardSettings);
            ws.addPropertyChangeListener(WizardSettings.PROPERTY_POWER_USER, new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {

                    if (toolbarDeveloper != null) {
                        try {
                            boolean isPowerUser = wizardSettings.isPowerUser();
                            LOGGER
                                .info("The power user property has changed, set the developer toolbar visible: {}",
                                    isPowerUser);
                            toolbarDeveloper.setVisible(isPowerUser);
                        }
                        catch (Exception ex) {
                            LOGGER.warn("Change visibility of developer toolbar failed.", ex);
                        }
                    }
                }
            });
        }
        catch (Exception ex) {
            LOGGER.warn("Add property change listeners failed.", ex);
        }

        mainModel.addNodeListListener(new DefaultNodeListListener() {

            @Override
            public void nodeChanged(final NodeInterface node) {

                final boolean nodeScriptWizardEnabled = (mainModel.getSelectedNode() != null);
                LOGGER.info("The selected node has changed, nodeScriptWizardEnabled: {}", nodeScriptWizardEnabled);
                SwingUtils.executeInEDT(() -> nodeScriptingButton.setEnabled(nodeScriptWizardEnabled));
            }
        });

        this.windowStateListener = new WindowStateListener() {

            @Override
            public void windowStateChanged(WindowEvent e) {

                LOGGER.info("The window state has been changed: {}", e.getNewState());

                MainView.this.extendedWindowState = e.getNewState();

            }
        };
        this.frame.addWindowStateListener(this.windowStateListener);
    }

    public DefaultBusyFrame getFrame() {
        return frame;
    }

    private void fireConnect() {
        this.mainMenuListener.connect();
    }

    private void fireDisconnect() {
        this.mainMenuListener.disconnect();
    }

    private void fireListenNetBidib() {
        this.mainMenuListener.listenNetBidib();
    }

    private void fireAllBoosterOff() {
        this.mainMenuListener.allBoosterOff();
    }

    private void fireAllBoosterOn() {
        this.mainMenuListener.allBoosterOn();
    }

    private void fireShowLocoDialog() {
        this.mainMenuListener.showLocoDialog();
    }

    private void fireShowCarDialog() {
        this.mainMenuListener.showCarDialog();
    }

    private void fireShowNodeScriptWizard() {
        this.mainMenuListener.showNodeScriptWizard();
    }

    private void fireShowFirmwareRepo() {
        this.mainMenuListener.showFirmwareRepo();
    }

    private void fireBackupAllNodes() {
        this.mainMenuListener.backupAllNodes();
    }

    private void fireShowNodesClient() {
        this.mainMenuListener.showNodesClient();
    }

    private void fireShowScriptClient() {
        this.mainMenuListener.showScriptClient();
    }

    private void fireShowWorkList() {
        this.mainMenuListener.showWorkItemList();
    }

    private void fireShowPreferences() {
        this.mainMenuListener.preferences();
    }

    private void fireShowRxTxLoggerView() {
        this.mainMenuListener.showRxTxLoggerView();
    }

    private void fireShowDebugConsole() {
        this.mainMenuListener.debugConsole();
    }

    private void fireSaveNodeTreeForSimulation() {
        this.mainMenuListener.saveNodeTreeForSimulation();
    }

    private void fireSaveNodeTreeForComparison() {
        this.mainMenuListener.saveNodeTreeForComparison();
    }

    private void enableListenNetBidibItem() {
        String connectionId = ConnectionRegistry.CONNECTION_ID_MAIN;
        ConnectionConfiguration connectionConfig =
            this.globalSettings
                .getConnectionConfigurations().stream().filter(cfg -> cfg.getId().equals(connectionId)).findFirst()
                .orElse(null);
        if (connectionConfig != null && "NetBidibClient".equals(connectionConfig.getConnectionProvider())) {
            ConnectionPhase connectionPhase = connectionPhaseModel.getConnectionPhase();
            if (connectionPhase == null || ConnectionPhase.DISCONNECTED == connectionPhase) {

                // TODO enable the listenNetBidibButton
                // listenNetBidibButton.setEnabled(true);
            }
            else {
                listenNetBidibButton.setEnabled(false);
            }
        }
        else {
            listenNetBidibButton.setEnabled(false);
        }

    }

    /**
     * @return the desktop
     */
    public DockingDesktop getDesktop() {
        return desktop;
    }

    private void addBidibButtons(VLToolBar toolbar) {
        connectButton =
            ButtonUtils
                .makeNavigationButton("connect.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.bidib.connect"),
                    Resources.getString(getClass(), "toolbar.bidib.connect.alttext"));
        connectButton.addActionListener(e -> fireConnect());
        toolbar.add(connectButton);

        disconnectButton =
            ButtonUtils
                .makeNavigationButton("disconnect.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.bidib.disconnect"),
                    Resources.getString(getClass(), "toolbar.bidib.disconnect.alttext"));
        disconnectButton.addActionListener(e -> fireDisconnect());
        disconnectButton.setEnabled(false);
        toolbar.add(disconnectButton);

        listenNetBidibButton =
            ButtonUtils
                .makeNavigationButton("socket.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.bidib.socket"),
                    Resources.getString(getClass(), "toolbar.bidib.socket.alttext"));
        listenNetBidibButton.addActionListener(e -> fireListenNetBidib());
        listenNetBidibButton.setEnabled(false);
        toolbar.add(listenNetBidibButton);

        enableListenNetBidibItem();

        toolbar.addSeparator();

        allBoosterOffButton =
            ButtonUtils
                .makeNavigationButton("boosterOff.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.bidib.all-booster-off"),
                    Resources.getString(getClass(), "toolbar.bidib.all-booster-off.alttext"));
        allBoosterOffButton.addActionListener(e -> fireAllBoosterOff());
        allBoosterOffButton.setEnabled(false);
        toolbar.add(allBoosterOffButton);

        allBoosterOnButton =
            ButtonUtils
                .makeNavigationButton("boosterOn.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.bidib.all-booster-on"),
                    Resources.getString(getClass(), "toolbar.bidib.all-booster-on.alttext"));
        allBoosterOnButton.addActionListener(e -> fireAllBoosterOn());
        allBoosterOnButton.setEnabled(false);
        toolbar.add(allBoosterOnButton);

        toolbar.addSeparator();

        savePendingChangesButton =
            ButtonUtils
                .makeNavigationButton("save.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.bidib.save-pending-changes"),
                    Resources.getString(getClass(), "toolbar.bidib.save-pending-changes.alttext"));
        savePendingChangesButton.addActionListener(e -> savePendingChanges());
        savePendingChangesButton.setEnabled(false);
        toolbar.add(savePendingChangesButton);

        // Add listener for changes of selected connection type
        try {
            final GlobalSettings gs = AopUtils.getTargetObject(settingsService.getGlobalSettings());
            gs.addPropertyChangeListener(GlobalSettings.PROPERTY_SELECTED_PORTTYPE, new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    // listen to changes
                    if (GlobalSettings.PROPERTY_SELECTED_PORTTYPE.equals(evt.getPropertyName())) {
                        LOGGER.info("The selected port type has changed.");

                        enableListenNetBidibItem();

                        MainView.this.mainMenuBar.enableListenNetBidibItem();
                    }
                }
            });
        }
        catch (Exception ex) {
            LOGGER.warn("Register for changes of selected port type failed.", ex);
        }
    }

    private void addToolsButtons(VLToolBar toolbar, final DockingDesktop desktop) {

        // settings
        preferencesButton =
            ButtonUtils
                .makeNavigationButton("settings_32x32.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.preferences.open"),
                    Resources.getString(getClass(), "toolbar.preferences.open.alttext"));

        preferencesButton.addActionListener(e -> fireShowPreferences());
        toolbar.add(preferencesButton);

        toolbar.addSeparator();

        // loco dialog
        locoDialogButton =
            ButtonUtils
                .makeNavigationButton("toy-train.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.locodialog.open"),
                    Resources.getString(getClass(), "toolbar.locodialog.open.alttext"));
        locoDialogButton.addActionListener(e -> fireShowLocoDialog());
        toolbar.add(locoDialogButton);

        // car dialog
        carDialogButton =
            ButtonUtils
                .makeNavigationButton("car-toy.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.cardialog.open"),
                    Resources.getString(getClass(), "toolbar.cardialog.open.alttext"));
        carDialogButton.addActionListener(e -> fireShowCarDialog());
        toolbar.add(carDialogButton);

        toolbar.addSeparator();

        // node script
        nodeScriptingButton =
            ButtonUtils
                .makeNavigationButton("nodescripting.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.nodescripting.open"),
                    Resources.getString(getClass(), "toolbar.nodescripting.open.alttext"));
        nodeScriptingButton.addActionListener(e -> fireShowNodeScriptWizard());
        toolbar.add(nodeScriptingButton);

        // firmware repo
        firmwareRepoButton =
            ButtonUtils
                .makeNavigationButton("software.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.firmwarerepo.open"),
                    Resources.getString(getClass(), "toolbar.firmwarerepo.open.alttext"));
        firmwareRepoButton.addActionListener(e -> fireShowFirmwareRepo());
        toolbar.add(firmwareRepoButton);

        // backup all nodes
        backupAllNodesButton =
            ButtonUtils
                .makeNavigationButton("backupnodes.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.backup-all-nodes.open"),
                    Resources.getString(getClass(), "toolbar.backup-all-nodes.open.alttext"));
        backupAllNodesButton.addActionListener(e -> fireBackupAllNodes());
        toolbar.add(backupAllNodesButton);

        // nodes client
        nodesClientButton =
            ButtonUtils
                .makeNavigationButton("tree.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.nodesClient.open"),
                    Resources.getString(getClass(), "toolbar.nodesClient.open.alttext"));
        nodesClientButton.addActionListener(e -> fireShowNodesClient());
        toolbar.add(nodesClientButton);

        // export current node tree for comparison
        comparisonExportButton =
            ButtonUtils
                .makeNavigationButton(UIManager.getString("comparison.icon.name"), "/32x32", "",
                    Resources.getString(getClass(), "toolbar.comparison.export"),
                    Resources.getString(getClass(), "toolbar.comparison.export.alttext"));
        comparisonExportButton.addActionListener(e -> fireSaveNodeTreeForComparison());
        comparisonExportButton.setEnabled(false);
        toolbar.add(comparisonExportButton);

        // workList
        workListButton =
            ButtonUtils
                .makeNavigationButton("worklist.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.worklist.open"),
                    Resources.getString(getClass(), "toolbar.worklist.open.alttext"));
        workListButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // create the workList controller
                fireShowWorkList();
            }
        });
        toolbar.add(workListButton);

        nodeScriptingButton.setEnabled(false);
        backupAllNodesButton.setEnabled(false);
        nodesClientButton.setEnabled(false);
        locoDialogButton.setEnabled(false);
        carDialogButton.setEnabled(false);

        comparisonExportButton.setEnabled(false);
    }

    private void addSimulationButtons(VLToolBar toolbar, final DockingDesktop desktop) {
        simulationButton =
            ButtonUtils
                .makeNavigationButton("sim-mode.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.simulation.open"),
                    Resources.getString(getClass(), "toolbar.simulation.open.alttext"));
        simulationButton.addActionListener(e -> {
            // create the simulation controller
            if (mainModel.getSelectedNode() != null) {
                final SimulationControllerFactory simulationControllerFactory =
                    applicationContext.getBean(SimulationControllerFactory.class);

                SimulationController simulationController = simulationControllerFactory.createController(desktop);
                simulationController.start();

                simulationController.activate(mainModel.getSelectedNode());
            }
        });
        toolbar.add(simulationButton);

    }

    private void addDeveloperButtons(VLToolBar toolbar, final DockingDesktop desktop) {
        developerDebugInterfaceButton =
            ButtonUtils
                .makeNavigationButton("console.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.debuginterface.open"),
                    Resources.getString(getClass(), "toolbar.debuginterface.open.alttext"));
        developerDebugInterfaceButton.addActionListener(e -> {
            // create the debug interface controller
            DebugInterfaceControllerFactory debugInterfaceControllerFactory =
                applicationContext.getBean(DebugInterfaceControllerFactory.class);

            DebugInterfaceController debugInterfaceController =
                debugInterfaceControllerFactory.createController(desktop, MainView.this.settingsService);
            debugInterfaceController.start();
        });
        toolbar.add(developerDebugInterfaceButton);

        // developer debug console
        developerDebugConsoleButton =
            ButtonUtils
                .makeNavigationButton("debugconsole.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.debugconsole.open"),
                    Resources.getString(getClass(), "toolbar.debugconsole.open.alttext"));
        developerDebugConsoleButton.addActionListener(e -> fireShowDebugConsole());
        toolbar.add(developerDebugConsoleButton);

        // developer RXTX logger view
        developerRxTxLoggerViewButton =
            ButtonUtils
                .makeNavigationButton("loupe.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.rxtxloggerview.open"),
                    Resources.getString(getClass(), "toolbar.rxtxloggerview.open.alttext"));
        developerRxTxLoggerViewButton.addActionListener(e -> fireShowRxTxLoggerView());
        toolbar.add(developerRxTxLoggerViewButton);

        // export current node tree as simulation
        simulationExportButton =
            ButtonUtils
                .makeNavigationButton("sim-export.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.simulation.export"),
                    Resources.getString(getClass(), "toolbar.simulation.export.alttext"));
        simulationExportButton.addActionListener(e -> fireSaveNodeTreeForSimulation());
        simulationExportButton.setEnabled(false);
        toolbar.add(simulationExportButton);

        // script client
        scriptClientButton =
            ButtonUtils
                .makeNavigationButton("script.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.scriptClient.open"),
                    Resources.getString(getClass(), "toolbar.scriptClient.open.alttext"));
        scriptClientButton.addActionListener(e -> fireShowScriptClient());
        toolbar.add(scriptClientButton);
    }

    private void addBidibPiButtons(VLToolBar toolbar, final DockingDesktop desktop) {
        bidibPiResetButton =
            ButtonUtils
                .makeNavigationButton("lightning.png", "/32x32", "",
                    Resources.getString(getClass(), "toolbar.bidibpi.reset"),
                    Resources.getString(getClass(), "toolbar.bidibpi.reset.alttext"));
        bidibPiResetButton.addActionListener(e -> {
            // reset the Bidib-Pi
            BidibPiController bidibPiController =
                DefaultApplicationContext
                    .getInstance().get(org.bidib.wizard.api.context.ApplicationContext.KEY_BIDIB_PI_CONTROLLER,
                        BidibPiController.class);
            if (bidibPiController != null) {
                LOGGER.info("Call reset on the Bidib-Pi");
                bidibPiController.reset();
            }
            else {
                LOGGER.info("No bidib-pi available.");
            }
        });
        toolbar.add(bidibPiResetButton);
    }

    public void addNodeListListener(NodeListActionListener l) {
        this.mainPanel.addNodeListListener(l);
    }

    public void addNodeListSelectionListener(ListSelectionListener l) {
        this.mainPanel.addNodeListSelectionListener(l);
    }

    public void addCvDefinitionRequestListener(CvDefinitionRequestListener l) {
        this.mainPanel.addCvDefinitionRequestListener(l);
    }

    public void prepareFrame() {
        LOGGER.info("Prepare the frame.");
        frame.setMinimumSize(new Dimension(1024, 600));

        frame.pack();

    }

    private int getExtendedState() {
        return this.extendedWindowState;
    }

    private void adjustSize() {

        org.bidib.wizard.common.model.settings.types.Frame windowPosition = wizardSettings.getFrame();

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension size = frame.getSize();

        LOGGER.info("Current screenSize: {}, stored windowPosition: {}", screenSize, windowPosition);

        // first set a default position and size
        frame.setLocation((screenSize.width - size.width) / 2, (screenSize.height - size.height) / 2);

        if (windowPosition == null) {
            LOGGER.info("Set the default frame size.");
            frame.setPreferredSize(new Dimension(Math.min(screenSize.width, 1400), Math.min(screenSize.height, 800)));
        }
        else {
            // Restore the window position from settings
            Point windowPos = new Point(windowPosition.getPosition().getX(), windowPosition.getPosition().getY());
            Dimension windowSize =
                new Dimension(windowPosition.getSize().getWidth(), windowPosition.getSize().getHeight());
            int extendedState = windowPosition.getExtendedState();
            LOGGER.info("Restore frame at pos: {}, size: {}, extendedState: {}", windowPos, windowSize, extendedState);

            frame.setSize(windowSize);

            if (windowPos != null) {

                if (WindowUtils
                    .isValidScreenLocation(
                        new Rectangle(windowPos.x, windowPos.y, windowSize.width, windowSize.height))) {

                    LOGGER.info("The location on the screen is valid: {}", windowPos);

                    frame.setLocation(windowPos);
                }
                else {

                    if (windowPos.x > (screenSize.width - 20)) {
                        windowPos.x = screenSize.width - 20;
                    }
                    if (windowPos.y > (screenSize.height - 20)) {
                        windowPos.y = screenSize.height - 20;
                    }

                    if (windowPos.x < 0) {
                        windowPos.x = 0;
                    }
                    if (windowPos.y < 0) {
                        windowPos.y = 0;
                    }

                    LOGGER.info("The location on the screen is not valid. Adjusted position: {}", windowPos);

                    frame.setLocation(windowPos);
                }
            }

            // set the extended state last
            frame.setExtendedState(extendedState);
        }
    }

    public void saveWindowPosition() {
        try {
            int extendedState = /* frame. */ getExtendedState();
            LOGGER.info("Save the window position. Current extendedState: {}", extendedState);

            if (extendedState != java.awt.Frame.MAXIMIZED_BOTH) {

                org.bidib.wizard.common.model.settings.types.Point position =
                    new org.bidib.wizard.common.model.settings.types.Point(frame.getLocation().x,
                        frame.getLocation().y);

                final Dimension frameSize = frame.getSize();

                org.bidib.wizard.common.model.settings.types.Dimension size =
                    new org.bidib.wizard.common.model.settings.types.Dimension(frameSize.width, frameSize.height);

                LOGGER.info("Prepared window position: {}, size: {}, extendedState: {}", position, size, extendedState);

                wizardSettings.saveWindowPosition(position, size, extendedState);
            }
            else {
                LOGGER.info("In maximized state only save extended state.");

                org.bidib.wizard.common.model.settings.types.Point position =
                    new org.bidib.wizard.common.model.settings.types.Point(frame.getLocation().x,
                        frame.getLocation().y);

                wizardSettings
                    .saveWindowPosition(/* wizardSettings.getFrame().getPosition() */ position,
                        wizardSettings.getFrame().getSize(), extendedState);

            }

            settingsWrapper.storeGlobalSettings(null);

        }
        catch (Exception ex) {
            LOGGER.warn("Save window position during shutdown failed.", ex);
        }
    }

    public void setWindowListener(WindowListener l) {
        frame.addWindowListener(l);
    }

    /**
     * Display a text in the statusbar.
     * 
     * @param statusText
     *            the text to display
     * @param displayDuration
     *            Time wait for clearing the message (in seconds). Any value lesser than 1 disable this functionality.
     */
    public void setStatusText(String statusText, int displayDuration) {
        if (statusBar != null) {
            statusBar.setStatusText(statusText, displayDuration);
        }
    }

    public void setVisible(boolean visible) {
        frame.setVisible(visible);
        if (visible) {
            adjustSize();
        }
    }

    public void bringWindowToFront() {
        LOGGER.info("Bring the MainView to front.");

        // int sta = frame.getExtendedState() & ~JFrame.ICONIFIED & JFrame.NORMAL;
        //
        // frame.setExtendedState(sta);
        frame.setAlwaysOnTop(true);
        frame.toFront();
        frame.requestFocus();
        frame.setAlwaysOnTop(false);
        // WindowUtils.bringWindowToFront(frame);
    }

    @Override
    public boolean setBusy(boolean busy) {
        return frame.setBusy(busy);
    }

    public void performShutdown() {
        if (this.mainPanel != null) {
            this.mainPanel.performShutdown();
        }
    }

    public void savePendingChanges() {
        LOGGER.info("Save pending changes.");

        if (this.mainPanel != null) {
            this.mainPanel.savePendingChanges();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy