From 471b25e6a8644f4505a62de67decb7fd7fec2819 Mon Sep 17 00:00:00 2001 From: Yuriy Puchkov Date: Tue, 15 Sep 2020 19:37:34 +0300 Subject: [PATCH] Code Refactoring for s3 and imgur storages, create base class for both --- .clang-format | 6 + flameshot.pro | 22 +- src/tools/imgs3/imgs3uploader.cpp | 467 ----------- src/tools/imgs3/imgs3uploader.h | 103 --- src/tools/imgur/imguruploader.cpp | 182 ----- .../{imgs3 => storage}/imgs3settings.cpp | 0 src/tools/{imgs3 => storage}/imgs3settings.h | 0 src/tools/storage/imgs3uploader.cpp | 377 +++++++++ src/tools/storage/imgs3uploader.h | 69 ++ .../{imgs3 => storage}/imgs3uploadertool.cpp | 37 +- .../{imgs3 => storage}/imgs3uploadertool.h | 0 src/tools/storage/imguploader.cpp | 226 ++++++ src/tools/storage/imguploader.h | 98 +++ src/tools/storage/imguruploader.cpp | 111 +++ src/tools/{imgur => storage}/imguruploader.h | 39 +- .../{imgur => storage}/imguruploadertool.cpp | 40 +- .../{imgur => storage}/imguruploadertool.h | 1 + src/tools/toolfactory.cpp | 149 ++-- src/widgets/capture/capturewidget.cpp | 753 ++++++++++-------- src/widgets/historywidget.cpp | 122 +-- src/widgets/historywidget.h | 20 +- translations/Internationalization_ca.ts | 143 ++-- translations/Internationalization_de_DE.ts | 141 ++-- translations/Internationalization_es.ts | 141 ++-- translations/Internationalization_fr.ts | 155 ++-- translations/Internationalization_hu.ts | 61 +- translations/Internationalization_ja.ts | 141 ++-- translations/Internationalization_ka.ts | 155 ++-- translations/Internationalization_nl.ts | 141 ++-- translations/Internationalization_pl.ts | 141 ++-- translations/Internationalization_pt_br.ts | 141 ++-- translations/Internationalization_ru.ts | 175 ++-- translations/Internationalization_sk.ts | 141 ++-- translations/Internationalization_sr.ts | 141 ++-- translations/Internationalization_tr.ts | 141 ++-- translations/Internationalization_uk.ts | 175 ++-- translations/Internationalization_zh_CN.ts | 141 ++-- translations/Internationalization_zh_TW.ts | 155 ++-- 38 files changed, 3187 insertions(+), 2064 deletions(-) create mode 100644 .clang-format delete mode 100644 src/tools/imgs3/imgs3uploader.cpp delete mode 100644 src/tools/imgs3/imgs3uploader.h delete mode 100644 src/tools/imgur/imguruploader.cpp rename src/tools/{imgs3 => storage}/imgs3settings.cpp (100%) rename src/tools/{imgs3 => storage}/imgs3settings.h (100%) create mode 100644 src/tools/storage/imgs3uploader.cpp create mode 100644 src/tools/storage/imgs3uploader.h rename src/tools/{imgs3 => storage}/imgs3uploadertool.cpp (66%) rename src/tools/{imgs3 => storage}/imgs3uploadertool.h (100%) create mode 100644 src/tools/storage/imguploader.cpp create mode 100644 src/tools/storage/imguploader.h create mode 100644 src/tools/storage/imguruploader.cpp rename src/tools/{imgur => storage}/imguruploader.h (61%) rename src/tools/{imgur => storage}/imguruploadertool.cpp (65%) rename src/tools/{imgur => storage}/imguruploadertool.h (97%) diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..c4ac57ae --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +Language: Cpp +BasedOnStyle: Mozilla +IndentWidth: 4 +AccessModifierOffset: -4 +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None diff --git a/flameshot.pro b/flameshot.pro index cd80d8c9..f397fcfd 100644 --- a/flameshot.pro +++ b/flameshot.pro @@ -87,7 +87,6 @@ SOURCES += src/main.cpp \ src/config/filepathconfiguration.cpp \ src/config/setshortcutwidget.cpp \ src/config/shortcutswidget.cpp \ - src/tools/imgs3/imgs3settings.cpp \ src/utils/configshortcuts.cpp \ src/widgets/historywidget.cpp \ src/utils/configenterprise.cpp \ @@ -112,8 +111,6 @@ SOURCES += src/main.cpp \ src/tools/circle/circletool.cpp \ src/tools/copy/copytool.cpp \ src/tools/exit/exittool.cpp \ - src/tools/imgur/imguruploadertool.cpp \ - src/tools/imgs3/imgs3uploadertool.cpp \ src/tools/line/linetool.cpp \ src/tools/marker/markertool.cpp \ src/tools/move/movetool.cpp \ @@ -130,8 +127,12 @@ SOURCES += src/main.cpp \ src/cli/commandoption.cpp \ src/cli/commandargument.cpp \ src/utils/screenshotsaver.cpp \ - src/tools/imgur/imguruploader.cpp \ - src/tools/imgs3/imgs3uploader.cpp \ + src/tools/storage/imguploader.cpp \ + src/tools/storage/imguruploadertool.cpp \ + src/tools/storage/imguruploader.cpp \ + src/tools/storage/imgs3uploadertool.cpp \ + src/tools/storage/imgs3uploader.cpp \ + src/tools/storage/imgs3settings.cpp \ src/widgets/loadspinner.cpp \ src/widgets/imagelabel.cpp \ src/widgets/notificationwidget.cpp \ @@ -170,7 +171,6 @@ HEADERS += src/widgets/capture/buttonhandler.h \ src/config/filepathconfiguration.h \ src/config/setshortcutwidget.h \ src/config/shortcutswidget.h \ - src/tools/imgs3/imgs3settings.h \ src/utils/configshortcuts.h \ src/widgets/historywidget.h \ src/utils/configenterprise.h \ @@ -196,8 +196,6 @@ HEADERS += src/widgets/capture/buttonhandler.h \ src/tools/circle/circletool.h \ src/tools/copy/copytool.h \ src/tools/exit/exittool.h \ - src/tools/imgur/imguruploadertool.h \ - src/tools/imgs3/imgs3uploadertool.h \ src/tools/line/linetool.h \ src/tools/marker/markertool.h \ src/tools/move/movetool.h \ @@ -213,8 +211,12 @@ HEADERS += src/widgets/capture/buttonhandler.h \ src/cli/commandoption.h \ src/cli/commandargument.h \ src/utils/screenshotsaver.h \ - src/tools/imgur/imguruploader.h \ - src/tools/imgs3/imgs3uploader.h \ + src/tools/storage/imguploader.h \ + src/tools/storage/imguruploadertool.h \ + src/tools/storage/imguruploader.h \ + src/tools/storage/imgs3uploader.h \ + src/tools/storage/imgs3uploadertool.h \ + src/tools/storage/imgs3settings.h \ src/widgets/loadspinner.h \ src/widgets/imagelabel.h \ src/widgets/notificationwidget.h \ diff --git a/src/tools/imgs3/imgs3uploader.cpp b/src/tools/imgs3/imgs3uploader.cpp deleted file mode 100644 index a6afaa14..00000000 --- a/src/tools/imgs3/imgs3uploader.cpp +++ /dev/null @@ -1,467 +0,0 @@ -// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors -// -// This file is part of Flameshot. -// -// Flameshot 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 3 of the License, or -// (at your option) any later version. -// -// Flameshot 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 Flameshot. If not, see . - -#include "imgs3uploader.h" -#include "src/utils/filenamehandler.h" -#include "src/utils/systemnotification.h" -#include "src/widgets/loadspinner.h" -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -ImgS3Uploader::ImgS3Uploader(const QPixmap &capture, QWidget *parent) : - QWidget(parent), m_pixmap(capture) -{ - init(tr("Upload image to S3"), tr("Uploading Image")); -} - -ImgS3Uploader::ImgS3Uploader(QWidget *parent) : - QWidget(parent) -{ - init(tr("Delete image from S3"), tr("Deleting image...")); -} - -void ImgS3Uploader::init(const QString &title, const QString &label) { - m_imageLabel = nullptr; - m_spinner = nullptr; - - m_proxy = nullptr; - m_NetworkAMUpload = nullptr; - m_NetworkAMGetCreds = nullptr; - m_NetworkAMRemove = nullptr; - - m_success = false; - setWindowTitle(title); - setWindowIcon(QIcon(":img/app/flameshot.svg")); - - m_spinner = new LoadSpinner(this); - m_spinner->setColor(ConfigHandler().uiMainColorValue()); - m_spinner->start(); - - m_infoLabel = new QLabel(label); - m_infoLabel->setAlignment(Qt::AlignCenter); - - m_vLayout = new QVBoxLayout(); - setLayout(m_vLayout); - m_vLayout->addWidget(m_spinner, 0, Qt::AlignHCenter); - m_vLayout->addWidget(m_infoLabel); - - setAttribute(Qt::WA_DeleteOnClose); -} - -QNetworkProxy *ImgS3Uploader::proxy() { - if(m_proxy == nullptr) { - initProxy(); - } - return m_proxy; -} - -QNetworkProxy *ImgS3Uploader::initProxy() { - // get enterprise settings - ConfigEnterprise *configEnterprise = new ConfigEnterprise(); - - // get proxy settings from "config.ini" file - QSettings *settings = configEnterprise->settings(); - QString httpProxyHost = settings->value("HTTP_PROXY_HOST").toString(); - - if(httpProxyHost.length() > 0) { - m_proxy = new QNetworkProxy(); - - if(settings->contains("HTTP_PROXY_TYPE")) { - switch (settings->value("HTTP_PROXY_TYPE").toInt()) { - case 0: - m_proxy->setType(QNetworkProxy::DefaultProxy); - break; - case 1: - m_proxy->setType(QNetworkProxy::Socks5Proxy); - break; - case 2: - m_proxy->setType(QNetworkProxy::NoProxy); - break; - case 4: - m_proxy->setType(QNetworkProxy::HttpCachingProxy); - break; - case 5: - m_proxy->setType(QNetworkProxy::FtpCachingProxy); - break; - case 3: - default: - m_proxy->setType(QNetworkProxy::HttpProxy); - break; - } - } - - m_proxy->setHostName(httpProxyHost); - int nProxyPort = 3128; - if(settings->contains("HTTP_PROXY_PORT")) { - nProxyPort = settings->value("HTTP_PROXY_PORT").toInt(); - } - m_proxy->setPort(nProxyPort); - - if(settings->contains("HTTP_PROXY_USER")) { - qDebug() << "Proxy user" << settings->value("HTTP_PROXY_PASSWORD").toString(); - m_proxy->setUser(settings->value("HTTP_PROXY_USER").toString()); - } - if(settings->contains("HTTP_PROXY_PASSWORD")) { - qDebug() << "Proxy password is not empty"; - m_proxy->setPassword(settings->value("HTTP_PROXY_PASSWORD").toString()); - } - } - else { - // Get proxy settings from OS settings - QNetworkProxyQuery q(QUrl(m_s3Settings.credsUrl().toUtf8())); - q.setQueryType(QNetworkProxyQuery::UrlRequest); - q.setProtocolTag("http"); - - QList proxies = QNetworkProxyFactory::systemProxyForQuery(q); - if( proxies.size() > 0 && proxies[0].type() != QNetworkProxy::NoProxy ){ - m_proxy = new QNetworkProxy(); - m_proxy->setHostName(proxies[0].hostName()); - m_proxy->setPort(proxies[0].port()); - m_proxy->setType(proxies[0].type()); - m_proxy->setUser(proxies[0].user()); - m_proxy->setPassword(proxies[0].password()); - } - } -#ifdef QT_DEBUG - if(m_proxy != nullptr) { - qDebug() << "Using proxy server"; - qDebug() << "proxy host:" << m_proxy->hostName(); - qDebug() << "proxy port:" << m_proxy->port(); - qDebug() << "proxy type:" << m_proxy->type(); - qDebug() << "proxy user:" << (m_proxy->user().length() > 0 ? m_proxy->user() : "no user"); - qDebug() << "proxy password:" << (m_proxy->password().length() > 0 ? "***" : "no password"); - } - else { - qDebug() << "No proxy"; - } -#endif - return m_proxy; -} - -void ImgS3Uploader::clearProxy() { - if(m_proxy != nullptr) { - delete m_proxy; - m_proxy = nullptr; - } -} - - -void ImgS3Uploader::handleReplyUpload(QNetworkReply *reply) { - hideSpinner(); - m_s3ImageName.clear(); - if (reply->error() == QNetworkReply::NoError) { - // save history - QString imageName = m_imageURL.toString(); - int lastSlash = imageName.lastIndexOf("/"); - if (lastSlash >= 0) { - imageName = imageName.mid(lastSlash + 1); - } - m_s3ImageName = imageName; - History history; - imageName = history.packFileName(SCREENSHOT_STORAGE_TYPE_S3, m_deleteToken, imageName); - history.save(m_pixmap, imageName); - m_success = true; - - // Copy url to clipboard if required - if (ConfigHandler().copyAndCloseAfterUploadEnabled()) { - QApplication::clipboard()->setText(m_imageURL.toString()); - SystemNotification().sendMessage(tr("URL copied to clipboard.")); - close(); - } else { - onUploadOk(); - } - } else { - QString reason = reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute ).toString(); - setInfoLabelText(reply->errorString()); - } - new QShortcut(Qt::Key_Escape, this, SLOT(close())); -} - -void ImgS3Uploader::removeImagePreview() { - // remove local file - History history; - QString packedFileName = history.packFileName(SCREENSHOT_STORAGE_TYPE_S3, m_deleteToken, m_s3ImageName); - QString fullFileName = history.path() + packedFileName; - - QFile file(fullFileName); - if (file.exists()) { - file.remove(); - } - m_deleteToken.clear(); - m_s3ImageName.clear(); - m_success = true; -} - -void ImgS3Uploader::handleReplyDeleteResource(QNetworkReply *reply) { - auto replyError = reply->error(); - if (replyError == QNetworkReply::NoError) { - removeImagePreview(); - } else { - hide(); - - // generate error message - QString message = tr("Unable to remove screenshot from the remote storage."); - if(replyError == QNetworkReply::UnknownNetworkError) { - message += "\n" + tr("Network error"); - } - else if(replyError == QNetworkReply::UnknownServerError) { - message += "\n" + tr("Possibly it doesn't exist anymore"); - } - message += "\n\n" + reply->errorString(); - message += "\n\n" + tr("Do you want to remove screenshot from local history anyway?"); - - if (QMessageBox::Yes == QMessageBox::question(NULL, - tr("Remove screenshot from history?"), - message, - QMessageBox::Yes|QMessageBox::No)) { - removeImagePreview(); - } - } - close(); -} - -void ImgS3Uploader::startDrag() { - QMimeData *mimeData = new QMimeData; - mimeData->setUrls(QList { m_imageURL }); - mimeData->setImageData(m_pixmap); - - QDrag *dragHandler = new QDrag(this); - dragHandler->setMimeData(mimeData); - dragHandler->setPixmap(m_pixmap.scaled(256, 256, Qt::KeepAspectRatioByExpanding, - Qt::SmoothTransformation)); - dragHandler->exec(); -} - -void ImgS3Uploader::handleReplyGetCreds(QNetworkReply *reply){ - if (reply->error() == QNetworkReply::NoError) { - QJsonDocument response = QJsonDocument::fromJson(reply->readAll()); - uploadToS3(response); - } else { - if(m_s3Settings.credsUrl().length() == 0){ - setInfoLabelText(tr("S3 Creds URL is not found in your configuration file")); - } - else { - setInfoLabelText(reply->errorString()); - } - } - new QShortcut(Qt::Key_Escape, this, SLOT(close())); -} - -void ImgS3Uploader::uploadToS3(QJsonDocument &response) { - // set paramets from "fields" - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - - // read JSON response - QJsonObject json = response.object(); - QString resultURL = json["resultURL"].toString(); - QJsonObject formData = json["formData"].toObject(); - QString url = formData["url"].toString(); - m_deleteToken = json["deleteToken"].toString(); - - QJsonObject fields = formData["fields"].toObject(); - foreach (auto key, fields.keys()) { - QString field = fields[key].toString(); - QHttpPart part; - part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"" + key + "\"")); - part.setBody(field.toLatin1()); - multiPart->append(part); - } - - QHttpPart imagePart; - imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png")); - imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, - QVariant("form-data; name=\"file\"")); - - QByteArray byteArray; - QBuffer buffer(&byteArray); - buffer.open(QIODevice::WriteOnly); - m_pixmap.save(&buffer, "PNG"); - - imagePart.setBody(byteArray); - multiPart->append(imagePart); - - m_imageURL.setUrl(resultURL); - - QUrl qUrl(url); - QNetworkRequest request(qUrl); - - // upload - m_NetworkAMUpload->post(request, multiPart); -} - -void ImgS3Uploader::deleteResource(const QString &fileName, const QString &deleteToken) { - // read network settings on each call to simplify configuration management without restarting - clearProxy(); - if(m_NetworkAMRemove != nullptr) { - delete m_NetworkAMRemove; - m_NetworkAMRemove = nullptr; - } - m_NetworkAMRemove = new QNetworkAccessManager(this); - connect(m_NetworkAMRemove, &QNetworkAccessManager::finished, this, &ImgS3Uploader::handleReplyDeleteResource); - if(proxy() != nullptr) { - m_NetworkAMRemove->setProxy(*proxy()); - } - - QNetworkRequest request; - m_s3ImageName = fileName; - m_deleteToken = deleteToken; - request.setUrl(m_s3Settings.credsUrl().toUtf8() + fileName); - request.setRawHeader("X-API-Key", m_s3Settings.xApiKey().toLatin1()); - request.setRawHeader("Authorization", "Bearer " + deleteToken.toLatin1()); - m_NetworkAMRemove->deleteResource(request); -} - -void ImgS3Uploader::upload() { - m_deleteToken.clear(); - m_s3ImageName.clear(); - - // read network settings on each call to simplify configuration management without restarting - // init creds and upload network access managers - clearProxy(); - if(m_NetworkAMGetCreds != nullptr) { - delete m_NetworkAMGetCreds; - m_NetworkAMGetCreds = nullptr; - } - m_NetworkAMGetCreds = new QNetworkAccessManager(this); - connect(m_NetworkAMGetCreds, &QNetworkAccessManager::finished, this, &ImgS3Uploader::handleReplyGetCreds); - - if(m_NetworkAMUpload != nullptr) { - delete m_NetworkAMUpload; - m_NetworkAMUpload = nullptr; - } - m_NetworkAMUpload = new QNetworkAccessManager(this); - connect(m_NetworkAMUpload, &QNetworkAccessManager::finished, this, &ImgS3Uploader::handleReplyUpload); - if(proxy() != nullptr) { - m_NetworkAMGetCreds->setProxy(*proxy()); - m_NetworkAMUpload->setProxy(*proxy()); - } - - // get creads - QUrl creds(m_s3Settings.credsUrl()); - QNetworkRequest requestCreds(creds); - if(m_s3Settings.xApiKey().length() > 0) { - requestCreds.setRawHeader(QByteArray("X-API-Key"), QByteArray(m_s3Settings.xApiKey().toLocal8Bit())); - } - m_NetworkAMGetCreds->get(requestCreds); -} - -void ImgS3Uploader::onUploadOk() { - hideSpinner(); - - m_notification = new NotificationWidget(); - m_vLayout->addWidget(m_notification); - - if(nullptr == m_imageLabel) { - m_imageLabel = new ImageLabel(); - m_imageLabel->setScreenshot(m_pixmap); - m_imageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - connect(m_imageLabel, &ImageLabel::dragInitiated, this, &ImgS3Uploader::startDrag); - m_vLayout->addWidget(m_imageLabel); - } - - m_hLayout = new QHBoxLayout(); - m_vLayout->addLayout(m_hLayout); - - m_copyUrlButton = new QPushButton(tr("Copy URL")); - m_openUrlButton = new QPushButton(tr("Open URL")); - m_deleteImageOnS3 = new QPushButton(tr("Delete image")); - m_toClipboardButton = new QPushButton(tr("Image to Clipboard.")); - m_hLayout->addWidget(m_copyUrlButton); - m_hLayout->addWidget(m_openUrlButton); - m_hLayout->addWidget(m_deleteImageOnS3); - m_hLayout->addWidget(m_toClipboardButton); - - connect(m_copyUrlButton, &QPushButton::clicked, - this, &ImgS3Uploader::copyURL); - connect(m_openUrlButton, &QPushButton::clicked, - this, &ImgS3Uploader::openURL); - connect(m_deleteImageOnS3, &QPushButton::clicked, - this, &ImgS3Uploader::deleteImageOnS3); - connect(m_toClipboardButton, &QPushButton::clicked, - this, &ImgS3Uploader::copyImage); -} - -void ImgS3Uploader::openURL() { - bool successful = QDesktopServices::openUrl(m_imageURL); - if (!successful) { - m_notification->showMessage(tr("Unable to open the URL.")); - } -} - -void ImgS3Uploader::copyURL() { - QApplication::clipboard()->setText(m_imageURL.toString()); - m_notification->showMessage(tr("URL copied to clipboard.")); -} - -void ImgS3Uploader::copyImage() { - QApplication::clipboard()->setPixmap(m_pixmap); - m_notification->showMessage(tr("Screenshot copied to clipboard.")); -} - -void ImgS3Uploader::deleteImageOnS3() { - if(nullptr != m_imageLabel) { - m_imageLabel->hide(); - } - m_spinner->show(); - setInfoLabelText(tr("Deleting image...")); - deleteResource(m_s3ImageName, m_deleteToken); -} - -bool ImgS3Uploader::success() { - return m_success; -} - -void ImgS3Uploader::hideSpinner() { - if(nullptr != m_spinner) { - m_spinner->hide(); - } - if(nullptr != m_imageLabel) { - m_imageLabel->hide(); - } -} - -void ImgS3Uploader::setInfoLabelText(const QString &infoText) { - m_infoLabel->setText(infoText); - m_infoLabel->show(); -} diff --git a/src/tools/imgs3/imgs3uploader.h b/src/tools/imgs3/imgs3uploader.h deleted file mode 100644 index 755fa01b..00000000 --- a/src/tools/imgs3/imgs3uploader.h +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors -// -// This file is part of Flameshot. -// -// Flameshot 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 3 of the License, or -// (at your option) any later version. -// -// Flameshot 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 Flameshot. If not, see . - -#pragma once - -#define S3_API_IMG_PATH "v2/image/" - -#include "imgs3settings.h" -#include -#include - -class QNetworkReply; -class QNetworkProxy; -class QNetworkAccessManager; -class QHBoxLayout; -class QVBoxLayout; -class QLabel; -class LoadSpinner; -class QPushButton; -class QUrl; -class NotificationWidget; -class ConfigEnterprise; -class ImageLabel; - -class ImgS3Uploader : public QWidget { - Q_OBJECT -public: - explicit ImgS3Uploader(const QPixmap &capture, QWidget *parent = nullptr); - explicit ImgS3Uploader(QWidget *parent = nullptr); - void upload(); - void deleteResource(const QString &, const QString &); - bool success(); - -private slots: - void handleReplyUpload(QNetworkReply *reply); - void handleReplyGetCreds(QNetworkReply *reply); - void handleReplyDeleteResource(QNetworkReply *reply); - void startDrag(); - - void openURL(); - void copyURL(); - void copyImage(); - void deleteImageOnS3(); - -private: - void init(const QString &title, const QString &label); - void uploadToS3(QJsonDocument &response); - QNetworkProxy *initProxy(); - void clearProxy(); - void removeImagePreview(); - - void onUploadOk(); - - void hideSpinner(); - void setInfoLabelText(const QString &); - QNetworkProxy *proxy(); - - -// class members -private: - bool m_success; - ImgS3Settings m_s3Settings; - - ImageLabel *m_imageLabel; - - QString m_hostName; - QPixmap m_pixmap; - QNetworkProxy *m_proxy; - QNetworkAccessManager *m_NetworkAMUpload; - QNetworkAccessManager *m_NetworkAMGetCreds; - QNetworkAccessManager *m_NetworkAMRemove; - - QVBoxLayout *m_vLayout; - QHBoxLayout *m_hLayout; - // loading - QLabel *m_infoLabel; - LoadSpinner *m_spinner; - // uploaded - QPushButton *m_openUrlButton; - QPushButton *m_copyUrlButton; - QPushButton *m_toClipboardButton; - QPushButton *m_deleteImageOnS3; - QUrl m_imageURL; - NotificationWidget *m_notification; - - // Temporary variables - QString m_deleteToken; - QString m_s3ImageName; -}; diff --git a/src/tools/imgur/imguruploader.cpp b/src/tools/imgur/imguruploader.cpp deleted file mode 100644 index cd0dfc63..00000000 --- a/src/tools/imgur/imguruploader.cpp +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors -// -// This file is part of Flameshot. -// -// Flameshot 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 3 of the License, or -// (at your option) any later version. -// -// Flameshot 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 Flameshot. If not, see . - -#include "imguruploader.h" -#include "src/utils/filenamehandler.h" -#include "src/utils/systemnotification.h" -#include "src/widgets/loadspinner.h" -#include "src/widgets/imagelabel.h" -#include "src/widgets/notificationwidget.h" -#include "src/utils/confighandler.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -ImgurUploader::ImgurUploader(const QPixmap &capture, QWidget *parent) : - QWidget(parent), m_pixmap(capture) -{ - setWindowTitle(tr("Upload to Imgur")); - setWindowIcon(QIcon(":img/app/flameshot.svg")); - - m_spinner = new LoadSpinner(this); - m_spinner->setColor(ConfigHandler().uiMainColorValue()); - m_spinner->start(); - - m_infoLabel = new QLabel(tr("Uploading Image")); - - m_vLayout = new QVBoxLayout(); - setLayout(m_vLayout); - m_vLayout->addWidget(m_spinner, 0, Qt::AlignHCenter); - m_vLayout->addWidget(m_infoLabel); - - m_NetworkAM = new QNetworkAccessManager(this); - connect(m_NetworkAM, &QNetworkAccessManager::finished, this, - &ImgurUploader::handleReply); - - setAttribute(Qt::WA_DeleteOnClose); - - upload(); - // QTimer::singleShot(2000, this, &ImgurUploader::onUploadOk); // testing -} - -void ImgurUploader::handleReply(QNetworkReply *reply) { - m_spinner->deleteLater(); - if (reply->error() == QNetworkReply::NoError) { - QJsonDocument response = QJsonDocument::fromJson(reply->readAll()); - QJsonObject json = response.object(); - QJsonObject data = json[QStringLiteral("data")].toObject(); - m_imageURL.setUrl(data[QStringLiteral("link")].toString()); - m_deleteImageURL.setUrl(QStringLiteral("https://imgur.com/delete/%1").arg( - data[QStringLiteral("deletehash")].toString())); - if (ConfigHandler().copyAndCloseAfterUploadEnabled()) { - QApplication::clipboard()->setText(m_imageURL.toString()); - SystemNotification().sendMessage(QObject::tr("URL copied to clipboard.")); - close(); - } else { - onUploadOk(); - } - } else { - m_infoLabel->setText(reply->errorString()); - } - new QShortcut(Qt::Key_Escape, this, SLOT(close())); -} - -void ImgurUploader::startDrag() { - QMimeData *mimeData = new QMimeData; - mimeData->setUrls(QList { m_imageURL }); - mimeData->setImageData(m_pixmap); - - QDrag *dragHandler = new QDrag(this); - dragHandler->setMimeData(mimeData); - dragHandler->setPixmap(m_pixmap.scaled(256, 256, Qt::KeepAspectRatioByExpanding, - Qt::SmoothTransformation)); - dragHandler->exec(); -} - -void ImgurUploader::upload() { - QByteArray byteArray; - QBuffer buffer(&byteArray); - m_pixmap.save(&buffer, "PNG"); - - QUrlQuery urlQuery; - urlQuery.addQueryItem(QStringLiteral("title"), QStringLiteral("flameshot_screenshot")); - QString description = FileNameHandler().parsedPattern(); - urlQuery.addQueryItem(QStringLiteral("description"), description); - - QUrl url(QStringLiteral("https://api.imgur.com/3/image")); - url.setQuery(urlQuery); - QNetworkRequest request(url); - request.setHeader(QNetworkRequest::ContentTypeHeader, - "application/application/x-www-form-urlencoded"); - request.setRawHeader("Authorization", QStringLiteral("Client-ID %1").arg(IMGUR_CLIENT_ID).toUtf8()); - - m_NetworkAM->post(request, byteArray); -} - -void ImgurUploader::onUploadOk() { - m_infoLabel->deleteLater(); - - m_notification = new NotificationWidget(); - m_vLayout->addWidget(m_notification); - - ImageLabel *imageLabel = new ImageLabel(); - imageLabel->setScreenshot(m_pixmap); - imageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - connect(imageLabel, &ImageLabel::dragInitiated, this, &ImgurUploader::startDrag); - m_vLayout->addWidget(imageLabel); - - m_hLayout = new QHBoxLayout(); - m_vLayout->addLayout(m_hLayout); - - m_copyUrlButton = new QPushButton(tr("Copy URL")); - m_openUrlButton = new QPushButton(tr("Open URL")); - m_openDeleteUrlButton = new QPushButton(tr("Delete image")); - m_toClipboardButton = new QPushButton(tr("Image to Clipboard.")); - m_hLayout->addWidget(m_copyUrlButton); - m_hLayout->addWidget(m_openUrlButton); - m_hLayout->addWidget(m_openDeleteUrlButton); - m_hLayout->addWidget(m_toClipboardButton); - - connect(m_copyUrlButton, &QPushButton::clicked, - this, &ImgurUploader::copyURL); - connect(m_openUrlButton, &QPushButton::clicked, - this, &ImgurUploader::openURL); - connect(m_openDeleteUrlButton, &QPushButton::clicked, - this, &ImgurUploader::openDeleteURL); - connect(m_toClipboardButton, &QPushButton::clicked, - this, &ImgurUploader::copyImage); -} - -void ImgurUploader::openURL() { - bool successful = QDesktopServices::openUrl(m_imageURL); - if (!successful) { - m_notification->showMessage(tr("Unable to open the URL.")); - } -} - -void ImgurUploader::copyURL() { - QApplication::clipboard()->setText(m_imageURL.toString()); - m_notification->showMessage(tr("URL copied to clipboard.")); -} - -void ImgurUploader::openDeleteURL() -{ - bool successful = QDesktopServices::openUrl(m_deleteImageURL); - if (!successful) { - m_notification->showMessage(tr("Unable to open the URL.")); - } -} - -void ImgurUploader::copyImage() { - QApplication::clipboard()->setPixmap(m_pixmap); - m_notification->showMessage(tr("Screenshot copied to clipboard.")); -} diff --git a/src/tools/imgs3/imgs3settings.cpp b/src/tools/storage/imgs3settings.cpp similarity index 100% rename from src/tools/imgs3/imgs3settings.cpp rename to src/tools/storage/imgs3settings.cpp diff --git a/src/tools/imgs3/imgs3settings.h b/src/tools/storage/imgs3settings.h similarity index 100% rename from src/tools/imgs3/imgs3settings.h rename to src/tools/storage/imgs3settings.h diff --git a/src/tools/storage/imgs3uploader.cpp b/src/tools/storage/imgs3uploader.cpp new file mode 100644 index 00000000..0a90afb7 --- /dev/null +++ b/src/tools/storage/imgs3uploader.cpp @@ -0,0 +1,377 @@ +// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot 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 3 of the License, or +// (at your option) any later version. +// +// Flameshot 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 Flameshot. If not, see . + +#include "imgs3uploader.h" +#include "src/utils/configenterprise.h" +#include "src/utils/confighandler.h" +#include "src/utils/filenamehandler.h" +#include "src/utils/history.h" +#include "src/utils/systemnotification.h" +#include "src/widgets/imagelabel.h" +#include "src/widgets/loadspinner.h" +#include "src/widgets/notificationwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ImgS3Uploader::ImgS3Uploader(const QPixmap& capture, QWidget* parent) + : ImgUploader(capture, parent) +{ + init(tr("Upload image to S3"), tr("Uploading Image")); +} + +ImgS3Uploader::ImgS3Uploader(QWidget* parent) + : ImgUploader(parent) +{ + init(tr("Delete image from S3"), tr("Deleting image...")); +} + +void ImgS3Uploader::init(const QString& title, const QString& label) +{ + m_proxy = nullptr; + m_NetworkAMUpload = nullptr; + m_NetworkAMGetCreds = nullptr; + m_NetworkAMRemove = nullptr; + + resultStatus = false; + setWindowTitle(title); + setWindowIcon(QIcon(":img/app/flameshot.svg")); +} + +QNetworkProxy* ImgS3Uploader::proxy() +{ + if (m_proxy == nullptr) { + initProxy(); + } + return m_proxy; +} + +QNetworkProxy* ImgS3Uploader::initProxy() +{ + // get enterprise settings + ConfigEnterprise* configEnterprise = new ConfigEnterprise(); + + // get proxy settings from "config.ini" file + QSettings* settings = configEnterprise->settings(); + QString httpProxyHost = settings->value("HTTP_PROXY_HOST").toString(); + + if (httpProxyHost.length() > 0) { + m_proxy = new QNetworkProxy(); + + if (settings->contains("HTTP_PROXY_TYPE")) { + switch (settings->value("HTTP_PROXY_TYPE").toInt()) { + case 0: + m_proxy->setType(QNetworkProxy::DefaultProxy); + break; + case 1: + m_proxy->setType(QNetworkProxy::Socks5Proxy); + break; + case 2: + m_proxy->setType(QNetworkProxy::NoProxy); + break; + case 4: + m_proxy->setType(QNetworkProxy::HttpCachingProxy); + break; + case 5: + m_proxy->setType(QNetworkProxy::FtpCachingProxy); + break; + case 3: + default: + m_proxy->setType(QNetworkProxy::HttpProxy); + break; + } + } + + m_proxy->setHostName(httpProxyHost); + int nProxyPort = 3128; + if (settings->contains("HTTP_PROXY_PORT")) { + nProxyPort = settings->value("HTTP_PROXY_PORT").toInt(); + } + m_proxy->setPort(nProxyPort); + + if (settings->contains("HTTP_PROXY_USER")) { + qDebug() << "Proxy user" + << settings->value("HTTP_PROXY_PASSWORD").toString(); + m_proxy->setUser(settings->value("HTTP_PROXY_USER").toString()); + } + if (settings->contains("HTTP_PROXY_PASSWORD")) { + qDebug() << "Proxy password is not empty"; + m_proxy->setPassword( + settings->value("HTTP_PROXY_PASSWORD").toString()); + } + } else { + // Get proxy settings from OS settings + QNetworkProxyQuery q(QUrl(m_s3Settings.credsUrl().toUtf8())); + q.setQueryType(QNetworkProxyQuery::UrlRequest); + q.setProtocolTag("http"); + + QList proxies = + QNetworkProxyFactory::systemProxyForQuery(q); + if (proxies.size() > 0 && proxies[0].type() != QNetworkProxy::NoProxy) { + m_proxy = new QNetworkProxy(); + m_proxy->setHostName(proxies[0].hostName()); + m_proxy->setPort(proxies[0].port()); + m_proxy->setType(proxies[0].type()); + m_proxy->setUser(proxies[0].user()); + m_proxy->setPassword(proxies[0].password()); + } + } +#ifdef QT_DEBUG + if (m_proxy != nullptr) { + qDebug() << "Using proxy server"; + qDebug() << "proxy host:" << m_proxy->hostName(); + qDebug() << "proxy port:" << m_proxy->port(); + qDebug() << "proxy type:" << m_proxy->type(); + qDebug() << "proxy user:" + << (m_proxy->user().length() > 0 ? m_proxy->user() + : "no user"); + qDebug() << "proxy password:" + << (m_proxy->password().length() > 0 ? "***" : "no password"); + } else { + qDebug() << "No proxy"; + } +#endif + return m_proxy; +} + +void ImgS3Uploader::clearProxy() +{ + if (m_proxy != nullptr) { + delete m_proxy; + m_proxy = nullptr; + } +} + +void ImgS3Uploader::handleReplyUpload(QNetworkReply* reply) +{ + hideSpinner(); + m_storageImageName.clear(); + if (reply->error() == QNetworkReply::NoError) { + // save history + QString imageName = imageUrl().toString(); + int lastSlash = imageName.lastIndexOf("/"); + if (lastSlash >= 0) { + imageName = imageName.mid(lastSlash + 1); + } + m_storageImageName = imageName; + History history; + imageName = history.packFileName( + SCREENSHOT_STORAGE_TYPE_S3, m_deleteToken, imageName); + history.save(pixmap(), imageName); + resultStatus = true; + + // Copy url to clipboard if required + if (ConfigHandler().copyAndCloseAfterUploadEnabled()) { + QApplication::clipboard()->setText(imageUrl().toString()); + SystemNotification().sendMessage(tr("URL copied to clipboard.")); + close(); + } else { + onUploadOk(); + } + } else { + QString reason = + reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute) + .toString(); + setInfoLabelText(reply->errorString()); + } + new QShortcut(Qt::Key_Escape, this, SLOT(close())); +} + +void ImgS3Uploader::handleReplyDeleteResource(QNetworkReply* reply) +{ + auto replyError = reply->error(); + if (replyError == QNetworkReply::NoError) { + removeImagePreview(); + } else { + hide(); + + // generate error message + QString message = + tr("Unable to remove screenshot from the remote storage."); + if (replyError == QNetworkReply::UnknownNetworkError) { + message += "\n" + tr("Network error"); + } else if (replyError == QNetworkReply::UnknownServerError) { + message += "\n" + tr("Possibly it doesn't exist anymore"); + } + message += "\n\n" + reply->errorString(); + message += + "\n\n" + + tr("Do you want to remove screenshot from local history anyway?"); + + if (QMessageBox::Yes == + QMessageBox::question(NULL, + tr("Remove screenshot from history?"), + message, + QMessageBox::Yes | QMessageBox::No)) { + removeImagePreview(); + } + } + close(); +} + +void ImgS3Uploader::handleReplyGetCreds(QNetworkReply* reply) +{ + if (reply->error() == QNetworkReply::NoError) { + QJsonDocument response = QJsonDocument::fromJson(reply->readAll()); + uploadToS3(response); + } else { + if (m_s3Settings.credsUrl().length() == 0) { + setInfoLabelText( + tr("S3 Creds URL is not found in your configuration file")); + } else { + setInfoLabelText(reply->errorString()); + } + } + new QShortcut(Qt::Key_Escape, this, SLOT(close())); +} + +void ImgS3Uploader::uploadToS3(QJsonDocument& response) +{ + // set paramets from "fields" + QHttpMultiPart* multiPart = + new QHttpMultiPart(QHttpMultiPart::FormDataType); + + // read JSON response + QJsonObject json = response.object(); + QString resultUrl = json["resultURL"].toString(); + QJsonObject formData = json["formData"].toObject(); + QString url = formData["url"].toString(); + m_deleteToken = json["deleteToken"].toString(); + + QJsonObject fields = formData["fields"].toObject(); + foreach (auto key, fields.keys()) { + QString field = fields[key].toString(); + QHttpPart part; + part.setHeader(QNetworkRequest::ContentDispositionHeader, + QVariant("form-data; name=\"" + key + "\"")); + part.setBody(field.toLatin1()); + multiPart->append(part); + } + + QHttpPart imagePart; + imagePart.setHeader(QNetworkRequest::ContentTypeHeader, + QVariant("image/png")); + imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, + QVariant("form-data; name=\"file\"")); + + QByteArray byteArray; + QBuffer buffer(&byteArray); + buffer.open(QIODevice::WriteOnly); + pixmap().save(&buffer, "PNG"); + + imagePart.setBody(byteArray); + multiPart->append(imagePart); + + setImageUrl(QUrl(resultUrl)); + + QUrl qUrl(url); + QNetworkRequest request(qUrl); + + // upload + m_NetworkAMUpload->post(request, multiPart); +} + +void ImgS3Uploader::deleteResource(const QString& fileName, + const QString& deleteToken) +{ + // read network settings on each call to simplify configuration management + // without restarting + clearProxy(); + if (m_NetworkAMRemove != nullptr) { + delete m_NetworkAMRemove; + m_NetworkAMRemove = nullptr; + } + m_NetworkAMRemove = new QNetworkAccessManager(this); + connect(m_NetworkAMRemove, + &QNetworkAccessManager::finished, + this, + &ImgS3Uploader::handleReplyDeleteResource); + if (proxy() != nullptr) { + m_NetworkAMRemove->setProxy(*proxy()); + } + + QNetworkRequest request; + m_storageImageName = fileName; + m_deleteToken = deleteToken; + request.setUrl(m_s3Settings.credsUrl().toUtf8() + fileName); + request.setRawHeader("X-API-Key", m_s3Settings.xApiKey().toLatin1()); + request.setRawHeader("Authorization", "Bearer " + deleteToken.toLatin1()); + m_NetworkAMRemove->deleteResource(request); +} + +void ImgS3Uploader::upload() +{ + m_deleteToken.clear(); + m_storageImageName.clear(); + + // read network settings on each call to simplify configuration management + // without restarting init creds and upload network access managers + clearProxy(); + if (m_NetworkAMGetCreds != nullptr) { + delete m_NetworkAMGetCreds; + m_NetworkAMGetCreds = nullptr; + } + m_NetworkAMGetCreds = new QNetworkAccessManager(this); + connect(m_NetworkAMGetCreds, + &QNetworkAccessManager::finished, + this, + &ImgS3Uploader::handleReplyGetCreds); + + if (m_NetworkAMUpload != nullptr) { + delete m_NetworkAMUpload; + m_NetworkAMUpload = nullptr; + } + m_NetworkAMUpload = new QNetworkAccessManager(this); + connect(m_NetworkAMUpload, + &QNetworkAccessManager::finished, + this, + &ImgS3Uploader::handleReplyUpload); + if (proxy() != nullptr) { + m_NetworkAMGetCreds->setProxy(*proxy()); + m_NetworkAMUpload->setProxy(*proxy()); + } + + // get creads + QUrl creds(m_s3Settings.credsUrl()); + QNetworkRequest requestCreds(creds); + if (m_s3Settings.xApiKey().length() > 0) { + requestCreds.setRawHeader( + QByteArray("X-API-Key"), + QByteArray(m_s3Settings.xApiKey().toLocal8Bit())); + } + m_NetworkAMGetCreds->get(requestCreds); +} diff --git a/src/tools/storage/imgs3uploader.h b/src/tools/storage/imgs3uploader.h new file mode 100644 index 00000000..6e8267e9 --- /dev/null +++ b/src/tools/storage/imgs3uploader.h @@ -0,0 +1,69 @@ +// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot 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 3 of the License, or +// (at your option) any later version. +// +// Flameshot 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 Flameshot. If not, see . + +#pragma once + +#define S3_API_IMG_PATH "v2/image/" + +#include "imgs3settings.h" +#include "imguploader.h" +#include +#include + +class QNetworkReply; +class QNetworkProxy; +class QNetworkAccessManager; +class QHBoxLayout; +class QVBoxLayout; +class QLabel; +class QPushButton; +class QUrl; +class NotificationWidget; +class ConfigEnterprise; +class ImageLabel; + +class ImgS3Uploader : public ImgUploader +{ + Q_OBJECT +public: + explicit ImgS3Uploader(const QPixmap& capture, QWidget* parent = nullptr); + explicit ImgS3Uploader(QWidget* parent = nullptr); + void upload(); + void deleteResource(const QString&, const QString&); + +private slots: + void handleReplyUpload(QNetworkReply* reply); + void handleReplyGetCreds(QNetworkReply* reply); + void handleReplyDeleteResource(QNetworkReply* reply); + +private: + void init(const QString& title, const QString& label); + void uploadToS3(QJsonDocument& response); + + QNetworkProxy* initProxy(); + void clearProxy(); + QNetworkProxy* proxy(); + + // class members +private: + ImgS3Settings m_s3Settings; + + QNetworkProxy* m_proxy; + QNetworkAccessManager* m_NetworkAMUpload; + QNetworkAccessManager* m_NetworkAMGetCreds; + QNetworkAccessManager* m_NetworkAMRemove; +}; diff --git a/src/tools/imgs3/imgs3uploadertool.cpp b/src/tools/storage/imgs3uploadertool.cpp similarity index 66% rename from src/tools/imgs3/imgs3uploadertool.cpp rename to src/tools/storage/imgs3uploadertool.cpp index 45f04aaf..e1694470 100644 --- a/src/tools/imgs3/imgs3uploadertool.cpp +++ b/src/tools/storage/imgs3uploadertool.cpp @@ -18,49 +18,56 @@ #include "imgs3uploadertool.h" #include "imgs3uploader.h" #include -#include -#include +ImgS3UploaderTool::ImgS3UploaderTool(QObject* parent) + : AbstractActionTool(parent) +{} -ImgS3UploaderTool::ImgS3UploaderTool(QObject *parent) : AbstractActionTool(parent) { -} - -bool ImgS3UploaderTool::closeOnButtonPressed() const { +bool ImgS3UploaderTool::closeOnButtonPressed() const +{ return true; } -QIcon ImgS3UploaderTool::icon(const QColor &background, bool inEditor) const { +QIcon ImgS3UploaderTool::icon(const QColor& background, bool inEditor) const +{ Q_UNUSED(inEditor); return QIcon(iconPath(background) + "cloud-upload.svg"); } -QString ImgS3UploaderTool::name() const { +QString ImgS3UploaderTool::name() const +{ return tr("Image Uploader"); } -QString ImgS3UploaderTool::nameID() { +QString ImgS3UploaderTool::nameID() +{ return QLatin1String(""); } -QString ImgS3UploaderTool::description() const { +QString ImgS3UploaderTool::description() const +{ return tr("Upload the selection to S3 bucket"); } -QWidget *ImgS3UploaderTool::widget() { - ImgS3Uploader *p = new ImgS3Uploader(capture); +QWidget* ImgS3UploaderTool::widget() +{ + ImgS3Uploader* p = new ImgS3Uploader(capture); p->upload(); return p; } -void ImgS3UploaderTool::setCapture(const QPixmap &pixmap) { +void ImgS3UploaderTool::setCapture(const QPixmap& pixmap) +{ capture = pixmap; } -CaptureTool *ImgS3UploaderTool::copy(QObject *parent) { +CaptureTool* ImgS3UploaderTool::copy(QObject* parent) +{ return new ImgS3UploaderTool(parent); } -void ImgS3UploaderTool::pressed(const CaptureContext &context) { +void ImgS3UploaderTool::pressed(const CaptureContext& context) +{ capture = context.selectedScreenshotArea(); emit requestAction(REQ_CAPTURE_DONE_OK); emit requestAction(REQ_ADD_EXTERNAL_WIDGETS); diff --git a/src/tools/imgs3/imgs3uploadertool.h b/src/tools/storage/imgs3uploadertool.h similarity index 100% rename from src/tools/imgs3/imgs3uploadertool.h rename to src/tools/storage/imgs3uploadertool.h diff --git a/src/tools/storage/imguploader.cpp b/src/tools/storage/imguploader.cpp new file mode 100644 index 00000000..c696fdec --- /dev/null +++ b/src/tools/storage/imguploader.cpp @@ -0,0 +1,226 @@ +// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot 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 3 of the License, or +// (at your option) any later version. +// +// Flameshot 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 Flameshot. If not, see . + +#include "imguploader.h" +#include "src/utils/configenterprise.h" +#include "src/utils/confighandler.h" +#include "src/utils/filenamehandler.h" +#include "src/utils/history.h" +#include "src/utils/systemnotification.h" +#include "src/widgets/imagelabel.h" +#include "src/widgets/loadspinner.h" +#include "src/widgets/notificationwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ImgUploader::ImgUploader(const QPixmap& capture, QWidget* parent) + : QWidget(parent) + , m_pixmap(capture) +{ + init(tr("Upload image to S3"), tr("Uploading Image")); +} + +ImgUploader::ImgUploader(QWidget* parent) + : QWidget(parent) +{ + init(tr("Upload image"), tr("Uploading Image")); +} + +void ImgUploader::init(const QString& title, const QString& label) +{ + m_imageLabel = nullptr; + m_spinner = nullptr; + + resultStatus = false; + setWindowTitle(title); + setWindowIcon(QIcon(":img/app/flameshot.svg")); + + m_spinner = new LoadSpinner(this); + m_spinner->setColor(ConfigHandler().uiMainColorValue()); + m_spinner->start(); + + m_infoLabel = new QLabel(label); + m_infoLabel->setAlignment(Qt::AlignCenter); + + m_vLayout = new QVBoxLayout(); + setLayout(m_vLayout); + m_vLayout->addWidget(m_spinner, 0, Qt::AlignHCenter); + m_vLayout->addWidget(m_infoLabel); + + setAttribute(Qt::WA_DeleteOnClose); +} + +void ImgUploader::removeImagePreview() +{ + // remove local file + History history; + QString packedFileName = history.packFileName( + SCREENSHOT_STORAGE_TYPE_S3, m_deleteToken, m_storageImageName); + QString fullFileName = history.path() + packedFileName; + + QFile file(fullFileName); + if (file.exists()) { + file.remove(); + } + m_deleteToken.clear(); + m_storageImageName.clear(); + resultStatus = true; +} + +void ImgUploader::openURL() +{ + bool successful = QDesktopServices::openUrl(imageUrl()); + if (!successful) { + m_notification->showMessage(tr("Unable to open the URL.")); + } +} + +void ImgUploader::copyURL() +{ + QApplication::clipboard()->setText(imageUrl().toString()); + m_notification->showMessage(tr("URL copied to clipboard.")); +} + +void ImgUploader::copyImage() +{ + QApplication::clipboard()->setPixmap(m_pixmap); + m_notification->showMessage(tr("Screenshot copied to clipboard.")); +} + +void ImgUploader::deleteImageOnStorage() +{ + if (nullptr != m_imageLabel) { + m_imageLabel->hide(); + } + m_spinner->show(); + setInfoLabelText(tr("Deleting image...")); + deleteResource(m_storageImageName, m_deleteToken); +} + +void ImgUploader::startDrag() +{ + QMimeData* mimeData = new QMimeData; + mimeData->setUrls(QList{ imageUrl() }); + mimeData->setImageData(m_pixmap); + + QDrag* dragHandler = new QDrag(this); + dragHandler->setMimeData(mimeData); + dragHandler->setPixmap(m_pixmap.scaled( + 256, 256, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation)); + dragHandler->exec(); +} + +void ImgUploader::hideSpinner() +{ + if (nullptr != m_spinner) { + m_spinner->hide(); + } + if (nullptr != m_imageLabel) { + m_imageLabel->hide(); + } +} + +void ImgUploader::setInfoLabelText(const QString& infoText) +{ + m_infoLabel->setText(infoText); + m_infoLabel->show(); +} + +const QPixmap& ImgUploader::pixmap() +{ + return m_pixmap; +} + +void ImgUploader::onUploadOk() +{ + hideSpinner(); + + m_notification = new NotificationWidget(); + m_vLayout->addWidget(m_notification); + + if (nullptr == m_imageLabel) { + m_imageLabel = new ImageLabel(); + m_imageLabel->setScreenshot(pixmap()); + m_imageLabel->setSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Expanding); + connect(m_imageLabel, + &ImageLabel::dragInitiated, + this, + &ImgUploader::startDrag); + m_vLayout->addWidget(m_imageLabel); + } + + m_hLayout = new QHBoxLayout(); + m_vLayout->addLayout(m_hLayout); + + m_copyUrlButton = new QPushButton(tr("Copy URL")); + m_openUrlButton = new QPushButton(tr("Open URL")); + m_deleteImageOnStorage = new QPushButton(tr("Delete image")); + m_toClipboardButton = new QPushButton(tr("Image to Clipboard.")); + m_hLayout->addWidget(m_copyUrlButton); + m_hLayout->addWidget(m_openUrlButton); + m_hLayout->addWidget(m_deleteImageOnStorage); + m_hLayout->addWidget(m_toClipboardButton); + + connect( + m_copyUrlButton, &QPushButton::clicked, this, &ImgUploader::copyURL); + connect( + m_openUrlButton, &QPushButton::clicked, this, &ImgUploader::openURL); + connect(m_deleteImageOnStorage, + &QPushButton::clicked, + this, + &ImgUploader::deleteImageOnStorage); + connect(m_toClipboardButton, + &QPushButton::clicked, + this, + &ImgUploader::copyImage); +} + +void ImgUploader::setImageUrl(const QUrl& imageURL) +{ + m_imageURL = imageURL; +} +const QUrl& ImgUploader::imageUrl() +{ + return m_imageURL; +} + +void ImgUploader::showNotificationMessage(const QString& notificationMessage) { + m_notification->showMessage(notificationMessage); +} + diff --git a/src/tools/storage/imguploader.h b/src/tools/storage/imguploader.h new file mode 100644 index 00000000..2337d363 --- /dev/null +++ b/src/tools/storage/imguploader.h @@ -0,0 +1,98 @@ +// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot 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 3 of the License, or +// (at your option) any later version. +// +// Flameshot 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 Flameshot. If not, see . + +#pragma once + +#define S3_API_IMG_PATH "v2/image/" + +#include "imgs3settings.h" +#include +#include + +class QNetworkReply; +class QNetworkProxy; +class QNetworkAccessManager; +class QHBoxLayout; +class QVBoxLayout; +class QLabel; +class LoadSpinner; +class QPushButton; +class QUrl; +class NotificationWidget; +class ConfigEnterprise; +class ImageLabel; + +class ImgUploader : public QWidget +{ + Q_OBJECT +public: + explicit ImgUploader(const QPixmap& capture, QWidget* parent = nullptr); + explicit ImgUploader(QWidget* parent = nullptr); + + virtual void upload(){}; + virtual void deleteResource(const QString&, const QString&){}; + +protected: + const QPixmap& pixmap(); + void setImageUrl(const QUrl&); + const QUrl& imageUrl(); + void onUploadOk(); + void hideSpinner(); + void setInfoLabelText(const QString&); + void removeImagePreview(); + void showNotificationMessage(const QString&); + +public slots: + virtual void openURL(); + virtual void copyURL(); + virtual void copyImage(); + virtual void deleteImageOnStorage(); + virtual void startDrag(); + +private: + void init(const QString& title, const QString& label); + + // class members +private: + QPixmap m_pixmap; + + QUrl m_imageURL; + ImageLabel* m_imageLabel; + + NotificationWidget* m_notification; + + QVBoxLayout* m_vLayout; + QHBoxLayout* m_hLayout; + // loading + LoadSpinner* m_spinner; + QLabel* m_infoLabel; + // uploaded + QPushButton* m_openUrlButton; + QPushButton* m_copyUrlButton; + QPushButton* m_toClipboardButton; + QPushButton* m_deleteImageOnStorage; + +protected: + // bool m_success; + + // Temporary variables + QString m_deleteToken; + QString m_storageImageName; + +public: + bool resultStatus; +}; diff --git a/src/tools/storage/imguruploader.cpp b/src/tools/storage/imguruploader.cpp new file mode 100644 index 00000000..afadbbfa --- /dev/null +++ b/src/tools/storage/imguruploader.cpp @@ -0,0 +1,111 @@ +// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot 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 3 of the License, or +// (at your option) any later version. +// +// Flameshot 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 Flameshot. If not, see . + +#include "imguruploader.h" +#include "src/utils/confighandler.h" +#include "src/utils/filenamehandler.h" +#include "src/utils/systemnotification.h" +#include "src/widgets/imagelabel.h" +#include "src/widgets/loadspinner.h" +#include "src/widgets/notificationwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ImgurUploader::ImgurUploader(const QPixmap& capture, QWidget* parent) + : ImgUploader(capture, parent) +{ + setWindowTitle(tr("Upload to Imgur")); + + m_NetworkAM = new QNetworkAccessManager(this); + connect(m_NetworkAM, + &QNetworkAccessManager::finished, + this, + &ImgurUploader::handleReply); + // QTimer::singleShot(2000, this, &ImgurUploader::onUploadOk); // testing +} + +void ImgurUploader::handleReply(QNetworkReply* reply) +{ + if (reply->error() == QNetworkReply::NoError) { + QJsonDocument response = QJsonDocument::fromJson(reply->readAll()); + QJsonObject json = response.object(); + QJsonObject data = json[QStringLiteral("data")].toObject(); + setImageUrl(data[QStringLiteral("link")].toString()); + m_deleteImageURL.setUrl( + QStringLiteral("https://imgur.com/delete/%1") + .arg(data[QStringLiteral("deletehash")].toString())); + if (ConfigHandler().copyAndCloseAfterUploadEnabled()) { + QApplication::clipboard()->setText(imageUrl().toString()); + SystemNotification().sendMessage( + QObject::tr("URL copied to clipboard.")); + close(); + } else { + onUploadOk(); + } + } else { + setInfoLabelText(reply->errorString()); + } + new QShortcut(Qt::Key_Escape, this, SLOT(close())); +} + +void ImgurUploader::upload() +{ + QByteArray byteArray; + QBuffer buffer(&byteArray); + pixmap().save(&buffer, "PNG"); + + QUrlQuery urlQuery; + urlQuery.addQueryItem(QStringLiteral("title"), + QStringLiteral("flameshot_screenshot")); + QString description = FileNameHandler().parsedPattern(); + urlQuery.addQueryItem(QStringLiteral("description"), description); + + QUrl url(QStringLiteral("https://api.imgur.com/3/image")); + url.setQuery(urlQuery); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, + "application/application/x-www-form-urlencoded"); + request.setRawHeader( + "Authorization", + QStringLiteral("Client-ID %1").arg(IMGUR_CLIENT_ID).toUtf8()); + + m_NetworkAM->post(request, byteArray); +} + +void ImgurUploader::deleteImageOnStorage() +{ + bool successful = QDesktopServices::openUrl(m_deleteImageURL); + if (!successful) { + showNotificationMessage(tr("Unable to open the URL.")); + } +} diff --git a/src/tools/imgur/imguruploader.h b/src/tools/storage/imguruploader.h similarity index 61% rename from src/tools/imgur/imguruploader.h rename to src/tools/storage/imguruploader.h index 94458655..f2987457 100644 --- a/src/tools/imgur/imguruploader.h +++ b/src/tools/storage/imguruploader.h @@ -17,8 +17,9 @@ #pragma once -#include +#include "imguploader.h" #include +#include class QNetworkReply; class QNetworkAccessManager; @@ -30,38 +31,22 @@ class QPushButton; class QUrl; class NotificationWidget; -class ImgurUploader : public QWidget { +class ImgurUploader : public ImgUploader +{ Q_OBJECT public: - explicit ImgurUploader(const QPixmap &capture, QWidget *parent = nullptr); + explicit ImgurUploader(const QPixmap& capture, QWidget* parent = nullptr); + void upload(); private slots: - void handleReply(QNetworkReply *reply); - void startDrag(); + void handleReply(QNetworkReply* reply); + // void openDeleteURL(); - void openURL(); - void copyURL(); - void openDeleteURL(); - void copyImage(); +protected slots: + void deleteImageOnStorage(); + // class members private: - QPixmap m_pixmap; - QNetworkAccessManager *m_NetworkAM; - - QVBoxLayout *m_vLayout; - QHBoxLayout *m_hLayout; - // loading - QLabel *m_infoLabel; - LoadSpinner *m_spinner; - // uploaded - QPushButton *m_openUrlButton; - QPushButton *m_openDeleteUrlButton; - QPushButton *m_copyUrlButton; - QPushButton *m_toClipboardButton; - QUrl m_imageURL; + QNetworkAccessManager* m_NetworkAM; QUrl m_deleteImageURL; - NotificationWidget *m_notification; - - void upload(); - void onUploadOk(); }; diff --git a/src/tools/imgur/imguruploadertool.cpp b/src/tools/storage/imguruploadertool.cpp similarity index 65% rename from src/tools/imgur/imguruploadertool.cpp rename to src/tools/storage/imguruploadertool.cpp index ea68303c..44dabf4a 100644 --- a/src/tools/imgur/imguruploadertool.cpp +++ b/src/tools/storage/imguruploadertool.cpp @@ -19,39 +19,55 @@ #include "imguruploader.h" #include -ImgurUploaderTool::ImgurUploaderTool(QObject *parent) : AbstractActionTool(parent) { +ImgurUploaderTool::ImgurUploaderTool(QObject* parent) + : AbstractActionTool(parent) +{} -} - -bool ImgurUploaderTool::closeOnButtonPressed() const { +bool ImgurUploaderTool::closeOnButtonPressed() const +{ return true; } -QIcon ImgurUploaderTool::icon(const QColor &background, bool inEditor) const { +QIcon ImgurUploaderTool::icon(const QColor& background, bool inEditor) const +{ Q_UNUSED(inEditor); return QIcon(iconPath(background) + "cloud-upload.svg"); } -QString ImgurUploaderTool::name() const { + +QString ImgurUploaderTool::name() const +{ return tr("Image Uploader"); } -QString ImgurUploaderTool::nameID() { +QString ImgurUploaderTool::nameID() +{ return QLatin1String(""); } -QString ImgurUploaderTool::description() const { +QString ImgurUploaderTool::description() const +{ return tr("Upload the selection to Imgur"); } -QWidget* ImgurUploaderTool::widget() { - return new ImgurUploader(capture); +QWidget* ImgurUploaderTool::widget() +{ + ImgurUploader* p = new ImgurUploader(capture); + p->upload(); + return p; } -CaptureTool* ImgurUploaderTool::copy(QObject *parent) { +void ImgurUploaderTool::setCapture(const QPixmap& pixmap) +{ + capture = pixmap; +} + +CaptureTool* ImgurUploaderTool::copy(QObject* parent) +{ return new ImgurUploaderTool(parent); } -void ImgurUploaderTool::pressed(const CaptureContext &context) { +void ImgurUploaderTool::pressed(const CaptureContext& context) +{ capture = context.selectedScreenshotArea(); emit requestAction(REQ_CAPTURE_DONE_OK); emit requestAction(REQ_ADD_EXTERNAL_WIDGETS); diff --git a/src/tools/imgur/imguruploadertool.h b/src/tools/storage/imguruploadertool.h similarity index 97% rename from src/tools/imgur/imguruploadertool.h rename to src/tools/storage/imguruploadertool.h index e0e49617..b2d3066b 100644 --- a/src/tools/imgur/imguruploadertool.h +++ b/src/tools/storage/imguruploadertool.h @@ -34,6 +34,7 @@ public: QWidget* widget() override; CaptureTool* copy(QObject *parent = nullptr) override; + void setCapture(const QPixmap&); public slots: void pressed(const CaptureContext &context) override; diff --git a/src/tools/toolfactory.cpp b/src/tools/toolfactory.cpp index f76d7ca8..8a216411 100644 --- a/src/tools/toolfactory.cpp +++ b/src/tools/toolfactory.cpp @@ -17,97 +17,96 @@ #include "toolfactory.h" #include "arrow/arrowtool.h" +#include "blur/blurtool.h" #include "circle/circletool.h" #include "copy/copytool.h" #include "exit/exittool.h" -#include "imgur/imguruploadertool.h" -#include "imgs3/imgs3uploadertool.h" +#include "launcher/applaunchertool.h" #include "line/linetool.h" #include "marker/markertool.h" #include "move/movetool.h" #include "pencil/penciltool.h" +#include "pin/pintool.h" #include "rectangle/rectangletool.h" +#include "redo/redotool.h" #include "save/savetool.h" #include "selection/selectiontool.h" #include "sizeindicator/sizeindicatortool.h" -#include "undo/undotool.h" -#include "launcher/applaunchertool.h" -#include "blur/blurtool.h" -#include "redo/redotool.h" -#include "pin/pintool.h" +#include "storage/imgs3uploadertool.h" +#include "storage/imguruploadertool.h" #include "text/texttool.h" +#include "undo/undotool.h" -ToolFactory::ToolFactory(QObject *parent) : QObject(parent) { +ToolFactory::ToolFactory(QObject* parent) + : QObject(parent) +{} -} - -CaptureTool* ToolFactory::CreateTool( - CaptureButton::ButtonType t, - QObject *parent) +CaptureTool* ToolFactory::CreateTool(CaptureButton::ButtonType t, + QObject* parent) { - CaptureTool *tool; + CaptureTool* tool; switch (t) { - case CaptureButton::TYPE_ARROW: - tool = new ArrowTool(parent); - break; - case CaptureButton::TYPE_CIRCLE: - tool = new CircleTool(parent); - break; - case CaptureButton::TYPE_COPY: - tool = new CopyTool(parent); - break; - case CaptureButton::TYPE_EXIT: - tool = new ExitTool(parent); - break; - case CaptureButton::TYPE_IMAGEUPLOADER: -// tool = new ImgurUploaderTool(parent); - tool = new ImgS3UploaderTool(parent); - break; - case CaptureButton::TYPE_DRAWER: - tool = new LineTool(parent); - break; - case CaptureButton::TYPE_MARKER: - tool = new MarkerTool(parent); - break; - case CaptureButton::TYPE_MOVESELECTION: - tool = new MoveTool(parent); - break; - case CaptureButton::TYPE_PENCIL: - tool = new PencilTool(parent); - break; - case CaptureButton::TYPE_RECTANGLE: - tool = new RectangleTool(parent); - break; - case CaptureButton::TYPE_SAVE: - tool = new SaveTool(parent); - break; - case CaptureButton::TYPE_SELECTION: - tool = new SelectionTool(parent); - break; - case CaptureButton::TYPE_SELECTIONINDICATOR: - tool = new SizeIndicatorTool(parent); - break; - case CaptureButton::TYPE_UNDO: - tool = new UndoTool(parent); - break; - case CaptureButton::TYPE_REDO: - tool = new RedoTool(parent); - break; - case CaptureButton::TYPE_OPEN_APP: - tool = new AppLauncher(parent); - break; - case CaptureButton::TYPE_BLUR: - tool = new BlurTool(parent); - break; - case CaptureButton::TYPE_PIN: - tool = new PinTool(parent); - break; - case CaptureButton::TYPE_TEXT: - tool = new TextTool(parent); - break; - default: - tool = nullptr; - break; + case CaptureButton::TYPE_ARROW: + tool = new ArrowTool(parent); + break; + case CaptureButton::TYPE_CIRCLE: + tool = new CircleTool(parent); + break; + case CaptureButton::TYPE_COPY: + tool = new CopyTool(parent); + break; + case CaptureButton::TYPE_EXIT: + tool = new ExitTool(parent); + break; + case CaptureButton::TYPE_IMAGEUPLOADER: + tool = new ImgurUploaderTool(parent); + // tool = new ImgS3UploaderTool(parent); + break; + case CaptureButton::TYPE_DRAWER: + tool = new LineTool(parent); + break; + case CaptureButton::TYPE_MARKER: + tool = new MarkerTool(parent); + break; + case CaptureButton::TYPE_MOVESELECTION: + tool = new MoveTool(parent); + break; + case CaptureButton::TYPE_PENCIL: + tool = new PencilTool(parent); + break; + case CaptureButton::TYPE_RECTANGLE: + tool = new RectangleTool(parent); + break; + case CaptureButton::TYPE_SAVE: + tool = new SaveTool(parent); + break; + case CaptureButton::TYPE_SELECTION: + tool = new SelectionTool(parent); + break; + case CaptureButton::TYPE_SELECTIONINDICATOR: + tool = new SizeIndicatorTool(parent); + break; + case CaptureButton::TYPE_UNDO: + tool = new UndoTool(parent); + break; + case CaptureButton::TYPE_REDO: + tool = new RedoTool(parent); + break; + case CaptureButton::TYPE_OPEN_APP: + tool = new AppLauncher(parent); + break; + case CaptureButton::TYPE_BLUR: + tool = new BlurTool(parent); + break; + case CaptureButton::TYPE_PIN: + tool = new PinTool(parent); + break; + case CaptureButton::TYPE_TEXT: + tool = new TextTool(parent); + break; + default: + tool = nullptr; + break; } return tool; } diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index b4799890..4c45363f 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -15,55 +15,72 @@ // You should have received a copy of the GNU General Public License // along with Flameshot. If not, see . -// Based on Lightscreen areadialog.cpp, Copyright 2017 Christian Kaiser -// released under the GNU GPL2 +// Based on Lightscreen areadialog.cpp, Copyright 2017 Christian Kaiser +// released under the GNU GPL2 +// -// Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 Luca Gugelmann -// released under the GNU LGPL +// Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 +// Luca Gugelmann released under the GNU LGPL +// #include "capturewidget.h" -#include "src/widgets/capture/hovereventfilter.h" -#include "src/widgets/panel/sidepanelwidget.h" +#include "src/core/controller.h" +#include "src/tools/storage/imgs3uploadertool.h" +#include "src/tools/storage/imguruploadertool.h" +#include "src/tools/toolfactory.h" #include "src/utils/colorutils.h" #include "src/utils/globalvalues.h" -#include "src/widgets/capture/notifierbox.h" -#include "src/widgets/capture/colorpicker.h" #include "src/utils/screengrabber.h" -#include "src/utils/systemnotification.h" #include "src/utils/screenshotsaver.h" -#include "src/core/controller.h" +#include "src/utils/systemnotification.h" +#include "src/widgets/capture/colorpicker.h" +#include "src/widgets/capture/hovereventfilter.h" #include "src/widgets/capture/modificationcommand.h" -#include "src/tools/imgs3/imgs3uploadertool.h" -#include "src/tools/toolfactory.h" -#include -#include -#include +#include "src/widgets/capture/notifierbox.h" +#include "src/widgets/panel/sidepanelwidget.h" #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include -// CaptureWidget is the main component used to capture the screen. It contains an -// are of selection with its respective buttons. +// CaptureWidget is the main component used to capture the screen. It contains +// an are of selection with its respective buttons. // enableSaveWIndow -CaptureWidget::CaptureWidget(const uint id, const QString &savePath, - bool fullScreen, QWidget *parent) : - QWidget(parent), m_mouseIsClicked(false), m_rightClick(false), - m_newSelection(false), m_grabbing(false), m_captureDone(false), - m_previewEnabled(true), m_adjustmentButtonPressed(false), m_activeButton(nullptr), - m_activeTool(nullptr), m_toolWidget(nullptr), - m_mouseOverHandle(SelectionWidget::NO_SIDE), m_id(id) +CaptureWidget::CaptureWidget(const uint id, + const QString& savePath, + bool fullScreen, + QWidget* parent) + : QWidget(parent) + , m_mouseIsClicked(false) + , m_rightClick(false) + , m_newSelection(false) + , m_grabbing(false) + , m_captureDone(false) + , m_previewEnabled(true) + , m_adjustmentButtonPressed(false) + , m_activeButton(nullptr) + , m_activeTool(nullptr) + , m_toolWidget(nullptr) + , m_mouseOverHandle(SelectionWidget::NO_SIDE) + , m_id(id) { // Base config of the widget m_eventFilter = new HoverEventFilter(this); - connect(m_eventFilter, &HoverEventFilter::hoverIn, - this, &CaptureWidget::childEnter); - connect(m_eventFilter, &HoverEventFilter::hoverOut, - this, &CaptureWidget::childLeave); + connect(m_eventFilter, + &HoverEventFilter::hoverIn, + this, + &CaptureWidget::childEnter); + connect(m_eventFilter, + &HoverEventFilter::hoverOut, + this, + &CaptureWidget::childLeave); setAttribute(Qt::WA_DeleteOnClose); m_showInitialMsg = m_config.showHelpValue(); m_opacity = m_config.contrastOpacityValue(); @@ -73,36 +90,33 @@ CaptureWidget::CaptureWidget(const uint id, const QString &savePath, #ifdef Q_OS_WIN // Top left of the whole set of screens - QPoint topLeft(0,0); + QPoint topLeft(0, 0); #endif if (fullScreen) { // Grab Screenshot bool ok = true; m_context.screenshot = ScreenGrabber().grabEntireDesktop(ok); - if(!ok) { + if (!ok) { SystemNotification().sendMessage(tr("Unable to capture screen")); this->close(); } m_context.origScreenshot = m_context.screenshot; #ifdef Q_OS_WIN - setWindowFlags(Qt::WindowStaysOnTopHint - | Qt::FramelessWindowHint - | Qt::Popup); + setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | + Qt::Popup); - for (QScreen *const screen : QGuiApplication::screens()) { + for (QScreen* const screen : QGuiApplication::screens()) { QPoint topLeftScreen = screen->geometry().topLeft(); if (topLeft.x() > topLeftScreen.x() || - topLeft.y() > topLeftScreen.y()) { + topLeft.y() > topLeftScreen.y()) { topLeft = topLeftScreen; } } move(topLeft); #else - setWindowFlags(Qt::BypassWindowManagerHint - | Qt::WindowStaysOnTopHint - | Qt::FramelessWindowHint - | Qt::Tool); + setWindowFlags(Qt::BypassWindowManagerHint | Qt::WindowStaysOnTopHint | + Qt::FramelessWindowHint | Qt::Tool); #endif resize(pixmap().size()); } @@ -111,7 +125,7 @@ CaptureWidget::CaptureWidget(const uint id, const QString &savePath, updateButtons(); QVector areas; if (m_context.fullscreen) { - for (QScreen *const screen : QGuiApplication::screens()) { + for (QScreen* const screen : QGuiApplication::screens()) { QRect r = screen->geometry(); #ifdef Q_OS_WIN r.moveTo(r.topLeft() - topLeft); @@ -129,20 +143,24 @@ CaptureWidget::CaptureWidget(const uint id, const QString &savePath, // Init color picker m_colorPicker = new ColorPicker(this); - connect(m_colorPicker, &ColorPicker::colorSelected, - this, &CaptureWidget::setDrawColor); + connect(m_colorPicker, + &ColorPicker::colorSelected, + this, + &CaptureWidget::setDrawColor); m_colorPicker->hide(); // Init notification widget m_notifierBox = new NotifierBox(this); m_notifierBox->hide(); - connect(&m_undoStack, &QUndoStack::indexChanged, - this, [this](int){ this->update(); }); + connect(&m_undoStack, &QUndoStack::indexChanged, this, [this](int) { + this->update(); + }); initPanel(); } -CaptureWidget::~CaptureWidget() { +CaptureWidget::~CaptureWidget() +{ if (m_captureDone) { emit captureTaken(m_id, this->pixmap()); } else { @@ -153,13 +171,14 @@ CaptureWidget::~CaptureWidget() { // redefineButtons retrieves the buttons configured to be shown with the // selection in the capture -void CaptureWidget::updateButtons() { +void CaptureWidget::updateButtons() +{ m_uiColor = m_config.uiMainColorValue(); m_contrastUiColor = m_config.uiContrastColorValue(); QVector vectorButtons; - for (const CaptureButton::ButtonType &t: m_config.getButtons()) { - CaptureButton *b = new CaptureButton(t, this); + for (const CaptureButton::ButtonType& t : m_config.getButtons()) { + CaptureButton* b = new CaptureButton(t, this); if (t == CaptureButton::TYPE_SELECTIONINDICATOR) { m_sizeIndButton = b; } @@ -168,37 +187,44 @@ void CaptureWidget::updateButtons() { makeChild(b); switch (t) { - case CaptureButton::ButtonType::TYPE_EXIT: - case CaptureButton::ButtonType::TYPE_SAVE: - case CaptureButton::ButtonType::TYPE_COPY: - case CaptureButton::ButtonType::TYPE_UNDO: - case CaptureButton::ButtonType::TYPE_REDO: - case CaptureButton::ButtonType::TYPE_IMAGEUPLOADER: - // nothing to do, just skip non-dynamic buttons with existing hard coded slots - break; - default: - // Set shortcuts for a tool - QString shortcut = ConfigHandler().shortcut(QVariant::fromValue(t).toString()); - if( !shortcut.isNull() ){ - QShortcut *key = new QShortcut(QKeySequence(shortcut), this); - CaptureWidget *captureWidget = this; - connect(key, &QShortcut::activated, this, [=]() { - emit captureWidget->setState(b); - }); - } - break; + case CaptureButton::ButtonType::TYPE_EXIT: + case CaptureButton::ButtonType::TYPE_SAVE: + case CaptureButton::ButtonType::TYPE_COPY: + case CaptureButton::ButtonType::TYPE_UNDO: + case CaptureButton::ButtonType::TYPE_REDO: + case CaptureButton::ButtonType::TYPE_IMAGEUPLOADER: + // nothing to do, just skip non-dynamic buttons with existing + // hard coded slots + break; + default: + // Set shortcuts for a tool + QString shortcut = + ConfigHandler().shortcut(QVariant::fromValue(t).toString()); + if (!shortcut.isNull()) { + QShortcut* key = + new QShortcut(QKeySequence(shortcut), this); + CaptureWidget* captureWidget = this; + connect(key, &QShortcut::activated, this, [=]() { + emit captureWidget->setState(b); + }); + } + break; } - connect(b, &CaptureButton::pressedButton, this, &CaptureWidget::setState); - connect(b->tool(), &CaptureTool::requestAction, - this, &CaptureWidget::handleButtonSignal); + connect( + b, &CaptureButton::pressedButton, this, &CaptureWidget::setState); + connect(b->tool(), + &CaptureTool::requestAction, + this, + &CaptureWidget::handleButtonSignal); vectorButtons << b; } m_buttonHandler->setButtons(vectorButtons); } -QPixmap CaptureWidget::pixmap() { +QPixmap CaptureWidget::pixmap() +{ QPixmap p; if (m_toolWidget && m_activeTool) { p = m_context.selectedScreenshotArea().copy(); @@ -210,11 +236,11 @@ QPixmap CaptureWidget::pixmap() { return m_context.selectedScreenshotArea(); } -void CaptureWidget::deleteToolwidgetOrClose() { - if(m_panel->isVisible()){ +void CaptureWidget::deleteToolwidgetOrClose() +{ + if (m_panel->isVisible()) { m_panel->hide(); - } - else if (m_toolWidget) { + } else if (m_toolWidget) { m_toolWidget->deleteLater(); m_toolWidget = nullptr; } else { @@ -222,7 +248,8 @@ void CaptureWidget::deleteToolwidgetOrClose() { } } -void CaptureWidget::paintEvent(QPaintEvent *) { +void CaptureWidget::paintEvent(QPaintEvent*) +{ QPainter painter(this); painter.drawPixmap(0, 0, m_context.screenshot); @@ -231,8 +258,7 @@ void CaptureWidget::paintEvent(QPaintEvent *) { m_activeTool->process(painter, m_context.screenshot); painter.restore(); } else if (m_activeButton && m_activeButton->tool()->showMousePreview() && - m_previewEnabled) - { + m_previewEnabled) { painter.save(); m_activeButton->tool()->paintMousePreview(painter, m_context); painter.restore(); @@ -255,14 +281,16 @@ void CaptureWidget::paintEvent(QPaintEvent *) { QRect helpRect = QGuiApplication::primaryScreen()->geometry(); helpRect.moveTo(mapFromGlobal(helpRect.topLeft())); - QString helpTxt = tr("Select an area with the mouse, or press Esc to exit." - "\nPress Enter to capture the screen." - "\nPress Right Click to show the color picker." - "\nUse the Mouse Wheel to change the thickness of your tool." - "\nPress Space to open the side panel."); + QString helpTxt = + tr("Select an area with the mouse, or press Esc to exit." + "\nPress Enter to capture the screen." + "\nPress Right Click to show the color picker." + "\nUse the Mouse Wheel to change the thickness of your tool." + "\nPress Space to open the side panel."); // We draw the white contrasting background for the text, using the - //same text and options to get the boundingRect that the text will have. + // same text and options to get the boundingRect that the text will + // have. QRectF bRect = painter.boundingRect(helpRect, Qt::AlignCenter, helpTxt); // These four calls provide padding for the rect @@ -274,8 +302,8 @@ void CaptureWidget::paintEvent(QPaintEvent *) { QColor rectColor(m_uiColor); rectColor.setAlpha(180); - QColor textColor((ColorUtils::colorIsDark(rectColor) ? - Qt::white : Qt::black)); + QColor textColor( + (ColorUtils::colorIsDark(rectColor) ? Qt::white : Qt::black)); painter.setBrush(QBrush(rectColor, Qt::SolidPattern)); painter.setPen(QPen(textColor)); @@ -289,13 +317,14 @@ void CaptureWidget::paintEvent(QPaintEvent *) { painter.setPen(m_uiColor); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(m_uiColor); - for(auto r: m_selection->handlerAreas()) { + for (auto r : m_selection->handlerAreas()) { painter.drawRoundRect(r, 100, 100); } } } -void CaptureWidget::mousePressEvent(QMouseEvent *e) { +void CaptureWidget::mousePressEvent(QMouseEvent* e) +{ if (e->button() == Qt::RightButton) { m_rightClick = true; m_colorPicker->move(e->pos().x() - m_colorPicker->width() / 2, @@ -320,12 +349,18 @@ void CaptureWidget::mousePressEvent(QMouseEvent *e) { } m_activeTool = m_activeButton->tool()->copy(this); - connect(this, &CaptureWidget::colorChanged, - m_activeTool, &CaptureTool::colorChanged); - connect(this, &CaptureWidget::thicknessChanged, - m_activeTool, &CaptureTool::thicknessChanged); - connect(m_activeTool, &CaptureTool::requestAction, - this, &CaptureWidget::handleButtonSignal); + connect(this, + &CaptureWidget::colorChanged, + m_activeTool, + &CaptureTool::colorChanged); + connect(this, + &CaptureWidget::thicknessChanged, + m_activeTool, + &CaptureTool::thicknessChanged); + connect(m_activeTool, + &CaptureTool::requestAction, + this, + &CaptureWidget::handleButtonSignal); m_activeTool->drawStart(m_context); return; } @@ -334,8 +369,7 @@ void CaptureWidget::mousePressEvent(QMouseEvent *e) { m_selection->saveGeometry(); // New selection if (!m_selection->geometry().contains(e->pos()) && - m_mouseOverHandle == SelectionWidget::NO_SIDE) - { + m_mouseOverHandle == SelectionWidget::NO_SIDE) { m_selection->setGeometry(QRect(e->pos(), e->pos())); m_selection->setVisible(false); m_newSelection = true; @@ -348,7 +382,8 @@ void CaptureWidget::mousePressEvent(QMouseEvent *e) { updateCursor(); } -void CaptureWidget::mouseMoveEvent(QMouseEvent *e) { +void CaptureWidget::mouseMoveEvent(QMouseEvent* e) +{ m_context.mousePos = e->pos(); if (m_mouseIsClicked && !m_activeButton) { @@ -358,12 +393,13 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent *e) { if (m_newSelection) { m_selection->setVisible(true); m_selection->setGeometry( - QRect(m_dragStartPoint, m_context.mousePos).normalized()); + QRect(m_dragStartPoint, m_context.mousePos).normalized()); update(); } else if (m_mouseOverHandle == SelectionWidget::NO_SIDE) { // Moving the whole selection QRect initialRect = m_selection->savedGeometry().normalized(); - QPoint newTopLeft = initialRect.topLeft() + (e->pos() - m_dragStartPoint); + QPoint newTopLeft = + initialRect.topLeft() + (e->pos() - m_dragStartPoint); QRect finalRect(newTopLeft, initialRect.size()); if (finalRect.left() < rect().left()) { @@ -376,7 +412,8 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent *e) { } else if (finalRect.bottom() > rect().bottom()) { finalRect.setBottom(rect().bottom()); } - m_selection->setGeometry(finalRect.normalized().intersected(rect())); + m_selection->setGeometry( + finalRect.normalized().intersected(rect())); update(); } else { // Dragging a handle @@ -385,37 +422,37 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent *e) { bool symmetryMod = qApp->keyboardModifiers() & Qt::ShiftModifier; using sw = SelectionWidget; - if (m_mouseOverHandle == sw::TOPLEFT_SIDE - || m_mouseOverHandle == sw::TOP_SIDE - || m_mouseOverHandle == sw::TOPRIGHT_SIDE) - { // dragging one of the top handles + if (m_mouseOverHandle == sw::TOPLEFT_SIDE || + m_mouseOverHandle == sw::TOP_SIDE || + m_mouseOverHandle == + sw::TOPRIGHT_SIDE) { // dragging one of the top handles r.setTop(r.top() + offset.y()); if (symmetryMod) { r.setBottom(r.bottom() - offset.y()); } } - if (m_mouseOverHandle == sw::TOPLEFT_SIDE - || m_mouseOverHandle == sw::LEFT_SIDE - || m_mouseOverHandle == sw::BOTTONLEFT_SIDE) - { // dragging one of the left handles + if (m_mouseOverHandle == sw::TOPLEFT_SIDE || + m_mouseOverHandle == sw::LEFT_SIDE || + m_mouseOverHandle == + sw::BOTTONLEFT_SIDE) { // dragging one of the left handles r.setLeft(r.left() + offset.x()); if (symmetryMod) { r.setRight(r.right() - offset.x()); } } - if (m_mouseOverHandle == sw::BOTTONLEFT_SIDE - || m_mouseOverHandle == sw::BOTTON_SIDE - || m_mouseOverHandle == sw::BOTTONRIGHT_SIDE) - { // dragging one of the bottom handles + if (m_mouseOverHandle == sw::BOTTONLEFT_SIDE || + m_mouseOverHandle == sw::BOTTON_SIDE || + m_mouseOverHandle == + sw::BOTTONRIGHT_SIDE) { // dragging one of the bottom handles r.setBottom(r.bottom() + offset.y()); if (symmetryMod) { r.setTop(r.top() - offset.y()); } } - if (m_mouseOverHandle == sw::TOPRIGHT_SIDE - || m_mouseOverHandle == sw::RIGHT_SIDE - || m_mouseOverHandle == sw::BOTTONRIGHT_SIDE) - { // dragging one of the right handles + if (m_mouseOverHandle == sw::TOPRIGHT_SIDE || + m_mouseOverHandle == sw::RIGHT_SIDE || + m_mouseOverHandle == + sw::BOTTONRIGHT_SIDE) { // dragging one of the right handles r.setRight(r.right() + offset.x()); if (symmetryMod) { r.setLeft(r.left() - offset.x()); @@ -432,9 +469,11 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent *e) { m_activeTool->drawMove(e->pos()); } update(); - // Hides the buttons under the mouse. If the mouse leaves, it shows them. + // Hides the buttons under the mouse. If the mouse leaves, it shows + // them. if (m_buttonHandler->buttonsAreInside()) { - const bool containsMouse = m_buttonHandler->contains(m_context.mousePos); + const bool containsMouse = + m_buttonHandler->contains(m_context.mousePos); if (containsMouse) { m_buttonHandler->hide(); } else { @@ -452,20 +491,21 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent *e) { } } -void CaptureWidget::mouseReleaseEvent(QMouseEvent *e) { +void CaptureWidget::mouseReleaseEvent(QMouseEvent* e) +{ if (e->button() == Qt::RightButton || m_colorPicker->isVisible()) { m_colorPicker->hide(); m_rightClick = false; - if(!m_context.color.isValid()) { + if (!m_context.color.isValid()) { m_panel->show(); } - // when we end the drawing we have to register the last point and - //add the temp modification to the list of modifications + // when we end the drawing we have to register the last point and + // add the temp modification to the list of modifications } else if (m_mouseIsClicked && m_activeTool) { m_activeTool->drawEnd(m_context.mousePos); if (m_activeTool->isValid()) { pushToolToStack(); - } else if (!m_toolWidget){ + } else if (!m_toolWidget) { m_activeTool->deleteLater(); m_activeTool = nullptr; } @@ -500,7 +540,8 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent *e) { updateCursor(); } -void CaptureWidget::leftMove() { +void CaptureWidget::leftMove() +{ if (m_selection->geometry().left() > rect().left()) { m_selection->move(QPoint(m_selection->x() - 1, m_selection->y())); m_buttonHandler->updatePosition(m_selection->geometry()); @@ -508,9 +549,10 @@ void CaptureWidget::leftMove() { } } -void CaptureWidget::rightMove() { +void CaptureWidget::rightMove() +{ if (m_selection->geometry().right() < rect().right()) { - m_selection->move(QPoint(m_selection->x() +1, m_selection->y())); + m_selection->move(QPoint(m_selection->x() + 1, m_selection->y())); QRect newGeometry = m_selection->geometry().intersected(rect()); m_context.selection = extendedRect(&newGeometry); m_buttonHandler->updatePosition(m_selection->geometry()); @@ -518,9 +560,10 @@ void CaptureWidget::rightMove() { } } -void CaptureWidget::upMove() { +void CaptureWidget::upMove() +{ if (m_selection->geometry().top() > rect().top()) { - m_selection->move(QPoint(m_selection->x(), m_selection->y() -1)); + m_selection->move(QPoint(m_selection->x(), m_selection->y() - 1)); QRect newGeometry = m_selection->geometry().intersected(rect()); m_context.selection = extendedRect(&newGeometry); m_buttonHandler->updatePosition(m_selection->geometry()); @@ -528,9 +571,10 @@ void CaptureWidget::upMove() { } } -void CaptureWidget::downMove() { +void CaptureWidget::downMove() +{ if (m_selection->geometry().bottom() < rect().bottom()) { - m_selection->move(QPoint(m_selection->x(), m_selection->y() +1)); + m_selection->move(QPoint(m_selection->x(), m_selection->y() + 1)); QRect newGeometry = m_selection->geometry().intersected(rect()); m_context.selection = extendedRect(&newGeometry); m_buttonHandler->updatePosition(m_selection->geometry()); @@ -538,30 +582,35 @@ void CaptureWidget::downMove() { } } - -void CaptureWidget::keyPressEvent(QKeyEvent *e) { +void CaptureWidget::keyPressEvent(QKeyEvent* e) +{ if (!m_selection->isVisible()) { return; } else if (e->key() == Qt::Key_Control) { m_adjustmentButtonPressed = true; } else if (e->key() == Qt::Key_Enter) { // Make no difference for Return and Enter keys - QKeyEvent * keyReturn = new QKeyEvent (QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); - QCoreApplication::postEvent (this, keyReturn); + QKeyEvent* keyReturn = + new QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); + QCoreApplication::postEvent(this, keyReturn); } } -void CaptureWidget::keyReleaseEvent(QKeyEvent *e) { +void CaptureWidget::keyReleaseEvent(QKeyEvent* e) +{ if (e->key() == Qt::Key_Control) { m_adjustmentButtonPressed = false; } } -void CaptureWidget::wheelEvent(QWheelEvent *e) { +void CaptureWidget::wheelEvent(QWheelEvent* e) +{ m_context.thickness += e->delta() / 120; m_context.thickness = qBound(0, m_context.thickness, 100); - QPoint topLeft = qApp->desktop()->screenGeometry( - qApp->desktop()->screenNumber(QCursor::pos())).topLeft(); + QPoint topLeft = + qApp->desktop() + ->screenGeometry(qApp->desktop()->screenNumber(QCursor::pos())) + .topLeft(); int offset = m_notifierBox->width() / 4; m_notifierBox->move(mapFromGlobal(topLeft) + QPoint(offset, offset)); m_notifierBox->showMessage(QString::number(m_context.thickness)); @@ -571,32 +620,36 @@ void CaptureWidget::wheelEvent(QWheelEvent *e) { emit thicknessChanged(m_context.thickness); } -void CaptureWidget::resizeEvent(QResizeEvent *e) { +void CaptureWidget::resizeEvent(QResizeEvent* e) +{ QWidget::resizeEvent(e); m_context.widgetDimensions = rect(); - m_context.widgetOffset = mapToGlobal(QPoint(0,0)); + m_context.widgetOffset = mapToGlobal(QPoint(0, 0)); m_panel->setFixedHeight(height()); if (!m_context.fullscreen) { m_buttonHandler->updateScreenRegions(rect()); } } -void CaptureWidget::moveEvent(QMoveEvent *e) { +void CaptureWidget::moveEvent(QMoveEvent* e) +{ QWidget::moveEvent(e); - m_context.widgetOffset = mapToGlobal(QPoint(0,0)); + m_context.widgetOffset = mapToGlobal(QPoint(0, 0)); } -void CaptureWidget::initContext(const QString &savePath, bool fullscreen) { +void CaptureWidget::initContext(const QString& savePath, bool fullscreen) +{ m_context.widgetDimensions = rect(); m_context.color = m_config.drawColorValue(); m_context.savePath = savePath; - m_context.widgetOffset = mapToGlobal(QPoint(0,0)); - m_context.mousePos= mapFromGlobal(QCursor::pos()); + m_context.widgetOffset = mapToGlobal(QPoint(0, 0)); + m_context.mousePos = mapFromGlobal(QCursor::pos()); m_context.thickness = m_config.drawThicknessValue(); m_context.fullscreen = fullscreen; } -void CaptureWidget::initPanel() { +void CaptureWidget::initPanel() +{ m_panel = new UtilityPanel(this); makeChild(m_panel); QRect panelRect = rect(); @@ -607,34 +660,43 @@ void CaptureWidget::initPanel() { panelRect.setWidth(m_colorPicker->width() * 1.5); m_panel->setGeometry(panelRect); - SidePanelWidget *sidePanel = - new SidePanelWidget(&m_context.screenshot); - connect(sidePanel, &SidePanelWidget::colorChanged, - this, &CaptureWidget::setDrawColor); - connect(sidePanel, &SidePanelWidget::thicknessChanged, - this, &CaptureWidget::setDrawThickness); - connect(this, &CaptureWidget::colorChanged, - sidePanel, &SidePanelWidget::updateColor); - connect(this, &CaptureWidget::thicknessChanged, - sidePanel, &SidePanelWidget::updateThickness); - connect(sidePanel, &SidePanelWidget::togglePanel, - m_panel, &UtilityPanel::toggle); + SidePanelWidget* sidePanel = new SidePanelWidget(&m_context.screenshot); + connect(sidePanel, + &SidePanelWidget::colorChanged, + this, + &CaptureWidget::setDrawColor); + connect(sidePanel, + &SidePanelWidget::thicknessChanged, + this, + &CaptureWidget::setDrawThickness); + connect(this, + &CaptureWidget::colorChanged, + sidePanel, + &SidePanelWidget::updateColor); + connect(this, + &CaptureWidget::thicknessChanged, + sidePanel, + &SidePanelWidget::updateThickness); + connect( + sidePanel, &SidePanelWidget::togglePanel, m_panel, &UtilityPanel::toggle); sidePanel->colorChanged(m_context.color); sidePanel->thicknessChanged(m_context.thickness); m_panel->pushWidget(sidePanel); m_panel->pushWidget(new QUndoView(&m_undoStack, this)); } -void CaptureWidget::initSelection() { +void CaptureWidget::initSelection() +{ m_selection = new SelectionWidget(m_uiColor, this); - connect(m_selection, &SelectionWidget::animationEnded, this, [this](){ + connect(m_selection, &SelectionWidget::animationEnded, this, [this]() { this->m_buttonHandler->updatePosition(this->m_selection->geometry()); }); m_selection->setVisible(false); m_selection->setGeometry(QRect()); } -void CaptureWidget::setState(CaptureButton *b) { +void CaptureWidget::setState(CaptureButton* b) +{ if (!b) { return; } @@ -654,7 +716,7 @@ void CaptureWidget::setState(CaptureButton *b) { if (b->tool()->isSelectable()) { if (m_activeButton != b) { - QWidget *confW = b->tool()->configurationWidget(); + QWidget* confW = b->tool()->configurationWidget(); m_panel->addToolWidget(confW); if (m_activeButton) { m_activeButton->setColor(m_uiColor); @@ -671,7 +733,8 @@ void CaptureWidget::setState(CaptureButton *b) { } } -void CaptureWidget::processTool(CaptureTool *t) { +void CaptureWidget::processTool(CaptureTool* t) +{ auto backup = m_activeTool; // The tool is active during the pressed(). m_activeTool = t; @@ -679,102 +742,108 @@ void CaptureWidget::processTool(CaptureTool *t) { m_activeTool = backup; } -void CaptureWidget::handleButtonSignal(CaptureTool::Request r) { +void CaptureWidget::handleButtonSignal(CaptureTool::Request r) +{ switch (r) { - case CaptureTool::REQ_CLEAR_MODIFICATIONS: - m_undoStack.setIndex(0); - update(); - break; - case CaptureTool::REQ_CLOSE_GUI: - close(); - break; - case CaptureTool::REQ_HIDE_GUI: - hide(); - break; - case CaptureTool::REQ_HIDE_SELECTION: - m_newSelection = true; - m_selection->setVisible(false); - updateCursor(); - break; - case CaptureTool::REQ_SELECT_ALL: - m_selection->setGeometryAnimated(rect()); - break; - case CaptureTool::REQ_UNDO_MODIFICATION: - m_undoStack.undo(); - break; - case CaptureTool::REQ_REDO_MODIFICATION: - m_undoStack.redo(); - break; - case CaptureTool::REQ_REDRAW: - update(); - break; - case CaptureTool::REQ_TOGGLE_SIDEBAR: - m_panel->toggle(); - break; - case CaptureTool::REQ_SHOW_COLOR_PICKER: - break; - case CaptureTool::REQ_MOVE_MODE: - setState(m_activeButton); // Disable the actual button - break; - case CaptureTool::REQ_CAPTURE_DONE_OK: - m_captureDone = true; - break; - case CaptureTool::REQ_ADD_CHILD_WIDGET: - if (!m_activeTool) { + case CaptureTool::REQ_CLEAR_MODIFICATIONS: + m_undoStack.setIndex(0); + update(); break; - } - if (m_toolWidget) { - m_toolWidget->deleteLater(); - } - m_toolWidget = m_activeTool->widget(); - if (m_toolWidget) { - makeChild(m_toolWidget); - m_toolWidget->move(m_context.mousePos); - m_toolWidget->show(); - m_toolWidget->setFocus(); - } - break; - case CaptureTool::REQ_ADD_CHILD_WINDOW: - if (!m_activeTool) { + case CaptureTool::REQ_CLOSE_GUI: + close(); break; - } else { - QWidget *w = m_activeTool->widget(); - connect(this, &CaptureWidget::destroyed, w, &QWidget::deleteLater); - w->show(); - } - break; - case CaptureTool::REQ_ADD_EXTERNAL_WIDGETS: - if (!m_activeTool) { + case CaptureTool::REQ_HIDE_GUI: + hide(); + break; + case CaptureTool::REQ_HIDE_SELECTION: + m_newSelection = true; + m_selection->setVisible(false); + updateCursor(); + break; + case CaptureTool::REQ_SELECT_ALL: + m_selection->setGeometryAnimated(rect()); + break; + case CaptureTool::REQ_UNDO_MODIFICATION: + m_undoStack.undo(); + break; + case CaptureTool::REQ_REDO_MODIFICATION: + m_undoStack.redo(); + break; + case CaptureTool::REQ_REDRAW: + update(); + break; + case CaptureTool::REQ_TOGGLE_SIDEBAR: + m_panel->toggle(); + break; + case CaptureTool::REQ_SHOW_COLOR_PICKER: + break; + case CaptureTool::REQ_MOVE_MODE: + setState(m_activeButton); // Disable the actual button + break; + case CaptureTool::REQ_CAPTURE_DONE_OK: + m_captureDone = true; + break; + case CaptureTool::REQ_ADD_CHILD_WIDGET: + if (!m_activeTool) { + break; + } + if (m_toolWidget) { + m_toolWidget->deleteLater(); + } + m_toolWidget = m_activeTool->widget(); + if (m_toolWidget) { + makeChild(m_toolWidget); + m_toolWidget->move(m_context.mousePos); + m_toolWidget->show(); + m_toolWidget->setFocus(); + } + break; + case CaptureTool::REQ_ADD_CHILD_WINDOW: + if (!m_activeTool) { + break; + } else { + QWidget* w = m_activeTool->widget(); + connect( + this, &CaptureWidget::destroyed, w, &QWidget::deleteLater); + w->show(); + } + break; + case CaptureTool::REQ_ADD_EXTERNAL_WIDGETS: + if (!m_activeTool) { + break; + } else { + QWidget* w = m_activeTool->widget(); + w->setAttribute(Qt::WA_DeleteOnClose); + w->show(); + } + break; + default: break; - } else { - QWidget *w = m_activeTool->widget(); - w->setAttribute(Qt::WA_DeleteOnClose); - w->show(); - } - break; - default: - break; } } -void CaptureWidget::setDrawColor(const QColor &c) { +void CaptureWidget::setDrawColor(const QColor& c) +{ m_context.color = c; - if(m_context.color.isValid()) { + if (m_context.color.isValid()) { ConfigHandler().setDrawColor(m_context.color); emit colorChanged(c); } } -void CaptureWidget::setDrawThickness(const int &t) +void CaptureWidget::setDrawThickness(const int& t) { m_context.thickness = qBound(0, t, 100); ConfigHandler().setdrawThickness(m_context.thickness); emit thicknessChanged(m_context.thickness); } -void CaptureWidget::leftResize() { - if (m_selection->isVisible() && m_selection->geometry().right() > m_selection->geometry().left()) { - m_selection->setGeometry(m_selection->geometry() + QMargins(0, 0, -1, 0)); +void CaptureWidget::leftResize() +{ + if (m_selection->isVisible() && + m_selection->geometry().right() > m_selection->geometry().left()) { + m_selection->setGeometry(m_selection->geometry() + + QMargins(0, 0, -1, 0)); QRect newGeometry = m_selection->geometry().intersected(rect()); m_context.selection = extendedRect(&newGeometry); m_buttonHandler->updatePosition(m_selection->geometry()); @@ -783,9 +852,12 @@ void CaptureWidget::leftResize() { } } -void CaptureWidget::rightResize() { - if (m_selection->isVisible() && m_selection->geometry().right() < rect().right()) { - m_selection->setGeometry(m_selection->geometry() + QMargins(0, 0, 1, 0)); +void CaptureWidget::rightResize() +{ + if (m_selection->isVisible() && + m_selection->geometry().right() < rect().right()) { + m_selection->setGeometry(m_selection->geometry() + + QMargins(0, 0, 1, 0)); QRect newGeometry = m_selection->geometry().intersected(rect()); m_context.selection = extendedRect(&newGeometry); m_buttonHandler->updatePosition(m_selection->geometry()); @@ -794,9 +866,12 @@ void CaptureWidget::rightResize() { } } -void CaptureWidget::upResize() { - if (m_selection->isVisible() && m_selection->geometry().bottom() > m_selection->geometry().top()) { - m_selection->setGeometry(m_selection->geometry() + QMargins(0, 0, 0, -1)); +void CaptureWidget::upResize() +{ + if (m_selection->isVisible() && + m_selection->geometry().bottom() > m_selection->geometry().top()) { + m_selection->setGeometry(m_selection->geometry() + + QMargins(0, 0, 0, -1)); QRect newGeometry = m_selection->geometry().intersected(rect()); m_context.selection = extendedRect(&newGeometry); m_buttonHandler->updatePosition(m_selection->geometry()); @@ -805,9 +880,12 @@ void CaptureWidget::upResize() { } } -void CaptureWidget::downResize() { - if (m_selection->isVisible() && m_selection->geometry().bottom() < rect().bottom()) { - m_selection->setGeometry(m_selection->geometry() + QMargins(0, 0, 0, 1)); +void CaptureWidget::downResize() +{ + if (m_selection->isVisible() && + m_selection->geometry().bottom() < rect().bottom()) { + m_selection->setGeometry(m_selection->geometry() + + QMargins(0, 0, 0, 1)); QRect newGeometry = m_selection->geometry().intersected(rect()); m_context.selection = extendedRect(&newGeometry); m_buttonHandler->updatePosition(m_selection->geometry()); @@ -816,77 +894,108 @@ void CaptureWidget::downResize() { } } -void CaptureWidget::initShortcuts() { - QString shortcut = ConfigHandler().shortcut(QVariant::fromValue(CaptureButton::ButtonType::TYPE_EXIT).toString()); +void CaptureWidget::initShortcuts() +{ + QString shortcut = ConfigHandler().shortcut( + QVariant::fromValue(CaptureButton::ButtonType::TYPE_EXIT).toString()); new QShortcut(QKeySequence(shortcut), this, SLOT(close())); - shortcut = ConfigHandler().shortcut(QVariant::fromValue(CaptureButton::ButtonType::TYPE_SAVE).toString()); + shortcut = ConfigHandler().shortcut( + QVariant::fromValue(CaptureButton::ButtonType::TYPE_SAVE).toString()); new QShortcut(QKeySequence(shortcut), this, SLOT(saveScreenshot())); - shortcut = ConfigHandler().shortcut(QVariant::fromValue(CaptureButton::ButtonType::TYPE_COPY).toString()); + shortcut = ConfigHandler().shortcut( + QVariant::fromValue(CaptureButton::ButtonType::TYPE_COPY).toString()); new QShortcut(QKeySequence(shortcut), this, SLOT(copyScreenshot())); - shortcut = ConfigHandler().shortcut(QVariant::fromValue(CaptureButton::ButtonType::TYPE_UNDO).toString()); + shortcut = ConfigHandler().shortcut( + QVariant::fromValue(CaptureButton::ButtonType::TYPE_UNDO).toString()); new QShortcut(QKeySequence(shortcut), this, SLOT(undo())); - shortcut = ConfigHandler().shortcut(QVariant::fromValue(CaptureButton::ButtonType::TYPE_REDO).toString()); + shortcut = ConfigHandler().shortcut( + QVariant::fromValue(CaptureButton::ButtonType::TYPE_REDO).toString()); new QShortcut(QKeySequence(shortcut), this, SLOT(redo())); - shortcut = ConfigHandler().shortcut(QVariant::fromValue(CaptureButton::ButtonType::TYPE_IMAGEUPLOADER).toString()); + shortcut = ConfigHandler().shortcut( + QVariant::fromValue(CaptureButton::ButtonType::TYPE_IMAGEUPLOADER) + .toString()); new QShortcut(shortcut, this, SLOT(uploadScreenshot())); - new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_TOGGLE_PANEL")), this, SLOT(togglePanel())); + new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_TOGGLE_PANEL")), + this, + SLOT(togglePanel())); - new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_LEFT")), this, SLOT(leftResize())); - new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_RIGHT")), this, SLOT(rightResize())); - new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_UP")), this, SLOT(upResize())); - new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_DOWN")), this, SLOT(downResize())); + new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_LEFT")), + this, + SLOT(leftResize())); + new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_RIGHT")), + this, + SLOT(rightResize())); + new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_UP")), + this, + SLOT(upResize())); + new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_DOWN")), + this, + SLOT(downResize())); - new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_LEFT")), this, SLOT(leftMove())); - new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_RIGHT")), this, SLOT(rightMove())); - new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_UP")), this, SLOT(upMove())); - new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_DOWN")), this, SLOT(downMove())); + new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_LEFT")), + this, + SLOT(leftMove())); + new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_RIGHT")), + this, + SLOT(rightMove())); + new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_UP")), + this, + SLOT(upMove())); + new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_DOWN")), + this, + SLOT(downMove())); new QShortcut(Qt::Key_Escape, this, SLOT(deleteToolwidgetOrClose())); } -void CaptureWidget::updateSizeIndicator() { - if (m_sizeIndButton){ - const QRect &selection = extendedSelection(); +void CaptureWidget::updateSizeIndicator() +{ + if (m_sizeIndButton) { + const QRect& selection = extendedSelection(); m_sizeIndButton->setText(QStringLiteral("%1\n%2") - .arg(selection.width()) - .arg(selection.height())); + .arg(selection.width()) + .arg(selection.height())); } } -void CaptureWidget::updateCursor() { +void CaptureWidget::updateCursor() +{ if (m_rightClick) { setCursor(Qt::ArrowCursor); } else if (m_grabbing) { setCursor(Qt::ClosedHandCursor); } else if (!m_activeButton) { using sw = SelectionWidget; - if (m_mouseOverHandle != sw::NO_SIDE){ + if (m_mouseOverHandle != sw::NO_SIDE) { // cursor on the handlers switch (m_mouseOverHandle) { - case sw::TOPLEFT_SIDE: case sw::BOTTONRIGHT_SIDE: - setCursor(Qt::SizeFDiagCursor); - break; - case sw::TOPRIGHT_SIDE: case sw::BOTTONLEFT_SIDE: - setCursor(Qt::SizeBDiagCursor); - break; - case sw::LEFT_SIDE: case sw::RIGHT_SIDE: - setCursor(Qt::SizeHorCursor); - break; - case sw::TOP_SIDE: case sw::BOTTON_SIDE: - setCursor(Qt::SizeVerCursor); - break; - default: - break; + case sw::TOPLEFT_SIDE: + case sw::BOTTONRIGHT_SIDE: + setCursor(Qt::SizeFDiagCursor); + break; + case sw::TOPRIGHT_SIDE: + case sw::BOTTONLEFT_SIDE: + setCursor(Qt::SizeBDiagCursor); + break; + case sw::LEFT_SIDE: + case sw::RIGHT_SIDE: + setCursor(Qt::SizeHorCursor); + break; + case sw::TOP_SIDE: + case sw::BOTTON_SIDE: + setCursor(Qt::SizeVerCursor); + break; + default: + break; } } else if (m_selection->isVisible() && - m_selection->geometry().contains(m_context.mousePos)) - { + m_selection->geometry().contains(m_context.mousePos)) { setCursor(Qt::OpenHandCursor); } else { setCursor(Qt::CrossCursor); @@ -896,13 +1005,17 @@ void CaptureWidget::updateCursor() { } } -void CaptureWidget::pushToolToStack() { - auto mod = new ModificationCommand( - &m_context.screenshot, m_activeTool); - disconnect(this, &CaptureWidget::colorChanged, - m_activeTool, &CaptureTool::colorChanged); - disconnect(this, &CaptureWidget::thicknessChanged, - m_activeTool, &CaptureTool::thicknessChanged); +void CaptureWidget::pushToolToStack() +{ + auto mod = new ModificationCommand(&m_context.screenshot, m_activeTool); + disconnect(this, + &CaptureWidget::colorChanged, + m_activeTool, + &CaptureTool::colorChanged); + disconnect(this, + &CaptureWidget::thicknessChanged, + m_activeTool, + &CaptureTool::thicknessChanged); if (m_panel->toolWidget()) { disconnect(m_panel->toolWidget(), nullptr, m_activeTool, nullptr); } @@ -910,39 +1023,47 @@ void CaptureWidget::pushToolToStack() { m_activeTool = nullptr; } -void CaptureWidget::makeChild(QWidget *w) { +void CaptureWidget::makeChild(QWidget* w) +{ w->setParent(this); w->installEventFilter(m_eventFilter); } -void CaptureWidget::togglePanel() { +void CaptureWidget::togglePanel() +{ m_panel->toggle(); } -void CaptureWidget::childEnter() { +void CaptureWidget::childEnter() +{ m_previewEnabled = false; update(); } -void CaptureWidget::childLeave() { +void CaptureWidget::childLeave() +{ m_previewEnabled = true; update(); } -void CaptureWidget::uploadScreenshot() { - m_activeTool = new ImgS3UploaderTool(); +void CaptureWidget::uploadScreenshot() +{ + // m_activeTool = new ImgS3UploaderTool(); + m_activeTool = new ImgurUploaderTool(); m_activeTool->setCapture(pixmap()); handleButtonSignal(CaptureTool::REQ_ADD_EXTERNAL_WIDGETS); close(); } -void CaptureWidget::copyScreenshot() { +void CaptureWidget::copyScreenshot() +{ m_captureDone = true; ScreenshotSaver().saveToClipboard(pixmap()); close(); } -void CaptureWidget::saveScreenshot() { +void CaptureWidget::saveScreenshot() +{ m_captureDone = true; hide(); if (m_context.savePath.isEmpty()) { @@ -953,25 +1074,29 @@ void CaptureWidget::saveScreenshot() { close(); } -void CaptureWidget::undo() { +void CaptureWidget::undo() +{ m_undoStack.undo(); } -void CaptureWidget::redo() { +void CaptureWidget::redo() +{ m_undoStack.redo(); } -QRect CaptureWidget::extendedSelection() const { +QRect CaptureWidget::extendedSelection() const +{ if (!m_selection->isVisible()) return QRect(); QRect r = m_selection->geometry(); return extendedRect(&r); } -QRect CaptureWidget::extendedRect(QRect *r) const { +QRect CaptureWidget::extendedRect(QRect* r) const +{ auto devicePixelRatio = m_context.screenshot.devicePixelRatio(); - return QRect(r->left() * devicePixelRatio, - r->top() * devicePixelRatio, - r->width() * devicePixelRatio, + return QRect(r->left() * devicePixelRatio, + r->top() * devicePixelRatio, + r->width() * devicePixelRatio, r->height() * devicePixelRatio); } diff --git a/src/widgets/historywidget.cpp b/src/widgets/historywidget.cpp index f313b543..fbfd61de 100644 --- a/src/widgets/historywidget.cpp +++ b/src/widgets/historywidget.cpp @@ -1,26 +1,28 @@ #include "historywidget.h" +#include "src/tools/storage/imgs3uploader.h" #include "src/utils/history.h" #include "src/widgets/notificationwidget.h" -#include "src/tools/imgs3/imgs3uploader.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include -HistoryWidget::HistoryWidget(QWidget *parent) : QDialog(parent) +HistoryWidget::HistoryWidget(QWidget* parent) + : QDialog(parent) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowTitle(tr("Latest Uploads")); @@ -30,46 +32,46 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QDialog(parent) m_pVBox = new QVBoxLayout(this); m_pVBox->setAlignment(Qt::AlignTop); - QScrollArea *scrollArea = new QScrollArea( this ); - scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); - scrollArea->setWidgetResizable( true ); - scrollArea->setGeometry( this->frameGeometry() ); + 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 ); + QWidget* widget = new QWidget(); + scrollArea->setWidget(widget); + widget->setLayout(m_pVBox); loadHistory(); } -void HistoryWidget::loadHistory() { +void HistoryWidget::loadHistory() +{ // read history files History history = History(); QList historyFiles = history.history(); - if(historyFiles.isEmpty()) { + if (historyFiles.isEmpty()) { setEmptyMessage(); - } - else { + } else { // generate history list - foreach(QString fileName, historyFiles) { + foreach (QString fileName, historyFiles) { addLine(history.path(), fileName); } } } -void HistoryWidget::setEmptyMessage() { - QPushButton *buttonEmpty = new QPushButton; +void HistoryWidget::setEmptyMessage() +{ + QPushButton* buttonEmpty = new QPushButton; buttonEmpty->setText(tr("Screenshots history is empty")); buttonEmpty->setMinimumSize(1, HISTORYPIXMAP_MAX_PREVIEW_HEIGHT); - connect(buttonEmpty, &QPushButton::clicked, this, [=](){ - this->close(); - }); + connect(buttonEmpty, &QPushButton::clicked, this, [=]() { this->close(); }); m_pVBox->addWidget(buttonEmpty); } -void HistoryWidget::addLine(const QString &path, const QString& fileName) { - QHBoxLayout *phbl = new QHBoxLayout(); +void HistoryWidget::addLine(const QString& path, const QString& fileName) +{ + QHBoxLayout* phbl = new QHBoxLayout(); QString fullFileName = path + fileName; History history; @@ -79,60 +81,62 @@ void HistoryWidget::addLine(const QString &path, const QString& fileName) { // load pixmap QPixmap pixmap; - pixmap.load( fullFileName, "png" ); + pixmap.load(fullFileName, "png"); - if (pixmap.height() / HISTORYPIXMAP_MAX_PREVIEW_HEIGHT >= pixmap.width() / HISTORYPIXMAP_MAX_PREVIEW_WIDTH) { + if (pixmap.height() / HISTORYPIXMAP_MAX_PREVIEW_HEIGHT >= + pixmap.width() / HISTORYPIXMAP_MAX_PREVIEW_WIDTH) { pixmap = pixmap.scaledToHeight(HISTORYPIXMAP_MAX_PREVIEW_HEIGHT); } else { pixmap = pixmap.scaledToWidth(HISTORYPIXMAP_MAX_PREVIEW_WIDTH); } // get file info - QFileInfo *pFileInfo = new QFileInfo(fullFileName); - QString lastModified = pFileInfo->lastModified().toString(" yyyy-MM-dd\nhh:mm:ss"); + QFileInfo* pFileInfo = new QFileInfo(fullFileName); + QString lastModified = + pFileInfo->lastModified().toString(" yyyy-MM-dd\nhh:mm:ss"); // screenshot preview - QLabel *pScreenshot = new QLabel(); + QLabel* pScreenshot = new QLabel(); pScreenshot->setStyleSheet("padding: 5px;"); pScreenshot->setMinimumHeight(HISTORYPIXMAP_MAX_PREVIEW_HEIGHT); pScreenshot->setPixmap(pixmap); // screenshot datetime - QLabel *pScreenshotText = new QLabel(); + QLabel* pScreenshotText = new QLabel(); pScreenshotText->setStyleSheet("padding: 5px;"); pScreenshotText->setMinimumHeight(HISTORYPIXMAP_MAX_PREVIEW_HEIGHT); pScreenshotText->setAlignment(Qt::AlignCenter); pScreenshotText->setText(lastModified); // copy url - QPushButton *buttonCopyUrl = new QPushButton; + QPushButton* buttonCopyUrl = new QPushButton; buttonCopyUrl->setText(tr("Copy URL")); buttonCopyUrl->setMinimumHeight(HISTORYPIXMAP_MAX_PREVIEW_HEIGHT); - connect(buttonCopyUrl, &QPushButton::clicked, this, [=](){ + connect(buttonCopyUrl, &QPushButton::clicked, this, [=]() { QApplication::clipboard()->setText(url); m_notification->showMessage(tr("URL copied to clipboard.")); this->close(); }); // open in browser - QPushButton *buttonOpen = new QPushButton; + QPushButton* buttonOpen = new QPushButton; buttonOpen->setText(tr("Open in browser")); buttonOpen->setMinimumHeight(HISTORYPIXMAP_MAX_PREVIEW_HEIGHT); - connect(buttonOpen, &QPushButton::clicked, this, [=](){ + connect(buttonOpen, &QPushButton::clicked, this, [=]() { QDesktopServices::openUrl(QUrl(url)); this->close(); }); // delete - QPushButton *buttonDelete = new QPushButton; + QPushButton* buttonDelete = new QPushButton; buttonDelete->setIcon(QIcon(":/img/material/black/delete.svg")); buttonDelete->setMinimumHeight(HISTORYPIXMAP_MAX_PREVIEW_HEIGHT); - connect(buttonDelete, &QPushButton::clicked, this, [=](){ + connect(buttonDelete, &QPushButton::clicked, this, [=]() { if (unpackFileName.token.length() > 0) { removeItem(phbl, unpackFileName.file, unpackFileName.token); - } - else { - // for compatibility with previous versions and to be able to remove previous screenshots + } else { + // for compatibility with previous versions and to be able to remove + // previous screenshots QFile file(fullFileName); if (file.exists()) { file.remove(); @@ -158,23 +162,27 @@ void HistoryWidget::addLine(const QString &path, const QString& fileName) { m_pVBox->addLayout(phbl); } -void HistoryWidget::removeItem(QLayout *pl, const QString& s3FileName, const QString& deleteToken) { - ImgS3Uploader *uploader = new ImgS3Uploader(); +void HistoryWidget::removeItem(QLayout* pl, + const QString& s3FileName, + const QString& deleteToken) +{ + ImgS3Uploader* uploader = new ImgS3Uploader(); hide(); uploader->show(); uploader->deleteResource(s3FileName, deleteToken); - connect(uploader, &QWidget::destroyed, this, [=](){ - if(uploader->success()) { + connect(uploader, &QWidget::destroyed, this, [=]() { + if (uploader->resultStatus) { removeLocalItem(pl); } show(); }); } -void HistoryWidget::removeLocalItem(QLayout *pl) { +void HistoryWidget::removeLocalItem(QLayout* pl) +{ // remove current row or refresh list - while(pl->count() > 0) { - QLayoutItem *item = pl->takeAt(0); + while (pl->count() > 0) { + QLayoutItem* item = pl->takeAt(0); delete item->widget(); delete item; } @@ -182,7 +190,7 @@ void HistoryWidget::removeLocalItem(QLayout *pl) { delete pl; // set "empty" message if no items left - if(m_pVBox->count() == 0) { + if (m_pVBox->count() == 0) { setEmptyMessage(); } } diff --git a/src/widgets/historywidget.h b/src/widgets/historywidget.h index b29cb000..e0242c64 100644 --- a/src/widgets/historywidget.h +++ b/src/widgets/historywidget.h @@ -4,11 +4,11 @@ #define HISTORYPIXMAP_MAX_PREVIEW_WIDTH 160 #define HISTORYPIXMAP_MAX_PREVIEW_HEIGHT 90 -#include -#include +#include "src/tools/storage/imgs3settings.h" #include +#include #include -#include "src/tools/imgs3/imgs3settings.h" +#include class QLayout; class QVBoxLayout; @@ -18,21 +18,23 @@ class HistoryWidget : public QDialog { Q_OBJECT public: - explicit HistoryWidget(QWidget *parent = nullptr); + explicit HistoryWidget(QWidget* parent = nullptr); signals: private: void loadHistory(); - void addLine(const QString &, const QString &); - void removeItem(QLayout *pl, const QString& s3FileName, const QString& deleteToken); - void removeLocalItem(QLayout *pl); + void addLine(const QString&, const QString&); + void removeItem(QLayout* pl, + const QString& s3FileName, + const QString& deleteToken); + void removeLocalItem(QLayout* pl); void setEmptyMessage(); private: ImgS3Settings m_s3Settings; - QVBoxLayout *m_pVBox; - NotificationWidget *m_notification; + QVBoxLayout* m_pVBox; + NotificationWidget* m_notification; }; #endif // HISTORYWIDGET_H diff --git a/translations/Internationalization_ca.ts b/translations/Internationalization_ca.ts index 3b7fbcaa..9f5b77ec 100644 --- a/translations/Internationalization_ca.ts +++ b/translations/Internationalization_ca.ts @@ -457,27 +457,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Copia l'URL - + URL copied to clipboard. L'URL s'ha copiat al porta-retalls. - + Open in browser @@ -485,151 +485,198 @@ Press Space to open the side panel. ImgS3Uploader - + Uploading Image S'està pujant la imatge - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - Copia l'URL + Copia l'URL - Open URL - Obri l'URL + Obri l'URL - - Delete image - - - - Image to Clipboard. - Imatge al porta-retalls. + Imatge al porta-retalls. - Unable to open the URL. - No es pot obrir l'URL. + No es pot obrir l'URL. - - + URL copied to clipboard. L'URL s'ha copiat al porta-retalls. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - La captura s'ha copiat al porta-retalls. + La captura s'ha copiat al porta-retalls. ImgS3UploaderTool - + Image Uploader Puja la imatge - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + S'està pujant la imatge + + + + Upload image + + + + + Unable to open the URL. + No es pot obrir l'URL. + + + + URL copied to clipboard. + L'URL s'ha copiat al porta-retalls. + + + + Screenshot copied to clipboard. + La captura s'ha copiat al porta-retalls. + + + + Deleting image... + + + + + Copy URL + Copia l'URL + + + + Open URL + Obri l'URL + + + + Delete image + + + + + Image to Clipboard. + Imatge al porta-retalls. + + ImgurUploader - + Upload to Imgur Puja a Imgur - + Uploading Image S'està pujant la imatge - + Copy URL Copia l'URL - + Open URL Obri l'URL - + Image to Clipboard. Imatge al porta-retalls. - - + + Unable to open the URL. No es pot obrir l'URL. - + URL copied to clipboard. L'URL s'ha copiat al porta-retalls. - + Screenshot copied to clipboard. La captura s'ha copiat al porta-retalls. - + Delete image @@ -637,12 +684,12 @@ Press Space to open the side panel. ImgurUploaderTool - + Image Uploader Puja la imatge - + Upload the selection to Imgur Puja la selecció a Imgur @@ -840,7 +887,7 @@ Press Space to open the side panel. - + URL copied to clipboard. L'URL s'ha copiat al porta-retalls. diff --git a/translations/Internationalization_de_DE.ts b/translations/Internationalization_de_DE.ts index 33be19a9..a85e764c 100644 --- a/translations/Internationalization_de_DE.ts +++ b/translations/Internationalization_de_DE.ts @@ -460,27 +460,27 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL URL kopieren - + URL copied to clipboard. URL kopiert. - + Open in browser @@ -488,151 +488,202 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. ImgS3Uploader - + Uploading Image Bild hochladen - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - URL kopieren + URL kopieren - Open URL - URL öffnen + URL öffnen - Delete image - Bild löschen + Bild löschen - Image to Clipboard. - Bild in Zwischenablage. + Bild in Zwischenablage. - Unable to open the URL. - Kann URL nicht öffnen. + Kann URL nicht öffnen. - - + URL copied to clipboard. URL kopiert. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - Bildschirmaufnahme in Zwischenablage kopiert. + Bildschirmaufnahme in Zwischenablage kopiert. ImgS3UploaderTool - + Image Uploader Bild hochladen - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + Bild hochladen + + + + Upload image + + + + + Unable to open the URL. + Kann URL nicht öffnen. + + + + URL copied to clipboard. + URL kopiert. + + + + Screenshot copied to clipboard. + Bildschirmaufnahme in Zwischenablage kopiert. + + + + Deleting image... + + + + + Copy URL + URL kopieren + + + + Open URL + URL öffnen + + + + Delete image + Bild löschen + + + + Image to Clipboard. + Bild in Zwischenablage. + + ImgurUploader - + Upload to Imgur Zu Imgur hochladen - + Uploading Image Bild hochladen - + Copy URL URL kopieren - + Open URL URL öffnen - + Delete image Bild löschen - + Image to Clipboard. Bild in Zwischenablage. - - + + Unable to open the URL. Kann URL nicht öffnen. - + URL copied to clipboard. URL kopiert. - + Screenshot copied to clipboard. Bildschirmaufnahme in Zwischenablage kopiert. @@ -640,12 +691,12 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. ImgurUploaderTool - + Image Uploader Bild hochladen - + Upload the selection to Imgur Auswahl zu Imgur hochladen @@ -851,7 +902,7 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. Kein Schreibzugriff auf - + URL copied to clipboard. URL kopiert. diff --git a/translations/Internationalization_es.ts b/translations/Internationalization_es.ts index 77ebce9d..388a61c5 100644 --- a/translations/Internationalization_es.ts +++ b/translations/Internationalization_es.ts @@ -460,27 +460,27 @@ Presiona Espacio para abrir el panel lateral. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Copiar URL - + URL copied to clipboard. URL copiada al portapapeles. - + Open in browser @@ -488,151 +488,202 @@ Presiona Espacio para abrir el panel lateral. ImgS3Uploader - + Uploading Image Subiendo Imagen - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - Copiar URL + Copiar URL - Open URL - Abrir URL + Abrir URL - Delete image - Borrar imagen + Borrar imagen - Image to Clipboard. - Imagen al Portapapeles. + Imagen al Portapapeles. - Unable to open the URL. - No puede abrir la URL. + No puede abrir la URL. - - + URL copied to clipboard. URL copiada al portapapeles. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - Captura copiada al portapapeles. + Captura copiada al portapapeles. ImgS3UploaderTool - + Image Uploader Subir Imagen - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + Subiendo Imagen + + + + Upload image + + + + + Unable to open the URL. + No puede abrir la URL. + + + + URL copied to clipboard. + URL copiada al portapapeles. + + + + Screenshot copied to clipboard. + Captura copiada al portapapeles. + + + + Deleting image... + + + + + Copy URL + Copiar URL + + + + Open URL + Abrir URL + + + + Delete image + Borrar imagen + + + + Image to Clipboard. + Imagen al Portapapeles. + + ImgurUploader - + Upload to Imgur Subir a Imgur - + Uploading Image Subiendo Imagen - + Copy URL Copiar URL - + Open URL Abrir URL - + Delete image Borrar imagen - + Image to Clipboard. Imagen al Portapapeles. - - + + Unable to open the URL. No puede abrir la URL. - + URL copied to clipboard. URL copiada al portapapeles. - + Screenshot copied to clipboard. Captura copiada al portapapeles. @@ -640,12 +691,12 @@ Presiona Espacio para abrir el panel lateral. ImgurUploaderTool - + Image Uploader Subir Imagen - + Upload the selection to Imgur Sube la selección a Imgur @@ -847,7 +898,7 @@ Presiona Espacio para abrir el panel lateral. Imposible escribir en - + URL copied to clipboard. URL copiada al portapapeles. diff --git a/translations/Internationalization_fr.ts b/translations/Internationalization_fr.ts index ad86d1a1..da6bf5bb 100644 --- a/translations/Internationalization_fr.ts +++ b/translations/Internationalization_fr.ts @@ -460,27 +460,27 @@ Appuyer sur Espace pour ouvrir le panneau latéral. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Copier l'URL - + URL copied to clipboard. URL copiée dans le Presse-papier. - + Open in browser @@ -488,151 +488,198 @@ Appuyer sur Espace pour ouvrir le panneau latéral. ImgS3Uploader - + Uploading Image Mise en ligne de l'image - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - Copier l'URL + Copier l'URL - Open URL - Ouvrir l'URL + Ouvrir l'URL - - Delete image - - - - Image to Clipboard. - Image dans le Presse-papier. + Image dans le Presse-papier. - Unable to open the URL. - Impossible d'ouvrir l'URL. + Impossible d'ouvrir l'URL. - - + URL copied to clipboard. URL copiée dans le Presse-papier. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - Capture d'écran copiée dans le Presse-papier. + Capture d'écran copiée dans le Presse-papier. ImgS3UploaderTool - + Image Uploader Mise en ligne d'images - + Upload the selection to S3 bucket - ImgurUploader + ImgUploader - - Upload to Imgur - Mettre en ligne vers Imgur + + Upload image to S3 + - + + Uploading Image - Mise en ligne de l'image + Mise en ligne de l'image - + + Upload image + + + + + Unable to open the URL. + Impossible d'ouvrir l'URL. + + + + URL copied to clipboard. + URL copiée dans le Presse-papier. + + + + Screenshot copied to clipboard. + Capture d'écran copiée dans le Presse-papier. + + + + Deleting image... + + + + Copy URL - Copier l'URL + Copier l'URL - + Open URL - Ouvrir l'URL + Ouvrir l'URL - + Delete image - + + Image to Clipboard. + Image dans le Presse-papier. + + + + ImgurUploader + + + Upload to Imgur + Mettre en ligne vers Imgur + + + + Uploading Image + Mise en ligne de l'image + + + + Copy URL + Copier l'URL + + + + Open URL + Ouvrir l'URL + + + + Delete image + + + + Image to Clipboard. Image dans le Presse-papier. - - + + Unable to open the URL. Impossible d'ouvrir l'URL. - + URL copied to clipboard. URL copiée dans le Presse-papier. - + Screenshot copied to clipboard. Capture d'écran copiée dans le Presse-papier. @@ -640,12 +687,12 @@ Appuyer sur Espace pour ouvrir le panneau latéral. ImgurUploaderTool - + Image Uploader Mise en ligne d'images - + Upload the selection to Imgur Mettre en ligne la sélection vers Imgur @@ -843,7 +890,7 @@ Appuyer sur Espace pour ouvrir le panneau latéral. Imposible d'écrire par dessus - + URL copied to clipboard. URL copiée dans le Presse-papier. diff --git a/translations/Internationalization_hu.ts b/translations/Internationalization_hu.ts index c4fa8b2f..aa4e4023 100644 --- a/translations/Internationalization_hu.ts +++ b/translations/Internationalization_hu.ts @@ -425,19 +425,19 @@ Press Space to open the side panel. Copy URL - URL másolása + URL másolása Open URL - URL megnyitása + URL megnyitása Image to Clipboard. - Kép a vágolapra. + Kép a vágolapra. Unable to open the URL. - Nem lehet az URL-t megnyitni. + Nem lehet az URL-t megnyitni. URL copied to clipboard. @@ -445,7 +445,7 @@ Press Space to open the side panel. Screenshot copied to clipboard. - Képernyőmentés másolva a vágólapra. + Képernyőmentés másolva a vágólapra. Upload image to S3 @@ -455,10 +455,6 @@ Press Space to open the side panel. Delete image from S3 - - Delete image - - S3 Creds URL is not found in your configuration file @@ -499,6 +495,53 @@ Press Space to open the side panel. + + ImgUploader + + Upload image to S3 + + + + Uploading Image + Kép felötlése + + + Upload image + + + + Unable to open the URL. + Nem lehet az URL-t megnyitni. + + + URL copied to clipboard. + URL másolva a vágólapra. + + + Screenshot copied to clipboard. + Képernyőmentés másolva a vágólapra. + + + Deleting image... + + + + Copy URL + URL másolása + + + Open URL + URL megnyitása + + + Delete image + + + + Image to Clipboard. + Kép a vágolapra. + + ImgurUploader diff --git a/translations/Internationalization_ja.ts b/translations/Internationalization_ja.ts index 2f295ffe..e7690956 100644 --- a/translations/Internationalization_ja.ts +++ b/translations/Internationalization_ja.ts @@ -460,27 +460,27 @@ Enter を押すと画面をキャプチャー。 HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL URL をコピー - + URL copied to clipboard. URL をクリップボードにコピーしました。 - + Open in browser @@ -488,151 +488,202 @@ Enter を押すと画面をキャプチャー。 ImgS3Uploader - + Uploading Image 画像をアップロード中 - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - URL をコピー + URL をコピー - Open URL - URL を開く + URL を開く - Delete image - 画像を削除 + 画像を削除 - Image to Clipboard. - 画像をクリップボードへ。 + 画像をクリップボードへ。 - Unable to open the URL. - URL を開けません。 + URL を開けません。 - - + URL copied to clipboard. URL をクリップボードにコピーしました。 - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - スクリーンショットをクリップボードにコピーしました。 + スクリーンショットをクリップボードにコピーしました。 ImgS3UploaderTool - + Image Uploader 画像アップローダー - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + 画像をアップロード中 + + + + Upload image + + + + + Unable to open the URL. + URL を開けません。 + + + + URL copied to clipboard. + URL をクリップボードにコピーしました。 + + + + Screenshot copied to clipboard. + スクリーンショットをクリップボードにコピーしました。 + + + + Deleting image... + + + + + Copy URL + URL をコピー + + + + Open URL + URL を開く + + + + Delete image + 画像を削除 + + + + Image to Clipboard. + 画像をクリップボードへ。 + + ImgurUploader - + Upload to Imgur Imgur にアップロード - + Uploading Image 画像をアップロード中 - + Copy URL URL をコピー - + Open URL URL を開く - + Delete image 画像を削除 - + Image to Clipboard. 画像をクリップボードへ。 - - + + Unable to open the URL. URL を開けません。 - + URL copied to clipboard. URL をクリップボードにコピーしました。 - + Screenshot copied to clipboard. スクリーンショットをクリップボードにコピーしました。 @@ -640,12 +691,12 @@ Enter を押すと画面をキャプチャー。 ImgurUploaderTool - + Image Uploader 画像アップローダー - + Upload the selection to Imgur Imgur に選択範囲をアップロードする @@ -843,7 +894,7 @@ Enter を押すと画面をキャプチャー。 書き込めません: - + URL copied to clipboard. URL をクリップボードにコピーしました。 diff --git a/translations/Internationalization_ka.ts b/translations/Internationalization_ka.ts index e84f9153..5c002f0e 100644 --- a/translations/Internationalization_ka.ts +++ b/translations/Internationalization_ka.ts @@ -456,27 +456,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL URL-ის კოპირება - + URL copied to clipboard. URL დაკოპირდა გაცვლის ბუფერში. - + Open in browser @@ -484,151 +484,198 @@ Press Space to open the side panel. ImgS3Uploader - + Uploading Image სურათის ატვირთვა - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - URL-ის კოპირება + URL-ის კოპირება - Open URL - URL-ის გახსნა + URL-ის გახსნა - - Delete image - - - - Image to Clipboard. - სურათის გაცვლის ბუფერში გაგზავნა + სურათის გაცვლის ბუფერში გაგზავნა - Unable to open the URL. - URL-ის გახსნა ვერ მოხერხდა. + URL-ის გახსნა ვერ მოხერხდა. - - + URL copied to clipboard. URL დაკოპირდა გაცვლის ბუფერში. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - სურათი დაკოპირდა გაცვლის ბუფერში. + სურათი დაკოპირდა გაცვლის ბუფერში. ImgS3UploaderTool - + Image Uploader სურათის ამტვირთველი - + Upload the selection to S3 bucket - ImgurUploader + ImgUploader - - Upload to Imgur - Imgur-ზე ატვირთვა + + Upload image to S3 + - + + Uploading Image - სურათის ატვირთვა + სურათის ატვირთვა - + + Upload image + + + + + Unable to open the URL. + URL-ის გახსნა ვერ მოხერხდა. + + + + URL copied to clipboard. + URL დაკოპირდა გაცვლის ბუფერში. + + + + Screenshot copied to clipboard. + სურათი დაკოპირდა გაცვლის ბუფერში. + + + + Deleting image... + + + + Copy URL - URL-ის კოპირება + URL-ის კოპირება - + Open URL - URL-ის გახსნა + URL-ის გახსნა - + Delete image - + + Image to Clipboard. + სურათის გაცვლის ბუფერში გაგზავნა + + + + ImgurUploader + + + Upload to Imgur + Imgur-ზე ატვირთვა + + + + Uploading Image + სურათის ატვირთვა + + + + Copy URL + URL-ის კოპირება + + + + Open URL + URL-ის გახსნა + + + + Delete image + + + + Image to Clipboard. სურათის გაცვლის ბუფერში გაგზავნა - - + + Unable to open the URL. URL-ის გახსნა ვერ მოხერხდა. - + URL copied to clipboard. URL დაკოპირდა გაცვლის ბუფერში. - + Screenshot copied to clipboard. სურათი დაკოპირდა გაცვლის ბუფერში. @@ -636,12 +683,12 @@ Press Space to open the side panel. ImgurUploaderTool - + Image Uploader სურათის ამტვირთველი - + Upload the selection to Imgur შერჩეულის Imgur-ზე ატვირთვა @@ -839,7 +886,7 @@ Press Space to open the side panel. შემდეგ მისამართზე ჩაწერა ვერ მოხერხდა: - + URL copied to clipboard. URL დაკოპირდა გაცვლის ბუფერში. diff --git a/translations/Internationalization_nl.ts b/translations/Internationalization_nl.ts index 38e5842c..05adeaee 100644 --- a/translations/Internationalization_nl.ts +++ b/translations/Internationalization_nl.ts @@ -460,27 +460,27 @@ Druk op spatie om het zijpaneel te openen. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL URL kopiëren - + URL copied to clipboard. URL gekopieerd naar klembord. - + Open in browser @@ -488,151 +488,202 @@ Druk op spatie om het zijpaneel te openen. ImgS3Uploader - + Uploading Image Bezig met uploaden van afbeelding... - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - URL kopiëren + URL kopiëren - Open URL - URL openen + URL openen - Delete image - Afbeelding verwijderen + Afbeelding verwijderen - Image to Clipboard. - Afbeelding naar klembord. + Afbeelding naar klembord. - Unable to open the URL. - Kan URL niet openen. + Kan URL niet openen. - - + URL copied to clipboard. URL gekopieerd naar klembord. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - Schermafdruk gekopieerd naar klembord. + Schermafdruk gekopieerd naar klembord. ImgS3UploaderTool - + Image Uploader Afbeeldingsuploader - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + Bezig met uploaden van afbeelding... + + + + Upload image + + + + + Unable to open the URL. + Kan URL niet openen. + + + + URL copied to clipboard. + URL gekopieerd naar klembord. + + + + Screenshot copied to clipboard. + Schermafdruk gekopieerd naar klembord. + + + + Deleting image... + + + + + Copy URL + URL kopiëren + + + + Open URL + URL openen + + + + Delete image + Afbeelding verwijderen + + + + Image to Clipboard. + Afbeelding naar klembord. + + ImgurUploader - + Upload to Imgur Uploaden naar Imgur - + Uploading Image Bezig met uploaden van afbeelding... - + Copy URL URL kopiëren - + Open URL URL openen - + Delete image Afbeelding verwijderen - + Image to Clipboard. Afbeelding naar klembord. - - + + Unable to open the URL. Kan URL niet openen. - + URL copied to clipboard. URL gekopieerd naar klembord. - + Screenshot copied to clipboard. Schermafdruk gekopieerd naar klembord. @@ -640,12 +691,12 @@ Druk op spatie om het zijpaneel te openen. ImgurUploaderTool - + Image Uploader Afbeeldingsuploader - + Upload the selection to Imgur Upload de selectie naar Imgur @@ -847,7 +898,7 @@ Druk op spatie om het zijpaneel te openen. Kan niet wegschrijven naar - + URL copied to clipboard. URL gekopieerd naar klembord. diff --git a/translations/Internationalization_pl.ts b/translations/Internationalization_pl.ts index aa0f8841..e0a44a60 100644 --- a/translations/Internationalization_pl.ts +++ b/translations/Internationalization_pl.ts @@ -459,27 +459,27 @@ Spacja, aby pokazać panel boczny. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Kopiuj URL - + URL copied to clipboard. URL skopiowany do schowka. - + Open in browser @@ -487,151 +487,202 @@ Spacja, aby pokazać panel boczny. ImgS3Uploader - + Uploading Image Wysyłanie obrazka - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - Kopiuj URL + Kopiuj URL - Open URL - Otwórz URL + Otwórz URL - Delete image - Usuń obrazek + Usuń obrazek - Image to Clipboard. - Obrazek do schowka. + Obrazek do schowka. - Unable to open the URL. - Nie można otworzyć adresu URL. + Nie można otworzyć adresu URL. - - + URL copied to clipboard. URL skopiowany do schowka. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - Zrzut ekranu skopiowany do schowka. + Zrzut ekranu skopiowany do schowka. ImgS3UploaderTool - + Image Uploader Uploader obrazów - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + Wysyłanie obrazka + + + + Upload image + + + + + Unable to open the URL. + Nie można otworzyć adresu URL. + + + + URL copied to clipboard. + URL skopiowany do schowka. + + + + Screenshot copied to clipboard. + Zrzut ekranu skopiowany do schowka. + + + + Deleting image... + + + + + Copy URL + Kopiuj URL + + + + Open URL + Otwórz URL + + + + Delete image + Usuń obrazek + + + + Image to Clipboard. + Obrazek do schowka. + + ImgurUploader - + Upload to Imgur Wyślij do Imgur - + Uploading Image Wysyłanie obrazka - + Copy URL Kopiuj URL - + Open URL Otwórz URL - + Delete image Usuń obrazek - + Image to Clipboard. Obrazek do schowka. - - + + Unable to open the URL. Nie można otworzyć adresu URL. - + URL copied to clipboard. URL skopiowany do schowka. - + Screenshot copied to clipboard. Zrzut ekranu skopiowany do schowka. @@ -639,12 +690,12 @@ Spacja, aby pokazać panel boczny. ImgurUploaderTool - + Image Uploader Uploader obrazów - + Upload the selection to Imgur Wyślij zaznaczenie do Imgur @@ -842,7 +893,7 @@ Spacja, aby pokazać panel boczny. Nie można zapisać w - + URL copied to clipboard. URL skopiowany do schowka. diff --git a/translations/Internationalization_pt_br.ts b/translations/Internationalization_pt_br.ts index b52272e8..0239a92b 100644 --- a/translations/Internationalization_pt_br.ts +++ b/translations/Internationalization_pt_br.ts @@ -460,27 +460,27 @@ Pressione espaço abrir o painel lateral. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Copiar URL - + URL copied to clipboard. URL copiada para o clipboard. - + Open in browser @@ -488,151 +488,202 @@ Pressione espaço abrir o painel lateral. ImgS3Uploader - + Uploading Image Upando Imagem - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - Copiar URL + Copiar URL - Open URL - Abrir URL + Abrir URL - Delete image - Deletar imagem + Deletar imagem - Image to Clipboard. - Imagem no Clipboard. + Imagem no Clipboard. - Unable to open the URL. - Não foi possível abrir a URL. + Não foi possível abrir a URL. - - + URL copied to clipboard. URL copiada para o clipboard. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - Screenshot copiada para o clipboard. + Screenshot copiada para o clipboard. ImgS3UploaderTool - + Image Uploader Uploader de imagens - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + Upando Imagem + + + + Upload image + + + + + Unable to open the URL. + Não foi possível abrir a URL. + + + + URL copied to clipboard. + URL copiada para o clipboard. + + + + Screenshot copied to clipboard. + Screenshot copiada para o clipboard. + + + + Deleting image... + + + + + Copy URL + Copiar URL + + + + Open URL + Abrir URL + + + + Delete image + Deletar imagem + + + + Image to Clipboard. + Imagem no Clipboard. + + ImgurUploader - + Upload to Imgur Upload no Imgur - + Uploading Image Upando Imagem - + Copy URL Copiar URL - + Open URL Abrir URL - + Delete image Deletar imagem - + Image to Clipboard. Imagem no Clipboard. - - + + Unable to open the URL. Não foi possível abrir a URL. - + URL copied to clipboard. URL copiada para o clipboard. - + Screenshot copied to clipboard. Screenshot copiada para o clipboard. @@ -640,12 +691,12 @@ Pressione espaço abrir o painel lateral. ImgurUploaderTool - + Image Uploader Uploader de imagens - + Upload the selection to Imgur Upa a seleção no Imgur @@ -843,7 +894,7 @@ Pressione espaço abrir o painel lateral. Não foi possível escrever em - + URL copied to clipboard. URL copiada para o clipboard. diff --git a/translations/Internationalization_ru.ts b/translations/Internationalization_ru.ts index 0200c6d7..097e5d7c 100644 --- a/translations/Internationalization_ru.ts +++ b/translations/Internationalization_ru.ts @@ -476,27 +476,27 @@ Press Space to open the side panel. История скриншотов пустая - + Latest Uploads Последние загрузки - + Screenshots history is empty История скриншотов пуста - + Copy URL Скопировать URL - + URL copied to clipboard. URL скопирован в буфер обмена. - + Open in browser Открыть в браузере @@ -508,17 +508,17 @@ Press Space to open the side panel. Загрузить на S3 - + Uploading Image Загрузка изображения - + Upload image to S3 Загрузить на S3 - + Delete image from S3 Удалить скриншот с S3 @@ -527,87 +527,79 @@ Press Space to open the side panel. Удалить скриншот - + Remove screenshot from history? Удалить скриншот из истории? - + S3 Creds URL is not found in your configuration file Параметры доступов к S3 не найдены в конфигурационном файле - Copy URL - Скопировать URL + Скопировать URL - Open URL - Открыть URL + Открыть URL - Delete image - Удалить изображение + Удалить изображение - Image to Clipboard. - Изображение в буфер обмена. + Изображение в буфер обмена. - Unable to open the URL. - Не удалось открыть URL. + Не удалось открыть URL. - - + URL copied to clipboard. URL скопирован в буфер обмена. - - + Deleting image... Удаление скриншота... - + Unable to remove screenshot from the remote storage. Невозможно удалить снимок экрана из удаленного хранилища. - + Network error Ошибка сети - + Possibly it doesn't exist anymore Возможно, его больше не существует - + Do you want to remove screenshot from local history anyway? Вы все равно хотите удалить скриншот из локальной истории? - Screenshot copied to clipboard. - Снимок скопирован в буфер обмена. + Снимок скопирован в буфер обмена. ImgS3UploaderTool - + Image Uploader Отправка изображений - + Upload the selection to S3 bucket Загрузить выделение на S3 @@ -617,50 +609,109 @@ Press Space to open the side panel. - ImgurUploader + ImgUploader - - Upload to Imgur - Загрузить в Imgur + + Upload image to S3 + Загрузить на S3 - + + Uploading Image Загрузка изображения - - Copy URL - Скопировать URL + + Upload image + Загрузить изображение - - Open URL - Открыть URL - - - - Delete image - Удалить изображение - - - - Image to Clipboard. - Изображение в буфер обмена. - - - - + Unable to open the URL. Не удалось открыть URL. - + URL copied to clipboard. URL скопирован в буфер обмена. - + + Screenshot copied to clipboard. + Снимок скопирован в буфер обмена. + + + + Deleting image... + Удаление скриншота... + + + + Copy URL + Скопировать URL + + + + Open URL + Открыть URL + + + + Delete image + Удалить изображение + + + + Image to Clipboard. + Изображение в буфер обмена. + + + + ImgurUploader + + + Upload to Imgur + Загрузить в Imgur + + + + Uploading Image + Загрузка изображения + + + + Copy URL + Скопировать URL + + + + Open URL + Открыть URL + + + + Delete image + Удалить изображение + + + + Image to Clipboard. + Изображение в буфер обмена. + + + + + Unable to open the URL. + Не удалось открыть URL. + + + + URL copied to clipboard. + URL скопирован в буфер обмена. + + + Screenshot copied to clipboard. Снимок скопирован в буфер обмена. @@ -668,12 +719,12 @@ Press Space to open the side panel. ImgurUploaderTool - + Image Uploader Отправка изображений - + Upload the selection to Imgur Загрузить выделение на Imgur @@ -887,7 +938,7 @@ Press Space to open the side panel. Не удалось сохранить - + URL copied to clipboard. URL скопирован в буфер обмена. diff --git a/translations/Internationalization_sk.ts b/translations/Internationalization_sk.ts index f235432f..f33aa6e0 100644 --- a/translations/Internationalization_sk.ts +++ b/translations/Internationalization_sk.ts @@ -460,27 +460,27 @@ Stlačte medzerník pre otvorenie postranného panelu. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Kopírovať URL - + URL copied to clipboard. URL skopírovaná do schránky. - + Open in browser @@ -488,151 +488,202 @@ Stlačte medzerník pre otvorenie postranného panelu. ImgS3Uploader - + Uploading Image Nahrávam obrázok - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - Kopírovať URL + Kopírovať URL - Open URL - Otvoriť URL + Otvoriť URL - Delete image - Vymazať obrázok + Vymazať obrázok - Image to Clipboard. - Obrázok do schránky. + Obrázok do schránky. - Unable to open the URL. - Nepodarilo sa otvoriť URL. + Nepodarilo sa otvoriť URL. - - + URL copied to clipboard. URL skopírovaná do schránky. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - Snímka obrazovky bola skopírovaná do schránky. + Snímka obrazovky bola skopírovaná do schránky. ImgS3UploaderTool - + Image Uploader Uploader obrázkov - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + Nahrávam obrázok + + + + Upload image + + + + + Unable to open the URL. + Nepodarilo sa otvoriť URL. + + + + URL copied to clipboard. + URL skopírovaná do schránky. + + + + Screenshot copied to clipboard. + Snímka obrazovky bola skopírovaná do schránky. + + + + Deleting image... + + + + + Copy URL + Kopírovať URL + + + + Open URL + Otvoriť URL + + + + Delete image + Vymazať obrázok + + + + Image to Clipboard. + Obrázok do schránky. + + ImgurUploader - + Upload to Imgur Nahrať na Imgur - + Uploading Image Nahrávam obrázok - + Copy URL Kopírovať URL - + Open URL Otvoriť URL - + Delete image Vymazať obrázok - + Image to Clipboard. Obrázok do schránky. - - + + Unable to open the URL. Nepodarilo sa otvoriť URL. - + URL copied to clipboard. URL skopírovaná do schránky. - + Screenshot copied to clipboard. Snímka obrazovky bola skopírovaná do schránky. @@ -640,12 +691,12 @@ Stlačte medzerník pre otvorenie postranného panelu. ImgurUploaderTool - + Image Uploader Uploader obrázkov - + Upload the selection to Imgur Nahrať výber na Imgur @@ -851,7 +902,7 @@ Stlačte medzerník pre otvorenie postranného panelu. Chyba pri ukladaní - + URL copied to clipboard. URL skopírovaná do schránky. diff --git a/translations/Internationalization_sr.ts b/translations/Internationalization_sr.ts index 4dc05af2..92f99f8a 100644 --- a/translations/Internationalization_sr.ts +++ b/translations/Internationalization_sr.ts @@ -460,27 +460,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Запамти интернет адресу - + URL copied to clipboard. Интернет адреса је сачувана у привременој меморији. - + Open in browser @@ -488,151 +488,202 @@ Press Space to open the side panel. ImgS3Uploader - + Uploading Image Објављујем слику - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - Запамти интернет адресу + Запамти интернет адресу - Open URL - Посети интернет адресу + Посети интернет адресу - Delete image - Избриши слику + Избриши слику - Image to Clipboard. - Сачувај у привремену меморију. + Сачувај у привремену меморију. - Unable to open the URL. - Нисам успео да посетим интернет адресу. + Нисам успео да посетим интернет адресу. - - + URL copied to clipboard. Интернет адреса је сачувана у привременој меморији. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - Слика је сачувана у привременој меморији. + Слика је сачувана у привременој меморији. ImgS3UploaderTool - + Image Uploader Објављивање слике - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + Објављујем слику + + + + Upload image + + + + + Unable to open the URL. + Нисам успео да посетим интернет адресу. + + + + URL copied to clipboard. + Интернет адреса је сачувана у привременој меморији. + + + + Screenshot copied to clipboard. + Слика је сачувана у привременој меморији. + + + + Deleting image... + + + + + Copy URL + Запамти интернет адресу + + + + Open URL + Посети интернет адресу + + + + Delete image + Избриши слику + + + + Image to Clipboard. + Сачувај у привремену меморију. + + ImgurUploader - + Upload to Imgur Објави на Imgur - + Uploading Image Објављујем слику - + Copy URL Запамти интернет адресу - + Open URL Посети интернет адресу - + Delete image Избриши слику - + Image to Clipboard. Сачувај у привремену меморију. - - + + Unable to open the URL. Нисам успео да посетим интернет адресу. - + URL copied to clipboard. Интернет адреса је сачувана у привременој меморији. - + Screenshot copied to clipboard. Слика је сачувана у привременој меморији. @@ -640,12 +691,12 @@ Press Space to open the side panel. ImgurUploaderTool - + Image Uploader Објављивање слике - + Upload the selection to Imgur Објави избор на Imgur сајту @@ -843,7 +894,7 @@ Press Space to open the side panel. Нисам успео са сачувам - + URL copied to clipboard. Интернет адреса је сачувана у привременој меморији. diff --git a/translations/Internationalization_tr.ts b/translations/Internationalization_tr.ts index 1160935c..99876eb0 100644 --- a/translations/Internationalization_tr.ts +++ b/translations/Internationalization_tr.ts @@ -460,27 +460,27 @@ Yan paneli açmak için Boşluk tuşuna basın. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL URL Kopyala - + URL copied to clipboard. URL panoya kopyalandı. - + Open in browser @@ -488,151 +488,202 @@ Yan paneli açmak için Boşluk tuşuna basın. ImgS3Uploader - + Uploading Image Resim Yükleniyor - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - URL Kopyala + URL Kopyala - Open URL - URL Aç + URL Aç - Delete image - Resmi sil + Resmi sil - Image to Clipboard. - Resim Pano'ya. + Resim Pano'ya. - Unable to open the URL. - URL açılamıyor. + URL açılamıyor. - - + URL copied to clipboard. URL panoya kopyalandı. - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - Ekran görüntüsü panoya kopyalandı. + Ekran görüntüsü panoya kopyalandı. ImgS3UploaderTool - + Image Uploader Resim Yükleme Aracı - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + Resim Yükleniyor + + + + Upload image + + + + + Unable to open the URL. + URL açılamıyor. + + + + URL copied to clipboard. + URL panoya kopyalandı. + + + + Screenshot copied to clipboard. + Ekran görüntüsü panoya kopyalandı. + + + + Deleting image... + + + + + Copy URL + URL Kopyala + + + + Open URL + URL Aç + + + + Delete image + Resmi sil + + + + Image to Clipboard. + Resim Pano'ya. + + ImgurUploader - + Upload to Imgur Imgur'a yükle - + Uploading Image Resim Yükleniyor - + Copy URL URL Kopyala - + Open URL URL Aç - + Delete image Resmi sil - + Image to Clipboard. Resim Pano'ya. - - + + Unable to open the URL. URL açılamıyor. - + URL copied to clipboard. URL panoya kopyalandı. - + Screenshot copied to clipboard. Ekran görüntüsü panoya kopyalandı. @@ -640,12 +691,12 @@ Yan paneli açmak için Boşluk tuşuna basın. ImgurUploaderTool - + Image Uploader Resim Yükleme Aracı - + Upload the selection to Imgur Seçimi Imgur'a yükler @@ -843,7 +894,7 @@ Yan paneli açmak için Boşluk tuşuna basın. Yazma mümkün değil - + URL copied to clipboard. URL panoya kopyalandı. diff --git a/translations/Internationalization_uk.ts b/translations/Internationalization_uk.ts index 179c3c3d..aedaefa8 100644 --- a/translations/Internationalization_uk.ts +++ b/translations/Internationalization_uk.ts @@ -476,27 +476,27 @@ Press Space to open the side panel. Історія скріншотів пуста - + Latest Uploads Останні завантаження - + Screenshots history is empty Історія скріншотів пуста - + Copy URL Скопіювати URL - + URL copied to clipboard. URL скопійовано до буферу обміну. - + Open in browser Відкрити у браузері @@ -508,17 +508,17 @@ Press Space to open the side panel. Вивантажити на S3 - + Uploading Image Вивантаження зображення - + Upload image to S3 Завантажити на S3 - + Delete image from S3 Видалити скріншот з S3 @@ -527,87 +527,79 @@ Press Space to open the side panel. Видалити скіншот - + Remove screenshot from history? Видалити скріншот із історії? - + S3 Creds URL is not found in your configuration file Параметри доступів до S3 не знайдені у конфігураціонному файлі - Copy URL - Скопіювати URL + Скопіювати URL - Open URL - Відкрити URL + Відкрити URL - Delete image - Видалити зображення + Видалити зображення - Image to Clipboard. - Зображення до буферу обміну. + Зображення до буферу обміну. - Unable to open the URL. - Не вдалось відкрити URL. + Не вдалось відкрити URL. - - + URL copied to clipboard. URL скопійовано до буферу обміну. - - + Deleting image... Видалення скріншоту... - + Unable to remove screenshot from the remote storage. Не вдалося видалити скріншот із віддаленого сховища. - + Network error Помилка мережі - + Possibly it doesn't exist anymore Можливо, його більше не існує - + Do you want to remove screenshot from local history anyway? Ви все одно хочете видалити скріншот із локальної історії? - Screenshot copied to clipboard. - Знімок скопійовано до буферу обміну. + Знімок скопійовано до буферу обміну. ImgS3UploaderTool - + Image Uploader Вивантаження зображень - + Upload the selection to S3 bucket Вивантажити виділення на S3 @@ -617,50 +609,109 @@ Press Space to open the side panel. - ImgurUploader + ImgUploader - - Upload to Imgur - Вивантажити до Imgur + + Upload image to S3 + Завантажити на S3 - + + Uploading Image Вивантаження зображення - - Copy URL - Скопіювати URL + + Upload image + Вивантажити зображення - - Open URL - Відкрити URL - - - - Delete image - Видалити зображення - - - - Image to Clipboard. - Зображення до буферу обміну. - - - - + Unable to open the URL. Не вдалось відкрити URL. - + URL copied to clipboard. URL скопійовано до буферу обміну. - + + Screenshot copied to clipboard. + Знімок скопійовано до буферу обміну. + + + + Deleting image... + Видалення скріншоту... + + + + Copy URL + Скопіювати URL + + + + Open URL + Відкрити URL + + + + Delete image + Видалити зображення + + + + Image to Clipboard. + Зображення до буферу обміну. + + + + ImgurUploader + + + Upload to Imgur + Вивантажити до Imgur + + + + Uploading Image + Вивантаження зображення + + + + Copy URL + Скопіювати URL + + + + Open URL + Відкрити URL + + + + Delete image + Видалити зображення + + + + Image to Clipboard. + Зображення до буферу обміну. + + + + + Unable to open the URL. + Не вдалось відкрити URL. + + + + URL copied to clipboard. + URL скопійовано до буферу обміну. + + + Screenshot copied to clipboard. Знімок скопійовано до буферу обміну. @@ -668,12 +719,12 @@ Press Space to open the side panel. ImgurUploaderTool - + Image Uploader Вивантаження зображень - + Upload the selection to Imgur Вивантажити вибране до Imgur @@ -887,7 +938,7 @@ Press Space to open the side panel. Не вдалось зберегти - + URL copied to clipboard. URL скопійовано до буферу обміну. diff --git a/translations/Internationalization_zh_CN.ts b/translations/Internationalization_zh_CN.ts index 710d93ca..a20d9c3d 100644 --- a/translations/Internationalization_zh_CN.ts +++ b/translations/Internationalization_zh_CN.ts @@ -461,27 +461,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL 复制链接 - + URL copied to clipboard. 复制链接到剪贴板。 - + Open in browser @@ -489,151 +489,202 @@ Press Space to open the side panel. ImgS3Uploader - + Uploading Image 正在上传 - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - 复制链接 + 复制链接 - Open URL - 打开链接 + 打开链接 - Delete image - 删除图像 + 删除图像 - Image to Clipboard. - 保存文件到剪贴板。 + 保存文件到剪贴板。 - Unable to open the URL. - 无法打开此链接。 + 无法打开此链接。 - - + URL copied to clipboard. 复制链接到剪贴板。 - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - 截图复制到剪贴板。 + 截图复制到剪贴板。 ImgS3UploaderTool - + Image Uploader 上传图片 - + Upload the selection to S3 bucket + + ImgUploader + + + Upload image to S3 + + + + + + Uploading Image + 正在上传 + + + + Upload image + + + + + Unable to open the URL. + 无法打开此链接。 + + + + URL copied to clipboard. + 复制链接到剪贴板。 + + + + Screenshot copied to clipboard. + 截图复制到剪贴板。 + + + + Deleting image... + + + + + Copy URL + 复制链接 + + + + Open URL + 打开链接 + + + + Delete image + 删除图像 + + + + Image to Clipboard. + 保存文件到剪贴板。 + + ImgurUploader - + Upload to Imgur 上传到Imgur - + Uploading Image 正在上传 - + Copy URL 复制链接 - + Open URL 打开链接 - + Delete image 删除图像 - + Image to Clipboard. 保存文件到剪贴板。 - - + + Unable to open the URL. 无法打开此链接。 - + URL copied to clipboard. 复制链接到剪贴板。 - + Screenshot copied to clipboard. 截图复制到剪贴板。 @@ -641,12 +692,12 @@ Press Space to open the side panel. ImgurUploaderTool - + Image Uploader 上传图片 - + Upload the selection to Imgur 上传选择到 Imgur @@ -852,7 +903,7 @@ Press Space to open the side panel. 无法写入 - + URL copied to clipboard. 复制链接到剪贴板。 diff --git a/translations/Internationalization_zh_TW.ts b/translations/Internationalization_zh_TW.ts index 6194cfb4..e4b51abd 100644 --- a/translations/Internationalization_zh_TW.ts +++ b/translations/Internationalization_zh_TW.ts @@ -456,27 +456,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL 複製連結 - + URL copied to clipboard. 連結已複製到剪貼簿 - + Open in browser @@ -484,151 +484,198 @@ Press Space to open the side panel. ImgS3Uploader - + Uploading Image 正在上傳 - + Upload image to S3 - + Delete image from S3 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + S3 Creds URL is not found in your configuration file - Copy URL - 複製連結 + 複製連結 - Open URL - 打開連結 + 打開連結 - - Delete image - - - - Image to Clipboard. - 將檔案複製到剪貼簿 + 將檔案複製到剪貼簿 - Unable to open the URL. - 無法打開此連結 + 無法打開此連結 - - + URL copied to clipboard. 連結已複製到剪貼簿 - - + Deleting image... - + Remove screenshot from history? - Screenshot copied to clipboard. - 截圖已複製到剪貼簿 + 截圖已複製到剪貼簿 ImgS3UploaderTool - + Image Uploader 上傳圖片 - + Upload the selection to S3 bucket - ImgurUploader + ImgUploader - - Upload to Imgur - 上傳到 Imgur + + Upload image to S3 + - + + Uploading Image - 正在上傳 + 正在上傳 - + + Upload image + + + + + Unable to open the URL. + 無法打開此連結 + + + + URL copied to clipboard. + 連結已複製到剪貼簿 + + + + Screenshot copied to clipboard. + 截圖已複製到剪貼簿 + + + + Deleting image... + + + + Copy URL - 複製連結 + 複製連結 - + Open URL - 打開連結 + 打開連結 - + Delete image - + + Image to Clipboard. + 將檔案複製到剪貼簿 + + + + ImgurUploader + + + Upload to Imgur + 上傳到 Imgur + + + + Uploading Image + 正在上傳 + + + + Copy URL + 複製連結 + + + + Open URL + 打開連結 + + + + Delete image + + + + Image to Clipboard. 將檔案複製到剪貼簿 - - + + Unable to open the URL. 無法打開此連結 - + URL copied to clipboard. 連結已複製到剪貼簿 - + Screenshot copied to clipboard. 截圖已複製到剪貼簿 @@ -636,12 +683,12 @@ Press Space to open the side panel. ImgurUploaderTool - + Image Uploader 上傳圖片 - + Upload the selection to Imgur 上傳到 Imgur @@ -839,7 +886,7 @@ Press Space to open the side panel. 無法寫入 - + URL copied to clipboard. 連結已複製到剪貼簿