diff --git a/dialogs/optionsdialog.cpp b/dialogs/optionsdialog.cpp
index 781e2f2..2b43515 100644
--- a/dialogs/optionsdialog.cpp
+++ b/dialogs/optionsdialog.cpp
@@ -281,6 +281,19 @@ void OptionsDialog::loadSettings()
settings()->beginGroup("imgur");
ui.imgurOptions->setUser(settings()->value("account_username", "").toString());
settings()->endGroup();
+
+ settings()->beginGroup("pomf");
+ QString pomf_url = settings()->value("pomf_url", "").toString();
+
+ if (!pomf_url.isEmpty()) {
+ if (ui.pomfOptions->ui.pomfUrlComboBox->findText(pomf_url, Qt::MatchFixedString) == -1) {
+ ui.pomfOptions->ui.pomfUrlComboBox->addItem(pomf_url);
+ }
+
+ ui.pomfOptions->ui.pomfUrlComboBox->setCurrentText(settings()->value("pomf_url", "").toString());
+ }
+ settings()->endGroup();
+
settings()->endGroup();
QTimer::singleShot(0, this, &OptionsDialog::updatePreview);
@@ -381,8 +394,12 @@ void OptionsDialog::saveSettings()
settings()->setValue("service", ui.uploadServiceComboBox->currentIndex());
settings()->beginGroup("imgur");
- settings()->setValue("anonymous", settings()->value("account_username").toString().isEmpty());
- settings()->setValue("album" , ui.imgurOptions->ui.albumComboBox->property("currentData").toString());
+ settings()->setValue("anonymous", settings()->value("account_username").toString().isEmpty());
+ settings()->setValue("album" , ui.imgurOptions->ui.albumComboBox->property("currentData").toString());
+ settings()->endGroup();
+
+ settings()->beginGroup("pomf");
+ settings()->setValue("pomf_url", ui.pomfOptions->ui.pomfUrlComboBox->currentText());
settings()->endGroup();
settings()->endGroup();
@@ -576,6 +593,8 @@ void OptionsDialog::init()
// Version
ui.versionLabel->setText(tr("Version %1").arg(qApp->applicationVersion()));
+ ui.uploadSslWarningLabel->setVisible(!QSslSocket::supportsSsl());
+
setEnabled(false); // We disable the widgets to prevent any user interaction until the settings have loaded.
//
@@ -650,12 +669,13 @@ void OptionsDialog::init()
}
});
- connect(ui.mainLabel , &QLabel::linkActivated, this, &OptionsDialog::openUrl);
- connect(ui.licenseAboutLabel, &QLabel::linkActivated, this, &OptionsDialog::openUrl);
- connect(ui.linksLabel, &QLabel::linkActivated, this, &OptionsDialog::openUrl);
+ connect(ui.mainLabel , &QLabel::linkActivated, this, &OptionsDialog::openUrl);
+ connect(ui.licenseAboutLabel, &QLabel::linkActivated, this, &OptionsDialog::openUrl);
+ connect(ui.linksLabel, &QLabel::linkActivated, this, &OptionsDialog::openUrl);
+ connect(ui.uploadSslWarningLabel,&QLabel::linkActivated, this, &OptionsDialog::openUrl);
connect(ui.tabWidget, &QTabWidget::currentChanged, [&](int index) {
- if (index == 2 && !ui.imgurOptions->mCurrentUser.isEmpty() && ui.imgurOptions->ui.albumComboBox->count() == 1) {
+ if (index == 2 && ui.uploadServiceStackWidget->currentIndex() == 0 && !ui.imgurOptions->mCurrentUser.isEmpty() && ui.imgurOptions->ui.albumComboBox->count() == 1) {
QTimer::singleShot(20, ui.imgurOptions, &ImgurOptionsWidget::requestAlbumList);
}
});
diff --git a/dialogs/optionsdialog.ui b/dialogs/optionsdialog.ui
index f429608..071e5a8 100644
--- a/dialogs/optionsdialog.ui
+++ b/dialogs/optionsdialog.ui
@@ -6,7 +6,7 @@
0
0
- 399
+ 401
318
@@ -555,6 +555,22 @@ Quality is related to file size and of course to readability and overall quality
Upload
+ -
+
+
+
+ 75
+ true
+
+
+
+ QLabel { padding: 4px; border: 1px solid red; background-color: rgba(248, 182, 182, 60); }
+
+
+ WARNING: You have no SSL support, <a href="http://lightscreen.com.ar/help#SSL">click here</a> to learn more.
+
+
+
-
@@ -585,6 +601,11 @@ Quality is related to file size and of course to readability and overall quality
Imgur
+ -
+
+ Pomf-clone
+
+
-
@@ -624,7 +645,55 @@ Quality is related to file size and of course to readability and overall quality
4
-
-
+
+
+ 0
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
@@ -676,7 +745,7 @@ Quality is related to file size and of course to readability and overall quality
0
0
- 358
+ 360
706
@@ -1360,6 +1429,12 @@ Created by <a href="https://ckaiser.com.ar">Christian Kaiser<
widgets/imguroptionswidget.h
1
+
+ PomfOptionsWidget
+ QWidget
+ widgets/pomfoptionswidget.h
+ 1
+
fileGroupBox
@@ -1459,5 +1534,21 @@ Created by <a href="https://ckaiser.com.ar">Christian Kaiser<
+
+ uploadServiceComboBox
+ currentIndexChanged(int)
+ uploadServiceStackWidget
+ setCurrentIndex(int)
+
+
+ 92
+ 96
+
+
+ 198
+ 196
+
+
+
diff --git a/lightscreen.pro b/lightscreen.pro
index 85107b6..706c18e 100644
--- a/lightscreen.pro
+++ b/lightscreen.pro
@@ -16,8 +16,10 @@ HEADERS += dialogs/areadialog.h \
widgets/hotkeywidget.h \
tools/uploader/imageuploader.h \
tools/uploader/imguruploader.h \
+ tools/uploader/pomfuploader.h \
tools/uploader/uploader.h \
- widgets/imguroptionswidget.h
+ widgets/imguroptionswidget.h \
+ widgets/pomfoptionswidget.h
SOURCES += dialogs/areadialog.cpp \
dialogs/historydialog.cpp \
@@ -35,14 +37,17 @@ SOURCES += dialogs/areadialog.cpp \
widgets/hotkeywidget.cpp \
tools/uploader/imageuploader.cpp \
tools/uploader/imguruploader.cpp \
+ tools/uploader/pomfuploader.cpp \
tools/uploader/uploader.cpp \
- widgets/imguroptionswidget.cpp
+ widgets/imguroptionswidget.cpp \
+ widgets/pomfoptionswidget.cpp
FORMS += dialogs/historydialog.ui \
dialogs/namingdialog.ui \
dialogs/optionsdialog.ui \
lightscreenwindow.ui \
- widgets/imguroptions.ui
+ widgets/pomfoptionswidget.ui \
+ widgets/imguroptionswidget.ui
RESOURCES += lightscreen.qrc
CODECFORSRC = UTF-8
diff --git a/lightscreenwindow.cpp b/lightscreenwindow.cpp
index 73ad0b0..3a1310e 100644
--- a/lightscreenwindow.cpp
+++ b/lightscreenwindow.cpp
@@ -548,7 +548,7 @@ void LightscreenWindow::screenshotAction(int mode)
options.upload = settings()->value("options/uploadAuto", false).toBool();
options.optimize = settings()->value("options/optipng", false).toBool();
- options.uploadService = settings()->value("options/upload/service", "imgur").toString();
+ options.uploadService = Uploader::serviceName(settings()->value("upload/service", 0).toInt());
Screenshot::NamingOptions namingOptions;
namingOptions.naming = (Screenshot::Naming) settings()->value("file/naming").toInt();
@@ -780,7 +780,7 @@ void LightscreenWindow::updaterDone(bool result)
void LightscreenWindow::upload(const QString &fileName)
{
- Uploader::instance()->upload(fileName, settings()->value("options/upload/service", "imgur").toString());
+ Uploader::instance()->upload(fileName, Uploader::serviceName(settings()->value("upload/service", 0).toInt()));
}
void LightscreenWindow::uploadCancel()
diff --git a/tools/uploader/imageuploader.cpp b/tools/uploader/imageuploader.cpp
index 57d2eff..887b9e6 100644
--- a/tools/uploader/imageuploader.cpp
+++ b/tools/uploader/imageuploader.cpp
@@ -1,5 +1,6 @@
#include "imageuploader.h"
#include "imguruploader.h"
+#include "pomfuploader.h"
#include
#include "../screenshotmanager.h"
@@ -7,7 +8,9 @@
ImageUploader *ImageUploader::factory(const QString &name)
{
if (name == "imgur") {
- return new ImgurUploader(0);
+ return new ImgurUploader;
+ } else if (name == "pomf") {
+ return new PomfUploader;
}
return 0;
diff --git a/tools/uploader/imguruploader.cpp b/tools/uploader/imguruploader.cpp
index b82c6a6..5c839ca 100644
--- a/tools/uploader/imguruploader.cpp
+++ b/tools/uploader/imguruploader.cpp
@@ -105,6 +105,7 @@ void ImgurUploader::upload(const QString &fileName)
QNetworkReply *reply = Uploader::instance()->nam()->post(request, multiPart);
reply->setProperty("fileName", fileName);
this->setProperty("fileName", fileName);
+ multiPart->setParent(reply);
connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64)));
connect(this , SIGNAL(cancelRequest()), reply, SLOT(abort()));
@@ -177,6 +178,8 @@ void ImgurUploader::uploadProgress(qint64 bytesReceived, qint64 bytesTotal)
void ImgurUploader::authorizationReply(QNetworkReply *reply, AuthorizationCallback callback)
{
+ reply->deleteLater();
+
connect(reply, &QNetworkReply::finished, [reply, callback] {
bool authorized = false;
diff --git a/tools/uploader/imguruploader.h b/tools/uploader/imguruploader.h
index 82e916c..4f9dd59 100644
--- a/tools/uploader/imguruploader.h
+++ b/tools/uploader/imguruploader.h
@@ -14,7 +14,7 @@ class ImgurUploader : public ImageUploader
public:
typedef std::function AuthorizationCallback;
- ImgurUploader(QObject *parent);
+ ImgurUploader(QObject *parent = 0);
static const QString clientId();
static const QString clientSecret();
static void authorize(const QString &pin, AuthorizationCallback callback);
diff --git a/tools/uploader/pomfuploader.cpp b/tools/uploader/pomfuploader.cpp
new file mode 100644
index 0000000..59d49d0
--- /dev/null
+++ b/tools/uploader/pomfuploader.cpp
@@ -0,0 +1,121 @@
+#include "pomfuploader.h"
+#include "../uploader/uploader.h"
+
+#include
+#include
+#include
+
+PomfUploader::PomfUploader(QObject *parent) : ImageUploader(parent)
+{
+ mUploaderType = "pomf";
+ loadSettings();
+}
+
+void PomfUploader::verify(const QString &url, VerificationCallback callback)
+{
+ QNetworkRequest request(QUrl::fromUserInput(QString("%1/upload.php").arg(url)));
+
+ if (!request.url().isValid()) {
+ callback(false);
+ }
+
+ QNetworkReply *reply = Uploader::instance()->nam()->get(request);
+
+ connect(reply, &QNetworkReply::finished, [reply, callback] {
+ reply->deleteLater();
+
+ const QJsonObject pomfResponse = QJsonDocument::fromJson(reply->readAll()).object();
+
+ if (!pomfResponse.isEmpty() && pomfResponse.contains("success")) {
+ callback(true);
+ } else {
+ callback(false);
+ }
+ });
+}
+
+void PomfUploader::upload(const QString &fileName)
+{
+ QString pomfUrl = mSettings["pomf_url"].toString();
+
+ if (pomfUrl.isEmpty()) {
+ emit error(ImageUploader::HostError, tr("Invalid pomf uploader URL!"), fileName);
+ return;
+ }
+
+ QUrl url = QUrl::fromUserInput(pomfUrl + "/upload.php");
+
+ QFile *file = new QFile(fileName);
+
+ if (!file->open(QIODevice::ReadOnly)) {
+ emit error(ImageUploader::FileError, tr("Unable to read screenshot file"), fileName);
+ file->deleteLater();
+ return;
+ }
+
+ QNetworkRequest request(url);
+
+ QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
+
+ QHttpPart imagePart;
+ imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QMimeDatabase().mimeTypeForFile(fileName, QMimeDatabase::MatchExtension).name());
+ imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"files[]\"; filename=\"%1\"").arg(QFileInfo(fileName).fileName()));
+ imagePart.setBodyDevice(file);
+
+ file->setParent(multiPart);
+ multiPart->append(imagePart);
+
+ QNetworkReply *reply = Uploader::instance()->nam()->post(request, multiPart);
+ this->setProperty("fileName", fileName);
+ multiPart->setParent(reply);
+
+ connect(this , &PomfUploader::cancelRequest, reply, &QNetworkReply::abort);
+ connect(this , &PomfUploader::cancelRequest, reply, &QNetworkReply::deleteLater);
+
+ connect(reply, &QNetworkReply::uploadProgress, this, [&](qint64 bytesSent, qint64 bytesTotal) {
+ float b = (float) bytesSent / bytesTotal;
+ int p = qRound(b * 100);
+ setProgress(p);
+ });
+
+ connect(reply, &QNetworkReply::finished, this, [&, reply, fileName] {
+ const QJsonObject pomfResponse = QJsonDocument::fromJson(reply->readAll()).object();
+
+ if (reply->error() != QNetworkReply::NoError && pomfResponse.isEmpty()) {
+ emit error(ImageUploader::NetworkError, tr("Error reaching uploader"), fileName);
+ return;
+ }
+
+ if (!pomfResponse.contains("success") || !pomfResponse.contains("files")) {
+ emit error(ImageUploader::HostError, tr("Invalid response from uploader"), fileName);
+ return;
+ }
+
+ if (pomfResponse["success"].toBool()) {
+ emit uploaded(fileName, pomfResponse["files"].toArray().at(0).toObject()["url"].toString(), "");
+ } else {
+ QString description;
+
+ if (pomfResponse.contains("description")) {
+ description = pomfResponse["description"].toString();
+ }
+
+ if (description.isEmpty()) {
+ description = tr("Host error");
+ }
+
+ emit error(ImageUploader::HostError, description, fileName);
+ }
+ });
+}
+
+void PomfUploader::retry()
+{
+ upload(property("fileName").toString());
+}
+
+void PomfUploader::cancel()
+{
+ emit cancelRequest();
+}
+
diff --git a/tools/uploader/pomfuploader.h b/tools/uploader/pomfuploader.h
new file mode 100644
index 0000000..5b746e1
--- /dev/null
+++ b/tools/uploader/pomfuploader.h
@@ -0,0 +1,27 @@
+#ifndef POMFUPLOADER_H
+#define POMFUPLOADER_H
+
+#include "imageuploader.h"
+#include
+
+class PomfUploader : public ImageUploader
+{
+ Q_OBJECT
+
+public:
+ PomfUploader(QObject *parent = 0);
+
+ typedef std::function VerificationCallback;
+ static void verify(const QString &url, VerificationCallback callback);
+
+public slots:
+ void upload(const QString &fileName);
+ void retry();
+ void cancel();
+
+signals:
+ void cancelRequest();
+
+};
+
+#endif // POMFUPLOADER_H
diff --git a/tools/uploader/uploader.cpp b/tools/uploader/uploader.cpp
index 506d1be..8332cc3 100644
--- a/tools/uploader/uploader.cpp
+++ b/tools/uploader/uploader.cpp
@@ -49,6 +49,17 @@ QNetworkAccessManager *Uploader::nam()
return mNetworkAccessManager;
}
+QString Uploader::serviceName(int index)
+{ // TODO: Move somewhere else? Use indexes everywhere? an enum?
+ switch (index) {
+ case 1:
+ return "pomf";
+ case 0:
+ default:
+ return "imgur";
+ }
+}
+
QString Uploader::lastUrl() const
{
return mLastUrl;
diff --git a/tools/uploader/uploader.h b/tools/uploader/uploader.h
index 3c001f2..0951136 100644
--- a/tools/uploader/uploader.h
+++ b/tools/uploader/uploader.h
@@ -33,6 +33,7 @@ class Uploader : public QObject
QString lastUrl() const;
int progress() const;
QNetworkAccessManager *nam();
+ static QString serviceName(int index);
public slots:
void cancel();
diff --git a/widgets/imguroptionswidget.cpp b/widgets/imguroptionswidget.cpp
index 8b48274..6520c95 100644
--- a/widgets/imguroptionswidget.cpp
+++ b/widgets/imguroptionswidget.cpp
@@ -71,7 +71,10 @@ void ImgurOptionsWidget::authorize()
ui.authButton->setText(tr("Authorizing.."));
ui.authButton->setEnabled(false);
- ImgurUploader::authorize(pin, [&](bool result) {
+ QPointer guard(parentWidget());
+ ImgurUploader::authorize(pin, [&, guard](bool result) {
+ if (guard.isNull()) return;
+
ui.authButton->setEnabled(true);
if (result) {
@@ -100,9 +103,10 @@ void ImgurOptionsWidget::requestAlbumList()
request.setRawHeader("Authorization", QByteArray("Bearer ") + settings()->value("upload/imgur/access_token").toByteArray());
QNetworkReply *reply = Uploader::instance()->nam()->get(request);
+ QPointer guard(parentWidget());
- connect(reply, &QNetworkReply::finished, this, [&, reply] {
- if (mCurrentUser.isEmpty()) return;
+ connect(reply, &QNetworkReply::finished, this, [&, guard, reply] {
+ if (mCurrentUser.isEmpty() || guard.isNull()) return;
if (reply->error() != QNetworkReply::NoError)
{
diff --git a/widgets/imguroptionswidget.h b/widgets/imguroptionswidget.h
index 1c3fed9..bea88f0 100644
--- a/widgets/imguroptionswidget.h
+++ b/widgets/imguroptionswidget.h
@@ -1,8 +1,9 @@
-#ifndef IMGUROPTIONS_H
-#define IMGUROPTIONS_H
+#ifndef IMGUROPTIONSWIDGET_H
+#define IMGUROPTIONSWIDGET_H
#include
-#include "ui_imguroptions.h"
+
+#include "ui_imguroptionswidget.h"
class QSettings;
class ImgurOptionsWidget : public QWidget
@@ -23,4 +24,4 @@ private slots:
friend class OptionsDialog;
};
-#endif // IMGUROPTIONS_H
+#endif // IMGUROPTIONSWIDGET_H
diff --git a/widgets/imguroptions.ui b/widgets/imguroptionswidget.ui
similarity index 100%
rename from widgets/imguroptions.ui
rename to widgets/imguroptionswidget.ui
diff --git a/widgets/pomfoptionswidget.cpp b/widgets/pomfoptionswidget.cpp
new file mode 100644
index 0000000..83c58ab
--- /dev/null
+++ b/widgets/pomfoptionswidget.cpp
@@ -0,0 +1,61 @@
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include "pomfoptionswidget.h"
+#include "../uploader/uploader.h"
+#include "../uploader/pomfuploader.h"
+
+#include "../screenshotmanager.h"
+#include "../os.h"
+
+PomfOptionsWidget::PomfOptionsWidget(QWidget *parent) : QWidget(parent)
+{
+ ui.setupUi(this);
+
+ connect(ui.verifyButton, &QPushButton::clicked, this, [&]() {
+ ui.verifyButton->setEnabled(false);
+ ui.pomfUrlComboBox->setEnabled(false);
+
+ QPointer guard(parentWidget());
+ PomfUploader::verify(ui.pomfUrlComboBox->currentText(), [&, guard](bool result) {
+ if (guard.isNull()) return;
+
+ ui.verifyButton->setEnabled(true);
+ ui.pomfUrlComboBox->setEnabled(true);
+
+ if (result) {
+ ui.verifyButton->setText(tr("Valid uploader!"));
+ ui.verifyButton->setStyleSheet("color: green;");
+ ui.verifyButton->setIcon(os::icon("yes"));
+ } else {
+ ui.verifyButton->setStyleSheet("color: red;");
+ ui.verifyButton->setIcon(os::icon("no"));
+ ui.verifyButton->setText(tr("Invalid :("));
+ }
+ });
+ });
+
+ connect(ui.pomfUrlComboBox, &QComboBox::currentTextChanged, [&](const QString &text) {
+ bool validUrl = false;
+ if (text.startsWith("http://") || text.startsWith("https://")) { // TODO: Something a bit more complex
+ validUrl = true;
+ }
+
+ ui.visitButton->setEnabled(validUrl);
+ ui.verifyButton->setEnabled(validUrl);
+
+ if (ui.verifyButton->styleSheet().count() > 0) {
+ ui.verifyButton->setStyleSheet("");
+ ui.verifyButton->setIcon(QIcon());
+ ui.verifyButton->setText(tr("Verify"));
+ }
+ });
+
+ connect(ui.visitButton, &QPushButton::clicked, this, [&]() {
+ QDesktopServices::openUrl(ui.pomfUrlComboBox->currentText());
+ });
+}
diff --git a/widgets/pomfoptionswidget.h b/widgets/pomfoptionswidget.h
new file mode 100644
index 0000000..38d13c8
--- /dev/null
+++ b/widgets/pomfoptionswidget.h
@@ -0,0 +1,18 @@
+#ifndef POMFOPTIONSWIDGET_H
+#define POMFOPTIONSWIDGET_H
+
+#include
+#include "ui_pomfoptionswidget.h"
+
+class PomfOptionsWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit PomfOptionsWidget(QWidget *parent = 0);
+
+private:
+ Ui::PomfOptions ui;
+ friend class OptionsDialog;
+};
+
+#endif // POMFOPTIONSWIDGET_H
diff --git a/widgets/pomfoptionswidget.ui b/widgets/pomfoptionswidget.ui
new file mode 100644
index 0000000..2956498
--- /dev/null
+++ b/widgets/pomfoptionswidget.ui
@@ -0,0 +1,66 @@
+
+
+ PomfOptions
+
+
+
+ 0
+ 0
+ 305
+ 75
+
+
+
+ Form
+
+
+ -
+
+
+ Pomf Clone URL:
+
+
+
+ -
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+ Visit Site
+
+
+
+ -
+
+
+ Verify
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 198
+ 97
+
+
+
+
+
+
+
+
+