Hey it only took me two days to fix a segfault!!!!
This commit is contained in:
parent
6128ac40b5
commit
8f5197b826
@ -48,7 +48,9 @@ SOURCES += main.cpp\
|
||||
cropeditor/drawing/textitem.cpp \
|
||||
colorpicker/colorpickerscene.cpp \
|
||||
worker/worker.cpp \
|
||||
screenareaselector/screenareaselector.cpp
|
||||
screenareaselector/screenareaselector.cpp \
|
||||
recording/recordingpreview.cpp \
|
||||
recording/recordingcontroller.cpp
|
||||
|
||||
HEADERS += mainwindow.hpp \
|
||||
cropeditor/cropeditor.hpp \
|
||||
@ -78,7 +80,9 @@ HEADERS += mainwindow.hpp \
|
||||
platformbackend.hpp \
|
||||
gif-h/gif.h \
|
||||
worker/worker.hpp \
|
||||
screenareaselector/screenareaselector.hpp
|
||||
screenareaselector/screenareaselector.hpp \
|
||||
recording/recordingpreview.hpp \
|
||||
recording/recordingcontroller.hpp
|
||||
|
||||
mac {
|
||||
SOURCES += $$PWD/platformspecifics/mac/macbackend.cpp
|
||||
|
2
QHotkey
2
QHotkey
@ -1 +1 @@
|
||||
Subproject commit 9eace8fbbd8dede95db623eea5e25403fd59b490
|
||||
Subproject commit 2578b69dc51e3786402777e650181c5735015e1a
|
@ -20,14 +20,14 @@ void hotkeying::hotkey(QString seqName, QKeySequence seq, std::function<void()>
|
||||
}
|
||||
|
||||
// forces the hotkey from settings
|
||||
void hotkeying::load(QString seqName, std::function<void()> func) {
|
||||
void hotkeying::load(QString seqName, std::function<void()> func, QString def) {
|
||||
QHotkey *h;
|
||||
QString name = seqName;
|
||||
name.prepend("hotkey_");
|
||||
if (settings::settings().contains(name))
|
||||
h = new QHotkey(QKeySequence(settings::settings().value(name).toString()), true);
|
||||
else
|
||||
h = new QHotkey;
|
||||
h = new QHotkey(def.isNull() ? "" : def, true);
|
||||
QObject::connect(h, &QHotkey::activated, func);
|
||||
hotkeys.insert(seqName, h);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace hotkeying {
|
||||
void hotkey(QString seqName, QKeySequence seq, std::function<void()> func);
|
||||
bool valid(QString seq);
|
||||
void load(QString seqName, std::function<void()> func);
|
||||
void load(QString seqName, std::function<void()> func, QString def = QString());
|
||||
QString sequence(QString seqName);
|
||||
}
|
||||
|
||||
|
3
main.cpp
3
main.cpp
@ -5,8 +5,6 @@
|
||||
#include <QtGlobal>
|
||||
#include <iostream>
|
||||
#include <notifications.hpp>
|
||||
#include <screenareaselector/screenareaselector.hpp>
|
||||
#include <stdio.h>
|
||||
#include <worker/worker.hpp>
|
||||
|
||||
bool verbose = false;
|
||||
@ -63,6 +61,5 @@ int main(int argc, char *argv[]) {
|
||||
Worker::init();
|
||||
a.connect(&a, &QApplication::aboutToQuit, Worker::end);
|
||||
if (!parser.isSet(h)) w.show();
|
||||
(new ScreenAreaSelector())->show();
|
||||
return a.exec();
|
||||
}
|
||||
|
@ -23,11 +23,11 @@
|
||||
|
||||
MainWindow *MainWindow::instance;
|
||||
|
||||
void addHotkeyItem(QString text, QString name, std::function<void()> *func) {
|
||||
void addHotkeyItem(QString text, QString name, std::function<void()> func, QString def = QString()) {
|
||||
QListWidgetItem *item = new QListWidgetItem(text, MainWindow::inst()->ui->hotkeys);
|
||||
item->setData(Qt::UserRole + 1, name);
|
||||
MainWindow::inst()->fncs.insert(name, func);
|
||||
hotkeying::load(name, *func);
|
||||
hotkeying::load(name, func, def);
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
|
||||
@ -84,9 +84,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
|
||||
ui->hotkeys->setSelectionMode(QListWidget::SingleSelection);
|
||||
|
||||
addHotkeyItem("Fullscreen image", "fullscreen", new std::function<void()>([] { screenshotter::fullscreen(); }));
|
||||
addHotkeyItem("Area image", "area", new std::function<void()>([] { screenshotter::area(); }));
|
||||
addHotkeyItem("Color picker", "picker", new std::function<void()>([] { ColorPickerScene::showPicker(); }));
|
||||
addHotkeyItem("Fullscreen image", "fullscreen", [] { screenshotter::fullscreen(); });
|
||||
addHotkeyItem("Area image", "area", [] { screenshotter::area(); });
|
||||
addHotkeyItem("Color picker", "picker", [] { ColorPickerScene::showPicker(); });
|
||||
addHotkeyItem("Stop Recording", "recordingstop", [&] { controller->end(); });
|
||||
|
||||
ui->quickMode->setChecked(settings::settings().value("quickMode", false).toBool());
|
||||
ui->hideToTray->setChecked(settings::settings().value("hideOnClose", true).toBool());
|
||||
@ -169,8 +170,9 @@ void MainWindow::on_hotkeys_doubleClicked(const QModelIndex &) {
|
||||
QListWidgetItem *i = ui->hotkeys->selectedItems().at(0);
|
||||
QString str = i->data(Qt::UserRole + 1).toString();
|
||||
bool ok;
|
||||
QString seq = QInputDialog::getText(ui->centralWidget, "Hotkey Input", "Insert hotkey:", QLineEdit::Normal, hotkeying::sequence(str), &ok);
|
||||
if (ok && hotkeying::valid(seq)) hotkeying::hotkey(str, QKeySequence(seq), *fncs.value(str));
|
||||
QString seq = QInputDialog::getText(ui->centralWidget, "Hotkey Input", "Insert hotkey:", QLineEdit::Normal,
|
||||
hotkeying::sequence(str), &ok);
|
||||
if (ok && hotkeying::valid(seq)) hotkeying::hotkey(str, QKeySequence(seq), fncs.value(str));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QSystemTrayIcon>
|
||||
#include <functional>
|
||||
|
||||
#include <recording/recordingcontroller.hpp>
|
||||
#include <uploaders/uploader.hpp>
|
||||
|
||||
namespace Ui {
|
||||
@ -15,7 +16,7 @@ class MainWindow;
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
private slots:
|
||||
void quit();
|
||||
void toggleVisible();
|
||||
void newUploader(Uploader *u);
|
||||
@ -33,7 +34,7 @@ class MainWindow : public QMainWindow {
|
||||
void on_actionColor_Picker_triggered();
|
||||
void on_captureCursor_clicked(bool checked);
|
||||
|
||||
public:
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
Ui::MainWindow *ui;
|
||||
@ -43,12 +44,13 @@ class MainWindow : public QMainWindow {
|
||||
QDoubleSpinBox *delay();
|
||||
|
||||
static MainWindow *inst();
|
||||
QMap<QString, std::function<void()> *> fncs;
|
||||
QMap<QString, std::function<void()>> fncs;
|
||||
|
||||
private:
|
||||
private:
|
||||
static MainWindow *instance;
|
||||
RecordingController *controller = new RecordingController;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
};
|
||||
|
||||
|
68
recording/recordingcontroller.cpp
Normal file
68
recording/recordingcontroller.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "recordingcontroller.hpp"
|
||||
#include <QImage>
|
||||
#include <QRect>
|
||||
#include <QTimer>
|
||||
#include <iostream>
|
||||
#include <mainwindow.hpp>
|
||||
#include <screenareaselector/screenareaselector.hpp>
|
||||
#include <screenshotutil.hpp>
|
||||
#include <settings.hpp>
|
||||
#include <stdio.h>
|
||||
#include <worker/worker.hpp>
|
||||
|
||||
RecordingController::RecordingController() : timer(this) {
|
||||
connect(&timer, &QTimer::timeout, this, &RecordingController::timeout);
|
||||
}
|
||||
|
||||
bool RecordingController::isRunning() {
|
||||
return timer.isActive();
|
||||
}
|
||||
|
||||
bool RecordingController::start(RecordingContext *context) {
|
||||
if (isRunning()) return false;
|
||||
if (_context) delete _context;
|
||||
_context = context;
|
||||
ScreenAreaSelector *sel = new ScreenAreaSelector;
|
||||
connect(sel, &ScreenAreaSelector::selectedArea, this, &RecordingController::startWithArea);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RecordingController::end() {
|
||||
if (!isRunning()) return false;
|
||||
timer.stop();
|
||||
area = QRect();
|
||||
preview->close();
|
||||
preview = 0;
|
||||
_context->finalizer();
|
||||
frame = 0;
|
||||
time = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RecordingController::timeout() {
|
||||
if (isRunning()) {
|
||||
time++;
|
||||
int localTime = time * timer.interval() - 3000;
|
||||
if (localTime > 0) {
|
||||
QPixmap *pp = screenshotutil::fullscreenArea(settings::settings().value("captureCursor", true).toBool(),
|
||||
area.x(), area.y(), area.width(), area.height());
|
||||
QScopedPointer<QPixmap> p(pp);
|
||||
WorkerContext *context = new WorkerContext;
|
||||
context->consumer = _context->consumer;
|
||||
context->targetFormat = _context->format;
|
||||
context->pixmap = *pp;
|
||||
frame++;
|
||||
preview->setPixmap(*pp);
|
||||
Worker::queue(context);
|
||||
}
|
||||
long second = localTime / 1000 % 60;
|
||||
long minute = localTime / 60000;
|
||||
preview->setTime(QString("%1:%2").arg(QString::number(minute)).arg(QString::number(second)), frame);
|
||||
}
|
||||
}
|
||||
|
||||
void RecordingController::startWithArea(QRect newArea) {
|
||||
area = newArea;
|
||||
preview = new RecordingPreview(newArea);
|
||||
timer.start(1000 / settings::settings().value("recording/framerate", 30).toInt());
|
||||
}
|
42
recording/recordingcontroller.hpp
Normal file
42
recording/recordingcontroller.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef RECORDINGCONTROLLER_HPP
|
||||
#define RECORDINGCONTROLLER_HPP
|
||||
|
||||
#include "recordingpreview.hpp"
|
||||
|
||||
#include <QImage>
|
||||
#include <QRect>
|
||||
#include <QTimer>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
class RecordingContext {
|
||||
public:
|
||||
QImage::Format format;
|
||||
std::function<void(QImage)> consumer;
|
||||
std::function<void()> finalizer;
|
||||
};
|
||||
|
||||
class RecordingController : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RecordingController();
|
||||
bool isRunning();
|
||||
public slots:
|
||||
// Returns false if isRunning
|
||||
bool start(RecordingContext *context);
|
||||
// Returns false if not running
|
||||
bool end();
|
||||
private slots:
|
||||
void timeout();
|
||||
void startWithArea(QRect newArea);
|
||||
|
||||
private:
|
||||
QRect area;
|
||||
RecordingContext *_context = 0;
|
||||
QTimer timer;
|
||||
RecordingPreview *preview = nullptr;
|
||||
unsigned int frame = 0;
|
||||
unsigned int time = 0;
|
||||
};
|
||||
|
||||
#endif // RECORDINGCONTROLLER_HPP
|
50
recording/recordingpreview.cpp
Normal file
50
recording/recordingpreview.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "recordingpreview.hpp"
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QGridLayout>
|
||||
#include <QLayout>
|
||||
#include <QScreen>
|
||||
#include <QTimer>
|
||||
#include <hotkeying.hpp>
|
||||
|
||||
RecordingPreview::RecordingPreview(QRect area, QWidget *parent) : QWidget(parent) {
|
||||
recordingArea = area;
|
||||
setStyleSheet("background-color: rgba(0, 0, 0, 0.7);");
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setWindowFlags(windowFlags() | Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
|
||||
QTimer::singleShot(0, [&] {
|
||||
adjustSize();
|
||||
move(0, 0);
|
||||
if (geometry().intersects(recordingArea)) // Formatter please
|
||||
move(QApplication::primaryScreen()->size().width() - rect().width(), 0);
|
||||
if (geometry().intersects(recordingArea)) // Formatter please
|
||||
move(0, QApplication::primaryScreen()->size().height() - rect().height());
|
||||
if (geometry().intersects(recordingArea))
|
||||
move(QApplication::primaryScreen()->size().width() - rect().width(),
|
||||
QApplication::primaryScreen()->size().height() - rect().height());
|
||||
if (!geometry().intersects(recordingArea)) show();
|
||||
});
|
||||
label = new QLabel;
|
||||
hintLabel = new QLabel;
|
||||
auto ly = new QGridLayout(this);
|
||||
setLayout(ly);
|
||||
layout()->addWidget(hintLabel);
|
||||
layout()->addWidget(label);
|
||||
hintLabel->setText(QString("Time: 00:00\nFrame: 0\nStop key: ") + hotkeying::sequence("recordingstop"));
|
||||
}
|
||||
|
||||
RecordingPreview::~RecordingPreview() {
|
||||
// delete everything;
|
||||
delete label;
|
||||
delete hintLabel;
|
||||
}
|
||||
|
||||
void RecordingPreview::setPixmap(QPixmap map) {
|
||||
label->setPixmap(map);
|
||||
}
|
||||
void RecordingPreview::setTime(QString time, int frame) {
|
||||
hintLabel->setText(QString("Time: ") + time + "\nFrame: " + QString::number(frame)
|
||||
+ "\nStop key: " + hotkeying::sequence("recordingstop"));
|
||||
}
|
23
recording/recordingpreview.hpp
Normal file
23
recording/recordingpreview.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef RECORDINGPREVIEW_HPP
|
||||
#define RECORDINGPREVIEW_HPP
|
||||
|
||||
#include <QLabel>
|
||||
#include <QObject>
|
||||
#include <QRect>
|
||||
#include <QWidget>
|
||||
|
||||
class RecordingPreview : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RecordingPreview(QRect recordingArea, QWidget *parent = 0);
|
||||
~RecordingPreview();
|
||||
void setPixmap(QPixmap map);
|
||||
void setTime(QString time, int frame);
|
||||
|
||||
private:
|
||||
QLabel *label;
|
||||
QLabel *hintLabel;
|
||||
QRect recordingArea;
|
||||
};
|
||||
|
||||
#endif // RECORDINGPREVIEW_HPP
|
@ -19,6 +19,7 @@ ScreenAreaSelector::ScreenAreaSelector() {
|
||||
move(rect.topLeft());
|
||||
}
|
||||
hintLabel->setText(QString::number(width()) + "x" + QString::number(height()));
|
||||
show();
|
||||
});
|
||||
setLayout(new QStackedLayout());
|
||||
hintLabel = new QLabel();
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <settings.hpp>
|
||||
|
||||
void screenshotter::area() {
|
||||
CropEditor *editor = new CropEditor(screenshotutil::fullscreen());
|
||||
CropEditor *editor = new CropEditor(screenshotutil::fullscreen(settings::settings().value("captureCursor", true).toBool()));
|
||||
QObject::connect(editor, &CropEditor::cropped, [&](QPixmap *pixmap) {
|
||||
UploaderSingleton::inst().upload(pixmap);
|
||||
QScopedPointer<CropEditor>(editor);
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
QSettings &settings::settings() {
|
||||
static QDir configDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation));
|
||||
if (configDir.path() == QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)) {
|
||||
if (configDir.dirName() != "KShare") {
|
||||
configDir.mkdir("KShare");
|
||||
configDir.cd("KShare");
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
Worker *Worker::inst = 0;
|
||||
QMutex Worker::workerLock;
|
||||
QMutex Worker::lock;
|
||||
|
||||
// QPixmaps don't like existing on non GUI threads.
|
||||
// Because of this we have to:
|
||||
@ -17,7 +18,7 @@ void Worker::queue(WorkerContext *context) {
|
||||
c->image = context->pixmap.toImage();
|
||||
c->consumer = context->consumer;
|
||||
c->targetFormat = context->targetFormat;
|
||||
qqueue.enqueue(c);
|
||||
inst->qqueue.enqueue(c);
|
||||
}
|
||||
|
||||
void Worker::init() {
|
||||
|
@ -24,13 +24,13 @@ struct _WorkerContext {
|
||||
class Worker : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
void queue(WorkerContext *context);
|
||||
static void queue(WorkerContext *context);
|
||||
static void init();
|
||||
|
||||
private:
|
||||
Worker();
|
||||
~Worker();
|
||||
QMutex lock;
|
||||
static QMutex lock;
|
||||
QMutex endLock;
|
||||
QThread *thr;
|
||||
QQueue<_WorkerContext *> qqueue; // Say that ten times as fast
|
||||
|
Loading…
Reference in New Issue
Block a user