-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshotmd.cpp
More file actions
137 lines (115 loc) · 4.17 KB
/
shotmd.cpp
File metadata and controls
137 lines (115 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//
// Created by kvto on 9/15/24.
//
// You may need to build the project (run Qt uic code generator) to get "ui_shotmd.h" resolved
#include <QScreen>
#include <QMouseEvent>
#include <QPainter>
#include <QBuffer>
#include <QClipboard>
#include <QTimer>
#include <QStandardPaths>
#include <QDateTime>
#include <QGuiApplication>
#include <QScreen>
#include <QMessageBox>
#include "shotmd.h"
#include "ui_shotmd.h"
shotmd::shotmd(QWidget* parent) : QMainWindow(parent), ui(new Ui::shotmd) {
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
QScreen* screen = QGuiApplication::screenAt(QCursor::pos());
if (!screen) {
screen = QGuiApplication::primaryScreen();
}
originalPixmap = screen->grabWindow(0);
screenshotLabel = new QLabel(this);
screenshotLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
screenshotLabel->setAlignment(Qt::AlignCenter);
screenshotLabel->setFixedSize(screen->geometry().size());
screenshotLabel->setPixmap(originalPixmap);
screenshotLabel->show();
ui->setupUi(this);
updateOverlay();
}
void shotmd::mousePressEvent(QMouseEvent* event) {
if (event->button() == Qt::RightButton) {
QGuiApplication::exit();
return;
}
if (event->button() == Qt::LeftButton) {
selection.origin = selection.current = event->pos();
selection.active = true;
updateOverlay();
}
}
void shotmd::mouseMoveEvent(QMouseEvent* event) {
if (!selection.active) return;
selection.current = event->pos();
updateOverlay();
}
void shotmd::updateOverlay() {
// Start from original screenshot
QPixmap composited = originalPixmap.copy();
QPainter painter(&composited);
// Dim whole screen with semi-transparent layer
painter.fillRect(composited.rect(), QColor(0, 0, 0, 120)); // 120 alpha black
if (selection.active) {
const QRect sel = selection.rect();
// Restore the selection area ("hole") by drawing original region back
painter.drawPixmap(sel.topLeft(), originalPixmap.copy(sel));
// Draw selection border
QPen pen(Qt::red, 2);
painter.setPen(pen);
painter.drawRect(sel);
}
painter.end();
screenshotLabel->setPixmap(composited);
}
void shotmd::captureRegion(const QRect &r) {
const QPixmap finalPixmap = originalPixmap.copy(r);
QByteArray data;
QBuffer buffer(&data);
finalPixmap.save(&buffer, "JPEG");
data = data.toBase64();
const QString html = QString(R"(<img src="data:image/jpeg;base64,)") + data + QString(R"(" alt="screenshot" />)");
QClipboard *cb = QGuiApplication::clipboard();
cb->setText(html, QClipboard::Clipboard);
cb->setText(html, QClipboard::Selection);
const QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss");
QString downloadsPath = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
if (downloadsPath.isEmpty()) downloadsPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
const QString filePath = downloadsPath + "/" + QString("shotmd-%1.jpeg").arg(timestamp);
if (!finalPixmap.save(filePath, "JPEG")) {
QMessageBox::critical(nullptr, "Save Failed",
QString("Could not save screenshot to:\n%1\n\nCheck write permissions.").arg(filePath),
QMessageBox::Ok);
}
//x11 need the clipboard src alive to finish the paste
hide();
QTimer::singleShot(60 * 1000, QGuiApplication::instance(), &QGuiApplication::quit);
}
void shotmd::shot(const QPoint Tl, const QPoint RD) { // legacy wrapper
captureRegion(QRect(Tl, RD));
}
void shotmd::mouseReleaseEvent(QMouseEvent* event) {
if (!selection.active) return;
selection.current = event->pos();
captureRegion(selection.rect());
selection.reset();
}
void shotmd::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_F) {
const QScreen *screen = QGuiApplication::primaryScreen();
captureRegion(screen->geometry());
return;
}
if (event->key() == Qt::Key_Escape)
{
QApplication::quit();
}
QWidget::keyPressEvent(event);
}
shotmd::~shotmd()
{
delete ui;
}