diff --git a/doc/index.docbook b/doc/index.docbook index 83b1056..1013761 100644 --- a/doc/index.docbook +++ b/doc/index.docbook @@ -1,347 +1,351 @@ Spectacle"> BoudhayanGupta"> bgupta@kde.org"> ]> 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; 2017-11-06 Applications 17.12 &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, clicking the downward arrow beside the Save & Exit button, and selecting Preferences from the menu. + 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; this behavior can be configured in Spectacle's settings. The default save location and filename can also be configured there, as described later. To quickly save the image and quit &spectacle;, click on the arrow portion of the Save As... button and press the Save & Exit (&Ctrl;Q) 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 Content 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. Content Options The content 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. 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. Additional Functionality Buttons There are five buttons located at the bottom of the &spectacle; window. Their functions are described below: Help - This button gives you the common menu items described in the Help Menu of the &kde; Fundamentals. + This button gives you the common menu items described in the Help Menu of the &kde; Fundamentals. + + + + Configure... + + This button gives you access to Spectacle's Configure window where you can change the capture settings and default save location and filename. Export Image... This drop-down menu 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 This button copies the current screenshot to the clipboard. You can also use the &Ctrl;C keyboard shortcut for this. Save & Exit Clicking this button saves the screenshot as a PNG image in your default Pictures folder and immediately exits the application. - - Additionally, if you click the arrow on the right side of the button, a drop-down menu allows you to simply Save the image, save the image with a different filename, location and format (Save As...), Print the image, and configure the default Preferences, such as application preferences and where to save the image by default and what filename to save it as. Configure - Use Save & ExitPreferences to open the configuration dialog. + Use the Configure... button to open the configuration dialog. General General Remember last used Save mode The default behavior of the save button is to display Save As. Choosing another save mode by clicking on the arrow portion of the button will make that save mode the default one. Disable this option to make the button stop remembering the last used save mode Copy save location to clipboard 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 & Exit or the Save functions, &spectacle; saves the image with a default filename, in your Pictures folder under 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 or Save & Exit. 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 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 73ed41c..193b6bf 100644 --- a/src/Gui/KSMainWindow.cpp +++ b/src/Gui/KSMainWindow.cpp @@ -1,331 +1,334 @@ /* * 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 #include #include #include #include #include #include #ifdef XCB_FOUND #include #include #endif #include #include #include #include #include #include #include #include "SettingsDialog/SettingsDialog.h" #include "ExportMenu.h" #include "ExportManager.h" #include "SpectacleConfig.h" KSMainWindow::KSMainWindow(bool onClickAvailable, QWidget *parent) : QDialog(parent), mKSWidget(new KSWidget), mDivider(new QFrame), mDialogButtonBox(new QDialogButtonBox), mSendToButton(new QPushButton), + mConfigureButton(new QToolButton), mClipboardButton(new QToolButton), mSaveButton(new QToolButton), mSaveMenu(new QMenu), mMessageWidget(new KMessageWidget), 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(mSendToButton, KGuiItem(i18n("Export Image..."))); 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->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); mClipboardButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mDialogButtonBox->addButton(mClipboardButton, QDialogButtonBox::ActionRole); mSaveButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mSaveButton->setMenu(mSaveMenu); mSaveButton->setPopupMode(QToolButton::MenuButtonPopup); buildSaveMenu(); mDialogButtonBox->addButton(mSaveButton, QDialogButtonBox::ActionRole); // the help menu KHelpMenu *helpMenu = new KHelpMenu(this, KAboutData::applicationData(), true); mDialogButtonBox->button(QDialogButtonBox::Help)->setMenu(helpMenu->menu()); // 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(840, 420).expandedTo(minimumSize())); // done with the init } void KSMainWindow::buildSaveMenu() { // first clear the menu mSaveMenu->clear(); // get our actions in order QAction *actionSave = KStandardAction::save(this, &KSMainWindow::save, this); QAction *actionSaveAs = KStandardAction::saveAs(this, &KSMainWindow::saveAs, this); QAction *actionSaveExit = new QAction(QIcon::fromTheme(QStringLiteral("document-save")), i18n("Save &&& Exit"), this); actionSaveExit->setToolTip(i18n("Save screenshot in your Pictures directory and exit")); actionSaveExit->setShortcut(QKeySequence(QKeySequence::Quit)); connect(actionSaveExit, &QAction::triggered, this, &KSMainWindow::saveAndExit); // static or dynamic SpectacleConfig *cfgManager = SpectacleConfig::instance(); int switchState = cfgManager->useDynamicSaveButton() ? cfgManager->lastUsedSaveMode() : 0; // put the actions in order switch (switchState) { case 0: default: mSaveButton->setDefaultAction(actionSaveAs); mSaveMenu->addAction(actionSaveExit); mSaveMenu->addAction(actionSave); break; case 1: mSaveButton->setDefaultAction(actionSave); mSaveMenu->addAction(actionSaveExit); mSaveMenu->addAction(actionSaveAs); break; case 2: mSaveButton->setDefaultAction(actionSaveExit); mSaveMenu->addAction(actionSave); mSaveMenu->addAction(actionSaveAs); break; } // finish off building the menu mSaveMenu->addAction(KStandardAction::print(this, SLOT(showPrintDialog()), this)); - mSaveMenu->addSeparator(); - mSaveMenu->addAction(QIcon::fromTheme(QStringLiteral("applications-system")), i18n("Preferences"), - this, SLOT(showPreferencesDialog())); } // 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(); 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(); } 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::showImageSharedFeedback(bool error, const QString &message) { if (error) { mMessageWidget->setMessageType(KMessageWidget::Error); mMessageWidget->setText(i18n("There was a problem sharing the image: %1", message)); mMessageWidget->setIcon(QIcon::fromTheme(QStringLiteral("dialog-error"))); } else { mMessageWidget->setMessageType(KMessageWidget::Positive); if (message.isEmpty()) mMessageWidget->setText(i18n("Image shared")); else mMessageWidget->setText(i18n("You can find the shared image at: %1", message)); mMessageWidget->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok-apply"))); } mMessageWidget->animatedShow(); QTimer::singleShot(20000, mMessageWidget, &KMessageWidget::animatedHide); } void KSMainWindow::sendToClipboard() { ExportManager::instance()->doCopyToClipboard(); mMessageWidget->setMessageType(KMessageWidget::Information); mMessageWidget->setText(i18n("The screenshot has been copied to the clipboard.")); mMessageWidget->setIcon(QIcon::fromTheme(QStringLiteral("dialog-information"))); mMessageWidget->animatedShow(); QTimer::singleShot(10000, mMessageWidget, &KMessageWidget::animatedHide); } void KSMainWindow::showPreferencesDialog() { SettingsDialog prefDialog(this); prefDialog.exec(); } void KSMainWindow::setScreenshotWindowTitle(QUrl location) { setWindowTitle(location.fileName()); setWindowModified(false); } void KSMainWindow::save() { SpectacleConfig::instance()->setLastUsedSaveMode(1); buildSaveMenu(); ExportManager::instance()->doSave(); } void KSMainWindow::saveAs() { SpectacleConfig::instance()->setLastUsedSaveMode(0); buildSaveMenu(); ExportManager::instance()->doSaveAs(this); } void KSMainWindow::saveAndExit() { SpectacleConfig::instance()->setLastUsedSaveMode(2); qApp->setQuitOnLastWindowClosed(false); ExportManager::instance()->doSave(QUrl(), true); hide(); } diff --git a/src/Gui/KSMainWindow.h b/src/Gui/KSMainWindow.h index fe5104c..d35443d 100644 --- a/src/Gui/KSMainWindow.h +++ b/src/Gui/KSMainWindow.h @@ -1,85 +1,86 @@ /* * 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 KSMAINWINDOW_H #define KSMAINWINDOW_H #include #include #include #include #include #include #include "PlatformBackends/ImageGrabber.h" #include "ExportMenu.h" #include "KSWidget.h" class KSMainWindow : public QDialog { Q_OBJECT public: explicit KSMainWindow(bool onClickAvailable, QWidget *parent = 0); ~KSMainWindow(); private slots: void captureScreenshot(ImageGrabber::GrabMode mode, int timeout, bool includePointer, bool includeDecorations); void showPrintDialog(); void showPreferencesDialog(); void showImageSharedFeedback(bool error, const QString &message); void sendToClipboard(); void init(); void buildSaveMenu(); void save(); void saveAs(); void saveAndExit(); public slots: void setScreenshotAndShow(const QPixmap &pixmap); void setScreenshotWindowTitle(QUrl location); signals: void newScreenshotRequest(ImageGrabber::GrabMode mode, int timeout, bool includePointer, bool includeDecorations); void dragAndDropRequest(); protected: void moveEvent(QMoveEvent *event) Q_DECL_OVERRIDE; private: KSWidget *mKSWidget; QFrame *mDivider; QDialogButtonBox *mDialogButtonBox; QPushButton *mSendToButton; + QToolButton *mConfigureButton; QToolButton *mClipboardButton; QToolButton *mSaveButton; QMenu *mSaveMenu; KMessageWidget *mMessageWidget; ExportMenu *mExportMenu; bool mOnClickAvailable; }; #endif // KSMAINWINDOW_H