예제 #1
0
class MainWindow(QtWidgets.QMainWindow):
    """The main application
    """

    __company_name__ = 'Erkan Ozgur Yilmaz'
    __app_name__ = 'Project Manager'
    __version__ = '0.0.1'

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setup_db()

        # Authentication Storage
        self.login_action = None
        self.logout_action = None
        self.logged_in_user = self.login()

        self.project_dock_widget = None

        # import qdarkgraystyle
        # app = QtWidgets.QApplication.instance()
        #
        # from anima.ui.lib import IS_PYQT4, IS_PYSIDE, IS_PYSIDE2
        #
        # if IS_PYSIDE():
        #     app.setStyleSheet(qdarkgraystyle.load_stylesheet())
        # elif IS_PYQT4():
        #     app.setStyleSheet(qdarkgraystyle.load_stylesheet(pyside=False))
        # elif IS_PYSIDE2():
        #     app.setStyleSheet(qdarkgraystyle.load_stylesheet_pyqt5())

        # storage for UI stuff
        self.task_dashboard_widget = None
        self.tasks_tree_view = None

        # self.setWindowFlags(QtCore.Qt.ApplicationAttribute)

        self.settings = QtCore.QSettings(
            self.__company_name__,
            self.__app_name__
        )
        self.setup_ui()

    @classmethod
    def setup_db(cls):
        """setup the db
        """
        from anima.utils import do_db_setup
        do_db_setup()

    def setup_ui(self):
        """creates the UI widgets
        """
        self.setWindowTitle("%s v%s" % (self.__app_name__, self.__version__))

        # set application icon
        from anima import ui
        import os
        print('ui.__path__: %s' % ui.__path__[0])

        app_icon_path = os.path.join(
            ui.__path__[0],
            'images',
            'app_icon.png'
        )
        self.setWindowIcon(QtGui.QIcon(app_icon_path))

        self.create_main_menu()
        self.create_toolbars()
        self.create_dock_widgets()

        self.read_settings()

    def write_settings(self):
        """stores the settings to persistent storage
        """
        self.settings.beginGroup("MainWindow")

        self.settings.setValue("size", self.size())
        self.settings.setValue("pos", self.pos())
        self.settings.setValue("windowState", self.saveState())

        self.settings.endGroup()

    def read_settings(self):
        """read settings from persistent storage
        """
        self.settings.beginGroup('MainWindow')

        self.resize(self.settings.value('size', QtCore.QSize(800, 600)))
        self.move(self.settings.value('pos', QtCore.QPoint(100, 100)))
        self.restoreState(self.settings.value('windowState'))

        self.settings.endGroup()

    def reset_window_state(self):
        """reset window states
        """
        self.project_dock_widget.setVisible(True)

    def create_main_menu(self):
        """creates the main application menu
        """
        file_menu = self.menuBar().addMenu(self.tr("&File"))

        # -------------------------
        # Authentication Actions
        self.login_action = file_menu.addAction("&Login...")
        self.logout_action = file_menu.addAction("&Logout...")

        if self.logged_in_user:
            # hide login_action
            self.login_action.setVisible(False)
        else:
            # hide logout_action
            self.login_action.setVisible(False)

        QtCore.QObject.connect(
            self.login_action,
            QtCore.SIGNAL('triggered()'),
            self.login
        )

        QtCore.QObject.connect(
            self.logout_action,
            QtCore.SIGNAL('triggered()'),
            self.logout
        )

        file_menu.addSeparator()

        # ---------------------------
        # Standard File menu actions

        create_project_action = file_menu.addAction('&Create Project...')
        # open_action = file_menu.addAction('&Open...')
        # save_action = file_menu.addAction('&Save...')

        # run the new Project dialog
        QtCore.QObject.connect(
            create_project_action,
            QtCore.SIGNAL("triggered()"),
            self.create_project_action_clicked
        )

        file_menu.addSeparator()

        exit_action = file_menu.addAction('E&xit')
        QtCore.QObject.connect(
            exit_action,
            QtCore.SIGNAL('triggered()'),
            self.close
        )

        view_menu = self.menuBar().addMenu(self.tr("&View"))

        reset_action = view_menu.addAction("&Reset Window States")
        QtCore.QObject.connect(
            reset_action,
            QtCore.SIGNAL('triggered()'),
            self.reset_window_state
        )

        # QtWidgets.QAction.

    def create_project_action_clicked(self):
        """runs when new project menu action is clicked
        """
        # show the new project dialog
        from anima.ui import project_dialog
        dialog = project_dialog.MainDialog(parent=self)
        dialog.exec_()

        # and refresh the TaskTreeView
        try:
            # PySide and PySide2
            accepted = QtWidgets.QDialog.DialogCode.Accepted
        except AttributeError:
            # PyQt4
            accepted = QtWidgets.QDialog.Accepted

        # refresh the task list
        if dialog.result() == accepted:
            self.tasks_tree_view.fill()

        dialog.deleteLater()

    def login(self):
        """returns the logged in user
        """
        from stalker import LocalSession
        local_session = LocalSession()
        from stalker.db.session import DBSession
        with DBSession.no_autoflush:
            logged_in_user = local_session.logged_in_user

        if not logged_in_user:
            from anima.ui import login_dialog
            dialog = login_dialog.MainDialog(parent=self)
            # dialog.deleteLater()
            dialog.exec_()
            result = dialog.result()

            try:
                # PySide
                accepted = QtWidgets.QDialog.DialogCode.Accepted
            except AttributeError:
                # PyQt4
                accepted = QtWidgets.QDialog.Accepted

            if result == accepted:
                local_session = LocalSession()
                logged_in_user = local_session.logged_in_user
            else:
                # close the ui
                # logged_in_user = self.get_logged_in_user()
                self.close()

            dialog.deleteLater()

        return logged_in_user

    def logout(self):
        """log the current user out
        """
        from stalker import LocalSession
        session = LocalSession()
        session.delete()

        self.logged_in_user = None
        # update file menu actions
        # self.logout_action.setVisible(False)
        # self.login_action.setVisible(True)
        self.close()

    def create_toolbars(self):
        """creates the toolbars
        """
        file_toolbar = self.addToolBar(self.tr("File"))
        file_toolbar.setObjectName('file_toolbar')
        create_project_action = file_toolbar.addAction('Create Project')

        # Create signals
        QtCore.QObject.connect(
            create_project_action,
            QtCore.SIGNAL('triggered()'),
            self.create_project_action_clicked
        )

    def create_dock_widgets(self):
        """creates the dock widgets
        """
        # ----------------------------------------
        # create the Project Dock Widget
        self.project_dock_widget = QtWidgets.QDockWidget('Projects', self)
        self.project_dock_widget.setObjectName('project_dock_widget')
        # create the TaskTreeView as the main widget
        from anima.ui.views.task import TaskTreeView
        self.tasks_tree_view = TaskTreeView(parent=self, allow_multi_selection=True)
        self.tasks_tree_view.setEditTriggers(
            QtWidgets.QAbstractItemView.NoEditTriggers
        )

        self.tasks_tree_view.show_completed_projects = True
        self.tasks_tree_view.fill()

        # also setup the signal
        QtCore.QObject.connect(
            self.tasks_tree_view.selectionModel(),
            QtCore.SIGNAL('selectionChanged(const QItemSelection &, '
                          'const QItemSelection &)'),
            self.tasks_tree_view_changed
        )

        self.project_dock_widget.setWidget(self.tasks_tree_view)

        # and set the left dock widget
        self.addDockWidget(
            QtCore.Qt.LeftDockWidgetArea,
            self.project_dock_widget
        )

        # ----------------------------------------
        # create the Central Widget
        from anima.ui.widgets.task_dashboard import TaskDashboardWidget
        self.task_dashboard_widget = TaskDashboardWidget(parent=self)
        self.setCentralWidget(self.task_dashboard_widget)

    def tasks_tree_view_changed(self):
        """runs when the tasks tree view changed
        """
        # get the currently selected task
        task_id = None
        task_ids = self.tasks_tree_view.get_selected_task_ids()
        if task_ids:
            task_id = task_ids[-1]

        from stalker import Task
        task = Task.query.get(task_id)

        # update the task dashboard widget
        self.task_dashboard_widget.task = task

    def show_and_raise(self):
        """
        """
        self.show()
        self.raise_()

    def closeEvent(self, event):
        """The overridden close event
        """
        self.write_settings()
        event.accept()
