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

Plugins management UI implementation #5195

Merged
merged 18 commits into from Apr 22, 2024
Merged

Plugins management UI implementation #5195

merged 18 commits into from Apr 22, 2024

Conversation

nirvn
Copy link
Member

@nirvn nirvn commented Apr 18, 2024

(This PR temporarily includes #5189 , that should be reviewed and merged first)

This PR is the last foundational stone to the plugin framework. It implements a basic plugins popup where users can clear their remembered project plugin permissions, as well as install (from a URL) and activate/deactivate app plugins.

Here's an exciting screencast:

vokoscreenNG-2024-04-18_18-29-02.mp4

Plugins pop up when no plugin is present:

Screenshot from 2024-04-19 14-49-25

@nirvn nirvn changed the title Plugins2 Plugins management UI implementation Apr 18, 2024
Layout.margins: 20
visible: pluginsList.model.count === 0

text: qsTr('No plugins have been installed yet. To learn more about plugins, %1read the documentation%2.').arg('<a href="https://docs.qfield.org/">').arg('</a>')
Copy link
Member Author

@nirvn nirvn Apr 18, 2024

Choose a reason for hiding this comment

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

This will be replaced by an actual page on the documentation site I'm finishing drafting tomorrow. It'll introduce the whole concept of app and project plugins, how easy it is to deploy alongside projects on the cloud, etc.

Copy link
Member Author

Choose a reason for hiding this comment

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

Relevant documentation PR here: opengisch/QField-docs#446

@qfield-fairy
Copy link
Collaborator

qfield-fairy commented Apr 18, 2024

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

src/core/pluginmanager.cpp Outdated Show resolved Hide resolved
src/core/pluginmanager.cpp Show resolved Hide resolved
src/core/pluginmanager.cpp Show resolved Hide resolved
src/core/pluginmanager.cpp Show resolved Hide resolved
src/core/pluginmanager.cpp Show resolved Hide resolved
src/core/utils/featureutils.cpp Outdated Show resolved Hide resolved
src/core/utils/layerutils.cpp Outdated Show resolved Hide resolved
src/core/utils/layerutils.h Outdated Show resolved Hide resolved
@@ -26,7 +26,7 @@ TEST_CASE( "FeatureUtils" )

QgsGeometry geometry = QgsGeometry::fromWkt( QStringLiteral( "Polygon (((8 8, 9 8, 8 9, 8 8)))" ) );

QgsFeature f = FeatureUtils::initFeature( vl.get(), geometry );
QgsFeature f = FeatureUtils::createFeature( vl.get(), geometry );
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: variable 'f' of type 'QgsFeature' can be declared 'const' [misc-const-correctness]

Suggested change
QgsFeature f = FeatureUtils::createFeature( vl.get(), geometry );
QgsFeature const f = FeatureUtils::createFeature( vl.get(), geometry );

test/test_featureutils.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

settings.setValue( QStringLiteral( "permissionGranted" ), false );
settings.endGroup();
}

mPermissionRequestPluginPath.clear();
}

void PluginManager::clearPluginPermissions()
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: method 'clearPluginPermissions' can be made static [readability-convert-member-functions-to-static]

src/core/pluginmanager.h:77:

-     Q_INVOKABLE void clearPluginPermissions();
+     Q_INVOKABLE static void clearPluginPermissions();

return mAvailableAppPlugins.contains( uuid ) && mLoadedPlugins.contains( mAvailableAppPlugins[uuid].path() );
}

void PluginManager::installFromUrl( const QString &url )
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: function 'installFromUrl' has cognitive complexity of 43 (threshold 25) [readability-function-cognitive-complexity]

void PluginManager::installFromUrl( const QString &url )
                    ^
Additional context

src/core/pluginmanager.cpp:266: +1, including nesting penalty of 0, nesting level increased to 1

  if ( sanitizedUrl.isEmpty() )
  ^

src/core/pluginmanager.cpp:269: +1, including nesting penalty of 0, nesting level increased to 1

  if ( !sanitizedUrl.contains( QRegularExpression( "^([a-z][a-z0-9+\\-.]*):" ) ) )
  ^

