Skip to content

Commit

Permalink
Merge branch 'master' into qt66
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterPetrik authored Nov 30, 2023
2 parents 2accf76 + 67820e8 commit 5a300d1
Show file tree
Hide file tree
Showing 60 changed files with 2,355 additions and 383 deletions.
2 changes: 2 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ set(MM_SRCS
autosynccontroller.cpp
bluetoothdiscoverymodel.cpp
qrcodedecoder.cpp
changelogmodel.cpp
compass.cpp
featurelayerpair.cpp
featuresmodel.cpp
Expand Down Expand Up @@ -127,6 +128,7 @@ set(MM_HDRS
autosynccontroller.h
bluetoothdiscoverymodel.h
qrcodedecoder.h
changelogmodel.h
compass.h
enumhelper.h
featurelayerpair.h
Expand Down
125 changes: 125 additions & 0 deletions app/changelogmodel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/***************************************************************************
* *
* 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 "changelogmodel.h"
#include <QNetworkReply>
#include <QXmlStreamReader>
#include <QDebug>
#include "coreutils.h"
#include "inputhelp.h"

ChangelogModel::ChangelogModel( QObject *parent ) : QAbstractListModel{parent}
{
mNetworkManager = new QNetworkAccessManager( this );
connect( mNetworkManager, &QNetworkAccessManager::finished, this, &ChangelogModel::onFinished );
}

void ChangelogModel::onFinished( QNetworkReply *reply )
{
if ( reply->error() == QNetworkReply::NoError )
{
QXmlStreamReader xml( reply );
QString title, description, link, pubDate;
while ( !xml.atEnd() )
{
xml.readNext();
if ( xml.isStartElement() )
{
if ( xml.name().toString() == QStringLiteral( "item" ) )
{
title.clear();
description.clear();
link.clear();
pubDate.clear();
}
else if ( xml.name().toString() == QStringLiteral( "title" ) )
{
title = xml.readElementText();
}
else if ( xml.name().toString() == QStringLiteral( "description" ) )
{
description = xml.readElementText();
}
else if ( xml.name().toString() == QStringLiteral( "link" ) )
{
link = xml.readElementText();
}
else if ( xml.name().toString() == QStringLiteral( "pubDate" ) )
{
pubDate = xml.readElementText();
}
}
else if ( xml.isEndElement() )
{
if ( xml.name().toString() == "item" )
{
const QDateTime &dt = QDateTime::fromString( pubDate, "ddd, dd MMM yyyy hh:mm:ss t" );
beginInsertRows( QModelIndex(), rowCount(), rowCount() );
mLogs << Changelog{ title, description, link, dt };
endInsertRows();
}
}
}
if ( xml.hasError() )
{
CoreUtils::log( QStringLiteral( "Changelog" ), QStringLiteral( "Failed to parse changelog. Xml parse error: " ).arg( xml.errorString() ) );
}
}
else
{
CoreUtils::log( QStringLiteral( "Changelog" ), QStringLiteral( "Failed to get changelog. Server Error: %1" ).arg( reply->errorString() ) );
emit errorMsgChanged( reply->errorString() );
}
reply->deleteLater();

if ( !mLogs.isEmpty() )
{
emit dataChanged( createIndex( 0, 0 ), createIndex( rowCount(), 0 ) );
}
}

QHash<int, QByteArray> ChangelogModel::roleNames() const
{
return
{
{ TitleRole, "title" },
{ DescriptionRole, "description" },
{ LinkRole, "link" },
{ DateRole, "date" }
};
}

int ChangelogModel::rowCount( const QModelIndex &parent ) const
{
Q_UNUSED( parent )
return mLogs.size();
}

QVariant ChangelogModel::data( const QModelIndex &index, int role ) const
{
if ( !hasIndex( index.row(), index.column(), index.parent() ) )
return {};

Changelog log = mLogs.at( index.row() );
if ( role == TitleRole ) return log.title;
if ( role == DescriptionRole ) return log.descriptionWithoutImages();
if ( role == LinkRole ) return log.link;
if ( role == DateRole ) return log.date;

return {};
}

// fill the dialog
void ChangelogModel::seeChangelogs()
{
beginResetModel();
mLogs.clear();
endResetModel();
mNetworkManager->get( QNetworkRequest( QUrl( InputHelp::changelogLink() ) ) );
}
59 changes: 59 additions & 0 deletions app/changelogmodel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/***************************************************************************
* *
* 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 CHANGELOGMODEL_H
#define CHANGELOGMODEL_H

#include "QNetworkAccessManager"
#include <QAbstractListModel>
#include <QDate>
#include <QRegularExpression>

struct Changelog
{
QString title;
QString description;
QString link;
QDateTime date;

QString descriptionWithoutImages() { return description.replace( QRegularExpression( "<img .*?>" ), "" ); };
};

class ChangelogModel : public QAbstractListModel
{
Q_OBJECT
Q_ENUMS( MyRoles )

public:
enum MyRoles
{
TitleRole = Qt::UserRole + 1, DescriptionRole, LinkRole, DateRole
};

ChangelogModel( QObject *parent = nullptr );

QHash<int, QByteArray> roleNames() const override;
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;

Q_INVOKABLE void seeChangelogs();

private slots:
void onFinished( QNetworkReply *reply );

signals:
void finished( const QString &title, const QString &link );
void errorMsgChanged( const QString &msg );

private:
QList<Changelog> mLogs;
QNetworkAccessManager *mNetworkManager;
};

#endif // CHANGELOGMODEL_H
4 changes: 4 additions & 0 deletions app/icons/Close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions app/icons/Delete.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions app/icons/Done.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/icons/Edit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions app/icons/More.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions app/icons/Waiting.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions app/icons/icons.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,11 @@
<file>CloseButton.svg</file>
<file>UploadImage.svg</file>
<file>ReachedDataLimitImage.svg</file>
<file>Close.svg</file>
<file>Waiting.svg</file>
<file>Delete.svg</file>
<file>Done.svg</file>
<file>Edit.svg</file>
<file>More.svg</file>
</qresource>
</RCC>
7 changes: 7 additions & 0 deletions app/inputhelp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const QString helpRoot = QStringLiteral( "https://merginmaps.com/docs" );
const QString reportLogUrl = QStringLiteral( "https://g4pfq226j0.execute-api.eu-west-1.amazonaws.com/mergin_client_log_submit" );
const QString helpDeskMail = QStringLiteral( "support@merginmaps.com" );
const QString inputWeb = QStringLiteral( "https://merginmaps.com" );
const QString changelogRss = QStringLiteral( "https://wishlist.merginmaps.com/rss/changelog.xml" );

const QString utmTagHelp = QStringLiteral( "?utm_source=input-help&utm_medium=help&utm_campaign=input" );
const QString utmTagSubscription = QStringLiteral( "?utm_source=input-subs&utm_medium=subs&utm_campaign=input" );
Expand Down Expand Up @@ -164,6 +165,11 @@ QString InputHelp::whatsNewPostLink() const
return inputWeb + "/blog/introducing-workspaces-simplified-collaboration" + utmTagOther;
}

QString InputHelp::changelogLink()
{
return changelogRss;
}

QString InputHelp::migrationGuides() const
{
return helpRoot + "/dev/ce-migration/" + utmTagHelp;
Expand Down Expand Up @@ -218,6 +224,7 @@ QVector<QString> InputHelp::logHeader( bool isHtml )
{
QVector<QString> retLines;
retLines.push_back( QStringLiteral( "Input App: %1 - %2 (%3)" ).arg( CoreUtils::appVersion() ).arg( InputUtils::appPlatform() ).arg( CoreUtils::appVersionCode() ) );
retLines.push_back( QStringLiteral( "Data Dir: %1" ).arg( InputUtils::appDataDir() ) );
retLines.push_back( QStringLiteral( "System: %1" ).arg( QSysInfo::prettyProductName() ) );
retLines.push_back( QStringLiteral( "Mergin URL: %1" ).arg( mMerginApi->apiRoot() ) );
retLines.push_back( QStringLiteral( "Mergin User: %1" ).arg( mMerginApi->userAuth()->username() ) );
Expand Down
1 change: 1 addition & 0 deletions app/inputhelp.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class InputHelp: public QObject
QString merginTermsLink() const;
QString projectLoadingErrorHelpLink() const;
QString whatsNewPostLink() const;
static QString changelogLink();
QString migrationGuides() const;

bool submitReportPending() const;
Expand Down
6 changes: 6 additions & 0 deletions app/inpututils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,12 @@ bool InputUtils::isMobilePlatform()
return platform == QStringLiteral( "android" ) || platform == QStringLiteral( "ios" );
}

QString InputUtils::appDataDir()
{
QString dataDir = QString::fromLocal8Bit( qgetenv( "QGIS_QUICK_DATA_PATH" ) ) ;
return dataDir;
}

void InputUtils::onQgsLogMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level )
{
QString levelStr;
Expand Down
2 changes: 2 additions & 0 deletions app/inpututils.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ class InputUtils: public QObject
static QString appPlatform();
static bool isMobilePlatform();

static QString appDataDir();

/**
* Converts string in rational number format to double.
* @param rationalValue String - expecting value in format "numerator/denominator" (e.g "123/100").
Expand Down
19 changes: 18 additions & 1 deletion app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
#include "workspacesproxymodel.h"
#include "invitationsmodel.h"
#include "invitationsproxymodel.h"
#include "changelogmodel.h"

#include "streamingintervaltype.h"

Expand Down Expand Up @@ -250,6 +251,16 @@ static void init_qgis( const QString &pkgPath )
qDebug( "qgis providers:\n%s", QgsProviderRegistry::instance()->pluginList().toLatin1().data() );
}

static void init_pg( const QString &dataDir )
{
QFileInfo pgFile( QStringLiteral( "%1/pg_service.conf" ).arg( dataDir ) );
if ( pgFile.exists() && pgFile.isReadable() )
{
qputenv( "PGSYSCONFDIR", dataDir.toUtf8() );
CoreUtils::log( QStringLiteral( "PostgreSQL" ), QStringLiteral( "found pg_service.conf, setting PGSYSCONFDIR" ) );
}
}

void initDeclarative()
{
qmlRegisterUncreatableType<MerginUserAuth>( "lc", 1, 0, "MerginUserAuth", "" );
Expand Down Expand Up @@ -279,6 +290,7 @@ void initDeclarative()
qmlRegisterType<WorkspacesProxyModel>( "lc", 1, 0, "WorkspacesProxyModel" );
qmlRegisterType<InvitationsModel>( "lc", 1, 0, "InvitationsModel" );
qmlRegisterType<InvitationsProxyModel>( "lc", 1, 0, "InvitationsProxyModel" );
qmlRegisterType<ChangelogModel>( "lc", 1, 0, "ChangelogModel" );
qmlRegisterUncreatableType<AttributePreviewModel>( "lc", 1, 0, "AttributePreviewModel", "" );
qmlRegisterUncreatableMetaObject( ProjectStatus::staticMetaObject, "lc", 1, 0, "ProjectStatus", "ProjectStatus Enum" );
qRegisterMetaType< FeatureLayerPair >( "FeatureLayerPair" );
Expand Down Expand Up @@ -393,7 +405,7 @@ int main( int argc, char *argv[] )
tests.parseArgs( argc, argv );
#endif
qDebug() << "Mergin Maps Input App" << version << InputUtils::appPlatform() << "(" << CoreUtils::appVersionCode() << ")";
qDebug() << "Built with QGIS version " << VERSION_INT;
qDebug() << "Built with QGIS " << VERSION_INT << " and QT " << qVersion();

// Set/Get enviroment
QString dataDir = getDataDir();
Expand All @@ -413,6 +425,8 @@ int main( int argc, char *argv[] )
}

CoreUtils::setLogFilename( projectDir + "/.logs" );
CoreUtils::log( QStringLiteral( "Input" ), QStringLiteral( "Application has started: %1 (%2)" ).arg( version ).arg( CoreUtils::appVersionCode() ) );

setEnvironmentQgisPrefixPath();

// Initialize translations
Expand Down Expand Up @@ -451,6 +465,9 @@ int main( int argc, char *argv[] )
#endif
InputProjUtils inputProjUtils;
inputProjUtils.initProjLib( appBundleDir, dataDir, projectDir );

init_pg( dataDir );

init_qgis( appBundleDir );

// AppSettings has to be initialized after QGIS app init (because of correct reading/writing QSettings).
Expand Down
Loading

1 comment on commit 5a300d1

@inputapp-bot
Copy link
Collaborator

Choose a reason for hiding this comment

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

iOS - version 23.11.490611 just submitted!

Please sign in to comment.