diff '--color=auto' -Nurd screengrab-2.7.0/CMakeLists.txt screengrab-2.7.0.new/CMakeLists.txt --- screengrab-2.7.0/CMakeLists.txt 2023-11-05 04:30:13.000000000 -0800 +++ screengrab-2.7.0.new/CMakeLists.txt 2023-11-26 01:15:30.572898382 -0800 @@ -15,7 +15,7 @@ option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF) # Minimum Versions -set(KF5_MINIMUM_VERSION "5.101.0") +set(KF5_MINIMUM_VERSION "5.36.0") set(QT_MINIMUM_VERSION "5.15.0") set(QTXDG_MINIMUM_VERSION "3.12.0") diff '--color=auto' -Nurd screengrab-2.7.0/CMakeLists.txt.orig screengrab-2.7.0.new/CMakeLists.txt.orig --- screengrab-2.7.0/CMakeLists.txt.orig 1969-12-31 16:00:00.000000000 -0800 +++ screengrab-2.7.0.new/CMakeLists.txt.orig 2023-11-26 01:13:58.403649484 -0800 @@ -0,0 +1,224 @@ +cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) +# CMP0000: Call the cmake_minimum_required() command at the beginning of the top-level +# CMakeLists.txt file even before calling the project() command. +# The cmake_minimum_required(VERSION) command implicitly invokes the cmake_policy(VERSION) +# command to specify that the current project code is written for the given range of CMake +# versions. +project(screengrab) + +include(GNUInstallDirs) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +# options +option(SG_DBUS_NOTIFY "Enable D-Bus notifications" ON) +option(SG_EXT_EDIT "Enable ability to edit screenshots in external editor" ON) +option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF) + +# Minimum Versions +set(KF5_MINIMUM_VERSION "5.101.0") +set(QT_MINIMUM_VERSION "5.15.0") +set(QTXDG_MINIMUM_VERSION "3.12.0") + +find_package(Qt5LinguistTools ${QT_MINIMUM_VERSION} REQUIRED) +find_package(Qt5Network ${QT_MINIMUM_VERSION} REQUIRED) +find_package(Qt5Widgets ${QT_MINIMUM_VERSION} REQUIRED) +find_package(Qt5X11Extras ${QT_MINIMUM_VERSION} REQUIRED) +find_package(KF5WindowSystem ${KF5_MINIMUM_VERSION} REQUIRED) + +# right now we declare it as required +find_package(X11 REQUIRED) +set(HAVE_X11 1) + +find_package( + XCB REQUIRED MODULE COMPONENTS + XCB + SHAPE + XFIXES +) + +find_package( + X11_XCB REQUIRED MODULE +) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SCREENGRAB_VERSION "2.7.0") + +if (DEV_VERSION) + set(VERSION "${SCREENGRAB_VERSION}-dev (${DEV_VERSION})") +else() + set(VERSION ${SCREENGRAB_VERSION}) +endif() + +add_definitions( + -DVERSION="${VERSION}" + -DQT_NO_FOREACH +) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +message(STATUS "Build type: " ${CMAKE_BUILD_TYPE}) +message(STATUS "Install prefix: " ${CMAKE_INSTALL_PREFIX}) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Woverloaded-virtual -Wall -Wextra") + +# Although the names, LXQtTranslateTs and LXQtTranslateDesktop, they don't +# bring any dependency on lxqt. +include(LXQtTranslateTs) +include(LXQtTranslateDesktop) +include(Qt5TranslationLoader) + +if(SG_EXT_EDIT) + add_definitions( -DSG_EXT_EDIT="1") + find_package(Qt5Xdg ${QTXDG_MINIMUM_VERSION} REQUIRED) +endif() + +if(SG_DBUS_NOTIFY) + find_package(Qt5DBus ${QT_MINIMUM_VERSION} REQUIRED) + add_definitions( -DSG_DBUS_NOTIFY="1") +endif() + +message(STATUS "Editing screenshots in external editor support: " ${SG_EXT_EDIT}) +message(STATUS "Enable D-Bus notifications: " ${SG_DBUS_NOTIFY}) +message(STATUS "Use system Qxt Library: " ${SG_USE_SYSTEM_QXT}) +message(STATUS "Update source translation translations/*.ts files: " ${UPDATE_TRANSLATIONS}) + +# docs +# CMAKE_INSTALL_FULL_DOCDIR = CMAKE_INSTALL_PREFIX/CMAKE_INSTALL_DATADIR/doc/PROJECT_NAME +message(STATUS "Documentation directory: " ${CMAKE_INSTALL_FULL_DOCDIR}) +add_definitions(-DSG_DOCDIR="${CMAKE_INSTALL_FULL_DOCDIR}") + +# app icon path +add_definitions(-DSG_ICONPATH="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps/screengrab.svg") + +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src") +add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/src/common/qkeysequencewidget") +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/common/qkeysequencewidget/src") + +if (SG_EXT_EDIT) + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/modules/extedit") + add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/src/modules/extedit") +endif() + +set(SCREENGRAB_SRC + src/core/main.cpp + src/core/singleapp.cpp + src/core/core.cpp + src/core/config.cpp + src/core/regionselect.cpp + src/core/shortcutmanager.cpp + src/core/modulemanager.cpp + src/core/ui/configwidget.cpp + src/core/ui/about.cpp + src/core/ui/mainwindow.cpp +) + +if(SG_DBUS_NOTIFY) + set(SCREENGRAB_SRC ${SCREENGRAB_SRC} src/core/dbusnotifier.cpp) +endif() + +if(X11_FOUND) + set(SCREENGRAB_SRC ${SCREENGRAB_SRC} src/core/x11utils.cpp) +endif() + +set(SCREENGRAB_HDR + src/core/singleapp.h +) + +set(SCREENGRAB_UI + src/core/ui/configwidget.ui + src/core/ui/aboutwidget.ui + src/core/ui/mainwindow.ui +) + +# Qt resource file +set(SCREENGRAB_QRC screengrab.qrc) +qt5_add_resources(QRC_SOURCES ${SCREENGRAB_QRC}) + +message(STATUS "Generating localize ...") + +set(SCREENGRAB_CONFIG_FILES + screengrab.conf +) + +set(SCREENGRAB_DESKTOP_FILES_IN + screengrab.desktop.in +) + +lxqt_translate_ts(SCREENGRAB_QMS + USE_QT5 TRUE + UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS} + SOURCES + ${SCREENGRAB_SRC} + ${SCREENGRAB_UI} + INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/translations" +) + +lxqt_translate_desktop(SCREENGRAB_DESKTOP_FILES + SOURCES ${SCREENGRAB_DESKTOP_FILES_IN} + USE_YAML +) + +qt5_translation_loader(SCREENGRAB_QM_LOADER + "${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/translations" + ${PROJECT_NAME} +) + +# generating executable +add_executable(screengrab + ${SCREENGRAB_SRC} + ${SCREENGRAB_UI_H} + ${QRC_SOURCES} + ${SCREENGRAB_QMS} + ${SCREENGRAB_DESKTOP_FILES} + ${SCREENGRAB_QM_LOADER} +) + +if(SG_EXT_EDIT) + target_link_libraries(screengrab extedit) +endif() + +if(SG_DBUS_NOTIFY) + target_link_libraries(screengrab Qt5::DBus) +endif() + +if (X11_XCB_FOUND) + add_definitions( -DX11_XCB_FOUND="1") + target_link_libraries(screengrab ${X11_XCB_LIBRARIES}) +endif() + +if (XCB_XCB_FOUND) + add_definitions( -DXCB_XCB_FOUND="1") + target_link_libraries(screengrab ${XCB_XCB_LIBRARY}) +endif() + +if (XCB_SHAPE_FOUND) + add_definitions( -DXCB_SHAPE_FOUND="1") + target_link_libraries(screengrab ${XCB_SHAPE_LIBRARY}) +endif() + +if (XCB_XFIXES_FOUND) + add_definitions( -DXCB_XFOXES_FOUND="1") + target_link_libraries(screengrab ${XCB_XFIXES_LIBRARY}) +endif() + +# Link with Network and X11Extras. See pull#86. TODO: Should be optional when upload module is needed. +target_link_libraries(screengrab qkeysequencewidget Qt5::Widgets KF5::WindowSystem Qt5::X11Extras Qt5::Network ${X11_LIBRARIES}) + +# installing +install(TARGETS screengrab RUNTIME DESTINATION bin) +# install html docs +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/docs/html" DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}") +# install config files +install(FILES ${SCREENGRAB_CONFIG_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}) +# install desktop files +install(FILES ${SCREENGRAB_DESKTOP_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) +# install pixmap +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/img/screengrab.svg" DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps") +install(FILES screengrab.metainfo.xml + DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo +) diff '--color=auto' -Nurd screengrab-2.7.0/src/core/core.cpp screengrab-2.7.0.new/src/core/core.cpp --- screengrab-2.7.0/src/core/core.cpp 2023-11-05 04:30:13.000000000 -0800 +++ screengrab-2.7.0.new/src/core/core.cpp 2023-11-26 01:15:31.602889989 -0800 @@ -32,8 +32,7 @@ #include #include -#include -#include +#include #include #ifdef X11_XCB_FOUND @@ -269,15 +268,15 @@ if (screen == nullptr) screen = QGuiApplication::screens().at(0); - WId wnd = KX11Extras::activeWindow(); + WId wnd = KWindowSystem::activeWindow(); // this window screenshot will be invalid // if there's no active window or the active window is ours - bool invalid(!wnd || !KX11Extras::hasWId(wnd) || (_wnd && _wnd->winId() == wnd)); + bool invalid(!wnd || !KWindowSystem::hasWId(wnd) || (_wnd && _wnd->winId() == wnd)); if (!invalid) { // or if it isn't on the current desktop KWindowInfo info(wnd, NET::WMDesktop); - invalid = info.valid() && !info.isOnDesktop(KX11Extras::currentDesktop()); + invalid = info.valid() && !info.isOnDesktop(KWindowSystem::currentDesktop()); if (!invalid) { // or if it is a desktop or panel/dock info = KWindowInfo(wnd, NET::WMWindowType); diff '--color=auto' -Nurd screengrab-2.7.0/src/core/core.cpp.orig screengrab-2.7.0.new/src/core/core.cpp.orig --- screengrab-2.7.0/src/core/core.cpp.orig 1969-12-31 16:00:00.000000000 -0800 +++ screengrab-2.7.0.new/src/core/core.cpp.orig 2023-11-26 01:13:58.413649402 -0800 @@ -0,0 +1,623 @@ +/*************************************************************************** + * Copyright (C) 2009 - 2013 by Artem 'DOOMer' Galichkin * + * doomer3d@gmail.com * + * * + * 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, see . * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#ifdef X11_XCB_FOUND +#include "x11utils.h" +#endif + +#include "core/core.h" + +#ifdef SG_DBUS_NOTIFY +#include "dbusnotifier.h" +#endif + +Core* Core::corePtr = nullptr; + +Core::Core() +{ + qRegisterMetaType("StateNotifyMessage"); + + _conf = Config::instance(); + _conf->loadSettings(); + _lastSelectedArea = _conf->getLastSelection(); + + _pixelMap = new QPixmap; + _selector = nullptr; + _firstScreen = true; + + _cmdLine.setApplicationDescription(QStringLiteral("ScreenGrab ") + tr("is a crossplatform application for fast creating screenshots of your desktop.")); + _cmdLine.addHelpOption(); + _cmdLine.addVersionOption(); + + QCommandLineOption optFullScreen(QStringList() << QStringLiteral("f") << QStringLiteral("fullscreen"), tr("Take a fullscreen screenshot")); + _cmdLine.addOption(optFullScreen); + _screenTypeOpts.append(optFullScreen); + + QCommandLineOption optActiveWnd(QStringList() << QStringLiteral("a") << QStringLiteral("active"), tr("Take a screenshot of the active window")); + _cmdLine.addOption(optActiveWnd); + _screenTypeOpts.append(optActiveWnd); + + QCommandLineOption optSelectedRect(QStringList() << QStringLiteral("r") << QStringLiteral("region"), tr("Take a screenshot of a selection of the screen")); + _cmdLine.addOption(optSelectedRect); + _screenTypeOpts.append(optSelectedRect); + + QCommandLineOption optRunMinimized(QStringList() << QStringLiteral("m") << QStringLiteral("minimized"), tr("Run the application with a hidden main window")); + _cmdLine.addOption(optRunMinimized); + + sleep(250); + + _wnd = nullptr; +} + +Core::Core(const Core& ): QObject() +{ +} + +Core& Core::operator=(const Core &) +{ + return *this; +} + +Core* Core::instance() +{ + if (!corePtr) + corePtr = new Core; + return corePtr; +} + +Core::~Core() +{ + killTempFile(); + delete _pixelMap; + _conf->killInstance(); +} + +void Core::initWindow(const QString& ipcMessage) +{ + if (!_wnd) { + _wnd = new MainWindow; + _wnd->setConfig(_conf); + _wnd->updateModulesActions(_modules.generateModulesActions()); + _wnd->updateModulesMenus(_modules.generateModulesMenus()); + + screenShot(true); // first screenshot + + _wnd->resize(_conf->getRestoredWndSize()); + + if (_wnd) { + if (runAsMinimized()) + { + if (_wnd->isTrayed()) + _wnd->windowHideShow(); + else + _wnd->showMinimized(); + } else + _wnd->show(); + } + } else { + _wnd->showWindow(ipcMessage); + screenShot(); + } +} + +void Core::sleep(int msec) +{ + QMutex mutex; + mutex.lock(); + QWaitCondition pause; + pause.wait(&mutex, msec); // def 240 + mutex.unlock(); +} + +void Core::coreQuit() +{ + _conf->setLastSelection(_lastSelectedArea); + _conf->saveScreenshotSettings(); + + if (_wnd) { + _conf->setRestoredWndSize(_wnd->width(), _wnd->height()); + _conf->saveWndSize(); + _wnd->close(); + } + + if (corePtr) + { + delete corePtr; + corePtr = nullptr; + } + + qApp->quit(); +} + +void Core::setScreen() +{ + _wnd->hideToShot(); + + // new code experimental + if (_conf->getDelay() == 0) + QTimer::singleShot(200, this, SLOT(screenShot())); + else + QTimer::singleShot(1000 * _conf->getDelay(), this, SLOT(screenShot())); + +} + +void Core::getFullScreenPixmap(QScreen* screen) +{ + const auto siblings = screen->virtualSiblings(); + if (siblings.size() == 1) + *_pixelMap = screen->grabWindow(0); // 0 for the entire screen + else + { // consider all siblings + QPixmap pix = QPixmap(screen->virtualSize()); + pix.fill(Qt::transparent); + QPainter painter(&pix); + for (const auto& sc : siblings) + painter.drawPixmap(sc->geometry().topLeft(), sc->grabWindow(0)); + *_pixelMap = pix; + } +} + +// get screenshot +void Core::screenShot(bool first) +{ + killTempFile(); // remove the old temp file if any + + sleep(400); // delay for hide "fade effect" bug in the KWin with compositing + _firstScreen = first; + + // Update the last saving date, if this is the first screenshot + if (_firstScreen) + _conf->updateLastSaveDate(); + + switch(_conf->getDefScreenshotType()) + { + case Core::FullScreen: + { + auto screen = QGuiApplication::screenAt(QCursor::pos()); + if (screen == nullptr) + screen = QGuiApplication::screens().at(0); + getFullScreenPixmap(screen); + grabCursor(0, 0); + + checkAutoSave(first); + _wnd->updatePixmap(_pixelMap); + break; + } + case Core::Window: + { + getActiveWindow(); + checkAutoSave(first); + _wnd->updatePixmap(_pixelMap); + break; + } + case Core::Area: + { + _selector = new RegionSelect(_conf); + connect(_selector, &RegionSelect::processDone, this, &Core::regionGrabbed); + break; + } + case Core::PreviousSelection: + { + _selector = new RegionSelect(_conf, _lastSelectedArea); + connect(_selector, &RegionSelect::processDone, this, &Core::regionGrabbed); + break; + } + default: + getFullScreenPixmap(QGuiApplication::primaryScreen()); + break; + } + + + + _wnd->updatePixmap(_pixelMap); + _wnd->restoreFromShot(); +} + +void Core::checkAutoSave(bool first) +{ + if (_conf->getAutoSave()) + { + // hack + if (first) + { + if (_conf->getAutoSaveFirst()) + QTimer::singleShot(600, this, SLOT(autoSave())); + } + else + autoSave(); + } +} + +void Core::getActiveWindow() // called only with window screenshots +{ + auto screen = QGuiApplication::screenAt(QCursor::pos()); + if (screen == nullptr) + screen = QGuiApplication::screens().at(0); + + WId wnd = KX11Extras::activeWindow(); + + // this window screenshot will be invalid + // if there's no active window or the active window is ours + bool invalid(!wnd || !KX11Extras::hasWId(wnd) || (_wnd && _wnd->winId() == wnd)); + if (!invalid) + { // or if it isn't on the current desktop + KWindowInfo info(wnd, NET::WMDesktop); + invalid = info.valid() && !info.isOnDesktop(KX11Extras::currentDesktop()); + if (!invalid) + { // or if it is a desktop or panel/dock + info = KWindowInfo(wnd, NET::WMWindowType); + QFlags flags; + flags |= NET::DesktopMask; + flags |= NET::DockMask; + invalid = info.valid() && NET::typeMatchesMask(info.windowType(NET::AllTypesMask), flags); + } + } + + // also invalid if the window is shaded/invisible + KWindowInfo info(wnd, NET::XAWMState | NET::WMFrameExtents); + if (!invalid && info.mappingState() != NET::Visible) + invalid = true; + + // if this is an invalid screenshot, take a fullscreen shot instead + if (invalid) + { + qWarning() << "Could not take a window screenshot."; + *_pixelMap = screen->grabWindow(0); + return; + } + + // no decorations option is selected + if (_conf->getNoDecoration()) + { + *_pixelMap = screen->grabWindow(wnd); + return; + } + + QRect geometry = info.frameGeometry(); + + // WARNING: Until now, "KWindowInfo::frameGeometry" does not consider the screens's + // device pixel ratio. So, the frame geometry should be transformed. + qreal pixelRatio = screen->devicePixelRatio(); + geometry.setTopLeft(QPointF(geometry.topLeft() / pixelRatio).toPoint()); + geometry.setBottomRight(QPointF(geometry.bottomRight() / pixelRatio).toPoint()); + + // The offscreen part of the window will appear as a black area in the screenshot. + // Until a better method is found, the offscreen area is ignored here. + QRect r = screen->virtualGeometry().intersected(geometry); + + // the window positon should be calculated relative to the screen + *_pixelMap = screen->grabWindow(0, + r.x() - screen->geometry().x(), + r.y() - screen->geometry().y(), + r.width(), + r.height()); + + grabCursor(geometry.x(), geometry.y()); +} + +void Core::grabCursor(int offsetX, int offsetY) +{ +#ifdef XCB_XFOXES_FOUND + if (_conf->getIncludeCursor()) + X11Utils::compositePointer(offsetX, offsetY, _pixelMap); +#else + Q_UNUSED(offsetx); + Q_UNUSED(offsety); +#endif + + +} + +void Core::sendSystemNotify(const StateNotifyMessage& /*notify*/) +{ + qDebug() << "Send system notification"; +} + +QString Core::getSaveFilePath(const QString &format) +{ + QString initPath; + + do + { + QDir dir(_conf->getSaveDir()); + const QString filePath = dir.filePath(_conf->getSaveFileName()); + if (_conf->getDateTimeInFilename()) + initPath = filePath + QStringLiteral("-") + getDateTimeFileName() + QStringLiteral(".") + format; + else + { + if (_conf->getScrNum() != 0) + initPath = filePath + _conf->getScrNumStr() + QStringLiteral(".") + format; + else + initPath = filePath + QStringLiteral(".") + format; + } + } while (checkExsistFile(initPath)); + + return initPath; +} + +bool Core::checkExsistFile(const QString &path) +{ + bool exist = QFile::exists(path); + + if (exist) + _conf->increaseScrNum(); + + return exist; +} + +QString Core::getDateTimeFileName() +{ + QString currentDateTime = QDateTime::currentDateTime().toString(_conf->getDateTimeTpl()); + + if (currentDateTime == _conf->getLastSaveDate().toString(_conf->getDateTimeTpl()) && _conf->getScrNum() != 0) + currentDateTime += QStringLiteral("-") + _conf->getScrNumStr(); + else + _conf->resetScrNum(); + + return currentDateTime; +} + +Config *Core::config() +{ + return _conf; +} + +void Core::updatePixmap() +{ + if (QFile::exists(_tempFilename)) + { + _pixelMap->load(_tempFilename, "png"); + _wnd->updatePixmap(_pixelMap); + } +} + +QString Core::getTempFilename(const QString& format) +{ + if (_tempFilename.isEmpty()) + { + _tempFilename = QUuid::createUuid().toString(); + int size = _tempFilename.size() - 2; + _tempFilename = _tempFilename.mid(1, size).left(8); + _tempFilename = QDir::tempPath() + QDir::separator() + + QStringLiteral("screenshot-") + _tempFilename + + QStringLiteral(".") + format; + } + return _tempFilename; +} + +void Core::killTempFile() +{ + if (QFile::exists(_tempFilename)) + QFile::remove(_tempFilename); + _tempFilename.clear(); +} + +bool Core::writeScreen(QString& fileName, QString& format, bool tmpScreen) +{ + // adding extension format + if (!fileName.contains(QStringLiteral(".") + format)) + fileName.append(QStringLiteral(".") + format); + + // saving temp file + if (tmpScreen) + { + if (!fileName.isEmpty()) + return _pixelMap->save(fileName, format.toLatin1().constData(), _conf->getImageQuality()); + else + return false; + } + + // writing file + bool saved = false; + if (!fileName.isEmpty()) + { + if (format == QLatin1String("jpg")) + saved = _pixelMap->save(fileName,format.toLatin1().constData(), _conf->getImageQuality()); + else + saved = _pixelMap->save(fileName,format.toLatin1().constData(), -1); + + if (saved) + { + StateNotifyMessage message(tr("Saved"), tr("Saved to ") + fileName); + + message.message = message.message + copyFileNameToCliipboard(fileName); + _conf->updateLastSaveDate(); + sendNotify(message); + } + else + qWarning() << "Error saving file " << fileName; + } + + return saved; +} + +QString Core::copyFileNameToCliipboard(QString file) +{ + QString retString = QLatin1String(""); + switch (_conf->getAutoCopyFilenameOnSaving()) + { + case Config::nameToClipboardFile: + { + file = file.section(QLatin1Char('/'), -1); + QApplication::clipboard()->setText(file); + retString = QChar(QChar::LineSeparator) + tr("Name of saved file is copied to the clipboard"); + break; + } + case Config::nameToClipboardPath: + { + QApplication::clipboard()->setText(file); + retString = QChar(QChar::LineSeparator) + tr("Path to saved file is copied to the clipboard"); + break; + } + default: + break; + } + return retString; +} + +void Core::sendNotify(const StateNotifyMessage &message) +{ +#ifdef SG_DBUS_NOTIFY + DBusNotifier *notifier = new DBusNotifier(); + notifier->displayNotify(message); +#else + _wnd->showTrayMessage(message.header, message.message); +#endif +} + +void Core::copyScreen() +{ + QApplication::clipboard()->setPixmap(*_pixelMap, QClipboard::Clipboard); + StateNotifyMessage message(tr("Copied"), tr("Screenshot is copied to clipboard")); + sendNotify(message); +} + +void Core::openInExtViewer() +{ + if (_conf->getEnableExtView()) + { + QString format = _conf->getSaveFormat(); + if (format.isEmpty()) + format = QLatin1String("png"); + + QString tempFileName = getTempFilename(format); + writeScreen(tempFileName, format, true); + + QMimeDatabase db; + XdgMimeApps mimeAppsDb; + QMimeType mt = db.mimeTypeForFile(tempFileName); + auto app = mimeAppsDb.defaultApp(mt.name()); + if (app != nullptr) + { + QString exec; + exec = app->expandExecString().first(); + delete app; + QStringList args; + args << tempFileName; + + QProcess::startDetached(exec, args); + } + } +} + +ModuleManager* Core::modules() +{ + return &_modules; +} + +void Core::addCmdLineOption(const QCommandLineOption& option) +{ + _cmdLine.addOption(option); +} + +bool Core::checkCmdLineOption(const QCommandLineOption& option) +{ + return _cmdLine.isSet(option); +} + +bool Core::checkCmdLineOptions(const QStringList &options) +{ + for (int i = 0; i < options.count(); ++i) + if (_cmdLine.isSet(options.at(i))) + return true; + return false; +} + +void Core::processCmdLineOpts(const QStringList& arguments) +{ + _cmdLine.process(arguments); + + // Check commandline parameters and set screenshot type + for (int i=0; i < _screenTypeOpts.count(); ++i) + if (_cmdLine.isSet(_screenTypeOpts.at(i))) + _conf->setDefScreenshotType(i); + + initWindow(); +} + +bool Core::runAsMinimized() +{ + return (_cmdLine.isSet(QStringLiteral("minimized")) || _cmdLine.isSet(QStringLiteral("m"))); +} + +void Core::autoSave() +{ + QString format = _conf->getSaveFormat(); + QString fileName = getSaveFilePath(format); + writeScreen(fileName, format); +} + +QString Core::getVersionPrintable() +{ + QString str = QStringLiteral("ScreenGrab: ") + qApp->applicationVersion() + QStringLiteral("\n"); + str += QStringLiteral("Qt: ") + QString::fromLatin1(qVersion()) + QStringLiteral("\n"); + return str; +} + +QPixmap* Core::getPixmap() +{ + return _pixelMap; +} + +QByteArray Core::getScreenData() +{ + QByteArray bytes; + QBuffer buffer(&bytes); + buffer.open(QIODevice::WriteOnly); + _pixelMap->save(&buffer, _conf->getSaveFormat().toLatin1().constData()); + return bytes; +} + +void Core::regionGrabbed(bool grabbed) +{ + if (grabbed) + { + *_pixelMap = _selector->getSelection(); + + int x = _selector->getSelectionStartPos().x(); + int y = _selector->getSelectionStartPos().y(); + int w = _pixelMap->rect().width() / _pixelMap->devicePixelRatio(); + int h = _pixelMap->rect().height() / _pixelMap->devicePixelRatio(); + _lastSelectedArea.setRect(x, y, w, h); + + checkAutoSave(); + } + + _wnd->updatePixmap(_pixelMap); + _selector->deleteLater(); +}