352 lines
16 KiB
Python
352 lines
16 KiB
Python
import sys, os, subprocess
|
|
from PySide6.QtWidgets import QApplication, QDialog, QButtonGroup, QFileDialog, QMessageBox
|
|
from PySide6.QtCore import Slot
|
|
from PySide6.QtGui import QIntValidator
|
|
# Import the generated UI class from the ui_form.py file
|
|
from ui_read_disk import Ui_ReadDialog
|
|
|
|
class ReadDiskWindow(QDialog):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
|
|
self.ui = Ui_ReadDialog()
|
|
self.ui.setupUi(self)
|
|
|
|
# --- Set up Logical Button Groups ---
|
|
self.flippy_type_group = QButtonGroup(self)
|
|
self.flippy_type_group.addButton(self.ui.rb_panasonic, 1)
|
|
self.flippy_type_group.addButton(self.ui.rb_teac, 2)
|
|
|
|
self.pin2_setting_group = QButtonGroup(self)
|
|
self.pin2_setting_group.addButton(self.ui.rb_pin2_high, 1)
|
|
self.pin2_setting_group.addButton(self.ui.rb_pin2_low, 2)
|
|
|
|
# --- Connect Signals to Slots ---
|
|
self.ui.cb_fake_index.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_bitrate.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_double_step.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_revs.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_drive_select.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_pllspec.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_retries.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_head_sets.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_head_swap.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_ss_legacy.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_cylinder_sets.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_rev_track_data.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_hard_sectors.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_no_clobber.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_raw.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_pin2.toggled.connect(self.on_update_settings)
|
|
self.ui.rb_pin2_high.toggled.connect(self.on_update_settings)
|
|
self.ui.rb_pin2_low.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_flippy.toggled.connect(self.on_update_settings)
|
|
self.ui.rb_panasonic.toggled.connect(self.on_update_settings)
|
|
self.ui.rb_teac.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_adjust_speed.toggled.connect(self.on_update_settings)
|
|
self.ui.combo_drive_select.currentIndexChanged.connect(self.on_update_settings)
|
|
self.ui.combo_fake_index.currentIndexChanged.connect(self.on_update_settings)
|
|
self.ui.combo_adjust_speed.currentIndexChanged.connect(self.on_update_settings)
|
|
self.ui.combo_disktype.currentIndexChanged.connect(self.on_update_settings)
|
|
self.ui.combo_format.currentIndexChanged.connect(self.on_update_settings)
|
|
self.ui.le_fake_index.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_lowpass.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_period.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_phase.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_bitrate.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_revs.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_double_step.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_retries.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_head_sets.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_cylinder_sets.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_adjust_speed.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_suffix.textChanged.connect(self.on_update_settings)
|
|
self.ui.le_fileprefix.textChanged.connect(self.on_update_settings)
|
|
#self.ui.btn_suffix_inc.clicked.connect(self.on_update_settings)
|
|
#self.ui.btn_suffix_dec.clicked.connect(self.on_update_settings)
|
|
# self.ui.btn_path_select.clicked.connect(self.on_path_select)
|
|
self.ui.btn_file_select.clicked.connect(self.on_update_settings)
|
|
self.ui.cb_format.toggled.connect(self.on_update_settings)
|
|
self.ui.cb_inc.toggled.connect(self.on_update_settings)
|
|
|
|
# --- Connect Buttons to Dialog's Built-in Slots ---
|
|
# The "Launch" button will "accept" the dialog (like OK)
|
|
# The "Back" button will "reject" the dialog (like Cancel)
|
|
self.ui.btn_launch.clicked.connect(self.on_launch)
|
|
self.ui.btn_back.clicked.connect(self.reject)
|
|
|
|
# Initialize command attribute
|
|
self.command = ""
|
|
|
|
def calc_suffix(self, inc: int) -> None:
|
|
# Increments or decrements the numeric value in the suffix text field.
|
|
try:
|
|
current_value = int(self.ui.le_suffix.text())
|
|
current_value = current_value + inc
|
|
except ValueError:
|
|
current_value = 0
|
|
|
|
self.ui.le_suffix.setText(str(current_value))
|
|
|
|
@Slot()
|
|
def on_btn_suffix_inc_clicked(self):
|
|
self.calc_suffix(1)
|
|
|
|
@Slot()
|
|
def on_btn_suffix_dec_clicked(self):
|
|
self.calc_suffix(-1)
|
|
|
|
@Slot()
|
|
def on_btn_file_select_clicked(self):
|
|
file, ok = QFileDialog.getOpenFileName(self, "Select File", self.ui.le_filepath.text())
|
|
|
|
if file == "":
|
|
return
|
|
|
|
file_path, file_name = os.path.split(file)
|
|
name, extension = os.path.splitext(file_name)
|
|
|
|
self.ui.le_filepath.setText(file_path)
|
|
self.ui.le_fileprefix.setText(name)
|
|
self.ui.le_suffix.setText("")
|
|
self.ui.combo_disktype.setCurrentText(extension)
|
|
self.on_update_settings()
|
|
|
|
@Slot()
|
|
def on_btn_path_select_clicked(self):
|
|
path = QFileDialog.getExistingDirectory(self, "Select Folder")
|
|
self.ui.le_filepath.setText(path)
|
|
self.on_update_settings()
|
|
|
|
@Slot()
|
|
def on_launch(self):
|
|
try:
|
|
completed = subprocess.run(self.command, check=True)
|
|
except FileNotFoundError as e:
|
|
QMessageBox.critical(self, "Error", f"Command not found: {e}")
|
|
except subprocess.CalledProcessError as e:
|
|
QMessageBox.critical(self, "Error", f"Failed to launch command: {e}")
|
|
|
|
if self.ui.cb_inc.isChecked():
|
|
self.calc_suffix(1)
|
|
|
|
def get_settings(self):
|
|
"""
|
|
A helper method to gather all settings from the UI into a dictionary.
|
|
This is a clean way to pass the data out of the dialog.
|
|
"""
|
|
settings = {
|
|
"fileprefix": self.ui.le_fileprefix.text(),
|
|
"filepath": self.ui.le_filepath.text(),
|
|
"double_step_enabled": self.ui.cb_double_step.isChecked(),
|
|
"double_step_value": self.ui.le_double_step.text(),
|
|
"fake_index_enabled": self.ui.cb_fake_index.isChecked(),
|
|
"fake_index_value": self.ui.le_fake_index.text(),
|
|
"fake_index_unit": self.ui.combo_fake_index.currentText(),
|
|
"bitrate_enabled": self.ui.cb_bitrate.isChecked(),
|
|
"bitrate_value": self.ui.le_bitrate.text(),
|
|
"revs_enabled": self.ui.cb_revs.isChecked(),
|
|
"revs_value": self.ui.le_revs.text(),
|
|
"drive_select_enabled": self.ui.cb_drive_select.isChecked(),
|
|
"drive_select_value": self.ui.combo_drive_select.currentText(),
|
|
"retries_enabled": self.ui.cb_retries.isChecked(),
|
|
"retries_value": self.ui.le_retries.text(),
|
|
"pllspec_enabled": self.ui.cb_pllspec.isChecked(),
|
|
"pll_period": self.ui.le_period.text(),
|
|
"pll_phase": self.ui.le_phase.text(),
|
|
"pll_lowpass": self.ui.le_lowpass.text(),
|
|
"head_sets_enabled": self.ui.cb_head_sets.isChecked(),
|
|
"head_sets_value": self.ui.le_head_sets.text(),
|
|
"head_swap_enabled": self.ui.cb_head_swap.isChecked(),
|
|
"ss_legacy_enabled": self.ui.cb_ss_legacy.isChecked(),
|
|
"cylinder_sets_enabled": self.ui.cb_cylinder_sets.isChecked(),
|
|
"cylinder_sets_value": self.ui.le_cylinder_sets.text(),
|
|
"rev_track_data_enabled": self.ui.cb_rev_track_data.isChecked(),
|
|
"hard_sectors_enabled": self.ui.cb_hard_sectors.isChecked(),
|
|
"no_clobber_enabled": self.ui.cb_no_clobber.isChecked(),
|
|
"raw_enabled": self.ui.cb_raw.isChecked(),
|
|
"pin2_enabled": self.ui.cb_pin2.isChecked(),
|
|
"pin2_high": self.ui.rb_pin2_high.isChecked(),
|
|
"pin2_low": self.ui.rb_pin2_low.isChecked(),
|
|
"flippy_enabled": self.ui.cb_flippy.isChecked(),
|
|
"flippy_panasonic": self.ui.rb_panasonic.isChecked(),
|
|
"flippy_teac": self.ui.rb_teac.isChecked(),'"' +
|
|
"adjust_speed_enabled": self.ui.cb_adjust_speed.isChecked(),
|
|
"adjust_speed_value": self.ui.le_adjust_speed.text(),
|
|
"adjust_speed_unit": self.ui.combo_adjust_speed.currentText(),
|
|
"suffix_value": self.ui.le_suffix.text(),
|
|
"inc_enabled": self.ui.cb_inc.isChecked(),
|
|
"format_enabled": self.ui.cb_format.isChecked(),
|
|
"format_value": self.ui.combo_format.currentText(),
|
|
"disktype_value": self.ui.combo_disktype.currentText(),
|
|
}
|
|
|
|
return settings
|
|
|
|
def set_settings(self, settings):
|
|
self.ui.le_fileprefix.setText(settings.get("fileprefix", ""))
|
|
self.ui.le_filepath.setText(settings.get("filepath", ""))
|
|
self.ui.cb_double_step.setChecked(settings.get("double_step_enabled", False))
|
|
self.ui.le_double_step.setText(settings.get("double_step_value", ""))
|
|
self.ui.cb_fake_index.setChecked(settings.get("fake_index_enabled", False))
|
|
self.ui.le_fake_index.setText(settings.get("fake_index_value", ""))
|
|
self.ui.combo_fake_index.setCurrentText(settings.get("fake_index_unit", ""))
|
|
self.ui.cb_bitrate.setChecked(settings.get("bitrate_enabled", False))
|
|
self.ui.le_bitrate.setText(settings.get("bitrate_value", ""))
|
|
self.ui.cb_revs.setChecked(settings.get("revs_enabled", False))
|
|
self.ui.le_revs.setText(settings.get("revs_value", ""))
|
|
self.ui.cb_drive_select.setChecked(settings.get("drive_select_enabled", False))
|
|
self.ui.combo_drive_select.setCurrentText(settings.get("drive_select_value", ""))
|
|
self.ui.cb_retries.setChecked(settings.get("retries_enabled", False))
|
|
self.ui.le_retries.setText(settings.get("retries_value", ""))
|
|
self.ui.cb_pllspec.setChecked(settings.get("pllspec_enabled", False))
|
|
self.ui.le_period.setText(settings.get("pll_period", ""))
|
|
self.ui.le_phase.setText(settings.get("pll_phase", ""))
|
|
self.ui.le_lowpass.setText(settings.get("pll_lowpass", ""))
|
|
self.ui.cb_head_sets.setChecked(settings.get("head_sets_enabled", False))
|
|
self.ui.le_head_sets.setText(settings.get("head_sets_value", ""))
|
|
self.ui.cb_head_swap.setChecked(settings.get("head_swap_enabled", False))
|
|
self.ui.cb_ss_legacy.setChecked(settings.get("ss_legacy_enabled", False))
|
|
self.ui.cb_cylinder_sets.setChecked(settings.get("cylinder_sets_enabled", False))
|
|
self.ui.le_cylinder_sets.setText(settings.get("cylinder_sets_value", ""))
|
|
self.ui.cb_rev_track_data.setChecked(settings.get("rev_track_data_enabled", False))
|
|
self.ui.cb_hard_sectors.setChecked(settings.get("hard_sectors_enabled", False))
|
|
self.ui.cb_no_clobber.setChecked(settings.get("no_clobber_enabled", False))
|
|
self.ui.cb_raw.setChecked(settings.get("raw_enabled", False))
|
|
self.ui.cb_pin2.setChecked(settings.get("pin2_enabled", False))
|
|
self.ui.rb_pin2_high.setChecked(settings.get("pin2_high", False))
|
|
self.ui.rb_pin2_low.setChecked(settings.get("pin2_low", False))
|
|
self.ui.cb_flippy.setChecked(settings.get("flippy_enabled", False))
|
|
self.ui.rb_panasonic.setChecked(settings.get("flippy_panasonic", False))
|
|
self.ui.rb_teac.setChecked(settings.get("flippy_teac", False))
|
|
self.ui.cb_adjust_speed.setChecked(settings.get("adjust_speed_enabled", False))
|
|
self.ui.le_adjust_speed.setText(settings.get("adjust_speed_value", ""))
|
|
self.ui.combo_adjust_speed.setCurrentText(settings.get("adjust_speed_unit", ""))
|
|
self.ui.le_suffix.setText(settings.get("suffix_value", ""))
|
|
self.ui.cb_inc.setChecked(settings.get("inc_enabled", False))
|
|
self.ui.cb_format.setChecked(settings.get("format_enabled", False))
|
|
self.ui.combo_format.setCurrentText(settings.get("format_value", ""))
|
|
self.ui.combo_disktype.setCurrentText(settings.get("disktype_value", ""))
|
|
# Note: command is not set here, as it is generated from UI state
|
|
|
|
def on_update_settings(self, *args, **kwargs):
|
|
fileprefix = self.ui.le_fileprefix.text()
|
|
drive = ""
|
|
bitrate = ""
|
|
legacy_ss = ""
|
|
revs = ""
|
|
retries = ""
|
|
fake_index = ""
|
|
pll = ""
|
|
tracks = ""
|
|
densel = ""
|
|
no_clobber = ""
|
|
raw = ""
|
|
reverse = ""
|
|
hard_sectors = ""
|
|
adjust_speed = ""
|
|
disktype = ""
|
|
|
|
if self.ui.cb_revs.isChecked():
|
|
revs = "--revs=" + self.ui.le_revs.text()
|
|
|
|
if self.ui.cb_drive_select.isChecked():
|
|
drive = "--drive=" + self.ui.combo_drive_select.currentText()
|
|
|
|
if self.ui.cb_bitrate.isChecked():
|
|
bitrate = "::bitrate=" + self.ui.le_bitrate.text()
|
|
|
|
if self.ui.cb_ss_legacy.isChecked():
|
|
legacy_ss = "::legacy_ss"
|
|
|
|
if self.ui.cb_retries.isChecked():
|
|
retries = "--retries=" + self.ui.le_retries.text()
|
|
|
|
if self.ui.cb_fake_index.isChecked(): command = " ".join(self.command)
|
|
|
|
|
|
fake_index = "--fake-index=" + self.ui.le_fake_index.text() + self.ui.combo_fake_index.currentText()
|
|
|
|
if self.ui.cb_pllspec.isChecked():
|
|
pll = "--pll=period=" + self.ui.le_period.text() + ":phase=m" + self.ui.le_phase.text()
|
|
|
|
if self.ui.le_lowpass.text() != "":
|
|
pll = pll + ":lowpass=" + self.ui.le_lowpass.text()
|
|
|
|
# --tracks combines multiple settings into a single argument
|
|
if self.ui.cb_double_step.isChecked():
|
|
tracks = "step=" + self.ui.le_double_step.text()
|
|
|
|
if self.ui.cb_cylinder_sets.isChecked():
|
|
if tracks != "":
|
|
tracks = tracks + ":"
|
|
|
|
tracks = tracks + "c=" + self.ui.le_cylinder_sets.text()
|
|
|
|
if self.ui.cb_head_sets.isChecked():
|
|
if tracks != "":
|
|
tracks = tracks + ":"
|
|
|
|
tracks = tracks + "h=" + self.ui.le_head_sets.text()
|
|
|
|
if self.ui.cb_head_swap.isChecked():
|
|
if tracks != "":
|
|
tracks = tracks + ":"
|
|
|
|
tracks = tracks + "hswap"
|
|
|
|
if self.ui.cb_flippy.isChecked():
|
|
if tracks != "":
|
|
tracks = tracks + ":"
|
|
|
|
if self.ui.rb_panasonic.isChecked():
|
|
tracks = tracks + "h1.off=-8"
|
|
else:
|
|
tracks = tracks + "h0.off=+8"
|
|
|
|
if tracks != "":
|
|
tracks = "--tracks=" + tracks
|
|
|
|
if self.ui.cb_rev_track_data.isChecked():
|
|
reverse = "--reverse"
|
|
|
|
if self.ui.cb_hard_sectors.isChecked():
|
|
hard_sectors = "--hard-sectors"
|
|
|
|
if self.ui.cb_no_clobber.isChecked():
|
|
no_clobber = "--no-clobber"
|
|
|
|
if self.ui.cb_pin2.isChecked():
|
|
if self.ui.rb_pin2_high.isChecked():
|
|
densel = "--densel H"
|
|
else:
|
|
densel = "--densel L"
|
|
|
|
if self.ui.cb_raw.isChecked():
|
|
raw = "--raw"
|
|
|
|
if self.ui.cb_adjust_speed.isChecked():
|
|
adjust_speed = "--adjust-speed=" + self.ui.le_adjust_speed.text() + self.ui.combo_adjust_speed.currentText()
|
|
|
|
suffix = self.ui.le_suffix.text()
|
|
|
|
if suffix != "":
|
|
suffix = "-" + suffix
|
|
|
|
filepath = self.ui.le_filepath.text()
|
|
|
|
disktype = self.ui.combo_disktype.currentText()
|
|
generated_filename = fileprefix + suffix + disktype
|
|
filename = os.path.join(filepath, generated_filename) + bitrate + legacy_ss
|
|
|
|
self.command = [
|
|
item for item in [
|
|
"gw", "read", tracks, revs, drive, densel,
|
|
adjust_speed, no_clobber, raw, reverse,
|
|
hard_sectors, fake_index, pll, retries, filename
|
|
] if item
|
|
]
|
|
|
|
self.ui.le_filename.setText(generated_filename)
|
|
self.ui.te_command_line.setPlainText(" ".join(self.command))
|