Compare commits
No commits in common. "main" and "1.8.2" have entirely different histories.
2 changed files with 143 additions and 216 deletions
|
|
@ -1,31 +1,42 @@
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from optima35.core import OptimaManager
|
from optima35.core import OptimaManager
|
||||||
from PySide6 import QtCore, QtWidgets
|
|
||||||
from PySide6.QtCore import (
|
|
||||||
QDate,
|
|
||||||
QObject,
|
|
||||||
QRegularExpression,
|
|
||||||
QRunnable,
|
|
||||||
Qt,
|
|
||||||
QThreadPool,
|
|
||||||
Signal,
|
|
||||||
)
|
|
||||||
from PySide6.QtGui import QIcon, QRegularExpressionValidator
|
|
||||||
from PySide6.QtWidgets import QApplication, QFileDialog, QMainWindow, QMessageBox
|
|
||||||
|
|
||||||
from OptimaLab35 import __version__
|
from OptimaLab35 import __version__
|
||||||
|
from .const import (
|
||||||
|
APPLICATION_NAME,
|
||||||
|
CONFIG_BASE_PATH
|
||||||
|
)
|
||||||
|
|
||||||
from .const import APPLICATION_NAME, CONFIG_BASE_PATH
|
from .ui import resources_rc
|
||||||
from .previewWindow import PreviewWindow
|
from .previewWindow import PreviewWindow
|
||||||
from .settingsWindow import SettingsWindow
|
from .settingsWindow import SettingsWindow
|
||||||
from .ui import resources_rc
|
|
||||||
from .ui.exif_handler_window import ExifEditor
|
|
||||||
from .ui.main_window import Ui_MainWindow
|
|
||||||
from .ui.simple_dialog import SimpleDialog # Import the SimpleDialog class
|
|
||||||
from .utils.utility import Utilities
|
|
||||||
|
|
||||||
|
from .utils.utility import Utilities
|
||||||
|
from .ui.main_window import Ui_MainWindow
|
||||||
|
from .ui.exif_handler_window import ExifEditor
|
||||||
|
from .ui.simple_dialog import SimpleDialog # Import the SimpleDialog class
|
||||||
|
|
||||||
|
from PySide6 import QtWidgets, QtCore
|
||||||
|
|
||||||
|
from PySide6.QtCore import (
|
||||||
|
QRunnable,
|
||||||
|
QThreadPool,
|
||||||
|
Signal,
|
||||||
|
QObject,
|
||||||
|
QRegularExpression,
|
||||||
|
Qt,
|
||||||
|
QDate
|
||||||
|
)
|
||||||
|
|
||||||
|
from PySide6.QtWidgets import (
|
||||||
|
QMessageBox,
|
||||||
|
QApplication,
|
||||||
|
QMainWindow,
|
||||||
|
QFileDialog
|
||||||
|
)
|
||||||
|
|
||||||
|
from PySide6.QtGui import QRegularExpressionValidator, QIcon
|
||||||
|
|
||||||
class OptimaLab35(QMainWindow, Ui_MainWindow):
|
class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
@ -87,7 +98,6 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
self.ui.lat_lineEdit.setValidator(validator)
|
self.ui.lat_lineEdit.setValidator(validator)
|
||||||
self.ui.long_lineEdit.setValidator(validator)
|
self.ui.long_lineEdit.setValidator(validator)
|
||||||
self.ui.dateEdit.setDate(QDate.currentDate())
|
self.ui.dateEdit.setDate(QDate.currentDate())
|
||||||
|
|
||||||
# UI related function, changing parts, open, etc.
|
# UI related function, changing parts, open, etc.
|
||||||
def open_preview_window(self):
|
def open_preview_window(self):
|
||||||
self.preview_window = PreviewWindow()
|
self.preview_window = PreviewWindow()
|
||||||
|
|
@ -108,7 +118,7 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
def info_window(self):
|
def info_window(self):
|
||||||
info_text = f"""
|
info_text = f"""
|
||||||
<h3>{self.name} v{self.version}</h3>
|
<h3>{self.name} v{self.version}</h3>
|
||||||
<p>(C) 2024-2026 Mr Finchum aka CodeByMrFinchum</p>
|
<p>(C) 2024-2025 Mr Finchum aka CodeByMrFinchum</p>
|
||||||
<p>{self.name} is a GUI for {self.o.name} (v{self.o.version}), enhancing its functionality with a user-friendly interface for efficient image and metadata management.</p>
|
<p>{self.name} is a GUI for {self.o.name} (v{self.o.version}), enhancing its functionality with a user-friendly interface for efficient image and metadata management.</p>
|
||||||
|
|
||||||
<h4>Features:</h4>
|
<h4>Features:</h4>
|
||||||
|
|
@ -175,12 +185,8 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
filtered.append(stripped)
|
filtered.append(stripped)
|
||||||
# ignore anything else
|
# ignore anything else
|
||||||
# Sort: NA first, then valid times ascending
|
# Sort: NA first, then valid times ascending
|
||||||
return sorted(
|
return sorted(filtered, key=lambda x: (0, 0) if (x is None or str(x).strip().upper() in {"NA"})
|
||||||
filtered,
|
else (1, self.parse_time(x)))
|
||||||
key=lambda x: (0, 0)
|
|
||||||
if (x is None or str(x).strip().upper() in {"NA"})
|
|
||||||
else (1, self.parse_time(x)),
|
|
||||||
)
|
|
||||||
|
|
||||||
def sort_dict_of_lists(self, input_dict):
|
def sort_dict_of_lists(self, input_dict):
|
||||||
# Partily ChatGPT
|
# Partily ChatGPT
|
||||||
|
|
@ -198,9 +204,7 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
elif all(isinstance(x, str) for x in lst):
|
elif all(isinstance(x, str) for x in lst):
|
||||||
sorted_dict[key] = sorted(
|
sorted_dict[key] = sorted(
|
||||||
lst,
|
lst,
|
||||||
key=lambda x: (0, x.lower())
|
key=lambda x: (0, x.lower()) if str(x).lower() == "na" else (1, str(x).lower())
|
||||||
if str(x).lower() == "na"
|
|
||||||
else (1, str(x).lower()),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return sorted_dict
|
return sorted_dict
|
||||||
|
|
@ -287,9 +291,7 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
|
|
||||||
def image_list_from_folder(self, path):
|
def image_list_from_folder(self, path):
|
||||||
image_files = [
|
image_files = [
|
||||||
f
|
f for f in os.listdir(path) if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp"))
|
||||||
for f in os.listdir(path)
|
|
||||||
if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp"))
|
|
||||||
]
|
]
|
||||||
image_files.sort()
|
image_files.sort()
|
||||||
return image_files
|
return image_files
|
||||||
|
|
@ -305,17 +307,11 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
|
|
||||||
if process == "image":
|
if process == "image":
|
||||||
if not input_folder or not output_folder:
|
if not input_folder or not output_folder:
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(self, "Warning", "Input or output folder not selected")
|
||||||
self, "Warning", "Input or output folder not selected"
|
|
||||||
)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not input_folder_valid or not output_folder_valid:
|
if not input_folder_valid or not output_folder_valid:
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(self, "Warning", f"Input location {input_folder_valid}\nOutput folder {output_folder_valid}...")
|
||||||
self,
|
|
||||||
"Warning",
|
|
||||||
f"Input location {input_folder_valid}\nOutput folder {output_folder_valid}...",
|
|
||||||
)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if len(self.image_list_from_folder(output_folder)) != 0:
|
if len(self.image_list_from_folder(output_folder)) != 0:
|
||||||
|
|
@ -330,6 +326,7 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
elif process == "exif":
|
elif process == "exif":
|
||||||
|
|
||||||
if not input_folder:
|
if not input_folder:
|
||||||
QMessageBox.warning(self, "Warning", "Input not selected")
|
QMessageBox.warning(self, "Warning", "Input not selected")
|
||||||
return False
|
return False
|
||||||
|
|
@ -346,18 +343,14 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not input_folder_valid :
|
if not input_folder_valid :
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(self, "Warning", f"Input location {input_folder_valid}")
|
||||||
self, "Warning", f"Input location {input_folder_valid}"
|
|
||||||
)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("Something went wrong")
|
print("Something went wrong")
|
||||||
|
|
||||||
if len(image_list) == 0:
|
if len(image_list) == 0:
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(self, "Warning", "Selected folder has no supported files.")
|
||||||
self, "Warning", "Selected folder has no supported files."
|
|
||||||
)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
@ -376,9 +369,7 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
|
|
||||||
image_list = self.image_list_from_folder(self.settings["input_folder"])
|
image_list = self.image_list_from_folder(self.settings["input_folder"])
|
||||||
# Create a worker ChatGPT
|
# Create a worker ChatGPT
|
||||||
worker = ImageProcessorRunnable(
|
worker = ImageProcessorRunnable(image_list, self.settings, self.handle_qprogressbar)
|
||||||
image_list, self.settings, self.handle_qprogressbar
|
|
||||||
)
|
|
||||||
worker.signals.finished.connect(self.on_processing_finished)
|
worker.signals.finished.connect(self.on_processing_finished)
|
||||||
# Start worker in thread pool ChatGPT
|
# Start worker in thread pool ChatGPT
|
||||||
self.thread_pool.start(worker)
|
self.thread_pool.start(worker)
|
||||||
|
|
@ -396,13 +387,13 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
|
|
||||||
i = 1
|
i = 1
|
||||||
for image_file in image_files:
|
for image_file in image_files:
|
||||||
|
|
||||||
input_path = os.path.join(input_folder, image_file)
|
input_path = os.path.join(input_folder, image_file)
|
||||||
|
|
||||||
self.o.insert_exif_to_image(
|
self.o.insert_exif_to_image(
|
||||||
exif_dict = self.settings["user_selected_exif"],
|
exif_dict = self.settings["user_selected_exif"],
|
||||||
image_path = input_path,
|
image_path = input_path,
|
||||||
gps=self.settings["gps"],
|
gps = self.settings["gps"])
|
||||||
)
|
|
||||||
self.change_statusbar(image_file, 100)
|
self.change_statusbar(image_file, 100)
|
||||||
self.handle_qprogressbar(int((i / len(image_files)) * 100))
|
self.handle_qprogressbar(int((i / len(image_files)) * 100))
|
||||||
i += 1
|
i += 1
|
||||||
|
|
@ -424,11 +415,7 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
image_list = self.image_list_from_folder(self.settings["input_folder"])
|
image_list = self.image_list_from_folder(self.settings["input_folder"])
|
||||||
print(image_list)
|
print(image_list)
|
||||||
if not self.control_ending(image_list):
|
if not self.control_ending(image_list):
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(self, "Warning", f"Error: one or more filenames do not end on a number.\nCan not adjust time")
|
||||||
self,
|
|
||||||
"Warning",
|
|
||||||
f"Error: one or more filenames do not end on a number.\nCan not adjust time",
|
|
||||||
)
|
|
||||||
self.toggle_buttons(True)
|
self.toggle_buttons(True)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -477,21 +464,12 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
user_data["lens"] = self.ui.lens_comboBox.currentText()
|
user_data["lens"] = self.ui.lens_comboBox.currentText()
|
||||||
user_data["iso"] = self.ui.iso_comboBox.currentText()
|
user_data["iso"] = self.ui.iso_comboBox.currentText()
|
||||||
lab_info = self.add_laboratory_info()
|
lab_info = self.add_laboratory_info()
|
||||||
user_data["image_description"] = (
|
user_data["image_description"] = f"{self.ui.image_description_comboBox.currentText()} {lab_info}"
|
||||||
f"{self.ui.image_description_comboBox.currentText()} {lab_info}"
|
|
||||||
)
|
|
||||||
user_data["artist"] = self.ui.artist_comboBox.currentText()
|
user_data["artist"] = self.ui.artist_comboBox.currentText()
|
||||||
user_data["copyright_info"] = self.ui.copyright_info_comboBox.currentText()
|
user_data["copyright_info"] = self.ui.copyright_info_comboBox.currentText()
|
||||||
user_data["software"] = (
|
user_data["software"] = f"{self.name} {self.version} with {self.o.name} {self.o.version}"
|
||||||
f"{self.name} {self.version} with {self.o.name} {self.o.version}"
|
if int(self.ui.contrast_spinBox.text()) != 0 or int(self.ui.brightness_spinBox.text()) != 0:
|
||||||
)
|
user_data["user_comment"] = f"{self.ui.user_comment_comboBox.currentText()}, contrast: {self.ui.contrast_spinBox.text()}, brightness: {self.ui.brightness_spinBox.text()}"
|
||||||
if (
|
|
||||||
int(self.ui.contrast_spinBox.text()) != 0
|
|
||||||
or int(self.ui.brightness_spinBox.text()) != 0
|
|
||||||
):
|
|
||||||
user_data["user_comment"] = (
|
|
||||||
f"{self.ui.user_comment_comboBox.currentText()}, contrast: {self.ui.contrast_spinBox.text()}, brightness: {self.ui.brightness_spinBox.text()}"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
user_data["user_comment"] = self.ui.user_comment_comboBox.currentText()
|
user_data["user_comment"] = self.ui.user_comment_comboBox.currentText()
|
||||||
|
|
||||||
|
|
@ -499,18 +477,13 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
|
|
||||||
def get_selected_exif(self):
|
def get_selected_exif(self):
|
||||||
"""Collect selected EXIF data and handle date and GPS if necessary."""
|
"""Collect selected EXIF data and handle date and GPS if necessary."""
|
||||||
selected_exif = (
|
selected_exif = self.collect_selected_exif() if self.ui.exif_checkbox.isChecked() else None
|
||||||
self.collect_selected_exif() if self.ui.exif_checkbox.isChecked() else None
|
|
||||||
)
|
|
||||||
if selected_exif:
|
if selected_exif:
|
||||||
if self.ui.add_date_checkBox.isChecked():
|
if self.ui.add_date_checkBox.isChecked():
|
||||||
selected_exif["date_time_original"] = self.get_date()
|
selected_exif["date_time_original"] = self.get_date()
|
||||||
if self.ui.gps_checkBox.isChecked():
|
if self.ui.gps_checkBox.isChecked():
|
||||||
try:
|
try:
|
||||||
self.settings["gps"] = [
|
self.settings["gps"] = [float(self.ui.lat_lineEdit.text()), float(self.ui.long_lineEdit.text())]
|
||||||
float(self.ui.lat_lineEdit.text()),
|
|
||||||
float(self.ui.long_lineEdit.text()),
|
|
||||||
]
|
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
self.settings["gps"] = "Wrong gps data"
|
self.settings["gps"] = "Wrong gps data"
|
||||||
else:
|
else:
|
||||||
|
|
@ -530,47 +503,22 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
self.settings["output_folder"] = self.get_text_value(self.ui.output_path)
|
self.settings["output_folder"] = self.get_text_value(self.ui.output_path)
|
||||||
self.settings["file_format"] = self.ui.image_type.currentText()
|
self.settings["file_format"] = self.ui.image_type.currentText()
|
||||||
# Quality
|
# Quality
|
||||||
self.settings["jpg_quality"] = self.get_spinbox_value(
|
self.settings["jpg_quality"] = self.get_spinbox_value(self.ui.jpg_quality_spinBox)
|
||||||
self.ui.jpg_quality_spinBox
|
self.settings["png_compression"] = self.get_spinbox_value(self.ui.png_quality_spinBox)
|
||||||
)
|
self.settings["resize"] = int(self.ui.resize_spinBox.text()) if self.ui.resize_spinBox.text() != "100" else None
|
||||||
self.settings["png_compression"] = self.get_spinbox_value(
|
|
||||||
self.ui.png_quality_spinBox
|
|
||||||
)
|
|
||||||
self.settings["resize"] = (
|
|
||||||
int(self.ui.resize_spinBox.text())
|
|
||||||
if self.ui.resize_spinBox.text() != "100"
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
self.settings["optimize"] = self.get_checkbox_value(self.ui.optimize_checkBox)
|
self.settings["optimize"] = self.get_checkbox_value(self.ui.optimize_checkBox)
|
||||||
# Changes for image
|
# Changes for image
|
||||||
self.settings["brightness"] = (
|
self.settings["brightness"] = int(self.ui.brightness_spinBox.text()) if self.ui.brightness_spinBox.text() != "0" else None
|
||||||
int(self.ui.brightness_spinBox.text())
|
self.settings["contrast"] = int(self.ui.contrast_spinBox.text()) if self.ui.contrast_spinBox.text() != "0" else None
|
||||||
if self.ui.brightness_spinBox.text() != "0"
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
self.settings["contrast"] = (
|
|
||||||
int(self.ui.contrast_spinBox.text())
|
|
||||||
if self.ui.contrast_spinBox.text() != "0"
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
self.settings["grayscale"] = self.get_checkbox_value(self.ui.grayscale_checkBox)
|
self.settings["grayscale"] = self.get_checkbox_value(self.ui.grayscale_checkBox)
|
||||||
# Watermark
|
# Watermark
|
||||||
self.settings["font_size"] = self.get_combobox_value(self.ui.font_size_comboBox)
|
self.settings["font_size"] = self.get_combobox_value(self.ui.font_size_comboBox)
|
||||||
self.settings["watermark"] = self.get_text_value(self.ui.watermark_lineEdit)
|
self.settings["watermark"] = self.get_text_value(self.ui.watermark_lineEdit)
|
||||||
# Naming
|
# Naming
|
||||||
new_name = (
|
new_name = self.get_text_value(self.ui.filename, False) if self.ui.rename_checkbox.isChecked() else False
|
||||||
self.get_text_value(self.ui.filename, False)
|
if isinstance(new_name, str): new_name = new_name.replace(" ", "_")
|
||||||
if self.ui.rename_checkbox.isChecked()
|
|
||||||
else False
|
|
||||||
)
|
|
||||||
if isinstance(new_name, str):
|
|
||||||
new_name = new_name.replace(" ", "_")
|
|
||||||
self.settings["new_file_names"] = new_name
|
self.settings["new_file_names"] = new_name
|
||||||
self.settings["invert_image_order"] = (
|
self.settings["invert_image_order"] = self.get_checkbox_value(self.ui.revert_checkbox) if new_name is not False else None
|
||||||
self.get_checkbox_value(self.ui.revert_checkbox)
|
|
||||||
if new_name is not False
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
# Handle EXIF data selection
|
# Handle EXIF data selection
|
||||||
self.settings["copy_exif"] = self.get_checkbox_value(self.ui.exif_copy_checkBox)
|
self.settings["copy_exif"] = self.get_checkbox_value(self.ui.exif_copy_checkBox)
|
||||||
self.settings["own_exif"] = self.get_checkbox_value(self.ui.exif_checkbox)
|
self.settings["own_exif"] = self.get_checkbox_value(self.ui.exif_checkbox)
|
||||||
|
|
@ -602,13 +550,11 @@ class OptimaLab35(QMainWindow, Ui_MainWindow):
|
||||||
QApplication.closeAllWindows()
|
QApplication.closeAllWindows()
|
||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
|
|
||||||
class WorkerSignals(QObject):
|
class WorkerSignals(QObject):
|
||||||
# ChatGPT
|
# ChatGPT
|
||||||
progress = Signal(int)
|
progress = Signal(int)
|
||||||
finished = Signal()
|
finished = Signal()
|
||||||
|
|
||||||
|
|
||||||
class ImageProcessorRunnable(QRunnable):
|
class ImageProcessorRunnable(QRunnable):
|
||||||
# ChatGPT gave rough function layout
|
# ChatGPT gave rough function layout
|
||||||
def __init__(self, image_files, settings, progress_callback):
|
def __init__(self, image_files, settings, progress_callback):
|
||||||
|
|
@ -627,12 +573,7 @@ class ImageProcessorRunnable(QRunnable):
|
||||||
for i, image_file in enumerate(self.image_files, start=1):
|
for i, image_file in enumerate(self.image_files, start=1):
|
||||||
input_path = os.path.join(input_folder, image_file)
|
input_path = os.path.join(input_folder, image_file)
|
||||||
if self.settings["new_file_names"] != False:
|
if self.settings["new_file_names"] != False:
|
||||||
image_name = self.u.append_number_to_name(
|
image_name = self.u.append_number_to_name(self.settings["new_file_names"], i, len(self.image_files), self.settings["invert_image_order"])
|
||||||
self.settings["new_file_names"],
|
|
||||||
i,
|
|
||||||
len(self.image_files),
|
|
||||||
self.settings["invert_image_order"],
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
image_name = os.path.splitext(image_file)[0]
|
image_name = os.path.splitext(image_file)[0]
|
||||||
output_path = os.path.join(output_folder, image_name)
|
output_path = os.path.join(output_folder, image_name)
|
||||||
|
|
@ -652,7 +593,7 @@ class ImageProcessorRunnable(QRunnable):
|
||||||
contrast = self.settings["contrast"],
|
contrast = self.settings["contrast"],
|
||||||
dict_for_exif = self.settings["user_selected_exif"],
|
dict_for_exif = self.settings["user_selected_exif"],
|
||||||
gps = self.settings["gps"],
|
gps = self.settings["gps"],
|
||||||
copy_exif=self.settings["copy_exif"],
|
copy_exif = self.settings["copy_exif"]
|
||||||
)
|
)
|
||||||
self.signals.progress.emit(int((i / len(self.image_files)) * 100))
|
self.signals.progress.emit(int((i / len(self.image_files)) * 100))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,32 @@
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from PyPiUpdater import PyPiUpdater
|
from PyPiUpdater import PyPiUpdater
|
||||||
from PySide6 import QtCore, QtWidgets
|
|
||||||
from PySide6.QtCore import QRegularExpression, Qt, QTimer
|
|
||||||
from PySide6.QtGui import QIcon
|
|
||||||
from PySide6.QtWidgets import QApplication, QMainWindow, QMessageBox
|
|
||||||
|
|
||||||
from OptimaLab35 import __version__
|
from OptimaLab35 import __version__
|
||||||
|
from .const import (
|
||||||
|
CONFIG_BASE_PATH
|
||||||
|
)
|
||||||
|
|
||||||
from .const import CONFIG_BASE_PATH
|
|
||||||
from .ui import resources_rc
|
from .ui import resources_rc
|
||||||
from .ui.settings_window import Ui_Settings_Window
|
|
||||||
from .utils.utility import Utilities
|
from .utils.utility import Utilities
|
||||||
|
from .ui.settings_window import Ui_Settings_Window
|
||||||
|
|
||||||
|
from PySide6 import QtWidgets, QtCore
|
||||||
|
|
||||||
|
from PySide6.QtCore import (
|
||||||
|
QRegularExpression,
|
||||||
|
Qt,
|
||||||
|
QTimer
|
||||||
|
)
|
||||||
|
|
||||||
|
from PySide6.QtWidgets import (
|
||||||
|
QMessageBox,
|
||||||
|
QApplication,
|
||||||
|
QMainWindow
|
||||||
|
)
|
||||||
|
|
||||||
|
from PySide6.QtGui import QIcon
|
||||||
|
|
||||||
class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
# Mixture of code by me, code/functions refactored by ChatGPT and code directly from ChatGPT
|
# Mixture of code by me, code/functions refactored by ChatGPT and code directly from ChatGPT
|
||||||
|
|
@ -33,12 +45,8 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
self.optimalab35_localversion = optimalab35_localversion
|
self.optimalab35_localversion = optimalab35_localversion
|
||||||
self.optima35_localversion = optima35_localversion
|
self.optima35_localversion = optima35_localversion
|
||||||
# Create PyPiUpdater instances
|
# Create PyPiUpdater instances
|
||||||
self.ppu_ol35 = PyPiUpdater(
|
self.ppu_ol35 = PyPiUpdater("OptimaLab35", self.optimalab35_localversion, self.update_log_file)
|
||||||
"OptimaLab35", self.optimalab35_localversion, self.update_log_file
|
self.ppu_o35 = PyPiUpdater("optima35", self.optima35_localversion, self.update_log_file)
|
||||||
)
|
|
||||||
self.ppu_o35 = PyPiUpdater(
|
|
||||||
"optima35", self.optima35_localversion, self.update_log_file
|
|
||||||
)
|
|
||||||
self.ol35_last_state = self.ppu_ol35.get_last_state()
|
self.ol35_last_state = self.ppu_ol35.get_last_state()
|
||||||
self.o35_last_state = self.ppu_o35.get_last_state()
|
self.o35_last_state = self.ppu_o35.get_last_state()
|
||||||
# Track which packages need an update
|
# Track which packages need an update
|
||||||
|
|
@ -60,9 +68,7 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
# Connect buttons to functions
|
# Connect buttons to functions
|
||||||
self.ui.check_for_update_Button.clicked.connect(self.check_for_updates)
|
self.ui.check_for_update_Button.clicked.connect(self.check_for_updates)
|
||||||
self.ui.update_and_restart_Button.clicked.connect(self.update_and_restart)
|
self.ui.update_and_restart_Button.clicked.connect(self.update_and_restart)
|
||||||
self.ui.label_last_check.setText(
|
self.ui.label_last_check.setText(f"Last check: {self.time_to_string(self.ol35_last_state[0])}")
|
||||||
f"Last check: {self.time_to_string(self.ol35_last_state[0])}"
|
|
||||||
)
|
|
||||||
self.ui.dev_widget.setVisible(False)
|
self.ui.dev_widget.setVisible(False)
|
||||||
|
|
||||||
# Timer for long press detection
|
# Timer for long press detection
|
||||||
|
|
@ -73,9 +79,7 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
# Connect button press/release
|
# Connect button press/release
|
||||||
self.ui.check_for_update_Button.pressed.connect(self.start_long_press)
|
self.ui.check_for_update_Button.pressed.connect(self.start_long_press)
|
||||||
self.ui.check_for_update_Button.released.connect(self.cancel_long_press)
|
self.ui.check_for_update_Button.released.connect(self.cancel_long_press)
|
||||||
self.ui.label_5.setText(
|
self.ui.label_5.setText('<li><a href="https://code.boxyfoxy.net/CodeByMrFinchum/OptimaLab35/src/branch/main/CHANGELOG.md">Changelog</a></li>')
|
||||||
'<li><a href="https://code.boxyfoxy.net/CodeByMrFinchum/OptimaLab35/wiki/Changelog">Changelog</a></li>'
|
|
||||||
)
|
|
||||||
self.ui.label_5.setOpenExternalLinks(True)
|
self.ui.label_5.setOpenExternalLinks(True)
|
||||||
#settings related
|
#settings related
|
||||||
self.load_settings_into_ui()
|
self.load_settings_into_ui()
|
||||||
|
|
@ -97,9 +101,7 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
pkg_available = settings["theme"]["theme_pkg"]
|
pkg_available = settings["theme"]["theme_pkg"]
|
||||||
|
|
||||||
if pkg_available:
|
if pkg_available:
|
||||||
index = self.ui.theme_selection_comboBox.findText(
|
index = self.ui.theme_selection_comboBox.findText(theme_mode, QtCore.Qt.MatchFlag.MatchExactly)
|
||||||
theme_mode, QtCore.Qt.MatchFlag.MatchExactly
|
|
||||||
)
|
|
||||||
if index != -1:
|
if index != -1:
|
||||||
self.ui.theme_selection_comboBox.setCurrentIndex(index)
|
self.ui.theme_selection_comboBox.setCurrentIndex(index)
|
||||||
self.ui.enable_theme_checkBox.setChecked(use_custom_theme)
|
self.ui.enable_theme_checkBox.setChecked(use_custom_theme)
|
||||||
|
|
@ -128,12 +130,8 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
self.ui.install_pkg_Button.setText("Try again?")
|
self.ui.install_pkg_Button.setText("Try again?")
|
||||||
|
|
||||||
def save_settings(self):
|
def save_settings(self):
|
||||||
self.app_settings["theme"]["mode"] = (
|
self.app_settings["theme"]["mode"] = self.ui.theme_selection_comboBox.currentText()
|
||||||
self.ui.theme_selection_comboBox.currentText()
|
self.app_settings["theme"]["use_custom_theme"] = self.ui.enable_theme_checkBox.isChecked()
|
||||||
)
|
|
||||||
self.app_settings["theme"]["use_custom_theme"] = (
|
|
||||||
self.ui.enable_theme_checkBox.isChecked()
|
|
||||||
)
|
|
||||||
self.u.save_settings(self.app_settings)
|
self.u.save_settings(self.app_settings)
|
||||||
|
|
||||||
def save_and_close(self):
|
def save_and_close(self):
|
||||||
|
|
@ -145,9 +143,7 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
msg.setIcon(QMessageBox.Icon.Question)
|
msg.setIcon(QMessageBox.Icon.Question)
|
||||||
msg.setWindowTitle("Confirm Reset")
|
msg.setWindowTitle("Confirm Reset")
|
||||||
msg.setText("Are you sure you want to restart the app?")
|
msg.setText("Are you sure you want to restart the app?")
|
||||||
msg.setStandardButtons(
|
msg.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
|
||||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
|
||||||
)
|
|
||||||
|
|
||||||
# Show the message box and wait for the user's response
|
# Show the message box and wait for the user's response
|
||||||
response = msg.exec()
|
response = msg.exec()
|
||||||
|
|
@ -166,9 +162,7 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
msg.setIcon(QMessageBox.Icon.Question)
|
msg.setIcon(QMessageBox.Icon.Question)
|
||||||
msg.setWindowTitle("Confirm Reset")
|
msg.setWindowTitle("Confirm Reset")
|
||||||
msg.setText("Are you sure you want to reset the EXIF options to default?")
|
msg.setText("Are you sure you want to reset the EXIF options to default?")
|
||||||
msg.setStandardButtons(
|
msg.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
|
||||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
|
||||||
)
|
|
||||||
|
|
||||||
# Show the message box and wait for the user's response
|
# Show the message box and wait for the user's response
|
||||||
response = msg.exec()
|
response = msg.exec()
|
||||||
|
|
@ -220,9 +214,7 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
|
|
||||||
def local_update(self):
|
def local_update(self):
|
||||||
dist_folder = os.path.expanduser("~/.config/OptimaLab35/dist/")
|
dist_folder = os.path.expanduser("~/.config/OptimaLab35/dist/")
|
||||||
packages_to_update = [
|
packages_to_update = [pkg for pkg, update in self.updates_available.items() if update]
|
||||||
pkg for pkg, update in self.updates_available.items() if update
|
|
||||||
]
|
|
||||||
|
|
||||||
if not packages_to_update:
|
if not packages_to_update:
|
||||||
QMessageBox.information(self, "Update", "No updates available.")
|
QMessageBox.information(self, "Update", "No updates available.")
|
||||||
|
|
@ -251,9 +243,7 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
elif package == "optima35":
|
elif package == "optima35":
|
||||||
pkg_info = self.ppu_o35.update_from_local(dist_folder)
|
pkg_info = self.ppu_o35.update_from_local(dist_folder)
|
||||||
|
|
||||||
update_results.append(
|
update_results.append(f"{package}: {'Success' if pkg_info[0] else 'Failed'}\n{pkg_info[1]}")
|
||||||
f"{package}: {'Success' if pkg_info[0] else 'Failed'}\n{pkg_info[1]}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Show summary of updates
|
# Show summary of updates
|
||||||
# Show update completion message
|
# Show update completion message
|
||||||
|
|
@ -312,9 +302,7 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
|
|
||||||
def update_and_restart(self):
|
def update_and_restart(self):
|
||||||
"""Update selected packages and restart the application."""
|
"""Update selected packages and restart the application."""
|
||||||
packages_to_update = [
|
packages_to_update = [pkg for pkg, update in self.updates_available.items() if update]
|
||||||
pkg for pkg, update in self.updates_available.items() if update
|
|
||||||
]
|
|
||||||
|
|
||||||
if not packages_to_update:
|
if not packages_to_update:
|
||||||
QMessageBox.information(self, "Update", "No updates available.")
|
QMessageBox.information(self, "Update", "No updates available.")
|
||||||
|
|
@ -343,9 +331,7 @@ class SettingsWindow(QMainWindow, Ui_Settings_Window):
|
||||||
elif package == "optima35":
|
elif package == "optima35":
|
||||||
pkg_info = self.ppu_o35.update_package()
|
pkg_info = self.ppu_o35.update_package()
|
||||||
|
|
||||||
update_results.append(
|
update_results.append(f"{package}: {'Success' if pkg_info[0] else 'Failed'}\n{pkg_info[1]}")
|
||||||
f"{package}: {'Success' if pkg_info[0] else 'Failed'}\n{pkg_info[1]}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Show summary of updates
|
# Show summary of updates
|
||||||
# Show update completion message
|
# Show update completion message
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue