Source code for cgl.ui.widgets.dialog

import datetime
import logging
import re
from PySide6 import QtCore, QtGui, QtWidgets
from cgl.core.utils.read_write import zip_path
from cgl.ui.widgets.base import LJDialog
from cgl.ui.widgets.containers.menu import LJMenu
from cgl.ui.widgets.containers.model import ListItemModel
from cgl.ui.widgets.containers.table import LJTableWidget
from cgl.ui.widgets.widgets import AdvComboBox
from cgl.core.config.query import AlchemyConfigManager

CFG = AlchemyConfigManager()


[docs] class TimeTracker(LJDialog): def __init__( self, ): LJDialog.__init__(self) self.calendar_popup_window = None self.calendar_popup = None self.cfg = CFG # user = current_user() # user_info = {} self.timelogs = {} self.new_logs = [] self.edited_logs = [] self.task_dict = {} self.ftrack_projects = [] self.ftrack_tasks = [] self.setWindowTitle("Time Tracker") self.weekdays = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", ] self.today = datetime.datetime.today() self.day_name = self.weekdays[self.today.weekday()] self.date = self.today.date() self.total_hrs = 0 print(1) self.setup_ui() print(2) # self.setup_connections() # self.load_task_hours()
[docs] def setup_ui(self): # user_info = {} first = "Tom" last = "Mikota" email = "tom.m@premisestudio.com" calendar_icon_path = self.cfg.icon_path("calendar24px.png") layout = QtWidgets.QVBoxLayout() self.calendar_tool_button = QtWidgets.QToolButton() self.calendar_tool_button.setIcon(QtGui.QIcon(calendar_icon_path)) self.calendar_tool_button.setMinimumWidth(24) self.calendar_tool_button.setMinimumHeight(24) self.calendar_tool_button.setProperty("class", "border") time_for_date_label = QtWidgets.QLabel("Time Card") time_for_date_label.setProperty("class", "ultra_title") label_user_name = QtWidgets.QLabel("%s %s" % (first, last)) label_user_login = QtWidgets.QLabel("(%s)" % email) label_user_login.setProperty("class", "large") label_user_name.setProperty("class", "ultra_title") self.label_time_recorded = QtWidgets.QLabel("<b>Time Recorded:</b>") self.label_time_recorded.setProperty("class", "large") self.total_time_label = QtWidgets.QLabel("Total Time Today:") self.total_time_label.setProperty("class", "large") button_submit_time_card = QtWidgets.QPushButton("Submit Time Card") button_submit_time_card.setProperty("class", "add_button") self.button_add_task = QtWidgets.QPushButton("Add Task") self.button_add_task.setProperty("class", "basic") project_label = QtWidgets.QLabel("Project") self.project_combo = AdvComboBox() task_label = QtWidgets.QLabel("Task") self.task_combo = AdvComboBox() self.calendar = QtWidgets.QCalendarWidget() self.task_table = QtWidgets.QTableWidget() self.task_table.setColumnCount(7) self.task_table.setColumnHidden(4, True) self.task_table.setHorizontalHeaderLabels( [ "Project", "Shot/Asset", "Task", "Hours", "Task ID", "Hours Worked", "Bid Hours", ] ) # header = self.task_table.horizontalHeader() # header.setResizeMode(0, QtWidgets.QHeaderView.ResizeToContents) # header.setResizeMode(1, QtWidgets.QHeaderView.Stretch) # header.setResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) # header.setResizeMode(3, QtWidgets.QHeaderView.Stretch) # header.setResizeMode(5, QtWidgets.QHeaderView.Stretch) # header.setResizeMode(6, QtWidgets.QHeaderView.Stretch) self.task_table.setMinimumHeight(250) self.task_table.setMinimumWidth(400) button_row = QtWidgets.QHBoxLayout() button_row.addWidget(project_label) button_row.addWidget(self.project_combo) button_row.addWidget(task_label) button_row.addWidget(self.task_combo) button_row.addWidget(self.button_add_task) submit_row = QtWidgets.QHBoxLayout() submit_row.addStretch(1) submit_row.addWidget(button_submit_time_card) user_row = QtWidgets.QHBoxLayout() user_row.addWidget(label_user_name) user_row.addWidget(label_user_login) user_row.addStretch(1) user_row.addWidget(time_for_date_label) time_row = QtWidgets.QHBoxLayout() time_row.addWidget(self.calendar_tool_button) time_row.addWidget(self.label_time_recorded) time_row.addWidget(self.total_time_label) time_row.addStretch(1) layout.addLayout(user_row) layout.addLayout(time_row) layout.addWidget(self.task_table) layout.addLayout(button_row) layout.addLayout(submit_row) self.setLayout(layout)
[docs] def setup_connections(self): self.project_combo.currentIndexChanged.connect(self.on_project_select) self.task_combo.currentIndexChanged.connect(self.on_task_changed) self.button_add_task.clicked.connect(self.add_task_clicked) # self.button_submit_time_card.clicked.connect(self.submit_button_clicked) self.calendar_tool_button.clicked.connect(self.open_calendar) self.task_table.itemChanged.connect(self.on_hours_changed) self.get_projects_from_ftrack() self.button_add_task.setEnabled(False)
# self.task_table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
[docs] def set_date(self, new_date): self.today = new_date self.load_task_hours()
[docs] def on_task_changed(self): """ Function to ensure add_task button only shows after a task has been selected :return: None """ if self.task_combo.currentText(): self.button_add_task.setEnabled(True)
[docs] def open_calendar(self): """ Function to open calendar gui when icon is clicked :return: None """ self.calendar_popup_window = LJDialog(self) self.calendar_popup_window.setWindowTitle("Select Date") self.calendar_popup = QtWidgets.QCalendarWidget(self.calendar_popup_window) self.calendar_popup.resize(300, 160) self.calendar_popup_window.resize(303, 170) self.calendar_popup.setGridVisible(True) self.calendar_popup_window.exec() self.today = datetime.datetime( self.calendar_popup.selectedDate().year(), self.calendar_popup.selectedDate().month(), self.calendar_popup.selectedDate().day(), ) self.load_task_hours()
[docs] def submit_button_clicked(self): import cgl.plugins.ftrack.util as ftrack_util """ Function to edit/create timelog when submit timecard button is clicked :return: None """ for row in range(0, self.task_table.rowCount()): timelog_id = self.task_table.item(row, 4).text() if timelog_id in self.edited_logs: import cgl.plugins.project_management.ftrack.util as ftrack_util duration = float(self.task_table.item(row, 3).text()) ftrack_util.edit_timelog(timelog_id, duration) elif timelog_id in self.new_logs: task_object = self.task_dict[timelog_id] duration = float(self.task_table.item(row, 3).text()) ftrack_util.create_timelog( task_object, duration, self.today.month, self.today.day, self.today.year, ) self.accept()
[docs] def on_project_select(self): """ Function to fill task combo box with the tasks of the selected project :return: None """ import cgl.plugins.project_management.ftrack.util as ftrack_util self.task_combo.clear() project_name = self.project_combo.currentText() tasks = ftrack_util.get_all_tasks(project_name) for task in tasks: self.task_dict[task["name"]] = task self.task_combo.addItem(task["name"])
[docs] def get_projects_from_ftrack(self): """ Function to collect list of project names and fill project combo box :return: """ import cgl.plugins.project_management.ftrack.util as ftrack_util self.project_combo.addItems(ftrack_util.get_all_projects()) self.project_combo.addItems("") num = self.project_combo.findText("") self.project_combo.setCurrentIndex(num)
[docs] def get_timelogs(self, month, date, year): """ Function to create list of tuples containing existing timelog information :return: List of tuples(project, asset, task, hours, task_name, hours worked, bid hours) of timelog info """ import cgl.plugins.project_management.ftrack.util as ftrack_util self.ftrack_tasks = [[]] daily_hours = 0 timelogs = ftrack_util.get_timelogs(month, date, year) for log in timelogs: row = [] project = log["context"]["parent"]["project"]["name"] asset = log["context"]["parent"]["name"] task = self.cfg.project_config["project_management"]["ftrack"]["tasks"][ "VFX" ]["long_to_short"]["shots"][log["context"]["type"]["name"]] hours = log["duration"] hours = hours / 60 / 60 bid = log["context"]["bid"] bid = bid / 60 / 60 total_hours = ftrack_util.get_total_time(log["context"]) daily_hours += hours row.append(project) row.append(asset) row.append(task) row.append(hours) row.append(log["id"]) row.append(total_hours) row.append(bid) self.timelogs[log["id"]] = log self.ftrack_tasks.append(row) self.total_time_label.setText("%s Logged hours" % str(daily_hours)) return self.ftrack_tasks
[docs] def add_task_clicked(self): """ Function to add new task to time card table when add_task button is clicked :return: None """ import cgl.plugins.project_management.ftrack.util as ftrack_util project = self.project_combo.currentText() task = self.task_combo.currentText() task_data = self.task_dict[task] asset = task_data["parent"]["name"] bid = task_data["bid"] bid = bid / 60 / 60 total_hours = ftrack_util.get_total_time(task_data) task_short_name = self.cfg.project_config["project_management"]["ftrack"][ "tasks" ]["VFX"]["long_to_short"]["shots"][task_data["type"]["name"]] pos = self.task_table.rowCount() self.task_table.insertRow(pos) self.task_table.setItem(pos, 0, QtWidgets.QTableWidgetItem(project)) self.task_table.setItem(pos, 1, QtWidgets.QTableWidgetItem(asset)) self.task_table.setItem(pos, 2, QtWidgets.QTableWidgetItem(task_short_name)) self.task_table.setItem(pos, 3, QtWidgets.QTableWidgetItem(0)) self.task_table.setItem(pos, 4, QtWidgets.QTableWidgetItem(task)) self.task_table.setItem(pos, 5, QtWidgets.QTableWidgetItem(str(total_hours))) self.task_table.setItem(pos, 6, QtWidgets.QTableWidgetItem(str(bid))) self.new_logs.append(task) # add the task to the array self.lock_table()
[docs] def lock_table(self): for r in range(self.task_table.rowCount()): for c in range(0, 7): if c == 3: pass else: self.task_table.item(r, c).setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
[docs] def on_hours_changed(self, item): """ Function to add timelog_id to edited_logs list whenever an existing log's hours are edited :param item: Box in table being edited :return: None """ row = item.row() try: timelog_id = self.task_table.item(row, 4).text() if timelog_id in self.timelogs.keys(): if timelog_id not in self.edited_logs: self.edited_logs.append(timelog_id) except AttributeError: pass
[docs] def load_task_hours(self): """ Function to load existing timelogs into gui whenever a date is selected or Time Tracker is first run :return: None """ # clear self.task_table self.day_name = self.weekdays[self.today.weekday()] self.task_table.clear() self.task_table.setHorizontalHeaderLabels( [ "Project", "Shot/Asset", "Task", "Hours", "Task ID", "Hours Worked", "Bid Hours", ] ) self.task_table.setRowCount(0) total = 0 tasks = self.get_timelogs(self.today.month, self.today.day, self.today.year) if len(tasks) == 1: pass else: for i, each in enumerate(tasks): if tasks[i]: row = self.task_table.rowCount() self.task_table.insertRow(row) self.task_table.setItem( row, 0, QtWidgets.QTableWidgetItem(tasks[i][0]) ) self.task_table.setItem( row, 1, QtWidgets.QTableWidgetItem(tasks[i][1]) ) self.task_table.setItem( row, 2, QtWidgets.QTableWidgetItem(tasks[i][2]) ) self.task_table.setItem( row, 3, QtWidgets.QTableWidgetItem(str(tasks[i][3])) ) self.task_table.setItem( row, 4, QtWidgets.QTableWidgetItem(tasks[i][4]) ) self.task_table.setItem( row, 5, QtWidgets.QTableWidgetItem(str(tasks[i][5])) ) self.task_table.setItem( row, 6, QtWidgets.QTableWidgetItem(str(tasks[i][6])) ) total = float(each[3]) + total label_text = "%s, %s %s:" % ( self.day_name, self.today.strftime("%B"), self.today.day, ) self.label_time_recorded.setText(label_text) self.edited_logs = [] self.lock_table()
[docs] class FileTableModel(ListItemModel):
[docs] def data(self, index, role): row = index.row() col = index.column() if role == QtCore.Qt.DisplayRole: return self.data_[row][col]
[docs] class ItemTable(LJTableWidget): delete_item_signal = QtCore.Signal() rename_item_signal = QtCore.Signal() show_in_folder_signal = QtCore.Signal() def __init__(self, parent, title): LJTableWidget.__init__(self, parent) self.item_right_click_menu = LJMenu(self) self.label = title self.clicked.connect(self.row_selected) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.item_right_click_menu.create_action( "Show in Folder", self.show_in_folder_signal ) self.customContextMenuRequested.connect(self.item_right_click)
[docs] def item_right_click(self, position): self.item_right_click_menu.exec(self.mapToGlobal(position))
[docs] class MagicList(LJDialog): """ Magic List is an incredibly useful dialog that allows you a lot of flexibility when creating custom "list" dialogs """ combo_changed_signal = QtCore.Signal() item_selected = QtCore.Signal(object) button_name = "" button_signal = QtCore.Signal(object) def __init__( self, parent=None, title="Dialog Title", list_items=None, buttons=None, message=None, combo_box=None, combo_label="Label", combo=False, button_functions=None, auto_close=True, on_selection=None, on_button_clicked=None, ): """ :param parent: Parent GUI :param title: Title of the Gui :param list_items: Items that will go into the table view :param buttons: List of buttons that will be created - up to 4 allowed :param combo_box: List of items to populate the combo_box :param combo_label: Label for the combo_box :param combo: If False combo_box is hidden, if True it is displayed :param button_functions: Allows for a list of static methods that correspond to the button list :param auto_close: Closes the dialog after button is pushed """ LJDialog.__init__(self, parent) if list_items is None: list_items = [] if buttons is None: buttons = [] if combo_box is None: combo_box = [] self.auto_close = auto_close self.selection = None self.setMinimumWidth(600) self.list_items = list_items self.button_functions = button_functions self.user_buttons = buttons self.combo_defaults = combo_box # self.root_path = paths()["root"] self.v_layout = QtWidgets.QVBoxLayout(self) self.combo_row = QtWidgets.QHBoxLayout(self) self.combo_label = QtWidgets.QLabel("<b>%s</b>" % combo_label) self.message = QtWidgets.QLabel("\n\n%s\n\n" % message) self.combo = AdvComboBox(self) self.combo_row.addWidget(self.combo_label) self.combo_row.addWidget(self.combo) if not combo: self.combo_label.hide() self.combo.hide() self.buttons = QtWidgets.QHBoxLayout(self) self.button1 = QtWidgets.QPushButton("Button1") self.button2 = QtWidgets.QPushButton("Button2") self.button3 = QtWidgets.QPushButton("Button3") self.button4 = QtWidgets.QPushButton("Button4") button_list = [self.button1, self.button2, self.button3, self.button4] for i in range(len(buttons)): button_list[i].setText(buttons[i]) self.buttons.addWidget(button_list[i]) self.data_table = LJTableWidget(self) self.data_table.set_item_model(FileTableModel([], [""])) self.data_table.selected.connect(self.on_selected) self.v_layout.addLayout(self.combo_row) self.v_layout.addWidget(self.data_table) if message: self.v_layout.addWidget(self.message) self.v_layout.addLayout(self.buttons) self.setLayout(self.v_layout) self.setWindowTitle(title) self.load_combo() self.load_items() self.combo.currentIndexChanged.connect(self.on_combo_changed) self.button1.clicked.connect(self.on_button_clicked) self.button2.clicked.connect(self.on_button_clicked) self.button3.clicked.connect(self.on_button_clicked) self.button4.clicked.connect(self.on_button_clicked) if on_button_clicked: self.button_signal.connect(on_button_clicked) if on_selection: self.item_selected.connect(on_selection)
[docs] def on_button_clicked(self): if self.button_functions: position = self.user_buttons.index(self.sender().text()) self.button_functions[position]() else: self.button_name = self.sender().text() data = [self.sender(), self.selection] self.button_signal.emit(data) self.accept()
[docs] def load_combo(self): if self.combo_defaults: self.combo.addItem("") for item in self.combo_defaults: self.combo.addItem(item)
[docs] def load_items(self): """ loads items, set up initially to handle a list only. :return: """ items = [] for each in self.list_items: items.append([each]) self.data_table.set_item_model(FileTableModel(items, [""]))
[docs] def on_combo_changed(self): self.combo_changed_signal.emit()
[docs] def on_selected(self, data): self.get_data_info(data) self.selection = data self.item_selected.emit(data)
[docs] @staticmethod def get_data_info(data): logging.info(data)
[docs] class FrameRange(LJDialog): cancel_signal = QtCore.Signal() button = True def __init__( self, parent=None, title="Frame Range", sframe=None, eframe=None, minframe=None, maxframe=None, camera=None, message="Animation Frame Range to Publish", both=False, ): """ Frame Range Dialog. :param parent: :param title: :param sframe: :param eframe: :param minframe: :param maxframe: :param camera: :param message: :param both: """ LJDialog.__init__(self, parent) layout = QtWidgets.QFormLayout() # hlayout = QtWidgets.QHBoxLayout() blayout = QtWidgets.QHBoxLayout() grid = QtWidgets.QGridLayout() self.message = QtWidgets.QLabel(message) self.sframe = sframe self.eframe = eframe self.minframe = minframe self.maxframe = maxframe logging.info("minframe {}".format(minframe)) logging.info("maxframe {}".format(maxframe)) self.both = both if camera: self.title = "%s for: %s" % (title, camera) else: self.title = title self.sframe_label = QtWidgets.QLabel("Header Frame In") self.eframe_label = QtWidgets.QLabel("Tail Frame Out") self.cut_in_label = QtWidgets.QLabel("Cut In") self.cut_out_label = QtWidgets.QLabel("Cut Out") self.cut_in_line_edit = QtWidgets.QLineEdit() self.cut_out_line_edit = QtWidgets.QLineEdit() self.sframe_line_edit = QtWidgets.QLineEdit() self.eframe_line_edit = QtWidgets.QLineEdit() if sframe: self.sframe_line_edit.setText(str(sframe)) if eframe: self.eframe_line_edit.setText(str(eframe)) if minframe: self.cut_in_line_edit.setText(str(minframe)) else: self.cut_in_line_edit.setText("0") if maxframe: self.cut_out_line_edit.setText(str(maxframe)) if both: grid.addWidget(self.sframe_line_edit, 1, 0) grid.addWidget(self.cut_in_line_edit, 1, 1) grid.addWidget(self.cut_out_line_edit, 1, 2) grid.addWidget(self.eframe_line_edit, 1, 3) grid.addWidget(self.sframe_label, 2, 0) grid.addWidget(self.cut_in_label, 2, 1) grid.addWidget(self.cut_out_label, 2, 2) grid.addWidget(self.eframe_label, 2, 3) else: grid.addWidget(self.sframe_line_edit, 1, 0) grid.addWidget(self.eframe_line_edit, 1, 1) grid.addWidget(self.sframe_label, 2, 0) grid.addWidget(self.eframe_label, 2, 1) self.button_cancel = QtWidgets.QPushButton("Cancel") self.button = QtWidgets.QPushButton("Confirm Frame Range") blayout.addWidget(self.button_cancel) blayout.addWidget(self.button) layout.addWidget(self.message) layout.addRow(grid) layout.addRow(blayout) self.setLayout(layout) self.setWindowTitle(self.title) self.button.clicked.connect(self.on_button_clicked) self.button_cancel.clicked.connect(self.cancel_clicked) self.cut_out_line_edit.textChanged.connect(self.line_edit_changed) self.sframe_line_edit.textChanged.connect(self.line_edit_changed) self.eframe_line_edit.textChanged.connect(self.line_edit_changed) self.cut_in_line_edit.textChanged.connect(self.line_edit_changed) self.button.setEnabled(False) self.line_edit_changed()
[docs] def line_edit_changed(self): if self.both: if ( self.cut_out_line_edit.text() and self.cut_in_line_edit.text() and self.sframe_line_edit.text() and self.eframe_line_edit.text() ): self.button.setEnabled(True) else: if self.sframe_line_edit.text() and self.eframe_line_edit.text(): self.button.setEnabled(True)
[docs] def cancel_clicked(self): self.button = False self.cancel_signal.emit() self.accept()
[docs] def on_button_clicked(self): self.button = True sframe = self.sframe_line_edit.text() eframe = self.eframe_line_edit.text() self.maxframe = self.cut_out_line_edit.text() self.minframe = self.cut_in_line_edit.text() if sframe: if eframe: self.eframe = eframe self.sframe = sframe self.accept() else: logging.info("No end frame defined") else: logging.info("No Start Frame Defined")
[docs] class CheckFailedDialog(LJDialog): def __init__( self, title="Check Failed", message="", force_top_level=True, parent=None ): super().__init__(None if force_top_level else parent) self.setWindowTitle(title) self.setModal(True) self.setMinimumWidth(520) self.setSizeGripEnabled(True) self.setObjectName("check_failed_dialog") # --- Frame appearance (matches InputDialog layout style) --- frame = QtWidgets.QFrame() frame.setProperty("surface", "1") layout = QtWidgets.QVBoxLayout(frame) layout.setContentsMargins(20, 20, 20, 20) layout.setSpacing(15) # --- Label / title area --- title_label = QtWidgets.QLabel(title) title_label.setProperty("role", "h2") # Alchemy style system layout.addWidget(title_label) # --- Message text area (selectable, scrollable) --- self.text_box = QtWidgets.QTextEdit() self.text_box.setReadOnly(True) self.text_box.setText(message) self.text_box.setMinimumHeight(200) self.text_box.setWordWrapMode(QtGui.QTextOption.WrapAtWordBoundaryOrAnywhere) layout.addWidget(self.text_box) # --- Buttons --- btn_row = QtWidgets.QHBoxLayout() btn_row.addStretch(1) ok = QtWidgets.QPushButton("OK") ok.setProperty("variant", "primary") ok.setFixedHeight(34) ok.clicked.connect(self.accept) btn_row.addWidget(ok) layout.addLayout(btn_row) root = QtWidgets.QVBoxLayout(self) root.setContentsMargins(0, 0, 0, 0) root.addWidget(frame)
[docs] class InputDialog(LJDialog): button_clicked = QtCore.Signal(object) def __init__( self, parent=None, title="Attention:", message="message", buttons=None, line_edit=False, line_edit_text=False, combo_box_items=None, combo_box2_items=None, regex=None, name_example=None, line_edit2=False, force_top_level=False, ): """ Meant to be a catch all dialog for handling just about anything. It can handle 3 buttons :param parent: :param message: """ if force_top_level: LJDialog.__init__(self, parent, force_top_level=True) else: LJDialog.__init__(self, parent) self.original_message = message if buttons is None: buttons = ["Cancel", "Ok", ""] layout = QtWidgets.QFormLayout() button_box = QtWidgets.QHBoxLayout() self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) self.name_example = name_example self.regex = regex self.values = "" self.button = "" self.input_text = "" self.message = QtWidgets.QLabel(message) self.combo_box = AdvComboBox(self) self.combo_box2 = AdvComboBox(self) self.line_edit = QtWidgets.QLineEdit() self.line_edit2 = QtWidgets.QLineEdit() self.line_edit2.hide() if line_edit_text: self.line_edit.setText(line_edit_text) layout.addRow(self.message) layout.addRow(self.combo_box) self.combo_box.hide() layout.addRow(self.combo_box2) self.combo_box2.hide() if combo_box_items: self.combo_box.addItems(combo_box_items) self.combo_box.show() if combo_box2_items: self.combo_box2.addItems(combo_box2_items) self.combo_box2.show() if line_edit: layout.addRow(self.line_edit) if line_edit2: layout.addRow(self.line_edit2) self.line_edit2.show() if buttons: i = len(buttons) while i < 3: buttons.append("") i += 1 self.btn1 = QtWidgets.QPushButton(buttons[0]) self.btn2 = QtWidgets.QPushButton(buttons[1]) self.btn3 = QtWidgets.QPushButton(buttons[2]) button_box.addItem( QtWidgets.QSpacerItem( 0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum ) ) button_box.addWidget(self.btn1) if buttons[1]: button_box.addWidget(self.btn2) if buttons[2]: button_box.addWidget(self.btn3) layout.addRow(button_box) self.setLayout(layout) self.setWindowTitle(title) self.btn1.clicked.connect(self.on_button_clicked) self.btn1.clicked.connect(self.close) self.btn2.clicked.connect(self.on_button_clicked) self.btn2.clicked.connect(self.close) self.btn3.clicked.connect(self.on_button_clicked) self.btn3.clicked.connect(self.close) if regex: self.line_edit.textChanged.connect(self.on_text_changed_regex) try: self.combo_box.textChanged.connect(self.on_text_changed_regex) except AttributeError: self.combo_box.editTextChanged.connect(self.on_text_changed_regex)
[docs] def on_button_clicked(self): self.button = self.sender().text() self.input_text = self.line_edit.text()
[docs] def on_text_changed_regex(self): message = "" text = "" if self.sender() == self.line_edit: text = self.line_edit.text() elif self.sender() == self.combo_box: text = self.combo_box.currentText() if re.match(self.regex, text): message = "%s\n%s Passes!" % (self.original_message, text) self.btn1.setEnabled(True) self.btn2.setEnabled(True) self.btn3.setEnabled(True) else: bad_name = "%s\n%s does not pass" % (self.original_message, text) message = "%s\n%s" % (bad_name, self.name_example) self.btn1.setEnabled(False) self.btn2.setEnabled(False) self.btn3.setEnabled(False) self.message.setText(message)
[docs] class PlaylistDialog(InputDialog): def __init__(self, parent=None, project_name=None): InputDialog.__init__( self, parent, title="Add To Playlist", message="Choose a day for review", combo_box_items=["Today", "Tomorrow"], ) self.day = "Today" self.project_name = project_name self.playlist_name = None self.playlist = {} self.on_day_chosen() self.combo_box.currentIndexChanged.connect(self.on_day_chosen)
[docs] def on_day_chosen(self): self.day = self.combo_box.currentText() if self.day == "Today": self.playlist_name = "%s_%s" % (self.project_name, datetime.date.today()) if self.day == "Tomorrow": tomorrow_date = datetime.date.today() + datetime.timedelta(days=1) self.playlist_name = "%s_%s" % (self.project_name, tomorrow_date)
[docs] class UploadGlobals(LJDialog): def __init__(self, parent=None, cfg=None, company=None, project=None): LJDialog.__init__(self, parent) cfg = CFG self.globals_root = cfg.globals_root self.master_globals_root = cfg.master_globals_root if not self.master_globals_root: self.master_globals_root = self.globals_root.replace(company, "master") self.master_globals_root = self.master_globals_root.replace( project, "master" ) self.setWindowTitle("Update Studio Globals") layout = QtWidgets.QVBoxLayout(self) upload_existing_radio = QtWidgets.QRadioButton() message = QtWidgets.QLabel("Which would you like to do?") message2 = QtWidgets.QLabel( "Studio Globals: {}".format(self.master_globals_root) ) message3 = QtWidgets.QLabel("Project Globals: {}".format(self.globals_root)) upload_existing_radio.setText("Studio Globals -> Cloud") update_radio = QtWidgets.QRadioButton() update_radio.setText("Current Globals -> Studio Globals") self.update = None button_row = QtWidgets.QHBoxLayout() self.button = QtWidgets.QPushButton("Update") button_row.addStretch(1) button_row.addWidget(self.button) layout.addWidget(message) layout.addWidget(upload_existing_radio) layout.addWidget(message2) layout.addWidget(update_radio) layout.addWidget(message3) layout.addLayout(button_row) update_radio.clicked.connect(self.on_radio_clicked) upload_existing_radio.clicked.connect(self.on_radio_clicked) self.button.clicked.connect(self.on_button_clicked)
[docs] def on_radio_clicked(self): logging.info(self.sender().text()) if "Cloud" in self.sender().text(): self.update = "studio" else: self.update = "current"
[docs] def on_button_clicked(self): if self.update == "studio": logging.info("Studio to Cloud") logging.info("zip {}".format(self.master_globals_root)) else: logging.info("Project to Studio to Cloud") logging.info("delete current master {}".format(self.master_globals_root)) logging.info( "copy {} to {}".format(self.globals_root, self.master_globals_root) ) zip_file = "{}.zip".format(self.globals_root) logging.info("zip {} to {}".format(self.globals_root, zip_file)) zip_path(self.globals_root, zip_file)
# TODO - as soon as i can grab the "aws company name" from the sync globals i'm good here. # upload_file(zip_file, bucket)
[docs] class ConfirmationDialog(QtWidgets.QDialog): def __init__(self, parent=None, title=None, message=None, image_path=None): super().__init__(parent) self.setWindowTitle(title) self.message = QtWidgets.QLabel(message) self.image_button = QtWidgets.QPushButton() self.image_button.setIcon(QtGui.QIcon(image_path)) self.button_box = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel ) self.button_box.accepted.connect(self.ok_clicked) self.button_box.rejected.connect(self.reject) layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.message) layout.addWidget(self.image_button) layout.addWidget(self.button_box) self.setLayout(layout) if not image_path: self.image_button.hide()
[docs] def ok_clicked(self): self.accept()
[docs] def reject(self): self.accept()
if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) # app = do_gui_init() mw = TimeTracker() mw.setWindowTitle("Time Tracker") mw.show() mw.raise_() # load_style_sheet() app.exec()