Redesigned uploaders a bit to support more stuff.
Added a functionality of uploading byte arrays and even files. Created RecordingFormat, which allows me to create states, I guess??, for RecordingContex's. Needed for, eg. gifs, which are horrible and I strongly suggest against, which will actually be stored as files per frame which are QImages encoded with QImage::Format_RGB888 (confirmation needed).
This commit is contained in:
parent
8f5197b826
commit
34624e5762
@ -50,7 +50,8 @@ SOURCES += main.cpp\
|
||||
worker/worker.cpp \
|
||||
screenareaselector/screenareaselector.cpp \
|
||||
recording/recordingpreview.cpp \
|
||||
recording/recordingcontroller.cpp
|
||||
recording/recordingcontroller.cpp \
|
||||
recording/recordingformats.cpp
|
||||
|
||||
HEADERS += mainwindow.hpp \
|
||||
cropeditor/cropeditor.hpp \
|
||||
@ -82,7 +83,8 @@ HEADERS += mainwindow.hpp \
|
||||
worker/worker.hpp \
|
||||
screenareaselector/screenareaselector.hpp \
|
||||
recording/recordingpreview.hpp \
|
||||
recording/recordingcontroller.hpp
|
||||
recording/recordingcontroller.hpp \
|
||||
recording/recordingformats.hpp
|
||||
|
||||
mac {
|
||||
SOURCES += $$PWD/platformspecifics/mac/macbackend.cpp
|
||||
|
@ -37,5 +37,7 @@ bool hotkeying::valid(QString seq) {
|
||||
}
|
||||
|
||||
QString hotkeying::sequence(QString seqName) {
|
||||
return hotkeys.contains(seqName) ? hotkeys.value(seqName)->shortcut().toString() : "";
|
||||
return hotkeys.contains(seqName) ?
|
||||
hotkeys.value(seqName)->isRegistered() ? hotkeys.value(seqName)->shortcut().toString() : "" :
|
||||
"";
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>512</width>
|
||||
<height>399</height>
|
||||
<height>410</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -25,6 +25,18 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="9" column="1">
|
||||
<widget class="QComboBox" name="comboBox">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Recording disabled</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLineEdit" name="nameScheme">
|
||||
<property name="toolTip">
|
||||
@ -63,7 +75,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<item row="11" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string><a href="https://github.com/ArsenArsen/KShare">Source code available free for everyone. Forever.</a>
|
||||
@ -92,13 +104,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="hideToTray">
|
||||
<property name="text">
|
||||
<string>Pressing <X> hides to tray</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="5">
|
||||
<widget class="QListWidget" name="hotkeys"/>
|
||||
</item>
|
||||
@ -112,13 +117,27 @@
|
||||
<item row="1" column="0">
|
||||
<widget class="QListWidget" name="uploaderList"/>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<item row="9" column="0">
|
||||
<widget class="QCheckBox" name="captureCursor">
|
||||
<property name="text">
|
||||
<string>Capture cursor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QCheckBox" name="hideToTray">
|
||||
<property name="text">
|
||||
<string>Pressing <X> hides to tray</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1" rowspan="2">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Recording format</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
@ -127,7 +146,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>512</width>
|
||||
<height>24</height>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <screenshotutil.hpp>
|
||||
#include <settings.hpp>
|
||||
#include <stdio.h>
|
||||
#include <uploaders/uploadersingleton.hpp>
|
||||
#include <worker/worker.hpp>
|
||||
|
||||
RecordingController::RecordingController() : timer(this) {
|
||||
@ -33,7 +34,7 @@ bool RecordingController::end() {
|
||||
area = QRect();
|
||||
preview->close();
|
||||
preview = 0;
|
||||
_context->finalizer();
|
||||
UploaderSingleton::inst().upload(_context->finalizer());
|
||||
frame = 0;
|
||||
time = 0;
|
||||
return true;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "recordingpreview.hpp"
|
||||
|
||||
#include <QFile>
|
||||
#include <QImage>
|
||||
#include <QRect>
|
||||
#include <QTimer>
|
||||
@ -13,7 +14,7 @@ class RecordingContext {
|
||||
public:
|
||||
QImage::Format format;
|
||||
std::function<void(QImage)> consumer;
|
||||
std::function<void()> finalizer;
|
||||
std::function<QFile()> finalizer;
|
||||
};
|
||||
|
||||
class RecordingController : public QObject {
|
||||
|
35
recording/recordingformats.cpp
Normal file
35
recording/recordingformats.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "recordingformats.hpp"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
RecordingFormats::RecordingFormats(RecordingFormats::Format f) {
|
||||
switch (f) {
|
||||
case GIF:
|
||||
// TODO
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::function<void(QImage)> RecordingFormats::getConsumer() {
|
||||
return consumer;
|
||||
}
|
||||
|
||||
std::function<QFile()> RecordingFormats::getFinalizer() {
|
||||
return finalizer;
|
||||
}
|
||||
|
||||
QString RecordingFormats::getPrettyName(RecordingFormats::Format f) {
|
||||
switch (f) {
|
||||
case None:
|
||||
return "None";
|
||||
break;
|
||||
case GIF:
|
||||
return "gif";
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
break;
|
||||
}
|
||||
}
|
23
recording/recordingformats.hpp
Normal file
23
recording/recordingformats.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef RECORDINGFORMATS_HPP
|
||||
#define RECORDINGFORMATS_HPP
|
||||
|
||||
#include <QFile>
|
||||
#include <QImage>
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
|
||||
class RecordingFormats {
|
||||
public:
|
||||
enum Format { None, GIF };
|
||||
RecordingFormats(Format f);
|
||||
std::function<void(QImage)> getConsumer();
|
||||
std::function<QByteArray()> getFinalizer();
|
||||
|
||||
static QString getPrettyName(Format f);
|
||||
|
||||
private:
|
||||
std::function<void(QImage)> consumer;
|
||||
std::function<QByteArray()> finalizer;
|
||||
};
|
||||
|
||||
#endif // RECORDINGFORMATS_HPP
|
@ -64,11 +64,11 @@ CustomUploader::CustomUploader(QString absFilePath) {
|
||||
if (formatValue.isString()) {
|
||||
QString formatString = formatValue.toString().toLower();
|
||||
if (formatString == "x-www-form-urlencoded")
|
||||
format = RequestFormat::X_WWW_FORM_URLENCODED;
|
||||
rFormat = RequestFormat::X_WWW_FORM_URLENCODED;
|
||||
else if (formatString == "json")
|
||||
format = RequestFormat::JSON;
|
||||
rFormat = RequestFormat::JSON;
|
||||
else if (formatString == "plain")
|
||||
format = RequestFormat::PLAIN;
|
||||
rFormat = RequestFormat::PLAIN;
|
||||
else
|
||||
error(absFilePath, "format invalid");
|
||||
}
|
||||
@ -85,7 +85,7 @@ CustomUploader::CustomUploader(QString absFilePath) {
|
||||
} else
|
||||
error(absFilePath, "imageformat invalid");
|
||||
QJsonValue bodyValue = obj["body"];
|
||||
if (format != RequestFormat::PLAIN) {
|
||||
if (rFormat != RequestFormat::PLAIN) {
|
||||
if (bodyValue.isUndefined()) error(absFilePath, "body not set");
|
||||
if (bodyValue.isObject())
|
||||
body = bodyValue;
|
||||
@ -123,6 +123,10 @@ QString CustomUploader::description() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
std::tuple<QString, QString> CustomUploader::format() {
|
||||
return std::tuple<QString, QString>(getFormatString(false), getFormatString(true));
|
||||
}
|
||||
|
||||
QString getCType(RequestFormat format, QString plainType) {
|
||||
switch (format) {
|
||||
case RequestFormat::X_WWW_FORM_URLENCODED:
|
||||
@ -149,14 +153,6 @@ QList<QPair<QString, QString>> getHeaders(QJsonObject h, QString imageFormat, QM
|
||||
return headers;
|
||||
}
|
||||
|
||||
QByteArray imageBytes(QPixmap *pixmap, QString format) {
|
||||
QByteArray returnVal;
|
||||
QBuffer buff(&returnVal);
|
||||
buff.open(QIODevice::WriteOnly);
|
||||
pixmap->save(&buff, format.toUpper().toLocal8Bit().constData());
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
QString CustomUploader::getFormatString(bool animated) {
|
||||
if (iFormat == "base64")
|
||||
return animated ? "GIF" : "PNG";
|
||||
@ -238,13 +234,12 @@ void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec,
|
||||
}
|
||||
}
|
||||
|
||||
void CustomUploader::doUpload(QPixmap *pixmap) {
|
||||
auto h = getHeaders(headers, getFormatString(false), types, this->format);
|
||||
void CustomUploader::doUpload(QByteArray imgData) {
|
||||
auto h = getHeaders(headers, getFormatString(false), types, this->rFormat);
|
||||
QString format = getFormatString(false); // Soon:tm:
|
||||
QByteArray data;
|
||||
QByteArray imgData = imageBytes(pixmap, format);
|
||||
if (iFormat == "base64" || QRegExp("base64\\([^+]\\+[^+]\\)").exactMatch(iFormat)) imgData = imgData.toBase64();
|
||||
switch (this->format) {
|
||||
switch (this->rFormat) {
|
||||
case RequestFormat::PLAIN: {
|
||||
data = imgData;
|
||||
} break;
|
||||
|
@ -11,19 +11,20 @@ enum class HttpMethod { POST };
|
||||
enum class RequestFormat { X_WWW_FORM_URLENCODED, JSON, PLAIN };
|
||||
|
||||
class CustomUploader : public Uploader {
|
||||
public:
|
||||
public:
|
||||
CustomUploader(QString absFilePath);
|
||||
QString name();
|
||||
QString description();
|
||||
void doUpload(QPixmap *pixmap);
|
||||
std::tuple<QString, QString> format();
|
||||
void doUpload(QByteArray imgData);
|
||||
QString getFormatString(bool animated);
|
||||
QMap<QString, QString> types;
|
||||
|
||||
private:
|
||||
private:
|
||||
double limit = -1;
|
||||
QString desc;
|
||||
QString uName;
|
||||
RequestFormat format = RequestFormat::JSON;
|
||||
RequestFormat rFormat = RequestFormat::JSON;
|
||||
HttpMethod method = HttpMethod::POST;
|
||||
QUrl target;
|
||||
QJsonValue body;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QClipboard>
|
||||
#include <notifications.hpp>
|
||||
|
||||
void ClipboardUploader::doUpload(QPixmap *pixmap) {
|
||||
QApplication::clipboard()->setImage(pixmap->toImage());
|
||||
void ClipboardUploader::doUpload(QByteArray imgData) {
|
||||
QApplication::clipboard()->setImage(QImage::fromData(imgData, std::get<0>(format()).toLocal8Bit().constData()));
|
||||
notifications::notify("KShare", "Copied to clipboard!");
|
||||
}
|
||||
|
@ -5,14 +5,18 @@
|
||||
#include <uploaders/uploader.hpp>
|
||||
|
||||
class ClipboardUploader : public Uploader {
|
||||
public:
|
||||
public:
|
||||
QString name() {
|
||||
return "clipboard";
|
||||
}
|
||||
QString description() {
|
||||
return "Copies the image to clipboard";
|
||||
}
|
||||
void doUpload(QPixmap *pixmap);
|
||||
std::tuple<QString, QString> format() {
|
||||
return std::tuple<QString, QString>("PNG", "MP4");
|
||||
}
|
||||
|
||||
void doUpload(QByteArray imgData);
|
||||
};
|
||||
|
||||
#endif // CLIPBOARDUPLOADER_HPP
|
||||
|
@ -7,20 +7,19 @@
|
||||
#include <notifications.hpp>
|
||||
#include <screenshotutil.hpp>
|
||||
|
||||
void ImgurUploader::doUpload(QPixmap *pixmap) {
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
pixmap->save(&buffer, "PNG");
|
||||
if (buffer.size() > 1e+7) {
|
||||
void ImgurUploader::doUpload(QByteArray byteArray) {
|
||||
if (byteArray.size() > 1e+7) {
|
||||
notifications::notify("KShare imgur Uploader ", "Failed upload! Image too big");
|
||||
return;
|
||||
}
|
||||
ioutils::postJson(QUrl("https://api.imgur.com/3/image"),
|
||||
QList<QPair<QString, QString>>() << QPair<QString, QString>("Content-Type", "application/x-www-form-urlencoded")
|
||||
<< QPair<QString, QString>("Authorization", "Client-ID 8a98f183fc895da"),
|
||||
QList<QPair<QString, QString>>()
|
||||
<< QPair<QString, QString>("Content-Type", "application/x-www-form-urlencoded")
|
||||
<< QPair<QString, QString>("Authorization", "Client-ID 8a98f183fc895da"),
|
||||
byteArray, [](QJsonDocument res, QByteArray, QNetworkReply *) {
|
||||
QString result = res.object()["data"].toObject()["link"].toString();
|
||||
screenshotutil::toClipboard(result);
|
||||
notifications::notify("KShare imgur Uploader ", result.isEmpty() ? "Failed upload!" : "Uploaded to imgur!");
|
||||
notifications::notify("KShare imgur Uploader ",
|
||||
result.isEmpty() ? "Failed upload!" : "Uploaded to imgur!");
|
||||
});
|
||||
}
|
||||
|
@ -4,14 +4,17 @@
|
||||
#include "../uploader.hpp"
|
||||
|
||||
class ImgurUploader : public Uploader {
|
||||
public:
|
||||
public:
|
||||
QString name() {
|
||||
return "imgur";
|
||||
}
|
||||
QString description() {
|
||||
return "imgur.com uploader";
|
||||
}
|
||||
void doUpload(QPixmap *pixmap);
|
||||
std::tuple<QString, QString> format() {
|
||||
return std::tuple<QString, QString>("PNG", "MP4");
|
||||
}
|
||||
void doUpload(QByteArray byteArray);
|
||||
};
|
||||
|
||||
#endif // IMGURUPLOADER_HPP
|
||||
|
@ -5,10 +5,11 @@
|
||||
#include <QString>
|
||||
|
||||
class Uploader {
|
||||
public:
|
||||
virtual void doUpload(QPixmap *pixmap) = 0;
|
||||
public:
|
||||
virtual void doUpload(QByteArray imgData) = 0;
|
||||
virtual QString name() = 0;
|
||||
virtual QString description() = 0;
|
||||
virtual std::tuple<QString, QString> format() = 0;
|
||||
};
|
||||
|
||||
#endif // UPLOADER_HPP
|
||||
|
@ -2,13 +2,15 @@
|
||||
#include "customuploader.hpp"
|
||||
#include "default/clipboarduploader.hpp"
|
||||
#include "default/imguruploader.hpp"
|
||||
#include <QBuffer>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <formatter.hpp>
|
||||
#include <settings.hpp>
|
||||
|
||||
UploaderSingleton::UploaderSingleton() : QObject(), saveDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)) {
|
||||
UploaderSingleton::UploaderSingleton()
|
||||
: QObject(), saveDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)) {
|
||||
if (QStandardPaths::writableLocation(QStandardPaths::PicturesLocation).isEmpty()) {
|
||||
qFatal("Cannot determine location for pictures");
|
||||
}
|
||||
@ -54,16 +56,30 @@ void UploaderSingleton::registerUploader(Uploader *uploader) {
|
||||
}
|
||||
|
||||
void UploaderSingleton::upload(QPixmap *pixmap) {
|
||||
if (settings::settings().contains("fileFormat")) {
|
||||
QString format = settings::settings().value("fileFormat").toString();
|
||||
if (!format.isEmpty()) {
|
||||
pixmap->save(saveDir.absoluteFilePath(formatter::format(format) + ".png"), "PNG");
|
||||
}
|
||||
}
|
||||
uploaders.value(uploader)->doUpload(pixmap);
|
||||
auto u = uploaders.value(uploader);
|
||||
QByteArray arr;
|
||||
QBuffer data(&arr);
|
||||
pixmap->save(&data, std::get<0>(u->format()).toLocal8Bit().constData());
|
||||
u->doUpload(arr);
|
||||
data.close();
|
||||
delete pixmap;
|
||||
}
|
||||
|
||||
void UploaderSingleton::upload(QByteArray img) {
|
||||
uploaders.value(uploader)->doUpload(img);
|
||||
}
|
||||
|
||||
void UploaderSingleton::upload(QFile img) {
|
||||
if (img.open(QIODevice::ReadOnly)) {
|
||||
uploaders.value(uploader)->doUpload(img.readAll());
|
||||
img.close();
|
||||
}
|
||||
}
|
||||
|
||||
std::tuple<QString, QString> UploaderSingleton::format() {
|
||||
return uploaders.value(uploader)->format();
|
||||
}
|
||||
|
||||
QList<Uploader *> UploaderSingleton::uploaderList() {
|
||||
return uploaders.values();
|
||||
}
|
||||
|
@ -7,21 +7,24 @@
|
||||
|
||||
class UploaderSingleton : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
public:
|
||||
static UploaderSingleton &inst() {
|
||||
static UploaderSingleton inst;
|
||||
return inst;
|
||||
}
|
||||
void registerUploader(Uploader *uploader);
|
||||
void upload(QPixmap *pixmap);
|
||||
void upload(QByteArray img);
|
||||
void upload(QFile img);
|
||||
virtual std::tuple<QString, QString> format();
|
||||
QList<Uploader *> uploaderList();
|
||||
void set(QString uploader);
|
||||
QString selectedUploader();
|
||||
QList<std::runtime_error> errors();
|
||||
signals:
|
||||
signals:
|
||||
void newUploader(Uploader *u);
|
||||
|
||||
private:
|
||||
private:
|
||||
QDir saveDir;
|
||||
UploaderSingleton();
|
||||
QMap<QString, Uploader *> uploaders;
|
||||
|
Loading…
Reference in New Issue
Block a user