From 52b6872f8561be83f7c245b560748a37c8c60360 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 4 Jul 2017 22:35:34 +0200 Subject: [PATCH 001/293] Make the default name scheme Windows compatable --- settingsdialog.cpp | 2 +- settingsdialog.ui | 2 +- uploaders/uploadersingleton.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/settingsdialog.cpp b/settingsdialog.cpp index 7c2ed0c..eb67258 100644 --- a/settingsdialog.cpp +++ b/settingsdialog.cpp @@ -41,7 +41,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Se for (Uploader *u : UploaderSingleton::inst().uploaderList()) newUploader(u); // Set filename scheme - setScheme(settings::settings().value("fileFormat", "Screenshot %(yyyy-MM-dd HH:mm:ss)date.%ext").toString()); + setScheme(settings::settings().value("fileFormat", "Screenshot %(yyyy-MM-dd HH-mm-ss)date.%ext").toString()); // Set delay if ((settings::settings().contains("delay"))) diff --git a/settingsdialog.ui b/settingsdialog.ui index ba64411..0acfd66 100644 --- a/settingsdialog.ui +++ b/settingsdialog.ui @@ -84,7 +84,7 @@ %(date format)date and %ext are supported - Screenshot %(yyyy-MM-dd HH:mm:ss)date.%ext + Screenshot %(yyyy-MM-dd HH-mm-ss)date.%ext diff --git a/uploaders/uploadersingleton.cpp b/uploaders/uploadersingleton.cpp index f40f0dc..8198b06 100644 --- a/uploaders/uploadersingleton.cpp +++ b/uploaders/uploadersingleton.cpp @@ -82,7 +82,7 @@ void UploaderSingleton::upload(QPixmap pixmap) { } QString format = settings::settings().value("captureformat", "PNG").toString(); QFile file(saveDir.absoluteFilePath( - formatter::format(settings::settings().value("fileFormat", "Screenshot %(yyyy-MM-dd HH:mm:ss)date.%ext").toString(), + formatter::format(settings::settings().value("fileFormat", "Screenshot %(yyyy-MM-dd HH-mm-ss)date.%ext").toString(), format.toLower()))); if (file.open(QFile::ReadWrite)) { From 4cf1c980c504b3ac0a1ae5401e4c09dfab4ad21b Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 12:05:55 +0200 Subject: [PATCH 002/293] Add a filename resolution method Closes #11 --- KShare.pro | 6 ++++-- filenamevalidator.cpp | 12 ++++++++++++ filenamevalidator.hpp | 12 ++++++++++++ platformbackend.hpp | 7 ++++--- platformspecifics/mac/macbackend.cpp | 4 ++++ platformspecifics/mac/macbackend.hpp | 1 + platformspecifics/u32/u32backend.cpp | 4 ++++ platformspecifics/u32/u32backend.hpp | 1 + platformspecifics/x11/x11backend.cpp | 4 ++++ platformspecifics/x11/x11backend.hpp | 1 + settingsdialog.cpp | 2 ++ 11 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 filenamevalidator.cpp create mode 100644 filenamevalidator.hpp diff --git a/KShare.pro b/KShare.pro index 283fe23..59c9675 100644 --- a/KShare.pro +++ b/KShare.pro @@ -65,7 +65,8 @@ SOURCES += main.cpp\ hotkeyinputdialog.cpp \ cropeditor/drawing/arrowitem.cpp \ uploaders/default/imgursettingsdialog.cpp \ - uploaders/default/imgplusuploader.cpp + uploaders/default/imgplusuploader.cpp \ + filenamevalidator.cpp HEADERS += mainwindow.hpp \ cropeditor/cropeditor.hpp \ @@ -109,7 +110,8 @@ HEADERS += mainwindow.hpp \ hotkeyinputdialog.hpp \ cropeditor/drawing/arrowitem.hpp \ uploaders/default/imgursettingsdialog.hpp \ - uploaders/default/imgplusuploader.hpp + uploaders/default/imgplusuploader.hpp \ + filenamevalidator.hpp CONFIG += link_pkgconfig PKGCONFIG += libavformat libavcodec libswscale libavutil diff --git a/filenamevalidator.cpp b/filenamevalidator.cpp new file mode 100644 index 0000000..928f1d0 --- /dev/null +++ b/filenamevalidator.cpp @@ -0,0 +1,12 @@ +#include "filenamevalidator.hpp" + +#include +#include + +FilenameValidator::FilenameValidator(QObject *parent) : QValidator(parent) { +} + +QValidator::State FilenameValidator::validate(QString &input, int &) const { + QString name = formatter::format(input, "lol"); + return PlatformBackend::inst().filenameValid(name) ? State::Acceptable : State::Invalid; +} diff --git a/filenamevalidator.hpp b/filenamevalidator.hpp new file mode 100644 index 0000000..66a46b7 --- /dev/null +++ b/filenamevalidator.hpp @@ -0,0 +1,12 @@ +#ifndef FILENAMEVALIDATOR_HPP +#define FILENAMEVALIDATOR_HPP + +#include + +class FilenameValidator : public QValidator { +public: + FilenameValidator(QObject *parent = nullptr); + QValidator::State validate(QString &input, int &) const override; +}; + +#endif // FILENAMEVALIDATOR_HPP diff --git a/platformbackend.hpp b/platformbackend.hpp index 8133ebc..28a666f 100644 --- a/platformbackend.hpp +++ b/platformbackend.hpp @@ -1,13 +1,14 @@ #ifndef PLATFORMBACKEND_HPP #define PLATFORMBACKEND_HPP +#include -#ifdef __APPLE__ +#ifdef Q_OS_MACOS #include #endif -#ifdef _WIN32 +#ifdef Q_OS_WIN #include #endif -#ifdef __unix__ +#ifdef Q_OS_UNIX #include #endif diff --git a/platformspecifics/mac/macbackend.cpp b/platformspecifics/mac/macbackend.cpp index c750eb9..675cc63 100644 --- a/platformspecifics/mac/macbackend.cpp +++ b/platformspecifics/mac/macbackend.cpp @@ -11,3 +11,7 @@ QPixmap PlatformBackend::getCursor() { pid_t PlatformBackend::pid() { return getpid(); } + +bool PlatformBackend::filenameValid(QString name) { + return !name.contains('/'); +} diff --git a/platformspecifics/mac/macbackend.hpp b/platformspecifics/mac/macbackend.hpp index 4016511..ea15166 100644 --- a/platformspecifics/mac/macbackend.hpp +++ b/platformspecifics/mac/macbackend.hpp @@ -13,6 +13,7 @@ public: static PlatformBackend inst; return inst; } + bool filenameValid(QString name); }; #endif // MACBACKEND_HPP diff --git a/platformspecifics/u32/u32backend.cpp b/platformspecifics/u32/u32backend.cpp index 344ba68..d084928 100644 --- a/platformspecifics/u32/u32backend.cpp +++ b/platformspecifics/u32/u32backend.cpp @@ -28,3 +28,7 @@ DWORD PlatformBackend::pid() { WId PlatformBackend::getActiveWID() { return (WId)GetForegroundWindow(); } + +bool PlatformBackend::filenamValid(QString name) { + return IsValidFileName(name.toLocal8Bit().constData()) == 0; +} diff --git a/platformspecifics/u32/u32backend.hpp b/platformspecifics/u32/u32backend.hpp index 8cb9075..891a808 100644 --- a/platformspecifics/u32/u32backend.hpp +++ b/platformspecifics/u32/u32backend.hpp @@ -17,6 +17,7 @@ public: return inst; } WId getActiveWID(); + bool filenamValid(QString name); }; #endif // U32BACKEND_HPP diff --git a/platformspecifics/x11/x11backend.cpp b/platformspecifics/x11/x11backend.cpp index 8bf841b..fe4fc94 100644 --- a/platformspecifics/x11/x11backend.cpp +++ b/platformspecifics/x11/x11backend.cpp @@ -54,3 +54,7 @@ WId PlatformBackend::getActiveWID() { delete treeReply; return window; } + +bool PlatformBackend::filenameValid(QString name) { + return !name.contains('/'); +} diff --git a/platformspecifics/x11/x11backend.hpp b/platformspecifics/x11/x11backend.hpp index fc1f1c5..63e8d2b 100644 --- a/platformspecifics/x11/x11backend.hpp +++ b/platformspecifics/x11/x11backend.hpp @@ -16,6 +16,7 @@ public: return inst; } WId getActiveWID(); + bool filenameValid(QString name); }; #endif // X11BACKEND_HPP diff --git a/settingsdialog.cpp b/settingsdialog.cpp index eb67258..3a39548 100644 --- a/settingsdialog.cpp +++ b/settingsdialog.cpp @@ -1,4 +1,5 @@ #include "settingsdialog.hpp" +#include "filenamevalidator.hpp" #include "hotkeyinputdialog.hpp" #include "mainwindow.hpp" #include "ui_settingsdialog.h" @@ -77,6 +78,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Se ui->cropX->setValue(settings::settings().value("cropx", 0).toInt()); ui->cropY->setValue(settings::settings().value("cropy", 0).toInt()); setWindowTitle("Settings"); + ui->nameScheme->setValidator(new FilenameValidator(ui->nameScheme)); #ifndef PLATFORM_CAPABILITY_CURSOR ui->captureCursor->setEnabled(false); ui->captureCursor->setText("Capture cursor (disabled: implementation missing)"); From 38d822620441b6b42968e20e3c35206300d0277c Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 12:15:14 +0200 Subject: [PATCH 003/293] Add the ability to abort recording Fixes #14 --- mainwindow.cpp | 11 +++++++++-- recording/recordingcontroller.cpp | 24 ++++++++++++++++++++++++ recording/recordingcontroller.hpp | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 9d9e0eb..3589a58 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -55,6 +55,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi QAction *picker = new QAction("Show color picker", this); QAction *rec = new QAction("Record screen", this); QAction *recoff = new QAction("Stop recording", this); + QAction *recabort = new QAction("Abort recording", this); menu->addActions({ quit, shtoggle, picker }); menu->addSeparator(); menu->addActions({ fullscreen, area, active }); @@ -62,7 +63,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi menu->addAction(area); #endif menu->addSeparator(); - menu->addActions({ rec, recoff }); + menu->addActions({ rec, recoff, recabort }); connect(quit, &QAction::triggered, this, &MainWindow::quit); connect(shtoggle, &QAction::triggered, this, &MainWindow::toggleVisible); connect(picker, &QAction::triggered, [] { ColorPickerScene::showPicker(); }); @@ -73,7 +74,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi connect(fullscreen, &QAction::triggered, this, [] { screenshotter::fullscreenDelayed(); }); connect(area, &QAction::triggered, this, [] { screenshotter::areaDelayed(); }); connect(rec, &QAction::triggered, this, &MainWindow::rec); - connect(recoff, &QAction::triggered, [this] { controller->end(); }); + connect(recoff, &QAction::triggered, controller, &RecordingController::end); + connect(recabort, &QAction::triggered, controller, &RecordingController::abort); connect(ui->settings, &QPushButton::clicked, this, &MainWindow::on_actionSettings_triggered); tray->setContextMenu(menu); @@ -83,6 +85,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi addHotkey("active", [] { screenshotter::active(); }); addHotkey("picker", [] { ColorPickerScene::showPicker(); }); addHotkey("recordingstop", [&] { controller->end(); }); + addHotkey("recordingabort", [&] { controller->abort(); }); addHotkey("recordingstart", [&] { this->rec(); }); auto errors = UploaderSingleton::inst().errors(); @@ -163,3 +166,7 @@ void MainWindow::on_actionAbout_triggered() { void MainWindow::on_actionActive_window_triggered() { screenshotter::activeDelayed(); } + +void MainWindow::on_actionAbort_triggered() { + controller->abort(); +} diff --git a/recording/recordingcontroller.cpp b/recording/recordingcontroller.cpp index 5320e70..3f55fbc 100644 --- a/recording/recordingcontroller.cpp +++ b/recording/recordingcontroller.cpp @@ -56,6 +56,30 @@ bool RecordingController::end() { return true; } +bool RecordingController::abort() { + emit ended(); + if (!isRunning()) return false; + area = QRect(); + if (preview) { + preview->close(); + preview->deleteLater(); + } + + preview = 0; + WorkerContext *c = new WorkerContext; + c->consumer = [&](QImage) { + _context->finalizer(); + _context->postUploadTask(); + }; + c->targetFormat = QImage::Format_Alpha8; + c->pixmap = QPixmap(0, 0); + Worker::queue(c); + + frame = 0; + time = 0; + return true; +} + void RecordingController::queue(_QueueContext arr) { QMutexLocker l(&lock); uploadQueue.enqueue(arr); diff --git a/recording/recordingcontroller.hpp b/recording/recordingcontroller.hpp index 96044d5..e4792c3 100644 --- a/recording/recordingcontroller.hpp +++ b/recording/recordingcontroller.hpp @@ -38,6 +38,7 @@ public slots: // Returns false if not running bool end(); void queue(_QueueContext arr); + bool abort(); private slots: void timeout(); void startWithArea(QRect newArea); From 6c5dff0be6addcd602bab26287c8dd8ae8765243 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 12:36:44 +0200 Subject: [PATCH 004/293] Fix filename validity check --- mainwindow.hpp | 2 +- mainwindow.ui | 6 ++++++ platformspecifics/u32/u32backend.cpp | 13 ++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/mainwindow.hpp b/mainwindow.hpp index 4eb3b53..a5a87c4 100644 --- a/mainwindow.hpp +++ b/mainwindow.hpp @@ -28,8 +28,8 @@ private slots: void on_actionSettings_triggered(); void on_actionColor_Picker_triggered(); void on_actionAbout_triggered(); - void on_actionActive_window_triggered(); + void on_actionAbort_triggered(); public: static MainWindow *inst(); diff --git a/mainwindow.ui b/mainwindow.ui index 699f6df..fc55e2c 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -84,6 +84,7 @@ + @@ -136,6 +137,11 @@ Active window + + + Abort + + diff --git a/platformspecifics/u32/u32backend.cpp b/platformspecifics/u32/u32backend.cpp index d084928..5919a9d 100644 --- a/platformspecifics/u32/u32backend.cpp +++ b/platformspecifics/u32/u32backend.cpp @@ -29,6 +29,17 @@ WId PlatformBackend::getActiveWID() { return (WId)GetForegroundWindow(); } +QString illegal(QStringLiteral("<>:\"/\|?*")); +QStringList illegalNames({ "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", + "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" }); + bool PlatformBackend::filenamValid(QString name) { - return IsValidFileName(name.toLocal8Bit().constData()) == 0; + unsigned int periods = 0; + for (QChar c : name) { + if (c == '.') periods++; + if (illegal.contains(c)) return false; + if (c < 32) return false; + } + if (periods == name.length()) return false; + return !illegalNames.contains(name); } From 37be9946d605fa8dc479b597cc9bf251f66ea90a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 12:39:16 +0200 Subject: [PATCH 005/293] fuck typing --- platformspecifics/u32/u32backend.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformspecifics/u32/u32backend.hpp b/platformspecifics/u32/u32backend.hpp index 891a808..6cff62e 100644 --- a/platformspecifics/u32/u32backend.hpp +++ b/platformspecifics/u32/u32backend.hpp @@ -17,7 +17,7 @@ public: return inst; } WId getActiveWID(); - bool filenamValid(QString name); + bool filenameValid(QString name); }; #endif // U32BACKEND_HPP From 7d45d794a64ed9d5b6898fd91c0a6082b2511914 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 12:41:09 +0200 Subject: [PATCH 006/293] ........ --- platformspecifics/u32/u32backend.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platformspecifics/u32/u32backend.cpp b/platformspecifics/u32/u32backend.cpp index 5919a9d..90150d7 100644 --- a/platformspecifics/u32/u32backend.cpp +++ b/platformspecifics/u32/u32backend.cpp @@ -29,12 +29,12 @@ WId PlatformBackend::getActiveWID() { return (WId)GetForegroundWindow(); } -QString illegal(QStringLiteral("<>:\"/\|?*")); +QString illegal(QStringLiteral("<>:\"/\\|?*")); QStringList illegalNames({ "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" }); -bool PlatformBackend::filenamValid(QString name) { - unsigned int periods = 0; +bool PlatformBackend::filenameValid(QString name) { + int periods = 0; for (QChar c : name) { if (c == '.') periods++; if (illegal.contains(c)) return false; From 7d5be857ff915cdf41bf6807c1438028433ef9ea Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 13:01:53 +0200 Subject: [PATCH 007/293] Add a warning for unset recording formats --- mainwindow.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 3589a58..c7d4afd 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -4,6 +4,7 @@ #include "screenshotutil.hpp" #include "settingsdialog.hpp" #include "ui_mainwindow.h" +#include #include #include #include @@ -19,7 +20,10 @@ void MainWindow::rec() { if (controller->isRunning()) return; auto f = static_cast(settings::settings().value("recording/format", (int)formats::Recording::None).toInt()); - if (f >= formats::Recording::None) return; + if (f >= formats::Recording::None) { + qWarning() << "Recording format not set in settings. Aborting."; + return; + } RecordingContext *ctx = new RecordingContext; RecordingFormats *format = new RecordingFormats(f); ctx->consumer = format->getConsumer(); From 159720d9faf21bd4ca4535ffca61c79c0fef0a6c Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 15:30:50 +0200 Subject: [PATCH 008/293] Fix empty hotkeys being loaded --- hotkeying.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/hotkeying.cpp b/hotkeying.cpp index 17288ca..2dd5971 100644 --- a/hotkeying.cpp +++ b/hotkeying.cpp @@ -28,9 +28,13 @@ void hotkeying::load(QString seqName, std::function func, QString def) { QString name = seqName; name.prepend("hotkey_"); if (hotkeys.contains(seqName)) return; - if (settings::settings().contains(name)) - h = new QHotkey(QKeySequence(settings::settings().value(name).toString()), true); - else + if (settings::settings().contains(name)) { + QString k = settings::settings().value(name).toString(); + if (!k.isEmpty()) + h = new QHotkey(QKeySequence(settings::settings().value(k).toString()), true); + else + h = new QHotkey(def.isNull() ? "" : def, true); + } else h = new QHotkey(def.isNull() ? "" : def, true); QObject::connect(h, &QHotkey::activated, func); hotkeys.insert(seqName, h); From 698d1238152150cb21ece2a25ffe65c3045bbfb9 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 16:41:53 +0200 Subject: [PATCH 009/293] Partial fix for #9 - now the position is good --- cropeditor/cropeditor.cpp | 4 +++- hotkeying.cpp | 10 +++++----- screenshotutil.cpp | 17 ++++++++++++++--- screenshotutil.hpp | 1 + 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/cropeditor/cropeditor.cpp b/cropeditor/cropeditor.cpp index de15ffa..16291ff 100644 --- a/cropeditor/cropeditor.cpp +++ b/cropeditor/cropeditor.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include CropEditor::CropEditor(QPixmap image, QObject *parent) : QObject(parent) { @@ -20,7 +21,8 @@ CropEditor::CropEditor(QPixmap image, QObject *parent) : QObject(parent) { scene->setSceneRect(image.rect()); view->resize(image.width(), image.height()); view->setMinimumSize(image.size()); - view->move(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); + QPoint p = screenshotutil::smallestScreenCoordinate(); + view->move(p.x() + settings::settings().value("cropx", 0).toInt(), p.y() + settings::settings().value("cropy", 0).toInt()); view->setWindowTitle("KShare Crop Editor"); view->show(); diff --git a/hotkeying.cpp b/hotkeying.cpp index 2dd5971..90de05d 100644 --- a/hotkeying.cpp +++ b/hotkeying.cpp @@ -28,17 +28,17 @@ void hotkeying::load(QString seqName, std::function func, QString def) { QString name = seqName; name.prepend("hotkey_"); if (hotkeys.contains(seqName)) return; - if (settings::settings().contains(name)) { - QString k = settings::settings().value(name).toString(); + QString k = settings::settings().value(name).toString(); + if (!k.isEmpty()) { if (!k.isEmpty()) h = new QHotkey(QKeySequence(settings::settings().value(k).toString()), true); else - h = new QHotkey(def.isNull() ? "" : def, true); + h = new QHotkey(def.isEmpty() ? "" : def, true); } else - h = new QHotkey(def.isNull() ? "" : def, true); + h = new QHotkey(def.isEmpty() ? "" : def, true); QObject::connect(h, &QHotkey::activated, func); hotkeys.insert(seqName, h); - if (!h->isRegistered() && (settings::settings().contains(name) || !def.isEmpty())) + if (!h->isRegistered() && !h->shortcut().toString().isEmpty()) qWarning().noquote().nospace() << "Could not bind the hotkey " << seqName << "! Is the keybind already registered?"; } diff --git a/screenshotutil.cpp b/screenshotutil.cpp index d0ec325..b6d3268 100644 --- a/screenshotutil.cpp +++ b/screenshotutil.cpp @@ -11,16 +11,17 @@ QPixmap screenshotutil::fullscreen(bool cursor) { QPixmap image; QPainter painter; + QPoint smallestCoordinate = smallestScreenCoordinate(); - // Hack for https://bugreports.qt.io/browse/QTBUG-58110 - static QStringList qVer = QString(qVersion()).split('.'); +// Hack for https://bugreports.qt.io/browse/QTBUG-58110 #ifdef Q_OS_LINUX + static QStringList qVer = QString(qVersion()).split('.'); if (qVer.at(0).toInt() == 5 && qVer.at(1).toInt() < 9) { image = window(0); painter.begin(&image); } else { #endif - int height = 0, width = 0; + int height = qAbs(smallestCoordinate.y()), width = qAbs(smallestCoordinate.x()); // qute abs for (QScreen *screen : QApplication::screens()) { QRect geo = screen->geometry(); width = qMax(geo.left() + geo.width(), width); @@ -30,6 +31,7 @@ QPixmap screenshotutil::fullscreen(bool cursor) { image.fill(Qt::transparent); width = 0; painter.begin(&image); + painter.translate(qAbs(smallestCoordinate.x()), qAbs(smallestCoordinate.y())); for (QScreen *screen : QApplication::screens()) { QPixmap currentScreen = window(0, screen); @@ -61,3 +63,12 @@ void screenshotutil::toClipboard(QString value) { QPixmap screenshotutil::fullscreenArea(bool cursor, qreal x, qreal y, qreal w, qreal h) { return fullscreen(cursor).copy(x, y, w, h); } + +QPoint screenshotutil::smallestScreenCoordinate() { + QPoint smallestCoordinate; + for (QScreen *screen : QApplication::screens()) { + smallestCoordinate.rx() = qMin(smallestCoordinate.x(), screen->geometry().left()); + smallestCoordinate.ry() = qMin(smallestCoordinate.y(), screen->geometry().top()); + } + return smallestCoordinate; +} diff --git a/screenshotutil.hpp b/screenshotutil.hpp index 02808ea..df156d6 100644 --- a/screenshotutil.hpp +++ b/screenshotutil.hpp @@ -9,6 +9,7 @@ QPixmap fullscreen(bool cursor = true); QPixmap fullscreenArea(bool cursor = true, qreal x = 0, qreal y = 0, qreal w = -1, qreal h = -1); QPixmap window(WId wid, QScreen *w = QApplication::primaryScreen()); void toClipboard(QString value); +QPoint smallestScreenCoordinate(); } #endif // SCREENSHOTUTIL_HPP From e609a1a9a5cf2199004ec6b30c326cbe3a105000 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 16:51:02 +0200 Subject: [PATCH 010/293] Make the screen size calculation work for Win too Fixes #9 --- screenshotutil.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/screenshotutil.cpp b/screenshotutil.cpp index b6d3268..9c939f0 100644 --- a/screenshotutil.cpp +++ b/screenshotutil.cpp @@ -21,17 +21,18 @@ QPixmap screenshotutil::fullscreen(bool cursor) { painter.begin(&image); } else { #endif - int height = qAbs(smallestCoordinate.y()), width = qAbs(smallestCoordinate.x()); // qute abs + int height = 0, width = 0; + int ox = smallestCoordinate.x() * -1, oy = smallestCoordinate.y() * -1; for (QScreen *screen : QApplication::screens()) { QRect geo = screen->geometry(); - width = qMax(geo.left() + geo.width(), width); - height = qMax(geo.top() + geo.height(), height); + width = qMax(ox + geo.left() + geo.width(), width); + height = qMax(oy + geo.top() + geo.height(), height); // qute abs } image = QPixmap(width, height); image.fill(Qt::transparent); width = 0; painter.begin(&image); - painter.translate(qAbs(smallestCoordinate.x()), qAbs(smallestCoordinate.y())); + painter.translate(ox, oy); for (QScreen *screen : QApplication::screens()) { QPixmap currentScreen = window(0, screen); From cf148375526844212a482d8fb296235841561ef3 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 19:24:53 +0200 Subject: [PATCH 011/293] Fix app icon on Windows --- cropeditor/cropscene.cpp | 2 +- icon.qrc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index c0765a2..fc5a526 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -141,7 +141,7 @@ void CropScene::setVisible(bool visible) { void CropScene::fontAsk() { hide(); bool ok = false; - QFont font = QFontDialog::getFont(&ok, this->font(), nullptr, "Font to use"); + QFont font = QFontDialog::getFont(&ok, this->font(), this->views()[0], "Font to use"); if (ok) _font = font; show(); } diff --git a/icon.qrc b/icon.qrc index 1e85526..4feaf3f 100644 --- a/icon.qrc +++ b/icon.qrc @@ -2,5 +2,6 @@ icons/icon.png icons/icon.svg + icons/icon.ico From 37ea6e49b765e48cbda7a4f002ceb74c121276c8 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 19:38:38 +0200 Subject: [PATCH 012/293] Try two after reading the docs --- KShare.pro | 2 ++ icon.rc | 1 + icons/icon.icns | Bin 0 -> 69700 bytes 3 files changed, 3 insertions(+) create mode 100644 icon.rc create mode 100644 icons/icon.icns diff --git a/KShare.pro b/KShare.pro index 59c9675..1eb36c2 100644 --- a/KShare.pro +++ b/KShare.pro @@ -151,6 +151,8 @@ DISTFILES += \ RESOURCES += \ icon.qrc +RC_FILE = icon.rc + ICON = icons/icon.ico # Enable debug symbols diff --git a/icon.rc b/icon.rc new file mode 100644 index 0000000..0ac9804 --- /dev/null +++ b/icon.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "icons/icon.icns" diff --git a/icons/icon.icns b/icons/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..402501fbc00d4ebb5c29714eb9b143bbb17ef545 GIT binary patch literal 69700 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

3AoD%#o1 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 P^FR!qm3lZ8M!)~rLRUM@ literal 0 HcmV?d00001 From b852b4086367caeb24de8bb61172ebdade8d9bed Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 19:41:41 +0200 Subject: [PATCH 013/293] Take three --- KShare.pro | 7 +++---- icon.rc | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/KShare.pro b/KShare.pro index 1eb36c2..9e63752 100644 --- a/KShare.pro +++ b/KShare.pro @@ -117,16 +117,19 @@ CONFIG += link_pkgconfig PKGCONFIG += libavformat libavcodec libswscale libavutil mac { + ICON = icons/icon.icns SOURCES += $$PWD/platformspecifics/mac/macbackend.cpp HEADERS += $$PWD/platformspecifics/mac/macbackend.hpp LIBS += -framework Carbon warning(Mac is on TODO); } else:win32 { + RC_FILE = myapp.rc SOURCES += $$PWD/platformspecifics/u32/u32backend.cpp HEADERS += $$PWD/platformspecifics/u32/u32backend.hpp LIBS += -luser32 -lkernel32 -lpthread QT += winextras } else:unix { + RC_FILE = myapp.rc SOURCES += $$PWD/platformspecifics/x11/x11backend.cpp HEADERS += $$PWD/platformspecifics/x11/x11backend.hpp QT += x11extras @@ -151,10 +154,6 @@ DISTFILES += \ RESOURCES += \ icon.qrc -RC_FILE = icon.rc - -ICON = icons/icon.ico - # Enable debug symbols QMAKE_CFLAGS_DEBUG += -g diff --git a/icon.rc b/icon.rc index 0ac9804..2e42c32 100644 --- a/icon.rc +++ b/icon.rc @@ -1 +1 @@ -IDI_ICON1 ICON DISCARDABLE "icons/icon.icns" +IDI_ICON1 ICON DISCARDABLE "icons/icon.ico" From d2ff0e96482641578b3da83ea231afcda4a3776d Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 19:43:20 +0200 Subject: [PATCH 014/293] Take 5? I lost count. Fixes #10 for app icon --- KShare.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/KShare.pro b/KShare.pro index 9e63752..de293ee 100644 --- a/KShare.pro +++ b/KShare.pro @@ -123,13 +123,13 @@ mac { LIBS += -framework Carbon warning(Mac is on TODO); } else:win32 { - RC_FILE = myapp.rc + RC_FILE = icon.rc SOURCES += $$PWD/platformspecifics/u32/u32backend.cpp HEADERS += $$PWD/platformspecifics/u32/u32backend.hpp LIBS += -luser32 -lkernel32 -lpthread QT += winextras } else:unix { - RC_FILE = myapp.rc + RC_FILE = icon.rc SOURCES += $$PWD/platformspecifics/x11/x11backend.cpp HEADERS += $$PWD/platformspecifics/x11/x11backend.hpp QT += x11extras From e44c90098bf6a58a8f44e4365121efcc33bf485a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 5 Jul 2017 20:10:39 +0200 Subject: [PATCH 015/293] How does AppVeyor work --- KShare.pro | 43 ++++++++++++++++++++++++------------------- appveyor.yml | 15 +++++++++++++++ 2 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 appveyor.yml diff --git a/KShare.pro b/KShare.pro index de293ee..9676e39 100644 --- a/KShare.pro +++ b/KShare.pro @@ -113,29 +113,33 @@ HEADERS += mainwindow.hpp \ uploaders/default/imgplusuploader.hpp \ filenamevalidator.hpp -CONFIG += link_pkgconfig -PKGCONFIG += libavformat libavcodec libswscale libavutil +nopkg { + LIBS += -lavcodec -lavformat -lavutil -lswscale +} else { + CONFIG += link_pkgconfig + PKGCONFIG += libavformat libavcodec libswscale libavutil +} mac { - ICON = icons/icon.icns - SOURCES += $$PWD/platformspecifics/mac/macbackend.cpp - HEADERS += $$PWD/platformspecifics/mac/macbackend.hpp - LIBS += -framework Carbon - warning(Mac is on TODO); + ICON = icons/icon.icns + SOURCES += $$PWD/platformspecifics/mac/macbackend.cpp + HEADERS += $$PWD/platformspecifics/mac/macbackend.hpp + LIBS += -framework Carbon + warning(Mac is on TODO); } else:win32 { - RC_FILE = icon.rc - SOURCES += $$PWD/platformspecifics/u32/u32backend.cpp - HEADERS += $$PWD/platformspecifics/u32/u32backend.hpp - LIBS += -luser32 -lkernel32 -lpthread - QT += winextras + RC_FILE = icon.rc + SOURCES += $$PWD/platformspecifics/u32/u32backend.cpp + HEADERS += $$PWD/platformspecifics/u32/u32backend.hpp + LIBS += -luser32 -lkernel32 -lpthread + QT += winextras } else:unix { - RC_FILE = icon.rc - SOURCES += $$PWD/platformspecifics/x11/x11backend.cpp - HEADERS += $$PWD/platformspecifics/x11/x11backend.hpp - QT += x11extras - LIBS += -lxcb-cursor -lxcb-xfixes -lxcb + RC_FILE = icon.rc + SOURCES += $$PWD/platformspecifics/x11/x11backend.cpp + HEADERS += $$PWD/platformspecifics/x11/x11backend.hpp + QT += x11extras + LIBS += -lxcb-cursor -lxcb-xfixes -lxcb } else { - error(Unsupported platform); + error(Unsupported platform); } FORMS += mainwindow.ui \ @@ -149,7 +153,8 @@ FORMS += mainwindow.ui \ DISTFILES += \ README.md \ LICENSE \ - OlderSystemFix.patch + OlderSystemFix.patch \ + appveyor.yml RESOURCES += \ icon.qrc diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..b60fe2f --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,15 @@ +enviroment: + QTDIR: C:\Qt\5.9\mingw53_32 + PATH: %PATH%;%QTDIR%\bin;C:\MinGW\bin +build_script: + - git submodule update --init --recursive + - qmake CONFIG+=nopkg KShare.pro + - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-3.3.2-win64-dev.zip + - 7z x ffmpeg-3.3.2-win64-dev.zip + - set CPATH=ffmpeg-3.3.2-win64-dev\include;%CPATH% + - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-3.3.2-win64-static.zip + - 7z x ffmpeg-3.3.2-win64-static.zip + - set LIBRARY_PATH=ffmpeg-3.3.2-win64-static\lib;%LIBRARY_PATH% + - mingw32-make -j8 +artifacts: + - path: release/KShare.exe From 6bc6775e7ffe3171bd1c75ba5471d27078980e4f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 13:02:00 +0200 Subject: [PATCH 016/293] AppVeyor works now --- .gitignore | 2 +- AppVeyor/appveyor.yml | 27 ++++++++++++++ AppVeyor/make_installer.sh | 34 +++++++++++++++++ KShare.pro | 17 ++++++++- appveyor.yml | 15 -------- packages/arch/KShare-Stable/.gitignore | 1 + packages/arch/KShare-Stable/PKGBUILD | 27 ++++++++++++++ packages/arch/KShare-Stable/release.sh | 5 +++ packages/arch/KShare/PKGBUILD | 28 ++++++++++++++ packages/arch/KShare/PKGBUILD.sample | 28 ++++++++++++++ packages/arch/KShare/pre-push | 12 ++++++ packages/windows/LICENSE.txt | 1 + packages/windows/installer.iss.pattern.bottom | 11 ++++++ packages/windows/installer.iss.pattern.top | 37 +++++++++++++++++++ 14 files changed, 228 insertions(+), 17 deletions(-) create mode 100644 AppVeyor/appveyor.yml create mode 100644 AppVeyor/make_installer.sh delete mode 100644 appveyor.yml create mode 100644 packages/arch/KShare-Stable/.gitignore create mode 100644 packages/arch/KShare-Stable/PKGBUILD create mode 100755 packages/arch/KShare-Stable/release.sh create mode 100644 packages/arch/KShare/PKGBUILD create mode 100644 packages/arch/KShare/PKGBUILD.sample create mode 100755 packages/arch/KShare/pre-push create mode 100644 packages/windows/LICENSE.txt create mode 100644 packages/windows/installer.iss.pattern.bottom create mode 100644 packages/windows/installer.iss.pattern.top diff --git a/.gitignore b/.gitignore index 3dc99e9..c7c374a 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,7 @@ CMakeLists.txt.user Makefile # Executable -KShare +./KShare # Other *.out diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml new file mode 100644 index 0000000..33853c3 --- /dev/null +++ b/AppVeyor/appveyor.yml @@ -0,0 +1,27 @@ +environment: + QTDIR: C:\Qt\5.9\mingw53_32 +build_script: + - dir + - mkdir build + - cd build + - set PATH=%PATH%;%QTDIR%\bin;C:\Qt\Tools\mingw530_32\bin;C:\MinGW\msys\1.0\bin + - git submodule update --init --recursive + - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-3.3.2-win64-dev.zip + - 7z x ffmpeg-3.3.2-win64-dev.zip + - set FFMPEG_DEV_PATH=%CD%\ffmpeg-3.3.2-win64-dev + - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-3.3.2-win64-shared.zip + - 7z x ffmpeg-3.3.2-win64-shared.zip + - set FFMPEG_SHARED_PATH=%cd%\ffmpeg-3.3.2-win64-shared + - ps: Start-FileDownload https://downloads.sourceforge.net/project/qtav/depends/QtAV-depends-windows-x86%2Bx64.7z av.7z + - 7z x av.7z > NUL + - xcopy ffmpeg-3.3.2-win64-shared\* %QTDIR% /e /i /Y + - xcopy ffmpeg-3.3.2-win64-dev\* %QTDIR% /e /i /Y + - xcopy QtAV-depends-windows-x86+x64\* %QTDIR% /e /i /Y + - qmake CONFIG+=nopkg ../KShare.pro + - mingw32-make.exe -j8 + - copy release\KShare.exe ..\KShare.exe + - cd .. + - bash -xe AppVeyor\make_installer.sh +artifacts: + - path: KShare.exe + - path: installer.exe diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh new file mode 100644 index 0000000..40ba302 --- /dev/null +++ b/AppVeyor/make_installer.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +function addFile { + cp $1 . + echo "Source: \"$(basename $1)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss +} +ver=$(cat main.cpp | grep setApplicationVersion | sed "s/\\s*a.setApplicationVersion(\"//g" | sed "s/\");//g") + +cd packages/windows +cp ../../KShare.exe . || exit 1 +# BOOOOOOIII Feeels good, it's not powershell. + +sed "s/;VER;/$ver/" installer.iss.pattern.top > installer.iss + +addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avcodec-57.dll +#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avdevice-57.dll +#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avfilter-6.dll +addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avformat-57.dll +addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avutil-55.dll +#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/postproc-54.dll +#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/swresample-2.dll +addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/swscale-4.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Core.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Gui.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Widgets.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5WinExtras.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll +addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL +addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL +addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL + +cat installer.iss.pattern.bottom >> installer.iss +"C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss +cp Output/setup.exe ../../installer.exe || exit 1 diff --git a/KShare.pro b/KShare.pro index 9676e39..d46b19e 100644 --- a/KShare.pro +++ b/KShare.pro @@ -114,7 +114,21 @@ HEADERS += mainwindow.hpp \ filenamevalidator.hpp nopkg { +# win32 { +# !exists($$(FFMPEG_DEV_PATH)\README.txt) { +# error("You must define a valid FFMPEG_DEV_PATH") +# } + +# !exists($$(FFMPEG_SHARED_PATH)\README.txt) { +# error("You must define a valid FFMPEG_SHARED_PATH") +# } + +# INCLUDEPATH += $$(FFMPEG_DEV_PATH)\include +# LIBS += -L$$(FFMPEG_DEV_PATH)\lib +# message(Set the library and include paths); +# } LIBS += -lavcodec -lavformat -lavutil -lswscale + message(nopkg); } else { CONFIG += link_pkgconfig PKGCONFIG += libavformat libavcodec libswscale libavutil @@ -154,7 +168,8 @@ DISTFILES += \ README.md \ LICENSE \ OlderSystemFix.patch \ - appveyor.yml + AppVeyor/appveyor.yml \ + AppVeyor/make_installer.sh RESOURCES += \ icon.qrc diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index b60fe2f..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,15 +0,0 @@ -enviroment: - QTDIR: C:\Qt\5.9\mingw53_32 - PATH: %PATH%;%QTDIR%\bin;C:\MinGW\bin -build_script: - - git submodule update --init --recursive - - qmake CONFIG+=nopkg KShare.pro - - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-3.3.2-win64-dev.zip - - 7z x ffmpeg-3.3.2-win64-dev.zip - - set CPATH=ffmpeg-3.3.2-win64-dev\include;%CPATH% - - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-3.3.2-win64-static.zip - - 7z x ffmpeg-3.3.2-win64-static.zip - - set LIBRARY_PATH=ffmpeg-3.3.2-win64-static\lib;%LIBRARY_PATH% - - mingw32-make -j8 -artifacts: - - path: release/KShare.exe diff --git a/packages/arch/KShare-Stable/.gitignore b/packages/arch/KShare-Stable/.gitignore new file mode 100644 index 0000000..0f868b8 --- /dev/null +++ b/packages/arch/KShare-Stable/.gitignore @@ -0,0 +1 @@ +PKGBUILD.sample diff --git a/packages/arch/KShare-Stable/PKGBUILD b/packages/arch/KShare-Stable/PKGBUILD new file mode 100644 index 0000000..42e737e --- /dev/null +++ b/packages/arch/KShare-Stable/PKGBUILD @@ -0,0 +1,27 @@ +# Maintainer: ArsenArsen +pkgname=kshare +pkgver=4.1 +pkgrel=1 +conflicts=("kshare-git") +pkgdesc="A ShareX inspired cross platform utility written with Qt." +arch=('i686' 'x86_64') +url="https://github.com/ArsenArsen/KShare" +license=('MIT') +provides=('kshare=$pkgver') +depends=(qt5-base qt5-x11extras xcb-util-cursor ffmpeg libxfixes) +source=(git+https://github.com/ArsenArsen/KShare.git#tag=v${pkgver}) +sha1sums=('SKIP') + +build() { + cd "${srcdir}/KShare" + git submodule update --init --recursive + qmake + make +} + +package() { + cd "${srcdir}/KShare" + mkdir -p "$pkgdir/usr/bin" + install ./KShare "$pkgdir/usr/bin/kshare" +} + diff --git a/packages/arch/KShare-Stable/release.sh b/packages/arch/KShare-Stable/release.sh new file mode 100755 index 0000000..9d2ce27 --- /dev/null +++ b/packages/arch/KShare-Stable/release.sh @@ -0,0 +1,5 @@ +sed "s/;VER;/$1/" PKGBUILD.sample > PKGBUILD +makepkg --printsrcinfo > .SRCINFO +git stage .SRCINFO PKGBUILD +git commit -m "Release $1" +git push diff --git a/packages/arch/KShare/PKGBUILD b/packages/arch/KShare/PKGBUILD new file mode 100644 index 0000000..a146935 --- /dev/null +++ b/packages/arch/KShare/PKGBUILD @@ -0,0 +1,28 @@ +# Maintainer: ArsenArsen +pkgname=kshare-git +pkgver=cfdecf06cedd9002b2fb4e1ef8df67c72fc540f94 +pkgrel=1 +conflicts=("kshare") +pkgdesc="A ShareX inspired cross platform utility written with Qt." +arch=('i686' 'x86_64') +url="https://github.com/ArsenArsen/KShare" +license=('MIT') +provides=('kshare=$pkgver') +depends=(qt5-base qt5-x11extras xcb-util-cursor ffmpeg libxfixes) +source=(git+https://github.com/ArsenArsen/KShare.git) +sha1sums=('SKIP') + +build() { + cd "${srcdir}/KShare" + git checkout dev + git submodule update --init --recursive + qmake + make +} + +package() { + cd "${srcdir}/KShare" + mkdir -p "$pkgdir/usr/bin" + install ./KShare "$pkgdir/usr/bin/kshare" +} + diff --git a/packages/arch/KShare/PKGBUILD.sample b/packages/arch/KShare/PKGBUILD.sample new file mode 100644 index 0000000..8915b05 --- /dev/null +++ b/packages/arch/KShare/PKGBUILD.sample @@ -0,0 +1,28 @@ +# Maintainer: ArsenArsen +pkgname=kshare-git +pkgver=;COMMIT; +pkgrel=1 +conflicts=("kshare") +pkgdesc="A ShareX inspired cross platform utility written with Qt." +arch=('i686' 'x86_64') +url="https://github.com/ArsenArsen/KShare" +license=('MIT') +provides=('kshare=$pkgver') +depends=(qt5-base qt5-x11extras xcb-util-cursor ffmpeg libxfixes) +source=(git+https://github.com/ArsenArsen/KShare.git) +sha1sums=('SKIP') + +build() { + cd "${srcdir}/KShare" + git checkout dev + git submodule update --init --recursive + qmake + make +} + +package() { + cd "${srcdir}/KShare" + mkdir -p "$pkgdir/usr/bin" + install ./KShare "$pkgdir/usr/bin/kshare" +} + diff --git a/packages/arch/KShare/pre-push b/packages/arch/KShare/pre-push new file mode 100755 index 0000000..7d393f0 --- /dev/null +++ b/packages/arch/KShare/pre-push @@ -0,0 +1,12 @@ +#!/bin/bash +if [[ `git rev-parse --abbrev-ref HEAD 2>/dev/null` == "dev" ]] +then + HASH=`git rev-parse --verify HEAD` + sed "s/;COMMIT;/c$HASH/g" /media/arsen/Data/Packages/KShare/PKGBUILD.sample > /media/arsen/Data/Packages/KShare/PKGBUILD + cd /media/arsen/Data/Packages/KShare + makepkg --printsrcinfo > .SRCINFO + git stage . + git commit -m "UPDATE $HASH" + git push +fi + diff --git a/packages/windows/LICENSE.txt b/packages/windows/LICENSE.txt new file mode 100644 index 0000000..f2610ef --- /dev/null +++ b/packages/windows/LICENSE.txt @@ -0,0 +1 @@ +BLANK: FILL IN BEFORE RELEASE diff --git a/packages/windows/installer.iss.pattern.bottom b/packages/windows/installer.iss.pattern.bottom new file mode 100644 index 0000000..cedf697 --- /dev/null +++ b/packages/windows/installer.iss.pattern.bottom @@ -0,0 +1,11 @@ +;Source: "FILE"; DestDir: "{app}"; Flags: ignoreversion +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" +Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + diff --git a/packages/windows/installer.iss.pattern.top b/packages/windows/installer.iss.pattern.top new file mode 100644 index 0000000..6887350 --- /dev/null +++ b/packages/windows/installer.iss.pattern.top @@ -0,0 +1,37 @@ +; Script generated by the Inno Script Studio Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define MyAppName "KShare" +#define MyAppVersion ";VER;" +#define MyAppPublisher "ArsenArsen" +#define MyAppURL "http://kshare.arsenarsen.com/" +#define MyAppExeName "KShare.exe" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{4D052A58-8982-4FB0-A542-22D1E3936AA9} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={pf}\{#MyAppName} +DefaultGroupName={#MyAppName} +LicenseFile=LICENSE.txt +OutputBaseFilename=setup +Compression=lzma +SolidCompression=yes + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "KShare.exe"; DestDir: "{app}"; Flags: ignoreversion + From ddc8d7e36b048687c3888f82c4fe28449f6d7748 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 14:38:43 +0200 Subject: [PATCH 017/293] Try to bundle more DLLs because with the exe --- AppVeyor/make_installer.sh | 44 +++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 40ba302..b95fad4 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -3,6 +3,13 @@ function addFile { cp $1 . echo "Source: \"$(basename $1)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss } + +function addAllFiles { + find $1 -type f -iname $2 | while read -r filename; do + addFile filename + done +} + ver=$(cat main.cpp | grep setApplicationVersion | sed "s/\\s*a.setApplicationVersion(\"//g" | sed "s/\");//g") cd packages/windows @@ -11,23 +18,26 @@ cp ../../KShare.exe . || exit 1 sed "s/;VER;/$ver/" installer.iss.pattern.top > installer.iss -addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avcodec-57.dll -#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avdevice-57.dll -#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avfilter-6.dll -addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avformat-57.dll -addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avutil-55.dll -#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/postproc-54.dll -#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/swresample-2.dll -addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/swscale-4.dll -addFile /c/Qt/5.9/mingw53_32/bin/Qt5Core.dll -addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll -addFile /c/Qt/5.9/mingw53_32/bin/Qt5Gui.dll -addFile /c/Qt/5.9/mingw53_32/bin/Qt5Widgets.dll -addFile /c/Qt/5.9/mingw53_32/bin/Qt5WinExtras.dll -addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll -addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL -addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL -addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL +#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avcodec-57.dll +##addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avdevice-57.dll +##addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avfilter-6.dll +#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avformat-57.dll +#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avutil-55.dll +##addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/postproc-54.dll +##addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/swresample-2.dll +#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/swscale-4.dll +#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Core.dll +#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll +#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Gui.dll +#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Widgets.dll +#addFile /c/Qt/5.9/mingw53_32/bin/Qt5WinExtras.dll +#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll +#addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL +#addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL +#addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL + +addAllFiles /c/Qt/5.9/mingw53_32/bin/ '*.dll' +addAllFiles ../../build/ffmpeg-3.3.2-win64-shared/bin/ '*.dll' cat installer.iss.pattern.bottom >> installer.iss "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss From f67d9613f72d38d94d2e2df000f3c64077848148 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 14:48:24 +0200 Subject: [PATCH 018/293] Fix a stupid error in the installer thing --- AppVeyor/make_installer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index b95fad4..93aa335 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -6,7 +6,7 @@ function addFile { function addAllFiles { find $1 -type f -iname $2 | while read -r filename; do - addFile filename + addFile $filename done } From 4e91d8f8e592e324bd982cb87a704ee3ca519b18 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 14:55:23 +0200 Subject: [PATCH 019/293] Fix another stupid error in the installer thing --- AppVeyor/make_installer.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 93aa335..38cf4ad 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -5,8 +5,10 @@ function addFile { } function addAllFiles { - find $1 -type f -iname $2 | while read -r filename; do - addFile $filename + (find $1 -type f -iname "$2" || exit 1) | while read -r filename; do + cp $filename . + echo $filename + echo "Source: \"$(basename $filename)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss done } From 23b6493758f4090989f7822a4c1ac7947cdaa588 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 14:57:50 +0200 Subject: [PATCH 020/293] Use different DLLs --- AppVeyor/make_installer.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 38cf4ad..8cc3dac 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -8,7 +8,7 @@ function addAllFiles { (find $1 -type f -iname "$2" || exit 1) | while read -r filename; do cp $filename . echo $filename - echo "Source: \"$(basename $filename)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss + echo "Source: \"$(basename $filename)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss done } @@ -39,7 +39,7 @@ sed "s/;VER;/$ver/" installer.iss.pattern.top > installer.iss #addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL addAllFiles /c/Qt/5.9/mingw53_32/bin/ '*.dll' -addAllFiles ../../build/ffmpeg-3.3.2-win64-shared/bin/ '*.dll' +addAllFiles ../../build/QtAV-depends-windows-x86+x64/bin/ '*.dll' cat installer.iss.pattern.bottom >> installer.iss "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss From 2bac3ceabd6171e98ee6ac0becae2fdc792f2ba0 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 15:04:46 +0200 Subject: [PATCH 021/293] How does one use bash? --- AppVeyor/make_installer.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 8cc3dac..9a57600 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -1,15 +1,12 @@ #!/usr/bin/env bash function addFile { + echo $1 cp $1 . echo "Source: \"$(basename $1)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss } function addAllFiles { - (find $1 -type f -iname "$2" || exit 1) | while read -r filename; do - cp $filename . - echo $filename - echo "Source: \"$(basename $filename)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss - done + for file in $1/$2; do addFile "$file"; done } ver=$(cat main.cpp | grep setApplicationVersion | sed "s/\\s*a.setApplicationVersion(\"//g" | sed "s/\");//g") From 300c82075946a7a6846cccd60e9922380b78492a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 15:13:20 +0200 Subject: [PATCH 022/293] I have no idea what am I doing with these DLLs --- AppVeyor/make_installer.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 9a57600..59adcfd 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -17,26 +17,26 @@ cp ../../KShare.exe . || exit 1 sed "s/;VER;/$ver/" installer.iss.pattern.top > installer.iss -#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avcodec-57.dll -##addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avdevice-57.dll -##addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avfilter-6.dll -#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avformat-57.dll -#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/avutil-55.dll -##addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/postproc-54.dll -##addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/swresample-2.dll -#addFile ../../build/ffmpeg-3.3.2-win64-shared/bin/swscale-4.dll -#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Core.dll -#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll -#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Gui.dll -#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Widgets.dll -#addFile /c/Qt/5.9/mingw53_32/bin/Qt5WinExtras.dll -#addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll -#addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL -#addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL -#addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL +addFile ../../build/QtAV-depends-windows-x86+x64/bin/avcodec-57.dll +#addFile ../../build/QtAV-depends-windows-x86+x64/bin/avdevice-57.dll +#addFile ../../build/QtAV-depends-windows-x86+x64/bin/avfilter-6.dll +addFile ../../build/QtAV-depends-windows-x86+x64/bin/avformat-57.dll +addFile ../../build/QtAV-depends-windows-x86+x64/bin/avutil-55.dll +#addFile ../../build/QtAV-depends-windows-x86+x64/bin/postproc-54.dll +#addFile ../../build/QtAV-depends-windows-x86+x64/bin/swresample-2.dll +addFile ../../build/QtAV-depends-windows-x86+x64/bin/swscale-4.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Core.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Gui.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Widgets.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5WinExtras.dll +addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll +addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL +addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL +addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL -addAllFiles /c/Qt/5.9/mingw53_32/bin/ '*.dll' -addAllFiles ../../build/QtAV-depends-windows-x86+x64/bin/ '*.dll' +#addAllFiles /c/Qt/5.9/mingw53_32/bin/ '*.dll' +#addAllFiles ../../build/QtAV-depends-windows-x86+x64/bin/ '*.dll' cat installer.iss.pattern.bottom >> installer.iss "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss From 16ba31fec2aea704742f63c00f4266c5167b0be1 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 15:21:13 +0200 Subject: [PATCH 023/293] I still dont know but I apparently need this --- AppVeyor/make_installer.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 59adcfd..d3ad584 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -22,8 +22,8 @@ addFile ../../build/QtAV-depends-windows-x86+x64/bin/avcodec-57.dll #addFile ../../build/QtAV-depends-windows-x86+x64/bin/avfilter-6.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/avformat-57.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/avutil-55.dll -#addFile ../../build/QtAV-depends-windows-x86+x64/bin/postproc-54.dll -#addFile ../../build/QtAV-depends-windows-x86+x64/bin/swresample-2.dll +addFile ../../build/QtAV-depends-windows-x86+x64/bin/postproc-54.dll +addFile ../../build/QtAV-depends-windows-x86+x64/bin/swresample-2.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/swscale-4.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5Core.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll From 411fc7f92b9527b3f5c81227ac10066bc9e6e5cb Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 15:24:13 +0200 Subject: [PATCH 024/293] I don't have this though --- AppVeyor/make_installer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index d3ad584..03fc7d2 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -22,7 +22,7 @@ addFile ../../build/QtAV-depends-windows-x86+x64/bin/avcodec-57.dll #addFile ../../build/QtAV-depends-windows-x86+x64/bin/avfilter-6.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/avformat-57.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/avutil-55.dll -addFile ../../build/QtAV-depends-windows-x86+x64/bin/postproc-54.dll +#addFile ../../build/QtAV-depends-windows-x86+x64/bin/postproc-54.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/swresample-2.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/swscale-4.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5Core.dll From fb92397fb0de94e9f88fc0d04ba234ec3f290c62 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 15:33:56 +0200 Subject: [PATCH 025/293] I missed the Windows plugin --- AppVeyor/make_installer.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 03fc7d2..dfb42d2 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -5,6 +5,13 @@ function addFile { echo "Source: \"$(basename $1)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss } +function addFileIn { + echo $1 + mkdir -p $2 + cp $1 $2 + echo "Source: \"$2\\$2\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss +} + function addAllFiles { for file in $1/$2; do addFile "$file"; done } @@ -31,6 +38,9 @@ addFile /c/Qt/5.9/mingw53_32/bin/Qt5Gui.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5Widgets.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5WinExtras.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll + +addFileIn /c/Qt/5.9/mingw53_32/plugins/platforms/qwindows.dll platforms + addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL From a48248ec79ef4f2042b1a872f0759bc34898c4f8 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 15:36:33 +0200 Subject: [PATCH 026/293] OOps --- AppVeyor/make_installer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index dfb42d2..1494649 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -9,7 +9,7 @@ function addFileIn { echo $1 mkdir -p $2 cp $1 $2 - echo "Source: \"$2\\$2\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss + echo "Source: \"$2\\$(basename $1)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss } function addAllFiles { From 69d0796881986980d052a3b91eff359a4db71875 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 15:41:18 +0200 Subject: [PATCH 027/293] Make the addFileIn target right --- AppVeyor/make_installer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 1494649..60e7007 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -9,7 +9,7 @@ function addFileIn { echo $1 mkdir -p $2 cp $1 $2 - echo "Source: \"$2\\$(basename $1)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss + echo "Source: \"$2\\$(basename $1)\"; DestDir: \"{app}\\$2\"; Flags: ignoreversion" >> installer.iss } function addAllFiles { From 010278105ddc7596f2abd684729cc00545eaaef0 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 16:26:00 +0200 Subject: [PATCH 028/293] Fix a logic error --- AppVeyor/make_installer.sh | 11 -- README.md | 2 +- hotkeying.cpp | 5 +- packages/windows/LICENSE.txt | 256 ++++++++++++++++++++++++++++++++++- 4 files changed, 257 insertions(+), 17 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 60e7007..2f241a9 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -12,24 +12,16 @@ function addFileIn { echo "Source: \"$2\\$(basename $1)\"; DestDir: \"{app}\\$2\"; Flags: ignoreversion" >> installer.iss } -function addAllFiles { - for file in $1/$2; do addFile "$file"; done -} - ver=$(cat main.cpp | grep setApplicationVersion | sed "s/\\s*a.setApplicationVersion(\"//g" | sed "s/\");//g") cd packages/windows cp ../../KShare.exe . || exit 1 -# BOOOOOOIII Feeels good, it's not powershell. sed "s/;VER;/$ver/" installer.iss.pattern.top > installer.iss addFile ../../build/QtAV-depends-windows-x86+x64/bin/avcodec-57.dll -#addFile ../../build/QtAV-depends-windows-x86+x64/bin/avdevice-57.dll -#addFile ../../build/QtAV-depends-windows-x86+x64/bin/avfilter-6.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/avformat-57.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/avutil-55.dll -#addFile ../../build/QtAV-depends-windows-x86+x64/bin/postproc-54.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/swresample-2.dll addFile ../../build/QtAV-depends-windows-x86+x64/bin/swscale-4.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5Core.dll @@ -45,9 +37,6 @@ addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL -#addAllFiles /c/Qt/5.9/mingw53_32/bin/ '*.dll' -#addAllFiles ../../build/QtAV-depends-windows-x86+x64/bin/ '*.dll' - cat installer.iss.pattern.bottom >> installer.iss "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss cp Output/setup.exe ../../installer.exe || exit 1 diff --git a/README.md b/README.md index c835253..7931c7f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A [ShareX](https://getsharex.com/) inspired cross platform utility written with |Linux|Windows|OS X| |:---:|:-----:|:--:| -|[![Build Status](https://nativeci.arsenarsen.com/job/KShare/badge/icon)](https://nativeci.arsenarsen.com/job/KShare)| [![Build Status](https://nativeci.arsenarsen.com/job/KShare%20Windows%20x86_64/badge/icon)](https://nativeci.arsenarsen.com/job/KShare%20Windows%20x86_64/)| Soon | +|[![Build Status](https://nativeci.arsenarsen.com/job/KShare/badge/icon)](https://nativeci.arsenarsen.com/job/KShare)| [![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)| Soon | ## Screenshot Made with KShare itself, of course :) ![](http://i.imgur.com/ffWvCun.png) diff --git a/hotkeying.cpp b/hotkeying.cpp index 90de05d..98aeeb1 100644 --- a/hotkeying.cpp +++ b/hotkeying.cpp @@ -30,10 +30,7 @@ void hotkeying::load(QString seqName, std::function func, QString def) { if (hotkeys.contains(seqName)) return; QString k = settings::settings().value(name).toString(); if (!k.isEmpty()) { - if (!k.isEmpty()) - h = new QHotkey(QKeySequence(settings::settings().value(k).toString()), true); - else - h = new QHotkey(def.isEmpty() ? "" : def, true); + h = new QHotkey(QKeySequence(k), true); } else h = new QHotkey(def.isEmpty() ? "" : def, true); QObject::connect(h, &QHotkey::activated, func); diff --git a/packages/windows/LICENSE.txt b/packages/windows/LICENSE.txt index f2610ef..2c68ee9 100644 --- a/packages/windows/LICENSE.txt +++ b/packages/windows/LICENSE.txt @@ -1 +1,255 @@ -BLANK: FILL IN BEFORE RELEASE +Copyright (c) 2017 ArsenArsen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +This software uses and possibly bundles Qt, OpenSSL, FFMpeg, and QHotkey, whose licenses are respectively: + +------------------------------ Qt: +GNU LESSER GENERAL PUBLIC LICENSE + + +The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. +Contact: http://www.qt.io/licensing/ + + +You may use, distribute and copy the Qt Toolkit under the terms of +GNU Lesser General Public License version 3, which is displayed below. +This license makes reference to the version 3 of the GNU General +Public License, which you can find in the LICENSE.GPLv3 file. + + +------------------------------ OpenSSL: +LICENSE ISSUES +============== + + +The OpenSSL toolkit stays under a double license, i.e. both the conditions of +the OpenSSL License and the original SSLeay license apply to the toolkit. +See below for the actual license texts. + + +OpenSSL License +--------------- + + +/* ==================================================================== +* Copyright (c) 1998-2017 The OpenSSL Project. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. All advertising materials mentioning features or use of this +* software must display the following acknowledgment: +* "This product includes software developed by the OpenSSL Project +* for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +* +* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +* endorse or promote products derived from this software without +* prior written permission. For written permission, please contact +* openssl-core@openssl.org. +* +* 5. Products derived from this software may not be called "OpenSSL" +* nor may "OpenSSL" appear in their names without prior written +* permission of the OpenSSL Project. +* +* 6. Redistributions of any form whatsoever must retain the following +* acknowledgment: +* "This product includes software developed by the OpenSSL Project +* for use in the OpenSSL Toolkit (http://www.openssl.org/)" +* +* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +* ==================================================================== +* +* This product includes cryptographic software written by Eric Young +* (eay@cryptsoft.com). This product includes software written by Tim +* Hudson (tjh@cryptsoft.com). +* +*/ + + +Original SSLeay License +----------------------- + + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +* All rights reserved. +* +* This package is an SSL implementation written +* by Eric Young (eay@cryptsoft.com). +* The implementation was written so as to conform with Netscapes SSL. +* +* This library is free for commercial and non-commercial use as long as +* the following conditions are aheared to. The following conditions +* apply to all code found in this distribution, be it the RC4, RSA, +* lhash, DES, etc., code; not just the SSL code. The SSL documentation +* included with this distribution is covered by the same copyright terms +* except that the holder is Tim Hudson (tjh@cryptsoft.com). +* +* Copyright remains Eric Young's, and as such any Copyright notices in +* the code are not to be removed. +* If this package is used in a product, Eric Young should be given attribution +* as the author of the parts of the library used. +* This can be in the form of a textual message at program startup or +* in documentation (online or textual) provided with the package. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. All advertising materials mentioning features or use of this software +* must display the following acknowledgement: +* "This product includes cryptographic software written by +* Eric Young (eay@cryptsoft.com)" +* The word 'cryptographic' can be left out if the rouines from the library +* being used are not cryptographic related :-). +* 4. If you include any Windows specific code (or a derivative thereof) from +* the apps directory (application code) you must include an acknowledgement: +* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" +* +* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* The licence and distribution terms for any publically available version or +* derivative of this code cannot be changed. i.e. this code cannot simply be +* copied and put under another distribution licence +* [including the GNU Public Licence.] +*/ + + +------------------------------ FFMpeg: +License +Most files in FFmpeg are under the GNU Lesser General Public License version 2.1 or later (LGPL v2.1+). Read the file COPYING.LGPLv2.1 for details. Some other files have MIT/X11/BSD-style licenses. In combination the LGPL v2.1+ applies to FFmpeg. +Some optional parts of FFmpeg are licensed under the GNU General Public License version 2 or later (GPL v2+). See the file COPYING.GPLv2 for details. None of these parts are used by default, you have to explicitly pass --enable-gpl to configure to activate them. In this case, FFmpeg's license changes to GPL v2+. +Specifically, the GPL parts of FFmpeg are: +libpostproc +optional x86 optimization in the files +libavcodec/x86/flac_dsp_gpl.asm +libavcodec/x86/idct_mmx.c +libavfilter/x86/vf_removegrain.asm +the following building and testing tools +compat/solaris/make_sunver.pl +doc/t2h.pm +doc/texi2pod.pl +libswresample/swresample-test.c +tests/checkasm/* +tests/tiny_ssim.c +the following filters in libavfilter: +vf_blackframe.c +vf_boxblur.c +vf_colormatrix.c +vf_cover_rect.c +vf_cropdetect.c +vf_delogo.c +vf_eq.c +vf_find_rect.c +vf_fspp.c +vf_geq.c +vf_histeq.c +vf_hqdn3d.c +vf_interlace.c +vf_kerndeint.c +vf_mcdeint.c +vf_mpdecimate.c +vf_owdenoise.c +vf_perspective.c +vf_phase.c +vf_pp.c +vf_pp7.c +vf_pullup.c +vf_repeatfields.c +vf_sab.c +vf_smartblur.c +vf_spp.c +vf_stereo3d.c +vf_super2xsai.c +vf_tinterlace.c +vf_uspp.c +vsrc_mptestsrc.c +Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then the configure parameter --enable-version3 will activate this licensing option for you. Read the file COPYING.LGPLv3 or, if you have enabled GPL parts, COPYING.GPLv3 to learn the exact legal terms that apply in this case. +There are a handful of files under other licensing terms, namely: +The files libavcodec/jfdctfst.c, libavcodec/jfdctint_template.c and libavcodec/jrevdct.c are taken from libjpeg, see the top of the files for licensing details. Specifically note that you must credit the IJG in the documentation accompanying your program if you only distribute executables. You must also indicate any changes including additions and deletions to those three files in the documentation. +tests/reference.pnm is under the expat license. +External libraries +FFmpeg can be combined with a number of external libraries, which sometimes affect the licensing of binaries resulting from the combination. +Compatible libraries +The following libraries are under GPL: +frei0r +libcdio +librubberband +libvidstab +libx264 +libx265 +libxavs +libxvid +When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by passing --enable-gpl to configure. +The OpenCORE and VisualOn libraries are under the Apache License 2.0. That license is incompatible with the LGPL v2.1 and the GPL v2, but not with version 3 of those licenses. So to combine these libraries with FFmpeg, the license version needs to be upgraded by passing --enable-version3 to configure. +Incompatible libraries +There are certain libraries you can combine with FFmpeg whose licenses are not compatible with the GPL and/or the LGPL. If you wish to enable these libraries, even in circumstances that their license may be incompatible, pass --enable-nonfree to configure. But note that if you enable any of these libraries the resulting binary will be under a complex license mix that is more restrictive than the LGPL and that may result in additional obligations. It is possible that these restrictions cause the resulting binary to be unredistributable. +The Fraunhofer FDK AAC and OpenSSL libraries are under licenses which are incompatible with the GPLv2 and v3. To the best of our knowledge, they are compatible with the LGPL. +The NVENC library, while its header file is licensed under the compatible MIT license, requires a proprietary binary blob at run time, and is deemed to be incompatible with the GPL. We are not certain if it is compatible with the LGPL, but we require --enable-nonfree even with LGPL configurations in case it is not. + +------------------------------ QHotkey: +Copyright (c) 2016, Felix Barz +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of QHotkey nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From ce01c74530d5852ca50df1cece90e58cad2ba68c Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 17:33:03 +0200 Subject: [PATCH 029/293] Will this work? --- .travis.yml | 9 +++++++++ KShare.pro | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..64214a8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +os: osx +before_install: + - brew install qt + - brew install ffmpeg@3.2 + - brew link ffmpeg + - brew link qt + - export CPATH=/usr/local/Cellar/ffmpeg/3.2/include:$CPATH + - export LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.2/lib:$LIBRARY_PATH + - export DYLD_LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.2/lib:$DYLD_LIBRARY_PATH diff --git a/KShare.pro b/KShare.pro index d46b19e..1892928 100644 --- a/KShare.pro +++ b/KShare.pro @@ -169,7 +169,8 @@ DISTFILES += \ LICENSE \ OlderSystemFix.patch \ AppVeyor/appveyor.yml \ - AppVeyor/make_installer.sh + AppVeyor/make_installer.sh \ + .travis.yml RESOURCES += \ icon.qrc From 10a6aef454ba298e33b6ac6c3c4afc5906cccba6 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 17:37:55 +0200 Subject: [PATCH 030/293] Nope --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 64214a8..e3dc58c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,14 @@ os: osx +language: cpp before_install: - brew install qt - brew install ffmpeg@3.2 - brew link ffmpeg - - brew link qt + - brew link qt --force - export CPATH=/usr/local/Cellar/ffmpeg/3.2/include:$CPATH - export LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.2/lib:$LIBRARY_PATH - export DYLD_LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.2/lib:$DYLD_LIBRARY_PATH + - export PKG_CONFIG_PATH=:$PKG_CONFIG_PATH +script: + - qmake + - make -j4 From 130d64fb935b86315367b8c96971f04d4f191ee8 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 18:09:57 +0200 Subject: [PATCH 031/293] Homebrew being stupid --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3dc58c..51bd01e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,12 @@ os: osx language: cpp before_install: - brew install qt - - brew install ffmpeg@3.2 + - brew install ffmpeg - brew link ffmpeg - brew link qt --force - - export CPATH=/usr/local/Cellar/ffmpeg/3.2/include:$CPATH - - export LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.2/lib:$LIBRARY_PATH - - export DYLD_LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.2/lib:$DYLD_LIBRARY_PATH + - export CPATH=/usr/local/Cellar/ffmpeg/3.3.2/include:$CPATH + - export LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.3.2/lib:$LIBRARY_PATH + - export DYLD_LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.3.2/lib:$DYLD_LIBRARY_PATH - export PKG_CONFIG_PATH=:$PKG_CONFIG_PATH script: - qmake From f0a2687de70b33c5be69d4e76336518a82e4e776 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 7 Jul 2017 22:41:10 +0200 Subject: [PATCH 032/293] Make the artifacts named on AppVeyor --- .travis.yml | 1 - AppVeyor/appveyor.yml | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 51bd01e..b36c40f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,6 @@ before_install: - export CPATH=/usr/local/Cellar/ffmpeg/3.3.2/include:$CPATH - export LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.3.2/lib:$LIBRARY_PATH - export DYLD_LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.3.2/lib:$DYLD_LIBRARY_PATH - - export PKG_CONFIG_PATH=:$PKG_CONFIG_PATH script: - qmake - make -j4 diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index 33853c3..a50ce55 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -24,4 +24,6 @@ build_script: - bash -xe AppVeyor\make_installer.sh artifacts: - path: KShare.exe + name: Shared link - path: installer.exe + name: Installer From 33d757c2f6326c4ed5bb4f0bbae8542cd52c1c28 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 10:54:58 +0200 Subject: [PATCH 033/293] x64 build --- AppVeyor/appveyor.yml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index a50ce55..fd00fa9 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -1,23 +1,18 @@ environment: QTDIR: C:\Qt\5.9\mingw53_32 +platform:x64 build_script: - dir - mkdir build - cd build - set PATH=%PATH%;%QTDIR%\bin;C:\Qt\Tools\mingw530_32\bin;C:\MinGW\msys\1.0\bin - git submodule update --init --recursive - - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-3.3.2-win64-dev.zip - - 7z x ffmpeg-3.3.2-win64-dev.zip - - set FFMPEG_DEV_PATH=%CD%\ffmpeg-3.3.2-win64-dev - - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-3.3.2-win64-shared.zip - - 7z x ffmpeg-3.3.2-win64-shared.zip - - set FFMPEG_SHARED_PATH=%cd%\ffmpeg-3.3.2-win64-shared - ps: Start-FileDownload https://downloads.sourceforge.net/project/qtav/depends/QtAV-depends-windows-x86%2Bx64.7z av.7z - 7z x av.7z > NUL - - xcopy ffmpeg-3.3.2-win64-shared\* %QTDIR% /e /i /Y - - xcopy ffmpeg-3.3.2-win64-dev\* %QTDIR% /e /i /Y - - xcopy QtAV-depends-windows-x86+x64\* %QTDIR% /e /i /Y - - qmake CONFIG+=nopkg ../KShare.pro + - xcopy QtAV-depends-windows-x86+x64\bin\x64\* %QTDIR%\bin\ /e /i /Y + - xcopy QtAV-depends-windows-x86+x64\lib\x64\* %QTDIR%\lib\ /e /i /Y + - xcopy QtAV-depends-windows-x86+x64\include\* %QTDIR%\include\ /e /i /Y + - qmake ../KShare.pro - mingw32-make.exe -j8 - copy release\KShare.exe ..\KShare.exe - cd .. From a4680b8742dcd84f3d0ed14bdbb428a80cfa5ca6 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 10:56:01 +0200 Subject: [PATCH 034/293] Yaml is too sensitive --- AppVeyor/appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index fd00fa9..14f2158 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -1,6 +1,6 @@ environment: QTDIR: C:\Qt\5.9\mingw53_32 -platform:x64 +platform: x64 build_script: - dir - mkdir build From 58e1f58e9b3db5359e32442ce85f207807cd1ba7 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 10:57:50 +0200 Subject: [PATCH 035/293] Use nopkg on AppVeyor again --- AppVeyor/appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index 14f2158..4683e13 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -12,7 +12,7 @@ build_script: - xcopy QtAV-depends-windows-x86+x64\bin\x64\* %QTDIR%\bin\ /e /i /Y - xcopy QtAV-depends-windows-x86+x64\lib\x64\* %QTDIR%\lib\ /e /i /Y - xcopy QtAV-depends-windows-x86+x64\include\* %QTDIR%\include\ /e /i /Y - - qmake ../KShare.pro + - qmake CONFIG+=nopkg ../KShare.pro - mingw32-make.exe -j8 - copy release\KShare.exe ..\KShare.exe - cd .. From 5148bf4831d61d6dc8af2a46c5315aebd7aae1b0 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:13:02 +0200 Subject: [PATCH 036/293] I broke it again --- AppVeyor/appveyor.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index 4683e13..1febeb2 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -7,8 +7,14 @@ build_script: - cd build - set PATH=%PATH%;%QTDIR%\bin;C:\Qt\Tools\mingw530_32\bin;C:\MinGW\msys\1.0\bin - git submodule update --init --recursive + - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-3.3.2-win64-dev.zip + - 7z x ffmpeg-3.3.2-win64-dev.zip + - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-3.3.2-win64-shared.zip + - 7z x ffmpeg-3.3.2-win64-shared.zip - ps: Start-FileDownload https://downloads.sourceforge.net/project/qtav/depends/QtAV-depends-windows-x86%2Bx64.7z av.7z - 7z x av.7z > NUL + - xcopy ffmpeg-3.3.2-win64-shared\* %QTDIR% /e /i /Y + - xcopy ffmpeg-3.3.2-win64-dev\* %QTDIR% /e /i /Y - xcopy QtAV-depends-windows-x86+x64\bin\x64\* %QTDIR%\bin\ /e /i /Y - xcopy QtAV-depends-windows-x86+x64\lib\x64\* %QTDIR%\lib\ /e /i /Y - xcopy QtAV-depends-windows-x86+x64\include\* %QTDIR%\include\ /e /i /Y From a17a91e41e327c716921815880ffbbb9abebd98d Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:17:16 +0200 Subject: [PATCH 037/293] Oh God it broke again --- AppVeyor/appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index 1febeb2..8123f44 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -1,6 +1,5 @@ environment: QTDIR: C:\Qt\5.9\mingw53_32 -platform: x64 build_script: - dir - mkdir build @@ -9,8 +8,10 @@ build_script: - git submodule update --init --recursive - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-3.3.2-win64-dev.zip - 7z x ffmpeg-3.3.2-win64-dev.zip + - set FFMPEG_DEV_PATH=%CD%\ffmpeg-3.3.2-win64-dev - curl -kLO https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-3.3.2-win64-shared.zip - 7z x ffmpeg-3.3.2-win64-shared.zip + - set FFMPEG_SHARED_PATH=%cd%\ffmpeg-3.3.2-win64-shared - ps: Start-FileDownload https://downloads.sourceforge.net/project/qtav/depends/QtAV-depends-windows-x86%2Bx64.7z av.7z - 7z x av.7z > NUL - xcopy ffmpeg-3.3.2-win64-shared\* %QTDIR% /e /i /Y From 25d2a6ad3040c59f94f6fd611eb708856ba03da4 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:19:30 +0200 Subject: [PATCH 038/293] Roll back all of that. --- AppVeyor/appveyor.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index 8123f44..a50ce55 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -16,9 +16,7 @@ build_script: - 7z x av.7z > NUL - xcopy ffmpeg-3.3.2-win64-shared\* %QTDIR% /e /i /Y - xcopy ffmpeg-3.3.2-win64-dev\* %QTDIR% /e /i /Y - - xcopy QtAV-depends-windows-x86+x64\bin\x64\* %QTDIR%\bin\ /e /i /Y - - xcopy QtAV-depends-windows-x86+x64\lib\x64\* %QTDIR%\lib\ /e /i /Y - - xcopy QtAV-depends-windows-x86+x64\include\* %QTDIR%\include\ /e /i /Y + - xcopy QtAV-depends-windows-x86+x64\* %QTDIR% /e /i /Y - qmake CONFIG+=nopkg ../KShare.pro - mingw32-make.exe -j8 - copy release\KShare.exe ..\KShare.exe From c45abe86c97e85402d30272771b8065028a242e2 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:22:42 +0200 Subject: [PATCH 039/293] Will x86 work? --- AppVeyor/appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index a50ce55..5f2dce3 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -1,5 +1,6 @@ environment: QTDIR: C:\Qt\5.9\mingw53_32 +platform: x86 build_script: - dir - mkdir build From 66cd2de2d9bb2798fdb26f88758135adf7f235d1 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:33:17 +0200 Subject: [PATCH 040/293] Add a portable version to Windows --- AppVeyor/appveyor.yml | 2 ++ AppVeyor/make_installer.sh | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index 5f2dce3..ed921b9 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -28,3 +28,5 @@ artifacts: name: Shared link - path: installer.exe name: Installer + - path: portable.zip + name: Portable version diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 2f241a9..49b3aca 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -9,13 +9,14 @@ function addFileIn { echo $1 mkdir -p $2 cp $1 $2 + 7z a -tzip $2\\$1 portable.zip echo "Source: \"$2\\$(basename $1)\"; DestDir: \"{app}\\$2\"; Flags: ignoreversion" >> installer.iss } ver=$(cat main.cpp | grep setApplicationVersion | sed "s/\\s*a.setApplicationVersion(\"//g" | sed "s/\");//g") cd packages/windows -cp ../../KShare.exe . || exit 1 +cp ../../KShare.exe . || exit 3 sed "s/;VER;/$ver/" installer.iss.pattern.top > installer.iss @@ -40,3 +41,4 @@ addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL cat installer.iss.pattern.bottom >> installer.iss "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss cp Output/setup.exe ../../installer.exe || exit 1 +cp Output/porable.zip ../../ || exit 2 From 8ba793500e3d2845cd266291871c36c83e90400f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:36:01 +0200 Subject: [PATCH 041/293] oops --- AppVeyor/make_installer.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 49b3aca..c64d7fc 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -9,8 +9,9 @@ function addFileIn { echo $1 mkdir -p $2 cp $1 $2 - 7z a -tzip $2\\$1 portable.zip - echo "Source: \"$2\\$(basename $1)\"; DestDir: \"{app}\\$2\"; Flags: ignoreversion" >> installer.iss + name=$2\\$(basename $1) + 7z a -tzip portable.zip $name + echo "Source: \"$name\"; DestDir: \"{app}\\$2\"; Flags: ignoreversion" >> installer.iss } ver=$(cat main.cpp | grep setApplicationVersion | sed "s/\\s*a.setApplicationVersion(\"//g" | sed "s/\");//g") From 54c9a9665966ad6b960b34bbaa0b46952129ad0a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:38:38 +0200 Subject: [PATCH 042/293] Ok then... --- AppVeyor/make_installer.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index c64d7fc..65b27f1 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -39,7 +39,9 @@ addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL +ls + cat installer.iss.pattern.bottom >> installer.iss "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss cp Output/setup.exe ../../installer.exe || exit 1 -cp Output/porable.zip ../../ || exit 2 +cp Output/portable.zip ../../ || exit 2 From a6a7dcfe3953d85edfd4b16f90a437642f7bb104 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:41:41 +0200 Subject: [PATCH 043/293] why it no work --- AppVeyor/appveyor.yml | 2 +- AppVeyor/make_installer.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index ed921b9..5c6c092 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -22,7 +22,7 @@ build_script: - mingw32-make.exe -j8 - copy release\KShare.exe ..\KShare.exe - cd .. - - bash -xe AppVeyor\make_installer.sh + - bash AppVeyor\make_installer.sh artifacts: - path: KShare.exe name: Shared link diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 65b27f1..0620e73 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -6,10 +6,10 @@ function addFile { } function addFileIn { - echo $1 + name=$2\\$(basename $1) + echo $1 $name mkdir -p $2 cp $1 $2 - name=$2\\$(basename $1) 7z a -tzip portable.zip $name echo "Source: \"$name\"; DestDir: \"{app}\\$2\"; Flags: ignoreversion" >> installer.iss } From e5dc2d0b992e6b0ac281503bb36c95ac481cc91d Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:45:29 +0200 Subject: [PATCH 044/293] Oh that's why --- AppVeyor/make_installer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 0620e73..5171d65 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -2,12 +2,12 @@ function addFile { echo $1 cp $1 . + 7z a -tzip portable.zip $(basename $1) echo "Source: \"$(basename $1)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss } function addFileIn { name=$2\\$(basename $1) - echo $1 $name mkdir -p $2 cp $1 $2 7z a -tzip portable.zip $name From 932df609cf40639ba0f90a3b0d123cb6052ccc5f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 11:48:14 +0200 Subject: [PATCH 045/293] I am bad --- AppVeyor/make_installer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 5171d65..732d0c5 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -44,4 +44,4 @@ ls cat installer.iss.pattern.bottom >> installer.iss "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss cp Output/setup.exe ../../installer.exe || exit 1 -cp Output/portable.zip ../../ || exit 2 +cp portable.zip ../../ || exit 2 From 6c4efc4340676a0e969bbcc86822fd163ab8fa7f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 12:28:47 +0200 Subject: [PATCH 046/293] Add SSL libs --- AppVeyor/make_installer.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 732d0c5..e293a43 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -39,6 +39,10 @@ addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL +for filename in /c/OpenSSL-Win32/bin/*.dll; do + addFile $filename +done + ls cat installer.iss.pattern.bottom >> installer.iss From 16c590c7d1fa44e5703e4f9ac47ca85e0b7c3de7 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 12:32:47 +0200 Subject: [PATCH 047/293] Add the KShare executable to the portable build --- AppVeyor/make_installer.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index e293a43..e7391e9 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -18,6 +18,7 @@ ver=$(cat main.cpp | grep setApplicationVersion | sed "s/\\s*a.setApplicationVer cd packages/windows cp ../../KShare.exe . || exit 3 +7z a -tzip portable.zip KShare.exe sed "s/;VER;/$ver/" installer.iss.pattern.top > installer.iss From 14671a0b5246b975a554bc4d65928a78ba852c21 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 12:39:43 +0200 Subject: [PATCH 048/293] Pinpoint the needed OpenSSL DLLs --- AppVeyor/make_installer.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index e7391e9..32dbb65 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -40,9 +40,9 @@ addFile /c/Qt/5.9/mingw53_32/bin/LIBSTDC++-6.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBWINPTHREAD-1.DLL addFile /c/Qt/5.9/mingw53_32/bin/LIBGCC_S_DW2-1.DLL -for filename in /c/OpenSSL-Win32/bin/*.dll; do - addFile $filename -done +addFile /c/OpenSSL-Win32/bin/libeay32.dll +addFile /c/OpenSSL-Win32/bin/ssleay32.dll +addFile /c/OpenSSL-Win32/bin/msvcr120.dll ls From 97db7ddc0cd88dc8eceaaf6006d0533152d828c4 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 12:53:08 +0200 Subject: [PATCH 049/293] Windows does not like svg --- mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index c7d4afd..8d2a8c3 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -42,7 +42,7 @@ void addHotkey(QString name, std::function action) { MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { instance = this; ui->setupUi(this); - setWindowIcon(QIcon(":/icons/icon.svg")); + setWindowIcon(QIcon(":/icons/icon.png")); tray = new QSystemTrayIcon(windowIcon(), this); tray->setToolTip("KShare"); tray->setVisible(true); From 15ca46f3d0e75f786eab69da2b7a1b5bb04eb3e4 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 8 Jul 2017 21:40:09 +0200 Subject: [PATCH 050/293] Add cursor slowdown WOW https://i.arsenarsen.com/khk0kdd2bh.png --- cropeditor/cropscene.cpp | 80 +++++++++++++++++++----------- cropeditor/cropscene.hpp | 8 ++- cropeditor/cropview.cpp | 1 + cropeditor/drawing/arrowitem.cpp | 11 ++-- cropeditor/drawing/arrowitem.hpp | 2 +- cropeditor/drawing/bluritem.cpp | 10 ++-- cropeditor/drawing/bluritem.hpp | 2 +- cropeditor/drawing/dotitem.cpp | 2 +- cropeditor/drawing/ellipseitem.cpp | 8 +-- cropeditor/drawing/ellipseitem.hpp | 2 +- cropeditor/drawing/eraseritem.cpp | 4 +- cropeditor/drawing/eraseritem.hpp | 2 +- cropeditor/drawing/lineitem.cpp | 6 +-- cropeditor/drawing/lineitem.hpp | 2 +- cropeditor/drawing/pathitem.cpp | 6 +-- cropeditor/drawing/pathitem.hpp | 2 +- cropeditor/drawing/rectitem.cpp | 8 +-- cropeditor/drawing/rectitem.hpp | 2 +- cropeditor/drawing/textitem.cpp | 8 +-- cropeditor/drawing/textitem.hpp | 2 +- main.cpp | 1 + 21 files changed, 100 insertions(+), 69 deletions(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index fc5a526..3e69c56 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -21,7 +21,7 @@ #include CropScene::CropScene(QObject *parent, QPixmap pixmap) -: QGraphicsScene(parent), drawingSelectionMaker([] { return nullptr; }), prevButtons(Qt::NoButton), +: QGraphicsScene(parent), cursorPos(0, 0), drawingSelectionMaker([] { return nullptr; }), prevButtons(Qt::NoButton), _brush(Qt::SolidPattern), _font(settings::settings().value("font", QFont()).value()) { _pixmap = pixmap; pen().setColor(settings::settings().value("penColor", pen().color()).value()); @@ -64,13 +64,23 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) show(); }); menu.addAction(settings); + QPolygonF cursorPoly; + cursorPoly << QPoint(-10, 0) // + << QPoint(10, 0) // + << QPoint(0, 0) // + << QPoint(0, 10) // + << QPoint(0, -10) // + << QPoint(0, 0); - magnifier = addPixmap(pixmap.copy(0, 0, 11, 11).scaled(110, 110)); + cursorItem = addPolygon(cursorPoly, QPen(Qt::white)); + cursorItem->setZValue(3); + + magnifier = addPixmap(QPixmap(110, 110)); magnifierBox = addRect(magnifier->boundingRect(), QPen(Qt::cyan)); - magnifier->setZValue(1); + magnifier->setZValue(3); magnifierBox->setZValue(1.1); magnifierBox->setParentItem(magnifier); - magnifierHint = addText("ptr: (0, 0)\nsel: (0, 0, 0, 0)"); + magnifierHint = addText("ptr: (0, 0)\nsel: (-1, -1, 0, 0)"); magnifierHint->setParentItem(magnifier); magnifierHint->setY(magnifier->boundingRect().height()); QColor c(Qt::cyan); @@ -80,20 +90,25 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) magnifierHintBox->setZValue(1); magnifierHint->setZValue(1.1); initMagnifierGrid(); - updateMag(QPointF(0, 0)); + updateMag(); connect(menu.addAction("Set Font"), &QAction::triggered, this, &CropScene::fontAsk); + QPolygonF poly; + QRect prect = pixmap.rect(); + poly.append(prect.topLeft()); + poly.append(prect.topRight()); + poly.append(prect.bottomRight()); + poly.append(prect.bottomLeft()); + polyItem = new QGraphicsPolygonItem(poly); + polyItem->setBrush(QBrush(QColor(0, 0, 0, 191))); + polyItem->setPen(QPen(Qt::NoPen)); + addItem(polyItem); QTimer::singleShot(0, [&] { - QPolygonF poly; - poly.append(sceneRect().topLeft()); - poly.append(sceneRect().topRight()); - poly.append(sceneRect().bottomRight()); - poly.append(sceneRect().bottomLeft()); - polyItem = new QGraphicsPolygonItem(poly); - polyItem->setBrush(QBrush(QColor(0, 0, 0, 191))); - polyItem->setPen(QPen(Qt::NoPen)); - addItem(polyItem); + auto pf = views()[0]->mapFromGlobal(QCursor::pos()); + cursorPos = QPoint(pf.x(), pf.y()); + cursorItem->setPos(cursorPos); + updateMag(); }); } @@ -147,14 +162,20 @@ void CropScene::fontAsk() { } void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { - updateMag(e->scenePos()); + QPointF delta = e->scenePos() - cursorPos; + if (e->modifiers() & Qt::ShiftModifier) { + cursorPos += delta / 2; + QCursor::setPos(views()[0]->mapToGlobal(cursorPos.toPoint())); + } else + cursorPos = e->scenePos(); + cursorItem->setPos(cursorPos); + updateMag(); auto buttons = e->buttons(); if (e->modifiers() & Qt::ControlModifier && buttons == Qt::LeftButton) { QTransform stupidThing = views()[0]->transform(); - auto item = itemAt(e->scenePos(), stupidThing); + auto item = itemAt(cursorPos, stupidThing); if (item && item != polyItem && item != rect && item->zValue() != -1) { - QPointF delta = e->scenePos() - e->lastScenePos(); item->moveBy(delta.x(), delta.y()); } return; @@ -163,14 +184,14 @@ void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { if (drawingSelection) { drawingSelection->mouseDragEvent(e, this); } else { - QPointF p = e->scenePos(); + QPointF p = cursorPos; if (rect == nullptr) { rect = new QGraphicsRectItem(p.x(), p.y(), 1, 1); initPos = p; QPen pen(Qt::NoBrush, 1); pen.setColor(Qt::cyan); rect->setPen(pen); - rect->setZValue(-0.1); + rect->setZValue(1); addItem(rect); } else { if (prevButtons == Qt::NoButton) { @@ -218,7 +239,7 @@ void CropScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { if (e->modifiers() & Qt::AltModifier) { QTransform stupidThing = views()[0]->transform(); - auto item = itemAt(e->scenePos(), stupidThing); + auto item = itemAt(cursorPos, stupidThing); if (item && item != polyItem && item != rect && item->zValue() != -1) { removeItem(item); } @@ -240,7 +261,7 @@ void CropScene::wheelEvent(QGraphicsSceneWheelEvent *event) { gridRectsY.clear(); initMagnifierGrid(); - updateMag(event->scenePos()); + updateMag(); } void CropScene::addDrawingAction(QMenu &menu, QString name, std::function item) { @@ -250,30 +271,32 @@ void CropScene::addDrawingAction(QMenu &menu, QString name, std::functionsetText(drawingName); - menu.exec(e->screenPos()); + menu.exec((cursorPos + contextOffset).toPoint()); e->accept(); } void CropScene::keyReleaseEvent(QKeyEvent *event) { - if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter || event->key() == Qt::Key_Escape) + if (((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && !drawingSelection) || event->key() == Qt::Key_Escape) done(event->key() != Qt::Key_Escape); } -void CropScene::updateMag(QPointF scenePos) { - QString rectStr("(0, 0, 0, 0)"); +void CropScene::updateMag() { + QString rectStr("(-1, -1, 0, 0)"); if (rect) { rectStr = "(%0, %1, %2, %3)"; rectStr = rectStr.arg(rect->rect().x()).arg(rect->rect().y()).arg(rect->rect().width()).arg(rect->rect().height()); } - magnifierHint->setPlainText(QString("ptr: (%0, %1)\nsel: %2").arg(scenePos.x()).arg(scenePos.y()).arg(rectStr)); + magnifierHint->setPlainText(QString("ptr: (%0, %1)\nsel: %2").arg(qRound(cursorPos.x())).arg(qRound(cursorPos.y())).arg(rectStr)); magnifierHintBox->setRect(magnifierHint->boundingRect()); int pixCnt = settings::settings().value("magnifierPixelCount", 11).toInt(); if (pixCnt % 2 == 0) pixCnt++; - QPointF magnifierTopLeft = scenePos - QPointF(pixCnt / 2., pixCnt / 2.); - QPointF magnifierPos = scenePos + QPointF(5, 5); + QPointF magnifierTopLeft = cursorPos - QPointF(pixCnt / 2., pixCnt / 2.); + QPointF magnifierPos = cursorPos + QPointF(5, 5); magnifier->setPos(magnifierPos); magnifier->setPixmap(_pixmap.copy(magnifierTopLeft.x(), magnifierTopLeft.y(), pixCnt, pixCnt).scaled(110, 110)); @@ -316,6 +339,7 @@ void CropScene::done(bool notEsc) { if (notEsc && rect) { rect->setPen(QPen(Qt::NoPen)); magnifier->setVisible(false); + cursorItem->setVisible(false); magnifierBox->setVisible(false); magnifierHint->setVisible(false); magnifierHintBox->setVisible(false); diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index 0f93daa..d2dcfd4 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -34,6 +34,9 @@ public: void hide(); void show(); void setVisible(bool visible); + QPointF cursorPosition() { + return cursorPos; + } public slots: void fontAsk(); @@ -47,15 +50,15 @@ protected: void mousePressEvent(QGraphicsSceneMouseEvent *e) override; void wheelEvent(QGraphicsSceneWheelEvent *event) override; // WHEEEEEEL void contextMenuEvent(QGraphicsSceneContextMenuEvent *e) override; - void keyReleaseEvent(QKeyEvent *e) override; private: - void updateMag(QPointF scenePos); + void updateMag(); void initMagnifierGrid(); void addDrawingAction(QMenu &menu, QString name, std::function item); void done(bool notEsc); bool fullscreen; + QPointF cursorPos; std::function drawingSelectionMaker; QFlags prevButtons; QPixmap _pixmap; @@ -75,6 +78,7 @@ private: QAction *display; QList gridRectsX; QList gridRectsY; + QGraphicsPolygonItem *cursorItem = nullptr; }; #endif // CROPSCENE_HPP diff --git a/cropeditor/cropview.cpp b/cropeditor/cropview.cpp index c4599c3..03e34f2 100644 --- a/cropeditor/cropview.cpp +++ b/cropeditor/cropview.cpp @@ -9,4 +9,5 @@ CropView::CropView(QGraphicsScene *scene) : QGraphicsView(scene) { setCursor(QCursor(Qt::CrossCursor)); setMouseTracking(true); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + setCursor(Qt::BlankCursor); } diff --git a/cropeditor/drawing/arrowitem.cpp b/cropeditor/drawing/arrowitem.cpp index e1558e4..c7b31f6 100644 --- a/cropeditor/drawing/arrowitem.cpp +++ b/cropeditor/drawing/arrowitem.cpp @@ -2,9 +2,9 @@ #include #include -void ArrowItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { +void ArrowItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (init.isNull()) { - init = e->scenePos(); + init = scene->cursorPosition(); line = scene->addLine(QLineF(init, init), scene->pen()); QPainterPath poly; qreal w = settings::settings().value("arrow/width", 20).toDouble() / 2; @@ -14,8 +14,9 @@ void ArrowItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { poly.lineTo(QPoint(w, h)); head = scene->addPath(poly, scene->pen(), scene->brush()); } else { - line->setLine(QLineF(init, e->scenePos())); - head->setRotation(270 + qRadiansToDegrees(qAtan2((init.y() - e->scenePos().y()), (init.x() - e->scenePos().x())))); + line->setLine(QLineF(init, scene->cursorPosition())); + head->setRotation( + 270 + qRadiansToDegrees(qAtan2((init.y() - scene->cursorPosition().y()), (init.x() - scene->cursorPosition().x())))); } - head->setPos(e->scenePos()); + head->setPos(scene->cursorPosition()); } diff --git a/cropeditor/drawing/arrowitem.hpp b/cropeditor/drawing/arrowitem.hpp index 13050f1..c43be3f 100644 --- a/cropeditor/drawing/arrowitem.hpp +++ b/cropeditor/drawing/arrowitem.hpp @@ -11,7 +11,7 @@ public: QString name() override { return "Arrow"; } - void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) override; void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override { } diff --git a/cropeditor/drawing/bluritem.cpp b/cropeditor/drawing/bluritem.cpp index aa2b2a8..23005f1 100644 --- a/cropeditor/drawing/bluritem.cpp +++ b/cropeditor/drawing/bluritem.cpp @@ -13,16 +13,16 @@ bool BlurItem::init(CropScene *) { return true; } -void BlurItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { +void BlurItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (pos.isNull()) { - pos = e->scenePos(); - rect = scene->addRect(QRect(e->scenePos().toPoint(), QSize(1, 1)), QPen(Qt::cyan), Qt::NoBrush); + pos = scene->cursorPosition(); + rect = scene->addRect(QRect(scene->cursorPosition().toPoint(), QSize(1, 1)), QPen(Qt::cyan), Qt::NoBrush); pixmap = scene->addPixmap(scene->pixmap().copy(rect->rect().toRect())); - pixmap->setPos(e->scenePos()); + pixmap->setPos(scene->cursorPosition()); pixmap->setZValue(rect->zValue() - 0.1); pixmap->setGraphicsEffect(effect); } else { - QPointF p = e->scenePos(); + QPointF p = scene->cursorPosition(); rect->setRect(QRect(qMin(pos.x(), p.x()), qMin(pos.y(), p.y()), qAbs(pos.x() - p.x()), qAbs(pos.y() - p.y()))); pixmap->setPixmap(scene->pixmap().copy(rect->rect().toRect())); pixmap->setPos(rect->rect().topLeft()); diff --git a/cropeditor/drawing/bluritem.hpp b/cropeditor/drawing/bluritem.hpp index c95229a..bfff86f 100644 --- a/cropeditor/drawing/bluritem.hpp +++ b/cropeditor/drawing/bluritem.hpp @@ -14,7 +14,7 @@ public: } bool init(CropScene *) override; - void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) override; void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override; private: diff --git a/cropeditor/drawing/dotitem.cpp b/cropeditor/drawing/dotitem.cpp index e6af596..8eaea94 100644 --- a/cropeditor/drawing/dotitem.cpp +++ b/cropeditor/drawing/dotitem.cpp @@ -7,7 +7,7 @@ DotItem::~DotItem() { } void DotItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { - scene->addEllipse(e->pos().x() - 1.5, e->pos().y() - 1.5, 3, 3, scene->pen(), scene->brush())->setPos(e->scenePos()); + scene->addEllipse(e->pos().x() - 1.5, e->pos().y() - 1.5, 3, 3, scene->pen(), scene->brush())->setPos(scene->cursorPosition()); } void DotItem::mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) { diff --git a/cropeditor/drawing/ellipseitem.cpp b/cropeditor/drawing/ellipseitem.cpp index ff1cfce..e21257c 100644 --- a/cropeditor/drawing/ellipseitem.cpp +++ b/cropeditor/drawing/ellipseitem.cpp @@ -1,11 +1,11 @@ #include "ellipseitem.hpp" -void EllipseItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { +void EllipseItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (!ellie) { - ellie = scene->addEllipse(e->scenePos().x(), e->scenePos().y(), 0, 0, scene->pen(), scene->brush()); - initPos = e->scenePos(); + ellie = scene->addEllipse(scene->cursorPosition().x(), scene->cursorPosition().y(), 0, 0, scene->pen(), scene->brush()); + initPos = scene->cursorPosition(); } else { - auto p = e->scenePos(); + auto p = scene->cursorPosition(); ellie->setRect(QRectF(qMin(initPos.x(), p.x()), qMin(initPos.y(), p.y()), qAbs(initPos.x() - p.x()), qAbs(initPos.y() - p.y()))); } diff --git a/cropeditor/drawing/ellipseitem.hpp b/cropeditor/drawing/ellipseitem.hpp index 116da7c..0169d74 100644 --- a/cropeditor/drawing/ellipseitem.hpp +++ b/cropeditor/drawing/ellipseitem.hpp @@ -12,7 +12,7 @@ public: } ~EllipseItem() { } - void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) override; void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override { } diff --git a/cropeditor/drawing/eraseritem.cpp b/cropeditor/drawing/eraseritem.cpp index 0d3a53c..89c8c56 100644 --- a/cropeditor/drawing/eraseritem.cpp +++ b/cropeditor/drawing/eraseritem.cpp @@ -6,9 +6,9 @@ EraserItem::EraserItem() { EraserItem::~EraserItem() { } -void EraserItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { +void EraserItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { for (auto i : scene->items()) { - if (i->contains(e->scenePos()) && i->zValue() != -1 && i != scene->polyItm() && i != scene->selRect()) { + if (i->contains(scene->cursorPosition()) && i->zValue() != -1 && i != scene->polyItm() && i != scene->selRect()) { scene->removeItem(i); break; } diff --git a/cropeditor/drawing/eraseritem.hpp b/cropeditor/drawing/eraseritem.hpp index 078cd2d..9184629 100644 --- a/cropeditor/drawing/eraseritem.hpp +++ b/cropeditor/drawing/eraseritem.hpp @@ -10,7 +10,7 @@ public: QString name() override { return "Eraser"; } - void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) override; void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override { } }; diff --git a/cropeditor/drawing/lineitem.cpp b/cropeditor/drawing/lineitem.cpp index 563ce3f..a8efb58 100644 --- a/cropeditor/drawing/lineitem.cpp +++ b/cropeditor/drawing/lineitem.cpp @@ -3,12 +3,12 @@ LineItem::LineItem() { } -void LineItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { +void LineItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (init.isNull()) { - init = e->scenePos(); + init = scene->cursorPosition(); line = scene->addLine(QLineF(init, init), scene->pen()); } else { - line->setLine(QLineF(init, e->scenePos())); + line->setLine(QLineF(init, scene->cursorPosition())); } } diff --git a/cropeditor/drawing/lineitem.hpp b/cropeditor/drawing/lineitem.hpp index c72edd8..a6f59fe 100644 --- a/cropeditor/drawing/lineitem.hpp +++ b/cropeditor/drawing/lineitem.hpp @@ -9,7 +9,7 @@ public: QString name() override { return "Straight line"; } - void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) override; void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override; private: diff --git a/cropeditor/drawing/pathitem.cpp b/cropeditor/drawing/pathitem.cpp index 9bc15b7..b4d8b7c 100644 --- a/cropeditor/drawing/pathitem.cpp +++ b/cropeditor/drawing/pathitem.cpp @@ -9,13 +9,13 @@ PathItem::~PathItem() { delete path; } -void PathItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { +void PathItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (path == nullptr) { - path = new QPainterPath(e->scenePos()); + path = new QPainterPath(scene->cursorPosition()); pathItem = scene->addPath(*path, scene->pen(), settings::settings().value("brushPath", false).toBool() ? scene->brush() : QBrush()); } else { - path->quadTo(path->currentPosition(), e->scenePos()); + path->quadTo(path->currentPosition(), scene->cursorPosition()); pathItem->setPath(*path); } } diff --git a/cropeditor/drawing/pathitem.hpp b/cropeditor/drawing/pathitem.hpp index e2dfba9..6eb347a 100644 --- a/cropeditor/drawing/pathitem.hpp +++ b/cropeditor/drawing/pathitem.hpp @@ -11,7 +11,7 @@ public: QString name() { return "Path"; } - void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene); + void mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene); void mouseDragEndEvent(QGraphicsSceneMouseEvent *e, CropScene *scene); private: diff --git a/cropeditor/drawing/rectitem.cpp b/cropeditor/drawing/rectitem.cpp index 5524661..aebf123 100644 --- a/cropeditor/drawing/rectitem.cpp +++ b/cropeditor/drawing/rectitem.cpp @@ -6,14 +6,14 @@ RectItem::RectItem() { RectItem::~RectItem() { } -void RectItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { +void RectItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (!rect) { - rect = scene->addRect(e->scenePos().x(), e->scenePos().y(), 0, 0); + rect = scene->addRect(scene->cursorPosition().x(), scene->cursorPosition().y(), 0, 0); rect->setBrush(scene->brush()); rect->setPen(scene->pen()); - initPos = e->scenePos(); + initPos = scene->cursorPosition(); } else { - auto p = e->scenePos(); + auto p = scene->cursorPosition(); rect->setRect( QRect(qMin(initPos.x(), p.x()), qMin(initPos.y(), p.y()), qAbs(initPos.x() - p.x()), qAbs(initPos.y() - p.y()))); } diff --git a/cropeditor/drawing/rectitem.hpp b/cropeditor/drawing/rectitem.hpp index 8e09d80..a0e32bf 100644 --- a/cropeditor/drawing/rectitem.hpp +++ b/cropeditor/drawing/rectitem.hpp @@ -10,7 +10,7 @@ public: QString name() override { return "Rectangle"; } - void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) override; void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override; private: diff --git a/cropeditor/drawing/textitem.cpp b/cropeditor/drawing/textitem.cpp index bf67849..8ed86f5 100644 --- a/cropeditor/drawing/textitem.cpp +++ b/cropeditor/drawing/textitem.cpp @@ -10,15 +10,15 @@ bool TextItem::init(CropScene *s) { return ok; } -void TextItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { +void TextItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (!textItem) { textItem = scene->addSimpleText(text, scene->font()); - textItem->setPos(e->scenePos()); + textItem->setPos(scene->cursorPosition()); textItem->setPen(scene->pen().color()); textItem->setBrush(scene->pen().color()); } else { - auto ee - = 180 + qRadiansToDegrees(qAtan2((textItem->pos().y() - e->scenePos().y()), (textItem->pos().x() - e->scenePos().x()))); + auto ee = 180 + qRadiansToDegrees(qAtan2((textItem->pos().y() - scene->cursorPosition().y()), + (textItem->pos().x() - scene->cursorPosition().x()))); textItem->setRotation(ee); } } diff --git a/cropeditor/drawing/textitem.hpp b/cropeditor/drawing/textitem.hpp index b2660ef..d60fb54 100644 --- a/cropeditor/drawing/textitem.hpp +++ b/cropeditor/drawing/textitem.hpp @@ -8,7 +8,7 @@ class TextItem : public DrawItem { public: QString name() override; bool init(CropScene *s) override; - void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) override; void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override; private: diff --git a/main.cpp b/main.cpp index 6a98de1..a16c765 100644 --- a/main.cpp +++ b/main.cpp @@ -32,6 +32,7 @@ bool stillAlive = true; } void handler(QtMsgType type, const QMessageLogContext &, const QString &msg) { + if (!verbose && msg.startsWith("QPixmap::fromWinHBITMAP")) return; std::string stdMsg = msg.toStdString(); switch (type) { case QtDebugMsg: From ce75426552749ff8bd5c3cb4a059bf5e77e7814a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 9 Jul 2017 14:23:52 +0200 Subject: [PATCH 051/293] Fix compilation errors on OS X and picker on MSW Related issue: #9 --- colorpicker/colorpickerscene.cpp | 1 + cropeditor/cropeditor.cpp | 2 -- cropeditor/cropscene.cpp | 1 + mainwindow.cpp | 2 +- platformspecifics/mac/macbackend.cpp | 4 +++- platformspecifics/mac/macbackend.hpp | 2 +- screenshotutil.cpp | 8 ++++++-- screenshotutil.hpp | 1 + 8 files changed, 14 insertions(+), 7 deletions(-) diff --git a/colorpicker/colorpickerscene.cpp b/colorpicker/colorpickerscene.cpp index 840ace5..1309462 100644 --- a/colorpicker/colorpickerscene.cpp +++ b/colorpicker/colorpickerscene.cpp @@ -17,6 +17,7 @@ ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) setMouseTracking(true); setWindowTitle("KShare Color Picker"); setGeometry(pixmap.rect()); + move(screenshotutil::smallestScreenCoordinate()); setAttribute(Qt::WA_DeleteOnClose); pItem = addPixmap(pixmap); diff --git a/cropeditor/cropeditor.cpp b/cropeditor/cropeditor.cpp index 16291ff..bac293d 100644 --- a/cropeditor/cropeditor.cpp +++ b/cropeditor/cropeditor.cpp @@ -13,10 +13,8 @@ CropEditor::CropEditor(QPixmap image, QObject *parent) : QObject(parent) { scene = new CropScene(parent, image); view = new CropView(scene); - qreal ratio = QApplication::primaryScreen()->devicePixelRatio(); QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(image); pixmapItem->setZValue(-1); - pixmapItem->setScale(1 / ratio); scene->addItem(pixmapItem); scene->setSceneRect(image.rect()); view->resize(image.width(), image.height()); diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 3e69c56..3c1702e 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -103,6 +103,7 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) polyItem = new QGraphicsPolygonItem(poly); polyItem->setBrush(QBrush(QColor(0, 0, 0, 191))); polyItem->setPen(QPen(Qt::NoPen)); + polyItem->setZValue(1); addItem(polyItem); QTimer::singleShot(0, [&] { auto pf = views()[0]->mapFromGlobal(QCursor::pos()); diff --git a/mainwindow.cpp b/mainwindow.cpp index 8d2a8c3..b54582d 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -62,7 +62,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi QAction *recabort = new QAction("Abort recording", this); menu->addActions({ quit, shtoggle, picker }); menu->addSeparator(); - menu->addActions({ fullscreen, area, active }); + menu->addActions({ fullscreen, area }); #ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW menu->addAction(area); #endif diff --git a/platformspecifics/mac/macbackend.cpp b/platformspecifics/mac/macbackend.cpp index 675cc63..f0d1b1b 100644 --- a/platformspecifics/mac/macbackend.cpp +++ b/platformspecifics/mac/macbackend.cpp @@ -1,6 +1,8 @@ #include "macbackend.hpp" -QPixmap PlatformBackend::getCursor() { +#include + +std::tuple PlatformBackend::getCursor() { #warning "TODO: Mac backend" return std::tuple(QPoint(0, 0), QPixmap()); // Not Monday: https://developer.apple.com/reference/appkit/nscursor/1527062-image diff --git a/platformspecifics/mac/macbackend.hpp b/platformspecifics/mac/macbackend.hpp index ea15166..a987d3f 100644 --- a/platformspecifics/mac/macbackend.hpp +++ b/platformspecifics/mac/macbackend.hpp @@ -7,7 +7,7 @@ class PlatformBackend { public: - QPixmap getCursor(); + std::tuple getCursor(); pid_t pid(); static PlatformBackend &inst() { static PlatformBackend inst; diff --git a/screenshotutil.cpp b/screenshotutil.cpp index 9c939f0..0cc7c1d 100644 --- a/screenshotutil.cpp +++ b/screenshotutil.cpp @@ -26,7 +26,7 @@ QPixmap screenshotutil::fullscreen(bool cursor) { for (QScreen *screen : QApplication::screens()) { QRect geo = screen->geometry(); width = qMax(ox + geo.left() + geo.width(), width); - height = qMax(oy + geo.top() + geo.height(), height); // qute abs + height = qMax(oy + geo.top() + geo.height(), height); } image = QPixmap(width, height); image.fill(Qt::transparent); @@ -36,7 +36,8 @@ QPixmap screenshotutil::fullscreen(bool cursor) { for (QScreen *screen : QApplication::screens()) { QPixmap currentScreen = window(0, screen); - painter.drawPixmap(screen->geometry().topLeft(), currentScreen); + QRect geo = screen->geometry(); + painter.drawPixmap(geo.left(), geo.top(), geo.width(), geo.height(), currentScreen); width += screen->size().width(); } #ifdef Q_OS_LINUX @@ -73,3 +74,6 @@ QPoint screenshotutil::smallestScreenCoordinate() { } return smallestCoordinate; } + +QPixmap screenshotutil::renderText(QString toRender, QColor background, QFont font) { +} diff --git a/screenshotutil.hpp b/screenshotutil.hpp index df156d6..83267db 100644 --- a/screenshotutil.hpp +++ b/screenshotutil.hpp @@ -10,6 +10,7 @@ QPixmap fullscreenArea(bool cursor = true, qreal x = 0, qreal y = 0, qreal w = - QPixmap window(WId wid, QScreen *w = QApplication::primaryScreen()); void toClipboard(QString value); QPoint smallestScreenCoordinate(); +QPixmap renderText(QString toRender, QColor background = Qt::transparent, QFont font = QFont()); } #endif // SCREENSHOTUTIL_HPP From 62e5f4f395e3309a2dc61fdcc61bd2e289967f7c Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 9 Jul 2017 14:27:04 +0200 Subject: [PATCH 052/293] I forgot Mac is Unix too --- platformbackend.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformbackend.hpp b/platformbackend.hpp index 28a666f..56c484a 100644 --- a/platformbackend.hpp +++ b/platformbackend.hpp @@ -8,7 +8,7 @@ #ifdef Q_OS_WIN #include #endif -#ifdef Q_OS_UNIX +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) #include #endif From bd7de48dcc3fc6c7d0e1a2dcdefe5248cb916529 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 9 Jul 2017 14:42:13 +0200 Subject: [PATCH 053/293] OS X TravisCI build --- .travis.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index b36c40f..7694b42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,11 @@ os: osx language: cpp before_install: - - brew install qt - - brew install ffmpeg - - brew link ffmpeg + - brew install qt ffmpeg pkg-config - brew link qt --force - - export CPATH=/usr/local/Cellar/ffmpeg/3.3.2/include:$CPATH - - export LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.3.2/lib:$LIBRARY_PATH - - export DYLD_LIBRARY_PATH=/usr/local/Cellar/ffmpeg/3.3.2/lib:$DYLD_LIBRARY_PATH + - mkdir build script: - - qmake + - cd build + - qmake .. - make -j4 + From 0dd4a40adc5cfed034fbd52b1a39c76f6ca55e78 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 9 Jul 2017 14:47:17 +0200 Subject: [PATCH 054/293] Travis has pkgconfig installed --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7694b42..99c5071 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ os: osx language: cpp before_install: - - brew install qt ffmpeg pkg-config + - brew install qt ffmpeg - brew link qt --force - mkdir build script: From e090389201ee2c1a8f3fc7700d2180ff047d878b Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 9 Jul 2017 21:04:21 +0200 Subject: [PATCH 055/293] Add usage hints --- .travis.yml | 3 +-- AppVeyor/appveyor.yml | 2 +- KShare.pro | 6 +++--- README.md | 2 +- cropeditor/cropeditor.cpp | 2 ++ cropeditor/cropscene.cpp | 11 ++++++++++ cropeditor/cropscene.hpp | 14 ++++++++++++ cropeditor/drawing/bluritem.hpp | 2 +- cropeditor/drawing/ellipseitem.hpp | 2 +- main.cpp | 2 +- recording/encoders/encodersettingsdialog.ui | 8 +++---- recording/recordingformats.cpp | 16 ++------------ recording/recordingformats.hpp | 3 ++- screenareaselector/screenareaselector.cpp | 2 +- screenshotutil.cpp | 24 ++++++++++++++++++++- screenshotutil.hpp | 2 +- 16 files changed, 69 insertions(+), 32 deletions(-) diff --git a/.travis.yml b/.travis.yml index 99c5071..d921d82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,5 +7,4 @@ before_install: script: - cd build - qmake .. - - make -j4 - + - make -j$(($(nproc) + 1)) diff --git a/AppVeyor/appveyor.yml b/AppVeyor/appveyor.yml index 5c6c092..fa1939d 100644 --- a/AppVeyor/appveyor.yml +++ b/AppVeyor/appveyor.yml @@ -19,7 +19,7 @@ build_script: - xcopy ffmpeg-3.3.2-win64-dev\* %QTDIR% /e /i /Y - xcopy QtAV-depends-windows-x86+x64\* %QTDIR% /e /i /Y - qmake CONFIG+=nopkg ../KShare.pro - - mingw32-make.exe -j8 + - mingw32-make.exe -j%NUMBER_OF_PROCESSORS% - copy release\KShare.exe ..\KShare.exe - cd .. - bash AppVeyor\make_installer.sh diff --git a/KShare.pro b/KShare.pro index 1892928..c92c8fc 100644 --- a/KShare.pro +++ b/KShare.pro @@ -135,19 +135,19 @@ nopkg { } mac { - ICON = icons/icon.icns + ICON = $$PWD/icons/icon.icns SOURCES += $$PWD/platformspecifics/mac/macbackend.cpp HEADERS += $$PWD/platformspecifics/mac/macbackend.hpp LIBS += -framework Carbon warning(Mac is on TODO); } else:win32 { - RC_FILE = icon.rc + RC_FILE = $$PWD/icon.rc SOURCES += $$PWD/platformspecifics/u32/u32backend.cpp HEADERS += $$PWD/platformspecifics/u32/u32backend.hpp LIBS += -luser32 -lkernel32 -lpthread QT += winextras } else:unix { - RC_FILE = icon.rc + RC_FILE = $$PWD/icon.rc SOURCES += $$PWD/platformspecifics/x11/x11backend.cpp HEADERS += $$PWD/platformspecifics/x11/x11backend.hpp QT += x11extras diff --git a/README.md b/README.md index 7931c7f..84e0371 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A [ShareX](https://getsharex.com/) inspired cross platform utility written with |Linux|Windows|OS X| |:---:|:-----:|:--:| -|[![Build Status](https://nativeci.arsenarsen.com/job/KShare/badge/icon)](https://nativeci.arsenarsen.com/job/KShare)| [![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)| Soon | +|[![Build Status](https://nativeci.arsenarsen.com/job/KShare/badge/icon)](https://nativeci.arsenarsen.com/job/KShare)| [![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)| [![Build Status](https://travis-ci.org/ArsenArsen/KShare.svg?branch=master)](https://travis-ci.org/ArsenArsen/KShare) | ## Screenshot Made with KShare itself, of course :) ![](http://i.imgur.com/ffWvCun.png) diff --git a/cropeditor/cropeditor.cpp b/cropeditor/cropeditor.cpp index bac293d..a0e5e5c 100644 --- a/cropeditor/cropeditor.cpp +++ b/cropeditor/cropeditor.cpp @@ -23,6 +23,8 @@ CropEditor::CropEditor(QPixmap image, QObject *parent) : QObject(parent) { view->move(p.x() + settings::settings().value("cropx", 0).toInt(), p.y() + settings::settings().value("cropy", 0).toInt()); view->setWindowTitle("KShare Crop Editor"); view->show(); + view->raise(); + view->activateWindow(); connect(scene, &CropScene::closedWithRect, this, &CropEditor::crop); } diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 3c1702e..6f5d3de 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -92,6 +92,10 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) initMagnifierGrid(); updateMag(); + addItem(hint); + hint->setPos(5, 5); + hint->setZValue(2); + hint->setVisible(settings::settings().value("crophint", true).toBool()); connect(menu.addAction("Set Font"), &QAction::triggered, this, &CropScene::fontAsk); QPolygonF poly; @@ -169,6 +173,7 @@ void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { QCursor::setPos(views()[0]->mapToGlobal(cursorPos.toPoint())); } else cursorPos = e->scenePos(); + hint->setVisible(!hint->sceneBoundingRect().contains(cursorPos)); cursorItem->setPos(cursorPos); updateMag(); @@ -283,6 +288,11 @@ void CropScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *e) { void CropScene::keyReleaseEvent(QKeyEvent *event) { if (((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && !drawingSelection) || event->key() == Qt::Key_Escape) done(event->key() != Qt::Key_Escape); + else if (event->key() == Qt::Key_F1) { + bool enabled = !settings::settings().value("crophint", true).toBool(); + hint->setVisible(enabled); + settings::settings().setValue("crophint", enabled); + } } void CropScene::updateMag() { @@ -338,6 +348,7 @@ void CropScene::initMagnifierGrid() { void CropScene::done(bool notEsc) { if (notEsc && rect) { + hint->setVisible(false); rect->setPen(QPen(Qt::NoPen)); magnifier->setVisible(false); cursorItem->setVisible(false); diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index d2dcfd4..67b1323 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -9,6 +9,7 @@ #include #include #include +#include class CropScene; #include @@ -79,6 +80,19 @@ private: QList gridRectsX; QList gridRectsY; QGraphicsPolygonItem *cursorItem = nullptr; + QGraphicsPixmapItem *hint = new QGraphicsPixmapItem(screenshotutil::renderText( // + "Press F1 to toggle this hint\n" + "\tHold Shift to slow the cursor down\n" + "\tCtrl+Drag a drawing to move it around\n" + "\tAlt+Click a drawing to remove it\n" + "\tPress Return/Enter to finish\n" + "\tPress ESC to cancel\n" + "\tRight-click to get a drawing menu\n" + "\tNOTE: You must select 'Reset pen selection' before closing the editor\n" + "\tIf you do not it will not close.", + 5, + QColor(0, 0, 0, 125), + Qt::white)); }; #endif // CROPSCENE_HPP diff --git a/cropeditor/drawing/bluritem.hpp b/cropeditor/drawing/bluritem.hpp index bfff86f..2882a5a 100644 --- a/cropeditor/drawing/bluritem.hpp +++ b/cropeditor/drawing/bluritem.hpp @@ -7,7 +7,7 @@ class BlurItem : public DrawItem { public: - QString name() { + QString name() override { return "Blur"; } ~BlurItem() { diff --git a/cropeditor/drawing/ellipseitem.hpp b/cropeditor/drawing/ellipseitem.hpp index 0169d74..46c8678 100644 --- a/cropeditor/drawing/ellipseitem.hpp +++ b/cropeditor/drawing/ellipseitem.hpp @@ -7,7 +7,7 @@ class EllipseItem : public DrawItem { public: EllipseItem() { } - QString name() { + QString name() override { return "Blur"; } ~EllipseItem() { diff --git a/main.cpp b/main.cpp index a16c765..a1ed9af 100644 --- a/main.cpp +++ b/main.cpp @@ -89,7 +89,7 @@ int main(int argc, char *argv[]) { Worker::init(); a.connect(&a, &QApplication::aboutToQuit, Worker::end); a.connect(&a, &QApplication::aboutToQuit, [] { stillAlive = false; }); - + screenshotutil::renderText("DICKS").save("/home/arsen/test.png"); if (!parser.isSet(h)) w.show(); return a.exec(); } diff --git a/recording/encoders/encodersettingsdialog.ui b/recording/encoders/encodersettingsdialog.ui index 0ba32c2..7c945c0 100644 --- a/recording/encoders/encodersettingsdialog.ui +++ b/recording/encoders/encodersettingsdialog.ui @@ -13,7 +13,7 @@ Dialog - + @@ -62,7 +62,7 @@ - 0 + 2 @@ -162,7 +162,7 @@ VP9 - + @@ -176,7 +176,7 @@ GIF - + diff --git a/recording/recordingformats.cpp b/recording/recordingformats.cpp index dfb5d37..c19d9c6 100644 --- a/recording/recordingformats.cpp +++ b/recording/recordingformats.cpp @@ -22,19 +22,10 @@ RecordingFormats::RecordingFormats(formats::Recording f) { validator = [](QSize) { return false; }; return; } - tmpDir = QDir(tmp); - QString name - = QString("KShareTemp-") + QString::number(PlatformBackend::inst().pid()) + "-" + QTime::currentTime().toString(); - tmpDir.mkdir(name); - tmpDir.cd(name); iFormat = QImage::Format_RGB888; - path = tmpDir.absoluteFilePath("res." + formats::recordingFormatName(f).toLower()); + path = tmpDir.filePath("res." + formats::recordingFormatName(f).toLower()); finalizer = [&] { delete enc; - if (interrupt || !frameAdded) { - tmpDir.removeRecursively(); - return QString(); - } return QFile(path).size() > 0 ? path : QString(); }; validator = [&](QSize s) { @@ -69,10 +60,7 @@ RecordingFormats::RecordingFormats(formats::Recording f) { interrupt = true; } }; - postUploadTask = [&] { - tmpDir.removeRecursively(); - QScopedPointer th(this); - }; + postUploadTask = [&] { QScopedPointer th(this); }; anotherFormat = formats::recordingFormatName(f); } diff --git a/recording/recordingformats.hpp b/recording/recordingformats.hpp index ad5825d..09fb505 100644 --- a/recording/recordingformats.hpp +++ b/recording/recordingformats.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -27,7 +28,7 @@ private: std::function postUploadTask; std::vector frames; QImage::Format iFormat; - QDir tmpDir; + QTemporaryDir tmpDir; QString path; Encoder *enc = NULL; bool interrupt = false; diff --git a/screenareaselector/screenareaselector.cpp b/screenareaselector/screenareaselector.cpp index 4a731b5..3d44ae5 100644 --- a/screenareaselector/screenareaselector.cpp +++ b/screenareaselector/screenareaselector.cpp @@ -35,7 +35,7 @@ ScreenAreaSelector::~ScreenAreaSelector() { void ScreenAreaSelector::keyPressEvent(QKeyEvent *event) { event->accept(); if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { - QRect r = QRect(pos(), rect().size()); + QRect r = QRect(mapToGlobal(pos()), rect().size()); emit selectedArea(r); close(); } else if (event->key() == Qt::Key_Escape) diff --git a/screenshotutil.cpp b/screenshotutil.cpp index 0cc7c1d..ffe2044 100644 --- a/screenshotutil.cpp +++ b/screenshotutil.cpp @@ -75,5 +75,27 @@ QPoint screenshotutil::smallestScreenCoordinate() { return smallestCoordinate; } -QPixmap screenshotutil::renderText(QString toRender, QColor background, QFont font) { +QPixmap screenshotutil::renderText(QString toRender, int padding, QColor background, QColor pen, QFont font) { + QFontMetrics metric(font); + QStringList lines = toRender.replace("\r", "").split('\n'); + QSize resultingSize(0, padding * 2); + int lineSpace = metric.leading(); + for (QString line : lines) { + QRect br = metric.boundingRect(line); + resultingSize.rheight() += lineSpace + br.height(); + resultingSize.rwidth() = qMax(br.width(), resultingSize.width()); + } + resultingSize.rwidth() += padding * 2; + QPixmap renderred(resultingSize); + renderred.fill(background); + QPainter painter(&renderred); + painter.setPen(pen); + int y = padding; + for (QString line : lines) { + QRect br = metric.boundingRect(line); + painter.drawText(padding, y, br.width(), br.height(), 0, line); + y += lineSpace + br.height(); + } + painter.end(); + return renderred; } diff --git a/screenshotutil.hpp b/screenshotutil.hpp index 83267db..91a7965 100644 --- a/screenshotutil.hpp +++ b/screenshotutil.hpp @@ -10,7 +10,7 @@ QPixmap fullscreenArea(bool cursor = true, qreal x = 0, qreal y = 0, qreal w = - QPixmap window(WId wid, QScreen *w = QApplication::primaryScreen()); void toClipboard(QString value); QPoint smallestScreenCoordinate(); -QPixmap renderText(QString toRender, QColor background = Qt::transparent, QFont font = QFont()); +QPixmap renderText(QString toRender, int padding = 5, QColor background = Qt::transparent, QColor pen = Qt::white, QFont font = QFont()); } #endif // SCREENSHOTUTIL_HPP From 147e0051f6ac4d9a3edf2c5de106c2c3bf116bf3 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 10 Jul 2017 15:44:03 +0200 Subject: [PATCH 056/293] Use an older (I hope) function --- recording/recordingformats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recording/recordingformats.cpp b/recording/recordingformats.cpp index c19d9c6..bf10f9a 100644 --- a/recording/recordingformats.cpp +++ b/recording/recordingformats.cpp @@ -23,7 +23,7 @@ RecordingFormats::RecordingFormats(formats::Recording f) { return; } iFormat = QImage::Format_RGB888; - path = tmpDir.filePath("res." + formats::recordingFormatName(f).toLower()); + path = tmpDir.path() + "/res." + formats::recordingFormatName(f).toLower(); finalizer = [&] { delete enc; return QFile(path).size() > 0 ? path : QString(); From a4118ea3acce132857af16090c3a79d7428a8e06 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 10 Jul 2017 16:27:38 +0200 Subject: [PATCH 057/293] Fix some issues with screen overlaying windows --- colorpicker/colorpickerscene.cpp | 7 ++++++- cropeditor/cropeditor.cpp | 9 +++++---- recording/recordingformats.cpp | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/colorpicker/colorpickerscene.cpp b/colorpicker/colorpickerscene.cpp index 1309462..45a4ab3 100644 --- a/colorpicker/colorpickerscene.cpp +++ b/colorpicker/colorpickerscene.cpp @@ -5,6 +5,7 @@ #include #include #include +#include ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) : QGraphicsScene(), QGraphicsView(this, parentWidget) { @@ -16,7 +17,6 @@ ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) setCursor(QCursor(Qt::CrossCursor)); setMouseTracking(true); setWindowTitle("KShare Color Picker"); - setGeometry(pixmap.rect()); move(screenshotutil::smallestScreenCoordinate()); setAttribute(Qt::WA_DeleteOnClose); @@ -36,6 +36,11 @@ ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) image = pixmap.toImage(); show(); + activateWindow(); + setGeometry(pixmap.rect()); + QPoint p = screenshotutil::smallestScreenCoordinate() + + QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); + move(p.x(), p.y()); } void ColorPickerScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { diff --git a/cropeditor/cropeditor.cpp b/cropeditor/cropeditor.cpp index a0e5e5c..4f0605c 100644 --- a/cropeditor/cropeditor.cpp +++ b/cropeditor/cropeditor.cpp @@ -13,17 +13,18 @@ CropEditor::CropEditor(QPixmap image, QObject *parent) : QObject(parent) { scene = new CropScene(parent, image); view = new CropView(scene); + view->show(); + view->raise(); QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(image); pixmapItem->setZValue(-1); scene->addItem(pixmapItem); scene->setSceneRect(image.rect()); view->resize(image.width(), image.height()); view->setMinimumSize(image.size()); - QPoint p = screenshotutil::smallestScreenCoordinate(); - view->move(p.x() + settings::settings().value("cropx", 0).toInt(), p.y() + settings::settings().value("cropy", 0).toInt()); + QPoint p = screenshotutil::smallestScreenCoordinate() + + QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); + view->move(p.x(), p.y()); view->setWindowTitle("KShare Crop Editor"); - view->show(); - view->raise(); view->activateWindow(); connect(scene, &CropScene::closedWithRect, this, &CropEditor::crop); diff --git a/recording/recordingformats.cpp b/recording/recordingformats.cpp index bf10f9a..b55ee5b 100644 --- a/recording/recordingformats.cpp +++ b/recording/recordingformats.cpp @@ -17,9 +17,9 @@ #include RecordingFormats::RecordingFormats(formats::Recording f) { - QString tmp = QStandardPaths::writableLocation(QStandardPaths::TempLocation); - if (tmp.isEmpty()) { + if (tmpDir.isValid()) { validator = [](QSize) { return false; }; + qCritical().noquote() << "Could not create temporary directory. Error: " + tmpDir.errorString(); return; } iFormat = QImage::Format_RGB888; From ad0dc3abe7f4f8b367cf1dd9dcb2d640276fa2ce Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 10 Jul 2017 16:33:04 +0200 Subject: [PATCH 058/293] Logic errors --- colorpicker/colorpickerscene.cpp | 1 - recording/recordingformats.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/colorpicker/colorpickerscene.cpp b/colorpicker/colorpickerscene.cpp index 45a4ab3..773d16a 100644 --- a/colorpicker/colorpickerscene.cpp +++ b/colorpicker/colorpickerscene.cpp @@ -17,7 +17,6 @@ ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) setCursor(QCursor(Qt::CrossCursor)); setMouseTracking(true); setWindowTitle("KShare Color Picker"); - move(screenshotutil::smallestScreenCoordinate()); setAttribute(Qt::WA_DeleteOnClose); pItem = addPixmap(pixmap); diff --git a/recording/recordingformats.cpp b/recording/recordingformats.cpp index b55ee5b..a95f1a5 100644 --- a/recording/recordingformats.cpp +++ b/recording/recordingformats.cpp @@ -17,7 +17,7 @@ #include RecordingFormats::RecordingFormats(formats::Recording f) { - if (tmpDir.isValid()) { + if (!tmpDir.isValid()) { validator = [](QSize) { return false; }; qCritical().noquote() << "Could not create temporary directory. Error: " + tmpDir.errorString(); return; From 7675fe59a5f2199bfb14c855bf66d103264e0735 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 10 Jul 2017 21:47:04 +0200 Subject: [PATCH 059/293] Make notification clicks only show the window --- mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index b54582d..7bcc344 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -71,7 +71,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi connect(quit, &QAction::triggered, this, &MainWindow::quit); connect(shtoggle, &QAction::triggered, this, &MainWindow::toggleVisible); connect(picker, &QAction::triggered, [] { ColorPickerScene::showPicker(); }); - connect(tray, &QSystemTrayIcon::messageClicked, this, &MainWindow::toggleVisible); + connect(tray, &QSystemTrayIcon::messageClicked, this, &QWidget::show); connect(tray, &QSystemTrayIcon::activated, this, [this](QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::DoubleClick) toggleVisible(); }); From 3790be68c5f483d790ac6ece2caddd536fb7c29b Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 10 Jul 2017 23:13:49 +0200 Subject: [PATCH 060/293] Fix a logic error resulting in strange recording --- screenareaselector/screenareaselector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/screenareaselector/screenareaselector.cpp b/screenareaselector/screenareaselector.cpp index 3d44ae5..000b960 100644 --- a/screenareaselector/screenareaselector.cpp +++ b/screenareaselector/screenareaselector.cpp @@ -35,7 +35,7 @@ ScreenAreaSelector::~ScreenAreaSelector() { void ScreenAreaSelector::keyPressEvent(QKeyEvent *event) { event->accept(); if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { - QRect r = QRect(mapToGlobal(pos()), rect().size()); + QRect r = QRect(mapToGlobal(QPoint(0, 0)), rect().size()); emit selectedArea(r); close(); } else if (event->key() == Qt::Key_Escape) From 3768ce2f51b7670850989298fd0c2d08d21de377 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 10 Jul 2017 23:16:20 +0200 Subject: [PATCH 061/293] Fix an error with ScreenAreaSelector region saving --- screenareaselector/screenareaselector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/screenareaselector/screenareaselector.cpp b/screenareaselector/screenareaselector.cpp index 000b960..44da6bb 100644 --- a/screenareaselector/screenareaselector.cpp +++ b/screenareaselector/screenareaselector.cpp @@ -47,6 +47,6 @@ void ScreenAreaSelector::resizeEvent(QResizeEvent *) { } void ScreenAreaSelector::closeEvent(QCloseEvent *) { - QRect r = QRect(pos(), rect().size()); + QRect r = QRect(mapToGlobal(QPoint(0, 0)), rect().size()); settings::settings().setValue("screenareaselector/rect", r); } From f57013d557c2835c15867d16cd9b70fa7d2eecb2 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 11 Jul 2017 16:24:36 +0200 Subject: [PATCH 062/293] Add an installer --- KShare.pro | 3 ++- README.md | 4 ++-- install.sh | 35 +++++++++++++++++++++++++++++ mainwindow.ui | 8 ++++--- recording/recordingformats.cpp | 4 ---- settings.cpp | 21 ++++++++++++----- settings.hpp | 1 + uploaders/default/imguruploader.cpp | 14 +++++++----- 8 files changed, 69 insertions(+), 21 deletions(-) create mode 100755 install.sh diff --git a/KShare.pro b/KShare.pro index c92c8fc..74d2d48 100644 --- a/KShare.pro +++ b/KShare.pro @@ -170,7 +170,8 @@ DISTFILES += \ OlderSystemFix.patch \ AppVeyor/appveyor.yml \ AppVeyor/make_installer.sh \ - .travis.yml + .travis.yml \ + install.sh RESOURCES += \ icon.qrc diff --git a/README.md b/README.md index 84e0371..0cb5725 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,11 @@ You have to obtain the dependencies though. ```bash git clone https://github.com/ArsenArsen/KShare.git cd KShare -qmake // Might be qmake-qt5 on your system +qmake # Might be qmake-qt5 on your system make ``` On systems with FFMpeg pre-3.1 you need to apply `OlderSystemFix.patch` to `recording/encoders/encoder.cpp`. On systems with Qt pre-5.7 you need to install the Qt version from their website. - +You can attempt to `curl https://raw.githubusercontent.com/ArsenArsen/KShare/master/install.sh | bash` ###### Started on 19th of April 2017 to bring some attention and improvement to Linux screenshotting. diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..c324471 --- /dev/null +++ b/install.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +uname=$(uname) +function installIfNeeded { + brew ls --versions $1 > /dev/null + if [[ ! $? = 0 ]]; then brew install $1 + else brew upgrade $1; fi +} + +resultfile="" + +if [[ "$uname" = "Darwin" ]]; then +export PATH="/usr/local/opt/qt/bin:$PATH" +installIfNeeded qt +installIfNeeded ffmpeg +installIfNeeded pkg-config +installIfNeeded git +resultfile="$(pwd)/KShare/build/KShare.app/" +elif [[ "$uname" = "Linux" ]]; then +echo "Please install Qt5 SDK, qmake, ffmpeg development files, git, and pkgcondig" +bash +resultfile="$(pwd)/KShare/build/KShare" +else echo "Unsupported OS!" && exit 1; fi + +git clone --recursive https://github.com/ArsenArsen/KShare.git || exit 2 +cd KShare +mkdir build || exit 3 +cd build +qmake-qt5 .. || qmake .. || exit 4 +make -j$(($(nproc) + 1)) || exit 5 +echo "------------------------------------------------------" +echo "Resulting file is $resultfile" +if [[ "$uname" = "Linux" ]]; then echo "To link the file into path, run sudo ln -s $resultfile /usr/bin/kshare"; fi +cd .. +echo "To update, go to $(pwd), git pull, cd build, and make -j$(($(nproc) + 1))" +echo "------------------------------------------------------" diff --git a/mainwindow.ui b/mainwindow.ui index fc55e2c..4c409dc 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -14,8 +14,8 @@ KShare - - :/icons/icon.jpg:/icons/icon.jpg + + :/icons/icon.svg:/icons/icon.svg @@ -144,6 +144,8 @@ - + + + diff --git a/recording/recordingformats.cpp b/recording/recordingformats.cpp index a95f1a5..a16abfb 100644 --- a/recording/recordingformats.cpp +++ b/recording/recordingformats.cpp @@ -39,8 +39,6 @@ RecordingFormats::RecordingFormats(formats::Recording f) { return false; } } catch (std::runtime_error &e) { - // notifications::notify("KShare Video Encoder Error", e.what(), - // QSystemTrayIcon::Critical); qCritical() << "Encoder error: " << e.what(); interrupt = true; delete enc; @@ -54,8 +52,6 @@ RecordingFormats::RecordingFormats(formats::Recording f) { frameAdded = true; enc->addFrame(img); } catch (std::runtime_error &e) { - // notifications::notify("KShare Video Encoder Error", e.what(), - // QSystemTrayIcon::Critical); qCritical() << "Encoder error: " << e.what(); interrupt = true; } diff --git a/settings.cpp b/settings.cpp index 4ab49d6..86cb78d 100644 --- a/settings.cpp +++ b/settings.cpp @@ -1,5 +1,6 @@ #include "settings.hpp" +#include #include #include @@ -7,11 +8,19 @@ QMutex *lock = new QMutex; QSettings &settings::settings() { QMutexLocker l(lock); - static QDir configDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); - if (configDir.dirName() != "KShare") { - configDir.mkdir("KShare"); - configDir.cd("KShare"); - } - static QSettings settings(configDir.absoluteFilePath("settings.ini"), QSettings::IniFormat); + static QSettings settings(dir().absoluteFilePath("settings.ini"), QSettings::IniFormat); return settings; } + +QDir settings::dir() { + static QDir configDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); + if (configDir.dirName() != "KShare") { + if (!configDir.cd("KShare")) + if (!configDir.mkdir("KShare")) { + qFatal("Could not make config directory"); + } else { + configDir.cd("KShare"); + } + } + return configDir; +} diff --git a/settings.hpp b/settings.hpp index e2a7870..e363b84 100644 --- a/settings.hpp +++ b/settings.hpp @@ -6,6 +6,7 @@ namespace settings { QSettings &settings(); +QDir dir(); } #endif // SETTINGS_HPP diff --git a/uploaders/default/imguruploader.cpp b/uploaders/default/imguruploader.cpp index 7103215..ec051a9 100644 --- a/uploaders/default/imguruploader.cpp +++ b/uploaders/default/imguruploader.cpp @@ -11,7 +11,7 @@ #include #include -struct SegfaultWorkaround { +struct SegfaultWorkaround { // I'm a scrub for doing this SegfaultWorkaround(QByteArray a, ImgurUploader *u, QString m) : byteArray(), dis(u), mime(m) { a.swap(byteArray); QJsonObject object; @@ -81,16 +81,20 @@ void ImgurUploader::handleSend(QString auth, QString mime, QByteArray byteArray) ioutils::postJson(QUrl("https://api.imgur.com/3/image"), QList>() << QPair("Content-Type", mime.toUtf8()) << QPair("Authorization", auth), - byteArray, [](QJsonDocument res, QByteArray, QNetworkReply *) { + byteArray, [byteArray, this, mime](QJsonDocument res, QByteArray, QNetworkReply *r) { QString result = res.object()["data"].toObject()["link"].toString(); + if (r->error() == QNetworkReply::ContentAccessDenied) { + new SegfaultWorkaround(byteArray, this, mime); + return; + } if (!result.isEmpty()) { screenshotutil::toClipboard(result); notifications::notify("KShare imgur Uploader ", "Uploaded to imgur!"); } else { notifications::notify("KShare imgur Uploader ", - QString("Failed upload! imgur said: HTTP %2: %1") - .arg(res.object()["data"].toObject()["error"].toString()) - .arg(QString::number(res.object()["status"].toInt()))); + QString("Failed upload! imgur said: HTTP %1: %2") + .arg(r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()) + .arg(r->errorString())); } }); } From 74d98fe8f3fc42e9d1aed2eb0694420a2cbb0ae7 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 11 Jul 2017 16:58:05 +0200 Subject: [PATCH 063/293] Try something in CropScene --- cropeditor/cropscene.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 6f5d3de..1d69a7b 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -154,7 +154,16 @@ void CropScene::setVisible(bool visible) { for (auto view : views()) { if (view->isVisible()) fullscreen |= view->isFullScreen(); view->setVisible(visible); - if (visible && fullscreen) view->showFullScreen(); + if (fullscreen) view->showFullScreen(); + if (visible) { + view->resize(_pixmap.width(), _pixmap.height()); + view->setMinimumSize(_pixmap.size()); + QPoint p = screenshotutil::smallestScreenCoordinate() + QPoint(settings::settings().value("cropx", 0).toInt(), + settings::settings().value("cropy", 0).toInt()); + view->move(p.x(), p.y()); + view->setWindowTitle("KShare Crop Editor"); + view->activateWindow(); + } } } From 9952edb9f85bec4c15d8e53b9b942da6ed10ba3e Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 12 Jul 2017 00:59:38 +0200 Subject: [PATCH 064/293] Fix some clicks and overrides --- cropeditor/cropscene.cpp | 22 ++++++++++++---------- cropeditor/cropscene.hpp | 1 + 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 1d69a7b..345d26d 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -142,6 +142,14 @@ void CropScene::setDrawingSelection(QString name, std::function dr if (!drawingSelection->init(this)) setDrawingSelection("None", [] { return nullptr; }); } +QGraphicsItem *CropScene::whichItem(QPointF scenePos) { + for (auto item : items()) { + if (item->sceneBoundingRect().contains(scenePos)) + if (item != polyItem && item != rect && item != cursorItem && item->zValue() != -1) return item; + } + return nullptr; +} + void CropScene::hide() { setVisible(false); } @@ -188,11 +196,8 @@ void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { auto buttons = e->buttons(); if (e->modifiers() & Qt::ControlModifier && buttons == Qt::LeftButton) { - QTransform stupidThing = views()[0]->transform(); - auto item = itemAt(cursorPos, stupidThing); - if (item && item != polyItem && item != rect && item->zValue() != -1) { - item->moveBy(delta.x(), delta.y()); - } + auto item = whichItem(cursorPos); + if (item) item->moveBy(delta.x(), delta.y()); return; } if (buttons == Qt::LeftButton || (prevButtons == Qt::NoButton && prevButtons != buttons)) { @@ -253,11 +258,8 @@ void CropScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { if (e->modifiers() & Qt::AltModifier) { - QTransform stupidThing = views()[0]->transform(); - auto item = itemAt(cursorPos, stupidThing); - if (item && item != polyItem && item != rect && item->zValue() != -1) { - removeItem(item); - } + auto item = whichItem(cursorItem->scenePos()); + if (item) removeItem(item); } } diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index 67b1323..2d4aa48 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -32,6 +32,7 @@ public: QGraphicsRectItem *selRect() { return rect; } + QGraphicsItem *whichItem(QPointF scenePos); void hide(); void show(); void setVisible(bool visible); From f980ef890491740ca802debee967900d0cdd07f6 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 12 Jul 2017 20:12:17 +0200 Subject: [PATCH 065/293] Add content disposition editing support --- KShare.pro | 6 ++++-- io/ioutils.cpp | 19 +++++++++++++++++++ io/ioutils.hpp | 1 + logs/requestlogging.cpp | 33 +++++++++++++++++++++++++++++++++ logs/requestlogging.hpp | 18 ++++++++++++++++++ main.cpp | 4 ++-- uploaders/customuploader.cpp | 5 ++++- 7 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 logs/requestlogging.cpp create mode 100644 logs/requestlogging.hpp diff --git a/KShare.pro b/KShare.pro index 74d2d48..432fc3e 100644 --- a/KShare.pro +++ b/KShare.pro @@ -66,7 +66,8 @@ SOURCES += main.cpp\ cropeditor/drawing/arrowitem.cpp \ uploaders/default/imgursettingsdialog.cpp \ uploaders/default/imgplusuploader.cpp \ - filenamevalidator.cpp + filenamevalidator.cpp \ + logs/requestlogging.cpp HEADERS += mainwindow.hpp \ cropeditor/cropeditor.hpp \ @@ -111,7 +112,8 @@ HEADERS += mainwindow.hpp \ cropeditor/drawing/arrowitem.hpp \ uploaders/default/imgursettingsdialog.hpp \ uploaders/default/imgplusuploader.hpp \ - filenamevalidator.hpp + filenamevalidator.hpp \ + logs/requestlogging.hpp nopkg { # win32 { diff --git a/io/ioutils.cpp b/io/ioutils.cpp index 2d190e6..c66bbc8 100644 --- a/io/ioutils.cpp +++ b/io/ioutils.cpp @@ -94,3 +94,22 @@ void ioutils::postData(QUrl target, delete reply; }); } + + +QString ioutils::methodString(QNetworkAccessManager::Operation operation) { + switch (operation) { + case QNetworkAccessManager::GetOperation: + return "GET"; + case QNetworkAccessManager::PostOperation: + return "POST"; + case QNetworkAccessManager::PutOperation: + return "PUT"; + case QNetworkAccessManager::DeleteOperation: + return "DELETE"; + case QNetworkAccessManager::HeadOperation: + return "HEAD"; + default: + // return "Dunno"; + return "Unknown"; + } +} diff --git a/io/ioutils.hpp b/io/ioutils.hpp index d4e50c7..4bef7a3 100644 --- a/io/ioutils.hpp +++ b/io/ioutils.hpp @@ -24,6 +24,7 @@ void postMultipartData(QUrl target, QList> headers, QHttpMultiPart *body, std::function callback); +QString methodString(QNetworkAccessManager::Operation operation); } #endif // IOUTILS_HPP diff --git a/logs/requestlogging.cpp b/logs/requestlogging.cpp new file mode 100644 index 0000000..a0d6e34 --- /dev/null +++ b/logs/requestlogging.cpp @@ -0,0 +1,33 @@ +#include "requestlogging.hpp" +#include +#include +#include +#include + +QDir responses(settings::dir().absoluteFilePath("response")); +void requestlogging::addEntry(RequestContext context) { + if (!responses.exists()) responses.mkpath("."); + QFile responseFile(responses.absoluteFilePath(context.sender + "-" + QDateTime().toString("yyyy-MM-dd HH-mm-ss"))); + if (!responseFile.open(QIODevice::WriteOnly)) { + qCritical().noquote() << "Could not save response! " + responseFile.errorString(); + return; + } + responseFile.write(( // + ioutils::methodString(context.reply->operation()) + // write method + " " + // space + context.reply->url().toString() + // write url + " " + // space + QString::number(context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)) + + // write status + "\n" // newline + ) + .toUtf8()); + for (auto header : context.reply->rawHeaderList()) responseFile.write(header + "\n"); + responseFile.write("\n\n" + context.response); + responseFile.close(); + + addGUIEntry(context, QFileInfo(responseFile).absoluteFilePath()); +} + +void requestlogging::addGUIEntry(RequestContext context, QString file) { +} diff --git a/logs/requestlogging.hpp b/logs/requestlogging.hpp new file mode 100644 index 0000000..fe6da48 --- /dev/null +++ b/logs/requestlogging.hpp @@ -0,0 +1,18 @@ +#ifndef REQUESTLOGGING_HPP +#define REQUESTLOGGING_HPP + +#include +#include + +struct RequestContext { + QByteArray response; + QString sender; + QNetworkReply *reply; +}; + +namespace requestlogging { +void addEntry(RequestContext context); +void addGUIEntry(RequestContext context, QString file); +} + +#endif // REQUESTLOGGING_HPP diff --git a/main.cpp b/main.cpp index a1ed9af..3c3a892 100644 --- a/main.cpp +++ b/main.cpp @@ -26,7 +26,7 @@ bool verbose = false; bool stillAlive = true; #define LOGACT(lvl) \ - std::cout << lvl << stdMsg << "\n"; \ + std::cout << lvl << stdMsg << "\n" << std::flush; \ if (stillAlive && MainWindow::inst() && MainWindow::inst()->valid()) { \ MainWindow::inst()->ui->logBox->addItem(lvl + msg); \ } @@ -89,7 +89,7 @@ int main(int argc, char *argv[]) { Worker::init(); a.connect(&a, &QApplication::aboutToQuit, Worker::end); a.connect(&a, &QApplication::aboutToQuit, [] { stillAlive = false; }); - screenshotutil::renderText("DICKS").save("/home/arsen/test.png"); + if (!parser.isSet(h)) w.show(); return a.exec(); } diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index 84973d6..f83f05b 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -318,6 +318,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { part.setBody(QJsonDocument::fromVariant(result.toVariantMap()).toJson()); multipart->append(part); } + QByteArray cdh("form-data"); for (QString headerVal : valo.keys()) { if (headerVal.startsWith("__")) { headerVal = headerVal.mid(2); @@ -325,8 +326,10 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { if (str.startsWith("/") && str.endsWith("/")) str = str.mid(1, str.length() - 1).replace("%contenttype", mime); part.setRawHeader(headerVal.toLatin1(), str.toLatin1()); - } + } else + cdh += "; " + headerVal + ": \"" + valo[headerVal].toString().replace("\"", "\\\"") + "\""; } + part.setHeader(QNetworkRequest::ContentDispositionHeader, cdh) } switch (method) { case HttpMethod::POST: From b17edd323e3e6e91e2b1bda60d48af7c4b9da4c2 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 12 Jul 2017 20:24:16 +0200 Subject: [PATCH 066/293] That aint compiling --- uploaders/customuploader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index f83f05b..e4bf01c 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -329,7 +329,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { } else cdh += "; " + headerVal + ": \"" + valo[headerVal].toString().replace("\"", "\\\"") + "\""; } - part.setHeader(QNetworkRequest::ContentDispositionHeader, cdh) + part.setHeader(QNetworkRequest::ContentDispositionHeader, cdh); } switch (method) { case HttpMethod::POST: From 54acaa3cb41583f9897859e110d0be32fd7cfb6a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 12 Jul 2017 22:59:26 +0200 Subject: [PATCH 067/293] Some changes to try and fix multipart --- logs/requestlogging.cpp | 2 +- uploaders/customuploader.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/logs/requestlogging.cpp b/logs/requestlogging.cpp index a0d6e34..4b38b8f 100644 --- a/logs/requestlogging.cpp +++ b/logs/requestlogging.cpp @@ -17,7 +17,7 @@ void requestlogging::addEntry(RequestContext context) { " " + // space context.reply->url().toString() + // write url " " + // space - QString::number(context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)) + QString::number(context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()) // + // write status "\n" // newline ) diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index e4bf01c..f9b8453 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -308,7 +308,9 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { if (i < split.size() - 1) body.append(imgData); } } - QBuffer *buffer = new QBuffer(&imgData); + QByteArray *bodyHeap = new QByteArray; + body.swap(*bodyHeap); + QBuffer *buffer = new QBuffer(bodyHeap); buffer->open(QIODevice::ReadOnly); part.setBodyDevice(buffer); multipart->append(part); @@ -327,7 +329,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { str = str.mid(1, str.length() - 1).replace("%contenttype", mime); part.setRawHeader(headerVal.toLatin1(), str.toLatin1()); } else - cdh += "; " + headerVal + ": \"" + valo[headerVal].toString().replace("\"", "\\\"") + "\""; + cdh += "; " + headerVal + "= \"" + valo[headerVal].toString().replace("\"", "\\\"") + "\""; } part.setHeader(QNetworkRequest::ContentDispositionHeader, cdh); } From beffabe167307ba03e06ae87bc8959f683285a60 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 13 Jul 2017 17:29:29 +0200 Subject: [PATCH 068/293] Fix headers in multipart --- AppVeyor/make_installer.sh | 1 - README.md | 2 ++ install.sh | 2 +- io/ioutils.cpp | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 32dbb65..61e5ad4 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -32,7 +32,6 @@ addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5Gui.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5Widgets.dll addFile /c/Qt/5.9/mingw53_32/bin/Qt5WinExtras.dll -addFile /c/Qt/5.9/mingw53_32/bin/Qt5Network.dll addFileIn /c/Qt/5.9/mingw53_32/plugins/platforms/qwindows.dll platforms diff --git a/README.md b/README.md index 0cb5725..6cd9215 100644 --- a/README.md +++ b/README.md @@ -50,4 +50,6 @@ make On systems with FFMpeg pre-3.1 you need to apply `OlderSystemFix.patch` to `recording/encoders/encoder.cpp`. On systems with Qt pre-5.7 you need to install the Qt version from their website. You can attempt to `curl https://raw.githubusercontent.com/ArsenArsen/KShare/master/install.sh | bash` + +You can find more details [here](https://blog.arsenarsen.com/posts/compiling-kshare-on-linux-mac-os-x-and-windows-final-revision) ###### Started on 19th of April 2017 to bring some attention and improvement to Linux screenshotting. diff --git a/install.sh b/install.sh index c324471..161f30a 100755 --- a/install.sh +++ b/install.sh @@ -16,7 +16,7 @@ installIfNeeded pkg-config installIfNeeded git resultfile="$(pwd)/KShare/build/KShare.app/" elif [[ "$uname" = "Linux" ]]; then -echo "Please install Qt5 SDK, qmake, ffmpeg development files, git, and pkgcondig" +echo "Please install Qt5 SDK, qmake, ffmpeg development files, git, and pkgconfig" bash resultfile="$(pwd)/KShare/build/KShare" else echo "Unsupported OS!" && exit 1; fi diff --git a/io/ioutils.cpp b/io/ioutils.cpp index c66bbc8..447fcb9 100644 --- a/io/ioutils.cpp +++ b/io/ioutils.cpp @@ -28,7 +28,7 @@ void ioutils::postMultipartData(QUrl target, std::function callback) { QNetworkRequest req(target); for (auto header : headers) { - req.setRawHeader(header.first.toUtf8(), header.second.toUtf8()); + if (header.first.toLower() != "content-type") req.setRawHeader(header.first.toUtf8(), header.second.toUtf8()); } QNetworkReply *reply = networkManager.post(req, body); QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { From f139fe1e0c1462704555afe0b136a36dbbbdbec1 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 13 Jul 2017 21:13:14 +0200 Subject: [PATCH 069/293] #19 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6cd9215..c62905a 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ See the [projects](https://github.com/ArsenArsen/KShare/projects) |:----:|:--:| |Arch Linux (development)|[kshare-git](https://aur.archlinux.org/packages/kshare-git/)| |Ubuntu (development)|[Ubuntu .deb](https://nativeci.arsenarsen.com/job/KShare/lastSuccessfulBuild/artifact/packages/simpleName.deb)| -|Arch Linux |[kshare](https://aur.archlinux.org/packages/kshare-git/)| +|Arch Linux |[kshare](https://aur.archlinux.org/packages/kshare/)| |Ubuntu |[Ubuntu .deb](https://nativeci.arsenarsen.com/job/KShare%20Stable/lastSuccessfulBuild/artifact/packages/simpleName.deb )| I do plan to make a Debian packages. From 0d58d67a3c40d93aa82d071e177faa2c17dff514 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 14 Jul 2017 18:49:00 +0200 Subject: [PATCH 070/293] Multipart works now --- README.md | 4 ++++ packages/arch/KShare/PKGBUILD.sample | 2 +- uploaders/customuploader.cpp | 27 ++++++++++++++++++--------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c62905a..9a25e68 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,10 @@ See the [wiki](https://github.com/ArsenArsen/KShare/wiki). * libavcodec * libavutil * libswscale +Additionally, on Linux, you require: +* XCB +* XCB xfixes +* XCB cursor Despite the name implying so, this project does not depend on the KDE API at all. diff --git a/packages/arch/KShare/PKGBUILD.sample b/packages/arch/KShare/PKGBUILD.sample index 8915b05..dd013cb 100644 --- a/packages/arch/KShare/PKGBUILD.sample +++ b/packages/arch/KShare/PKGBUILD.sample @@ -17,7 +17,7 @@ build() { git checkout dev git submodule update --init --recursive qmake - make + make -j$(($(nproc) + 1)) } package() { diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index f9b8453..0610672 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -293,6 +293,8 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { case RequestFormat::MULTIPART_FORM_DATA: { QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType); auto arr = body.toArray(); + QList buffersToDelete; + QList arraysToDelete; for (QJsonValue val : arr) { auto valo = val.toObject(); QHttpPart part; @@ -307,18 +309,19 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { body.append(split[i]); if (i < split.size() - 1) body.append(imgData); } - } + } else + body = s.toUtf8(); QByteArray *bodyHeap = new QByteArray; body.swap(*bodyHeap); QBuffer *buffer = new QBuffer(bodyHeap); buffer->open(QIODevice::ReadOnly); part.setBodyDevice(buffer); - multipart->append(part); + buffersToDelete.append(buffer); + arraysToDelete.append(bodyHeap); } else { auto bdo = bd.toObject(); QJsonObject result = recurseAndReplace(bdo, imgData, mime); part.setBody(QJsonDocument::fromVariant(result.toVariantMap()).toJson()); - multipart->append(part); } QByteArray cdh("form-data"); for (QString headerVal : valo.keys()) { @@ -328,22 +331,28 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { if (str.startsWith("/") && str.endsWith("/")) str = str.mid(1, str.length() - 1).replace("%contenttype", mime); part.setRawHeader(headerVal.toLatin1(), str.toLatin1()); - } else - cdh += "; " + headerVal + "= \"" + valo[headerVal].toString().replace("\"", "\\\"") + "\""; + } else if (headerVal != "body") + cdh += "; " + headerVal + "=\"" + valo[headerVal].toString().replace("\"", "\\\"") + "\""; } part.setHeader(QNetworkRequest::ContentDispositionHeader, cdh); + multipart->append(part); } switch (method) { case HttpMethod::POST: if (returnPathspec == "|") { - ioutils::postMultipartData(target, h, multipart, [&](QByteArray result, QNetworkReply *) { + ioutils::postMultipartData(target, h, multipart, [&, buffersToDelete, arraysToDelete](QByteArray result, QNetworkReply *) { QApplication::clipboard()->setText(QString::fromUtf8(result)); + for (auto buffer : buffersToDelete) buffer->deleteLater(); + for (auto arr : arraysToDelete) delete arr; notifications::notify("KShare Custom Uploader " + name(), "Copied upload result to clipboard!"); }); } else { - ioutils::postMultipart(target, h, multipart, [&](QJsonDocument result, QByteArray data, QNetworkReply *) { - parseResult(result, data, returnPathspec, name()); - }); + ioutils::postMultipart(target, h, multipart, + [&, buffersToDelete, arraysToDelete](QJsonDocument result, QByteArray data, QNetworkReply *) { + for (auto buffer : buffersToDelete) buffer->deleteLater(); + for (auto arr : arraysToDelete) delete arr; + parseResult(result, data, returnPathspec, name()); + }); } break; } From 55669aabe4e5a018d6ffb7e717455d95823cd141 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 15 Jul 2017 13:28:04 +0200 Subject: [PATCH 071/293] Try and fix the worker. --- worker/worker.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/worker/worker.cpp b/worker/worker.cpp index 598ab68..457bdb6 100644 --- a/worker/worker.cpp +++ b/worker/worker.cpp @@ -13,6 +13,7 @@ QMutex Worker::lock; // 1. Convert the image to the right format // 2. Consume the image. void Worker::queue(WorkerContext *context) { + init(); QMutexLocker ml(&lock); _WorkerContext *c = new _WorkerContext; c->image = context->pixmap.toImage(); From 9baadf63e95043a315d0440630b01b3205d2be60 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 16 Jul 2017 18:48:21 +0200 Subject: [PATCH 072/293] Fix #18 --- uploaders/uploadersingleton.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/uploaders/uploadersingleton.cpp b/uploaders/uploadersingleton.cpp index 8198b06..3f21481 100644 --- a/uploaders/uploadersingleton.cpp +++ b/uploaders/uploadersingleton.cpp @@ -95,7 +95,9 @@ void UploaderSingleton::upload(QPixmap pixmap) { void UploaderSingleton::upload(QByteArray img, QString format) { if (img.isEmpty()) return; - QFile file(saveDir.absoluteFilePath(formatter::format(settings::settings().value("fileFormat").toString(), format.toLower()))); + QFile file(saveDir.absoluteFilePath( + formatter::format(settings::settings().value("fileFormat", "Screenshot %(yyyy-MM-dd HH-mm-ss)date.%ext").toString(), + format.toLower()))); if (file.open(QFile::WriteOnly)) { file.write(img); file.close(); @@ -105,8 +107,9 @@ void UploaderSingleton::upload(QByteArray img, QString format) { void UploaderSingleton::upload(QFile &img, QString format) { if (img.size() <= 0) return; - if (img.rename( - saveDir.absoluteFilePath(formatter::format(settings::settings().value("fileFormat").toString(), format.toLower())))) { + if (img.rename(saveDir.absoluteFilePath( + formatter::format(settings::settings().value("fileFormat", "Screenshot %(yyyy-MM-dd HH-mm-ss)date.%ext").toString(), + format.toLower())))) { if (img.open(QFile::ReadWrite)) uploaders.value(uploader)->doUpload(img.readAll(), format); else From 7f9db557f9fe098aebd56eb6256b352626dfb45c Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 16 Jul 2017 19:26:41 +0200 Subject: [PATCH 073/293] Implement %FORMAT and %format --- .gdb_history | 1 + uploaders/customuploader.cpp | 98 ++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 54 deletions(-) create mode 100644 .gdb_history diff --git a/.gdb_history b/.gdb_history new file mode 100644 index 0000000..fc5962c --- /dev/null +++ b/.gdb_history @@ -0,0 +1 @@ +bt diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index 0610672..17a3807 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -168,25 +168,6 @@ QList> getHeaders(QJsonObject h, QString imageFormat, Re return headers; } -QJsonObject recurseAndReplace(QJsonObject &body, QByteArray &data, QString contentType) { - QJsonObject o; - for (QString s : body.keys()) { - QJsonValue v = body[s]; - if (v.isObject()) { - QJsonObject vo = v.toObject(); - o.insert(s, recurseAndReplace(vo, data, contentType)); - } else if (v.isString()) { - QString str = v.toString(); - if (str.startsWith("/") && str.endsWith("/")) { - o.insert(s, str.mid(1, str.length() - 2).replace("%imagedata", data).replace("%contenttype", contentType)); - } else - o.insert(s, v); - } else - o.insert(s, v); - } - return o; -} - QString parsePathspec(QJsonDocument &response, QString &pathspec) { if (!pathspec.startsWith(".")) { // Does not point to anything @@ -243,12 +224,46 @@ void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, } } +QByteArray substituteArgs(QByteArray arr, QString format, QByteArray imgData = QByteArray()) { + QString mime = normalFormatMIME(normalFormatFromName(format)); + if (mime.isEmpty()) mime = recordingFormatMIME(recordingFormatFromName(format)); + if (arr.startsWith("/") && arr.endsWith("/")) { + arr = arr.mid(1, arr.length() - 2); + + arr = arr.replace("%contenttype", mime.toUtf8()); + arr = arr.replace("%FORMAT", format.toUpper().toUtf8()); + arr = arr.replace("%format", format.toLower().toUtf8()); + + if (imgData.isNull()) return arr; + return arr.replace("%imagedata", imgData); + } else + return arr; +} + + +QJsonObject recurseAndReplace(QJsonObject &body, QByteArray &data, QString format) { + QJsonObject o; + for (QString s : body.keys()) { + QJsonValue v = body[s]; + if (v.isObject()) { + QJsonObject vo = v.toObject(); + o.insert(s, recurseAndReplace(vo, data, format)); + } else if (v.isString()) { + QString str = v.toString(); + if (str.startsWith("/") && str.endsWith("/")) { + o.insert(s, substituteArgs(str.toUtf8(), format, data)); + } else + o.insert(s, v); + } else + o.insert(s, v); + } + return o; +} + void CustomUploader::doUpload(QByteArray imgData, QString format) { auto h = getHeaders(headers, format, this->rFormat); QByteArray data; if (base64) imgData = imgData.toBase64(); - QString mime = normalFormatMIME(normalFormatFromName(format)); - if (mime.isEmpty()) mime = recordingFormatMIME(recordingFormatFromName(format)); switch (this->rFormat) { case RequestFormat::PLAIN: { @@ -256,14 +271,10 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { } break; case RequestFormat::JSON: { if (body.isString()) { - QStringList split = body.toString().replace("%contenttype", mime).split("%imagedata"); - for (int i = 0; i < split.size(); i++) { - data.append(split[i]); - if (i < split.size() - 1) data.append(imgData); - } + data = substituteArgs(body.toString().toUtf8(), format, imgData); } else { QJsonObject vo = body.toObject(); - data = QJsonDocument::fromVariant(recurseAndReplace(vo, imgData, mime).toVariantMap()).toJson(); + data = QJsonDocument::fromVariant(recurseAndReplace(vo, imgData, format).toVariantMap()).toJson(); } } break; case RequestFormat::X_WWW_FORM_URLENCODED: { @@ -271,17 +282,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { for (QString key : body.keys()) { QJsonValue val = body[key]; if (val.isString()) { - QString str = val.toString(); - QByteArray strB; - if (str.startsWith("/") && str.endsWith("/")) { - str = str.mid(1, str.length() - 2); - QStringList split = str.replace("%contenttype", mime).split("%imagedata"); - for (int i = 0; i < split.size(); i++) { - strB.append(split[i]); - if (i < split.size() - 1) strB.append(imgData); - } - } - data.append(QUrl::toPercentEncoding(key)).append('=').append(strB); + data.append(QUrl::toPercentEncoding(key)).append('=').append(substituteArgs(val.toString().toUtf8(), format, imgData)); } else { if (!data.isEmpty()) data.append('&'); data.append(QUrl::toPercentEncoding(key)) @@ -300,17 +301,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { QHttpPart part; QJsonValue bd = valo["body"]; if (bd.isString()) { - QString s = bd.toString(); - QByteArray body; - if (s.startsWith("/") && s.endsWith("/")) { - s = s.mid(1, s.length() - 1); - QStringList split = s.replace("%contenttype", mime).split("%imagedata"); - for (int i = 0; i < split.size(); i++) { - body.append(split[i]); - if (i < split.size() - 1) body.append(imgData); - } - } else - body = s.toUtf8(); + QByteArray body = substituteArgs(bd.toString().toUtf8(), format, imgData); QByteArray *bodyHeap = new QByteArray; body.swap(*bodyHeap); QBuffer *buffer = new QBuffer(bodyHeap); @@ -320,17 +311,16 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { arraysToDelete.append(bodyHeap); } else { auto bdo = bd.toObject(); - QJsonObject result = recurseAndReplace(bdo, imgData, mime); + QJsonObject result = recurseAndReplace(bdo, imgData, format); part.setBody(QJsonDocument::fromVariant(result.toVariantMap()).toJson()); } QByteArray cdh("form-data"); for (QString headerVal : valo.keys()) { if (headerVal.startsWith("__")) { headerVal = headerVal.mid(2); - QString str = valo[headerVal].toString(); - if (str.startsWith("/") && str.endsWith("/")) - str = str.mid(1, str.length() - 1).replace("%contenttype", mime); - part.setRawHeader(headerVal.toLatin1(), str.toLatin1()); + QByteArray str = valo[headerVal].toString().toUtf8(); + if (str.startsWith("/") && str.endsWith("/")) str = substituteArgs(str, format); + part.setRawHeader(headerVal.toLatin1(), str; } else if (headerVal != "body") cdh += "; " + headerVal + "=\"" + valo[headerVal].toString().replace("\"", "\\\"") + "\""; } From be68aa1f5bfb5a051d9f7bb73651ea75590d492e Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 16 Jul 2017 19:47:24 +0200 Subject: [PATCH 074/293] Fix the visibility in CropScene --- .gdb_history | 1 - cropeditor/cropscene.cpp | 1 - 2 files changed, 2 deletions(-) delete mode 100644 .gdb_history diff --git a/.gdb_history b/.gdb_history deleted file mode 100644 index fc5962c..0000000 --- a/.gdb_history +++ /dev/null @@ -1 +0,0 @@ -bt diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 345d26d..6f4434d 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -162,7 +162,6 @@ void CropScene::setVisible(bool visible) { for (auto view : views()) { if (view->isVisible()) fullscreen |= view->isFullScreen(); view->setVisible(visible); - if (fullscreen) view->showFullScreen(); if (visible) { view->resize(_pixmap.width(), _pixmap.height()); view->setMinimumSize(_pixmap.size()); From 8f856b927a3c890ee799b0e9f5dbd235989f464f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 16 Jul 2017 19:48:41 +0200 Subject: [PATCH 075/293] Ignore all history files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index c7c374a..9ce9cdd 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ Makefile vgcore.* *.Release + +.*_history From 2d863af60e2c76c220b157c635f977f237b7739a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 16 Jul 2017 19:50:28 +0200 Subject: [PATCH 076/293] Fix compilation errors --- uploaders/customuploader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index 17a3807..cdf572d 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -251,7 +251,7 @@ QJsonObject recurseAndReplace(QJsonObject &body, QByteArray &data, QString forma } else if (v.isString()) { QString str = v.toString(); if (str.startsWith("/") && str.endsWith("/")) { - o.insert(s, substituteArgs(str.toUtf8(), format, data)); + o.insert(s, QString::fromUtf8(substituteArgs(str.toUtf8(), format, data))); } else o.insert(s, v); } else @@ -320,7 +320,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { headerVal = headerVal.mid(2); QByteArray str = valo[headerVal].toString().toUtf8(); if (str.startsWith("/") && str.endsWith("/")) str = substituteArgs(str, format); - part.setRawHeader(headerVal.toLatin1(), str; + part.setRawHeader(headerVal.toLatin1(), str); } else if (headerVal != "body") cdh += "; " + headerVal + "=\"" + valo[headerVal].toString().replace("\"", "\\\"") + "\""; } From c492e9ac076e5b7f7c9f993d15f1e206d2333462 Mon Sep 17 00:00:00 2001 From: dm4uz3 Date: Mon, 17 Jul 2017 20:03:46 +0100 Subject: [PATCH 077/293] did it in dev --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a25e68..4e69e3e 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,9 @@ See the [projects](https://github.com/ArsenArsen/KShare/projects) |Distro|Link| |:----:|:--:| |Arch Linux (development)|[kshare-git](https://aur.archlinux.org/packages/kshare-git/)| -|Ubuntu (development)|[Ubuntu .deb](https://nativeci.arsenarsen.com/job/KShare/lastSuccessfulBuild/artifact/packages/simpleName.deb)| +|Ubuntu/Debian (development)|[.deb](https://nativeci.arsenarsen.com/job/KShare/lastSuccessfulBuild/artifact/packages/simpleName.deb)| |Arch Linux |[kshare](https://aur.archlinux.org/packages/kshare/)| -|Ubuntu |[Ubuntu .deb](https://nativeci.arsenarsen.com/job/KShare%20Stable/lastSuccessfulBuild/artifact/packages/simpleName.deb )| +|Ubuntu/Debian |[.deb](https://nativeci.arsenarsen.com/job/KShare%20Stable/lastSuccessfulBuild/artifact/packages/simpleName.deb )| I do plan to make a Debian packages. From 69ea0fb3eecf78db350e34ebf4f1feb6840cde69 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 17 Jul 2017 22:26:36 +0200 Subject: [PATCH 078/293] Try and add the Arch stable package --- packages/arch/KShare-Stable/.gitignore | 1 - packages/arch/KShare-Stable/PKGBUILD.sample | 27 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) delete mode 100644 packages/arch/KShare-Stable/.gitignore create mode 100644 packages/arch/KShare-Stable/PKGBUILD.sample diff --git a/packages/arch/KShare-Stable/.gitignore b/packages/arch/KShare-Stable/.gitignore deleted file mode 100644 index 0f868b8..0000000 --- a/packages/arch/KShare-Stable/.gitignore +++ /dev/null @@ -1 +0,0 @@ -PKGBUILD.sample diff --git a/packages/arch/KShare-Stable/PKGBUILD.sample b/packages/arch/KShare-Stable/PKGBUILD.sample new file mode 100644 index 0000000..8f8cfc0 --- /dev/null +++ b/packages/arch/KShare-Stable/PKGBUILD.sample @@ -0,0 +1,27 @@ +# Maintainer: ArsenArsen +pkgname=kshare +pkgver=;VER; +pkgrel=1 +conflicts=("kshare-git") +pkgdesc="A ShareX inspired cross platform utility written with Qt." +arch=('i686' 'x86_64') +url="https://github.com/ArsenArsen/KShare" +license=('MIT') +provides=('kshare=$pkgver') +depends=(qt5-base qt5-x11extras xcb-util-cursor ffmpeg libxfixes) +source=(git+https://github.com/ArsenArsen/KShare.git#tag=v${pkgver}) +sha1sums=('SKIP') + +build() { + cd "${srcdir}/KShare" + git submodule update --init --recursive + qmake + make -j$(($(nproc) + 1)) +} + +package() { + cd "${srcdir}/KShare" + mkdir -p "$pkgdir/usr/bin" + install ./KShare "$pkgdir/usr/bin/kshare" +} + From f509d44ccabe6550ceb2ee6164fbbb0993888b4c Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 18 Jul 2017 22:03:37 +0200 Subject: [PATCH 079/293] Use a mutex locker. I am currently working on another private project and that and the lack of the ability to reproduce some issues is why the development has slowed down --- worker/worker.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/worker/worker.cpp b/worker/worker.cpp index 457bdb6..ec317cf 100644 --- a/worker/worker.cpp +++ b/worker/worker.cpp @@ -58,14 +58,13 @@ bool Worker::ended() { void Worker::process() { while (!ended()) { - lock.lock(); + QMutexLocker ml(&lock); if (!qqueue.isEmpty()) { _WorkerContext *c = qqueue.dequeue(); c->consumer(c->image.convertToFormat(c->targetFormat)); delete c->underlyingThing; delete c; } - lock.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); // STL likes it's scopes } emit finished(); From f0dfe3d3919d9786b407dcc01853c75da2ae6345 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 00:23:07 +0200 Subject: [PATCH 080/293] Hack in array support --- uploaders/customuploader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index cdf572d..65e0cfe 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -208,7 +208,6 @@ QString parsePathspec(QJsonDocument &response, QString &pathspec) { void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name) { if (result.isObject()) { - qDebug() << result.object()[".url"]; QString url = parsePathspec(result, returnPathspec); if (!url.isEmpty()) { QApplication::clipboard()->setText(url); From e55185da059b630b6264a5ad3ca9ee083cc10011 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 00:40:39 +0200 Subject: [PATCH 081/293] Add in return_{ap,pre}pend --- uploaders/customuploader.cpp | 14 +++++++++----- uploaders/customuploader.hpp | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index 65e0cfe..24b868b 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -130,6 +130,8 @@ CustomUploader::CustomUploader(QString absFilePath) { base64 = bool64.toBool(); if (rFormat == RequestFormat::JSON && !base64) error(absFilePath, "base64 required with json"); } + urlPrepend = obj["return_prepend"].toString(); + urlAppend = obj["return_append"].toString(); } QString CustomUploader::name() { @@ -191,6 +193,8 @@ QString parsePathspec(QJsonDocument &response, QString &pathspec) { return ""; else if (val.isString()) return val.toString(); + else if (val.isArray()) + val = val.toArray()[fields.at(i).toInt()]; else if (!val.isObject()) return QString::fromUtf8(QJsonDocument::fromVariant(val.toVariant()).toJson()); else @@ -206,9 +210,9 @@ QString parsePathspec(QJsonDocument &response, QString &pathspec) { return ""; } -void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name) { +void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name, QString urlPrepend, QString urlAppend) { if (result.isObject()) { - QString url = parsePathspec(result, returnPathspec); + QString url = urlPrepend + parsePathspec(result, returnPathspec) + urlAppend; if (!url.isEmpty()) { QApplication::clipboard()->setText(url); notifications::notify("KShare Custom Uploader " + name, "Copied upload link to clipboard!"); @@ -340,13 +344,13 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { [&, buffersToDelete, arraysToDelete](QJsonDocument result, QByteArray data, QNetworkReply *) { for (auto buffer : buffersToDelete) buffer->deleteLater(); for (auto arr : arraysToDelete) delete arr; - parseResult(result, data, returnPathspec, name()); + parseResult(result, data, returnPathspec, name(), urlPrepend, urlPrepend); }); } break; } return; - } break; + } } if (limit > 0 && data.size() > limit) { notifications::notify("KShare Custom Uploader " + name(), "File limit exceeded!"); @@ -361,7 +365,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { }); } else { ioutils::postJson(target, h, data, [&](QJsonDocument result, QByteArray data, QNetworkReply *) { - parseResult(result, data, returnPathspec, name()); + parseResult(result, data, returnPathspec, name(), urlPrepend, urlPrepend); }); } break; diff --git a/uploaders/customuploader.hpp b/uploaders/customuploader.hpp index 5a0e791..22deaef 100644 --- a/uploaders/customuploader.hpp +++ b/uploaders/customuploader.hpp @@ -28,6 +28,7 @@ private: QJsonObject headers; bool base64 = false; QString returnPathspec; + QString urlPrepend, urlAppend; }; #endif // CUSTOMUPLOADER_HPP From 990bcd5ad98e10dc0ff8c857b754758517200efe Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 00:43:07 +0200 Subject: [PATCH 082/293] Fix a bug with descriptons --- uploaders/customuploader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index 24b868b..555b59b 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -35,7 +35,7 @@ CustomUploader::CustomUploader(QString absFilePath) { error(absFilePath, "name is not a string"); else uName = obj["name"].toString(); - if (!obj.contains("desc")) { + if (obj.contains("desc")) { if (!obj["desc"].isString()) /*t*/ error(absFilePath, "desc not a string"); else From afbe278155e7eaa84e09c1b93a04b1d24834c132 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 01:03:56 +0200 Subject: [PATCH 083/293] Fix a bug with multipart and return parsing --- io/ioutils.cpp | 2 +- uploaders/customuploader.cpp | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/io/ioutils.cpp b/io/ioutils.cpp index 447fcb9..5753178 100644 --- a/io/ioutils.cpp +++ b/io/ioutils.cpp @@ -12,7 +12,7 @@ void ioutils::postMultipart(QUrl target, std::function callback) { QNetworkRequest req(target); for (auto header : headers) { - req.setRawHeader(header.first.toUtf8(), header.second.toUtf8()); + if (header.first.toLower() != "content-type") req.setRawHeader(header.first.toUtf8(), header.second.toUtf8()); } QNetworkReply *reply = networkManager.post(req, body); QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index 555b59b..d481d19 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -182,12 +182,6 @@ QString parsePathspec(QJsonDocument &response, QString &pathspec) { return QString::fromUtf8(response.toJson()); } QJsonValue val = o[fields.at(0)]; - if (val.isUndefined() || val.isNull()) - return ""; - else if (val.isString()) - return val.toString(); - else if (!val.isObject()) - return QString::fromUtf8(QJsonDocument::fromVariant(val.toVariant()).toJson()); for (int i = 1; i < fields.size(); i++) { if (val.isUndefined() || val.isNull()) return ""; @@ -325,7 +319,8 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { if (str.startsWith("/") && str.endsWith("/")) str = substituteArgs(str, format); part.setRawHeader(headerVal.toLatin1(), str); } else if (headerVal != "body") - cdh += "; " + headerVal + "=\"" + valo[headerVal].toString().replace("\"", "\\\"") + "\""; + cdh += "; " + headerVal + "=\"" + + substituteArgs(valo[headerVal].toString().toUtf8(), format).replace("\"", "\\\"") + "\""; } part.setHeader(QNetworkRequest::ContentDispositionHeader, cdh); multipart->append(part); @@ -344,7 +339,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { [&, buffersToDelete, arraysToDelete](QJsonDocument result, QByteArray data, QNetworkReply *) { for (auto buffer : buffersToDelete) buffer->deleteLater(); for (auto arr : arraysToDelete) delete arr; - parseResult(result, data, returnPathspec, name(), urlPrepend, urlPrepend); + parseResult(result, data, returnPathspec, name(), urlPrepend, urlAppend); }); } break; @@ -365,7 +360,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { }); } else { ioutils::postJson(target, h, data, [&](QJsonDocument result, QByteArray data, QNetworkReply *) { - parseResult(result, data, returnPathspec, name(), urlPrepend, urlPrepend); + parseResult(result, data, returnPathspec, name(), urlPrepend, urlAppend); }); } break; From 9ef6aa562abe8285e22d70fbc67978e56212f7e9 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 14:18:28 +0200 Subject: [PATCH 084/293] Fix a recording performance issue This is why dev is a thing --- worker/worker.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/worker/worker.cpp b/worker/worker.cpp index ec317cf..88c1e0a 100644 --- a/worker/worker.cpp +++ b/worker/worker.cpp @@ -58,13 +58,15 @@ bool Worker::ended() { void Worker::process() { while (!ended()) { - QMutexLocker ml(&lock); + lock.lock(); if (!qqueue.isEmpty()) { _WorkerContext *c = qqueue.dequeue(); + lock.unlock(); c->consumer(c->image.convertToFormat(c->targetFormat)); delete c->underlyingThing; delete c; - } + } else + lock.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); // STL likes it's scopes } emit finished(); From 906986feed79aa252623f62b65ae0936b50a9f0f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 17:14:28 +0200 Subject: [PATCH 085/293] Add some example uploaders --- pictshare.uploader | 11 +++++++++++ pomf.uploader | 15 +++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 pictshare.uploader create mode 100644 pomf.uploader diff --git a/pictshare.uploader b/pictshare.uploader new file mode 100644 index 0000000..85fdb07 --- /dev/null +++ b/pictshare.uploader @@ -0,0 +1,11 @@ +{ + "name": "PictShare", + "desc" : "Example", + "target": ".../backend.php", + "base64": true, + "format": "x-www-form-urlencoded", + "body": { + "base64": "/data:%contenttype;base64,%imagedata/" + }, + "return": ".url" +} diff --git a/pomf.uploader b/pomf.uploader new file mode 100644 index 0000000..5a46025 --- /dev/null +++ b/pomf.uploader @@ -0,0 +1,15 @@ +{ + "name": "Uploader name", + "target": "POMF endpoint", + "format": "multipart-form-data", + "body": [ + { + "__Content-Type": "/%contenttype/", + "filename": "/image.%format/", + "name": "files[]", + "body": "/%imagedata/" + } + ], + "return": ".files.0.url", + "return_prepend": "Add only if the host does not fill out url" +} From 91e0a44d9642229963b725bb7179e878a08ba044 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 18:04:20 +0200 Subject: [PATCH 086/293] Fix a part header setting bug --- uploaders/customuploader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index d481d19..bf8ff6c 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -315,7 +315,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { for (QString headerVal : valo.keys()) { if (headerVal.startsWith("__")) { headerVal = headerVal.mid(2); - QByteArray str = valo[headerVal].toString().toUtf8(); + QByteArray str = valo["__" + headerVal].toString().toUtf8(); if (str.startsWith("/") && str.endsWith("/")) str = substituteArgs(str, format); part.setRawHeader(headerVal.toLatin1(), str); } else if (headerVal != "body") From a6bf7fd1e2b64b5cb629453e4181d9efd02a2e84 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 18:19:27 +0200 Subject: [PATCH 087/293] Move uploaders --- pictshare.uploader => examples/pictshare.uploader | 0 pomf.uploader => examples/pomf.uploader | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename pictshare.uploader => examples/pictshare.uploader (100%) rename pomf.uploader => examples/pomf.uploader (100%) diff --git a/pictshare.uploader b/examples/pictshare.uploader similarity index 100% rename from pictshare.uploader rename to examples/pictshare.uploader diff --git a/pomf.uploader b/examples/pomf.uploader similarity index 100% rename from pomf.uploader rename to examples/pomf.uploader From b2240022802e4813854b43219cdd65ed5e0ed1a4 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 18:24:45 +0200 Subject: [PATCH 088/293] Whack-A-CI is open again! --- AppVeyor/make_installer.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 61e5ad4..6ed54db 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -43,6 +43,8 @@ addFile /c/OpenSSL-Win32/bin/libeay32.dll addFile /c/OpenSSL-Win32/bin/ssleay32.dll addFile /c/OpenSSL-Win32/bin/msvcr120.dll +ls /c/OpenSSL-Win32/bin/ + ls cat installer.iss.pattern.bottom >> installer.iss From 85c4e29b5c7622b9cd1f8871bc7f4c6c67f3379f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 18:28:54 +0200 Subject: [PATCH 089/293] Whack-A-CI!! --- AppVeyor/make_installer.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 6ed54db..3692153 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -2,7 +2,7 @@ function addFile { echo $1 cp $1 . - 7z a -tzip portable.zip $(basename $1) + 7z a -tzip portable.zip $(basename $1) > /dev/null echo "Source: \"$(basename $1)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss } @@ -10,7 +10,7 @@ function addFileIn { name=$2\\$(basename $1) mkdir -p $2 cp $1 $2 - 7z a -tzip portable.zip $name + 7z a -tzip portable.zip $name > /dev/null echo "Source: \"$name\"; DestDir: \"{app}\\$2\"; Flags: ignoreversion" >> installer.iss } @@ -45,8 +45,6 @@ addFile /c/OpenSSL-Win32/bin/msvcr120.dll ls /c/OpenSSL-Win32/bin/ -ls - cat installer.iss.pattern.bottom >> installer.iss "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss cp Output/setup.exe ../../installer.exe || exit 1 From 4c71e727e133fbd53e890e576610e083fdef23be Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 18:45:10 +0200 Subject: [PATCH 090/293] Im squashing all these commits --- AppVeyor/make_installer.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 3692153..7006e3e 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -43,7 +43,9 @@ addFile /c/OpenSSL-Win32/bin/libeay32.dll addFile /c/OpenSSL-Win32/bin/ssleay32.dll addFile /c/OpenSSL-Win32/bin/msvcr120.dll -ls /c/OpenSSL-Win32/bin/ +echo ----------------- +ls /c/OpenSSL-Win32/bin/ -R +echo ----------------- cat installer.iss.pattern.bottom >> installer.iss "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" installer.iss From e26a6ae75b159c4e6d49e39d5353fe4b1fca1007 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 18:48:39 +0200 Subject: [PATCH 091/293] Some files got moved around --- AppVeyor/make_installer.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/AppVeyor/make_installer.sh b/AppVeyor/make_installer.sh index 7006e3e..fa08da4 100644 --- a/AppVeyor/make_installer.sh +++ b/AppVeyor/make_installer.sh @@ -1,17 +1,18 @@ #!/usr/bin/env bash function addFile { - echo $1 - cp $1 . + cp $1 . || (echo cp $1 failed ; return 1) 7z a -tzip portable.zip $(basename $1) > /dev/null echo "Source: \"$(basename $1)\"; DestDir: \"{app}\"; Flags: ignoreversion" >> installer.iss + echo $1 } function addFileIn { name=$2\\$(basename $1) mkdir -p $2 - cp $1 $2 + cp $1 $2 || (echo cp $name failed ; return 1) 7z a -tzip portable.zip $name > /dev/null echo "Source: \"$name\"; DestDir: \"{app}\\$2\"; Flags: ignoreversion" >> installer.iss + echo $name } ver=$(cat main.cpp | grep setApplicationVersion | sed "s/\\s*a.setApplicationVersion(\"//g" | sed "s/\");//g") From bf1c1f4def0825a0d5bd5b52dc753bb8a41ebb0a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 22:37:48 +0200 Subject: [PATCH 092/293] s3 test upload --- .travis.yml | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index d921d82..cc45940 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,23 @@ os: osx language: cpp before_install: - - brew install qt ffmpeg - - brew link qt --force - - mkdir build +- brew install qt ffmpeg +- brew link qt --force +- mkdir build script: - - cd build - - qmake .. - - make -j$(($(nproc) + 1)) +- cd build +- qmake .. +- make -j$(($(nproc) + 1)) +- mkdir done +- zip KShare.app done/output.zip -r +deploy: + provider: s3 + access_key_id: AKIAIHF2FGD2SKLGJOQA + secret_access_key: + secure: DzDQejh1jVi0fov/j9JQU+TGyrDSoKUSBO2YXu9XskyyJb5fDITZ4m1SicK4Iev5GeFUYCPP4xUqJyLPGDnfqLEF9Uc3AZJV48AUAwaUnfgfGy6QYs2cMjuT5CyKnpybVRJpqqWYOkiNeUNuLnuZ8quU/p8l1Ib4y4oZlMKNcK0xON83zb86oXTSrenqEFDrAIEvZDFLWjEXeLjKIiT5sy9aRsNDfizOekjU7n0tz6jBtbX4RzV3x31PKc4pwGuiUlFwjOxwLju4BSD6YtsvJGUIyN+FhS0wWBTqEGl1+6TAAJQDVuntvX/GjFCG6FLessqbFg6QxMi4sczHZMRNSQKiUj18sJfJMkrL0scMHUI7F5NoArvlsxE2C7EjhghEQzxV/8BcCw68LhUutXf64g0wt1E3wunktrFPGYLHEwMPYnRtqOLY+quwsDDoV/VYnIHFeiY18VkuwC47Ps1b6EZJuY0cmfRGFMCpK6qbeRIrkCxpN1ZTslthuuz0yBn4/8PYCn/jtIP5mI5fXtl1DGav7vD2o2g26E9gYpCpDxkFEOZAzBtUdEHzMogjcvvK2POyy4fMReHMDvgVZ5c0XZkcTJX0Db4iVmxOnNBMF9qxSQnDlZLLFEr0D5j48tKFIGTzsCxmRLj52syPii/4RRMhW2SAhF1qaqCNZPz0VXI= + bucket: kshare-s3 + local-dir: build/done + acl: public_read + on: + repo: ArsenArsen/KShare + branch: dev From b667c1de09e607315d3a4f152651263aa3008c06 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 20 Jul 2017 22:59:59 +0200 Subject: [PATCH 093/293] Oops --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cc45940..8c0130f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ script: - qmake .. - make -j$(($(nproc) + 1)) - mkdir done -- zip KShare.app done/output.zip -r +- zip done/output.zip KShare.app -r deploy: provider: s3 access_key_id: AKIAIHF2FGD2SKLGJOQA From bca220e00828cbecc8cc73067935033d0af67390 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 21 Jul 2017 09:33:16 +0200 Subject: [PATCH 094/293] Try to add a desktop file --- KShare.desktop | 15 +++++++++++++++ packages/arch/KShare/PKGBUILD.sample | 4 ++++ .../{KShare-Stable => Stable-KShare}/PKGBUILD | 0 .../PKGBUILD.sample | 0 .../{KShare-Stable => Stable-KShare}/release.sh | 0 5 files changed, 19 insertions(+) create mode 100755 KShare.desktop rename packages/arch/{KShare-Stable => Stable-KShare}/PKGBUILD (100%) rename packages/arch/{KShare-Stable => Stable-KShare}/PKGBUILD.sample (100%) rename packages/arch/{KShare-Stable => Stable-KShare}/release.sh (100%) diff --git a/KShare.desktop b/KShare.desktop new file mode 100755 index 0000000..909c550 --- /dev/null +++ b/KShare.desktop @@ -0,0 +1,15 @@ +[Desktop Entry] +Name=KShare +Comment=A ShareX inspired cross platform screen capture utility written with Qt. +GenericName=Screenshot Capture Utility +Exec=/usr/bin/kshare +Icon=/usr/share/pixmaps/kshare.png +Type=Application +StartupNotify=false +Categories=Qt;Utility; +StartupWMClass=KSharee +Actions=StartInBackground + +[Desktop Action StartInBackground] +Name=Start without showing the window +Exec=kshare -b diff --git a/packages/arch/KShare/PKGBUILD.sample b/packages/arch/KShare/PKGBUILD.sample index dd013cb..8e4c9af 100644 --- a/packages/arch/KShare/PKGBUILD.sample +++ b/packages/arch/KShare/PKGBUILD.sample @@ -24,5 +24,9 @@ package() { cd "${srcdir}/KShare" mkdir -p "$pkgdir/usr/bin" install ./KShare "$pkgdir/usr/bin/kshare" + mkdir -p "$pkgdir/usr/share/pixmaps" + install "${srcdir}/KShare/icons/icon.png" + mkdir -p "$pkgdir/usr/share/applications" + install KShare.desktop "$pkgdir/usr/share/applications" } diff --git a/packages/arch/KShare-Stable/PKGBUILD b/packages/arch/Stable-KShare/PKGBUILD similarity index 100% rename from packages/arch/KShare-Stable/PKGBUILD rename to packages/arch/Stable-KShare/PKGBUILD diff --git a/packages/arch/KShare-Stable/PKGBUILD.sample b/packages/arch/Stable-KShare/PKGBUILD.sample similarity index 100% rename from packages/arch/KShare-Stable/PKGBUILD.sample rename to packages/arch/Stable-KShare/PKGBUILD.sample diff --git a/packages/arch/KShare-Stable/release.sh b/packages/arch/Stable-KShare/release.sh similarity index 100% rename from packages/arch/KShare-Stable/release.sh rename to packages/arch/Stable-KShare/release.sh From d9f339479ad1ee9aaf89e8d85984d5acf3161cc8 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 21 Jul 2017 09:47:57 +0200 Subject: [PATCH 095/293] Add an icon --- packages/arch/KShare/PKGBUILD | 28 --------------------- packages/arch/KShare/PKGBUILD.sample | 2 +- packages/arch/Stable-KShare/PKGBUILD.sample | 4 +++ 3 files changed, 5 insertions(+), 29 deletions(-) delete mode 100644 packages/arch/KShare/PKGBUILD diff --git a/packages/arch/KShare/PKGBUILD b/packages/arch/KShare/PKGBUILD deleted file mode 100644 index a146935..0000000 --- a/packages/arch/KShare/PKGBUILD +++ /dev/null @@ -1,28 +0,0 @@ -# Maintainer: ArsenArsen -pkgname=kshare-git -pkgver=cfdecf06cedd9002b2fb4e1ef8df67c72fc540f94 -pkgrel=1 -conflicts=("kshare") -pkgdesc="A ShareX inspired cross platform utility written with Qt." -arch=('i686' 'x86_64') -url="https://github.com/ArsenArsen/KShare" -license=('MIT') -provides=('kshare=$pkgver') -depends=(qt5-base qt5-x11extras xcb-util-cursor ffmpeg libxfixes) -source=(git+https://github.com/ArsenArsen/KShare.git) -sha1sums=('SKIP') - -build() { - cd "${srcdir}/KShare" - git checkout dev - git submodule update --init --recursive - qmake - make -} - -package() { - cd "${srcdir}/KShare" - mkdir -p "$pkgdir/usr/bin" - install ./KShare "$pkgdir/usr/bin/kshare" -} - diff --git a/packages/arch/KShare/PKGBUILD.sample b/packages/arch/KShare/PKGBUILD.sample index 8e4c9af..0ce5932 100644 --- a/packages/arch/KShare/PKGBUILD.sample +++ b/packages/arch/KShare/PKGBUILD.sample @@ -25,7 +25,7 @@ package() { mkdir -p "$pkgdir/usr/bin" install ./KShare "$pkgdir/usr/bin/kshare" mkdir -p "$pkgdir/usr/share/pixmaps" - install "${srcdir}/KShare/icons/icon.png" + install "${srcdir}/KShare/icons/icon.png" "$pkgdir/usr/share/pixmaps" mkdir -p "$pkgdir/usr/share/applications" install KShare.desktop "$pkgdir/usr/share/applications" } diff --git a/packages/arch/Stable-KShare/PKGBUILD.sample b/packages/arch/Stable-KShare/PKGBUILD.sample index 8f8cfc0..c8814fb 100644 --- a/packages/arch/Stable-KShare/PKGBUILD.sample +++ b/packages/arch/Stable-KShare/PKGBUILD.sample @@ -23,5 +23,9 @@ package() { cd "${srcdir}/KShare" mkdir -p "$pkgdir/usr/bin" install ./KShare "$pkgdir/usr/bin/kshare" + mkdir -p "$pkgdir/usr/share/pixmaps" + install "${srcdir}/KShare/icons/icon.png" "$pkgdir/usr/share/pixmaps" + mkdir -p "$pkgdir/usr/share/applications" + install KShare.desktop "$pkgdir/usr/share/applications" } From 00c15536252e869b1af056e56a9957205d9109fd Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 21 Jul 2017 22:35:25 +0200 Subject: [PATCH 096/293] OS X dont have nproc :facepalm: --- install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 161f30a..657aba4 100755 --- a/install.sh +++ b/install.sh @@ -26,10 +26,10 @@ cd KShare mkdir build || exit 3 cd build qmake-qt5 .. || qmake .. || exit 4 -make -j$(($(nproc) + 1)) || exit 5 +make || exit 5 echo "------------------------------------------------------" echo "Resulting file is $resultfile" if [[ "$uname" = "Linux" ]]; then echo "To link the file into path, run sudo ln -s $resultfile /usr/bin/kshare"; fi cd .. -echo "To update, go to $(pwd), git pull, cd build, and make -j$(($(nproc) + 1))" +echo "To update, go to $(pwd), git pull, cd build, and \`make\`" echo "------------------------------------------------------" From e1a15c5bca33a40c3ec7156f791ef2e3af34a27f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 22 Jul 2017 11:29:45 +0200 Subject: [PATCH 097/293] Update build links --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e69e3e..1de8388 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A [ShareX](https://getsharex.com/) inspired cross platform utility written with |Linux|Windows|OS X| |:---:|:-----:|:--:| -|[![Build Status](https://nativeci.arsenarsen.com/job/KShare/badge/icon)](https://nativeci.arsenarsen.com/job/KShare)| [![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)| [![Build Status](https://travis-ci.org/ArsenArsen/KShare.svg?branch=master)](https://travis-ci.org/ArsenArsen/KShare) | +|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare (dev)/main=master)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=master/)|[![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare (dev)/main=osxslave)](https://nativeci.arsenarsen.com/job/KShare (dev)/main=osxslave)| ## Screenshot Made with KShare itself, of course :) ![](http://i.imgur.com/ffWvCun.png) From 57208ad434116880703451abaed4dcdbc665867c Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 22 Jul 2017 11:33:57 +0200 Subject: [PATCH 098/293] Try to fix the readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1de8388..5576cd2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A [ShareX](https://getsharex.com/) inspired cross platform utility written with |Linux|Windows|OS X| |:---:|:-----:|:--:| -|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare (dev)/main=master)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=master/)|[![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare (dev)/main=osxslave)](https://nativeci.arsenarsen.com/job/KShare (dev)/main=osxslave)| +|![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=master)(https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=master/)|[![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=osxslave)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=osxslave)| ## Screenshot Made with KShare itself, of course :) ![](http://i.imgur.com/ffWvCun.png) From 0c6f94713944990b3c5b89029736b9ccb980a5f9 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 22 Jul 2017 11:35:55 +0200 Subject: [PATCH 099/293] Fixed --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5576cd2..7b2541f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A [ShareX](https://getsharex.com/) inspired cross platform utility written with |Linux|Windows|OS X| |:---:|:-----:|:--:| -|![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=master)(https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=master/)|[![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=osxslave)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=osxslave)| +|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=master)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=master/)|[![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=osxslave)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=osxslave)| ## Screenshot Made with KShare itself, of course :) ![](http://i.imgur.com/ffWvCun.png) From 3fe016c6352dd94617ac5a6b274a162d7333299f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 23 Jul 2017 13:32:02 +0200 Subject: [PATCH 100/293] Add OS X bundle info --- KShare.pro | 14 +++++++++----- install.sh | 5 +++-- packages/macos/Info.plist | 20 ++++++++++++++++++++ settings.cpp | 5 ++--- 4 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 packages/macos/Info.plist diff --git a/KShare.pro b/KShare.pro index 432fc3e..5265869 100644 --- a/KShare.pro +++ b/KShare.pro @@ -4,9 +4,7 @@ # #------------------------------------------------- -QT += core gui network - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +QT += core gui network widgets TARGET = KShare TEMPLATE = app @@ -141,6 +139,7 @@ mac { SOURCES += $$PWD/platformspecifics/mac/macbackend.cpp HEADERS += $$PWD/platformspecifics/mac/macbackend.hpp LIBS += -framework Carbon + QMAKE_INFO_PLIST = $$PWD/packages/macos/Info.plist warning(Mac is on TODO); } else:win32 { RC_FILE = $$PWD/icon.rc @@ -178,7 +177,12 @@ DISTFILES += \ RESOURCES += \ icon.qrc -# Enable debug symbols -QMAKE_CFLAGS_DEBUG += -g +CONFIG += debug_and_release + +CONFIG(debug, debug|release) { + TARGET = debug_binary +} else { + TARGET = release_binary +} include(QHotkey/qhotkey.pri) diff --git a/install.sh b/install.sh index 657aba4..d0ab4cd 100755 --- a/install.sh +++ b/install.sh @@ -10,14 +10,15 @@ resultfile="" if [[ "$uname" = "Darwin" ]]; then export PATH="/usr/local/opt/qt/bin:$PATH" +command -v brew >/dev/null || { echo "Homebrew is required!"; exit } installIfNeeded qt installIfNeeded ffmpeg installIfNeeded pkg-config installIfNeeded git resultfile="$(pwd)/KShare/build/KShare.app/" elif [[ "$uname" = "Linux" ]]; then -echo "Please install Qt5 SDK, qmake, ffmpeg development files, git, and pkgconfig" -bash +echo "Please install Qt5 GUI, Widgets, Networking, and X11 Extras, qmake, ffmpeg development files, git, and pkgconfig" +sh resultfile="$(pwd)/KShare/build/KShare" else echo "Unsupported OS!" && exit 1; fi diff --git a/packages/macos/Info.plist b/packages/macos/Info.plist new file mode 100644 index 0000000..c23fa53 --- /dev/null +++ b/packages/macos/Info.plist @@ -0,0 +1,20 @@ + + + + + NSPrincipalClass + NSApplication + CFBundleIconFile + icon.icns + CFBundlePackageType + APPL + CFBundleGetInfoString + Created by Qt/QMake + CFBundleSignature + ???? + CFBundleExecutable + KShare + CFBundleIdentifier + com.arsenarsen.KShare + + diff --git a/settings.cpp b/settings.cpp index 86cb78d..e16c4d8 100644 --- a/settings.cpp +++ b/settings.cpp @@ -4,8 +4,6 @@ #include #include -QMutex *lock = new QMutex; - QSettings &settings::settings() { QMutexLocker l(lock); static QSettings settings(dir().absoluteFilePath("settings.ini"), QSettings::IniFormat); @@ -15,12 +13,13 @@ QSettings &settings::settings() { QDir settings::dir() { static QDir configDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); if (configDir.dirName() != "KShare") { - if (!configDir.cd("KShare")) + if (!configDir.cd("KShare")) { if (!configDir.mkdir("KShare")) { qFatal("Could not make config directory"); } else { configDir.cd("KShare"); } + } } return configDir; } From 49ddef12765c02f3be2c7f2c9a1fc993b4d77709 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 23 Jul 2017 13:34:16 +0200 Subject: [PATCH 101/293] Fix compile errors (oops) --- settings.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/settings.cpp b/settings.cpp index e16c4d8..f76c081 100644 --- a/settings.cpp +++ b/settings.cpp @@ -1,11 +1,9 @@ #include "settings.hpp" #include -#include #include QSettings &settings::settings() { - QMutexLocker l(lock); static QSettings settings(dir().absoluteFilePath("settings.ini"), QSettings::IniFormat); return settings; } From 828285373e3197edfdfbc2a956d0a7716fdb6ae7 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 23 Jul 2017 13:48:27 +0200 Subject: [PATCH 102/293] Revert changes with debug_and_release configs --- KShare.pro | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/KShare.pro b/KShare.pro index 5265869..7cec496 100644 --- a/KShare.pro +++ b/KShare.pro @@ -177,12 +177,6 @@ DISTFILES += \ RESOURCES += \ icon.qrc -CONFIG += debug_and_release - -CONFIG(debug, debug|release) { - TARGET = debug_binary -} else { - TARGET = release_binary -} +QMAKE_CFLAGS_DEBUG += -g include(QHotkey/qhotkey.pri) From 3ba317c6e29a9d2edb6ca0e65732ba5fe41c13d3 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 23 Jul 2017 16:56:28 +0200 Subject: [PATCH 103/293] Fix meta on mac --- hotkeyinputdialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hotkeyinputdialog.cpp b/hotkeyinputdialog.cpp index 8663f15..250ae13 100644 --- a/hotkeyinputdialog.cpp +++ b/hotkeyinputdialog.cpp @@ -21,7 +21,8 @@ HotkeyInputDialog::~HotkeyInputDialog() { void HotkeyInputDialog::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Shift || e->key() == Qt::Key_Control || e->key() == Qt::Key_Alt || e->key() == Qt::Key_AltGr - || e->key() == Qt::Key_Context1 || e->key() == Qt::Key_Context2 || e->key() == Qt::Key_Context3 || e->key() == Qt::Key_Context4) + || e->key() == Qt::Key_Context1 || e->key() == Qt::Key_Context2 || e->key() == Qt::Key_Context3 + || e->key() == Qt::Key_Context4 || e->key() == Qt::Key_Meta) return; if (recording) { QKeySequence seq(e->modifiers() + e->key()); From bf0bed2e2929e0f5dff825fb8757630913766dd8 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 24 Jul 2017 20:17:10 +0200 Subject: [PATCH 104/293] Start making a menu bar I need someone to draw icons or some public domains one --- cropeditor/cropscene.cpp | 69 +++++++++++++++++++++++++--------------- cropeditor/cropscene.hpp | 7 ++-- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 6f4434d..3a21568 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -3,9 +3,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -26,10 +28,12 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) _pixmap = pixmap; pen().setColor(settings::settings().value("penColor", pen().color()).value()); pen().setCosmetic(settings::settings().value("penCosmetic", pen().isCosmetic()).toBool()); - pen().setWidthF(settings::settings().value("penWidth", pen().widthF()).toFloat()); + pen().setWidthF(settings::settings().value("penWidth", pen().widthF()).toReal()); brush().setColor(settings::settings().value("brushColor", brush().color()).value()); - brush().setStyle((Qt::BrushStyle)settings::settings().value("brushStyle", (int)Qt::SolidPattern).toInt()); + brush().setStyle( + static_cast(settings::settings().value("brushStyle", static_cast(Qt::SolidPattern)).toInt())); + menu = new QMenuBar; addDrawingAction(menu, "Dot", [] { return new DotItem; }); addDrawingAction(menu, "Path", [] { return new PathItem; }); addDrawingAction(menu, "Blur", [] { return new BlurItem; }); @@ -39,31 +43,39 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) addDrawingAction(menu, "Ellipse", [] { return new EllipseItem; }); addDrawingAction(menu, "Arrow", [] { return new ArrowItem; }); - menu.addSeparator(); + menu->addSeparator(); addDrawingAction(menu, "Eraser", [] { return new EraserItem; }); - QAction *clear = menu.addAction("Clear all drawing"); + QAction *clear = menu->addAction("Clear all drawing"); connect(clear, &QAction::triggered, [&] { auto its = items(); for (auto i : its) { - if (i != rect && i != polyItem && i->zValue() != -1) removeItem(i); + if (i != polyItem && i != rect && i != cursorItem && i->zValue() != -1 && i != proxyMenu && i != hint + && i != magnifier && i != magnifierBox && i != magnifierHint && i != magnifierHintBox + && gridRectsX.contains(dynamic_cast(i)) + && gridRectsY.contains(dynamic_cast(i))) { + removeItem(i); + } } }); - QAction *reset = menu.addAction("Reset pen selection"); - connect(reset, &QAction::triggered, [&] { setDrawingSelection("None", [] { return nullptr; }); }); + QAction *reset = menu->addAction("Reset pen selection"); + connect(reset, &QAction::triggered, [this] { + menu->setActiveAction(0); + setDrawingSelection("None", [] { return nullptr; }); + }); - menu.addSeparator(); + menu->addSeparator(); QAction *settings = new QAction; settings->setText("Settings"); - menu.addSeparator(); - display = menu.addAction(drawingName); + menu->addSeparator(); + display = menu->addAction(drawingName); display->setDisabled(true); connect(settings, &QAction::triggered, [&] { hide(); BrushPenSelection(this).exec(); show(); }); - menu.addAction(settings); + menu->addAction(settings); QPolygonF cursorPoly; cursorPoly << QPoint(-10, 0) // << QPoint(10, 0) // @@ -96,7 +108,7 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) hint->setPos(5, 5); hint->setZValue(2); hint->setVisible(settings::settings().value("crophint", true).toBool()); - connect(menu.addAction("Set Font"), &QAction::triggered, this, &CropScene::fontAsk); + connect(menu->addAction("Set Font"), &QAction::triggered, this, &CropScene::fontAsk); QPolygonF poly; QRect prect = pixmap.rect(); @@ -109,6 +121,12 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) polyItem->setPen(QPen(Qt::NoPen)); polyItem->setZValue(1); addItem(polyItem); + + auto widget = addWidget(menu); + widget->setZValue(100); + widget->setPos(100, 100); + proxyMenu = widget; + QTimer::singleShot(0, [&] { auto pf = views()[0]->mapFromGlobal(QCursor::pos()); cursorPos = QPoint(pf.x(), pf.y()); @@ -145,7 +163,8 @@ void CropScene::setDrawingSelection(QString name, std::function dr QGraphicsItem *CropScene::whichItem(QPointF scenePos) { for (auto item : items()) { if (item->sceneBoundingRect().contains(scenePos)) - if (item != polyItem && item != rect && item != cursorItem && item->zValue() != -1) return item; + if (item != polyItem && item != rect && item != cursorItem && item->zValue() != -1 && item != proxyMenu) + return item; } return nullptr; } @@ -241,6 +260,8 @@ void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { } } prevButtons = buttons; + + QGraphicsScene::mouseMoveEvent(e); } void CropScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { @@ -253,6 +274,8 @@ void CropScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { } else if (settings::settings().value("quickMode", false).toBool()) done(true); prevButtons = Qt::NoButton; + + QGraphicsScene::mouseReleaseEvent(e); } void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { @@ -260,6 +283,8 @@ void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { auto item = whichItem(cursorItem->scenePos()); if (item) removeItem(item); } + + QGraphicsScene::mousePressEvent(e); } void CropScene::wheelEvent(QGraphicsSceneWheelEvent *event) { @@ -278,22 +303,16 @@ void CropScene::wheelEvent(QGraphicsSceneWheelEvent *event) { initMagnifierGrid(); updateMag(); + + QGraphicsScene::wheelEvent(event); } -void CropScene::addDrawingAction(QMenu &menu, QString name, std::function item) { - QAction *action = new QAction; - action->setText(name); - connect(action, &QAction::triggered, [this, item, name](bool) { setDrawingSelection(name, item); }); - menu.addAction(action); +void CropScene::addDrawingAction(QMenuBar *menu, QString name, std::function item) { + QAction *action = menu->addAction(name); + connect(action, &QAction::triggered, [this, &menu, action, item, name](bool) { setDrawingSelection(name, item); }); } -QPoint contextOffset(5, 5); - -void CropScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *e) { - display->setText(drawingName); - menu.exec((cursorPos + contextOffset).toPoint()); - e->accept(); -} +static QPoint contextOffset(5, 5); void CropScene::keyReleaseEvent(QKeyEvent *event) { if (((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && !drawingSelection) || event->key() == Qt::Key_Escape) diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index 2d4aa48..5fe8d49 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include class CropScene; @@ -51,13 +52,12 @@ protected: void mouseReleaseEvent(QGraphicsSceneMouseEvent *e) override; void mousePressEvent(QGraphicsSceneMouseEvent *e) override; void wheelEvent(QGraphicsSceneWheelEvent *event) override; // WHEEEEEEL - void contextMenuEvent(QGraphicsSceneContextMenuEvent *e) override; void keyReleaseEvent(QKeyEvent *e) override; private: void updateMag(); void initMagnifierGrid(); - void addDrawingAction(QMenu &menu, QString name, std::function item); + void addDrawingAction(QMenuBar *menu, QString name, std::function item); void done(bool notEsc); bool fullscreen; QPointF cursorPos; @@ -75,7 +75,8 @@ private: QFont _font; QGraphicsPolygonItem *polyItem = nullptr; DrawItem *drawingSelection = nullptr; - QMenu menu; + QMenuBar *menu = nullptr; + QGraphicsProxyWidget *proxyMenu = nullptr; QString drawingName = "None"; QAction *display; QList gridRectsX; From 52d991225cdb110d4a222ba1407c02560c075593 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 24 Jul 2017 20:19:30 +0200 Subject: [PATCH 105/293] Make the menu not visible in screenshots --- cropeditor/cropscene.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 3a21568..8dc2c93 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -380,6 +380,7 @@ void CropScene::done(bool notEsc) { hint->setVisible(false); rect->setPen(QPen(Qt::NoPen)); magnifier->setVisible(false); + proxyMenu->setVisible(false); cursorItem->setVisible(false); magnifierBox->setVisible(false); magnifierHint->setVisible(false); From e258a1c852035d505d9cb29408ce1fd77da9eb1d Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 25 Jul 2017 01:16:56 +0200 Subject: [PATCH 106/293] Use a menu bar instead of a context menu --- KShare.pro | 6 +-- cropeditor/cropscene.cpp | 60 +++++++++++++++-------- cropeditor/cropscene.hpp | 6 ++- cropeditor/drawing/dotitem.cpp | 14 ------ cropeditor/drawing/dotitem.hpp | 18 ------- icon.qrc | 13 +++++ icons/NOTICE.md | 11 +++++ icons/accept.svg | 1 + icons/arrow.svg | 1 + icons/blur.png | Bin 0 -> 77498 bytes icons/blur.svg | 87 +++++++++++++++++++++++++++++++++ icons/cancel.svg | 1 + icons/circle.svg | 1 + icons/delete.svg | 1 + icons/erase.svg | 1 + icons/fontsettings.svg | 70 ++++++++++++++++++++++++++ icons/line.svg | 63 ++++++++++++++++++++++++ icons/pencil.svg | 1 + icons/rectangle.svg | 1 + icons/settings.svg | 1 + icons/text.svg | 70 ++++++++++++++++++++++++++ 21 files changed, 368 insertions(+), 59 deletions(-) delete mode 100644 cropeditor/drawing/dotitem.cpp delete mode 100644 cropeditor/drawing/dotitem.hpp create mode 100644 icons/NOTICE.md create mode 100644 icons/accept.svg create mode 100644 icons/arrow.svg create mode 100644 icons/blur.png create mode 100644 icons/blur.svg create mode 100644 icons/cancel.svg create mode 100644 icons/circle.svg create mode 100644 icons/delete.svg create mode 100644 icons/erase.svg create mode 100644 icons/fontsettings.svg create mode 100644 icons/line.svg create mode 100644 icons/pencil.svg create mode 100644 icons/rectangle.svg create mode 100644 icons/settings.svg create mode 100644 icons/text.svg diff --git a/KShare.pro b/KShare.pro index 7cec496..ab036c9 100644 --- a/KShare.pro +++ b/KShare.pro @@ -4,12 +4,12 @@ # #------------------------------------------------- -QT += core gui network widgets +QT += core gui network widgets svg TARGET = KShare TEMPLATE = app -CONFIG += c++11 +CONFIG += c++11 thread # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked as deprecated (the exact warnings @@ -39,7 +39,6 @@ SOURCES += main.cpp\ uploaders/customuploader.cpp \ notifications.cpp \ hotkeying.cpp \ - cropeditor/drawing/dotitem.cpp \ cropeditor/settings/brushpenselection.cpp \ cropeditor/drawing/bluritem.cpp \ cropeditor/drawing/pathitem.cpp \ @@ -84,7 +83,6 @@ HEADERS += mainwindow.hpp \ notifications.hpp \ hotkeying.hpp \ cropeditor/drawing/drawitem.hpp \ - cropeditor/drawing/dotitem.hpp \ cropeditor/settings/brushpenselection.hpp \ cropeditor/drawing/bluritem.hpp \ cropeditor/drawing/pathitem.hpp \ diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 8dc2c93..bd71c72 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -34,18 +33,19 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) static_cast(settings::settings().value("brushStyle", static_cast(Qt::SolidPattern)).toInt())); menu = new QMenuBar; - addDrawingAction(menu, "Dot", [] { return new DotItem; }); - addDrawingAction(menu, "Path", [] { return new PathItem; }); - addDrawingAction(menu, "Blur", [] { return new BlurItem; }); - addDrawingAction(menu, "Straight line", [] { return new LineItem; }); - addDrawingAction(menu, "Text", [] { return new TextItem; }); - addDrawingAction(menu, "Rectangle", [] { return new RectItem; }); - addDrawingAction(menu, "Ellipse", [] { return new EllipseItem; }); - addDrawingAction(menu, "Arrow", [] { return new ArrowItem; }); + addDrawingAction(menu, "Free draw", ":/icons/pencil.svg", [] { return new PathItem; }); + addDrawingAction(menu, "Blur", ":/icons/blur.png", [] { return new BlurItem; }); + addDrawingAction(menu, "Straight line", ":/icons/line.svg", [] { return new LineItem; }); + addDrawingAction(menu, "Text", ":/icons/text.svg", [] { return new TextItem; }); + addDrawingAction(menu, "Rectangle", ":/icons/rectangle.svg", [] { return new RectItem; }); + addDrawingAction(menu, "Ellipse", ":/icons/circle.svg", [] { return new EllipseItem; }); + addDrawingAction(menu, "Arrow", ":/icons/arrow.svg", [] { return new ArrowItem; }); menu->addSeparator(); - addDrawingAction(menu, "Eraser", [] { return new EraserItem; }); - QAction *clear = menu->addAction("Clear all drawing"); + addDrawingAction(menu, "Eraser", ":/icons/erase.svg", [] { return new EraserItem; }); + QAction *clear = menu->addAction(""); + clear->setToolTip("Clear all drawing"); + clear->setIcon(QIcon(":/icons/delete.svg")); connect(clear, &QAction::triggered, [&] { auto its = items(); for (auto i : its) { @@ -66,7 +66,8 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) menu->addSeparator(); QAction *settings = new QAction; - settings->setText("Settings"); + settings->setToolTip("Settings"); + settings->setIcon(QIcon(":/icons/settings.svg")); menu->addSeparator(); display = menu->addAction(drawingName); display->setDisabled(true); @@ -75,7 +76,25 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) BrushPenSelection(this).exec(); show(); }); + + QAction *font = menu->addAction(""); + font->setIcon(QIcon(":/icons/fontsettings.svg")); + connect(font, &QAction::triggered, this, &CropScene::fontAsk); + menu->addAction(settings); + menu->addSeparator(); + QAction *confirm = menu->addAction(""); + confirm->setToolTip("Confirm"); + confirm->setIcon(QIcon(":/icons/accept.svg")); + connect(confirm, &QAction::triggered, [this] { done(true); }); + menu->addAction(confirm); + + QAction *cancel = menu->addAction(""); + cancel->setToolTip("Cancel"); + cancel->setIcon(QIcon(":/icons/cancel.svg")); + connect(cancel, &QAction::triggered, [this] { done(false); }); + menu->addAction(cancel); + QPolygonF cursorPoly; cursorPoly << QPoint(-10, 0) // << QPoint(10, 0) // @@ -108,7 +127,6 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) hint->setPos(5, 5); hint->setZValue(2); hint->setVisible(settings::settings().value("crophint", true).toBool()); - connect(menu->addAction("Set Font"), &QAction::triggered, this, &CropScene::fontAsk); QPolygonF poly; QRect prect = pixmap.rect(); @@ -156,6 +174,7 @@ void CropScene::setDrawingSelection(QString name, std::function dr drawingSelectionMaker = drawAction; drawingSelection = drawAction(); drawingName = name; + display->setText(drawingName); if (drawingSelection) if (!drawingSelection->init(this)) setDrawingSelection("None", [] { return nullptr; }); } @@ -163,8 +182,7 @@ void CropScene::setDrawingSelection(QString name, std::function dr QGraphicsItem *CropScene::whichItem(QPointF scenePos) { for (auto item : items()) { if (item->sceneBoundingRect().contains(scenePos)) - if (item != polyItem && item != rect && item != cursorItem && item->zValue() != -1 && item != proxyMenu) - return item; + if (item != polyItem && item != rect && item != cursorItem && item->zValue() != -1) return item; } return nullptr; } @@ -281,7 +299,7 @@ void CropScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { if (e->modifiers() & Qt::AltModifier) { auto item = whichItem(cursorItem->scenePos()); - if (item) removeItem(item); + if (item && item != proxyMenu) removeItem(item); } QGraphicsScene::mousePressEvent(e); @@ -307,13 +325,13 @@ void CropScene::wheelEvent(QGraphicsSceneWheelEvent *event) { QGraphicsScene::wheelEvent(event); } -void CropScene::addDrawingAction(QMenuBar *menu, QString name, std::function item) { - QAction *action = menu->addAction(name); - connect(action, &QAction::triggered, [this, &menu, action, item, name](bool) { setDrawingSelection(name, item); }); +void CropScene::addDrawingAction(QMenuBar *menu, QString name, QString icon, std::function item) { + QAction *action = menu->addAction(""); + action->setToolTip(name); + action->setIcon(QIcon(icon)); + connect(action, &QAction::triggered, [this, menu, action, item, name](bool) { setDrawingSelection(name, item); }); } -static QPoint contextOffset(5, 5); - void CropScene::keyReleaseEvent(QKeyEvent *event) { if (((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && !drawingSelection) || event->key() == Qt::Key_Escape) done(event->key() != Qt::Key_Escape); diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index 5fe8d49..07b79f8 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -54,11 +54,13 @@ protected: void wheelEvent(QGraphicsSceneWheelEvent *event) override; // WHEEEEEEL void keyReleaseEvent(QKeyEvent *e) override; +private slots: + void done(bool notEsc = true); + private: void updateMag(); void initMagnifierGrid(); - void addDrawingAction(QMenuBar *menu, QString name, std::function item); - void done(bool notEsc); + void addDrawingAction(QMenuBar *menu, QString name, QString icon, std::function item); bool fullscreen; QPointF cursorPos; std::function drawingSelectionMaker; diff --git a/cropeditor/drawing/dotitem.cpp b/cropeditor/drawing/dotitem.cpp deleted file mode 100644 index 8eaea94..0000000 --- a/cropeditor/drawing/dotitem.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "dotitem.hpp" - -DotItem::DotItem() { -} - -DotItem::~DotItem() { -} - -void DotItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { - scene->addEllipse(e->pos().x() - 1.5, e->pos().y() - 1.5, 3, 3, scene->pen(), scene->brush())->setPos(scene->cursorPosition()); -} - -void DotItem::mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) { -} diff --git a/cropeditor/drawing/dotitem.hpp b/cropeditor/drawing/dotitem.hpp deleted file mode 100644 index 232f284..0000000 --- a/cropeditor/drawing/dotitem.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef DOTITEM_HPP -#define DOTITEM_HPP - -#include "../cropscene.hpp" -#include "drawitem.hpp" - -class DotItem : public DrawItem { -public: - DotItem(); - ~DotItem(); - QString name() { - return "Dots (drag to add)"; - } - void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene); - void mouseDragEndEvent(QGraphicsSceneMouseEvent *e, CropScene *scene); -}; - -#endif // DOTITEM_HPP diff --git a/icon.qrc b/icon.qrc index 4feaf3f..ee9e8d0 100644 --- a/icon.qrc +++ b/icon.qrc @@ -3,5 +3,18 @@ icons/icon.png icons/icon.svg icons/icon.ico + icons/pencil.svg + icons/rectangle.svg + icons/line.svg + icons/text.svg + icons/delete.svg + icons/arrow.svg + icons/circle.svg + icons/settings.svg + icons/fontsettings.svg + icons/erase.svg + icons/blur.png + icons/accept.svg + icons/cancel.svg diff --git a/icons/NOTICE.md b/icons/NOTICE.md new file mode 100644 index 0000000..5556507 --- /dev/null +++ b/icons/NOTICE.md @@ -0,0 +1,11 @@ +The following icons are from [iconmonstr](https://iconmonstr.com/): + +* [pencil.svg](https://iconmonstr.com/pencil-9/) +* [rectangle.svg](https://iconmonstr.com/square-4/) +* [circle.svg](https://iconmonstr.com/circle-2/) +* [arrow.svg](https://iconmonstr.com/arrow-19/) +* [delete.svg](https://iconmonstr.com/x-mark-12/) +* [settings.svg](https://iconmonstr.com/gear-1/) +* [erase.svg](https://iconmonstr.com/x-mark-4/) +* [accept.svg](https://iconmonstr.com/checkbox-21/) +* [cancel.svg](https://iconmonstr.com/x-mark-8/) diff --git a/icons/accept.svg b/icons/accept.svg new file mode 100644 index 0000000..b209b7b --- /dev/null +++ b/icons/accept.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/arrow.svg b/icons/arrow.svg new file mode 100644 index 0000000..3c73d35 --- /dev/null +++ b/icons/arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/blur.png b/icons/blur.png new file mode 100644 index 0000000000000000000000000000000000000000..d0daf57460649d9353a7a20847d4cbde8c8dcb59 GIT binary patch literal 77498 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 + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/icons/cancel.svg b/icons/cancel.svg new file mode 100644 index 0000000..8a69429 --- /dev/null +++ b/icons/cancel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/circle.svg b/icons/circle.svg new file mode 100644 index 0000000..8868ede --- /dev/null +++ b/icons/circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/delete.svg b/icons/delete.svg new file mode 100644 index 0000000..dd335ca --- /dev/null +++ b/icons/delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/erase.svg b/icons/erase.svg new file mode 100644 index 0000000..8cc0a22 --- /dev/null +++ b/icons/erase.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/fontsettings.svg b/icons/fontsettings.svg new file mode 100644 index 0000000..bb9e5e4 --- /dev/null +++ b/icons/fontsettings.svg @@ -0,0 +1,70 @@ + + + + + + + + + + image/svg+xml + + + + + + + F + + diff --git a/icons/line.svg b/icons/line.svg new file mode 100644 index 0000000..f40ea3b --- /dev/null +++ b/icons/line.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/pencil.svg b/icons/pencil.svg new file mode 100644 index 0000000..e9c292c --- /dev/null +++ b/icons/pencil.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/rectangle.svg b/icons/rectangle.svg new file mode 100644 index 0000000..2e739ff --- /dev/null +++ b/icons/rectangle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/settings.svg b/icons/settings.svg new file mode 100644 index 0000000..9a64fbd --- /dev/null +++ b/icons/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/text.svg b/icons/text.svg new file mode 100644 index 0000000..91db3b5 --- /dev/null +++ b/icons/text.svg @@ -0,0 +1,70 @@ + + + + + + + + + + image/svg+xml + + + + + + + A + + From 91b8831e16a2be13b8a24bd7b2eabbc120916a6d Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 25 Jul 2017 01:33:01 +0200 Subject: [PATCH 107/293] Make the toolbar position better --- cropeditor/cropscene.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index bd71c72..c63de90 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -1,4 +1,5 @@ #include "cropscene.hpp" +#include #include #include #include @@ -8,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -145,11 +147,13 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) widget->setPos(100, 100); proxyMenu = widget; - QTimer::singleShot(0, [&] { + QTimer::singleShot(0, [&, widget] { auto pf = views()[0]->mapFromGlobal(QCursor::pos()); cursorPos = QPoint(pf.x(), pf.y()); cursorItem->setPos(cursorPos); updateMag(); + int w = QApplication::primaryScreen()->geometry().width(); + widget->setPos((w - widget->boundingRect().width()) / 2, 100); }); } From 95234a6d2e1901e2af12be6da8406d369e7f755d Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 25 Jul 2017 01:39:43 +0200 Subject: [PATCH 108/293] Update hint --- cropeditor/cropscene.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index 07b79f8..4d8c9f2 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -87,11 +87,11 @@ private: QGraphicsPixmapItem *hint = new QGraphicsPixmapItem(screenshotutil::renderText( // "Press F1 to toggle this hint\n" "\tHold Shift to slow the cursor down\n" - "\tCtrl+Drag a drawing to move it around\n" + "\tCtrl+Drag a thing to move it around\n" "\tAlt+Click a drawing to remove it\n" "\tPress Return/Enter to finish\n" "\tPress ESC to cancel\n" - "\tRight-click to get a drawing menu\n" + "\tUse the menu bar to draw\n" "\tNOTE: You must select 'Reset pen selection' before closing the editor\n" "\tIf you do not it will not close.", 5, From 309b2af8238317142a3ca418e4fde8b8f8a155c7 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 25 Jul 2017 01:46:06 +0200 Subject: [PATCH 109/293] Package fixes --- packages/arch/KShare/PKGBUILD.sample | 2 +- packages/arch/Stable-KShare/PKGBUILD.sample | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/arch/KShare/PKGBUILD.sample b/packages/arch/KShare/PKGBUILD.sample index 0ce5932..22aeeea 100644 --- a/packages/arch/KShare/PKGBUILD.sample +++ b/packages/arch/KShare/PKGBUILD.sample @@ -3,7 +3,7 @@ pkgname=kshare-git pkgver=;COMMIT; pkgrel=1 conflicts=("kshare") -pkgdesc="A ShareX inspired cross platform utility written with Qt." +pkgdesc="The free and open source and cross platform screen sharing software." arch=('i686' 'x86_64') url="https://github.com/ArsenArsen/KShare" license=('MIT') diff --git a/packages/arch/Stable-KShare/PKGBUILD.sample b/packages/arch/Stable-KShare/PKGBUILD.sample index c8814fb..b3856a0 100644 --- a/packages/arch/Stable-KShare/PKGBUILD.sample +++ b/packages/arch/Stable-KShare/PKGBUILD.sample @@ -3,7 +3,7 @@ pkgname=kshare pkgver=;VER; pkgrel=1 conflicts=("kshare-git") -pkgdesc="A ShareX inspired cross platform utility written with Qt." +pkgdesc="The free and open source and cross platform screen sharing software." arch=('i686' 'x86_64') url="https://github.com/ArsenArsen/KShare" license=('MIT') From 0ff1bdd5b5efdeb029bf2998bc1397c9d69d9c3e Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Jul 2017 19:46:34 -0400 Subject: [PATCH 110/293] Fix grammar error --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b2541f..f2da436 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ See the [projects](https://github.com/ArsenArsen/KShare/projects) |Arch Linux |[kshare](https://aur.archlinux.org/packages/kshare/)| |Ubuntu/Debian |[.deb](https://nativeci.arsenarsen.com/job/KShare%20Stable/lastSuccessfulBuild/artifact/packages/simpleName.deb )| -I do plan to make a Debian packages. +I do plan to make a Debian package. For other UNIX-like platforms, and MSYS2 (for Windows): From 18d36be37a6be5adbfe76bf5675b8d70b74ad9d8 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Jul 2017 19:51:31 -0400 Subject: [PATCH 111/293] Remove line because there is a Debian package --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index f2da436..a470859 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,6 @@ See the [projects](https://github.com/ArsenArsen/KShare/projects) |Arch Linux |[kshare](https://aur.archlinux.org/packages/kshare/)| |Ubuntu/Debian |[.deb](https://nativeci.arsenarsen.com/job/KShare%20Stable/lastSuccessfulBuild/artifact/packages/simpleName.deb )| -I do plan to make a Debian package. - For other UNIX-like platforms, and MSYS2 (for Windows): You have to obtain the dependencies though. From 687c37845673a927774c02742944f64282544f6f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 25 Jul 2017 10:13:39 +0200 Subject: [PATCH 112/293] Add more icons --- cropeditor/cropscene.cpp | 42 ++++++++++------------ icon.qrc | 3 +- icons/blur.png | Bin 77498 -> 60117 bytes icons/blur.svg | 44 ++++++++++------------- icons/crop.svg | 76 +++++++++++++++++++++++++++++++++++++++ mainwindow.cpp | 1 + mainwindow.ui | 3 ++ 7 files changed, 119 insertions(+), 50 deletions(-) create mode 100644 icons/crop.svg diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index c63de90..63a0c32 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -60,42 +60,38 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) } }); - QAction *reset = menu->addAction("Reset pen selection"); - connect(reset, &QAction::triggered, [this] { - menu->setActiveAction(0); - setDrawingSelection("None", [] { return nullptr; }); - }); + addDrawingAction(menu, "Crop", ":/icons/crop.svg", [] { return nullptr; }); menu->addSeparator(); - QAction *settings = new QAction; - settings->setToolTip("Settings"); - settings->setIcon(QIcon(":/icons/settings.svg")); + QAction *action = new QAction; + action->setToolTip("Settings"); + action->setIcon(QIcon(":/icons/settings.svg")); menu->addSeparator(); display = menu->addAction(drawingName); display->setDisabled(true); - connect(settings, &QAction::triggered, [&] { + connect(action, &QAction::triggered, [&] { hide(); BrushPenSelection(this).exec(); show(); }); - QAction *font = menu->addAction(""); - font->setIcon(QIcon(":/icons/fontsettings.svg")); - connect(font, &QAction::triggered, this, &CropScene::fontAsk); + action = menu->addAction(""); + action->setIcon(QIcon(":/icons/fontsettings.svg")); + connect(action, &QAction::triggered, this, &CropScene::fontAsk); - menu->addAction(settings); + menu->addAction(action); menu->addSeparator(); - QAction *confirm = menu->addAction(""); - confirm->setToolTip("Confirm"); - confirm->setIcon(QIcon(":/icons/accept.svg")); - connect(confirm, &QAction::triggered, [this] { done(true); }); - menu->addAction(confirm); + action = menu->addAction(""); + action->setToolTip("Confirm"); + action->setIcon(QIcon(":/icons/accept.svg")); + connect(action, &QAction::triggered, [this] { done(true); }); + menu->addAction(action); - QAction *cancel = menu->addAction(""); - cancel->setToolTip("Cancel"); - cancel->setIcon(QIcon(":/icons/cancel.svg")); - connect(cancel, &QAction::triggered, [this] { done(false); }); - menu->addAction(cancel); + action = menu->addAction(""); + action->setToolTip("Cancel"); + action->setIcon(QIcon(":/icons/cancel.svg")); + connect(action, &QAction::triggered, [this] { done(false); }); + menu->addAction(action); QPolygonF cursorPoly; cursorPoly << QPoint(-10, 0) // diff --git a/icon.qrc b/icon.qrc index ee9e8d0..f19863d 100644 --- a/icon.qrc +++ b/icon.qrc @@ -9,12 +9,13 @@ icons/text.svg icons/delete.svg icons/arrow.svg - icons/circle.svg icons/settings.svg icons/fontsettings.svg icons/erase.svg icons/blur.png icons/accept.svg icons/cancel.svg + icons/crop.svg + icons/circle.svg diff --git a/icons/blur.png b/icons/blur.png index d0daf57460649d9353a7a20847d4cbde8c8dcb59..d105e5b26401a8ed4c10fa8766c602ad0f2f117f 100644 GIT binary patch literal 60117 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 literal 77498 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 + id="filter878"> + id="feGaussianBlur876" /> - + transform="translate(0,-26.066725)"> + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:21.41490173;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill;filter:url(#filter878)" + id="rect10" + width="181.7851" + height="181.7851" + x="44.574112" + y="70.640831" + ry="0" /> diff --git a/icons/crop.svg b/icons/crop.svg new file mode 100644 index 0000000..fb234b0 --- /dev/null +++ b/icons/crop.svg @@ -0,0 +1,76 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/mainwindow.cpp b/mainwindow.cpp index 7bcc344..a2522bb 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -6,6 +6,7 @@ #include "ui_mainwindow.h" #include #include +#include #include #include #include diff --git a/mainwindow.ui b/mainwindow.ui index 4c409dc..e3c21b1 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -96,6 +96,9 @@ &Quit + + Ctrl+Q + From c8de78cc56dd666dd032171a8f4dbdba86ca7cc2 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 25 Jul 2017 10:21:31 +0200 Subject: [PATCH 113/293] Fix key release event --- cropeditor/cropscene.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 63a0c32..29d8f1c 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -340,6 +340,8 @@ void CropScene::keyReleaseEvent(QKeyEvent *event) { hint->setVisible(enabled); settings::settings().setValue("crophint", enabled); } + + QGraphicsScene::keyReleaseEvent(event); } void CropScene::updateMag() { From c557d13b7f16ebbbfe0efff33632492091d33dd1 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 25 Jul 2017 10:50:57 +0200 Subject: [PATCH 114/293] Fix the settings button --- cropeditor/cropscene.cpp | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 29d8f1c..2ae0d4e 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -63,35 +63,35 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) addDrawingAction(menu, "Crop", ":/icons/crop.svg", [] { return nullptr; }); menu->addSeparator(); - QAction *action = new QAction; - action->setToolTip("Settings"); - action->setIcon(QIcon(":/icons/settings.svg")); - menu->addSeparator(); - display = menu->addAction(drawingName); - display->setDisabled(true); - connect(action, &QAction::triggered, [&] { + QAction *settings = menu->addAction(""); + settings->setToolTip("Settings"); + settings->setIcon(QIcon(":/icons/settings.svg")); + connect(settings, &QAction::triggered, [&] { hide(); BrushPenSelection(this).exec(); show(); }); - - action = menu->addAction(""); - action->setIcon(QIcon(":/icons/fontsettings.svg")); - connect(action, &QAction::triggered, this, &CropScene::fontAsk); - - menu->addAction(action); menu->addSeparator(); - action = menu->addAction(""); - action->setToolTip("Confirm"); - action->setIcon(QIcon(":/icons/accept.svg")); - connect(action, &QAction::triggered, [this] { done(true); }); - menu->addAction(action); + display = menu->addAction(drawingName); + display->setDisabled(true); - action = menu->addAction(""); - action->setToolTip("Cancel"); - action->setIcon(QIcon(":/icons/cancel.svg")); - connect(action, &QAction::triggered, [this] { done(false); }); - menu->addAction(action); + QAction *fonts = menu->addAction(""); + fonts->setIcon(QIcon(":/icons/fontsettings.svg")); + connect(fonts, &QAction::triggered, this, &CropScene::fontAsk); + + menu->addAction(fonts); + menu->addSeparator(); + QAction *confirm = menu->addAction(""); + confirm->setToolTip("Confirm"); + confirm->setIcon(QIcon(":/icons/accept.svg")); + connect(confirm, &QAction::triggered, [this] { done(true); }); + menu->addAction(confirm); + + QAction *cancel = menu->addAction(""); + cancel->setToolTip("Cancel"); + cancel->setIcon(QIcon(":/icons/cancel.svg")); + connect(cancel, &QAction::triggered, [this] { done(false); }); + menu->addAction(cancel); QPolygonF cursorPoly; cursorPoly << QPoint(-10, 0) // From 09507ec2c95fed8ed8918dc3f0fe4be179f5bf59 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 25 Jul 2017 17:26:57 +0200 Subject: [PATCH 115/293] Some fixes for movin the bar --- cropeditor/cropscene.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 2ae0d4e..73ed969 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -139,6 +139,7 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) addItem(polyItem); auto widget = addWidget(menu); + widget->setFlag(QGraphicsItem::ItemIsMovable, true); widget->setZValue(100); widget->setPos(100, 100); proxyMenu = widget; @@ -293,7 +294,7 @@ void CropScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { done(true); prevButtons = Qt::NoButton; - QGraphicsScene::mouseReleaseEvent(e); + if (!(e->modifiers() & Qt::ControlModifier)) QGraphicsScene::mouseReleaseEvent(e); } void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { @@ -302,7 +303,7 @@ void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { if (item && item != proxyMenu) removeItem(item); } - QGraphicsScene::mousePressEvent(e); + if (!(e->modifiers() & Qt::ControlModifier)) QGraphicsScene::mousePressEvent(e); } void CropScene::wheelEvent(QGraphicsSceneWheelEvent *event) { @@ -322,7 +323,7 @@ void CropScene::wheelEvent(QGraphicsSceneWheelEvent *event) { initMagnifierGrid(); updateMag(); - QGraphicsScene::wheelEvent(event); + if (!(event->modifiers() & Qt::ControlModifier)) QGraphicsScene::wheelEvent(event); } void CropScene::addDrawingAction(QMenuBar *menu, QString name, QString icon, std::function item) { @@ -341,7 +342,7 @@ void CropScene::keyReleaseEvent(QKeyEvent *event) { settings::settings().setValue("crophint", enabled); } - QGraphicsScene::keyReleaseEvent(event); + if (!(event->modifiers() & Qt::ControlModifier)) QGraphicsScene::keyReleaseEvent(event); } void CropScene::updateMag() { From b5becd43860324d87f94b848fdae146c7f73ecc3 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 26 Jul 2017 21:37:10 +0200 Subject: [PATCH 116/293] Fix ScreenAreaSelector on Windows --- screenareaselector/screenareaselector.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/screenareaselector/screenareaselector.cpp b/screenareaselector/screenareaselector.cpp index 44da6bb..e5f35b6 100644 --- a/screenareaselector/screenareaselector.cpp +++ b/screenareaselector/screenareaselector.cpp @@ -6,12 +6,15 @@ #include #include +static QString hintPattern("Set the recording region by resizing this.\n%1x%2"); + ScreenAreaSelector::ScreenAreaSelector() { setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); - setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); + setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); setStyleSheet("background-color: rgba(0, 0, 0, 0.5);"); setWindowTitle("KShare: Select Area (By resizing this window)"); + setAutoFillBackground(true); QTimer::singleShot(0, [&] { QVariant val = settings::settings().value("screenareaselector/rect"); if (val.canConvert()) { @@ -19,7 +22,7 @@ ScreenAreaSelector::ScreenAreaSelector() { resize(rect.size()); move(rect.topLeft()); } - hintLabel->setText(QString::number(width()) + "x" + QString::number(height())); + hintLabel->setText(hintPattern.arg(QString::number(width()), QString::number(height()))); show(); }); setLayout(new QStackedLayout()); @@ -43,7 +46,7 @@ void ScreenAreaSelector::keyPressEvent(QKeyEvent *event) { } void ScreenAreaSelector::resizeEvent(QResizeEvent *) { - hintLabel->setText(QString::number(width()) + "x" + QString::number(height())); + hintLabel->setText(hintPattern.arg(QString::number(width()), QString::number(height()))); } void ScreenAreaSelector::closeEvent(QCloseEvent *) { From f3627356b6a2c9d1c5af9bf50037f317d02eb129 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 26 Jul 2017 22:19:44 +0200 Subject: [PATCH 117/293] Make all icons available as PNG --- cropeditor/cropscene.cpp | 26 +++++++++++++------------- icon.qrc | 28 ++++++++++++++-------------- icons/accept.png | Bin 0 -> 507 bytes icons/arrow.png | Bin 0 -> 289 bytes icons/blur.png | Bin 60117 -> 65021 bytes icons/cancel.png | Bin 0 -> 565 bytes icons/circle.png | Bin 0 -> 535 bytes icons/crop.png | Bin 0 -> 7791 bytes icons/delete.png | Bin 0 -> 347 bytes icons/erase.png | Bin 0 -> 540 bytes icons/fontsettings.png | Bin 0 -> 6550 bytes icons/icon.png | Bin 18799 -> 22874 bytes icons/line.png | Bin 0 -> 11850 bytes icons/pencil.png | Bin 0 -> 424 bytes icons/rectangle.png | Bin 0 -> 188 bytes icons/settings.png | Bin 0 -> 451 bytes icons/text.png | Bin 0 -> 25770 bytes 17 files changed, 27 insertions(+), 27 deletions(-) create mode 100644 icons/accept.png create mode 100644 icons/arrow.png create mode 100644 icons/cancel.png create mode 100644 icons/circle.png create mode 100644 icons/crop.png create mode 100644 icons/delete.png create mode 100644 icons/erase.png create mode 100644 icons/fontsettings.png create mode 100644 icons/line.png create mode 100644 icons/pencil.png create mode 100644 icons/rectangle.png create mode 100644 icons/settings.png create mode 100644 icons/text.png diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 73ed969..49e5084 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -35,19 +35,19 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) static_cast(settings::settings().value("brushStyle", static_cast(Qt::SolidPattern)).toInt())); menu = new QMenuBar; - addDrawingAction(menu, "Free draw", ":/icons/pencil.svg", [] { return new PathItem; }); + addDrawingAction(menu, "Free draw", ":/icons/pencil.png", [] { return new PathItem; }); addDrawingAction(menu, "Blur", ":/icons/blur.png", [] { return new BlurItem; }); - addDrawingAction(menu, "Straight line", ":/icons/line.svg", [] { return new LineItem; }); - addDrawingAction(menu, "Text", ":/icons/text.svg", [] { return new TextItem; }); - addDrawingAction(menu, "Rectangle", ":/icons/rectangle.svg", [] { return new RectItem; }); - addDrawingAction(menu, "Ellipse", ":/icons/circle.svg", [] { return new EllipseItem; }); - addDrawingAction(menu, "Arrow", ":/icons/arrow.svg", [] { return new ArrowItem; }); + addDrawingAction(menu, "Straight line", ":/icons/line.png", [] { return new LineItem; }); + addDrawingAction(menu, "Text", ":/icons/text.png", [] { return new TextItem; }); + addDrawingAction(menu, "Rectangle", ":/icons/rectangle.png", [] { return new RectItem; }); + addDrawingAction(menu, "Ellipse", ":/icons/circle.png", [] { return new EllipseItem; }); + addDrawingAction(menu, "Arrow", ":/icons/arrow.png", [] { return new ArrowItem; }); menu->addSeparator(); - addDrawingAction(menu, "Eraser", ":/icons/erase.svg", [] { return new EraserItem; }); + addDrawingAction(menu, "Eraser", ":/icons/erase.png", [] { return new EraserItem; }); QAction *clear = menu->addAction(""); clear->setToolTip("Clear all drawing"); - clear->setIcon(QIcon(":/icons/delete.svg")); + clear->setIcon(QIcon(":/icons/delete.png")); connect(clear, &QAction::triggered, [&] { auto its = items(); for (auto i : its) { @@ -60,12 +60,12 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) } }); - addDrawingAction(menu, "Crop", ":/icons/crop.svg", [] { return nullptr; }); + addDrawingAction(menu, "Crop", ":/icons/crop.png", [] { return nullptr; }); menu->addSeparator(); QAction *settings = menu->addAction(""); settings->setToolTip("Settings"); - settings->setIcon(QIcon(":/icons/settings.svg")); + settings->setIcon(QIcon(":/icons/settings.png")); connect(settings, &QAction::triggered, [&] { hide(); BrushPenSelection(this).exec(); @@ -76,20 +76,20 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) display->setDisabled(true); QAction *fonts = menu->addAction(""); - fonts->setIcon(QIcon(":/icons/fontsettings.svg")); + fonts->setIcon(QIcon(":/icons/fontsettings.png")); connect(fonts, &QAction::triggered, this, &CropScene::fontAsk); menu->addAction(fonts); menu->addSeparator(); QAction *confirm = menu->addAction(""); confirm->setToolTip("Confirm"); - confirm->setIcon(QIcon(":/icons/accept.svg")); + confirm->setIcon(QIcon(":/icons/accept.png")); connect(confirm, &QAction::triggered, [this] { done(true); }); menu->addAction(confirm); QAction *cancel = menu->addAction(""); cancel->setToolTip("Cancel"); - cancel->setIcon(QIcon(":/icons/cancel.svg")); + cancel->setIcon(QIcon(":/icons/cancel.png")); connect(cancel, &QAction::triggered, [this] { done(false); }); menu->addAction(cancel); diff --git a/icon.qrc b/icon.qrc index f19863d..3c1d69c 100644 --- a/icon.qrc +++ b/icon.qrc @@ -1,21 +1,21 @@ - icons/icon.png icons/icon.svg + icons/icon.png icons/icon.ico - icons/pencil.svg - icons/rectangle.svg - icons/line.svg - icons/text.svg - icons/delete.svg - icons/arrow.svg - icons/settings.svg - icons/fontsettings.svg - icons/erase.svg + icons/pencil.png + icons/rectangle.png + icons/line.png + icons/text.png + icons/delete.png + icons/arrow.png + icons/settings.png + icons/fontsettings.png + icons/erase.png icons/blur.png - icons/accept.svg - icons/cancel.svg - icons/crop.svg - icons/circle.svg + icons/accept.png + icons/cancel.png + icons/crop.png + icons/circle.png diff --git a/icons/accept.png b/icons/accept.png new file mode 100644 index 0000000000000000000000000000000000000000..13edeba282ac6142f70a5e46eb2c4e2aaee0fcad GIT binary patch literal 507 zcmVE^2#-y9$@nx;T`+jflrECErV86V-%0@E#?1$kpTY~k?94TW;EPL zCLbPRCuCF)z7LV5{K?=+zQIBO)&SoyrVJ6F>o0f x^|p+flN?rgYU(~)p1S*N`7PN<`{6rN{{h>zoqO@+&M^Q0002ovPDHLkV1j+l;O+nb literal 0 HcmV?d00001 diff --git a/icons/arrow.png b/icons/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..8407380c52df514e3c4e7320247f1bb68f1c5b43 GIT binary patch literal 289 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

3TBzk9y)C{dE%q=c!M0+2wz&@(3wUdxR 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

t7#6eEPu!tZIrfwXVqjYy>+CY~7vH_1 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 diff --git a/icons/cancel.png b/icons/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..22887391ce09e09b6f7aa335bcf5ec19ea6a99b0 GIT binary patch literal 565 zcmV-50?Pe~P)j315c0W$tertsC~>XKCnQ0sHzWa5c!S;!0WAB)&%s zU$Hp@emas{#SNHE7~Wze0pG9KZBza+7{$AU=^0i>;M>togK13GM zILW(et6IR>9t#@7^IDM^k?!1rFM;VJcK3i+8dA(dSfuN_K7u#F!&z*|goiqU9|7lN z_28PtBRP-d1Hdbd<8{fK$5vQ}`x3t!eQFrDa1pKlF9q$mu+ literal 0 HcmV?d00001 diff --git a/icons/circle.png b/icons/circle.png new file mode 100644 index 0000000000000000000000000000000000000000..460a0b7a9c0d9af1853ee47714906efaef6865d9 GIT binary patch literal 535 zcmV+y0_gpTP)ojfLD4O%m)S5V(@*31}fGXdv8DxfqO;zifr_;Q7v+n#+5vnhU9_Ka{qR!y>sx1p_oM<; zO7-NgmZbz$N(pOGJq^YlE*za4%jx!ijr8!Ow*U5N3peG0vn?gACJm+3P!*hwrVV2` zTr(+g-NQBMhW2qC_hW7*hvilahroF}lTJdLqW{_nF(<`to(A%><+6XDEmP^7e~kW# Z`U4VMd%Q(1D{lY*002ovPDHLkV1h_e-c|qr literal 0 HcmV?d00001 diff --git a/icons/crop.png b/icons/crop.png new file mode 100644 index 0000000000000000000000000000000000000000..9a08c6133546e205d2db3df62f670846338a8d70 GIT binary patch literal 7791 zcmeHM4Ny~87CtYA8j3Uor3%QuKrJ-d$qERhK@D1#7I(I-V#NYlk~;M#HPplKju){1JP)VtjsU2d}^nvQdhpK0(3f^bnA{6wOh(H71Eu% z)Q$hhjRJ^q6ew3bt#5K%mLJ^I_cD8BnIt0h(aj6qt+37WFpCG@Hu>6b%yRU;^{aV* z{f;^PQl9wGF>R7gAwea1b_b&XRqt!hpU(tL-+}(9+z}WSzZXtl} zd7s7&O;@dIv8m&rH5QYyy(MH*n6jReZL?9+FJ@W_pg0Ld7?422m(6l+m@Ky}N09eM z2)j&xvMFXVNI1!SEi!Kc4yLm~{{o&nt9><^;g3o1la9M$O?Go91vG!H8Xj>Z;FRZ9 z!V9-t7DHB5?E!g@WsO?Q064=1d3|V9Y&o$t(&{NpOvu_@Ozgen1+ALS4uF` zQV7M@NI?*qCo>pz9LsPfH#-jt(-(+0!#R=8*| zxKSg3KVTV+8&PJri(tFItoOos_nq1w2!lWSYkvwTWuo>c%#>vU_p>|&KI~^XlxgYl zvy8E(xS_|7H}fnb{7HYkOo97Z{$EMbb>R}ZNpcUT58Q5>-QR>53ex)Tj>(`Yq4>LFdY_H{yCXx$X87-pAEtI!#{Aup zF&?bKP{Rt<@aapd05p-!Jr=8KxKAw>41G0%7w1i@%(XV8bm(ed`?#B4X0dk+4q% z6X{@*Kts>5?e|J3B2Na$Ju2c((?NR}qko8$pDi~L#MEt5q0p8X*(3VfrsIG(DMq)B$N?0{1FmR^|oLzMAqZLA14)w7U zy?qo;M!$Se!tPu|q)vGv7}pR<->3xdULrYn*MXsc+6I)MQVnlaJ=P>A&U9m!EaP7} z60#1G(etB~`1n6ZXUFFe3kxJg5D+Yg$b|zlY=G6N#n5ifY>wsOQ^s=db<#}9+ZVIc@_*Gq0EV^pl6NI~k?-$uso-puxrXSghrut@GFMyM zK3mCJwU|p@D07XJo|=u_n))U6zS3s7$Q};ge)4D{&h1=QZ|q(K&S%cmqUKyz?Da$o zpj7u7X(^p-8+Yl1(ES;OI{tLSnu!xLDAW{fRt)_VY$q2cVb6(^ruz)34Ewc~PF%0{ z*sFpe_Z*#Aa_D+9Hk0(NTa@UuJ<6=Grr_%l>P8b$Z+uRPuX}zi!9Im;8){F0Z5gkn zqm~c06TEgI-PhRw+Ww>Af^8i??P9ub@HOBb z;gKH{dpj00?8cncSflJSh%Ca+ACEkN$X9{u;#X9-!P^nduvOUs7`#b#jBl?B*ZW2I)rJ7JJz zrX0!ZjYUbId7CaSJKfiWbGA``oz*y$3Ys8Z+f;9qt^nJ^)Std8-B+>~xI;8$=Wblw zJcd2CoTOZ4MC2N8o<59WB*VHtqz(4nJ z@ErkR#;MwT(m+AU64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1TUc)B=- zcyzwKvfq!%QJ~>t`~t--DqoJZJ$l1o8WH(o_XnAMoJ-FqxN@@|YYDUUQl8ssR(P_DHGcEmlpRxK`k$BE)`|mvZ9MPm`CnWk`dB=h1LyzoPY;9bH!X+Lr z6}kODs@uwuz29`Mk5gWo%^IB}YKD&7o7tju#n05)J~ur0m+$kP2dhl3F~%jo-*Tve zZ{eqP;#)pmSnzwVJ4@`DY?f;IB1iex9*>Mfw903<-`Ld2pqIU^`a*k{!J%(6n08El nk$!!hfX!oB^HAA2p2y6uH8D?hSLvV literal 0 HcmV?d00001 diff --git a/icons/erase.png b/icons/erase.png new file mode 100644 index 0000000000000000000000000000000000000000..010b805c00705f750e8b9e80c4275c1fff0bb8f5 GIT binary patch literal 540 zcmV+%0^|LOP)E0>~w>>qV#8u{+Zi_>)Q6o;m;d=kJ+mJL<87r+AEq=!fTj@EgbY zg3|_`87yK8mzXq+D;x#^t?&%zEr_e*FIJn#Uk63kC68A#tW$m)^0>&%O8PgnrOvMV zae{p6x*W{nTt4#1476MU6ak`eV&r#tH zHZvS+@IZQ_4I-8AGS-zv28sBE>G#9i#Dpu_eNy;(%&uySC#D_f+sG zW7T!X6`oYdOAOuqgR`C^FR^+N+9-0000N&PEETM%dHE zF{EP7o7)?ELjna{56aEpnKpx?NoE5_1CIw|w~hyc{B#zB14kHj?(6Yzika<8g? zrt?ad%wq&vK}TS*@ANl@9hEa?hTm3ZV3;@az47PbYL)_?>u(tgK9{B4%kO7ks7Ska z_DuU*!2^bSZpeY$_NSf+M6qyyNC5>9>CgZo85l<;fT1uNB=k-UG27W0Y!3FnWn?HQ z*uRaP;kY6LL;Bb1G`Vf=3=9V%EkL=dfdQPim_YfSfkOa9DmZ}1QHjwY8BGkM*6w~aa*PhAjteq02p5Cf zVWX`vP=X$9je$a8P&Ca!&9pl&3)Ad?-3o=LufH)gEEiyC*!;`bc>VU#hT3RLlwq_A z24&UJDtItg!K0m}(Ih(BSsE>=M@#C_1`Ev^EDtu>GUVw!w*Qnbm(LGMX@eO&$geJN l0QEQ(Ui^Pu#-fGIt?7(8A0+HG8w|lS2%fHfF6*2UngGlUaUlQz literal 0 HcmV?d00001 diff --git a/icons/icon.png b/icons/icon.png index cc3b7fb74832fc0e87a1e5112d35f851fa2c6f19..8667c3f4d9c261abbd56ad4747c74d6c3a1149a3 100644 GIT binary patch literal 22874 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 V|AqH1soE2oyXrc(%T%qy{x8>UDnS4M diff --git a/icons/line.png b/icons/line.png new file mode 100644 index 0000000000000000000000000000000000000000..f77ffc826975e3fa87eef554d2081f4b8a430b8a GIT binary patch literal 11850 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 literal 0 HcmV?d00001 diff --git a/icons/pencil.png b/icons/pencil.png new file mode 100644 index 0000000000000000000000000000000000000000..6d13c2af7a4d155ea238c863ecafb2a1c9f9a6c8 GIT binary patch literal 424 zcmV;Z0ayNsP)d-n4GW@gVE(r5{1s3zilg1=yZ>(nN7^a7s6 zCFW8Y%;MsM!2mZ3R?@&$Tvr45(d5dMl{5_7(#OU(Ca2TF2iV69YGX`#SS|vupo#Vu zCcSunD)?Rw-oZ*#l5bZ%CA<<9^^Jb~kCh*y!^m{muq~?r-;L+5Vf_E#2Y&_c{5E_o z;H?z!Y>1M<7mc=J%loa^^u8?<4-p*2$Gc_Xuf2PL(EW~;}CA=1ZF3P$4W$c); z=Xq@gBicp5nce_`<&NyZ SO0$~)00004nJ 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 literal 0 HcmV?d00001 From 097b6991dadce2cf856831d8db9014310b36006b Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 26 Jul 2017 23:29:26 +0200 Subject: [PATCH 118/293] Make the tool bar always visible on all screens --- cropeditor/cropscene.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 49e5084..fcee0b8 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -149,8 +149,9 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) cursorPos = QPoint(pf.x(), pf.y()); cursorItem->setPos(cursorPos); updateMag(); - int w = QApplication::primaryScreen()->geometry().width(); - widget->setPos((w - widget->boundingRect().width()) / 2, 100); + auto screen = QApplication::primaryScreen(); + int w = screen->geometry().width(); + widget->setPos((w - widget->boundingRect().width()) / 2, screen->geometry().top() + 100); }); } From eb802a28761c66f57ccd56248d05070b8dbc24b4 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 27 Jul 2017 12:49:29 +0200 Subject: [PATCH 119/293] Fix coordinates in crop scene --- cropeditor/cropscene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index fcee0b8..24a8743 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -151,7 +151,7 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) updateMag(); auto screen = QApplication::primaryScreen(); int w = screen->geometry().width(); - widget->setPos((w - widget->boundingRect().width()) / 2, screen->geometry().top() + 100); + widget->setPos(views()[0]->mapToScene(QPoint((w - widget->boundingRect().width()) / 2, screen->geometry().y() + 100))); }); } From 58d2e357575312316a3c7506936ef244b32fd738 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 27 Jul 2017 16:36:15 +0200 Subject: [PATCH 120/293] Add qt5 svg to dependencies --- packages/arch/KShare/PKGBUILD.sample | 2 +- packages/arch/Stable-KShare/PKGBUILD.sample | 2 +- packages/deb/DEBIAN/control | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/arch/KShare/PKGBUILD.sample b/packages/arch/KShare/PKGBUILD.sample index 22aeeea..fe835d9 100644 --- a/packages/arch/KShare/PKGBUILD.sample +++ b/packages/arch/KShare/PKGBUILD.sample @@ -8,7 +8,7 @@ arch=('i686' 'x86_64') url="https://github.com/ArsenArsen/KShare" license=('MIT') provides=('kshare=$pkgver') -depends=(qt5-base qt5-x11extras xcb-util-cursor ffmpeg libxfixes) +depends=(qt5-base qt5-svg qt5-x11extras xcb-util-cursor ffmpeg libxfixes) source=(git+https://github.com/ArsenArsen/KShare.git) sha1sums=('SKIP') diff --git a/packages/arch/Stable-KShare/PKGBUILD.sample b/packages/arch/Stable-KShare/PKGBUILD.sample index b3856a0..48829e6 100644 --- a/packages/arch/Stable-KShare/PKGBUILD.sample +++ b/packages/arch/Stable-KShare/PKGBUILD.sample @@ -8,7 +8,7 @@ arch=('i686' 'x86_64') url="https://github.com/ArsenArsen/KShare" license=('MIT') provides=('kshare=$pkgver') -depends=(qt5-base qt5-x11extras xcb-util-cursor ffmpeg libxfixes) +depends=(qt5-base qt5-svg qt5-x11extras xcb-util-cursor ffmpeg libxfixes) source=(git+https://github.com/ArsenArsen/KShare.git#tag=v${pkgver}) sha1sums=('SKIP') diff --git a/packages/deb/DEBIAN/control b/packages/deb/DEBIAN/control index db85e9b..8f711a2 100644 --- a/packages/deb/DEBIAN/control +++ b/packages/deb/DEBIAN/control @@ -4,6 +4,6 @@ Architecture: all Essential: no Section: contrib Priority: optional -Depends: qt5-default (>=5.7.0), libqt5x11extras5 (>=5.7.0), libavcodec57 (>=3.2.0), libavformat57 (>=3.2.0), libswscale4 (>=3.2.0), libavutil55 (>=3.2.0), libxcb-cursor0 (>=0.1.0), libxcb1 (>=1.11.0), libxcb-xfixes0 (>=1.11.0) +Depends: qt5-default (>=5.7.0), libqt5svg5-dev (>=5.7.0), libqt5x11extras5 (>=5.7.0), libavcodec57 (>=3.2.0), libavformat57 (>=3.2.0), libswscale4 (>=3.2.0), libavutil55 (>=3.2.0), libxcb-cursor0 (>=0.1.0), libxcb1 (>=1.11.0), libxcb-xfixes0 (>=1.11.0) Maintainer: ArsenArsen Description: The free open source and cross platform screen sharing software From e0ee91d4a38d2dfecd08c784cf78d124f316a005 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 28 Jul 2017 18:39:34 +0200 Subject: [PATCH 121/293] What if this fixes that crash (#20) --- worker/worker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worker/worker.cpp b/worker/worker.cpp index 88c1e0a..3b599cf 100644 --- a/worker/worker.cpp +++ b/worker/worker.cpp @@ -20,7 +20,7 @@ void Worker::queue(WorkerContext *context) { c->consumer = context->consumer; c->targetFormat = context->targetFormat; c->underlyingThing = context; - inst->qqueue.enqueue(c); + inst->qqueue.enqueue(std::move(c)); } void Worker::init() { From 9f57a10bb8e99f45aaffda8ac421b32d12f6934a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 29 Jul 2017 17:22:17 +0200 Subject: [PATCH 122/293] Make the project translatable Jeeeesh that's alot --- colorpicker/colorpickerscene.cpp | 2 +- colorpicker/colorpickerscene.hpp | 1 + cropeditor/cropeditor.cpp | 2 +- cropeditor/cropscene.cpp | 28 +++---- cropeditor/drawing/textitem.cpp | 2 +- cropeditor/drawing/textitem.hpp | 2 + cropeditor/settings/brushpenselection.cpp | 6 +- formats.cpp | 14 ---- hotkeying.cpp | 5 +- hotkeyinputdialog.cpp | 4 +- main.cpp | 17 ++++ mainwindow.cpp | 40 +++++++--- mainwindow.hpp | 4 +- recording/encoders/encodersettingsdialog.cpp | 2 +- recording/recordingformats.cpp | 6 +- recording/recordingformats.hpp | 2 + recording/recordingpreview.cpp | 8 +- screenareaselector/screenareaselector.cpp | 4 +- settings.cpp | 2 +- settingsdialog.cpp | 16 ++-- uploaders/customuploader.cpp | 83 +++++++++++--------- uploaders/customuploader.hpp | 4 + uploaders/default/clipboarduploader.cpp | 2 +- uploaders/default/clipboarduploader.hpp | 2 + uploaders/default/imgplusuploader.cpp | 7 +- uploaders/default/imgplusuploader.hpp | 2 + uploaders/default/imgursettingsdialog.cpp | 2 +- uploaders/default/imguruploader.cpp | 8 +- uploaders/default/imguruploader.hpp | 2 + uploaders/uploadersingleton.cpp | 17 ++-- uploaders/uploadersingleton.hpp | 2 +- 31 files changed, 170 insertions(+), 128 deletions(-) diff --git a/colorpicker/colorpickerscene.cpp b/colorpicker/colorpickerscene.cpp index 773d16a..ad02c24 100644 --- a/colorpicker/colorpickerscene.cpp +++ b/colorpicker/colorpickerscene.cpp @@ -16,7 +16,7 @@ ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); setCursor(QCursor(Qt::CrossCursor)); setMouseTracking(true); - setWindowTitle("KShare Color Picker"); + setWindowTitle(tr("KShare Color Picker")); setAttribute(Qt::WA_DeleteOnClose); pItem = addPixmap(pixmap); diff --git a/colorpicker/colorpickerscene.hpp b/colorpicker/colorpickerscene.hpp index e2e9c55..76aebd8 100644 --- a/colorpicker/colorpickerscene.hpp +++ b/colorpicker/colorpickerscene.hpp @@ -11,6 +11,7 @@ #include class ColorPickerScene : public QGraphicsScene, public QGraphicsView { + Q_OBJECT public: ColorPickerScene(QPixmap pixmap, QWidget *parentWidget); void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; diff --git a/cropeditor/cropeditor.cpp b/cropeditor/cropeditor.cpp index 4f0605c..511cd49 100644 --- a/cropeditor/cropeditor.cpp +++ b/cropeditor/cropeditor.cpp @@ -24,7 +24,7 @@ CropEditor::CropEditor(QPixmap image, QObject *parent) : QObject(parent) { QPoint p = screenshotutil::smallestScreenCoordinate() + QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); view->move(p.x(), p.y()); - view->setWindowTitle("KShare Crop Editor"); + view->setWindowTitle(tr("KShare Crop Editor")); view->activateWindow(); connect(scene, &CropScene::closedWithRect, this, &CropEditor::crop); diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 24a8743..2a76ddd 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -35,18 +35,18 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) static_cast(settings::settings().value("brushStyle", static_cast(Qt::SolidPattern)).toInt())); menu = new QMenuBar; - addDrawingAction(menu, "Free draw", ":/icons/pencil.png", [] { return new PathItem; }); - addDrawingAction(menu, "Blur", ":/icons/blur.png", [] { return new BlurItem; }); - addDrawingAction(menu, "Straight line", ":/icons/line.png", [] { return new LineItem; }); - addDrawingAction(menu, "Text", ":/icons/text.png", [] { return new TextItem; }); - addDrawingAction(menu, "Rectangle", ":/icons/rectangle.png", [] { return new RectItem; }); - addDrawingAction(menu, "Ellipse", ":/icons/circle.png", [] { return new EllipseItem; }); - addDrawingAction(menu, "Arrow", ":/icons/arrow.png", [] { return new ArrowItem; }); + addDrawingAction(menu, tr("Free draw"), ":/icons/pencil.png", [] { return new PathItem; }); + addDrawingAction(menu, tr("Blur"), ":/icons/blur.png", [] { return new BlurItem; }); + addDrawingAction(menu, tr("Straight line"), ":/icons/line.png", [] { return new LineItem; }); + addDrawingAction(menu, tr("Text"), ":/icons/text.png", [] { return new TextItem; }); + addDrawingAction(menu, tr("Rectangle"), ":/icons/rectangle.png", [] { return new RectItem; }); + addDrawingAction(menu, tr("Ellipse"), ":/icons/circle.png", [] { return new EllipseItem; }); + addDrawingAction(menu, tr("Arrow"), ":/icons/arrow.png", [] { return new ArrowItem; }); menu->addSeparator(); - addDrawingAction(menu, "Eraser", ":/icons/erase.png", [] { return new EraserItem; }); + addDrawingAction(menu, tr("Eraser"), ":/icons/erase.png", [] { return new EraserItem; }); QAction *clear = menu->addAction(""); - clear->setToolTip("Clear all drawing"); + clear->setToolTip(tr("Clear all drawing")); clear->setIcon(QIcon(":/icons/delete.png")); connect(clear, &QAction::triggered, [&] { auto its = items(); @@ -60,11 +60,11 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) } }); - addDrawingAction(menu, "Crop", ":/icons/crop.png", [] { return nullptr; }); + addDrawingAction(menu, tr("Crop"), ":/icons/crop.png", [] { return nullptr; }); menu->addSeparator(); QAction *settings = menu->addAction(""); - settings->setToolTip("Settings"); + settings->setToolTip(tr("Settings")); settings->setIcon(QIcon(":/icons/settings.png")); connect(settings, &QAction::triggered, [&] { hide(); @@ -82,13 +82,13 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) menu->addAction(fonts); menu->addSeparator(); QAction *confirm = menu->addAction(""); - confirm->setToolTip("Confirm"); + confirm->setToolTip(tr("Confirm")); confirm->setIcon(QIcon(":/icons/accept.png")); connect(confirm, &QAction::triggered, [this] { done(true); }); menu->addAction(confirm); QAction *cancel = menu->addAction(""); - cancel->setToolTip("Cancel"); + cancel->setToolTip(tr("Cancel")); cancel->setIcon(QIcon(":/icons/cancel.png")); connect(cancel, &QAction::triggered, [this] { done(false); }); menu->addAction(cancel); @@ -207,7 +207,7 @@ void CropScene::setVisible(bool visible) { QPoint p = screenshotutil::smallestScreenCoordinate() + QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); view->move(p.x(), p.y()); - view->setWindowTitle("KShare Crop Editor"); + view->setWindowTitle(tr("KShare Crop Editor")); view->activateWindow(); } } diff --git a/cropeditor/drawing/textitem.cpp b/cropeditor/drawing/textitem.cpp index 8ed86f5..294b45d 100644 --- a/cropeditor/drawing/textitem.cpp +++ b/cropeditor/drawing/textitem.cpp @@ -5,7 +5,7 @@ bool TextItem::init(CropScene *s) { bool ok; s->hide(); - text = QInputDialog::getText(nullptr, "Text to add", "Input", QLineEdit::Normal, QString(), &ok); + text = QInputDialog::getText(nullptr, tr("Text to add"), tr("Input"), QLineEdit::Normal, QString(), &ok); s->show(); return ok; } diff --git a/cropeditor/drawing/textitem.hpp b/cropeditor/drawing/textitem.hpp index d60fb54..9c49bf1 100644 --- a/cropeditor/drawing/textitem.hpp +++ b/cropeditor/drawing/textitem.hpp @@ -2,9 +2,11 @@ #define TEXTITEM_HPP #include "drawitem.hpp" +#include #include class TextItem : public DrawItem { + Q_DECLARE_TR_FUNCTIONS(TextItem) public: QString name() override; bool init(CropScene *s) override; diff --git a/cropeditor/settings/brushpenselection.cpp b/cropeditor/settings/brushpenselection.cpp index f2301ed..b26a681 100644 --- a/cropeditor/settings/brushpenselection.cpp +++ b/cropeditor/settings/brushpenselection.cpp @@ -37,7 +37,7 @@ BrushPenSelection::BrushPenSelection(CropScene *scene) : QDialog(), ui(new Ui::B ui->alphaSlider->setValue(brush.alpha()); ui->alphaSpin->setValue(brush.alpha()); - setWindowTitle("Crop editor settings"); + setWindowTitle(tr("Crop editor settings")); this->scene = scene; } @@ -46,12 +46,12 @@ BrushPenSelection::~BrushPenSelection() { } void BrushPenSelection::on_penColor_clicked(bool) { - pen = QColorDialog::getColor(pen, this, "Pen Color"); + pen = QColorDialog::getColor(pen, this, tr("Pen Color")); pen.setAlpha(ui->penAlphaSpin->value()); } void BrushPenSelection::on_brushColor_clicked(bool) { - brush = QColorDialog::getColor(brush, this, "Brush Color"); + brush = QColorDialog::getColor(brush, this, tr("Brush Color")); brush.setAlpha(ui->alphaSpin->value()); } diff --git a/formats.cpp b/formats.cpp index 21a8089..5e08ad3 100644 --- a/formats.cpp +++ b/formats.cpp @@ -4,13 +4,10 @@ QString formats::normalFormatName(formats::Normal format) { switch (format) { case Normal::JPG: return "JPG"; - break; case Normal::PNG: return "PNG"; - break; default: return QString(); - break; } } @@ -25,13 +22,10 @@ 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; } } @@ -39,16 +33,12 @@ QString formats::recordingFormatName(formats::Recording format) { switch (format) { case Recording::GIF: return "GIF"; - break; case Recording::WebM: return "WEBM"; - break; case Recording::MP4: return "MP4"; - break; default: return QString(); - break; } } @@ -63,15 +53,11 @@ QString formats::recordingFormatMIME(formats::Recording format) { switch (format) { case Recording::GIF: return "image/gif"; - break; case Recording::WebM: return "video/webm"; - break; case Recording::MP4: return "video/mp4"; - break; default: return QString(); - break; } } diff --git a/hotkeying.cpp b/hotkeying.cpp index 98aeeb1..4940bb8 100644 --- a/hotkeying.cpp +++ b/hotkeying.cpp @@ -19,7 +19,7 @@ void hotkeying::hotkey(QString seqName, QKeySequence seq, std::function settings::settings().setValue(seqName.prepend("hotkey_"), seq.toString()); if (!hotkey->isRegistered() && !seq.toString().isEmpty()) qWarning().noquote().nospace() - << "Could not bind the hotkey " << seqName << "! Is the keybind already registered?"; + << QObject::tr("Could not bind the hotkey %1! Is the keybind already registered?").arg(seqName); } // forces the hotkey from settings @@ -37,7 +37,8 @@ void hotkeying::load(QString seqName, std::function func, QString def) { hotkeys.insert(seqName, h); if (!h->isRegistered() && !h->shortcut().toString().isEmpty()) qWarning().noquote().nospace() - << "Could not bind the hotkey " << seqName << "! Is the keybind already registered?"; + << QObject::tr("Could not bind the hotkey %1! Is the keybind already registered?").arg(seqName); + ; } bool hotkeying::valid(QString seq) { diff --git a/hotkeyinputdialog.cpp b/hotkeyinputdialog.cpp index 250ae13..980ec7c 100644 --- a/hotkeyinputdialog.cpp +++ b/hotkeyinputdialog.cpp @@ -28,11 +28,11 @@ void HotkeyInputDialog::keyPressEvent(QKeyEvent *e) { QKeySequence seq(e->modifiers() + e->key()); ui->keySeq->setText(seq.toString()); recording = false; - ui->recordButton->setText("Record"); + ui->recordButton->setText(tr("Record")); } } void HotkeyInputDialog::on_recordButton_clicked() { recording = !recording; - ui->recordButton->setText(recording ? "Stop recording" : "Record"); + ui->recordButton->setText(recording ? tr("Stop recording") : tr("Record")); } diff --git a/main.cpp b/main.cpp index 3c3a892..acb0275 100644 --- a/main.cpp +++ b/main.cpp @@ -13,6 +13,7 @@ extern "C" { #include } #include +#include #include #include #include @@ -59,6 +60,19 @@ void handler(QtMsgType type, const QMessageLogContext &, const QString &msg) { } } +void loadTranslation(QString locale) { + QFile resource(":/langs/kshare_" + locale + ".qm"); + if (!resource.exists()) return; + resource.open(QIODevice::ReadOnly); + + QTranslator *translator = new QTranslator; + QByteArray file = resource.readAll(); + QByteArray *permFile = new QByteArray; + permFile->swap(file); + translator->load((const unsigned char *)permFile->constData(), permFile->size()); + QApplication::installTranslator(translator); +} + int main(int argc, char *argv[]) { av_register_all(); qInstallMessageHandler(handler); @@ -68,6 +82,9 @@ int main(int argc, char *argv[]) { a.setOrganizationName("ArsenArsen"); a.setApplicationVersion("4.1"); + QString locale = QLocale::system().name(); + if (locale != "en_US") loadTranslation(locale); + QCommandLineParser parser; parser.addHelpOption(); diff --git a/mainwindow.cpp b/mainwindow.cpp index a2522bb..a23cef8 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -19,10 +19,10 @@ MainWindow *MainWindow::instance; void MainWindow::rec() { if (controller->isRunning()) return; - auto f - = static_cast(settings::settings().value("recording/format", (int)formats::Recording::None).toInt()); + auto f = static_cast( + settings::settings().value("recording/format", static_cast(formats::Recording::None)).toInt()); if (f >= formats::Recording::None) { - qWarning() << "Recording format not set in settings. Aborting."; + qWarning() << tr("Recording format not set in settings. Aborting."); return; } RecordingContext *ctx = new RecordingContext; @@ -36,6 +36,22 @@ void MainWindow::rec() { controller->start(ctx); } +#define ACTION(english, menu) \ + [&]() -> QAction * { \ + QAction *a = menu->addAction(tr(english)); \ + acts.insert(a, english); \ + return a; \ + }() + +void MainWindow::changeEvent(QEvent *e) { + if (e->type() == QEvent::LocaleChange) { + ui->retranslateUi(this); + for (auto key : acts.keys()) { + key->setText(tr(acts.value(key))); + } + } +} + void addHotkey(QString name, std::function action) { hotkeying::load(name, action); } @@ -48,19 +64,19 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi tray->setToolTip("KShare"); tray->setVisible(true); QMenu *menu = new QMenu(this); - QAction *quit = new QAction("Quit", this); - QAction *shtoggle = new QAction("Show/Hide", this); - QAction *fullscreen = new QAction("Take fullscreen shot", this); - QAction *area = new QAction("Take area shot", this); + QAction *quit = ACTION("Quit", menu); + QAction *shtoggle = ACTION("Show/Hide", menu); + QAction *fullscreen = ACTION("Take fullscreen shot", menu); + QAction *area = ACTION("Take area shot", menu); #ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW - QAction *active = new QAction("Screenshot active window", this); + QAction *active = ACTION("Screenshot active window", menu); connect(active, &QAction::triggered, this, [] { screenshotter::activeDelayed(); }); #endif - QAction *picker = new QAction("Show color picker", this); - QAction *rec = new QAction("Record screen", this); - QAction *recoff = new QAction("Stop recording", this); - QAction *recabort = new QAction("Abort recording", this); + QAction *picker = ACTION("Show color picker", menu); + QAction *rec = ACTION("Record screen", menu); + QAction *recoff = ACTION("Stop recording", menu); + QAction *recabort = ACTION("Abort recording", menu); menu->addActions({ quit, shtoggle, picker }); menu->addSeparator(); menu->addActions({ fullscreen, area }); diff --git a/mainwindow.hpp b/mainwindow.hpp index a5a87c4..88a3d36 100644 --- a/mainwindow.hpp +++ b/mainwindow.hpp @@ -45,10 +45,12 @@ public slots: private: bool val = false; + QMap acts; static MainWindow *instance; protected: - void closeEvent(QCloseEvent *event); + void changeEvent(QEvent *e) override; + void closeEvent(QCloseEvent *event) override; }; #endif // MAINWINDOW_HPP diff --git a/recording/encoders/encodersettingsdialog.cpp b/recording/encoders/encodersettingsdialog.cpp index e182f8c..d70ba73 100644 --- a/recording/encoders/encodersettingsdialog.cpp +++ b/recording/encoders/encodersettingsdialog.cpp @@ -8,7 +8,7 @@ EncoderSettingsDialog::EncoderSettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::EncoderSettingsDialog) { ui->setupUi(this); - setWindowTitle("KShare Encoder Settings"); + setWindowTitle(tr("KShare Encoder Settings")); connect(ui->buttonBox, &QDialogButtonBox::accepted, [&] { EncoderSettings::inst().setbitrate(ui->bitrate->value()); EncoderSettings::inst().seth264Crf(ui->crf->value()); diff --git a/recording/recordingformats.cpp b/recording/recordingformats.cpp index a16abfb..b6840f7 100644 --- a/recording/recordingformats.cpp +++ b/recording/recordingformats.cpp @@ -19,7 +19,7 @@ RecordingFormats::RecordingFormats(formats::Recording f) { if (!tmpDir.isValid()) { validator = [](QSize) { return false; }; - qCritical().noquote() << "Could not create temporary directory. Error: " + tmpDir.errorString(); + qCritical().noquote() << tr("Could not create temporary directory. Error: ") + tmpDir.errorString(); return; } iFormat = QImage::Format_RGB888; @@ -39,7 +39,7 @@ RecordingFormats::RecordingFormats(formats::Recording f) { return false; } } catch (std::runtime_error &e) { - qCritical() << "Encoder error: " << e.what(); + qCritical() << tr("Encoder error: ") << e.what(); interrupt = true; delete enc; return false; @@ -52,7 +52,7 @@ RecordingFormats::RecordingFormats(formats::Recording f) { frameAdded = true; enc->addFrame(img); } catch (std::runtime_error &e) { - qCritical() << "Encoder error: " << e.what(); + qCritical() << tr("Encoder error: ") << e.what(); interrupt = true; } }; diff --git a/recording/recordingformats.hpp b/recording/recordingformats.hpp index 09fb505..1a75438 100644 --- a/recording/recordingformats.hpp +++ b/recording/recordingformats.hpp @@ -1,6 +1,7 @@ #ifndef RECORDINGFORMATS_HPP #define RECORDINGFORMATS_HPP +#include #include #include #include @@ -12,6 +13,7 @@ #include class RecordingFormats { + Q_DECLARE_TR_FUNCTIONS(RecordingFormats) public: RecordingFormats(formats::Recording f); std::function getConsumer(); diff --git a/recording/recordingpreview.cpp b/recording/recordingpreview.cpp index cab4563..1b079e6 100644 --- a/recording/recordingpreview.cpp +++ b/recording/recordingpreview.cpp @@ -7,7 +7,7 @@ #include #include -QSize max(300, 300); +static QSize max(300, 300); inline bool sizeGreater(QSize one, QSize two) { return one.height() > two.height() || one.width() > two.width(); @@ -44,7 +44,7 @@ RecordingPreview::RecordingPreview(QRect area, QWidget *parent) : QWidget(parent label->setPixmap(empty); layout()->addWidget(hintLabel); layout()->addWidget(label); - hintLabel->setText(QString("Time: 00:00\nFrame: 0\nStop key: ") + hotkeying::sequence("recordingstop")); + hintLabel->setText(QString(tr("Time: 00:00\nFrame: 0\nStop key: ")) + hotkeying::sequence("recordingstop")); } RecordingPreview::~RecordingPreview() { @@ -58,6 +58,6 @@ void RecordingPreview::setPixmap(QPixmap map) { } void RecordingPreview::setTime(QString time, int frame) { if (isVisible()) - hintLabel->setText(QString("Time: ") + time + "\nFrame: " + QString::number(frame) - + "\nStop key: " + hotkeying::sequence("recordingstop")); + hintLabel->setText( + tr("Time: %1\nFrame: %2\nStop key: %3").arg(time).arg(frame).arg(hotkeying::sequence("recordingstop"))); } diff --git a/screenareaselector/screenareaselector.cpp b/screenareaselector/screenareaselector.cpp index e5f35b6..e04aa02 100644 --- a/screenareaselector/screenareaselector.cpp +++ b/screenareaselector/screenareaselector.cpp @@ -6,14 +6,14 @@ #include #include -static QString hintPattern("Set the recording region by resizing this.\n%1x%2"); +static QString hintPattern(ScreenAreaSelector::tr("Set the recording region by resizing this.\n%1x%2")); ScreenAreaSelector::ScreenAreaSelector() { setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); setStyleSheet("background-color: rgba(0, 0, 0, 0.5);"); - setWindowTitle("KShare: Select Area (By resizing this window)"); + setWindowTitle(tr("KShare: Select Area (By resizing this window)")); setAutoFillBackground(true); QTimer::singleShot(0, [&] { QVariant val = settings::settings().value("screenareaselector/rect"); diff --git a/settings.cpp b/settings.cpp index f76c081..bb5ac9e 100644 --- a/settings.cpp +++ b/settings.cpp @@ -13,7 +13,7 @@ QDir settings::dir() { if (configDir.dirName() != "KShare") { if (!configDir.cd("KShare")) { if (!configDir.mkdir("KShare")) { - qFatal("Could not make config directory"); + qFatal("%s", QObject::tr("Could not make config directory").toLocal8Bit().constData()); } else { configDir.cd("KShare"); } diff --git a/settingsdialog.cpp b/settingsdialog.cpp index 3a39548..18949ed 100644 --- a/settingsdialog.cpp +++ b/settingsdialog.cpp @@ -20,7 +20,7 @@ #include #include -QMap> fncs; +static QMap> fncs; void addHotkeyItem(QListWidget *hotkeys, QString text, QString name, std::function func, QString def = QString()) { QListWidgetItem *item = new QListWidgetItem(text, hotkeys); @@ -52,14 +52,14 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Se ui->hotkeys->setSelectionMode(QListWidget::SingleSelection); - addHotkeyItem(ui->hotkeys, "Fullscreen image", "fullscreen", [] { screenshotter::fullscreen(); }); - addHotkeyItem(ui->hotkeys, "Area image", "area", [] { screenshotter::area(); }); + addHotkeyItem(ui->hotkeys, tr("Fullscreen image"), "fullscreen", [] { screenshotter::fullscreen(); }); + addHotkeyItem(ui->hotkeys, tr("Area image"), "area", [] { screenshotter::area(); }); #ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW - addHotkeyItem(ui->hotkeys, "Active window", "active", [&] { screenshotter::active(); }); + addHotkeyItem(ui->hotkeys, tr("Active window"), "active", [&] { screenshotter::active(); }); #endif - addHotkeyItem(ui->hotkeys, "Color picker", "picker", [] { ColorPickerScene::showPicker(); }); - addHotkeyItem(ui->hotkeys, "Stop Recording", "recordingstop", [&] { MainWindow::inst()->controller->end(); }); - addHotkeyItem(ui->hotkeys, "Start Recording", "recordingstart", [&] { MainWindow::inst()->rec(); }); + addHotkeyItem(ui->hotkeys, tr("Color picker"), "picker", [] { ColorPickerScene::showPicker(); }); + addHotkeyItem(ui->hotkeys, tr("Stop Recording"), "recordingstop", [&] { MainWindow::inst()->controller->end(); }); + addHotkeyItem(ui->hotkeys, tr("Start Recording"), "recordingstart", [&] { MainWindow::inst()->rec(); }); ui->quickMode->setChecked(settings::settings().value("quickMode", false).toBool()); ui->hideToTray->setChecked(settings::settings().value("hideOnClose", true).toBool()); @@ -81,7 +81,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Se ui->nameScheme->setValidator(new FilenameValidator(ui->nameScheme)); #ifndef PLATFORM_CAPABILITY_CURSOR ui->captureCursor->setEnabled(false); - ui->captureCursor->setText("Capture cursor (disabled: implementation missing)"); + ui->captureCursor->setText(tr("Capture cursor (disabled: implementation missing)")); #endif } diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index bf8ff6c..93020d1 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -18,8 +18,8 @@ using formats::recordingFormatFromName; using formats::recordingFormatMIME; using std::runtime_error; -void error(QString absFilePath, QString err) { - throw runtime_error((QString("Invalid file: ").append(absFilePath) + ": " + err).toStdString()); +[[noreturn]] void error(QString absFilePath, QString err) { + throw runtime_error((QObject::tr("Invalid file: ").append(absFilePath) + ": " + err).toStdString()); } CustomUploader::CustomUploader(QString absFilePath) { @@ -28,16 +28,16 @@ CustomUploader::CustomUploader(QString absFilePath) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) error(absFilePath, file.errorString()); QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); if (!doc.isObject()) { - error(absFilePath, "Root not an object"); + error(absFilePath, tr("Root not an object")); } QJsonObject obj = doc.object(); if (!obj["name"].isString()) - error(absFilePath, "name is not a string"); + error(absFilePath, tr("name is not a string")); else uName = obj["name"].toString(); if (obj.contains("desc")) { if (!obj["desc"].isString()) - /*t*/ error(absFilePath, "desc not a string"); + /*t*/ error(absFilePath, tr("desc not a string")); else desc = obj["desc"].toString(); @@ -45,19 +45,19 @@ CustomUploader::CustomUploader(QString absFilePath) { desc = absFilePath; QJsonValue m = obj["method"]; if (!m.isUndefined() && !m.isNull()) { - if (!m.isString()) error(absFilePath, "method not a string"); + if (!m.isString()) error(absFilePath, tr("method not a string")); QString toCheck = m.toString().toLower(); if (toCheck == "post") method = HttpMethod::POST; else - error(absFilePath, "method invalid"); + error(absFilePath, tr("method invalid")); } QJsonValue url = obj["target"]; if (!url.isString()) { - error(absFilePath, "target missing"); + error(absFilePath, tr("target missing")); } QUrl target(url.toString()); - if (!target.isValid()) error(absFilePath, "target not URL"); + if (!target.isValid()) error(absFilePath, tr("target not URL")); this->target = target; QJsonValue formatValue = obj["format"]; if (!formatValue.isUndefined() && !formatValue.isNull()) { @@ -72,45 +72,47 @@ CustomUploader::CustomUploader(QString absFilePath) { else if (formatString == "multipart-form-data") rFormat = RequestFormat::MULTIPART_FORM_DATA; else - error(absFilePath, "format invalid"); + error(absFilePath, tr("format invalid")); } } else - error(absFilePath, "format provided but not string"); + error(absFilePath, tr("format provided but not string")); QJsonValue bodyValue = obj["body"]; if (rFormat != RequestFormat::PLAIN) { - if (bodyValue.isUndefined()) error(absFilePath, "body not set"); + if (bodyValue.isUndefined()) error(absFilePath, tr("body not set")); if (rFormat == RequestFormat::MULTIPART_FORM_DATA) { if (bodyValue.isArray()) { for (QJsonValue val : bodyValue.toArray()) { - if (!val.isObject()) error(absFilePath, "all elements of body must be objects"); + if (!val.isObject()) error(absFilePath, tr("all elements of body must be objects")); if (!val.toObject()["body"].isObject() && !val.toObject().value("body").isString()) - error(absFilePath, "all parts must have a body which is object or string!"); + error(absFilePath, tr("all parts must have a body which is object or string!")); QJsonObject vo = val.toObject(); for (auto v : vo["body"].toObject()) if (!v.isObject() && !v.isString()) - error(absFilePath, "all parts of body must be string or object"); + error(absFilePath, tr("all parts of body must be string or object")); for (auto v : vo.keys()) if (v.startsWith("__") && !vo[v].isString()) - error(absFilePath, "all __headers must be strings"); + //: __ + error(absFilePath, tr("all __headers must be strings")); } body = bodyValue; } else - error(absFilePath, "body not array (needed for multipart)"); + error(absFilePath, tr("body not array (needed for multipart)")); } else { if (bodyValue.isObject()) body = bodyValue; else - error(absFilePath, "body not object"); + error(absFilePath, tr("body not object")); } } else { if (bodyValue.isString()) { body = bodyValue; } else - error(absFilePath, "body not string (reason: format: PLAIN)"); + //: `format: PLAIN` should stay the same + error(absFilePath, tr("body not string (reason: format: PLAIN)")); } QJsonValue headerVal = obj["headers"]; if (!(headerVal.isUndefined() || headerVal.isNull())) { - if (!headerVal.isObject()) error(absFilePath, "headers must be object"); + if (!headerVal.isObject()) error(absFilePath, tr("headers must be object")); headers = headerVal.toObject(); } else headers = QJsonObject(); @@ -118,17 +120,18 @@ CustomUploader::CustomUploader(QString absFilePath) { if (returnPsVal.isString()) { returnPathspec = returnPsVal.toString(); } else - error(absFilePath, "return invalid"); + error(absFilePath, tr("return invalid")); QJsonValue fileLimit = obj["fileLimit"]; if (!fileLimit.isNull() && !fileLimit.isUndefined()) { - if (!fileLimit.isDouble()) error(absFilePath, "fileLimit not double"); + //: fileLimit stays English + if (!fileLimit.isDouble()) error(absFilePath, tr("fileLimit not decimal")); limit = fileLimit.toDouble(); } QJsonValue bool64 = obj["base64"]; if (!bool64.isNull() && !bool64.isUndefined()) { - if (!bool64.isBool()) error(absFilePath, "base64 must be boolean"); + if (!bool64.isBool()) error(absFilePath, tr("base64 must be boolean")); base64 = bool64.toBool(); - if (rFormat == RequestFormat::JSON && !base64) error(absFilePath, "base64 required with json"); + if (rFormat == RequestFormat::JSON && !base64) error(absFilePath, tr("base64 required with json")); } urlPrepend = obj["return_prepend"].toString(); urlAppend = obj["return_append"].toString(); @@ -204,19 +207,19 @@ QString parsePathspec(QJsonDocument &response, QString &pathspec) { return ""; } -void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name, QString urlPrepend, QString urlAppend) { +void CustomUploader::parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name) { if (result.isObject()) { QString url = urlPrepend + parsePathspec(result, returnPathspec) + urlAppend; if (!url.isEmpty()) { QApplication::clipboard()->setText(url); - notifications::notify("KShare Custom Uploader " + name, "Copied upload link to clipboard!"); + notifications::notify(tr("KShare Custom Uploader ") + name, tr("Copied upload link to clipboard!")); } else { - notifications::notify("KShare Custom Uploader " + name, "Upload done, but result empty!"); + notifications::notify(tr("KShare Custom Uploader ") + name, tr("Upload done, but result empty!")); QApplication::clipboard()->setText(data); } } else { - notifications::notify("KShare Custom Uploader " + name, - "Upload done, but result is not JSON Object! Result in clipboard."); + notifications::notify(tr("KShare Custom Uploader ") + name, + tr("Upload done, but result is not JSON Object! Result in clipboard.")); QApplication::clipboard()->setText(data); } } @@ -328,18 +331,20 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { switch (method) { case HttpMethod::POST: if (returnPathspec == "|") { - ioutils::postMultipartData(target, h, multipart, [&, buffersToDelete, arraysToDelete](QByteArray result, QNetworkReply *) { - QApplication::clipboard()->setText(QString::fromUtf8(result)); - for (auto buffer : buffersToDelete) buffer->deleteLater(); - for (auto arr : arraysToDelete) delete arr; - notifications::notify("KShare Custom Uploader " + name(), "Copied upload result to clipboard!"); - }); + ioutils::postMultipartData(target, h, multipart, + [&, buffersToDelete, arraysToDelete](QByteArray result, QNetworkReply *) { + QApplication::clipboard()->setText(QString::fromUtf8(result)); + for (auto buffer : buffersToDelete) buffer->deleteLater(); + for (auto arr : arraysToDelete) delete arr; + notifications::notify(tr("KShare Custom Uploader ") + name(), + tr("Copied upload result to clipboard!")); + }); } else { ioutils::postMultipart(target, h, multipart, [&, buffersToDelete, arraysToDelete](QJsonDocument result, QByteArray data, QNetworkReply *) { for (auto buffer : buffersToDelete) buffer->deleteLater(); for (auto arr : arraysToDelete) delete arr; - parseResult(result, data, returnPathspec, name(), urlPrepend, urlAppend); + parseResult(result, data, returnPathspec, name()); }); } break; @@ -348,7 +353,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { } } if (limit > 0 && data.size() > limit) { - notifications::notify("KShare Custom Uploader " + name(), "File limit exceeded!"); + notifications::notify(tr("KShare Custom Uploader ") + name(), tr("File limit exceeded!")); return; } switch (method) { @@ -356,11 +361,11 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { if (returnPathspec == "|") { ioutils::postData(target, h, data, [&](QByteArray result, QNetworkReply *) { QApplication::clipboard()->setText(QString::fromUtf8(result)); - notifications::notify("KShare Custom Uploader " + name(), "Copied upload result to clipboard!"); + notifications::notify(tr("KShare Custom Uploader ") + name(), tr("Copied upload result to clipboard!")); }); } else { ioutils::postJson(target, h, data, [&](QJsonDocument result, QByteArray data, QNetworkReply *) { - parseResult(result, data, returnPathspec, name(), urlPrepend, urlAppend); + parseResult(result, data, returnPathspec, name()); }); } break; diff --git a/uploaders/customuploader.hpp b/uploaders/customuploader.hpp index 22deaef..35b54bf 100644 --- a/uploaders/customuploader.hpp +++ b/uploaders/customuploader.hpp @@ -2,6 +2,7 @@ #define CUSTOMUPLOADER_HPP #include "uploader.hpp" +#include #include #include #include @@ -11,6 +12,8 @@ enum class HttpMethod { POST }; enum class RequestFormat { X_WWW_FORM_URLENCODED, JSON, MULTIPART_FORM_DATA, PLAIN }; class CustomUploader : public Uploader { + Q_DECLARE_TR_FUNCTIONS(CustomUploader) + public: CustomUploader(QString absFilePath); QString name(); @@ -29,6 +32,7 @@ private: bool base64 = false; QString returnPathspec; QString urlPrepend, urlAppend; + void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name); }; #endif // CUSTOMUPLOADER_HPP diff --git a/uploaders/default/clipboarduploader.cpp b/uploaders/default/clipboarduploader.cpp index 57aa7a2..5955d29 100644 --- a/uploaders/default/clipboarduploader.cpp +++ b/uploaders/default/clipboarduploader.cpp @@ -14,5 +14,5 @@ void ClipboardUploader::doUpload(QByteArray imgData, QString format) { QApplication::clipboard()->setMimeData(data); } else QApplication::clipboard()->setImage(QImage::fromData(imgData, format.toLocal8Bit().constData())); - notifications::notify("KShare", "Copied to clipboard!"); + notifications::notify(tr("KShare"), tr("Copied to clipboard!")); } diff --git a/uploaders/default/clipboarduploader.hpp b/uploaders/default/clipboarduploader.hpp index 5794386..07e78f0 100644 --- a/uploaders/default/clipboarduploader.hpp +++ b/uploaders/default/clipboarduploader.hpp @@ -1,10 +1,12 @@ #ifndef CLIPBOARDUPLOADER_HPP #define CLIPBOARDUPLOADER_HPP +#include #include #include class ClipboardUploader : public Uploader { + Q_DECLARE_TR_FUNCTIONS(ClipboardUploader) public: QString name() { return "clipboard"; diff --git a/uploaders/default/imgplusuploader.cpp b/uploaders/default/imgplusuploader.cpp index dcb1ce0..5cbdb6a 100644 --- a/uploaders/default/imgplusuploader.cpp +++ b/uploaders/default/imgplusuploader.cpp @@ -36,14 +36,15 @@ void ImgplusUploader::doUpload(QByteArray byteArray, QString format) { [](QByteArray link, QNetworkReply *) { QApplication::clipboard()->setText(QString::fromUtf8(link)); if (!link.startsWith("http")) - qCritical() << "Failed to upload! Copied the response to clipboard"; + qCritical() << QObject::tr("Failed to upload! Copied the response to clipboard"); else - notifications::notify("KShare imgur Uploader ", "Uploaded to ImagePlus!"); + notifications::notify(QObject::tr("KShare imgplus Uploader"), + QObject::tr("Uploaded to ImagePlus!")); }); } void ImgplusUploader::showSettings() { - QString text = QInputDialog::getText(0, "imgplus API key", "Enter the imgpl.us API key (Found in Settings)", + QString text = QInputDialog::getText(0, tr("imgplus API key"), tr("Enter the imgpl.us API key (Found in Settings)"), QLineEdit::Normal, settings::settings().value("imgplus/apikey").toString()); if (!text.isNull()) settings::settings().setValue("imgplus/apikey", text); } diff --git a/uploaders/default/imgplusuploader.hpp b/uploaders/default/imgplusuploader.hpp index a7050c6..7ef3836 100644 --- a/uploaders/default/imgplusuploader.hpp +++ b/uploaders/default/imgplusuploader.hpp @@ -1,9 +1,11 @@ #ifndef IMGPLUSUPLOADER_HPP #define IMGPLUSUPLOADER_HPP +#include #include class ImgplusUploader : public Uploader { + Q_DECLARE_TR_FUNCTIONS(ImgplusUploader) public: QString name() override { return "ImagePlus"; diff --git a/uploaders/default/imgursettingsdialog.cpp b/uploaders/default/imgursettingsdialog.cpp index f69aba6..fbaa65e 100644 --- a/uploaders/default/imgursettingsdialog.cpp +++ b/uploaders/default/imgursettingsdialog.cpp @@ -60,7 +60,7 @@ void ImgurSettingsDialog::on_authorize_clicked() { QDateTime::currentDateTimeUtc().addSecs(res["expires_in"].toInt())); settings::settings().setValue("imgur/refresh", res["refresh_token"].toString()); settings::settings().setValue("imgur/access", res["refresh_token"].toString()); - ui->status->setText("It works!"); + ui->status->setText(tr("It works!")); ui->status->setStyleSheet("* { color: green; }"); ui->authorize->setEnabled(false); diff --git a/uploaders/default/imguruploader.cpp b/uploaders/default/imguruploader.cpp index ec051a9..fa6457b 100644 --- a/uploaders/default/imguruploader.cpp +++ b/uploaders/default/imguruploader.cpp @@ -53,7 +53,7 @@ private: void ImgurUploader::doUpload(QByteArray byteArray, QString format) { if (byteArray.size() > 1e+7) { - notifications::notify("KShare imgur Uploader ", "Failed upload! Image too big"); + notifications::notify(tr("KShare imgur Uploader"), tr("Failed upload! Image too big")); return; } QString mime; @@ -89,10 +89,10 @@ void ImgurUploader::handleSend(QString auth, QString mime, QByteArray byteArray) } if (!result.isEmpty()) { screenshotutil::toClipboard(result); - notifications::notify("KShare imgur Uploader ", "Uploaded to imgur!"); + notifications::notify(tr("KShare imgur Uploader"), tr("Uploaded to imgur!")); } else { - notifications::notify("KShare imgur Uploader ", - QString("Failed upload! imgur said: HTTP %1: %2") + notifications::notify(tr("KShare imgur Uploader "), + QString(tr("Failed upload! imgur said: HTTP %1: %2")) .arg(r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()) .arg(r->errorString())); } diff --git a/uploaders/default/imguruploader.hpp b/uploaders/default/imguruploader.hpp index 5419f31..78c38af 100644 --- a/uploaders/default/imguruploader.hpp +++ b/uploaders/default/imguruploader.hpp @@ -2,8 +2,10 @@ #define IMGURUPLOADER_HPP #include "../uploader.hpp" +#include class ImgurUploader : public Uploader { + Q_DECLARE_TR_FUNCTIONS(ImgurUploader) friend struct SegfaultWorkaround; public: diff --git a/uploaders/uploadersingleton.cpp b/uploaders/uploadersingleton.cpp index 3f21481..4bac1fa 100644 --- a/uploaders/uploadersingleton.cpp +++ b/uploaders/uploadersingleton.cpp @@ -18,18 +18,17 @@ UploaderSingleton::UploaderSingleton() : QObject() { case 0: saveDir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); if (QStandardPaths::writableLocation(QStandardPaths::PicturesLocation).isEmpty()) { - qFatal("Cannot determine location for pictures"); + qFatal("%s", tr("Cannot determine location for pictures").toLocal8Bit().constData()); } break; case 1: if (QStandardPaths::writableLocation(QStandardPaths::HomeLocation).isEmpty()) { - qFatal("Cannot determine location of your home directory"); + qFatal("%s", tr("Cannot determine location of your home directory").toLocal8Bit().constData()); } saveDir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/Screenshots"; break; default: - qFatal("Invalid config [saveLocation not int or is not in range]"); - break; + qFatal("%s", tr("Invalid config [saveLocation not int or is not in range]").toLocal8Bit().constData()); } if (!saveDir.exists()) { @@ -68,7 +67,7 @@ UploaderSingleton::UploaderSingleton() : QObject() { void UploaderSingleton::registerUploader(Uploader *uploader) { if (uploaders.contains(uploader->name())) - throw std::runtime_error(("Ambigious uploader " + uploader->name()).toStdString()); + throw std::runtime_error((tr("Ambigious uploader ") + uploader->name()).toStdString()); uploaders.insert(uploader->name(), uploader); emit newUploader(uploader); } @@ -78,7 +77,7 @@ void UploaderSingleton::upload(QPixmap pixmap) { if (!u->validate()) { u = uploaders.value("imgur"); set("imgur"); - qWarning() << "Currently selected uploader is not set up properly! Falling back to imgur"; + qWarning() << tr("Currently selected uploader is not set up properly! Falling back to imgur"); } QString format = settings::settings().value("captureformat", "PNG").toString(); QFile file(saveDir.absoluteFilePath( @@ -90,7 +89,7 @@ void UploaderSingleton::upload(QPixmap pixmap) { file.seek(0); u->doUpload(file.readAll(), format); } else - notifications::notify("KShare - Failed to save picture", file.errorString(), QSystemTrayIcon::Warning); + notifications::notify(tr("KShare - Failed to save picture"), file.errorString(), QSystemTrayIcon::Warning); } void UploaderSingleton::upload(QByteArray img, QString format) { @@ -113,9 +112,9 @@ void UploaderSingleton::upload(QFile &img, QString format) { if (img.open(QFile::ReadWrite)) uploaders.value(uploader)->doUpload(img.readAll(), format); else - notifications::notify("KShare - Failed to save picture", img.errorString(), QSystemTrayIcon::Warning); + notifications::notify(tr("KShare - Failed to save picture"), img.errorString(), QSystemTrayIcon::Warning); } else - notifications::notify("KShare - Failed to save picture", img.errorString(), QSystemTrayIcon::Warning); + notifications::notify(tr("KShare - Failed to save picture"), img.errorString(), QSystemTrayIcon::Warning); } void UploaderSingleton::showSettings() { diff --git a/uploaders/uploadersingleton.hpp b/uploaders/uploadersingleton.hpp index fc1fb2a..50f5f99 100644 --- a/uploaders/uploadersingleton.hpp +++ b/uploaders/uploadersingleton.hpp @@ -30,10 +30,10 @@ signals: private: QDir saveDir; - UploaderSingleton(); QMap uploaders; QString uploader = "imgur"; QList errs; + UploaderSingleton(); }; #endif // UPLOADERSINGLETON_HPP From f77519da0b400ce042466f779d1836b737d3ff1f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 29 Jul 2017 23:54:22 +0200 Subject: [PATCH 123/293] Add Serbian translation, and a translation guide --- translations.qrc | 1 + translations/README.md | 9 + translations/sr_RS.qm | Bin 0 -> 23983 bytes translations/sr_RS.ts | 1014 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1024 insertions(+) create mode 100644 translations.qrc create mode 100644 translations/README.md create mode 100644 translations/sr_RS.qm create mode 100644 translations/sr_RS.ts diff --git a/translations.qrc b/translations.qrc new file mode 100644 index 0000000..7646d2b --- /dev/null +++ b/translations.qrc @@ -0,0 +1 @@ + diff --git a/translations/README.md b/translations/README.md new file mode 100644 index 0000000..2c8d9ed --- /dev/null +++ b/translations/README.md @@ -0,0 +1,9 @@ +## So, I hear ya want to translate +here is how to do it: +Firstly, run `lupdate ../KShare.pro -no-obsolete -ts .ts` + +If you see something that looks like it was just changed a bit, take the old translation and update it, as `-no-obsolete` removed it. +Then open and edit the file in Qt Linguist. +When you're done editing the file, save it and run `lrelease ` and add an entry into `../translations.qrc` for the newly produced `.qm` file (if there isn't one). + +That's all, thank you! diff --git a/translations/sr_RS.qm b/translations/sr_RS.qm new file mode 100644 index 0000000000000000000000000000000000000000..72cd5da88b78b8eefedaa0dcf7e4ca2d125ee7ab GIT binary patch literal 23983 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 + + + + AboutBox + + + About KShare + O Programu KShare + + + + <html><head/><body><p><img src=":/icons/icon.svg" width="50" style="vertical-align: middle;"/><span style=" font-weight:600; vertical-align:middle;"> KShare</span><span style=" vertical-align:middle;"> - The free and open source and cross platform screen sharing software</span></p><p>Version %0<br/>Links: <a href="https://github.com/ArsenArsen/KShare"><span style=" text-decoration: underline; color:#007af4;">Source code</span></a>, <a href="https://github.com/ArsenArsen/KShare/issues"><span style=" text-decoration: underline; color:#007af4;">Issue tracker</span></a>, <a href="http://kshare.arsenarsen.com"><span style=" text-decoration: underline; color:#007af4;">Website</span></a>, <a href="https://patreon.com/arsen"><span style=" text-decoration: underline; color:#007af4;">Patreon</span></a></p></body></html> + <html><head/><body><p><img src=":/icons/icon.svg" width="50" style="vertical-align: middle;"/><span style=" font-weight:600; vertical-align:middle;"> KShare</span><span style=" vertical-align:middle;"> - Besplatan i slobodan program otvorenog koda za</span></p><p>Verzija %0<br/>Linkovi: <a href="https://github.com/ArsenArsen/KShare"><span style=" text-decoration: underline; color:#007af4;">Izvorni kod</span></a>, <a href="https://github.com/ArsenArsen/KShare/issues"><span style=" text-decoration: underline; color:#007af4;">Traker problema</span></a>, <a href="http://kshare.arsenarsen.com"><span style=" text-decoration: underline; color:#007af4;">Web sajt</span></a>, <a href="https://patreon.com/arsen"><span style=" text-decoration: underline; color:#007af4;">Patreon</span></a></p></body></html> + + + + BrushPenSelection + + + Pen settings + Podešavanja olovke + + + + Choose pen color + Izaberi boju olovke + + + + Cosmetic + Kozmetična olovka + + + + Width + Širina + + + + Pen alpha + Providnost olovke + + + + Blur settings + Podešavanja mućenja + + + + Performance Hint + Performanse + + + + <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Blur Hints + <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Opcije + + + + Blur Radius + Radius mućenja + + + + Animated Hint + Optimizacija animacije + + + + Quality Hint + Povećan kvalitet + + + + Brush settings + Podešavanja četke + + + + Brush alpha + Providnost četke + + + + No Brush + Prazno + + + + Solid + Puno + + + + Dense 1 + Gustina 1 + + + + Dense 2 + Gustina 2 + + + + Dense 3 + Gustina 3 + + + + Dense 4 + Gustina 4 + + + + Dense 5 + Gustina 5 + + + + Dense 6 + Gustina 6 + + + + Dense 7 + Gustina 7 + + + + Horizontal + Horizontalne linije + + + + Vertical + Vertikalne linije + + + + Cross pattern + Krstasto + + + + Backwards diagonal + Diagonalno unazad + + + + Forwards diagonal + Diagonalno unapred + + + + Diagonal cross + Diagonalno krstasti + + + + Choose brush color + Izaberi boju četke + + + + Path item has brush + Da li popuniti oblast linije + + + + Arrow settings + Podešavanja strela + + + + Arrow width and height + Visina i debljina strela + + + + Crop editor settings + Podešavanja editora + + + + Pen Color + Boja olovke + + + + Brush Color + Boja četke + + + + ClipboardUploader + + + Copied to clipboard! + Ne znam prevod za clipboard xD + Copirano u klipbord! + + + + ColorPickerScene + + + KShare Color Picker + KShare Birač Boja + + + + CropEditor + + + KShare Crop Editor + KShare Urednik + + + + CropScene + + + Free draw + Crtanje + + + + Blur + Mućenje slike + + + + Straight line + Prava Linija + + + + Text + Tekst + + + + Rectangle + Pravougaonik + + + + Ellipse + Krug i Elipsa + + + + Arrow + Strela + + + + Eraser + Brisač + + + + Clear all drawing + Očisti sliku + + + + Crop + Opseci + + + + Settings + Podešavanja + + + + Confirm + Potvrdi + + + + Cancel + Otkaži + + + + KShare Crop Editor + KShare Urednik Slika + + + + Press F1 to toggle this hint + Hold Shift to slow the cursor down + Ctrl+Drag a thing to move it around + Alt+Click a drawing to remove it + Press Return/Enter to finish + Press ESC to cancel + Use the menu bar to draw + NOTE: You must select 'Crop' before closing the editor + If you do not it will not close. + Pritisni F1 da uključiš i isključiš ovo + Drži Shift da usporiš miša + Ctrl+vuci da pomeriš nešto + Alt+Klik da ukloniš nešto + Press Return/Enter da potvrdiš + Press ESC da otkažeš + Koristi traku da crtaš + PS: Moraš izabrati opseci da bi potrvrdio ili otkazao. + + + + CustomUploader + + + Root not an object + Koren nije objekat + + + + name is not a string + name nije string + + + + desc not a string + desc nije string + + + + method not a string + method nije string + + + + method invalid + method nije validan + + + + target missing + target nije unet + + + + target not URL + target nije URL + + + + format invalid + format nije validan + + + + format provided but not string + format nije string + + + + body not set + bodz ne postoji + + + + all elements of body must be objects + svi elementi body-ja moraju biti objekti + + + + all parts must have a body which is object or string! + svi delovi moraju imati telo koje je ili objekat ili string! + + + + all parts of body must be string or object + svi delovi body-ja moraju biti objekti ili stringovi + + + + all __headers must be strings + svi __header-i moraju biti stringovi + + + + body not array (needed for multipart) + body nije array + + + + body not object + body nije objekat + + + + body not string (reason: format: PLAIN) + `format: PLAIN` should stay the same + body nije string (razlog: format: PLAIN) + + + + headers must be object + headers mora biti objekat + + + + return invalid + return nije validan + + + + fileLimit not decimal + fileLimit stays English + fileLimit nije decimala + + + + base64 must be boolean + base64 mora biti boolean + + + + base64 required with json + json zahteva base64 + + + + + + + + + KShare Custom Uploader + KShare Prilagodivi Uploader + + + + Copied upload link to clipboard! + Kopirao link u klipbord! + + + + Upload done, but result empty! + Slanje gotovo, ali rezultat je prazan! + + + + Upload done, but result is not JSON Object! Result in clipboard. + Slanje gotobo, ali rezultat nije JSON objekat! Kopiran rezultat. + + + + + Copied upload result to clipboard! + Rezultat kopiran u klipboard! + + + + File limit exceeded! + Fajl je prevelik! + + + + EncoderSettingsDialog + + + Image Encoder Settings + Podešavanja kodeka za slike + + + + <html><head/><body><p><a href="http://doc.qt.io/qt-5/qpixmap.html#save"><span style=" text-decoration: underline; color:#007af4;">Quality</span></a></p></body></html> + <html><head/><body><p><a href="http://doc.qt.io/qt-5/qpixmap.html#save"><span style=" text-decoration: underline; color:#007af4;">Kvalitet</span></a></p></body></html> + + + + Format default + Podrazumevan za format + + + + Video Encoder Settings + Podešavanja video kodeka + + + + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">Preset</span></a></p></body></html> + + + + + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">CRF</span></a></p></body></html> + + + + + Lossless (not recommended) + Kompresija bez gubitaka (nije preporučeno) + + + + TODO: Find whatever configuration GIF can have in ffmpeg's libav + + + + + Bitrate + + + + + The number of pictures in a group of pictures, or 0 for intra only + Broj slika u grupi slika, ili 0 da bi ostale samo intra slike + + + + GOP size + Veličina GOP-a + + + + KShare Encoder Settings + KShare Podešavanja Kodeka + + + + HotkeyInputDialog + + + + + Record + Snjimaj tastaturu + + + + Stop recording + Obustavi snjimanje + + + + ImgplusUploader + + + imgplus API key + imgplus API ključ + + + + Enter the imgpl.us API key (Found in Settings) + Unesi imgpl.us API ključ (Iz podešavanja) + + + + ImgurSettingsDialog + + + Imgur auth + Imgur autentikacija + + + + OAuth2 + OAuth2 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Create a new application:</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Napravi novu aplikaciju:</p></body></html> + + + + Open imgur + Otvori imgur + + + + Insert Client ID and secret: + Unesi Client ID i secret: + + + + Client ID + Client ID + + + + Client Secret + Client Secret + + + + Get the pin + Nabavi PIN + + + + Insert the pin below: + Unesi PIN: + + + + PIN + + + + + Authorize + Autorizuj + + + + Not working + Ne radi + + + + It works! + Radi! + + + + ImgurUploader + + + + KShare imgur Uploader + KShare imgur Uploader + + + + Failed upload! Image too big + Neuspelo slanje! Slika je prevelika + + + + Uploaded to imgur! + Poslato na imgur! + + + + KShare imgur Uploader + KShare imgur Uploader + + + + Failed upload! imgur said: HTTP %1: %2 + Neuspeh! imgur kaže: HTTP %1: %2 + + + + MainWindow + + + + Settings + Podešavanja + + + + Log + Zapis + + + + Fi&le + Faj&l + + + + Scree&nshot + Slika&nje + + + + &Utilities + &Alati + + + + &Recording + &Snjimanje + + + + &Quit + Iza&đi + + + + &Fullscreen + &Ceo Ekran + + + + &Area + &Prostor + + + + &Color Picker + &Birač Boja + + + + Start + Počni + + + + Stop + Zaustavi + + + + About + O Programu + + + + Active window + Aktivni prozor + + + + Abort + Obustavi + + + + Recording format not set in settings. Aborting. + Format snjimanja nije podešen! Otkazujem. + + + + QObject + + + + Could not bind the hotkey %1! Is the keybind already registered? + Neuspela registracija hotkeya %1! Da li je već registrovan? + + + + Could not make config directory + Neuspeh pri pravljenju foldera za konfiguraciju + + + + Invalid file: + Neispravan fajl: + + + + Failed to upload! Copied the response to clipboard + Neuspelo slanje! Rezultat kopiran + + + + KShare imgplus Uploader + KShare imgplus Uploader + + + + Uploaded to ImagePlus! + Poslato na ImagePlus! + + + + RecordingFormats + + + Could not create temporary directory. Error: + Nije moguće napraviti privremeni folder. Greška: + + + + + Encoder error: + Greška na kodeku: + + + + RecordingPreview + + + Time: 00:00 +Frame: 0 +Stop key: + Vreme: 00:00 +Slika: 0 +Stop dugme: + + + + Time: %1 +Frame: %2 +Stop key: %3 + Vreme: %1 +Slika: %2 +Stop dugme: %3 + + + + ScreenAreaSelector + + + Set the recording region by resizing this. +%1x%2 + Izaberi oblast ekrana tako što ćeš povećati ovaj prozor. +%1x%2 + + + + KShare: Select Area (By resizing this window) + KShare: Izaberi Oblast Ekrana (Menjanjem veličine ovog prozora) + + + + SettingsDialog + + + Crop editor settings + Podešavanja + + + + Quick mode (mouse release screenshots) + Brzi mod (Potvrdi optuštanjem miša) + + + + Delay before taking a screenshot + Pauza pre slikanja + + + + In seconds + (u sekundama) + + + + A delay before taking a screenshot, in seconds + Pauza pre slikanja, u sekundama + + + + Hotkeys + Prečice + + + + Still image format + Format slika + + + + Recording format + Format videa + + + + Capture cursor + Slikaj kursor + + + + %(date format)date and %ext are supported + %(format za datum)date i %ext su podržani + + + + File name scheme: + Format za ime fajlova: + + + + Pressing <X> hides to tray + Pritiskanje <X> sakriva prozor + + + + Open settings directory + Otvori folder sa podešavanjima + + + + Destination: + Destinacija: + + + + Pictures folder + Folder za slike + + + + Screenshots folder (In your user folder) + Screenshots (U vašem korisničkom folderu) + + + + File save location + Mesto za čuvanje fajlova + + + + Advanced + Napredno + + + + Editor Position (tweak if the editor does not cover the entire screen) + Pozicija urednika (menjajte ako urednik ne pokriva ceo ekran) + + + + Encoder settings + Podešavanja Kodeka + + + + Fullscreen image + Slika Celog Ekrana + + + + Area image + Slika prostora na ekranu + + + + Active window + Aktivni prozor + + + + Color picker + Birač Boja + + + + Stop Recording + Zaustavi snjimanje + + + + Start Recording + Sapočni snjimanje + + + + Capture cursor (disabled: implementation missing) + Snjimaj kursor (onemogućenoč fali implementacija) + + + + TextItem + + + Text to add + Tekst za dodavanje + + + + Input + Unos + + + + UploaderSingleton + + + Cannot determine location for pictures + Nije moguće odrediti lokaciju za slike + + + + Cannot determine location of your home directory + Nije moguće odrediti vaš korisnički folder + + + + Invalid config [saveLocation not int or is not in range] + Nepravilna konfiguracija [saveLocation not int or is not in range] + + + + Ambigious uploader + Dvosmislen Aplauder + + + + Currently selected uploader is not set up properly! Falling back to imgur + Trenutni uploader nije podešen! Vraćanje na imgur + + + + + + KShare - Failed to save picture + KShare - Neuspešno sačuvana slika + + + From 72954a795a6f25039b7c85c44b58ac0cf8e838de Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 29 Jul 2017 23:58:09 +0200 Subject: [PATCH 124/293] Oops --- KShare.pro | 3 +- aboutbox.ui | 4 +-- colorpicker/colorpickerscene.hpp | 2 +- cropeditor/cropscene.hpp | 27 ++++++++-------- cropeditor/settings/brushpenselection.ui | 14 ++++---- hotkeyinputdialog.ui | 2 +- main.cpp | 2 +- mainwindow.ui | 4 +-- recording/encoders/encodersettingsdialog.ui | 36 ++++++++++----------- settingsdialog.ui | 8 ++--- translations.qrc | 6 +++- uploaders/default/clipboarduploader.cpp | 2 +- 12 files changed, 58 insertions(+), 52 deletions(-) diff --git a/KShare.pro b/KShare.pro index ab036c9..1b95264 100644 --- a/KShare.pro +++ b/KShare.pro @@ -173,7 +173,8 @@ DISTFILES += \ install.sh RESOURCES += \ - icon.qrc + icon.qrc \ + translations.qrc QMAKE_CFLAGS_DEBUG += -g diff --git a/aboutbox.ui b/aboutbox.ui index 8c48a8f..b292fd3 100644 --- a/aboutbox.ui +++ b/aboutbox.ui @@ -6,7 +6,7 @@ 0 0 - 531 + 590 231 @@ -24,7 +24,7 @@ - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> diff --git a/colorpicker/colorpickerscene.hpp b/colorpicker/colorpickerscene.hpp index 76aebd8..8c6c060 100644 --- a/colorpicker/colorpickerscene.hpp +++ b/colorpicker/colorpickerscene.hpp @@ -11,7 +11,7 @@ #include class ColorPickerScene : public QGraphicsScene, public QGraphicsView { - Q_OBJECT + Q_DECLARE_TR_FUNCTIONS(ColorPickerScene) public: ColorPickerScene(QPixmap pixmap, QWidget *parentWidget); void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index 4d8c9f2..8dce960 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -84,19 +84,20 @@ private: QList gridRectsX; QList gridRectsY; QGraphicsPolygonItem *cursorItem = nullptr; - QGraphicsPixmapItem *hint = new QGraphicsPixmapItem(screenshotutil::renderText( // - "Press F1 to toggle this hint\n" - "\tHold Shift to slow the cursor down\n" - "\tCtrl+Drag a thing to move it around\n" - "\tAlt+Click a drawing to remove it\n" - "\tPress Return/Enter to finish\n" - "\tPress ESC to cancel\n" - "\tUse the menu bar to draw\n" - "\tNOTE: You must select 'Reset pen selection' before closing the editor\n" - "\tIf you do not it will not close.", - 5, - QColor(0, 0, 0, 125), - Qt::white)); + QGraphicsPixmapItem *hint + = new QGraphicsPixmapItem(screenshotutil::renderText(tr( // + "Press F1 to toggle this hint\n" + "\tHold Shift to slow the cursor down\n" + "\tCtrl+Drag a thing to move it around\n" + "\tAlt+Click a drawing to remove it\n" + "\tPress Return/Enter to finish\n" + "\tPress ESC to cancel\n" + "\tUse the menu bar to draw\n" + "\tNOTE: You must select 'Crop' before closing the editor\n" + "\tIf you do not it will not close."), + 5, + QColor(0, 0, 0, 125), + Qt::white)); }; #endif // CROPSCENE_HPP diff --git a/cropeditor/settings/brushpenselection.ui b/cropeditor/settings/brushpenselection.ui index b949d86..3688e28 100644 --- a/cropeditor/settings/brushpenselection.ui +++ b/cropeditor/settings/brushpenselection.ui @@ -14,7 +14,7 @@ Qt::StrongFocus - Dialog + Dialog @@ -110,7 +110,7 @@ - http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum + http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Blur Hints @@ -126,7 +126,7 @@ - px + px 30.000000000000000 @@ -322,20 +322,20 @@ - w: + w: - px + px - h: + h: - px + px diff --git a/hotkeyinputdialog.ui b/hotkeyinputdialog.ui index 859ec05..22a2c36 100644 --- a/hotkeyinputdialog.ui +++ b/hotkeyinputdialog.ui @@ -11,7 +11,7 @@ - Dialog + Dialog diff --git a/main.cpp b/main.cpp index acb0275..db39488 100644 --- a/main.cpp +++ b/main.cpp @@ -61,7 +61,7 @@ void handler(QtMsgType type, const QMessageLogContext &, const QString &msg) { } void loadTranslation(QString locale) { - QFile resource(":/langs/kshare_" + locale + ".qm"); + QFile resource(":/translations/" + locale + ".qm"); if (!resource.exists()) return; resource.open(QIODevice::ReadOnly); diff --git a/mainwindow.ui b/mainwindow.ui index e3c21b1..3328122 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -11,7 +11,7 @@ - KShare + KShare @@ -97,7 +97,7 @@ &Quit - Ctrl+Q + Ctrl+Q diff --git a/recording/encoders/encodersettingsdialog.ui b/recording/encoders/encodersettingsdialog.ui index 7c945c0..f3a70ad 100644 --- a/recording/encoders/encodersettingsdialog.ui +++ b/recording/encoders/encodersettingsdialog.ui @@ -11,7 +11,7 @@ - Dialog + Dialog @@ -62,14 +62,14 @@ - 2 + 0 Qt::LeftToRight - h264/h265 + h264/h265 @@ -82,59 +82,59 @@ - medium + ultrafast - 5 + 0 - ultrafast + ultrafast - superfast + superfast - veryfast + veryfast - faster + faster - fast + fast - medium + medium - slow + slow - slower + slower - veryslow + veryslow - placebo + placebo @@ -160,7 +160,7 @@ - VP9 + VP9 @@ -174,7 +174,7 @@ - GIF + GIF @@ -198,7 +198,7 @@ - kbps + kbps 999999.000000000000000 diff --git a/settingsdialog.ui b/settingsdialog.ui index 0acfd66..bde0889 100644 --- a/settingsdialog.ui +++ b/settingsdialog.ui @@ -40,7 +40,7 @@ A delay before taking a screenshot, in seconds - s + s @@ -84,7 +84,7 @@ %(date format)date and %ext are supported - Screenshot %(yyyy-MM-dd HH-mm-ss)date.%ext + Screenshot %(yyyy-MM-dd HH-mm-ss)date.%ext @@ -166,7 +166,7 @@ - x: + x: -999999 @@ -179,7 +179,7 @@ - y: + y: -999999 diff --git a/translations.qrc b/translations.qrc index 7646d2b..a0a6b1f 100644 --- a/translations.qrc +++ b/translations.qrc @@ -1 +1,5 @@ - + + + translations/sr_RS.qm + + diff --git a/uploaders/default/clipboarduploader.cpp b/uploaders/default/clipboarduploader.cpp index 5955d29..bbb2cfd 100644 --- a/uploaders/default/clipboarduploader.cpp +++ b/uploaders/default/clipboarduploader.cpp @@ -14,5 +14,5 @@ void ClipboardUploader::doUpload(QByteArray imgData, QString format) { QApplication::clipboard()->setMimeData(data); } else QApplication::clipboard()->setImage(QImage::fromData(imgData, format.toLocal8Bit().constData())); - notifications::notify(tr("KShare"), tr("Copied to clipboard!")); + notifications::notify("KShare", tr("Copied to clipboard!")); } From 13b4ba795852618531890b0f25cbba0d4f45586d Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 30 Jul 2017 00:49:15 +0200 Subject: [PATCH 125/293] Fix the drawing bar screen position --- cropeditor/cropscene.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 2a76ddd..33a6b49 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -151,7 +151,8 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) updateMag(); auto screen = QApplication::primaryScreen(); int w = screen->geometry().width(); - widget->setPos(views()[0]->mapToScene(QPoint((w - widget->boundingRect().width()) / 2, screen->geometry().y() + 100))); + widget->setPos(views()[0]->mapToScene( + QPoint(screen->geometry().x() + (w - widget->boundingRect().width()) / 2, screen->geometry().y() + 100))); }); } From a291ce1c0677bf163daa0128e620e8b934367ebf Mon Sep 17 00:00:00 2001 From: L1Q <0xL1Q@ex.ua> Date: Sun, 30 Jul 2017 06:07:09 +0300 Subject: [PATCH 126/293] Add russian translation --- translations.qrc | 1 + translations/ru_RU.qm | Bin 0 -> 24860 bytes translations/ru_RU.ts | 1015 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1016 insertions(+) create mode 100644 translations/ru_RU.qm create mode 100644 translations/ru_RU.ts diff --git a/translations.qrc b/translations.qrc index a0a6b1f..8a5fc91 100644 --- a/translations.qrc +++ b/translations.qrc @@ -1,5 +1,6 @@ translations/sr_RS.qm + translations/ru_RU.qm diff --git a/translations/ru_RU.qm b/translations/ru_RU.qm new file mode 100644 index 0000000000000000000000000000000000000000..0c200eb1a18b1670e1ee3d24acfb71ce0944f7c0 GIT binary patch literal 24860 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 literal 0 HcmV?d00001 diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts new file mode 100644 index 0000000..fb402bf --- /dev/null +++ b/translations/ru_RU.ts @@ -0,0 +1,1015 @@ + + + + + AboutBox + + + About KShare + О KShare + + + + <html><head/><body><p><img src=":/icons/icon.svg" width="50" style="vertical-align: middle;"/><span style=" font-weight:600; vertical-align:middle;"> KShare</span><span style=" vertical-align:middle;"> - The free and open source and cross platform screen sharing software</span></p><p>Version %0<br/>Links: <a href="https://github.com/ArsenArsen/KShare"><span style=" text-decoration: underline; color:#007af4;">Source code</span></a>, <a href="https://github.com/ArsenArsen/KShare/issues"><span style=" text-decoration: underline; color:#007af4;">Issue tracker</span></a>, <a href="http://kshare.arsenarsen.com"><span style=" text-decoration: underline; color:#007af4;">Website</span></a>, <a href="https://patreon.com/arsen"><span style=" text-decoration: underline; color:#007af4;">Patreon</span></a></p></body></html> + <html><head/><body><p><img src=":/icons/icon.svg" width="50" style="vertical-align: middle;"/><span style=" font-weight:600; vertical-align:middle;"> KShare</span><span style=" vertical-align:middle;"> - свободное кроссплатформенное ПО с открытым исходным кодом</span></p><p>Версия %0<br/>Ссылки: <a href="https://github.com/ArsenArsen/KShare"><span style=" text-decoration: underline; color:#007af4;">Исходный код</span></a>, <a href="https://github.com/ArsenArsen/KShare/issues"><span style=" text-decoration: underline; color:#007af4;">Issue tracker</span></a>, <a href="http://kshare.arsenarsen.com"><span style=" text-decoration: underline; color:#007af4;">Веб-сайт</span></a>, <a href="https://patreon.com/arsen"><span style=" text-decoration: underline; color:#007af4;">Patreon</span></a></p></body></html> + + + + BrushPenSelection + + + Pen settings + Настройки пера + + + + Choose pen color + Выбрать цвет пера + + + + Cosmetic + Никто не знает что это D: + Косметическое + + + + Width + Ширина + + + + Pen alpha + Прозрачность пера + + + + Blur settings + Настройки размытия + + + + Performance Hint + Производительность + + + + <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Blur Hints + + + + + Blur Radius + Радиус размытия + + + + Animated Hint + Анимация + + + + Quality Hint + Качество + + + + Brush settings + Настройки штриховки + + + + Brush alpha + Прозрачность штриховки + + + + No Brush + Без штриховки + + + + Solid + Сплошная + + + + Dense 1 + Толщина 1 + + + + Dense 2 + Толщина 2 + + + + Dense 3 + Толщина 3 + + + + Dense 4 + Толщина 4 + + + + Dense 5 + Толщина 5 + + + + Dense 6 + Толщина 6 + + + + Dense 7 + Толщина 7 + + + + Horizontal + Горизонтальная линия + + + + Vertical + Вертикальная линия + + + + Cross pattern + Крестики + + + + Backwards diagonal + Диагонально назад + + + + Forwards diagonal + Диагонально вперед + + + + Diagonal cross + Диагональные крестики + + + + Choose brush color + Выбрать цвет кисти + + + + Path item has brush + Штриховать при рисовании + + + + Arrow settings + Настройки стрелок + + + + Arrow width and height + Ширина и высота стрелок + + + + Crop editor settings + Настройки редактора кадрирования + + + + Pen Color + Цвет пера + + + + Brush Color + Цвет штриховки + + + + ClipboardUploader + + + Copied to clipboard! + Скопировано в буфер обмена! + + + + ColorPickerScene + + + KShare Color Picker + Пипетка KShare + + + + CropEditor + + + KShare Crop Editor + Редактор кадрирования KShare + + + + CropScene + + + Free draw + Рисование от руки + + + + Blur + Размытие + + + + Straight line + Прямая линия + + + + Text + Текст + + + + Rectangle + Прямоугольник + + + + Ellipse + Эллипс + + + + Arrow + Стрелка + + + + Eraser + Ластик + + + + Clear all drawing + Очистить + + + + Crop + Кадрировать + + + + Settings + Настройки + + + + Confirm + Подтвердить + + + + Cancel + Отменить + + + + KShare Crop Editor + Редактор кадрирования KShare + + + + Press F1 to toggle this hint + Hold Shift to slow the cursor down + Ctrl+Drag a thing to move it around + Alt+Click a drawing to remove it + Press Return/Enter to finish + Press ESC to cancel + Use the menu bar to draw + NOTE: You must select 'Crop' before closing the editor + If you do not it will not close. + Нажмите F1, чтобы переключать эти подсказки + Удерживание Shift — замедлить курсор + Ctrl+Потянуть объект для перемещения + Alt+клик по рисунку — удалить рисунок + Нажмите Enter, чтобы закночить + Нажмите Esc, чтобы отменить + Используйте панель меню для рисования + ЗАМЕТКА: Нужно выбрать "Кадрирование перед закрыванием редактора" + Иначе он не закроется. + + + + CustomUploader + + + Root not an object + Корень не объект + + + + name is not a string + имя не строка + + + + desc not a string + desc не строка + + + + method not a string + метод не строка + + + + method invalid + метод неверный + + + + target missing + цель отсутствует + + + + target not URL + цель не URL + + + + format invalid + формат не действительный + + + + format provided but not string + предоставлен формат, но не строка + + + + body not set + тело не задано + + + + all elements of body must be objects + все элементы тела должны быть объектами + + + + all parts must have a body which is object or string! + все части должны иметь тело, которое является объектом или стркой! + + + + all parts of body must be string or object + все части тела должны быть троками или объектом + + + + all __headers must be strings + все _header-ы должны быть строками + + + + body not array (needed for multipart) + тело не массив (нужно для загрузки частями) + + + + body not object + тело не объект + + + + body not string (reason: format: PLAIN) + `format: PLAIN` should stay the same + тело не строка (причина: формат: PLAIN) + + + + headers must be object + заголовки должны быть объектом + + + + return invalid + return не действителен + + + + fileLimit not decimal + fileLimit stays English + fileLimit не целое число + + + + base64 must be boolean + base64 должно быть boolean + + + + base64 required with json + json требует base64 + + + + + + + + + KShare Custom Uploader + Пользовательский загркзчик KShare + + + + Copied upload link to clipboard! + Ссыслка на зугрузку скопирована в буфер обмена! + + + + Upload done, but result empty! + Загрузка завершена, но результат пуст! + + + + Upload done, but result is not JSON Object! Result in clipboard. + Загрузка завершена, но результат не является объектом JSON! Результат в буфере обмена. + + + + + Copied upload result to clipboard! + Результат загрузки скопирован в буфер обмена! + + + + File limit exceeded! + Ограницение файла превышено! + + + + EncoderSettingsDialog + + + Image Encoder Settings + Настройки кодировщика изображений + + + + <html><head/><body><p><a href="http://doc.qt.io/qt-5/qpixmap.html#save"><span style=" text-decoration: underline; color:#007af4;">Quality</span></a></p></body></html> + <html><head/><body><p><a href="http://doc.qt.io/qt-5/qpixmap.html#save"><span style=" text-decoration: underline; color:#007af4;">Качество</span></a></p></body></html> + + + + Format default + По умолчанию для формата + + + + Video Encoder Settings + Настройки кодировщика видео + + + + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">Preset</span></a></p></body></html> + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">Предустановка</span></a></p></body></html> + + + + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">CRF</span></a></p></body></html> + + + + + Lossless (not recommended) + Без потерь (не рекомендуется) + + + + TODO: Find whatever configuration GIF can have in ffmpeg's libav + + + + + Bitrate + Витрейт + + + + The number of pictures in a group of pictures, or 0 for intra only + Количество изображений в группе изображений, 0 = только интра кадры + + + + GOP size + Размер группы изображений + + + + KShare Encoder Settings + Настройки кодировщика KShare + + + + HotkeyInputDialog + + + + + Record + Запись + + + + Stop recording + Остановить запись + + + + ImgplusUploader + + + imgplus API key + ключ API imgplus + + + + Enter the imgpl.us API key (Found in Settings) + Введите ключ API imgpl.us (Из настроек) + + + + ImgurSettingsDialog + + + Imgur auth + Imgur аутентификация + + + + OAuth2 + OAuth2 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Create a new application:</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Создать новое приложение:</p></body></html> + + + + Open imgur + Открытьi imgur + + + + Insert Client ID and secret: + Введите ID клиента и секрет: + + + + Client ID + ID клиента + + + + Client Secret + Секрет клиента + + + + Get the pin + Получить PIN + + + + Insert the pin below: + Введите PIN: + + + + PIN + + + + + Authorize + Авторизировать + + + + Not working + Не работает + + + + It works! + Работает! + + + + ImgurUploader + + + + KShare imgur Uploader + Загрузчик KShare на imgur + + + + Failed upload! Image too big + Не удалось загрузить! Изображение слишком велико + + + + Uploaded to imgur! + Загруено на imgur! + + + + KShare imgur Uploader + Загрузчик KShare на imgur + + + + Failed upload! imgur said: HTTP %1: %2 + Не удалось загрузить! imgur говорит: HTTP %1: %2 + + + + MainWindow + + + + Settings + Настройки + + + + Log + Журнал + + + + Fi&le + &Файл + + + + Scree&nshot + &Скриншот + + + + &Utilities + &Инструменты + + + + &Recording + &Запись + + + + &Quit + &Выход + + + + &Fullscreen + &Весь экран + + + + &Area + &Область + + + + &Color Picker + &Пипетка + + + + Start + Пуск + + + + Stop + Стоп + + + + About + О программе + + + + Active window + Активное окно + + + + Abort + Отмена + + + + Recording format not set in settings. Aborting. + Формат записи не задан в настроках! Отмена. + + + + QObject + + + + Could not bind the hotkey %1! Is the keybind already registered? + Не удалось привязать горячую клавишу %1! Клавиша уже зарегистрирована? + + + + Could not make config directory + Не удалось создать папку конфигураций + + + + Invalid file: + Неверный файл: + + + + Failed to upload! Copied the response to clipboard + Не удалось загрузить! Ответ скопирован в буфер обмена + + + + KShare imgplus Uploader + Загрузчик KShare на imgplus + + + + Uploaded to ImagePlus! + Загружено на ImagePlus! + + + + RecordingFormats + + + Could not create temporary directory. Error: + Не удалось создать временную папку. Ошибка: + + + + + Encoder error: + Ошибка кодировщика: + + + + RecordingPreview + + + Time: 00:00 +Frame: 0 +Stop key: + Время: 00:00 +Кадр: 0 +Стоп клавиша: + + + + Time: %1 +Frame: %2 +Stop key: %3 + Время: %1 +Кадр: %2 +Стоп клавиша: %3 + + + + ScreenAreaSelector + + + Set the recording region by resizing this. +%1x%2 + Задайте область захвата, переместив это. +%1x%2 + + + + KShare: Select Area (By resizing this window) + KShare: Выберите Область (Изменив размер этого окна) + + + + SettingsDialog + + + Crop editor settings + Настройки редактора кадрирования + + + + Quick mode (mouse release screenshots) + Быстрый режим (скриншот по отпусканию мыши) + + + + Delay before taking a screenshot + Задержка перед скриншотом + + + + In seconds + в секундах + + + + A delay before taking a screenshot, in seconds + Задержка перед скриншотом в секундах + + + + Hotkeys + Горячие клавиши + + + + Still image format + Формат изображений + + + + Recording format + Формат записей + + + + Capture cursor + Захватывать курсор + + + + %(date format)date and %ext are supported + поддерживаются %(формат даты)date и %ext + + + + File name scheme: + Формат имени файла: + + + + Pressing <X> hides to tray + Нажатие <X> скрывает в трей + + + + Open settings directory + Открыть папку настроек + + + + Destination: + Сервис: + + + + Pictures folder + Папка картинок + + + + Screenshots folder (In your user folder) + Папка скриншотов (В папке пользователя) + + + + File save location + Место сохранения файлов + + + + Advanced + Расширенные + + + + Editor Position (tweak if the editor does not cover the entire screen) + Позиция редактора (регулируйте, если редактор покрывает не всю область) + + + + Encoder settings + Настройки кодировщика + + + + Fullscreen image + Полноэкранное изображение + + + + Area image + Изображение области + + + + Active window + Активное окно + + + + Color picker + Пипетка + + + + Stop Recording + Остановить запись + + + + Start Recording + Начать запись + + + + Capture cursor (disabled: implementation missing) + Захват курсора (отключено: реализация отсутсвует) + + + + TextItem + + + Text to add + Текст для добавления + + + + Input + Ввод + + + + UploaderSingleton + + + Cannot determine location for pictures + Не удается установить расположение изображений + + + + Cannot determine location of your home directory + Не удается установить расположение вашей домашней директории + + + + Invalid config [saveLocation not int or is not in range] + Неверная конфигурация [saveLocation not int or is not in range] + + + + Ambigious uploader + Двусмысленный загрузчик + + + + Currently selected uploader is not set up properly! Falling back to imgur + Текущий загрузчик не настроен корректно! Возвращаемся к imgur + + + + + + KShare - Failed to save picture + KShare - Не удалось сохранить изображение + + + From d2002c47321525ef95b04e526fc8f7b358faf5b1 Mon Sep 17 00:00:00 2001 From: L1Q <0xL1Q@ex.ua> Date: Sun, 30 Jul 2017 06:58:06 +0300 Subject: [PATCH 127/293] Fix russian translation --- translations/ru_RU.qm | Bin 24860 -> 25013 bytes translations/ru_RU.ts | 30 +++++++++++++++--------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/translations/ru_RU.qm b/translations/ru_RU.qm index 0c200eb1a18b1670e1ee3d24acfb71ce0944f7c0..3971bce7164d45c4de030e298e4c46c47000b5d6 100644 GIT binary patch delta 1888 zcmZ`(dr(wm96gu4cX#jIySoAlnu?;C2!bFF@dYRd3V}R)fMjYat`ERqMM`H{e57b4 z)%px4P1BGzQ^AbMqufQfb=ObwjU&C8{id-fs1mkANkV3jW5`s%70YjGy!B?7rK?{UoC7D3Pav|Ky3OjrU3-Q}dl2{S4 z#;yYfJQZGDeG8DCf-QpJKcE7JnVJLX8))rq&8fv7k+@ZJ>IelS`)VG{iUrbkYFcaP)C<3hJuB&ud#UKN zrydB}BwE+3B0dtg#vi5CZ;3mv1+sOC;_=cy0iPD}->p+5= z*c$RNt+^`c5<-BG^OEb9B4Esyl7C?<1@4fBpFTv(r%Sna<^U#Z7bee>Y}O{gC`)T< zxlYwfZ|$W6q4Cl_`3DOBP^wnB(bQt8!AW6;D(PA(g?hP2_by!Gyo*w+{X`0ru~IAB za{<44tz-TXAj+)W-7tw8_0?A0lo`y!+S7@yI2OQSdJ&mO05&D*I7{2~x`af)snEn#kP<#sryeGS@y#S=H zkyCw`oq=KU^eGdVr8Ifj1_#iuM1KD$*NyEX@2r|lp>yN|YsnjPS^j!%EpJ|uUB0NX zv4=^DaP0vtoT-R+Nhse^0?YF_b}CVRB#sMJlG8{qzDmisPN&$Exs7Mp!-b=lzDCfdaqN;4{QKNXDanu$YUNr%qLoj+|OK2Ttc+p<(~pxlOWU+cMpKIulyJ6Fy zZ9LfqLuJZD-ljmq$s{_Qv|d%K_`a|_R=wn7Z0!v-P+?Z=K>=!r?ne^jsWBzAZuA~C z^*JgXGeym}GypwTscUC$VKxHP_4nz(q&D?~Crq~`U;RqpNqV2|!f{8{+f56(zQgEg zoxzQ_8wVFMI}>fj#9u}*(d-Zz;J*7BNq<(V!{ zUC9mmnC^#e*J{*s*R=c75EupoCyKvr%+PXEZxp?Bxl z=4f>7RZ(izX#{^qhg&a4xogjgMz;jP>;`Xfq&P|p6QhYS4qr>KyQkQfl}J`1_&b)E z=vZh8`rrD#XVh;$qweGJ|2*@aQQz~7db3Bc&%dR9Y0JDjlrh9UoXW^xn_kR9FQh8PEm-T&bn OBgTlsDpKOk^!yubWd*+g delta 1766 zcmZuxX-rgS6g`jm9y9ai%?!dgR0KsuSzN#Y+?7=p85BhXX=|xsu&z~9tR@|`)~$5| z6<%g@&Mr72Km}<5pW2qCl})rGgrl+Ma6CG|^w@eRsZl@A=L>cYdgrHdjfj zEsg>pITeWV0!H2h2E{|B1p2w1uw2>%UT zzZO75KDuA=VcZUzTQ<+H5W9XY5E({1Mx2JY4Oy(a0z+DF16;jfKinB`L_S1PDld#G z#Awe_lBh=dST=IojP#u>5S@t+U+e@d{+N)_fr%euQkoMm@C9bYl6d5Hyywsn@D>U_hLSV>AsWMRp(vM0%mDB*;;-nVsP#`qWsaur`(C$m8 z(Hj;49q&3Ff94OQxH`SsOM)qTG&-j(KuoPhxyW;HgGOm4j!M#m{9Ni_qk7HcBjbU@ zewrD@DxfrKic?oo!c@)aX(ZBMRaxD0P$Aax0Ju9ug-uJ>|<2#HnRffV)=IKDGe?OC#pU>HLlDp+JlaQa>=ga|0epH@%e;i%YXF3L=knWndcw!K`VSI~+vNOw7GKcX=MB2gcYbk}${6Fcz6Bwa z*iT#3n~kF$YAfbZNtX(3Wlh5Jfqsw3E4NL1Od9vPh$weUP zv3|HOz0-N4{)3b_dZ|o5cV!;n-J;K}U|#qt{g(2vRO-IIcnRx9CFl=lR&$gU4*gY4 zHeG!{k#0SrM2$+|?&-W3s)Plw;NU`K*a#-Z`YCC(REWdKyl{?dIZm1Q9%mYHQdxSF zd1)_|oz`_g+Xu?-;*~)EBg*l7)-i1-&LGwi*~i?8IFmS*IE(1m%8%Lns3qo5vi8aa zr)aLx@5;^drEK@P^5hz4*6+GO*M^1L*Bg?&Pf*IMhS`s`G*fTGXZtijhdG9IejE6r zzYL{GLxE0f4W|;Rto@m)mh*qYlA(I(D@kOm8mQ1Cfw^k1_A>Y1dPR*|Mac#z>hLyX z8g@{fVX0x^Ms>+Y`E+Tny1a=BB#%=!zND+&uBwM5zQi-|4MulW8}CeHex}iyHHPae z8N24tGl{p2_FwvPZ4Jha`$?dk)wsJmy^!i<-1m1C`?wlw_D<*i$F4En+r+~DcTDE< z!Mw28G-z&bnq!VBY|2PBOgBv(;z>monzGmUQ|cb3b?cYY6C+IftGS+@S4>w&Eo8$L zrlyd!^nhe)y3VbLdunRQxB-l=H>;QGfP}f`NnTM@Xr_7kWd3fqns@yAJqucW%%xL! zq5o9#@g6NifAi_GZJcde^ZjiL0I!@+fcMi%4$2Ms5_cCxlNaP6+9!yfB3uNCNMVP! zh!HjsDkAySPxKKHBC^EpmLi!wcqR1TBZK@Quh?QUyNZrtkmxVs85<~q@*Z1)-iq~U z{dR2LJ7SgZh)LGBbEDr8TVl2OTF46_z3sc^} <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Blur Hints - + @@ -95,37 +95,37 @@ Dense 1 - Толщина 1 + Плотность 1 Dense 2 - Толщина 2 + Плотность 2 Dense 3 - Толщина 3 + Плотность 3 Dense 4 - Толщина 4 + Плотность 4 Dense 5 - Толщина 5 + Плотность 5 Dense 6 - Толщина 6 + Плотность 6 Dense 7 - Толщина 7 + Плотность 7 @@ -140,7 +140,7 @@ Cross pattern - Крестики + В клетку @@ -155,12 +155,12 @@ Diagonal cross - Диагональные крестики + В клетку по диагонали Choose brush color - Выбрать цвет кисти + Выбрать цвет штриховки @@ -507,7 +507,7 @@ Bitrate - Витрейт + Битрейт @@ -635,7 +635,7 @@ p, li { white-space: pre-wrap; } KShare imgur Uploader - Загрузчик KShare на imgur + Imgur загрузчик KShare @@ -645,12 +645,12 @@ p, li { white-space: pre-wrap; } Uploaded to imgur! - Загруено на imgur! + Загружено на imgur! KShare imgur Uploader - Загрузчик KShare на imgur + Imgur загрузчик KShare From 1ffc8c5179b4792a527e52f5e938aad446ea539f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 30 Jul 2017 11:14:17 +0200 Subject: [PATCH 128/293] Fix tray button order --- mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index a23cef8..b1e1eb7 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -81,7 +81,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi menu->addSeparator(); menu->addActions({ fullscreen, area }); #ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW - menu->addAction(area); + menu->addAction(active); #endif menu->addSeparator(); menu->addActions({ rec, recoff, recabort }); From a310a8f70f744185b9a1dbc897bcaf79cf8c73dd Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 31 Jul 2017 00:21:24 +0200 Subject: [PATCH 129/293] Add Bulgarian translations --- mainwindow.cpp | 2 +- mainwindow.hpp | 1 + translations.qrc | 1 + translations/bg_BG.qm | Bin 0 -> 26308 bytes translations/bg_BG.ts | 1014 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1017 insertions(+), 1 deletion(-) create mode 100644 translations/bg_BG.qm create mode 100644 translations/bg_BG.ts diff --git a/mainwindow.cpp b/mainwindow.cpp index b1e1eb7..2c32327 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -63,7 +63,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi tray = new QSystemTrayIcon(windowIcon(), this); tray->setToolTip("KShare"); tray->setVisible(true); - QMenu *menu = new QMenu(this); + menu = new QMenu(this); QAction *quit = ACTION("Quit", menu); QAction *shtoggle = ACTION("Show/Hide", menu); QAction *fullscreen = ACTION("Take fullscreen shot", menu); diff --git a/mainwindow.hpp b/mainwindow.hpp index 88a3d36..bd2d0d1 100644 --- a/mainwindow.hpp +++ b/mainwindow.hpp @@ -46,6 +46,7 @@ public slots: private: bool val = false; QMap acts; + QMenu *menu; static MainWindow *instance; protected: diff --git a/translations.qrc b/translations.qrc index 8a5fc91..764c5d4 100644 --- a/translations.qrc +++ b/translations.qrc @@ -2,5 +2,6 @@ translations/sr_RS.qm translations/ru_RU.qm + translations/bg_BG.qm diff --git a/translations/bg_BG.qm b/translations/bg_BG.qm new file mode 100644 index 0000000000000000000000000000000000000000..adf773f836f290ba4c8a8c86b3585ee079288987 GIT binary patch literal 26308 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 literal 0 HcmV?d00001 diff --git a/translations/bg_BG.ts b/translations/bg_BG.ts new file mode 100644 index 0000000..a9c9d4f --- /dev/null +++ b/translations/bg_BG.ts @@ -0,0 +1,1014 @@ + + + + + AboutBox + + + About KShare + За KShare + + + + <html><head/><body><p><img src=":/icons/icon.svg" width="50" style="vertical-align: middle;"/><span style=" font-weight:600; vertical-align:middle;"> KShare</span><span style=" vertical-align:middle;"> - The free and open source and cross platform screen sharing software</span></p><p>Version %0<br/>Links: <a href="https://github.com/ArsenArsen/KShare"><span style=" text-decoration: underline; color:#007af4;">Source code</span></a>, <a href="https://github.com/ArsenArsen/KShare/issues"><span style=" text-decoration: underline; color:#007af4;">Issue tracker</span></a>, <a href="http://kshare.arsenarsen.com"><span style=" text-decoration: underline; color:#007af4;">Website</span></a>, <a href="https://patreon.com/arsen"><span style=" text-decoration: underline; color:#007af4;">Patreon</span></a></p></body></html> + <html><head/><body><p><img src=":/icons/icon.svg" width="50" style="vertical-align: middle;"/><span style=" font-weight:600; vertical-align:middle;"> KShare</span><span style=" vertical-align:middle;"> - свободния и отворен софтуер за споделяне на екран</span></p><p>Версия %0<br/>Линкове: <a href="https://github.com/ArsenArsen/KShare"><span style=" text-decoration: underline; color:#007af4;">Програмен код</span></a>, <a href="https://github.com/ArsenArsen/KShare/issues"><span style=" text-decoration: underline; color:#007af4;">Тракер на проблемите</span></a>, <a href="http://kshare.arsenarsen.com"><span style=" text-decoration: underline; color:#007af4;">Уебсайт</span></a>, <a href="https://patreon.com/arsen"><span style=" text-decoration: underline; color:#007af4;">Patreon</span></a></p></body></html> + + + + BrushPenSelection + + + Pen settings + Настройки на химикала + + + + Choose pen color + Изберете цвят на химикала + + + + Cosmetic + Козметично + + + + Width + Широчина + + + + Pen alpha + Алфа на химикала + + + + Blur settings + Настройки на замъгляването + + + + Performance Hint + Намек за производителност + + + + <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Blur Hints + <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Намеци за замъгляването + + + + Blur Radius + Радиус на замъгляването + + + + Animated Hint + Намек за анимация + + + + Quality Hint + Намек за качество + + + + Brush settings + Настройки на четката + + + + Brush alpha + Алфа на четката + + + + No Brush + Без четка + + + + Solid + Солидно + + + + Dense 1 + Плътно 1 + + + + Dense 2 + Плътно 2 + + + + Dense 3 + Плътно 3 + + + + Dense 4 + Плътно 4 + + + + Dense 5 + Плътно 5 + + + + Dense 6 + Плътно 6 + + + + Dense 7 + Плътно 7 + + + + Horizontal + Хоризонтално + + + + Vertical + Вертикално + + + + Cross pattern + Шарка с кръстове + + + + Backwards diagonal + Обратно диагонално + + + + Forwards diagonal + Право диагонално + + + + Diagonal cross + Диагонални кръстове + + + + Choose brush color + Изберете цвят на четката + + + + Path item has brush + Елемента по пътя има четка + + + + Arrow settings + Настройки на стрелката + + + + Arrow width and height + Широчина и височина на стрелката + + + + Crop editor settings + Настройки на редактора за кастрене + + + + Pen Color + Цвят на химикала + + + + Brush Color + Цвят на четката + + + + ClipboardUploader + + + Copied to clipboard! + Копирано в клипборда! + + + + ColorPickerScene + + + KShare Color Picker + KShare избирач на цветове + + + + CropEditor + + + KShare Crop Editor + KShare редактор за кастрене + + + + CropScene + + + Free draw + Свободно рисуване + + + + Blur + Замъгляване + + + + Straight line + Права линия + + + + Text + Текст + + + + Rectangle + Правоъгълник + + + + Ellipse + Елипса + + + + Arrow + Стрелка + + + + Eraser + Гума + + + + Clear all drawing + Изтрий всички рисунки + + + + Crop + Изкастряй + + + + Settings + Настройки + + + + Confirm + Потвърди + + + + Cancel + Отказ + + + + KShare Crop Editor + KShare редактор за кастрене + + + + Press F1 to toggle this hint + Hold Shift to slow the cursor down + Ctrl+Drag a thing to move it around + Alt+Click a drawing to remove it + Press Return/Enter to finish + Press ESC to cancel + Use the menu bar to draw + NOTE: You must select 'Crop' before closing the editor + If you do not it will not close. + Натиснете F1 за да покажете или да скриете този намек + Задръжте Shift за да забавите курсора + Ctrl+Провлачете нещо за да го изместите + Alt+Кликнете върху рисунка за да я премахнете + Натиснете Return/Enter за да приключите + Натиснете ESC за да откажете + Използвайте лентата с меню за да рисувате + ЗАБЕЛЕЖКА: Трябва да изберете 'Изкастряй' преди да затворите редактора + Ако не направите това, той няма да се затвори + + + + CustomUploader + + + Root not an object + Коренът не е обект + + + + name is not a string + името не е низ + + + + desc not a string + описанието не е низ + + + + method not a string + методът не е низ + + + + method invalid + методът не е валиден + + + + target missing + челта липсва + + + + target not URL + челта не е URL + + + + format invalid + форматът е невалиден + + + + format provided but not string + форматът е предоставен, но не е низ + + + + body not set + тялото не е зададено + + + + all elements of body must be objects + всички елементи от тялото трябва да бъдат обекти + + + + all parts must have a body which is object or string! + всички части трябва да имат тяло, което е или обект, или низ! + + + + all parts of body must be string or object + всички части от тялото трябва да са или низ, или обект + + + + all __headers must be strings + всички __хедъри трябва да са низове + + + + body not array (needed for multipart) + тялото не е масив (нужно за multipart) + + + + body not object + тялото не е обект + + + + body not string (reason: format: PLAIN) + `format: PLAIN` should stay the same + тялото не е низ (причина: format: PLAIN) + + + + headers must be object + хедърите трябва да са обекти + + + + return invalid + връщането е невалидно + + + + fileLimit not decimal + fileLimit stays English + fileLimit не е десетичен + + + + base64 must be boolean + base64 трябва да е булев + + + + base64 required with json + base64 е задължителен с json + + + + + + + + + KShare Custom Uploader + KShare персонализиран ъплоудър + + + + Copied upload link to clipboard! + Линкът за качване е копиран в клипборда! + + + + Upload done, but result empty! + Качването завърши, но резултатът е празен! + + + + Upload done, but result is not JSON Object! Result in clipboard. + Качването завърши, но резултатът не е JSON обект! Резултатът е в клипборда. + + + + + Copied upload result to clipboard! + Резултатът от копирането е копиран в клипборда! + + + + File limit exceeded! + Ограничението на файловете бе превишено! + + + + EncoderSettingsDialog + + + Image Encoder Settings + Настройки на енкодера за изображения + + + + <html><head/><body><p><a href="http://doc.qt.io/qt-5/qpixmap.html#save"><span style=" text-decoration: underline; color:#007af4;">Quality</span></a></p></body></html> + <html><head/><body><p><a href="http://doc.qt.io/qt-5/qpixmap.html#save"><span style=" text-decoration: underline; color:#007af4;">Качество</span></a></p></body></html> + + + + Format default + Формат по подразбиране + + + + Video Encoder Settings + Настройки на енкодера за видео + + + + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">Preset</span></a></p></body></html> + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">Предварително зададени настройки</span></a></p></body></html> + + + + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">CRF</span></a></p></body></html> + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">CRF</span></a></p></body></html> + + + + Lossless (not recommended) + Без загуба (не се препоръчва) + + + + TODO: Find whatever configuration GIF can have in ffmpeg's libav + TODO: Find whatever configuration GIF can have in ffmpeg's libav + + + + Bitrate + Битрейт + + + + The number of pictures in a group of pictures, or 0 for intra only + Броя на снимките в група от снимки, или 0 само за вътрешни + + + + GOP size + Размер на GOP + + + + KShare Encoder Settings + KShare настройки на енкодера + + + + HotkeyInputDialog + + + + + Record + Запиши + + + + Stop recording + Спри записватено + + + + ImgplusUploader + + + imgplus API key + imgplus ППИ ключ + + + + Enter the imgpl.us API key (Found in Settings) + Въведете imgpl.us ППИ ключа (Намерен в Настройки) + + + + ImgurSettingsDialog + + + Imgur auth + Imgur автентикация + + + + OAuth2 + OAuth2 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Create a new application:</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Създай ново приложение:</p></body></html> + + + + Open imgur + Отвори Imgur + + + + Insert Client ID and secret: + Въведете ID на клиента и тайна: + + + + Client ID + ID на клиента + + + + Client Secret + Тайна на клиента + + + + Get the pin + Вземи пина + + + + Insert the pin below: + Въведете пина долу: + + + + PIN + ПИН + + + + Authorize + Упълномощи + + + + Not working + Не работи + + + + It works! + Работи! + + + + ImgurUploader + + + + KShare imgur Uploader + KShare ъплоудър за Imgur + + + + Failed upload! Image too big + Качването не е успешно! Изображението е твърде голямо + + + + Uploaded to imgur! + Качено в Imgur! + + + + KShare imgur Uploader + KShare ъплоудър за Imgur + + + + Failed upload! imgur said: HTTP %1: %2 + Качването не бе успешно! Imgur каза: HTTP %1: %2 + + + + MainWindow + + + + Settings + Настройки + + + + Log + Дневник + + + + Fi&le + &Файл + + + + Scree&nshot + &Снимка на екрана + + + + &Utilities + &Инструменти + + + + &Recording + &Запис + + + + &Quit + &Излез + + + + &Fullscreen + &Цял екран + + + + &Area + &Район + + + + &Color Picker + &Избирач на цветове + + + + Start + Започни + + + + Stop + Спри + + + + About + За + + + + Active window + Активен прозорец + + + + Abort + Абортирай + + + + Recording format not set in settings. Aborting. + Форматът за записване не е зададен в настройките. Абортиране. + + + + QObject + + + + Could not bind the hotkey %1! Is the keybind already registered? + Свързването на клавиша %1 е неуспешно! Клавишът регистриран ли е вече? + + + + Could not make config directory + Съдаването на директорията config е неуспешно + + + + Invalid file: + Неправилен файл: + + + + Failed to upload! Copied the response to clipboard + Качването е неуспешно! Отговорът е копиран в клипбодра + + + + KShare imgplus Uploader + KShare ъплоудър за imgplus + + + + Uploaded to ImagePlus! + Качено в ImagePlus! + + + + RecordingFormats + + + Could not create temporary directory. Error: + Създаването на временна директория е неуспешно. Грешка: + + + + + Encoder error: + Грешка в енкодера: + + + + RecordingPreview + + + Time: 00:00 +Frame: 0 +Stop key: + Време: 00:00 +Кадър: 0 +Клавиш за спиране: + + + + Time: %1 +Frame: %2 +Stop key: %3 + Време: %1 +Кадър: %2 +Клавиш за спиране: %3 + + + + ScreenAreaSelector + + + Set the recording region by resizing this. +%1x%2 + Нагласете района на записване като промените размера на този прозорец. +%1x%2 + + + + KShare: Select Area (By resizing this window) + KShare: Изберете район (Като сменяте размера на този прозорец) + + + + SettingsDialog + + + Crop editor settings + Настройки на редактора за кастрене + + + + Quick mode (mouse release screenshots) + Бърз режим (снимка при пускане на мишката) + + + + Delay before taking a screenshot + Закъснение преди правене на снимка + + + + In seconds + В секунди + + + + A delay before taking a screenshot, in seconds + Закъснение преди правене на снимка, в секунди + + + + Hotkeys + Клавиши + + + + Still image format + Формат на неподвижни снимки + + + + Recording format + Формат на записи + + + + Capture cursor + Заснеми курсора + + + + %(date format)date and %ext are supported + %(date format)date и %ext сe поддържат + + + + File name scheme: + Схема за имената на файловете + + + + Pressing <X> hides to tray + Натискане на <X> скрива програмата в системниия tray + + + + Open settings directory + Отвори директорията на настройките + + + + Destination: + Дестинация: + + + + Pictures folder + Папка за снимки + + + + Screenshots folder (In your user folder) + Папка за снимки на екрана (Във вашата потребителска папка) + + + + File save location + Място за записване на файлове + + + + Advanced + Разширени + + + + Editor Position (tweak if the editor does not cover the entire screen) + Позиция на редактора (променете ако редакторът не покрива целия екран) + + + + Encoder settings + Настройки на енкодера + + + + Fullscreen image + Снимка на целия екран + + + + Area image + Снимка на район + + + + Active window + Активен прозорец + + + + Color picker + Избирач на цветове + + + + Stop Recording + Спри записването + + + + Start Recording + Стартирай записването + + + + Capture cursor (disabled: implementation missing) + Заснеми курсора (изключено: липсва имплементация) + + + + TextItem + + + Text to add + Текст за добавяне + + + + Input + Вход + + + + UploaderSingleton + + + Cannot determine location for pictures + Мястото за снимки не можа да се намери + + + + Cannot determine location of your home directory + Домашната ви директория не можа да се намери + + + + Invalid config [saveLocation not int or is not in range] + Неправилна конфигурация [saveLocation не е int или не е в диапазона] + + + + Ambigious uploader + Неясен ъплоудър + + + + Currently selected uploader is not set up properly! Falling back to imgur + Избраният ъплоудър не е нагласен правилно! Връщане към Imgur + + + + + + KShare - Failed to save picture + KShare - Неуспешно записване на снимка + + + From b081b5adc1e8da10a105dadc0c21edecc871cb1f Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 31 Jul 2017 20:02:47 +0200 Subject: [PATCH 130/293] Update CI links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a470859..3ae9f68 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,9 @@ See the [projects](https://github.com/ArsenArsen/KShare/projects) |Distro|Link| |:----:|:--:| |Arch Linux (development)|[kshare-git](https://aur.archlinux.org/packages/kshare-git/)| -|Ubuntu/Debian (development)|[.deb](https://nativeci.arsenarsen.com/job/KShare/lastSuccessfulBuild/artifact/packages/simpleName.deb)| +|Ubuntu/Debian (development)|[.deb](https://nativeci.arsenarsen.com/job/KShare%20(dev\)/main=linux/lastSuccessfulBuild/artifact/build/KShare)| |Arch Linux |[kshare](https://aur.archlinux.org/packages/kshare/)| -|Ubuntu/Debian |[.deb](https://nativeci.arsenarsen.com/job/KShare%20Stable/lastSuccessfulBuild/artifact/packages/simpleName.deb )| +|Ubuntu/Debian |[.deb](https://nativeci.arsenarsen.com/job/KShare%20(master\)/main=linux/lastSuccessfulBuild/artifact/build/KShare)| For other UNIX-like platforms, and MSYS2 (for Windows): From 433ee87ce5f9438927c484dc685bc49c3bd7461a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 1 Aug 2017 23:33:45 +0200 Subject: [PATCH 131/293] Make tray options translatable --- mainwindow.cpp | 30 +++++++++------------------ mainwindow.hpp | 1 - translations/sr_RS.qm | Bin 23983 -> 24744 bytes translations/sr_RS.ts | 47 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 22 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 2c32327..22375ba 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -38,20 +38,10 @@ void MainWindow::rec() { #define ACTION(english, menu) \ [&]() -> QAction * { \ - QAction *a = menu->addAction(tr(english)); \ - acts.insert(a, english); \ + QAction *a = menu->addAction(english); \ return a; \ }() -void MainWindow::changeEvent(QEvent *e) { - if (e->type() == QEvent::LocaleChange) { - ui->retranslateUi(this); - for (auto key : acts.keys()) { - key->setText(tr(acts.value(key))); - } - } -} - void addHotkey(QString name, std::function action) { hotkeying::load(name, action); } @@ -64,19 +54,19 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi tray->setToolTip("KShare"); tray->setVisible(true); menu = new QMenu(this); - QAction *quit = ACTION("Quit", menu); - QAction *shtoggle = ACTION("Show/Hide", menu); - QAction *fullscreen = ACTION("Take fullscreen shot", menu); - QAction *area = ACTION("Take area shot", menu); + QAction *quit = ACTION(tr("Quit"), menu); + QAction *shtoggle = ACTION(tr("Show/Hide"), menu); + QAction *fullscreen = ACTION(tr("Take fullscreen shot"), menu); + QAction *area = ACTION(tr("Take area shot"), menu); #ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW - QAction *active = ACTION("Screenshot active window", menu); + QAction *active = ACTION(tr("Screenshot active window"), menu); connect(active, &QAction::triggered, this, [] { screenshotter::activeDelayed(); }); #endif - QAction *picker = ACTION("Show color picker", menu); - QAction *rec = ACTION("Record screen", menu); - QAction *recoff = ACTION("Stop recording", menu); - QAction *recabort = ACTION("Abort recording", menu); + QAction *picker = ACTION(tr("Show color picker"), menu); + QAction *rec = ACTION(tr("Record screen"), menu); + QAction *recoff = ACTION(tr("Stop recording"), menu); + QAction *recabort = ACTION(tr("Abort recording"), menu); menu->addActions({ quit, shtoggle, picker }); menu->addSeparator(); menu->addActions({ fullscreen, area }); diff --git a/mainwindow.hpp b/mainwindow.hpp index bd2d0d1..c130c76 100644 --- a/mainwindow.hpp +++ b/mainwindow.hpp @@ -45,7 +45,6 @@ public slots: private: bool val = false; - QMap acts; QMenu *menu; static MainWindow *instance; diff --git a/translations/sr_RS.qm b/translations/sr_RS.qm index 72cd5da88b78b8eefedaa0dcf7e4ca2d125ee7ab..3690bcafd21df2c7bee4a2f59ee663bd71e4e895 100644 GIT binary patch delta 1379 zcmZ8f4NR1E9Dd$=?;GyDaeR&)^kRr1@*%NM%LC-&1o=Kb&s7}9DaYX*9A9BGl2)P1 zioIx?j9Fu26bvF==n%1xGAn99Ury5rF$;1`F*O_ZyJIoOZSVcwkKgnBp6B`f2S=FR z&zN_86gL4wF_75P9u%1UmYD8-fTXVsNPZoX{v|*=j4($akkgEfZ9{-giwIYr?t4W3 z6iV+ki1n@m61GEstb?kP>IJIz+Yk7+yoB6hdMHXlsrD35V1}`rNPYTX?4{=9Vm$w_ z7x0ZjWmyQ|y$7}u5%BD*sOcXDc07Rwy-QxqO3m!Tdm$Tu_03prZ=xYRjHZ79(D01U z-z37z#)Q8}{3#_&Y^MQef0(Gr=wd!Os3EQ~=3JHpFsg)9CTvH+fM|Jus0(+oa?$%h zS`Vw7qUX)RN=-h^D(|?yFR=Vl3Q;Q9xL?SE@;+NVW&yH7g)Syoncd3XE=vXS#)Jtb zYF$d7_>0baK-gjN#Y3M1{)^)4cYT1T%EhxY*Man8!B_N*D0@Q45{2a#o{&uTzXo_V zNUr5gP}cR5TT{Q1hIz@IFLMF?pj6Rf2f|CGLgg^Ua#z~@X(7etE$yBpd)%1x%nb!? za9TS47qRa&3!|domNY+EfBZC%G$T9vvL~f7Av@Q<2t+T)F6Ev9qW+Z4rF}@S-LknG zn}KbYT`Psq|HcXj%K$(+YPAT6OM%iFdiBY)9 zzM;uK>TxPJ8+cOXaWRVoWd0#Eh|^jO9-hblJxizLH_s7P|577|~`cd^!B>62GRt-L)B|O)xnjEO5I1Q@#PT~z$ za_aA%28shX-TrurRl+6gE1-F$oIOK}-B|xESJxg+4Igtyj~yms|8PU&ACQn4?&qRb z8hDUfjOzeGb==~W8OnWxTPnK>lt!pMr)Pm(HEMq5Z92A()V82x3c*iZTTOkLoNz=E zAv1QcfHXreZS@zTqXSOfk~Ag=dGS$lbyB&*SII$cEGtx7GQ9*)Kxm_d6T)`+GydMto8~=lbbhCzdbP& zxrB4`GOxIK%ITjZF)Er;PHa^$t@3#pDjiL{*-`Cq@-9xozv#_^Tjyj>iLfOa)h9vRQbO(_-SunJZTvzXonz Z3tv^?;|A|(sIFc~_BE&zPDs*r0bHDYicT$m}Y6FuI}pUdeq{gVUiemgh__=hY?g3 zQR%OPjOc<;+w!Q8%A>MKrL3@vs0i02(n7k8w5IxNnBUBAzVn%x#+zKrb?%_2`V^3D z2Ug_N`T2yMF9722!rl1=(09PN(FaKDLvU>y5UWSXJ~y%t5&Co;O_937-m* zfDD;UabbM?PZr7>cvC&I@{xR+C)>#z`K*uZ0&fUToK~o7%7LI<1zX<%#C%np9n1#g z9>vvRHL=cB^nQ2)B(<|C-cXZJq;xKMOvrPTo!h8`8F!T3&IurVTsdI73WU8^j+&YP zTeEU>cp2rMwGZcoPo=}oH98~%WQt!k`t z60qvjn%cKOs6p+qdx-o`>de4BU=2c$xMI7yYh5qVonZF`qqy>(n2}WoB*wET!N9L- zVt#JBJTgW!mu>05TuIYsr3Nff?24PI#^%sA{OY9Dz1CjmXdn8h|295P`_8q2`V}Pa z;x+WGN($LR_^G~9+KXr)*+*(MRfC zi3qx>d9m`uOBY}gOtkaži - + KShare Crop Editor KShare Urednik Slika @@ -740,6 +740,51 @@ p, li { white-space: pre-wrap; } Recording format not set in settings. Aborting. Format snjimanja nije podešen! Otkazujem. + + + Quit + Izađi + + + + Show/Hide + Prikaži/Sakrij + + + + Take fullscreen shot + Slikaj ceo ekran + + + + Take area shot + Slikaj deo ekrana + + + + Screenshot active window + Slikaj trenutni prozor + + + + Show color picker + Prikaži birač boja + + + + Record screen + Snjimi ekran + + + + Stop recording + Zaustavi snjimanje + + + + Abort recording + Obustavi snjimanje + QObject From 741cb8daf09d20d2061800302636a37e820d5be5 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 1 Aug 2017 23:37:01 +0200 Subject: [PATCH 132/293] Oops --- mainwindow.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/mainwindow.hpp b/mainwindow.hpp index c130c76..5bb6e75 100644 --- a/mainwindow.hpp +++ b/mainwindow.hpp @@ -49,7 +49,6 @@ private: static MainWindow *instance; protected: - void changeEvent(QEvent *e) override; void closeEvent(QCloseEvent *event) override; }; From ad1734927b7c9d2d70c906be7f03f30b5a868af6 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 2 Aug 2017 01:20:35 +0200 Subject: [PATCH 133/293] Update links --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3ae9f68..35d0bd5 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,11 @@ See the [projects](https://github.com/ArsenArsen/KShare/projects) |Distro|Link| |:----:|:--:| |Arch Linux (development)|[kshare-git](https://aur.archlinux.org/packages/kshare-git/)| -|Ubuntu/Debian (development)|[.deb](https://nativeci.arsenarsen.com/job/KShare%20(dev\)/main=linux/lastSuccessfulBuild/artifact/build/KShare)| +|Ubuntu/Debian (development)|[.deb](https://nativeci.arsenarsen.com/job/KShare%20\(dev\)/main=linux/lastSuccessfulBuild/artifact/packages/simpleName.deb)| +|OS X (development)|[.dmg](https://nativeci.arsenarsen.com/job/KShare%20\(dev\)/main=osx/lastSuccessfulBuild/artifact/build/KShare.dmg)| |Arch Linux |[kshare](https://aur.archlinux.org/packages/kshare/)| -|Ubuntu/Debian |[.deb](https://nativeci.arsenarsen.com/job/KShare%20(master\)/main=linux/lastSuccessfulBuild/artifact/build/KShare)| +|Ubuntu/Debian |[.deb](https://nativeci.arsenarsen.com/job/KShare%20\(master\)/main=linux/lastSuccessfulBuild/artifact/packages/simpleName.deb)| +|OS X|[.dmg](https://nativeci.arsenarsen.com/job/KShare%20\(master\)/main=osx/lastSuccessfulBuild/artifact/build/KShare.dmg)| For other UNIX-like platforms, and MSYS2 (for Windows): From c19221cd37b53437ed0e45a11ef44ddd706fafaf Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Thu, 3 Aug 2017 22:00:15 +0200 Subject: [PATCH 134/293] Make single screen overlays better --- colorpicker/colorpickerscene.cpp | 6 +++++- cropeditor/cropeditor.cpp | 5 ++++- cropeditor/cropscene.cpp | 2 +- cropeditor/cropscene.hpp | 1 - 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/colorpicker/colorpickerscene.cpp b/colorpicker/colorpickerscene.cpp index ad02c24..5899e8f 100644 --- a/colorpicker/colorpickerscene.cpp +++ b/colorpicker/colorpickerscene.cpp @@ -34,7 +34,11 @@ ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) ellipse->setBrush(color); image = pixmap.toImage(); - show(); + if (QApplication::screens().size() == 1) + showFullScreen(); + else + show(); + activateWindow(); setGeometry(pixmap.rect()); QPoint p = screenshotutil::smallestScreenCoordinate() diff --git a/cropeditor/cropeditor.cpp b/cropeditor/cropeditor.cpp index 511cd49..81ab8a6 100644 --- a/cropeditor/cropeditor.cpp +++ b/cropeditor/cropeditor.cpp @@ -13,7 +13,10 @@ CropEditor::CropEditor(QPixmap image, QObject *parent) : QObject(parent) { scene = new CropScene(parent, image); view = new CropView(scene); - view->show(); + if (QApplication::screens().size() > 1) + view->show(); + else + view->showFullScreen(); view->raise(); QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(image); pixmapItem->setZValue(-1); diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 33a6b49..1c70f71 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -200,9 +200,9 @@ void CropScene::show() { void CropScene::setVisible(bool visible) { for (auto view : views()) { - if (view->isVisible()) fullscreen |= view->isFullScreen(); view->setVisible(visible); if (visible) { + if (QApplication::screens().size() == 1) view->showFullScreen(); view->resize(_pixmap.width(), _pixmap.height()); view->setMinimumSize(_pixmap.size()); QPoint p = screenshotutil::smallestScreenCoordinate() + QPoint(settings::settings().value("cropx", 0).toInt(), diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index 8dce960..c965153 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -61,7 +61,6 @@ private: void updateMag(); void initMagnifierGrid(); void addDrawingAction(QMenuBar *menu, QString name, QString icon, std::function item); - bool fullscreen; QPointF cursorPos; std::function drawingSelectionMaker; QFlags prevButtons; From db1108079d850fc6614a64335f75f39f690441dd Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 5 Aug 2017 21:20:24 +0200 Subject: [PATCH 135/293] Make highlight colors and grid changeable --- colorpicker/colorpickerscene.cpp | 3 + cropeditor/cropscene.cpp | 34 +++++-- cropeditor/cropscene.hpp | 20 ++++ cropeditor/drawing/bluritem.cpp | 2 +- cropeditor/settings/brushpenselection.cpp | 12 +++ cropeditor/settings/brushpenselection.hpp | 4 +- cropeditor/settings/brushpenselection.ui | 106 ++++++++++++---------- 7 files changed, 122 insertions(+), 59 deletions(-) diff --git a/colorpicker/colorpickerscene.cpp b/colorpicker/colorpickerscene.cpp index 5899e8f..10118f7 100644 --- a/colorpicker/colorpickerscene.cpp +++ b/colorpicker/colorpickerscene.cpp @@ -1,6 +1,7 @@ #include "colorpickerscene.hpp" #include #include +#include #include #include #include @@ -76,9 +77,11 @@ void ColorPickerScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { void ColorPickerScene::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Return) QApplication::clipboard()->setText(color.name()); if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Escape) close(); + qInfo().noquote() << tr("Copied hex code to clipboard."); } void ColorPickerScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *) { QApplication::clipboard()->setText(color.name()); close(); + qInfo().noquote() << tr("Copied hex code to clipboard."); } diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 1c70f71..6125ebe 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -33,6 +33,7 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) brush().setColor(settings::settings().value("brushColor", brush().color()).value()); brush().setStyle( static_cast(settings::settings().value("brushStyle", static_cast(Qt::SolidPattern)).toInt())); + _highlight = settings::settings().value("highlightColor", QColor(Qt::cyan)).value(); menu = new QMenuBar; addDrawingAction(menu, tr("Free draw"), ":/icons/pencil.png", [] { return new PathItem; }); @@ -105,20 +106,19 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) cursorItem->setZValue(3); magnifier = addPixmap(QPixmap(110, 110)); - magnifierBox = addRect(magnifier->boundingRect(), QPen(Qt::cyan)); + magnifierBox = addRect(magnifier->boundingRect(), QPen(_highlight)); magnifier->setZValue(3); magnifierBox->setZValue(1.1); magnifierBox->setParentItem(magnifier); magnifierHint = addText("ptr: (0, 0)\nsel: (-1, -1, 0, 0)"); magnifierHint->setParentItem(magnifier); magnifierHint->setY(magnifier->boundingRect().height()); - QColor c(Qt::cyan); + QColor c(_highlight); c.setAlphaF(.25); magnifierHintBox = addRect(magnifierHint->boundingRect(), Qt::NoPen, c); magnifierHintBox->setParentItem(magnifierHint); magnifierHintBox->setZValue(1); magnifierHint->setZValue(1.1); - initMagnifierGrid(); updateMag(); addItem(hint); @@ -153,6 +153,7 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) int w = screen->geometry().width(); widget->setPos(views()[0]->mapToScene( QPoint(screen->geometry().x() + (w - widget->boundingRect().width()) / 2, screen->geometry().y() + 100))); + setGrid(settings::settings().value("gridEnabled", true).toBool()); }); } @@ -172,6 +173,19 @@ QFont &CropScene::font() { return _font; } +void CropScene::setHighlight(QColor highlight) { + _highlight = highlight; + QColor c = highlight; + c.setAlphaF(.4); + magnifierHintBox->setBrush(c); + if (grid()) setGrid(true); + if (rect) rect->setPen(highlight); + int i = settings::settings().value("magnifierPixelCount", 11).toInt() / 2; + if (gridRectsX.isEmpty() || gridRectsY.isEmpty()) return; + gridRectsX[i]->setBrush(c); + gridRectsY[i]->setBrush(c); +} + void CropScene::setDrawingSelection(QString name, std::function drawAction) { this->setFocus(); drawingSelectionMaker = drawAction; @@ -229,7 +243,7 @@ void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { QCursor::setPos(views()[0]->mapToGlobal(cursorPos.toPoint())); } else cursorPos = e->scenePos(); - hint->setVisible(!hint->sceneBoundingRect().contains(cursorPos)); + hint->setVisible(settings::settings().value("crophint").toBool() && !hint->sceneBoundingRect().contains(cursorPos)); cursorItem->setPos(cursorPos); updateMag(); @@ -248,7 +262,7 @@ void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { rect = new QGraphicsRectItem(p.x(), p.y(), 1, 1); initPos = p; QPen pen(Qt::NoBrush, 1); - pen.setColor(Qt::cyan); + pen.setColor(_highlight); rect->setPen(pen); rect->setZValue(1); addItem(rect); @@ -322,7 +336,7 @@ void CropScene::wheelEvent(QGraphicsSceneWheelEvent *event) { for (auto item : gridRectsY) delete item; gridRectsY.clear(); - initMagnifierGrid(); + if (grid()) initMagnifierGrid(); updateMag(); if (!(event->modifiers() & Qt::ControlModifier)) QGraphicsScene::wheelEvent(event); @@ -378,7 +392,9 @@ void CropScene::updateMag() { } void CropScene::initMagnifierGrid() { - QColor c(Qt::cyan); + if (!gridRectsX.isEmpty() || !gridRectsY.isEmpty()) return; + + QColor c(_highlight); c.setAlphaF(.25); int pixCnt = settings::settings().value("magnifierPixelCount", 11).toInt(); if (pixCnt % 2 == 0) pixCnt++; @@ -387,8 +403,8 @@ void CropScene::initMagnifierGrid() { auto gridRectY = addRect(i * 110. / pixCnt, 0, 110. / pixCnt, 110, QPen(Qt::black, 0.5)); gridRectX->setParentItem(magnifierBox); gridRectY->setParentItem(magnifierBox); - gridRectX->setZValue(1); - gridRectY->setZValue(1); + gridRectX->setZValue(5); + gridRectY->setZValue(5); gridRectsX.append(gridRectX); gridRectsY.append(gridRectY); if (i == (pixCnt / 2)) { diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index c965153..6ad2191 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -23,6 +23,24 @@ public: QPen &pen(); QBrush &brush(); QFont &font(); + QColor highlight() { + return _highlight; + } + void setHighlight(QColor highlight); + bool grid() { + return _grid; + } + void setGrid(bool grid) { + _grid = grid; + if (grid) { + initMagnifierGrid(); + } else { + for (auto r : gridRectsX) delete r; + gridRectsX.clear(); + for (auto r : gridRectsY) delete r; + gridRectsY.clear(); + } + } void setDrawingSelection(QString name, std::function drawAction); QPixmap pixmap() { return _pixmap; @@ -74,6 +92,8 @@ private: QPen _pen; QBrush _brush; QFont _font; + QColor _highlight; + bool _grid; QGraphicsPolygonItem *polyItem = nullptr; DrawItem *drawingSelection = nullptr; QMenuBar *menu = nullptr; diff --git a/cropeditor/drawing/bluritem.cpp b/cropeditor/drawing/bluritem.cpp index 23005f1..1964075 100644 --- a/cropeditor/drawing/bluritem.cpp +++ b/cropeditor/drawing/bluritem.cpp @@ -16,7 +16,7 @@ bool BlurItem::init(CropScene *) { void BlurItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (pos.isNull()) { pos = scene->cursorPosition(); - rect = scene->addRect(QRect(scene->cursorPosition().toPoint(), QSize(1, 1)), QPen(Qt::cyan), Qt::NoBrush); + rect = scene->addRect(QRect(scene->cursorPosition().toPoint(), QSize(1, 1)), QPen(scene->highlight()), Qt::NoBrush); pixmap = scene->addPixmap(scene->pixmap().copy(rect->rect().toRect())); pixmap->setPos(scene->cursorPosition()); pixmap->setZValue(rect->zValue() - 0.1); diff --git a/cropeditor/settings/brushpenselection.cpp b/cropeditor/settings/brushpenselection.cpp index b26a681..02a7f9e 100644 --- a/cropeditor/settings/brushpenselection.cpp +++ b/cropeditor/settings/brushpenselection.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,8 @@ BrushPenSelection::BrushPenSelection(CropScene *scene) : QDialog(), ui(new Ui::B ui->radSlider->setValue(settings::settings().value("blur/radius", 5.).toDouble() * 100); ui->radSpinner->setValue(settings::settings().value("blur/radius", 5.).toDouble()); + ui->gridBox->setChecked(scene->grid()); + ui->cosmetic->setChecked(scene->pen().isCosmetic()); ui->widthSlider->setValue(scene->pen().width()); ui->widthSpinner->setValue(scene->pen().widthF()); @@ -36,6 +39,7 @@ BrushPenSelection::BrushPenSelection(CropScene *scene) : QDialog(), ui(new Ui::B brush = scene->brush().color(); ui->alphaSlider->setValue(brush.alpha()); ui->alphaSpin->setValue(brush.alpha()); + highlight = scene->highlight(); setWindowTitle(tr("Crop editor settings")); this->scene = scene; @@ -60,12 +64,16 @@ void BrushPenSelection::on_buttonBox_accepted() { scene->pen().setCosmetic(ui->cosmetic->isChecked()); scene->pen().setWidthF(ui->widthSpinner->value()); scene->brush().setColor(brush); + scene->setHighlight(highlight); + scene->setGrid(ui->gridBox->isChecked()); scene->brush().setStyle((Qt::BrushStyle)ui->brushStyle->currentIndex()); settings::settings().setValue("penColor", scene->pen().color()); settings::settings().setValue("penCosmetic", scene->pen().isCosmetic()); settings::settings().setValue("penWidth", scene->pen().widthF()); settings::settings().setValue("brushColor", scene->brush().color()); + settings::settings().setValue("highlightColor", scene->highlight()); + settings::settings().setValue("gridEnabled", scene->grid()); settings::settings().setValue("brushStyle", (int)scene->brush().style()); settings::settings().setValue("brushPath", ui->pathItemHasBrush->isChecked()); settings::settings().setValue("blur/radius", ui->radSpinner->value()); @@ -104,3 +112,7 @@ void BrushPenSelection::on_alphaSpin_valueChanged(int arg1) { void BrushPenSelection::on_penAlphaSpin_valueChanged(int arg1) { pen.setAlpha(arg1); } + +void BrushPenSelection::on_highlightColor_clicked() { + highlight = QColorDialog::getColor(highlight, this, tr("Highlight color")); +} diff --git a/cropeditor/settings/brushpenselection.hpp b/cropeditor/settings/brushpenselection.hpp index 3ae277d..eaad6e4 100644 --- a/cropeditor/settings/brushpenselection.hpp +++ b/cropeditor/settings/brushpenselection.hpp @@ -27,10 +27,12 @@ private slots: void on_widthSpinner_valueChanged(double arg1); void on_penAlphaSpin_valueChanged(int arg1); + void on_highlightColor_clicked(); + private: Ui::BrushPenSelection *ui; CropScene *scene; - QColor brush, pen; + QColor brush, pen, highlight; }; #endif // BRUSHPENSELECTION_HPP diff --git a/cropeditor/settings/brushpenselection.ui b/cropeditor/settings/brushpenselection.ui index 3688e28..74f5ec6 100644 --- a/cropeditor/settings/brushpenselection.ui +++ b/cropeditor/settings/brushpenselection.ui @@ -7,7 +7,7 @@ 0 0 442 - 493 + 550 @@ -84,7 +84,7 @@ - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -100,6 +100,16 @@ Blur settings + + + + 3000 + + + Qt::Horizontal + + + @@ -107,6 +117,20 @@ + + + + Animated Hint + + + + + + + Quality Hint + + + @@ -123,6 +147,13 @@ + + + + Blur Radius + + + @@ -133,54 +164,10 @@ - - - - 3000 - - - Qt::Horizontal - - - - - - - Blur Radius - - - - - - - Animated Hint - - - - - - - Quality Hint - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + Brush settings @@ -306,7 +293,7 @@ - + Arrow settings @@ -342,6 +329,29 @@ + + + + Other editor settings + + + + + + Enable grid + + + + + + + Highligh color + + + + + + From fe86bfe178f5b924597eca61392ccba963eb2653 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 5 Aug 2017 21:21:48 +0200 Subject: [PATCH 136/293] Add tags to ignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9ce9cdd..54e95dc 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,7 @@ Makefile # Other *.out - +tags *.Debug vgcore.* From 9cf4f85694089e1ab292b46cb73ce5758fe34557 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 6 Aug 2017 00:51:02 +0200 Subject: [PATCH 137/293] Improve pkgbuild --- packages/arch/KShare/PKGBUILD.sample | 39 ++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/packages/arch/KShare/PKGBUILD.sample b/packages/arch/KShare/PKGBUILD.sample index fe835d9..43d8e28 100644 --- a/packages/arch/KShare/PKGBUILD.sample +++ b/packages/arch/KShare/PKGBUILD.sample @@ -1,32 +1,39 @@ # Maintainer: ArsenArsen pkgname=kshare-git -pkgver=;COMMIT; +pkgver=v4.1.139.gfe86bfe pkgrel=1 -conflicts=("kshare") pkgdesc="The free and open source and cross platform screen sharing software." arch=('i686' 'x86_64') url="https://github.com/ArsenArsen/KShare" license=('MIT') -provides=('kshare=$pkgver') -depends=(qt5-base qt5-svg qt5-x11extras xcb-util-cursor ffmpeg libxfixes) -source=(git+https://github.com/ArsenArsen/KShare.git) +provides=(kshare) +conflicts=(kshare) +depends=(qt5-base qt5-x11extras xcb-util-cursor ffmpeg libxfixes) +source=(git+https://github.com/ArsenArsen/KShare.git#branch=dev) sha1sums=('SKIP') +pkgver() { + cd KShare + echo "$(git describe --long --tags | tr - .)" +} + +prepare() { + cd KShare + git submodule update --init --recursive +} + build() { - cd "${srcdir}/KShare" - git checkout dev - git submodule update --init --recursive + cd KShare qmake - make -j$(($(nproc) + 1)) + make } package() { - cd "${srcdir}/KShare" - mkdir -p "$pkgdir/usr/bin" - install ./KShare "$pkgdir/usr/bin/kshare" - mkdir -p "$pkgdir/usr/share/pixmaps" - install "${srcdir}/KShare/icons/icon.png" "$pkgdir/usr/share/pixmaps" - mkdir -p "$pkgdir/usr/share/applications" - install KShare.desktop "$pkgdir/usr/share/applications" + cd KShare + install -Dm755 KShare "$pkgdir/usr/bin/kshare" + install -Dm644 icons/icon.png "$pkgdir/usr/share/pixmaps/kshare.png" + install -Dm644 KShare.desktop "$pkgdir/usr/share/applications" + + install -Dm644 LICENSE "$pkgdir/usr/share/licenses/${pkgname}/LICENSE" } From 78670a8be1f15b1a5d5cb8d04b55d74e3ec801a3 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 6 Aug 2017 10:38:11 +0200 Subject: [PATCH 138/293] Update Serbian localization --- translations/sr_RS.qm | Bin 24744 -> 25251 bytes translations/sr_RS.ts | 118 ++++++++++++++++++++++++++---------------- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/translations/sr_RS.qm b/translations/sr_RS.qm index 3690bcafd21df2c7bee4a2f59ee663bd71e4e895..2af58eb04184d04707243511823a2813cf376c21 100644 GIT binary patch delta 1902 zcmah}Yfw~W7=8|C&tA@+-4#MW1X{E}Kp=s%)F1`o65y&Jh+Vks%2jq-AhTxNyo?$( zny#p*nMoEJlQ%|UQYnx^Q@Ut(MaoMxT9MGbp`IP4%fEh{dC&R2?|t9reV*q#EpH0V zJ%VfIYu13%-|uWZ8yeJE^uqCrvjO!OV17O@dl``158U${RPHVyzya01B4FGCNYALa zzZcRg{7x-^)H)1=G$70#2+YkwT2KPk?aXaP%cVr527q0-5x`e443W1qf!n9xljaV&YH1#sCP_WH<3b_3h z!Lj-(pxY_bCUF4&?ZTEBD}gMBaCn6ekg`cQku3p>288#I^a0VC!muU>NN9I?P3|Jy zX2EOv0V@IYcr9#N4cr#x)$?lvCtl&zyQ`FqHhYb{%1QD=M6K6uAbpuApW}D@;?bD; zv?vdG_B%!Ma0;2ZASQf5#^hhb>P{Pw^RwtYr~t}%@nHUXN@5dF*FJlqOniW}Pj{ZkYo+#vd4Nxq)Tyvx zzEkRJB|xQKx-^%7L(-)0&V9=BC#0dbEkMRfwa!%oL`_z^%iGznSKWLx4=$u!Q#bd` z2aKKSjxTjU-plIlZ;3o}s`|HjPUJs48UrV(e?LQ}jHR0JZ3#fyH=5RI1d@DIbLoZ1kqID3M(y2LZ>7aLxYp&h5kM&|S*S?%W?>wi~x16Mz6Sa}gdpy*yz3WPcizX=1 zHlLy?VuG|MM-nMPwD#H?bo0bT+UvEy@;bS7`gK>i|AWqF?KxoHqq@1_G+o$X-2-{) zbiJs1e7zf(FjKeb81s^vbh|rB2vnmxxR!O3{dC8z-Mq@7x{t+LN-E33rJH1SysY{* zn+0`W$+7z%;X;v|6v@JA7J1G*7D(@r3kFCTZDf7#EVZ2|R|Zh)d(X-1`dOebT5j=c z1cJ}V`wy-MW=wNOs}fz4)N=p3ZGirO{L`mYVtR>QJC56-3-uQBTO=q?|LBhzmK)M9 zJ0KGGNqys_CgLmC@4U&jKJEH8OAhbAfW9}IgykGlln(w*{9aRnbtmW$yAmtY39%ED zc+H2bvsy{sKpti+SLTj$Qqjcoiqp3b2z*jm`|wtJ@foFIkcD&mmF<7fyM9xY*98(0 zq92VZdCJ$9D_P(pgJ0Q0yv-SgsHJqmoaYT$pWRIl?=oyZL;$z881_d~;erOkfj_%| z#4JPKtK=;s%y4}N>qcHQn%<44q6OEDiH}dC6mX!k5uzq_7|p?K97BwxATIjZ3z!f|Ju|OGt9WxbgF$1m78d~ zv1bJ*iKqY`C?ommOm|Ui?2)PJM(;ZUF$YUvM;Yn`4Ju&fmlHN&IqJ0@7pVE@Q)`M# zs%_>nXNA>W95CMfj{l-50hrCSN)$7t7*!~R4K=7k@jq$C^op|bYCh&td$rx^$&CB| zEYsgvb^oTh!vdZ)B_M^!>WS3T(&3&p!8epI^&YsevUdeh{M&u(oVs$G(><8$>)z$< zf8=O@zqmN@KbY&8Th7eK7#DLACkHPke$RR(*UhYEhl5p}T(991^Uq|#$#zGD&1x>U gJw}jLo4L+zF0HO`l-P@%))==TDDcSH@t>#s1${CHYXATM delta 1496 zcmX9;Yfuwc7(L7GCfQ`ODF_%bC}~kd1O=Q5K7tr|3K&FQ(N+eqs3ehqvj zeH%A}uNnY!HjG{A0?f_B_<~x%po7=@I>S|X|K?8r9pE=C2MC&hu;Se`W+Ti}e4Zw+ z5MGi&09lB1Isy#SBkIf;0{8-^L|RV>MzXG+$fUuXN|@0LJ9u?ao}nEoUqaRlR_N8{_zrnAvAC zo{I=zb`s;aKMwH8W&G~-0Arsq9~YW|sd>y4S0d_B%S4p4(!RCK;^1w-N4J?(n;rtf z0VXGi8gRPE6i>?sA`dbrHaHNGM&@iZ517@=uXP=OS1vOkj{*F8EOrx`J^)7f*d>>2 z0zOQ#YZ>&UPLJEYJx>(wZUeK4u)t2fO$sSr zvCA751JUkmc8v&#BiWk79b~~Swr%BM!Wm@SY(y+3pM9PZ0>oMx+5RTl=)Q|{sV7Mt z)ttxoEr53&m$79dDZp@hBTkbwcev8~6A7r2yRiRXQe->Vx~++_(8qPXa0JGsay{K$ zK!lO&_y3L*GV}6Ce_+y0-hR(|U`8rGA-5k;CGr97C&;2uKC3qkuxK z)iS}71$ZXQtV?VJ^g>qlQ#@s5n5?WL4v-pU4G#ng_zhX}(=J#Lo+f*}hB|T94~^P* z*_%rwk(4I)*gKh|ca~R8Ap*hO^3z|Er1mZHvsHb-#9n#3seu&wOa3VIC>^*!{^)@( zWu#r9syI)f%~Xs(L|GZ9QUvr+onN7%tc|>%5TQ8#)Tz(mvyYP}-16MCC%wRysJ? zD4a=e2Ij>Gx7ZxI4L0jjcGT36uatA=QCaA7Wl|RjLm^4OdYPOvDVJ%<$si~TI-dhc zW@UwQ5ioL4d8}p!5SVTa;S83s{>siP^<-SN^5q@UJD^ad7(vUUx2Q~R7f6PD)!G+w zKUT}R^gMOP z@zoTZIQ5hLbgrjT(p>Qe619?H-4qKYh?jy^%qPHPDJxP(ug7I6XQw9>)JR3e+sUWb zQf)KcEnT;CD>&XX{#B@6P@oYp}0% diff --git a/translations/sr_RS.ts b/translations/sr_RS.ts index 266eff6..58fd583 100644 --- a/translations/sr_RS.ts +++ b/translations/sr_RS.ts @@ -47,150 +47,170 @@ Podešavanja mućenja - + Performance Hint Performanse - + <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Blur Hints <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Opcije - + Blur Radius Radius mućenja - + Animated Hint Optimizacija animacije - + Quality Hint Povećan kvalitet - + Brush settings Podešavanja četke - + Brush alpha Providnost četke - + No Brush Prazno - + Solid Puno - + Dense 1 Gustina 1 - + Dense 2 Gustina 2 - + Dense 3 Gustina 3 - + Dense 4 Gustina 4 - + Dense 5 Gustina 5 - + Dense 6 Gustina 6 - + Dense 7 Gustina 7 - + Horizontal Horizontalne linije - + Vertical Vertikalne linije - + Cross pattern Krstasto - + Backwards diagonal Diagonalno unazad - + Forwards diagonal Diagonalno unapred - + Diagonal cross Diagonalno krstasti - + Choose brush color Izaberi boju četke - + Path item has brush Da li popuniti oblast linije - + Arrow settings Podešavanja strela - + Arrow width and height Visina i debljina strela - + + Other editor settings + Druga podešavanja urednika + + + + Enable grid + Omogući mrežu + + + + Highligh color + Boja akcenta + + + Crop editor settings Podešavanja editora - + Pen Color Boja olovke - + Brush Color Boja četke + + + Highlight color + Boja akcenta + ClipboardUploader @@ -204,15 +224,21 @@ ColorPickerScene - + KShare Color Picker KShare Birač Boja + + + + Copied hex code to clipboard. + Boja u hex formatu je kopirana. + CropEditor - + KShare Crop Editor KShare Urednik @@ -220,77 +246,77 @@ CropScene - + Free draw Crtanje - + Blur Mućenje slike - + Straight line Prava Linija - + Text Tekst - + Rectangle Pravougaonik - + Ellipse Krug i Elipsa - + Arrow Strela - + Eraser Brisač - + Clear all drawing Očisti sliku - + Crop Opseci - + Settings Podešavanja - + Confirm Potvrdi - + Cancel Otkaži - + KShare Crop Editor KShare Urednik Slika - + Press F1 to toggle this hint Hold Shift to slow the cursor down Ctrl+Drag a thing to move it around From e6074a28829ce12cfcb3621bca2a84ba89bbc951 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 6 Aug 2017 13:20:51 +0200 Subject: [PATCH 139/293] Add German translations --- translations.qrc | 1 + translations/de_DE.qm | Bin 0 -> 28709 bytes translations/de_DE.ts | 1085 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1086 insertions(+) create mode 100644 translations/de_DE.qm create mode 100644 translations/de_DE.ts diff --git a/translations.qrc b/translations.qrc index 764c5d4..5140cf2 100644 --- a/translations.qrc +++ b/translations.qrc @@ -3,5 +3,6 @@ translations/sr_RS.qm translations/ru_RU.qm translations/bg_BG.qm + translations/de_DE.qm diff --git a/translations/de_DE.qm b/translations/de_DE.qm new file mode 100644 index 0000000000000000000000000000000000000000..3864f55287c0f37937b2e8759752c3db5c0c32b9 GIT binary patch literal 28709 zcmeHwdvqMtndg=Du+)+zzYt&^DYvmK8>?HkWkX~kkoB+xLXs^R8wUdYs8$#1?rK+6 zTeg$zZf03Rn4G*J4>FlNW(Z_BdCah3I7^Z_1hRzPVX~9VWHK{^%)pSDO=gD;gls09 z%>I7&c2#w^s#`L4PWF#I9ILyl>VEgT-~Ha-cZ-2PPG0oPzkK4}Kiz!k*KhyySD!l| zL{qa6vqy!P+$Y4`4}=(dSTua-2_Y_iLNq*dyAYe65smL@!2LT!;~(Jn^mjz#!>fx$AEcJ%4!xu5S{%H`w_7-^9WDJ}kry&G>v0pYIpr zADajKd&Tt^d`1ZToBZllz;6;WM{z&-ytw(&M}&y~OdOA6o(nG(#~;M_=}(JWfB7JO z-!Ia)Z^pPEiG^dUfbZ=h|L~(iObv^|L9FA3$JOWYOTeB_(k2(|EsHR{@9&DbZ=kv)GxLRkr-R` z^d}RT=b2T%`U2LG_^0~jRiDD%e6l|D9sJ(ESAEVj)Q4Wd@8tXIwO2=g|8#xdUx8ks z*XuK1*M&I#V!idHHX+(BssGZ^_k#ZI_1`i-EyNX}`foi7Ja38D|Md1zA#VG5{VPvk z+>T#1Y-@O0lpwEeh zr{DdA5SQ$2_~Fks3K9MNh8JJ>p%6Ej4X^C^JA^P9hxb7qWL5T71Htt+} zMTpk7G+zD8A7a0{8goCvIy?5L&s#p%XwSbO#G0oX@A?MDwLQ`J+Yf*){XcJfsO7t$ z*9RIOz2~qH8w!nIZ^L}aH#a`}Fz{>pPmRwX0=}CsYy4l|`9A3LuEtmX>kN4K%S|o+ zJ|{%)r%9u%3(e zsn1IuY5L`V2c6nKw0he|`-C|Bwbc(_1w5weS3mwX&~-!G>Styi1AYE&^-E(92@!i} z^-F)hONi02=GF(F6hd!l-toKOn`mG2)i2_?f%i3k_FLeCz8^L}`Kv+D{l4ax{sjEH zZF}>N?O#AnUTSH*`yW8}OIp^y>pMcc_3v5^Z3CZOnQpn|$T;}Cr{&ChKP1G~KX3Wq z;}|z_b<3w7ivz#SEnj*U;7wzkKhcP{+%w#!<+27Y>|EgAyf zTy?x{&+5MboK_-{`Laq!b?p8W#oGXAGKeb zox?tTyZw%1SkFb{?YZkOg`WCEyZwRfLZnjd_uh98_~g3wFMk7ayZN5>@7?rUn0L7S z<-QL?Uhi#x`EMaFM}FM?>g~@7ksj@6`|gWE9DA}udja&EyuV}NvSH9I({Un$=Wez- z9{8KjVSghXk7V)O@HHJzMP3E{|Fz>=kA4RH^i0Q3KJ!kjV}k*u^*SiuG$sZ_S~wyr zGGb7E*F{VuMO6NZ3lrZ@%kO#l*T9qWLKC*IL_%C6!lEC~8u)IC9IpD`BlvX^&xY~z zBA!TMmb4tPSMn0-6JQ z1g{_ps9XvE-UJvHpc|5kn%D}O4Tw0dk?xbYo)ZhW&z%_nJPmZ=%qh8-q_hJ#ydTAX z^LU=SUjT%NJ-6MbmLT19 za8j;B0{pf9rq(!9hFS1#@~YAdQP9J;2vO``(Q-7?xo8rie(ylq$z}!z(t0cz9UO?8 z$hBezcozbrepVTeKNW?Nd zv5YaF>({bIGMUl$hXK&e$8zptTFT5hJ&U?ApLY89_4e-9Dh9ga2DKYz(=kgQh;n!Z zkg8*Pw7Imdr7T_7V!5Pd=5@?$7OaH&ov=*X*7BK{lQONWW+(6<9>6?C4r?`2&SJ@w zQP3bic$03~hMCj0_723Y=-{N0Td@1JftZ%I^wc%swBzLM{%CaGaMFc%Bw=QwLzb=Q zfZB+9u=eN>OzhO^A_ z^D)QL&79l-IqSL1IHQ1-EOUU&5LKcPmErOj&l{j7IC0>e;m)}aIXi?+N?WZ73}nk zo}1M(7y&VnG~Owuu|RqY^z}$<>Uj;`NKRh!JqawuLvhVe&dA0bJt^VW0N*8MB&7^c zMiZlQt#l1_{3b2wl$8Q*AF?cSQL}Z&fd;9C_>MBj2c%(9M#^<~G%+q-Bb`08I~8=P zY^6R+OTAeG|J~9BjR8v7umXB>C&{UFP`H=fVoba) zcX2y@jRALy!s@NQRq~rQO!Zr1*%wuS9Rf%ST&xmMER#>iY5?l40JQwl+ZBc@SbM)X zDqaLqYWKNELhrRj__WZ{=GB0{5dnsY zoy=k#6n&|WJc2h5n|4-*^HBrBfH+P*m3oXp7{gMAT%?Ty*i_le@4&`k%gk$f(r`>` zWimg4Ss8SvrQSG$nWX-}%r<5`C}*d3vAor+!5s8aVveI*xf)B_Q98W1y{7;w15(oi zcJQep&s`qy)gyWid%EkqfZbgQcK3M!yQdQDp7R2>uM%wEc>%k(671gd0(M^|*nQ^( z>{XRuuc`qy9AHbTac%oZ(PC)Q#jXMM@(Q*klb!+FGTBpVSzAYQv3N$;<}D*x1Ki3D z-el3>9rkFjZp^e+Z0~maHUq+zf-RxW7^mzaDMbxJ{L}bG7mzx}w~FoK2zL+`Ew4w< zWtI+i7H0(tbzGusfb?_}s4FraT|(ogWt>5rR?`9Kgi_|V(VZwUEgqESDN~actH$ni zOTUe(m~r+>RPY7UPFlClLI)23Ia(j4;Fuh+kOU#W6|i6QX6Z0$_|1h71=mZEzMi+3 z4TuQR8iJ6lmX6uVDArh4C$dpAR5X1-&PEIT+GSmhav)0`4GCm9H>0ZzljTiZ8!=mf zi_r?k{Ao&krW9YWhEWaomZv)y6 z6_8kPPA><`kHJ)Skr^*oK@U#jteL5)P}UY*Q*Pe^QSpX0BNHG~95t5GhM0=1EIoT~ zWaCk$OKJ=o5ED|4TvzS5%)a|!7cDyNI#rAYw3thFqo2**G#iJ_ynz_UF||a-$j43i z@|)$X!|u-``HUGuu0h69Gg5t>f?o98VL(?B{YEf}c$i#P#3Zesf-XuTZ%~3#gea|* zj`obfY{G0p&*>7QE6Os-zT|MVd90loYTsqwpt37UkTeCWI_yXV>}4E6Z!PQHS?K$X zO5cx@gy;*ZpAz+u)HB?9pJN(j{KltS__V*yjY08`H)8{1oPbg5p)KS1j|^4}$h|R5 z!;~}`uvN?zLFWIpqU%fUp>(Oh;J9Q|LSoQg8QQKJ&gd~qi)Aue(uyr2ybVBU6Ih38 zfYLHAolX@gms;}G!)7jJSlNK#oq=w-AGbG!17bXX|gs=7vJP8mK{MHn8P!Cz_`sWau@kZ8de@{G!}u$Jc9 zH5a~ue4_`0FsZ5NAQ7TlwW9_jm)ZDaD3=q2J`BjL^jryEpiWbEfU?e-7jabcDB|<3 zC9f!4b-5PlI!b6m64NUo>*NlX9%_~3{?g4;JnzD1&45oRj58%Nqwp-J@FPQ#H-CIrED6ccU!Ii3nmAfvr z9=bfF2W8!*{5Y)66r7?_e9p?s8^cvrZOIFSqKR$65{m28Bz$hsOEr+cNDbu^kd{da zkCvGCM$5u&W!<<-x_BOQkr(Ko<>a#*sUYw^xq$gS;!mvTZ}2;DWG#<*Bulz@+(q8u z+=>IsXDx+Njsa)(ELdG+#?ldnkL{xAa?JU8gd$Gbu(dRNnNZ8PnMrE1X(Q$EzMVl1 z5PqqaC|EX914(l+7it-Htjv`oR%~92aVQE5cr^3c~!(+oDGNvuD1q7Ar2(?V4w9^=rG_{=R z5dTF3c7fmdv@T70xlR&mp>UO*qFg`{JyqLs7?Z|wAZdW2+ypkEXmM+mEm>-snrBP$ ztrgQ=g!qyhPmiArG%2BhiM;98%%Y0H`jf_rO8^SZVh%%5qxOb0%%Nfv@Z^|RRX-QM z$@k#k%195cAl)?Lw;=b`b>E~n*FKD`GqYu`+!Uy$BG9-L6bj56cjSD8!sQ4-CJGtJ z^5qU@5K4^98C+5CurTo&q?{Y_y3`S@98*p$+?8G((DtX@IA%cJGDa4hrk_gadQw-O zY|upG6^@;Xzg;CswLq0bYEYG^f&op_5jYQQC{Ub&E8ccr=(>E8(3(qWjT{h!!3bF0 z#D7#x-B4o8`BC9!1ar+wA=7OqDX0jqhq|4H>SZ22F7Ckfg%W04f7pavQMO_^&5Yjx zVW~FpEi!T<9cck+U%A+v)QQS6aiMBj(w_E#B;fZUJVzVL_>GA3I>TXQ=}ULxazy}0 ze@@@2#S0G9ljH+En|DrE<;ka4gq#~_RHCCAUV^CBQ%W_l8K{rQon5-5MY$7754>?{ z@Qi}Et{Nd=7r0;7&rVNi({jf)Yljt$45YVR@s(;ah=JaY-Eh5f*0s1FVR0M&3*#FZ zn%y|GjNDzd$E-0j4opc_W5J5|Xd7RLY`OlP@9*#~S_B=_>@Ywz``uexs#x?-d zyp@HB>!{qbIxfpOLAcMA;7+}%Fj4lGYA6i+RsTU4GgjhPA^;e>6sIeQ6RZ?WnPY2a zN@EGuLrqCXRn#7=f?7F=T=5|BN|9CBA*D@}lR*)quu)V>#i|;S+4RND@}Dk~c)(D) z!B>2Hx!ior!dj()PRHOb#MGh}QA0%z3RI9Brm+Sgx2CED-d$z=#A*4hap_X(G?z2c z^6RT)u^s;UD)&;Yg{!Kq^G1+jVO*f2E3gkFbiGw~Lzw1^Nz1~GqAbxzcjn&O>Ou3TzOhOjjHJEyU{Zm0v5nGQ?BP?CvTbIL2^>~TMdvkYqbJyPd!K%7mWpe3m_;V?R zSVBE-zBX?@J#wu}>UKi8Bt@N5 zjb;brx|9u|>#eL=xC*t%;AiAh^gGT-x%Ja$7o^|?PD&?`T#1G$G;zojSCDA#kTbj4 zXvOUAT2%X~3nGz7&_H zbYC@^4q$rfGS^XMPw7(bTh6WQthDR3C5_}%^>)^@l4Vm?B`3=8X*0PJa#jOSCLRZ)Vz^m^H6EXuq@>#8+dfodLjHVJY2$BZzD!J^popli)`VPgVh5H-$zvx5;cJ z=M$=RqOYv!jkSSO*jF~bMZ9^pz|zO$X@TEVmu^KRt4i1PS@h|O2debxmbRh>wBO~8 zQ`uNvwcOe8C(orZvRH*%wlVU8(H!eOmYb+SdqBpVXQ8BS<~(tSdrraaZI3`2Qs4vD ziRQrxsw5wkxxoeSh|1Br=K`V#P9tKs^dYyvsb?kgH^nK#5Hg&`i_j%Y`G#*mNk5Mlw(a;-jKfa@KZ?X9kxaH?n) z!&s$C;xAK&e&px|&0}&el-FL;;xi_laX6`|7-A)w#v1diM=UT6f1fRY#muOOYV*PA z8O=7%EQjl0^+Y+~y4aE&8T?|;fJ(J7`-kkSH(%#OHa4$oMTM=o8he=)^j9QZnTslg zzmi@aH_dw1Q>)H&_G42R+{1Q^ey6ZpW@uDGlg5C>DAfs@D+#JLO`^#%!wOF~of!*f zF|tT8!6%n-RE@3sIEn+)@Sdh+$TlvCsS05#$4tUAlSIaGvqdUZmjf=$2{1cM?onb%lhR#vqxypg561wVz9eH^rqLZl{45CiPT+NO(<9UU+L(bOFpFuh zJK|ldxW}hl?i!W9D@}poC6)qGfaWKPl@e29{d`ZPSWHBj z4=26ynMlFbhGr%-5KrqKV|kK{;pzh^7abFPuwc6tkz&(M7})TLag9}b^zD#y`BRbA zg22{)1zx~rDQLqGxtl@4Q4nAp-)}^ogxQiKQ1+7`>@a?X(Z$45t4GBi{N}e2JULP} zq7PfrEANfU91BNLRq)iSiZvD?wu^Xb5m0;&at{7k6#qs6xkrxR$?HA|i(9}NmO5IK z#4m=*gQ#W)$3TpSRP4*B$BjsNCi_GY4lzin{MYMEy| zPfOP3GcJTE#u9WuP)+~aTQNqzeBEx zKB_w>G2nSZm6_l#H`C8NtNRr3DLvWEW=v*Mjk%#j0=6T@1#CmKDvXE+)inHy0z`Xas2=;%~flV>RrpDZpeMi%$T&}8m#^zi6# z508uW^+uT{!{M={lMD}rN}Sfg0c3(=8q+h^giqj^G*4KDY4RM@jjjpr3Tr%v%9E;^ zb2^Ww_&_va<49yEzY|7JdmAhz`g?nD+BBi}Yk5oWS;V=u{n|T1a7Z~4=l_^OQwL;` z{gKCB)p^!bENf&=_ivjr(P=Ro%h}uZs~hy=`gir_o#OA}!Ph<>e3d6*C7AvkoyQDL zdxi$`9^@=CIYzDr=BU3ne`>#0{2ezPRR7B^W%QI&cEOUzYvrgOoWYA{%)~+uya5oS zA2ZAIr|wUH4i63^r|huOl+zcrSU!)A6m>K;_}t?L*nvVoa1W*FzJ#CvCZ%dnmX#YiYJv1=&m(qqBbpMDC0&O%{pEfZTm8x5L5)4&Ta~^Fy zdnxFrDo>{0Ti~S=IA3HrnztA7*rF}z*k2Q)z5s8^C7}w&hzFIHUrqJry`VU6k+x`M zLQ7Wd2?wMLNXD#6R=Ggc7_JJEp0{4VhkFBSo&vBfjSit)W!n-E%2) z(8%$sjHXGcrIX}0?r=q_oJiMr4&>&GUv}ZzR-`xm4eP2{huk{Njv2{*nBln@ZR@Un zZL4IAfEDei2={%KSkg!3ZS@7kE-E#XOCWB3zyv#2K0!&NR%hT8vQH~;4i)q^HC~=sypfGvhYE%?hLsqs$Czs2bf`;3=0$B)Idmh29svh49H4xXaDHkk)OEx$aO%g< zWs6Vc;9BP)8u6|LD-hc&Kp$%IQul>l4A^wV@8+itF6Rx zJye4QUT1{DY#@ApZ?^hLQ|hwHF-)fh@j^p2R_G35K1tGQnVU6=KZ@^S30mkkJ?*Ys zEtPtuO;DXKt~Re=K@gQ8F3lDhnW2rJ8(eudg=1A_PibPld1FcTNY3Q8ptJE(c~>O2 zVzZLgauM|;qS(P98!M3bX1WC*@=X#EO)?(DCK5ywo(*(g8`dS+hic4MIjysNwM|#f zPMd*j$k%1Lw-G*-dYk||>)OiDVIF=>f}UL@y{(`d2fIQFbtyDQmoN3p$z)b*`+ zZ3Vh+HjUmbNqJqpiC9jT}iREMxJ%5B%DL0X0;-pbzOuPjSmP-O?|!*cfH-p8r)T; z>%9{UOD5eq(pJ-UsR|%p9qALl$LCxaOQyeYyg!e3vRS8n_Kj$xc*B#W_GYbTxmC5-mXgRf z3;8ps;6hdWlxITB%V+LzE1vptu&*oHB^Bc_t_yi8l2IRHypXgu%671Lt#p^VyT@a- zH_aJYu-MjJp)m`2QpS2AS?Yq)!4LV86@PuG#Gf>D6{M8oz!$MHdEHxq34hOm#RKrD z#G$vhzqi*#qqhVLvS%<3A1n(GxwfG94IKuhsfDTeRYi?L(hc5LiE?!umPZ_2pV5o= zy=!a`=co#g2UlpOSR_$LBmFvBj|xKjQ7V(C=@{&3-3O??k^Y4T2i=aQLFLKIGTM6O zHSs|;##9ILKODHKO23x;|IL?{(j`5S$G*IHR8rkfWezVv^5M=vsj){zXl?u&;oo!A072W}M|dFf#9RPg}} zY*L+g2|)CG`SnY~&mgk&%2JXlzfoJ$=b`Bxg$%kOElW(?9+J&pZu3y`BoC`rrTDox zr6DPS=oO!r-gyw_-6$f*fESOv(W$`@cAgwXL#I+BKHsHqRd)WCG_~w1M^Woe8aCgdgbbgN&8st1vZ~{D2dgs! z0c_L>^~dlf4jh8sywRqTQhq!YMB`ucJJ*7yyzX4()Khla$THGcjR7{n3bMmQ{Fi!rZ9*b8NW%4G%Lp|3{W zFv?{flw~%p1MeE5EwJHIWYFba4dy8*_|n(142WZBzi?m7p?uI_f79>xQo-yTn9_!! zpg~Z=NIR=u?ZMg*^B4T2pqJX&P4ev#^dtt34dUGuILF246}_-BFc0G6DeM^~f%2jH zL#R7$lme-uPTzR)L^-t*<7!F}EtN`!xT#iOXRv&bSilP~@H(jOtXV)DZNXv2@yik) z$F8aqm^d%%*ei1w{r){aekl5T)i&ptTqnsztbISNgqg4w6+EZ}63MJQJZ8oH_pmU{ z>$8r(;%+}V>T-(K4Zg>lG%OA4w~FjjW6g}H+&tovth2}K9Wt+|dC_ULC5K_wiK=q4 zmr+c!D7|Eqa#)6vXP1jy7R#lt-)NN0oLp5iU&JwiI9*2GOP_4zeR6m#DP7C*=Xc7~ z45f%PRYtM$Ef8)?o}VY!FqB29*8s;BlS0@y;*=k&9vmc>5|uV_I5Fc+?F0T9FQiX zpchZ7;Tdo5CWZ@^g;u7_>Ea7|y!HcdUh()L3>&x+ZEE;m99Wsto3$~Vtf!uj<0al+ zrMkxUJ|38+9LB=jK6NU;YQC&bmeSLLlpTiO>VMqg7FdttDnpghw*{0kvvRspf zMoYRey#*~z)Ud%Y2YTE{pj~i#kPeW?3!#Yfx?n5U{NfqAa^&E&Z@e) F{|icz>vsSE literal 0 HcmV?d00001 diff --git a/translations/de_DE.ts b/translations/de_DE.ts new file mode 100644 index 0000000..ddbffd5 --- /dev/null +++ b/translations/de_DE.ts @@ -0,0 +1,1085 @@ + + + + + AboutBox + + + About KShare + Über KShare + + + + <html><head/><body><p><img src=":/icons/icon.svg" width="50" style="vertical-align: middle;"/><span style=" font-weight:600; vertical-align:middle;"> KShare</span><span style=" vertical-align:middle;"> - The free and open source and cross platform screen sharing software</span></p><p>Version %0<br/>Links: <a href="https://github.com/ArsenArsen/KShare"><span style=" text-decoration: underline; color:#007af4;">Source code</span></a>, <a href="https://github.com/ArsenArsen/KShare/issues"><span style=" text-decoration: underline; color:#007af4;">Issue tracker</span></a>, <a href="http://kshare.arsenarsen.com"><span style=" text-decoration: underline; color:#007af4;">Website</span></a>, <a href="https://patreon.com/arsen"><span style=" text-decoration: underline; color:#007af4;">Patreon</span></a></p></body></html> + <html><head/><body><p><img src=":/icons/icon.svg" width="50" style="vertical-align: middle;"/><span style=" font-weight:600; vertical-align:middle;"> KShare</span><span style=" vertical-align:middle;"> - Die freie und opne-source Screen sharing software</span></p><p>Version %0<br/>Links: <a href="https://github.com/ArsenArsen/KShare"><span style=" text-decoration: underline; color:#007af4;">Source code</span></a>, <a href="https://github.com/ArsenArsen/KShare/issues"><span style=" text-decoration: underline; color:#007af4;">Issue tracker</span></a>, <a href="http://kshare.arsenarsen.com"><span style=" text-decoration: underline; color:#007af4;">Website</span></a>, <a href="https://patreon.com/arsen"><span style=" text-decoration: underline; color:#007af4;">Patreon</span></a></p></body></html> + + + + BrushPenSelection + + + Pen settings + Stift Einstellungen + + + + Choose pen color + Wähle die Stiftfarbe + + + + Cosmetic + Kosmetisch + + + + Width + Breite + + + + Pen alpha + Stift Alpha + + + + Blur settings + Verwischen Einstellungen + + + + Performance Hint + Performance + + + + Animated Hint + Optimierte Animationen + + + + Quality Hint + Hohe Qualität + + + + <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Blur Hints + <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Verwischen hints + + + + Blur Radius + Radius + + + + Brush settings + Pinsel Einstellungen + + + + Brush alpha + Pinsel Alpha + + + + No Brush + Kein Pinsel + + + + Solid + Überdeckend + + + + Dense 1 + Gitter Pixelabstand 1 + + + + Dense 2 + Gitter Pixelabstand 2 + + + + Dense 3 + Gitter Pixelabstand 3 + + + + Dense 4 + Gitter Pixelabstand 4 + + + + Dense 5 + Gitter Pixelabstand 5 + + + + Dense 6 + Gitter Pixelabstand 6 + + + + Dense 7 + Gitter Pixelabstand 7 + + + + Horizontal + Horizontal + + + + Vertical + Vertikal + + + + Cross pattern + Durchgezogenes Gitter + + + + Backwards diagonal + Diagonale Streifen OR->UL + + + + Forwards diagonal + Diagonale Streifen OL->UR + + + + Diagonal cross + Diagonales Gitter + + + + Choose brush color + Wähle die Pinsel (Füll) Farbe + + + + Path item has brush + Pfad Werkzeug hat eine Füllung + + + + Arrow settings + Pfeil Einstellungen + + + + Arrow width and height + Pfeil Breite und Höhe + + + + Other editor settings + Andere Einstellungen + + + + Enable grid + Gitter anzeigen + + + + Highligh color + Farbe für Hervorgehobenes + + + + Crop editor settings + Zuschneideeditor Einstellungen + + + + Pen Color + Stift Farbe + + + + Brush Color + Pinsel (Füll) Farbe + + + + Highlight color + Farbe für Hervorgehobenes + + + + ClipboardUploader + + + Copied to clipboard! + In die Zwischenablage kopiert! + + + + ColorPickerScene + + + KShare Color Picker + KShare Farbpipette + + + + + Copied hex code to clipboard. + Hex-Farbe in die Zwischenablage kopiert. + + + + CropEditor + + + KShare Crop Editor + KShare Zuschneideeditor + + + + CropScene + + + Free draw + Freies Zeichnen + + + + Blur + Verwischen + + + + Straight line + Gerade Linie + + + + Text + Text + + + + Rectangle + Rechteck + + + + Ellipse + Ellipse + + + + Arrow + Pfeil + + + + Eraser + Radiergummi + + + + Clear all drawing + Lösche alle Zeichnungen + + + + Crop + Zuschneiden + + + + Settings + Einstellungen + + + + Confirm + Fertigstellen + + + + Cancel + Abbrechen + + + + KShare Crop Editor + KShare Zuschneideeditor + + + + Press F1 to toggle this hint + Hold Shift to slow the cursor down + Ctrl+Drag a thing to move it around + Alt+Click a drawing to remove it + Press Return/Enter to finish + Press ESC to cancel + Use the menu bar to draw + NOTE: You must select 'Crop' before closing the editor + If you do not it will not close. + Drücke F1 um diesen Hinweis ein/auszublenden + Halte Shift um den Mauszeiger zu verlangsamen + Ctrl+Ziehe etwas um es herumzubewegen + Alt+Klicke eine Zeichnung um sie zu löschen + Drücke Eingabe/Enter zum Fertigstellen + Drücke ESC zum Abbrechen + Benutze die Menüleiste um zu zeichnen + HINWEIS: Du musst 'Zuschneiden' auswählen before du den Editor schließt + Wenn due dies nicht machst, wird sich der Editor nicht schließen. + + + + CustomUploader + + + Root not an object + Root (Wurzel) ist kein JSON Objekt + + + + name is not a string + "name" ist keine Zeichenkette + + + + desc not a string + "desc" ist keine Zeichenkette + + + + method not a string + "method" ist keine Zeichenkette + + + + method invalid + "method" ist ungültig + + + + target missing + Das Ziel fehlt + + + + target not URL + Das Ziel ist keine URL + + + + format invalid + "format" ist ungültig + + + + format provided but not string + "format" ist keine Zeichenkette + + + + body not set + Die Antwort hatte keinen "body" + + + + all elements of body must be objects + Alle Teile des "body"s müssen Objekte sein + + + + all parts must have a body which is object or string! + Alle Teile müssen einen "body" haben, welcher eine Zeichenkette oder ein Objekt ist! + + + + all parts of body must be string or object + Alle Teile des "body"s müssen eine Zeichenkette oder ein Objekt sein + + + + all __headers must be strings + Alle mit "__" beginnenden Kopfzeilen müssen Zeichenketten sein + + + + body not array (needed for multipart) + Der "body"ist kein Array (für "multipart" benötigt) + + + + body not object + Der "body" ist kein Objekt + + + + body not string (reason: format: PLAIN) + `format: PLAIN` should stay the same + Antwort "body" ist keine Zeichenkette (Grund: "format: PLAIN") + + + + headers must be object + "headers" ist kein JSON Objekt + + + + return invalid + Antwort ungültig + + + + fileLimit not decimal + fileLimit stays English + "fileLimit" ist keine Dezimalzahl + + + + base64 must be boolean + Base64 muss ein Wahrheitswert sein + + + + base64 required with json + Base64 für JSON benötigt + + + + + + + + + KShare Custom Uploader + KShare benutzerdefinierter Uploader + + + + Copied upload link to clipboard! + Link in die Zwischenablage kopiert! + + + + Upload done, but result empty! + Hochgeladen, aber eine leere Antwort erhalten! + + + + Upload done, but result is not JSON Object! Result in clipboard. + Hochgeladen, aber die Antwort war kein JSON-Objekt! Die Antwort wurde in die Zwischenablage kopiert. + + + + + Copied upload result to clipboard! + Ergebnis in die Zwischenablage kopiert! + + + + File limit exceeded! + Dateigröße überschritten! + + + + EncoderSettingsDialog + + + Image Encoder Settings + Einstellungen des Bildkodierers + + + + <html><head/><body><p><a href="http://doc.qt.io/qt-5/qpixmap.html#save"><span style=" text-decoration: underline; color:#007af4;">Quality</span></a></p></body></html> + <html><head/><body><p><a href="http://doc.qt.io/qt-5/qpixmap.html#save"><span style=" text-decoration: underline; color:#007af4;">Qualität</span></a></p></body></html> + + + + Format default + Standardwert des Formats + + + + Video Encoder Settings + Videokodierer Einstellungen + + + + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">Preset</span></a></p></body></html> + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">Voreinstellung</span></a></p></body></html> + + + + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">CRF</span></a></p></body></html> + <html><head/><body><p><a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf"><span style=" text-decoration: underline; color:#007af4;">CRF</span></a></p></body></html> + + + + Lossless (not recommended) + Verlustfrei (Nicht empfohlen) + + + + TODO: Find whatever configuration GIF can have in ffmpeg's libav + TODO: Herausfinden welche Konfigurationen ffmpegs "libav" für GIF unterstützt + + + + Bitrate + Bitrate + + + + The number of pictures in a group of pictures, or 0 for intra only + + + + + GOP size + GOP Größe + + + + KShare Encoder Settings + KShare Kodierer Einstellungen + + + + HotkeyInputDialog + + + + + Record + Aufnehmen + + + + Stop recording + Stoppe Aufnahme + + + + ImgplusUploader + + + imgplus API key + "imgpl.us" API key + + + + Enter the imgpl.us API key (Found in Settings) + Gebe den "imgpl.us" API key ein (Kann auf der Website in den Einstellungen gefunden werden) + + + + ImgurSettingsDialog + + + Imgur auth + Imgur Authentifizierung + + + + OAuth2 + OAuth2 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Create a new application:</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Erstelle eine neue Anwendung:</p></body></html> + + + + Open imgur + Öffne "imgur" + + + + Insert Client ID and secret: + gebe die "Client ID" und Geheimnis ein: + + + + Client ID + Client ID + + + + Client Secret + Client Secret + + + + Get the pin + Fordere den PIN an + + + + Insert the pin below: + Gebe den PIN darunter ein: + + + + PIN + PIN + + + + Authorize + Versuche Authorisierung + + + + Not working + Authentifizierung fehlgeschlagen + + + + It works! + Authentifizierung erfolgreich! + + + + ImgurUploader + + + + KShare imgur Uploader + KShare imgur Uploader + + + + Failed upload! Image too big + Hochladen fehlgeschlagen! Das Bild überschreitet die maximale Größe + + + + Uploaded to imgur! + Auf imgur hochgeladen! + + + + KShare imgur Uploader + KShare imgur Uploader + + + + Failed upload! imgur said: HTTP %1: %2 + Hochladen fehlgeschlagen! Imgur hat hiermit geantwortet: "HTTP %1:%2" + + + + MainWindow + + + + Settings + Einstellungen + + + + Log + Protokoll + + + + Fi&le + Date&i + + + + Scree&nshot + Scree&nshot + + + + &Utilities + &Utilities + + + + &Recording + &Aufnahme + + + + &Quit + &Beenden + + + + &Fullscreen + Ganzer &Bildschirm + + + + &Area + &Gebiet + + + + &Color Picker + &Farbpipette + + + + Start + Starten + + + + Stop + Stoppen + + + + About + Über + + + + Active window + Aktives Fenster + + + + Abort + Abbrechen + + + + Recording format not set in settings. Aborting. + Das Format für die Aufnahmen wurde nicht in den Einstellungen definiert. Aufnahme wird abgebrochen. + + + + Quit + Beenden + + + + Show/Hide + Zeigen / Verstecken + + + + Take fullscreen shot + Screenshot des ganzen Bildschirms + + + + Take area shot + Screenshot eines Gebietes + + + + Screenshot active window + Screenshot des aktiven Fensters + + + + Show color picker + Zeige die Farbpipette + + + + Record screen + Bildschirm aufnehmen + + + + Stop recording + Stoppe Aufnahme + + + + Abort recording + Breche Aufnahme ab + + + + QObject + + + + Could not bind the hotkey %1! Is the keybind already registered? + Konnte den Hotkey "%1" nicht erstellen! Ist er bereits registriert? + + + + Could not make config directory + Konnte den Ordner für die Konfigurationsdateien nicht erstellen + + + + Invalid file: + Ungültige Datei: + + + + Failed to upload! Copied the response to clipboard + Hochladen fehlgeschlagen! Die Antwort wurde in die Zwischenablage kopiert + + + + KShare imgplus Uploader + KShare imgplus Uploader + + + + Uploaded to ImagePlus! + Auf ImagePlus hochgeladen! + + + + RecordingFormats + + + Could not create temporary directory. Error: + Konnte den Ordner für die temporären Dateien nicht erstellen. Fehler: + + + + + Encoder error: + Fehler im Kodierer: + + + + RecordingPreview + + + Time: 00:00 +Frame: 0 +Stop key: + Zeit: 00:00 +Bild: 0 +Stopptaste: + + + + Time: %1 +Frame: %2 +Stop key: %3 + Zeit: %1 +Bild: %2 +Stopptaste: %3 + + + + ScreenAreaSelector + + + Set the recording region by resizing this. +%1x%2 + Wähle die Aufnahmeregion indem du die Größe dieses Fensters anpasst. +%1x%2 + + + + KShare: Select Area (By resizing this window) + KShare: Wähle die Region aus (Indem du die Größe dieses Fensters anpasst) + + + + SettingsDialog + + + Crop editor settings + Zuschneideeditor Einstellungen + + + + Quick mode (mouse release screenshots) + Schneller Modus (Maus loslassen reicht) + + + + Delay before taking a screenshot + Verzögerung vor einem Screenshot + + + + In seconds + In Sekunden + + + + A delay before taking a screenshot, in seconds + Verzögerung vor einem Screenshot in Sekunden + + + + Hotkeys + Hotkeys + + + + Still image format + Format für Bilder + + + + Recording format + Aufnahmeformate + + + + Capture cursor + Mauszeiger aufnehmen + + + + %(date format)date and %ext are supported + %(Datumsformat)Datum ujnd %ext werden unterstützt + + + + File name scheme: + Benennungsschema: + + + + Pressing <X> hides to tray + Drücke <X> um dieses Fenster in die Taskleiste zu minimieren + + + + Open settings directory + Öffne Konfigurationsordner + + + + Destination: + Speicherziel: + + + + Pictures folder + Ordner für Bilder + + + + Screenshots folder (In your user folder) + Screenshot ordner (In deinem Benutzerordner) + + + + File save location + Speicherort für Bilder + + + + Advanced + Erweiterte Einstellungen + + + + Editor Position (tweak if the editor does not cover the entire screen) + Editor Position (Ändern, wenn nicht der ganzen Bildschirm ausgefüllt ist) + + + + Encoder settings + Kodierer Einstellungen + + + + Fullscreen image + Screenshot des ganzen Bildschirms + + + + Area image + Screenshot eines Gebietes + + + + Active window + Screenshot des aktiven Fensters + + + + Color picker + Farbpipette + + + + Stop Recording + Stoppe Aufnahme + + + + Start Recording + Starte Aufnahme + + + + Capture cursor (disabled: implementation missing) + Mauszeiger aufnehmen (Deaktiviert: Implementierung fehlt) + + + + TextItem + + + Text to add + Text + + + + Input + Text + + + + UploaderSingleton + + + Cannot determine location for pictures + Die Position des Ordners für Bilder kann nicht bestimmt werden + + + + Cannot determine location of your home directory + Die Position des Benutzerverzeichnisses kann nicht bestimmt werden + + + + Invalid config [saveLocation not int or is not in range] + Ungültige Config (Speicherziel ist keine natürliche Zahl oder nicht in einem gültigen Bereich) + + + + Ambigious uploader + Unklarer Uploadername + + + + Currently selected uploader is not set up properly! Falling back to imgur + Ausgewählter Uploader ist nicht korrekt eingestellt! Nutze imgur als Ersatz + + + + + + KShare - Failed to save picture + KShare - Speichern des Bildes fehlgeschlagen + + + From 242ca2e4b78a76eb0b9857f5bc2b66c47bdff5d9 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 7 Aug 2017 17:16:05 +0200 Subject: [PATCH 140/293] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 35d0bd5..68e5ff4 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A [ShareX](https://getsharex.com/) inspired cross platform utility written with |Linux|Windows|OS X| |:---:|:-----:|:--:| -|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=master)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=master/)|[![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=osxslave)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=osxslave)| +|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=linux)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=linux/)|[![Build status](https://ci.appveyor.com/api/projects/status/7wa4f0bl6u62lo6v?svg=true)](https://ci.appveyor.com/project/ArsenArsen/kshare)|[![Build Status](https://nativeci.arsenarsen.com/buildStatus/icon?job=KShare%20(dev)/main=osx)](https://nativeci.arsenarsen.com/job/KShare%20(dev)/main=osx)| ## Screenshot Made with KShare itself, of course :) ![](http://i.imgur.com/ffWvCun.png) From 1dc5813b79b64edb338d6c8055fa4395924e3511 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 11 Aug 2017 22:33:56 +0200 Subject: [PATCH 141/293] Make crop editor work without workarounds on TWMs Unless your settings are terrible --- cropeditor/cropview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cropeditor/cropview.cpp b/cropeditor/cropview.cpp index 03e34f2..f09f0f1 100644 --- a/cropeditor/cropview.cpp +++ b/cropeditor/cropview.cpp @@ -4,7 +4,7 @@ CropView::CropView(QGraphicsScene *scene) : QGraphicsView(scene) { setFrameShape(QFrame::NoFrame); // Time taken to solve: A george99g and 38 minutes. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::ToolTip); setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); setCursor(QCursor(Qt::CrossCursor)); setMouseTracking(true); From c2cedde21f74b154a883abbd80d6894262c0450b Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Fri, 11 Aug 2017 23:46:40 +0200 Subject: [PATCH 142/293] Fix the last commit --- cropeditor/cropview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cropeditor/cropview.cpp b/cropeditor/cropview.cpp index f09f0f1..a10e72d 100644 --- a/cropeditor/cropview.cpp +++ b/cropeditor/cropview.cpp @@ -4,7 +4,7 @@ CropView::CropView(QGraphicsScene *scene) : QGraphicsView(scene) { setFrameShape(QFrame::NoFrame); // Time taken to solve: A george99g and 38 minutes. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::ToolTip); + setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Popup); setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); setCursor(QCursor(Qt::CrossCursor)); setMouseTracking(true); From 65f9e84a61f6eac570eab06ff74c10f3120228f6 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 12 Aug 2017 00:47:38 +0200 Subject: [PATCH 143/293] This actually fixed it --- cropeditor/cropview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cropeditor/cropview.cpp b/cropeditor/cropview.cpp index a10e72d..7568d0f 100644 --- a/cropeditor/cropview.cpp +++ b/cropeditor/cropview.cpp @@ -4,7 +4,7 @@ CropView::CropView(QGraphicsScene *scene) : QGraphicsView(scene) { setFrameShape(QFrame::NoFrame); // Time taken to solve: A george99g and 38 minutes. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Popup); + setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Dialog); setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); setCursor(QCursor(Qt::CrossCursor)); setMouseTracking(true); From c7da820b5dfa9805b589371bf5091b1081306486 Mon Sep 17 00:00:00 2001 From: poncethecat Date: Fri, 18 Aug 2017 22:23:38 +0100 Subject: [PATCH 144/293] here --- docs/Gemfile | 3 + docs/Gemfile.lock | 216 ++++++++++++++++++++++++++++++++++ docs/_config.yml | 1 + docs/_layouts/layout.html | 66 +++++++++++ docs/_layouts/wikipage.html | 77 ++++++++++++ docs/assets/css/style.scss | 13 ++ docs/{README.md => index.md} | 5 + docs/wiki/Basic-usage.md | 42 +++++++ docs/wiki/Destinations.md | 44 +++++++ docs/wiki/Encoder-settings.md | 29 +++++ docs/wiki/Hotkeys.md | 23 ++++ docs/wiki/Settings.md | 23 ++++ docs/wiki/Tools.md | 34 ++++++ docs/wiki/index.md | 11 ++ 14 files changed, 587 insertions(+) create mode 100644 docs/Gemfile create mode 100644 docs/Gemfile.lock create mode 100644 docs/_layouts/layout.html create mode 100644 docs/_layouts/wikipage.html create mode 100644 docs/assets/css/style.scss rename docs/{README.md => index.md} (98%) create mode 100644 docs/wiki/Basic-usage.md create mode 100644 docs/wiki/Destinations.md create mode 100644 docs/wiki/Encoder-settings.md create mode 100644 docs/wiki/Hotkeys.md create mode 100644 docs/wiki/Settings.md create mode 100644 docs/wiki/Tools.md create mode 100644 docs/wiki/index.md diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 0000000..d35b615 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem "github-pages", group: :jekyll_plugins diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock new file mode 100644 index 0000000..9c69262 --- /dev/null +++ b/docs/Gemfile.lock @@ -0,0 +1,216 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (4.2.8) + i18n (~> 0.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + colorator (1.1.0) + ethon (0.10.1) + ffi (>= 1.3.0) + execjs (2.7.0) + faraday (0.13.0) + multipart-post (>= 1.2, < 3) + ffi (1.9.18) + forwardable-extended (2.6.0) + gemoji (3.0.0) + github-pages (155) + activesupport (= 4.2.8) + github-pages-health-check (= 1.3.5) + jekyll (= 3.5.2) + jekyll-avatar (= 0.4.2) + jekyll-coffeescript (= 1.0.1) + jekyll-default-layout (= 0.1.4) + jekyll-feed (= 0.9.2) + jekyll-gist (= 1.4.1) + jekyll-github-metadata (= 2.8.0) + jekyll-mentions (= 1.2.0) + jekyll-optional-front-matter (= 0.2.0) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.1.0) + jekyll-redirect-from (= 0.12.1) + jekyll-relative-links (= 0.4.1) + jekyll-sass-converter (= 1.5.0) + jekyll-seo-tag (= 2.2.3) + jekyll-sitemap (= 1.0.0) + jekyll-swiss (= 0.4.0) + jekyll-theme-architect (= 0.1.0) + jekyll-theme-cayman (= 0.1.0) + jekyll-theme-dinky (= 0.1.0) + jekyll-theme-hacker (= 0.1.0) + jekyll-theme-leap-day (= 0.1.0) + jekyll-theme-merlot (= 0.1.0) + jekyll-theme-midnight (= 0.1.0) + jekyll-theme-minimal (= 0.1.0) + jekyll-theme-modernist (= 0.1.0) + jekyll-theme-primer (= 0.5.0) + jekyll-theme-slate (= 0.1.0) + jekyll-theme-tactile (= 0.1.0) + jekyll-theme-time-machine (= 0.1.0) + jekyll-titles-from-headings (= 0.4.0) + jemoji (= 0.8.0) + kramdown (= 1.13.2) + liquid (= 4.0.0) + listen (= 3.0.6) + mercenary (~> 0.3) + minima (= 2.1.1) + rouge (= 1.11.1) + terminal-table (~> 1.4) + github-pages-health-check (1.3.5) + addressable (~> 2.3) + net-dns (~> 0.8) + octokit (~> 4.0) + public_suffix (~> 2.0) + typhoeus (~> 0.7) + html-pipeline (2.7.0) + activesupport (>= 2) + nokogiri (>= 1.4) + i18n (0.8.6) + jekyll (3.5.2) + addressable (~> 2.4) + colorator (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.3) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (~> 1.7) + safe_yaml (~> 1.0) + jekyll-avatar (0.4.2) + jekyll (~> 3.0) + jekyll-coffeescript (1.0.1) + coffee-script (~> 2.2) + jekyll-default-layout (0.1.4) + jekyll (~> 3.0) + jekyll-feed (0.9.2) + jekyll (~> 3.3) + jekyll-gist (1.4.1) + octokit (~> 4.2) + jekyll-github-metadata (2.8.0) + jekyll (~> 3.1) + octokit (~> 4.0, != 4.4.0) + jekyll-mentions (1.2.0) + activesupport (~> 4.0) + html-pipeline (~> 2.3) + jekyll (~> 3.0) + jekyll-optional-front-matter (0.2.0) + jekyll (~> 3.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.1.0) + jekyll (~> 3.0) + jekyll-redirect-from (0.12.1) + jekyll (~> 3.3) + jekyll-relative-links (0.4.1) + jekyll (~> 3.3) + jekyll-sass-converter (1.5.0) + sass (~> 3.4) + jekyll-seo-tag (2.2.3) + jekyll (~> 3.3) + jekyll-sitemap (1.0.0) + jekyll (~> 3.3) + jekyll-swiss (0.4.0) + jekyll-theme-architect (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.5.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.2) + jekyll-theme-slate (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.4.0) + jekyll (~> 3.3) + jekyll-watch (1.5.0) + listen (~> 3.0, < 3.1) + jemoji (0.8.0) + activesupport (~> 4.0) + gemoji (~> 3.0) + html-pipeline (~> 2.2) + jekyll (>= 3.0) + kramdown (1.13.2) + liquid (4.0.0) + listen (3.0.6) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9.7) + mercenary (0.3.6) + mini_portile2 (2.2.0) + minima (2.1.1) + jekyll (~> 3.3) + minitest (5.10.3) + multipart-post (2.0.0) + net-dns (0.8.0) + nokogiri (1.8.0) + mini_portile2 (~> 2.2.0) + octokit (4.7.0) + sawyer (~> 0.8.0, >= 0.5.3) + pathutil (0.14.0) + forwardable-extended (~> 2.6) + public_suffix (2.0.5) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + rouge (1.11.1) + safe_yaml (1.0.4) + sass (3.5.1) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + typhoeus (0.8.0) + ethon (>= 0.8.0) + tzinfo (1.2.3) + thread_safe (~> 0.1) + unicode-display_width (1.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + github-pages + +BUNDLED WITH + 1.15.3 diff --git a/docs/_config.yml b/docs/_config.yml index fff4ab9..c5bddac 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1 +1,2 @@ theme: jekyll-theme-minimal +categories: [wiki] diff --git a/docs/_layouts/layout.html b/docs/_layouts/layout.html new file mode 100644 index 0000000..87645da --- /dev/null +++ b/docs/_layouts/layout.html @@ -0,0 +1,66 @@ + + + + + + +{% seo %} + + + + + + +

+
+

{{ site.title | default: site.github.repository_name }}

+

{{ site.description | default: site.github.project_tagline }}

+

Click here to visit the wiki

+ + {% if site.github.is_project_page %} +

View the Project on GitHub {{ github_name }}

+ {% endif %} + + {% if site.github.is_user_page %} +

View My GitHub Profile

+ {% endif %} + + {% if site.show_downloads %} + + {% endif %} +
+
+ + {{ content }} + +
+
+

Copyright (c) ArsenArsen 2017

+ {% if site.github.is_project_page %} +

This project is maintained by {{ site.github.owner_name }}

+ {% endif %} +

Hosted on GitHub Pages — Theme by orderedlist

+
+
+ + + + {% if site.google_analytics %} + + {% endif %} + + diff --git a/docs/_layouts/wikipage.html b/docs/_layouts/wikipage.html new file mode 100644 index 0000000..f0b485b --- /dev/null +++ b/docs/_layouts/wikipage.html @@ -0,0 +1,77 @@ + + + + + + +{% seo %} + + + + + + +
+
+

{{ site.title | default: site.github.repository_name }}

+

{{ site.description | default: site.github.project_tagline }}

+

Click here to go back to the homepage

+

Wiki Pages:

+
    + {% for page in site.pages %} + {% if page.categories contains 'wiki' %} +
  • {{ page.title }}
  • + {% endif %} + {% endfor %} +
+ + +
+
+ {% if site.github.is_project_page %} +

View the Project on GitHub {{ github_name }}

+ {% endif %} + + {% if site.github.is_user_page %} +

View My GitHub Profile

+ {% endif %} + + {% if site.show_downloads %} + + {% endif %} +
+
+ + {{ content }} + +
+
+

Copyright (c) ArsenArsen 2017

+ {% if site.github.is_project_page %} +

This project is maintained by {{ site.github.owner_name }}

+ {% endif %} +

Hosted on GitHub Pages — Theme by orderedlist

+
+
+ + + + {% if site.google_analytics %} + + {% endif %} + + diff --git a/docs/assets/css/style.scss b/docs/assets/css/style.scss new file mode 100644 index 0000000..55a2807 --- /dev/null +++ b/docs/assets/css/style.scss @@ -0,0 +1,13 @@ +--- +--- + +@import "{{ site.theme }}"; + +/* stupid css killed the cat */ +header ul { + background: none; + border-radius: 0px; + border: 0px solid #e0e0e0; + + +} diff --git a/docs/README.md b/docs/index.md similarity index 98% rename from docs/README.md rename to docs/index.md index 2980699..6fc5f93 100644 --- a/docs/README.md +++ b/docs/index.md @@ -1,3 +1,8 @@ +--- +layout: layout +--- + + # **KShare** ## The free open source and cross platform screen sharing software ###### Inspired by [ShareX](https://getsharex.com) diff --git a/docs/wiki/Basic-usage.md b/docs/wiki/Basic-usage.md new file mode 100644 index 0000000..39c0e76 --- /dev/null +++ b/docs/wiki/Basic-usage.md @@ -0,0 +1,42 @@ +--- +title: Basic Usage +categories: [wiki] +layout: wikipage +--- +# Basic usage +When you start the app (with no arguments, discussed later) a window is popped up, and a tray icon is made. + +## The window +![](http://i.imgur.com/QOebwEM.png) + +The main window is a log window with a settings button. + +The menu bar has a `File` menu. It has two options, `Quit`, which exits ~~no need to press it :^)~~, and `About`, which contains licensing information: +![](http://i.imgur.com/4fVJb1w.png) + +There is a second menu, namely `Screenshot`. It has two options, area, and fullscreen capture. See below. + +The third, `Utility`, menu has the color picker in it. + +The third and final menu, `Recording`, has a start and stop recording button. + +## The tray +![](http://i.imgur.com/quVDzRN.png) + +The tray consists of a small, but nice, icon made by @BriannaFoxwell. Upon right clicking it you get the context menu shown above. The menu is rather simple, containing basic controls, and screenshotting options. +These options will be explained below. + +## Screenshotting options +### Area capture +Area capture takes a snapshot of the screen, and shows you a fullscreen editor for you to select a region in. This editor is explained in a section below. + +### Fullscreen capture +Fullscreen capture takes a snapshot of the entire screen and skips the editor part. Straight to the destination (explained later as well). + +### Active window capture +Takes the active window and uploads it straight to your destination of choice + +## Crop Editor +Crop Editor is a window you can use to select the area of the screen to upload. It consists of a grey overlay and a re-sizable rectangle. The rectangle is resized by holding the mouse buttons. When you let go of the button, a new selection will start replacing the old one. On the first press the same thing happens. +Press `Escape` to cancel, and `Return`, or `Enter` to submit. +Oh. And you can draw with right click. diff --git a/docs/wiki/Destinations.md b/docs/wiki/Destinations.md new file mode 100644 index 0000000..7325362 --- /dev/null +++ b/docs/wiki/Destinations.md @@ -0,0 +1,44 @@ +--- +title: Destinations +categories: [wiki] +layout: wikipage +--- +# Destinations +Destinations determine where your image goes + +There is a set of default uploaders, two, to be exact. +## Default uploaders: +### imgur +Uploads your image to imgur. +### clipboard +Copies your image to clipboard. + +## Custom uploaders +Placed into `CONFIG PATH/KShare/uploaders` +Eg: `$HOME/.config/KShare/uploaders` +All uploaders have to be `.uploader` files! +Custom uploaders can be added, and are made with JSON, and follow this template: +```js +{ + "name": "", // String, required + "desc": "", // String, optional + "method": "", // String, default: "POST", for now, just POST. Request more if you need them + "target": "", // URL, required + "format": "", // String, default: "json", can be `x-www-form-urlencoded` or `json` or `multipart-form-data`. Setting to `PLAIN` will make the body ignored and only the image sent. + "base64": false, // Optional, makes the data base64 + "body": {}, // A JSON object, where one of the nodes can be a string in the format `/ANYTHING/`. In `ANYTHING`, `%contenttype` is replaced with the image type and `%imagedata` is replaced with the image encoded with `imageformat`. Unless you use multipart, see below + "return": "" // Return pathspec. `|` copies the entire body, `.path.to.node` copies the value of the node. The dot IS IMPORTANT. Without it, nothing happens. If one of the nodes is not a string, the string is copied, if one is an object, recursion continues, if one is null, nothing is copied, otherwise the node is JSON stringified. Only supports JSON for now. +} +``` +Note that QJson does not support comments. +### Multipart +Multipart is obviously made out of multiple parts. The way you define a multipart body is: +```js +[ + { + "__HeaderName": "HeaderValue", // No limit here. Must start with __, which is removed later. + "body": { /* same way you define it for anything json */ } // Can be string. Strings matching `/.../` are processed same way as in a json field. + } +] +``` +This would go in the `body` field of the above JSON. diff --git a/docs/wiki/Encoder-settings.md b/docs/wiki/Encoder-settings.md new file mode 100644 index 0000000..f90a139 --- /dev/null +++ b/docs/wiki/Encoder-settings.md @@ -0,0 +1,29 @@ +--- +title: Encoder Settings +categories: [wiki] +layout: wikipage +--- +# Encoder settings +The encoders used can be customized to a high degree. Every encoder besides GIF has some settings. +![](http://i.imgur.com/O8nfeos.png) + +## Image encoder settings +The only option here is quality, by default it uses the default for the format you use. You can change it by unticking format default. [More info](http://doc.qt.io/qt-5/qpixmap.html#save) + +## Video encoder settings +The common settings are bitrate and GOP size. + +GOP Size is the size of a group of pictures. +Bitrate is the target bitrate. + +### h264/h265 +The H.26[45] MP4 codec has a few presets to choose. The recommended is to choose the slowest one you can cope with. +I recommend medium. + +CRF is the constant rate factor of this video stream, and again I recommend leaving the default value, `23`. + +### VP9 +VP9 is the WebP codec. Only option it has is lossless encoding, and you want it off, trust me. + +### GIF +GIF has no options. diff --git a/docs/wiki/Hotkeys.md b/docs/wiki/Hotkeys.md new file mode 100644 index 0000000..78f3c93 --- /dev/null +++ b/docs/wiki/Hotkeys.md @@ -0,0 +1,23 @@ +--- +title: Hotkeys +categories: [wiki] +layout: wikipage +--- +# Hotkeys +Hotkeys are configured in the settings UI. +![](http://i.imgur.com/esYoMWo.png) +Currently available hotkeys are: +## Fullscreen image +This bind lets you take a fullscreen image and upload it instantly. +## Area image +Equivalent to `Take area shot` and `Screenshot -> Area`. Takes a snapshot and opens the crop editor. +## Active window +Equivalent to `Active window` and `Screenshot -> Active window`. Takes a snapshot of the active window and sends it. +## Color picker +Opens the color picker +## Recording start/stop +Starts and stops recording + +## Editing hotkeys +All binds can be modified using by double clicking the hotkey name. +You can either type the hotkey in or press record and press the key combination you want on your keyboard diff --git a/docs/wiki/Settings.md b/docs/wiki/Settings.md new file mode 100644 index 0000000..bed6747 --- /dev/null +++ b/docs/wiki/Settings.md @@ -0,0 +1,23 @@ +--- +title: Settings +categories: [wiki] +layout: wikipage +--- +# Settings +## Destination +![](http://i.imgur.com/540REFK.png) +Select the active destination. Adding more is possible and explained it Custom Uploaders +**Default:** `imgur` +## Filename scheme +![](http://i.imgur.com/RHHEO3K.png) +Used to generate filenames. Extensions are placed in place of `%ext`. `%(DATE FORMAT)date` can be used to replace the date format with a format as specified by [this documentation page](http://doc.qt.io/qt-5/qdatetime.html#toString) +**Default:** `Screenshot %(yyyy-MM-dd HH:mm:ss)date.%ext` +## Delay before taking a screenshot +![](http://i.imgur.com/j0D7OqI.png) +Applies only to the buttons in menus. Hotkeys do not follow this rule. In seconds. Mostly used to let animations fade. +Min: `0.00` +Max: `99.99` +**Default:** `0.25` + +## Hotkeys +**Explained on a separate page.** diff --git a/docs/wiki/Tools.md b/docs/wiki/Tools.md new file mode 100644 index 0000000..60c5ec9 --- /dev/null +++ b/docs/wiki/Tools.md @@ -0,0 +1,34 @@ +--- +title: Tools +categories: [wiki] +layout: wikipage +--- +# Drawing +![](http://i.imgur.com/5nWhpqw.png) +On-screen drawing is pretty simple. Right click in the crop editor to show a pen selection tool. When you click on a pen it will stay selected until you press `Reset`. + +You can move drawings around by Ctrl+Dragging them + +## Available pens: +### Dot +Draws dots as you move your mouse +### Path +Makes a path where your mouse went. +### Blur +Allows you to set a rectangle to blur out. You'll get a settings popup upon selecting this pen. +### Straight line +A line between where you start and end dragging +### Text +Asks you to insert some text. +**WARNING:** Avoid pressing return and enter +### Rectangle +Drag to draw a rectangle +### Ellipse +Drag to draw an ellipse +### Eraser[](https://www.youtube.com/watch?v=OjGrcJ4lZCc) +Removes all items you drag your mouse over + +### Clear all drawings +Removes all drawings +### Reset +Allows you to choose a region to cut for the final result. diff --git a/docs/wiki/index.md b/docs/wiki/index.md new file mode 100644 index 0000000..741db33 --- /dev/null +++ b/docs/wiki/index.md @@ -0,0 +1,11 @@ +--- +title: Index +categories: [wiki] +layout: wikipage +--- + +# Welcome to the KShare wiki! +The cross platform screenshotting utility + +# Usage +See the [`Basic usage`](/wiki/Basic-Usage) page From b7edd8a2238cf438dfbf0ba7eac1e0672cfcb947 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 19 Aug 2017 00:29:08 +0200 Subject: [PATCH 145/293] Full screen fix, some site edits and fixes --- cropeditor/cropscene.cpp | 4 +--- docs/README.md | 16 ++++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 6125ebe..f24aa40 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -61,7 +61,7 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) } }); - addDrawingAction(menu, tr("Crop"), ":/icons/crop.png", [] { return nullptr; }); + addDrawingAction(menu, tr("None"), ":/icons/crop.png", [] { return nullptr; }); menu->addSeparator(); QAction *settings = menu->addAction(""); @@ -217,8 +217,6 @@ void CropScene::setVisible(bool visible) { view->setVisible(visible); if (visible) { if (QApplication::screens().size() == 1) view->showFullScreen(); - view->resize(_pixmap.width(), _pixmap.height()); - view->setMinimumSize(_pixmap.size()); QPoint p = screenshotutil::smallestScreenCoordinate() + QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); view->move(p.x(), p.y()); diff --git a/docs/README.md b/docs/README.md index 2980699..c39b6ce 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,5 @@ # **KShare** ## The free open source and cross platform screen sharing software -###### Inspired by [ShareX](https://getsharex.com) KShare is a screenshotting utility built using Qt and written in C++. It has many features, including: @@ -17,28 +16,29 @@ It has many features, including: * Custom upload destinations ## Enough talking, show us how it looks -The main window is rather simple, with only a log, and a button in it: +The main window is rather simple, with only a log, and a button in it: ![image1](http://i.imgur.com/QOebwEM.png) -The settings have quite a bit more going on: +The settings have quite a bit more going on: ![image2](http://i.imgur.com/kZzQzGr.png) -The area selection editor is simple: +The area selection editor is simple: ![image3](http://i.imgur.com/kyWZk3p.jpg) -And the color picker is the simplest thing ever: +And the color picker is the simplest thing ever: ![image4](http://i.imgur.com/VIeGbdQ.jpg) -The way you select the area to record is by resizing this simple widget: +The way you select the area to record is by resizing this simple widget: ![image5](http://i.imgur.com/0iXFHnm.png) -And when you start recording there is a simple preview shown: +And when you start recording there is a simple preview shown: ![image6](http://i.imgur.com/6fu33TR.png) ## Download Currently, the only good download I provide is for Arch Linux and Ubuntu 17.04 The Arch download is on the AUR as `kshare` and `kshare-git`, -and the Ubuntu build is a .deb found on my CI: [kshare.deb](https://nativeci.arsenarsen.com/job/KShare/73/artifact/packages/simpleName.deb) +The OS X and Debian/Ubuntu builds can be found here: [CI](https://nativeci.arsenarsen.com/job/KShare%20(master\)) +There is a windows build on [AppVeyor]() ## Wait.. how do I actually use this? From 45f07cfb997ab1d81f8407c1542a6d55875de66e Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 19 Aug 2017 00:32:20 +0200 Subject: [PATCH 146/293] Update arch packages --- .../arch/KShare/{PKGBUILD.sample => PKGBUILD} | 4 +-- packages/arch/KShare/pre-push | 12 ------- packages/arch/Stable-KShare/PKGBUILD | 10 ++++-- packages/arch/Stable-KShare/PKGBUILD.sample | 31 ------------------- packages/arch/Stable-KShare/release.sh | 5 --- 5 files changed, 9 insertions(+), 53 deletions(-) rename packages/arch/KShare/{PKGBUILD.sample => PKGBUILD} (84%) delete mode 100755 packages/arch/KShare/pre-push delete mode 100644 packages/arch/Stable-KShare/PKGBUILD.sample delete mode 100755 packages/arch/Stable-KShare/release.sh diff --git a/packages/arch/KShare/PKGBUILD.sample b/packages/arch/KShare/PKGBUILD similarity index 84% rename from packages/arch/KShare/PKGBUILD.sample rename to packages/arch/KShare/PKGBUILD index 43d8e28..8f75791 100644 --- a/packages/arch/KShare/PKGBUILD.sample +++ b/packages/arch/KShare/PKGBUILD @@ -31,8 +31,8 @@ build() { package() { cd KShare install -Dm755 KShare "$pkgdir/usr/bin/kshare" - install -Dm644 icons/icon.png "$pkgdir/usr/share/pixmaps/kshare.png" - install -Dm644 KShare.desktop "$pkgdir/usr/share/applications" + install -Dm644 icons/icon.png "$pkgdir/usr/share/pixmaps/KShare.png" + install -Dm644 KShare.desktop "$pkgdir/usr/share/applications/KShare.desktop" install -Dm644 LICENSE "$pkgdir/usr/share/licenses/${pkgname}/LICENSE" } diff --git a/packages/arch/KShare/pre-push b/packages/arch/KShare/pre-push deleted file mode 100755 index 7d393f0..0000000 --- a/packages/arch/KShare/pre-push +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -if [[ `git rev-parse --abbrev-ref HEAD 2>/dev/null` == "dev" ]] -then - HASH=`git rev-parse --verify HEAD` - sed "s/;COMMIT;/c$HASH/g" /media/arsen/Data/Packages/KShare/PKGBUILD.sample > /media/arsen/Data/Packages/KShare/PKGBUILD - cd /media/arsen/Data/Packages/KShare - makepkg --printsrcinfo > .SRCINFO - git stage . - git commit -m "UPDATE $HASH" - git push -fi - diff --git a/packages/arch/Stable-KShare/PKGBUILD b/packages/arch/Stable-KShare/PKGBUILD index 42e737e..2bcf2b6 100644 --- a/packages/arch/Stable-KShare/PKGBUILD +++ b/packages/arch/Stable-KShare/PKGBUILD @@ -1,15 +1,15 @@ # Maintainer: ArsenArsen pkgname=kshare -pkgver=4.1 +pkgver=4.1r6 pkgrel=1 conflicts=("kshare-git") -pkgdesc="A ShareX inspired cross platform utility written with Qt." +pkgdesc="The free and open source and cross platform screen sharing software." arch=('i686' 'x86_64') url="https://github.com/ArsenArsen/KShare" license=('MIT') provides=('kshare=$pkgver') depends=(qt5-base qt5-x11extras xcb-util-cursor ffmpeg libxfixes) -source=(git+https://github.com/ArsenArsen/KShare.git#tag=v${pkgver}) +source=(git+https://github.com/ArsenArsen/KShare.git) sha1sums=('SKIP') build() { @@ -23,5 +23,9 @@ package() { cd "${srcdir}/KShare" mkdir -p "$pkgdir/usr/bin" install ./KShare "$pkgdir/usr/bin/kshare" + mkdir -p "$pkgdir/usr/share/pixmaps" + install "${srcdir}/KShare/icons/icon.png" "$pkgdir/usr/share/pixmaps/KShare.png" + mkdir -p "$pkgdir/usr/share/applications" +# install KShare.desktop "$pkgdir/usr/share/applications" } diff --git a/packages/arch/Stable-KShare/PKGBUILD.sample b/packages/arch/Stable-KShare/PKGBUILD.sample deleted file mode 100644 index 48829e6..0000000 --- a/packages/arch/Stable-KShare/PKGBUILD.sample +++ /dev/null @@ -1,31 +0,0 @@ -# Maintainer: ArsenArsen -pkgname=kshare -pkgver=;VER; -pkgrel=1 -conflicts=("kshare-git") -pkgdesc="The free and open source and cross platform screen sharing software." -arch=('i686' 'x86_64') -url="https://github.com/ArsenArsen/KShare" -license=('MIT') -provides=('kshare=$pkgver') -depends=(qt5-base qt5-svg qt5-x11extras xcb-util-cursor ffmpeg libxfixes) -source=(git+https://github.com/ArsenArsen/KShare.git#tag=v${pkgver}) -sha1sums=('SKIP') - -build() { - cd "${srcdir}/KShare" - git submodule update --init --recursive - qmake - make -j$(($(nproc) + 1)) -} - -package() { - cd "${srcdir}/KShare" - mkdir -p "$pkgdir/usr/bin" - install ./KShare "$pkgdir/usr/bin/kshare" - mkdir -p "$pkgdir/usr/share/pixmaps" - install "${srcdir}/KShare/icons/icon.png" "$pkgdir/usr/share/pixmaps" - mkdir -p "$pkgdir/usr/share/applications" - install KShare.desktop "$pkgdir/usr/share/applications" -} - diff --git a/packages/arch/Stable-KShare/release.sh b/packages/arch/Stable-KShare/release.sh deleted file mode 100755 index 9d2ce27..0000000 --- a/packages/arch/Stable-KShare/release.sh +++ /dev/null @@ -1,5 +0,0 @@ -sed "s/;VER;/$1/" PKGBUILD.sample > PKGBUILD -makepkg --printsrcinfo > .SRCINFO -git stage .SRCINFO PKGBUILD -git commit -m "Release $1" -git push From 206387578c78e4e2e3bac83da80ec0179658af85 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 19 Aug 2017 00:45:26 +0200 Subject: [PATCH 147/293] Further consistency for icon names --- KShare.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KShare.desktop b/KShare.desktop index 909c550..2a9774b 100755 --- a/KShare.desktop +++ b/KShare.desktop @@ -3,7 +3,7 @@ Name=KShare Comment=A ShareX inspired cross platform screen capture utility written with Qt. GenericName=Screenshot Capture Utility Exec=/usr/bin/kshare -Icon=/usr/share/pixmaps/kshare.png +Icon=/usr/share/pixmaps/KShare.png Type=Application StartupNotify=false Categories=Qt;Utility; From 4ecade7b2ee75186da1fb911a0a9a6743d17b654 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sun, 20 Aug 2017 17:06:44 +0200 Subject: [PATCH 148/293] Revamp logging system Plan: * Have a dialog that shows history * Once you double click an item it opens the response in a new window --- logs/requestlogging.cpp | 61 +++++++++++++++++++++++++++++++---------- logs/requestlogging.hpp | 31 ++++++++++++++++++++- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/logs/requestlogging.cpp b/logs/requestlogging.cpp index 4b38b8f..3ff5edd 100644 --- a/logs/requestlogging.cpp +++ b/logs/requestlogging.cpp @@ -1,33 +1,64 @@ #include "requestlogging.hpp" #include #include +#include #include -#include -QDir responses(settings::dir().absoluteFilePath("response")); +// $type $url $status $time +// $type = GET POST PATCH DELETE etc +// $url = request target +// $status = response code +// $time = time of request, file name for response: $SETTINGS_DIR/responses/$time + +QDir responses(settings::dir().absoluteFilePath("responses")); +QString requestPath = settings::dir().absoluteFilePath("history"); + void requestlogging::addEntry(RequestContext context) { if (!responses.exists()) responses.mkpath("."); - QFile responseFile(responses.absoluteFilePath(context.sender + "-" + QDateTime().toString("yyyy-MM-dd HH-mm-ss"))); + QString timeNow = QDateTime::currentDateTime().toUTC().toString("yyyy-MM-dd HH-mm-ss-zzz"); + QFile responseFile(responses.absoluteFilePath(timeNow)); + QFile requestFile(requestPath); + if (!responseFile.open(QIODevice::WriteOnly)) { qCritical().noquote() << "Could not save response! " + responseFile.errorString(); return; } - responseFile.write(( // - ioutils::methodString(context.reply->operation()) + // write method - " " + // space - context.reply->url().toString() + // write url - " " + // space - QString::number(context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()) // - + // write status - "\n" // newline - ) - .toUtf8()); + + if (!requestFile.open(QIODevice::Append)) { + qCritical().noquote() << "Could not append request! " + responseFile.errorString(); + return; + } + for (auto header : context.reply->rawHeaderList()) responseFile.write(header + "\n"); responseFile.write("\n\n" + context.response); responseFile.close(); - addGUIEntry(context, QFileInfo(responseFile).absoluteFilePath()); + QTextStream(&requestFile) << ioutils::methodString(context.reply->operation()) << " " // $type + << context.reply->url().toString() << " " // $url + << context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() // $status + << timeNow; // $time + requestFile.close(); } -void requestlogging::addGUIEntry(RequestContext context, QString file) { +using requestlogging::LoggedRequest; + +QList requestlogging::getRequests() { + QList ret; + + QFile requestFile(requestPath); + + QByteArray line; + while ((line = requestFile.readLine()).size() != 0) { + LoggedRequest r; + QTextStream stream(&line); + stream >> r.type; + stream >> r.url; + stream >> r.responseCode; + QString time; + stream >> time; + r.time = QDateTime::fromString(time, "yyyy-MM-dd HH-mm-ss-zzz"); + ret.append(r); + } + + return ret; } diff --git a/logs/requestlogging.hpp b/logs/requestlogging.hpp index fe6da48..ae2483c 100644 --- a/logs/requestlogging.hpp +++ b/logs/requestlogging.hpp @@ -3,6 +3,7 @@ #include #include +#include struct RequestContext { QByteArray response; @@ -12,7 +13,35 @@ struct RequestContext { namespace requestlogging { void addEntry(RequestContext context); -void addGUIEntry(RequestContext context, QString file); + +class LoggedRequest { + friend QList getRequests(); + +public: + QString getUrl() { + return url; + } + QString getType() { + return type; + } + QDateTime getTime() { + return time; + } + int getResponseCode() { + return responseCode; + } + QByteArray getResponse() { + return QFile(settings::dir().absoluteFilePath("responses/" + time.toString("yyyy-MM-dd HH-mm-ss-zzz"))).readAll(); + } + +private: + QString url; + QString type; + QDateTime time; + int responseCode; +}; + +QList getRequests(); } #endif // REQUESTLOGGING_HPP From db24653f7dd5578fcfd245f3b3f274715c8b5b8a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 21 Aug 2017 16:17:20 +0200 Subject: [PATCH 149/293] Request logging --- KShare.pro | 12 ++++-- io/ioutils.cpp | 25 ++++++++++-- logs/historydialog.cpp | 37 +++++++++++++++++ logs/historydialog.h | 24 +++++++++++ logs/historydialog.ui | 88 +++++++++++++++++++++++++++++++++++++++++ logs/requestlogging.cpp | 18 +++++---- logs/requestlogging.hpp | 17 ++++---- mainwindow.cpp | 6 +++ mainwindow.hpp | 1 + mainwindow.ui | 31 +++++++++------ monospacetextdialog.cpp | 13 ++++++ monospacetextdialog.h | 21 ++++++++++ monospacetextdialog.ui | 73 ++++++++++++++++++++++++++++++++++ 13 files changed, 331 insertions(+), 35 deletions(-) create mode 100644 logs/historydialog.cpp create mode 100644 logs/historydialog.h create mode 100644 logs/historydialog.ui create mode 100644 monospacetextdialog.cpp create mode 100644 monospacetextdialog.h create mode 100644 monospacetextdialog.ui diff --git a/KShare.pro b/KShare.pro index 1b95264..78b1496 100644 --- a/KShare.pro +++ b/KShare.pro @@ -64,7 +64,9 @@ SOURCES += main.cpp\ uploaders/default/imgursettingsdialog.cpp \ uploaders/default/imgplusuploader.cpp \ filenamevalidator.cpp \ - logs/requestlogging.cpp + logs/requestlogging.cpp \ + logs/historydialog.cpp \ + monospacetextdialog.cpp HEADERS += mainwindow.hpp \ cropeditor/cropeditor.hpp \ @@ -109,7 +111,9 @@ HEADERS += mainwindow.hpp \ uploaders/default/imgursettingsdialog.hpp \ uploaders/default/imgplusuploader.hpp \ filenamevalidator.hpp \ - logs/requestlogging.hpp + logs/requestlogging.hpp \ + logs/historydialog.h \ + monospacetextdialog.h nopkg { # win32 { @@ -161,7 +165,9 @@ FORMS += mainwindow.ui \ settingsdialog.ui \ aboutbox.ui \ hotkeyinputdialog.ui \ - uploaders/default/imgursettingsdialog.ui + uploaders/default/imgursettingsdialog.ui \ + logs/historydialog.ui \ + monospacetextdialog.ui DISTFILES += \ README.md \ diff --git a/io/ioutils.cpp b/io/ioutils.cpp index 5753178..0f54d0e 100644 --- a/io/ioutils.cpp +++ b/io/ioutils.cpp @@ -3,9 +3,19 @@ #include #include #include +#include QNetworkAccessManager ioutils::networkManager; +void addLogEntry(QNetworkReply *reply, QByteArray data) { + requestlogging::RequestContext ctx; + + ctx.reply = reply; + ctx.response = data; + + requestlogging::addEntry(ctx); +} + void ioutils::postMultipart(QUrl target, QList> headers, QHttpMultiPart *body, @@ -17,6 +27,7 @@ void ioutils::postMultipart(QUrl target, QNetworkReply *reply = networkManager.post(req, body); QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { QByteArray data = reply->readAll(); + addLogEntry(reply, data); callback(QJsonDocument::fromJson(data), data, reply); delete reply; }); @@ -32,7 +43,9 @@ void ioutils::postMultipartData(QUrl target, } QNetworkReply *reply = networkManager.post(req, body); QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { - callback(reply->readAll(), reply); + QByteArray data = reply->readAll(); + addLogEntry(reply, data); + callback(data, reply); delete reply; }); } @@ -47,6 +60,7 @@ void ioutils::getJson(QUrl target, QNetworkReply *reply = networkManager.get(req); QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { QByteArray data = reply->readAll(); + addLogEntry(reply, data); callback(QJsonDocument::fromJson(data), data, reply); reply->deleteLater(); }); @@ -63,6 +77,7 @@ void ioutils::postJson(QUrl target, QNetworkReply *reply = networkManager.post(req, body); QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { QByteArray data = reply->readAll(); + addLogEntry(reply, data); callback(QJsonDocument::fromJson(data), data, reply); delete reply; }); @@ -75,7 +90,9 @@ void ioutils::getData(QUrl target, QList> headers, std:: } QNetworkReply *reply = networkManager.get(req); QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { - callback(reply->readAll(), reply); + QByteArray data = reply->readAll(); + addLogEntry(reply, data); + callback(data, reply); delete reply; }); } @@ -90,7 +107,9 @@ void ioutils::postData(QUrl target, } QNetworkReply *reply = networkManager.post(req, body); QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { - callback(reply->readAll(), reply); + QByteArray data = reply->readAll(); + addLogEntry(reply, data); + callback(data, reply); delete reply; }); } diff --git a/logs/historydialog.cpp b/logs/historydialog.cpp new file mode 100644 index 0000000..9cd2f47 --- /dev/null +++ b/logs/historydialog.cpp @@ -0,0 +1,37 @@ +#include "historydialog.h" +#include "requestlogging.hpp" +#include "ui_historydialog.h" + +#include + +using requestlogging::LoggedRequest; + +HistoryDialog::HistoryDialog(QWidget *parent) : QDialog(parent), ui(new Ui::HistoryDialog) { + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + ui->treeWidget->setColumnWidth(0, 50); + ui->treeWidget->setColumnWidth(1, 150); + ui->treeWidget->setColumnWidth(2, 50); + ui->treeWidget->setColumnWidth(3, 100); + + QList requests = requestlogging::getRequests(); + for (LoggedRequest req : requests) { + ui->treeWidget->addTopLevelItem(new QTreeWidgetItem( + { req.getType(), req.getUrl(), QString::number(req.getResponseCode()), req.getTime() + " UTC" })); + } +} + +HistoryDialog::~HistoryDialog() { + delete ui; +} + +void HistoryDialog::on_treeWidget_doubleClicked(const QModelIndex &) { + QString file = ui->treeWidget->currentItem()->text(3); + file = settings::dir().absoluteFilePath("responses/" + file.left(file.length() - 4)); + + QFile dataFile(file); + if (!dataFile.open(QIODevice::ReadOnly)) return; + MonospaceTextDialog *dialog = new MonospaceTextDialog(file, dataFile.readAll()); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); +} diff --git a/logs/historydialog.h b/logs/historydialog.h new file mode 100644 index 0000000..a3d3d36 --- /dev/null +++ b/logs/historydialog.h @@ -0,0 +1,24 @@ +#ifndef HISTORYDIALOG_H +#define HISTORYDIALOG_H + +#include + +namespace Ui { +class HistoryDialog; +} + +class HistoryDialog : public QDialog { + Q_OBJECT + +public: + explicit HistoryDialog(QWidget *parent = 0); + ~HistoryDialog(); + +private slots: + void on_treeWidget_doubleClicked(const QModelIndex &); + +private: + Ui::HistoryDialog *ui; +}; + +#endif // HISTORYDIALOG_H diff --git a/logs/historydialog.ui b/logs/historydialog.ui new file mode 100644 index 0000000..556f425 --- /dev/null +++ b/logs/historydialog.ui @@ -0,0 +1,88 @@ + + + HistoryDialog + + + + 0 + 0 + 400 + 300 + + + + Request History + + + + + + + Type + + + + + URL + + + + + Status + + + + + Time + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + HistoryDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + HistoryDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/logs/requestlogging.cpp b/logs/requestlogging.cpp index 3ff5edd..593436f 100644 --- a/logs/requestlogging.cpp +++ b/logs/requestlogging.cpp @@ -13,6 +13,7 @@ QDir responses(settings::dir().absoluteFilePath("responses")); QString requestPath = settings::dir().absoluteFilePath("history"); + void requestlogging::addEntry(RequestContext context) { if (!responses.exists()) responses.mkpath("."); QString timeNow = QDateTime::currentDateTime().toUTC().toString("yyyy-MM-dd HH-mm-ss-zzz"); @@ -29,14 +30,15 @@ void requestlogging::addEntry(RequestContext context) { return; } - for (auto header : context.reply->rawHeaderList()) responseFile.write(header + "\n"); + for (auto header : context.reply->rawHeaderList()) + responseFile.write(header + ": " + context.reply->rawHeader(header) + "\n"); responseFile.write("\n\n" + context.response); responseFile.close(); - QTextStream(&requestFile) << ioutils::methodString(context.reply->operation()) << " " // $type - << context.reply->url().toString() << " " // $url - << context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() // $status - << timeNow; // $time + QTextStream(&requestFile) << ioutils::methodString(context.reply->operation()) << " " // $type + << context.reply->url().toString() << " " // $url + << context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() << " " // $status + << timeNow.replace(" ", "_"); // $time requestFile.close(); } @@ -46,6 +48,7 @@ QList requestlogging::getRequests() { QList ret; QFile requestFile(requestPath); + if (!requestFile.exists() || !requestFile.open(QIODevice::ReadOnly)) return ret; QByteArray line; while ((line = requestFile.readLine()).size() != 0) { @@ -54,9 +57,8 @@ QList requestlogging::getRequests() { stream >> r.type; stream >> r.url; stream >> r.responseCode; - QString time; - stream >> time; - r.time = QDateTime::fromString(time, "yyyy-MM-dd HH-mm-ss-zzz"); + stream >> r.time; + r.time = r.time.replace("_", " "); ret.append(r); } diff --git a/logs/requestlogging.hpp b/logs/requestlogging.hpp index ae2483c..87202ef 100644 --- a/logs/requestlogging.hpp +++ b/logs/requestlogging.hpp @@ -5,14 +5,12 @@ #include #include -struct RequestContext { - QByteArray response; - QString sender; - QNetworkReply *reply; -}; namespace requestlogging { -void addEntry(RequestContext context); +struct RequestContext { + QByteArray response; + QNetworkReply *reply; +}; class LoggedRequest { friend QList getRequests(); @@ -24,24 +22,25 @@ public: QString getType() { return type; } - QDateTime getTime() { + QString getTime() { return time; } int getResponseCode() { return responseCode; } QByteArray getResponse() { - return QFile(settings::dir().absoluteFilePath("responses/" + time.toString("yyyy-MM-dd HH-mm-ss-zzz"))).readAll(); + return QFile(settings::dir().absoluteFilePath("responses/" + time)).readAll(); } private: QString url; QString type; - QDateTime time; + QString time; int responseCode; }; QList getRequests(); +void addEntry(RequestContext context); } #endif // REQUESTLOGGING_HPP diff --git a/mainwindow.cpp b/mainwindow.cpp index 22375ba..afd8370 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -181,3 +182,8 @@ void MainWindow::on_actionActive_window_triggered() { void MainWindow::on_actionAbort_triggered() { controller->abort(); } + +void MainWindow::on_history_clicked() { + HistoryDialog *dialog = new HistoryDialog; + dialog->show(); +} diff --git a/mainwindow.hpp b/mainwindow.hpp index 5bb6e75..9cf807e 100644 --- a/mainwindow.hpp +++ b/mainwindow.hpp @@ -30,6 +30,7 @@ private slots: void on_actionAbout_triggered(); void on_actionActive_window_triggered(); void on_actionAbort_triggered(); + void on_history_clicked(); public: static MainWindow *inst(); diff --git a/mainwindow.ui b/mainwindow.ui index 3328122..63f1a40 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 352 - 220 + 340 + 239 @@ -25,13 +25,6 @@ - - - - Settings - - - @@ -44,15 +37,30 @@ + + + + Settings + + + + + + + Open request history + + + + 0 0 - 352 - 25 + 340 + 22 @@ -91,7 +99,6 @@ - &Quit diff --git a/monospacetextdialog.cpp b/monospacetextdialog.cpp new file mode 100644 index 0000000..cef111a --- /dev/null +++ b/monospacetextdialog.cpp @@ -0,0 +1,13 @@ +#include "monospacetextdialog.h" +#include "ui_monospacetextdialog.h" + +MonospaceTextDialog::MonospaceTextDialog(QString name, QByteArray data, QWidget *parent) +: QDialog(parent), ui(new Ui::MonospaceTextDialog) { + ui->setupUi(this); + setWindowTitle(name); + ui->textEdit->setText(data); +} + +MonospaceTextDialog::~MonospaceTextDialog() { + delete ui; +} diff --git a/monospacetextdialog.h b/monospacetextdialog.h new file mode 100644 index 0000000..d2b6463 --- /dev/null +++ b/monospacetextdialog.h @@ -0,0 +1,21 @@ +#ifndef MONOSPACETEXTDIALOG_H +#define MONOSPACETEXTDIALOG_H + +#include + +namespace Ui { +class MonospaceTextDialog; +} + +class MonospaceTextDialog : public QDialog { + Q_OBJECT + +public: + explicit MonospaceTextDialog(QString name, QByteArray data, QWidget *parent = 0); + ~MonospaceTextDialog(); + +private: + Ui::MonospaceTextDialog *ui; +}; + +#endif // MONOSPACETEXTDIALOG_H diff --git a/monospacetextdialog.ui b/monospacetextdialog.ui new file mode 100644 index 0000000..8c72446 --- /dev/null +++ b/monospacetextdialog.ui @@ -0,0 +1,73 @@ + + + MonospaceTextDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + + Monospace + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + MonospaceTextDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + MonospaceTextDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + From 4d53e2c403d5bbefdee3196c7d2cc56168036280 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 21 Aug 2017 16:23:07 +0200 Subject: [PATCH 150/293] Update some properties --- logs/historydialog.ui | 2 +- monospacetextdialog.ui | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/logs/historydialog.ui b/logs/historydialog.ui index 556f425..39d98ff 100644 --- a/logs/historydialog.ui +++ b/logs/historydialog.ui @@ -44,7 +44,7 @@ Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Close diff --git a/monospacetextdialog.ui b/monospacetextdialog.ui index 8c72446..5a98ec3 100644 --- a/monospacetextdialog.ui +++ b/monospacetextdialog.ui @@ -16,11 +16,17 @@ + + true + Monospace + + true + From 6881200563168969bf36a3152f35b5ef523aac8d Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 21 Aug 2017 16:25:11 +0200 Subject: [PATCH 151/293] Fix newlines --- logs/requestlogging.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/logs/requestlogging.cpp b/logs/requestlogging.cpp index 593436f..3da7d51 100644 --- a/logs/requestlogging.cpp +++ b/logs/requestlogging.cpp @@ -38,7 +38,8 @@ void requestlogging::addEntry(RequestContext context) { QTextStream(&requestFile) << ioutils::methodString(context.reply->operation()) << " " // $type << context.reply->url().toString() << " " // $url << context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() << " " // $status - << timeNow.replace(" ", "_"); // $time + << timeNow.replace(" ", "_") << endl + << flush; // $time requestFile.close(); } From c5bf007234c4505fd132ab4c9e6a1ebd9246d366 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 21 Aug 2017 16:35:02 +0200 Subject: [PATCH 152/293] Update Serbian translation --- monospacetextdialog.ui | 2 +- translations/sr_RS.qm | Bin 25251 -> 25660 bytes translations/sr_RS.ts | 91 ++++++++++++++++++++++++++++------------- 3 files changed, 63 insertions(+), 30 deletions(-) diff --git a/monospacetextdialog.ui b/monospacetextdialog.ui index 5a98ec3..8749ed5 100644 --- a/monospacetextdialog.ui +++ b/monospacetextdialog.ui @@ -11,7 +11,7 @@ - Dialog + Dialog diff --git a/translations/sr_RS.qm b/translations/sr_RS.qm index 2af58eb04184d04707243511823a2813cf376c21..3ee9fb6ac8dbee81b382604563962759033c04ea 100644 GIT binary patch delta 1908 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 diff --git a/translations/sr_RS.ts b/translations/sr_RS.ts index 58fd583..ff90167 100644 --- a/translations/sr_RS.ts +++ b/translations/sr_RS.ts @@ -292,8 +292,8 @@ - Crop - Opseci + None + Ništa @@ -311,7 +311,7 @@ Otkaži - + KShare Crop Editor KShare Urednik Slika @@ -550,6 +550,34 @@ KShare Podešavanja Kodeka + + HistoryDialog + + + Request History + Istorija slanja + + + + Type + Tip + + + + URL + URL + + + + Status + Status + + + + Time + Vreme + + HotkeyInputDialog @@ -686,128 +714,133 @@ p, li { white-space: pre-wrap; } MainWindow - - + + Settings Podešavanja - + Log Zapis - + + Open request history + Prikaži istoriju slanja + + + Fi&le Faj&l - + Scree&nshot Slika&nje - + &Utilities &Alati - + &Recording &Snjimanje - + &Quit Iza&đi - + &Fullscreen &Ceo Ekran - + &Area &Prostor - + &Color Picker &Birač Boja - + Start Počni - + Stop Zaustavi - + About O Programu - + Active window Aktivni prozor - + Abort Obustavi - + Recording format not set in settings. Aborting. Format snjimanja nije podešen! Otkazujem. - + Quit Izađi - + Show/Hide Prikaži/Sakrij - + Take fullscreen shot Slikaj ceo ekran - + Take area shot Slikaj deo ekrana - + Screenshot active window Slikaj trenutni prozor - + Show color picker Prikaži birač boja - + Record screen Snjimi ekran - + Stop recording Zaustavi snjimanje - + Abort recording Obustavi snjimanje From c5f16293134ff09b2bb59864829f3a0075d2275c Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 21 Aug 2017 17:34:38 +0200 Subject: [PATCH 153/293] Wiki update --- docs/_layouts/wikipage.html | 62 ++++++++++++++++++------------------- docs/wiki/Basic-usage.md | 2 +- docs/wiki/Tools.md | 2 +- docs/wiki/index.md | 2 +- 4 files changed, 33 insertions(+), 35 deletions(-) diff --git a/docs/_layouts/wikipage.html b/docs/_layouts/wikipage.html index f0b485b..6a5e042 100644 --- a/docs/_layouts/wikipage.html +++ b/docs/_layouts/wikipage.html @@ -4,12 +4,12 @@ -{% seo %} + {% seo %} @@ -17,42 +17,40 @@

{{ site.title | default: site.github.repository_name }}

{{ site.description | default: site.github.project_tagline }}

-

Click here to go back to the homepage

-

Wiki Pages:

-
    - {% for page in site.pages %} - {% if page.categories contains 'wiki' %} -
  • {{ page.title }}
  • - {% endif %} - {% endfor %} -
- +

Click here to go back to the homepage

-
-
- {% if site.github.is_project_page %} -

View the Project on GitHub {{ github_name }}

+ {% for page in site.pages %} + {% if page.categories contains 'wiki' %} + {{ page.title }}
+ {% endif %} + {% endfor %} + + +
+
+ {% if site.github.is_project_page %} +

View the Project on GitHub {{ github_name }}

{% endif %} {% if site.github.is_user_page %} -

View My GitHub Profile

+

View My GitHub Profile

{% endif %} {% if site.show_downloads %} - + {% endif %}
- {{ content }} + {{ content }}