diff --git a/comictaggerlib/settingswindow.py b/comictaggerlib/settingswindow.py
index a5558cf..888e440 100644
--- a/comictaggerlib/settingswindow.py
+++ b/comictaggerlib/settingswindow.py
@@ -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()
diff --git a/comictaggerlib/ui/settingswindow.ui b/comictaggerlib/ui/settingswindow.ui
index c1485c9..82b1129 100644
--- a/comictaggerlib/ui/settingswindow.ui
+++ b/comictaggerlib/ui/settingswindow.ui
@@ -340,15 +340,7 @@
Comic Sources
-
- -
-
-
- -1
-
-
-
-
+
diff --git a/comictaggerlib/ui/talkeruigenerator.py b/comictaggerlib/ui/talkeruigenerator.py
index 3a5c236..15aed6a 100644
--- a/comictaggerlib/ui/talkeruigenerator.py
+++ b/comictaggerlib/ui/talkeruigenerator.py
@@ -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__: 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
diff --git a/tests/talker_test.py b/tests/talker_test.py
index c7ced2c..c305a52 100644
--- a/tests/talker_test.py
+++ b/tests/talker_test.py
@@ -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