1 /***************************************************************************
2                          qgspointcloudsourceselect.cpp
3                          --------------------
4     begin                : October 2020
5     copyright            : (C) 2020 by Peter Petrik
6     email                : zilolv at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include <QMessageBox>
19 
20 #include "qgspointcloudsourceselect.h"
21 #include "qgsproviderregistry.h"
22 #include "qgsprovidermetadata.h"
23 
24 ///@cond PRIVATE
25 
QgsPointCloudSourceSelect(QWidget * parent,Qt::WindowFlags fl,QgsProviderRegistry::WidgetMode widgetMode)26 QgsPointCloudSourceSelect::QgsPointCloudSourceSelect( QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode widgetMode ):
27   QgsAbstractDataSourceWidget( parent, fl, widgetMode )
28 {
29   setupUi( this );
30   setupButtons( buttonBox );
31 
32   connect( mRadioSrcFile, &QRadioButton::toggled, this, &QgsPointCloudSourceSelect::radioSrcFile_toggled );
33   connect( mRadioSrcProtocol, &QRadioButton::toggled, this, &QgsPointCloudSourceSelect::radioSrcProtocol_toggled );
34   connect( cmbProtocolTypes, &QComboBox::currentTextChanged, this, &QgsPointCloudSourceSelect::cmbProtocolTypes_currentIndexChanged );
35 
36   radioSrcFile_toggled( true );
37   setProtocolWidgetsVisibility();
38 
39   mFileWidget->setDialogTitle( tr( "Open Point Cloud Dataset" ) );
40   mFileWidget->setFilter( QgsProviderRegistry::instance()->filePointCloudFilters() );
41   mFileWidget->setStorageMode( QgsFileWidget::GetMultipleFiles );
42   connect( mFileWidget, &QgsFileWidget::fileChanged, this, [ = ]( const QString & path )
43   {
44     mPath = path;
45     emit enableButtons( ! mPath.isEmpty() );
46   } );
47 
48   connect( protocolURI, &QLineEdit::textChanged, this, [ = ]( const QString & path )
49   {
50     mPath = path;
51     emit enableButtons( ! mPath.isEmpty() );
52   } );
53 
54 
55   const QStringList protocolTypes = QStringLiteral( "HTTP/HTTPS/FTP,vsicurl" ).split( ';' );
56   for ( int i = 0; i < protocolTypes.count(); i++ )
57   {
58     const QString protocolType = protocolTypes.at( i );
59     if ( ( !protocolType.isEmpty() ) && ( !protocolType.isNull() ) )
60       cmbProtocolTypes->addItem( protocolType.split( ',' ).at( 0 ) );
61   }
62 }
63 
addButtonClicked()64 void QgsPointCloudSourceSelect::addButtonClicked()
65 {
66   if ( mDataSourceType == QLatin1String( "file" ) )
67   {
68     if ( mPath.isEmpty() )
69     {
70       QMessageBox::information( this,
71                                 tr( "Add Point Cloud Layers" ),
72                                 tr( "No layers selected." ) );
73       return;
74     }
75 
76     for ( const QString &path : QgsFileWidget::splitFilePaths( mPath ) )
77     {
78       // auto determine preferred provider for each path
79 
80       const QList< QgsProviderRegistry::ProviderCandidateDetails > preferredProviders = QgsProviderRegistry::instance()->preferredProvidersForUri( mPath );
81       // maybe we should raise an assert if preferredProviders size is 0 or >1? Play it safe for now...
82       if ( preferredProviders.empty() )
83         continue;
84       emit addPointCloudLayer( path, QFileInfo( path ).baseName(), preferredProviders.at( 0 ).metadata()->key() ) ;
85     }
86   }
87   else if ( mDataSourceType == QLatin1String( "remote" ) )
88   {
89     if ( mPath.isEmpty() )
90     {
91       QMessageBox::information( this,
92                                 tr( "Add Point Cloud Layers" ),
93                                 tr( "No layers selected." ) );
94       return;
95     }
96 
97     if ( !mPath.endsWith( QLatin1String( "/ept.json" ) ) )
98     {
99       QMessageBox::information( this,
100                                 tr( "Add Point Cloud Layers" ),
101                                 tr( "Unvalid point cloud URL \"%1\", please make sure your URL ends with /ept.json" ).arg( mPath ) );
102       return;
103     }
104 
105     // auto determine preferred provider for each path
106     const QList< QgsProviderRegistry::ProviderCandidateDetails > preferredProviders = QgsProviderRegistry::instance()->preferredProvidersForUri( mPath );
107     // maybe we should raise an assert if preferredProviders size is 0 or >1? Play it safe for now...
108     if ( !preferredProviders.empty() )
109     {
110       QString baseName = QStringLiteral( "remote ept layer" );
111       QStringList separatedPath = mPath.split( '/' );
112       if ( separatedPath.size() >= 2 )
113         baseName = separatedPath[ separatedPath.size() - 2 ];
114       emit addPointCloudLayer( mPath, baseName, preferredProviders.at( 0 ).metadata()->key() ) ;
115     }
116   }
117 }
118 
radioSrcFile_toggled(bool checked)119 void QgsPointCloudSourceSelect::radioSrcFile_toggled( bool checked )
120 {
121   if ( checked )
122   {
123     fileGroupBox->show();
124     protocolGroupBox->hide();
125 
126     mFileWidget->setDialogTitle( tr( "Open Point Cloud Dataset" ) );
127     mFileWidget->setFilter( QgsProviderRegistry::instance()->filePointCloudFilters() );
128     mFileWidget->setStorageMode( QgsFileWidget::GetMultipleFiles );
129 
130     mDataSourceType = QStringLiteral( "file" );
131 
132     emit enableButtons( ! mFileWidget->filePath().isEmpty() );
133   }
134 }
135 
radioSrcProtocol_toggled(bool checked)136 void QgsPointCloudSourceSelect::radioSrcProtocol_toggled( bool checked )
137 {
138   if ( checked )
139   {
140     fileGroupBox->hide();
141     protocolGroupBox->show();
142 
143     mDataSourceType = QStringLiteral( "remote" );
144 
145     setProtocolWidgetsVisibility();
146 
147     emit enableButtons( ! protocolURI->text().isEmpty() );
148   }
149 }
150 
cmbProtocolTypes_currentIndexChanged(const QString & text)151 void QgsPointCloudSourceSelect::cmbProtocolTypes_currentIndexChanged( const QString &text )
152 {
153   Q_UNUSED( text )
154   setProtocolWidgetsVisibility();
155 }
156 
setProtocolWidgetsVisibility()157 void QgsPointCloudSourceSelect::setProtocolWidgetsVisibility()
158 {
159   labelProtocolURI->show();
160   protocolURI->show();
161   mAuthGroupBox->show();
162   labelBucket->hide();
163   mBucket->hide();
164   labelKey->hide();
165   mKey->hide();
166   mAuthWarning->hide();
167 }
168 
169 ///@endcond
170