gui works

This commit is contained in:
Dawson Matthews
2026-03-08 18:36:45 -06:00
parent 6257e63357
commit 71a71dcc5e
2 changed files with 126 additions and 8 deletions
+2 -1
View File
@@ -1,2 +1,3 @@
profiles/
*.json
*.json
__pycache__/
+124 -7
View File
@@ -5,8 +5,22 @@ import json
import subprocess
import sys
import os
from pathlib import Path
# Try to import PySide6 for the GUI
try:
from PySide6.QtWidgets import (
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QListWidget, QPushButton, QInputDialog, QMessageBox, QLabel,
QFileDialog
)
from PySide6.QtCore import Qt
PYSIDE_AVAILABLE = True
except ImportError:
PYSIDE_AVAILABLE = False
VERBOSE = True
DEFAULT_PROFILE_DIR = Path.home() / ".local/share/kde-display-profiles"
def log(*args):
if VERBOSE:
@@ -35,8 +49,8 @@ def save_profile(profile_path):
subprocess.run(['kscreen-doctor', '--json'], stdout=f, check=True)
log("Profile saved successfully.")
except Exception as e:
print(f"Error saving profile: {e}", file=sys.stderr)
sys.exit(1)
log(f"Error saving profile: {e}")
raise e
def apply_attribute(output_name, attribute, value, value_map=None):
if value is None:
@@ -61,15 +75,14 @@ def apply_attribute(output_name, attribute, value, value_map=None):
def load_profile(profile_path):
log(f"Loading display profile from {profile_path}...")
if not os.path.exists(profile_path):
print(f"Profile file not found: {profile_path}", file=sys.stderr)
sys.exit(1)
raise FileNotFoundError(f"Profile file not found: {profile_path}")
try:
with open(profile_path, 'r') as f:
profile = json.load(f)
except Exception as e:
print(f"Error reading profile JSON: {e}", file=sys.stderr)
sys.exit(1)
log(f"Error reading profile JSON: {e}")
raise e
outputs = profile.get('outputs', [])
@@ -179,9 +192,108 @@ def load_profile(profile_path):
log("Display configuration restored.")
class DisplayProfileManagerGUI(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("KDE Display Profile Manager")
self.setMinimumSize(400, 300)
# Ensure default directory exists
DEFAULT_PROFILE_DIR.mkdir(parents=True, exist_ok=True)
self.setup_ui()
self.refresh_profiles()
def setup_ui(self):
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
layout.addWidget(QLabel("Available Profiles:"))
self.profile_list = QListWidget()
layout.addWidget(self.profile_list)
btn_layout = QHBoxLayout()
self.load_btn = QPushButton("Load Profile")
self.load_btn.clicked.connect(self.on_load_clicked)
btn_layout.addWidget(self.load_btn)
self.save_btn = QPushButton("Save Current")
self.save_btn.clicked.connect(self.on_save_clicked)
btn_layout.addWidget(self.save_btn)
self.refresh_btn = QPushButton("Refresh")
self.refresh_btn.clicked.connect(self.refresh_profiles)
btn_layout.addWidget(self.refresh_btn)
layout.addLayout(btn_layout)
def refresh_profiles(self):
self.profile_list.clear()
if DEFAULT_PROFILE_DIR.exists():
profiles = sorted(DEFAULT_PROFILE_DIR.glob("*.json"))
for profile in profiles:
self.profile_list.addItem(profile.stem)
def get_default_profile_name(self):
existing_names = []
if DEFAULT_PROFILE_DIR.exists():
existing_names = [p.stem for p in DEFAULT_PROFILE_DIR.glob("*.json")]
i = 1
while f"Profile {i}" in existing_names:
i += 1
return f"Profile {i}"
def on_save_clicked(self):
default_name = self.get_default_profile_name()
name, ok = QInputDialog.getText(self, "Save Profile", "Profile Name:", text=default_name)
if ok and name:
profile_path = DEFAULT_PROFILE_DIR / f"{name}.json"
if profile_path.exists():
reply = QMessageBox.question(self, "Overwrite?",
f"Profile '{name}' already exists. Overwrite?",
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.No:
return
try:
save_profile(str(profile_path))
self.refresh_profiles()
QMessageBox.information(self, "Success", f"Profile '{name}' saved.")
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to save profile: {e}")
def on_load_clicked(self):
selected_item = self.profile_list.currentItem()
if not selected_item:
QMessageBox.warning(self, "No Selection", "Please select a profile to load.")
return
profile_name = selected_item.text()
profile_path = DEFAULT_PROFILE_DIR / f"{profile_name}.json"
try:
load_profile(str(profile_path))
QMessageBox.information(self, "Success", f"Profile '{profile_name}' loaded.")
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to load profile: {e}")
def show_gui():
if not PYSIDE_AVAILABLE:
print("Error: PySide6 is not installed. Please install it to use the GUI.", file=sys.stderr)
sys.exit(1)
app = QApplication(sys.argv)
window = DisplayProfileManagerGUI()
window.show()
sys.exit(app.exec())
def main():
parser = argparse.ArgumentParser(description="KDE Display Profile Manager")
subparsers = parser.add_subparsers(dest="command", required=True)
subparsers = parser.add_subparsers(dest="command", required=False)
# Save command
save_parser = subparsers.add_parser("save", help="Save current display configuration to a profile")
@@ -191,12 +303,17 @@ def main():
load_parser = subparsers.add_parser("load", help="Load a display configuration from a profile")
load_parser.add_argument("profile", help="Path to the profile file")
# GUI command
subparsers.add_parser("gui", help="Launch the GUI manager")
args = parser.parse_args()
if args.command == "save":
save_profile(args.profile)
elif args.command == "load":
load_profile(args.profile)
elif args.command == "gui" or args.command is None:
show_gui()
if __name__ == "__main__":
main()