// PathVisio, // a tool for data visualization and analysis using Biological Pathways // Copyright 2006-2011 BiGCaT Bioinformatics // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package org.pathvisio.desktop; import java.util.HashMap; import java.util.Map; import javax.swing.Action; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JTabbedPane; import org.bridgedb.IDMapperException; import org.osgi.framework.BundleContext; import org.pathvisio.core.ApplicationEvent; import org.pathvisio.core.Engine.ApplicationEventListener; import org.pathvisio.core.data.GdbEvent; import org.pathvisio.core.data.GdbManager.GdbEventListener; import org.pathvisio.core.debug.Logger; import org.pathvisio.core.model.ObjectType; import org.pathvisio.core.model.Pathway; import org.pathvisio.core.model.PathwayElement; import org.pathvisio.core.preferences.GlobalPreference; import org.pathvisio.core.preferences.PreferenceManager; import org.pathvisio.core.view.VPathway; import org.pathvisio.desktop.data.DBConnDerby; import org.pathvisio.desktop.data.DBConnectorSwing; import org.pathvisio.desktop.gex.CachedData; import org.pathvisio.desktop.gex.GexManager; import org.pathvisio.desktop.plugin.PluginDialogSwitch; import org.pathvisio.desktop.plugin.PluginManager; import org.pathvisio.desktop.util.StandaloneCompat; import org.pathvisio.desktop.visualization.Visualization; import org.pathvisio.desktop.visualization.VisualizationEvent; import org.pathvisio.desktop.visualization.VisualizationManager; import org.pathvisio.gui.SwingEngine; import org.pathvisio.gui.PathwayElementMenuListener.PathwayElementMenuHook; /** * PvDesktop ties together several * other important singletons and provides access to them for * the entire PathVisio standalone application. * PvDesktop provides access to components * such as data visualization and gene expression data. It * is also a contact point for Plugins, and makes sure * Gex data is cached when a suitable pgdb, pgex and gpml are loaded. *
* PvDesktop is a singleton: There should be always exactly
* one instance of it.
*/
public class PvDesktop implements ApplicationEventListener, GdbEventListener, VisualizationManager.VisualizationListener
{
private final VisualizationManager visualizationManager;
private final GexManager gexManager;
private final SwingEngine swingEngine;
private final StandaloneCompat compat;
private final PreferencesDlg preferencesDlg;
private BundleContext context;
public BundleContext getContext() {
return context;
}
/**
* During construction, visualizationManager and gexManager will be initialized.
* SwingEngine needs to have been initialized already.
*
* BundleContext is an OSGi class with contains the ServiceRegistry, this is
* needed in the PluginManager to get the registered Plugins
*/
public PvDesktop(SwingEngine swingEngine, BundleContext context)
{
this.context = context;
if (swingEngine == null) throw new NullPointerException();
this.swingEngine = swingEngine;
swingEngine.getEngine().addApplicationEventListener(this);
swingEngine.getGdbManager().addGdbEventListener(this);
gexManager = new GexManager();
visualizationManager = new VisualizationManager(
swingEngine.getEngine(), gexManager);
visualizationManager.addListener(this);
compat = new StandaloneCompat(this);
preferencesDlg = new PreferencesDlg(PreferenceManager.getCurrent());
initPanels();
}
public void initPanels()
{
preferencesDlg.addPanel ("Display",
preferencesDlg.builder()
.integerField (
GlobalPreference.GUI_SIDEPANEL_SIZE,
"Initial side panel size (percent of window size):", 0, 100)
.booleanField (
GlobalPreference.DATANODES_ROUNDED,
"Use rounded rectangles for data nodes")
.integerField(
GlobalPreference.MAX_NR_CITATIONS,
"Maximum citations to show (use -1 to show all)",
-1, 1000)
.booleanField(
GlobalPreference.SNAP_TO_ANGLE,
"Snap to angle when moving line and rotation handles")
.integerField (
GlobalPreference.SNAP_TO_ANGLE_STEP,
"Distance between snap-steps in degrees:", 1, 90)
.booleanField (
GlobalPreference.MIM_SUPPORT,
"Load support for molecular interaction maps (MIM) at program start")
.booleanField (
GlobalPreference.SHOW_ADVANCED_PROPERTIES,
"Show advanced properties (e.g. references)")
.booleanField (
GlobalPreference.USE_SYSTEM_LOOK_AND_FEEL,
"Use Java System look-and-feel at program start")
.booleanField(
GlobalPreference.ENABLE_DOUBLE_BUFFERING,
"Enable double-buffering (pathway is drawn slower, but flickerless)")
.build());
preferencesDlg.addPanel ("Display.Colors",
preferencesDlg.builder()
.colorField(
GlobalPreference.COLOR_NO_CRIT_MET,
"Default color for 'no criteria met':")
.colorField(
GlobalPreference.COLOR_NO_GENE_FOUND,
"Default color for 'gene not found':")
.colorField(
GlobalPreference.COLOR_NO_DATA_FOUND,
"Default color for 'no data found':")
.colorField(
GlobalPreference.COLOR_SELECTED,
"Line color for selected objects:")
.colorField(
GlobalPreference.COLOR_HIGHLIGHTED,
"Highlight color")
.build());
preferencesDlg.addPanel ("Files", preferencesDlg.builder()
.fileField(
GlobalPreference.FILE_LOG,
"Log file:", false)
.build());
preferencesDlg.addPanel ("Directories", preferencesDlg.builder()
.fileField (GlobalPreference.DIR_PWFILES,
"Gpml pathways:", true)
.fileField (GlobalPreference.DIR_GDB,
"Gene databases:", true)
.fileField (GlobalPreference.DIR_EXPR,
"Expression datasets:", true)
.build());
preferencesDlg.addPanel ("Database", preferencesDlg.builder()
.stringField (GlobalPreference.DB_ENGINE_GEX,
"Database connector class for expression dataset:")
.build());
preferencesDlg.addPanel("Plugin Manager",
preferencesDlg.builder().booleanField(PluginDialogSwitch.PLUGIN_DIALOG_SWITCH,
"Select if you want to use the new plug-in manager (work in progress)")
.build());
}
/** return the preferences dialog, can be used to add panels */
public PreferencesDlg getPreferencesDlg()
{
return preferencesDlg;
}
/**
* Return the global visualizationManager instance.
*/
public VisualizationManager getVisualizationManager()
{
return visualizationManager;
}
/**
* returns the global gexManager instance.
*/
public GexManager getGexManager()
{
return gexManager;
}
/**
* returns the global swingEngine instance.
*/
public SwingEngine getSwingEngine()
{
return swingEngine;
}
/**
* Load the Gex cache for the current pathway. Only starts loading
* when an expression dataset is available and a pathway is open.
*/
public void loadGexCache() {
final CachedData gex = gexManager.getCachedData();
final Pathway p = swingEngine.getEngine().getActivePathway();
if(p != null && gex != null) {
try
{
gex.clearCache();
gex.setMapper (swingEngine.getGdbManager().getCurrentGdb());
gex.preSeed(p.getDataNodeXrefs());
swingEngine.getEngine().getActiveVPathway().redraw();
}
catch (IDMapperException e)
{
Logger.log.error ("Exception while caching expression data ", e);
}
}
}
/**
* Update Gex cache in response to opening pathways.
*/
public void applicationEvent(ApplicationEvent e)
{
if(e.getType() == ApplicationEvent.PATHWAY_OPENED)
{
loadGexCache();
}
}
/**
* Update gex cache in response to opening / closing gene databases
*/
public void gdbEvent(GdbEvent e)
{
loadGexCache();
}
/**
* Shortcut for getSwingEngine().getFrame()
* Returns frame of main application window.
* Useful for positioning / parenting dialogs
*/
public JFrame getFrame()
{
return swingEngine.getFrame();
}
/**
* register an action as a menu item
* @param submenu one of "File", "Edit", "Data" or "Help"
*/
public void registerMenuAction (String submenu, Action a)
{
JMenuBar menuBar = swingEngine.getApplicationPanel().getMenuBar();
if(menuBar == null) {
Logger.log.warn("Trying to register menu action while no menubar is available " +
"(running in headless mode?)");
return;
}
for (int i = 0; i < menuBar.getMenuCount(); ++i)
{
JMenu menuAt = menuBar.getMenu(i);
if (menuAt.getText().equals (submenu))
{
JMenuItem item = menuAt.add(a);
registeredActions.put(a, item);
break;
}
}
}
private Map