def open_project(self, name=False, path=None): """ If name==false, display a widget to choose project to open. Then open project. """ self.pm.discover() projects = self.pm.projects self.proj_selector = ProjectSelectorScroll(projects=projects) self.proj_selector.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.proj_selector.show()
class ProjectManagerView(QtGui.QTreeView): def __init__(self): QtGui.QTreeView.__init__(self) self._model = ProjectManagerModel() self.pm = ProjectManager() 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._actions = [] self._new_file_actions = {} self.paradigms_actions = [] self.paradigms = {} self.actionEditMeta = QtGui.QAction(qicon("book.png"), "Edit Project Information", self) self.actionEditMeta.triggered.connect(self.edit_metadata) self.actionImportFile = QtGui.QAction(qicon("open.png"), "Import file", self) self.actionImportFile.triggered.connect(self.import_file) self.actionSaveProjAs = QtGui.QAction(qicon("save.png"), "Save As", self) self.actionSaveProjAs.triggered.connect(self.save_as) self.actionSaveProj = QtGui.QAction(qicon("save.png"), "Save project", self) self.actionSaveProj.triggered.connect(self.save) self.actionSaveProj.setShortcut( QtGui.QApplication.translate("MainWindow", "Ctrl+Shift+S", None, QtGui.QApplication.UnicodeUTF8)) self.actionCloseProj = QtGui.QAction(qicon("closeButton.png"), "Close project", self) self.actionCloseProj.triggered.connect(self.close) self.actionCloseProj.setShortcut(self.tr("Ctrl+Shift+W")) self.actionNewProj = QtGui.QAction(qicon("new.png"), "New Project", self) self.actionNewProj.triggered.connect(self.new_project) self.actionNewProj.setShortcut(self.tr("Ctrl+Shift+N")) self.actionOpenProj = QtGui.QAction(qicon("open.png"), "Open Project", self) self.actionOpenProj.triggered.connect(self.open_project) self.actionOpenProj.setShortcut(self.tr('Ctrl+Shift+O')) # API def _get_paradigm_container(self): if plugin_instance_exists('oalab.applet', 'EditorManager'): return plugin_instance('oalab.applet', 'EditorManager') paradigm_container = property(fget=_get_paradigm_container) def initialize(self): pass def set_project(self, project): # 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.close_all_scripts() # self.open_all_scripts_from_project(project) self.expandAll() else: self.close_all_scripts() def refresh(self): self._model.refresh() # Convenience methods def getItem(self): index = self.getIndex() if index: return self._model.itemFromIndex(index) def getIndex(self): indices = self.selectedIndexes() for index in indices: return index def project(self): if self.pm: return self.pm.cproject def selected_data(self): index = self.getIndex() project = self.project() data = self._model.projectdata(index) if index is None or project is None or data is None: return (None, None, None) else: category, name = data return project, category, name # Slots def _on_model_changed(self): self.expandAll() # Contextual menu def add_new_file_actions(self, menu): for applet in self.paradigm_container.paradigms.values(): action = QtGui.QAction(qicon(applet.icon), 'New %s' % applet.default_name, self) action.triggered.connect(self.new_file) self._new_file_actions[action] = applet menu.addAction(action) menu.addSeparator() def create_menu(self): menu = QtGui.QMenu(self) project, category, obj = self.selected_data() if category == 'category' and obj == 'model': self.add_new_file_actions(menu) elif category == 'category' and obj == 'data': import_data = QtGui.QAction(qicon('import.png'), 'Import data', self) import_data.triggered.connect(self.open) menu.addAction(import_data) elif category == 'category' and obj in ('startup', 'doc', 'lib'): new_startup = QtGui.QAction(qicon('filenew.png'), 'New file', self) new_startup.triggered.connect(self.new_file) menu.addAction(new_startup) if category == 'model': self.add_new_file_actions(menu) if category in ['model', 'src', 'startup', 'doc', 'data', 'lib']: editAction = QtGui.QAction(qicon('open.png'), 'Open "%s"' % obj, self) menu.addAction(editAction) editAction.triggered.connect(self.open) rename = QtGui.QAction(qicon('Crystal_Clear_action_editcopy.png'), 'Rename', self) rename.triggered.connect(self.rename) menu.addAction(rename) remove = QtGui.QAction(qicon('Crystal_Clear_action_edit_remove.png'), 'Remove', self) remove.triggered.connect(self.remove) menu.addAction(remove) menu.addSeparator() deleteAction = QtGui.QAction(qicon('Crystal_Clear_action_stop.png'), 'Delete', self) menu.addAction(deleteAction) deleteAction.triggered.connect(self.delete) if category in ['project']: menu.addAction(self.actionEditMeta) menu.addAction(self.actionSaveProj) menu.addAction(self.actionSaveProjAs) menu.addAction(self.actionCloseProj) return menu def contextMenuEvent(self, event): if self.pm.cproject is None: return menu = self.create_menu() menu.exec_(event.globalPos()) # Action's slots def edit_metadata(self): project = self.project() if project: project_creator = CreateProjectWidget(project) dialog = ModalDialog(project_creator) if dialog.exec_(): _proj = project_creator.project() if _proj.name != project.name or _proj.projectdir != project.projectdir: project.move(_proj.path) project.metadata = project_creator.metadata() project.save() def open_project(self, name=False, path=None): """ If name==false, display a widget to choose project to open. Then open project. """ self.pm.discover() projects = self.pm.projects self.proj_selector = ProjectSelectorScroll(projects=projects) self.proj_selector.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.proj_selector.show() def new_project(self): project_creator = CreateProjectWidget() dialog = ModalDialog(project_creator) if dialog.exec_(): project = project_creator.project() self.pm.cproject = project def open_all_scripts_from_project(self, project): if self.paradigm_container is not None: for model in project.model.values(): self.paradigm_container.open_data(model) def new_file(self, dtype=None): try: applet = self._new_file_actions[self.sender()] except KeyError: dtype = None else: dtype = applet.default_name project, category, data = self.selected_data() code = '' project = self.project() if category == 'category': category = data elif category in project.DEFAULT_CATEGORIES: pass else: category = None if dtype is None and category in ['startup', 'lib']: dtype = 'Python' if category in ['startup', 'lib']: d = {'startup': 'start.py', 'lib': 'algo.py'} name = d[category] elif dtype: klass = DataClass(MimeType(name=dtype)) name = '%s_%s.%s' % (klass.default_name, category, klass.extension) else: name = category category, data = self.paradigm_container.add(project, name, code, dtype=dtype, category=category) if data: self.paradigm_container.open_data(data) def open(self): project, category, name = self.selected_data() if project: 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.paradigm_container.open_data(project.get(category, name)) def _rename(self, project, category, name): if category in project.DEFAULT_CATEGORIES: filelist = getattr(project, category).keys() renamer = RenameModel(filelist, name) dialog = ModalDialog(renamer) if dialog.exec_(): old_name = renamer.old_name() new_name = renamer.new_name() project.rename_item(category, old_name, new_name) elif category == 'project': self.edit_metadata() def rename(self): project, category, name = self.selected_data() if project: self._rename(project, category, name) def remove(self): project, category, name = self.selected_data() if project: project.remove(category, filename=name) def delete(self): project, category, name = self.selected_data() if project: if category in project.DEFAULT_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() if self.paradigm_container: self.paradigm_container.close_data(data) def save(self): project = self.project() if project: project.save() if self.paradigm_container: self.paradigm_container.save_all() def save_as(self): project = self.project() if project: p = path(self.showNewProjectDialog(default_name=None, text="Select name to save project")).abspath() projectdir, name = p.splitpath() if name: project.save_as(projectdir, name) def close(self): self.pm.cproject = None def close_all_scripts(self): if self.paradigm_container is None: return self.paradigm_container.closeAll() def import_file(self): print 'import_file' def showNewProjectDialog(self, default_name=None, text=None, parent=None): my_path = path(settings.get_project_dir()) if default_name: my_path = my_path / default_name if not text: text = 'Select name to create project' fname = QtGui.QFileDialog.getSaveFileName(parent, text, my_path) return fname def showOpenProjectDialog(self, parent=None): my_path = path(settings.get_project_dir()) fname = QtGui.QFileDialog.getExistingDirectory(parent, 'Select Project Directory', my_path) return fname # Drag and drop def startDrag(self, supportedActions): index = self.getIndex() item = self.getItem() data = self._model.projectdata(index) if data is None: return category, name = data # Check item in src # TODO move this part in dragEnterEvent with mimetype obj = self._model._project.get(category, name) if category in ['src', 'model']: # Read file and parse model to get inputs, outputs, doc that may be # useful once dropped. obj.read() text = item.text() # name_without_ext = ".".join(text.split(".")[:-1]) name_without_ext = text name_without_space = "_".join(name_without_ext.split()) for sym in ["-", "+", "*", "/", "\"", "."]: name_without_space = "_".join(name_without_space.split(sym)) python_call_string = '%s = Model("%s")' % (name_without_space, name_without_ext) icon = item.icon() pixmap = icon.pixmap(20, 20) itemData = QtCore.QByteArray() dataStream = QtCore.QDataStream(itemData, QtCore.QIODevice.WriteOnly) model_id = name_without_ext dataStream.writeString(str(python_call_string)) dataStream.writeString(str(model_id)) mimeData = QtCore.QMimeData() mimeData.setText(python_call_string) mimeData.setData("openalealab/model", itemData) drag = QtGui.QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(QtCore.QPoint(pixmap.width() / 2, pixmap.height() / 2)) drag.setPixmap(pixmap) drag.start(QtCore.Qt.CopyAction) elif category == 'data': p = '%s/%r' % (category, str(obj.filename)) mimetype, mimedata = encode(obj, mimetype='openalealab/data') qmime_data = QtCore.QMimeData() qmime_data.setData(mimetype, mimedata) qmime_data.setText(p) drag = QtGui.QDrag(self) drag.setMimeData(qmime_data) drag.start() def dragEnterEvent(self, event): if event.mimeData().hasFormat("openalealab/model"): event.accept() else: event.ignore() def dragMoveEvent(self, event): if event.mimeData().hasFormat("openalealab/model"): event.setDropAction(QtCore.Qt.MoveAction) event.accept() else: event.ignore() def dropEvent(self, event): event.ignore()
class ProjectManagerView(QtGui.QTreeView): def __init__(self): QtGui.QTreeView.__init__(self) self._model = ProjectManagerModel() self.pm = ProjectManager() 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._actions = [] self._new_file_actions = {} self.paradigms_actions = [] self.paradigms = {} self.actionEditMeta = QtGui.QAction(qicon("book.png"), "Edit Project Information", self) self.actionEditMeta.triggered.connect(self.edit_metadata) self.actionImportFile = QtGui.QAction(qicon("open.png"), "Import file", self) self.actionImportFile.triggered.connect(self.import_file) self.actionSaveProjAs = QtGui.QAction(qicon("save.png"), "Save As", self) self.actionSaveProjAs.triggered.connect(self.save_as) self.actionSaveProj = QtGui.QAction(qicon("save.png"), "Save project", self) self.actionSaveProj.triggered.connect(self.save) self.actionSaveProj.setShortcut( QtGui.QApplication.translate("MainWindow", "Ctrl+Shift+S", None, QtGui.QApplication.UnicodeUTF8)) self.actionCloseProj = QtGui.QAction(qicon("closeButton.png"), "Close project", self) self.actionCloseProj.triggered.connect(self.close) self.actionCloseProj.setShortcut(self.tr("Ctrl+Shift+W")) self.actionNewProj = QtGui.QAction(qicon("new.png"), "New Project", self) self.actionNewProj.triggered.connect(self.new_project) self.actionNewProj.setShortcut(self.tr("Ctrl+Shift+N")) self.actionOpenProj = QtGui.QAction(qicon("open.png"), "Open Project", self) self.actionOpenProj.triggered.connect(self.open_project) self.actionOpenProj.setShortcut(self.tr('Ctrl+Shift+O')) # API def _get_paradigm_container(self): if plugin_instance_exists('oalab.applet', 'EditorManager'): return plugin_instance('oalab.applet', 'EditorManager') paradigm_container = property(fget=_get_paradigm_container) def initialize(self): pass def set_project(self, project): # 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.close_all_scripts() # self.open_all_scripts_from_project(project) self.expandAll() else: self.close_all_scripts() def refresh(self): self._model.refresh() # Convenience methods def getItem(self): index = self.getIndex() if index: return self._model.itemFromIndex(index) def getIndex(self): indices = self.selectedIndexes() for index in indices: return index def project(self): if self.pm: return self.pm.cproject def selected_data(self): index = self.getIndex() project = self.project() data = self._model.projectdata(index) if index is None or project is None or data is None: return (None, None, None) else: category, name = data return project, category, name # Slots def _on_model_changed(self): self.expandAll() # Contextual menu def add_new_file_actions(self, menu): for applet in self.paradigm_container.paradigms.values(): action = QtGui.QAction(qicon(applet.icon), 'New %s' % applet.default_name, self) action.triggered.connect(self.new_file) self._new_file_actions[action] = applet menu.addAction(action) menu.addSeparator() def create_menu(self): menu = QtGui.QMenu(self) project, category, obj = self.selected_data() if category == 'category' and obj == 'model': self.add_new_file_actions(menu) elif category == 'category' and obj == 'data': import_data = QtGui.QAction(qicon('import.png'), 'Import data', self) import_data.triggered.connect(self.open) menu.addAction(import_data) elif category == 'category' and obj in ('startup', 'doc', 'lib'): new_startup = QtGui.QAction(qicon('filenew.png'), 'New file', self) new_startup.triggered.connect(self.new_file) menu.addAction(new_startup) if category == 'model': self.add_new_file_actions(menu) if category in ['model', 'src', 'startup', 'doc', 'data', 'lib']: editAction = QtGui.QAction(qicon('open.png'), 'Open "%s"' % obj, self) menu.addAction(editAction) editAction.triggered.connect(self.open) rename = QtGui.QAction(qicon('Crystal_Clear_action_editcopy.png'), 'Rename', self) rename.triggered.connect(self.rename) menu.addAction(rename) remove = QtGui.QAction( qicon('Crystal_Clear_action_edit_remove.png'), 'Remove', self) remove.triggered.connect(self.remove) menu.addAction(remove) menu.addSeparator() deleteAction = QtGui.QAction( qicon('Crystal_Clear_action_stop.png'), 'Delete', self) menu.addAction(deleteAction) deleteAction.triggered.connect(self.delete) if category in ['project']: menu.addAction(self.actionEditMeta) menu.addAction(self.actionSaveProj) menu.addAction(self.actionSaveProjAs) menu.addAction(self.actionCloseProj) return menu def contextMenuEvent(self, event): if self.pm.cproject is None: return menu = self.create_menu() menu.exec_(event.globalPos()) # Action's slots def edit_metadata(self): project = self.project() if project: project_creator = CreateProjectWidget(project) dialog = ModalDialog(project_creator) if dialog.exec_(): _proj = project_creator.project() if _proj.name != project.name or _proj.projectdir != project.projectdir: project.move(_proj.path) project.metadata = project_creator.metadata() project.save() def open_project(self, name=False, path=None): """ If name==false, display a widget to choose project to open. Then open project. """ self.pm.discover() projects = self.pm.projects self.proj_selector = ProjectSelectorScroll(projects=projects) self.proj_selector.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.proj_selector.show() def new_project(self): project_creator = CreateProjectWidget() dialog = ModalDialog(project_creator) if dialog.exec_(): project = project_creator.project() self.pm.cproject = project def open_all_scripts_from_project(self, project): if self.paradigm_container is not None: for model in project.model.values(): self.paradigm_container.open_data(model) def new_file(self, dtype=None): try: applet = self._new_file_actions[self.sender()] except KeyError: dtype = None else: dtype = applet.default_name project, category, data = self.selected_data() code = '' project = self.project() if category == 'category': category = data elif category in project.DEFAULT_CATEGORIES: pass else: category = None if dtype is None and category in ['startup', 'lib']: dtype = 'Python' if category in ['startup', 'lib']: d = {'startup': 'start.py', 'lib': 'algo.py'} name = d[category] elif dtype: klass = DataClass(MimeType(name=dtype)) name = '%s_%s.%s' % (klass.default_name, category, klass.extension) else: name = category category, data = self.paradigm_container.add(project, name, code, dtype=dtype, category=category) if data: self.paradigm_container.open_data(data) def open(self): project, category, name = self.selected_data() if project: 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.paradigm_container.open_data(project.get(category, name)) def _rename(self, project, category, name): if category in project.DEFAULT_CATEGORIES: filelist = getattr(project, category).keys() renamer = RenameModel(filelist, name) dialog = ModalDialog(renamer) if dialog.exec_(): old_name = renamer.old_name() new_name = renamer.new_name() project.rename_item(category, old_name, new_name) elif category == 'project': self.edit_metadata() def rename(self): project, category, name = self.selected_data() if project: self._rename(project, category, name) def remove(self): project, category, name = self.selected_data() if project: project.remove(category, filename=name) def delete(self): project, category, name = self.selected_data() if project: if category in project.DEFAULT_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() if self.paradigm_container: self.paradigm_container.close_data(data) def save(self): project = self.project() if project: project.save() if self.paradigm_container: self.paradigm_container.save_all() def save_as(self): project = self.project() if project: p = path( self.showNewProjectDialog( default_name=None, text="Select name to save project")).abspath() projectdir, name = p.splitpath() if name: project.save_as(projectdir, name) def close(self): self.pm.cproject = None def close_all_scripts(self): if self.paradigm_container is None: return self.paradigm_container.closeAll() def import_file(self): print 'import_file' def showNewProjectDialog(self, default_name=None, text=None, parent=None): my_path = path(settings.get_project_dir()) if default_name: my_path = my_path / default_name if not text: text = 'Select name to create project' fname = QtGui.QFileDialog.getSaveFileName(parent, text, my_path) return fname def showOpenProjectDialog(self, parent=None): my_path = path(settings.get_project_dir()) fname = QtGui.QFileDialog.getExistingDirectory( parent, 'Select Project Directory', my_path) return fname # Drag and drop def startDrag(self, supportedActions): index = self.getIndex() item = self.getItem() data = self._model.projectdata(index) if data is None: return category, name = data # Check item in src # TODO move this part in dragEnterEvent with mimetype obj = self._model._project.get(category, name) if category in ['src', 'model']: # Read file and parse model to get inputs, outputs, doc that may be # useful once dropped. obj.read() text = item.text() # name_without_ext = ".".join(text.split(".")[:-1]) name_without_ext = text name_without_space = "_".join(name_without_ext.split()) for sym in ["-", "+", "*", "/", "\"", "."]: name_without_space = "_".join(name_without_space.split(sym)) python_call_string = '%s = Model("%s")' % (name_without_space, name_without_ext) icon = item.icon() pixmap = icon.pixmap(20, 20) itemData = QtCore.QByteArray() dataStream = QtCore.QDataStream(itemData, QtCore.QIODevice.WriteOnly) model_id = name_without_ext dataStream.writeString(str(python_call_string)) dataStream.writeString(str(model_id)) mimeData = QtCore.QMimeData() mimeData.setText(python_call_string) mimeData.setData("openalealab/model", itemData) drag = QtGui.QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot( QtCore.QPoint(pixmap.width() / 2, pixmap.height() / 2)) drag.setPixmap(pixmap) drag.start(QtCore.Qt.CopyAction) elif category == 'data': p = '%s/%r' % (category, str(obj.filename)) mimetype, mimedata = encode(obj, mimetype='openalealab/data') qmime_data = QtCore.QMimeData() qmime_data.setData(mimetype, mimedata) qmime_data.setText(p) drag = QtGui.QDrag(self) drag.setMimeData(qmime_data) drag.start() def dragEnterEvent(self, event): if event.mimeData().hasFormat("openalealab/model"): event.accept() else: event.ignore() def dragMoveEvent(self, event): if event.mimeData().hasFormat("openalealab/model"): event.setDropAction(QtCore.Qt.MoveAction) event.accept() else: event.ignore() def dropEvent(self, event): event.ignore()