diff --git a/doc/index.docbook b/doc/index.docbook index a6db8e4..adbc003 100644 --- a/doc/index.docbook +++ b/doc/index.docbook @@ -1,364 +1,364 @@ Spectacle"> ]> The &spectacle; Handbook &Boudhayan.Gupta; &Boudhayan.Gupta.mail; &Boudhayan.Gupta; &Boudhayan.Gupta.mail; 1997-2000&Richard.J.Moore; 2000&Matthias.Ettrich; 2015&Boudhayan.Gupta; &FDLNotice; 2018-03-06 Applications 18.04 &spectacle; is a simple application for capturing desktop screenshots. It can capture images of the entire desktop, a single monitor, the currently active window, the window currently under the mouse, or a rectangular region of the screen. The images can then be printed, sent to other applications for manipulation, or quickly be saved as-is. KDE spectacle kdegraphics screenshot screen capture screen grab Introduction &spectacle; is a simple application for capturing desktop screenshots. It can capture images of the entire desktop, a single monitor, the currently active window, the window currently under the mouse, or a rectangular region of the screen. The images can then be printed, sent to other applications for manipulation, or quickly be saved as-is. Please report any problems or feature requests to the &kde; Bug Tracking System. Starting &spectacle; &spectacle; can be started in a variety of ways, as described below: In the application launcher menu, &spectacle; can be found at ApplicationsUtilitiesScreenshot Capture Utility &spectacle; Pressing the Print button on the keyboard will immediately launch &spectacle;. Additionally, three more keyboard shortcuts are available to take screenshots and save them in your default save folder without showing the &GUI;: MetaPrint will take a screenshot of the active window &Shift;Print will take a screenshot of your entire desktop, &ie; all monitors Meta&Shift;Print will take a rectangular region screenshot You can configure the default save location and filename by starting &spectacle; normally and clicking on the Configure... button, then navigating to the Save section. The mini command line &krunner; (invoked with &Alt;F2) may also be used to start &spectacle;. &spectacle; can be started from the command-line. &spectacle; has an extensive set of command-line options, including a background mode which can be used to script the capture of screenshots without showing the &GUI; or requiring user interaction. To start &spectacle; from the command prompt, type in: % spectacle & To view the full list of command-line options and their explanation, type in: % spectacle --help Using &spectacle; Once &spectacle; starts, you will see a window like the following: &spectacle; Main Window &spectacle; grabs an image of your entire desktop immediately after it is started, but before it displays itself on screen. This allows you to quickly create full-desktop screenshot images. The snapshot taken by &spectacle; is displayed in the preview window, which is located on the left-hand side of the &spectacle; application window. The image can be saved to a location of your choice by clicking on the Save As button or typing &Ctrl;&Shift;S. This opens the standard save dialog, where you can choose the filename, the folder location, and the format that your screenshot will be saved in. You may edit the filename to anything you wish, including the name of a previously saved screenshot. To save a screenshot to the default location, click on the arrow portion of the Save As... button and press the Save (&Ctrl;S) button. The new save mode will be remembered for next time. The default save location and filename can be configured, as described later. To quickly save the image and quit &spectacle;, click on the checkbox beside Quit after Save or Copy, then click the arrow portion of the Save As... button and press the Save (&Ctrl;S) item. This saves the image as a PNG file in your default Pictures folder, and exits the application immediately. As above, this new save mode will be remembered. Taking A Screenshot When you open spectacle, it immediately takes a screenshot of the whole screen as a convenience and shows a preview of it in the main window. You can save this screenshot using the buttons on the bottom of the window, or take a new one using the controls to the right of the preview. To discard the current screenshot and take another screenshot, press the Take a New Screenshot (&Ctrl;N) button. You may configure certain options on the right hand side of the application window before taking a new screenshot. These options allow you to select the area of the screen that is to be captured, set a delay before capturing the image, and configure whether the mouse cursor and/or the window decorations should be captured along with the screenshot. Capture Mode The capture mode settings allow you to set the area of the screen that should be captured, and whether there should be a delay between pressing the Take a New Screenshot (&Ctrl;N) button and taking the screenshot. You may also enable the On Click checkbox, which disables the delay function and only takes the screenshot after you click anywhere on the screen after clicking the Take a New Screenshot (&Ctrl;N) button. The Area combo-box allows you to set the area of the screen that should be captured. There are five options to select from, as described below. The Full Screen (All Monitors) option takes a screenshot of your entire desktop, spread across all the outputs, including all the monitors, projectors etc. The Current Screen option takes a screenshot of the output that currently contains the mouse pointer. The Active Window option takes a screenshot of the window that currently has focus. It is advisable to use a delay with this mode, to give you time to select and activate a window before the screenshot is taken. The Window Under Cursor option takes a screenshot of the window that is under the mouse cursor. If the cursor is on top of a popup menu, &spectacle; tries to take a screenshot of the menu as well as its parent window. While this works most of the time, in certain cases it may fail to obtain information about the parent window. In this case, &spectacle; falls back to old way of capturing the image automatically, and captures an image of only the popup menu. You can also force the old way of capturing the image by checking the Capture the current pop-up only checkbox under Options The Rectangular Region option allows you to select a rectangular region of your desktop with your mouse. This region may be spread across different outputs. This mode does not immediately take a screenshot but allows you to draw a rectangle on your screen, which can be moved and resized as needed. Once the desired selection rectangle has been drawn, double-clicking anywhere on the screen, or pressing the &Enter; button on the keyboard will capture the screenshot. The Delay spin-box allows you to set the delay between pressing the Take a New Screenshot (&Ctrl;N) button and taking the screenshot. This delay can be set in increments of 1 seconds using the spinbox buttons or the keyboard. Enabling the On Click checkbox overrides the delay. When this checkbox is enabled, pressing the Take a New Screenshot (&Ctrl;N) button hides the &spectacle; window and changes the mouse cursor to a crosshair. The screenshot is captured when the mouse is left-clicked, or aborted if any other mouse buttons are clicked. Note that you cannot interact with the desktop using the mouse while the cursor is a crosshair, but you can use the keyboard. Options The Options settings allow you to select whether the mouse cursor should be included in the screenshots, and whether to capture window decorations along with the image of a single application window. In Window Under Cursor mode, it also allows you to select if &spectacle; shall only capture the image of the current popup menu under the cursor, or also include the parent window. Finally, Quit after Save or Copy will quit Spectacle after any save or copy operations. Enabling the Include mouse pointer checkbox includes an image of the mouse pointer in the screenshot. The Include window titlebar and borders option is only enabled when either the Active Window mode or the Window Under Cursor mode is selected in the Area combo-box. Checking this option includes the window borders and decoration in the screenshot, while unchecking it gives an image of only the window contents. The Capture the current pop-up only option is only enabled when the Window Under Cursor mode is selected in the Area combo-box. Checking this option captures only the popup menu under the cursor, without its parent window. The Quit after Save or Copy option will quit Spectacle after any saving or copying operations. Note that a copied screenshot will only be retained if you are running a clipboard manager that accepts images. KDE Klipper can be configured in this manner by right-clicking on its icon, selecting Configure Clipboard..., and unchecking Ignore images. Additional Functionality Buttons There are some buttons located at the bottom of the &spectacle; window. Their functions are described below: Help Gives you the common menu items described in the Help Menu of the &kde; Fundamentals. Configure... Gives you access to Spectacle's Configure window where you can change the capture settings and default save location and filename. Tools Opens a drop-down menu which offers various tools: Open Screenshots Folder will highlight the last saved screenshot in the default file manager Access to the Print dialog A range of external programs for Screen Recording Export Opens a drop-down menu that will allow you to directly open the screenshot with all programs that are associated with the PNG (Portable Network Graphics) &MIME; type. Depending on what programs are installed, you will be able to open and edit the snapshot in your graphics applications or viewers. Furthermore, if you have the KIPI Plugins installed, you will be able to email your screenshots and export them directly to some social networks and websites. Copy To Clipboard Copies the current screenshot to the clipboard. You can also use the &Ctrl;C keyboard shortcut for this. Save As Saves the screenshot as a PNG image in your default Pictures folder and immediately exits the application. Configure Use the Configure... button to open the configuration dialog. General General - Copy save location to clipboard + Copy file location to clipboard after saving When a screenshot is saved, copy the location at which the file was saved to the clipboard. You can then paste it anywhere that accepts text input. Note that you must be running a clipboard manager in order to keep the path in the clipboard after &spectacle; quits. Use light background Use a light background color to mask the cropped-out area in the rectangular region selector. This may make dark cursors easier to see. Remember selected area By default, &spectacle; does not show an initial selection when you take a screenshot of a rectangular region. Enable this option to remember the last selected region of the screen, and set it as the initial selection when you use the rectangular region selector the next time. Save When you use the Save function, &spectacle; saves the image with a default filename, in your Pictures folder (which is inside your home folder). The default filename includes the date and time when the image was taken. The Save page allows you to set the default save location and filename. Clicking this option brings up a dialog box like the following: Save Default Save Location In the Location text box set the folder where you'd like to save your screenshots when you press Save. Default Save Filename Set a default filename for saved screenshots. You can use the following placeholders in the filename, which will be replaced with actual text when the file is saved: %Y: Year (4 digit) %y: Year (2 digit) %M: Month %D: Day %H: Hour %m: Minute %S: Second %T: Window title If a file with this name already exists, a serial number will be appended to the filename. For example, if the filename is Screenshot, and Screenshot.png already exists, the image will be saved as Screenshot-1.png. Typing an extension into the filename will automatically set the image format correctly and remove the extension from the filename field. Drag and Drop A captured image can be dragged to another application or document. If the application is able to handle images, a copy of the full image is inserted there. If you drag a screenshot into a file manager window, a dialog pops up where you can edit the filename and select the image format and the file will be inserted into the actual folder. If you drag the screenshot to a text box, the path to the temporary saved file is inserted. This is useful for example to upload a screenshot through web forms or to attach screenshots into bug reports on the &kde; bugtracker. This works with all clients that do not pick up the image data, but only look for a &URL; in the dragged mimedata. Credits and License Program copyright © 2015 &Boudhayan.Gupta; &Boudhayan.Gupta.mail;. Portions of the code are based directly on code from the &ksnapshot; project. Copyright © 1997-2011 The &ksnapshot; Developers. Detailed copyright assignment notices are available in the headers in the source code. Portions of the code are based directly on code from the &kwin; project. Copyright © 2008, 2013 The &kwin; Developers. Detailed copyright assignment notices are available in the headers in the source code. Documentation based on the original &ksnapshot; documentation: Copyright © 1997-2000 &Richard.J.Moore; &Richard.J.Moore.mail; Copyright © 2000 &Matthias.Ettrich; &Matthias.Ettrich.mail; &underFDL; &underGPL; &documentation.index; diff --git a/src/Gui/KSMainWindow.cpp b/src/Gui/KSMainWindow.cpp index cd16002..56f6b27 100644 --- a/src/Gui/KSMainWindow.cpp +++ b/src/Gui/KSMainWindow.cpp @@ -1,415 +1,417 @@ /* * 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 "KSMainWindow.h" #include "Config.h" #include "SettingsDialog/SettingsDialog.h" #include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include #include #ifdef XCB_FOUND #include #include #endif static const int DEFAULT_WINDOW_HEIGHT = 420; static const int DEFAULT_WINDOW_WIDTH = 840; static const int MAXIMUM_WINDOW_WIDTH = 1000; KSMainWindow::KSMainWindow(bool onClickAvailable, QWidget *parent) : QDialog(parent), mKSWidget(new KSWidget), mDivider(new QFrame), mDialogButtonBox(new QDialogButtonBox), mConfigureButton(new QToolButton), mToolsButton(new QPushButton), mSendToButton(new QPushButton), mClipboardButton(new QToolButton), mSaveButton(new QToolButton), mSaveMenu(new QMenu), mSaveAsAction(new QAction(this)), mSaveAction(new QAction(this)), mMessageWidget(new KMessageWidget), mToolsMenu(new QMenu), mScreenRecorderToolsMenu(new QMenu), mExportMenu(new ExportMenu(this)), mOnClickAvailable(onClickAvailable) { // before we do anything, we need to set a window property // that skips the close/hide window animation on kwin. this // fixes a ghost image of the spectacle window that appears // on subsequent screenshots taken with the take new screenshot // button // // credits for this goes to Thomas Lübking #ifdef XCB_FOUND if (KWindowSystem::isPlatformX11()) { // create a window if we haven't already. note that the QWidget constructor // should already have done this if (winId() == 0) { create(0, true, true); } // do the xcb shenanigans xcb_connection_t *xcbConn = QX11Info::connection(); const QByteArray effectName = QByteArrayLiteral("_KDE_NET_WM_SKIP_CLOSE_ANIMATION"); xcb_intern_atom_cookie_t atomCookie = xcb_intern_atom_unchecked(xcbConn, false, effectName.length(), effectName.constData()); QScopedPointer atom(xcb_intern_atom_reply(xcbConn, atomCookie, nullptr)); if (atom.isNull()) { goto done; } uint32_t value = 1; xcb_change_property(xcbConn, XCB_PROP_MODE_REPLACE, winId(), atom->atom, XCB_ATOM_CARDINAL, 32, 1, &value); } #endif done: QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); } KSMainWindow::~KSMainWindow() {} // GUI init void KSMainWindow::init() { KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("spectaclerc")); KConfigGroup guiConfig(config, "GuiConfig"); // window properties setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QPoint location = guiConfig.readEntry("window-position", QPoint(50, 50)); move(location); // change window title on save connect(ExportManager::instance(), &ExportManager::imageSaved, this, &KSMainWindow::setScreenshotWindowTitle); // the KSGWidget connect(mKSWidget, &KSWidget::newScreenshotRequest, this, &KSMainWindow::captureScreenshot); connect(mKSWidget, &KSWidget::dragInitiated, this, &KSMainWindow::dragAndDropRequest); // the Button Bar mDialogButtonBox->setStandardButtons(QDialogButtonBox::Help); mConfigureButton->setDefaultAction(KStandardAction::preferences(this, SLOT(showPreferencesDialog()), this)); mConfigureButton->setText(i18n("Configure...")); mConfigureButton->setToolTip(i18n("Change Spectacle's settings.")); mConfigureButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mDialogButtonBox->addButton(mConfigureButton, QDialogButtonBox::ResetRole); KGuiItem::assign(mToolsButton, KGuiItem(i18n("Tools"))); mToolsButton->setIcon(QIcon::fromTheme(QStringLiteral("application-menu"))); mDialogButtonBox->addButton(mToolsButton, QDialogButtonBox::ActionRole); mToolsButton->setMenu(mToolsMenu); KGuiItem::assign(mSendToButton, KGuiItem(i18n("Export"))); mSendToButton->setIcon(QIcon::fromTheme(QStringLiteral("document-share"))); mDialogButtonBox->addButton(mSendToButton, QDialogButtonBox::ActionRole); mClipboardButton->setDefaultAction(KStandardAction::copy(this, SLOT(sendToClipboard()), this)); mClipboardButton->setText(i18n("Copy To Clipboard")); mClipboardButton->setToolTip(i18n("Copy the current screenshot image to the clipboard.")); mClipboardButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mDialogButtonBox->addButton(mClipboardButton, QDialogButtonBox::ActionRole); mSaveButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mSaveButton->setMenu(mSaveMenu); mSaveButton->setPopupMode(QToolButton::MenuButtonPopup); mDialogButtonBox->addButton(mSaveButton, QDialogButtonBox::ActionRole); // the help menu KHelpMenu *helpMenu = new KHelpMenu(this, KAboutData::applicationData(), true); mDialogButtonBox->button(QDialogButtonBox::Help)->setMenu(helpMenu->menu()); // the tools menu mToolsMenu->addAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), i18n("Open Screenshots Folder"), this, &KSMainWindow::openScreenshotsFolder); mToolsMenu->addAction(KStandardAction::print(this, &KSMainWindow::showPrintDialog, this)); mScreenRecorderToolsMenu = mToolsMenu->addMenu(i18n("Record Screen")); connect(mScreenRecorderToolsMenu, &QMenu::aboutToShow, [this]() { mScreenrecorderToolsMenuFactory.reset(new KMoreToolsMenuFactory(QStringLiteral("spectacle/screenrecorder-tools"))); mScreenRecorderToolsMenu->clear(); mScreenrecorderToolsMenuFactory->fillMenuFromGroupingNames(mScreenRecorderToolsMenu, { QStringLiteral("screenrecorder") }); } ); // the save menu mSaveAsAction = KStandardAction::saveAs(this, &KSMainWindow::saveAs, this); mSaveAction = KStandardAction::save(this, &KSMainWindow::save, this); mSaveMenu->addAction(mSaveAsAction); mSaveMenu->addAction(mSaveAction); setDefaultSaveAction(); // message widget connect(mMessageWidget, &KMessageWidget::linkActivated, this, [](const QString &str) { QDesktopServices::openUrl(QUrl(str)); } ); // layouts mDivider->setFrameShape(QFrame::HLine); mDivider->setLineWidth(2); QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(mKSWidget); layout->addWidget(mMessageWidget); layout->addWidget(mDivider); layout->addWidget(mDialogButtonBox); mMessageWidget->hide(); // populate our send-to actions mSendToButton->setMenu(mExportMenu); connect(mExportMenu, &ExportMenu::imageShared, this, &KSMainWindow::showImageSharedFeedback); // disable onClick mode if not available on the platform if (!mOnClickAvailable) { mKSWidget->disableOnClick(); } resize(QSize(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT).expandedTo(minimumSize())); // Allow Ctrl+Q to quit the app QAction *actionQuit = KStandardAction::quit(qApp, &QApplication::quit, this); actionQuit->setShortcut(QKeySequence::Quit); addAction(actionQuit); // done with the init } int KSMainWindow::windowWidth(const QPixmap &pixmap) const { // Calculates what the width of the window should be for the captured image to perfectly fit // the area reserved for the image, with the height already set. const float pixmapAspectRatio = (float)pixmap.width() / pixmap.height(); const int imageHeight = mKSWidget->height() - 2 * layout()->spacing(); const int imageWidth = pixmapAspectRatio * imageHeight; 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: mSaveButton->setDefaultAction(mSaveAsAction); break; case SaveMode::Save: mSaveButton->setDefaultAction(mSaveAction); break; } } // overrides void KSMainWindow::moveEvent(QMoveEvent *event) { Q_UNUSED(event); KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("spectaclerc")); KConfigGroup guiConfig(config, "GuiConfig"); guiConfig.writeEntry("window-position", pos()); guiConfig.sync(); } // slots void KSMainWindow::captureScreenshot(ImageGrabber::GrabMode mode, int timeout, bool includePointer, bool includeDecorations) { hide(); mMessageWidget->hide(); emit newScreenshotRequest(mode, timeout, includePointer, includeDecorations); } void KSMainWindow::setScreenshotAndShow(const QPixmap &pixmap) { mKSWidget->setScreenshotPixmap(pixmap); mExportMenu->imageUpdated(); setWindowTitle(i18nc("Unsaved Screenshot", "Unsaved[*]")); setWindowModified(true); show(); resize(QSize(windowWidth(pixmap), DEFAULT_WINDOW_HEIGHT)); } void KSMainWindow::showPrintDialog() { QPrinter *printer = new QPrinter(QPrinter::HighResolution); QPrintDialog printDialog(printer, this); if (printDialog.exec() == QDialog::Accepted) { ExportManager::instance()->doPrint(printer); return; } delete printer; } void KSMainWindow::openScreenshotsFolder() { // Highlight last screenshot in file manager if user saved at least once, // or open default directory as determined by save button QUrl location = ExportManager::instance()->lastSavePath(); if (!ExportManager::instance()->isFileExists(location)) { switch(SpectacleConfig::instance()->lastUsedSaveMode()) { case SaveMode::Save: location = QUrl::fromLocalFile(ExportManager::instance()->saveLocation() + QStringLiteral("/")); break; case SaveMode::SaveAs: location = SpectacleConfig::instance()->lastSaveAsLocation(); // already has a "/" at the end break; } if (!ExportManager::instance()->isFileExists(location)) { location = QUrl(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + QStringLiteral("/")); } } KIO::highlightInFileManager({location}); } void KSMainWindow::quit(const QuitBehavior quitBehavior) { qApp->setQuitOnLastWindowClosed(false); hide(); if (quitBehavior == QuitBehavior::QuitImmediately) { // Allow some time for clipboard content to transfer // TODO: Find better solution QTimer::singleShot(250, qApp, &QApplication::quit); } // TODO for else case: // Currently it is expected that you emit forceNotify, and finally quit // via a callback through KNotification::action1Activated. However, that // is not working quite right, see Bug #389694 which needs fixing. } void KSMainWindow::showInlineMessage(const QString& message, const KMessageWidget::MessageType messageType, const MessageDuration messageDuration) { mMessageWidget->setText(message); mMessageWidget->setMessageType(messageType); switch (messageType) { case KMessageWidget::Error: mMessageWidget->setIcon(QIcon::fromTheme(QStringLiteral("dialog-error"))); break; case KMessageWidget::Positive: mMessageWidget->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok-apply"))); break; case KMessageWidget::Information: mMessageWidget->setIcon(QIcon::fromTheme(QStringLiteral("dialog-information"))); break; default: ; } mMessageWidget->animatedShow(); if (messageDuration == MessageDuration::AutoHide) { QTimer::singleShot(10000, mMessageWidget, &KMessageWidget::animatedHide); } } void KSMainWindow::showImageSharedFeedback(bool error, const QString &message) { if (error) { showInlineMessage(i18n("There was a problem sharing the image: %1", message), KMessageWidget::Error); } else { if (message.isEmpty()) { showInlineMessage(i18n("Image shared"), KMessageWidget::Positive); } else { - showInlineMessage(i18n("You can find the shared image at: %1", message), + showInlineMessage(i18n("The shared image link (%1) has been copied to the clipboard.", message), KMessageWidget::Positive, MessageDuration::Persistent); + QApplication::clipboard()->setText(message); } } } void KSMainWindow::sendToClipboard() { ExportManager::instance()->doCopyToClipboard(); SpectacleConfig::instance()->quitAfterSaveOrCopyChecked() ? quit() : showInlineMessage(i18n("The screenshot has been copied to the clipboard."), KMessageWidget::Information); } void KSMainWindow::showPreferencesDialog() { SettingsDialog prefDialog(this); prefDialog.exec(); } void KSMainWindow::setScreenshotWindowTitle(QUrl location) { setWindowTitle(location.fileName()); setWindowModified(false); } void KSMainWindow::save() { SpectacleConfig::instance()->setLastUsedSaveMode(SaveMode::Save); setDefaultSaveAction(); const bool quitChecked = SpectacleConfig::instance()->quitAfterSaveOrCopyChecked(); ExportManager::instance()->doSave(QUrl(), /* notify */ quitChecked); if (quitChecked) { quit(QuitBehavior::QuitExternally); } } void KSMainWindow::saveAs() { SpectacleConfig::instance()->setLastUsedSaveMode(SaveMode::SaveAs); setDefaultSaveAction(); const bool quitChecked = SpectacleConfig::instance()->quitAfterSaveOrCopyChecked(); if (ExportManager::instance()->doSaveAs(this, /* notify */ quitChecked) && quitChecked) { quit(QuitBehavior::QuitExternally); } } diff --git a/src/Gui/SettingsDialog/GeneralOptionsPage.cpp b/src/Gui/SettingsDialog/GeneralOptionsPage.cpp index 18f33f8..b94bb46 100644 --- a/src/Gui/SettingsDialog/GeneralOptionsPage.cpp +++ b/src/Gui/SettingsDialog/GeneralOptionsPage.cpp @@ -1,111 +1,111 @@ /* * 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 "GeneralOptionsPage.h" #include "SpectacleConfig.h" #include #include #include #include GeneralOptionsPage::GeneralOptionsPage(QWidget *parent) : SettingsPage(parent) { // preamble and stuff QVBoxLayout *mainLayout = new QVBoxLayout(this); - // copy save path to clipboard + // copy file location to clipboard after saving - mCopyPathToClipboard = new QCheckBox(i18n("Copy save location to the clipboard"), this); + mCopyPathToClipboard = new QCheckBox(i18n("Copy file location to clipboard after saving"), this); connect(mCopyPathToClipboard, &QCheckBox::toggled, this, &GeneralOptionsPage::markDirty); mainLayout->addWidget(mCopyPathToClipboard, 1); // Rectangular Region settings QGroupBox *rrGroup = new QGroupBox(i18n("Rectangular Region")); QVBoxLayout *rrLayout = new QVBoxLayout; rrGroup->setLayout(rrLayout); // use light background mUseLightBackground = new QCheckBox(i18n("Use light background"), this); connect(mUseLightBackground, &QCheckBox::toggled, this, &GeneralOptionsPage::markDirty); mainLayout->addWidget(mUseLightBackground, 1); // remember Rectangular Region box mRememberRect = new QCheckBox(i18n("Remember selected area"), this); connect(mRememberRect, &QCheckBox::toggled, this, &GeneralOptionsPage::markDirty); // show magnifier mShowMagnifier = new QCheckBox(i18n("Show magnifier"), this); connect(mShowMagnifier, &QCheckBox::toggled, this, &GeneralOptionsPage::markDirty); QVBoxLayout *rrCLayout = new QVBoxLayout; // rrCLayout->setContentsMargins(15, 10, 0, 10); rrCLayout->addWidget(mUseLightBackground); rrCLayout->addWidget(mRememberRect); rrCLayout->addWidget(mShowMagnifier); rrLayout->addLayout(rrCLayout); mainLayout->addWidget(rrGroup, 1); // read in the data resetChanges(); // finish up with the main layout mainLayout->addStretch(4); setLayout(mainLayout); } void GeneralOptionsPage::markDirty(bool checked) { Q_UNUSED(checked); mChangesMade = true; } void GeneralOptionsPage::saveChanges() { SpectacleConfig *cfgManager = SpectacleConfig::instance(); cfgManager->setUseLightRegionMaskColour(mUseLightBackground->checkState() == Qt::Checked); cfgManager->setRememberLastRectangularRegion(mRememberRect->checkState() == Qt::Checked); cfgManager->setShowMagnifierChecked(mShowMagnifier->checkState() == Qt::Checked); cfgManager->setCopySaveLocationToClipboard(mCopyPathToClipboard->checkState() == Qt::Checked); mChangesMade = false; } void GeneralOptionsPage::resetChanges() { SpectacleConfig *cfgManager = SpectacleConfig::instance(); mUseLightBackground->setChecked(cfgManager->useLightRegionMaskColour()); mRememberRect->setChecked(cfgManager->rememberLastRectangularRegion()); mShowMagnifier->setChecked(cfgManager->showMagnifierChecked()); mCopyPathToClipboard->setChecked(cfgManager->copySaveLocationToClipboard()); mChangesMade = false; } diff --git a/src/SpectacleConfig.cpp b/src/SpectacleConfig.cpp index afaf329..1517e31 100644 --- a/src/SpectacleConfig.cpp +++ b/src/SpectacleConfig.cpp @@ -1,268 +1,268 @@ /* * 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" SpectacleConfig::SpectacleConfig(QObject *parent) : QObject(parent) { mConfig = KSharedConfig::openConfig(QStringLiteral("spectaclerc")); mGeneralConfig = KConfigGroup(mConfig, "General"); mGuiConfig = KConfigGroup(mConfig, "GuiConfig"); } SpectacleConfig::~SpectacleConfig() {} SpectacleConfig* SpectacleConfig::instance() { static SpectacleConfig instance; return &instance; } // lastSaveAsLocation QUrl SpectacleConfig::lastSaveAsLocation() const { return mGeneralConfig.readEntry(QStringLiteral("lastSaveAsLocation"), QUrl::fromUserInput(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + QStringLiteral("/"))); } void SpectacleConfig::setLastSaveAsLocation(const QUrl &location) { mGeneralConfig.writeEntry(QStringLiteral("lastSaveAsLocation"), location); mGeneralConfig.sync(); } // 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(); } // 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 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"), false); } void SpectacleConfig::setRememberLastRectangularRegion(bool enabled) { mGuiConfig.writeEntry(QStringLiteral("rememberLastRectangularRegion"), 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(); } // 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 { return mGeneralConfig.readEntry(QStringLiteral("save-filename-format"), QStringLiteral("Screenshot_%Y%M%D_%H%m%S")); } void SpectacleConfig::setAutoSaveFilenameFormat(const QString &format) { mGeneralConfig.writeEntry(QStringLiteral("save-filename-format"), format); mGeneralConfig.sync(); } // autosave location QString SpectacleConfig::autoSaveLocation() const { return mGeneralConfig.readPathEntry(QStringLiteral("default-save-location"), QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); } void SpectacleConfig::setAutoSaveLocation(const QString &location) { mGeneralConfig.writePathEntry(QStringLiteral("default-save-location"), location); mGeneralConfig.sync(); } -// copy save location to clipboard +// 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(); }