/*******************************************************************************
* Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.workbench.framework.internal;
import java.awt.Component;
import java.util.prefs.Preferences;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JSplitPane;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import org.eclipse.persistence.tools.workbench.framework.app.ApplicationNode;
import org.eclipse.persistence.tools.workbench.framework.app.NavigatorSelectionModel;
import org.eclipse.persistence.tools.workbench.framework.context.WorkbenchContext;
import org.eclipse.persistence.tools.workbench.framework.uitools.OSplitPane;
import org.eclipse.persistence.tools.workbench.framework.uitools.SwingTools;
import org.eclipse.persistence.tools.workbench.uitools.app.PropertyValueModel;
import org.eclipse.persistence.tools.workbench.uitools.app.SimplePropertyValueModel;
import org.eclipse.persistence.tools.workbench.uitools.app.ValueModel;
/**
* A workspace view is typically contained inside a workbench window.
* A workspace view contains a navigator view, an editor view, and
* a problems view.
*
* @see WorkbenchWindow
* @see NavigatorView
* @see EditorView
* @see ProblemsView
*/
final class WorkspaceView {
/**
* this holds the navigator and editor on the top
* and the problems on the bottom
*/
private JSplitPane splitPane;
/**
* This holds the navigator on the "left" and the
* editor on the "right" (depending on the component orientation).
*/
private JSplitPane topSplitPane;
/**
* Listen to the tree selection so we can update
* the selected node etc.
*/
private TreeSelectionListener treeSelectionListener;
/** the top "left" side view */
private NavigatorView navigatorView;
/** the top "right" side view */
private EditorView editorView;
/** the bottom view */
private ProblemsView problemsView;
/** this holds either the (single) selected node or one of the "pseudo-nodes" */
private PropertyValueModel selectedNodeHolder;
/** the pseudo-node used when there are multiple nodes selected in the tree */
private MultiSelectionPseudoNode multiSelectionNode;
/** the pseudo-node used when none of the nodes in the tree are selected */
private ApplicationNode emptySelectionNode;
// ********** construction/initialization **********
WorkspaceView(WorkbenchContext context, ValueModel selectionMenuDescriptionHolder) {
super();
this.multiSelectionNode = new MultiSelectionPseudoNode(context.getApplicationContext());
this.emptySelectionNode = new EmptySelectionPseudoNode(context.getApplicationContext());
this.selectedNodeHolder = new SimplePropertyValueModel(this.emptySelectionNode);
this.navigatorView = new NavigatorView(context.getApplicationContext(), selectionMenuDescriptionHolder);
this.treeSelectionListener = this.buildTreeSelectionListener();
this.navigatorView.addTreeSelectionListener(this.treeSelectionListener);
this.editorView = new EditorView(this.selectedNodeHolder, context);
this.problemsView = new ProblemsView(this.selectedNodeHolder, this.navigatorSelectionModel(), context);
this.topSplitPane = buildTopSplitPane();
this.splitPane = this.buildSplitPane();
}
private TreeSelectionListener buildTreeSelectionListener() {
return new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
ApplicationNode[] selectedNodes = ((NavigatorSelectionModel) e.getSource()).getSelectedNodes();
WorkspaceView.this.selectedNodesChanged(selectedNodes);
}
};
}
/**
* This split pane will have the navigator and editor on top
* and the problems on the bottom.
*/
private JSplitPane buildSplitPane() {
JSplitPane sPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
sPane.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
sPane.setDoubleBuffered(false);
SwingTools.setSplitPaneDividerBorder(sPane, BorderFactory.createEmptyBorder());
sPane.setDividerSize(3);
sPane.setResizeWeight(1);
sPane.setContinuousLayout(false);
sPane.setTopComponent(this.topSplitPane);
sPane.setBottomComponent(this.problemsView.getComponent());
sPane.setDividerLocation(475);
return sPane;
}
/**
* This split pane will have the navigator on the "left" and the
* editor on the "right" (depending on the component orientation).
*/
private JSplitPane buildTopSplitPane() {
JSplitPane sPane = new OSplitPane(JSplitPane.HORIZONTAL_SPLIT);
sPane.setBorder(BorderFactory.createEmptyBorder());
sPane.setDoubleBuffered(false);
SwingTools.setSplitPaneDividerBorder(sPane, BorderFactory.createEmptyBorder());
sPane.setDividerSize(3);
sPane.setResizeWeight(0);
sPane.setContinuousLayout(false);
sPane.setLeftComponent(this.navigatorView.getComponent());
sPane.setRightComponent(this.editorView.getComponent());
sPane.setDividerLocation(250);
return sPane;
}
// ********** queries **********
Component getComponent() {
return this.splitPane;
}
/**
* This is provided to clients via the WorkbenchContext.
*/
NavigatorSelectionModel navigatorSelectionModel() {
return this.navigatorView.getSelectionModel();
}
boolean problemsAreVisible() {
return this.splitPane.getBottomComponent() != null;
}
/**
* the problem report action is shared by the problems
* view and the workbench window
*/
Action problemReportAction() {
return this.problemsView.getProblemReportAction();
}
Component getPropertiesPage() {
return this.editorView.getPropertiesPage();
}
// ********** behavior **********
/**
* Whenever nodes are selected or deselected, notify interested parties.
*/
void selectedNodesChanged(ApplicationNode[] selectedNodes) {
this.multiSelectionNode.setSelectedNodes(selectedNodes);
ApplicationNode selectedNode;
switch (selectedNodes.length) {
case 0: selectedNode = this.emptySelectionNode; break;
case 1: selectedNode = selectedNodes[0]; break;
default: selectedNode = this.multiSelectionNode; break;
}
this.selectedNodeHolder.setValue(selectedNode);
}
/**
* Return the new setting.
*/
boolean toggleShowProblems() {
if (this.problemsAreVisible()) {
this.splitPane.setBottomComponent(null);
return false;
}
this.splitPane.setBottomComponent(this.problemsView.getComponent());
this.splitPane.setDividerLocation(0.8);
return true;
}
void addNavigatorTreeSelectionListener(TreeSelectionListener listener) {
this.navigatorView.addTreeSelectionListener(listener);
}
void removeNavigatorTreeSelectionListener(TreeSelectionListener listener) {
this.navigatorView.removeTreeSelectionListener(listener);
}
void copySettingsFrom(WorkspaceView workspace) {
this.splitPane.setDividerLocation(workspace.splitPane.getDividerLocation());
this.topSplitPane.setDividerLocation(workspace.topSplitPane.getDividerLocation());
if ( ! workspace.problemsAreVisible()) {
this.toggleShowProblems();
}
}
void saveState(Preferences windowsPreferences) {
windowsPreferences.putInt("split pane divider location", this.splitPane.getDividerLocation());
windowsPreferences.putInt("top split pane divider location", this.topSplitPane.getDividerLocation());
}
void restoreState(Preferences windowsPreferences) {
int dividerLocation = windowsPreferences.getInt("split pane divider location", this.splitPane.getDividerLocation());
this.splitPane.setDividerLocation(dividerLocation);
int topDividerLocation = windowsPreferences.getInt("top split pane divider location", this.topSplitPane.getDividerLocation());
this.topSplitPane.setDividerLocation(topDividerLocation);
}
void saveTreeExpansionState(Preferences windowsPreferences) {
this.navigatorView.saveTreeExpansionState(windowsPreferences);
}
void restoreTreeExpansionState(Preferences windowsPreferences) {
this.navigatorView.restoreTreeExpansionState(windowsPreferences);
}
/**
* This is called when the window containing the workspace is closed.
*/
void close() {
this.navigatorView.close();
this.editorView.close();
this.problemsView.close();
this.navigatorView.removeTreeSelectionListener(this.treeSelectionListener);
}
}