commit e38231f2b19151299aadd615107d058ee990d4de Author: ArsenArsen Date: Sun Apr 23 15:05:48 2017 +0200 Initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d6839f7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,48 @@ +# C++ objects and libs + +*.slo +*.lo +*.o +*.a +*.la +*.lai +*.so +*.dll +*.dylib + +# Qt-es + +/.qmake.cache +/.qmake.stash +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +qrc_*.cpp +ui_*.h +Makefile* +*build-* + +# QtCreator + +*.autosave + +# QtCtreator Qml +*.qmlproject.user +*.qmlproject.user.* + +# QtCtreator CMake +CMakeLists.txt.user +Makefile + +# Executable +KShare + +# Other +*.out + +*.Debug + +*.Release diff --git a/KShare.pro b/KShare.pro new file mode 100644 index 0000000..61733fc --- /dev/null +++ b/KShare.pro @@ -0,0 +1,64 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-04-19T15:47:09 +# +#------------------------------------------------- + +QT += core gui network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = KShare +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += main.cpp\ + mainwindow.cpp \ + cropeditor/cropeditor.cpp \ + cropeditor/cropview.cpp \ + cropeditor/cropscene.cpp \ + uploaders/uploadersingleton.cpp \ + screenshotter.cpp \ + screenshotutil.cpp \ + uploaders/default/imguruploader.cpp \ + io/ioutils.cpp \ + settings.cpp \ + uploaders/default/clipboarduploader.cpp + +HEADERS += mainwindow.hpp \ + cropeditor/cropeditor.hpp \ + cropeditor/cropview.hpp \ + cropeditor/cropscene.hpp \ + uploaders/uploader.hpp \ + uploaders/uploadersingleton.hpp \ + screenshotter.hpp \ + screenshotutil.hpp \ + uploaders/default/imguruploader.hpp \ + io/ioutils.hpp \ + settings.hpp \ + uploaders/default/clipboarduploader.hpp + +FORMS += mainwindow.ui + +DISTFILES += \ + README.md \ + LICENSE + +RESOURCES += \ + icon.qrc + +ICON = icons/favicon.ico + +# Enable debug symbols +QMAKE_CFLAGS_DEBUG += -g diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e8d61c9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..416d3e3 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# KShare +A [ShareX](https://github.com/ShareX/) clone written in Qt. Should be cross platform + +**Note:** Windows users, stick to ShareX. + +## Goals +* Same support for Windows, Linux and Mac (if I ever get testers) +* Screenshotting: +* 1. Fullscreen, +* 2. Area; +* Screen recording, same options as above: +* 1. WebM +* 2. GIF (nopls) +* Custom uploader support +* Default uploaders, including: +* 1. imgur +* 2. Clipboard (not an uploader) +* 3. (S)FTP +* Oh, and a good icon. + +###### Started on 19th of April 2017 to bring some attention and improvement to Linux screenshotting. diff --git a/cropeditor/cropeditor.cpp b/cropeditor/cropeditor.cpp new file mode 100644 index 0000000..2b12978 --- /dev/null +++ b/cropeditor/cropeditor.cpp @@ -0,0 +1,38 @@ +#include "cropeditor.hpp" + +#include "cropview.hpp" +#include +#include +#include +#include + +CropEditor::CropEditor(QPixmap *image, QObject *parent) : QObject(parent) +{ + pixmap = image; + scene = new CropScene(parent); + view = new CropView(scene); + + pixmapItem = new QGraphicsPixmapItem(*pixmap); + scene->addItem(pixmapItem); + scene->setSceneRect(pixmap->rect()); + + QTimer::singleShot(0, [&] { view->showFullScreen(); }); + + connect(scene, &CropScene::closedWithRect, this, &CropEditor::crop); +} + +CropEditor::~CropEditor() +{ + delete scene; + delete view; + delete pixmap; + delete pixmapItem; +} + +void CropEditor::crop(QRect rect) +{ + QPixmap crop = pixmap->copy(rect); + QPixmap *cropp = new QPixmap; + crop.swap(*cropp); + emit cropped(cropp); +} diff --git a/cropeditor/cropeditor.hpp b/cropeditor/cropeditor.hpp new file mode 100644 index 0000000..cd50e22 --- /dev/null +++ b/cropeditor/cropeditor.hpp @@ -0,0 +1,28 @@ +#ifndef CROPEDITOR_HPP +#define CROPEDITOR_HPP + +#include "cropscene.hpp" +#include "cropview.hpp" +#include +#include +#include +#include + +class CropEditor : public QObject +{ + Q_OBJECT + public: + CropEditor(QPixmap *image, QObject *parent = 0); + ~CropEditor(); + signals: + QPixmap *cropped(QPixmap *pixmap); + + private: + void crop(QRect rect); + QPixmap *pixmap = nullptr; + CropScene *scene = nullptr; + CropView *view = nullptr; + QGraphicsPixmapItem *pixmapItem = nullptr; +}; + +#endif // CROPEDITOR_HPP diff --git a/cropeditor/cropeditor.ui b/cropeditor/cropeditor.ui new file mode 100644 index 0000000..757b834 --- /dev/null +++ b/cropeditor/cropeditor.ui @@ -0,0 +1,19 @@ + + + CropEditor + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp new file mode 100644 index 0000000..17c0125 --- /dev/null +++ b/cropeditor/cropscene.cpp @@ -0,0 +1,70 @@ +#include "cropscene.hpp" +#include +#include + +CropScene::CropScene(QObject *parent) : QGraphicsScene(parent), prevButtons(Qt::NoButton) +{ +} + +CropScene::~CropScene() +{ + delete rect; +} + +void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) +{ + auto buttons = e->buttons(); + if (buttons == Qt::LeftButton || prevButtons == Qt::NoButton) + { + QPointF p = e->scenePos(); + 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); + addItem(rect); + } + else + { + if (prevButtons == Qt::NoButton) + { + initPos = p; + rect->setRect(p.x(), p.y(), 1, 1); + } + else + { + rect->setRect(QRect(qMin(initPos.x(), p.x()), qMin(initPos.y(), p.y()), + qAbs(initPos.x() - p.x()), qAbs(initPos.y() - p.y()))); + } + } + e->accept(); + } + else + QGraphicsScene::mouseMoveEvent(e); + prevButtons = buttons; +} + +void CropScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) +{ + prevButtons = Qt::NoButton; + QGraphicsScene::mouseReleaseEvent(e); +} + +void CropScene::keyReleaseEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) done(); +} + +void CropScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) +{ + done(); + QGraphicsScene::mouseDoubleClickEvent(e); +} + +void CropScene::done() +{ + for (QGraphicsView *v : views()) v->close(); + emit closedWithRect(rect != nullptr ? rect->rect().toRect() : QRect()); +} diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp new file mode 100644 index 0000000..cbd4723 --- /dev/null +++ b/cropeditor/cropscene.hpp @@ -0,0 +1,32 @@ +#ifndef CROPSCENE_HPP +#define CROPSCENE_HPP + +#include +#include +#include +#include + +class CropScene : public QGraphicsScene +{ + Q_OBJECT + public: + CropScene(QObject *parent); + virtual ~CropScene(); + signals: + void closedWithRect(QRect rect); + + protected: + void mouseMoveEvent(QGraphicsSceneMouseEvent *e) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent *e) override; + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) override; + + void keyReleaseEvent(QKeyEvent *e) override; + + private: + void done(); + QFlags prevButtons; + QGraphicsRectItem *rect = nullptr; + QPointF initPos; +}; + +#endif // CROPSCENE_HPP diff --git a/cropeditor/cropview.cpp b/cropeditor/cropview.cpp new file mode 100644 index 0000000..5f383bd --- /dev/null +++ b/cropeditor/cropview.cpp @@ -0,0 +1,20 @@ +#include "cropview.hpp" + +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(Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint); +} + +void CropView::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Escape) + { + close(); + e->accept(); + return; + } + QGraphicsView::keyPressEvent(e); +} diff --git a/cropeditor/cropview.hpp b/cropeditor/cropview.hpp new file mode 100644 index 0000000..15eeaaa --- /dev/null +++ b/cropeditor/cropview.hpp @@ -0,0 +1,16 @@ +#ifndef CROPVIEW_HPP +#define CROPVIEW_HPP + +#include +#include + +class CropView : public QGraphicsView +{ + public: + CropView(QGraphicsScene *scene); + + protected: + void keyPressEvent(QKeyEvent *e) override; +}; + +#endif // CROPVIEW_HPP diff --git a/icon.qrc b/icon.qrc new file mode 100644 index 0000000..0b15495 --- /dev/null +++ b/icon.qrc @@ -0,0 +1,5 @@ + + + icons/icon.jpg + + diff --git a/icons/icon.jpg b/icons/icon.jpg new file mode 100644 index 0000000..223ebdb Binary files /dev/null and b/icons/icon.jpg differ diff --git a/io/ioutils.cpp b/io/ioutils.cpp new file mode 100644 index 0000000..d0dae2b --- /dev/null +++ b/io/ioutils.cpp @@ -0,0 +1,41 @@ +#include "ioutils.hpp" +#include +#include +#include +#include + +namespace ioutils +{ +QNetworkAccessManager networkManager; +} + +void ioutils::getJson(QUrl target, QList> headers, std::function callback) +{ + QNetworkRequest req(target); + for (auto header : headers) + { + req.setRawHeader(header.first.toUtf8(), header.second.toUtf8()); + } + QNetworkReply *reply = networkManager.get(req); + QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { + callback(QJsonDocument::fromJson(reply->readAll())); + reply->deleteLater(); + }); +} + +void ioutils::postJson(QUrl target, + QList> headers, + QByteArray body, + std::function callback) +{ + QNetworkRequest req(target); + for (auto header : headers) + { + req.setRawHeader(header.first.toUtf8(), header.second.toUtf8()); + } + QNetworkReply *reply = networkManager.post(req, body); + QObject::connect(reply, &QNetworkReply::finished, [reply, callback] { + callback(QJsonDocument::fromJson(reply->readAll())); + reply->deleteLater(); + }); +} diff --git a/io/ioutils.hpp b/io/ioutils.hpp new file mode 100644 index 0000000..bd4c3fc --- /dev/null +++ b/io/ioutils.hpp @@ -0,0 +1,23 @@ +#ifndef IOUTILS_HPP +#define IOUTILS_HPP + +#include +#include +#include +#include +#include + +namespace ioutils +{ +extern QNetworkAccessManager networkManager; +void getJson(QUrl target, QList> headers, std::function callback); +void postJson(QUrl target, + QList> headers, + QByteArray body, + std::function callback); +// If I need more I will add +// Maybe when people start with plugins and custom uploaders +// Wait, that's a secret +} + +#endif // IOUTILS_HPP diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..6589c23 --- /dev/null +++ b/main.cpp @@ -0,0 +1,14 @@ +#include "mainwindow.hpp" +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..db959cc --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,93 @@ +#include "mainwindow.hpp" +#include "screenshotter.hpp" +#include "screenshotutil.hpp" +#include "ui_mainwindow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); + setWindowIcon(QIcon(":/icons/icon.jpg")); + tray = new QSystemTrayIcon(windowIcon(), this); + 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); + menu->addActions({ quit, shtoggle }); + menu->addSeparator(); + menu->addActions({ fullscreen, area }); + connect(quit, &QAction::triggered, this, &MainWindow::quit); + connect(shtoggle, &QAction::triggered, this, &MainWindow::toggleVisible); + connect(fullscreen, &QAction::triggered, this, &MainWindow::on_actionFullscreen_triggered); + connect(area, &QAction::triggered, this, &MainWindow::on_actionArea_triggered); + tray->setContextMenu(menu); + + ui->uploaderList->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->uploaderList->setSelectionMode(QAbstractItemView::SingleSelection); + + // Add items to uploader selection + for (Uploader *u : UploaderSingleton::inst().uploaderList()) + { + QListWidgetItem *item = new QListWidgetItem(u->name()); + item->setToolTip(u->description()); + // ui->uploaderList->setCurrentIndex(ui->uploaderList->model()->index(++i, 0)) + ui->uploaderList->addItem(item); + if (u->name() == UploaderSingleton::inst().selectedUploader()) item->setSelected(true); + } +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::closeEvent(QCloseEvent *event) +{ + event->ignore(); + QTimer::singleShot(0, this, &MainWindow::hide); +} + +void MainWindow::quit() +{ + QCoreApplication::quit(); +} + +void MainWindow::toggleVisible() +{ + this->setVisible(!this->isVisible()); +} + +void MainWindow::on_actionQuit_triggered() +{ + quit(); +} + +void MainWindow::on_actionFullscreen_triggered() +{ + QTimer::singleShot(0, &screenshotter::fullscreen); +} + +void MainWindow::on_actionArea_triggered() +{ + QTimer::singleShot(0, &screenshotter::area); +} + +void MainWindow::on_uploaderList_clicked(const QModelIndex &) +{ + QList index = ui->uploaderList->selectedItems(); + if (index.size() == 1) + { + UploaderSingleton::inst().set(index.at(0)->text()); + } +} diff --git a/mainwindow.hpp b/mainwindow.hpp new file mode 100644 index 0000000..3a72857 --- /dev/null +++ b/mainwindow.hpp @@ -0,0 +1,36 @@ +#ifndef MAINWINDOW_HPP +#define MAINWINDOW_HPP + +#include +#include + +namespace Ui +{ +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + private slots: + void quit(); + void toggleVisible(); + + void on_actionQuit_triggered(); + void on_actionFullscreen_triggered(); + void on_actionArea_triggered(); + void on_uploaderList_clicked(const QModelIndex &); + + public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + + private: + Ui::MainWindow *ui; + QSystemTrayIcon *tray; + + protected: + void closeEvent(QCloseEvent *event); +}; + +#endif // MAINWINDOW_HPP diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..9693bc1 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,97 @@ + + + MainWindow + + + + 0 + 0 + 262 + 239 + + + + KShare + + + + :/icons/icon.jpg:/icons/icon.jpg + + + + + 0 + 0 + + + + + + 0 + 0 + 241 + 19 + + + + Uploader selection: + + + + + + 0 + 20 + 256 + 192 + + + + + + + + 0 + 0 + 262 + 24 + + + + + Fi&le + + + + + + Scree&nshot + + + + + + + + + + &Quit + + + + + &Fullscreen + + + + + &Area + + + + + + + + + diff --git a/rendererwindow.cpp b/rendererwindow.cpp new file mode 100644 index 0000000..4706451 --- /dev/null +++ b/rendererwindow.cpp @@ -0,0 +1,53 @@ +#include "rendererwindow.hpp" + +RendererWindow::RendererWindow(QRect &size, QWindow *parent) : + QWindow(*parent) +{ + create(); + backingStore = new QBackingStore(this); + setGeometry(size); +} + +bool RasterWindow::event(QEvent *event) +{ + if (event->type() == QEvent::UpdateRequest) { + renderNow(); + return true; + } + return QWindow::event(event); +} + +void RendererWindow::renderLater() { + requestUpdate(); +} + +void RasterWindow::resizeEvent(QResizeEvent *resizeEvent) +{ + m_backingStore->resize(resizeEvent->size()); + if (isExposed()) + renderNow(); +} + +void RasterWindow::exposeEvent(QExposeEvent *) +{ + if (isExposed()) + renderNow(); +} + +void RasterWindow::renderNow() +{ + if (!isExposed()) + return; + + QRect rect(0, 0, width(), height()); + m_backingStore->beginPaint(rect); + + QPaintDevice *device = m_backingStore->paintDevice(); + QPainter painter(device); + + painter.fillRect(0, 0, width(), height(), Qt::white); + render(&painter); + + m_backingStore->endPaint(); + m_backingStore->flush(rect); +} diff --git a/rendererwindow.hpp b/rendererwindow.hpp new file mode 100644 index 0000000..2f59ccd --- /dev/null +++ b/rendererwindow.hpp @@ -0,0 +1,23 @@ +#ifndef RENDERERWINDOW_HPP +#define RENDERERWINDOW_HPP + +#include + +class RendererWindow : public QWindow +{ + Q_OBJECT +public: + RendererWindow(QRect &size, QWindow *parent = 0); + virtual void render(QPainter *painter); +public slots: + void renderLater(); + void renderNow(); +protected: + bool event(QEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void exposeEvent(QExposeEvent *event) override; +private: + QBackingStore *backingStore; +}; + +#endif // RENDERERWINDOW_HPP diff --git a/screenshotter.cpp b/screenshotter.cpp new file mode 100644 index 0000000..c6b5810 --- /dev/null +++ b/screenshotter.cpp @@ -0,0 +1,15 @@ +#include "screenshotter.hpp" +#include "cropeditor/cropeditor.hpp" +#include "screenshotutil.hpp" +#include "uploaders/uploadersingleton.hpp" + +void screenshotter::area() +{ + CropEditor *editor = new CropEditor(screenshotutil::fullscreen()); + QObject::connect(editor, &CropEditor::cropped, [&](QPixmap *pixmap) { UploaderSingleton::inst().upload(pixmap); }); +} + +void screenshotter::fullscreen() +{ + UploaderSingleton::inst().upload(screenshotutil::fullscreen()); +} diff --git a/screenshotter.hpp b/screenshotter.hpp new file mode 100644 index 0000000..00ec27c --- /dev/null +++ b/screenshotter.hpp @@ -0,0 +1,10 @@ +#ifndef SCREENSHOTTER_HPP +#define SCREENSHOTTER_HPP + +namespace screenshotter +{ +void fullscreen(); +void area(); +} + +#endif // SCREENSHOTTER_HPP diff --git a/screenshotutil.cpp b/screenshotutil.cpp new file mode 100644 index 0000000..cd477b0 --- /dev/null +++ b/screenshotutil.cpp @@ -0,0 +1,25 @@ +#include "screenshotutil.hpp" + +#include +#include +#include +#include + +QPixmap *screenshotutil::fullscreen() +{ + return window(0); +} + +QPixmap *screenshotutil::window(long wid) +{ + QScreen *w = QApplication::primaryScreen(); + QPixmap screen = w->grabWindow(wid); + QPixmap *pm = new QPixmap(screen.size()); + screen.swap(*pm); + return pm; +} + +void screenshotutil::toClipboard(QString value) +{ + QApplication::clipboard()->setText(value); +} diff --git a/screenshotutil.hpp b/screenshotutil.hpp new file mode 100644 index 0000000..1dc9970 --- /dev/null +++ b/screenshotutil.hpp @@ -0,0 +1,13 @@ +#ifndef SCREENSHOTUTIL_HPP +#define SCREENSHOTUTIL_HPP + +#include + +namespace screenshotutil +{ +QPixmap fullscreen(); +QPixmap window(long wid); +void toClipboard(QString value); +} + +#endif // SCREENSHOTUTIL_HPP diff --git a/settings.cpp b/settings.cpp new file mode 100644 index 0000000..2ceddcd --- /dev/null +++ b/settings.cpp @@ -0,0 +1,15 @@ +#include "settings.hpp" + +#include + +QSettings &settings::settings() +{ + static QDir configDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); + if (configDir.path() == QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)) + { + configDir.mkdir("KShare"); + configDir.cd("KShare"); + } + static QSettings settings(configDir.absoluteFilePath("settings.ini"), QSettings::IniFormat); + return settings; +} diff --git a/settings.hpp b/settings.hpp new file mode 100644 index 0000000..6e43223 --- /dev/null +++ b/settings.hpp @@ -0,0 +1,12 @@ +#ifndef SETTINGS_HPP +#define SETTINGS_HPP + +#include +#include + +namespace settings +{ +QSettings &settings(); +} + +#endif // SETTINGS_HPP diff --git a/uploaders/default/clipboarduploader.cpp b/uploaders/default/clipboarduploader.cpp new file mode 100644 index 0000000..d188f95 --- /dev/null +++ b/uploaders/default/clipboarduploader.cpp @@ -0,0 +1,9 @@ +#include "clipboarduploader.hpp" + +#include +#include + +void ClipboardUploader::doUpload(QPixmap *pixmap) +{ + QApplication::clipboard()->setImage(pixmap->toImage()); +} diff --git a/uploaders/default/clipboarduploader.hpp b/uploaders/default/clipboarduploader.hpp new file mode 100644 index 0000000..5616b75 --- /dev/null +++ b/uploaders/default/clipboarduploader.hpp @@ -0,0 +1,21 @@ +#ifndef CLIPBOARDUPLOADER_HPP +#define CLIPBOARDUPLOADER_HPP + +#include +#include + +class ClipboardUploader : public Uploader +{ + public: + QString name() + { + return "clipboard"; + } + QString description() + { + return "Copies the image to clipboard"; + } + void doUpload(QPixmap *pixmap); +}; + +#endif // CLIPBOARDUPLOADER_HPP diff --git a/uploaders/default/imguruploader.cpp b/uploaders/default/imguruploader.cpp new file mode 100644 index 0000000..34131ba --- /dev/null +++ b/uploaders/default/imguruploader.cpp @@ -0,0 +1,22 @@ +#include "imguruploader.hpp" + +#include +#include +#include +#include +#include + +void ImgurUploader::doUpload(QPixmap *pixmap) +{ + QByteArray byteArray; + QBuffer buffer(&byteArray); + pixmap->save(&buffer, "PNG"); + ioutils::postJson(QUrl("https://api.imgur.com/3/image"), + QList>() + << QPair("Content-Type", + "application/x-www-form-urlencoded") + << QPair("Authorization", "Client-ID 8a98f183fc895da"), + byteArray, [](QJsonDocument res) { + screenshotutil::toClipboard(res.object()["data"].toObject()["link"].toString()); + }); +} diff --git a/uploaders/default/imguruploader.hpp b/uploaders/default/imguruploader.hpp new file mode 100644 index 0000000..b76acb5 --- /dev/null +++ b/uploaders/default/imguruploader.hpp @@ -0,0 +1,20 @@ +#ifndef IMGURUPLOADER_HPP +#define IMGURUPLOADER_HPP + +#include "../uploader.hpp" + +class ImgurUploader : public Uploader +{ + public: + QString name() + { + return "imgur"; + } + QString description() + { + return "imgur.com uploader"; + } + void doUpload(QPixmap *pixmap); +}; + +#endif // IMGURUPLOADER_HPP diff --git a/uploaders/uploader.hpp b/uploaders/uploader.hpp new file mode 100644 index 0000000..3da10b3 --- /dev/null +++ b/uploaders/uploader.hpp @@ -0,0 +1,15 @@ +#ifndef UPLOADER_HPP +#define UPLOADER_HPP + +#include +#include + +class Uploader +{ + public: + virtual void doUpload(QPixmap *pixmap) = 0; + virtual QString name() = 0; + virtual QString description() = 0; +}; + +#endif // UPLOADER_HPP diff --git a/uploaders/uploadersingleton.cpp b/uploaders/uploadersingleton.cpp new file mode 100644 index 0000000..9f48716 --- /dev/null +++ b/uploaders/uploadersingleton.cpp @@ -0,0 +1,63 @@ +#include "uploadersingleton.hpp" +#include "default/clipboarduploader.hpp" +#include "default/imguruploader.hpp" +#include +#include +#include + +UploaderSingleton::UploaderSingleton() +{ + // QDir + // configDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); + // configDir.mkpath("KShare/uploaders"); + // configDir.cd("KShare/uploaders"); + // configDir.setNameFilters({"*.uploader"}); + // for (QString file : configDir.entryList()) { + // registerUploader(new CustomUploader(file)); + // } + // TODO + + // UPLOADERS + registerUploader(new ImgurUploader); + registerUploader(new ClipboardUploader); + // --------- + + if (settings::settings().contains("uploader")) + uploader = settings::settings().value("uploader").toString(); + else + settings::settings().setValue("uploader", uploader); + if (!uploaders.contains(uploader)) + { + settings::settings().setValue("uploader", uploader); + uploader = "imgur"; + } +} + +void UploaderSingleton::registerUploader(Uploader *uploader) +{ + uploaders.insert(uploader->name(), uploader); +} + +void UploaderSingleton::upload(QPixmap *pixmap) +{ + uploaders.value(uploader)->doUpload(pixmap); +} + +QList UploaderSingleton::uploaderList() +{ + return uploaders.values(); +} + +void UploaderSingleton::set(QString uploader) +{ + if (uploaders.contains(uploader)) + { + this->uploader = uploader; + settings::settings().setValue("uploader", uploader); + } +} + +QString UploaderSingleton::selectedUploader() +{ + return uploader; +} diff --git a/uploaders/uploadersingleton.hpp b/uploaders/uploadersingleton.hpp new file mode 100644 index 0000000..0fb3d13 --- /dev/null +++ b/uploaders/uploadersingleton.hpp @@ -0,0 +1,27 @@ +#ifndef UPLOADERSINGLETON_HPP +#define UPLOADERSINGLETON_HPP + +#include "uploader.hpp" +#include + +class UploaderSingleton +{ + public: + static UploaderSingleton &inst() + { + static UploaderSingleton inst; + return inst; + } + void registerUploader(Uploader *uploader); + void upload(QPixmap *pixmap); + QList uploaderList(); + void set(QString uploader); + QString selectedUploader(); + + private: + UploaderSingleton(); + QMap uploaders; + QString uploader = "imgur"; +}; + +#endif // UPLOADERSINGLETON_HPP