QGIS API Documentation  3.20.0-Odense (decaadbb31)
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  }
134  default:
135  break;
136  }
137 
138  return QgsIconUtils::iconTable();
139  }
140  else if ( role == RoleWkbType )
141  return table.geometryColumnTypes().at( 0 ).wkbType;
142  else if ( role == RoleCrs )
143  return table.geometryColumnTypes().at( 0 ).crs;
144 
145  return QVariant();
146  }
147 
148  case RoleSchema:
149  return table.schema();
150 
151  case RoleTableFlags:
152  return static_cast< int >( table.flags() );
153 
154  case RoleComment:
155  return table.comment();
156 
157  case RoleCustomInfo:
158  return table.info();
159 
160  }
161 
162  return QVariant();
163 }
164 
165 QModelIndex QgsDatabaseTableModel::index( int row, int column, const QModelIndex &parent ) const
166 {
167  if ( hasIndex( row, column, parent ) )
168  {
169  return createIndex( row, column, row );
170  }
171 
172  return QModelIndex();
173 }
174 
176 {
177  if ( allowEmpty == mAllowEmpty )
178  return;
179 
180  if ( allowEmpty )
181  {
182  beginInsertRows( QModelIndex(), 0, 0 );
183  mAllowEmpty = true;
184  endInsertRows();
185  }
186  else
187  {
188  beginRemoveRows( QModelIndex(), 0, 0 );
189  mAllowEmpty = false;
190  endRemoveRows();
191  }
192 }
193 
195 {
196  const QList< QgsAbstractDatabaseProviderConnection::TableProperty > newTables = mConnection->tables( mSchema );
197  const QList< QgsAbstractDatabaseProviderConnection::TableProperty > oldTables = mTables;
198 
199  for ( const QgsAbstractDatabaseProviderConnection::TableProperty &oldTable : oldTables )
200  {
201  if ( !newTables.contains( oldTable ) )
202  {
203  int r = mTables.indexOf( oldTable );
204  beginRemoveRows( QModelIndex(), r + ( mAllowEmpty ? 1 : 0 ), r + ( mAllowEmpty ? 1 : 0 ) );
205  mTables.removeAt( r );
206  endRemoveRows();
207  }
208  }
209 
210  for ( const QgsAbstractDatabaseProviderConnection::TableProperty &newTable : newTables )
211  {
212  if ( !mTables.contains( newTable ) )
213  {
214  beginInsertRows( QModelIndex(), mTables.count() + ( mAllowEmpty ? 1 : 0 ), mTables.count() + ( mAllowEmpty ? 1 : 0 ) );
215  mTables.append( newTable );
216  endInsertRows();
217  }
218  }
219 }
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 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:938
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.