Add delayed capture support

Adding this option required to modify the dbus API, with this changed I've improved the logic which saves the captures.
This commit is contained in:
lupoDharkael
2017-07-25 00:05:31 +02:00
parent 8d76deaa5a
commit 8870fd1ed4
13 changed files with 141 additions and 168 deletions

View File

@@ -2,48 +2,31 @@
<node>
<interface name="org.dharkael.Flameshot">
<!--
openCapture:
Opens the user interface used to capture pictures of the screen.
<!--
graphicCapture:
@path: the path where the screenshot will be saved. When the argument is empty the program will ask for a path graphically.
@delay: delay time in milliseconds.
Open the user interface used to capture the screen.
-->
<method name="openCapture">
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
<!--
openCaptureWithPath:
@path: the path where the screenshot will be saved
Opens the user interface used to capture pictures of the screen with
a predefined save path (wont ask for it when saving the capture).
-->
<method name="openCaptureWithPath">
<method name="graphicCapture">
<arg name="path" type="s" direction="in"/>
<arg name="delay" type="i" direction="in"/>
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
<!--
fullScreen:
@toClipboard: Whether to copy the screenshot to clipboard or not
Takes a simple screenshot of the whole screen.
fullScreen:
@path: the path where the screenshot will be saved. When the argument is empty the program will ask for a path graphically.
@toClipboard: Whether to copy the screenshot to clipboard or not.
@delay: delay time in milliseconds.
Takes a screenshot of the whole screen.
-->
<method name="fullScreen">
<arg name="toClipboard" type="b" direction="in"/>
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
<!--
fullScreenWithPath:
@path: the path where the screenshot will be saved
@toClipboard: Whether to copy the screenshot to clipboard or not
Takes a simple screenshot of the whole screen with
a predefined save path (wont ask for it when saving the capture).
-->
<method name="fullScreenWithPath">
<arg name="path" type="s" direction="in"/>
<arg name="toClipboard" type="b" direction="in"/>
<arg name="delay" type="i" direction="in"/>
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
</interface>

View File