src/core/pluginmanager.cpp:282: nesting level increased to 1

  connect( reply, &QNetworkReply::downloadProgress, this, [=]( int bytesReceived, int bytesTotal ) {
                                                          ^

src/core/pluginmanager.cpp:283: +2, including nesting penalty of 1, nesting level increased to 2

    if ( bytesTotal != 0 )
    ^

src/core/pluginmanager.cpp:289: nesting level increased to 1

  connect( reply, &QNetworkReply::finished, this, [=]() {
                                                  ^

src/core/pluginmanager.cpp:292: +2, including nesting penalty of 1, nesting level increased to 2

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
    ^

src/core/pluginmanager.cpp:292: +1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
                            ^

src/core/pluginmanager.cpp:296: +3, including nesting penalty of 2, nesting level increased to 3

      if ( !contentDisposition.isEmpty() )
      ^

src/core/pluginmanager.cpp:300: +4, including nesting penalty of 3, nesting level increased to 4

        if ( match.hasMatch() )
        ^

src/core/pluginmanager.cpp:308: +3, including nesting penalty of 2, nesting level increased to 3

      if ( fileSuffix == QLatin1String( "zip" ) )
      ^

src/core/pluginmanager.cpp:313: +4, including nesting penalty of 3, nesting level increased to 4

        if ( file.open( QIODevice::WriteOnly ) )
        ^

src/core/pluginmanager.cpp:320: +5, including nesting penalty of 4, nesting level increased to 5

          if ( zipFiles.contains( QStringLiteral( "main.qml" ) ) )
          ^

src/core/pluginmanager.cpp:323: +6, including nesting penalty of 5, nesting level increased to 6

            if ( pluginDirectory.exists() )
            ^

src/core/pluginmanager.cpp:328: +6, including nesting penalty of 5, nesting level increased to 6

            if ( ZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
            ^

src/core/pluginmanager.cpp:337: +1, nesting level increased to 6

            else
            ^

src/core/pluginmanager.cpp:343: +1, nesting level increased to 5

          else
          ^

src/core/pluginmanager.cpp:349: +1, nesting level increased to 4

        else
        ^

src/core/pluginmanager.cpp:354: +1, nesting level increased to 3

      else
      ^

src/core/pluginmanager.cpp:359: +1, nesting level increased to 2

    else
    ^

}
} );

connect( reply, &QNetworkReply::finished, this, [=]() {
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: lambda has cognitive complexity of 31 (threshold 25) [readability-function-cognitive-complexity]

  connect( reply, &QNetworkReply::finished, this, [=]() {
                                                  ^
Additional context

src/core/pluginmanager.cpp:292: +1, including nesting penalty of 0, nesting level increased to 1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
    ^

src/core/pluginmanager.cpp:292: +1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
                            ^

src/core/pluginmanager.cpp:296: +2, including nesting penalty of 1, nesting level increased to 2

      if ( !contentDisposition.isEmpty() )
      ^

src/core/pluginmanager.cpp:300: +3, including nesting penalty of 2, nesting level increased to 3

        if ( match.hasMatch() )
        ^

src/core/pluginmanager.cpp:308: +2, including nesting penalty of 1, nesting level increased to 2

      if ( fileSuffix == QLatin1String( "zip" ) )
      ^

src/core/pluginmanager.cpp:313: +3, including nesting penalty of 2, nesting level increased to 3

        if ( file.open( QIODevice::WriteOnly ) )
        ^

src/core/pluginmanager.cpp:320: +4, including nesting penalty of 3, nesting level increased to 4

          if ( zipFiles.contains( QStringLiteral( "main.qml" ) ) )
          ^

src/core/pluginmanager.cpp:323: +5, including nesting penalty of 4, nesting level increased to 5

            if ( pluginDirectory.exists() )
            ^

src/core/pluginmanager.cpp:328: +5, including nesting penalty of 4, nesting level increased to 5

            if ( ZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
            ^

src/core/pluginmanager.cpp:337: +1, nesting level increased to 5

            else
            ^

src/core/pluginmanager.cpp:343: +1, nesting level increased to 4

          else
          ^

src/core/pluginmanager.cpp:349: +1, nesting level increased to 3

        else
        ^

src/core/pluginmanager.cpp:354: +1, nesting level increased to 2

      else
      ^

src/core/pluginmanager.cpp:359: +1, nesting level increased to 1

    else
    ^


QVariantMap ProjectUtils::mapLayers( QgsProject *project )
{
if ( !project )
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: implicit conversion 'QgsProject *' -> bool [readability-implicit-bool-conversion]

Suggested change
if ( !project )
if ( project == nullptr )

QVariantMap ProjectUtils::mapLayers( QgsProject *project )
{
if ( !project )
return QVariantMap();
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
return QVariantMap();
if ( !project ) {
return QVariantMap();
}

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

f.setGeometry( geometry );
return f;
QgsFeature feature;
QgsAttributeMap attributes;
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: variable 'attributes' of type 'QgsAttributeMap' (aka 'QMap<int, QVariant>') can be declared 'const' [misc-const-correctness]

Suggested change
QgsAttributeMap attributes;
QgsAttributeMap const attributes;

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

@@ -116,14 +142,246 @@ void PluginManager::denyRequestedPluginPermission( bool permanent )
if ( permanent )
{
QSettings settings;
settings.beginGroup( QStringLiteral( "/qfield/plugins/%1" ).arg( mPermissionRequestPluginPath ) );
QString pluginKey = mPermissionRequestPluginPath;
pluginKey.replace( QChar( '/' ), QChar( '_' ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: method 'clearPluginPermissions' can be made static [readability-convert-member-functions-to-static]

src/core/pluginmanager.h:77:

-     Q_INVOKABLE void clearPluginPermissions();
+     Q_INVOKABLE static void clearPluginPermissions();

}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: variable 'pluginsDir' of type 'QDir' can be declared 'const' [misc-const-correctness]

Suggested change
}
QDir const pluginsDir( dataDir += QStringLiteral( "plugins" ) );

{
const QString path = QStringLiteral( "%1/main.qml" ).arg( candidate.absoluteFilePath() );
if ( QFileInfo::exists( path ) )
{
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: variable 'metadata' of type 'QSettings' can be declared 'const' [misc-const-correctness]

Suggested change
{
QSettings const metadata( metadataPath, QSettings::IniFormat );

settings.endGroup();

unloadPlugin( mAvailableAppPlugins[uuid].path() );
}
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: function 'installFromUrl' has cognitive complexity of 43 (threshold 25) [readability-function-cognitive-complexity]

void PluginManager::installFromUrl( const QString &url )
                    ^
Additional context

src/core/pluginmanager.cpp:270: +1, including nesting penalty of 0, nesting level increased to 1

  if ( sanitizedUrl.isEmpty() )
  ^

src/core/pluginmanager.cpp:273: +1, including nesting penalty of 0, nesting level increased to 1

  if ( !sanitizedUrl.contains( QRegularExpression( "^([a-z][a-z0-9+\\-.]*):" ) ) )
  ^

src/core/pluginmanager.cpp:286: nesting level increased to 1

  connect( reply, &QNetworkReply::downloadProgress, this, [=]( int bytesReceived, int bytesTotal ) {
                                                          ^

src/core/pluginmanager.cpp:287: +2, including nesting penalty of 1, nesting level increased to 2

    if ( bytesTotal != 0 )
    ^

src/core/pluginmanager.cpp:293: nesting level increased to 1

  connect( reply, &QNetworkReply::finished, this, [=]() {
                                                  ^

src/core/pluginmanager.cpp:296: +2, including nesting penalty of 1, nesting level increased to 2

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
    ^

src/core/pluginmanager.cpp:296: +1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
                            ^

src/core/pluginmanager.cpp:300: +3, including nesting penalty of 2, nesting level increased to 3

      if ( !contentDisposition.isEmpty() )
      ^

src/core/pluginmanager.cpp:304: +4, including nesting penalty of 3, nesting level increased to 4

        if ( match.hasMatch() )
        ^

src/core/pluginmanager.cpp:312: +3, including nesting penalty of 2, nesting level increased to 3

      if ( fileSuffix == QLatin1String( "zip" ) )
      ^

src/core/pluginmanager.cpp:317: +4, including nesting penalty of 3, nesting level increased to 4

        if ( file.open( QIODevice::WriteOnly ) )
        ^

src/core/pluginmanager.cpp:324: +5, including nesting penalty of 4, nesting level increased to 5

          if ( zipFiles.contains( QStringLiteral( "main.qml" ) ) )
          ^

src/core/pluginmanager.cpp:327: +6, including nesting penalty of 5, nesting level increased to 6

            if ( pluginDirectory.exists() )
            ^

src/core/pluginmanager.cpp:332: +6, including nesting penalty of 5, nesting level increased to 6

            if ( ZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
            ^

src/core/pluginmanager.cpp:341: +1, nesting level increased to 6

            else
            ^

src/core/pluginmanager.cpp:347: +1, nesting level increased to 5

          else
          ^

src/core/pluginmanager.cpp:353: +1, nesting level increased to 4

        else
        ^

src/core/pluginmanager.cpp:358: +1, nesting level increased to 3

      else
      ^

src/core/pluginmanager.cpp:363: +1, nesting level increased to 2

    else
    ^

}
}

bool PluginManager::isAppPluginEnabled( const QString &uuid ) const
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
bool PluginManager::isAppPluginEnabled( const QString &uuid ) const
if ( sanitizedUrl.isEmpty() ) {
return;
}

QRegularExpression rx( QStringLiteral( "filename=\"?([^\";]*)\"?" ) );
QRegularExpressionMatch match = rx.match( contentDisposition );
if ( match.hasMatch() )
{
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: variable 'filePath' of type 'QString' can be declared 'const' [misc-const-correctness]

Suggested change
{
QString const filePath = QStringLiteral( "%1/plugins/%2" ).arg( dataDir, fileName );

}
pluginDirectory.mkpath( "." );
if ( ZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
{
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: do not use 'else' after 'return' [readability-else-after-return]

Suggested change
{
pluginDirectory.removeRecursively();
error = tr( "The downloaded zip file could not be decompressed" );

{
error = tr( "Download file is not an zipped plugin" );
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: variable name 'fi' is too short, expected at least 3 characters [readability-identifier-length]

  const QFileInfo fi( projectPath );
                  ^

else
{
error = tr( "Network error" );
}
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: constness of 'pluginPath' prevents automatic move [performance-no-automatic-move]

    return pluginPath;
           ^


void installTriggered( const QString &name );
void installProgress( double progress );
void installEnded( const QString &uuid = QString(), const QString &error = QString() );

private slots:
void handleWarnings( const QList<QQmlError> &warnings );
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: redundant access specifier has the same accessibility as the previous access specifier [readability-redundant-access-specifiers]

Suggested change
void handleWarnings( const QList<QQmlError> &warnings );
Additional context

src/core/pluginmanager.h:100: previously declared here

  private slots:
  ^

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

settings.setValue( QStringLiteral( "permissionGranted" ), false );
settings.endGroup();
}

mPermissionRequestPluginPath.clear();
}

void PluginManager::clearPluginPermissions()
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: method 'clearPluginPermissions' can be made static [readability-convert-member-functions-to-static]

src/core/pluginmanager.h:79:

-     Q_INVOKABLE void clearPluginPermissions();
+     Q_INVOKABLE static void clearPluginPermissions();

return mAvailableAppPlugins.contains( uuid ) && mLoadedPlugins.contains( mAvailableAppPlugins[uuid].path() );
}

void PluginManager::installFromUrl( const QString &url )
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: function 'installFromUrl' has cognitive complexity of 43 (threshold 25) [readability-function-cognitive-complexity]

void PluginManager::installFromUrl( const QString &url )
                    ^
Additional context

src/core/pluginmanager.cpp:279: +1, including nesting penalty of 0, nesting level increased to 1

  if ( sanitizedUrl.isEmpty() )
  ^

src/core/pluginmanager.cpp:282: +1, including nesting penalty of 0, nesting level increased to 1

  if ( !sanitizedUrl.contains( QRegularExpression( "^([a-z][a-z0-9+\\-.]*):" ) ) )
  ^

src/core/pluginmanager.cpp:295: nesting level increased to 1

  connect( reply, &QNetworkReply::downloadProgress, this, [=]( int bytesReceived, int bytesTotal ) {
                                                          ^

src/core/pluginmanager.cpp:296: +2, including nesting penalty of 1, nesting level increased to 2

    if ( bytesTotal != 0 )
    ^

src/core/pluginmanager.cpp:302: nesting level increased to 1

  connect( reply, &QNetworkReply::finished, this, [=]() {
                                                  ^

src/core/pluginmanager.cpp:305: +2, including nesting penalty of 1, nesting level increased to 2

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
    ^

src/core/pluginmanager.cpp:305: +1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
                            ^

src/core/pluginmanager.cpp:309: +3, including nesting penalty of 2, nesting level increased to 3

      if ( !contentDisposition.isEmpty() )
      ^

src/core/pluginmanager.cpp:313: +4, including nesting penalty of 3, nesting level increased to 4

        if ( match.hasMatch() )
        ^

src/core/pluginmanager.cpp:321: +3, including nesting penalty of 2, nesting level increased to 3

      if ( fileSuffix == QLatin1String( "zip" ) )
      ^

src/core/pluginmanager.cpp:326: +4, including nesting penalty of 3, nesting level increased to 4

        if ( file.open( QIODevice::WriteOnly ) )
        ^

src/core/pluginmanager.cpp:333: +5, including nesting penalty of 4, nesting level increased to 5

          if ( zipFiles.contains( QStringLiteral( "main.qml" ) ) )
          ^

src/core/pluginmanager.cpp:339: +6, including nesting penalty of 5, nesting level increased to 6

            if ( pluginDirectory.exists() )
            ^

src/core/pluginmanager.cpp:344: +6, including nesting penalty of 5, nesting level increased to 6

            if ( ZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
            ^

src/core/pluginmanager.cpp:353: +1, nesting level increased to 6

            else
            ^

src/core/pluginmanager.cpp:359: +1, nesting level increased to 5

          else
          ^

src/core/pluginmanager.cpp:365: +1, nesting level increased to 4

        else
        ^

src/core/pluginmanager.cpp:370: +1, nesting level increased to 3

      else
      ^

src/core/pluginmanager.cpp:375: +1, nesting level increased to 2

    else
    ^

}
} );

connect( reply, &QNetworkReply::finished, this, [=]() {
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: lambda has cognitive complexity of 31 (threshold 25) [readability-function-cognitive-complexity]

  connect( reply, &QNetworkReply::finished, this, [=]() {
                                                  ^
Additional context

src/core/pluginmanager.cpp:305: +1, including nesting penalty of 0, nesting level increased to 1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
    ^

src/core/pluginmanager.cpp:305: +1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
                            ^

src/core/pluginmanager.cpp:309: +2, including nesting penalty of 1, nesting level increased to 2

      if ( !contentDisposition.isEmpty() )
      ^

src/core/pluginmanager.cpp:313: +3, including nesting penalty of 2, nesting level increased to 3

        if ( match.hasMatch() )
        ^

src/core/pluginmanager.cpp:321: +2, including nesting penalty of 1, nesting level increased to 2

      if ( fileSuffix == QLatin1String( "zip" ) )
      ^

src/core/pluginmanager.cpp:326: +3, including nesting penalty of 2, nesting level increased to 3

        if ( file.open( QIODevice::WriteOnly ) )
        ^

src/core/pluginmanager.cpp:333: +4, including nesting penalty of 3, nesting level increased to 4

          if ( zipFiles.contains( QStringLiteral( "main.qml" ) ) )
          ^

src/core/pluginmanager.cpp:339: +5, including nesting penalty of 4, nesting level increased to 5

            if ( pluginDirectory.exists() )
            ^

src/core/pluginmanager.cpp:344: +5, including nesting penalty of 4, nesting level increased to 5

            if ( ZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
            ^

src/core/pluginmanager.cpp:353: +1, nesting level increased to 5

            else
            ^

src/core/pluginmanager.cpp:359: +1, nesting level increased to 4

          else
          ^

src/core/pluginmanager.cpp:365: +1, nesting level increased to 3

        else
        ^

src/core/pluginmanager.cpp:370: +1, nesting level increased to 2

      else
      ^

src/core/pluginmanager.cpp:375: +1, nesting level increased to 1

    else
    ^

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

return mAvailableAppPlugins.contains( uuid ) && mLoadedPlugins.contains( mAvailableAppPlugins[uuid].path() );
}

void PluginManager::installFromUrl( const QString &url )
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: function 'installFromUrl' has cognitive complexity of 43 (threshold 25) [readability-function-cognitive-complexity]

void PluginManager::installFromUrl( const QString &url )
                    ^
Additional context

src/core/pluginmanager.cpp:305: +1, including nesting penalty of 0, nesting level increased to 1

  if ( sanitizedUrl.isEmpty() )
  ^

src/core/pluginmanager.cpp:308: +1, including nesting penalty of 0, nesting level increased to 1

  if ( !sanitizedUrl.contains( QRegularExpression( "^([a-z][a-z0-9+\\-.]*):" ) ) )
  ^

src/core/pluginmanager.cpp:321: nesting level increased to 1

  connect( reply, &QNetworkReply::downloadProgress, this, [=]( int bytesReceived, int bytesTotal ) {
                                                          ^

src/core/pluginmanager.cpp:322: +2, including nesting penalty of 1, nesting level increased to 2

    if ( bytesTotal != 0 )
    ^

src/core/pluginmanager.cpp:328: nesting level increased to 1

  connect( reply, &QNetworkReply::finished, this, [=]() {
                                                  ^

src/core/pluginmanager.cpp:331: +2, including nesting penalty of 1, nesting level increased to 2

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
    ^

src/core/pluginmanager.cpp:331: +1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
                            ^

src/core/pluginmanager.cpp:335: +3, including nesting penalty of 2, nesting level increased to 3

      if ( !contentDisposition.isEmpty() )
      ^

src/core/pluginmanager.cpp:339: +4, including nesting penalty of 3, nesting level increased to 4

        if ( match.hasMatch() )
        ^

src/core/pluginmanager.cpp:347: +3, including nesting penalty of 2, nesting level increased to 3

      if ( fileSuffix == QLatin1String( "zip" ) )
      ^

src/core/pluginmanager.cpp:352: +4, including nesting penalty of 3, nesting level increased to 4

        if ( file.open( QIODevice::WriteOnly ) )
        ^

src/core/pluginmanager.cpp:359: +5, including nesting penalty of 4, nesting level increased to 5

          if ( zipFiles.contains( QStringLiteral( "main.qml" ) ) )
          ^

src/core/pluginmanager.cpp:365: +6, including nesting penalty of 5, nesting level increased to 6

            if ( pluginDirectory.exists() )
            ^

src/core/pluginmanager.cpp:370: +6, including nesting penalty of 5, nesting level increased to 6

            if ( ZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
            ^

src/core/pluginmanager.cpp:379: +1, nesting level increased to 6

            else
            ^

src/core/pluginmanager.cpp:385: +1, nesting level increased to 5

          else
          ^

src/core/pluginmanager.cpp:391: +1, nesting level increased to 4

        else
        ^

src/core/pluginmanager.cpp:396: +1, nesting level increased to 3

      else
      ^

src/core/pluginmanager.cpp:401: +1, nesting level increased to 2

    else
    ^

}
} );

connect( reply, &QNetworkReply::finished, this, [=]() {
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: lambda has cognitive complexity of 31 (threshold 25) [readability-function-cognitive-complexity]

  connect( reply, &QNetworkReply::finished, this, [=]() {
                                                  ^
Additional context

src/core/pluginmanager.cpp:331: +1, including nesting penalty of 0, nesting level increased to 1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
    ^

src/core/pluginmanager.cpp:331: +1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
                            ^

src/core/pluginmanager.cpp:335: +2, including nesting penalty of 1, nesting level increased to 2

      if ( !contentDisposition.isEmpty() )
      ^

src/core/pluginmanager.cpp:339: +3, including nesting penalty of 2, nesting level increased to 3

        if ( match.hasMatch() )
        ^

src/core/pluginmanager.cpp:347: +2, including nesting penalty of 1, nesting level increased to 2

      if ( fileSuffix == QLatin1String( "zip" ) )
      ^

src/core/pluginmanager.cpp:352: +3, including nesting penalty of 2, nesting level increased to 3

        if ( file.open( QIODevice::WriteOnly ) )
        ^

src/core/pluginmanager.cpp:359: +4, including nesting penalty of 3, nesting level increased to 4

          if ( zipFiles.contains( QStringLiteral( "main.qml" ) ) )
          ^

src/core/pluginmanager.cpp:365: +5, including nesting penalty of 4, nesting level increased to 5

            if ( pluginDirectory.exists() )
            ^

src/core/pluginmanager.cpp:370: +5, including nesting penalty of 4, nesting level increased to 5

            if ( ZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
            ^

src/core/pluginmanager.cpp:379: +1, nesting level increased to 5

            else
            ^

src/core/pluginmanager.cpp:385: +1, nesting level increased to 4

          else
          ^

src/core/pluginmanager.cpp:391: +1, nesting level increased to 3

        else
        ^

src/core/pluginmanager.cpp:396: +1, nesting level increased to 2

      else
      ^

src/core/pluginmanager.cpp:401: +1, nesting level increased to 1

    else
    ^

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

// Cloud-served projects come with a _cloud suffix, take that into account
if ( completeBaseName.endsWith( "_cloud" ) )
{
possiblePluginPaths << QStringLiteral( "%1/%2.qml" ).arg( fi.absolutePath(), fi.completeBaseName().mid( 0, completeBaseName.size() - 6 ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: 6 is a magic number; consider replacing it with a named constant [cppcoreguidelines-avoid-magic-numbers]

    possiblePluginPaths << QStringLiteral( "%1/%2.qml" ).arg( fi.absolutePath(), fi.completeBaseName().mid( 0, completeBaseName.size() - 6 ) );
                                                                                                                                         ^

{
possiblePluginPaths << QStringLiteral( "%1/%2.qml" ).arg( fi.absolutePath(), fi.completeBaseName().mid( 0, completeBaseName.size() - 6 ) );
}
for ( QString &possiblePluginPath : possiblePluginPaths )
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: variable 'possiblePluginPath' of type 'QString &' can be declared 'const' [misc-const-correctness]

Suggested change
for ( QString &possiblePluginPath : possiblePluginPaths )
for ( QString const&possiblePluginPath : possiblePluginPaths )

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

return mAvailableAppPlugins.contains( uuid ) && mLoadedPlugins.contains( mAvailableAppPlugins[uuid].path() );
}

void PluginManager::installFromUrl( const QString &url )
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: function 'installFromUrl' has cognitive complexity of 43 (threshold 25) [readability-function-cognitive-complexity]

void PluginManager::installFromUrl( const QString &url )
                    ^
Additional context

src/core/pluginmanager.cpp:305: +1, including nesting penalty of 0, nesting level increased to 1

  if ( sanitizedUrl.isEmpty() )
  ^

src/core/pluginmanager.cpp:308: +1, including nesting penalty of 0, nesting level increased to 1

  if ( !sanitizedUrl.contains( QRegularExpression( "^([a-z][a-z0-9+\\-.]*):" ) ) )
  ^

src/core/pluginmanager.cpp:321: nesting level increased to 1

  connect( reply, &QNetworkReply::downloadProgress, this, [=]( int bytesReceived, int bytesTotal ) {
                                                          ^

src/core/pluginmanager.cpp:322: +2, including nesting penalty of 1, nesting level increased to 2

    if ( bytesTotal != 0 )
    ^

src/core/pluginmanager.cpp:328: nesting level increased to 1

  connect( reply, &QNetworkReply::finished, this, [=]() {
                                                  ^

src/core/pluginmanager.cpp:331: +2, including nesting penalty of 1, nesting level increased to 2

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
    ^

src/core/pluginmanager.cpp:331: +1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
                            ^

src/core/pluginmanager.cpp:335: +3, including nesting penalty of 2, nesting level increased to 3

      if ( !contentDisposition.isEmpty() )
      ^

src/core/pluginmanager.cpp:339: +4, including nesting penalty of 3, nesting level increased to 4

        if ( match.hasMatch() )
        ^

src/core/pluginmanager.cpp:347: +3, including nesting penalty of 2, nesting level increased to 3

      if ( fileSuffix == QLatin1String( "zip" ) )
      ^

src/core/pluginmanager.cpp:352: +4, including nesting penalty of 3, nesting level increased to 4

        if ( file.open( QIODevice::WriteOnly ) )
        ^

src/core/pluginmanager.cpp:359: +5, including nesting penalty of 4, nesting level increased to 5

          if ( zipFiles.contains( QStringLiteral( "main.qml" ) ) )
          ^

src/core/pluginmanager.cpp:365: +6, including nesting penalty of 5, nesting level increased to 6

            if ( pluginDirectory.exists() )
            ^

src/core/pluginmanager.cpp:370: +6, including nesting penalty of 5, nesting level increased to 6

            if ( QgsZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
            ^

src/core/pluginmanager.cpp:379: +1, nesting level increased to 6

            else
            ^

src/core/pluginmanager.cpp:385: +1, nesting level increased to 5

          else
          ^

src/core/pluginmanager.cpp:391: +1, nesting level increased to 4

        else
        ^

src/core/pluginmanager.cpp:396: +1, nesting level increased to 3

      else
      ^

src/core/pluginmanager.cpp:401: +1, nesting level increased to 2

    else
    ^

}
} );

connect( reply, &QNetworkReply::finished, this, [=]() {
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: lambda has cognitive complexity of 31 (threshold 25) [readability-function-cognitive-complexity]

  connect( reply, &QNetworkReply::finished, this, [=]() {
                                                  ^
Additional context

src/core/pluginmanager.cpp:331: +1, including nesting penalty of 0, nesting level increased to 1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
    ^

src/core/pluginmanager.cpp:331: +1

    if ( !dataDir.isEmpty() && reply->error() == QNetworkReply::NoError )
                            ^

src/core/pluginmanager.cpp:335: +2, including nesting penalty of 1, nesting level increased to 2

      if ( !contentDisposition.isEmpty() )
      ^

src/core/pluginmanager.cpp:339: +3, including nesting penalty of 2, nesting level increased to 3

        if ( match.hasMatch() )
        ^

src/core/pluginmanager.cpp:347: +2, including nesting penalty of 1, nesting level increased to 2

      if ( fileSuffix == QLatin1String( "zip" ) )
      ^

src/core/pluginmanager.cpp:352: +3, including nesting penalty of 2, nesting level increased to 3

        if ( file.open( QIODevice::WriteOnly ) )
        ^

src/core/pluginmanager.cpp:359: +4, including nesting penalty of 3, nesting level increased to 4

          if ( zipFiles.contains( QStringLiteral( "main.qml" ) ) )
          ^

src/core/pluginmanager.cpp:365: +5, including nesting penalty of 4, nesting level increased to 5

            if ( pluginDirectory.exists() )
            ^

src/core/pluginmanager.cpp:370: +5, including nesting penalty of 4, nesting level increased to 5

            if ( QgsZipUtils::unzip( filePath, pluginDirectory.absolutePath(), zipFiles, false ) )
            ^

src/core/pluginmanager.cpp:379: +1, nesting level increased to 5

            else
            ^

src/core/pluginmanager.cpp:385: +1, nesting level increased to 4

          else
          ^

src/core/pluginmanager.cpp:391: +1, nesting level increased to 3

        else
        ^

src/core/pluginmanager.cpp:396: +1, nesting level increased to 2

      else
      ^

src/core/pluginmanager.cpp:401: +1, nesting level increased to 1

    else
    ^

Copy link
Member

@domi4484 domi4484 left a comment

Choose a reason for hiding this comment

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

@nirvn I went quickly trough the code and couldn't see anything bad. I could also try out the apk and install the plugin you provided to me.

At the moment we can remove an installed plugin only by hand correct?

@nirvn
Copy link
Member Author

nirvn commented Apr 22, 2024

@domi4484 , correct, no delete yet.

@nirvn nirvn merged commit 3280a63 into master Apr 22, 2024
25 checks passed
@nirvn nirvn deleted the plugins2 branch April 22, 2024 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants