Remove general tab from talker tab and use base tab from settings window. Additional clean up.

This commit is contained in:
Mizaki 2023-02-19 23:33:22 +00:00
parent a24bd1c719
commit fefb3ce6cd
4 changed files with 101 additions and 101 deletions

View File

@ -187,7 +187,7 @@ class SettingsWindow(QtWidgets.QDialog):
self.rename_error: Exception | None = None
self.sources: dict = comictaggerlib.ui.talkeruigenerator.generate_source_option_tabs(
self.tTalkerTabs, self.config, self.talkers
self.tComicTalkers, self.config, self.talkers
)
self.connect_signals()
self.settings_to_form()
@ -456,21 +456,8 @@ class SettingsWindow(QtWidgets.QDialog):
self.config[0].rename_strict = self.cbxRenameStrict.isChecked()
self.config[0].rename_replacements = self.get_replacements()
# Read settings from sources tabs and generate self.config data
for tab in self.sources.items():
for name, widget in tab[1]["widgets"].items():
widget_value = None
if isinstance(widget, (QtWidgets.QSpinBox, QtWidgets.QDoubleSpinBox)):
widget_value = widget.value()
elif isinstance(widget, QtWidgets.QLineEdit):
widget_value = widget.text().strip()
elif isinstance(widget, QtWidgets.QCheckBox):
widget_value = widget.isChecked()
# The talker source dropdown
elif isinstance(widget, QtWidgets.QComboBox):
widget_value = widget.itemData(widget.currentIndex())
setattr(self.config[0], name, widget_value)
# Read settings from talker tabs
comictaggerlib.ui.talkeruigenerator.form_settings_to_config(self.sources, self.config)
self.update_talkers_config()

View File

@ -340,15 +340,7 @@
<attribute name="title">
<string>Comic Sources</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QTabWidget" name="tTalkerTabs">
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
</layout>
<layout class="QVBoxLayout" name="verticalLayout_4"/>
</widget>
<widget class="QWidget" name="tCBL">
<attribute name="title">

View File

@ -63,79 +63,72 @@ def api_url_btn_connect(
btn.clicked.connect(lambda: call_check_api_url(talker_id, sources_info, talkers))
def format_internal_name(int_name: str = "") -> str:
# Presume talker_<name>_<nm>: talker_comicvine_cv_widget_name
int_name_split = int_name.split("_")
del int_name_split[0:3]
def format_internal_name(dest_name: str) -> str:
int_name_split = dest_name.split("_")
del int_name_split[0:1]
int_name_split[0] = int_name_split[0].capitalize()
new_name = " ".join(int_name_split)
return new_name
def generate_checkbox(
option: settngs.Setting, layout: QtWidgets.QGridLayout
) -> tuple[QtWidgets.QGridLayout, QtWidgets.QCheckBox]:
# bool equals a checkbox (QCheckBox)
widget = QtWidgets.QCheckBox(format_internal_name(option.internal_name))
# Add tooltip text
def generate_checkbox(option: settngs.Setting, layout: QtWidgets.QGridLayout) -> QtWidgets.QCheckBox:
widget = QtWidgets.QCheckBox(format_internal_name(option.dest))
widget.setToolTip(option.help)
# Add widget and span all columns
layout.addWidget(widget, layout.rowCount() + 1, 0, 1, -1)
layout.addWidget(widget, layout.rowCount(), 0, 1, -1)
return layout, widget
return widget
def generate_spinbox(
option: settngs.Setting, value: int | float, layout: QtWidgets.QGridLayout
) -> tuple[QtWidgets.QGridLayout, QtWidgets.QSpinBox | QtWidgets.QDoubleSpinBox]:
if isinstance(value, int):
# int equals a spinbox (QSpinBox)
lbl = QtWidgets.QLabel(option.internal_name)
# Create a label
layout.addWidget(lbl, layout.rowCount() + 1, 0)
widget = QtWidgets.QSpinBox()
widget.setRange(0, 9999)
widget.setToolTip(option.help)
layout.addWidget(widget, layout.rowCount() - 1, 1, alignment=QtCore.Qt.AlignLeft)
def generate_spinbox(option: settngs.Setting, layout: QtWidgets.QGridLayout) -> QtWidgets.QSpinBox:
row = layout.rowCount()
lbl = QtWidgets.QLabel(format_internal_name(option.dest))
layout.addWidget(lbl, row, 0)
widget = QtWidgets.QSpinBox()
widget.setRange(0, 9999)
widget.setToolTip(option.help)
layout.addWidget(widget, row, 1, alignment=QtCore.Qt.AlignLeft)
if isinstance(value, float):
# float equals a spinbox (QDoubleSpinBox)
lbl = QtWidgets.QLabel(format_internal_name(option.internal_name))
# Create a label
layout.addWidget(lbl, layout.rowCount() + 1, 0)
widget = QtWidgets.QDoubleSpinBox()
widget.setRange(0, 9999.99)
widget.setToolTip(option.help)
layout.addWidget(widget, layout.rowCount() - 1, 1, alignment=QtCore.Qt.AlignLeft)
return widget
return layout, widget
def generate_doublespinbox(option: settngs.Setting, layout: QtWidgets.QGridLayout) -> QtWidgets.QDoubleSpinBox:
row = layout.rowCount()
lbl = QtWidgets.QLabel(format_internal_name(option.dest))
layout.addWidget(lbl, row, 0)
widget = QtWidgets.QDoubleSpinBox()
widget.setRange(0, 9999.99)
widget.setToolTip(option.help)
layout.addWidget(widget, row, 1, alignment=QtCore.Qt.AlignLeft)
return widget
def generate_textbox(
option: settngs.Setting, layout: QtWidgets.QGridLayout
) -> tuple[QtWidgets.QGridLayout, QtWidgets.QLineEdit, QtWidgets.QPushButton]:
) -> tuple[QtWidgets.QLineEdit, QtWidgets.QPushButton]:
btn = None
# str equals a text field (QLineEdit)
lbl = QtWidgets.QLabel(format_internal_name(option.internal_name))
# Create a label
layout.addWidget(lbl, layout.rowCount() + 1, 0)
row = layout.rowCount()
lbl = QtWidgets.QLabel(format_internal_name(option.dest))
layout.addWidget(lbl, row, 0)
widget = QtWidgets.QLineEdit()
widget.setObjectName(option.internal_name)
widget.setToolTip(option.help)
layout.addWidget(widget, layout.rowCount() - 1, 1)
layout.addWidget(widget, row, 1)
# Special case for api_key, make a test button
if option.internal_name.endswith("api_key"):
btn = QtWidgets.QPushButton("Test Key")
layout.addWidget(btn, layout.rowCount() - 1, 2)
layout.addWidget(btn, row, 2)
if option.internal_name.endswith("url"):
btn = QtWidgets.QPushButton("Test URL")
layout.addWidget(btn, layout.rowCount() - 1, 2)
layout.addWidget(btn, row, 2)
return layout, widget, btn
return widget, btn
def settings_to_talker_form(sources: dict[str, QtWidgets.QWidget], config: settngs.Config[settngs.Namespace]):
def settings_to_talker_form(sources: dict[str, QtWidgets.QWidget], config: settngs.Config[settngs.Namespace]) -> None:
for talker in sources.items():
for name, widget in talker[1]["widgets"].items():
value = getattr(config[0], name)
@ -155,8 +148,25 @@ def settings_to_talker_form(sources: dict[str, QtWidgets.QWidget], config: settn
logger.debug("Failed to set value of %s", name)
def form_settings_to_config(sources: dict[str, QtWidgets.QWidget], config: settngs.Config[settngs.Namespace]) -> None:
for tab in sources.items():
for name, widget in tab[1]["widgets"].items():
widget_value = None
if isinstance(widget, (QtWidgets.QSpinBox, QtWidgets.QDoubleSpinBox)):
widget_value = widget.value()
elif isinstance(widget, QtWidgets.QLineEdit):
widget_value = widget.text().strip()
elif isinstance(widget, QtWidgets.QCheckBox):
widget_value = widget.isChecked()
# The talker source dropdown
elif isinstance(widget, QtWidgets.QComboBox):
widget_value = widget.itemData(widget.currentIndex())
setattr(config[0], name, widget_value)
def generate_source_option_tabs(
tabs: QtWidgets.QTabWidget,
comic_talker_tab: QtWidgets.QWidget,
config: settngs.Config[settngs.Namespace],
talkers: dict[str, ComicTalker],
) -> dict[str, QtWidgets.QWidget]:
@ -165,30 +175,32 @@ def generate_source_option_tabs(
"""
sources: dict = {}
# Use a dict to make a var name from var
source_info = {}
# Add General tab
source_info["general"] = {"tab": QtWidgets.QWidget(), "widgets": {}}
general_layout = QtWidgets.QGridLayout()
# Tab comes with a QVBoxLayout
comic_talker_tab_layout = comic_talker_tab.layout()
talker_layout = QtWidgets.QGridLayout()
lbl_info = QtWidgets.QLabel("Information Source:")
cbx_info = QtWidgets.QComboBox()
general_layout.addWidget(lbl_info, 0, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
general_layout.addWidget(cbx_info, 0, 1, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
vspacer = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
general_layout.addItem(vspacer, 1, 0)
source_info["general"]["widgets"]["talker_source"] = cbx_info
line = QtWidgets.QFrame()
line.setFrameShape(QtWidgets.QFrame.HLine)
line.setFrameShadow(QtWidgets.QFrame.Sunken)
talker_tabs = QtWidgets.QTabWidget()
source_info["general"]["tab"].setLayout(general_layout)
tabs.addTab(source_info["general"]["tab"], "General")
talker_layout.addWidget(lbl_info, 0, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
talker_layout.addWidget(cbx_info, 0, 1, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
talker_layout.addWidget(line, 1, 0, 1, -1)
talker_layout.addWidget(talker_tabs, 2, 0, 1, -1)
comic_talker_tab_layout.addLayout(talker_layout)
# Add source sub tabs to Comic Sources tab
for talker_id, talker_obj in talkers.items():
# Add source to general tab dropdown list
source_info["general"]["widgets"]["talker_source"].addItem(talker_obj.name, talker_id)
cbx_info.addItem(talker_obj.name, talker_id)
tab_name = talker_id
source_info[tab_name] = {"tab": QtWidgets.QWidget(), "widgets": {}}
sources[tab_name] = {"tab": QtWidgets.QWidget(), "widgets": {}}
layout_grid = QtWidgets.QGridLayout()
for option in config[1][f"talker_{talker_id}"][1].values():
@ -199,24 +211,25 @@ def generate_source_option_tabs(
or option.action == "store_true"
or option.action == "store_false"
):
layout_grid, current_widget = generate_checkbox(option, layout_grid)
source_info[tab_name]["widgets"][option.internal_name] = current_widget
elif option.type is int or option.type is float:
layout_grid, current_widget = generate_spinbox(
option, getattr(config[0], option.internal_name), layout_grid
)
source_info[tab_name]["widgets"][option.internal_name] = current_widget
current_widget = generate_checkbox(option, layout_grid)
sources[tab_name]["widgets"][option.internal_name] = current_widget
elif option.type is int:
current_widget = generate_spinbox(option, layout_grid)
sources[tab_name]["widgets"][option.internal_name] = current_widget
elif option.type is float:
current_widget = generate_doublespinbox(option, layout_grid)
sources[tab_name]["widgets"][option.internal_name] = current_widget
# option.type of None should be string
elif option.type is None or option.type is str:
layout_grid, current_widget, btn = generate_textbox(option, layout_grid)
source_info[tab_name]["widgets"][option.internal_name] = current_widget
current_widget, btn = generate_textbox(option, layout_grid)
sources[tab_name]["widgets"][option.internal_name] = current_widget
if option.internal_name.endswith("key"):
# Attach test api function to button. A better way?
api_key_btn_connect(btn, talker_id, source_info, talkers)
api_key_btn_connect(btn, talker_id, sources, talkers)
if option.internal_name.endswith("url"):
# Attach test api function to button. A better way?
api_url_btn_connect(btn, talker_id, source_info, talkers)
api_url_btn_connect(btn, talker_id, sources, talkers)
else:
logger.debug(f"Unsupported talker option found. Name: {option.internal_name} Type: {option.type}")
@ -224,10 +237,9 @@ def generate_source_option_tabs(
vspacer = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
layout_grid.addItem(vspacer, layout_grid.rowCount() + 1, 0)
# Display the new widgets
source_info[tab_name]["tab"].setLayout(layout_grid)
sources[tab_name]["tab"].setLayout(layout_grid)
# Add new sub tab to Comic Source tab
tabs.addTab(source_info[tab_name]["tab"], talker_obj.name)
sources.update(source_info)
talker_tabs.addTab(sources[tab_name]["tab"], talker_obj.name)
return sources

View File

@ -1,7 +1,16 @@
from __future__ import annotations
import pytest
import comictaggerlib.ui.talkeruigenerator
test_names = [
("cv_test_name", "Test name"),
("cv2_test_name", "Test name"),
]
def test_format_internal_name():
assert comictaggerlib.ui.talkeruigenerator.format_internal_name("talker_comicvine_cv_test_name") == "Test name"
@pytest.mark.parametrize("int_name, expected", test_names)
def test_format_internal_name(int_name, expected):
results = comictaggerlib.ui.talkeruigenerator.format_internal_name(int_name)
assert results == expected