Source code for bgdev.tools.renamer.ui

"""Main UI for the renamer.

:created: 06/04/2016
:author: Benoit Gielly <benoit.gielly@gmail.com>
"""
from functools import partial

from PySide2 import QtCore, QtWidgets

from .utils import check_image


[docs]def maya_window(): """Return the MayaWindow if in Maya else None.""" for each in QtWidgets.QApplication.topLevelWidgets(): if each.objectName() == "MayaWindow": return each return None
class GroupBox(QtWidgets.QGroupBox): """Create a custom groupBox.""" def __init__(self, title, visible=True, color=None, height=None): super(GroupBox, self).__init__() self.default_visibility = visible self.header_color = color or "palette(light)" self.header_height = height or 24 # set properties self.setStyleSheet(self.css) self.setCheckable(True) self.setTitle(title) self.setStyle(QtWidgets.QStyleFactory.create("Fusion")) self.setFlat(True) # add a layout main_layout = QtWidgets.QVBoxLayout(self) top = self.header_height main_layout.setContentsMargins(0, top if top > 0 else 1, 0, 0) main_layout.setSpacing(0) # create content widget self.widget = QtWidgets.QFrame(self) main_layout.addWidget(self.widget) self.layout = QtWidgets.QVBoxLayout(self.widget) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(1) # set signal and visibility self.setChecked(self.default_visibility) self.setFocusPolicy(QtCore.Qt.NoFocus) def set_style(self, shape, shadow): """Set the children frame style. Args: shape (str): Any property belonging to QtWidgets.QFrame.Shape shadow (str): Any property belonging to QtWidgets.QFrame.Shadow """ shape = getattr(self.widget, shape, None) if shape: self.widget.setFrameShape(shape) shadow = getattr(self.widget, shadow, None) if shadow: self.widget.setFrameShadow(shadow) @property def css(self): """Create the styleSheet for the groupBox.""" css = """ GroupBox { font: bold; border: none; } GroupBox::title { padding-right: 10000; background-color: %s; } GroupBox::indicator { width: %s; height: %s; } GroupBox::indicator:checked { image: url(%s); } GroupBox::indicator:unchecked { image: url(%s); } """ css = css % ( self.header_color, self.header_height, self.header_height, check_image("../arrow_down.png", normalized=True), check_image("../arrow_right.png", normalized=True), ) return css def setChecked(self, checked): # pylint: disable=invalid-name """Add the widget visibility toggle to the setChecked method.""" super(GroupBox, self).setChecked(checked) self.widget.setVisible(checked) def mouseReleaseEvent(self, event): # pylint: disable=invalid-name """Trigger the setChecked method when mouse is released.""" pos_y = event.pos().y() if pos_y < self.header_height: self.setChecked(1 - self.isChecked()) self.shift_expand() def shift_expand(self): """Expand all siblings when shift is pressed. Note: Pressing "Ctrl" will reset the visibility to default. """ modifier = QtWidgets.QApplication.queryKeyboardModifiers() if modifier != QtCore.Qt.ShiftModifier: return siblings = [] for each in self.parent().children() or []: if isinstance(each, GroupBox): siblings.append(each) visibility = self.isChecked() index = siblings.index(self) or 0 for each in siblings[index::]: each.setChecked(visibility) class RenamerUi(QtWidgets.QDialog): """Main UI for the renamer.""" def __init__(self, *args, **kwargs): parent = kwargs.pop("parent", None) or maya_window() super(RenamerUi, self).__init__(parent=parent, *args, **kwargs) # get icons self.icons = {} for each in ["rename", "add", "remove", "replace"]: name = "../{0}.png".format(each) self.icons[each] = check_image(name, as_icon=True) # set properties self.setWindowTitle("Renamer") self.setStyleSheet(self.css) self.setup_ui() @property def css(self): """Return the CSS string.""" return """ QWidget, Qlabel { font: 9pt utopia; color: rgb(220,220,220) } QLineEdit { font: 10pt helvetica; background-color: None } """ def keyPressEvent(self, event): # pylint: disable=invalid-name """Override the keyPressedEvent to avoid Maya taking focus out.""" pass def hash_rename(self, text=None, start=None, letters=None): """Override this method in the main class.""" pass def search_replace(self, search=None, replace=None, hierarchy=None): """Override this method in the main class.""" pass def prefix_suffix(self, prefix=None, suffix=None, mode=None): """Override this method in the main class.""" pass def setup_ui(self): # pylint: disable=too-many-statements, too-many-locals """Create widgets.""" main_layout = QtWidgets.QVBoxLayout(self) main_layout.setSpacing(2) main_layout.setContentsMargins(2, 2, 2, 2) # --- HASH RENAME hash_box = GroupBox("Hash rename", color="None") hash_row1 = QtWidgets.QHBoxLayout() hash_row1.setSpacing(5) hash_row1.setContentsMargins(2, 2, 2, 2) hash_box.layout.addLayout(hash_row1) self.hash_text = QtWidgets.QLineEdit(hash_box) tip = 'Use hashes ("##") for padding' self.hash_text.setToolTip(tip) self.hash_text.setStatusTip(tip) self.hash_text.setPlaceholderText(" L name ## suffix") self.hash_text.returnPressed.connect(self.hash_rename) hash_start_label = QtWidgets.QLabel(hash_box) tip = "Choose the start index" hash_start_label.setToolTip(tip) hash_start_label.setStatusTip(tip) hash_start_label.setText("Start :") self.hash_spinbox = QtWidgets.QSpinBox(hash_box) self.hash_spinbox.setMinimum(1) tip = "Choose the start index" self.hash_spinbox.setToolTip(tip) self.hash_spinbox.setStatusTip(tip) hash_row1.addWidget(self.hash_text) hash_row1.addWidget(hash_start_label) hash_row1.addWidget(self.hash_spinbox) hash_row1.setStretch(0, 1) hash_row2 = QtWidgets.QHBoxLayout() hash_row2.setSpacing(0) hash_row2.setContentsMargins(2, 2, 2, 2) hash_box.layout.addLayout(hash_row2) self.hash_number_radio = QtWidgets.QRadioButton(hash_box) self.hash_number_radio.setChecked(True) tip = 'Replace hashes ("##") with numbers' self.hash_number_radio.setToolTip(tip) self.hash_number_radio.setStatusTip(tip) self.hash_number_radio.setText("Numbers") self.hash_letters_radio = QtWidgets.QRadioButton(hash_box) tip = 'Replace hashes ("##") with letters' self.hash_letters_radio.setToolTip(tip) self.hash_letters_radio.setStatusTip(tip) self.hash_letters_radio.setText("Letters") hash_rename_btn = QtWidgets.QPushButton(hash_box) hash_rename_btn.setMaximumWidth(30) hash_rename_btn.setMinimumHeight(26) hash_rename_btn.setIcon(self.icons["rename"]) hash_rename_btn.setToolTip("Execute hash renamer") hash_rename_btn.setStatusTip("Execute hash renamer") hash_rename_btn.clicked.connect(self.hash_rename) hash_row2.addWidget(self.hash_number_radio) hash_row2.addWidget(self.hash_letters_radio) hash_row2.addWidget(hash_rename_btn) main_layout.addWidget(hash_box) # SEARCH AND REPLACE --- snr_box = GroupBox("Search and replace", color="None") self.search_text = QtWidgets.QLineEdit(snr_box) tip = "Type in string to search" self.search_text.setToolTip(tip) self.search_text.setStatusTip(tip) self.search_text.setPlaceholderText(" Search") self.search_text.returnPressed.connect(self.search_replace) self.replace_text = QtWidgets.QLineEdit(snr_box) tip = "Type in string to replace with" self.replace_text.setStatusTip(tip) self.replace_text.setWhatsThis(tip) self.replace_text.setPlaceholderText(" Replace") self.replace_text.returnPressed.connect(self.search_replace) snr_box.layout.addWidget(self.search_text) snr_box.layout.addWidget(self.replace_text) snr_row = QtWidgets.QHBoxLayout() snr_row.setSpacing(0) snr_row.setContentsMargins(2, 2, 2, 2) snr_box.layout.addLayout(snr_row) self.select_radio = QtWidgets.QRadioButton(snr_box) self.select_radio.setChecked(True) tip = "Affects the current selection" self.select_radio.setToolTip(tip) self.select_radio.setStatusTip(tip) self.select_radio.setText("Select") self.hierarchy_radio = QtWidgets.QRadioButton(snr_box) tip = "Affects the whole hierarchy under selection" self.hierarchy_radio.setToolTip(tip) self.hierarchy_radio.setStatusTip(tip) self.hierarchy_radio.setText("Hierarchy") snr_rename_btn = QtWidgets.QPushButton(snr_box) snr_rename_btn.setMaximumWidth(30) snr_rename_btn.setMinimumHeight(26) snr_rename_btn.setIcon(self.icons["rename"]) tip = "Execute search & replace" snr_rename_btn.setToolTip(tip) snr_rename_btn.setStatusTip(tip) snr_rename_btn.clicked.connect(self.search_replace) snr_row.addWidget(self.select_radio) snr_row.addWidget(self.hierarchy_radio) snr_row.addWidget(snr_rename_btn) main_layout.addWidget(snr_box) # PREFIX AND SUFFIX --- pns_box = GroupBox("Prefix and suffix", color="None") prefix_row = QtWidgets.QHBoxLayout() prefix_row.setSpacing(0) prefix_row.setContentsMargins(2, 2, 2, 2) pns_box.layout.addLayout(prefix_row) self.prefix_text = QtWidgets.QLineEdit(pns_box) self.prefix_text.setStatusTip("Type prefix here") self.prefix_text.setWhatsThis("Type prefix here") self.prefix_text.setPlaceholderText(" Prefix") cmd = partial(self.prefix_suffix, prefix=True, mode="replace") self.prefix_text.returnPressed.connect(cmd) prefix_replace_btn = QtWidgets.QPushButton(pns_box) prefix_replace_btn.setMaximumWidth(30) prefix_replace_btn.setMinimumHeight(26) prefix_replace_btn.setIcon(self.icons["replace"]) tip = "Replace current prefix with given one" prefix_replace_btn.setToolTip(tip) prefix_replace_btn.setStatusTip(tip) cmd = partial(self.prefix_suffix, prefix=True, mode="replace") prefix_replace_btn.clicked.connect(cmd) prefix_add_btn = QtWidgets.QPushButton(pns_box) prefix_add_btn.setMaximumWidth(30) prefix_add_btn.setMinimumHeight(26) prefix_add_btn.setIcon(self.icons["add"]) tip = "Add given prefix" prefix_add_btn.setToolTip(tip) prefix_add_btn.setStatusTip(tip) cmd = partial(self.prefix_suffix, prefix=True, mode="add") prefix_add_btn.clicked.connect(cmd) prefix_remove_btn = QtWidgets.QPushButton(pns_box) prefix_remove_btn.setMaximumWidth(30) prefix_remove_btn.setMinimumHeight(26) prefix_remove_btn.setIcon(self.icons["remove"]) tip = "Remove current prefix" prefix_remove_btn.setToolTip(tip) prefix_remove_btn.setStatusTip(tip) cmd = partial(self.prefix_suffix, prefix=True, mode="remove") prefix_remove_btn.clicked.connect(cmd) prefix_row.addWidget(self.prefix_text) prefix_row.addWidget(prefix_replace_btn) prefix_row.addWidget(prefix_add_btn) prefix_row.addWidget(prefix_remove_btn) prefix_row.setStretch(0, 1) suffix_row = QtWidgets.QHBoxLayout() suffix_row.setSpacing(0) suffix_row.setContentsMargins(2, 2, 2, 2) pns_box.layout.addLayout(suffix_row) self.suffix_text = QtWidgets.QLineEdit(pns_box) tip = "Type suffix here" self.suffix_text.setStatusTip(tip) self.suffix_text.setWhatsThis(tip) self.suffix_text.setPlaceholderText(" Suffix") cmd = partial(self.prefix_suffix, suffix=True, mode="replace") self.suffix_text.returnPressed.connect(cmd) suffix_replace_btn = QtWidgets.QPushButton(pns_box) suffix_replace_btn.setMaximumWidth(30) suffix_replace_btn.setMinimumHeight(26) suffix_replace_btn.setIcon(self.icons["replace"]) tip = "Replace current suffix with given one" suffix_replace_btn.setToolTip(tip) suffix_replace_btn.setStatusTip(tip) cmd = partial(self.prefix_suffix, suffix=True, mode="replace") suffix_replace_btn.clicked.connect(cmd) suffix_add_btn = QtWidgets.QPushButton(pns_box) suffix_add_btn.setMaximumWidth(30) suffix_add_btn.setMinimumHeight(26) suffix_add_btn.setIcon(self.icons["add"]) tip = "Add given suffix" suffix_add_btn.setToolTip(tip) suffix_add_btn.setStatusTip(tip) cmd = partial(self.prefix_suffix, suffix=True, mode="add") suffix_add_btn.clicked.connect(cmd) suffix_remove_btn = QtWidgets.QPushButton(pns_box) suffix_remove_btn.setMaximumWidth(30) suffix_remove_btn.setMinimumHeight(26) suffix_remove_btn.setIcon(self.icons["remove"]) tip = "Remove current suffix" suffix_remove_btn.setToolTip(tip) suffix_remove_btn.setStatusTip(tip) cmd = partial(self.prefix_suffix, suffix=True, mode="remove") suffix_remove_btn.clicked.connect(cmd) suffix_row.addWidget(self.suffix_text) suffix_row.addWidget(suffix_replace_btn) suffix_row.addWidget(suffix_add_btn) suffix_row.addWidget(suffix_remove_btn) suffix_row.setStretch(0, 1) main_layout.addWidget(pns_box) main_layout.addStretch()