Skip to content

Commit

Permalink
take screenshots in app for user documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed Oct 4, 2018
1 parent 2a974e3 commit ffdf617
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 0 deletions.
7 changes: 7 additions & 0 deletions python/gui/auto_generated/qgisinterface.sip.in
Expand Up @@ -598,6 +598,13 @@ used for interacting and adding widgets and messages to the app's
status bar (do not use the native Qt statusBar() method).

.. versionadded:: 3.0
%End

virtual void takeAppScreenShots( const QString &saveDirectory, const int categories = 0 );
%Docstring
Take screenshots for the user documentation

.. versionadded:: 3.4
%End

public slots: // TODO: do these functions really need to be slots?
Expand Down
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -13,6 +13,7 @@ SET(QGIS_APP_SRCS
qgsappwindowmanager.cpp
qgsaddattrdialog.cpp
qgsaddtaborgroup.cpp
qgsappscreenshots.cpp
qgsjoindialog.cpp
qgsannotationwidget.cpp
qgsattributeactiondialog.cpp
Expand Down Expand Up @@ -236,6 +237,7 @@ SET (QGIS_APP_MOC_HDRS
qgsaddattrdialog.h
qgsalignrasterdialog.h
qgsappbrowserproviders.h
qgsappscreenshots.h
qgsjoindialog.h
qgsaddtaborgroup.h
qgsannotationwidget.h
Expand Down
7 changes: 7 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -149,6 +149,7 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "qgsauthcertutils.h"
#include "qgsauthsslerrorsdialog.h"
#endif
#include "qgsappscreenshots.h"
#include "qgsbookmarks.h"
#include "qgsbrowserdockwidget.h"
#include "qgsadvanceddigitizingdockwidget.h"
Expand Down Expand Up @@ -13062,6 +13063,12 @@ void QgisApp::zoomToBookmarkIndex( const QModelIndex &index )
mBookMarksDockWidget->zoomToBookmarkIndex( index );
}

void QgisApp::takeAppScreenShots( const QString &saveDirectory, const int categories )
{
QgsAppScreenShots ass( saveDirectory );
ass.takeScreenshots( QgsAppScreenShots::Categories( categories ) );
}

// Slot that gets called when the project file was saved with an older
// version of QGIS

Expand Down
3 changes: 3 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -696,6 +696,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Returns pointer to the identify map tool - used by identify tool in 3D view
QgsMapToolIdentifyAction *identifyMapTool() const { return mMapTools.mIdentify; }

//! Take screenshots for user documentation
void takeAppScreenShots( const QString &saveDirectory, const int categories = 0 );

public slots:
//! save current vector layer
void saveAsFile( QgsMapLayer *layer = nullptr, bool onlySelected = false );
Expand Down
5 changes: 5 additions & 0 deletions src/app/qgisappinterface.cpp
Expand Up @@ -789,3 +789,8 @@ bool QgisAppInterface::askForDatumTransform( QgsCoordinateReferenceSystem source
{
return qgis->askUserForDatumTransform( sourceCrs, destinationCrs );
}

void QgisAppInterface::takeAppScreenShots( const QString &saveDirectory, const int categories )
{
return qgis->takeAppScreenShots( saveDirectory, categories );
}
2 changes: 2 additions & 0 deletions src/app/qgisappinterface.h
Expand Up @@ -551,6 +551,8 @@ class APP_EXPORT QgisAppInterface : public QgisInterface

bool askForDatumTransform( QgsCoordinateReferenceSystem sourceCrs, QgsCoordinateReferenceSystem destinationCrs ) override;

void takeAppScreenShots( const QString &saveDirectory, const int categories = 0 ) override;


private slots:

Expand Down
96 changes: 96 additions & 0 deletions src/app/qgsappscreenshots.cpp
@@ -0,0 +1,96 @@


#include <QWindow>
#include <QScreen>
#include <QImageWriter>

#include "qgsappscreenshots.h"

#include "qgsvectorlayerproperties.h"
#include "qgsvectorlayer.h"
#include "qgsproject.h"
#include "qgsmessagelog.h"

QgsAppScreenShots::QgsAppScreenShots( const QString &saveDirectory )
: mSaveDirectory( saveDirectory )
{
QString layerDef = QStringLiteral( "Point?crs=epsg:4326&field=pk:integer&field=my_text:string&field=my_integer:integer&field=my_double:double&key=pk" );
mVectorLayer = new QgsVectorLayer( layerDef, QStringLiteral( "Layer" ), QStringLiteral( "memory" ) );
QgsProject::instance()->addMapLayer( mVectorLayer );
}

void QgsAppScreenShots::saveScreenshot( const QString &name, QWidget *widget, GrabMode mode )
{
QPixmap pix;
int x = 0;
int y = 0;
int w = -1;
int h = -1;

QScreen *screen = QGuiApplication::primaryScreen();
if ( widget )
{
const QWindow *window = widget->windowHandle();
if ( window )
{
screen = window->screen();
}
widget->raise();
if ( mode == GrabWidget )
{
pix = widget->grab();
}
else if ( mode == GrabWidgetAndFrame )
{
const QRect geom = widget->frameGeometry();
QPoint tl = geom.topLeft();
x = tl.x();
y = tl.y();
w = geom.width();
h = geom.height();
}
}
if ( !widget || mode != GrabWidget )
{
pix = screen->grabWindow( 0, x, y, w, h );
}

const QString &fileName = mSaveDirectory + "/" + name + ".png";
pix.save( fileName );
QMetaEnum metaEnum = QMetaEnum::fromType<GrabMode>();
QgsMessageLog::logMessage( QString( "Screenshot saved: %1 (%2)" ).arg( fileName, metaEnum.key( mode ) ) );
}

void QgsAppScreenShots::takeScreenshots( Categories categories )
{
if ( !categories || categories.testFlag( VectorLayerProperties ) )
takeVectorLayerProperties();
}

void QgsAppScreenShots::takeVectorLayerProperties()
{
QgsVectorLayerProperties *dlg = new QgsVectorLayerProperties( mVectorLayer );
dlg->show();
// ----------------
// do all the pages
for ( int row = 0; row < dlg->mOptionsListWidget->count(); ++row )
{
dlg->mOptionsListWidget->setCurrentRow( row );
dlg->adjustSize();
QCoreApplication::processEvents();
QString name = dlg->mOptionsListWidget->item( row )[0].text().toLower();
name.replace( " ", "_" );
saveScreenshot( name, dlg );
}
// ------------------
// style menu clicked
dlg->mOptionsListWidget->setCurrentRow( 0 );
QCoreApplication::processEvents();
dlg->mBtnStyle->click();
saveScreenshot( "style", dlg );

// exit properly
dlg->close();
dlg->deleteLater();
}

45 changes: 45 additions & 0 deletions src/app/qgsappscreenshots.h
@@ -0,0 +1,45 @@
#ifndef QGSAPPSCREENSHOTS_H
#define QGSAPPSCREENSHOTS_H

#include <QObject>

class QgsVectorLayer;

class QgsAppScreenShots
{
Q_GADGET
public:
enum GrabMode
{
GrabWidget,
GrabWidgetAndFrame,
GrabWholeWindow
};
Q_ENUM( GrabMode )

enum Category
{
VectorLayerProperties = 1,
};
Q_ENUM( Category )
Q_DECLARE_FLAGS( Categories, Category )
Q_FLAG( Categories )

QgsAppScreenShots( const QString &saveDirectory );

//! if categories is null, then takes all categories
void takeScreenshots( Categories categories = nullptr );

private:
void takeVectorLayerProperties();


void saveScreenshot( const QString &name, QWidget *widget = nullptr, GrabMode mode = GrabWidgetAndFrame );

QString mSaveDirectory;
QgsVectorLayer *mVectorLayer = nullptr;
};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAppScreenShots::Categories )

#endif // QGSAPPSCREENSHOTS_H
2 changes: 2 additions & 0 deletions src/app/qgsvectorlayerproperties.h
Expand Up @@ -251,6 +251,8 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private

private slots:
void openPanel( QgsPanelWidget *panel );

friend class QgsAppScreenShots;
};


Expand Down
6 changes: 6 additions & 0 deletions src/gui/qgisinterface.h
Expand Up @@ -528,6 +528,12 @@ class GUI_EXPORT QgisInterface : public QObject
*/
virtual QgsStatusBar *statusBarIface() = 0;

/**
* Take screenshots for the user documentation
* \since QGIS 3.4
*/
virtual void takeAppScreenShots( const QString &saveDirectory, const int categories = 0 ) {Q_UNUSED( saveDirectory ); Q_UNUSED( categories );}

public slots: // TODO: do these functions really need to be slots?

/* Exposed functions */
Expand Down

0 comments on commit ffdf617

Please sign in to comment.