Esempio n. 1
0
 def reject(self):
     QtWidgets.QDialog.reject(self)
     from stalker.db.session import DBSession
     if self.version:
         DBSession.delete(self.version)
         DBSession.commit()
     DBSession.rollback()
Esempio n. 2
0
 def reject(self):
     QtWidgets.QDialog.reject(self)
     from stalker.db.session import DBSession
     if self.version:
         DBSession.delete(self.version)
         DBSession.commit()
     DBSession.rollback()
Esempio n. 3
0
    def closeEvent(self, event):
        """if user tries to close the publish_checker dialog
        pop up a question dialog
        """
        answer = QtWidgets.QMessageBox.question(
            self, 'DO NOT Close Window!!!',
            'You should <b>NOT</b> close this window!!!<br/>'
            ' <br/>'
            'Drag Publish Checker to the side and fix your scene<br/>'
            'When fixed hit Check buttons until Published!!!<br/>'
            ' <br/>'
            'Close Anyway !!!', QtWidgets.QMessageBox.Yes,
            QtWidgets.QMessageBox.No)

        if answer == QtWidgets.QMessageBox.Yes:
            # delete any empty published versions if created
            if self.version.is_latest_published_version() \
                    and self.version.absolute_full_path == '.' \
                    and self.version.extension == '' \
                    and not self.version.created_with:  # this means the last published version is empty
                from stalker.db.session import DBSession
                try:
                    DBSession.delete(self.version)
                    # DBSession.commit() # no need to commit
                except Exception:
                    DBSession.rollback()

            event.accept()
        else:
            event.ignore()
Esempio n. 4
0
def delete_budgetentry_action(budgetentry):

    logger.debug('delete_budgetentry_action %s' % budgetentry.name)
    budgetentry_name = budgetentry.name
    try:
        DBSession.delete(budgetentry)
        transaction.commit()
    except Exception as e:
        transaction.abort()
        c = StdErrToHTMLConverter(e)
        transaction.abort()
Esempio n. 5
0
    def test_deleting_data(self):
        """testing deleting data
        """
        d1 = DAGMixinFooMixedInClass(**self.kwargs)
        d2 = DAGMixinFooMixedInClass(**self.kwargs)
        d3 = DAGMixinFooMixedInClass(**self.kwargs)
        d4 = DAGMixinFooMixedInClass(**self.kwargs)

        d1.children = [d2, d3]
        d2.children = [d4]

        from stalker.db.session import DBSession
        DBSession.add_all([d1, d2, d3, d4])
        DBSession.commit()

        DBSession.delete(d1)
        DBSession.commit()

        all_data = DAGMixinFooMixedInClass.query.all()
        assert len(all_data) == 0
Esempio n. 6
0
def delete_good(request):
    """deletes the good with data from request
    """

    logger.debug('***delete good method starts ***')

    good_id = request.params.get('id')
    good = Good.query.filter_by(id=good_id).first()

    if not good:
        transaction.abort()
        return Response('There is no good with id: %s' % good_id, 500)

    good_name = good.name
    try:
        DBSession.delete(good)
        transaction.commit()
    except Exception as e:
        transaction.abort()
        c = StdErrToHTMLConverter(e)
        transaction.abort()
        return Response(c.html(), 500)

    return Response('Successfully deleted good with name %s' % good_name)
