def upload_thumbnail_button_clicked(self): """replaces the thumbnail """ # print('thumbnail button clicked') # self.upload_thumbnail_button.setVisible(False) from anima.ui import utils thumbnail_full_path = utils.choose_thumbnail(self) utils.upload_thumbnail(self.task, thumbnail_full_path) self.fill_ui()
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