Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions resources/function_help/json/project_bookmark
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "project_bookmark",
"type": "function",
"groups": ["Bookmarks"],
"description": "Returns a project bookmark by name.",
"arguments": [{
"arg": "name",
"description": "a project bookmark name"
}],
"examples": [{
"expression": "project_bookmark('Home')",
"returns": "A map representing the 'Home' project bookmark."
}],
"tags": ["bookmarks", "project"]
}
15 changes: 15 additions & 0 deletions resources/function_help/json/user_bookmark
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "user_bookmark",
"type": "function",
"groups": ["Bookmarks"],
"description": "Returns a user (profile) bookmark by name.",
"arguments": [{
"arg": "name",
"description": "a user bookmark name"
}],
"examples": [{
"expression": "user_bookmark('Home')",
"returns": "A map representing the 'Home' user bookmark."
}],
"tags": ["bookmarks", "user", "profile"]
}
2 changes: 2 additions & 0 deletions src/core/expression/qgsexpressioncontextutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,8 @@ void QgsExpressionContextUtils::registerContextFunctions()
{
QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
QgsExpression::registerFunction( new GetNamedProjectColorObject( nullptr ) );
QgsExpression::registerFunction( new GetNamedProjectBookmark( nullptr ) );
QgsExpression::registerFunction( new GetNamedUserBookmark() );
QgsExpression::registerFunction( new GetSensorData( ) );
QgsExpression::registerFunction( new GetLayoutItemVariables( nullptr ) );
QgsExpression::registerFunction( new GetLayoutMapLayerCredits( nullptr ) );
Expand Down
122 changes: 122 additions & 0 deletions src/core/project/qgsproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2979,6 +2979,9 @@ QgsExpressionContextScope *QgsProject::createExpressionContextScope() const
mProjectScope->addFunction( QStringLiteral( "project_color" ), new GetNamedProjectColor( this ) );
mProjectScope->addFunction( QStringLiteral( "project_color_object" ), new GetNamedProjectColorObject( this ) );

mProjectScope->addFunction( QStringLiteral( "project_bookmark" ), new GetNamedProjectBookmark( this ) );
mProjectScope->addFunction( QStringLiteral( "user_bookmark" ), new GetNamedUserBookmark( ) );

return createExpressionContextScope();
}

Expand Down Expand Up @@ -5566,6 +5569,125 @@ QgsScopedExpressionFunction *GetNamedProjectColorObject::clone() const
return new GetNamedProjectColorObject( mColors );
}

// Helper to build the hash
static QHash<QString, QVariantMap> loadBookmarksFromProject( const QgsProject *project )
{
QHash<QString, QVariantMap> bookmarks;
const QgsBookmarkManager *bookmarkManager = project->bookmarkManager();
if ( !bookmarkManager )
return bookmarks;

const QList<QgsBookmark> projectBookmarks = bookmarkManager->bookmarks();
for ( const QgsBookmark &bm : projectBookmarks )
{
QVariantMap bmMap;
bmMap["name"] = bm.name();
bmMap["id"] = bm.id();
bmMap["group"] = bm.group();

QVariantMap extentMap;
extentMap["x_min"] = bm.extent().xMinimum();
extentMap["y_min"] = bm.extent().yMinimum();
extentMap["x_max"] = bm.extent().xMaximum();
extentMap["y_max"] = bm.extent().yMaximum();
bmMap["extent_rect"] = extentMap;

bmMap["width"] = bm.extent().width();
bmMap["height"] = bm.extent().height();
bmMap["crs"] = bm.extent().crs().authid();
bmMap["rotation"] = bm.rotation();

QgsGeometry geomBounds = QgsGeometry::fromRect( bm.extent() );
QVariant result = !geomBounds.isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
bmMap["extent"] = result;

bookmarks[bm.name()] = bmMap;
}
return bookmarks;
}

// Constructor
GetNamedProjectBookmark::GetNamedProjectBookmark( const QgsProject * )
: QgsScopedExpressionFunction( QStringLiteral( "project_bookmark" ), 1, QStringLiteral( "Bookmarks" ) )
{
}

QVariant GetNamedProjectBookmark::func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * )
{
if ( values.isEmpty() )
return QVariant();

const QgsProject *project = QgsProject::instance();
if ( !project )
return QVariant();

const QHash<QString, QVariantMap> bookmarks = loadBookmarksFromProject( project );
const QString bookmarkName = values.at( 0 ).toString();
const QVariantMap bmMap = bookmarks.value( bookmarkName );
if ( bmMap.isEmpty() )
return QVariant();
return bmMap;
}

QgsScopedExpressionFunction *GetNamedProjectBookmark::clone() const
{
return new GetNamedProjectBookmark( nullptr );
}


// Helper to build the hash for user bookmarks
static QHash<QString, QVariantMap> loadUserBookmarks()
{
QHash<QString, QVariantMap> bookmarks;
const auto userBookmarks = QgsApplication::bookmarkManager()->bookmarks();
for ( const QgsBookmark &b : userBookmarks )
{
QVariantMap map;
map["id"] = b.id();
map["name"] = b.name();
map["group"] = b.group();

QVariantMap extentMap;
extentMap["x_min"] = b.extent().xMinimum();
extentMap["y_min"] = b.extent().yMinimum();
extentMap["x_max"] = b.extent().xMaximum();
extentMap["y_max"] = b.extent().yMaximum();
map["extent_rect"] = extentMap;

map["width"] = b.extent().width();
map["height"] = b.extent().height();
map["crs"] = b.extent().crs().authid();
map["rotation"] = b.rotation();

QgsGeometry geomBounds = QgsGeometry::fromRect( b.extent() );
QVariant result = !geomBounds.isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
map["extent"] = result;

bookmarks[b.name()] = map;
}
return bookmarks;
}

GetNamedUserBookmark::GetNamedUserBookmark()
: QgsScopedExpressionFunction( QStringLiteral( "user_bookmark" ), 1, QStringLiteral( "Bookmarks" ) )
{}

QVariant GetNamedUserBookmark::func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * )
{
if ( values.isEmpty() )
return QVariant();

const QString name = values.at( 0 ).toString();
const auto bookmarks = loadUserBookmarks();
return bookmarks.value( name );
}

QgsScopedExpressionFunction *GetNamedUserBookmark::clone() const
{
return new GetNamedUserBookmark();
}


// ----------------

GetSensorData::GetSensorData( const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
Expand Down
23 changes: 23 additions & 0 deletions src/core/project/qgsproject.h
Original file line number Diff line number Diff line change
Expand Up @@ -2740,6 +2740,29 @@ class GetNamedProjectColorObject : public QgsScopedExpressionFunction
};


class GetNamedProjectBookmark : public QgsScopedExpressionFunction
{
public:
GetNamedProjectBookmark( const QgsProject *project );
GetNamedProjectBookmark( const QHash<QString, QVariantMap> &bookmarks );

QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override;
QgsScopedExpressionFunction *clone() const override;

private:
QHash<QString, QVariantMap> mBookmarks;
};

class GetNamedUserBookmark : public QgsScopedExpressionFunction
{
public:
GetNamedUserBookmark();
QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override;
QgsScopedExpressionFunction *clone() const override;
};




class GetSensorData : public QgsScopedExpressionFunction
{
Expand Down
Loading