Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QField 💖 QML & HTML #1221

Merged
merged 4 commits into from
Aug 21, 2020
Merged
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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ IF (ANDROID)
ADD_CUSTOM_TARGET(assets ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/android-build/assets/assets.zip")
ENDIF (ANDROID)

FIND_PACKAGE(Qt5 COMPONENTS Test Concurrent Core Qml Gui Xml Positioning Widgets PrintSupport Network Quick Svg OpenGL Sql PrintSupport Sensors REQUIRED)
FIND_PACKAGE(Qt5 COMPONENTS Test Concurrent Core Qml Gui Xml Positioning Widgets PrintSupport Network Quick Svg OpenGL Sql PrintSupport Sensors WebView REQUIRED)

ADD_SUBDIRECTORY(3rdparty/tessellate)
ADD_SUBDIRECTORY(src/qgsquick)
Expand Down
2 changes: 1 addition & 1 deletion sdk.conf
Original file line number Diff line number Diff line change
@@ -1 +1 @@
osgeo4a_version=20200818
nirvn marked this conversation as resolved.
Show resolved Hide resolved
osgeo4a_version=20200820
2 changes: 1 addition & 1 deletion src/app/app.pro
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ include( ../../qgis.pri )
include( ../../version.pri )
include( ../../assets.pri )

QT += widgets concurrent xml positioning printsupport svg sql opengl sensors quick quickcontrols2 qml
QT += widgets concurrent xml positioning printsupport svg sql opengl sensors quick quickcontrols2 qml webview

android {
QT += androidextras
Expand Down
4 changes: 3 additions & 1 deletion src/app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <QLabel>
#include <QDialog>
#include <QApplication>
#include <QtWebView/QtWebView>

#include "qgsapplication.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -101,9 +102,10 @@ int main( int argc, char **argv )
app.setPluginPath( QApplication::applicationDirPath() );
app.setPkgDataPath( AndroidPlatformUtilities().packagePath() );
#else
QtWebView::initialize();
QgsApplication app( argc, argv, true );
QSettings settings;

QSettings settings;
app.setThemeName( settings.value( "/Themes", "default" ).toString() );
app.setPrefixPath( CMAKE_INSTALL_PREFIX, true );
#endif
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ TARGET_LINK_LIBRARIES(qfield_core
Qt5::Positioning
Qt5::Sql
Qt5::Concurrent
Qt5::WebView
${QGIS_CORE_LIBRARY}
${QGIS_ANALYSIS_LIBRARY}
)
Expand Down
3 changes: 2 additions & 1 deletion src/core/attributeformmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ class AttributeFormModel : public QSortFilterProxyModel
ConstraintHardValid,
ConstraintSoftValid,
ConstraintDescription,
AttributeAllowEdit
AttributeAllowEdit,
EditorWidgetCode //<! Returns a QML or HTML code string used by the relevant widgets
};

Q_ENUM( FeatureRoles )
Expand Down
87 changes: 84 additions & 3 deletions src/core/attributeformmodelbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ QHash<int, QByteArray> AttributeFormModelBase::roleNames() const
roles[AttributeFormModel::ConstraintSoftValid] = "ConstraintSoftValid";
roles[AttributeFormModel::ConstraintDescription] = "ConstraintDescription";
roles[AttributeFormModel::AttributeAllowEdit] = "AttributeAllowEdit";
roles[AttributeFormModel::EditorWidgetCode] = "EditorWidgetCode";

return roles;
}
Expand Down Expand Up @@ -120,6 +121,7 @@ void AttributeFormModelBase::setFeatureModel( FeatureModel *featureModel )

connect( mFeatureModel, &FeatureModel::currentLayerChanged, this, &AttributeFormModelBase::onLayerChanged );
connect( mFeatureModel, &FeatureModel::modelReset, this, &AttributeFormModelBase::onFeatureChanged );
connect( mFeatureModel, &FeatureModel::featureUpdated, this, &AttributeFormModelBase::onFeatureChanged );

