Пример #1
0
 def upload_thumbnail_button_clicked(self):
     """replaces the thumbnail
     """
     # print('thumbnail button clicked')
     # self.upload_thumbnail_button.setVisible(False)
     from anima.ui import utils
     thumbnail_full_path = utils.choose_thumbnail(self)
     utils.upload_thumbnail(self.task, thumbnail_full_path)
     self.fill_ui()
Пример #2
0
 def upload_thumbnail_button_clicked(self):
     """replaces the thumbnail
     """
     # print('thumbnail button clicked')
     # self.upload_thumbnail_button.setVisible(False)
     from anima.ui import utils
     thumbnail_full_path = utils.choose_thumbnail(self)
     utils.upload_thumbnail(self.task, thumbnail_full_path)
     self.fill_ui()
Пример #3
0
    def show_context_menu(self, position):
        """the custom context menu
        """
        # convert the position to global screen position
        global_position = self.mapToGlobal(position)

        index = self.indexAt(position)
        model = self.model()
        item = model.itemFromIndex(index)
        logger.debug('itemAt(position) : %s' % item)
        task_id = None
        entity = None

        # if not item:
        #     return

        # if item and not hasattr(item, 'task'):
        #     return

        from anima.ui.models.task import TaskItem
        #if not isinstance(item, TaskItem):
        #    return

        if item and item.task:
            task_id = item.task.id

        # if not task_id:
        #     return

        from anima import utils
        file_browser_name = utils.file_browser_name()

        # create the menu
        menu = QtWidgets.QMenu()  # Open in browser

        # sub menus
        create_sub_menu = menu.addMenu('Create')
        update_sub_menu = menu.addMenu('Update')

        # -----------------------------------
        # actions created in different scopes
        create_time_log_action = None
        create_project_action = None
        update_task_action = None
        upload_thumbnail_action = None
        create_child_task_action = None
        duplicate_task_hierarchy_action = None
        delete_task_action = None
        no_deps_action = None
        create_project_structure_action = None
        create_task_structure_action = None
        update_project_action = None
        assign_users_action = None
        open_in_web_browser_action = None
        open_in_file_browser_action = None
        copy_url_action = None
        copy_id_to_clipboard = None
        fix_task_status_action = None
        change_status_menu_actions = []

        from anima import defaults
        from stalker import LocalSession
        local_session = LocalSession()
        logged_in_user = local_session.logged_in_user

        from stalker import SimpleEntity, Task, Project
        # TODO: Update this to use only task_id
        if task_id:
            entity = SimpleEntity.query.get(task_id)

        if defaults.is_power_user(logged_in_user):
            # create the Create Project menu item
            create_project_action = \
                create_sub_menu.addAction(u'\uf0e8 Create Project...')

            if isinstance(entity, Project):
                # this is a project!
                if defaults.is_power_user(logged_in_user):
                    update_project_action = \
                        update_sub_menu.addAction(u'\uf044 Update Project...')
                    assign_users_action = \
                        menu.addAction(u'\uf0c0 Assign Users...')
                    create_project_structure_action = \
                        create_sub_menu.addAction(
                            u'\uf115 Create Project Structure'
                        )
                    create_child_task_action = \
                        create_sub_menu.addAction(
                            u'\uf0ae Create Child Task...'
                        )

        if entity:
            # separate the Project and Task related menu items
            menu.addSeparator()

            open_in_web_browser_action = \
                menu.addAction(u'\uf14c Open In Web Browser...')
            open_in_file_browser_action = \
                menu.addAction(u'\uf07c Browse Folders...')
            copy_url_action = menu.addAction(u'\uf0c5 Copy URL')
            copy_id_to_clipboard = \
                menu.addAction(u'\uf0c5 Copy ID to clipboard')

            if isinstance(entity, Task):
                # this is a task
                create_task_structure_action = \
                    create_sub_menu.addAction(
                        u'\uf115 Create Task Folder Structure'
                    )

                task = entity
                from stalker import Status
                status_wfd = Status.query.filter(Status.code == 'WFD').first()
                status_prev = \
                    Status.query.filter(Status.code == 'PREV').first()
                status_cmpl = \
                    Status.query.filter(Status.code == 'CMPL').first()
                if logged_in_user in task.resources \
                        and task.status not in [status_wfd, status_prev,
                                                status_cmpl]:
                    create_sub_menu.addSeparator()
                    create_time_log_action = \
                        create_sub_menu.addAction(u'\uf073 Create TimeLog...')

                # Add Depends To menu
                menu.addSeparator()
                depends = task.depends
                if depends:
                    depends_to_menu = menu.addMenu(u'\uf090 Depends To')

                    for dTask in depends:
                        action = depends_to_menu.addAction(dTask.name)
                        action.task = dTask

                # Add Dependent Of Menu
                dependent_of = task.dependent_of
                if dependent_of:
                    dependent_of_menu = menu.addMenu(u'\uf08b Dependent Of')

                    for dTask in dependent_of:
                        action = dependent_of_menu.addAction(dTask.name)
                        action.task = dTask

                if not depends and not dependent_of:
                    no_deps_action = menu.addAction(u'\uf00d No Dependencies')
                    no_deps_action.setEnabled(False)

                # update task and create child task menu items
                menu.addSeparator()
                if defaults.is_power_user(logged_in_user):
                    create_sub_menu.addSeparator()
                    update_task_action = \
                        update_sub_menu.addAction(u'\uf044 Update Task...')

                    upload_thumbnail_action = \
                        update_sub_menu.addAction(
                            u'\uf03e Upload Thumbnail...'
                        )

                    create_child_task_action = \
                        create_sub_menu.addAction(
                            u'\uf0ae Create Child Task...'
                        )
                    duplicate_task_hierarchy_action = \
                        create_sub_menu.addAction(
                            u'\uf0c5 Duplicate Task Hierarchy...'
                        )
                    delete_task_action = \
                        menu.addAction(u'\uf1f8 Delete Task...')

                # create the status_menu
                status_menu = update_sub_menu.addMenu('Status')

                fix_task_status_action = \
                    status_menu.addAction(u'\uf0e8 Fix Task Status')

                assert isinstance(status_menu, QtWidgets.QMenu)
                status_menu.addSeparator()

                # get all task statuses
                from anima import defaults

                menu_style_sheet = ''
                defaults_status_colors = defaults.status_colors
                for status_code in defaults.status_colors:
                    change_status_menu_action = \
                        status_menu.addAction(status_code)

                    change_status_menu_action.setObjectName('status_%s' %
                                                            status_code)

                    change_status_menu_actions.append(
                        change_status_menu_action)

                    menu_style_sheet = "%s %s" % (
                        menu_style_sheet,
                        "QMenu#status_%s { background: %s %s %s}" % (
                            status_code,
                            defaults_status_colors[status_code][0],
                            defaults_status_colors[status_code][1],
                            defaults_status_colors[status_code][2],
                        ))

                # change the BG Color of the status
                status_menu.setStyleSheet(menu_style_sheet)

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

        selected_item = menu.exec_(global_position)
        if selected_item:
            if create_project_action \
               and selected_item == create_project_action:
                from anima.ui import project_dialog
                project_main_dialog = project_dialog.MainDialog(parent=self,
                                                                project=None)
                project_main_dialog.exec_()
                result = project_main_dialog.result()

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

                project_main_dialog.deleteLater()

            if entity:
                from anima import defaults
                url = 'http://%s/%ss/%s/view' % (
                    defaults.stalker_server_internal_address,
                    entity.entity_type.lower(), entity.id)

                if selected_item is open_in_web_browser_action:
                    import webbrowser
                    webbrowser.open(url)
                elif selected_item is open_in_file_browser_action:
                    from anima import utils
                    try:
                        utils.open_browser_in_location(entity.absolute_path)
                    except IOError as e:
                        QtWidgets.QMessageBox.critical(
                            self, "Error", "%s" % e, QtWidgets.QMessageBox.Ok)
                elif selected_item is copy_url_action:
                    clipboard = QtWidgets.QApplication.clipboard()
                    clipboard.setText(url)

                    # and warn the user about a new version is created and the
                    # clipboard is set to the new version full path
                    QtWidgets.QMessageBox.warning(
                        self, "URL Copied To Clipboard",
                        "URL:<br><br>%s<br><br>is copied to clipboard!" % url,
                        QtWidgets.QMessageBox.Ok)
                elif selected_item is copy_id_to_clipboard:
                    clipboard = QtWidgets.QApplication.clipboard()
                    clipboard.setText('%s' % entity.id)

                    # and warn the user about a new version is created and the
                    # clipboard is set to the new version full path
                    QtWidgets.QMessageBox.warning(
                        self, "ID Copied To Clipboard",
                        "ID %s is copied to clipboard!" % entity.id,
                        QtWidgets.QMessageBox.Ok)

                elif selected_item is create_time_log_action:
                    from anima.ui import time_log_dialog
                    time_log_dialog_main_dialog = time_log_dialog.MainDialog(
                        parent=self,
                        task=entity,
                    )
                    time_log_dialog_main_dialog.exec_()
                    result = time_log_dialog_main_dialog.result()
                    time_log_dialog_main_dialog.deleteLater()

                    if result == accepted:
                        # refresh the task list
                        if item.parent:
                            item.parent.reload()
                        else:
                            self.fill()

                        # reselect the same task
                        self.find_and_select_entity_item(entity)

                elif selected_item is update_task_action:
                    from anima.ui import task_dialog
                    task_main_dialog = task_dialog.MainDialog(parent=self,
                                                              task=entity)
                    task_main_dialog.exec_()
                    result = task_main_dialog.result()
                    task_main_dialog.deleteLater()

                    # refresh the task list
                    if result == accepted:
                        # just reload the same item
                        if item.parent:
                            item.parent.reload()
                        else:
                            # reload the entire
                            self.fill()
                        self.find_and_select_entity_item(entity)

                elif selected_item is upload_thumbnail_action:
                    from anima.ui import utils as ui_utils
                    thumbnail_full_path = ui_utils.choose_thumbnail(self)

                    # if the thumbnail_full_path is empty do not do anything
                    if thumbnail_full_path == "":
                        return

                    # get the current task
                    ui_utils.upload_thumbnail(entity, thumbnail_full_path)

                elif selected_item == create_child_task_action:
                    from anima.ui import task_dialog
                    task_main_dialog = task_dialog.MainDialog(
                        parent=self, parent_task=entity)
                    task_main_dialog.exec_()
                    result = task_main_dialog.result()
                    task = task_main_dialog.task
                    task_main_dialog.deleteLater()

                    if result == accepted and task:
                        # reload the parent item
                        if item.parent:
                            item.parent.reload()
                        else:
                            self.fill()
                        self.find_and_select_entity_item(task)

                elif selected_item is duplicate_task_hierarchy_action:
                    duplicate_task_hierarchy_dialog = \
                        DuplicateTaskHierarchyDialog(
                            parent=self, duplicated_task_name=item.task.name
                        )
                    duplicate_task_hierarchy_dialog.exec_()

                    result = duplicate_task_hierarchy_dialog.result()
                    if result == accepted:
                        new_task_name = \
                            duplicate_task_hierarchy_dialog.line_edit.text()

                        keep_resources = \
                            duplicate_task_hierarchy_dialog\
                                .check_box.checkState()

                        from anima import utils
                        from stalker import Task
                        task = Task.query.get(item.task.id)
                        new_task = utils.duplicate_task_hierarchy(
                            task,
                            None,
                            new_task_name,
                            description='Duplicated from Task(%s)' % task.id,
                            user=logged_in_user,
                            keep_resources=keep_resources)
                        if new_task:
                            from stalker.db.session import DBSession
                            DBSession.commit()
                            item.parent.reload()
                            self.find_and_select_entity_item(new_task)

                elif selected_item is delete_task_action:
                    answer = QtWidgets.QMessageBox.question(
                        self, 'Delete Task?',
                        "Delete the task and children?<br><br>(NO UNDO!!!!)",
                        QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
                    if answer == QtWidgets.QMessageBox.Yes:
                        from stalker.db.session import DBSession
                        from stalker import Task
                        task = Task.query.get(item.task.id)
                        DBSession.delete(task)
                        DBSession.commit()
                        # reload the parent
                        if item.parent:
                            item.parent.reload()
                        else:
                            self.fill()
                        self.find_and_select_entity_item(item.parent.task)

                elif selected_item == create_project_structure_action:
                    answer = QtWidgets.QMessageBox.question(
                        self, 'Create Project Folder Structure?',
                        "This will create project folders, OK?",
                        QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
                    if answer == QtWidgets.QMessageBox.Yes:
                        from anima import utils
                        try:
                            utils.create_project_structure(entity)
                        except Exception as e:
                            pass
                        finally:
                            QtWidgets.QMessageBox.information(
                                self,
                                'Project Folder Structure is created!',
                                'Project Folder Structure is created!',
                            )
                    else:
                        return

                elif selected_item == create_task_structure_action:
                    answer = QtWidgets.QMessageBox.question(
                        self, 'Create Folder Structure?',
                        "This will create task folders, OK?",
                        QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
                    if answer == QtWidgets.QMessageBox.Yes:
                        from anima import utils
                        try:
                            utils.create_task_structure(entity)
                        except Exception as e:
                            pass
                        finally:
                            QtWidgets.QMessageBox.information(
                                self,
                                'Folder Structure is created!',
                                'Folder Structure is created!',
                            )
                    else:
                        return

                elif selected_item == fix_task_status_action:
                    from stalker import Task
                    if isinstance(entity, Task):
                        from anima import utils
                        utils.fix_task_statuses(entity)

                        from stalker.db.session import DBSession
                        DBSession.add(entity)
                        DBSession.commit()

                        if item.parent:
                            item.parent.reload()

                elif selected_item == update_project_action:
                    from anima.ui import project_dialog
                    project_main_dialog = project_dialog.MainDialog(
                        parent=self, project=entity)
                    project_main_dialog.exec_()
                    result = project_main_dialog.result()

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

                        # reselect the same task
                        self.find_and_select_entity_item(entity)

                    project_main_dialog.deleteLater()

                elif selected_item == assign_users_action:
                    from anima.ui import project_users_dialog
                    project_users_main_dialog = \
                        project_users_dialog.MainDialog(
                            parent=self,
                            project=entity
                        )
                    project_users_main_dialog.exec_()
                    result = project_users_main_dialog.result()

                    project_users_main_dialog.deleteLater()

                elif selected_item in change_status_menu_actions:
                    # get the status code
                    status_code = selected_item.text()

                    from sqlalchemy import func
                    status = \
                        Status.query.filter(
                            func.lower(Status.code) == func.lower(status_code)
                        ).first()

                    # change the status of the entity
                    # if it is a leaf task
                    # if it doesn't have any dependent_of
                    # assert isinstance(entity, Task)
                    if isinstance(entity, Task):
                        if entity.is_leaf and not entity.dependent_of:
                            # then we can update it
                            entity.status = status

                            # # fix other task statuses
                            # from anima import utils
                            # utils.fix_task_statuses(entity)

                            # refresh the tree
                            from stalker.db.session import DBSession
                            DBSession.add(entity)
                            DBSession.commit()

                            if item.parent:
                                item.parent.reload()
                                self.find_and_select_entity_item(entity)
                else:
                    try:
                        # go to the dependencies
                        dep_task = selected_item.task
                        self.find_and_select_entity_item(dep_task, self)
                    except AttributeError:
                        pass