# -*- coding: utf-8 -*-
# -*- python -*-
#
# Main Window class
# VPlantsLab GUI is created here
#
# OpenAlea.OALab: Multi-Paradigm GUI
#
# Copyright 2013 INRIA - CIRAD - INRA
#
# File author(s): Julien Coste <julien.coste@inria.fr>
#
# File contributor(s):
#
# Distributed under the Cecill-C License.
# See accompanying file LICENSE.txt or copy at
# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
# OpenAlea WebSite : http://openalea.gforge.inria.fr
#
###############################################################################
__revision__ = ""
import types
from openalea.vpltk.qt import QtGui, QtCore
from openalea.core import logger
from openalea.core.path import path
from openalea.core.settings import get_openalea_home_dir
from openalea.oalab.config.template import config_file_default, config_file_mini, config_file_3d, config_file_tissue, config_file_plant
[docs]class MainWindow(QtGui.QMainWindow):
"""
Main Window Class
"""
def __init__(self, session, controller, parent=None, args=None):
super(QtGui.QMainWindow, self).__init__()
self.session = session
self.controller = controller
self._dockwidgets = {}
self.changeExtension(extension=self.session.extension)
# Central Widget
self.setCentralWidget(self.controller.applet_container)
self.readSettings()
self.setSettingsInMenu()
self.setShowDockInMenu()
self.setSelectLabInMenu()
# print self.controller.classical_menu.actions()
self.setMenuBar(self.controller.classical_menu)
[docs] def changeExtension(self, extension=None):
"""
Change to a new extension.
:param extension: can be "mini", "3d", "tissue", "plant"
"""
self.removeDocksWidgets()
filename = 'oalab.py'
conf = path(get_openalea_home_dir()) / filename
if extension in ["mini", "3d", "tissue", "plant"]:
filename = ('oalab_' + extension + '.py')
conf = path(get_openalea_home_dir()) / filename
if not conf.exists():
with conf.open('w') as f:
# TODO : auto generate config file
# f.write(self._config.generate_config_file())
if extension == "mini":
f.write(config_file_mini)
elif extension == "3d":
f.write(config_file_3d)
elif extension == "tissue":
f.write(config_file_tissue)
elif extension == "plant":
f.write(config_file_plant)
else:
f.write(config_file_default)
self.session.load_config_file(filename=filename, path=get_openalea_home_dir())
self.setWidgets(self.controller)
[docs] def closeEvent(self, event):
self.writeSettings()
super(QtGui.QMainWindow, self).closeEvent(event)
####################################################################
# ## Settings
####################################################################
[docs] def writeSettings(self):
"""
Register current settings (geometry and window state)
in a setting file
"""
settings = QtCore.QSettings("OpenAlea", "OpenAleaLaboratory")
settings.setValue("geometry", self.saveGeometry())
settings.setValue("windowState", self.saveState())
settings.setValue("session", self.session.project)
[docs] def readSettings(self):
"""
Read a setting file and restore
registered settings (geometry and window state)
"""
settings = QtCore.QSettings("OpenAlea", "OpenAleaLaboratory")
try:
self.restoreGeometry(settings.value("geometry"))
# self.restoreState(settings.value("windowState"))
except:
# if you launch application for the first time,
# it will save the default state
settings.setValue("defaultGeometry", self.saveGeometry())
# settings.setValue("defaultWindowState", self.saveState())
logger.warning("Can t restore session")
[docs] def setSettingsInMenu(self):
class FakeWidget(object):
def __init__(self, parent):
"""
Use it to add features like setting widgets layout
"""
super(FakeWidget, self).__init__()
self.mainwindow = parent
def actions(self):
actionDefault = QtGui.QAction(QtGui.QIcon(":/images/resources/layout_blue.png"), "Load Default", self.mainwindow)
actionRestorePref = QtGui.QAction(QtGui.QIcon(":/images/resources/layout_green.png"), "Load Prefered", self.mainwindow)
actionSetPref = QtGui.QAction(QtGui.QIcon(":/images/resources/layout_red.png"), "Save Prefered", self.mainwindow)
QtCore.QObject.connect(actionDefault, QtCore.SIGNAL('triggered(bool)'), self.mainwindow.defaultSettings)
QtCore.QObject.connect(actionRestorePref, QtCore.SIGNAL('triggered(bool)'), self.mainwindow.preferedSettings)
QtCore.QObject.connect(actionSetPref, QtCore.SIGNAL('triggered(bool)'), self.mainwindow.registerPreferedSettings)
_actions = [["Help", "Window Layout", actionDefault, 1],
["Help", "Window Layout", actionRestorePref, 1],
["Help", "Window Layout", actionSetPref, 1]]
return _actions
settings = FakeWidget(parent=self)
self.controller.connect_actions(settings)
[docs] def setShowDockInMenu(self):
"""
Use it to add show/hide dockwidget in menu
"""
children = self.findChildren(QtGui.QDockWidget)
for child in children:
name = child.windowTitle()
if name.lower() == "menu":
continue
btn = QtGui.QCheckBox(name, self)
btn.setChecked(child.isVisibleTo(self))
btn.toggled.connect(child.setVisible)
# child.visibilityChanged.connect(btn.setChecked)
child._actions = [["View", "Show", btn, "smallwidget"], ]
def actions(self):
return self._actions
child.actions = types.MethodType(actions, child)
self.controller.connect_actions(child)
[docs] def setSelectLabInMenu(self):
class FakeWidget(object):
def __init__(self, parent):
"""
Use it to add features like setting widgets layout
Actually not used
"""
super(FakeWidget, self).__init__()
self.mainwindow = parent
def actions(self):
minilab = QtGui.QAction(QtGui.QIcon(":/images/resources/openalealogo.png"), "MiniLab", self.mainwindow)
lab3d = QtGui.QAction(QtGui.QIcon(":/images/resources/openalealogo.png"), "3DLab", self.mainwindow)
plantlab = QtGui.QAction(QtGui.QIcon(":/images/resources/openalealogo.png"), "PlantLab", self.mainwindow)
tissuelab = QtGui.QAction(QtGui.QIcon(":/images/resources/openalealogo.png"), "TissueLab", self.mainwindow)
QtCore.QObject.connect(minilab, QtCore.SIGNAL('triggered(bool)'), self.mainwindow._mini)
QtCore.QObject.connect(lab3d, QtCore.SIGNAL('triggered(bool)'), self.mainwindow._lab3d)
QtCore.QObject.connect(plantlab, QtCore.SIGNAL('triggered(bool)'), self.mainwindow._plant)
QtCore.QObject.connect(tissuelab, QtCore.SIGNAL('triggered(bool)'), self.mainwindow._tissue)
_actions = [["Extension", "Select an Extension", minilab, 0],
["Extension", "Select an Extension", lab3d, 0],
["Extension", "Select an Extension", plantlab, 0],
["Extension", "Select an Extension", tissuelab, 0]]
return None
settings = FakeWidget(parent=self)
self.controller.connect_actions(settings)
[docs] def defaultSettings(self):
"""
Restore default settings (geometry and window state)
"""
settings = QtCore.QSettings("OpenAlea", "OpenAleaLaboratory")
self.restoreGeometry(settings.value("defaultGeometry"))
self.restoreState(settings.value("defaultWindowState"))
[docs] def preferedSettings(self):
"""
Get prefered settings and restore them
"""
try:
settings = QtCore.QSettings("OpenAlea", "OpenAleaLaboratory")
self.restoreGeometry(settings.value("preferedGeometry"))
self.restoreState(settings.value("preferedWindowState"))
except:
logger.warning("Can t restore prefered session")
[docs] def registerPreferedSettings(self):
"""
Register current settings as preferd settings
"""
settings = QtCore.QSettings("OpenAlea", "OpenAleaLaboratory")
settings.setValue("preferedGeometry", self.saveGeometry())
settings.setValue("preferedWindowState", self.saveState())
####################################################################
# ## Widgets
####################################################################
def _dockWidget(self, identifier, widget, name=None, allowed_area=None, position=None, alias=None):
if name is None :
name = identifier.capitalize()
if allowed_area is None:
allowed_area = QtCore.Qt.LeftDockWidgetArea | QtCore.Qt.RightDockWidgetArea | QtCore.Qt.TopDockWidgetArea | QtCore.Qt.BottomDockWidgetArea
if position is None:
position = QtCore.Qt.LeftDockWidgetArea
if alias:
dock_widget = QtGui.QDockWidget(alias, self)
else:
dock_widget = QtGui.QDockWidget(name, self)
dock_widget.setObjectName("%sPanel" % identifier)
dock_widget.setAllowedAreas(allowed_area)
dock_widget.setWidget(widget)
self.addDockWidget(position, dock_widget)
self._dockwidgets[identifier] = dock_widget
display = self.session.config.get('MainWindowConfig').get(identifier.lower(), False)
dock_widget.setVisible(display)
return dock_widget
[docs] def setWidgets(self, controller):
# Menu
dock_menu = self._dockWidget("Menu", controller.menu,
allowed_area=QtCore.Qt.TopDockWidgetArea,
position=QtCore.Qt.TopDockWidgetArea)
dock_menu.setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
# Docks
self._dockWidget("Viewer3D", controller.applets["Viewer3D"], name="3D Viewer", position=QtCore.Qt.RightDockWidgetArea)
# self._dockWidget("Store", controller.applets["Store"], name="OpenAlea Store", position=QtCore.Qt.RightDockWidgetArea)
self._dockWidget("HelpWidget", controller.applets["HelpWidget"], position=QtCore.Qt.RightDockWidgetArea, alias="Help")
self._dockWidget("Project", controller.applets["Project"], position=QtCore.Qt.RightDockWidgetArea)
# self._dockWidget("ProjectManager", controller.applets["ProjectManager"],position=QtCore.Qt.RightDockWidgetArea) # Project Manager
self._dockWidget("Shell", controller.shell, name="IPython Shell", position=QtCore.Qt.BottomDockWidgetArea)
self._dockWidget("Logger", controller.applets["Logger"], position=QtCore.Qt.BottomDockWidgetArea)
self._dockWidget("Packages", controller.applets["Packages"], position=QtCore.Qt.BottomDockWidgetArea)
self._dockWidget("PackageCategories", controller.applets["PackageCategories"], name="Package Categories", position=QtCore.Qt.BottomDockWidgetArea)
self._dockWidget("PackageSearch", controller.applets["PackageSearch"], name="Package Search", position=QtCore.Qt.BottomDockWidgetArea)
if controller.applets.has_key("ControlPanel"):
self._dockWidget("ControlPanel", controller.applets["ControlPanel"], name="Control Panel", position=QtCore.Qt.BottomDockWidgetArea)
controller.applets['ControlPanel'].geometry_editor.setStatusBar(self.statusBar())
# self._dockwidgets['Store'].hide()
# Status bar
status = self.statusBar()
status.setSizeGripEnabled(False)
controller.statusBar = status
self.statusBar().showMessage("OALab is ready!", 10000)
# Tabify docks
self.tabifyDockWidget(self._dockwidgets['Logger'], self._dockwidgets['Shell'])
self.tabifyDockWidget(self._dockwidgets['PackageSearch'], self._dockwidgets['PackageCategories'])
self.tabifyDockWidget(self._dockwidgets['PackageCategories'], self._dockwidgets['Packages'])
if self._dockwidgets.has_key("Packages") and self._dockwidgets.has_key("ControlPanel"):
self.tabifyDockWidget(self._dockwidgets['Packages'], self._dockwidgets['ControlPanel'])
self.tabifyDockWidget(self._dockwidgets['Project'], self._dockwidgets['HelpWidget'])
# self._dockwidgets['Store'].setTitleBarWidget(QtGui.QWidget())
[docs] def removeDocksWidgets(self):
children = self.findChildren(QtGui.QDockWidget)
for child in children:
self.removeDockWidget(child)
[docs] def changeMenuTab(self, old, new):
"""
Set tab of 'new' current in the menu.
This class is designed to be connected to focusChanged signal.
:param old: old widget. Not used.
:param new: current widget to check if we have to change menu
"""
if new and hasattr(new, 'mainMenu') :
# new=None means application has lost focus, so do not change PanedMenu.
# (for example, click outside application)
# Get Tab Name
name = new.mainMenu()
# Get Menu
menu = self._dockwidgets['Menu'].widget()
menu.showPane(name)
def _mini(self):
self.changeExtension("mini")
def _lab3d(self):
self.changeExtension("3d")
def _plant(self):
self.changeExtension("plant")
def _tissue(self):
self.changeExtension("tissue")