Esempio n. 7
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
Esempio n. 8
0
def move_references():
    """moves the old style references to their new places
    """
    mm = MediaManager()

    # get all tasks that has a reference
    tasks = Task.query.filter(Task.references != None).all()

    #print('Number of Tasks that has a reference: %s' % len(tasks))

    processed_references = {}
    for t in tasks:
        # go over references
        task_references = copy.copy(t.references)
        for r in task_references:
            if r.full_path.startswith('SPL'):
                if r.id not in processed_references:
                    # convert the path to absolute path
                    current_full_path = \
                        mm.convert_file_link_to_full_path(r.full_path)

                    # create a new reference out of this path
                    new_ref = None
                    if os.path.exists(current_full_path):
                        print('moving %s' % current_full_path)
                        with open(current_full_path) as f:
                            new_ref = \
                                mm.upload_reference(t, f, r.original_filename)
                        print('to %s' % new_ref.full_path)

                        # also update tags
                        print('adding tags: %s' %
                              map(lambda x: x.name, r.tags))
                        new_ref.tags = r.tags
                        # add this new_ref to DBSession
                        DBSession.add(new_ref)

                    # store this reference to be deleted
                    processed_references[r.id] = {
                        'old_ref': r,
                        'new_ref': new_ref
                    }

                    # delete the old file
                    print('removing old reference at: %s' % current_full_path)
                    try:
                        os.remove(current_full_path)
                    except OSError:
                        pass

                    # also remove the thumbnail
                    current_thumbnail = r.thumbnail
                    if current_thumbnail:
                        current_thumbnail_full_path = \
                            mm.convert_file_link_to_full_path(
                                current_thumbnail.full_path
                            )
                        print('also removing old thumbnail at: %s' %
                              current_thumbnail_full_path)
                        try:
                            os.remove(current_thumbnail_full_path)
                        except OSError:
                            pass
                else:
                    new_ref = processed_references[r.id]['new_ref']
                    if new_ref is not None:
                        if new_ref not in t.references:
                            t.references.append(new_ref)

                # remove this reference from this task
                t.references.remove(r)

    # find if there are any tasks still using the old link
    for v in processed_references.values():
        old_ref = v['old_ref']
        new_ref = v['new_ref']
        for task in Task.query.filter(Task.references.contains(old_ref)).all():
            print('%s is referencing %s, breaking this relation' %
                  (task, old_ref))
            task.references.remove(old_ref)
            if new_ref is not None:
                if new_ref not in task.references:
                    task.references.append(new_ref)

    # and delete old ones
    for v in processed_references.values():
        old_ref = v['old_ref']
        # delete the thumbnail
        with DBSession.no_autoflush:
            old_thumbnail = old_ref.thumbnail

        DBSession.delete(old_ref)
        if old_thumbnail:
            DBSession.delete(old_thumbnail)

    print("Processed %s Link objects!" % len(processed_references))

    # commit to database
    DBSession.commit()
Esempio n. 9
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

        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
        # -----------------------------------
        # actions created in different scopes
        create_time_log_action = None
        create_project_action = None
        update_task_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
        open_in_web_browser_action = None
        open_in_file_browser_action = None
        copy_url_action = None
        copy_id_to_clipboard = None

        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 = 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 = \
                        menu.addAction(u'\uf044 Update Project...')
                    create_project_structure_action = \
                        menu.addAction(u'\uf115 Create Project Structure')
                    create_child_task_action = \
                        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 Open In %s...' % file_browser_name)
            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 = \
                    menu.addAction(u'\uf115 Create Task 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]:
                    menu.addSeparator()
                    create_time_log_action = \
                        menu.addAction(u'\uf073 Create TimeLog...')

                # update task and create child task menu items
                if defaults.is_power_user(logged_in_user):
                    menu.addSeparator()
                    update_task_action = \
                        menu.addAction(u'\uf044 Update Task...')
                    create_child_task_action = \
                        menu.addAction(u'\uf0ae Create Child Task...')
                    duplicate_task_hierarchy_action = \
                        menu.addAction(u'\uf0c5 Duplicate Task Hierarchy...')
                    delete_task_action = \
                        menu.addAction(u'\uf1f8 Delete Task...')

                menu.addSeparator()

                # Add Depends To menu
                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)

        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
                    utils.open_browser_in_location(entity.absolute_path)
                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 == 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:
                    new_task_name, result = QtWidgets.QInputDialog.getText(
                        self, "Input Dialog", "Duplicated Task Name:",
                        QtWidgets.QLineEdit.Normal, item.task.name)
                    if result:
                        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)
                        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 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 Structure is created!',
                                'Project Structure is created!',
                            )
                    else:
                        return

                elif selected_item == create_task_structure_action:
                    answer = QtWidgets.QMessageBox.question(
                        self, 'Create Task 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,
                                'Task Structure is created!',
                                'Task Structure is created!',
                            )
                    else:
                        return

                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()

                else:
                    # go to the dependencies
                    dep_task = selected_item.task
                    self.find_and_select_entity_item(dep_task, self)
Esempio n. 10
0
DBSession.add(sh004)
DBSession.commit()

sh004.code = "SH005"
DBSession.commit()

# first find the data
wrong_shot = Shot.query.filter_by(code="SH005").first()

# now update it
wrong_shot.code = "SH004"

# commit the changes to the database
DBSession.commit()

DBSession.delete(wrong_shot)
DBSession.commit()

