def reject(self): QtWidgets.QDialog.reject(self) from stalker.db.session import DBSession if self.version: DBSession.delete(self.version) DBSession.commit() DBSession.rollback()
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()
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()
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
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)
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
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()
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)
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)
def delete_entity(self): """deletes one note """ from stalker.db.session import DBSession DBSession.delete(self.entity) DBSession.flush()
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
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