def _read_theme_file(theme, gui=None): logging.debug("theme: %s", theme) css_f = QtCore.QFile(theme) css_f.open(QtCore.QIODevice.ReadOnly) theme_data = "" in_ = QtCore.QTextStream(css_f) theme_dev = False if ":" not in theme: # theme dev mode, fix the file theme_dev = True logging.info("in theme dev mode") while not in_.atEnd(): line = in_.readLine() # A QByteArray if theme_dev: rsc_dir = join(dirname(dirname(dirname(__file__))), "resources") line = line.replace("url(:", "url(%s/" % rsc_dir) theme_data += line css_f.close() app = QtWidgets.QApplication.instance() logging.info('setting theme: %s' % gui) if gui: gui.setStyleSheet(theme_data) else: app.setStyleSheet(theme_data)
def _load_lang(): locale = QtCore.QLocale() full_locale = locale.bcp47Name() if "LUMBERJACK_LOCALE" in os.environ: full_locale = os.environ["LUMBERJACK_LOCALE"] logging.info("LOCAL OVERRIDE %s" % full_locale) if "-" in full_locale: lang, _ = full_locale.split("-") else: lang = full_locale if lang == "en": # we write in english by default, maybe one day we will deal with British/US english logging.info("English language") return region_lang = ":i18n/%s.qm" % full_locale lang_lang = ":i18n/%s.qm" % lang lang_file = QtCore.QFile(region_lang) if not lang_file.exists(): logging.debug("language %s does not exist" % region_lang) lang_file.close() lang_file = QtCore.QFile(lang_lang) if not lang_file.exists(): logging.info("language %s does not exist" % lang_lang) lang_file.close() logging.debug("falling back to english") return logging.debug("found lang file %s " % lang_file.fileName()) app = QtWidgets.QApplication.instance() trans = QtCore.QTranslator(app) trans.load(lang_file.fileName()) app = QtWidgets.QApplication.instance() app.installTranslator(trans)
def paintEvent(self, event): mouse_pos = self.mapFromGlobal(QtGui.QCursor.pos()) click_pos = None if self.click_position is not None: click_pos = self.mapFromGlobal(self.click_position) qp = QtGui.QPainter(self) # initialize the crosshairs qp.setBrush(QtGui.QColor(0, 0, 0, 1)) qp.setPen(QtCore.Qt.NoPen) qp.drawRect(event.rect()) # Clear the capture area if click_pos is not None: self.rectangle = QtCore.QRect(click_pos, mouse_pos) qp.setCompositionMode(QtGui.QPainter.CompositionMode_Clear) qp.drawRect(self.rectangle) qp.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver) pen = QtGui.QPen(QtGui.QColor('white'), 3, QtCore.Qt.SolidLine) qp.setPen(pen) # Draw cropping markers at click position if click_pos is not None: # left line qp.drawLine(mouse_pos.x(), click_pos.y(), mouse_pos.x(), mouse_pos.y()) # top line qp.drawLine(click_pos.x(), click_pos.y(), mouse_pos.x(), click_pos.y()) # right line qp.drawLine(click_pos.x(), click_pos.y(), click_pos.x(), mouse_pos.y()) # bottom line qp.drawLine(click_pos.x(), mouse_pos.y(), mouse_pos.x(), mouse_pos.y())
def __init__(self, parent=None, path_object=None): QtWidgets.QWidget.__init__(self, parent) if path_object: self.path_object = path_object.copy(seq=None, shot=None, ingest_source=None, resolution='', version='', user=None, scope=None) else: return self.panel = QtWidgets.QVBoxLayout(self) for each in ['assets', 'shots']: if each == 'assets': image_name = 'flower_80px.png' elif each == 'shots': image_name = 'shots96px.png' elif each == 'my tasks': image_name = 'star96px.png' else: image_name = 'ingest96px.png' button = LJButton(str(each)) button.setIcon( QtGui.QIcon( QtGui.QPixmap(os.path.join(icon_path(), image_name)))) button.setIconSize(QtCore.QSize(50, 50)) button.setProperty('class', 'ultra_button') self.panel.addWidget(button) button.clicked.connect(self.on_button_clicked) self.panel.addStretch(1)
class AssetWidget(QtWidgets.QWidget): button_clicked = QtCore.Signal(object) filter_changed = QtCore.Signal() def __init__(self, parent, title, scope): QtWidgets.QWidget.__init__(self, parent) v_layout = QtWidgets.QVBoxLayout(self) h_layout = QtWidgets.QHBoxLayout(self) if scope == 'assets': self.category_row = LabelComboRow('%s Category' % scope.title(), button=False, bold=False) self.name_row = LabelComboRow('%s Name(s)' % scope.title(), button=False, bold=False) if scope == 'shots': self.category_row = LabelComboRow('Sequence', button=False, bold=False) self.name_row = LabelComboRow('Shot Name(s)', button=False, bold=False) self.label = title self.project_label = QtWidgets.QLabel( "<b>Create %s tasks For: %s</b>" % (scope.title(), title)) self.message = QtWidgets.QLabel("") h_layout.addWidget(self.project_label) h_layout.addItem( QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)) v_layout.addLayout(h_layout) v_layout.addItem( QtWidgets.QSpacerItem(0, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)) v_layout.addLayout(self.category_row) v_layout.addLayout(self.name_row) v_layout.addWidget(self.message) self.message.hide() def set_title(self, new_title): self.title.setText('<b>%s</b>' % new_title.title())
def paintEvent(self, event): painter = QtWidgets.QStylePainter(self) opt = QtWidgets.QStyleOptionTab() for i in range(self.count()): self.initStyleOption(opt, i) painter.drawControl(QtWidgets.QStyle.CE_TabBarTabShape, opt) painter.save() s = opt.rect.size() s.transpose() r = QtCore.QRect(QtCore.QPoint(), s) r.moveCenter(opt.rect.center()) opt.rect = r c = self.tabRect(i).center() painter.translate(c) painter.rotate(90) painter.translate(-c) painter.drawControl(QtWidgets.QStyle.CE_TabBarTabLabel, opt) painter.restore()
class ScopePanel(QtWidgets.QWidget): location_changed = QtCore.Signal(object) def __init__(self, parent=None, path_object=None): QtWidgets.QWidget.__init__(self, parent) if path_object: self.path_object = path_object.copy(seq=None, shot=None, ingest_source=None, resolution='', version='', user=None, scope=None) else: return self.panel = QtWidgets.QVBoxLayout(self) for each in ['assets', 'shots']: if each == 'assets': image_name = 'flower_80px.png' elif each == 'shots': image_name = 'shots96px.png' elif each == 'my tasks': image_name = 'star96px.png' else: image_name = 'ingest96px.png' button = LJButton(str(each)) button.setIcon( QtGui.QIcon( QtGui.QPixmap(os.path.join(icon_path(), image_name)))) button.setIconSize(QtCore.QSize(50, 50)) button.setProperty('class', 'ultra_button') self.panel.addWidget(button) button.clicked.connect(self.on_button_clicked) self.panel.addStretch(1) def on_button_clicked(self): if self.sender().text() == 'ingest': self.path_object.set_attr(scope='IO') elif self.sender().text() == 'my tasks': self.path_object.set_attr(scope='my_tasks', seq='*') else: scope = self.sender().text() self.path_object.set_attr(scope=scope) self.path_object.set_attr(seq='*') self.location_changed.emit(self.path_object) def clear_layout(self, layout=None): clear_layout(self, layout=layout)
class EmptyStateWidgetIO(EmptyStateWidget): files_added = QtCore.Signal(object) def __init__(self, parent=None, path_object=None): EmptyStateWidget.__init__(self, parent) self.setText('Drag/Drop to Create a \nNew Import Version') self.setProperty('class', 'empty_state') def dropEvent(self, e): if e.mimeData().hasUrls: e.setDropAction(QtCore.Qt.CopyAction) e.accept() file_list = [] for url in e.mimeData().urls(): file_list.append(str(url.toLocalFile())) self.files_added.emit(file_list) else: e.ignore()
def __init__(self, parent=None): """ Constructor """ super(ScreenCapture, self).__init__(parent) self.click_position = None file_name = datetime.now().strftime('screen_grab_%Y-%m-%d_at_%H.%M.%S.png') self.output_path = os.path.expanduser(r'~/Desktop/%s' % file_name).replace('\\', '/') self.rectangle = QtCore.QRect() self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.Tool) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setCursor(QtCore.Qt.CrossCursor) self.setMouseTracking(True) self.set_screen_area() desktop = QtWidgets.QApplication.instance().desktop() desktop.resized.connect(self.set_screen_area) desktop.screenCountChanged.connect(self.set_screen_area)
class CGLMenuButton(QtWidgets.QWidget): """ Represents the "Button" within the parent "Menu". """ save_all_signal = QtCore.Signal() def __init__(self, parent=None, preflight_name='', preflight_step_name='', attrs=None, preflight_path='', menu_type='preflights'): # TODO - we need to choose better variable names, this is obviously "preflight" specific. QtWidgets.QWidget.__init__(self, parent) try: dialog = self.parent().parent().parent() print dialog self.software = dialog.software_combo.currentText() except AttributeError: # TODO - look into this a bit deeper, this is a fairly generic catch right now. dialog = self.parent().parent().parent().parent().parent() self.software = dialog.software_combo.currentText() self.menu_type = menu_type self.attrs = attrs self.name = preflight_step_name self.preflight_name = preflight_name self.preflight_path = preflight_path self.do_save = True # Create the Layouts layout = QtWidgets.QVBoxLayout(self) grid_layout = QtWidgets.QGridLayout() tool_row = QtWidgets.QHBoxLayout() # labels module_label = QtWidgets.QLabel('module') required_label = QtWidgets.QLabel('required') label_label = QtWidgets.QLabel('label') icon_button = QtWidgets.QToolButton() icon_button.setIcon(QtGui.QIcon(os.path.join(icon_path(), 'folder24px.png'))) self.icon_label = QtWidgets.QLabel('icon') name_label = QtWidgets.QLabel('name') # line edits self.command_line_edit = QtWidgets.QLineEdit() self.command_line_edit.setEnabled(False) self.required_line_edit = QtWidgets.QLineEdit() self.required_line_edit.setText('True') self.icon_path_line_edit = QtWidgets.QLineEdit() # self.required_line_edit.setEnabled(False) self.label_line_edit = QtWidgets.QLineEdit() self.name_line_edit = QtWidgets.QLineEdit() self.attrs_dict = {'module': self.command_line_edit, 'required': self.required_line_edit, 'label': self.label_line_edit, 'name': self.name_line_edit, 'icon': self.icon_path_line_edit} # tool buttons delete_button = QtWidgets.QPushButton('Delete') delete_button.setProperty('class', 'basic') open_button = QtWidgets.QPushButton('Open in Editor') open_button.setProperty('class', 'basic') self.save_button = QtWidgets.QPushButton('Save All') self.save_button.setProperty('class', 'basic') # Text Edit self.code_text_edit = QtWidgets.QPlainTextEdit() metrics = QtGui.QFontMetrics(self.code_text_edit.font()) self.code_text_edit.setTabStopWidth(4 * metrics.width(' ')) Highlighter(self.code_text_edit.document()) # Layout the Grid grid_layout.addWidget(label_label, 0, 0) grid_layout.addWidget(self.label_line_edit, 0, 1) grid_layout.addWidget(module_label, 1, 0) grid_layout.addWidget(self.command_line_edit, 1, 1) grid_layout.addWidget(required_label, 2, 0) grid_layout.addWidget(self.required_line_edit, 2, 1) grid_layout.addWidget(self.icon_label, 3, 0) grid_layout.addWidget(self.icon_path_line_edit, 3, 1) grid_layout.addWidget(icon_button, 3, 2) grid_layout.addWidget(name_label, 4, 0) grid_layout.addWidget(self.name_line_edit, 4, 1) name_label.hide() self.name_line_edit.hide() if self.menu_type != 'shelves': self.icon_label.hide() self.icon_path_line_edit.hide() icon_button.hide() else: self.required_line_edit.hide() required_label.hide() # Layout the tool row tool_row.addStretch(1) tool_row.addWidget(open_button) tool_row.addWidget(delete_button) tool_row.addWidget(self.save_button) # layout the widget layout.addLayout(grid_layout) layout.addWidget(self.code_text_edit) layout.addLayout(tool_row) # Signals and Slots self.code_text_edit.textChanged.connect(self.on_code_changed) icon_button.clicked.connect(self.on_icon_button_clicked) delete_button.clicked.connect(self.on_delete_clicked) open_button.clicked.connect(self.on_open_clicked) self.save_button.clicked.connect(self.on_save_clicked) self.load_attrs() self.label_line_edit.textChanged.connect(self.on_code_changed) def on_icon_button_clicked(self): default_folder = os.path.join(get_cgl_tools(), self.software, self.menu_type, self.preflight_name) file_paths = QtWidgets.QFileDialog.getOpenFileName(self, 'Choose a File to Attach', default_folder, "*") from_path = file_paths[0].replace('\\', '/') _, file_ = os.path.split(from_path) to_path = os.path.join(default_folder, file_).replace('\\', '/') if from_path != to_path: dirname = os.path.dirname(to_path) if not os.path.exists(dirname): os.makedirs(dirname) cgl_copy(from_path, to_path) self.icon_path_line_edit.setText(to_path) icon = QtGui.QIcon(to_path) tab_ = self.parent().parent() index_ = tab_.currentIndex() # print index_ tab_.setTabIcon(index_, icon) # # display the icon? self.on_save_clicked() def on_save_clicked(self): print 'save_clicked 172, emit.' self.save_all_signal.emit() def on_open_clicked(self): code_path = os.path.join(os.path.dirname(self.preflight_path), self.menu_type, self.preflight_name, '%s.py' % self.name) start(code_path) def on_code_changed(self): self.do_save = True def load_attrs(self): """ Loads the attrs for each "button" in the "Menu". :return: """ for attr in self.attrs: if attr in self.attrs_dict: attr_value = str(self.attrs[attr]) if attr == 'name': if not str(self.attrs[attr]): split = self.attrs['module'].split() print 'setting name to module name: %s' % split[-1].split('.run()')[0] attr_value = split[-1].split('.run()')[0] self.attrs_dict[attr].setText(attr_value) # load the python file into the text edit code_text = self.load_code_text() if code_text: self.code_text_edit.setPlainText(code_text) self.do_save = False else: code_text = self.load_default_text() self.code_text_edit.setPlainText(code_text) def load_code_text(self): code_path = os.path.join(os.path.dirname(self.preflight_path), self.menu_type, self.preflight_name, '%s.py' % self.name) if os.path.exists(code_path): try: return open(code_path).read() except IOError: with open(code_path, 'w+') as y: y.write("") return None def load_default_text(self): print self.menu_type, self.software, 11111111111 if self.menu_type == 'preflights': preflight = "from plugins.preflight.preflight_check import PreflightCheck\n" \ "\n\n" \ "class %s(PreflightCheck):\n" \ "\n" \ " def getName(self):\n" \ " pass\n" \ "\n" \ " def run(self):\n" \ " print '%s'\n" \ " # self.pass_check('Check Passed')\n" \ " # self.fail_check('Check Failed')\n\n" % (self.name, self.name) return preflight elif self.menu_type == 'menus' and self.software == 'lumbermill': return "\n\ndef run(lumbermill):\n print(\"hello world: %s\")" % self.name else: return "\n\ndef run():\n print(\"hello world: %s\")" % self.name def on_delete_clicked(self): print self print self.parent().parent() print self.parent().parent().parent() print '--------------------' print self.parent().parent().currentIndex() self.parent().parent().removeTab(self.parent().parent().currentIndex())
class CGLMenu(QtWidgets.QWidget): """ This creates the top level "Menu" Tab with the "buttons" within it. Menu is a catch all for "Menus", "Shelves", "Preflights", "Context-menus" and anything else in the future that fits the structure we've got here. """ save_clicked = QtCore.Signal() def __init__(self, parent=None, software=None, menu_type='menus', menu_name='', menu=None, menu_path=''): QtWidgets.QWidget.__init__(self, parent) # initialize variables self.menu_type = menu_type if self.menu_type == 'shelves': self.singular = 'shelf' elif self.menu_type == 'menus': self.singular = 'menu' elif self.menu_type == 'preflights': self.singular = 'preflight' elif self.menu_type == 'context-menus': self.singular = 'context-menu' else: self.singluar = 'not defined' self.software = software self.menu = menu self.menu_name = menu_name self.menu_path = menu_path self.new_button_widget = None # create layouts layout = QtWidgets.QVBoxLayout(self) title_layout = QtWidgets.QHBoxLayout() if menu_type != 'shelves': self.buttons_tab_widget = LJTabWidget() self.buttons_tab_widget.setProperty('class', 'vertical') self.buttons_tab_widget.tabBar().setProperty('class', 'vertical') else: self.buttons_tab_widget = QtWidgets.QTabWidget() self.title = '' if self.menu_type == 'menus': self.title = QtWidgets.QLabel('%s %s Buttons: (Drag to Reorder)' % (self.menu_name, self.menu_type.title())) elif self.menu_type == 'preflights': self.title = QtWidgets.QLabel('%s %s Steps: (Drag to Reorder)' % (self.menu_name, self.menu_type.title())) elif self.menu_type == 'shelves': self.title = QtWidgets.QLabel('%s Shelf Buttons: (Drag to Reorder)' % self.menu_name) elif self.menu_type == 'context-menus': self.title = QtWidgets.QLabel('Context Menu Buttons: (Drag to Reorder)') self.title.setProperty('class', 'title') if self.menu_type == 'shelves': self.add_button = QtWidgets.QPushButton('add shelf button') self.import_menu_button = QtWidgets.QPushButton('import shelf button') elif self.menu_type == 'preflights': self.add_button = QtWidgets.QPushButton('add preflight step') self.import_menu_button = QtWidgets.QPushButton('import preflight step') else: self.add_button = QtWidgets.QPushButton('add %s button' % self.singular) self.import_menu_button = QtWidgets.QPushButton('import %s button' % self.singular) self.add_submenu_button = QtWidgets.QPushButton('add submenu') self.add_submenu_button.hide() self.import_menu_button.hide() self.add_button.setProperty('class', 'add_button') self.add_submenu_button.setProperty('class', 'add_button') self.import_menu_button.setProperty('class', 'add_button') # set parameters self.buttons_tab_widget.setMovable(True) # layout the widget title_layout.addWidget(self.title) title_layout.addWidget(self.add_submenu_button) title_layout.addWidget(self.import_menu_button) title_layout.addWidget(self.add_button) title_layout.addStretch(1) layout.addLayout(title_layout) layout.addWidget(self.buttons_tab_widget) # connect SIGNALS and SLOTS self.add_button.clicked.connect(self.on_add_menu_button) self.add_submenu_button.clicked.connect(self.on_submenu_button_clicked) self.import_menu_button.clicked.connect(self.on_import_menu_button_clicked) self.load_buttons() @staticmethod def on_import_menu_button_clicked(): dialog = InputDialog(title="Feature In Progress", message="This button will allow you to import buttons/preflights from other menus") dialog.exec_() if dialog.button == 'Ok' or dialog.button == 'Cancel': dialog.accept() @staticmethod def on_submenu_button_clicked(): dialog = InputDialog(title="Feature In Progress", message="This button will allow you to create a submenu!") dialog.exec_() if dialog.button == 'Ok' or dialog.button == 'Cancel': dialog.accept() def on_add_menu_button(self): if self.menu_type == 'preflights': title_ = 'Add Preflight Step' message = 'Enter a Name for your Preflight Step' elif self.menu_type == 'menus': title_ = 'Add Menu' message = 'Enter a Name for your Menu Button' elif self.menu_type == 'shelves': title_ = 'Add Shelf' message = 'Enter a Name for your shelf button' elif self.menu_type == 'context-menus': title_ = 'Add Context Menu Item' message = 'Enter a name for your Context Menu Item' dialog = InputDialog(title=title_, message=message, line_edit=True, regex='^([A-Z][a-z]+)+$', name_example='class name must be CamelCase - ExamplePreflightName') dialog.exec_() if dialog.button == 'Ok': preflight_name = dialog.line_edit.text() command = self.get_command_text(button_name=preflight_name, menu_type=self.menu_type) module = self.default_preflight_text(preflight_name) if self.menu_type == 'preflights': attrs = {'label': preflight_name, 'name': preflight_name, 'required': 'True', 'module': module} elif self.menu_type == 'menus' or self.menu_type == 'context-menus': attrs = {'label': preflight_name, 'name': preflight_name, 'module': command} elif self.menu_type == 'shelves': attrs = {'label': preflight_name, 'module': command, 'name': preflight_name, 'icon': ''} self.new_button_widget = CGLMenuButton(parent=self.buttons_tab_widget, preflight_name=self.menu_name, preflight_step_name=dialog.line_edit.text(), attrs=attrs, preflight_path=self.menu_path, menu_type=self.menu_type) self.new_button_widget.save_all_signal.connect(self.on_save_clicked) if 'icon' in attrs.keys(): icon = QtGui.QIcon(attrs['icon']) index = self.buttons_tab_widget.addTab(self.new_button_widget, icon, preflight_name) else: index = self.buttons_tab_widget.addTab(self.new_button_widget, preflight_name) self.buttons_tab_widget.setCurrentIndex(index) def on_save_clicked(self): print 'save_clicked emit, 1' self.save_clicked.emit() def get_command_text(self, button_name, menu_type): print 'import cgl_tools.%s.%s.%s.%s as %s; %s.run()' % (self.software, menu_type, self.menu_name, button_name, button_name, button_name) return 'import cgl_tools.%s.%s.%s.%s as %s; %s.run()' % (self.software, menu_type, self.menu_name, button_name, button_name, button_name) def default_preflight_text(self, preflight_name): return 'cgl_tools.%s.%s.%s.%s' % (self.software, self.menu_type, self.menu_name, preflight_name) def load_buttons(self): for i in range(len(self.menu)): for button in self.menu: if button != 'order': if i == self.menu[button]['order']: button_widget = CGLMenuButton(parent=self.buttons_tab_widget, preflight_name=self.menu_name, preflight_step_name=button, attrs=self.menu[button], preflight_path=self.menu_path, menu_type=self.menu_type) if 'icon' in self.menu[button].keys(): if self.menu[button]['icon']: icon = QtGui.QIcon(self.menu[button]['icon']) self.buttons_tab_widget.addTab(button_widget, icon, self.menu[button]['name']) else: self.buttons_tab_widget.addTab(button_widget, button) else: self.buttons_tab_widget.addTab(button_widget, button)
class FilesPanel(QtWidgets.QWidget): source_selection_changed = QtCore.Signal(object) location_changed = QtCore.Signal(object) render_location_changed = QtCore.Signal(object) open_signal = QtCore.Signal() import_signal = QtCore.Signal() new_version_signal = QtCore.Signal() review_signal = QtCore.Signal() publish_signal = QtCore.Signal() def __init__(self, parent=None, path_object=None, user_email='', machine_user=None, show_import=False): QtWidgets.QWidget.__init__(self, parent) # self.setWidgetResizable(True) self.work_files = [] self.in_current_folder = False self.render_files_widget = None self.high_files = [] self.render_files = [] self.version_obj = None self.task = path_object.task self.task_widgets_dict = {} self.show_import = show_import self.path_object = path_object self.project_management = CONFIG['account_info']['project_management'] self.schema = CONFIG['project_management'][ self.project_management]['api']['default_schema'] schema = CONFIG['project_management'][ self.project_management]['tasks'][self.schema] self.user_info = CONFIG['project_management'][ self.project_management]['users'][current_user()] self.proj_man_tasks = schema['long_to_short'][self.path_object.scope] self.proj_man_tasks_short_to_long = schema['short_to_long'][ self.path_object.scope] self.current_location = path_object.data self.panel = QtWidgets.QVBoxLayout(self) self.tasks = QtWidgets.QHBoxLayout() self.in_file_tree = None self.user_changed_versions = False self.user_email = user_email if machine_user: self.user = machine_user else: self.user = current_user() self.project_management = CONFIG['account_info']['project_management'] self.on_task_selected(self.path_object) self.panel.addLayout(self.tasks) self.panel.addStretch(1) self.force_clear = False self.auto_publish_tasks = ['plate', 'element'] def on_task_selected(self, data): try: if isinstance(data, PathObject): current = data.copy() elif isinstance(data, dict): 'its a dict, this sucks' current = PathObject(data) except IndexError: print 'Nothing Selected' return if data: self.clear_layout(self.panel) # reset the GUI if not current.task: current.set_attr(task='*') current.set_attr(root=self.path_object.root) # current.set_attr(user_email=self.user_email) self.panel.seq = current.seq self.panel.shot = current.shot self.update_task_location(path_object=current) self.panel.tasks = [] try: if 'elem' in self.task: title = self.task else: title = self.proj_man_tasks_short_to_long[self.task] except KeyError: return task_widget = TaskWidget(parent=self, title=title, path_object=current, show_import=self.show_import) task_widget.task = self.task self.render_files_widget = task_widget.files_area.export_files_table task_widget.files_area.export_files_table.hide() self.task_widgets_dict[self.task] = task_widget # find the version information for the task: user = self.populate_users_combo(task_widget, current, self.task) self.current_location['user'] = user version = self.populate_versions_combo(task_widget, current, self.task) self.current_location['version'] = version resolution = self.populate_resolutions_combo( task_widget, current, self.task) self.current_location['resolution'] = resolution self.update_task_location(self.current_location) self.panel.addWidget(task_widget) self.panel.tasks.append(self.task) self.version_obj = current.copy(task=self.task, user=user, version=version, resolution=resolution, context='source', filename='*') task_widget.files_area.work_files_table.task = self.version_obj.task task_widget.files_area.work_files_table.user = self.version_obj.user task_widget.files_area.work_files_table.version = self.version_obj.version task_widget.files_area.work_files_table.resolution = self.version_obj.resolution try: self.work_files = self.version_obj.glob_project_element( 'filename', full_path=True) self.high_files = self.version_obj.copy( resolution='high').glob_project_element('filename', full_path=True) except ValueError: self.work_files = [] self.high_files = [] # check to see if there are work files for the 'high' version self.render_files = [] if user != 'publish': my_files_label = 'My Work Files' if not self.work_files: my_files_label = 'Drag/Drop Work Files' task_widget.files_area.work_files_table.hide() else: my_files_label = 'Published Work Files' logging.debug('Work Files: %s' % self.work_files) task_widget.setup( task_widget.files_area.work_files_table, FileTableModel( self.prep_list_for_table(self.work_files, basename=True), [my_files_label])) self.load_render_files(task_widget) task_widget.create_empty_version.connect( self.new_empty_version_clicked) task_widget.files_area.review_button_clicked.connect( self.on_review_clicked) task_widget.files_area.publish_button_clicked.connect( self.on_publish_clicked) task_widget.copy_latest_version.connect( self.new_version_from_latest) task_widget.copy_selected_version.connect( self.version_up_selected_clicked) task_widget.files_area.work_files_table.selected.connect( self.on_source_selected) task_widget.files_area.export_files_table.selected.connect( self.on_render_selected) task_widget.files_area.export_files_table.double_clicked.connect( self.on_render_double_clicked) task_widget.files_area.export_files_table.show_in_folder.connect( self.show_selected_in_folder) task_widget.files_area.work_files_table.doubleClicked.connect( self.on_open_clicked) task_widget.files_area.open_button.clicked.connect( self.on_open_clicked) task_widget.files_area.import_button.clicked.connect( self.on_import_clicked) task_widget.versions.currentIndexChanged.connect( self.on_task_info_changed) task_widget.users.currentIndexChanged.connect( self.on_task_info_changed) task_widget.resolutions.currentIndexChanged.connect( self.on_task_info_changed) task_widget.start_task_clicked.connect( self.on_assign_button_clicked) task_widget.files_area.work_files_table.dropped.connect( self.on_file_dragged_to_source) task_widget.files_area.export_files_table.dropped.connect( self.on_file_dragged_to_render) task_widget.files_area.work_files_table.show_in_folder.connect( self.show_selected_in_folder) task_widget.files_area.work_files_table.copy_folder_path.connect( self.copy_folder_path) task_widget.files_area.work_files_table.copy_file_path.connect( self.copy_file_path) task_widget.files_area.work_files_table.import_version_from.connect( self.import_versions_from) task_widget.empty_state.files_added.connect( self.on_file_dragged_to_source) if not user: task_widget.users_label.hide() task_widget.users.hide() task_widget.files_area.hide() task_widget.versions_label.hide() task_widget.versions.hide() task_widget.resolutions_label.hide() task_widget.resolutions.hide() task_widget.empty_state.hide() task_widget.status_button.hide() else: if task_widget.users.currentText() == current_user(): task_widget.refresh_task_info() else: task_widget.status_button.hide() def add_stretch_to_source(self): self.panel.addStretch(1) def new_files_dragged(self, files): to_object = PathObject(self.sender().to_object) to_folder = to_object.path_root for f in files: file_ = os.path.split(f)[-1] to_file = os.path.join(to_folder, file_) if '.' in file_: logging.info('Copying %s to %s' % (f, to_file)) cgl_copy(f, to_file) CreateProductionData(path_object=to_object) self.on_task_selected(self.version_obj) else: logging.info('Copying directory %s to %s' % (f, to_file)) cgl_copy(f, to_file) CreateProductionData(path_object=to_object) self.on_task_selected(self.version_obj) def update_task_location(self, path_object): """ Method that sends the path object dictionary for anything happening within the Tasks Panel. :param path_object: :return: """ if path_object: if isinstance(path_object, dict): path_object = PathObject(path_object) self.current_location = path_object.data self.path_object = path_object.copy() self.location_changed.emit(self.path_object) def on_create_asset(self): if self.current_location['scope'] == 'IO': dialog = InputDialog(self, title='Create Input Company', message='Enter the CLIENT or name of VENDOR', combo_box_items=['CLIENT']) dialog.exec_() self.current_location[ 'ingest_source'] = dialog.combo_box.currentText() ingest_source_location = PathObject( self.current_location).path_root if ingest_source_location.endswith(dialog.combo_box.currentText()): CreateProductionData(self.current_location, json=False) else: from apps.lumbermill.elements import asset_creator if 'asset' in self.current_location: task_mode = True else: task_mode = False dialog = asset_creator.AssetCreator( self, path_dict=self.current_location, task_mode=task_mode) dialog.exec_() def populate_users_combo(self, widget, path_object, task): if path_object.user: self.user = path_object.user object_ = path_object.copy(user='******', task=task) users = object_.glob_project_element('user') for each in users: widget.users.addItem(each) # self.set_user_from_radio_buttons() if self.user == 'publish': index_ = widget.users.findText('publish') if index_ != -1: widget.users.setCurrentIndex(index_) self.user = '******' else: index_ = widget.users.findText(self.user) if index_ != -1: widget.users.setCurrentIndex(index_) return widget.users.currentText() @staticmethod def populate_versions_combo(task_widget, path_object, task, set_to_latest=False): version = path_object.version task_widget.versions.show() task_widget.versions.clear() object_ = path_object.copy(user=task_widget.users.currentText(), task=task, version='*') try: items = object_.glob_project_element('version') except ValueError: items = ['000.000'] try: latest = items[-1] except IndexError: latest = '000.000' if set_to_latest: version = latest if not version: version = latest for each in items: task_widget.versions.addItem(each) task_widget.versions.setEnabled(True) index_ = task_widget.versions.findText(version) if index_ != -1: task_widget.versions.setCurrentIndex(index_) else: task_widget.versions.setCurrentIndex(0) return task_widget.versions.currentText() @staticmethod def populate_resolutions_combo(task_widget, path_object, task): object_ = path_object.copy(user=task_widget.users.currentText(), task=task, version=task_widget.versions.currentText(), resolution='*') try: items = object_.glob_project_element('resolution') except ValueError: items = ['high'] for each in items: task_widget.resolutions.addItem(each) if path_object.resolution: index_ = task_widget.resolutions.findText(path_object.resolution) else: index_ = task_widget.resolutions.findText('high') if index_: task_widget.resolutions.setCurrentIndex(index_) return task_widget.resolutions.currentText() def set_user_from_radio_buttons(self): if self.user == self.path_object.user: pass elif self.path_object.user == 'publish': self.user = '******' elif self.path_object.user == '*': self.user = '' def on_source_selected(self, data): reload_render = False new_data = [] temp_ = PathObject(self.current_location) if temp_.resolution: if temp_.render_pass: reload_render = True object_ = PathObject(temp_.split_after('resolution')) else: object_ = temp_ parent = self.sender().parent() object_.set_attr(root=self.path_object.root) object_.set_attr(version=parent.parent().versions.currentText()) object_.set_attr(context='source') object_.set_attr(resolution=parent.parent().resolutions.currentText()) object_.set_attr(user=parent.parent().users.currentText()) object_.set_attr(task=self.sender().task) try: object_.set_attr(filename=data[0][0]) filename_base, ext = os.path.splitext(data[0][0]) object_.set_attr(filename_base=filename_base) object_.set_attr(ext=ext.replace('.', '')) except IndexError: # this indicates a selection within the module, but not a specific selected files pass self.update_task_location(object_) for each in data: dir_ = os.path.dirname(object_.path_root) new_data.append(os.path.join(dir_, each[0])) self.source_selection_changed.emit(new_data) self.clear_task_selection_except(self.sender().task) self.sender().parent().show_tool_buttons(user=object_.user) if reload_render: self.load_render_files(self.task_widgets_dict[object_.task]) def on_render_double_clicked(self, data): if data: self.in_current_folder = False # print self.path_object.path_root # print self.path_object.render_pass # print self.path_object.camera # print self.path_object.aov # print '----------------------------' selected = data[0][0] print selected if selected == '.': print 'going back a folder' last = self.path_object.get_last_attr() self.path_object.set_attr(last, None) print self.path_object.path_root self.update_task_location(self.path_object) self.enter_render_folder() return if os.path.splitext(selected)[1]: print selected, 'is a file' else: print self.path_object.path_root, 'entering folder' self.enter_render_folder() @staticmethod def get_next_path_object_variable(path_object, current=False): if '\\' in path_object.path: pieces = path_object.path.split('\\') else: pieces = path_object.path.split('/') if current: position = len(pieces) - 1 else: position = len(pieces) selected_variable = path_object.template[position] print 'selected variable:', selected_variable return selected_variable def on_render_selected(self, data): if data: new_data = [] if self.current_location['context'] == 'source': self.current_location['filename'] = '' self.current_location['ext'] = '' self.current_location['context'] = 'render' object_ = PathObject(self.current_location) if not self.in_current_folder: current_variable = self.get_next_path_object_variable(object_) self.in_current_folder = True else: current_variable = self.get_next_path_object_variable( object_, current=True) print current_variable, object_.path_root if current_variable != 'filename': if object_.filename: object_.set_attr(filename='') object_.set_attr(ext='') new_path_object = PathObject(object_).copy() new_path_object.set_attr(attr=current_variable, value=data[0][0]) object_.set_attr(attr=current_variable, value=data[0][0]) # object_.set_attr(task=self.sender().task) if current_variable == 'filename': if os.path.splitext(data[0][0]): print 'this is a file' object_.set_attr(filename=data[0][0]) filename_base, ext = os.path.splitext(data[0][0]) object_.set_attr(filename_base=filename_base) object_.set_attr(ext=ext.replace('.', '')) else: print 'this is a folder i thought was a file' self.update_task_location(new_path_object) for each in data: dir_ = os.path.dirname(object_.path_root) new_data.append(os.path.join(dir_, each[0])) self.source_selection_changed.emit(new_data) # self.clear_task_selection_except(self.sender().task) self.sender().parent().show_tool_buttons(user=self.user) self.sender().parent().review_button.setEnabled(True) self.sender().parent().publish_button.setEnabled(True) self.add_context_menu() else: logging.debug( 'No render Files, Drag/Drop them to interface, or create them through software.' ) def add_context_menu(self): """ :return: """ from cgl.core.utils.general import load_json from cgl.core.project import get_cgl_tools # get the current task if self.task and 'elem' not in self.task: menu_file = '%s/lumbermill/context-menus.cgl' % get_cgl_tools() if os.path.exists(menu_file): menu_items = load_json('%s/lumbermill/context-menus.cgl' % get_cgl_tools()) if self.task in menu_items['lumbermill']: for item in menu_items['lumbermill'][self.task]: if item != 'order': button_label = menu_items['lumbermill'][ self.task][item]['label'] button_command = menu_items['lumbermill'][ self.task][item]['module'] module = button_command.split()[1] loaded_module = __import__(module, globals(), locals(), item, -1) widget = self.render_files_widget if widget.item_right_click_menu.action_exists( button_label): widget.item_right_click_menu.create_action( button_label, lambda: loaded_module.run( self.path_object)) @staticmethod def new_version_from_latest(): print 'version up_latest' def new_empty_version_clicked(self): """ Action when "Empty Version" is clicked :return: """ current = PathObject(self.version_obj) next_minor = current.new_minor_version_object() next_minor.set_attr(filename='') next_minor.set_attr(ext='') CreateProductionData(next_minor, create_default_file=True) self.on_task_selected(next_minor) def version_up_selected_clicked(self): current = PathObject(self.current_location) # current location needs to have the version in it. next_minor = current.new_minor_version_object() next_minor.set_attr(filename='') next_minor.set_attr(resolution=self.current_location['resolution']) next_minor.set_attr(ext='') CreateProductionData(next_minor) cgl_copy(os.path.dirname(current.path_root), next_minor.path_root) # reselect the original asset. self.on_task_selected(next_minor) def on_open_clicked(self): self.open_signal.emit() def on_import_clicked(self): self.import_signal.emit() def on_review_clicked(self): self.review_signal.emit() def on_publish_clicked(self): print 'Publishing stuff now' current = PathObject(self.current_location) current.publish() dialog = InputDialog(title='Publish Successful', message='Publish Files at: \n%s' % current.publish_render) dialog.exec_() def on_task_info_changed(self): """ This method runs whenever version, user, or resolution is changed in the TaskWidget. It essentially refreshes the task window. :return: """ version = None user = self.sender().parent().users.currentText() version = self.sender().parent().versions.currentText() resolution = self.sender().parent().resolutions.currentText() name = None if self.sender().name: name = self.sender().name if name == 'users': self.path_object = self.path_object.copy(user=user, latest=True, resolution='high', render_pass=None, camera=None, aov=None, filename=None, context='source') elif name == 'versions': self.path_object = self.path_object.copy(user=user, version=version, resolution='high', render_pass=None, camera=None, aov=None, filename=None, context='source') else: self.path_object = self.path_object.copy(user=user, version=version, resolution=resolution, render_pass=None, camera=None, aov=None, filename=None, context='source') files_widget = self.sender().parent().parent() # self.current_location = self.path_object.data files_widget.on_task_selected(self.path_object) def on_assign_button_clicked(self, data): print data task = self.sender().task users_dict = CONFIG['project_management'][ self.project_management]['users'] all_users = [] for each in users_dict.keys(): all_users.append(each.lower()) dialog = InputDialog(title="%s Task Ownership" % task, combo_box_items=users_dict.keys(), message='Who are you assigning this Task?', buttons=['Cancel', 'Start']) index = dialog.combo_box.findText(current_user().lower()) if index != -1: dialog.combo_box.setCurrentIndex(index) dialog.exec_() if dialog.button == 'Start': selected_user = dialog.combo_box.currentText( ) # this denotes the OS login name of the user print selected_user user_info = CONFIG['project_management'][ self.project_management]['users'][selected_user] self.path_object.set_attr(task=task) self.path_object.set_attr(user=selected_user) self.path_object.set_attr(version='000.000') self.path_object.set_attr(resolution='high') self.path_object.set_attr(shot=data.shot) self.path_object.set_attr(seq=data.seq) self.path_object.set_attr(filename=None) self.path_object.set_attr(ext=None) self.path_object.set_attr(filename_base=None) CreateProductionData(path_object=self.path_object, project_management=self.project_management, user_login=user_info['login'], force_pm_creation=True) self.update_task_location(path_object=self.path_object) def show_selected_in_folder(self): show_in_folder(self.path_object.path_root) def copy_folder_path(self): clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(os.path.dirname(self.path_object.path_root)) def copy_file_path(self): clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(self.path_object.path_root) @staticmethod def import_versions_from(): print 'import versions' @staticmethod def push(): print 'push' @staticmethod def pull(): print 'pull' @staticmethod def share_download_link(): print 'download link' # LOAD FUNCTIONS def on_file_dragged_to_render(self, data): object_ = PathObject.copy(self.version_obj, context='render') process_method(self.parent().progress_bar, self.on_file_dragged, args=(object_, data), text='Lumber-hacking Files') self.on_task_selected(object_) # logging.debug('Files Dragged to Render %s' % data) def on_file_dragged_to_source(self, data): object_ = PathObject.copy(self.version_obj, context='source') process_method(self.parent().progress_bar, self.on_file_dragged, args=(object_, data), text='Lumber-hacking Files') self.on_task_selected(object_) def on_file_dragged(self, path_object, data): logging.debug('Path: %s has files added to it' % path_object.path_root) self.update_task_location(path_object) self.clear_task_selection_except(path_object.task) to_path = path_object.path_root if os.path.isfile(to_path): to_path = os.path.dirname(to_path) elif to_path.endswith('*'): to_path = os.path.dirname(to_path) for d in data: filename_ = os.path.split(d)[-1] if os.path.isfile(d): filename_ = replace_illegal_filename_characters(filename_) logging.info('Copying File From %s to %s' % (d, os.path.join(to_path, filename_))) cgl_copy(d, os.path.join(to_path, filename_)) elif os.path.isdir(d): logging.info('Copying Folder From %s to %s' % (d, to_path)) cgl_copy(d, os.path.join(to_path, filename_)) self.parent().progress_bar.hide() def reload_task_widget(self, widget, path_object=None, populate_versions=True): if path_object: path_obj = PathObject(path_object) else: path_obj = PathObject(self.current_location) path_obj.set_attr(user=widget.users.currentText()) if populate_versions: path_obj.set_attr(version=self.populate_versions_combo( widget, path_obj, widget.label)) else: path_obj.set_attr(version=widget.versions.currentText()) path_obj.set_attr(resolution=widget.resolutions.currentText()) path_obj.set_attr(task=widget.task) self.update_task_location(path_obj) list_ = [] files_ = glob.glob('%s/*' % path_obj.path_root) for each in files_: list_.append(os.path.basename(each)) # this is what's doing the loading of the files. widget.files_area.clear() # widget.setup(widget.files_area.work_files_table, FileTableModel(self.prep_list_for_table(list_), ['Name'])) # self.on_task_selected(path_obj.data) def clear_task_selection_except(self, task=None): layout = self.panel i = -1 while i <= layout.count(): i += 1 child = layout.itemAt(i) if child: if child.widget(): if isinstance(child.widget(), AssetWidget): if task: if task != child.widget( ).files_area.work_files_table.task: child.widget().hide_tool_buttons() child.widget( ).files_area.work_files_table.clearSelection() else: child.widget().hide_tool_buttons() child.widget( ).files_area.work_files_table.clearSelection() return def enter_render_folder(self, render_path=None): """ :param path_object: :return: """ if not render_path: glob_path = self.path_object.path_root else: glob_path = render_path files_ = glob.glob('%s/*' % glob_path) data_ = self.prep_list_for_table(files_, basename=True, length=1, back=True) model = FilesModel(data_, ['Ready to Review/Publish']) self.render_files_widget.set_item_model(model) def load_render_files(self, widget): logging.debug('loading render files') widget.files_area.work_files_table.show() render_table = widget.files_area.export_files_table current = PathObject(self.version_obj) if widget.files_area.work_files_table.user: renders = current.copy( context='render', task=widget.task, user=widget.files_area.work_files_table.user, version=widget.files_area.work_files_table.version, resolution=widget.files_area.work_files_table.resolution, filename='*') files_ = glob.glob(renders.path_root) if current.user == 'publish': render_files_label = 'Published Files' widget.files_area.publish_button.hide() widget.files_area.new_version_button.hide() else: widget.files_area.new_version_button.show() widget.files_area.review_button.show() widget.files_area.publish_button.show() render_files_label = 'Ready to Review/Publish' logging.debug('Published Files for %s' % current.path_root) data_ = self.prep_list_for_table(files_, basename=True, length=1) model = FilesModel(data_, [render_files_label]) widget.setup(render_table, model) render_table.show() widget.files_area.open_button.show() widget.empty_state.hide() if not files_: widget.files_area.review_button.hide() widget.files_area.publish_button.hide() if not self.work_files: render_table.hide() widget.files_area.open_button.hide() widget.files_area.new_version_button.hide() widget.files_area.work_files_table.hide() widget.empty_state.show() def clear_layout(self, layout=None): clear_layout(self, layout) @staticmethod def prep_list_for_table(list_, path_filter=None, basename=False, length=None, back=False): """ Allows us to prepare lists for display in LJTables. :param list_: list to put into the table. :param path_filter: return a specific element from the path rather than the filename. For instance if you wanted to pull out only the "shot" name you'd use 'shot' as a path filter. :param basename: if true we only return the os.path.basename() result of the string. :return: list of prepared files/items. """ if not list_: return list_.sort() output_ = [] dirname = os.path.dirname(list_[0]) files = lj_list_dir(dirname, path_filter=path_filter, basename=basename) for each in files: output_.append([each]) if back: output_.insert(0, '.') return output_
def mouseReleaseEvent(self, event): self.rectangle = QtCore.QRect(self.click_position, event.globalPos()).normalized() self.click_position = None pix = capture_area(self.rectangle, self.output_path) self.close() return pix
def sizeHint(self): return QtCore.QSize(self.height_hint, self.width_hint)
class TaskPanel(QtWidgets.QWidget): """ Vertical Button Panel - built to display tasks in a vertical line. This is essentially the Task Panel """ add_button = QtCore.Signal(object) location_changed = QtCore.Signal(object) def __init__(self, parent=None, path_object=None, element='task', pixmap=None): QtWidgets.QWidget.__init__(self, parent) self.element = element if path_object: self.path_object = path_object elements = self.path_object.glob_project_element(element) else: return self.project_management = CONFIG['account_info']['project_management'] self.schema = CONFIG['project_management'][ self.project_management]['api']['default_schema'] schema = CONFIG['project_management'][ self.project_management]['tasks'][self.schema] self.proj_man_tasks = schema['long_to_short'][self.path_object.scope] self.proj_man_tasks_short_to_long = schema['short_to_long'][ self.path_object.scope] self.panel = QtWidgets.QVBoxLayout(self) self.title_layout = QtWidgets.QHBoxLayout() self.task_button = QtWidgets.QToolButton() self.task_button.setText('add %s' % element) self.task_button.setProperty('class', 'add_button') if pixmap: self.icon = QtWidgets.QLabel() self.icon.setPixmap(pixmap) self.h_layout.addWidget(self.icon) self.title_layout.addWidget(pixmap) self.title = QtWidgets.QLabel('%ss' % element.title()) self.title.setProperty('class', 'ultra_title') self.title_layout.addWidget(self.title) self.title_layout.addStretch(1) self.title_layout.addWidget(self.task_button) self.panel.addLayout(self.title_layout) self.task_button.clicked.connect(self.add_button_clicked) for each in elements: if 'elem' in each: task = each else: try: task = self.proj_man_tasks_short_to_long[each] except KeyError: print('%s not found in short_to_long' % each) task = each button = LJButton(str(task)) # button.setIcon(QtGui.QIcon(QtGui.QPixmap(os.path.join(icon_path(), image_name)))) # button.setIconSize(QtCore.QSize(50, 50)) button.setProperty('class', 'ultra_button') self.panel.addWidget(button) button.clicked.connect(self.on_button_clicked) self.panel.addStretch(1) def add_button_clicked(self): self.add_button.emit(self.path_object) def on_button_clicked(self): text = self.sender().text() if text: if 'elem' in text: short = text else: short = self.proj_man_tasks[text] self.path_object.__dict__[self.element] = short self.path_object.data[self.element] = short self.path_object.set_path() self.location_changed.emit(self.path_object) def clear_layout(self, layout=None): clear_layout(self, layout=layout)
class CompanyPanel(QtWidgets.QWidget): location_changed = QtCore.Signal(object) def __init__(self, parent=None, path_object=None, search_box=None): QtWidgets.QWidget.__init__(self, parent) self.search_box = search_box self.path_object = path_object self.panel = QtWidgets.QVBoxLayout(self) pixmap = QtGui.QPixmap(icon_path('company24px.png')) #self.company_widget = LJListWidget('Companies', pixmap=pixmap, search_box=search_box) self.data_table = LJTableWidget(self, path_object=self.path_object) self.company_widget.add_button.setText('add company') self.company_widget.list.setSizePolicy( QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding) self.user_root = CONFIG['cg_lumberjack_dir'] self.panel.addWidget(self.company_widget) self.panel.addStretch(0) self.load_companies() self.project_management = 'lumbermill' self.company_widget.add_button.clicked.connect(self.on_create_company) self.company_widget.list.itemDoubleClicked.connect( self.on_company_changed) def on_company_changed(self): self.path_object.set_attr( company=self.company_widget.list.selectedItems()[0].text()) if self.path_object.company: if self.path_object.company != '*': self.project_management = CONFIG['account_info'][ 'project_management'] self.check_default_company_globals() self.update_location() def on_create_company(self): dialog = InputDialog(title='Create Company', message='Enter the name for the company:', line_edit=True) dialog.exec_() if dialog.button == 'Ok': company = dialog.line_edit.text() self.path_object.set_attr(company=company) CreateProductionData(self.path_object, project_management='lumbermill') self.load_companies() def create_company_globals(self, company, proj_management): print 'Creating Company Globals %s' % company dir_ = os.path.join(self.user_root, 'companies', company) if not os.path.exists(dir_): print '%s doesnt exist, making it' % dir_ os.makedirs(dir_) app_config(company=company, proj_management=proj_management) # set the config stuff according to what's up def check_default_company_globals(self): """ ensures there are globals directories in the right place, this should really have a popup if it's not successful. :return: """ self.path_object.set_project_config() if self.path_object.company: if self.path_object.company != '*': dir_ = os.path.dirname(self.path_object.company_config) if not os.path.exists(dir_): print 'Creating Directory for Company Config File %s' % dir_ os.makedirs(dir_) def load_companies(self): self.company_widget.list.clear() companies_loc = '%s/*' % self.path_object.root companies = glob.glob(companies_loc) if companies: for each in companies: print each, 3 if '_config' not in each: c = os.path.basename(each) self.company_widget.list.addItem(c) def clear_layout(self, layout=None): clear_layout(self, layout=layout) def update_location(self, path_object=None): if not path_object: path_object = self.path_object path_object.set_attr(context='source') path_object.set_attr(project='*') self.location_changed.emit(path_object.data)
class ProjectPanel(QtWidgets.QWidget): location_changed = QtCore.Signal(object) def __init__(self, parent=None, path_object=None, search_box=None, title='Projects'): QtWidgets.QWidget.__init__(self, parent) self.path_object = path_object self.project_management = CONFIG['account_info']['project_management'] self.user_email = CONFIG['project_management'][ self.project_management]['users'][current_user()] self.root = CONFIG['paths']['root'] # Company Specific self.user_root = CONFIG['cg_lumberjack_dir'] self.left_column_visibility = True self.title = title # Create the Left Panel self.panel = QtWidgets.QVBoxLayout(self) if title == 'Projects': pixmap = QtGui.QPixmap(icon_path('project24px.png')) elif title == 'Companies': pixmap = QtGui.QPixmap(icon_path('company24px.png')) self.project_filter = ProjectWidget(title=title, pixmap=pixmap, search_box=search_box, path_object=self.path_object) self.panel.addWidget(self.project_filter) if title == 'Projects': self.load_projects() elif title == 'Companies': self.load_companies() self.project_filter.data_table.doubleClicked.connect( self.on_project_changed) self.project_filter.add_button.clicked.connect(self.on_create_project) def on_project_changed(self, data): data = self.project_filter.data_table.items_ print data if self.title == 'Projects': self.path_object.set_attr(project=data[0][0]) self.path_object.set_attr(scope='*') self.update_location(self.path_object) elif self.title == 'Companies': self.path_object.set_attr(company=data[0][0], context='source', project='*') # self.path_object.set_path(bob=True) self.update_location(self.path_object) def toggle_visibility(self): if self.left_column_visibility: self.hide() else: self.show() def hide(self): self.project_filter.hide_all() # project filter self.left_column_visibility = False def show(self): self.project_filter.show_all() def load_projects(self): self.path_object.set_attr(project='*') projects = self.path_object.glob_project_element('project') if not projects: print 'no projects for %s' % self.path_object.company self.project_filter.data_table.setEnabled(False) self.project_filter.add_button.setText('Create First Project') else: self.project_filter.data_table.setEnabled(True) self.project_filter.add_button.setText('Add Project') self.project_filter.setup( ListItemModel(prep_list_for_table(projects, split_for_file=True), ['Name'])) self.update_location(self.path_object) def load_companies(self): companies_loc = '%s/*' % self.path_object.root print companies_loc companies = glob.glob(companies_loc) clean_companies = [] for c in companies: if '_config' not in c: clean_companies.append(c) if not clean_companies: print 'no companies' self.project_filter.data_table.setEnabled(False) self.project_filter.add_button.setText('Create First Company') else: self.project_filter.data_table.setEnabled(True) self.project_filter.add_button.setText('Add Company') self.project_filter.setup( ListItemModel( prep_list_for_table(clean_companies, split_for_file=True), ['Name'])) self.update_location(self.path_object) def update_location(self, path_object=None): if not path_object: path_object = self.path_object self.location_changed.emit(path_object.data) def on_create_project(self): if self.title == 'Projects': progress_bar = self.parent().progress_bar dialog = CreateProjectDialog(parent=None, variable='project') dialog.exec_() if dialog.button == 'Ok': project_name = dialog.proj_line_edit.text() self.path_object.set_attr(project=project_name) production_management = dialog.proj_management_combo.currentText( ) print self.path_object.path_root print production_management process_method(progress_bar, self.do_create_project, args=(progress_bar, self.path_object, production_management), text='Creating Project') self.path_object.set_attr(project='*') self.update_location() elif self.title == 'Companies': dialog = InputDialog(title='Create Company', message='Enter the name for the company:', line_edit=True) dialog.exec_() if dialog.button == 'Ok': company = dialog.line_edit.text() self.path_object.set_attr(company=company) CreateProductionData(self.path_object, project_management='lumbermill') self.load_companies() @staticmethod def do_create_project(progress_bar, path_object, production_management): CreateProductionData(path_object=path_object.path_root, file_system=True, project_management=production_management) print 'setting project management to %s' % production_management create_project_config(path_object.company, path_object.project) progress_bar.hide() def clear_layout(self, layout=None): clear_layout(self, layout=layout)
class ProductionPanel(QtWidgets.QWidget): location_changed = QtCore.Signal(object) def __init__(self, parent=None, path_object=None, search_box=None, my_tasks=False): QtWidgets.QWidget.__init__(self, parent) # Create the Middle Panel if path_object: self.path_object = path_object.copy(seq='*', shot='*', ingest_source='*', resolution='', version='', user=None) else: return self.my_tasks = my_tasks self.panel = QtWidgets.QVBoxLayout(self) self.assets = None self.assets_filter_default = filter self.root = CONFIG['paths']['root'] self.radio_filter = 'Everything' self.clear_layout() self.assets = AssetWidget(self, title="", search_box=search_box) self.assets.add_button.show() self.set_scope_radio() self.panel.addWidget(self.assets) self.load_assets() self.assets.data_table.selected.connect(self.on_main_asset_selected) self.assets.shots_radio.clicked.connect(self.on_filter_radio_changed) self.assets.assets_radio.clicked.connect(self.on_filter_radio_changed) self.assets.tasks_radio.clicked.connect(self.load_tasks) def load_tasks(self): from cgl.core.config import UserConfig # TODO - figure out how to add the progress bar to this. self.assets.add_button.setEnabled(False) self.assets.data_table.clearSpans() data = [] proj_man = CONFIG['account_info']['project_management'] login = CONFIG['project_management'][proj_man]['users'][ current_user()]['login'] if proj_man == 'ftrack': # ideally we load from a .csv file and run this in the background only to update the .csv file. from plugins.project_management.ftrack.main import find_user_assignments process_method(self.parent().progress_bar, find_user_assignments, args=(self.path_object, login), text='Finding Your Tasks') try: company_json = UserConfig().d['my_tasks'][ self.path_object.company] except KeyError: print 'Couldnt find company %s in company_json tasks file.' % self.path_object.company self.parent().progress_bar.hide() return if self.path_object.project in company_json: project_tasks = company_json[self.path_object.project] if project_tasks: for task in project_tasks: data.append([ project_tasks[task]['seq'], project_tasks[task]['shot_name'], project_tasks[task]['filepath'], project_tasks[task]['due_date'], project_tasks[task]['status'], project_tasks[task]['task_type'] ]) if data: self.assets.data_table.show() self.assets.search_box.show() self.assets.message.setText('') self.assets.setup( ListItemModel(data, [ 'Category', 'Name', 'Path', 'Due Date', 'Status', 'Task' ])) self.assets.data_table.hideColumn(0) self.assets.data_table.hideColumn(2) self.assets.data_table.hideColumn(3) else: self.assets.data_table.hide() self.assets.message.setText('No Tasks for %s Found!' % login) self.assets.message.show() self.parent().progress_bar.hide() return True else: print 'No Tasks Assigned for %s' % self.path_object.project self.parent().progress_bar.hide() return False else: self.parent().progress_bar.hide() return False def load_assets(self): red_palette = QtGui.QPalette() red_palette.setColor(self.foregroundRole(), QtGui.QColor(255, 0, 0)) self.assets.data_table.clearSpans() items = glob.glob(self.path_object.path_root) data = [] temp_ = [] self.assets.add_button.clicked.connect(self.on_create_asset) d = None if items: self.assets.data_table.show() self.assets.search_box.show() self.assets.message.hide() self.assets.message.setText('') for each in items: obj_ = PathObject(str(each)) d = obj_.data shot_name = '%s_%s' % (d['seq'], d['shot']) if shot_name not in temp_: temp_.append(shot_name) if d['scope'] == 'assets': data.append([d['seq'], d['shot'], each, '', '', '']) elif d['scope'] == 'shots': data.append([d['seq'], shot_name, each, '', '', '']) if d['scope'] == 'assets': self.assets.setup( ListItemModel(data, [ 'Category', 'Name', 'Path', 'Due Date', 'Status', 'Task' ])) elif d['scope'] == 'shots': self.assets.setup( ListItemModel( data, ['Seq', 'Shot', 'Path', 'Due Date', 'Status', 'Task'])) self.assets.data_table.hideColumn(0) self.assets.data_table.hideColumn(2) self.assets.data_table.hideColumn(3) self.assets.data_table.hideColumn(5) else: self.assets.data_table.hide() self.assets.message.setText( 'No %s Found! \nClick + button to create %s' % (self.path_object.scope.title(), self.path_object.scope)) self.assets.message.setPalette(red_palette) self.assets.message.show() def on_main_asset_selected(self, data): print 'selecting' if data: print data[0][2] path_object = PathObject(data[0][2]) if not path_object.task: path_object.set_attr(task='*') else: path_object.set_attr(user=None) self.update_location(path_object) def update_location(self, path_object=None): if path_object: self.location_changed.emit(path_object.data) else: self.path_object.set_attr(seq='*') self.location_changed.emit(self.path_object.data) def set_scope_radio(self): if self.path_object.scope == 'assets': self.assets.assets_radio.setChecked(True) elif self.path_object.scope == 'shots': self.assets.shots_radio.setChecked(True) elif self.path_object.scope == '': self.path_object.scope.set_attr(scope='assets') self.assets.assets_radio.setChecked(True) def on_create_asset(self): from apps.lumbermill.elements import asset_creator if self.path_object.scope == 'assets': task_mode = True else: task_mode = False dialog = asset_creator.AssetCreator(self, path_dict=self.path_object.data, task_mode=task_mode) dialog.exec_() self.update_location() def on_filter_radio_changed(self): if self.sender().text() == 'Assets': self.assets.add_button.setEnabled(True) self.path_object.set_attr(scope='assets') self.sender().parent().set_icon('assets') self.path_object.data['my_tasks'] = False elif self.sender().text() == 'Shots': self.assets.add_button.setEnabled(True) self.path_object.set_attr(scope='shots') self.sender().parent().set_icon('shots') self.path_object.data['my_tasks'] = False elif self.sender().text() == 'My Tasks': self.path_object.data['my_tasks'] = True self.update_location(self.path_object) def clear_layout(self, layout=None): clear_layout(self, layout=layout)
class NavigationWidget(QtWidgets.QFrame): location_changed = QtCore.Signal(object) my_tasks_clicked = QtCore.Signal() ingest_button_clicked = QtCore.Signal() refresh_button_clicked = QtCore.Signal(object) def __init__(self, parent=None, path_object=None): QtWidgets.QFrame.__init__(self, parent) if path_object: self.path_object = path_object else: return self.setProperty('class', 'light_grey') self.my_tasks_button = QtWidgets.QPushButton() self.my_tasks_button.setToolTip('My Tasks') tasks_icon = os.path.join(cglpath.icon_path(), 'star24px.png') self.my_tasks_button.setProperty('class', 'grey_border') self.my_tasks_button.setIcon(QtGui.QIcon(tasks_icon)) self.my_tasks_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.refresh_button = QtWidgets.QPushButton() self.refresh_button.setToolTip('Refresh') refresh_icon = os.path.join(cglpath.icon_path(), 'spinner11.png') self.refresh_button.setProperty('class', 'grey_border') self.refresh_button.setIcon(QtGui.QIcon(refresh_icon)) self.refresh_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.ingest_button = QtWidgets.QPushButton() self.ingest_button.setToolTip('My Tasks') self.ingest_button.setProperty('class', 'grey_border') ingest_icon = os.path.join(cglpath.icon_path(), 'ingest24px.png') self.ingest_button.setIcon(QtGui.QIcon(ingest_icon)) self.ingest_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.back_button = QtWidgets.QPushButton() self.back_button.setToolTip('Go back') self.projects_button = QtWidgets.QPushButton() self.projects_button.setToolTip('Go to Projects') self.companies_button = QtWidgets.QPushButton() self.companies_button.setToolTip('Go to Companies') self.my_tasks_button.setProperty('class', 'grey_border') self.back_button.setStyleSheet("background: transparent;") self.projects_button.setStyleSheet("background: transparent;") self.companies_button.setStyleSheet("background: transparent;") back_icon = os.path.join(cglpath.icon_path(), 'back24px.png') home_icon = os.path.join(cglpath.icon_path(), 'project24px.png') company_icon = os.path.join(cglpath.icon_path(), 'company24px.png') self.back_button.setIcon(QtGui.QIcon(back_icon)) self.back_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.companies_button.setIcon(QtGui.QIcon(company_icon)) self.companies_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.projects_button.setIcon(QtGui.QIcon(home_icon)) self.projects_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.current_location_line_edit = QtWidgets.QLineEdit() self.current_location_line_edit.setReadOnly(True) self.current_location_line_edit.setMinimumHeight(ICON_WIDTH * 1.28) self.current_location_line_edit.hide() self.search_box = LJSearchEdit(self) layout = QtWidgets.QVBoxLayout(self) self.cl_row = QtWidgets.QHBoxLayout() self.cl_row.addWidget(self.back_button) self.cl_row.addWidget(self.companies_button) self.cl_row.addWidget(self.projects_button) self.cl_row.addWidget(self.my_tasks_button) self.cl_row.addWidget(self.refresh_button) self.cl_row.addWidget(self.search_box) self.cl_row.addWidget(self.ingest_button) layout.addLayout(self.cl_row) layout.addWidget(self.current_location_line_edit) self.my_tasks_button.clicked.connect(self.my_tasks_pressed) self.ingest_button.clicked.connect(self.ingest_clicked) self.refresh_button.clicked.connect(self.refresh_clicked) self.back_button.clicked.connect(self.back_button_pressed) self.companies_button.clicked.connect(self.buttons_pressed) self.projects_button.clicked.connect(self.buttons_pressed) self.set_text(self.path_object.path_root) def refresh_clicked(self): print 'Refresh clicked' self.refresh_button_clicked.emit(self.path_object) def text(self): return self.current_location_line_edit.text() def set_text(self, text): self.current_location_line_edit.setText(text.replace('\\', '/')) if self.current_location_line_edit.text(): self.path_object = cglpath.PathObject( self.current_location_line_edit.text()) def show_company(self): self.companies_button.show() self.projects_button.hide() self.my_tasks_button.hide() def show_projects(self): self.companies_button.show() self.projects_button.show() self.my_tasks_button.hide() def show_production(self): self.companies_button.show() self.projects_button.show() self.my_tasks_button.show() def show_none(self): self.shots_button.hide() self.my_tasks_button.hide() self.companies_button.hide() self.projects_button.hide() def update_buttons(self, path_object=None): if not path_object: if self.path_object: path_object = self.path_object else: return if not path_object.company: self.show_none() elif path_object.company == '*': self.show_company() elif path_object.project == '*': self.show_projects() elif path_object.scope == 'IO': self.show_production() elif path_object.scope == '*': self.show_production() elif path_object.seq == '*': self.show_production() elif path_object.type == '*': self.show_production() else: self.show_production() def buttons_pressed(self): path = None if self.sender() == self.projects_button: path = '%s/%s/source/*' % (self.path_object.root, self.path_object.company) elif self.sender() == self.companies_button: path = '%s/%s' % (self.path_object.root, '*') elif self.sender() == self.shots_button: path = '%s/%s/source/%s/%s/*' % ( self.path_object.root, self.path_object.company, self.path_object.project, self.path_object.scope) new_obj = cglpath.PathObject(path) self.location_changed.emit(new_obj) def my_tasks_pressed(self): self.my_tasks_clicked.emit() def ingest_clicked(self): if self.path_object.project and self.path_object.company and self.path_object.project != '*': self.path_object = self.path_object.copy(seq=None, shot=None, ingest_source=None, resolution='', version='', user=None, scope='IO') self.location_changed.emit(self.path_object) else: print 'Please Choose a Company and a Project before pushing the ingest button' def back_button_pressed(self): path_object = cglpath.PathObject( self.current_location_line_edit.text()) path_object.set_attr(context='source') # if i'm a task, show me all the assets or shots last = path_object.get_last_attr() if last == 'filename': last = 'task' if last == 'resolution': last = 'task' if last == 'version': if path_object.scope == 'IO': last = 'scope' else: last = 'task' if last == 'user': last = 'task' if last == 'task': if path_object.task == '*': new_path = self.format_new_path(path_object, 'scope') else: # send them to the tasks page new_path = self.format_new_path(path_object, 'shot') elif last == 'seq' or last == 'type': if path_object.seq == '*' or path_object.type == '*': # send them to the projects page new_path = self.format_new_path(path_object, split_after='project') else: new_path = self.format_new_path(path_object, split_after='scope') elif last == 'shot' or last == 'asset': new_path = self.format_new_path(path_object, split_after='scope') elif last == 'scope': if path_object.scope == '*': # send them to the scope page new_path = self.format_new_path(path_object, split_after='context') else: # send them to the projects page new_path = self.format_new_path(path_object, split_after='project') elif last == 'project' or last == 'company': # send them to the "Companies" page new_path = path_object.root elif last == 'ingest_source': # send them to projects page new_path = self.format_new_path(path_object, split_after='project') else: logging.debug(path_object.path_root) logging.debug('Nothing built for %s' % last) return self.path_object = cglpath.PathObject(new_path) self.update_buttons() self.location_changed.emit(self.path_object) @staticmethod def format_new_path(path_object, split_after=None): new_path = '%s/%s' % (path_object.split_after(split_after), '*') return new_path
class IOPanel(QtWidgets.QWidget): location_changed = QtCore.Signal(object) def __init__(self, parent=None, path_object=None): QtWidgets.QWidget.__init__(self, parent) if path_object: self.path_object = path_object else: print 'No Path Object found, exiting' return self.project_management = CONFIG['account_info']['project_management'] self.schema = CONFIG['project_management'][ self.project_management]['api']['default_schema'] self.schema_dict = CONFIG['project_management'][ self.project_management]['tasks'][self.schema] self.path_object_next = None self.panel = QtWidgets.QVBoxLayout(self) h_layout = QtWidgets.QHBoxLayout() self.title = 'Import to %s' % path_object.project self.task = None self.version = '000.000' self.latest_version = '000.000' self.user = None self.resolution = None self.root = None self.company = None self.project = None self.data_frame = None self.width_hint = 1300 self.height_hint = 1200 self.current_selection = None self.path_object.set_attr(scope='IO') self.path_object.set_attr(ingest_source='*') self.data_frame = None self.pandas_path = '' self.io_statuses = ['Imported', 'Tagged', 'Published'] self.file_tree = LJTreeWidget(self) #self.width_hint = self.file_tree.width_hint pixmap = QtGui.QPixmap(icon_path('back24px.png')) import_empty_icon = QtGui.QIcon(pixmap) self.source_widget = LJListWidget('Sources', pixmap=None) self.ingest_widget = LJListWidget('Ingests', pixmap=None, empty_state_text='Select Source', empty_state_icon=import_empty_icon) # self.import_events.hide()f self.tags_title = QtWidgets.QLineEdit( "<b>Select File(s) or Folder(s) to tag</b>") self.tags_title.setReadOnly(True) self.tags_title.setProperty('class', 'feedback') self.tags_button = QtWidgets.QPushButton('View Publish') self.tags_button.setProperty('class', 'basic') self.tags_button.setMaximumWidth(180) self.tags_title_row = QtWidgets.QHBoxLayout() self.tags_title_row.addWidget(self.tags_title) self.tags_title_row.addWidget(self.tags_button) self.tags_button.hide() self.scope_label = QtWidgets.QLabel('Scope') self.scope_combo = AdvComboBox() self.scope_combo.addItems(['', 'assets', 'shots']) self.seq_row = QtWidgets.QHBoxLayout() self.seq_row.addWidget(self.scope_label) self.seq_row.addWidget(self.scope_combo) self.feedback_area = QtWidgets.QLabel('') self.seq_label = QtWidgets.QLabel('Seq ') self.seq_combo = AdvComboBox() self.seq_row.addWidget(self.seq_label) self.seq_row.addWidget(self.seq_combo) self.shot_label = QtWidgets.QLabel('Shot') self.shot_combo = AdvComboBox() self.seq_row.addWidget(self.shot_label) self.seq_row.addWidget(self.shot_combo) self.task_label = QtWidgets.QLabel('Task') self.task_combo = AdvComboBox() self.task_combo.setEditable(False) self.seq_row.addWidget(self.task_label) self.seq_row.addWidget(self.task_combo) self.tags_label = QtWidgets.QLabel("Tags") self.tags_label.setWordWrap(True) self.tags_label.setMaximumWidth(100) self.tags_line_edit = QtWidgets.QLineEdit() self.tags_row = QtWidgets.QHBoxLayout() self.tags_row.addWidget(self.tags_label) self.tags_row.addWidget(self.tags_line_edit) # create buttons row self.buttons_row = QtWidgets.QHBoxLayout() self.publish_button = QtWidgets.QPushButton('Publish Selected') self.view_in_lumbermill = QtWidgets.QPushButton('View in Lumbermill') self.view_in_lumbermill.setMinimumWidth(220) self.refresh_button = QtWidgets.QPushButton('Refresh') self.refresh_button.hide() self.publish_button.setProperty('class', 'basic') self.view_in_lumbermill.setProperty('class', 'basic') self.refresh_button.setProperty('class', 'basic') self.buttons_row.addStretch(1) self.buttons_row.addWidget(self.refresh_button) self.buttons_row.addWidget(self.view_in_lumbermill) self.buttons_row.addWidget(self.publish_button) self.empty_state = EmptyStateWidgetIO(path_object=self.path_object) self.empty_state.setText( 'Select a Source:\n Click + to Create a new one') self.progress_bar = ProgressGif() self.progress_bar.hide() self.view_in_lumbermill.hide() h_layout.addWidget(self.source_widget) h_layout.addWidget(self.ingest_widget) self.panel.addLayout(h_layout) self.panel.addWidget(self.file_tree) self.panel.addWidget(self.empty_state) self.panel.addLayout(self.tags_title_row) self.panel.addWidget(self.progress_bar) self.panel.addLayout(self.seq_row) self.panel.addLayout(self.tags_row) self.panel.addLayout(self.buttons_row) self.panel.addWidget(self.feedback_area) self.panel.addStretch(1) self.load_companies() self.ingest_widget.empty_state.show() self.ingest_widget.list.hide() self.hide_tags() self.file_tree.hide() self.view_in_lumbermill.clicked.connect( self.on_view_in_lumbermill_clicked) self.refresh_button.clicked.connect(self.on_ingest_selected) self.scope_combo.currentIndexChanged.connect(self.on_scope_changed) self.seq_combo.currentIndexChanged.connect(self.on_seq_changed) self.file_tree.selected.connect(self.on_file_selected) self.seq_combo.currentIndexChanged.connect(self.edit_data_frame) self.shot_combo.currentIndexChanged.connect(self.edit_data_frame) self.task_combo.currentIndexChanged.connect(self.edit_data_frame) self.tags_line_edit.textChanged.connect(self.edit_tags) self.source_widget.add_button.clicked.connect( self.on_source_add_clicked) self.source_widget.list.clicked.connect(self.on_source_selected) self.ingest_widget.list.clicked.connect(self.on_ingest_selected) self.ingest_widget.add_button.clicked.connect(self.on_add_ingest_event) self.publish_button.clicked.connect(self.publish_selected_asset) self.empty_state.files_added.connect(self.new_files_dragged) logging.info('Testing the popup') self.on_scope_changed() def on_source_add_clicked(self): print self.path_object.scope dialog = InputDialog(title='Add Source Company or Gear', message='Add an Import Source:', line_edit=True, buttons=['Cancel', 'Add Source']) dialog.exec_() if dialog.button == 'Add Source': root_ = self.path_object.path_root.split(self.path_object.scope)[0] new_source = os.path.join(root_, 'IO', dialog.line_edit.text()) if not os.path.exists(new_source): os.makedirs(new_source) self.parent().parent().centralWidget( ).update_location_to_latest(self.path_object) else: print 'Source %s already exists!' % new_source def file_interaction(self, files, path, to_folder): # TODO - ultimately we want to figure out how to handle the progress bar through the cgl_execute function. if path == '*': print 'Please Select An Ingest Source Before Dragging Files' return from cgl.core.utils.general import cgl_copy publish_data_csv = os.path.join(to_folder, 'publish_data.csv').replace('\\', '/') if os.path.exists(to_folder): create_new = False else: create_new = True cgl_copy(files, to_folder, verbose=False, dest_is_folder=True) self.progress_bar.hide() if create_new: self.load_import_events(new=True) num = self.ingest_widget.list.count() item = self.ingest_widget.list.item(num - 1) item.setSelected(True) self.parent().parent().centralWidget().update_location_to_latest( self.path_object) # self.empty_state.hide() if os.path.exists(publish_data_csv): os.remove(publish_data_csv) time.sleep( .5 ) # seems like on the network i have to force it to sleep so it has time to delete. self.load_data_frame() self.populate_tree() def new_files_dragged(self, files): """ What happens when i drag something to new files. :param files: :return: """ to_folder = self.path_object.path_root path = self.path_object.ingest_source self.progress_bar.show() #QtWidgets.qApp.processEvents() file_process = threading.Thread(target=self.file_interaction, args=(files, path, to_folder)) #QtWidgets.qApp.processEvents() file_process.start() # TODO - how do i know if the location changed? # if os.path.exists(to_folder): # print 'dragging to exsting folder' # else: # print 'dragging to new folder' # self.location_changed.emit(self.path_object) # self.empty_state.hide() # TODO - No idea why none of these are working for selecting the version. # num = self.ingest_widget.list.count() # item = self.ingest_widget.list.item(num - 1) # item.setSelected(True) # self.ingest_widget.list.setCurrentItem(item) # self.ingest_widget.list.setCurrentRow(-1) def load_companies(self): self.source_widget.list.clear() dir_ = self.path_object.glob_project_element('ingest_source') if 'CLIENT' not in dir_: dir_.insert(0, 'CLIENT') self.source_widget.list.addItems(dir_) def on_source_selected(self): self.hide_tags() self.file_tree.hide() self.empty_state.show() self.source_widget.list.selectedItems()[-1].text() self.empty_state.setText( 'Drag Media Here \nto Create New Ingest Version') self.path_object.set_attr( ingest_source=self.source_widget.list.selectedItems()[-1].text()) self.load_import_events() def load_import_events(self, new=False): latest = '-001.000' self.ingest_widget.list.clear() events = glob.glob( '%s/%s' % (self.path_object.split_after('ingest_source'), '*')) if events: self.ingest_widget.empty_state.hide() self.ingest_widget.show() for e in events: self.ingest_widget.list.addItem(os.path.split(e)[-1]) latest = os.path.split(e)[-1] else: self.ingest_widget.empty_state.show() self.ingest_widget.empty_state.setText("No Ingests") pixmap = QtGui.QPixmap(icon_path('axeWarning24px.png')) icon = QtGui.QIcon(pixmap) self.ingest_widget.set_icon(icon) self.path_object.set_attr(version=latest) if not new: self.path_object = self.path_object.next_major_version() self.empty_state.setText('Drag Files Here to %s' % self.path_object.version) def on_ingest_selected(self): self.ingest_widget.empty_state.hide() self.hide_tags() self.clear_all() self.path_object.set_attr( version=self.ingest_widget.list.selectedItems()[-1].text()) # Load the Tree Widget self.load_data_frame() self.populate_tree() self.location_changed.emit(self.path_object) def populate_tree(self): self.file_tree.clear() if os.listdir(self.path_object.path_root): # self.empty_state.hide() self.version = self.path_object.version self.empty_state.setText('Drag Files To Add To Ingest %s' % self.version) self.file_tree.show() self.file_tree.directory = self.path_object.path_root self.file_tree.populate_from_data_frame( self.path_object, self.data_frame, CONFIG['definitions']['ingest_browser_header']) self.tags_title.show() return else: self.file_tree.hide() self.hide_tags() self.empty_state.show() def load_data_frame(self): dir_ = self.path_object.path_root print 'loading %s' % dir_ self.pandas_path = os.path.join(dir_, 'publish_data.csv') if os.path.exists(self.pandas_path): self.data_frame = pd.read_csv(self.pandas_path) else: data = [] data = self.append_data_children(data, dir_) self.data_frame = pd.DataFrame( data, columns=CONFIG['definitions']['ingest_browser_header']) self.save_data_frame() def append_data_children(self, data, directory, parent='self'): # regex = r"#{3,}.[aA-zZ]{2,} \d{3,}-\d{3,}$" files = lj_list_dir(directory, basename=True) if files: for filename in files: type_ = get_file_type(filename) split_frange = split_sequence_frange(filename) if split_frange: file_, frange = split_frange else: file_ = filename frange = ' ' print file_ print '\t', frange fullpath = os.path.join(os.path.abspath(directory), file_) data.append( (file_, fullpath, type_, frange, ' ', False, ' ', ' ', ' ', ' ', ' ', ' ', self.io_statuses[0], parent)) if type_ == 'folder': self.append_data_children(data, fullpath, file_) return data def save_data_frame(self): self.data_frame.to_csv(self.pandas_path, index=False) # can i set the value of the "Status" in the row? def edit_tags(self): files = self.current_selection tags = self.tags_line_edit.text() if tags: for f in files: row = self.data_frame.loc[self.data_frame['Filename'] == f[FILENAME]].index[0] self.data_frame.at[row, 'Tags'] = tags self.save_data_frame() def edit_data_frame(self): if self.current_selection[0][STATUS] == 'Published': return if self.seq_combo.currentText(): seq = str(self.seq_combo.currentText()) self.tags_title.setText( 'CGL:> Choose a %s Name or Type to Create a New One' % self.shot_label.text().title()) if self.shot_combo.currentText(): schema = CONFIG['project_management'][ self.project_management]['tasks'][self.schema] if self.scope_combo.currentText(): proj_man_tasks = schema['long_to_short'][ self.scope_combo.currentText()] else: return shot = str(self.shot_combo.currentText()) self.tags_title.setText( 'CGL:> Which Task will this be published to?') if self.task_combo.currentText(): try: task = proj_man_tasks[str( self.task_combo.currentText())] to_object = self.path_object.copy( scope=self.scope_combo.currentText(), seq=seq, shot=shot, task=task, context='render', version='000.000', user='******', resolution='high') status = '' for f in self.current_selection: row = self.data_frame.loc[ (self.data_frame['Filename'] == f[FILENAME]) & (self.data_frame['Parent'] == f[PARENT] )].index[0] status = self.data_frame.at[row, 'Status'] if status == 'Imported': status = 'Tagged' to_path = os.path.join(to_object.path_root, f[FILENAME]) if status == 'Published': self.tags_title.setText('CGL:> Published!') # self.tags_button.clicked.connect(lambda: self.go_to_location(to_path)) # self.tags_button.show() # self.publish_button.hide() else: self.tags_title.setText( 'CGL:> Tagged & Ready For Publish!') self.publish_button.setEnabled(True) self.data_frame.at[ row, 'Scope'] = self.scope_combo.currentText() self.data_frame.at[row, 'Seq'] = seq self.data_frame.at[row, 'Shot'] = shot self.data_frame.at[row, 'Task'] = task self.data_frame.at[row, 'Publish_Filepath'] = to_path self.data_frame.at[row, 'Status'] = status for each in self.file_tree.selectionModel( ).selectedRows(): self.file_tree.set_text(each, PUBLISH_FILEPATH, to_path) self.file_tree.set_text(each, STATUS, status) self.file_tree.set_text( each, SCOPE, self.scope_combo.currentText()) self.file_tree.set_text(each, SEQ, seq) self.file_tree.set_text(each, SHOT, shot) self.file_tree.set_text(each, TASK, task) self.save_data_frame() # how do i edit the text only on the selected item? except KeyError: print 'Error with something:' print 'scope', self.scope_combo.currentText() print 'seq', seq print 'shot', shot def go_to_location(self, to_path): path_object = PathObject(to_path).copy(context='source', user='', resolution='', filename='', ext='', filename_base='', version='') self.location_changed.emit(path_object) def clear_all(self): self.scope_combo.setCurrentIndex(0) self.seq_combo.clear() self.shot_combo.clear() self.task_combo.clear() self.tags_line_edit.clear() def show_tags_info(self, data): """ Shows all the information for the tags. :param data: :return: """ self.tags_line_edit.clear() filepath = data[-1][0].replace('/', '\\') if data[-1][1] == 'sequence': print 'found a sequence, doing different' # if this is a sequence do something different. row = self.data_frame.loc[self.data_frame['Filepath'] == filepath].index[0] tags = self.data_frame.loc[row, 'Tags'] if type(tags) != float: if tags: self.tags_line_edit.setText(tags) def set_combo_to_text(self, combo, text): index = combo.findText(text) if index != -1: combo.setCurrentIndex(index) else: combo.addItem(text) self.set_combo_to_text(combo, text) def show_combo_info(self, data): if data: f = data[0] try: row = self.data_frame.loc[ (self.data_frame['Filename'] == f[FILENAME]) & (self.data_frame['Parent'] == f[PARENT])].index[0] except IndexError: self.hide_tags() return scope = self.data_frame.loc[row, 'Scope'] seq = self.data_frame.loc[row, 'Seq'] shot = self.data_frame.loc[row, 'Shot'] task = self.data_frame.loc[row, 'Task'] if type(scope) != float: if scope: if scope != ' ': self.set_combo_to_text(self.scope_combo, scope) if type(seq) != float: if seq: if seq != ' ': try: seq = '%03d' % int(seq) self.set_combo_to_text(self.seq_combo, seq) except ValueError: self.set_combo_to_text(self.seq_combo, seq) if type(shot) != float: if shot: if shot != ' ': try: length = CONFIG['rules']['path_variables']['shot'][ 'length'] if length == 3: shot = '%03d' % int(shot) elif length == 4: shot = '%04d' % int(shot) elif length == 5: shot = '%05d' % int(shot) self.set_combo_to_text(self.shot_combo, shot) except ValueError: self.set_combo_to_text(self.shot_combo, shot) if type(task) != float: if task: if task != ' ': task = self.schema_dict['short_to_long'][ self.scope_combo.currentText()][task] # task = self.proj_man_tasks_short_to_long[task] self.set_combo_to_text(self.task_combo, task) def hide_tags(self): self.tags_title.setText("<b>Select File(s) or Folder(s) to tag</b>") self.tags_title.hide() self.scope_label.hide() self.scope_combo.hide() self.seq_label.hide() self.seq_combo.hide() self.shot_label.hide() self.shot_combo.hide() self.task_label.hide() self.task_combo.hide() self.tags_label.hide() self.tags_line_edit.hide() self.publish_button.hide() def show_tags_gui(self): self.tags_title.show() self.scope_combo.show() self.scope_label.show() self.seq_label.show() self.seq_combo.show() self.shot_label.show() self.shot_combo.show() self.task_label.show() self.task_combo.show() self.tags_label.show() self.tags_line_edit.show() self.publish_button.show() def populate_tasks(self): self.task_combo.clear() ignore = ['default_steps', ''] schema = CONFIG['project_management'][ self.project_management]['tasks'][self.schema] tasks = schema['long_to_short'][self.scope_combo.currentText()] self.populate_seq() task_names = [''] for each in tasks: if each not in ignore: task_names.append(each) self.task_combo.addItems(sorted(task_names)) def populate_seq(self): self.seq_combo.clear() self.seq_combo.lineEdit().setPlaceholderText('Type, or Choose') seqs = [''] if self.scope_combo.currentText() == 'shots': element = 'seq' else: element = 'type' if self.scope_combo.currentText() == 'shots': seqs = self.path_object.copy( seq='*', scope=self.scope_combo.currentText()).glob_project_element( element) elif self.scope_combo.currentText() == 'assets': seqs = CONFIG['asset_category_long_list'] if not seqs: seqs = [''] self.seq_combo.addItems(seqs) return seqs def on_scope_changed(self): # see if we can set scope based off the data_frame if self.scope_combo.currentText(): if self.scope_combo.currentText() == 'assets': self.seq_label.setText('Type') self.shot_label.setText('Asset') elif self.scope_combo.currentText() == 'shots': self.seq_label.setText('Sequence') self.shot_label.setText('Shot') self.tags_title.setText( "<b>CGL:></b> Type to Create a %s or Choose it from the list" % (self.seq_label.text())) self.populate_seq() self.populate_tasks() def on_seq_changed(self): shots = None self.shot_combo.clear() scope = self.scope_combo.currentText() seq = self.seq_combo.currentText() if seq: _ = self.path_object.copy(scope=scope, seq=seq, shot='*') if self.scope_combo.currentText() == 'shots': shots = self.path_object.copy( scope=scope, seq=seq, shot='*').glob_project_element('shot') elif self.scope_combo.currentText() == 'assets': shots = self.path_object.copy( scope=scope, seq=seq, shot='*').glob_project_element('asset') if shots: shots.insert(0, '') self.shot_combo.addItems(shots) def on_file_selected(self, data): self.tags_title.setText( "<b>CGL:></b> Choose 'Assets' or 'Shots' for your scope") print 'file selected, showing gui' self.show_tags_gui() self.current_selection = data self.scope_combo.setCurrentIndex(0) self.seq_combo.clear() self.shot_combo.clear() self.task_combo.clear() self.tags_line_edit.clear() self.sender().parent().show_combo_info(data) if not self.task_combo.currentText(): self.publish_button.setEnabled(False) else: self.publish_button.setEnabled(True) if self.current_selection[0][STATUS] == "Published": self.view_in_lumbermill.show() self.hide_tags() self.publish_button.setEnabled(False) else: self.view_in_lumbermill.hide() self.show_tags_gui() self.publish_button.setEnabled(True) # self.sender().parent().show_tags_gui(files=files) # self.sender().parent().show_tags_info(data) def on_view_in_lumbermill_clicked(self): path_object = PathObject( self.current_selection[0][PUBLISH_FILEPATH]).copy(context='source', user='', resolution='', filename='', ext='', filename_base='', version='') self.location_changed.emit(path_object) def on_add_ingest_event(self): # deselect everything in the event # change the file path to reflect no selection self.path_object = self.path_object.next_major_version() self.empty_state.setText('Drag Media Here to %s' % self.path_object.version) self.hide_tags() self.file_tree.hide() self.empty_state.show() def publish_selected_asset(self): task = self.schema_dict['long_to_short'][ self.scope_combo.currentText()][self.task_combo.currentText()] # TODO - would be nice to figure out a more elegant way of doing this. Perhaps handle the exception # within the Preflight itself? try: dialog = Preflight( self, software='ingest', preflight=task, data_frame=self.data_frame, file_tree=self.file_tree, pandas_path=self.pandas_path, current_selection=self.current_selection, selected_rows=self.file_tree.selectionModel().selectedRows(), ingest_browser_header=CONFIG['definitions'] ['ingest_browser_header']) except KeyError: dialog = Preflight( self, software='ingest', preflight='default', data_frame=self.data_frame, file_tree=self.file_tree, pandas_path=self.pandas_path, current_selection=self.current_selection, selected_rows=self.file_tree.selectionModel().selectedRows(), ingest_browser_header=CONFIG['definitions'] ['ingest_browser_header']) dialog.show() # noinspection PyListCreation @staticmethod def make_source_file(to_path, row): source_path = PathObject(to_path) source_path.set_attr(context='source') source_path.set_attr(filename='system_report.csv') dir_ = os.path.dirname(source_path.path_root) if not os.path.exists(dir_): os.makedirs(dir_) data = [] data.append( (row["Filepath"], row["Filename"], row["Filetype"], row["Frame_Range"], row["Tags"], row["Keep_Client_Naming"], row["Scope"], row["Seq"], row["Shot"], row["Task"], row["Publish_Filepath"], row["Publish_Date"], row["Status"])) df = pd.DataFrame( data, columns=CONFIG['definitions']['ingest_browser_header']) df.to_csv(source_path.path_root, index=False) def clear_layout(self, layout=None): clear_layout(self, layout) def sizeHint(self): return QtCore.QSize(self.height_hint, self.width_hint)
def __init__(self, parent=None, path_object=None): QtWidgets.QFrame.__init__(self, parent) if path_object: self.path_object = path_object else: return self.setProperty('class', 'light_grey') self.my_tasks_button = QtWidgets.QPushButton() self.my_tasks_button.setToolTip('My Tasks') tasks_icon = os.path.join(cglpath.icon_path(), 'star24px.png') self.my_tasks_button.setProperty('class', 'grey_border') self.my_tasks_button.setIcon(QtGui.QIcon(tasks_icon)) self.my_tasks_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.refresh_button = QtWidgets.QPushButton() self.refresh_button.setToolTip('Refresh') refresh_icon = os.path.join(cglpath.icon_path(), 'spinner11.png') self.refresh_button.setProperty('class', 'grey_border') self.refresh_button.setIcon(QtGui.QIcon(refresh_icon)) self.refresh_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.ingest_button = QtWidgets.QPushButton() self.ingest_button.setToolTip('My Tasks') self.ingest_button.setProperty('class', 'grey_border') ingest_icon = os.path.join(cglpath.icon_path(), 'ingest24px.png') self.ingest_button.setIcon(QtGui.QIcon(ingest_icon)) self.ingest_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.back_button = QtWidgets.QPushButton() self.back_button.setToolTip('Go back') self.projects_button = QtWidgets.QPushButton() self.projects_button.setToolTip('Go to Projects') self.companies_button = QtWidgets.QPushButton() self.companies_button.setToolTip('Go to Companies') self.my_tasks_button.setProperty('class', 'grey_border') self.back_button.setStyleSheet("background: transparent;") self.projects_button.setStyleSheet("background: transparent;") self.companies_button.setStyleSheet("background: transparent;") back_icon = os.path.join(cglpath.icon_path(), 'back24px.png') home_icon = os.path.join(cglpath.icon_path(), 'project24px.png') company_icon = os.path.join(cglpath.icon_path(), 'company24px.png') self.back_button.setIcon(QtGui.QIcon(back_icon)) self.back_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.companies_button.setIcon(QtGui.QIcon(company_icon)) self.companies_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.projects_button.setIcon(QtGui.QIcon(home_icon)) self.projects_button.setIconSize(QtCore.QSize(ICON_WIDTH, ICON_WIDTH)) self.current_location_line_edit = QtWidgets.QLineEdit() self.current_location_line_edit.setReadOnly(True) self.current_location_line_edit.setMinimumHeight(ICON_WIDTH * 1.28) self.current_location_line_edit.hide() self.search_box = LJSearchEdit(self) layout = QtWidgets.QVBoxLayout(self) self.cl_row = QtWidgets.QHBoxLayout() self.cl_row.addWidget(self.back_button) self.cl_row.addWidget(self.companies_button) self.cl_row.addWidget(self.projects_button) self.cl_row.addWidget(self.my_tasks_button) self.cl_row.addWidget(self.refresh_button) self.cl_row.addWidget(self.search_box) self.cl_row.addWidget(self.ingest_button) layout.addLayout(self.cl_row) layout.addWidget(self.current_location_line_edit) self.my_tasks_button.clicked.connect(self.my_tasks_pressed) self.ingest_button.clicked.connect(self.ingest_clicked) self.refresh_button.clicked.connect(self.refresh_clicked) self.back_button.clicked.connect(self.back_button_pressed) self.companies_button.clicked.connect(self.buttons_pressed) self.projects_button.clicked.connect(self.buttons_pressed) self.set_text(self.path_object.path_root)
class PathItemWidget(QtWidgets.QWidget): line_edit_changed = QtCore.Signal(object) root_set = QtCore.Signal() def __init__(self, parent=None, paths_dict=None, hide_on_find=False): QtWidgets.QWidget.__init__(self, parent) self.layout = QtWidgets.QVBoxLayout(self) self.globals_layout = QtWidgets.QGridLayout() self.paths_layout = QtWidgets.QGridLayout() self.vfx_paths_layout = QtWidgets.QGridLayout() self.user_dir = os.path.expanduser("~") self.user_name = self.get_user_name() self.cgl_dir = self.get_default_cgl_dir() self.user_globals_path = self.get_user_config(self.cgl_dir) self.globals_label = QtWidgets.QLabel('Globals Locations') self.globals_label.setProperty('class', 'ultra_title') self.paths_label = QtWidgets.QLabel('CGL Tool Paths') self.paths_label.setProperty('class', 'ultra_title') self.paths_label.hide() self.vfx_label = QtWidgets.QLabel('VFX Paths') self.vfx_label.setProperty('class', 'ultra_title') self.vfx_label.hide() # self.red_palette, self.green_palette, self.black_palette = define_palettes() self.cgl_tools_folder = None self.widget_dict = {} # Add User Globals, Root and The "Paths" label to the first slots. i = 0 i = self.add_path_line(self.globals_layout, 'root', paths_dict, i, hide_on_find) self.add_path_line(self.globals_layout, 'user_globals', paths_dict, i, hide_on_find) self.layout.addWidget(self.paths_label) self.layout.addLayout(self.globals_layout) self.layout.addWidget(self.paths_label) self.layout.addLayout(self.paths_layout) self.layout.addWidget(self.vfx_label) self.layout.addLayout(self.vfx_paths_layout) default_paths = [ 'cgl_tools', 'code_root', 'dev_pkg', 'ffmpeg', 'ffplay', 'ffprobe', 'magick', 'wget', 'globals' ] vfx_paths = ['ari_convert', 'maketx', 'mayapy', 'nuke'] prow = 0 vrow = 0 for key in paths_dict: if key in default_paths: prow += 2 self.add_path_line(self.paths_layout, key, paths_dict, prow, hide_on_find) elif key in vfx_paths: vrow += 2 self.add_path_line(self.vfx_paths_layout, key, paths_dict, vrow, hide_on_find) def add_path_line(self, layout_, key, paths_dict, row, hide_on_find): """ :param layout_: :param key: :param paths_dict: :param row: :param hide_on_find: :return: """ label = QtWidgets.QLabel(key) line_edit = QtWidgets.QLineEdit() line_edit.setText(paths_dict[key]) if key == 'root': line_edit.editingFinished.connect(self.on_root_set) folder_button = QtWidgets.QToolButton() if key == 'cgl_tools': self.cgl_tools_folder = folder_button folder_button.setIcon(QtGui.QIcon(self.icon_path('folder24px.png'))) folder_button.line_edit = line_edit folder_button.label = label message = QtWidgets.QLabel('Path Not Found, Please Specify %s' % key) # message.setPalette(self.red_palette) folder_button.message = message self.widget_dict[key] = { 'label': label, 'line_edit': line_edit, 'message': message } layout_.addWidget(label, row, 0) layout_.addWidget(line_edit, row, 1) layout_.addWidget(folder_button, row, 2) layout_.addWidget(message, row + 1, 1) folder_button.clicked.connect(self.on_path_chosen) self.check_path(key, label, line_edit, message, folder_button, hide_on_find=hide_on_find) line_edit.textChanged.connect(lambda: self.on_line_edit_changed(key)) return row + 2 def on_root_set(self): self.root_set.emit() @staticmethod def icon_path(filename): this = __file__.split('cglumberjack')[0] return os.path.join(this, 'cglumberjack', 'resources', 'icons', filename) def on_line_edit_changed(self, key): self.line_edit_changed.emit({key: self.sender()}) def check_path(self, path_name, label, line_edit, message, folder_button, hide_on_find): path_ = line_edit.text() if os.path.exists(path_): line_edit.setEnabled(False) message.setText('%s Found Path, Ready for Ass Kicking!' % path_name) # message.setPalette(self.black_palette) self.hide_line(label, line_edit, message, folder_button, hide_on_find) else: if path_name == 'cgl_tools': line_edit.setEnabled(False) message.setText('%s Path Not Found, set "root"!' % path_name) self.hide_line(label, line_edit, message, folder_button, hide_on_find) elif path_name == 'code_root': code_root = __file__.split('cglumberjack')[0] code_root = '%s/cglumberjack' % code_root line_edit.setEnabled(False) line_edit.setText(code_root) message.setText('%s Path Found, Ready for Ass Kicking!' % path_name) # message.setPalette(self.black_palette) self.hide_line(label, line_edit, message, folder_button, hide_on_find) elif path_name == 'user_globals': line_edit.setText(self.user_globals_path) line_edit.setEnabled(False) message.setText( 'Setting As Default Location, Click Folder Button to Change' ) # message.setPalette(self.black_palette) elif path_name == 'globals': line_edit.setEnabled(False) message.setText('%s Path Not Found, set "root"!' % path_name) self.hide_line(label, line_edit, message, folder_button, hide_on_find, force_hide=False) @staticmethod def hide_line(label, line_edit, message, folder_button, hide_on_find, force_hide=False): if hide_on_find or force_hide: label.hide() line_edit.hide() message.hide() folder_button.hide() def on_path_chosen(self): folder = QtWidgets.QFileDialog.getExistingDirectory() self.sender().line_edit.setText(folder) self.check_path(folder, self.sender().label, self.sender().line_edit, self.sender().message, self.sender(), hide_on_find=True) if self.sender().label.text() == 'root': self.cgl_tools_folder.line_edit.setText( os.path.join(folder, '_config', 'cgl_tools')) self.cgl_tools_folder.message.setText( '%s Path Found, Ready for Ass Kicking!' % 'cgl_tools') # self.cgl_tools_folder.message.setPalette(self.black_palette) self.widget_dict['globals']['line_edit'].setText( os.path.join(folder, '_config', 'globals.json')) self.widget_dict['globals']['message'].setText( '%s Path Found, Ready for Ass Kicking!' % 'globals') # self.widget_dict['globals']['message'].setPalette(self.black_palette) @staticmethod def get_user_name(): """ find the currently logged in user Returns: str: username """ return getpass.getuser() def get_default_cgl_dir(self): if 'Documents' in self.user_dir: cg_lumberjack_dir = os.path.join(self.user_dir, 'cglumberjack') else: cg_lumberjack_dir = os.path.join(self.user_dir, 'Documents', 'cglumberjack') return cg_lumberjack_dir @staticmethod def get_user_config(cgl_dir): return os.path.join(cgl_dir, 'user_globals.json')
def set_screen_area(self): desktop = QtWidgets.QApplication.instance().desktop() total_desktop = QtCore.QRect() for r in range(desktop.screenCount()): total_desktop = total_desktop.united(desktop.screenGeometry(r)) self.setGeometry(total_desktop)