1.0.0 Release
This commit is contained in:
153
src/options_dialog.py
Normal file
153
src/options_dialog.py
Normal file
@@ -0,0 +1,153 @@
|
||||
from PyQt5 import QtWidgets, QtCore, QtGui
|
||||
import logging
|
||||
from logging_config import get_logger
|
||||
from launch_agent import get_launch_agent_manager
|
||||
|
||||
|
||||
class OptionsDialog(QtWidgets.QDialog):
|
||||
"""Options dialog for configuring HereIAm settings"""
|
||||
|
||||
def __init__(self, current_wait_time=240, current_start_enabled=True, current_log_level="INFO", current_move_px=10, current_launch_at_startup=False, parent=None):
|
||||
super().__init__(parent)
|
||||
self.logger = get_logger(__name__)
|
||||
|
||||
# Store current values
|
||||
self.wait_time = current_wait_time
|
||||
self.start_enabled = current_start_enabled
|
||||
self.log_level = current_log_level
|
||||
self.move_px = current_move_px
|
||||
self.launch_at_startup = current_launch_at_startup
|
||||
|
||||
# Initialize launch agent manager
|
||||
self.launch_agent_manager = get_launch_agent_manager()
|
||||
|
||||
self.setupUI()
|
||||
self.load_current_values()
|
||||
|
||||
def setupUI(self):
|
||||
"""Setup the dialog UI"""
|
||||
self.setWindowTitle("HereIAm Options")
|
||||
self.setModal(True)
|
||||
self.setFixedSize(400, 220) # Increased height to accommodate new option
|
||||
|
||||
# Ensure dialog appears on top and is properly managed
|
||||
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowStaysOnTopHint)
|
||||
# Remove WA_DeleteOnClose to prevent automatic deletion conflicts
|
||||
|
||||
# Main layout
|
||||
layout = QtWidgets.QVBoxLayout(self)
|
||||
layout.setSpacing(10) # Reduce spacing between elements
|
||||
|
||||
# Create form layout
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
form_layout.setVerticalSpacing(8) # Reduce vertical spacing between form rows
|
||||
form_layout.setHorizontalSpacing(10) # Set horizontal spacing
|
||||
|
||||
# Wait Time setting
|
||||
self.wait_time_spinbox = QtWidgets.QSpinBox()
|
||||
self.wait_time_spinbox.setRange(10, 3600) # 10 seconds to 1 hour
|
||||
self.wait_time_spinbox.setSuffix(" seconds")
|
||||
self.wait_time_spinbox.setToolTip("Time to wait before moving mouse when idle (Range: 10-3600 seconds)")
|
||||
self.wait_time_spinbox.setKeyboardTracking(True) # Enable keyboard input
|
||||
self.wait_time_spinbox.setButtonSymbols(QtWidgets.QAbstractSpinBox.UpDownArrows) # Ensure arrows are visible
|
||||
self.wait_time_spinbox.lineEdit().setReadOnly(False) # Allow typing in the field
|
||||
form_layout.addRow("Wait Time (10-3600s):", self.wait_time_spinbox)
|
||||
|
||||
# Mouse Movement Distance setting
|
||||
self.move_px_spinbox = QtWidgets.QSpinBox()
|
||||
self.move_px_spinbox.setRange(1, 100) # 1 to 100 pixels
|
||||
self.move_px_spinbox.setSuffix(" pixels")
|
||||
self.move_px_spinbox.setToolTip("Distance to move mouse in pixels (Range: 1-100 pixels)")
|
||||
self.move_px_spinbox.setKeyboardTracking(True) # Enable keyboard input
|
||||
self.move_px_spinbox.setButtonSymbols(QtWidgets.QAbstractSpinBox.UpDownArrows) # Ensure arrows are visible
|
||||
self.move_px_spinbox.lineEdit().setReadOnly(False) # Allow typing in the field
|
||||
form_layout.addRow("Movement Distance (1-100px):", self.move_px_spinbox)
|
||||
|
||||
# Start Enabled setting
|
||||
self.start_enabled_checkbox = QtWidgets.QCheckBox()
|
||||
self.start_enabled_checkbox.setToolTip("Start HereIAm enabled when application launches")
|
||||
form_layout.addRow("Start Enabled:", self.start_enabled_checkbox)
|
||||
|
||||
# Launch at Startup setting
|
||||
self.launch_at_startup_checkbox = QtWidgets.QCheckBox()
|
||||
self.launch_at_startup_checkbox.setToolTip("Automatically launch HereIAm when you log in to macOS")
|
||||
form_layout.addRow("Launch at Startup:", self.launch_at_startup_checkbox)
|
||||
|
||||
# Log Level setting
|
||||
self.log_level_combo = QtWidgets.QComboBox()
|
||||
self.log_level_combo.addItems(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"])
|
||||
self.log_level_combo.setToolTip("Set the logging level for the application")
|
||||
form_layout.addRow("Log Level:", self.log_level_combo)
|
||||
|
||||
layout.addLayout(form_layout)
|
||||
|
||||
# Button box
|
||||
button_box = QtWidgets.QDialogButtonBox(
|
||||
QtWidgets.QDialogButtonBox.Save | QtWidgets.QDialogButtonBox.Cancel
|
||||
)
|
||||
button_box.accepted.connect(self.accept)
|
||||
button_box.rejected.connect(self.reject)
|
||||
|
||||
layout.addWidget(button_box)
|
||||
|
||||
# Center the dialog on screen
|
||||
self.center_on_screen()
|
||||
|
||||
def center_on_screen(self):
|
||||
"""Center the dialog on the screen"""
|
||||
screen = QtWidgets.QApplication.primaryScreen()
|
||||
if screen:
|
||||
screen_geometry = screen.geometry()
|
||||
dialog_geometry = self.geometry()
|
||||
x = (screen_geometry.width() - dialog_geometry.width()) // 2
|
||||
y = (screen_geometry.height() - dialog_geometry.height()) // 2
|
||||
self.move(x, y)
|
||||
|
||||
def showEvent(self, event):
|
||||
"""Called when dialog is shown"""
|
||||
super().showEvent(event)
|
||||
self.raise_()
|
||||
self.activateWindow()
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""Called when dialog is closed"""
|
||||
self.logger.debug("Options dialog closing")
|
||||
super().closeEvent(event)
|
||||
|
||||
def load_current_values(self):
|
||||
"""Load current values into the form"""
|
||||
self.wait_time_spinbox.setValue(self.wait_time)
|
||||
self.move_px_spinbox.setValue(self.move_px)
|
||||
self.start_enabled_checkbox.setChecked(self.start_enabled)
|
||||
|
||||
# Check current startup status from the system
|
||||
current_startup_enabled = self.launch_agent_manager.is_startup_enabled()
|
||||
self.launch_at_startup_checkbox.setChecked(current_startup_enabled)
|
||||
|
||||
# Set log level
|
||||
index = self.log_level_combo.findText(self.log_level)
|
||||
if index >= 0:
|
||||
self.log_level_combo.setCurrentIndex(index)
|
||||
|
||||
def get_values(self):
|
||||
"""Get the values from the form"""
|
||||
try:
|
||||
return {
|
||||
'wait_time': self.wait_time_spinbox.value(),
|
||||
'move_px': self.move_px_spinbox.value(),
|
||||
'start_enabled': self.start_enabled_checkbox.isChecked(),
|
||||
'launch_at_startup': self.launch_at_startup_checkbox.isChecked(),
|
||||
'log_level': self.log_level_combo.currentText()
|
||||
}
|
||||
except AttributeError as e:
|
||||
# If widgets are already destroyed, return None
|
||||
self.logger.error(f"Error getting dialog values: {e}")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_options(current_wait_time=240, current_start_enabled=True, current_log_level="INFO", current_move_px=10, current_launch_at_startup=False, parent=None):
|
||||
"""Static method to show the dialog and return values"""
|
||||
dialog = OptionsDialog(current_wait_time, current_start_enabled, current_log_level, current_move_px, current_launch_at_startup, parent)
|
||||
if dialog.exec_() == QtWidgets.QDialog.Accepted:
|
||||
return dialog.get_values(), True
|
||||
return None, False
|
||||
Reference in New Issue
Block a user