diff --git a/desktop/CMakeLists.txt b/desktop/CMakeLists.txt --- a/desktop/CMakeLists.txt +++ b/desktop/CMakeLists.txt @@ -24,6 +24,10 @@ FILES spectacle_shortcuts.upd DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR} ) +install( + FILES spectacle_newConfig.upd + DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR} +) add_executable(spectacle-migrate-shortcuts MigrateShortcuts.cpp) target_link_libraries(spectacle-migrate-shortcuts Qt5::DBus KF5::GlobalAccel KF5::ConfigCore KF5::XmlGui KF5::I18n) install( diff --git a/desktop/spectacle_newConfig.upd b/desktop/spectacle_newConfig.upd new file mode 100644 --- /dev/null +++ b/desktop/spectacle_newConfig.upd @@ -0,0 +1,23 @@ +Version=5 +Id=spectacle-new-config +File=spectaclerc +Group=GuiConfig,General +Key=showMagnifier +Key=useReleaseToCapture +Key=useLightMaskColour +Key=rememberLastRectangularRegion +Key=alwaysRememberRegion +Key=printKeyActionRunning +Group=GuiConfig,Save +Key=compressionQuality +Key=lastUsedSaveMode +Group=General,Save +Key=copySaveLocation +Key=lastSaveAsFile,lastSaveAsLocation +Key=lastSaveFile,lastSaveLocation +Key=save-filename-format,saveFilenameFormat +Key=default-save-location,defaultSaveLocation +Key=default-save-image-format,defaultSaveImageFormat +Group=GuiConfig +Key=captureModeIndex,captureMode + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,23 +26,24 @@ Main.cpp ExportManager.cpp SpectacleCore.cpp - SpectacleConfig.cpp SpectacleDBusAdapter.cpp + ShortcutActions.cpp ${SPECTACLE_SRCS_PLATFORM} Gui/KSMainWindow.cpp Gui/KSWidget.cpp Gui/KSImageWidget.cpp Gui/ExportMenu.cpp Gui/ProgressButton.cpp Gui/SmartSpinBox.cpp - Gui/SettingsDialog/SettingsDialog.cpp - Gui/SettingsDialog/SettingsPage.cpp Gui/SettingsDialog/SaveOptionsPage.cpp + Gui/SettingsDialog/SettingsDialog.cpp Gui/SettingsDialog/GeneralOptionsPage.cpp Gui/SettingsDialog/ShortcutsOptionsPage.cpp QuickEditor/QuickEditor.cpp ) +kconfig_add_kcfg_files(SPECTACLE_SRCS_DEFAULT Gui/SettingsDialog/settings.kcfgc) + ecm_qt_declare_logging_category(SPECTACLE_SRCS_DEFAULT HEADER spectacle_core_debug.h IDENTIFIER SPECTACLE_CORE_LOG CATEGORY_NAME org.kde.spectacle.core) ecm_qt_declare_logging_category(SPECTACLE_SRCS_DEFAULT HEADER spectacle_gui_debug.h IDENTIFIER SPECTACLE_GUI_LOG CATEGORY_NAME org.kde.spectacle.gui) diff --git a/src/ExportManager.cpp b/src/ExportManager.cpp --- a/src/ExportManager.cpp +++ b/src/ExportManager.cpp @@ -1,4 +1,5 @@ /* This file is part of Spectacle, the KDE screenshot utility + * Copyright 2019 David Redondo * Copyright (C) 2015 Boudhayan Gupta * * This program is free software; you can redistribute it and/or modify @@ -21,6 +22,8 @@ #include "ExportManager.h" +#include "settings.h" + #include #include #include @@ -41,17 +44,15 @@ #include #include -#include "SpectacleConfig.h" + ExportManager::ExportManager(QObject *parent) : QObject(parent), mSavePixmap(QPixmap()), mTempFile(QUrl()), mTempDir(nullptr) { - connect(this, &ExportManager::imageSaved, [](const QUrl &savedAt) { - SpectacleConfig::instance()->setLastSaveFile(savedAt); - }); + connect(this, &ExportManager::imageSaved, &Settings::setLastSaveLocation); } ExportManager::~ExportManager() @@ -119,7 +120,7 @@ QString ExportManager::defaultSaveLocation() const { - QString savePath = SpectacleConfig::instance()->defaultSaveLocation().toLocalFile(); + QString savePath = Settings::self()->defaultSaveLocation().toLocalFile(); savePath = QDir::cleanPath(savePath); QDir savePathDir(savePath); @@ -136,7 +137,7 @@ const QDir baseDirPath(baseDir); const QString filename = makeAutosaveFilename(); const QString fullpath = autoIncrementFilename(baseDirPath.filePath(filename), - SpectacleConfig::instance()->saveImageFormat(), + Settings::self()->defaultSaveImageFormat(), &ExportManager::isFileExists); const QUrl fileNameUrl = QUrl::fromUserInput(fullpath); @@ -160,7 +161,7 @@ QString ExportManager::makeAutosaveFilename() { - return formatFilename(SpectacleConfig::instance()->autoSaveFilenameFormat()); + return formatFilename(Settings::self()->saveFilenameFormat()); } QString ExportManager::formatFilename(const QString &nameTemplate) @@ -245,7 +246,7 @@ } if (result.isEmpty()) { - result = SpectacleConfig::instance()->defaultFilename(); + result = QStringLiteral("Screenshot"); } return truncatedFilename(result); } @@ -279,15 +280,15 @@ QString type = mimedb.mimeTypeForUrl(url).preferredSuffix(); if (type.isEmpty()) { - return SpectacleConfig::instance()->saveImageFormat(); + return Settings::self()->defaultSaveImageFormat(); } return type; } bool ExportManager::writeImage(QIODevice *device, const QByteArray &format) { QImageWriter imageWriter(device, format); - imageWriter.setQuality(SpectacleConfig::instance()->compressionQuality()); + imageWriter.setQuality(Settings::self()->compressionQuality()); /** Set compression 50 if the format is png. Otherwise if no compression value is specified * it will fallback to using quality (QTBUG-43618) and produce huge files. * See also qpnghandler.cpp#n1075. The other formats that do compression seem to have it @@ -454,7 +455,6 @@ if (save(savePath)) { QDir dir(savePath.path()); dir.cdUp(); - SpectacleConfig::instance()->setLastSaveFile(savePath); emit imageSaved(savePath); if (notify) { @@ -466,21 +466,20 @@ bool ExportManager::doSaveAs(QWidget *parentWindow, bool notify) { QStringList supportedFilters; - SpectacleConfig *config = SpectacleConfig::instance(); // construct the supported mimetype list const auto mimeTypes = QImageWriter::supportedMimeTypes(); for (const auto &mimeType : mimeTypes) { supportedFilters.append(QString::fromUtf8(mimeType).trimmed()); } // construct the file name - const QString filenameExtension = SpectacleConfig::instance()->saveImageFormat(); - const QString mimetype = QMimeDatabase().mimeTypeForFile(QLatin1String("~/fakefile.") + filenameExtension, QMimeDatabase::MatchExtension).name(); + const QString filenameExtension = Settings::self()->defaultSaveImageFormat(); + const QString mimetype = QMimeDatabase().mimeTypeForFile(QStringLiteral("~/fakefile.") + filenameExtension, QMimeDatabase::MatchExtension).name(); QFileDialog dialog(parentWindow); dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setFileMode(QFileDialog::AnyFile); - dialog.setDirectoryUrl(config->lastSaveAsLocation()); + dialog.setDirectoryUrl(Settings::self()->lastSaveAsLocation()); dialog.selectFile(makeAutosaveFilename() + QStringLiteral(".") + filenameExtension); dialog.setDefaultSuffix(QStringLiteral(".") + filenameExtension); dialog.setMimeTypeFilters(supportedFilters); @@ -492,8 +491,7 @@ if (saveUrl.isValid()) { if (save(saveUrl)) { emit imageSaved(saveUrl); - config->setLastSaveAsFile(saveUrl); - + Settings::setLastSaveAsLocation(saveUrl); if (notify) { emit forceNotify(saveUrl); } @@ -515,15 +513,14 @@ if (save(savePath)) { QDir dir(savePath.path()); dir.cdUp(); - SpectacleConfig::instance()->setLastSaveFile(savePath); + Settings::setLastSaveLocation(savePath); doCopyToClipboard(false); emit imageSavedAndCopied(savePath); } } // misc helpers - void ExportManager::doCopyToClipboard(bool notify) { auto data = new QMimeData(); diff --git a/src/Gui/KSMainWindow.h b/src/Gui/KSMainWindow.h --- a/src/Gui/KSMainWindow.h +++ b/src/Gui/KSMainWindow.h @@ -31,7 +31,7 @@ #include #include "SpectacleCommon.h" -#include "SpectacleConfig.h" + #include "KSWidget.h" #include "ExportMenu.h" #include "Platforms/Platform.h" diff --git a/src/Gui/KSMainWindow.cpp b/src/Gui/KSMainWindow.cpp --- a/src/Gui/KSMainWindow.cpp +++ b/src/Gui/KSMainWindow.cpp @@ -23,7 +23,11 @@ #include "KSMainWindow.h" #include "Config.h" +#include "settings.h" #include "SettingsDialog/SettingsDialog.h" +#include "SettingsDialog/GeneralOptionsPage.h" +#include "SettingsDialog/SaveOptionsPage.h" +#include "SettingsDialog/ShortcutsOptionsPage.h" #include #include @@ -47,7 +51,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -174,7 +181,7 @@ // the tools menu mToolsMenu->addAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), - i18n("Open Screenshots Folder"), + i18n("Open Default Screenshots Folder"), this, &KSMainWindow::openScreenshotsFolder); mToolsMenu->addAction(KStandardAction::print(this, &KSMainWindow::showPrintDialog, this)); mScreenRecorderToolsMenu = mToolsMenu->addMenu(i18n("Record Screen")); @@ -228,11 +235,11 @@ // message: open containing folder mOpenContaining = new QAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), i18n("Open Containing Folder"), mMessageWidget); - connect(mOpenContaining, &QAction::triggered, [=] { KIO::highlightInFileManager({SpectacleConfig::instance()->lastSaveFile()});}); + connect(mOpenContaining, &QAction::triggered, [=] { KIO::highlightInFileManager({Settings::lastSaveLocation()});}); mHideMessageWidgetTimer = new QTimer(this); - connect(mHideMessageWidgetTimer, &QTimer::timeout, - mMessageWidget, &KMessageWidget::animatedHide); +// connect(mHideMessageWidgetTimer, &QTimer::timeout, +// mMessageWidget, &KMessageWidget::animatedHide); mHideMessageWidgetTimer->setInterval(10000); // done with the init } @@ -249,19 +256,17 @@ int alignedWindowWidth = qMin(mKSWidget->imagePaddingWidth() + imageWidth, MAXIMUM_WINDOW_WIDTH); alignedWindowWidth += layout()->contentsMargins().left() + layout()->contentsMargins().right(); alignedWindowWidth += 2; // margins is removing 1 - 1 pixel for some reason - return alignedWindowWidth; } void KSMainWindow::setDefaultSaveAction() { - switch (SpectacleConfig::instance()->lastUsedSaveMode()) { - case SaveMode::SaveAs: - default: + switch (Settings::lastUsedSaveMode()) { + case Settings::SaveAs: mSaveButton->setDefaultAction(mSaveAsAction); mSaveButton->setText(i18n("Save As...")); break; - case SaveMode::Save: + case Settings::Save: mSaveButton->setDefaultAction(mSaveAction); break; } @@ -367,31 +372,7 @@ void KSMainWindow::openScreenshotsFolder() { - // Highlight last screenshot in file manager if user saved at least once ever - // (since last save and saveas file names are stored in spectaclerc), otherwise, - // if in save mode, open default save location from configure > save > location - // if in save as mode, open last save as files location - // failsafe for either option is default save location from configure > save > location - SpectacleConfig *cfgManager = SpectacleConfig::instance(); - ExportManager *exportManager = ExportManager::instance(); - QUrl location; - - switch(cfgManager->lastUsedSaveMode()) { - case SaveMode::Save: - location = cfgManager->lastSaveFile(); - if (!exportManager->isFileExists(location)) { - location = cfgManager->defaultSaveLocation(); - } - break; - case SaveMode::SaveAs: - location = cfgManager->lastSaveAsFile(); // already has a "/" at the end - if (!exportManager->isFileExists(location)) { - location = cfgManager->lastSaveAsLocation(); - } - break; - } - - KIO::highlightInFileManager({location}); + new KRun(Settings::defaultSaveLocation(), this); } void KSMainWindow::quit(const QuitBehavior quitBehavior) @@ -464,7 +445,7 @@ void KSMainWindow::copy() { - const bool quitChecked = SpectacleConfig::instance()->quitAfterSaveOrCopyChecked(); + const bool quitChecked = Settings::quitAfterSaveCopyExport(); ExportManager::instance()->doCopyToClipboard(); if (quitChecked) { quit(QuitBehavior::QuitExternally); @@ -479,8 +460,10 @@ void KSMainWindow::showPreferencesDialog() { - SettingsDialog prefDialog(this); - prefDialog.exec(); + if (KConfigDialog::showDialog(QStringLiteral("settings"))) { + return; + } + (new SettingsDialog(this))->show(); } void KSMainWindow::imageSaved(const QUrl &location) @@ -503,22 +486,22 @@ void KSMainWindow::save() { - SpectacleConfig::instance()->setLastUsedSaveMode(SaveMode::Save); + Settings::setLastUsedSaveMode(Settings::Save); setDefaultSaveAction(); - const bool quitChecked = SpectacleConfig::instance()->quitAfterSaveOrCopyChecked(); + const bool quitChecked = Settings::quitAfterSaveCopyExport(); ExportManager::instance()->doSave(QUrl(), /* notify */ quitChecked); if (quitChecked) { quit(QuitBehavior::QuitExternally); } } void KSMainWindow::saveAs() { - SpectacleConfig::instance()->setLastUsedSaveMode(SaveMode::SaveAs); + Settings::setLastUsedSaveMode(Settings::SaveAs); setDefaultSaveAction(); - const bool quitChecked = SpectacleConfig::instance()->quitAfterSaveOrCopyChecked(); + const bool quitChecked = Settings::quitAfterSaveCopyExport(); if (ExportManager::instance()->doSaveAs(this, /* notify */ quitChecked) && quitChecked) { quit(QuitBehavior::QuitExternally); } @@ -529,7 +512,7 @@ if (isWindowModified()) { setWindowTitle(i18nc("@title:window Unsaved Screenshot", "Unsaved[*]")); } else { - setWindowTitle(SpectacleConfig::instance()->lastSaveFile().fileName()); + setWindowTitle(Settings::lastSaveLocation().fileName()); } } diff --git a/src/Gui/KSWidget.cpp b/src/Gui/KSWidget.cpp --- a/src/Gui/KSWidget.cpp +++ b/src/Gui/KSWidget.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2019 David Redondo * Copyright (C) 2015 Boudhayan Gupta * * This program is free software; you can redistribute it and/or modify @@ -21,8 +22,8 @@ #include "spectacle_gui_debug.h" #include "KSImageWidget.h" +#include "settings.h" #include "SmartSpinBox.h" -#include "SpectacleConfig.h" #include "ProgressButton.h" #include @@ -40,9 +41,6 @@ KSWidget::KSWidget(const Platform::GrabModes &theGrabModes, QWidget *parent) : QWidget(parent) { - // get a handle to the configuration manager - SpectacleConfig *lConfigMgr = SpectacleConfig::instance(); - // we'll init the widget that holds the image first mImageWidget = new KSImageWidget(this); mImageWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -55,19 +53,25 @@ ? i18n("Full Screen") : i18n("Full Screen (All Monitors)"); - if (theGrabModes.testFlag(Platform::GrabMode::AllScreens)) - mCaptureArea->insertItem(1, lFullScreenLabel, Spectacle::CaptureMode::AllScreens); - if (theGrabModes.testFlag(Platform::GrabMode::CurrentScreen)) + if (theGrabModes.testFlag(Platform::GrabMode::AllScreens)) { + mCaptureArea->insertItem(0, lFullScreenLabel, Spectacle::CaptureMode::AllScreens); + mCaptureArea->insertItem(1, i18n("Rectangular Region"), Spectacle::CaptureMode::RectangularRegion); + } + if (theGrabModes.testFlag(Platform::GrabMode::CurrentScreen)) { mCaptureArea->insertItem(2, i18n("Current Screen"), Spectacle::CaptureMode::CurrentScreen); - if (theGrabModes.testFlag(Platform::GrabMode::ActiveWindow)) + } + if (theGrabModes.testFlag(Platform::GrabMode::ActiveWindow)) { mCaptureArea->insertItem(3, i18n("Active Window"), Spectacle::CaptureMode::ActiveWindow); - if (theGrabModes.testFlag(Platform::GrabMode::WindowUnderCursor)) + } + if (theGrabModes.testFlag(Platform::GrabMode::WindowUnderCursor)) { mCaptureArea->insertItem(4, i18n("Window Under Cursor"), Spectacle::CaptureMode::WindowUnderCursor); + } if (theGrabModes.testFlag(Platform::GrabMode::TransientWithParent)) { mTransientWithParentAvailable = true; } - mCaptureArea->insertItem(5, i18n("Rectangular Region"), Spectacle::CaptureMode::RectangularRegion); mCaptureArea->setMinimumWidth(240); + int index = mCaptureArea->findData(Settings::captureMode()); + mCaptureArea->setCurrentIndex(index >= 0 ? index : 0); connect(mCaptureArea, qOverload(&QComboBox::currentIndexChanged), this, &KSWidget::captureModeChanged); mDelayMsec = new SmartSpinBox(this); @@ -77,12 +81,12 @@ mDelayMsec->setMaximum(999.9); mDelayMsec->setSpecialValueText(i18n("No Delay")); mDelayMsec->setMinimumWidth(160); - connect(mDelayMsec, qOverload(&SmartSpinBox::valueChanged), lConfigMgr, &SpectacleConfig::setCaptureDelay); + connect(mDelayMsec, qOverload(&SmartSpinBox::valueChanged), &Settings::setCaptureDelay); mCaptureOnClick = new QCheckBox(i18n("On Click"), this); mCaptureOnClick->setToolTip(i18n("Wait for a mouse click before capturing the screenshot image")); connect(mCaptureOnClick, &QCheckBox::stateChanged, this, &KSWidget::onClickStateChanged); - connect(mCaptureOnClick, &QCheckBox::clicked, lConfigMgr, &SpectacleConfig::setOnClickChecked); + connect(mCaptureOnClick, &QCheckBox::clicked, &Settings::setOnClickChecked); mDelayLayout = new QHBoxLayout; mDelayLayout->addWidget(mDelayMsec); @@ -99,22 +103,22 @@ mMousePointer = new QCheckBox(i18n("Include mouse pointer"), this); mMousePointer->setToolTip(i18n("Show the mouse cursor in the screenshot image")); - connect(mMousePointer, &QCheckBox::clicked, lConfigMgr, &SpectacleConfig::setIncludePointerChecked); + connect(mMousePointer, &QCheckBox::clicked, &Settings::setIncludePointer); mWindowDecorations = new QCheckBox(i18n("Include window titlebar and borders"), this); mWindowDecorations->setToolTip(i18n("Show the window title bar, the minimize/maximize/close buttons, and the window border")); mWindowDecorations->setEnabled(false); - connect(mWindowDecorations, &QCheckBox::clicked, lConfigMgr, &SpectacleConfig::setIncludeDecorationsChecked); + connect(mWindowDecorations, &QCheckBox::clicked, &Settings::setIncludeDecorations); mCaptureTransientOnly = new QCheckBox(i18n("Capture the current pop-up only"), this); mCaptureTransientOnly->setToolTip(i18n("Capture only the current pop-up window (like a menu, tooltip etc).\n" "If disabled, the pop-up is captured along with the parent window")); mCaptureTransientOnly->setEnabled(false); - connect(mCaptureTransientOnly, &QCheckBox::clicked, lConfigMgr, &SpectacleConfig::setCaptureTransientWindowOnlyChecked); + connect(mCaptureTransientOnly, &QCheckBox::clicked, &Settings::setTransientOnly); mQuitAfterSaveOrCopy = new QCheckBox(i18n("Quit after manual Save or Copy"), this); mQuitAfterSaveOrCopy->setToolTip(i18n("Quit Spectacle after manually saving or copying the image")); - connect(mQuitAfterSaveOrCopy, &QCheckBox::clicked, lConfigMgr, &SpectacleConfig::setQuitAfterSaveOrCopyChecked); + connect(mQuitAfterSaveOrCopy, &QCheckBox::clicked, &Settings::setQuitAfterSaveCopyExport); mContentOptionsForm = new QVBoxLayout; mContentOptionsForm->addWidget(mMousePointer); @@ -160,15 +164,12 @@ mMainLayout->setColumnMinimumWidth(1, 320); // and read in the saved checkbox states and capture mode indices - mMousePointer->setChecked (lConfigMgr->includePointerChecked()); - mWindowDecorations->setChecked (lConfigMgr->includeDecorationsChecked()); - mCaptureOnClick->setChecked (lConfigMgr->onClickChecked()); - mCaptureTransientOnly->setChecked (lConfigMgr->captureTransientWindowOnlyChecked()); - mQuitAfterSaveOrCopy->setChecked (lConfigMgr->quitAfterSaveOrCopyChecked()); - if (lConfigMgr->captureMode() >= 0) { - mCaptureArea->setCurrentIndex (lConfigMgr->captureMode()); - } - mDelayMsec->setValue (lConfigMgr->captureDelay()); + mMousePointer->setChecked(Settings::includePointer()); + mWindowDecorations->setChecked(Settings::includeDecorations()); + mCaptureOnClick->setChecked(Settings::onClickChecked()); + mCaptureTransientOnly->setChecked(Settings::transientOnly()); + mQuitAfterSaveOrCopy->setChecked(Settings::quitAfterSaveCopyExport()); + mDelayMsec->setValue(Settings::captureDelay()); } int KSWidget::imagePaddingWidth() const @@ -234,11 +235,10 @@ void KSWidget::captureModeChanged(int theIndex) { - SpectacleConfig::instance()->setCaptureMode(theIndex); - + Spectacle::CaptureMode captureMode = static_cast(mCaptureArea->itemData(theIndex).toInt()); + Settings::setCaptureMode(captureMode); - Spectacle::CaptureMode lCaptureMode = static_cast(mCaptureArea->itemData(theIndex).toInt()); - switch(lCaptureMode) { + switch(captureMode) { case Spectacle::CaptureMode::WindowUnderCursor: mWindowDecorations->setEnabled(true); if (mTransientWithParentAvailable) { diff --git a/src/Gui/SettingsDialog/GeneralOptionsPage.h b/src/Gui/SettingsDialog/GeneralOptionsPage.h --- a/src/Gui/SettingsDialog/GeneralOptionsPage.h +++ b/src/Gui/SettingsDialog/GeneralOptionsPage.h @@ -20,39 +20,15 @@ #ifndef GENERALOPTIONSPAGE_H #define GENERALOPTIONSPAGE_H -#include "SettingsPage.h" +#include -class QButtonGroup; -class QCheckBox; -class QRadioButton; - -class GeneralOptionsPage : public SettingsPage +class GeneralOptionsPage : public QWidget { Q_OBJECT public: explicit GeneralOptionsPage(QWidget *parent = nullptr); - - public Q_SLOTS: - - void saveChanges() override; - void resetChanges() override; - - private Q_SLOTS: - - void markDirty(); - - private: - - QButtonGroup *mPrintKeyActionGroup; - QRadioButton *mRememberAlways; - QRadioButton *mRememberUntilClosed; - QCheckBox *mCopyImageToClipboard; - QCheckBox *mAutoSaveImage; - QCheckBox *mUseLightBackground; - QCheckBox *mShowMagnifier; - QCheckBox *mReleaseToCapture; }; #endif // GENERALOPTIONSPAGE_H diff --git a/src/Gui/SettingsDialog/GeneralOptionsPage.cpp b/src/Gui/SettingsDialog/GeneralOptionsPage.cpp --- a/src/Gui/SettingsDialog/GeneralOptionsPage.cpp +++ b/src/Gui/SettingsDialog/GeneralOptionsPage.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2019 David Redondo * Copyright (C) 2015 Boudhayan Gupta * * This program is free software; you can redistribute it and/or modify @@ -19,20 +20,20 @@ #include "GeneralOptionsPage.h" -#include "SpectacleConfig.h" - #include #include #include #include #include +#include #include #include #include +#include GeneralOptionsPage::GeneralOptionsPage(QWidget *parent) : - SettingsPage(parent) + QWidget{parent} { QFormLayout *mainLayout = new QFormLayout(this); setLayout(mainLayout); @@ -44,30 +45,49 @@ mainLayout->addRow(runningTitle); QRadioButton* takeNew = new QRadioButton(i18n("Take a new screenshot"), this); QRadioButton* startNewInstance = new QRadioButton(i18n("Open a new Spectacle window"), this); - mPrintKeyActionGroup = new QButtonGroup(this); - mPrintKeyActionGroup->setExclusive(true); - mPrintKeyActionGroup->addButton(takeNew, SpectacleConfig::PrintKeyActionRunning::TakeNewScreenshot); - mPrintKeyActionGroup->addButton(startNewInstance, SpectacleConfig::PrintKeyActionRunning::StartNewInstance); - connect( mPrintKeyActionGroup, qOverload(&QButtonGroup::buttonToggled), this, &GeneralOptionsPage::markDirty); + QButtonGroup* printKeyActionGroup = new QButtonGroup(this); + printKeyActionGroup->setExclusive(true); + printKeyActionGroup->addButton(takeNew,0);// SpectacleConfig::PrintKeyActionRunning::TakeNewScreenshot); + printKeyActionGroup->addButton(startNewInstance,1);// SpectacleConfig::PrintKeyActionRunning::StartNewInstance); mainLayout->addRow(i18n("Press screenshot key to:"), takeNew); mainLayout->addRow(QString(), startNewInstance); //On Wayland we can't programmatically raise and focus the window so we have to hide the option if (!(KWindowSystem::isPlatformWayland() || qstrcmp(qgetenv("XDG_SESSION_TYPE"), "wayland") == 0)) { QRadioButton* focusWindow = new QRadioButton(i18n("Return focus to Spectacle"), this); - mPrintKeyActionGroup->addButton( focusWindow, SpectacleConfig::PrintKeyActionRunning::FocusWindow); + printKeyActionGroup->addButton( focusWindow,2);// SpectacleConfig::PrintKeyActionRunning::FocusWindow); mainLayout->addRow(QString(), focusWindow); } + //Workaround because KConfigWidgets doesn't support QButtonGroup (Bug 409037) + auto workaroundLabel = new QLineEdit(this); + workaroundLabel->setHidden(true); + workaroundLabel->setObjectName(QStringLiteral("kcfg_printKeyActionRunning")); + // Need to check default Button because we get no change event for that + takeNew->setChecked(true); + connect(workaroundLabel, &QLineEdit::textChanged, + printKeyActionGroup, [printKeyActionGroup, takeNew](const QString& text){ + auto button = printKeyActionGroup->button(text.toInt()); + // We are missing a button on Wayland + button ? button->setChecked(true) : takeNew->setChecked(true); + }); + connect(printKeyActionGroup, qOverload(&QButtonGroup::buttonToggled), + workaroundLabel, [workaroundLabel] (int value, bool checked) { + if (checked) { + workaroundLabel->setText(QString::number(value)); + } + }); + // /Workaround + mainLayout->addItem(new QSpacerItem(0, 18, QSizePolicy::Fixed, QSizePolicy::Fixed)); // actions to take after taking a screenshot - mCopyImageToClipboard = new QCheckBox(i18n("Copy image to clipboard"), this); - connect(mCopyImageToClipboard, &QCheckBox::toggled, this, &GeneralOptionsPage::markDirty); - mainLayout->addRow(i18n("After taking a screenshot:"), mCopyImageToClipboard); + auto copyImageToClipboard = new QCheckBox(i18n("Copy image to clipboard"), this); + copyImageToClipboard->setObjectName(QStringLiteral("kcfg_copyImageToClipboard")); + mainLayout->addRow(i18n("After taking a screenshot:"), copyImageToClipboard); - mAutoSaveImage = new QCheckBox(i18n("Autosave the image to the default location"), this); - connect(mAutoSaveImage, &QCheckBox::toggled, this, &GeneralOptionsPage::markDirty); - mainLayout->addRow(QString(), mAutoSaveImage); + auto autoSaveImage = new QCheckBox(i18n("Autosave the image to the default location"), this); + autoSaveImage->setObjectName(QStringLiteral("kcfg_autoSaveImage")); + mainLayout->addRow(QString(), autoSaveImage); mainLayout->addItem(new QSpacerItem(0, 18, QSizePolicy::Fixed, QSizePolicy::Fixed)); @@ -78,74 +98,35 @@ mainLayout->addRow(titleWidget); // use light background - mUseLightBackground = new QCheckBox(i18n("Use light background"), this); - connect(mUseLightBackground, &QCheckBox::toggled, this, &GeneralOptionsPage::markDirty); - mainLayout->addRow(i18n("General:"), mUseLightBackground); + QCheckBox* kcfg_useLightMaskColour = new QCheckBox(i18n("Use light background"), this); + kcfg_useLightMaskColour->setObjectName(QStringLiteral("kcfg_useLightMaskColour")); + mainLayout->addRow(i18n("General:"), kcfg_useLightMaskColour); // show magnifier - mShowMagnifier = new QCheckBox(i18n("Show magnifier"), this); - connect(mShowMagnifier, &QCheckBox::toggled, this, &GeneralOptionsPage::markDirty); - mainLayout->addRow(QString(), mShowMagnifier); + auto showMagnifier = new QCheckBox(i18n("Show magnifier"), this); + showMagnifier->setObjectName(QStringLiteral("kcfg_showMagnifier")); + mainLayout->addRow(QString(), showMagnifier); // release mouse-button to capture - mReleaseToCapture = new QCheckBox(i18n("Accept on click-and-release"), this); - connect(mReleaseToCapture, &QCheckBox::toggled, this, &GeneralOptionsPage::markDirty); - mainLayout->addRow(QString(), mReleaseToCapture); + auto releaseToCapture = new QCheckBox(i18n("Accept on click-and-release"), this); + releaseToCapture->setObjectName(QStringLiteral("kcfg_useReleaseToCapture")); + mainLayout->addRow(QString(), releaseToCapture); mainLayout->addItem(new QSpacerItem(0, 18, QSizePolicy::Fixed, QSizePolicy::Fixed)); // remember Rectangular Region box QButtonGroup* rememberGroup = new QButtonGroup(this); rememberGroup->setExclusive(true); QRadioButton* neverButton = new QRadioButton(i18n("Never"), this); - mRememberAlways = new QRadioButton(i18n("Always"), this); - mRememberUntilClosed = new QRadioButton(i18n("Until Spectacle is closed"), this); + auto rememberAlways = new QRadioButton(i18n("Always"), this); + rememberAlways->setObjectName(QStringLiteral("kcfg_alwaysRememberRegion")); + auto rememberUntilClosed = new QRadioButton(i18n("Until Spectacle is closed"), this); + rememberUntilClosed->setObjectName(QStringLiteral("kcfg_rememberLastRectangularRegion")); rememberGroup->addButton(neverButton); - rememberGroup->addButton(mRememberAlways); - rememberGroup->addButton(mRememberUntilClosed); - neverButton->setChecked(true); - connect(rememberGroup, qOverload(&QButtonGroup::buttonToggled), this, &GeneralOptionsPage::markDirty); + rememberGroup->addButton(rememberAlways); + rememberGroup->addButton(rememberUntilClosed); mainLayout->addRow(i18n("Remember selected area:"), neverButton); - mainLayout->addRow(QString(), mRememberAlways); - mainLayout->addRow(QString(), mRememberUntilClosed ); - - // read in the data - resetChanges(); -} -void GeneralOptionsPage::markDirty() -{ - mChangesMade = true; -} - -void GeneralOptionsPage::saveChanges() -{ - SpectacleConfig *cfgManager = SpectacleConfig::instance(); - - cfgManager->setUseLightRegionMaskColour(mUseLightBackground->checkState() == Qt::Checked); - cfgManager->setRememberLastRectangularRegion(mRememberUntilClosed->isChecked() || mRememberAlways->isChecked()); - cfgManager->setAlwaysRememberRegion (mRememberAlways->isChecked()); - cfgManager->setShowMagnifierChecked(mShowMagnifier->checkState() == Qt::Checked); - cfgManager->setUseReleaseToCaptureChecked(mReleaseToCapture->checkState() == Qt::Checked); - cfgManager->setPrintKeyActionRunning(static_cast(mPrintKeyActionGroup->checkedId())); - cfgManager->setCopyImageToClipboard(mCopyImageToClipboard->checkState() == Qt::Checked); - cfgManager->setAutoSaveImage(mAutoSaveImage->checkState() == Qt::Checked); - - mChangesMade = false; -} - -void GeneralOptionsPage::resetChanges() -{ - SpectacleConfig *cfgManager = SpectacleConfig::instance(); - - mUseLightBackground->setChecked(cfgManager->useLightRegionMaskColour()); - mRememberUntilClosed->setChecked(cfgManager->rememberLastRectangularRegion()); - mRememberAlways->setChecked(cfgManager->alwaysRememberRegion()); - mShowMagnifier->setChecked(cfgManager->showMagnifierChecked()); - mReleaseToCapture->setChecked(cfgManager->useReleaseToCapture()); - mPrintKeyActionGroup->button(cfgManager->printKeyActionRunning())->setChecked(true); - mCopyImageToClipboard->setChecked(cfgManager->copyImageToClipboard()); - mAutoSaveImage->setChecked(cfgManager->autoSaveImage()); - - mChangesMade = false; + mainLayout->addRow(QString(), rememberAlways); + mainLayout->addRow(QString(), rememberUntilClosed); } diff --git a/src/Gui/SettingsDialog/SaveOptionsPage.h b/src/Gui/SettingsDialog/SaveOptionsPage.h --- a/src/Gui/SettingsDialog/SaveOptionsPage.h +++ b/src/Gui/SettingsDialog/SaveOptionsPage.h @@ -20,42 +20,27 @@ #ifndef SAVEOPTIONSPAGE_H #define SAVEOPTIONSPAGE_H -#include "SettingsPage.h" +#include -class QLineEdit; class QComboBox; -class KUrlRequester; -class QCheckBox; -class QSlider; class QLabel; +class QLineEdit; -class SaveOptionsPage : public SettingsPage +class SaveOptionsPage : public QWidget { Q_OBJECT public: explicit SaveOptionsPage(QWidget *parent = nullptr); - - public Q_SLOTS: - - void saveChanges() override; - void resetChanges() override; - - private Q_SLOTS: - - void markDirty(); - + private: - + + QLineEdit* mSaveNameFormat; + QLabel* mPreviewLabel; + QComboBox* mSaveImageFormat; + void updateFilenamePreview(); - - QLineEdit *mSaveNameFormat; - KUrlRequester *mUrlRequester; - QComboBox *mSaveImageFormat; - QCheckBox *mCopyPathToClipboard; - QSlider *mQualitySlider; - QLabel *mPreviewLabel; }; #endif // SAVEOPTIONSPAGE_H diff --git a/src/Gui/SettingsDialog/SaveOptionsPage.cpp b/src/Gui/SettingsDialog/SaveOptionsPage.cpp --- a/src/Gui/SettingsDialog/SaveOptionsPage.cpp +++ b/src/Gui/SettingsDialog/SaveOptionsPage.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2019 David Redondo * Copyright (C) 2015 Boudhayan Gupta * * This program is free software; you can redistribute it and/or modify @@ -20,7 +21,6 @@ #include "SaveOptionsPage.h" #include "SpectacleCommon.h" -#include "SpectacleConfig.h" #include "ExportManager.h" #include @@ -35,52 +35,49 @@ #include #include -SaveOptionsPage::SaveOptionsPage(QWidget *parent) : - SettingsPage(parent) +SaveOptionsPage::SaveOptionsPage(QWidget *parent) : QWidget(parent) { QFormLayout *mainLayout = new QFormLayout; setLayout(mainLayout); // Save location - mUrlRequester = new KUrlRequester; - mUrlRequester->setMode(KFile::Directory); - connect(mUrlRequester, &KUrlRequester::textChanged, this, &SaveOptionsPage::markDirty); - mainLayout->addRow(i18n("Save Location:"), mUrlRequester); + auto urlRequester = new KUrlRequester(this); + urlRequester->setObjectName(QStringLiteral("kcfg_defaultSaveLocation")); + urlRequester->setMode(KFile::Directory); + mainLayout->addRow(i18n("Save Location:"), urlRequester); // copy file location to clipboard after saving - mCopyPathToClipboard = new QCheckBox(i18n("Copy file location to clipboard after saving"), this); - connect(mCopyPathToClipboard, &QCheckBox::toggled, this, &SaveOptionsPage::markDirty); - mainLayout->addRow(QString(), mCopyPathToClipboard); + auto copyPathToClipboard = new QCheckBox(i18n("Copy file location to clipboard after saving"), this); + copyPathToClipboard->setObjectName(QStringLiteral("kcfg_copySaveLocation")); + mainLayout->addRow(QString(), copyPathToClipboard); mainLayout->addItem(new QSpacerItem(0, 18, QSizePolicy::Fixed, QSizePolicy::Fixed)); // Compression quality slider and current value display - QHBoxLayout *sliderHorizLayout = new QHBoxLayout(); - QVBoxLayout *sliderVertLayout = new QVBoxLayout(); + QHBoxLayout *sliderHorizLayout = new QHBoxLayout(this); + QVBoxLayout *sliderVertLayout = new QVBoxLayout(this); // Current value - QSpinBox *mQualitySpinner = new QSpinBox(); - mQualitySpinner->setSuffix(QString::fromUtf8("%")); - mQualitySpinner->setRange(0, 100); - mQualitySpinner->setValue(SpectacleConfig::instance()->compressionQuality()); - connect(mQualitySpinner, QOverload::of(&QSpinBox::valueChanged), this, [=] (int value) {mQualitySlider->setValue(value);}); + auto qualitySpinner = new QSpinBox(this); + qualitySpinner->setSuffix(QString::fromUtf8("%")); + qualitySpinner->setRange(0, 100); + qualitySpinner->setObjectName(QStringLiteral("kcfg_compressionQuality")); // Slider - mQualitySlider = new QSlider(Qt::Horizontal); - mQualitySlider->setRange(0, 100); - mQualitySlider->setSliderPosition(SpectacleConfig::instance()->compressionQuality()); - mQualitySlider->setTracking(true); - connect(mQualitySlider, &QSlider::valueChanged, this, [=](int value) { - mQualitySpinner->setValue(value); - markDirty(); + auto qualitySlider = new QSlider(Qt::Horizontal, this); + qualitySlider->setRange(0, 100); + qualitySlider->setSliderPosition(qualitySpinner->value()); + qualitySlider->setTracking(true); + connect(qualitySlider, &QSlider::valueChanged, this, [=](int value) { + qualitySpinner->setValue(value); }); - - sliderHorizLayout->addWidget(mQualitySlider); - sliderHorizLayout->addWidget(mQualitySpinner); + connect(qualitySpinner, QOverload::of(&QSpinBox::valueChanged), this, [=] (int value) {qualitySlider->setValue(value);}); + sliderHorizLayout->addWidget(qualitySlider); + sliderHorizLayout->addWidget(qualitySpinner); sliderVertLayout->addLayout(sliderHorizLayout); - QLabel *qualitySliderDescription = new QLabel(); + QLabel *qualitySliderDescription = new QLabel(this); qualitySliderDescription->setText(i18n("Choose the image quality when saving with lossy image formats like JPEG")); sliderVertLayout->addWidget(qualitySliderDescription); @@ -90,9 +87,10 @@ mainLayout->addItem(new QSpacerItem(0, 18, QSizePolicy::Fixed, QSizePolicy::Fixed)); // filename chooser text field - QHBoxLayout *saveFieldLayout = new QHBoxLayout; - mSaveNameFormat = new QLineEdit; - connect(mSaveNameFormat, &QLineEdit::textEdited, this, &SaveOptionsPage::markDirty); + QHBoxLayout *saveFieldLayout = new QHBoxLayout(this); + mSaveNameFormat = new QLineEdit(this); + mSaveNameFormat->setObjectName(QStringLiteral("kcfg_saveFilenameFormat")); + connect(mSaveNameFormat, &QLineEdit::textEdited, this, [&](const QString &newText) { QString fmt; const auto imageFormats = QImageWriter::supportedImageFormats(); @@ -110,16 +108,17 @@ mSaveNameFormat->setPlaceholderText(QStringLiteral("%d")); saveFieldLayout->addWidget(mSaveNameFormat); - mSaveImageFormat = new QComboBox; + mSaveImageFormat = new QComboBox(this); + mSaveImageFormat->setObjectName(QStringLiteral("kcfg_defaultSaveImageFormat")); + mSaveImageFormat->setProperty("kcfg_property", QByteArray("currentText")); mSaveImageFormat->addItems([&](){ QStringList items; const auto formats = QImageWriter::supportedImageFormats(); for (const auto &fmt : formats) { items.append(QString::fromLocal8Bit(fmt).toUpper()); } return items; }()); - connect(mSaveImageFormat, &QComboBox::currentTextChanged, this, &SaveOptionsPage::markDirty); connect(mSaveImageFormat, &QComboBox::currentTextChanged, this, &SaveOptionsPage::updateFilenamePreview); saveFieldLayout->addWidget(mSaveImageFormat); mainLayout->addRow(i18n("Filename:"), saveFieldLayout); @@ -146,60 +145,6 @@ mSaveNameFormat->insert(placeholder); }); mainLayout->addWidget(fmtHelpText); - - // read in the data - resetChanges(); -} - -void SaveOptionsPage::markDirty() -{ - mChangesMade = true; -} - -void SaveOptionsPage::saveChanges() -{ - // bring up the configuration reader - - SpectacleConfig *cfgManager = SpectacleConfig::instance(); - - // save the data - - cfgManager->setDefaultSaveLocation(mUrlRequester->url()); - cfgManager->setAutoSaveFilenameFormat(mSaveNameFormat->text()); - cfgManager->setSaveImageFormat(mSaveImageFormat->currentText().toLower()); - cfgManager->setCopySaveLocationToClipboard(mCopyPathToClipboard->checkState() == Qt::Checked); - cfgManager->setCompressionQuality(mQualitySlider->value()); - - // done - - mChangesMade = false; -} - -void SaveOptionsPage::resetChanges() -{ - // bring up the configuration reader - - SpectacleConfig *cfgManager = SpectacleConfig::instance(); - - // read in the data - - mSaveNameFormat->setText(cfgManager->autoSaveFilenameFormat()); - mUrlRequester->setUrl(cfgManager->defaultSaveLocation()); - mCopyPathToClipboard->setChecked(cfgManager->copySaveLocationToClipboard()); - mQualitySlider->setSliderPosition(cfgManager->compressionQuality()); - - // read in the save image format and calculate its index - - { - int index = mSaveImageFormat->findText(cfgManager->saveImageFormat().toUpper()); - if (index >= 0) { - mSaveImageFormat->setCurrentIndex(index); - } - } - - // done - - mChangesMade = false; } void SaveOptionsPage::updateFilenamePreview() diff --git a/src/Gui/SettingsDialog/SettingsDialog.h b/src/Gui/SettingsDialog/SettingsDialog.h --- a/src/Gui/SettingsDialog/SettingsDialog.h +++ b/src/Gui/SettingsDialog/SettingsDialog.h @@ -20,31 +20,27 @@ #ifndef SETTINGSDIALOG_H #define SETTINGSDIALOG_H -#include -#include +#include -class KPageWidgetItem; +class ShortcutsOptionsPage; -class SettingsDialog : public KPageDialog +class SettingsDialog : public KConfigDialog { Q_OBJECT public: explicit SettingsDialog(QWidget *parent = nullptr); - public Q_SLOTS: - - void accept() override; - - private Q_SLOTS: - - void initPages(); - void onPageChanged(KPageWidgetItem *current, KPageWidgetItem *before); - private: - QSet mPages; + bool hasChanged() override; + bool isDefault() override; + void updateSettings() override; + void updateWidgets() override; + void updateWidgetsDefault() override; + + ShortcutsOptionsPage* mShortcutsPage; }; #endif // SETTINGSDIALOG_H diff --git a/src/Gui/SettingsDialog/SettingsDialog.cpp b/src/Gui/SettingsDialog/SettingsDialog.cpp --- a/src/Gui/SettingsDialog/SettingsDialog.cpp +++ b/src/Gui/SettingsDialog/SettingsDialog.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2019 David Redondo * Copyright (C) 2015 Boudhayan Gupta * * This program is free software; you can redistribute it and/or modify @@ -21,6 +22,7 @@ #include "GeneralOptionsPage.h" #include "SaveOptionsPage.h" +#include "settings.h" #include "ShortcutsOptionsPage.h" #include @@ -30,66 +32,50 @@ #include SettingsDialog::SettingsDialog(QWidget *parent) : - KPageDialog(parent) + KConfigDialog(parent, QStringLiteral("settings"), Settings::self()) { - // set up window options and geometry - setWindowTitle(i18nc("@title:window", "Configure")); - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - resize(600, 550); - setFaceType(List); - - // init all pages - QMetaObject::invokeMethod(this, "initPages", Qt::QueuedConnection); + addPage(new GeneralOptionsPage(this), Settings::self(), + i18n("General"), QStringLiteral("spectacle")); + addPage(new SaveOptionsPage(this), Settings::self(), + i18n("Save"), QStringLiteral("document-save")); + mShortcutsPage = new ShortcutsOptionsPage(this); + addPage(mShortcutsPage, i18n("Shortcuts"), QStringLiteral("preferences-desktop-keyboard")); + connect(mShortcutsPage, &ShortcutsOptionsPage::shortCutsChanged, this, [this] { + updateButtons(); + }); + resize(600, 590); + connect(this, &KConfigDialog::currentPageChanged, this, &SettingsDialog::updateButtons); } -void SettingsDialog::initPages() +bool SettingsDialog::hasChanged() { - KPageWidgetItem *generalOptions = new KPageWidgetItem(new GeneralOptionsPage(this), i18n("General")); - generalOptions->setHeader(i18n("General")); - generalOptions->setIcon(QIcon::fromTheme(QStringLiteral("spectacle"))); - addPage(generalOptions); - mPages.insert(generalOptions); - - KPageWidgetItem *saveOptions = new KPageWidgetItem(new SaveOptionsPage(this), i18n("Save")); - saveOptions->setHeader(i18n("Save")); - saveOptions->setIcon(QIcon::fromTheme(QStringLiteral("document-save"))); - addPage(saveOptions); - mPages.insert(saveOptions); - - KPageWidgetItem *shortcutOptions = new KPageWidgetItem(new ShortcutsOptionsPage(this), i18n("Shortcuts")); - shortcutOptions->setHeader(i18n("Shortcuts")); - shortcutOptions->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-keyboard"))); - addPage(shortcutOptions); - mPages.insert(shortcutOptions); + return mShortcutsPage->isModified() || KConfigDialog::hasChanged(); +} - connect(this, &SettingsDialog::currentPageChanged, this, &SettingsDialog::onPageChanged); +bool SettingsDialog::isDefault() +{ + return currentPage()->name() != i18n("Shortcuts") && KConfigDialog::isDefault(); } -void SettingsDialog::accept() +void SettingsDialog::updateSettings() { - for (auto page : qAsConst(mPages)) { - SettingsPage *pageWidget = dynamic_cast(page->widget()); - if (pageWidget) { - pageWidget->saveChanges(); - } - } + KConfigDialog::updateSettings(); + mShortcutsPage->saveChanges(); +} - done(QDialog::Accepted); +void SettingsDialog::updateWidgets() +{ + KConfigDialog::updateWidgets(); + mShortcutsPage->resetChanges(); } -void SettingsDialog::onPageChanged(KPageWidgetItem *current, KPageWidgetItem *before) +void SettingsDialog::updateWidgetsDefault() { - Q_UNUSED(current); + KConfigDialog::updateWidgetsDefault(); + mShortcutsPage->defaults(); +} + + + - SettingsPage *pageWidget = dynamic_cast(before->widget()); - if (pageWidget && (pageWidget->changesMade())) { - QMessageBox::StandardButton response = QMessageBox::question(this, i18n("Apply Unsaved Changes"), - i18n("You have made changes to the settings in this tab. Do you want to apply those changes?")); - if (response == QMessageBox::Yes) { - pageWidget->saveChanges(); - } else { - pageWidget->resetChanges(); - } - } -} diff --git a/src/Gui/SettingsDialog/SettingsPage.h b/src/Gui/SettingsDialog/SettingsPage.h deleted file mode 100644 --- a/src/Gui/SettingsDialog/SettingsPage.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2015 Boudhayan Gupta - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef SETTINGSPAGE_H -#define SETTINGSPAGE_H - -#include - -class SettingsPage : public QWidget -{ - Q_OBJECT - - public: - - explicit SettingsPage(QWidget *parent = nullptr); - virtual ~SettingsPage(); - - public Q_SLOTS: - - virtual void saveChanges() = 0; - virtual void resetChanges() = 0; - bool changesMade(); - - protected: - - bool mChangesMade; -}; - -#endif // SETTINGSPAGE_H diff --git a/src/Gui/SettingsDialog/SettingsPage.cpp b/src/Gui/SettingsDialog/SettingsPage.cpp deleted file mode 100644 --- a/src/Gui/SettingsDialog/SettingsPage.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2015 Boudhayan Gupta - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "SettingsPage.h" - -SettingsPage::SettingsPage(QWidget *parent) : - QWidget(parent), - mChangesMade(false) -{} - -SettingsPage::~SettingsPage() -{} - -bool SettingsPage::changesMade() -{ - return mChangesMade; -} diff --git a/src/Gui/SettingsDialog/ShortcutsOptionsPage.h b/src/Gui/SettingsDialog/ShortcutsOptionsPage.h --- a/src/Gui/SettingsDialog/ShortcutsOptionsPage.h +++ b/src/Gui/SettingsDialog/ShortcutsOptionsPage.h @@ -1,27 +1,48 @@ +/* + * Copyright (C) 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + #ifndef SHORTCUTSOPTIONSPAGE_H #define SHORTCUTSOPTIONSPAGE_H -#include "SettingsPage.h" +#include class KShortcutsEditor; -class ShortcutsOptionsPage : public SettingsPage +class ShortcutsOptionsPage : public QWidget { Q_OBJECT public: - explicit ShortcutsOptionsPage ( QWidget* parent ); + explicit ShortcutsOptionsPage (QWidget* parent); ~ShortcutsOptionsPage(); - public Q_SLOTS: + bool isModified(); + void defaults(); - void saveChanges() override; - void resetChanges() override; + Q_SIGNALS: + void shortCutsChanged(); + + public Q_SLOTS: - private Q_SLOTS: + void saveChanges(); + void resetChanges(); - void markDirty(); private: diff --git a/src/Gui/SettingsDialog/ShortcutsOptionsPage.cpp b/src/Gui/SettingsDialog/ShortcutsOptionsPage.cpp --- a/src/Gui/SettingsDialog/ShortcutsOptionsPage.cpp +++ b/src/Gui/SettingsDialog/ShortcutsOptionsPage.cpp @@ -1,19 +1,36 @@ +/* + * Copyright (C) 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + #include "ShortcutsOptionsPage.h" -#include "SpectacleConfig.h" +#include "ShortcutActions.h" #include #include -ShortcutsOptionsPage::ShortcutsOptionsPage(QWidget* parent) : SettingsPage(parent) +ShortcutsOptionsPage::ShortcutsOptionsPage(QWidget* parent) : QWidget(parent) { QVBoxLayout *mainLayout = new QVBoxLayout(this); setLayout(mainLayout); - - mEditor = new KShortcutsEditor(SpectacleConfig::instance()->shortCutActions, this, KShortcutsEditor::ActionType::GlobalAction); + mEditor = new KShortcutsEditor(ShortcutActions::self()->shortcutActions(), this, KShortcutsEditor::ActionType::GlobalAction); mainLayout->addWidget(mEditor); - connect(mEditor, &KShortcutsEditor::keyChange, this, &ShortcutsOptionsPage::markDirty); + connect(mEditor, &KShortcutsEditor::keyChange, this, &ShortcutsOptionsPage::shortCutsChanged); } ShortcutsOptionsPage::~ShortcutsOptionsPage() @@ -25,17 +42,21 @@ void ShortcutsOptionsPage::resetChanges() { mEditor->undoChanges(); - mChangesMade = false; } void ShortcutsOptionsPage::saveChanges() { mEditor->commit(); - mChangesMade = false; } -void ShortcutsOptionsPage::markDirty() +bool ShortcutsOptionsPage::isModified() +{ + return mEditor->isModified(); +} + +void ShortcutsOptionsPage::defaults() { - mChangesMade = true; + mEditor->allDefault(); } + diff --git a/src/Gui/SettingsDialog/settings.kcfgc b/src/Gui/SettingsDialog/settings.kcfgc new file mode 100644 --- /dev/null +++ b/src/Gui/SettingsDialog/settings.kcfgc @@ -0,0 +1,6 @@ +File=spectacle.kcfg +ClassName=Settings +Singleton=true +Mutators=true +UseEnumTypes=true +GlobalEnums=true diff --git a/src/Gui/SettingsDialog/spectacle.kcfg b/src/Gui/SettingsDialog/spectacle.kcfg new file mode 100644 --- /dev/null +++ b/src/Gui/SettingsDialog/spectacle.kcfg @@ -0,0 +1,124 @@ + + + +QStandardPaths +SpectacleCommon.h + + + + + + + + + + TakeNewScreenshot + + + + false + + + + false + + + + false + + + + false + + + + false + + + + true + + + + false + + + + + + 0,0,0,0 + + + + false + + + + true + + + + true + + + + false + + + + false + + + + 0 + + + + Spectacle::CaptureMode::AllScreens + + + + + + + QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)+QLatin1Char('/')) + + + + + true + + + + 90 + + + + PNG + + + + Screenshot_%Y%M%D_%H%m%S + + + + defaultSaveLocation() + + + + defaultSaveLocation() + + + + + + + + SaveAs + + + diff --git a/src/Main.cpp b/src/Main.cpp --- a/src/Main.cpp +++ b/src/Main.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2019 David Redondo * Copyright (C) 2015 Boudhayan Gupta * * This program is free software; you can redistribute it and/or modify @@ -18,6 +19,7 @@ */ #include "Config.h" +#include "settings.h" #include "SpectacleCommon.h" #include "SpectacleCore.h" #include "SpectacleDBusAdapter.h" @@ -145,7 +147,8 @@ SpectacleCore lCore(lStartMode, lCaptureMode, lFileName, lDelayMsec, lNotify, lCopyToClipboard); QObject::connect(&lCore, &SpectacleCore::allDone, qApp, &QApplication::quit); - + QObject::connect(qApp, &QApplication::aboutToQuit, Settings::self(), &Settings::save); + // create the dbus connections new KDBusService(KDBusService::Multiple, &lCore); diff --git a/src/QuickEditor/QuickEditor.cpp b/src/QuickEditor/QuickEditor.cpp --- a/src/QuickEditor/QuickEditor.cpp +++ b/src/QuickEditor/QuickEditor.cpp @@ -25,7 +25,7 @@ #include #include "QuickEditor.h" -#include "SpectacleConfig.h" +#include "settings.h" const int QuickEditor::handleRadiusMouse = 9; const int QuickEditor::handleRadiusTouch = 12; @@ -71,17 +71,16 @@ mMouseDragState(MouseState::None), mPixmap(thePixmap), mMagnifierAllowed(false), - mShowMagnifier(SpectacleConfig::instance()->showMagnifierChecked()), + mShowMagnifier(Settings::showMagnifier()), mToggleMagnifier(false), - mReleaseToCapture(SpectacleConfig::instance()->useReleaseToCapture()), - mRememberRegion(SpectacleConfig::instance()->alwaysRememberRegion() || SpectacleConfig::instance()->rememberLastRectangularRegion()), + mReleaseToCapture(Settings::useReleaseToCapture()), + mRememberRegion(Settings::alwaysRememberRegion() || Settings::rememberLastRectangularRegion()), mDisableArrowKeys(false), mPrimaryScreenGeo(QGuiApplication::primaryScreen()->geometry()), mbottomHelpLength(bottomHelpMaxLength), mHandleRadius(handleRadiusMouse) { - SpectacleConfig *config = SpectacleConfig::instance(); - if (config->useLightRegionMaskColour()) { + if (Settings::useLightMaskColour()) { mMaskColor = QColor(255, 255, 255, 100); } @@ -104,8 +103,9 @@ plasmashellSurface->setPanelTakesFocus(true); plasmashellSurface->setPosition(geometry().topLeft()); } - if (config->rememberLastRectangularRegion()) { - QRect cropRegion = config->cropRegion(); + if (Settings::rememberLastRectangularRegion() || Settings::alwaysRememberRegion()) { + auto savedRect = Settings::cropRegion(); + QRect cropRegion = QRect(savedRect[0], savedRect[1], savedRect[2], savedRect[3]); if (!cropRegion.isEmpty()) { mSelection = QRectF( cropRegion.x() * dprI, @@ -149,7 +149,7 @@ qRound(mSelection.width() * dpr), qRound(mSelection.height() * dpr) ); - SpectacleConfig::instance()->setCropRegion(scaledCropRegion); + Settings::setCropRegion({scaledCropRegion.x(), scaledCropRegion.y(), scaledCropRegion.width(), scaledCropRegion.height()}); emit grabDone(mPixmap.copy(scaledCropRegion)); } } diff --git a/src/ShortcutActions.h b/src/ShortcutActions.h new file mode 100644 --- /dev/null +++ b/src/ShortcutActions.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef SHORTCUT_ACTIONS_H +#define SHORTCUT_ACTIONS_H + +#include + +class ShortcutActions { +public: + static ShortcutActions* self(); + + KActionCollection* shortcutActions(); + + QString componentName() const; + + QAction* openAction() const; + QAction* fullScreenAction() const; + QAction* currentScreenAction() const; + QAction* activeWindowAction() const; + QAction* regionAction() const; + +private: + ShortcutActions(); + KActionCollection mActions; +}; + +#endif diff --git a/src/ShortcutActions.cpp b/src/ShortcutActions.cpp new file mode 100644 --- /dev/null +++ b/src/ShortcutActions.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "ShortcutActions.h" + +#include + +#include + +ShortcutActions* ShortcutActions::self() +{ + static ShortcutActions self; + return &self; +} + +ShortcutActions::ShortcutActions() : mActions{nullptr, QString()} +{ + //everything here is named to match the jumplist actions in our .desktop file + mActions.setComponentName(componentName()); + //qdbus org.kde.kglobalaccel /component/org_kde_spectacle_desktop org.kde.kglobalaccel.Component.shortcutNames + // ActiveWindowScreenShot + // CurrentMonitorScreenShot + // RectangularRegionScreenShot + // FullScreenScreenShot + // _launch + { + QAction *action = new QAction(i18n("Launch Spectacle")); + action->setObjectName(QStringLiteral("_launch")); + mActions.addAction(action->objectName(), action); + } + { + QAction *action = new QAction(i18n("Capture Entire Desktop")); + action->setObjectName(QStringLiteral("FullScreenScreenShot")); + mActions.addAction(action->objectName(), action); + } + { + QAction *action = new QAction(i18n("Capture Current Monitor")); + action->setObjectName(QStringLiteral("CurrentMonitorScreenShot")); + mActions.addAction(action->objectName(), action); + } + { + QAction *action = new QAction(i18n("Capture Active Window")); + action->setObjectName(QStringLiteral("ActiveWindowScreenShot")); + mActions.addAction(action->objectName(), action); + } + { + QAction *action = new QAction(i18n("Capture Rectangular Region")); + action->setObjectName(QStringLiteral("RectangularRegionScreenShot")); + mActions.addAction(action->objectName(), action); + } +} + +KActionCollection* ShortcutActions::shortcutActions() +{ + return &mActions; +} + +QString ShortcutActions::componentName() const +{ + return QGuiApplication::desktopFileName().append(QStringLiteral(".desktop")); +} + +QAction* ShortcutActions::openAction() const +{ + return mActions.action(0); +} + +QAction* ShortcutActions::fullScreenAction() const +{ + return mActions.action(1); +} + +QAction* ShortcutActions::currentScreenAction() const +{ + return mActions.action(2); +} + +QAction* ShortcutActions::activeWindowAction() const +{ + return mActions.action(3); +} + +QAction* ShortcutActions::regionAction() const +{ + return mActions.action(4); +} diff --git a/src/SpectacleConfig.h b/src/SpectacleConfig.h deleted file mode 100644 --- a/src/SpectacleConfig.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2015 Boudhayan Gupta - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef SPECTACLECONFIG_H -#define SPECTACLECONFIG_H - -#include -#include -#include - -#include -#include -#include - -enum class SaveMode { - SaveAs, - Save -}; - -class SpectacleConfig : public QObject -{ - Q_OBJECT - - // singleton-ize the class - - public: - - static SpectacleConfig* instance(); - - QString defaultFilename() const; - QString defaultTimestampTemplate() const; - - QUrl lastSaveAsLocation() const; - QUrl lastSaveLocation() const; - - enum PrintKeyActionRunning : int { - TakeNewScreenshot = 0, - StartNewInstance, - FocusWindow - }; - - KActionCollection* shortCutActions; - - private: - - explicit SpectacleConfig(QObject *parent = nullptr); - virtual ~SpectacleConfig(); - - SpectacleConfig(SpectacleConfig const&) = delete; - void operator= (SpectacleConfig const&) = delete; - - // everything else - - public Q_SLOTS: - - QUrl lastSaveAsFile() const; - void setLastSaveAsFile(const QUrl &location); - - QUrl lastSaveFile() const; - void setLastSaveFile(const QUrl &location); - - QRect cropRegion() const; - void setCropRegion(const QRect ®ion); - - bool onClickChecked() const; - void setOnClickChecked(bool enabled); - - bool includePointerChecked() const; - void setIncludePointerChecked(bool enabled); - - bool includeDecorationsChecked() const; - void setIncludeDecorationsChecked(bool enabled); - - bool captureTransientWindowOnlyChecked() const; - void setCaptureTransientWindowOnlyChecked(bool enabled); - - bool quitAfterSaveOrCopyChecked() const; - void setQuitAfterSaveOrCopyChecked(bool enabled); - - bool showMagnifierChecked() const; - void setShowMagnifierChecked(bool enabled); - - bool useReleaseToCapture() const; - void setUseReleaseToCaptureChecked(bool enabled); - - qreal captureDelay() const; - void setCaptureDelay(qreal delay); - - int captureMode() const; - void setCaptureMode(int index); - - bool rememberLastRectangularRegion() const; - void setRememberLastRectangularRegion(bool enabled); - - bool alwaysRememberRegion() const; - void setAlwaysRememberRegion(bool enabled); - - bool useLightRegionMaskColour() const; - void setUseLightRegionMaskColour(bool enabled); - - int compressionQuality() const; - void setCompressionQuality(int value); - - SaveMode lastUsedSaveMode() const; - void setLastUsedSaveMode(SaveMode mode); - - QString autoSaveFilenameFormat() const; - void setAutoSaveFilenameFormat(const QString &format); - - QUrl defaultSaveLocation() const; - void setDefaultSaveLocation(const QUrl &location); - - bool copyImageToClipboard() const; - void setCopyImageToClipboard(bool enabled); - - bool autoSaveImage() const; - void setAutoSaveImage(bool enabled); - - bool copySaveLocationToClipboard() const; - void setCopySaveLocationToClipboard(bool enabled); - - QString saveImageFormat() const; - void setSaveImageFormat(const QString &saveFmt); - - PrintKeyActionRunning printKeyActionRunning() const; - void setPrintKeyActionRunning (PrintKeyActionRunning action); - - private: - - KSharedConfigPtr mConfig; - KConfigGroup mGeneralConfig; - KConfigGroup mGuiConfig; -}; - -#endif // SPECTACLECONFIG_H diff --git a/src/SpectacleConfig.cpp b/src/SpectacleConfig.cpp deleted file mode 100644 --- a/src/SpectacleConfig.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (C) 2015 Boudhayan Gupta - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "SpectacleConfig.h" - -#include -#include - - - -SpectacleConfig::SpectacleConfig(QObject *parent) : - QObject(parent) -{ - mConfig = KSharedConfig::openConfig(QStringLiteral("spectaclerc")); - mGeneralConfig = KConfigGroup(mConfig, "General"); - mGuiConfig = KConfigGroup(mConfig, "GuiConfig"); - - shortCutActions = new KActionCollection(this); - - //everything here is named to match the jumplist actions in our .desktop file - shortCutActions->setComponentName(QStringLiteral("org.kde.spectacle.desktop")); - //qdbus org.kde.kglobalaccel /component/org_kde_spectacle_desktop org.kde.kglobalaccel.Component.shortcutNames - // ActiveWindowScreenShot - // CurrentMonitorScreenShot - // RectangularRegionScreenShot - // FullScreenScreenShot - // _launch - { - QAction *action = new QAction(i18n("Launch Spectacle")); - action->setObjectName(QStringLiteral("_launch")); - shortCutActions->addAction(action->objectName(), action); - } - { - QAction *action = new QAction(i18n("Capture Entire Desktop")); - action->setObjectName(QStringLiteral("FullScreenScreenShot")); - shortCutActions->addAction(action->objectName(), action); - } - { - QAction *action = new QAction(i18n("Capture Current Monitor")); - action->setObjectName(QStringLiteral("CurrentMonitorScreenShot")); - shortCutActions->addAction(action->objectName(), action); - } - { - QAction *action = new QAction(i18n("Capture Active Window")); - action->setObjectName(QStringLiteral("ActiveWindowScreenShot")); - shortCutActions->addAction(action->objectName(), action); - } - { - QAction *action = new QAction(i18n("Capture Rectangular Region")); - action->setObjectName(QStringLiteral("RectangularRegionScreenShot")); - shortCutActions->addAction(action->objectName(), action); - } -} - -SpectacleConfig::~SpectacleConfig() -{} - -SpectacleConfig* SpectacleConfig::instance() -{ - static SpectacleConfig instance; - return &instance; -} - -QString SpectacleConfig::defaultFilename() const -{ - return QStringLiteral("Screenshot"); -} - -QString SpectacleConfig::defaultTimestampTemplate() const -{ - // includes separator at the front - return QStringLiteral("_%Y%M%D_%H%m%S"); -} - -// lastSaveAsLocation - -QUrl SpectacleConfig::lastSaveAsFile() const -{ - return mGeneralConfig.readEntry(QStringLiteral("lastSaveAsFile"), this->defaultSaveLocation()); -} - -void SpectacleConfig::setLastSaveAsFile(const QUrl &location) -{ - mGeneralConfig.writeEntry(QStringLiteral("lastSaveAsFile"), location); - mGeneralConfig.sync(); -} - -QUrl SpectacleConfig::lastSaveAsLocation() const -{ - return this->lastSaveAsFile().adjusted(QUrl::RemoveFilename); -} - -// lastSaveLocation - -QUrl SpectacleConfig::lastSaveFile() const -{ - return mGeneralConfig.readEntry(QStringLiteral("lastSaveFile"), this->defaultSaveLocation()); -} - -void SpectacleConfig::setLastSaveFile(const QUrl &location) -{ - mGeneralConfig.writeEntry(QStringLiteral("lastSaveFile"), location); - mGeneralConfig.sync(); -} - -QUrl SpectacleConfig::lastSaveLocation() const -{ - return this->lastSaveFile().adjusted(QUrl::RemoveFilename); -} - -// cropRegion - -QRect SpectacleConfig::cropRegion() const -{ - return mGuiConfig.readEntry(QStringLiteral("cropRegion"), QRect()); -} - -void SpectacleConfig::setCropRegion(const QRect ®ion) -{ - mGuiConfig.writeEntry(QStringLiteral("cropRegion"), region); - mGuiConfig.sync(); -} - -// onclick - -bool SpectacleConfig::onClickChecked() const -{ - return mGuiConfig.readEntry(QStringLiteral("onClickChecked"), false); -} - -void SpectacleConfig::setOnClickChecked(bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("onClickChecked"), enabled); - mGuiConfig.sync(); -} - -// include pointer - -bool SpectacleConfig::includePointerChecked() const -{ - return mGuiConfig.readEntry(QStringLiteral("includePointer"), true); -} - -void SpectacleConfig::setIncludePointerChecked(bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("includePointer"), enabled); - mGuiConfig.sync(); -} - -// include decorations - -bool SpectacleConfig::includeDecorationsChecked() const -{ - return mGuiConfig.readEntry(QStringLiteral("includeDecorations"), true); -} - -void SpectacleConfig::setIncludeDecorationsChecked(bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("includeDecorations"), enabled); - mGuiConfig.sync(); -} - -// capture transient window only - -bool SpectacleConfig::captureTransientWindowOnlyChecked() const -{ - return mGuiConfig.readEntry(QStringLiteral("transientOnly"), false); -} - -void SpectacleConfig::setCaptureTransientWindowOnlyChecked(bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("transientOnly"), enabled); - mGuiConfig.sync(); -} - -// quit after saving, copying, or exporting the image - -bool SpectacleConfig::quitAfterSaveOrCopyChecked() const -{ - return mGuiConfig.readEntry(QStringLiteral("quitAfterSaveCopyExport"), false); -} - -void SpectacleConfig::setQuitAfterSaveOrCopyChecked(bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("quitAfterSaveCopyExport"), enabled); - mGuiConfig.sync(); -} - -// show magnifier - -bool SpectacleConfig::showMagnifierChecked() const -{ - return mGuiConfig.readEntry(QStringLiteral("showMagnifier"), false); -} - -void SpectacleConfig::setShowMagnifierChecked(bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("showMagnifier"), enabled); - mGuiConfig.sync(); -} - -// release mouse-button to capture - -bool SpectacleConfig::useReleaseToCapture() const -{ - return mGuiConfig.readEntry(QStringLiteral("useReleaseToCapture"), false); -} - -void SpectacleConfig::setUseReleaseToCaptureChecked(bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("useReleaseToCapture"), enabled); - mGuiConfig.sync(); -} - -// capture delay - -qreal SpectacleConfig::captureDelay() const -{ - return mGuiConfig.readEntry(QStringLiteral("captureDelay"), 0.0); -} - -void SpectacleConfig::setCaptureDelay(qreal delay) -{ - mGuiConfig.writeEntry(QStringLiteral("captureDelay"), delay); - mGuiConfig.sync(); -} - -// capture mode - -int SpectacleConfig::captureMode() const -{ - return std::max(0, mGuiConfig.readEntry(QStringLiteral("captureModeIndex"), 0)); -} - -void SpectacleConfig::setCaptureMode(int index) -{ - mGuiConfig.writeEntry(QStringLiteral("captureModeIndex"), index); - mGuiConfig.sync(); -} - -// remember last rectangular region - -bool SpectacleConfig::rememberLastRectangularRegion() const -{ - return mGuiConfig.readEntry(QStringLiteral("rememberLastRectangularRegion"), true); -} - -void SpectacleConfig::setRememberLastRectangularRegion(bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("rememberLastRectangularRegion"), enabled); - mGuiConfig.sync(); -} - -bool SpectacleConfig::alwaysRememberRegion() const -{ - // Default Value is for compatibility reasons as the old behavior was always to remember across restarts - bool useOldBehavior = mGuiConfig.readEntry(QStringLiteral("rememberLastRectangularRegion"), false); - return mGuiConfig.readEntry(QStringLiteral("alwaysRememberRegion"), useOldBehavior); -} - -void SpectacleConfig::setAlwaysRememberRegion (bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("alwaysRememberRegion"), enabled); - mGuiConfig.sync(); -} - -// use light region mask colour - -bool SpectacleConfig::useLightRegionMaskColour() const -{ - return mGuiConfig.readEntry(QStringLiteral("useLightMaskColour"), false); -} - -void SpectacleConfig::setUseLightRegionMaskColour(bool enabled) -{ - mGuiConfig.writeEntry(QStringLiteral("useLightMaskColour"), enabled); - mGuiConfig.sync(); -} - -// compression quality setting - -int SpectacleConfig::compressionQuality() const -{ - return mGuiConfig.readEntry(QStringLiteral("compressionQuality"), 90); -} - -void SpectacleConfig::setCompressionQuality(int value) -{ - mGuiConfig.writeEntry(QStringLiteral("compressionQuality"), value); - mGuiConfig.sync(); -} - -// last used save mode - -SaveMode SpectacleConfig::lastUsedSaveMode() const -{ - switch (mGuiConfig.readEntry(QStringLiteral("lastUsedSaveMode"), 0)) { - default: - case 0: - return SaveMode::SaveAs; - case 1: - return SaveMode::Save; - } -} - -void SpectacleConfig::setLastUsedSaveMode(SaveMode mode) -{ - mGuiConfig.writeEntry(QStringLiteral("lastUsedSaveMode"), static_cast(mode)); - mGuiConfig.sync(); -} - -// autosave filename format - -QString SpectacleConfig::autoSaveFilenameFormat() const -{ - const QString sff = mGeneralConfig.readEntry(QStringLiteral("save-filename-format"), - QString(defaultFilename() + defaultTimestampTemplate())); - return sff.isEmpty() ? QStringLiteral("%d") : sff; -} - -void SpectacleConfig::setAutoSaveFilenameFormat(const QString &format) -{ - mGeneralConfig.writeEntry(QStringLiteral("save-filename-format"), format); - mGeneralConfig.sync(); -} - -// autosave location - -QUrl SpectacleConfig::defaultSaveLocation() const -{ - QString path = mGeneralConfig.readPathEntry(QStringLiteral("default-save-location"), - (QStandardPaths::writableLocation(QStandardPaths::PicturesLocation))); - if (! path.endsWith(QLatin1Char('/'))) { - path += QLatin1Char('/'); - } - return QUrl::fromUserInput(path); -} - -void SpectacleConfig::setDefaultSaveLocation(const QUrl &location) -{ - mGeneralConfig.writePathEntry(QStringLiteral("default-save-location"), location.toString()); - mGeneralConfig.sync(); -} - -// copy file to clipboard after the screenshot has been made - -bool SpectacleConfig::copyImageToClipboard() const -{ - return mGeneralConfig.readEntry(QStringLiteral("copyImageToClipboard"), false); -} - -void SpectacleConfig::setCopyImageToClipboard (bool enabled) -{ - mGeneralConfig.writeEntry(QStringLiteral("copyImageToClipboard"), enabled); - mGeneralConfig.sync(); -} - -bool SpectacleConfig::autoSaveImage() const -{ - return mGeneralConfig.readEntry(QStringLiteral("autoSaveImage"), false); -} -void SpectacleConfig::setAutoSaveImage(bool enabled) -{ - mGeneralConfig.writeEntry(QStringLiteral("autoSaveImage"), enabled); - mGeneralConfig.sync(); -} - -// copy file location to clipboard after saving - -bool SpectacleConfig::copySaveLocationToClipboard() const -{ - return mGeneralConfig.readEntry(QStringLiteral("copySaveLocation"), false); -} - -void SpectacleConfig::setCopySaveLocationToClipboard(bool enabled) -{ - mGeneralConfig.writeEntry(QStringLiteral("copySaveLocation"), enabled); - mGeneralConfig.sync(); -} - -// autosave image format - -QString SpectacleConfig::saveImageFormat() const -{ - return mGeneralConfig.readEntry(QStringLiteral("default-save-image-format"), - QStringLiteral("png")); -} - -void SpectacleConfig::setSaveImageFormat(const QString &saveFmt) -{ - mGeneralConfig.writeEntry(QStringLiteral("default-save-image-format"), saveFmt); - mGeneralConfig.sync(); -} - -SpectacleConfig::PrintKeyActionRunning SpectacleConfig::printKeyActionRunning() const -{ - mConfig->reparseConfiguration(); - int newScreenshotAction = static_cast(SpectacleConfig::PrintKeyActionRunning::TakeNewScreenshot); - int readValue = mGuiConfig.readEntry(QStringLiteral("printKeyActionRunning"), newScreenshotAction); - if ((KWindowSystem::isPlatformWayland() || qstrcmp(qgetenv("XDG_SESSION_TYPE"), "wayland") == 0 ) - && readValue == SpectacleConfig::PrintKeyActionRunning::FocusWindow) { - return SpectacleConfig::PrintKeyActionRunning::TakeNewScreenshot; - } - return static_cast(readValue); -} - -void SpectacleConfig::setPrintKeyActionRunning (SpectacleConfig::PrintKeyActionRunning action) -{ - mGuiConfig.writeEntry(QStringLiteral("printKeyActionRunning"), static_cast(action)); - mGuiConfig.sync(); -} diff --git a/src/SpectacleCore.cpp b/src/SpectacleCore.cpp --- a/src/SpectacleCore.cpp +++ b/src/SpectacleCore.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2019 David Redondo * Copyright (C) 2015 Boudhayan Gupta * * This program is free software; you can redistribute it and/or modify @@ -21,6 +22,8 @@ #include "spectacle_core_debug.h" #include "Config.h" +#include "settings.h" +#include "ShortcutActions.h" #include #include @@ -57,9 +60,6 @@ mCopyToClipboard(theCopyToClipboard), mWaylandPlasmashell(nullptr) { - auto lConfig = KSharedConfig::openConfig(QStringLiteral("spectaclerc")); - KConfigGroup lGuiConfig(lConfig, "GuiConfig"); - if (!(theSaveFileName.isEmpty() || theSaveFileName.isNull())) { if (QDir::isRelativePath(theSaveFileName)) { theSaveFileName = QDir::current().absoluteFilePath(theSaveFileName); @@ -79,9 +79,8 @@ } // reset last region if it should not be remembered across restarts - auto lSpectacleConfig = SpectacleConfig::instance(); - if(!lSpectacleConfig->alwaysRememberRegion()) { - lSpectacleConfig->setCropRegion(QRect()); + if(!Settings::alwaysRememberRegion()) { + Settings::setCropRegion({0, 0, 0, 0}); } // set up the export manager @@ -116,39 +115,32 @@ case StartMode::Background: { auto lMsec = (KWindowSystem::compositingActive() ? 200 : 50) + theDelayMsec; auto lShutterMode = lImmediateAvailable ? Platform::ShutterMode::Immediate : Platform::ShutterMode::OnClick; - auto lIncludePointer = lGuiConfig.readEntry("includePointer", true); - auto lIncludeDecorations = lGuiConfig.readEntry("includeDecorations", true); + auto lIncludePointer = Settings::includePointer(); + auto lIncludeDecorations = Settings::includeDecorations(); const Platform::GrabMode lCaptureMode = toPlatformGrabMode(theCaptureMode); QTimer::singleShot(lMsec, this, [ this, lCaptureMode, lShutterMode, lIncludePointer, lIncludeDecorations ]() { mPlatform->doGrab(lShutterMode, lCaptureMode, lIncludePointer, lIncludeDecorations); }); } break; case StartMode::Gui: - initGui(lGuiConfig.readEntry("includePointer", true), lGuiConfig.readEntry("includeDecorations", true)); + initGui(Settings::includePointer(), Settings::includeDecorations()); break; } setUpShortcuts(); } void SpectacleCore::setUpShortcuts() { - SpectacleConfig* config = SpectacleConfig::instance(); - - QAction* openAction = config->shortCutActions->action(QStringLiteral("_launch")); - KGlobalAccel::self()->setGlobalShortcut(openAction, Qt::Key_Print); + KGlobalAccel::self()->setGlobalShortcut(ShortcutActions::self()->openAction(), Qt::Key_Print); - QAction* fullScreenAction = config->shortCutActions->action(QStringLiteral("FullScreenScreenShot")); - KGlobalAccel::self()->setGlobalShortcut(fullScreenAction, Qt::SHIFT + Qt::Key_Print); + KGlobalAccel::self()->setGlobalShortcut(ShortcutActions::self()->fullScreenAction(), Qt::SHIFT + Qt::Key_Print); - QAction* activeWindowAction = config->shortCutActions->action(QStringLiteral("ActiveWindowScreenShot")); - KGlobalAccel::self()->setGlobalShortcut(activeWindowAction, Qt::META + Qt::Key_Print); + KGlobalAccel::self()->setGlobalShortcut(ShortcutActions::self()->activeWindowAction(), Qt::META + Qt::Key_Print); - QAction* regionAction = config->shortCutActions->action(QStringLiteral("RectangularRegionScreenShot")); - KGlobalAccel::self()->setGlobalShortcut(regionAction, Qt::META + Qt::SHIFT + Qt::Key_Print); + KGlobalAccel::self()->setGlobalShortcut(ShortcutActions::self()->regionAction(), Qt::META + Qt::SHIFT + Qt::Key_Print); - QAction* currentScreenAction = config->shortCutActions->action(QStringLiteral("CurrentMonitorScreenShot")); - KGlobalAccel::self()->setGlobalShortcut(currentScreenAction, QList()); + KGlobalAccel::self()->setGlobalShortcut(ShortcutActions::self()->currentScreenAction(), QList()); } QString SpectacleCore::filename() const @@ -177,8 +169,8 @@ mStartMode = StartMode::Gui; initGui(lIncludePointer, lIncludeDecorations); } else { - using Actions = SpectacleConfig::PrintKeyActionRunning; - switch (SpectacleConfig::instance()->printKeyActionRunning()) { + using Actions = Settings::EnumPrintKeyActionRunning; + switch (Settings::printKeyActionRunning()) { case Actions::TakeNewScreenshot: { auto lShutterMode = mPlatform->supportedShutterModes().testFlag(Platform::ShutterMode::Immediate) ? Platform::ShutterMode::Immediate : Platform::ShutterMode::OnClick; auto lGrabMode = toPlatformGrabMode(ExportManager::instance()->captureMode()); @@ -285,8 +277,8 @@ case StartMode::Gui: mMainWindow->setScreenshotAndShow(thePixmap); - bool autoSaveImage = SpectacleConfig::instance()->autoSaveImage(); - bool copyImageToClipboard = SpectacleConfig::instance()->copyImageToClipboard(); + bool autoSaveImage = Settings::autoSaveImage(); + bool copyImageToClipboard = Settings::copyImageToClipboard(); if (autoSaveImage && copyImageToClipboard) { lExportManager->doSaveAndCopy(); @@ -361,16 +353,16 @@ if (index == 0) { new KRun(theSavedAt, nullptr); QTimer::singleShot(250, this, [this] { - if (mStartMode != StartMode::Gui || SpectacleConfig::instance()->quitAfterSaveOrCopyChecked()) { + if (mStartMode != StartMode::Gui || Settings::quitAfterSaveCopyExport()) { emit allDone(); } }); } }); } connect(lNotify, &QObject::destroyed, this, [this] { - if (mStartMode != StartMode::Gui || SpectacleConfig::instance()->quitAfterSaveOrCopyChecked()) { + if (mStartMode != StartMode::Gui || Settings::quitAfterSaveCopyExport()) { emit allDone(); } }); @@ -380,7 +372,7 @@ void SpectacleCore::doCopyPath(const QUrl &savedAt) { - if (SpectacleConfig::instance()->copySaveLocationToClipboard()) { + if (Settings::copySaveLocation()) { qApp->clipboard()->setText(savedAt.toLocalFile()); } } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,8 +1,16 @@ -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${PROJECT_SOURCE_DIR}/src) -ecm_add_test(FilenameTest.cpp - ../src/ExportManager.cpp ../src/SpectacleConfig.cpp ../src/Platforms/Platform.cpp +SET(FILENAME_TEST_SRCS + FilenameTest.cpp + ../src/ExportManager.cpp + ../src/Platforms/Platform.cpp +) + + +kconfig_add_kcfg_files(FILENAME_TEST_SRCS ${PROJECT_SOURCE_DIR}/src/Gui/SettingsDialog/settings.kcfgc) + +ecm_add_test( + ${FILENAME_TEST_SRCS} TEST_NAME "filename_test" LINK_LIBRARIES Qt5::Test Qt5::PrintSupport KF5::I18n KF5::ConfigCore KF5::GlobalAccel KF5::KIOCore KF5::WindowSystem KF5::XmlGui