qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
screenshotgrabber.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2015-2019 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  qTox is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "screenshotgrabber.h"
21 
22 #include <QApplication>
23 #include <QDebug>
24 #include <QDesktopWidget>
25 #include <QGraphicsPixmapItem>
26 #include <QGraphicsRectItem>
27 #include <QGraphicsSceneMouseEvent>
28 #include <QGraphicsView>
29 #include <QMouseEvent>
30 #include <QScreen>
31 #include <QTimer>
32 
35 #include "toolboxgraphicsitem.h"
36 #include "src/widget/widget.h"
37 
39  : QObject()
40  , mKeysBlocked(false)
41  , scene(nullptr)
42  , mQToxVisible(true)
43 {
44  window = new QGraphicsView(scene); // Top-level widget
45  window->setWindowFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint);
46  window->setContentsMargins(0, 0, 0, 0);
47  window->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
48  window->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
49  window->setFrameShape(QFrame::NoFrame);
50  window->installEventFilter(this);
51  pixRatio = QApplication::primaryScreen()->devicePixelRatio();
52 
53  setupScene();
54 }
55 
57 {
58  window->resetCachedContent();
59  setupScene();
60  showGrabber();
61  mKeysBlocked = false;
62 }
63 
65 {
66  delete scene;
67  delete window;
68 }
69 
70 bool ScreenshotGrabber::eventFilter(QObject* object, QEvent* event)
71 {
72  if (event->type() == QEvent::KeyPress)
73  return handleKeyPress(static_cast<QKeyEvent*>(event));
74 
75  return QObject::eventFilter(object, event);
76 }
77 
79 {
80  this->screenGrab = grabScreen();
81  this->screenGrabDisplay->setPixmap(this->screenGrab);
82  this->window->show();
83  this->window->setFocus();
84  this->window->grabKeyboard();
85 
86  QRect fullGrabbedRect = screenGrab.rect();
87  QRect rec = QApplication::primaryScreen()->virtualGeometry();
88 
89  this->window->setGeometry(rec);
90  this->scene->setSceneRect(fullGrabbedRect);
91  this->overlay->setRect(fullGrabbedRect);
92 
94 }
95 
96 bool ScreenshotGrabber::handleKeyPress(QKeyEvent* event)
97 {
98  if (mKeysBlocked)
99  return false;
100 
101  if (event->key() == Qt::Key_Escape)
102  reject();
103  else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
104  acceptRegion();
105  else if (event->key() == Qt::Key_Space) {
106  mKeysBlocked = true;
107 
108  if (mQToxVisible)
110  else
112 
113  window->hide();
114  QTimer::singleShot(350, this, SLOT(reInit()));
115  } else
116  return false;
117 
118  return true;
119 }
120 
122 {
123  QRect rect = this->chooserRect->chosenRect();
124  if (rect.width() < 1 || rect.height() < 1)
125  return;
126 
127  // Scale the accepted region from DIPs to actual pixels
128  rect.setRect(rect.x() * pixRatio, rect.y() * pixRatio, rect.width() * pixRatio,
129  rect.height() * pixRatio);
130 
131  emit regionChosen(rect);
132  qDebug() << "Screenshot accepted, chosen region" << rect;
133  QPixmap pixmap = this->screenGrab.copy(rect);
135  emit screenshotTaken(pixmap);
136 
137  deleteLater();
138 }
139 
141 {
142  delete scene;
143  scene = new QGraphicsScene;
144  window->setScene(scene);
145 
146  this->overlay = new ScreenGrabberOverlayItem(this);
148 
149  this->screenGrabDisplay = scene->addPixmap(this->screenGrab);
150  this->helperTooltip = scene->addText(QString());
151 
152  scene->addItem(this->overlay);
154  scene->addItem(this->helperToolbox);
155 
156  this->helperToolbox->addToGroup(this->helperTooltip);
157  this->helperTooltip->setDefaultTextColor(Qt::black);
159 
166 }
167 
169 {
170  helperTooltip->setHtml(
171  tr("Click and drag to select a region. Press %1 to "
172  "hide/show qTox window, or %2 to cancel.",
173  "Help text shown when no region has been selected yet")
174  .arg(QString("<b>%1</b>").arg(tr("Space", "[Space] key on the keyboard")),
175  QString("<b>%1</b>").arg(tr("Escape", "[Escape] key on the keyboard"))));
177 }
178 
180 {
181  helperTooltip->setHtml(
182  tr("Press %1 to send a screenshot of the selection, "
183  "%2 to hide/show qTox window, or %3 to cancel.",
184  "Help text shown when a region has been selected")
185  .arg(QString("<b>%1</b>").arg(tr("Enter", "[Enter] key on the keyboard")),
186  QString("<b>%1</b>").arg(tr("Space", "[Space] key on the keyboard")),
187  QString("<b>%1</b>").arg(tr("Escape", "[Escape] key on the keyboard"))));
189 }
190 
192 {
193  if (rect.size().isNull())
195  else
197 }
198 
204 {
205  QRect recGL = QGuiApplication::primaryScreen()->virtualGeometry();
206 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
207  const auto rec = QGuiApplication::screenAt(QCursor::pos())->geometry();
208 #else
209  const auto rec = qApp->desktop()->screenGeometry(QCursor::pos());
210 #endif
211  const QRectF ttRect = this->helperToolbox->childrenBoundingRect();
212  int x = qAbs(recGL.x()) + rec.x() + ((rec.width() - ttRect.width()) / 2);
213  int y = qAbs(recGL.y()) + rec.y();
214 
215  helperToolbox->setX(x);
216  helperToolbox->setY(y);
217 }
218 
220 {
222  deleteLater();
223 }
224 
226 {
227  QScreen* screen = QGuiApplication::primaryScreen();
228  QRect rec = screen->virtualGeometry();
229 
230  // Multiply by devicePixelRatio to get actual desktop size
231  return screen->grabWindow(QApplication::desktop()->winId(), rec.x() * pixRatio,
232  rec.y() * pixRatio, rec.width() * pixRatio, rec.height() * pixRatio);
233 }
234 
236 {
237  foreach (QWidget* w, qApp->topLevelWidgets()) {
238  if (w != window && w->isVisible()) {
239  mHiddenWindows << w;
240  w->setVisible(false);
241  }
242  }
243 
244  mQToxVisible = false;
245 }
246 
248 {
249  foreach (QWidget* w, mHiddenWindows) {
250  if (w)
251  w->setVisible(true);
252  }
253 
254  mHiddenWindows.clear();
255  mQToxVisible = true;
256 }
257 
258 void ScreenshotGrabber::beginRectChooser(QGraphicsSceneMouseEvent* event)
259 {
260  QPointF pos = event->scenePos();
261  this->chooserRect->setX(pos.x());
262  this->chooserRect->setY(pos.y());
263  this->chooserRect->beginResize(event->scenePos());
264 }
ScreenshotGrabber::mQToxVisible
bool mQToxVisible
Definition: screenshotgrabber.h:89
ScreenshotGrabber::pixRatio
qreal pixRatio
Definition: screenshotgrabber.h:87
ToolBoxGraphicsItem
Definition: toolboxgraphicsitem.h:26
ScreenshotGrabber::helperTooltip
QGraphicsTextItem * helperTooltip
Definition: screenshotgrabber.h:85
toolboxgraphicsitem.h
ScreenshotGrabber::eventFilter
bool eventFilter(QObject *object, QEvent *event) override
Definition: screenshotgrabber.cpp:70
screengrabberoverlayitem.h
ScreenshotGrabber::acceptRegion
void acceptRegion()
Definition: screenshotgrabber.cpp:121
screenshotgrabber.h
ScreenGrabberChooserRectItem::chosenRect
QRect chosenRect() const
Definition: screengrabberchooserrectitem.cpp:83
ScreenshotGrabber::handleKeyPress
bool handleKeyPress(QKeyEvent *event)
Definition: screenshotgrabber.cpp:96
ScreenshotGrabber::ScreenGrabberOverlayItem
friend class ScreenGrabberOverlayItem
Definition: screenshotgrabber.h:57
ScreenshotGrabber::hideVisibleWindows
void hideVisibleWindows()
Definition: screenshotgrabber.cpp:235
ScreenshotGrabber::mHiddenWindows
QVector< QPointer< QWidget > > mHiddenWindows
Definition: screenshotgrabber.h:90
ScreenshotGrabber::grabScreen
QPixmap grabScreen()
Definition: screenshotgrabber.cpp:225
ScreenGrabberOverlayItem::setChosenRect
void setChosenRect(QRect rect)
Definition: screengrabberoverlayitem.cpp:44
ScreenGrabberChooserRectItem::doubleClicked
void doubleClicked()
widget.h
ScreenshotGrabber::reject
void reject()
Definition: screenshotgrabber.cpp:219
ScreenshotGrabber::chooseHelperTooltipText
void chooseHelperTooltipText(QRect rect)
Definition: screenshotgrabber.cpp:191
ScreenshotGrabber::scene
QGraphicsScene * scene
Definition: screenshotgrabber.h:79
ScreenshotGrabber::useNothingSelectedTooltip
void useNothingSelectedTooltip()
Definition: screenshotgrabber.cpp:168
ScreenshotGrabber::beginRectChooser
void beginRectChooser(QGraphicsSceneMouseEvent *event)
Definition: screenshotgrabber.cpp:258
ScreenshotGrabber::screenshotTaken
void screenshotTaken(const QPixmap &pixmap)
ScreenshotGrabber::showGrabber
void showGrabber()
Definition: screenshotgrabber.cpp:78
ScreenshotGrabber::screenGrabDisplay
QGraphicsPixmapItem * screenGrabDisplay
Definition: screenshotgrabber.h:81
ScreenshotGrabber::helperToolbox
ToolBoxGraphicsItem * helperToolbox
Definition: screenshotgrabber.h:84
ScreenshotGrabber::screenGrab
QPixmap screenGrab
Definition: screenshotgrabber.h:78
ScreenshotGrabber::reInit
void reInit()
Definition: screenshotgrabber.cpp:56
ScreenshotGrabber::useRegionSelectedTooltip
void useRegionSelectedTooltip()
Definition: screenshotgrabber.cpp:179
ScreenshotGrabber::restoreHiddenWindows
void restoreHiddenWindows()
Definition: screenshotgrabber.cpp:247
ScreenshotGrabber::~ScreenshotGrabber
~ScreenshotGrabber() override
Definition: screenshotgrabber.cpp:64
ScreenshotGrabber::window
QGraphicsView * window
Definition: screenshotgrabber.h:80
ScreenshotGrabber::overlay
ScreenGrabberOverlayItem * overlay
Definition: screenshotgrabber.h:82
ScreenshotGrabber::adjustTooltipPosition
void adjustTooltipPosition()
Definition: screenshotgrabber.cpp:203
ScreenshotGrabber::setupScene
void setupScene()
Definition: screenshotgrabber.cpp:140
screengrabberchooserrectitem.h
ScreenshotGrabber::ScreenshotGrabber
ScreenshotGrabber()
Definition: screenshotgrabber.cpp:38
ScreenGrabberChooserRectItem
Definition: screengrabberchooserrectitem.h:24
ScreenshotGrabber::regionChosen
void regionChosen(QRect region)
ScreenGrabberChooserRectItem::beginResize
void beginResize(QPointF mousePos)
Definition: screengrabberchooserrectitem.cpp:71
ScreenGrabberChooserRectItem::regionChosen
void regionChosen(QRect rect)
ScreenshotGrabber::mKeysBlocked
bool mKeysBlocked
Definition: screenshotgrabber.h:58
ScreenshotGrabber::chooserRect
ScreenGrabberChooserRectItem * chooserRect
Definition: screenshotgrabber.h:83