QGIS API Documentation  3.27.0-Master (11ef3e5184)
qgsdatabasetablemodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdatabasetablemodel.cpp
3  ------------------------
4  Date : March 2020
5  Copyright : (C) 2020 Nyall Dawson
6  Email : nyall dot dawson 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 "qgsdatabasetablemodel.h"
16 #include "qgsproviderregistry.h"
17 #include "qgsprovidermetadata.h"
19 #include "qgsiconutils.h"
20 #include <QIcon>
21 
22 QgsDatabaseTableModel::QgsDatabaseTableModel( const QString &provider, const QString &connection, const QString &schema, QObject *parent )
23  : QAbstractItemModel( parent )
24  , mSchema( schema )
25 {
27  Q_ASSERT( metadata );
28 
29  mConnection.reset( dynamic_cast<QgsAbstractDatabaseProviderConnection *>( metadata->createConnection( connection ) ) );
30  Q_ASSERT( mConnection );
31  init();
32 }
33 
34 QgsDatabaseTableModel::QgsDatabaseTableModel( QgsAbstractDatabaseProviderConnection *connection, const QString &schema, QObject *parent )
35  : QAbstractItemModel( parent )
36  , mConnection( connection )
37  , mSchema( schema )
38 {
39  Q_ASSERT( mConnection );
40  init();
41 }
42 
43 void QgsDatabaseTableModel::init()
44 {
45  Q_ASSERT( mConnection->capabilities() & QgsAbstractDatabaseProviderConnection::Capability::Tables );
46  mTables = mConnection->tables( mSchema );
47 }
48 
49 QModelIndex QgsDatabaseTableModel::parent( const QModelIndex &child ) const
50 {
51  Q_UNUSED( child )
52  return QModelIndex();
53 }
54 
55 
56 int QgsDatabaseTableModel::rowCount( const QModelIndex &parent ) const
57 {
58  if ( parent.isValid() )
59  return 0;
60 
61  return mTables.count() + ( mAllowEmpty ? 1 : 0 );
62 }
63 
64 int QgsDatabaseTableModel::columnCount( const QModelIndex &parent ) const
65 {
66  Q_UNUSED( parent )
67  return 1;
68 }
69 
70 
71 QVariant QgsDatabaseTableModel::data( const QModelIndex &index, int role ) const
72 {
73  if ( !index.isValid() )
74  return QVariant();
75 
76  if ( index.row() == 0 && mAllowEmpty )
77  {
78  if ( role == RoleEmpty )
79  return true;
80 
81  return QVariant();
82  }
83 
84  if ( index.row() - ( mAllowEmpty ? 1 : 0 ) >= mTables.count() )
85  return QVariant();
86 
87  const QgsAbstractDatabaseProviderConnection::TableProperty &table = mTables[ index.row() - ( mAllowEmpty ? 1 : 0 ) ];
88  switch ( role )
89  {
90  case RoleEmpty:
91  return false;
92 
93  case Qt::DisplayRole:
94  case Qt::ToolTipRole:
95  case Qt::EditRole:
96  {
97  return mSchema.isEmpty() && !table.schema().isEmpty() ? QStringLiteral( "%1.%2" ).arg( table.schema(), table.tableName() ) : table.tableName();
98  }
99 
100  case RoleTableName:
101  {
102  return table.tableName();
103  }
104 
105  case Qt::DecorationRole:
106  case RoleWkbType:
107  case RoleCrs:
108  {
109  if ( table.geometryColumnTypes().empty() )
110  {
111  if ( role == Qt::DecorationRole )
112  return QgsIconUtils::iconTable();
113  else
114  return QVariant();
115  }
116 
117  if ( role == Qt::DecorationRole )
118  {
119  const QgsWkbTypes::GeometryType geomType = QgsWkbTypes::geometryType( table.geometryColumnTypes().at( 0 ).wkbType );
120  switch ( geomType )
121  {
123  {
124  return QgsIconUtils::iconPoint();
125  }
127  {
128  return QgsIconUtils::iconPolygon();
129  }
131  {
132  return QgsIconUtils::iconLine();
133  }
135  {
137  }
139  return QgsIconUtils::iconTable();
140  }
141 
142  return QgsIconUtils::iconTable();
143  }
144  else if ( role == RoleWkbType )
145  return table.geometryColumnTypes().at( 0 ).wkbType;
146  else if ( role == RoleCrs )
147  return table.geometryColumnTypes().at( 0 ).crs;
148 
149  return QVariant();
150  }
151 
152  case RoleSchema:
153  return table.schema();
154 
155  case RoleTableFlags:
156  return static_cast< int >( table.flags() );
157 
158  case RoleComment:
159  return table.comment();
160 
161  case RoleCustomInfo:
162  return table.info();
163 
164  }
165 
166  return QVariant();
167 }
168 
169 QModelIndex QgsDatabaseTableModel::index( int row, int column, const QModelIndex &parent ) const
170 {
171  if ( hasIndex( row, column, parent ) )
172  {
173  return createIndex( row, column, row );
174  }
175 
176  return QModelIndex();
177 }
178 
180 {
181  if ( allowEmpty == mAllowEmpty )
182  return;
183 
184  if ( allowEmpty )
185  {
186  beginInsertRows( QModelIndex(), 0, 0 );
187  mAllowEmpty = true;
188  endInsertRows();
189  }
190  else
191  {
192  beginRemoveRows( QModelIndex(), 0, 0 );
193  mAllowEmpty = false;
194  endRemoveRows();
195  }
196 }
197 
199 {
200  const QList< QgsAbstractDatabaseProviderConnection::TableProperty > newTables = mConnection->tables( mSchema );
201  const QList< QgsAbstractDatabaseProviderConnection::TableProperty > oldTables = mTables;
202 
203  for ( const QgsAbstractDatabaseProviderConnection::TableProperty &oldTable : oldTables )
204  {
205  if ( !newTables.contains( oldTable ) )
206  {
207  const int r = mTables.indexOf( oldTable );
208  beginRemoveRows( QModelIndex(), r + ( mAllowEmpty ? 1 : 0 ), r + ( mAllowEmpty ? 1 : 0 ) );
209  mTables.removeAt( r );
210  endRemoveRows();
211  }
212  }
213 
214  for ( const QgsAbstractDatabaseProviderConnection::TableProperty &newTable : newTables )
215  {
216  if ( !mTables.contains( newTable ) )
217  {
218  beginInsertRows( QModelIndex(), mTables.count() + ( mAllowEmpty ? 1 : 0 ), mTables.count() + ( mAllowEmpty ? 1 : 0 ) );
219  mTables.append( newTable );
220  endInsertRows();
221  }
222  }
223 }
The QgsAbstractDatabaseProviderConnection class provides common functionality for DB based connection...
QgsDatabaseTableModel(const QString &provider, const QString &connection, const QString &schema=QString(), QObject *parent=nullptr)
Constructor for QgsDatabaseTableModel, for the specified provider and connection name.
QModelIndex parent(const QModelIndex &child) const override
void refresh()
Refreshes the table list by querying the underlying connection.
QModelIndex index(int row, int column, const QModelIndex &parent) const override
void setAllowEmptyTable(bool allowEmpty)
Sets whether an optional empty table ("not set") option is present in the model.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
@ RoleWkbType
WKB type for primary (first) geometry column in table.
@ RoleEmpty
Entry is an empty entry.
@ RoleCrs
CRS for primary (first) geometry column in table.
@ RoleCustomInfo
Custom info variant map role.
@ RoleTableFlags
Table flags role.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
static QIcon iconLine()
Returns an icon representing line geometries.
static QIcon iconPolygon()
Returns an icon representing polygon geometries.
static QIcon iconGeometryCollection()
Returns an icon representing geometry collections.
static QIcon iconPoint()
Returns an icon representing point geometries.
static QIcon iconTable()
Returns an icon representing non-spatial layers (tables).
Holds data provider key, description, and associated shared library file or function pointer informat...
virtual QgsAbstractProviderConnection * createConnection(const QString &uri, const QVariantMap &configuration) SIP_THROW(QgsProviderConnectionException)
Creates a new connection from uri and configuration, the newly created connection is not automaticall...
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:968
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
The TableProperty class represents a database table or view.
QList< QgsAbstractDatabaseProviderConnection::TableProperty::GeometryColumnType > geometryColumnTypes() const
Returns the list of geometry column types and CRSs.
QVariantMap info() const
Returns additional information about the table.
QString schema() const
Returns the schema or an empty string for backends that do not support a schema.