diff --git a/flameshot.pro b/flameshot.pro index d02a08c4..0edb06fc 100644 --- a/flameshot.pro +++ b/flameshot.pro @@ -83,6 +83,9 @@ DEFINES += QAPPLICATION_CLASS=QApplication SOURCES += src/main.cpp \ src/config/filepathconfiguration.cpp \ + src/tools/historywidget.cpp \ + src/utils/configenterprise.cpp \ + src/utils/history.cpp \ src/widgets/capture/buttonhandler.cpp \ src/widgets/infowindow.cpp \ src/config/configwindow.cpp \ @@ -159,6 +162,9 @@ SOURCES += src/main.cpp \ HEADERS += src/widgets/capture/buttonhandler.h \ src/config/filepathconfiguration.h \ + src/tools/historywidget.h \ + src/utils/configenterprise.h \ + src/utils/history.h \ src/widgets/infowindow.h \ src/config/configwindow.h \ src/widgets/capture/capturewidget.h \ diff --git a/src/core/controller.cpp b/src/core/controller.cpp index 7860853f..0953417f 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -22,14 +22,19 @@ #include "src/config/configwindow.h" #include "src/widgets/capture/capturebutton.h" #include "src/widgets/capturelauncher.h" +#include "src/widgets/notificationwidget.h" #include "src/utils/systemnotification.h" #include "src/utils/screengrabber.h" +#include "src/utils/history.h" +#include "src/utils/configenterprise.h" +#include "src/tools/historywidget.h" #include #include #include #include #include #include +#include #ifdef Q_OS_WIN #include "src/core/globalshortcutfilter.h" @@ -171,6 +176,8 @@ void Controller::enableTrayIcon() { if (m_trayIcon) { return; } + QMenu *trayIconMenu = new QMenu(); + ConfigHandler().setDisabledTrayIcon(false); QAction *captureAction = new QAction(tr("&Take Screenshot"), this); connect(captureAction, &QAction::triggered, this, [this](){ @@ -180,6 +187,7 @@ void Controller::enableTrayIcon() { QAction *launcherAction = new QAction(tr("&Open Launcher"), this); connect(launcherAction, &QAction::triggered, this, &Controller::openLauncherWindow); + QAction *configAction = new QAction(tr("&Configuration"), this); connect(configAction, &QAction::triggered, this, &Controller::openConfigWindow); @@ -190,10 +198,16 @@ void Controller::enableTrayIcon() { connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); - QMenu *trayIconMenu = new QMenu(); + // recent screenshots + QAction *recentAction = new QAction(tr("&Recent Screenshot"), this); + connect(recentAction, SIGNAL(triggered()), this, SLOT(showRecentScreenshots())); + + // generate menu trayIconMenu->addAction(captureAction); trayIconMenu->addAction(launcherAction); trayIconMenu->addSeparator(); + trayIconMenu->addAction(recentAction); + trayIconMenu->addSeparator(); trayIconMenu->addAction(configAction); trayIconMenu->addAction(infoAction); trayIconMenu->addSeparator(); @@ -239,6 +253,11 @@ void Controller::updateConfigComponents() { } } +void Controller::showRecentScreenshots() { + HistoryWidget *pHistory = new HistoryWidget(); + pHistory->show(); +} + void Controller::startFullscreenCapture(const uint id) { bool ok = true; QPixmap p(ScreenGrabber().grabEntireDesktop(ok)); diff --git a/src/core/controller.h b/src/core/controller.h index bea0df12..2ef40f16 100644 --- a/src/core/controller.h +++ b/src/core/controller.h @@ -24,10 +24,17 @@ #include #include #include +#include + +#include +#include +#include +#include class CaptureWidget; class ConfigWindow; class InfoWindow; +class QMenu; class QSystemTrayIcon; using lambda = std::function; @@ -61,6 +68,8 @@ public slots: void updateConfigComponents(); + void showRecentScreenshots(); + private slots: void startFullscreenCapture(const uint id = 0); void startVisualCapture(const uint id = 0, diff --git a/src/core/globalshortcutfilter.cpp b/src/core/globalshortcutfilter.cpp index 313da9b4..4c9aebbc 100644 --- a/src/core/globalshortcutfilter.cpp +++ b/src/core/globalshortcutfilter.cpp @@ -17,14 +17,20 @@ #include "globalshortcutfilter.h" #include "src/core/controller.h" +#include "src/tools/historywidget.h" #include +#include GlobalShortcutFilter::GlobalShortcutFilter(QObject *parent) : QObject(parent) { // Forced Print Screen if (RegisterHotKey(NULL, 1, 0, VK_SNAPSHOT)) { - // ok + // ok - capture screen + } + + if (RegisterHotKey(NULL, 2, MOD_SHIFT, VK_SNAPSHOT)) { + // ok - show screenshots history } } @@ -38,13 +44,24 @@ bool GlobalShortcutFilter::nativeEventFilter( MSG* msg = static_cast(message); if (msg->message == WM_HOTKEY) { - //const quint32 keycode = HIWORD(msg->lParam); - //const quint32 modifiers = LOWORD(msg->lParam); - // TODO: this is just a temporal workwrround, proper global // support would need custom shortcuts defined by the user. - Controller::getInstance()->requestCapture( - CaptureRequest(CaptureRequest::GRAPHICAL_MODE)); + const quint32 keycode = HIWORD(msg->lParam); + const quint32 modifiers = LOWORD(msg->lParam); + + // Show screenshots history + if(VK_SNAPSHOT == keycode && MOD_SHIFT == modifiers) { + qDebug() << "Show screenshots history"; + HistoryWidget *pHistory = new HistoryWidget(); + pHistory->show(); + } + + // Capture screen + if(VK_SNAPSHOT == keycode && 0 == modifiers) { + Controller::getInstance()->requestCapture( + CaptureRequest(CaptureRequest::GRAPHICAL_MODE)); + } + return true; } return false; diff --git a/src/tools/historywidget.cpp b/src/tools/historywidget.cpp new file mode 100644 index 00000000..8ee155d0 --- /dev/null +++ b/src/tools/historywidget.cpp @@ -0,0 +1,78 @@ +#include "historywidget.h" +#include "src/utils/history.h" +#include "src/utils/configenterprise.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent) +{ + setWindowTitle(tr("Screenshots history")); + setFixedSize(this->size()); + + m_pVBox = new QVBoxLayout(this); + + QScrollArea *scrollArea = new QScrollArea( this ); + scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); + scrollArea->setWidgetResizable( true ); + scrollArea->setGeometry( this->frameGeometry() ); + + QWidget *widget = new QWidget(); + scrollArea->setWidget( widget ); + widget->setLayout( m_pVBox ); + + loadHistory(); +} + +void HistoryWidget::loadHistory() { + History history = History(); + QList historyFiles = history.history(); + + foreach(QString fileName, historyFiles) { + QString fullFileName = history.path() + fileName; + + QPixmap pixmap; + pixmap.load( fullFileName, "png" ); + pixmap = pixmap.scaledToWidth(120); + + QPushButton *button = new QPushButton; + button->setStyleSheet("Text-align:left"); + QIcon buttonIcon(fullFileName); + button->setIcon(buttonIcon); + button->setIconSize(pixmap.rect().size()); + + QFileInfo *pFileInfo = new QFileInfo(fullFileName); + QString lastModified = pFileInfo->lastModified().toString("yyyy-MM-dd hh:mm:ss"); + button->setText(lastModified); + + connect(button, &QPushButton::clicked, this, [=](){ + // TODO - optimize it + this->close(); + ConfigEnterprise configEnterprise; + QSettings *settings = configEnterprise.settings(); + settings->beginGroup("S3"); + QString url = settings->value("S3_URL").toString() + fileName; + settings->endGroup(); + QApplication::clipboard()->setText(url); +// qDebug() << "URL copied to clipboard:" << url; + +// NotificationWidget *notification = new NotificationWidget(); +// notification->showMessage(tr("URL copied to clipboard.")); + }); + + + m_pVBox->addWidget(button); + } +} diff --git a/src/tools/historywidget.h b/src/tools/historywidget.h new file mode 100644 index 00000000..6fec3cdf --- /dev/null +++ b/src/tools/historywidget.h @@ -0,0 +1,24 @@ +#ifndef HISTORYWIDGET_H +#define HISTORYWIDGET_H + +#include +#include + +class QVBoxLayout; + +class HistoryWidget : public QWidget +{ + Q_OBJECT +public: + explicit HistoryWidget(QWidget *parent = nullptr); + +signals: + +private: + void loadHistory(); + +private: + QVBoxLayout *m_pVBox; +}; + +#endif // HISTORYWIDGET_H diff --git a/src/tools/imgs3/imgs3uploader.cpp b/src/tools/imgs3/imgs3uploader.cpp index 34b71d33..2aab68b2 100644 --- a/src/tools/imgs3/imgs3uploader.cpp +++ b/src/tools/imgs3/imgs3uploader.cpp @@ -22,6 +22,8 @@ #include "src/widgets/imagelabel.h" #include "src/widgets/notificationwidget.h" #include "src/utils/confighandler.h" +#include "src/utils/history.h" +#include "src/utils/configenterprise.h" #include #include #include @@ -48,19 +50,6 @@ ImgS3Uploader::ImgS3Uploader(const QPixmap &capture, QWidget *parent) : QWidget(parent), m_pixmap(capture) { - QSettings *pSettings = nullptr; - QString configIniPath = QDir(QDir::currentPath()).filePath("config.ini"); -#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) - if(!(QFileInfo::exists(configIniPath) && QFileInfo(configIniPath).isFile())) { - configIniPath = "/etc/flameshot/config.ini"; - } -#endif - pSettings = new QSettings(configIniPath, QSettings::IniFormat); - pSettings->beginGroup("S3"); - m_s3CredsUrl = pSettings->value("S3_CREDS_URL").toString(); - m_s3XApiKey = pSettings->value("S3_X_API_KEY").toString(); - pSettings->endGroup(); - setWindowTitle(tr("Upload to ImgS3")); setWindowIcon(QIcon(":img/app/flameshot.svg")); @@ -83,13 +72,24 @@ ImgS3Uploader::ImgS3Uploader(const QPixmap &capture, QWidget *parent) : setAttribute(Qt::WA_DeleteOnClose); - QString httpProxyHost = pSettings->value("HTTP_PROXY_HOST").toString(); + // get enterprise settings + m_configEnterprise = new ConfigEnterprise(); + QSettings *settings = m_configEnterprise->settings(); + + // get s3 credentials + settings->beginGroup("S3"); + m_s3CredsUrl = settings->value("S3_CREDS_URL").toString(); + m_s3XApiKey = settings->value("S3_X_API_KEY").toString(); + settings->endGroup(); + + // set proxy server parameters + QString httpProxyHost = settings->value("HTTP_PROXY_HOST").toString(); if(httpProxyHost.length() > 0) { qDebug() << "Using proxy server"; m_proxy = new QNetworkProxy(); - if(pSettings->contains("HTTP_PROXY_TYPE")) { - switch (pSettings->value("HTTP_PROXY_TYPE").toInt()) { + if(settings->contains("HTTP_PROXY_TYPE")) { + switch (settings->value("HTTP_PROXY_TYPE").toInt()) { case 0: m_proxy->setType(QNetworkProxy::DefaultProxy); break; @@ -111,22 +111,26 @@ ImgS3Uploader::ImgS3Uploader(const QPixmap &capture, QWidget *parent) : break; } } + } + // set proxy server parameters + if(httpProxyHost.length() > 0) { m_proxy->setHostName(httpProxyHost); - if(pSettings->contains("HTTP_PROXY_PORT")) { - m_proxy->setPort(pSettings->value("HTTP_PROXY_PORT").toInt()); + if(settings->contains("HTTP_PROXY_PORT")) { + m_proxy->setPort(settings->value("HTTP_PROXY_PORT").toInt()); } else { m_proxy->setPort(3128); } - if(pSettings->contains("HTTP_PROXY_USER")) { - m_proxy->setUser(pSettings->value("HTTP_PROXY_USER").toString()); + if(settings->contains("HTTP_PROXY_USER")) { + m_proxy->setUser(settings->value("HTTP_PROXY_USER").toString()); } - if(pSettings->contains("HTTP_PROXY_PASSWORD")) { - m_proxy->setPassword(pSettings->value("HTTP_PROXY_PASSWORD").toString()); + if(settings->contains("HTTP_PROXY_PASSWORD")) { + m_proxy->setPassword(settings->value("HTTP_PROXY_PASSWORD").toString()); } QNetworkProxy::setApplicationProxy(*m_proxy); m_NetworkAM->setProxy(*m_proxy); + m_NetworkAMCreds->setProxy(*m_proxy); } upload(); @@ -135,6 +139,16 @@ ImgS3Uploader::ImgS3Uploader(const QPixmap &capture, QWidget *parent) : void ImgS3Uploader::handleReply(QNetworkReply *reply) { m_spinner->deleteLater(); if (reply->error() == QNetworkReply::NoError) { + // save history + QString imageName = m_imageURL.toString(); + int lastSlash = imageName.lastIndexOf("/"); + if (lastSlash >= 0) { + imageName = imageName.mid(lastSlash); + } + History history; + history.save(m_pixmap, imageName); + + // Copy url to clipboard if required if (ConfigHandler().copyAndCloseAfterUploadEnabled()) { QApplication::clipboard()->setText(m_imageURL.toString()); SystemNotification().sendMessage(QObject::tr("URL copied to clipboard.")); diff --git a/src/tools/imgs3/imgs3uploader.h b/src/tools/imgs3/imgs3uploader.h index 1ffd9b4f..d6a72b37 100644 --- a/src/tools/imgs3/imgs3uploader.h +++ b/src/tools/imgs3/imgs3uploader.h @@ -30,6 +30,7 @@ class LoadSpinner; class QPushButton; class QUrl; class NotificationWidget; +class ConfigEnterprise; class ImgS3Uploader : public QWidget { Q_OBJECT @@ -49,6 +50,7 @@ private: void uploadToS3(QJsonDocument &response); private: + ConfigEnterprise *m_configEnterprise; QString m_s3CredsUrl; QString m_s3XApiKey; diff --git a/src/utils/configenterprise.cpp b/src/utils/configenterprise.cpp new file mode 100644 index 00000000..2c3b0788 --- /dev/null +++ b/src/utils/configenterprise.cpp @@ -0,0 +1,22 @@ +#include "configenterprise.h" +#include +#include +#include + + +ConfigEnterprise::ConfigEnterprise() +{ + // get enterprise settings + m_settings = nullptr; + QString configIniPath = QDir(QDir::currentPath()).filePath("config.ini"); +#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) + if(!(QFileInfo::exists(configIniPath) && QFileInfo(configIniPath).isFile())) { + configIniPath = "/etc/flameshot/config.ini"; + } +#endif + m_settings = new QSettings(configIniPath, QSettings::IniFormat); +} + +QSettings *ConfigEnterprise::settings() { + return m_settings; +} diff --git a/src/utils/configenterprise.h b/src/utils/configenterprise.h new file mode 100644 index 00000000..55a44e82 --- /dev/null +++ b/src/utils/configenterprise.h @@ -0,0 +1,18 @@ +#ifndef CONFIGENTERPRISE_H +#define CONFIGENTERPRISE_H + +class QSettings; + + +class ConfigEnterprise +{ +public: + ConfigEnterprise(); + + QSettings *settings(); + +private: + QSettings *m_settings; +}; + +#endif // CONFIGENTERPRISE_H diff --git a/src/utils/confighandler.cpp b/src/utils/confighandler.cpp index 20960a45..b70ee392 100644 --- a/src/utils/confighandler.cpp +++ b/src/utils/confighandler.cpp @@ -20,6 +20,7 @@ #include #include #include +#include ConfigHandler::ConfigHandler(){ m_settings.setDefaultFormat(QSettings::IniFormat); @@ -372,6 +373,18 @@ QString ConfigHandler::configFilePath() const { return m_settings.fileName(); } +const QString ConfigHandler::userUuid() { + QString userUuid; + if (m_settings.contains(QStringLiteral("userUuid"))) { + userUuid = m_settings.value(QStringLiteral("userUuid")).toString(); + } else { + userUuid = QUuid::createUuid().toString(); + userUuid = userUuid.replace("{", "").replace("}", ""); + m_settings.setValue(QStringLiteral("userUuid"), userUuid); + } + return userUuid; +} + bool ConfigHandler::normalizeButtons(QVector &buttons) { auto listTypes = CaptureButton::getIterableButtonTypes(); QVector listTypesInt; diff --git a/src/utils/confighandler.h b/src/utils/confighandler.h index f37704cf..b1987587 100644 --- a/src/utils/confighandler.h +++ b/src/utils/confighandler.h @@ -81,6 +81,7 @@ public: void setAllTheButtons(); QString configFilePath() const; + const QString userUuid(); private: QSettings m_settings; diff --git a/src/utils/history.cpp b/src/utils/history.cpp new file mode 100644 index 00000000..6197a53b --- /dev/null +++ b/src/utils/history.cpp @@ -0,0 +1,53 @@ +#include "history.h" +#include "src/utils/confighandler.h" +#include +#include +#include +#include +#include + + +History::History() +{ + // Get cache history path + ConfigHandler config; + QString userUuid = config.userUuid(); + m_historyPath = QDir::homePath() + "/.cache/flameshot/history/"+ userUuid + "/"; + + // Check if directory for history exists and create if doesn't + QDir dir = QDir(m_historyPath); + if (!dir.exists()) + dir.mkpath("."); +} + +const QString &History::path() { + return m_historyPath; +} + +void History::save(const QPixmap &pixmap, const QString &fileName) { + QFile file(path() + fileName); + file.open(QIODevice::WriteOnly); + pixmap.scaled(HISTORY_THUNB_WIDTH, + HISTORY_THUNB_HEIGH, + Qt::KeepAspectRatio, + Qt::SmoothTransformation + ).save(&file, "PNG"); + history(); +} + +const QList &History::history() { + QDir directory(path()); + QStringList images = directory.entryList(QStringList() << "*.png" << "*.PNG", QDir::Files, QDir::Time); + int cnt = 0; + m_thumbs.clear(); + foreach(QString fileName, images) { + if(++cnt <= HISTORY_MAX_SIZE) { + m_thumbs.append(fileName); + } + else { + QFile file(path() + fileName); + file.remove(); + } + } + return m_thumbs; +} diff --git a/src/utils/history.h b/src/utils/history.h new file mode 100644 index 00000000..f7e9bec3 --- /dev/null +++ b/src/utils/history.h @@ -0,0 +1,30 @@ +#ifndef HISTORY_H +#define HISTORY_H + +#include + +#define HISTORY_MAX_SIZE 10 +#define HISTORY_THUNB_SCALE 1.5 +#define HISTORY_THUNB_WIDTH 160*HISTORY_THUNB_SCALE +#define HISTORY_THUNB_HEIGH 90*HISTORY_THUNB_SCALE + + +class QPixmap; +class QString; + + +class History +{ +public: + History(); + + void save(const QPixmap &, const QString &); + const QList &history(); + const QString &path(); + +private: + QString m_historyPath; + QList m_thumbs; +}; + +#endif // HISTORY_H