def create_controls(self): self.none_button = QtGui.QPushButton('Toggle All') self.none_button.setIcon(gf.get_icon('checkbox-multiple-marked-outline', icons_set='mdi', scale_factor=1)) self.none_button.setFlat(True) self.all_process_button = QtGui.QPushButton('Toggle Process') self.all_process_button.setIcon(gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6)) self.all_process_button.setFlat(True) self.all_with_builtins_button = QtGui.QPushButton('Toggle Builtin Processes') self.all_with_builtins_button.setIcon(gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6)) self.all_with_builtins_button.setFlat(True) self.all_children_button = QtGui.QPushButton('Toggle Children') self.all_children_button.setIcon(gf.get_icon('view-sequential', icons_set='mdi', scale_factor=1)) self.all_children_button.setFlat(True) self.togglers_widget = QtGui.QWidget() self.togglers_layout = QtGui.QGridLayout() self.togglers_layout.setContentsMargins(0, 0, 0, 0) self.togglers_layout.setSpacing(6) self.togglers_widget.setLayout(self.togglers_layout) self.togglers_layout.addWidget(self.none_button, 0, 0, 1, 1) self.togglers_layout.addWidget(self.all_process_button, 0, 1, 1, 1) self.togglers_layout.addWidget(self.all_with_builtins_button, 1, 0, 1, 1) self.togglers_layout.addWidget(self.all_children_button, 1, 1, 1, 1) # Creating collapsable self.controls_collapsable = Ui_collapsableWidget(state=True) layout_colapsable = QtGui.QVBoxLayout() self.controls_collapsable.setLayout(layout_colapsable) self.controls_collapsable.setText('Hide Togglers') self.controls_collapsable.setCollapsedText('Show Togglers') layout_colapsable.addWidget(self.togglers_widget) self.controls_collapsable.collapsed.connect(self.toggle_presets_edit_buttons) self.start_sync_button = QtGui.QPushButton('Begin Repo Sync') start_sync_color = Qt4Gui.QColor(16, 160, 16) start_sync_color_active = Qt4Gui.QColor(16, 220, 16) self.start_sync_button.setIcon(gf.get_icon('sync', color=start_sync_color, color_active=start_sync_color_active, icons_set='mdi', scale_factor=1)) self.progress_bar = QtGui.QProgressBar() self.grid.addWidget(self.controls_collapsable, 2, 0, 1, 2) self.grid.addWidget(self.start_sync_button, 3, 0, 1, 2) self.grid.addWidget(self.progress_bar, 4, 0, 1, 4)
def create_dependency_widget(self): pos = 0 check_list = [ 'sthpw/snapshot', 'sthpw/file', 'sthpw/note', 'sthpw/task', 'sthpw/status_log' ] self.check_boxes_list = [] for search_type, sobjects in self.dependencies.items(): # Filtering if the sobject points to self as dependency for sobject in self.sobjects: for dep_skey in list(sobjects.keys()): if sobject.get_search_key() == dep_skey: sobjects.pop(dep_skey) if len(sobjects) > 0: pos += 1 layout = QtGui.QHBoxLayout() deleting_check_box = QtGui.QCheckBox() deleting_check_box.setObjectName(search_type) if search_type in check_list: deleting_check_box.setChecked(True) layout.addWidget(deleting_check_box) self.check_boxes_list.append(deleting_check_box) collapse_wdg_files = Ui_collapsableWidget(state=True) layout_files = QtGui.QVBoxLayout() collapse_wdg_files.setLayout(layout_files) collapse_wdg_files.setText(u'Hide {0} | {1}'.format( search_type, len(sobjects))) collapse_wdg_files.setCollapsedText(u'Show {0} | {1}'.format( search_type, len(sobjects))) files_tree_widget = Ui_dependencyExpandWidget( sobjects=sobjects) files_tree_widget.setMinimumSize(600, 300) layout_files.addWidget(files_tree_widget) layout.addWidget(collapse_wdg_files) self.main_layout.addLayout(layout, pos, 0)
def create_dependency_widget(self): pos = 0 check_list = ['sthpw/snapshot', 'sthpw/file'] self.check_boxes_list = [] for search_type, sobjects in self.dependencies.items(): if len(sobjects) > 0: pos += 1 layout = QtGui.QHBoxLayout() deleting_check_box = QtGui.QCheckBox() deleting_check_box.setObjectName(search_type) if search_type in check_list: deleting_check_box.setChecked(True) layout.addWidget(deleting_check_box) self.check_boxes_list.append(deleting_check_box) collapse_wdg_files = Ui_collapsableWidget(state=True) layout_files = QtGui.QVBoxLayout() collapse_wdg_files.setLayout(layout_files) collapse_wdg_files.setText(u'Hide {0} | {1}'.format( search_type, len(sobjects))) collapse_wdg_files.setCollapsedText(u'Show {0} | {1}'.format( search_type, len(sobjects))) files_tree_widget = Ui_dependencyExpandWidget( sobjects=sobjects) files_tree_widget.setMinimumSize(600, 300) layout_files.addWidget(files_tree_widget) layout.addWidget(collapse_wdg_files) self.main_layout.addLayout(layout, pos, 0)
class Ui_repoSyncDialog(QtGui.QDialog): downloads_finished = QtCore.Signal() file_download_done = QtCore.Signal(object) def __init__(self, stype, sobject, parent=None): super(self.__class__, self).__init__(parent=parent) self.stype = stype self.sobject = sobject self.togglers = [False, False, False, False] self.repo_sync_items = [] self.sync_tasks = 0 self.sync_in_progress = False self.interrupted = False self.auto_close = False self.get_all_presets_from_server() self.create_ui() def create_ui(self): if self.sobject: self.setWindowTitle('Sync Repo for: {0}'.format(self.sobject.get_title())) else: self.setWindowTitle('Sync Repo for: {0}'.format(self.stype.get_pretty_name())) self.setSizeGripEnabled(True) self.setFocusPolicy(QtCore.Qt.StrongFocus) self.create_tree_widget() self.fill_presets_combo_box() self.fill_tree_widget() self.fit_to_content_tree_widget() self.create_controls() self.controls_actions() self.create_download_queue() self.resize(650, 550) self.readSettings() def controls_actions(self): self.none_button.clicked.connect(lambda: self.switch_items('none')) self.all_process_button.clicked.connect(lambda: self.switch_items('process')) self.all_with_builtins_button.clicked.connect(lambda: self.switch_items('builtins')) self.all_children_button.clicked.connect(lambda: self.switch_items('children')) self.tree_widget.itemChanged.connect(self.check_tree_items) self.presets_combo_box.currentIndexChanged.connect(self.apply_repo_sync_preset) self.start_sync_button.clicked.connect(self.start_sync_ui) def create_download_queue(self): self.download_queue = Ui_repoSyncQueueWidget(embedded=True) self.download_queue.downloads_finished.connect(self.files_downloads_finished) self.download_queue.file_download_done.connect(self.file_download_finished) self.grid.addWidget(self.download_queue, 0, 2, 4, 2) def files_downloads_finished(self): self.sync_in_progress = False if not self.interrupted: self.downloads_finished.emit() if self.auto_close: self.close() self.downloads_progress_bar.setVisible(False) self.toggle_ui(True) def file_download_finished(self, fl): if not self.interrupted: self.file_download_done.emit(fl) progress = self.downloads_progress_bar.value() self.downloads_progress_bar.setValue(progress + 1) self.downloads_progress_bar.setFormat(u'%v / %m {}'.format(fl.get_filename_with_ext())) def check_tree_items(self, changed_item): if len(self.tree_widget.selectedItems()) > 1: for item in self.tree_widget.selectedItems(): item.setCheckState(0, changed_item.checkState(0)) def switch_items(self, item_type='none'): preset_dict = self.get_current_preset_dict() if preset_dict: if item_type == 'process': gf.set_tree_widget_checked_state( self.tree_widget, preset_dict, only_types_tuple=(':{pr}'), state=self.togglers[0] ) self.togglers[0] = not self.togglers[0] elif item_type == 'builtins': gf.set_tree_widget_checked_state( self.tree_widget, preset_dict, only_types_tuple=(':{b}'), state=self.togglers[1] ) self.togglers[1] = not self.togglers[1] elif item_type == 'children': gf.set_tree_widget_checked_state( self.tree_widget, preset_dict, only_types_tuple=(':{s}'), state=self.togglers[2] ) self.togglers[2] = not self.togglers[2] elif item_type == 'none': gf.set_tree_widget_checked_state( self.tree_widget, preset_dict, only_types_tuple=(':{s}', ':{pr}', ':{b}'), state=self.togglers[3] ) self.togglers[3] = not self.togglers[3] def create_controls(self): self.versionChooserHorizontalLayout = QtGui.QHBoxLayout() self.versionChooserHorizontalLayout.setContentsMargins(0, 0, 0, 0) self.versionChooserHorizontalLayout.setObjectName("versionChooserHorizontalLayout") self.versionlessSyncRadioButton = QtGui.QRadioButton() self.versionlessSyncRadioButton.setChecked(True) self.versionlessSyncRadioButton.setObjectName("versionlessSyncRadioButton") self.versionlessSyncRadioButton.setText('Versionless Sync') self.fullSyncRadioButton = QtGui.QRadioButton() self.fullSyncRadioButton.setObjectName("fullSyncRadioButton") self.fullSyncRadioButton.setText('Full Sync') self.versionChooserHorizontalLayout.addWidget(self.versionlessSyncRadioButton) self.versionChooserHorizontalLayout.addWidget(self.fullSyncRadioButton) self.none_button = QtGui.QPushButton('Toggle All') self.none_button.setIcon(gf.get_icon('checkbox-multiple-marked-outline', icons_set='mdi', scale_factor=1)) self.none_button.setFlat(True) self.all_process_button = QtGui.QPushButton('Toggle Process') self.all_process_button.setIcon(gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6)) self.all_process_button.setFlat(True) self.all_with_builtins_button = QtGui.QPushButton('Toggle Builtin Processes') self.all_with_builtins_button.setIcon(gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6)) self.all_with_builtins_button.setFlat(True) self.all_children_button = QtGui.QPushButton('Toggle Children') self.all_children_button.setIcon(gf.get_icon('view-sequential', icons_set='mdi', scale_factor=1)) self.all_children_button.setFlat(True) self.togglers_widget = QtGui.QWidget() self.togglers_layout = QtGui.QGridLayout() self.togglers_layout.setContentsMargins(0, 0, 0, 0) self.togglers_layout.setSpacing(6) self.togglers_widget.setLayout(self.togglers_layout) self.togglers_layout.addWidget(self.none_button, 0, 0, 1, 1) self.togglers_layout.addWidget(self.all_process_button, 0, 1, 1, 1) self.togglers_layout.addWidget(self.all_with_builtins_button, 1, 0, 1, 1) self.togglers_layout.addWidget(self.all_children_button, 1, 1, 1, 1) self.togglers_layout.addLayout(self.versionChooserHorizontalLayout, 2, 0, 1, 2) # Creating collapsable self.controls_collapsable = Ui_collapsableWidget(state=True) layout_colapsable = QtGui.QVBoxLayout() self.controls_collapsable.setLayout(layout_colapsable) self.controls_collapsable.setText('Hide Togglers') self.controls_collapsable.setCollapsedText('Show Togglers') layout_colapsable.addWidget(self.togglers_widget) self.controls_collapsable.collapsed.connect(self.toggle_presets_edit_buttons) self.start_sync_button = QtGui.QPushButton('Begin Repo Sync') self.start_sync_button.setFlat(True) start_sync_color = Qt4Gui.QColor(16, 160, 16) start_sync_color_active = Qt4Gui.QColor(16, 220, 16) self.start_sync_button.setIcon(gf.get_icon('sync', color=start_sync_color, color_active=start_sync_color_active, icons_set='mdi', scale_factor=1)) self.progress_bar = QtGui.QProgressBar() self.progress_bar.setMaximum(100) self.progress_bar.setTextVisible(True) self.progress_bar.setHidden(True) self.downloads_progress_bar = QtGui.QProgressBar() self.downloads_progress_bar.setMaximum(100) self.downloads_progress_bar.setTextVisible(True) self.downloads_progress_bar.setHidden(True) self.grid.addWidget(self.controls_collapsable, 2, 0, 1, 2) self.grid.addWidget(self.start_sync_button, 3, 0, 1, 2) self.grid.addWidget(self.progress_bar, 4, 0, 1, 4) self.grid.addWidget(self.downloads_progress_bar, 5, 0, 1, 4) def toggle_presets_edit_buttons(self, state): if state: self.add_new_preset_button.setHidden(True) self.save_new_preset_button.setHidden(True) self.remove_preset_button.setHidden(True) else: self.add_new_preset_button.setHidden(False) self.save_new_preset_button.setHidden(False) self.remove_preset_button.setHidden(False) def set_auto_close(self, auto_close): self.auto_close = auto_close def create_tree_widget(self): self.grid = QtGui.QGridLayout() self.grid.setContentsMargins(9, 9, 9, 9) self.grid.setSpacing(6) self.setLayout(self.grid) self.create_presets_combo_box() self.tree_widget = QtGui.QTreeWidget(self) self.tree_widget.setTabKeyNavigation(True) self.tree_widget.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.tree_widget.setAllColumnsShowFocus(True) self.tree_widget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.tree_widget.setHeaderHidden(True) self.tree_widget.setObjectName('tree_widget') self.tree_widget.setAlternatingRowColors(True) self.tree_widget.setStyleSheet(gf.get_qtreeview_style()) self.tree_widget.setRootIsDecorated(True) self.grid.addWidget(self.tree_widget, 1, 0, 1, 2) self.grid.setRowStretch(1, 1) def create_presets_combo_box(self): self.grid_presets = QtGui.QGridLayout() self.presets_combo_box = QtGui.QComboBox() self.add_new_preset_button = QtGui.QToolButton() self.add_new_preset_button.setAutoRaise(True) self.add_new_preset_button.setIcon(gf.get_icon('plus-box', icons_set='mdi', scale_factor=1.2)) self.add_new_preset_button.clicked.connect(self.add_new_preset) self.add_new_preset_button.setToolTip('Create new Preset and Save (from current state)') self.add_new_preset_button.setHidden(True) self.save_new_preset_button = QtGui.QToolButton() self.save_new_preset_button.setAutoRaise(True) self.save_new_preset_button.setIcon(gf.get_icon('content-save', icons_set='mdi', scale_factor=1)) self.save_new_preset_button.clicked.connect(self.save_preset_to_server) self.save_new_preset_button.setToolTip('Save Current Preset Changes') self.save_new_preset_button.setHidden(True) self.remove_preset_button = QtGui.QToolButton() self.remove_preset_button.setAutoRaise(True) self.remove_preset_button.setIcon(gf.get_icon('delete', icons_set='mdi', scale_factor=1)) self.remove_preset_button.clicked.connect(self.delete_preset_from_server) self.remove_preset_button.setToolTip('Remove Current Preset') self.remove_preset_button.setHidden(True) self.grid_presets.addWidget(self.remove_preset_button, 0, 0, 1, 1) self.grid_presets.addWidget(self.presets_combo_box, 0, 1, 1, 1) self.grid_presets.addWidget(self.save_new_preset_button, 0, 2, 1, 1) self.grid_presets.addWidget(self.add_new_preset_button, 0, 3, 1, 1) self.grid_presets.setColumnStretch(1, 0) self.grid.addLayout(self.grid_presets, 0, 0, 1, 2) def fill_presets_combo_box(self, current_preset=None): self.presets_combo_box.clear() current_idx = 0 for i, preset in enumerate(self.presets_list): self.presets_combo_box.addItem(preset['pretty_preset_name']) self.presets_combo_box.setItemData(i, preset['preset_name']) if preset['preset_name'] == current_preset: current_idx = i self.presets_combo_box.setCurrentIndex(current_idx) def fill_tree_widget(self): self.fill_builtin_processes() self.fill_stype_pipeline(self.stype) self.fill_children_pipelines_and_processes(self.stype) def fill_builtin_processes(self, parent_tree_item=None): if not parent_tree_item: parent_tree_item_add = self.tree_widget.addTopLevelItem else: parent_tree_item_add = parent_tree_item.addChild # Builtin processes for key in ['publish', 'attachment', 'icon']: top_item = QtGui.QTreeWidgetItem() top_item.setText(0, key.capitalize() + ' (builtin)') top_item.setCheckState(0, QtCore.Qt.Checked) top_item.setData(1, 0, '{0}:{1}'.format(key, '{b}')) parent_tree_item_add(top_item) def fill_stype_pipeline(self, stype=None, parent_tree_item=None): if not parent_tree_item: parent_tree_item_add = self.tree_widget.addTopLevelItem else: parent_tree_item_add = parent_tree_item.addChild if stype.pipeline: for stype_pipeline in stype.pipeline.values(): top_item = QtGui.QTreeWidgetItem() title = stype_pipeline.info.get('name') if not title: title = stype_pipeline.info.get('code') top_item.setText(0, title) top_item.setData(1, 0, '{0}:{1}'.format(stype_pipeline.info.get('code'), '{pp}')) parent_tree_item_add(top_item) for key, val in stype_pipeline.pipeline.items(): child_item = QtGui.QTreeWidgetItem() child_item.setText(0, key.capitalize()) child_item.setCheckState(0, QtCore.Qt.Unchecked) child_item.setData(1, 0, '{0}:{1}'.format(key, '{pr}')) item_color = Qt4Gui.QColor(200, 200, 200) process = stype_pipeline.get_pipeline_process(key) if process: hex_color = process.get('color') color = None if hex_color: color = gf.hex_to_rgb(hex_color, tuple=True) if color: item_color = Qt4Gui.QColor(*color) child_item.setIcon(0, gf.get_icon('circle', color=item_color, scale_factor=0.55)) top_item.addChild(child_item) top_item.setExpanded(True) def fill_children_pipelines_and_processes(self, stype=None, parent_tree_item=None): if not parent_tree_item: parent_tree_item_add = self.tree_widget.addTopLevelItem else: parent_tree_item_add = parent_tree_item.addChild project = self.stype.get_project() # Children process if stype.schema: for child in stype.schema.children: child_stype = project.stypes.get(child['from']) relationship_type = child.get('type') if child_stype: ignored = False if child_stype and relationship_type not in ['many_to_many']: # Breaking recursion # Similar logic in items: check_for_child_recursion() if parent_tree_item: parent = parent_tree_item.parent() # we storing ignore dicts in parent stypes, and checking it, so we break recursion # and also getting as deep as needed when syncing assets if parent: ignore_dict = parent.data(2, QtCore.Qt.UserRole) parent_stype = parent.data(3, QtCore.Qt.UserRole) ignore_dict.setdefault('children', []).append(parent_stype.info['code']) else: ignore_dict = {} else: ignore_dict = {} # Already added stypes per child tree if ignore_dict: if ignore_dict.get('children'): if child_stype.info['code'] in ignore_dict['children']: ignored = True if not ignored: top_item = QtGui.QTreeWidgetItem() top_item.setText(0, child_stype.get_pretty_name() + ' (child)') # Making items unchecked by default, because someone can sync all repo in chain top_item.setCheckState(0, QtCore.Qt.Unchecked) top_item.setData(1, 0, '{0}:{1}'.format(child_stype.get_code(), '{s}')) # setting ignore dicts and stype for top item top_item.setData(2, QtCore.Qt.UserRole, ignore_dict) top_item.setData(3, QtCore.Qt.UserRole, child_stype) clr = child_stype.get_stype_color(tuple=True) stype_color = None if clr: stype_color = Qt4Gui.QColor(clr[0], clr[1], clr[2], 255) top_item.setIcon(0, gf.get_icon('view-sequential', color=stype_color, icons_set='mdi', scale_factor=1.1)) self.fill_builtin_processes(top_item) self.fill_stype_pipeline(child_stype, top_item) parent_tree_item_add(top_item) self.fill_children_pipelines_and_processes(child_stype, top_item) def fit_to_content_tree_widget(self): items_count = 0 for item in QtGui.QTreeWidgetItemIterator(self.tree_widget): if item.value().isExpanded(): items_count += 1 row_height = items_count * self.tree_widget.sizeHintForRow(0) + 500 mouse_pos = Qt4Gui.QCursor.pos() self.setGeometry(mouse_pos.x(), mouse_pos.y(), 450, row_height) def add_new_preset(self): add_preset_dialog = QtGui.QDialog(self) add_preset_dialog.setWindowTitle('Save as new Preset {}'.format(self.stype.get_pretty_name())) add_preset_dialog.setMinimumSize(320, 80) add_preset_dialog.setMaximumSize(450, 80) add_preset_dialog_layout = QtGui.QVBoxLayout() add_preset_dialog.setLayout(add_preset_dialog_layout) add_preset_dialog_line_edit = QtGui.QLineEdit('New Preset') add_preset_dialog_button = QtGui.QPushButton('Create and Save') add_preset_dialog_layout.addWidget(add_preset_dialog_line_edit) add_preset_dialog_layout.addWidget(add_preset_dialog_button) add_preset_dialog_button.clicked.connect(lambda: self.save_preset_to_server( preset_name=add_preset_dialog_line_edit.text().lower().replace(' ', '_'), pretty_preset_name=add_preset_dialog_line_edit.text() )) add_preset_dialog_button.clicked.connect(add_preset_dialog.close) add_preset_dialog.exec_() # self.fill_presets_combo_box() def get_current_preset_name(self): current_index = self.presets_combo_box.currentIndex() return self.presets_combo_box.itemData(current_index) def get_current_preset_dict(self): preset_dict = self.get_preset_config(self.get_current_preset_name(), json=False) return preset_dict['data'] def get_preset_dict_by_type(self, type='pipeline', preset_dict=None, only_enabled=False): result_preset_dict = {} if type == 'pipeline': for name, preset in preset_dict.items(): if name.endswith(':{pp}'): result_preset_dict[name.replace(':{pp}', '')] = preset if type == 'builtin': for name, preset in preset_dict.items(): if name.endswith(':{b}'): if only_enabled: if preset['state']: result_preset_dict[name.replace(':{b}', '')] = preset else: result_preset_dict[name.replace(':{b}', '')] = preset if type == 'process': for name, preset in preset_dict.items(): if name.endswith(':{pr}'): if only_enabled: if preset['state']: result_preset_dict[name.replace(':{pr}', '')] = preset else: result_preset_dict[name.replace(':{pr}', '')] = preset if type == 'child': for name, preset in preset_dict.items(): if name.endswith(':{s}'): if only_enabled: if preset['state']: result_preset_dict[name.replace(':{s}', '')] = preset else: result_preset_dict[name.replace(':{s}', '')] = preset return result_preset_dict def apply_repo_sync_preset(self, current_index=None, preset_name=None): if not preset_name: preset_name = self.presets_combo_box.itemData(current_index) preset_dict = self.get_preset_by_name(preset_name) if preset_dict: # Pipeline items should not have check state, filter it with {pp} tag gf.set_tree_widget_checked_state(self.tree_widget, preset_dict, ignore_types_tuple=(':{pp}')) if preset_dict.get('get_versions'): if preset_dict['get_versions']: self.fullSyncRadioButton.setChecked(True) else: self.versionlessSyncRadioButton.setChecked(True) else: self.versionlessSyncRadioButton.setChecked(True) def get_preset_by_name(self, preset_name): # Only used on initial items filling if self.presets_list: for preset in self.presets_list: if preset['preset_name'] == preset_name: return preset def get_all_presets_from_server(self): server = tc.server_start() key = 'search_type:{0}'.format(self.stype.get_code()) search_type = 'sthpw/wdg_settings' project_code = self.stype.get_project().get_code() filters = [('key', 'like', '{0}%'.format(key)), ('project_code', project_code)] columns = ['data'] presets = server.query(search_type, filters, columns) if not presets: self.presets_list = [ { 'pretty_preset_name': 'Default', 'preset_name': 'default', } ] else: new_presets_list = [] for preset in presets: new_presets_list.append(gf.from_json(preset['data'])) self.presets_list = new_presets_list def get_preset_config(self, preset_name=None, pretty_preset_name=None, json=True): if not preset_name: preset_name = 'default' if not pretty_preset_name: pretty_preset_name = preset_name.capitalize().replace('_', ' ') # Preparing preset data preset_dict = { 'preset_name': preset_name, 'pretty_preset_name': pretty_preset_name, 'get_versions': self.fullSyncRadioButton.isChecked() } gf.get_tree_widget_checked_state(self.tree_widget, preset_dict) key = 'search_type:{0}:preset_name:{1}'.format(self.stype.get_code(), preset_name) if json: data_dict = gf.to_json(preset_dict) else: data_dict = preset_dict data = { 'data': data_dict, 'key': key, 'login': '******', 'project_code': self.stype.get_project().get_code(), } return data def add_file_objects_to_queue(self, files_objects_list): for file_object in files_objects_list: self.repo_sync_items.append(self.download_queue.schedule_file_object(file_object)) self.download_queue.files_num_label.setText( str(self.download_queue.files_queue_tree_widget.topLevelItemCount()) ) def get_presets_list(self): return self.presets_list def download_files(self): self.downloads_progress_bar.setVisible(True) if not self.interrupted: for repo_sync_item in self.repo_sync_items: repo_sync_item.download() self.download_queue.files_num_label.setText( str(self.download_queue.files_queue_tree_widget.topLevelItemCount()) ) self.downloads_progress_bar.setMaximum(len(self.repo_sync_items)) if not self.repo_sync_items: self.files_downloads_finished() def clear_queue(self): self.download_queue.clear_queue() self.repo_sync_items = [] def start_sync(self, preset_dict=None): self.sync_in_progress = True # it is recommended to use finished signal if not preset_dict: preset_dict = self.get_current_preset_dict() self.clear_queue() self.sobject.update_snapshots() self.sync_by_pipeline(self.sobject, preset_dict) self.sync_children(self.sobject, preset_dict) # self.download_files() def start_sync_ui(self, preset_dict=None): self.show() self.sync_in_progress = True self.progress_bar.setHidden(False) self.toggle_ui(False) self.clear_queue() if not preset_dict: preset_dict = self.get_current_preset_dict() if self.sobject: self.progress_bar.setValue(0) self.progress_bar.setFormat(u'Getting: {0}'.format(self.sobject.get_title())) self.update_sobject_snapshots_threaded(self.sobject, preset_dict) self.sync_children(self.sobject, preset_dict) self.save_last_sync_date() else: self.progress_bar.setValue(0) self.progress_bar.setFormat(u'Getting all: {0}'.format(self.stype.get_pretty_name())) self.update_sobjects_threaded(preset_dict) # self.download_files() # self.progress_bar.setHidden(True) # self.toggle_ui(True) def check_sync_tasks(self): if self.sync_tasks == 0: self.progress_bar.setHidden(True) self.download_files() def do_sync_all_sobjects(self, result): sobjects, query_info, preset_dict = result for sobject in sobjects.values(): total = query_info['total_sobjects_query_count'] self.progress_bar.setMaximum(total) progress = self.progress_bar.value() self.progress_bar.setValue(progress + 1) self.progress_bar.setFormat(u'%v / %m {}'.format(sobject.get_title())) self.update_sobject_snapshots_threaded(sobject, preset_dict) self.sync_children(sobject, preset_dict) self.save_last_sync_date(sobject) self.sync_tasks -= 1 self.check_sync_tasks() def update_sobjects_threaded(self, preset_dict): worker = env_inst.server_pool.add_task( tc.get_sobjects, self.stype.get_code(), [], project_code=self.stype.project.get_code(), get_all_snapshots=True ) worker.add_result_data(preset_dict) worker.result.connect(self.do_sync_all_sobjects) worker.error.connect(gf.error_handle) worker.start() self.sync_tasks += 1 def update_sobject_snapshots_threaded(self, sobject, preset_dict): if preset_dict.get('only_updates'): worker = env_inst.server_pool.add_task(sobject.update_snapshots, filters=[('timestamp', 'is after', self.get_last_sync_date())]) else: worker = env_inst.server_pool.add_task(sobject.update_snapshots) worker.finished.connect(partial(self.sync_by_pipeline, sobject, preset_dict)) worker.error.connect(gf.error_handle) worker.start() self.sync_tasks += 1 def interrupt_sync_process(self): self.interrupted = True def toggle_ui(self, enable=False): self.start_sync_button.setEnabled(enable) self.remove_preset_button.setEnabled(enable) self.add_new_preset_button.setEnabled(enable) self.save_new_preset_button.setEnabled(enable) self.controls_collapsable.setEnabled(enable) self.presets_combo_box.setEnabled(enable) self.download_queue.clear_queue_push_button.setEnabled(enable) def sync_by_pipeline(self, sobject=None, preset_dict=None): if not sobject: sobject = self.sobject if not preset_dict: preset_dict = self.get_current_preset_dict() current_pipeline_preset_dict = self.get_preset_dict_by_type('pipeline', preset_dict) current_builtin_preset_dict = self.get_preset_dict_by_type('builtin', preset_dict, True) if current_pipeline_preset_dict: for pipeline_name, preset in current_pipeline_preset_dict.items(): self.sync_by_sobject(sobject, preset.get('sub'), current_builtin_preset_dict) elif current_builtin_preset_dict: self.sync_by_sobject(sobject, {}, current_builtin_preset_dict) self.sync_tasks -= 1 self.check_sync_tasks() def sync_children(self, sobject=None, preset_dict=None): if not preset_dict: preset_dict = self.get_current_preset_dict() children_preset_dict = self.get_preset_dict_by_type('child', preset_dict, True) for child_code, children_preset in children_preset_dict.items(): self.get_related_sobjects_threaded(sobject, child_code, children_preset) def get_related_sobjects_threaded(self, sobject, child_code, children_preset): stype = sobject.get_stype() project_obj = stype.get_project() worker = env_inst.server_pool.add_task( sobject.get_related_sobjects, child_stype=project_obj.stypes.get(child_code), parent_stype=stype, get_all_snapshots=True ) worker.add_result_data(children_preset) worker.result.connect(self.do_get_related_sobjects) worker.error.connect(gf.error_handle) worker.start() self.sync_tasks += 1 def do_get_related_sobjects(self, result): related_sobjects, query_info, children_preset = result if related_sobjects: for related_sobject in related_sobjects.values(): self.update_sobject_snapshots_threaded(related_sobject, children_preset.get('sub')) self.sync_children(related_sobject, children_preset.get('sub')) total = query_info['total_sobjects_query_count'] self.progress_bar.setMaximum(total) progress = self.progress_bar.value() self.progress_bar.setValue(progress + 1) self.progress_bar.setFormat(u'%v / %m {}'.format(related_sobject.get_title())) self.sync_tasks -= 1 self.check_sync_tasks() def sync_by_sobject(self, sobject=None, sync_preset_dict=None, builtin_preset_dict=None): process_objects = sobject.get_all_processes() enabled_processes = self.get_preset_dict_by_type('process', sync_preset_dict, True) versionless_list = [] versions_list = [] versionless_only = self.versionlessSyncRadioButton.isChecked() if builtin_preset_dict: all_precesses = dict(tuple(enabled_processes.items()) + tuple(builtin_preset_dict.items())) else: all_precesses = enabled_processes self.progress_bar.setMaximum(len(process_objects.items())) for process_name, process_object in process_objects.items(): progress = self.progress_bar.value() self.progress_bar.setValue(progress + 1) self.progress_bar.setFormat(u'%v / %m {}'.format('{0}: {1}'.format(sobject.get_title(), process_name))) if not self.interrupted: if process_name in list(all_precesses.keys()): contexts = process_object.get_contexts() for context, context_obj in contexts.items(): versionless_snapshots = context_obj.get_versionless() for code, snapshot in versionless_snapshots.items(): versionless_list.extend(snapshot.get_files_objects()) if not versionless_only: versions_snapshots = context_obj.get_versions() for code, snapshot in versions_snapshots.items(): versions_list.extend(snapshot.get_files_objects()) if versionless_only: self.add_file_objects_to_queue(versionless_list) else: self.add_file_objects_to_queue(versionless_list) self.add_file_objects_to_queue(versions_list) def delete_preset_from_server(self, preset_name=None): if not preset_name: idx = self.presets_combo_box.currentIndex() preset_name = self.presets_combo_box.itemData(idx) # ask before delete buttons = (('Yes', QtGui.QMessageBox.YesRole), ('Cancel', QtGui.QMessageBox.NoRole)) reply = gf.show_message_predefined( 'Removing preset from server', u'Are You sure want to remove <b>" {0} "</b> preset from Server?'.format(preset_name), buttons=buttons, message_type='question', parent=self ) if reply == QtGui.QMessageBox.YesRole: server = tc.server_start() data = self.get_preset_config(preset_name) search_type = 'sthpw/wdg_settings' # Checking for existing key filters = [('key', data['key'])] columns = ['code', 'project'] widget_settings = server.query(search_type, filters, columns, single=True) search_key = widget_settings['__search_key__'] server.delete_sobject(search_key) self.get_all_presets_from_server() self.fill_presets_combo_box(preset_name) def save_preset_to_server(self, preset_name=None, pretty_preset_name=None): if not preset_name: idx = self.presets_combo_box.currentIndex() preset_name = self.presets_combo_box.itemData(idx) server = tc.server_start() data = self.get_preset_config(preset_name, pretty_preset_name) search_type = 'sthpw/wdg_settings' # Checking for existing key filters = [('key', data['key'])] columns = ['code', 'project'] widget_settings = server.query(search_type, filters, columns, single=True) if widget_settings: code = widget_settings['code'] project = widget_settings['project'] search_key = server.build_search_key(search_type, code, project) server.insert_update(search_key, data, triggers=False) else: server.insert(search_type, data, triggers=False) self.get_all_presets_from_server() self.fill_presets_combo_box(preset_name) def get_settings_dict(self): settings_dict = { 'presets_combo_box': self.presets_combo_box.currentIndex(), } return settings_dict def set_settings_from_dict(self, settings_dict=None): ref_settings_dict = { 'presets_combo_box': 0, } settings = gf.check_config(ref_settings_dict, settings_dict) initial_index = self.presets_combo_box.currentIndex() self.presets_combo_box.setCurrentIndex(int(settings['presets_combo_box'])) if initial_index == int(settings['presets_combo_box']): self.apply_repo_sync_preset(initial_index) def get_last_sync_date(self, sobject=None): if not sobject: sobject = self.sobject group_path = 'ui_search/{0}/{1}/{2}/sobjects_conf'.format( self.stype.project.info['type'], self.stype.project.info['code'], self.stype.get_code().split('/')[1] ) return env_read_config(filename=sobject.get_code(), unique_id=group_path, long_abs_path=True ) def save_last_sync_date(self, sobject=None): if not sobject: sobject = self.sobject group_path = 'ui_search/{0}/{1}/{2}/sobjects_conf'.format( self.stype.project.info['type'], self.stype.project.info['code'], self.stype.get_code().split('/')[1] ) current_datetime = QtCore.QDateTime.currentDateTime() env_write_config( current_datetime.toString('yyyy.MM.dd hh:mm:ss'), filename=sobject.get_code(), unique_id=group_path, long_abs_path=True ) def refresh_search_widget(self): checkin_out = env_inst.get_check_tree(self.stype.get_project().get_code(), 'checkin_out', self.stype.get_code()) if checkin_out: checkin_out.refresh_current_results() def readSettings(self): group_path = 'ui_search/{0}/{1}/{2}'.format( self.stype.project.info['type'], self.stype.project.info['code'], self.stype.get_code().split('/')[1] ) self.set_settings_from_dict( env_read_config( filename='repo_sync', unique_id=group_path, long_abs_path=True ) ) def writeSettings(self): group_path = 'ui_search/{0}/{1}/{2}'.format( self.stype.project.info['type'], self.stype.project.info['code'], self.stype.get_code().split('/')[1] ) env_write_config( self.get_settings_dict(), filename='repo_sync', unique_id=group_path, long_abs_path=True ) def closeEvent(self, event): if not self.sync_in_progress: self.writeSettings() self.deleteLater() self.refresh_search_widget() event.accept() else: buttons = (('Ok', QtGui.QMessageBox.NoRole), ('Interrupt', QtGui.QMessageBox.ActionRole)) reply = gf.show_message_predefined( title='Download in Progress', message='Some files are not yet Downloaded.\nInterrupt the Sync Process?.', buttons=buttons, parent=self, message_type='question', ) if reply == QtGui.QMessageBox.ActionRole: self.interrupt_sync_process() self.deleteLater() event.accept() else: event.ignore()
def create_controls(self): self.versionChooserHorizontalLayout = QtGui.QHBoxLayout() self.versionChooserHorizontalLayout.setContentsMargins(0, 0, 0, 0) self.versionChooserHorizontalLayout.setObjectName( "versionChooserHorizontalLayout") self.versionlessSyncRadioButton = QtGui.QRadioButton() self.versionlessSyncRadioButton.setChecked(True) self.versionlessSyncRadioButton.setObjectName( "versionlessSyncRadioButton") self.versionlessSyncRadioButton.setText('Versionless Sync') self.fullSyncRadioButton = QtGui.QRadioButton() self.fullSyncRadioButton.setObjectName("fullSyncRadioButton") self.fullSyncRadioButton.setText('Full Sync') self.versionChooserHorizontalLayout.addWidget( self.versionlessSyncRadioButton) self.versionChooserHorizontalLayout.addWidget(self.fullSyncRadioButton) self.none_button = QtGui.QPushButton('Toggle All') self.none_button.setIcon( gf.get_icon('checkbox-multiple-marked-outline', icons_set='mdi', scale_factor=1)) self.none_button.setFlat(True) self.all_process_button = QtGui.QPushButton('Toggle Process') self.all_process_button.setIcon( gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6)) self.all_process_button.setFlat(True) self.all_with_builtins_button = QtGui.QPushButton( 'Toggle Builtin Processes') self.all_with_builtins_button.setIcon( gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6)) self.all_with_builtins_button.setFlat(True) self.all_children_button = QtGui.QPushButton('Toggle Children') self.all_children_button.setIcon( gf.get_icon('view-sequential', icons_set='mdi', scale_factor=1)) self.all_children_button.setFlat(True) self.togglers_widget = QtGui.QWidget() self.togglers_layout = QtGui.QGridLayout() self.togglers_layout.setContentsMargins(0, 0, 0, 0) self.togglers_layout.setSpacing(6) self.togglers_widget.setLayout(self.togglers_layout) self.togglers_layout.addWidget(self.none_button, 0, 0, 1, 1) self.togglers_layout.addWidget(self.all_process_button, 0, 1, 1, 1) self.togglers_layout.addWidget(self.all_with_builtins_button, 1, 0, 1, 1) self.togglers_layout.addWidget(self.all_children_button, 1, 1, 1, 1) self.togglers_layout.addLayout(self.versionChooserHorizontalLayout, 2, 0, 1, 2) # Creating collapsable self.controls_collapsable = Ui_collapsableWidget(state=True) layout_colapsable = QtGui.QVBoxLayout() self.controls_collapsable.setLayout(layout_colapsable) self.controls_collapsable.setText('Hide Togglers') self.controls_collapsable.setCollapsedText('Show Togglers') layout_colapsable.addWidget(self.togglers_widget) self.controls_collapsable.collapsed.connect( self.toggle_presets_edit_buttons) self.start_sync_button = QtGui.QPushButton('Begin Repo Sync') self.start_sync_button.setFlat(True) start_sync_color = Qt4Gui.QColor(16, 160, 16) start_sync_color_active = Qt4Gui.QColor(16, 220, 16) self.start_sync_button.setIcon( gf.get_icon('sync', color=start_sync_color, color_active=start_sync_color_active, icons_set='mdi', scale_factor=1)) self.progress_bar = QtGui.QProgressBar() self.progress_bar.setMaximum(100) # self.progressBarLayout.addWidget(self.progressBar) self.progress_bar.setTextVisible(True) self.progress_bar.setHidden(True) self.downloads_progress_bar = QtGui.QProgressBar() self.downloads_progress_bar.setMaximum(100) # self.progressBarLayout.addWidget(self.progressBar) self.downloads_progress_bar.setTextVisible(True) self.downloads_progress_bar.setHidden(True) self.grid.addWidget(self.controls_collapsable, 2, 0, 1, 2) self.grid.addWidget(self.start_sync_button, 3, 0, 1, 2) self.grid.addWidget(self.progress_bar, 4, 0, 1, 4) self.grid.addWidget(self.downloads_progress_bar, 5, 0, 1, 4)
class Ui_ingestDialog(QtGui.QDialog): def __init__(self, stype, sobject, parent=None): super(self.__class__, self).__init__(parent=parent) self.stype = stype self.sobject = sobject self.create_ui() def create_ui(self): self.setWindowTitle('Ingest Files') self.setSizeGripEnabled(True) self.setFocusPolicy(QtCore.Qt.StrongFocus) # self.create_tree_widget() # self.fill_presets_combo_box() # self.fill_tree_widget() # self.fit_to_content_tree_widget() # self.create_controls() # self.controls_actions() # # self.create_download_queue() self.resize(650, 550) # self.readSettings() def controls_actions(self): self.none_button.clicked.connect(lambda: self.switch_items('none')) self.all_process_button.clicked.connect(lambda: self.switch_items('process')) self.all_with_builtins_button.clicked.connect(lambda: self.switch_items('builtins')) self.all_children_button.clicked.connect(lambda: self.switch_items('children')) self.tree_widget.itemChanged.connect(self.check_tree_items) self.presets_combo_box.currentIndexChanged.connect(self.apply_repo_sync_preset) self.start_sync_button.clicked.connect(self.start_sync) def create_download_queue(self): self.download_queue = Ui_repoSyncQueueWidget(embedded=True) self.grid.addWidget(self.download_queue, 0, 2, 4, 2) def check_tree_items(self, changed_item): if len(self.tree_widget.selectedItems()) > 1: for item in self.tree_widget.selectedItems(): item.setCheckState(0, changed_item.checkState(0)) def switch_items(self, item_type='none'): preset_dict = self.get_current_preset_dict() if preset_dict: if item_type == 'process': gf.set_tree_widget_checked_state( self.tree_widget, preset_dict, only_types_tuple=(':{pr}'), state=self.togglers[0] ) self.togglers[0] = not self.togglers[0] elif item_type == 'builtins': gf.set_tree_widget_checked_state( self.tree_widget, preset_dict, only_types_tuple=(':{b}'), state=self.togglers[1] ) self.togglers[1] = not self.togglers[1] elif item_type == 'children': gf.set_tree_widget_checked_state( self.tree_widget, preset_dict, only_types_tuple=(':{s}'), state=self.togglers[2] ) self.togglers[2] = not self.togglers[2] elif item_type == 'none': gf.set_tree_widget_checked_state( self.tree_widget, preset_dict, only_types_tuple=(':{s}', ':{pr}', ':{b}'), state=self.togglers[3] ) self.togglers[3] = not self.togglers[3] def create_controls(self): self.none_button = QtGui.QPushButton('Toggle All') self.none_button.setIcon(gf.get_icon('checkbox-multiple-marked-outline', icons_set='mdi', scale_factor=1)) self.none_button.setFlat(True) self.all_process_button = QtGui.QPushButton('Toggle Process') self.all_process_button.setIcon(gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6)) self.all_process_button.setFlat(True) self.all_with_builtins_button = QtGui.QPushButton('Toggle Builtin Processes') self.all_with_builtins_button.setIcon(gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6)) self.all_with_builtins_button.setFlat(True) self.all_children_button = QtGui.QPushButton('Toggle Children') self.all_children_button.setIcon(gf.get_icon('view-sequential', icons_set='mdi', scale_factor=1)) self.all_children_button.setFlat(True) self.togglers_widget = QtGui.QWidget() self.togglers_layout = QtGui.QGridLayout() self.togglers_layout.setContentsMargins(0, 0, 0, 0) self.togglers_layout.setSpacing(6) self.togglers_widget.setLayout(self.togglers_layout) self.togglers_layout.addWidget(self.none_button, 0, 0, 1, 1) self.togglers_layout.addWidget(self.all_process_button, 0, 1, 1, 1) self.togglers_layout.addWidget(self.all_with_builtins_button, 1, 0, 1, 1) self.togglers_layout.addWidget(self.all_children_button, 1, 1, 1, 1) # Creating collapsable self.controls_collapsable = Ui_collapsableWidget(state=True) layout_colapsable = QtGui.QVBoxLayout() self.controls_collapsable.setLayout(layout_colapsable) self.controls_collapsable.setText('Hide Togglers') self.controls_collapsable.setCollapsedText('Show Togglers') layout_colapsable.addWidget(self.togglers_widget) self.controls_collapsable.collapsed.connect(self.toggle_presets_edit_buttons) self.start_sync_button = QtGui.QPushButton('Begin Repo Sync') start_sync_color = Qt4Gui.QColor(16, 160, 16) start_sync_color_active = Qt4Gui.QColor(16, 220, 16) self.start_sync_button.setIcon(gf.get_icon('sync', color=start_sync_color, color_active=start_sync_color_active, icons_set='mdi', scale_factor=1)) self.progress_bar = QtGui.QProgressBar() self.grid.addWidget(self.controls_collapsable, 2, 0, 1, 2) self.grid.addWidget(self.start_sync_button, 3, 0, 1, 2) self.grid.addWidget(self.progress_bar, 4, 0, 1, 4) def toggle_presets_edit_buttons(self, state): if state: self.add_new_preset_button.setHidden(True) self.save_new_preset_button.setHidden(True) self.remove_preset_button.setHidden(True) else: self.add_new_preset_button.setHidden(False) self.save_new_preset_button.setHidden(False) self.remove_preset_button.setHidden(False) def create_tree_widget(self): self.grid = QtGui.QGridLayout() self.grid.setContentsMargins(9, 9, 9, 9) self.grid.setSpacing(6) self.setLayout(self.grid) self.create_presets_combo_box() self.tree_widget = QtGui.QTreeWidget(self) self.tree_widget.setTabKeyNavigation(True) self.tree_widget.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.tree_widget.setAllColumnsShowFocus(True) self.tree_widget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.tree_widget.setHeaderHidden(True) self.tree_widget.setObjectName('tree_widget') self.tree_widget.setStyleSheet(gf.get_qtreeview_style()) self.tree_widget.setRootIsDecorated(True) self.grid.addWidget(self.tree_widget, 1, 0, 1, 2) self.grid.setRowStretch(1, 1) def create_presets_combo_box(self): self.grid_presets = QtGui.QGridLayout() self.presets_combo_box = QtGui.QComboBox() self.add_new_preset_button = QtGui.QToolButton() self.add_new_preset_button.setAutoRaise(True) self.add_new_preset_button.setIcon(gf.get_icon('plus-box', icons_set='mdi', scale_factor=1.2)) self.add_new_preset_button.clicked.connect(self.add_new_preset) self.add_new_preset_button.setToolTip('Create new Preset and Save (from current state)') self.add_new_preset_button.setHidden(True) self.save_new_preset_button = QtGui.QToolButton() self.save_new_preset_button.setAutoRaise(True) self.save_new_preset_button.setIcon(gf.get_icon('content-save', icons_set='mdi', scale_factor=1)) self.save_new_preset_button.clicked.connect(self.save_preset_to_server) self.save_new_preset_button.setToolTip('Save Current Preset Changes') self.save_new_preset_button.setHidden(True) self.remove_preset_button = QtGui.QToolButton() self.remove_preset_button.setAutoRaise(True) self.remove_preset_button.setIcon(gf.get_icon('delete', icons_set='mdi', scale_factor=1)) self.remove_preset_button.clicked.connect(self.close) self.remove_preset_button.setToolTip('Remove Current Preset') self.remove_preset_button.setHidden(True) self.grid_presets.addWidget(self.remove_preset_button, 0, 0, 1, 1) self.grid_presets.addWidget(self.presets_combo_box, 0, 1, 1, 1) self.grid_presets.addWidget(self.save_new_preset_button, 0, 2, 1, 1) self.grid_presets.addWidget(self.add_new_preset_button, 0, 3, 1, 1) self.grid_presets.setColumnStretch(1, 0) self.grid.addLayout(self.grid_presets, 0, 0, 1, 2) def fill_presets_combo_box(self, current_preset=None): self.presets_combo_box.clear() current_idx = 0 for i, preset in enumerate(self.presets_list): self.presets_combo_box.addItem(preset['pretty_preset_name']) self.presets_combo_box.setItemData(i, preset['preset_name']) if preset['preset_name'] == current_preset: current_idx = i self.presets_combo_box.setCurrentIndex(current_idx) def fill_tree_widget(self): self.fill_builtin_processes() self.fill_stype_pipeline(self.stype) self.fill_children_pipelines_and_processes(self.stype) def fill_builtin_processes(self, parent_tree_item=None): if not parent_tree_item: parent_tree_item_add = self.tree_widget.addTopLevelItem else: parent_tree_item_add = parent_tree_item.addChild # Builtin processes for key in ['publish', 'attachment', 'icon']: top_item = QtGui.QTreeWidgetItem() top_item.setText(0, key.capitalize() + ' (builtin)') top_item.setCheckState(0, QtCore.Qt.Checked) top_item.setData(1, 0, '{0}:{1}'.format(key, '{b}')) parent_tree_item_add(top_item) def fill_stype_pipeline(self, stype=None, parent_tree_item=None): if not parent_tree_item: parent_tree_item_add = self.tree_widget.addTopLevelItem else: parent_tree_item_add = parent_tree_item.addChild if stype.pipeline: for pipeline in stype.pipeline.itervalues(): top_item = QtGui.QTreeWidgetItem() title = pipeline.info.get('name') if not title: title = pipeline.info.get('code') top_item.setText(0, title) top_item.setData(1, 0, '{0}:{1}'.format(pipeline.info.get('code'), '{pp}')) parent_tree_item_add(top_item) for key, val in pipeline.process.items(): child_item = QtGui.QTreeWidgetItem() child_item.setText(0, key.capitalize()) child_item.setCheckState(0, QtCore.Qt.Checked) child_item.setData(1, 0, '{0}:{1}'.format(key, '{pr}')) item_color = Qt4Gui.QColor(200, 200, 200) process = pipeline.get_process(key) if process: hex_color = process.get('color') color = None if hex_color: color = gf.hex_to_rgb(hex_color, tuple=True) if color: item_color = Qt4Gui.QColor(*color) child_item.setIcon(0, gf.get_icon('circle', color=item_color, scale_factor=0.55)) top_item.addChild(child_item) top_item.setExpanded(True) def fill_children_pipelines_and_processes(self, stype=None, parent_tree_item=None, added_stypes=None): if not parent_tree_item: parent_tree_item_add = self.tree_widget.addTopLevelItem else: parent_tree_item_add = parent_tree_item.addChild if not added_stypes: added_stypes = [] # Children process for child in stype.schema.children: child_stype = stype.get_project().stypes.get(child['from']) relationship_type = child.get('type') if child_stype and relationship_type not in ['many_to_many']: top_item = QtGui.QTreeWidgetItem() top_item.setText(0, child_stype.get_pretty_name() + ' (child)') top_item.setCheckState(0, QtCore.Qt.Checked) top_item.setData(1, 0, '{0}:{1}'.format(child_stype.get_code(), '{s}')) clr = child_stype.get_stype_color(tuple=True) stype_color = None if clr: stype_color = Qt4Gui.QColor(clr[0], clr[1], clr[2], 255) top_item.setIcon(0, gf.get_icon('view-sequential', color=stype_color, icons_set='mdi', scale_factor=1.1)) parent_tree_item_add(top_item) self.fill_builtin_processes(top_item) # breaking recursion if child_stype not in added_stypes: added_stypes.append(child_stype) self.fill_stype_pipeline(child_stype, top_item) self.fill_children_pipelines_and_processes(child_stype, top_item, added_stypes) def fit_to_content_tree_widget(self): items_count = 0 for item in QtGui.QTreeWidgetItemIterator(self.tree_widget): if item.value().isExpanded(): items_count += 1 row_height = items_count * self.tree_widget.sizeHintForRow(0) + 500 mouse_pos = Qt4Gui.QCursor.pos() self.setGeometry(mouse_pos.x(), mouse_pos.y(), 450, row_height) def add_new_preset(self): add_preset_dialog = QtGui.QDialog(self) add_preset_dialog.setWindowTitle('Save as new Preset {}'.format(self.stype.get_pretty_name())) add_preset_dialog.setMinimumSize(320, 80) add_preset_dialog.setMaximumSize(450, 80) add_preset_dialog_layout = QtGui.QVBoxLayout() add_preset_dialog.setLayout(add_preset_dialog_layout) add_preset_dialog_line_edit = QtGui.QLineEdit('New Preset') add_preset_dialog_button = QtGui.QPushButton('Create and Save') add_preset_dialog_layout.addWidget(add_preset_dialog_line_edit) add_preset_dialog_layout.addWidget(add_preset_dialog_button) add_preset_dialog_button.clicked.connect(lambda: self.save_preset_to_server( preset_name=add_preset_dialog_line_edit.text().lower().replace(' ', '_'), pretty_preset_name=add_preset_dialog_line_edit.text() )) add_preset_dialog_button.clicked.connect(add_preset_dialog.close) add_preset_dialog.exec_() # self.fill_presets_combo_box() def get_current_preset_name(self): current_index = self.presets_combo_box.currentIndex() return self.presets_combo_box.itemData(current_index) def get_current_preset_dict(self): preset_dict = self.get_preset_config(self.get_current_preset_name(), json=False) return preset_dict['data'] def get_preset_dict_by_type(self, type='pipeline', preset_dict=None, only_enabled=False): result_preset_dict = {} if type == 'pipeline': for name, preset in preset_dict.items(): if name.endswith(':{pp}'): result_preset_dict[name.replace(':{pp}', '')] = preset if type == 'builtin': for name, preset in preset_dict.items(): if name.endswith(':{b}'): if only_enabled: if preset['state']: result_preset_dict[name.replace(':{b}', '')] = preset else: result_preset_dict[name.replace(':{b}', '')] = preset if type == 'process': for name, preset in preset_dict.items(): if name.endswith(':{pr}'): if only_enabled: if preset['state']: result_preset_dict[name.replace(':{pr}', '')] = preset else: result_preset_dict[name.replace(':{pr}', '')] = preset if type == 'child': for name, preset in preset_dict.items(): if name.endswith(':{s}'): if only_enabled: if preset['state']: result_preset_dict[name.replace(':{s}', '')] = preset else: result_preset_dict[name.replace(':{s}', '')] = preset return result_preset_dict def apply_repo_sync_preset(self, current_index=None, preset_name=None): if not preset_name: preset_name = self.presets_combo_box.itemData(current_index) preset_dict = self.get_preset_by_name(preset_name) if preset_dict: # Pipeline items should not have check state, filter it with {pp} tag gf.set_tree_widget_checked_state(self.tree_widget, preset_dict, ignore_types_tuple=(':{pp}')) def get_preset_by_name(self, preset_name): # Only used on initial items filling if self.presets_list: for preset in self.presets_list: if preset['preset_name'] == preset_name: return preset def get_all_presets_from_server(self): server = tc.server_start() key = 'search_type:{0}'.format(self.stype.get_code()) search_type = 'sthpw/wdg_settings' project_code = self.stype.get_project().get_code() filters = [('key', 'like', '{0}%'.format(key)), ('project_code', project_code)] columns = ['data'] presets = server.query(search_type, filters, columns) if not presets: self.presets_list = [ { 'pretty_preset_name': 'Default', 'preset_name': 'default', } ] else: new_presets_list = [] for preset in presets: new_presets_list.append(gf.from_json(preset['data'])) self.presets_list = new_presets_list def get_preset_config(self, preset_name=None, pretty_preset_name=None, json=True): if not preset_name: preset_name = 'default' if not pretty_preset_name: pretty_preset_name = preset_name.capitalize().replace('_', ' ') # Preparing preset data preset_dict = { 'preset_name': preset_name, 'pretty_preset_name': pretty_preset_name, } gf.get_tree_widget_checked_state(self.tree_widget, preset_dict) key = 'search_type:{0}:preset_name:{1}'.format(self.stype.get_code(), preset_name) if json: data_dict = gf.to_json(preset_dict) else: data_dict = preset_dict data = { 'data': data_dict, 'key': key, 'login': '******', 'project_code': self.stype.get_project().get_code(), } return data def download_files_objects_list(self, files_objects_list): for file_object in files_objects_list: repo_sync_item = self.download_queue.schedule_file_object(file_object) repo_sync_item.download() def start_sync(self): self.sync_by_pipeline() preset_dict = self.get_current_preset_dict() self.sync_children(self.sobject, preset_dict) def sync_by_pipeline(self, sobject=None, preset_dict=None): if not sobject: sobject = self.sobject if not preset_dict: preset_dict = self.get_current_preset_dict() current_pipeline_preset_dict = self.get_preset_dict_by_type('pipeline', preset_dict) current_builtin_preset_dict = self.get_preset_dict_by_type('builtin', preset_dict, True) if current_pipeline_preset_dict: for pipeline_name, preset in current_pipeline_preset_dict.items(): self.sync_by_sobject(sobject, preset.get('sub'), current_builtin_preset_dict) elif current_builtin_preset_dict: self.sync_by_sobject(sobject, {}, current_builtin_preset_dict) def sync_children(self, sobject=None, preset_dict=None): stype = sobject.get_stype() if not preset_dict: preset_dict = self.get_current_preset_dict() children_preset_dict = self.get_preset_dict_by_type('child', preset_dict, True) project_obj = stype.get_project() for child_code, children_preset in children_preset_dict.items(): import time start = time.time() related_sobjects = sobject.get_related_sobjects(child_stype=project_obj.stypes.get(child_code), parent_stype=stype) print time.time() - start, 'GETTING FROM SERVER' if related_sobjects[0]: for related_sobject in related_sobjects[0].values(): self.sync_by_pipeline(related_sobject, children_preset.get('sub')) self.sync_children(related_sobject, children_preset.get('sub')) def sync_by_sobject(self, sobject=None, sync_preset_dict=None, builtin_preset_dict=None): sobject.update_snapshots() process_objects = sobject.get_all_processes() enabled_processes = self.get_preset_dict_by_type('process', sync_preset_dict, True) versionless_list = [] versions_list = [] if builtin_preset_dict: all_precesses = dict(enabled_processes.items() + builtin_preset_dict.items()) else: all_precesses = enabled_processes for process_name, process_object in process_objects.items(): if process_name in all_precesses.keys(): contexts = process_object.get_contexts() for context, context_obj in contexts.items(): versionless_snapshots = context_obj.get_versionless() for code, snapshot in versionless_snapshots.items(): versionless_list.extend(snapshot.get_files_objects()) versions_snapshots = context_obj.get_versions() for code, snapshot in versions_snapshots.items(): versions_list.extend(snapshot.get_files_objects()) # print versionless_list # print versions_list self.download_files_objects_list(versionless_list) self.download_files_objects_list(versions_list) def save_preset_to_server(self, preset_name=None, pretty_preset_name=None): if not preset_name: idx = self.presets_combo_box.currentIndex() preset_name = self.presets_combo_box.itemData(idx) server = tc.server_start() data = self.get_preset_config(preset_name, pretty_preset_name) search_type = 'sthpw/wdg_settings' # Checking for existing key filters = [('key', data['key'])] columns = ['code', 'project'] widget_settings = server.query(search_type, filters, columns, single=True) if widget_settings: code = widget_settings['code'] project = widget_settings['project'] search_key = server.build_search_key(search_type, code, project) server.insert_update(search_key, data, triggers=False) else: tc.server_start().insert(search_type, data, triggers=False) self.get_all_presets_from_server() self.fill_presets_combo_box(preset_name) def get_settings_dict(self): settings_dict = { 'presets_combo_box': self.presets_combo_box.currentIndex(), } return settings_dict def set_settings_from_dict(self, settings_dict=None): if not settings_dict: settings_dict = { 'presets_combo_box': 0, } initial_index = self.presets_combo_box.currentIndex() self.presets_combo_box.setCurrentIndex(int(settings_dict.get('presets_combo_box'))) if initial_index == int(settings_dict.get('presets_combo_box')): self.apply_repo_sync_preset(initial_index) def readSettings(self): group_path = 'ui_search/{0}/{1}/{2}'.format( self.stype.project.info['type'], self.stype.project.info['code'], self.stype.get_code().split('/')[1] ) self.set_settings_from_dict( env_read_config( filename='repo_sync', unique_id=group_path, long_abs_path=True ) ) def writeSettings(self): group_path = 'ui_search/{0}/{1}/{2}'.format( self.stype.project.info['type'], self.stype.project.info['code'], self.stype.get_code().split('/')[1] ) env_write_config( self.get_settings_dict(), filename='repo_sync', unique_id=group_path, long_abs_path=True ) def closeEvent(self, event): self.writeSettings() event.accept()