コード例 #1
0
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)
コード例 #2
0
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)
コード例 #3
0
    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())
コード例 #4
0
ファイル: panels.py プロジェクト: Eric-coder/cglumberjack
 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)
コード例 #5
0
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())
コード例 #6
0
ファイル: utils.py プロジェクト: Eric-coder/cglumberjack
    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()
コード例 #7
0
ファイル: panels.py プロジェクト: Eric-coder/cglumberjack
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)
コード例 #8
0
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()
コード例 #9
0
    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)
コード例 #10
0
ファイル: utils.py プロジェクト: Eric-coder/cglumberjack
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())
コード例 #11
0
ファイル: utils.py プロジェクト: Eric-coder/cglumberjack
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)
コード例 #12
0
ファイル: FilesPanel.py プロジェクト: Eric-coder/cglumberjack
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_
コード例 #13
0
 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
コード例 #14
0
 def sizeHint(self):
     return QtCore.QSize(self.height_hint, self.width_hint)
コード例 #15
0
ファイル: panels.py プロジェクト: Eric-coder/cglumberjack
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)
コード例 #16
0
ファイル: panels.py プロジェクト: Eric-coder/cglumberjack
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)
コード例 #17
0
ファイル: panels.py プロジェクト: Eric-coder/cglumberjack
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)
コード例 #18
0
ファイル: panels.py プロジェクト: Eric-coder/cglumberjack
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)
コード例 #19
0
ファイル: main.py プロジェクト: Eric-coder/cglumberjack
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
コード例 #20
0
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)
コード例 #21
0
ファイル: main.py プロジェクト: Eric-coder/cglumberjack
    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)
コード例 #22
0
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')
コード例 #23
0
 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)