# -*- python -*-
#
# OpenAlea.OALab: Multi-Paradigm GUI
#
# Copyright 2013-2015 INRIA - CIRAD - INRA
#
# File author(s): Julien Coste <julien.coste@inria.fr>
# Guillaume Baty <guillaume.baty@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
#
###############################################################################
"""
TODO:
- use project known categories instead of hard coded 'model', 'src', ...
"""
from openalea.core.observer import AbstractListener
from openalea.core.path import path
from openalea.core.service.project import (projects, set_active_project)
from openalea.core.settings import get_default_home_dir
from openalea.oalab.project.dialog import rename_model, edit_metadata, new_project
from openalea.oalab.project.explorer import ProjectExplorer
from openalea.oalab.project.qtmodel import ProjectModel
from openalea.oalab.project.preview import DEFAULT_PROJECT_ICON
from openalea.oalab.utils import ModalDialog, qicon, obj_icon
from openalea.oalab.widget import resources_rc
from openalea.vpltk.qt import QtGui, QtCore
[docs]class ProjectBrowserView(QtGui.QTreeView, AbstractListener):
item_added = QtCore.Signal(object, str, str) # project, category, name
item_clicked = QtCore.Signal(object, str, str) # project, category, name
item_double_clicked = QtCore.Signal(object, str, str) # project, category, name
item_removed = QtCore.Signal(object, str, object) # project, category, item
project_closed = QtCore.Signal(object) # old project
project_open = QtCore.Signal(object) # new project
def __init__(self):
QtGui.QTreeView.__init__(self)
AbstractListener.__init__(self)
self._model = ProjectModel()
self.setModel(self._model)
self._model.dataChanged.connect(self._on_model_changed)
self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.connect(self, QtCore.SIGNAL('doubleClicked(const QModelIndex&)'), self.open)
self.setHeaderHidden(True)
self.setDragEnabled(True)
self.setDropIndicatorShown(True)
self.setAcceptDrops(True)
self._create_actions()
def _create_actions(self):
self._actions = []
self.actionEditMeta = QtGui.QAction(
qicon("adwaita_accessories-dictionary.png"),
"Edit Project Information",
self)
self.actionEditMeta.triggered.connect(self.edit_metadata)
self.actionCloseProj = QtGui.QAction(qicon("close_project.png"), "Close project", self)
self.actionCloseProj.triggered.connect(self.close)
self.actionCloseProj.setShortcut(self.tr("Ctrl+Shift+W"))
self.actionOpenProj = QtGui.QAction(qicon("open_project.png"), "Open Project", self)
self.actionOpenProj.triggered.connect(self.open_project)
self.actionOpenProj.setShortcut(self.tr('Ctrl+Shift+O'))
self.action_save_proj = QtGui.QAction(qicon("save_project.png"), "Save Project", self)
self.action_save_proj.triggered.connect(self.save_project)
self.action_save_proj.setShortcut(self.tr('Ctrl+Shift+S'))
# API
[docs] def notify(self, sender, event=None):
signal, data = event
if signal == 'project_changed':
self.refresh()
[docs] def set_project(self, project):
old_proj = self._model.project()
if old_proj:
old_proj.unregister_listener(self)
if project:
project.register_listener(self)
# TODO: Dirty hack to remove asap. Close project selector if widget has been created
if hasattr(self, "proj_selector"):
del self.proj_selector
self._model.set_project(project)
if project:
self.project_closed.emit(old_proj)
self.project_open.emit(project)
else:
self.project_closed.emit(old_proj)
[docs] def refresh(self):
self._model.refresh()
# Convenience methods
[docs] def getItem(self):
index = self.getIndex()
if index:
return self._model.itemFromIndex(index)
[docs] def getIndex(self):
indices = self.selectedIndexes()
for index in indices:
return index
[docs] def project(self):
return self._model.project()
[docs] def selected_data(self):
index = self.getIndex()
project = self.project()
data = self._model.projectdata(index)
if project is None:
return (None, None, None)
elif project and data is None:
return project, None, None
else:
category, name = data
return project, category, name
# Slots
def _on_model_changed(self):
self.expandAll()
# Contextual menu
[docs] def open_project(self, name=False, path=None):
"""
If name==false, display a widget to choose project to open.
Then open project.
"""
self.proj_selector = ProjectExplorer()
dialog = ModalDialog(self.proj_selector)
dialog.resize(800, 600)
dialog.setContentsMargins(3, 3, 3, 3)
if dialog.exec_():
project = self.proj_selector.item()
if project:
self.set_project(project)
set_active_project(project)
[docs] def open(self):
project, category, name = self.selected_data()
if project and category:
if category == 'category' and name == 'data':
p = QtGui.QFileDialog.getOpenFileName(self, 'Select File to open', project.path, "All (*)")
if p:
p = path(p)
project.add(name, path=p)
elif category == 'category':
pass
elif category == 'project':
pass
# self.open_all_scripts_from_project(project)
elif category == 'data':
from openalea.file.files import start
start(project.get(category, name).path)
else:
self.item_double_clicked.emit(project, category, name)
[docs] def save_project(self):
project = self.project()
if project:
project.save()
def _rename(self, project, category, name):
if category in project.categories:
rename_model(project, category, name)
elif category == 'project':
self.edit_metadata()
[docs] def rename(self):
project, category, name = self.selected_data()
if project and category:
self._rename(project, category, name)
[docs] def remove(self):
project, category, name = self.selected_data()
if project and category:
project.remove(category, filename=name)
[docs] def delete(self):
project, category, name = self.selected_data()
if project:
if category in project.categories:
data = project.get(category, name)
confirm = QtGui.QLabel('Remove %s ?' % data.path)
dialog = ModalDialog(confirm)
if dialog.exec_():
project.remove(category, data)
data.path.remove()
self.item_removed.emit(project, category, data)
[docs] def close(self):
self.set_project(None)
[docs] def import_file(self):
print 'import_file'