emit featureModelChanged();
}
Expand Down Expand Up @@ -239,6 +241,47 @@ void AttributeFormModelBase::updateAttributeValue( QStandardItem *item )
//set item visibility to false in case it's a linked attribute
item->setData( !mFeatureModel->data( mFeatureModel->index( fieldIndex ), FeatureModel::LinkedAttribute ).toBool(), AttributeFormModel::CurrentlyVisible );
}
else if ( item->data( AttributeFormModel::ElementType ) == QStringLiteral( "qml" ) ||
item->data( AttributeFormModel::ElementType ) == QStringLiteral( "html" ) )
{
QString code = mEditorWidgetCodes[item];

QRegularExpression re( "expression\\.evaluate\\(\\s*\\\"(.*?[^\\\\])\\\"\\s*\\)" );
QRegularExpressionMatch match = re.match( code );
while( match.hasMatch() )
{
QString expression = match.captured( 1 );
expression = expression.replace( QStringLiteral( "\\\"" ), QStringLiteral( "\"" ) );

QgsExpressionContext expressionContext = mLayer->createExpressionContext();
expressionContext.setFeature( mFeatureModel->feature() );

QgsExpression exp = QgsExpression( expression );
exp.prepare( &expressionContext );
QVariant result = exp.evaluate( &expressionContext );

QString resultString;
switch( result.type() )
{
case QMetaType::Int:
case QMetaType::UInt:
case QMetaType::Double:
case QMetaType::LongLong:
case QMetaType::ULongLong:
resultString = result.toString();
break;
case QMetaType::Bool:
resultString = result.toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" );
break;
default:
resultString = QStringLiteral( "'%1'" ).arg( result.toString() );
break;
}
code = code.mid( 0, match.capturedStart( 0 ) ) + resultString + code.mid( match.capturedEnd( 0 ) );
match = re.match( code );
}
item->setData( code, AttributeFormModel::EditorWidgetCode );
}
else
{
for ( int i = 0; i < item->rowCount(); ++i )
Expand Down Expand Up @@ -358,11 +401,49 @@ void AttributeFormModelBase::flatten( QgsAttributeEditorContainer *container, QS
break;
}

case QgsAttributeEditorElement::AeTypeInvalid:
// todo
case QgsAttributeEditorElement::AeTypeQmlElement:
{
QgsAttributeEditorQmlElement *qmlElement = static_cast<QgsAttributeEditorQmlElement *>( element );
QStandardItem *item = new QStandardItem();

item->setData( "qml", AttributeFormModel::ElementType );
item->setData( qmlElement->name(), AttributeFormModel::Name );
item->setData( true, AttributeFormModel::CurrentlyVisible );
item->setData( false, AttributeFormModel::AttributeEditable );
item->setData( false, AttributeFormModel::AttributeAllowEdit );
item->setData( container->isGroupBox() ? container->name() : QString(), AttributeFormModel::Group );

mEditorWidgetCodes.insert( item, qmlElement->qmlCode() );

updateAttributeValue( item );

items.append( item );
parent->appendRow( item );
break;
}

case QgsAttributeEditorElement::AeTypeQmlElement:
case QgsAttributeEditorElement::AeTypeHtmlElement:
{
QgsAttributeEditorHtmlElement *htmlElement = static_cast<QgsAttributeEditorHtmlElement *>( element );
QStandardItem *item = new QStandardItem();

item->setData( "html", AttributeFormModel::ElementType );
item->setData( htmlElement->name(), AttributeFormModel::Name );
item->setData( true, AttributeFormModel::CurrentlyVisible );
item->setData( false, AttributeFormModel::AttributeEditable );
item->setData( false, AttributeFormModel::AttributeAllowEdit );
item->setData( container->isGroupBox() ? container->name() : QString(), AttributeFormModel::Group );

mEditorWidgetCodes.insert( item, htmlElement->htmlCode() );

updateAttributeValue( item );

items.append( item );
parent->appendRow( item );
break;
}

case QgsAttributeEditorElement::AeTypeInvalid:
// todo
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/core/attributeformmodelbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class AttributeFormModelBase : public QStandardItemModel
typedef QPair<QgsExpression, QVector<QStandardItem *> > VisibilityExpression;
QList<VisibilityExpression> mVisibilityExpressions;
QMap<QStandardItem *, QgsFieldConstraints> mConstraints;
QMap<QStandardItem *, QString> mEditorWidgetCodes;

QgsExpressionContext mExpressionContext;
bool mConstraintsHardValid = true;
Expand Down
15 changes: 13 additions & 2 deletions src/core/featuremodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ FeatureModel::ModelModes FeatureModel::modelMode() const

void FeatureModel::setFeature( const QgsFeature &feature )
{
if ( mModelMode != SingleFeatureModel || mFeature == feature )
if ( mModelMode != SingleFeatureModel || feature == mFeature )
return;

beginResetModel();
Expand Down Expand Up @@ -341,9 +341,20 @@ bool FeatureModel::save()
{
QgsFeature modifiedFeature;
if ( mLayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeature.id() ) ).nextFeature( modifiedFeature ) )
setFeature( modifiedFeature );
{
if ( modifiedFeature != mFeature )
{
setFeature( modifiedFeature );
}
else
{
emit featureUpdated();
nirvn marked this conversation as resolved.
Show resolved Hide resolved
}
}
else
{
QgsMessageLog::logMessage( tr( "Feature %1 could not be fetched after commit" ).arg( mFeature.id() ), QStringLiteral( "QField" ), Qgis::Warning );
}
}
break;
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/featuremodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,14 @@ class FeatureModel : public QAbstractListModel

signals:
void modelModeChanged();

//! Emitted when the model's feature has been saved (i.e. updated) but not changed as a result
void featureUpdated();
nirvn marked this conversation as resolved.
Show resolved Hide resolved
//! Emitted when the model's single feature has been changed
void featureChanged();
//! Emitted when the model's multi features list has been changed
void featuresChanged();

void linkedParentFeatureChanged();
void linkedRelationChanged();
void vertexModelChanged();
Expand Down
Loading