Skip to content

Commit 0e98d1e

Browse files
committedMar 6, 2019
Load projects from storage at start
The check for qgs/qgs was preventing db-stored project to be opened at start when option to re-open last project is on
1 parent 4113505 commit 0e98d1e

6 files changed

+717
-3
lines changed
 

‎src/app/qgisapp.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5643,16 +5643,20 @@ void QgisApp::fileOpenAfterLaunch()
56435643
return;
56445644
}
56455645

5646-
if ( !projPath.endsWith( QLatin1String( ".qgs" ), Qt::CaseInsensitive ) &&
5647-
!projPath.endsWith( QLatin1String( ".qgz" ), Qt::CaseInsensitive ) )
5646+
// Is this a storage based project?
5647+
const bool projectIsFromStorage { QgsApplication::instance()->projectStorageRegistry()->projectStorageFromUri( projPath ) };
5648+
5649+
if ( !( projectIsFromStorage ||
5650+
projPath.endsWith( QLatin1String( ".qgs" ), Qt::CaseInsensitive ) ||
5651+
projPath.endsWith( QLatin1String( ".qgz" ), Qt::CaseInsensitive ) ) )
56485652
{
56495653
visibleMessageBar()->pushMessage( autoOpenMsgTitle,
56505654
tr( "Not valid project file: %1" ).arg( projPath ),
56515655
Qgis::Warning );
56525656
return;
56535657
}
56545658

