Exemple #1
0
 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 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()
Exemple #4
0
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()