예제 #2
0
class VersionMover(QtWidgets.QDialog, AnimaDialogBase):
    """Moves versions from one task to other.

    It is capable of moving the files or just copying and creating a new
    version instance.
    """
    def __init__(self, parent=None):
        super(VersionMover, self).__init__(parent)

        self.vertical_layout = None
        self.horizontal_layout = None
        self.horizontal_layout_2 = None
        self.from_task_tree_view = None
        self.to_task_tree_view = None
        self.copy_push_button = None

        self.setup_ui(self)

    def setup_ui(self, dialog):
        """Sets up the dialog

        :param dialog: QtGui.QDialog instance
        :return:
        """
        dialog.setObjectName("Dialog")
        dialog.setWindowModality(QtCore.Qt.ApplicationModal)
        dialog.resize(1200, 800)
        # layout vertical first
        self.vertical_layout = QtWidgets.QVBoxLayout(dialog)
        self.vertical_layout.setObjectName('verticalLayout1')

        self.horizontal_layout = QtWidgets.QHBoxLayout()

        self.from_task_tree_view = QtWidgets.QTreeView(dialog)
        self.from_task_tree_view.setObjectName("from_tasks_treeView")

        self.copy_push_button = QtWidgets.QPushButton(dialog)
        self.copy_push_button.setObjectName("copy_push_button")
        self.copy_push_button.setText('>')

        self.to_task_tree_view = TaskTreeView(dialog)
        self.to_task_tree_view.setObjectName("to_tasks_treeView")

        # self.horizontal_layout1.addWidget(self.from_task_tree_view)
        self.horizontal_layout.addWidget(self.from_task_tree_view)
        self.horizontal_layout.addWidget(self.copy_push_button)
        self.horizontal_layout.addWidget(self.to_task_tree_view)

        self.vertical_layout.addLayout(self.horizontal_layout)

        self.horizontal_layout_2 = QtWidgets.QHBoxLayout()
        self.horizontal_layout_2.setContentsMargins(-1, 10, -1, -1)
        self.horizontal_layout_2.setObjectName("horizontal_layout_2")

        self.vertical_layout.addLayout(self.horizontal_layout_2)

        QtCore.QMetaObject.connectSlotsByName(dialog)

        # initialize elements

        logged_in_user = self.get_logged_in_user()
        projects = Project.query.order_by(Project.name).all()

        task_tree_model = TaskTreeModel()
        task_tree_model.user = logged_in_user
        task_tree_model.populateTree(projects)

        # fit to elements
        self.from_tasks_tree_view_auto_fit_column()
        self.to_tasks_tree_view_auto_fit_column()

        self.from_task_tree_view.setModel(task_tree_model)
        self.to_task_tree_view.setModel(task_tree_model)

        # setup signals
        # tasks_treeView
        QtCore.QObject.connect(
            self.from_task_tree_view.selectionModel(),
            QtCore.SIGNAL('selectionChanged(const QItemSelection &, '
                          'const QItemSelection &)'),
            self.from_task_tree_view_changed)

        QtCore.QObject.connect(
            self.to_task_tree_view.selectionModel(),
            QtCore.SIGNAL('selectionChanged(const QItemSelection &, '
                          'const QItemSelection &)'),
            self.to_task_tree_view_changed)

        # fit column 0 on expand/collapse
        QtCore.QObject.connect(self.from_task_tree_view,
                               QtCore.SIGNAL('expanded(QModelIndex)'),
                               self.from_tasks_tree_view_auto_fit_column)

        QtCore.QObject.connect(self.to_task_tree_view,
                               QtCore.SIGNAL('expanded(QModelIndex)'),
                               self.to_tasks_tree_view_auto_fit_column)

        # copy_push_button
        QtCore.QObject.connect(self.copy_push_button,
                               QtCore.SIGNAL("clicked()"), self.copy_versions)

    def from_tasks_tree_view_auto_fit_column(self):
        """fits columns to content
        """
        self.from_task_tree_view.resizeColumnToContents(0)

    def to_tasks_tree_view_auto_fit_column(self):
        """fits columns to content
        """
        self.to_task_tree_view.resizeColumnToContents(0)

    def from_task_tree_view_changed(self):
        """
        """
        pass

    def to_task_tree_view_changed(self):
        """
        """
        pass

    def get_task_from_tree_view(self, tree_view):
        """returns the task object from the given QTreeView
        """
        task = None
        selection_model = tree_view.selectionModel()

        indexes = selection_model.selectedIndexes()

        if indexes:
            current_index = indexes[0]

            item_model = tree_view.model()
            current_item = item_model.itemFromIndex(current_index)

            if current_item:
                try:
                    task = current_item.task
                except AttributeError:
                    pass

        return task

    def copy_versions(self):
        """copies versions from one task to another
        """
        # get from task
        from_task = self.get_task_from_tree_view(self.from_task_tree_view)

        # get logged in user
        logged_in_user = self.get_logged_in_user()

        if not from_task:
            QtWidgets.QMessageBox.critical(
                self, 'Error',
                'Please select a task from <b>From Task</b> list')
            return

        # get to task
        to_task = self.get_task_from_tree_view(self.to_task_tree_view)

        if not to_task:
            QtWidgets.QMessageBox.critical(
                self, 'Error', 'Please select a task from <b>To Task</b> list')
            return

        # check if tasks are the same
        if from_task == to_task:
            QtWidgets.QMessageBox.critical(
                self, 'Error', 'Please select two different tasks')
            return

        # get take names and related versions
        # get distinct take names
        from stalker.db.session import DBSession
        from_take_names = map(
            lambda x: x[0],
            DBSession.query(distinct(Version.take_name)).filter(
                Version.task == from_task).order_by(Version.take_name).all())

        # create versions for each take
        answer = QtWidgets.QMessageBox.question(
            self, 'Info', "Will copy %s versions from take names:<br><br>"
            "%s"
            "<br><br>"
            "Is that Ok?" %
            (len(from_take_names), '<br>'.join(from_take_names)),
            QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)

        if answer == QtWidgets.QMessageBox.Yes:
            for take_name in from_take_names:
                latest_version = Version.query\
                    .filter_by(task=from_task)\
                    .filter_by(take_name=take_name)\
                    .order_by(Version.version_number.desc())\
                    .first()

                # create a new version
                new_version = Version(task=to_task, take_name=take_name)
                new_version.created_by = logged_in_user
                new_version.extension = latest_version.extension
                new_version.description = \
                    'Moved from another task (id=%s) with Version Mover' % \
                    latest_version.task.id
                new_version.created_with = latest_version.created_with
                DBSession.add(new_version)
                DBSession.commit()

                # update path
                new_version.update_paths()
                DBSession.add(new_version)
                DBSession.commit()

                # now copy the last_version file to the new_version path
                try:
                    os.makedirs(new_version.absolute_path)
                except OSError:  # path exists
                    pass

                # move the file there
                shutil.copyfile(latest_version.absolute_full_path,
                                new_version.absolute_full_path)

            # inform the user
            QtWidgets.QMessageBox.information(
                self, 'Success',
                'Successfully copied %s versions' % len(from_take_names))