5655-
if ( QFile::exists( projPath ) )
5659+
if ( projectIsFromStorage || QFile::exists( projPath ) )
56565660
{
56575661
// set flag to check on next app launch if the following project opened OK
56585662
settings.setValue( QStringLiteral( "qgis/projOpenedOKAtLaunch" ), QVariant( false ) );
Lines changed: 383 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,383 @@
1+
/***************************************************************************
2+
qgsgeopackageprojectstorage.cpp
3+
---------------------
4+
begin : March 2019
5+
copyright : (C) 2019 by Alessandro Pasotti
6+
email : elpaso at itopen dot it
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsgeopackageprojectstorage.h"
17+
18+
#include <sqlite3.h>
19+
#include <QUrlQuery>
20+
#include <QUrl>
21+
#include <QIODevice>
22+
#include <QJsonDocument>
23+
#include <QJsonObject>
24+
25+
#include "qgsmessagelog.h"
26+
#include "qgssqliteutils.h"
27+
#include "qgsreadwritecontext.h"
28+
29+
30+
static bool _parseMetadataDocument( const QJsonDocument &doc, QgsProjectStorage::Metadata &metadata )
31+
{
32+
if ( !doc.isObject() )
33+
return false;
34+
35+
QJsonObject docObj = doc.object();
36+
metadata.lastModified = QDateTime();
37+
if ( docObj.contains( "last_modified_time" ) )
38+
{
39+
QString lastModifiedTimeStr = docObj["last_modified_time"].toString();
40+
if ( !lastModifiedTimeStr.isEmpty() )
41+
{
42+
QDateTime lastModifiedUtc = QDateTime::fromString( lastModifiedTimeStr, Qt::ISODate );
43+
lastModifiedUtc.setTimeSpec( Qt::UTC );
44+
metadata.lastModified = lastModifiedUtc.toLocalTime();
45+
}
46+
}
47+
return true;
48+
}
49+
50+
static bool _projectsTableExists( const QString &database )
51+
{
52+
QString errCause;
53+
bool ok { false };
54+
sqlite3_database_unique_ptr db;
55+
sqlite3_statement_unique_ptr statement;
56+
57+
int status = db.open_v2( database, SQLITE_OPEN_READWRITE, nullptr );
58+
if ( status != SQLITE_OK )
59+
{
60+
errCause = QObject::tr( "There was an error opening the database <b>%1</b>: %2" )
61+
.arg( database,
62+
QString::fromUtf8( sqlite3_errmsg( db.get() ) ) );
63+
}
64+
else
65+
{
66+
statement = db.prepare( QStringLiteral( "SELECT count(*) FROM sqlite_master WHERE type ='table' AND name = 'qgis_projects'"), status);
67+
if ( status == SQLITE_OK )
68+
{
69+
if ( sqlite3_step( statement.get() ) == SQLITE_ROW )
70+
{
71+
ok = QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( statement.get(), 0 ) ) ) == '1';
72+
}
73+
else
74+
{
75+
errCause = QObject::tr( "There was an error querying the database <b>%1</b>: %2" )
76+
.arg( database,
77+
QString::fromUtf8( sqlite3_errmsg( db.get() ) ) );
78+
79+
}
80+
}
81+
else
82+
{
83+
errCause = QObject::tr( "There was an error querying the database <b>%1</b>: %2" )
84+
.arg( database,
85+
QString::fromUtf8( sqlite3_errmsg( db.get() ) ) );
86+
87+
}
88+
if ( ! errCause.isEmpty() )
89+
QgsMessageLog::logMessage(errCause, QStringLiteral("OGR"), Qgis::MessageLevel::Info );
90+
}
91+
return ok;
92+
}
93+
94+
95+
QStringList QgsGeoPackageProjectStorage::listProjects(const QString& uri)
96+
{
97+
QStringList lst;
98+
QString errCause;
99+
100+
QgsGeoPackageProjectUri projectUri = decodeUri( uri );
101+
if ( !projectUri.valid || ! _projectsTableExists(projectUri.database ))
102+
return lst;
103+
104+
sqlite3_database_unique_ptr database;
105+
sqlite3_statement_unique_ptr statement;
106+
107+
int status = database.open_v2( projectUri.database, SQLITE_OPEN_READWRITE, nullptr );
108+
if ( status != SQLITE_OK )
109+
{
110+
errCause = QObject::tr( "There was an error opening the database <b>%1</b>: %2" )
111+
.arg( projectUri.database,
112+
QString::fromUtf8( sqlite3_errmsg( database.get() ) ) );
113+
}
114+
else
115+
{
116+
statement = database.prepare( QStringLiteral( "SELECT name FROM qgis_projects"), status );
117+
if ( status == SQLITE_OK )
118+
{
119+
while( sqlite3_step( statement.get() ) == SQLITE_ROW )
120+
{
121+
lst << QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( statement.get(), 0 ) ) );
122+
}
123+
}
124+
else
125+
{
126+
errCause = QObject::tr( "There was an error querying the database <b>%1</b>: %2" )
127+
.arg( projectUri.database,
128+
QString::fromUtf8( sqlite3_errmsg( database.get() ) ) );
129+
}
130+
}
131+
if ( ! errCause.isEmpty() )
132+
QgsMessageLog::logMessage(errCause, QStringLiteral("OGR"), Qgis::MessageLevel::Info );
133+
return lst;
134+
}
135+
136+
bool QgsGeoPackageProjectStorage::readProject(const QString& uri, QIODevice* device, QgsReadWriteContext& context)
137+
{
138+
QgsGeoPackageProjectUri projectUri = decodeUri( uri );
139+
if ( !projectUri.valid )
140+
{
141+
context.pushMessage( QObject::tr( "Invalid URI for GeoPackage OGR provider: " ) + uri, Qgis::Critical );
142+
return false;
143+
}
144+
145+
QString errCause;
146+
QString xml;
147+
bool ok = false;
148+
sqlite3_database_unique_ptr database;
149+
sqlite3_statement_unique_ptr statement;
150+
151+
int status = database.open_v2( projectUri.database, SQLITE_OPEN_READWRITE, nullptr );
152+
if ( status != SQLITE_OK )
153+
{
154+
context.pushMessage( QObject::tr( "Could not connect to the database: " ) + projectUri.database, Qgis::Critical );
155+
return false;
156+
}
157+
else
158+
{
159+
statement = database.prepare( QStringLiteral("SELECT content FROM qgis_projects WHERE name = %1" )
160+
.arg( QgsSqliteUtils::quotedValue( projectUri.projectName ) ), status );
161+
if ( status == SQLITE_OK )
162+
{
163+
if ( sqlite3_step( statement.get() ) == SQLITE_ROW )
164+
{
165+
xml = QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( statement.get(), 0 ) ) );
166+
QString hexEncodedContent( xml );
167+
QByteArray binaryContent( QByteArray::fromHex( hexEncodedContent.toUtf8() ) );
168+
device->write( binaryContent );
169+
device->seek( 0 );
170+
ok = true;
171+
}
172+
else {
173+
errCause = QObject::tr( "There was an error querying the database <b>%1</b>: %2" )
174+
.arg( projectUri.database,
175+
QString::fromUtf8( sqlite3_errmsg( database.get() ) ) );
176+
177+
}
178+
}
179+
else
180+
{
181+
errCause = QObject::tr( "There was an error querying the database <b>%1</b>: %2" )
182+
.arg( projectUri.database,
183+
QString::fromUtf8( sqlite3_errmsg( database.get() ) ) );
184+
}
185+
}
186+
// TODO: do not log if table does not exists
187+
if ( ! errCause.isEmpty() )
188+
QgsMessageLog::logMessage(errCause, QStringLiteral("OGR"), Qgis::MessageLevel::Info );
189+
190+
return ok;
191+
192+
}
193+
194+
bool QgsGeoPackageProjectStorage::writeProject(const QString& uri, QIODevice* device, QgsReadWriteContext& context)
195+
{
196+
QgsGeoPackageProjectUri projectUri = decodeUri( uri );
197+
if ( !projectUri.valid )
198+
{
199+
context.pushMessage( QObject::tr( "Invalid URI for GeoPackage OGR provider: " ) + uri, Qgis::Critical );
200+
return false;
201+
}
202+
203+
sqlite3_database_unique_ptr database;
204+
sqlite3_statement_unique_ptr statement;
205+
206+
int status = database.open_v2( projectUri.database, SQLITE_OPEN_READWRITE, nullptr );
207+
if ( status != SQLITE_OK )
208+
{
209+
context.pushMessage( QObject::tr( "Could not connect to the database: " ) + projectUri.database, Qgis::Critical );
210+
return false;
211+
}
212+
else
213+
{
214+
if ( !_projectsTableExists( projectUri.database ) )
215+
{
216+
char *errmsg = nullptr;
217+
// try to create projects table
218+
( void )sqlite3_exec(
219+
database.get(), /* An open database */
220+
"CREATE TABLE qgis_projects(name TEXT PRIMARY KEY, metadata BLOB, content BLOB)" , /* SQL to be evaluated */
221+
nullptr, /* Callback function */
222+
nullptr, /* 1st argument to callback */
223+
&errmsg /* Error msg written here */
224+
);
225+
if ( status != SQLITE_OK || errmsg )
226+
{
227+
const QString errCause = QObject::tr( "Unable to save project. It's not possible to create the destination table on the database. <b>%1</b>: %2" )
228+
.arg( projectUri.database,
229+
QString::fromUtf8( errmsg ) );
230+
231+
context.pushMessage( errCause, Qgis::Critical );
232+
sqlite3_free( errmsg );
233+
return false;
234+
}
235+
236+
}
237+
238+
239+
// read from device and write to the table
240+
QByteArray content = device->readAll();
241+
242+
QString metadataExpr = QStringLiteral( "{\"last_modified_time\": \"%1\", \"last_modified_user\": \"%2\" }" ).arg(
243+
"2019-01-01",
244+
"username"
245+
);
246+
QString sql;
247+
if ( listProjects( uri ).contains( projectUri.projectName ) )
248+
{
249+
sql = QStringLiteral( "UPDATE qgis_projects SET metadata = %2, content = %3 WHERE name = %1");
250+
}
251+
else
252+
{
253+
sql = QStringLiteral( "INSERT INTO qgis_projects VALUES (%1, %2, %3)");
254+
}
255+
sql = sql.arg( QgsSqliteUtils::quotedIdentifier( projectUri.projectName),
256+
QgsSqliteUtils::quotedValue( metadataExpr ),
257+
QgsSqliteUtils::quotedValue(QString::fromAscii( content.toHex() ))
258+
);
259+
char *errmsg = nullptr;
260+
( void )sqlite3_exec(
261+
database.get(), /* An open database */
262+
sql.toLocal8Bit(), /* SQL to be evaluated */
263+
nullptr, /* Callback function */
264+
nullptr, /* 1st argument to callback */
265+
&errmsg /* Error msg written here */
266+
);
267+
if ( status != SQLITE_OK || errmsg )
268+
{
269+
const QString errCause = QObject::tr( "Unable to insert or update project (project=%1) in the destination table on the database: %2" )
270+
.arg( projectUri.database,
271+
QString::fromUtf8( errmsg ) );
272+
273+
context.pushMessage( errCause, Qgis::Critical );
274+
sqlite3_free( errmsg );
275+
return false;
276+
}
277+
return true;
278+
279+
}
280+
}
281+
282+
QString QgsGeoPackageProjectStorage::encodeUri(const QgsGeoPackageProjectUri& gpkgUri)
283+
{
284+
QUrl u;
285+
QUrlQuery urlQuery;
286+
u.setScheme( QStringLiteral( "geopackage") );
287+
u.setPath( gpkgUri.database );
288+
if ( !gpkgUri.projectName.isEmpty() )
289+
urlQuery.addQueryItem( QStringLiteral("projectName"), gpkgUri.projectName );
290+
u.setQuery( urlQuery );
291+
return QString::fromUtf8( u.toEncoded() );
292+
}
293+
294+
295+
QgsGeoPackageProjectUri QgsGeoPackageProjectStorage::decodeUri(const QString& uri)
296+
{
297+
// TODO check file exists
298+
QUrl url = QUrl::fromEncoded( uri.toUtf8() );
299+
QUrlQuery urlQuery( url.query() );
300+
301+
QgsGeoPackageProjectUri gpkgUri;
302+
gpkgUri.valid = url.isValid();
303+
304+
gpkgUri.database = url.path();
305+
gpkgUri.projectName = urlQuery.queryItemValue( "projectName" );
306+
return gpkgUri;
307+
}
308+
309+
bool QgsGeoPackageProjectStorage::removeProject(const QString& uri)
310+
{
311+
return true;
312+
}
313+
314+
bool QgsGeoPackageProjectStorage::renameProject(const QString& uri, const QString& uriNew)
315+
{
316+
return true;
317+
}
318+
319+
bool QgsGeoPackageProjectStorage::readProjectStorageMetadata(const QString& uri, QgsProjectStorage::Metadata& metadata)
320+
{
321+
QgsGeoPackageProjectUri projectUri = decodeUri( uri );
322+
if ( !projectUri.valid )
323+
return false;
324+
325+
bool ok = false;
326+
327+
sqlite3_database_unique_ptr database;
328+
sqlite3_statement_unique_ptr statement;
329+
330+
int status = database.open_v2( projectUri.database, SQLITE_OPEN_READWRITE, nullptr );
331+
if ( status != SQLITE_OK )
332+
{
333+
return false;
334+
}
335+
else
336+
{
337+
statement = database.prepare( QStringLiteral("SELECT metadata FROM qgis_projects WHERE name = %1" )
338+
.arg( QgsSqliteUtils::quotedValue( projectUri.projectName ) ), status );
339+
340+
if ( status == SQLITE_OK )
341+
{
342+
if ( sqlite3_step( statement.get() ) == SQLITE_ROW )
343+
{
344+
QString metadataStr = QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( statement.get(), 0 ) ) );
345+
metadata.name = projectUri.projectName;
346+
QJsonDocument doc( QJsonDocument::fromJson( metadataStr.toUtf8() ) );
347+
ok = _parseMetadataDocument( doc, metadata );
348+
}
349+
}
350+
}
351+
352+
return ok;
353+
}
354+
355+
356+
#ifdef HAVE_GUI
357+
358+
#include "qgsgeopackageprojectstoragedialog.h"
359+
360+
QString QgsGeoPackageProjectStorage::visibleName()
361+
{
362+
return QObject::tr( "GeoPackage" );
363+
}
364+
365+
QString QgsGeoPackageProjectStorage::showLoadGui()
366+
{
367+
QgsGeoPackageProjectStorageDialog dlg( false );
368+
if ( !dlg.exec() )
369+
return QString();
370+
371+
return dlg.currentProjectUri();
372+
}
373+
374+
QString QgsGeoPackageProjectStorage::showSaveGui()
375+
{
376+
QgsGeoPackageProjectStorageDialog dlg( true );
377+
if ( !dlg.exec() )
378+
return QString();
379+
380+
return dlg.currentProjectUri();
381+
}
382+
383+
#endif
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/***************************************************************************
2+
qgsgeopackageprojectstorage.h
3+
---------------------
4+
begin : March 2019
5+
copyright : (C) 2019 by Alessandro Pasotti
6+
email : elpaso at itopen dot it
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSGEOPACKAGEPROJECTSTORAGE_H
17+
#define QGSGEOPACKAGEPROJECTSTORAGE_H
18+
19+
#include "qgsconfig.h"
20+
#include "qgsprojectstorage.h"
21+
#include "qgsdatasourceuri.h"
22+
23+
//! Stores information parsed from postgres project URI
24+
typedef struct
25+
{
26+
bool valid;
27+
QString database;
28+
QString projectName;
29+
30+
} QgsGeoPackageProjectUri;
31+
32+
33+
class QgsGeoPackageProjectStorage : public QgsProjectStorage
34+
{
35+
public:
36+
37+
// QgsProjectStorage interface
38+
public:
39+
QString type() override { return QStringLiteral( "geopackage" ); }
40+
QStringList listProjects(const QString& uri) override;
41+
bool readProject(const QString& uri, QIODevice* device, QgsReadWriteContext& context) override;
42+
bool writeProject(const QString& uri, QIODevice* device, QgsReadWriteContext& context) override;
43+
bool removeProject(const QString& uri) override;
44+
bool renameProject(const QString& uri, const QString& uriNew) override;
45+
bool readProjectStorageMetadata(const QString& uri, QgsProjectStorage::Metadata& metadata) override;
46+
#ifdef HAVE_GUI
47+
QString visibleName() override;
48+
QString showLoadGui() override;
49+
QString showSaveGui() override;
50+
#endif
51+
static QString encodeUri( const QgsGeoPackageProjectUri &postUri );
52+
static QgsGeoPackageProjectUri decodeUri( const QString &uri );
53+
};
54+
55+
#endif // QGSGEOPACKAGEPROJECTSTORAGE_H
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/***************************************************************************
2+
qgsgeopackageprojectstoragedialog.cpp
3+
---------------------
4+
begin : April 2018
5+
copyright : (C) 2018 by Martin Dobias
6+
email : wonder dot sk at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
#include "qgsgeopackageprojectstoragedialog.h"
16+
#include "qgsgeopackageprojectstorage.h"
17+
#include "qgsapplication.h"
18+
#include "qgsprojectstorage.h"
19+
#include "qgsprojectstorageregistry.h"
20+
#include "qgsogrdbconnection.h"
21+
#include "qgis.h"
22+
23+
#include <QMenu>
24+
#include <QMessageBox>
25+
#include <QPushButton>
26+
27+
QgsGeoPackageProjectStorageDialog::QgsGeoPackageProjectStorageDialog( bool saving, QWidget *parent )
28+
: QDialog( parent )
29+
, mSaving( saving )
30+
{
31+
setupUi( this );
32+
33+
connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsGeoPackageProjectStorageDialog::onOK );
34+
35+
QPushButton *btnManageProjects = new QPushButton( tr( "Manage Projects" ), this );
36+
QMenu *menuManageProjects = new QMenu( btnManageProjects );
37+
mActionRemoveProject = menuManageProjects->addAction( tr( "Remove Project" ) );
38+
connect( mActionRemoveProject, &QAction::triggered, this, &QgsGeoPackageProjectStorageDialog::removeProject );
39+
btnManageProjects->setMenu( menuManageProjects );
40+
buttonBox->addButton( btnManageProjects, QDialogButtonBox::ActionRole );
41+
42+
if ( saving )
43+
{
44+
setWindowTitle( tr( "Save project to GeoPackage" ) );
45+
mCboProject->setEditable( true );
46+
}
47+
else
48+
{
49+
setWindowTitle( tr( "Load project from GeoPackage" ) );
50+
}
51+
52+
// populate connections
53+
mCboConnection->addItems( QgsOgrDbConnection::connectionList( QStringLiteral( "GPKG" ) ) );
54+
55+
// If possible, set the item currently displayed database
56+
QString toSelect = QgsOgrDbConnection::selectedConnection(QStringLiteral( "GPKG" ));
57+
mCboConnection->setCurrentIndex( mCboConnection->findText( toSelect ) );
58+
59+
connect( mCboProject, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGeoPackageProjectStorageDialog::projectChanged );
60+
61+
projectChanged();
62+
}
63+
64+
QString QgsGeoPackageProjectStorageDialog::connectionName() const
65+
{
66+
return mCboConnection->currentText();
67+
}
68+
69+
70+
QString QgsGeoPackageProjectStorageDialog::projectName() const
71+
{
72+
return mCboProject->currentText();
73+
}
74+
75+
76+
void QgsGeoPackageProjectStorageDialog::populateProjects()
77+
{
78+
mCboProject->clear();
79+
80+
QString uri = currentProjectUri();
81+
QgsProjectStorage *storage = QgsApplication::projectStorageRegistry()->projectStorageFromType( QStringLiteral( "geopackage" ) );
82+
Q_ASSERT( storage );
83+
const auto projects { storage->listProjects( uri ) };
84+
for (const auto &projectName: projects )
85+
{
86+
// Set data to true for existing projects
87+
mCboProject->addItem( projectName, true);
88+
}
89+
projectChanged();
90+
}
91+
92+
void QgsGeoPackageProjectStorageDialog::onOK()
93+
{
94+
// check that the fields are filled in
95+
if ( mCboProject->currentText().isEmpty() )
96+
return;
97+
98+
if ( mSaving )
99+
{
100+
// Check if this is an overwrite of an existing project
101+
if ( mCboProject->currentData( ).toBool() )
102+
{
103+
int res = QMessageBox::question( this, tr( "Overwrite project" ),
104+
tr( "A project with the same name already exists. Would you like to overwrite it?" ),
105+
QMessageBox::Yes | QMessageBox::No );
106+
if ( res != QMessageBox::Yes )
107+
return;
108+
}
109+
}
110+
111+
accept();
112+
}
113+
114+
void QgsGeoPackageProjectStorageDialog::projectChanged()
115+
{
116+
mActionRemoveProject->setEnabled( mCboProject->count() != 0 && mCboProject->findText( mCboProject->currentText() ) != -1 );
117+
}
118+
119+
void QgsGeoPackageProjectStorageDialog::removeProject()
120+
{
121+
int res = QMessageBox::question( this, tr( "Remove project" ),
122+
tr( "Do you really want to remove the project \"%1\"?" ).arg( mCboProject->currentText() ),
123+
QMessageBox::Yes | QMessageBox::No );
124+
if ( res != QMessageBox::Yes )
125+
return;
126+
127+
QgsProjectStorage *storage = QgsApplication::projectStorageRegistry()->projectStorageFromType( QStringLiteral( "GeoPackage" ) );
128+
Q_ASSERT( storage );
129+
storage->removeProject( currentProjectUri() );
130+
populateProjects();
131+
}
132+
133+
QString QgsGeoPackageProjectStorageDialog::currentProjectUri( )
134+
{
135+
QgsGeoPackageProjectUri gpkgUri;
136+
// find path in connections
137+
QgsOgrDbConnection conn( mCboConnection->currentText(), QStringLiteral( "GPKG") );
138+
gpkgUri.database = conn.path();
139+
gpkgUri.projectName = mCboProject->currentText();
140+
return QgsGeoPackageProjectStorage::encodeUri( gpkgUri );
141+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/***************************************************************************
2+
qgsgeopackageprojectstoragedialog.h
3+
---------------------
4+
begin : March 2019
5+
copyright : (C) 2019 by Alessandro Pasotti
6+
email : elpaso at itopen dot it
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
#ifndef QGSGEOPACKAGEPROJECTSTORAGEDIALOG_H
16+
#define QGSGEOPACKAGEPROJECTSTORAGEDIALOG_H
17+
18+
#include <QDialog>
19+
20+
#include "ui_qgsgeopackageprojectstoragedialog.h"
21+
22+
23+
class QgsGeoPackageProjectStorageDialog : public QDialog, private Ui::QgsGeoPackageProjectStorageDialog
24+
{
25+
Q_OBJECT
26+
public:
27+
explicit QgsGeoPackageProjectStorageDialog( bool saving, QWidget *parent = nullptr );
28+
29+
QString connectionName() const;
30+
QString schemaName() const;
31+
QString projectName() const;
32+
33+
QString currentProjectUri( );
34+
35+
signals:
36+
37+
private slots:
38+
void populateProjects();
39+
void onOK();
40+
void projectChanged();
41+
void removeProject();
42+
43+
private:
44+
45+
bool mSaving = false; //!< Whether using this dialog for loading or saving a project
46+
QAction *mActionRemoveProject = nullptr;
47+
};
48+
49+
#endif // QGSGEOPACKAGEPROJECTSTORAGEDIALOG_H
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>QgsGeoPackageProjectStorageDialog</class>
4+
<widget class="QDialog" name="QgsGeoPackageProjectStorageDialog">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>552</width>
10+
<height>128</height>
11+
</rect>
12+
</property>
13+
<layout class="QVBoxLayout" name="verticalLayout">
14+
<item>
15+
<layout class="QGridLayout" name="gridLayout">
16+
<item row="1" column="1">
17+
<widget class="QComboBox" name="mCboProject"/>
18+
</item>
19+
<item row="0" column="0">
20+
<widget class="QLabel" name="label">
21+
<property name="text">
22+
<string>Connection</string>
23+
</property>
24+
</widget>
25+
</item>
26+
<item row="1" column="0">
27+
<widget class="QLabel" name="label_3">
28+
<property name="text">
29+
<string>Project</string>
30+
</property>
31+
</widget>
32+
</item>
33+
<item row="0" column="1">
34+
<widget class="QComboBox" name="mCboConnection"/>
35+
</item>
36+
</layout>
37+
</item>
38+
<item>
39+
<spacer name="verticalSpacer">
40+
<property name="orientation">
41+
<enum>Qt::Vertical</enum>
42+
</property>
43+
<property name="sizeHint" stdset="0">
44+
<size>
45+
<width>20</width>
46+
<height>40</height>
47+
</size>
48+
</property>
49+
</spacer>
50+
</item>
51+
<item>
52+
<widget class="QDialogButtonBox" name="buttonBox">
53+
<property name="orientation">
54+
<enum>Qt::Horizontal</enum>
55+
</property>
56+
<property name="standardButtons">
57+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
58+
</property>
59+
</widget>
60+
</item>
61+
</layout>
62+
</widget>
63+
<resources/>
64+
<connections>
65+
<connection>
66+
<sender>buttonBox</sender>
67+
<signal>rejected()</signal>
68+
<receiver>QgsGeoPackageProjectStorageDialog</receiver>
69+
<slot>reject()</slot>
70+
<hints>
71+
<hint type="sourcelabel">
72+
<x>316</x>
73+
<y>260</y>
74+
</hint>
75+
<hint type="destinationlabel">
76+
<x>286</x>
77+
<y>274</y>
78+
</hint>
79+
</hints>
80+
</connection>
81+
</connections>
82+
</ui>

0 commit comments

Comments
 (0)
Please sign in to comment.