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