wrong_shot = Shot.query.filter_by(code="SH005").first()
print(wrong_shot)
# should print None

from stalker import Task

previs = Task(name="Previs", parent=sh001)

matchmove = Task(name="Matchmove", parent=sh001)

anim = Task(name="Animation", parent=sh001)

lighting = Task(name="Lighting", parent=sh001)
Esempio n. 11
0
 def delete_entity(self):
     """deletes one note
     """
     from stalker.db.session import DBSession
     DBSession.delete(self.entity)
     DBSession.flush()
Esempio n. 12
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:
            try:
                if item.task:
                    task_id = item.task.id
            except AttributeError:
                return

        # 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

        # -----------------------------------
        # 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
        export_to_json_action = None
        import_from_json_action = None
        no_deps_action = None
        create_project_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)

        reload_action = menu.addAction(u'\uf0e8 Reload')

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

        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...')
                    # Export and Import JSON
                    create_sub_menu.addSeparator()
                    # export_to_json_action = create_sub_menu.addAction(u'\uf1f8 Export To JSON...')

                    import_from_json_action = create_sub_menu.addAction(
                        u'\uf1f8 Import From JSON...')

        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_project_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...')

                    # Export and Import JSON
                    create_sub_menu.addSeparator()
                    export_to_json_action = create_sub_menu.addAction(
                        u'\uf1f8 Export To JSON...')

                    import_from_json_action = create_sub_menu.addAction(
                        u'\uf1f8 Import From JSON...')
                    create_sub_menu.addSeparator()

                    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...')

                    menu.addSeparator()

                # 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_action = menu.exec_(global_position)
        if selected_action:
            if selected_action is reload_action:
                if isinstance(entity, Project):
                    self.fill()
                    self.find_and_select_entity_item(item.task)
                else:
                    for item in self.get_selected_task_items():
                        item.reload()

            if create_project_action \
               and selected_action is 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_action is open_in_web_browser_action:
                    import webbrowser
                    webbrowser.open(url)
                elif selected_action 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_action 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_action is copy_id_to_clipboard:

                    clipboard = QtWidgets.QApplication.clipboard()
                    selected_entity_ids = ', '.join(
                        list(map(str, self.get_selected_task_ids())))
                    clipboard.setText(selected_entity_ids)

                    # 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",
                        "IDs are copied to clipboard!<br>%s" %
                        selected_entity_ids, QtWidgets.QMessageBox.Ok)

                elif selected_action 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_action is update_task_action:
                    from anima.ui import task_dialog
                    task_main_dialog = task_dialog.MainDialog(
                        parent=self, tasks=self.get_selected_tasks())
                    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_action is upload_thumbnail_action:
                    from anima.ui import utils as ui_utils
                    thumbnail_full_path = ui_utils.choose_thumbnail(
                        self,
                        start_path=entity.absolute_path,
                        dialog_title="Choose Thumbnail For: %s" % entity.name)

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

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

                elif selected_action is 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()
                    tasks = task_main_dialog.tasks
                    task_main_dialog.deleteLater()

                    if result == accepted and tasks:
                        # reload the parent item
                        if item.parent:
                            item.parent.reload()
                        else:
                            self.fill()
                        self.find_and_select_entity_item(tasks[0])

                elif selected_action 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_action 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

                        tasks = self.get_selected_tasks()
                        logger.debug("tasks   : %s" % tasks)

                        task = Task.query.get(item.task.id)

                        # get the next sibling or the previous
                        # to select after deletion
                        select_task = item.parent.task
                        if task.parent:
                            all_siblings = list(
                                Task.query.filter(
                                    Task.parent == task.parent).order_by(
                                        Task.name).all())
                            if len(all_siblings) > 1:
                                sibling_index = all_siblings.index(task)
                                if sibling_index < len(all_siblings) - 1:
                                    # this is not the last task in the list
                                    # select next one
                                    select_task = all_siblings[sibling_index +
                                                               1]
                                elif sibling_index == len(all_siblings) - 1:
                                    # this is the last task
                                    # select previous task
                                    select_task = all_siblings[sibling_index -
                                                               1]

                        for task in tasks:
                            DBSession.delete(task)
                        DBSession.commit()
                        # reload the parent
                        unique_parent_items = []
                        for item in self.get_selected_task_items():
                            if item.parent and item.parent not in unique_parent_items:
                                unique_parent_items.append(item.parent)

                        if unique_parent_items:
                            for parent_item in unique_parent_items:
                                parent_item.reload()
                        else:
                            self.fill()
                        # either select the next or previous task or the parent
                        self.find_and_select_entity_item(select_task)

                elif selected_action is export_to_json_action:
                    # show a file browser
                    dialog = QtWidgets.QFileDialog(self, "Choose file")
                    dialog.setNameFilter("JSON Files (*.json)")
                    dialog.setFileMode(QtWidgets.QFileDialog.AnyFile)
                    if dialog.exec_():
                        file_path = dialog.selectedFiles()[0]
                        if file_path:
                            import os
                            import json
                            from anima.utils import task_hierarchy_io

                            # check file extension
                            parts = os.path.splitext(file_path)

                            if not parts[1]:
                                file_path = '%s%s' % (parts[0], '.json')

                            data = json.dumps(
                                entity,
                                cls=task_hierarchy_io.StalkerEntityEncoder,
                                check_circular=False,
                                indent=4)
                            try:
                                with open(file_path, 'w') as f:
                                    f.write(data)
                            except Exception as e:
                                pass
                            finally:
                                QtWidgets.QMessageBox.information(
                                    self,
                                    'Task data Export to JSON!',
                                    'Task data Export to JSON!',
                                )

                elif selected_action is import_from_json_action:
                    # show a file browser
                    dialog = QtWidgets.QFileDialog(self, "Choose file")
                    dialog.setNameFilter("JSON Files (*.json)")
                    dialog.setFileMode(QtWidgets.QFileDialog.ExistingFile)
                    if dialog.exec_():
                        file_path = dialog.selectedFiles()[0]
                        if file_path:
                            import json
                            with open(file_path) as f:
                                data = json.load(f)
                            from anima.utils import task_hierarchy_io
                            if isinstance(entity, Task):
                                project = entity.project
                            elif isinstance(entity, Project):
                                project = entity

                            parent = None
                            if isinstance(entity, Task):
                                parent = entity

                            decoder = \
                                task_hierarchy_io.StalkerEntityDecoder(
                                    project=project
                                )
                            loaded_entity = decoder.loads(data, parent=parent)

                            try:
                                from stalker.db.session import DBSession
                                DBSession.add(loaded_entity)
                                DBSession.commit()
                            except Exception as e:
                                QtWidgets.QMessageBox.critical(
                                    self, "Error!", "%s" % e,
                                    QtWidgets.QMessageBox.Ok)
                            else:
                                item.reload()
                                QtWidgets.QMessageBox.information(
                                    self,
                                    'New Tasks are created!',
                                    'New Tasks are created',
                                )

                elif selected_action is 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:
                            for task in self.get_selected_tasks():
                                utils.create_structure(task)
                        except Exception as e:
                            QtWidgets.QMessageBox.critical(
                                self, "Error", str(e))
                        finally:
                            QtWidgets.QMessageBox.information(
                                self,
                                'Project Folder Structure is created!',
                                'Project Folder Structure is created!',
                            )
                    else:
                        return

                elif selected_action is fix_task_status_action:
                    from stalker.db.session import DBSession
                    from stalker import SimpleEntity, Task
                    from anima import utils
                    for entity in self.get_selected_tasks():
                        if isinstance(entity, Task):
                            utils.fix_task_statuses(entity)
                            utils.fix_task_computed_time(entity)
                            DBSession.add(entity)
                    DBSession.commit()

                    unique_parent_items = []
                    for item in self.get_selected_task_items():
                        if item.parent and item.parent not in unique_parent_items:
                            unique_parent_items.append(item.parent)

                    for parent_item in unique_parent_items:
                        parent_item.reload()

                elif selected_action is 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_action is 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_action in change_status_menu_actions:
                    # get the status code
                    status_code = selected_action.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)
                    for task in self.get_selected_tasks():
                        if task.is_leaf and not task.dependent_of:
                            # then we can update it
                            task.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(task)
                            DBSession.commit()

                            if item.parent:
                                item.parent.reload()
                                self.find_and_select_entity_item(entity)
                else:
                    try:
                        # go to the dependencies
                        dep_task = selected_action.task
                        self.find_and_select_entity_item(dep_task, self)
                    except AttributeError:
                        pass
Esempio n. 13
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
        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...')

                    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 == 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