// The Options dialog. Lane GUI. // // docs/03-gui-spec.md §4: every control here maps 1:1 onto a settings.* key from // contracts/schema/types/Settings.schema.json. The spec's "File Types" tab turned out to // have real backing after all (capture.monitoredExtensions/monitoredMimeTypes/ // autoStartTypes are settings.* keys, not Category — a mistake in an earlier pass here, // caught while checking this dialog covers all 43 keys against the now-live real veloxd); // it is named "Capture" below to match what it actually configures. "Site Logins" still // has no settings.* key (credentials go to the Secret Service) and stays out. #pragma once #include #include class QCheckBox; class QComboBox; class QLabel; class QLineEdit; class QPlainTextEdit; class QSpinBox; class QTabWidget; namespace velox::gui { namespace rpc { class RpcClient; } // namespace rpc class OptionsDialog : public QDialog { Q_OBJECT public: explicit OptionsDialog(rpc::RpcClient *client, QWidget *parent = nullptr); /// The settings.* keys every tab's controls bind to, in the order settings.get is /// called with. Exposed so a test can assert nothing here drifts from the schema. static QStringList allKeys(); /// Pure: keys in `current` whose value differs from `original` (or is altogether /// absent from `original`). settings.set is documented to write and broadcast exactly /// the keys present in its params, so sending only what actually changed matters. static QJsonObject diffChanged(const QJsonObject &original, const QJsonObject ¤t); private slots: void onSettingsLoaded(const QJsonObject &values); void apply(); private: void buildGeneralTab(); void buildCaptureTab(); void buildSaveToTab(); void buildConnectionTab(); void buildDownloadsTab(); void buildProxyTab(); void buildSoundsTab(); void populateFrom(const QJsonObject &values); QJsonObject currentValues() const; void browseInto(QLineEdit *target, bool pickFile); rpc::RpcClient *client_; QJsonObject original_; // last-known-saved values, keyed by settings.* name QTabWidget *tabs_; QLabel *statusLabel_; // General QCheckBox *launchOnLogin_; QCheckBox *minimizeToTray_; QCheckBox *showDropTarget_; QCheckBox *confirmOnExit_; QComboBox *language_; QCheckBox *checkForUpdates_; // Capture QCheckBox *captureEnabled_; QLineEdit *monitoredExtensions_; QLineEdit *monitoredMimeTypes_; QSpinBox *minSizeKiB_; QLineEdit *excludedHosts_; QComboBox *bypassModifier_; QLineEdit *autoStartTypes_; // Save To QLineEdit *defaultDir_; QLineEdit *tempDir_; QComboBox *fileExistsPolicy_; QCheckBox *createSubfolderPerSite_; QPlainTextEdit *allowedRoots_; // Connection QComboBox *connectionPreset_; QSpinBox *maxSegmentsPerDownload_; QComboBox *bufferBytes_; QSpinBox *maxConcurrentDownloads_; QSpinBox *timeoutSec_; QSpinBox *maxRetries_; QSpinBox *retryBackoffSec_; QSpinBox *maxTotalBufferMiB_; QSpinBox *maxActiveSegments_; // Downloads QCheckBox *speedLimitEnabled_; QSpinBox *speedLimitKiBps_; QLineEdit *virusScanCommand_; QLineEdit *postDownloadCommand_; QComboBox *duplicatePolicy_; QCheckBox *verifyChecksums_; // Proxy QComboBox *proxyMode_; QLineEdit *proxyHost_; QSpinBox *proxyPort_; QLineEdit *proxyUsername_; QLineEdit *proxyBypassHosts_; QLineEdit *proxyPacUrl_; // Sounds QCheckBox *soundsEnabled_; QLineEdit *soundOnComplete_; QLineEdit *soundOnQueueComplete_; QLineEdit *soundOnError_; }; } // namespace velox::gui