예제 #3
0
class MainWindow(QtWidgets.QMainWindow):
    """The main application
    """

    __company_name__ = 'Erkan Ozgur Yilmaz'
    __app_name__ = 'Project Manager'
    __version__ = '0.0.1'

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setup_db()

        # Authentication Storage
        self.login_action = None
        self.logout_action = None
        self.logged_in_user = self.login()

        self.project_dock_widget = None

        # import qdarkgraystyle
        # app = QtWidgets.QApplication.instance()
        #
        # from anima.ui.lib import IS_PYQT4, IS_PYSIDE, IS_PYSIDE2
        #
        # if IS_PYSIDE():
        #     app.setStyleSheet(qdarkgraystyle.load_stylesheet())
        # elif IS_PYQT4():
        #     app.setStyleSheet(qdarkgraystyle.load_stylesheet(pyside=False))
        # elif IS_PYSIDE2():
        #     app.setStyleSheet(qdarkgraystyle.load_stylesheet_pyqt5())

        # storage for UI stuff
        self.task_dashboard_widget = None
        self.tasks_tree_view = None

        self.setWindowFlags(QtCore.Qt.ApplicationAttribute)
        self.settings = QtCore.QSettings(
            self.__company_name__,
            self.__app_name__
        )
        self.setup_ui()

    @classmethod
    def setup_db(cls):
        """setup the db
        """
        from anima.utils import do_db_setup
        do_db_setup()

    def setup_ui(self):
        """creates the UI widgets
        """
        self.setWindowTitle("%s v%s" % (self.__app_name__, self.__version__))

        # set application icon
        from anima import ui
        import os
        print('ui.__path__: %s' % ui.__path__[0])

        app_icon_path = os.path.join(
            ui.__path__[0],
            'images',
            'app_icon.png'
        )
        self.setWindowIcon(QtGui.QIcon(app_icon_path))

        self.create_main_menu()
        self.create_toolbars()
        self.create_dock_widgets()

        self.read_settings()

    def write_settings(self):
        """stores the settings to persistent storage
        """
        self.settings.beginGroup("MainWindow")

        self.settings.setValue("size", self.size())
        self.settings.setValue("pos", self.pos())
        self.settings.setValue("windowState", self.saveState())

        self.settings.endGroup()

    def read_settings(self):
        """read settings from persistent storage
        """
        self.settings.beginGroup('MainWindow')

        self.resize(self.settings.value('size', QtCore.QSize(800, 600)))
        self.move(self.settings.value('pos', QtCore.QPoint(100, 100)))
        self.restoreState(self.settings.value('windowState'))

        self.settings.endGroup()

    def reset_window_state(self):
        """reset window states
        """
        self.project_dock_widget.setVisible(True)

    def create_main_menu(self):
        """creates the main application menu
        """
        file_menu = self.menuBar().addMenu(self.tr("&File"))

        # -------------------------
        # Authentication Actions
        self.login_action = file_menu.addAction("&Login...")
        self.logout_action = file_menu.addAction("&Logout...")

        if self.logged_in_user:
            # hide login_action
            self.login_action.setVisible(False)
        else:
            # hide logout_action
            self.login_action.setVisible(False)

        QtCore.QObject.connect(
            self.login_action,
            QtCore.SIGNAL('triggered()'),
            self.login
        )

        QtCore.QObject.connect(
            self.logout_action,
            QtCore.SIGNAL('triggered()'),
            self.logout
        )

        file_menu.addSeparator()

        # ---------------------------
        # Standard File menu actions

        create_project_action = file_menu.addAction('&Create Project...')
        # open_action = file_menu.addAction('&Open...')
        # save_action = file_menu.addAction('&Save...')

        # run the new Project dialog
        QtCore.QObject.connect(
            create_project_action,
            QtCore.SIGNAL("triggered()"),
            self.create_project_action_clicked
        )

        file_menu.addSeparator()

        exit_action = file_menu.addAction('E&xit')
        QtCore.QObject.connect(
            exit_action,
            QtCore.SIGNAL('triggered()'),
            self.close
        )

        view_menu = self.menuBar().addMenu(self.tr("&View"))

        reset_action = view_menu.addAction("&Reset Window States")
        QtCore.QObject.connect(
            reset_action,
            QtCore.SIGNAL('triggered()'),
            self.reset_window_state
        )

        # QtWidgets.QAction.

    def create_project_action_clicked(self):
        """runs when new project menu action is clicked
        """
        # show the new project dialog
        from anima.ui import project_dialog
        dialog = project_dialog.MainDialog(parent=self)
        dialog.exec_()

        # and refresh the TaskTreeView
        try:
            # PySide and PySide2
            accepted = QtWidgets.QDialog.DialogCode.Accepted
        except AttributeError:
            # PyQt4
            accepted = QtWidgets.QDialog.Accepted

        # refresh the task list
        if dialog.result() == accepted:
            self.tasks_tree_view.fill()

        dialog.deleteLater()

    def login(self):
        """returns the logged in user
        """
        from stalker import LocalSession
        local_session = LocalSession()
        from stalker.db.session import DBSession
        with DBSession.no_autoflush:
            logged_in_user = local_session.logged_in_user

        if not logged_in_user:
            from anima.ui import login_dialog
            dialog = login_dialog.MainDialog(parent=self)
            # dialog.deleteLater()
            dialog.exec_()
            result = dialog.result()

            try:
                # PySide
                accepted = QtWidgets.QDialog.DialogCode.Accepted
            except AttributeError:
                # PyQt4
                accepted = QtWidgets.QDialog.Accepted

            if result == accepted:
                local_session = LocalSession()
                logged_in_user = local_session.logged_in_user
            else:
                # close the ui
                # logged_in_user = self.get_logged_in_user()
                self.close()

            dialog.deleteLater()

        return logged_in_user

    def logout(self):
        """log the current user out
        """
        from stalker import LocalSession
        session = LocalSession()
        session.delete()

        self.logged_in_user = None
        # update file menu actions
        # self.logout_action.setVisible(False)
        # self.login_action.setVisible(True)
        self.close()

    def create_toolbars(self):
        """creates the toolbars
        """
        file_toolbar = self.addToolBar(self.tr("File"))
        file_toolbar.setObjectName('file_toolbar')
        create_project_action = file_toolbar.addAction('Create Project')

        # Create signals
        QtCore.QObject.connect(
            create_project_action,
            QtCore.SIGNAL('triggered()'),
            self.create_project_action_clicked
        )

    def create_dock_widgets(self):
        """creates the dock widgets
        """
        # ----------------------------------------
        # create the Project Dock Widget
        self.project_dock_widget = QtWidgets.QDockWidget('Projects', self)
        self.project_dock_widget.setObjectName('project_dock_widget')
        # create the TaskTreeView as the main widget
        from anima.ui.views.task import TaskTreeView
        self.tasks_tree_view = TaskTreeView(parent=self)
        self.tasks_tree_view.setEditTriggers(
            QtWidgets.QAbstractItemView.NoEditTriggers
        )

        self.tasks_tree_view.show_completed_projects = True
        self.tasks_tree_view.fill()

        # also setup the signal
        QtCore.QObject.connect(
            self.tasks_tree_view.selectionModel(),
            QtCore.SIGNAL('selectionChanged(const QItemSelection &, '
                          'const QItemSelection &)'),
            self.tasks_tree_view_changed
        )

        self.project_dock_widget.setWidget(self.tasks_tree_view)

        # and set the left dock widget
        self.addDockWidget(
            QtCore.Qt.LeftDockWidgetArea,
            self.project_dock_widget
        )

        # ----------------------------------------
        # create the Central Widget
        from anima.ui.widgets.task_dashboard import TaskDashboardWidget
        self.task_dashboard_widget = TaskDashboardWidget(parent=self)
        self.setCentralWidget(self.task_dashboard_widget)

    def tasks_tree_view_changed(self):
        """runs when the tasks tree view changed
        """
        # get the currently selected task
        task_id = self.tasks_tree_view.get_task_id()
        from stalker import Task
        task = Task.query.get(task_id)

        # update the task dashboard widget
        self.task_dashboard_widget.task = task
        self.task_dashboard_widget.fill_ui()

    def show_and_raise(self):
        """
        """
        self.show()
        self.raise_()

    def closeEvent(self, event):
        """The overridden close event
        """
        self.write_settings()
        event.accept()