Rewrite in order to support user-selected formats
This commit is contained in:
parent
1d059cc08a
commit
0b09000729
@ -51,7 +51,8 @@ SOURCES += main.cpp\
|
|||||||
screenareaselector/screenareaselector.cpp \
|
screenareaselector/screenareaselector.cpp \
|
||||||
recording/recordingpreview.cpp \
|
recording/recordingpreview.cpp \
|
||||||
recording/recordingcontroller.cpp \
|
recording/recordingcontroller.cpp \
|
||||||
recording/recordingformats.cpp
|
recording/recordingformats.cpp \
|
||||||
|
formats.cpp
|
||||||
|
|
||||||
HEADERS += mainwindow.hpp \
|
HEADERS += mainwindow.hpp \
|
||||||
cropeditor/cropeditor.hpp \
|
cropeditor/cropeditor.hpp \
|
||||||
@ -84,7 +85,8 @@ HEADERS += mainwindow.hpp \
|
|||||||
screenareaselector/screenareaselector.hpp \
|
screenareaselector/screenareaselector.hpp \
|
||||||
recording/recordingpreview.hpp \
|
recording/recordingpreview.hpp \
|
||||||
recording/recordingcontroller.hpp \
|
recording/recordingcontroller.hpp \
|
||||||
recording/recordingformats.hpp
|
recording/recordingformats.hpp \
|
||||||
|
formats.hpp
|
||||||
|
|
||||||
mac {
|
mac {
|
||||||
SOURCES += $$PWD/platformspecifics/mac/macbackend.cpp
|
SOURCES += $$PWD/platformspecifics/mac/macbackend.cpp
|
||||||
|
63
formats.cpp
Normal file
63
formats.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#include <formats.hpp>
|
||||||
|
|
||||||
|
QString formats::normalFormatName(formats::Normal format) {
|
||||||
|
switch (format) {
|
||||||
|
case Normal::JPG:
|
||||||
|
return "JPG";
|
||||||
|
break;
|
||||||
|
case Normal::PNG:
|
||||||
|
return "PNG";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return QString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formats::Normal formats::normalFormatFromName(QString format) {
|
||||||
|
if (format.toLower() == "jpg") return Normal::JPG;
|
||||||
|
if (format.toLower() == "jpeg") return Normal::JPG;
|
||||||
|
if (format.toLower() == "png") return Normal::PNG;
|
||||||
|
return Normal::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString formats::normalFormatMIME(formats::Normal format) {
|
||||||
|
switch (format) {
|
||||||
|
case Normal::JPG:
|
||||||
|
return "image/jpeg";
|
||||||
|
break;
|
||||||
|
case Normal::PNG:
|
||||||
|
return "image/png";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return QString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString formats::recordingFormatName(formats::Recording format) {
|
||||||
|
switch (format) {
|
||||||
|
case Recording::GIF:
|
||||||
|
return "GIF";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return QString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formats::Recording formats::recordingFormatFromName(QString format) {
|
||||||
|
if (format.toLower() == "gif") return Recording::GIF;
|
||||||
|
return Recording::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString formats::recordingFormatMIME(formats::Recording format) {
|
||||||
|
switch (format) {
|
||||||
|
case Recording::GIF:
|
||||||
|
return "image/gif";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return QString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
17
formats.hpp
Normal file
17
formats.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef FORMATS_HPP
|
||||||
|
#define FORMATS_HPP
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace formats {
|
||||||
|
enum class Normal { PNG, JPG, None };
|
||||||
|
QString normalFormatName(Normal format);
|
||||||
|
Normal normalFormatFromName(QString format);
|
||||||
|
QString normalFormatMIME(Normal format);
|
||||||
|
|
||||||
|
enum class Recording { GIF, None };
|
||||||
|
QString recordingFormatName(Recording format);
|
||||||
|
Recording recordingFormatFromName(QString format);
|
||||||
|
QString recordingFormatMIME(Recording format);
|
||||||
|
}
|
||||||
|
#endif // FORMATS_HPP
|
@ -3,7 +3,7 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
QString formatter::format(QString toFormat) {
|
QString formatter::format(QString toFormat, QString ext) {
|
||||||
QRegExp dateRegex("%\\((.+)\\)date");
|
QRegExp dateRegex("%\\((.+)\\)date");
|
||||||
dateRegex.indexIn(toFormat);
|
dateRegex.indexIn(toFormat);
|
||||||
QStringList capturedTexts(dateRegex.capturedTexts());
|
QStringList capturedTexts(dateRegex.capturedTexts());
|
||||||
@ -12,5 +12,6 @@ QString formatter::format(QString toFormat) {
|
|||||||
for (int i = 0; i < capturedTexts.length(); i += 2) {
|
for (int i = 0; i < capturedTexts.length(); i += 2) {
|
||||||
formatted = formatted.replace(capturedTexts.at(i), date.toString(capturedTexts.at(i + 1)));
|
formatted = formatted.replace(capturedTexts.at(i), date.toString(capturedTexts.at(i + 1)));
|
||||||
}
|
}
|
||||||
|
formatted = formatted.replace(QRegExp("%(?!%)ext"), ext);
|
||||||
return formatted;
|
return formatted;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace formatter {
|
namespace formatter {
|
||||||
QString format(QString toFormat);
|
QString format(QString toFormat, QString ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FORMATTER_HPP
|
#endif // FORMATTER_HPP
|
||||||
|
3
main.cpp
3
main.cpp
@ -2,7 +2,9 @@
|
|||||||
#include "screenshotutil.hpp"
|
#include "screenshotutil.hpp"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
|
#include <QDebug>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
#include <formatter.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <notifications.hpp>
|
#include <notifications.hpp>
|
||||||
#include <worker/worker.hpp>
|
#include <worker/worker.hpp>
|
||||||
@ -56,7 +58,6 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
verbose = parser.isSet(v);
|
verbose = parser.isSet(v);
|
||||||
|
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
Worker::init();
|
Worker::init();
|
||||||
a.connect(&a, &QApplication::aboutToQuit, Worker::end);
|
a.connect(&a, &QApplication::aboutToQuit, Worker::end);
|
||||||
|
@ -91,15 +91,16 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
addHotkeyItem("Color picker", "picker", [] { ColorPickerScene::showPicker(); });
|
addHotkeyItem("Color picker", "picker", [] { ColorPickerScene::showPicker(); });
|
||||||
addHotkeyItem("Stop Recording", "recordingstop", [&] { controller->end(); });
|
addHotkeyItem("Stop Recording", "recordingstop", [&] { controller->end(); });
|
||||||
addHotkeyItem("Start Recording", "recordingstart", [&] {
|
addHotkeyItem("Start Recording", "recordingstart", [&] {
|
||||||
auto f = static_cast<RecordingFormats::Format>(
|
auto f
|
||||||
settings::settings().value("recording/format", (int)RecordingFormats::None).toInt());
|
= static_cast<formats::Recording>(settings::settings().value("recording/format", (int)formats::Recording::None).toInt());
|
||||||
if (f == RecordingFormats::None) return;
|
if (f >= formats::Recording::None) return;
|
||||||
RecordingContext *ctx = new RecordingContext;
|
RecordingContext *ctx = new RecordingContext;
|
||||||
RecordingFormats *format = new RecordingFormats(f);
|
RecordingFormats *format = new RecordingFormats(f);
|
||||||
ctx->consumer = format->getConsumer();
|
ctx->consumer = format->getConsumer();
|
||||||
ctx->finalizer = format->getFinalizer();
|
ctx->finalizer = format->getFinalizer();
|
||||||
ctx->validator = format->getValidator();
|
ctx->validator = format->getValidator();
|
||||||
ctx->format = format->getFormat();
|
ctx->format = format->getFormat();
|
||||||
|
ctx->anotherFormat = format->getAnotherFormat();
|
||||||
controller->start(ctx);
|
controller->start(ctx);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -107,11 +108,16 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
ui->hideToTray->setChecked(settings::settings().value("hideOnClose", true).toBool());
|
ui->hideToTray->setChecked(settings::settings().value("hideOnClose", true).toBool());
|
||||||
ui->captureCursor->setChecked(settings::settings().value("captureCursor", true).toBool());
|
ui->captureCursor->setChecked(settings::settings().value("captureCursor", true).toBool());
|
||||||
|
|
||||||
for (int i = 0; i < RecordingFormats::None; i++) {
|
for (int i = 0; i < (int)formats::Recording::None; i++) {
|
||||||
ui->formatBox->addItem(RecordingFormats::getExt(static_cast<RecordingFormats::Format>(i)));
|
ui->formatBox->addItem(formats::recordingFormatName(static_cast<formats::Recording>(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)formats::Normal::None; i++) {
|
||||||
|
ui->imageFormatBox->addItem(formats::normalFormatName(static_cast<formats::Normal>(i)));
|
||||||
|
}
|
||||||
|
|
||||||
ui->formatBox->addItem("None");
|
ui->formatBox->addItem("None");
|
||||||
ui->formatBox->setCurrentIndex(settings::settings().value("recording/format", (int)RecordingFormats::None).toInt());
|
ui->formatBox->setCurrentIndex(settings::settings().value("recording/format", (int)formats::Recording::None).toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow() {
|
||||||
@ -219,3 +225,7 @@ void MainWindow::on_captureCursor_clicked(bool checked) {
|
|||||||
void MainWindow::on_formatBox_currentIndexChanged(int index) {
|
void MainWindow::on_formatBox_currentIndexChanged(int index) {
|
||||||
settings::settings().setValue("recording/format", index);
|
settings::settings().setValue("recording/format", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_imageFormatBox_currentIndexChanged(const QString &arg1) {
|
||||||
|
settings::settings().setValue("imageformat", arg1);
|
||||||
|
}
|
||||||
|
@ -33,8 +33,8 @@ private slots:
|
|||||||
void on_hideToTray_clicked(bool checked);
|
void on_hideToTray_clicked(bool checked);
|
||||||
void on_actionColor_Picker_triggered();
|
void on_actionColor_Picker_triggered();
|
||||||
void on_captureCursor_clicked(bool checked);
|
void on_captureCursor_clicked(bool checked);
|
||||||
|
|
||||||
void on_formatBox_currentIndexChanged(int index);
|
void on_formatBox_currentIndexChanged(int index);
|
||||||
|
void on_imageFormatBox_currentIndexChanged(const QString &arg1);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(QWidget *parent = 0);
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>512</width>
|
<width>483</width>
|
||||||
<height>412</height>
|
<height>478</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -25,7 +25,10 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="9" column="1">
|
<item row="15" column="1">
|
||||||
|
<widget class="QComboBox" name="imageFormatBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="12" column="1" rowspan="2">
|
||||||
<widget class="QComboBox" name="formatBox">
|
<widget class="QComboBox" name="formatBox">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>-1</number>
|
<number>-1</number>
|
||||||
@ -70,7 +73,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="0" colspan="2">
|
<item row="16" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_6">
|
<widget class="QLabel" name="label_6">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><a href="https://github.com/ArsenArsen/KShare">Source code available free for everyone. Forever.</a>
|
<string><a href="https://github.com/ArsenArsen/KShare">Source code available free for everyone. Forever.</a>
|
||||||
@ -112,24 +115,31 @@
|
|||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QListWidget" name="uploaderList"/>
|
<widget class="QListWidget" name="uploaderList"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0">
|
<item row="13" column="0">
|
||||||
<widget class="QCheckBox" name="captureCursor">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Capture cursor</string>
|
<string>Recording format</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0">
|
<item row="15" column="0">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Still image format</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="hideToTray">
|
<widget class="QCheckBox" name="hideToTray">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Pressing <X> hides to tray</string>
|
<string>Pressing <X> hides to tray</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1" rowspan="2">
|
<item row="7" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QCheckBox" name="captureCursor">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Recording format</string>
|
<string>Capture cursor</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -140,7 +150,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>512</width>
|
<width>483</width>
|
||||||
<height>25</height>
|
<height>25</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -38,7 +38,12 @@ bool RecordingController::end() {
|
|||||||
|
|
||||||
preview = 0;
|
preview = 0;
|
||||||
WorkerContext *c = new WorkerContext;
|
WorkerContext *c = new WorkerContext;
|
||||||
c->consumer = [&](QImage) { queue(_context->finalizer()); };
|
c->consumer = [&](QImage) {
|
||||||
|
_QueueContext contx;
|
||||||
|
contx.arr = _context->finalizer();
|
||||||
|
contx.format = _context->anotherFormat;
|
||||||
|
queue(contx);
|
||||||
|
};
|
||||||
c->targetFormat = QImage::Format_Alpha8;
|
c->targetFormat = QImage::Format_Alpha8;
|
||||||
c->pixmap = QPixmap(0, 0);
|
c->pixmap = QPixmap(0, 0);
|
||||||
Worker::queue(c);
|
Worker::queue(c);
|
||||||
@ -48,7 +53,7 @@ bool RecordingController::end() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordingController::queue(QByteArray arr) {
|
void RecordingController::queue(_QueueContext arr) {
|
||||||
QMutexLocker l(&lock);
|
QMutexLocker l(&lock);
|
||||||
uploadQueue.enqueue(arr);
|
uploadQueue.enqueue(arr);
|
||||||
}
|
}
|
||||||
@ -86,7 +91,10 @@ void RecordingController::timeout() {
|
|||||||
preview->setTime(QString("%1:%2").arg(QString::number(minute)).arg(QString::number(second)), frame);
|
preview->setTime(QString("%1:%2").arg(QString::number(minute)).arg(QString::number(second)), frame);
|
||||||
} else {
|
} else {
|
||||||
QMutexLocker l(&lock);
|
QMutexLocker l(&lock);
|
||||||
if (!uploadQueue.isEmpty()) UploaderSingleton::inst().upload(uploadQueue.dequeue());
|
if (!uploadQueue.isEmpty()) {
|
||||||
|
auto a = uploadQueue.dequeue();
|
||||||
|
UploaderSingleton::inst().upload(a.arr, a.format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,12 +12,17 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class RecordingContext {
|
struct RecordingContext {
|
||||||
public:
|
|
||||||
QImage::Format format;
|
QImage::Format format;
|
||||||
std::function<void(QImage)> consumer;
|
std::function<void(QImage)> consumer;
|
||||||
std::function<bool()> validator;
|
std::function<bool()> validator;
|
||||||
std::function<QByteArray()> finalizer;
|
std::function<QByteArray()> finalizer;
|
||||||
|
QString anotherFormat;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _QueueContext {
|
||||||
|
QByteArray arr;
|
||||||
|
QString format;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RecordingController : public QObject {
|
class RecordingController : public QObject {
|
||||||
@ -30,14 +35,14 @@ public slots:
|
|||||||
bool start(RecordingContext *context);
|
bool start(RecordingContext *context);
|
||||||
// Returns false if not running
|
// Returns false if not running
|
||||||
bool end();
|
bool end();
|
||||||
void queue(QByteArray arr);
|
void queue(_QueueContext arr);
|
||||||
private slots:
|
private slots:
|
||||||
void timeout();
|
void timeout();
|
||||||
void startWithArea(QRect newArea);
|
void startWithArea(QRect newArea);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMutex lock;
|
QMutex lock;
|
||||||
QQueue<QByteArray> uploadQueue;
|
QQueue<_QueueContext> uploadQueue;
|
||||||
QRect area;
|
QRect area;
|
||||||
RecordingContext *_context = 0;
|
RecordingContext *_context = 0;
|
||||||
QTimer timer;
|
QTimer timer;
|
||||||
|
@ -7,13 +7,14 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <formats.hpp>
|
||||||
#include <gif-h/gif.h>
|
#include <gif-h/gif.h>
|
||||||
#include <platformbackend.hpp>
|
#include <platformbackend.hpp>
|
||||||
#include <settings.hpp>
|
#include <settings.hpp>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
RecordingFormats::RecordingFormats(RecordingFormats::Format f) {
|
RecordingFormats::RecordingFormats(formats::Recording f) {
|
||||||
QString path = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
QString path = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
||||||
|
|
||||||
if (path.isEmpty()) {
|
if (path.isEmpty()) {
|
||||||
@ -26,7 +27,7 @@ RecordingFormats::RecordingFormats(RecordingFormats::Format f) {
|
|||||||
tmpDir.mkdir(name);
|
tmpDir.mkdir(name);
|
||||||
tmpDir.cd(name);
|
tmpDir.cd(name);
|
||||||
switch (f) {
|
switch (f) {
|
||||||
case GIF: {
|
case formats::Recording::GIF: {
|
||||||
iFormat = QImage::Format_RGBA8888;
|
iFormat = QImage::Format_RGBA8888;
|
||||||
validator = [] { return true; };
|
validator = [] { return true; };
|
||||||
consumer = [&](QImage img) { frames.push_back(img); };
|
consumer = [&](QImage img) { frames.push_back(img); };
|
||||||
@ -49,6 +50,7 @@ RecordingFormats::RecordingFormats(RecordingFormats::Format f) {
|
|||||||
QByteArray data = res.readAll();
|
QByteArray data = res.readAll();
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
anotherFormat = formats::recordingFormatName(f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -72,16 +74,6 @@ QImage::Format RecordingFormats::getFormat() {
|
|||||||
return iFormat;
|
return iFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString RecordingFormats::getExt(RecordingFormats::Format f) {
|
QString RecordingFormats::getAnotherFormat() {
|
||||||
switch (f) {
|
return anotherFormat;
|
||||||
case None:
|
|
||||||
return "None";
|
|
||||||
break;
|
|
||||||
case GIF:
|
|
||||||
return "gif";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return QString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,17 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <formats.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
class RecordingFormats {
|
class RecordingFormats {
|
||||||
public:
|
public:
|
||||||
enum Format { GIF, None };
|
RecordingFormats(formats::Recording f);
|
||||||
RecordingFormats(Format f);
|
|
||||||
std::function<void(QImage)> getConsumer();
|
std::function<void(QImage)> getConsumer();
|
||||||
std::function<QByteArray()> getFinalizer();
|
std::function<QByteArray()> getFinalizer();
|
||||||
std::function<bool()> getValidator();
|
std::function<bool()> getValidator();
|
||||||
QImage::Format getFormat();
|
QImage::Format getFormat();
|
||||||
|
QString getAnotherFormat();
|
||||||
static QString getExt(Format f);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void(QImage)> consumer;
|
std::function<void(QImage)> consumer;
|
||||||
@ -25,7 +24,7 @@ private:
|
|||||||
std::vector<QImage> frames;
|
std::vector<QImage> frames;
|
||||||
QImage::Format iFormat;
|
QImage::Format iFormat;
|
||||||
QDir tmpDir;
|
QDir tmpDir;
|
||||||
int frame = 0;
|
QString anotherFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RECORDINGFORMATS_HPP
|
#endif // RECORDINGFORMATS_HPP
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
#include <formats.hpp>
|
||||||
#include <io/ioutils.hpp>
|
#include <io/ioutils.hpp>
|
||||||
#include <notifications.hpp>
|
#include <notifications.hpp>
|
||||||
|
|
||||||
|
using formats::normalFormatFromName;
|
||||||
|
using formats::normalFormatMIME;
|
||||||
using std::runtime_error;
|
using std::runtime_error;
|
||||||
|
|
||||||
void error(QString absFilePath, QString err) {
|
void error(QString absFilePath, QString err) {
|
||||||
@ -17,12 +20,6 @@ void error(QString absFilePath, QString err) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomUploader::CustomUploader(QString absFilePath) {
|
CustomUploader::CustomUploader(QString absFilePath) {
|
||||||
types.insert("PNG", "image/png"); // This is a list of supported formats, too
|
|
||||||
types.insert("GIF", "image/gif");
|
|
||||||
types.insert("JPG", "image/jpeg");
|
|
||||||
types.insert("JPEG", "image/jpeg");
|
|
||||||
types.insert("WEBM", "video/webm");
|
|
||||||
types.insert("MP4", "video/mp4");
|
|
||||||
// Let's go
|
// Let's go
|
||||||
QFile file(absFilePath);
|
QFile file(absFilePath);
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) error(absFilePath, file.errorString());
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) error(absFilePath, file.errorString());
|
||||||
@ -74,16 +71,6 @@ CustomUploader::CustomUploader(QString absFilePath) {
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
error(absFilePath, "format provided but not string");
|
error(absFilePath, "format provided but not string");
|
||||||
QJsonValue imageValue = obj["imageformat"];
|
|
||||||
if (!imageValue.isString()) {
|
|
||||||
error(absFilePath, "imageformat not string");
|
|
||||||
}
|
|
||||||
QString imageFormat = imageValue.toString();
|
|
||||||
if (imageFormat == "base64" || QRegExp("base64\\([^+]+\\+[^+]+)").exactMatch(imageFormat)
|
|
||||||
|| QRegExp("[^+]+\\+[^+]+").exactMatch(imageFormat)) {
|
|
||||||
this->iFormat = imageFormat;
|
|
||||||
} else
|
|
||||||
error(absFilePath, "imageformat invalid");
|
|
||||||
QJsonValue bodyValue = obj["body"];
|
QJsonValue bodyValue = obj["body"];
|
||||||
if (rFormat != RequestFormat::PLAIN) {
|
if (rFormat != RequestFormat::PLAIN) {
|
||||||
if (bodyValue.isUndefined()) error(absFilePath, "body not set");
|
if (bodyValue.isUndefined()) error(absFilePath, "body not set");
|
||||||
@ -113,6 +100,11 @@ CustomUploader::CustomUploader(QString absFilePath) {
|
|||||||
if (!fileLimit.isDouble()) error(absFilePath, "fileLimit not double");
|
if (!fileLimit.isDouble()) error(absFilePath, "fileLimit not double");
|
||||||
limit = fileLimit.toDouble();
|
limit = fileLimit.toDouble();
|
||||||
}
|
}
|
||||||
|
QJsonValue bool64 = obj["base64"];
|
||||||
|
if (!bool64.isNull() && !bool64.isUndefined()) {
|
||||||
|
if (!bool64.isBool()) error(absFilePath, "base64 must be boolean");
|
||||||
|
base64 = bool64.toBool();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CustomUploader::name() {
|
QString CustomUploader::name() {
|
||||||
@ -123,10 +115,6 @@ QString CustomUploader::description() {
|
|||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<QString, QString> CustomUploader::format() {
|
|
||||||
return std::tuple<QString, QString>(getFormatString(false), getFormatString(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString getCType(RequestFormat format, QString plainType) {
|
QString getCType(RequestFormat format, QString plainType) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case RequestFormat::X_WWW_FORM_URLENCODED:
|
case RequestFormat::X_WWW_FORM_URLENCODED:
|
||||||
@ -139,7 +127,7 @@ QString getCType(RequestFormat format, QString plainType) {
|
|||||||
return plainType;
|
return plainType;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QPair<QString, QString>> getHeaders(QJsonObject h, QString imageFormat, QMap<QString, QString> types, RequestFormat format) {
|
QList<QPair<QString, QString>> getHeaders(QJsonObject h, QString imageFormat, RequestFormat format) {
|
||||||
QList<QPair<QString, QString>> headers;
|
QList<QPair<QString, QString>> headers;
|
||||||
for (QString s : h.keys()) {
|
for (QString s : h.keys()) {
|
||||||
if (s.toLower() == "content-type") continue;
|
if (s.toLower() == "content-type") continue;
|
||||||
@ -149,20 +137,10 @@ QList<QPair<QString, QString>> getHeaders(QJsonObject h, QString imageFormat, QM
|
|||||||
else
|
else
|
||||||
headers << QPair<QString, QString>(s, v.toString());
|
headers << QPair<QString, QString>(s, v.toString());
|
||||||
}
|
}
|
||||||
headers << QPair<QString, QString>("Content-Type", getCType(format, types.value(imageFormat)));
|
headers << QPair<QString, QString>("Content-Type", getCType(format, normalFormatMIME(normalFormatFromName(imageFormat))));
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CustomUploader::getFormatString(bool animated) {
|
|
||||||
if (iFormat == "base64")
|
|
||||||
return animated ? "GIF" : "PNG";
|
|
||||||
else if (QRegExp("[^+]+\\+[^+]+").exactMatch(iFormat))
|
|
||||||
return iFormat.split('+')[(int)animated];
|
|
||||||
else if (QRegExp("base64\\([^+]+\\+[^+]+)").exactMatch(iFormat))
|
|
||||||
return iFormat.mid(7, iFormat.length() - 8).split('+')[(int)animated];
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject recurseAndReplace(QJsonObject &body, QByteArray &data, QString contentType) {
|
QJsonObject recurseAndReplace(QJsonObject &body, QByteArray &data, QString contentType) {
|
||||||
QJsonObject o;
|
QJsonObject o;
|
||||||
for (QString s : body.keys()) {
|
for (QString s : body.keys()) {
|
||||||
@ -234,25 +212,26 @@ void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomUploader::doUpload(QByteArray imgData) {
|
void CustomUploader::doUpload(QByteArray imgData, QString format) {
|
||||||
auto h = getHeaders(headers, getFormatString(false), types, this->rFormat);
|
auto h = getHeaders(headers, format, this->rFormat);
|
||||||
QString format = getFormatString(false); // Soon:tm:
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
if (iFormat == "base64" || QRegExp("base64\\([^+]\\+[^+]\\)").exactMatch(iFormat)) imgData = imgData.toBase64();
|
if (base64) imgData = imgData.toBase64();
|
||||||
switch (this->rFormat) {
|
switch (this->rFormat) {
|
||||||
case RequestFormat::PLAIN: {
|
case RequestFormat::PLAIN: {
|
||||||
data = imgData;
|
data = imgData;
|
||||||
} break;
|
} break;
|
||||||
case RequestFormat::JSON: {
|
case RequestFormat::JSON: {
|
||||||
if (body.isString()) {
|
if (body.isString()) {
|
||||||
QStringList split = body.toString().replace("%contenttype", types.value(format)).split("%imagedata");
|
QStringList split = body.toString().replace("%contenttype", normalFormatMIME(normalFormatFromName(format))).split("%imagedata");
|
||||||
for (int i = 0; i < split.size(); i++) {
|
for (int i = 0; i < split.size(); i++) {
|
||||||
data.append(split[i]);
|
data.append(split[i]);
|
||||||
if (i < split.size() - 1) data.append(imgData);
|
if (i < split.size() - 1) data.append(imgData);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QJsonObject vo = body.toObject();
|
QJsonObject vo = body.toObject();
|
||||||
data = QJsonDocument::fromVariant(recurseAndReplace(vo, imgData, types.value(format)).toVariantMap()).toJson();
|
data = QJsonDocument::fromVariant(
|
||||||
|
recurseAndReplace(vo, imgData, normalFormatMIME(normalFormatFromName(format))).toVariantMap())
|
||||||
|
.toJson();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case RequestFormat::X_WWW_FORM_URLENCODED: {
|
case RequestFormat::X_WWW_FORM_URLENCODED: {
|
||||||
@ -264,7 +243,8 @@ void CustomUploader::doUpload(QByteArray imgData) {
|
|||||||
QByteArray strB;
|
QByteArray strB;
|
||||||
if (str.startsWith("/") && str.endsWith("/")) {
|
if (str.startsWith("/") && str.endsWith("/")) {
|
||||||
str = str.mid(1, str.length() - 2);
|
str = str.mid(1, str.length() - 2);
|
||||||
QStringList split = str.replace("%contenttype", types.value(format)).split("%imagedata");
|
QStringList split
|
||||||
|
= str.replace("%contenttype", normalFormatMIME(normalFormatFromName(format))).split("%imagedata");
|
||||||
for (int i = 0; i < split.size(); i++) {
|
for (int i = 0; i < split.size(); i++) {
|
||||||
strB.append(split[i]);
|
strB.append(split[i]);
|
||||||
if (i < split.size() - 1) strB.append(imgData);
|
if (i < split.size() - 1) strB.append(imgData);
|
||||||
|
@ -15,10 +15,7 @@ public:
|
|||||||
CustomUploader(QString absFilePath);
|
CustomUploader(QString absFilePath);
|
||||||
QString name();
|
QString name();
|
||||||
QString description();
|
QString description();
|
||||||
std::tuple<QString, QString> format();
|
void doUpload(QByteArray imgData, QString format);
|
||||||
void doUpload(QByteArray imgData);
|
|
||||||
QString getFormatString(bool animated);
|
|
||||||
QMap<QString, QString> types;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double limit = -1;
|
double limit = -1;
|
||||||
@ -29,8 +26,8 @@ private:
|
|||||||
QUrl target;
|
QUrl target;
|
||||||
QJsonValue body;
|
QJsonValue body;
|
||||||
QJsonObject headers;
|
QJsonObject headers;
|
||||||
|
bool base64 = false;
|
||||||
QString returnPathspec;
|
QString returnPathspec;
|
||||||
QString iFormat;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CUSTOMUPLOADER_HPP
|
#endif // CUSTOMUPLOADER_HPP
|
||||||
|
@ -2,9 +2,17 @@
|
|||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <formats.hpp>
|
||||||
#include <notifications.hpp>
|
#include <notifications.hpp>
|
||||||
|
|
||||||
void ClipboardUploader::doUpload(QByteArray imgData) {
|
void ClipboardUploader::doUpload(QByteArray imgData, QString format) {
|
||||||
QApplication::clipboard()->setImage(QImage::fromData(imgData, std::get<0>(format()).toLocal8Bit().constData()));
|
auto f = formats::recordingFormatFromName(format);
|
||||||
|
if (f != formats::Recording::None) {
|
||||||
|
auto data = new QMimeData();
|
||||||
|
data->setData(formats::recordingFormatMIME(f), imgData);
|
||||||
|
QApplication::clipboard()->setMimeData(data);
|
||||||
|
}
|
||||||
|
QApplication::clipboard()->setImage(QImage::fromData(imgData, format.toLocal8Bit().constData()));
|
||||||
notifications::notify("KShare", "Copied to clipboard!");
|
notifications::notify("KShare", "Copied to clipboard!");
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,8 @@ public:
|
|||||||
QString description() {
|
QString description() {
|
||||||
return "Copies the image to clipboard";
|
return "Copies the image to clipboard";
|
||||||
}
|
}
|
||||||
std::tuple<QString, QString> format() {
|
|
||||||
return std::tuple<QString, QString>("PNG", "MP4");
|
|
||||||
}
|
|
||||||
|
|
||||||
void doUpload(QByteArray imgData);
|
void doUpload(QByteArray imgData, QString format);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLIPBOARDUPLOADER_HPP
|
#endif // CLIPBOARDUPLOADER_HPP
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <notifications.hpp>
|
#include <notifications.hpp>
|
||||||
#include <screenshotutil.hpp>
|
#include <screenshotutil.hpp>
|
||||||
|
|
||||||
void ImgurUploader::doUpload(QByteArray byteArray) {
|
void ImgurUploader::doUpload(QByteArray byteArray, QString) {
|
||||||
if (byteArray.size() > 1e+7) {
|
if (byteArray.size() > 1e+7) {
|
||||||
notifications::notify("KShare imgur Uploader ", "Failed upload! Image too big");
|
notifications::notify("KShare imgur Uploader ", "Failed upload! Image too big");
|
||||||
return;
|
return;
|
||||||
|
@ -11,10 +11,7 @@ public:
|
|||||||
QString description() {
|
QString description() {
|
||||||
return "imgur.com uploader";
|
return "imgur.com uploader";
|
||||||
}
|
}
|
||||||
std::tuple<QString, QString> format() {
|
void doUpload(QByteArray byteArray, QString);
|
||||||
return std::tuple<QString, QString>("PNG", "MP4");
|
|
||||||
}
|
|
||||||
void doUpload(QByteArray byteArray);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IMGURUPLOADER_HPP
|
#endif // IMGURUPLOADER_HPP
|
||||||
|
@ -6,10 +6,9 @@
|
|||||||
|
|
||||||
class Uploader {
|
class Uploader {
|
||||||
public:
|
public:
|
||||||
virtual void doUpload(QByteArray imgData) = 0;
|
virtual void doUpload(QByteArray imgData, QString format) = 0;
|
||||||
virtual QString name() = 0;
|
virtual QString name() = 0;
|
||||||
virtual QString description() = 0;
|
virtual QString description() = 0;
|
||||||
virtual std::tuple<QString, QString> format() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UPLOADER_HPP
|
#endif // UPLOADER_HPP
|
||||||
|
@ -5,8 +5,11 @@
|
|||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <formats.hpp>
|
||||||
#include <formatter.hpp>
|
#include <formatter.hpp>
|
||||||
|
#include <notifications.hpp>
|
||||||
#include <settings.hpp>
|
#include <settings.hpp>
|
||||||
|
|
||||||
UploaderSingleton::UploaderSingleton()
|
UploaderSingleton::UploaderSingleton()
|
||||||
@ -57,29 +60,29 @@ void UploaderSingleton::registerUploader(Uploader *uploader) {
|
|||||||
|
|
||||||
void UploaderSingleton::upload(QPixmap *pixmap) {
|
void UploaderSingleton::upload(QPixmap *pixmap) {
|
||||||
auto u = uploaders.value(uploader);
|
auto u = uploaders.value(uploader);
|
||||||
QByteArray arr;
|
QString format = settings::settings().value("captureformat", "PNG").toString();
|
||||||
QBuffer data(&arr);
|
QFile file(saveDir.absoluteFilePath(formatter::format(settings::settings().value("fileFormat").toString(), format.toLower())));
|
||||||
pixmap->save(&data, std::get<0>(u->format()).toLocal8Bit().constData());
|
|
||||||
u->doUpload(arr);
|
if (file.open(QFile::ReadWrite)) {
|
||||||
data.close();
|
pixmap->save(&file, format.toLocal8Bit().constData());
|
||||||
|
file.seek(0);
|
||||||
|
u->doUpload(file.readAll(), format);
|
||||||
|
} else
|
||||||
|
notifications::notify("KShare - Failed to save picture", file.errorString(), QSystemTrayIcon::Warning);
|
||||||
delete pixmap;
|
delete pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UploaderSingleton::upload(QByteArray img) {
|
void UploaderSingleton::upload(QByteArray img, QString format) {
|
||||||
uploaders.value(uploader)->doUpload(img);
|
uploaders.value(uploader)->doUpload(img, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UploaderSingleton::upload(QFile img) {
|
void UploaderSingleton::upload(QFile img, QString format) {
|
||||||
if (img.open(QIODevice::ReadOnly)) {
|
if (img.open(QIODevice::ReadOnly)) {
|
||||||
uploaders.value(uploader)->doUpload(img.readAll());
|
uploaders.value(uploader)->doUpload(img.readAll(), format);
|
||||||
img.close();
|
img.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<QString, QString> UploaderSingleton::format() {
|
|
||||||
return uploaders.value(uploader)->format();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Uploader *> UploaderSingleton::uploaderList() {
|
QList<Uploader *> UploaderSingleton::uploaderList() {
|
||||||
return uploaders.values();
|
return uploaders.values();
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,8 @@ public:
|
|||||||
}
|
}
|
||||||
void registerUploader(Uploader *uploader);
|
void registerUploader(Uploader *uploader);
|
||||||
void upload(QPixmap *pixmap);
|
void upload(QPixmap *pixmap);
|
||||||
void upload(QByteArray img);
|
void upload(QByteArray img, QString format);
|
||||||
void upload(QFile img);
|
void upload(QFile img, QString format);
|
||||||
virtual std::tuple<QString, QString> format();
|
|
||||||
QList<Uploader *> uploaderList();
|
QList<Uploader *> uploaderList();
|
||||||
void set(QString uploader);
|
void set(QString uploader);
|
||||||
QString selectedUploader();
|
QString selectedUploader();
|
||||||
|
Loading…
Reference in New Issue
Block a user