2015-03-10 01:32:30 +08:00
/*
2015-06-06 09:40:08 +08:00
Copyright © 2015 by The qTox Project
2015-03-10 01:32:30 +08:00
This file is part of qTox , a Qt - based graphical interface for Tox .
2015-06-06 09:40:08 +08:00
qTox is libre software : you can redistribute it and / or modify
2015-03-10 01:32:30 +08:00
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
2015-06-06 09:40:08 +08:00
qTox is distributed in the hope that it will be useful ,
2015-03-10 01:32:30 +08:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2015-06-06 09:40:08 +08:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2015-03-10 01:32:30 +08:00
2015-06-06 09:40:08 +08:00
You should have received a copy of the GNU General Public License
along with qTox . If not , see < http : //www.gnu.org/licenses/>.
2015-03-10 01:32:30 +08:00
*/
# include "screenshotgrabber.h"
2015-10-10 23:34:33 +08:00
# include <QApplication>
# include <QDebug>
# include <QDesktopWidget>
2015-03-10 01:32:30 +08:00
# include <QGraphicsPixmapItem>
# include <QGraphicsRectItem>
2015-10-10 23:34:33 +08:00
# include <QGraphicsSceneMouseEvent>
2015-03-10 01:32:30 +08:00
# include <QGraphicsView>
# include <QMouseEvent>
# include <QScreen>
2015-10-10 23:34:33 +08:00
# include <QTimer>
2015-03-10 01:32:30 +08:00
2015-03-25 09:48:26 +08:00
# include "screengrabberchooserrectitem.h"
# include "screengrabberoverlayitem.h"
# include "toolboxgraphicsitem.h"
2015-08-24 06:10:31 +08:00
# include "src/widget/widget.h"
2015-03-10 01:32:30 +08:00
2015-09-26 03:47:49 +08:00
ScreenshotGrabber : : ScreenshotGrabber ( QObject * parent )
: QObject ( parent )
2015-10-10 23:54:56 +08:00
, mKeysBlocked ( false )
2015-10-10 23:39:59 +08:00
, scene ( 0 )
2015-10-10 23:45:23 +08:00
, mQToxVisible ( true )
2015-03-10 01:32:30 +08:00
{
2015-05-10 04:35:58 +08:00
window = new QGraphicsView ( scene ) ; // Top-level widget
2015-10-10 23:39:59 +08:00
window - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
window - > setWindowFlags ( Qt : : FramelessWindowHint | Qt : : BypassWindowManagerHint ) ;
window - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
window - > setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
window - > setVerticalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
window - > setFrameShape ( QFrame : : NoFrame ) ;
window - > installEventFilter ( this ) ;
2016-04-08 23:50:32 +08:00
# if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
pixRatio = QApplication : : primaryScreen ( ) - > devicePixelRatio ( ) ;
# endif
// Scale window down by devicePixelRatio to show full screen region
window - > scale ( 1 / pixRatio , 1 / pixRatio ) ;
2015-10-10 23:39:59 +08:00
setupScene ( ) ;
2015-08-24 06:10:31 +08:00
}
2015-06-06 09:40:08 +08:00
2015-08-24 06:10:31 +08:00
void ScreenshotGrabber : : reInit ( )
{
2015-10-10 23:54:56 +08:00
window - > resetCachedContent ( ) ;
2015-10-10 23:39:59 +08:00
setupScene ( ) ;
2015-08-24 06:10:31 +08:00
showGrabber ( ) ;
2015-10-10 23:54:56 +08:00
mKeysBlocked = false ;
2015-03-10 01:32:30 +08:00
}
ScreenshotGrabber : : ~ ScreenshotGrabber ( )
{
2015-05-10 04:35:58 +08:00
delete scene ;
2015-03-10 01:32:30 +08:00
}
bool ScreenshotGrabber : : eventFilter ( QObject * object , QEvent * event )
{
if ( event - > type ( ) = = QEvent : : KeyPress )
return handleKeyPress ( static_cast < QKeyEvent * > ( event ) ) ;
2015-06-06 09:40:08 +08:00
2015-09-26 03:47:49 +08:00
return QObject : : eventFilter ( object , event ) ;
2015-03-10 01:32:30 +08:00
}
void ScreenshotGrabber : : showGrabber ( )
{
this - > screenGrab = grabScreen ( ) ;
this - > screenGrabDisplay - > setPixmap ( this - > screenGrab ) ;
this - > window - > show ( ) ;
this - > window - > setFocus ( ) ;
this - > window - > grabKeyboard ( ) ;
2015-09-25 20:25:14 +08:00
QRect fullGrabbedRect = screenGrab . rect ( ) ;
2015-09-28 05:57:01 +08:00
QRect rec = QApplication : : primaryScreen ( ) - > virtualGeometry ( ) ;
2015-09-25 20:25:14 +08:00
2015-09-28 05:57:01 +08:00
this - > window - > setGeometry ( rec ) ;
2015-09-26 03:44:54 +08:00
this - > scene - > setSceneRect ( fullGrabbedRect ) ;
2015-09-25 20:25:14 +08:00
this - > overlay - > setRect ( fullGrabbedRect ) ;
2015-03-10 01:32:30 +08:00
adjustTooltipPosition ( ) ;
}
bool ScreenshotGrabber : : handleKeyPress ( QKeyEvent * event )
{
2015-10-10 23:54:56 +08:00
if ( mKeysBlocked )
return false ;
2015-03-10 01:32:30 +08:00
if ( event - > key ( ) = = Qt : : Key_Escape )
reject ( ) ;
else if ( event - > key ( ) = = Qt : : Key_Return | | event - > key ( ) = = Qt : : Key_Enter )
acceptRegion ( ) ;
2015-10-10 23:54:56 +08:00
else if ( event - > key ( ) = = Qt : : Key_Space ) {
mKeysBlocked = true ;
if ( mQToxVisible )
hideVisibleWindows ( ) ;
2015-08-31 01:44:33 +08:00
else
2015-10-10 23:54:56 +08:00
restoreHiddenWindows ( ) ;
2015-08-31 01:44:33 +08:00
2015-10-10 23:54:56 +08:00
window - > hide ( ) ;
2015-12-21 08:14:09 +08:00
QTimer : : singleShot ( 350 , this , SLOT ( reInit ( ) ) ) ;
2015-08-24 06:10:31 +08:00
}
2015-03-10 01:32:30 +08:00
else
return false ;
2015-06-06 09:40:08 +08:00
2015-03-10 01:32:30 +08:00
return true ;
}
void ScreenshotGrabber : : acceptRegion ( )
{
QRect rect = this - > chooserRect - > chosenRect ( ) ;
if ( rect . width ( ) < 1 | | rect . height ( ) < 1 )
return ;
2015-06-06 09:40:08 +08:00
2015-03-10 01:32:30 +08:00
qDebug ( ) < < " Screenshot accepted, chosen region " < < rect ;
emit screenshotTaken ( this - > screenGrab . copy ( rect ) ) ;
this - > window - > close ( ) ;
2015-10-10 23:54:56 +08:00
restoreHiddenWindows ( ) ;
2015-03-10 01:32:30 +08:00
}
2015-10-10 23:39:59 +08:00
void ScreenshotGrabber : : setupScene ( )
2015-03-10 01:32:30 +08:00
{
2015-10-10 23:39:59 +08:00
delete scene ;
scene = new QGraphicsScene ;
window - > setScene ( scene ) ;
2015-03-10 01:32:30 +08:00
this - > overlay = new ScreenGrabberOverlayItem ( this ) ;
this - > helperToolbox = new ToolBoxGraphicsItem ;
2015-06-06 09:40:08 +08:00
2015-03-10 01:32:30 +08:00
this - > screenGrabDisplay = scene - > addPixmap ( this - > screenGrab ) ;
this - > helperTooltip = scene - > addText ( QString ( ) ) ;
2016-04-08 23:50:32 +08:00
// Scale UI elements up by devicePixelRatio to compensate for window downscaling
this - > helperToolbox - > setScale ( pixRatio ) ;
this - > helperTooltip - > setScale ( pixRatio ) ;
2015-03-10 01:32:30 +08:00
scene - > addItem ( this - > overlay ) ;
this - > chooserRect = new ScreenGrabberChooserRectItem ( scene ) ;
scene - > addItem ( this - > helperToolbox ) ;
2015-06-06 09:40:08 +08:00
2015-03-10 01:32:30 +08:00
this - > helperToolbox - > addToGroup ( this - > helperTooltip ) ;
this - > helperTooltip - > setDefaultTextColor ( Qt : : black ) ;
useNothingSelectedTooltip ( ) ;
2015-06-06 09:40:08 +08:00
2015-03-10 01:32:30 +08:00
connect ( this - > chooserRect , & ScreenGrabberChooserRectItem : : doubleClicked , this , & ScreenshotGrabber : : acceptRegion ) ;
2015-03-26 23:43:49 +08:00
connect ( this - > chooserRect , & ScreenGrabberChooserRectItem : : regionChosen , this , & ScreenshotGrabber : : chooseHelperTooltipText ) ;
2015-03-10 01:32:30 +08:00
connect ( this - > chooserRect , & ScreenGrabberChooserRectItem : : regionChosen , this - > overlay , & ScreenGrabberOverlayItem : : setChosenRect ) ;
}
void ScreenshotGrabber : : useNothingSelectedTooltip ( )
{
2015-08-31 03:16:50 +08:00
helperTooltip - > setHtml ( tr ( " Click and drag to select a region. Press <b>Space</b> to hide/show qTox window, or <b>Escape</b> to cancel. " ,
2015-03-26 23:43:49 +08:00
" Help text shown when no region has been selected yet " ) ) ;
2015-03-10 01:32:30 +08:00
adjustTooltipPosition ( ) ;
}
void ScreenshotGrabber : : useRegionSelectedTooltip ( )
{
2015-08-31 02:50:01 +08:00
helperTooltip - > setHtml ( tr ( " Press <b>Enter</b> to send a screenshot of the selection, <b>Space</b> to hide/show qTox window, or <b>Escape</b> to cancel. " ,
2015-03-26 23:43:49 +08:00
" Help text shown when a region has been selected " ) ) ;
2015-03-10 01:32:30 +08:00
adjustTooltipPosition ( ) ;
}
2015-03-26 23:43:49 +08:00
void ScreenshotGrabber : : chooseHelperTooltipText ( QRect rect )
{
if ( rect . size ( ) . isNull ( ) )
useNothingSelectedTooltip ( ) ;
else
useRegionSelectedTooltip ( ) ;
}
2015-10-03 16:03:14 +08:00
/**
* @ internal
*
* Align the tooltip centred at top of screen with the mouse cursor .
*/
2015-03-10 01:32:30 +08:00
void ScreenshotGrabber : : adjustTooltipPosition ( )
{
2015-10-03 16:03:14 +08:00
QRect recGL = QGuiApplication : : primaryScreen ( ) - > virtualGeometry ( ) ;
QRect rec = qApp - > desktop ( ) - > screenGeometry ( QCursor : : pos ( ) ) ;
const QRectF ttRect = this - > helperToolbox - > childrenBoundingRect ( ) ;
int x = abs ( recGL . x ( ) ) + rec . x ( ) + ( ( rec . width ( ) - ttRect . width ( ) ) / 2 ) ;
int y = abs ( recGL . y ( ) ) + rec . y ( ) ;
2016-04-08 23:50:32 +08:00
// Multiply by devicePixelRatio to get centered positions under scaling
helperToolbox - > setX ( x * pixRatio ) ;
helperToolbox - > setY ( y * pixRatio ) ;
2015-03-10 01:32:30 +08:00
}
void ScreenshotGrabber : : reject ( )
{
qDebug ( ) < < " Rejected screenshot " ;
this - > window - > close ( ) ;
2015-10-10 23:54:56 +08:00
restoreHiddenWindows ( ) ;
2015-03-10 01:32:30 +08:00
}
2015-05-28 05:23:26 +08:00
QPixmap ScreenshotGrabber : : grabScreen ( )
{
2015-09-28 05:57:01 +08:00
QScreen * screen = QGuiApplication : : primaryScreen ( ) ;
QRect rec = screen - > virtualGeometry ( ) ;
2016-04-08 23:50:32 +08:00
// Multiply by devicePixelRatio to get actual desktop size
2015-09-28 05:57:01 +08:00
return screen - > grabWindow ( QApplication : : desktop ( ) - > winId ( ) ,
2016-04-08 23:50:32 +08:00
rec . x ( ) * pixRatio ,
rec . y ( ) * pixRatio ,
rec . width ( ) * pixRatio ,
rec . height ( ) * pixRatio ) ;
2015-03-10 01:32:30 +08:00
}
2015-10-10 23:45:23 +08:00
void ScreenshotGrabber : : hideVisibleWindows ( )
{
foreach ( QWidget * w , qApp - > topLevelWidgets ( ) ) {
if ( w ! = window & & w - > isVisible ( ) ) {
mHiddenWindows < < w ;
w - > setVisible ( false ) ;
}
}
mQToxVisible = false ;
}
void ScreenshotGrabber : : restoreHiddenWindows ( )
{
foreach ( QWidget * w , mHiddenWindows ) {
if ( w )
w - > setVisible ( true ) ;
}
mHiddenWindows . clear ( ) ;
mQToxVisible = true ;
}
2015-03-10 01:32:30 +08:00
void ScreenshotGrabber : : beginRectChooser ( QGraphicsSceneMouseEvent * event )
{
QPointF pos = event - > scenePos ( ) ;
this - > chooserRect - > setX ( pos . x ( ) ) ;
this - > chooserRect - > setY ( pos . y ( ) ) ;
2015-03-26 23:40:47 +08:00
this - > chooserRect - > beginResize ( event - > scenePos ( ) ) ;
2015-03-10 01:32:30 +08:00
}