Skip to content

Commit

Permalink
Merge pull request #4448 from opengisch/projects_preview
Browse files Browse the repository at this point in the history
Recent projects preview image
  • Loading branch information
nirvn authored Jul 15, 2023
2 parents 67ef871 + c69f03f commit 21d5f8c
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 70 deletions.
Binary file added resources/sample_projects/bees.qgz.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/sample_projects/wastewater.qgz.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ set(QFIELD_CORE_SRCS
printlayoutlistmodel.cpp
projectinfo.cpp
projectsource.cpp
projectsimageprovider.cpp
qfieldappauthrequesthandler.cpp
qfieldcloudconnection.cpp
qfieldcloudprojectsmodel.cpp
Expand Down Expand Up @@ -184,6 +185,7 @@ set(QFIELD_CORE_HDRS
printlayoutlistmodel.h
projectinfo.h
projectsource.h
projectsimageprovider.h
qfieldappauthrequesthandler.h
qfieldcloudconnection.h
qfieldcloudprojectsmodel.h
Expand Down
32 changes: 32 additions & 0 deletions src/core/projectsimageprovider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/***************************************************************************
localfilesimageprovider.cpp - LocalFilesImageProvider
---------------------
begin : 18.05.2022
copyright : (C) 2022 by Mathieu Pellerin
email : mathieu at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "projectsimageprovider.h"

#include <QFileInfo>

ProjectsImageProvider::ProjectsImageProvider()
: QQuickImageProvider( Pixmap )
{
}

QImage ProjectsImageProvider::requestImage( const QString &id, QSize *size, const QSize &requestedSize )
{
// the id is passed on as an encoded URL string which needs decoding
const QString path = QUrl::fromPercentEncoding( id.toUtf8() );
const QString previewPath = QStringLiteral( "%1.jpg" ).arg( path );
return QFileInfo::exists( previewPath ) ? QImage( previewPath ) : QImage();
}
30 changes: 30 additions & 0 deletions src/core/projectsimageprovider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/***************************************************************************
projectsimageprovider.h - ProjectsImageProvider
---------------------
begin : 15.07.2023
copyright : (C) 2023 by Mathieu Pellerin
email : mathieu at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef PROJECTSIMAGEPROVIDER_H
#define PROJECTSIMAGEPROVIDER_H

#include <QQuickImageProvider>

class ProjectsImageProvider : public QQuickImageProvider
{
public:
explicit ProjectsImageProvider();

QQmlImageProviderBase::ImageType imageType() const override { return QQmlImageProviderBase::Image; }
QImage requestImage( const QString &id, QSize *size, const QSize &requestedSize ) override;
};

#endif // PROJECTSIMAGEPROVIDER_H
32 changes: 32 additions & 0 deletions src/core/qgismobileapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
#include "positioningutils.h"
#include "printlayoutlistmodel.h"
#include "projectinfo.h"
#include "projectsimageprovider.h"
#include "projectsource.h"
#include "qfield.h"
#include "qfieldcloudconnection.h"
Expand Down Expand Up @@ -258,6 +259,7 @@ QgisMobileapp::QgisMobileapp( QgsApplication *app, QObject *parent )
mFlatLayerTree = new FlatLayerTreeModel( mProject->layerTreeRoot(), mProject, this );
mLegendImageProvider = new LegendImageProvider( mFlatLayerTree->layerTreeModel() );
mLocalFilesImageProvider = new LocalFilesImageProvider();
mProjectsImageProvider = new ProjectsImageProvider();
mTrackingModel = new TrackingModel;

mBookmarkModel = std::make_unique<BookmarkModel>( QgsApplication::bookmarkManager(), mProject->bookmarkManager(), nullptr );
Expand Down Expand Up @@ -547,6 +549,7 @@ void QgisMobileapp::initDeclarative()

addImageProvider( QLatin1String( "legend" ), mLegendImageProvider );
addImageProvider( QLatin1String( "localfiles" ), mLocalFilesImageProvider );
addImageProvider( QLatin1String( "projects" ), mProjectsImageProvider );
}

void QgisMobileapp::loadProjectQuirks()
Expand Down Expand Up @@ -652,6 +655,18 @@ void QgisMobileapp::onAfterFirstRendering()
}
}

void QgisMobileapp::onMapCanvasRefreshed()
{
disconnect( mMapCanvas, &QgsQuickMapCanvasMap::mapCanvasRefreshed, this, &QgisMobileapp::onMapCanvasRefreshed );
if ( !mProjectFilePath.isEmpty() )
{
if ( !QFileInfo::exists( QStringLiteral( "%1.jpg" ).arg( mProjectFilePath ) ) )
{
saveProjectPreviewImage();
}
}
}

bool QgisMobileapp::loadProjectFile( const QString &path, const QString &name )
{
QFileInfo fi( path );
Expand All @@ -664,6 +679,8 @@ bool QgisMobileapp::loadProjectFile( const QString &path, const QString &name )
const QString suffix = fi.suffix().toLower();
if ( SUPPORTED_PROJECT_EXTENSIONS.contains( suffix ) || SUPPORTED_VECTOR_EXTENSIONS.contains( suffix ) || SUPPORTED_RASTER_EXTENSIONS.contains( suffix ) )
{
saveProjectPreviewImage();

mAuthRequestHandler->clearStoredRealms();

mProjectFilePath = path;
Expand Down Expand Up @@ -1182,6 +1199,8 @@ void QgisMobileapp::readProjectFile()
}

emit loadProjectEnded( mProjectFilePath, mProjectFileName );

connect( mMapCanvas, &QgsQuickMapCanvasMap::mapCanvasRefreshed, this, &QgisMobileapp::onMapCanvasRefreshed );
}

QString QgisMobileapp::readProjectEntry( const QString &scope, const QString &key, const QString &def ) const
Expand Down Expand Up @@ -1390,6 +1409,18 @@ bool QgisMobileapp::event( QEvent *event )
return QQmlApplicationEngine::event( event );
}

void QgisMobileapp::saveProjectPreviewImage()
{
if ( !mProjectFilePath.isEmpty() && mMapCanvas && !mMapCanvas->isRendering() )
{
const QImage grab = mMapCanvas->image();
const int pixels = std::min( grab.width(), grab.height() );
const QRect rect( ( grab.width() - pixels ) / 2, ( grab.height() - pixels ) / 2, pixels, pixels );
const QImage img = grab.copy( rect );
img.save( QStringLiteral( "%1.jpg" ).arg( mProjectFilePath ) );
}
}

void QgisMobileapp::requestQuit()
{
mApp->exitQgis();
Expand All @@ -1398,6 +1429,7 @@ void QgisMobileapp::requestQuit()

QgisMobileapp::~QgisMobileapp()
{
saveProjectPreviewImage();
delete mOfflineEditing;
mProject->removeAllMapLayers();
delete mProject;
Expand Down
5 changes: 4 additions & 1 deletion src/core/qgismobileapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class FlatLayerTreeModel;
class LayerTreeModel;
class LegendImageProvider;
class LocalFilesImageProvider;
class ProjectsImageProvider;
class TrackingModel;
class LocatorFiltersModel;
class QgsProject;
Expand Down Expand Up @@ -185,12 +186,13 @@ class QFIELD_CORE_EXPORT QgisMobileapp : public QQmlApplicationEngine
private slots:

void onAfterFirstRendering();

void onMapCanvasRefreshed();
void requestQuit();

private:
void initDeclarative();
void loadProjectQuirks();
void saveProjectPreviewImage();
bool printAtlas( QgsPrintLayout *layoutToPrint, const QString &destination );

QgsOfflineEditing *mOfflineEditing = nullptr;
Expand All @@ -203,6 +205,7 @@ class QFIELD_CORE_EXPORT QgisMobileapp : public QQmlApplicationEngine
bool mFirstRenderingFlag;
LegendImageProvider *mLegendImageProvider = nullptr;
LocalFilesImageProvider *mLocalFilesImageProvider = nullptr;
ProjectsImageProvider *mProjectsImageProvider = nullptr;

QgsProject *mProject = nullptr;
QString mProjectFilePath;
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsquick/qgsquickmapcanvasmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ class QgsQuickMapCanvasMap : public QQuickItem
//! \copydoc QgsQuickMapCanvasMap::incrementalRendering
void setIncrementalRendering( bool incrementalRendering );

/**
* Returns an image of the last successful map canvas rendering
*/
QImage image() const { return mImage; }

signals:

/**
Expand Down
10 changes: 6 additions & 4 deletions src/qml/QFieldCloudScreen.qml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ Page {
delegate: Rectangle {
id: rectangle

property bool isPressed: false
property string projectId: Id
property string projectOwner: Owner
property string projectName: Name
Expand Down Expand Up @@ -328,6 +329,7 @@ Page {
font.pointSize: Theme.tipFont.pointSize
font.underline: true
color: Theme.mainColor
opacity: rectangle.isPressed ? 0.8 : 1
wrapMode: Text.WordWrap
Layout.fillWidth: true
}
Expand Down Expand Up @@ -440,19 +442,19 @@ Page {
table.contentY + mouse.y
)
if (item) {
pressedItem = item.children[1].children[1].children[0];
pressedItem.color = "#5a8725"
pressedItem = item
pressedItem.isPressed = true
}
}
onCanceled: {
if (pressedItem) {
pressedItem.color = Theme.mainColor
pressedItem.isPressed = false
pressedItem = null
}
}
onReleased: {
if (pressedItem) {
pressedItem.color = Theme.mainColor
pressedItem.isPressed = false
pressedItem = null
}
}
Expand Down
Loading

1 comment on commit 21d5f8c

@qfield-fairy
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.