@@ -47,13 +47,11 @@ namespace {
// size of the handlers at the corners of the selection
const int HANDLE_SIZE = 9;
}
// http://doc.qt.io/qt-5/qwidget.html#setMask
CaptureWidget::CaptureWidget(bool enableSaveWindow, QWidget *parent) :
// enableSaveWIndow
CaptureWidget::CaptureWidget(const QString &forcedSavePath, QWidget *parent) :
QWidget(parent), m_mouseOverHandle(0), m_mouseIsClicked(false),
m_rightClick(false), m_newSelection(false), m_grabbing(false),
m_onButton(false), m_enableSaveWindow(enableSaveWindow),
m_onButton(false), m_forcedSavePath(forcedSavePath),
m_state(CaptureButton::TYPE_MOVESELECTION)
{
m_showInitialMsg = ConfigHandler().getShowHelp();
@@ -389,37 +387,29 @@ void CaptureWidget::keyPressEvent(QKeyEvent *e) {
}
QString CaptureWidget::saveScreenshot(bool toClipboard) {
hide();
QString path;
if (m_selection.isNull()) {
path = m_screenshot->graphicalSave(QRect(), this);
} else { // save full screen when no selection
path = m_screenshot->graphicalSave(getExtendedSelection(), this);
}
if (!path.isEmpty()) {
QString saveMessage(tr("Capture saved in "));
Q_EMIT newMessage(saveMessage + path);
QString savePath, saveMessage;
bool ok = true;
if(m_forcedSavePath.isEmpty()) {
if(isVisible()) {
hide();
}
savePath = m_screenshot->graphicalSave(ok, getExtendedSelection(), this);
} else {
ConfigHandler config;
config.setSavePath(m_forcedSavePath);
savePath = m_screenshot->fileSave(ok, getExtendedSelection());
if(!ok || config.getSavePath() != m_forcedSavePath) {
saveMessage = tr("Error trying to save in ") + savePath;
Q_EMIT newMessage(saveMessage);
}
}
if (toClipboard) {
copyScreenshot();
}
close();
return path;
}
QString CaptureWidget::saveScreenshot(QString path, bool toClipboard) {
ConfigHandler().setSavePath(path);
QString savePath;
if (m_selection.isNull()) {
savePath = m_screenshot->fileSave();
} else { // save full screen when no selection
savePath = m_screenshot->fileSave(getExtendedSelection());
if(ok) {
saveMessage = tr("Capture saved in ") + savePath;
Q_EMIT newMessage(saveMessage);
}
if (toClipboard) {
copyScreenshot();
}
QString saveMessage(tr("Capture saved in "));
Q_EMIT newMessage(saveMessage + savePath);
close();
return savePath;
}
@@ -556,9 +546,7 @@ void CaptureWidget::handleButtonSignal(CaptureTool::Request r) {
setCursor(Qt::CrossCursor);
break;
case CaptureTool::REQ_SAVE_SCREENSHOT:
m_enableSaveWindow ?
saveScreenshot() :
saveScreenshot(ConfigHandler().getSavePath());
saveScreenshot();
break;
case CaptureTool::REQ_SELECT_ALL:
m_selection = rect();
@@ -649,6 +637,7 @@ QPoint CaptureWidget::limitPointToRect(const QPoint &p, const QRect &r) const {
}
QRect CaptureWidget::getExtendedSelection() const {
if(m_selection.isNull()) return QRect();
auto devicePixelRatio = m_screenshot->getScreenshot().devicePixelRatio();
return QRect(m_selection.left() * devicePixelRatio,

View File

@@ -45,13 +45,13 @@ class CaptureWidget : public QWidget {
friend class CaptureButton;
public:
explicit CaptureWidget(bool enableSaveWindow = true, QWidget *parent = nullptr);
explicit CaptureWidget(const QString &forcedSavePath = "",
QWidget *parent = nullptr);
~CaptureWidget();
void updateButtons();
public slots:
QString saveScreenshot(bool toClipboard = false);
QString saveScreenshot(QString path, bool toClipboard = false);
void handleButtonSignal(CaptureTool::Request r);
signals:
@@ -97,7 +97,8 @@ protected:
bool m_grabbing;
bool m_onButton;
bool m_showInitialMsg;
bool m_enableSaveWindow;
const QString m_forcedSavePath;
// naming convention for handles
// T top, B bottom, R Right, L left

View File

@@ -59,7 +59,10 @@ QPixmap Screenshot::getScreenshot() const {
// graphicalSave generates a graphical window to ask about the save path and
// saves the screenshot with all the modifications in such directory
QString Screenshot::graphicalSave(const QRect &selection, QWidget *parent) const {
QString Screenshot::graphicalSave(bool &ok,
const QRect &selection,
QWidget *parent) const
{
QString savePath = FileNameHandler().getAbsoluteSavePath();
// setup window
QFileDialog fileDialog(parent, QObject::tr("Save As"), savePath);
@@ -74,7 +77,6 @@ QString Screenshot::graphicalSave(const QRect &selection, QWidget *parent) const
fileDialog.setDefaultSuffix("png");
fileDialog.setWindowIcon(QIcon(":img/flameshot.png"));
bool saved = false;
QString fileName;
do {
if (fileDialog.exec() != QDialog::Accepted) { return ""; }
@@ -89,8 +91,8 @@ QString Screenshot::graphicalSave(const QRect &selection, QWidget *parent) const
} else { // save full screen when no selection
pixToSave = m_modifiedScreenshot.copy(selection);
}
saved = pixToSave.save(fileName);
if (!saved) {
ok = pixToSave.save(fileName);
if (!ok) {
QMessageBox saveErrBox(
QMessageBox::Warning,
QObject::tr("Save Error"),
@@ -99,11 +101,11 @@ QString Screenshot::graphicalSave(const QRect &selection, QWidget *parent) const
saveErrBox.setWindowIcon(QIcon(":img/flameshot.png"));
saveErrBox.exec();
}
} while(!saved);
} while(!ok);
return savePath;
}
QString Screenshot::fileSave(const QRect &selection) const {
QString Screenshot::fileSave(bool &ok, const QRect &selection) const {
QString savePath = FileNameHandler().getAbsoluteSavePath();
QPixmap pixToSave;
if (selection.isEmpty()) {
@@ -111,7 +113,8 @@ QString Screenshot::fileSave(const QRect &selection) const {
} else { // save full screen when no selection
pixToSave = m_modifiedScreenshot.copy(selection);
}
return pixToSave.save(savePath) ? savePath : "";
ok = pixToSave.save(savePath);
return savePath;
}
// paintModification adds a new modification to the screenshot

View File

@@ -37,8 +37,10 @@ public:
QPixmap getBaseScreenshot() const;
QPixmap getScreenshot() const;
QString graphicalSave(const QRect &selection = QRect(), QWidget *parent = 0) const;
QString fileSave(const QRect &selection = QRect()) const;
QString graphicalSave(bool &ok,
const QRect &selection = QRect(),
QWidget *parent = 0) const;
QString fileSave(bool &ok, const QRect &selection = QRect()) const;
void uploadToImgur(QNetworkAccessManager *,
const QRect &selection = QRect());
QPixmap paintModification(const CaptureModification*);

View File

@@ -46,16 +46,12 @@ Controller::Controller(QObject *parent) : QObject(parent),
}
QString Controller::saveScreenshot(bool toClipboard) {
QPointer<CaptureWidget> w = createCapture();
QString Controller::saveScreenshot(const QString &path,
bool const toClipboard) {
QPointer<CaptureWidget> w = createCaptureWidget(path);
return w->saveScreenshot(toClipboard);
}
QString Controller::saveScreenshot(QString path, bool toClipboard) {
QPointer<CaptureWidget> w = createCapture();
return w->saveScreenshot(path, toClipboard);
}
// creates the items of the trayIcon
void Controller::createActions() {
m_configAction = new QAction(tr("&Configuration"), this);
@@ -104,17 +100,17 @@ void Controller::trayIconActivated(QSystemTrayIcon::ActivationReason r) {
}
// creation of a new capture
QPointer<CaptureWidget> Controller::createCapture(bool enableSaveWindow) {
QPointer<CaptureWidget> w = new CaptureWidget(enableSaveWindow);
QPointer<CaptureWidget> Controller::createCaptureWidget(const QString &forcedSavePath) {
QPointer<CaptureWidget> w = new CaptureWidget(forcedSavePath);
connect(w, &CaptureWidget::newMessage,
this, &Controller::showDesktopNotification);
return w;
}
// creation of a new capture in GUI mode
void Controller::createVisualCapture(bool enableSaveWindow) {
void Controller::createVisualCapture(const QString &forcedSavePath) {
if (!m_captureWindow) {
m_captureWindow = createCapture(enableSaveWindow);
m_captureWindow = createCaptureWidget(forcedSavePath);
m_captureWindow->showFullScreen();
}
}

View File

@@ -35,12 +35,11 @@ class Controller : public QObject {
public:
explicit Controller(QObject *parent = nullptr);
QString saveScreenshot(bool toClipboard = false);
QString saveScreenshot(QString path, bool toClipboard = false);
public slots:
QPointer<CaptureWidget> createCapture(bool enableSaveWindow = true);
void createVisualCapture(bool enableSaveWindow = true);
QString saveScreenshot(const QString &path = "",
bool const toClipboard = false);
void createVisualCapture(const QString &forcedSavePath = "");
void openConfigWindow();
void openInfoWindow();
void showDesktopNotification(QString);
@@ -50,6 +49,8 @@ private slots:
void trayIconActivated(QSystemTrayIcon::ActivationReason r);
private:
QPointer<CaptureWidget> createCaptureWidget(const QString &forcedSavePath = "");
void createActions();
void createTrayIcon();

View File

@@ -17,6 +17,7 @@
#include "flameshotdbusadapter.h"
#include "src/utils/confighandler.h"
#include <QTimer>
FlameshotDBusAdapter::FlameshotDBusAdapter(Controller *parent)
: QDBusAbstractAdaptor(parent)
@@ -32,25 +33,19 @@ Controller *FlameshotDBusAdapter::parent() const {
return static_cast<Controller *>(QObject::parent());
}
void FlameshotDBusAdapter::openCapture() {
parent()->createVisualCapture();
void FlameshotDBusAdapter::graphicCapture(QString path, int delay) {
auto p = parent();
auto f = [p, path, this]() {
p->createVisualCapture(path);
};
QTimer::singleShot(delay, p, f);
}
void FlameshotDBusAdapter::openCaptureWithPath(QString path) {
ConfigHandler().setSavePath(path);
parent()->createVisualCapture(false);
}
void FlameshotDBusAdapter::fullScreen(QString path, bool toClipboard, int delay) {
auto p = parent();
auto f = [p, path, toClipboard, this]() {
p->saveScreenshot(path, toClipboard);
};
QTimer::singleShot(delay, p, f);
void FlameshotDBusAdapter::fullScreen(bool toClipboard) {
QString path = parent()->saveScreenshot(toClipboard);
if (!path.isEmpty()) {
QString saveMessage(tr("Capture saved in "));
parent()->showDesktopNotification(saveMessage + path);
}
}
void FlameshotDBusAdapter::fullScreenWithPath(QString path, bool toClipboard) {
QString finalPath = parent()->saveScreenshot(path, toClipboard);
QString saveMessage(tr("Capture saved in "));
parent()->showDesktopNotification(saveMessage + finalPath);
}

View File

@@ -32,11 +32,9 @@ public:
inline Controller *parent() const;
public slots:
Q_NOREPLY void openCapture();
Q_NOREPLY void openCaptureWithPath(QString path);
Q_NOREPLY void graphicCapture(QString path, int delay);
Q_NOREPLY void fullScreen(QString path, bool toClipboard, int delay);
Q_NOREPLY void fullScreen(bool toClipboard);
Q_NOREPLY void fullScreenWithPath(QString path, bool toClipboard);
};
#endif // FLAMESHOTDBUSADAPTER_H

View File

@@ -72,53 +72,53 @@ int main(int argc, char *argv[]) {
"pathVal");
QCommandLineOption clipboardOption({{"c", "clipboard"},
QObject::tr("Save the capture to the clipboard")});
QCommandLineOption delayOption(QStringList() << "d" << "delay",
QObject::tr("Delay time in milliseconds"),
"pathVal");
if (command == "full") {
parser.clearPositionalArguments();
parser.addPositionalArgument(
"full", fullDescription, "full [full_options]");
parser.addOptions({ pathOption, clipboardOption });
parser.addOptions({ pathOption, clipboardOption, delayOption });
} else if (command == "gui") {
parser.clearPositionalArguments();
parser.addPositionalArgument(
"gui", guiDescription, "gui [gui_options]");
parser.addOption(pathOption);
parser.addOptions({ pathOption, delayOption });
}
parser.process(app);
// obtain values
QDBusMessage m;
QString pathValue;
bool pathIsSetAndValid = parser.isSet("path");
if (pathIsSetAndValid) {
if (parser.isSet("path")) {
pathValue = QString::fromStdString(parser.value("path").toStdString());
pathIsSetAndValid = QDir(pathValue).exists();
if (!pathIsSetAndValid) {
if (!QDir(pathValue).exists()) {
qWarning() << QObject::tr("Invalid path.");
return 0;
}
}
if (command == "gui") {
if (pathIsSetAndValid) {
m = QDBusMessage::createMethodCall("org.dharkael.Flameshot",
"/", "", "openCaptureWithPath");
m << pathValue;
} else {
m = QDBusMessage::createMethodCall("org.dharkael.Flameshot",
"/", "", "openCapture");
int delay = 0;
if (parser.isSet("delay")) {
delay = parser.value("delay").toInt();
if (delay < 0) {
qWarning() << QObject::tr("Invalid negative delay.");
return 0;
}
}
// process commands
if (command == "gui") {
m = QDBusMessage::createMethodCall("org.dharkael.Flameshot",
"/", "", "graphicCapture");
m << pathValue << delay;
QDBusConnection::sessionBus().call(m);
} else if (command == "full") {
if (pathIsSetAndValid) {
m = QDBusMessage::createMethodCall("org.dharkael.Flameshot",
"/", "", "fullScreenWithPath");
m << pathValue;
} else {
m = QDBusMessage::createMethodCall("org.dharkael.Flameshot",
"/", "", "fullScreen");
}
m << parser.isSet("clipboard");
m = QDBusMessage::createMethodCall("org.dharkael.Flameshot",
"/", "", "fullScreen");
m << pathValue << parser.isSet("clipboard") << delay;
QDBusConnection::sessionBus().call(m);
}
return 0;

View File

@@ -58,14 +58,14 @@ QString FileNameHandler::getAbsoluteSavePath() {
if (savePath.isEmpty() || !QDir(savePath).exists() || !QFileInfo(savePath).isWritable()) {
changed = true;
savePath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
if (savePath.isEmpty()) {
savePath = QDir::currentPath();
}
}
if(changed) {
config.setSavePath(savePath);
}
QString tempName = "/"+ FileNameHandler().getParsedPattern();
// first add slash if needed
QString tempName = savePath.endsWith("/") ? "" : "/";
// add the parsed pattern in a correct format for the filesystem
tempName += FileNameHandler().getParsedPattern().replace("/", "");
// find unused name adding _n where n is a number
QFileInfo checkFile(savePath + tempName + ".png");
if (checkFile.exists()) {

View File

@@ -17,7 +17,7 @@
<context>
<name>CaptureWidget</name>
<message>
<location filename="../src/capture/capturewidget.cpp" line="160"/>
<location filename="../src/capture/capturewidget.cpp" line="158"/>
<source>Select an area with the mouse, or press Esc to exit.
Press Enter to capture the screen.
Press Right Click to show the color picker.</source>
@@ -26,13 +26,17 @@ Presiona Enter para capturar la pantalla.
Presiona click derecho para mostrar el selector de color.</translation>
</message>
<message>
<location filename="../src/capture/capturewidget.cpp" line="400"/>
<location filename="../src/capture/capturewidget.cpp" line="421"/>
<location filename="../src/capture/capturewidget.cpp" line="401"/>
<source>Error trying to save in </source>
<translation>Error intentando guardar en </translation>
</message>
<message>
<location filename="../src/capture/capturewidget.cpp" line="410"/>
<source>Capture saved in </source>
<translation>Captura guardada en </translation>
</message>
<message>
<location filename="../src/capture/capturewidget.cpp" line="475"/>
<location filename="../src/capture/capturewidget.cpp" line="465"/>
<source>Uploading image...</source>
<translation>Subiendo imagen...</translation>
</message>
@@ -71,17 +75,17 @@ Presiona click derecho para mostrar el selector de color.</translation>
<context>
<name>Controller</name>
<message>
<location filename="../src/controller.cpp" line="61"/>
<location filename="../src/controller.cpp" line="57"/>
<source>&amp;Configuration</source>
<translation>&amp;Configuración</translation>
</message>
<message>
<location filename="../src/controller.cpp" line="65"/>
<location filename="../src/controller.cpp" line="61"/>
<source>&amp;Information</source>
<translation>&amp;Información</translation>
</message>
<message>
<location filename="../src/controller.cpp" line="69"/>
<location filename="../src/controller.cpp" line="65"/>
<source>&amp;Quit</source>
<translation>&amp;Salir</translation>
</message>
@@ -153,15 +157,6 @@ Presiona click derecho para mostrar el selector de color.</translation>
<translation>captura</translation>
</message>
</context>
<context>
<name>FlameshotDBusAdapter</name>
<message>
<location filename="../src/flameshotdbusadapter.cpp" line="47"/>
<location filename="../src/flameshotdbusadapter.cpp" line="54"/>
<source>Capture saved in </source>
<translation>Captura guardada en </translation>
</message>
</context>
<context>
<name>GeneneralConf</name>
<message>
@@ -322,17 +317,17 @@ Presiona click derecho para mostrar el selector de color.</translation>
<context>
<name>QObject</name>
<message>
<location filename="../src/capture/screenshot.cpp" line="65"/>
<location filename="../src/capture/screenshot.cpp" line="68"/>
<source>Save As</source>
<translation>Guardar Como</translation>
</message>
<message>
<location filename="../src/capture/screenshot.cpp" line="96"/>
<location filename="../src/capture/screenshot.cpp" line="98"/>
<source>Save Error</source>
<translation>Error al Guardar</translation>
</message>
<message>
<location filename="../src/capture/screenshot.cpp" line="97"/>
<location filename="../src/capture/screenshot.cpp" line="99"/>
<source>The image could not be saved to &quot;%1&quot;.</source>
<translation>la imagen no pudo ser guardada en &quot;%1&quot;.</translation>
</message>
@@ -362,17 +357,27 @@ Presiona click derecho para mostrar el selector de color.</translation>
<translation>Guarda la captura en el portapapeles</translation>
</message>
<message>
<location filename="../src/main.cpp" line="96"/>
<source>Invalid path.</source>
<translation>Rura inválida.</translation>
<location filename="../src/main.cpp" line="76"/>
<source>Delay time in milliseconds</source>
<translation>Tiempo de espera en milisegundos</translation>
</message>
<message>
<location filename="../src/capture/capturewidget.cpp" line="446"/>
<location filename="../src/main.cpp" line="98"/>
<source>Invalid path.</source>
<translation>Ruta inválida.</translation>
</message>
<message>
<location filename="../src/main.cpp" line="106"/>
<source>Invalid negative delay.</source>
<translation>Valor negativo de espera inválido.</translation>
</message>
<message>
<location filename="../src/capture/capturewidget.cpp" line="436"/>
<source>Resource Error</source>
<translation>Error de Recurso</translation>
</message>
<message>
<location filename="../src/capture/capturewidget.cpp" line="447"/>
<location filename="../src/capture/capturewidget.cpp" line="437"/>
<source>Unable to open the URL.</source>
<translation>No puede abrir la URL.</translation>
</message>