QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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  break;
135  }
136 
137  return QgsLayerItem::iconTable();
138  }
139  else if ( role == RoleWkbType )
140  return table.geometryColumnTypes().at( 0 ).wkbType;
141  else if ( role == RoleCrs )
142  return table.geometryColumnTypes().at( 0 ).crs;
143 
144  return QVariant();
145  }
146 
147  case RoleSchema:
148  return table.schema();
149 
150  case RoleTableFlags:
151  return static_cast< int >( table.flags() );
152 
153  case RoleComment:
154  return table.comment();
155 
156  case RoleCustomInfo:
157  return table.info();
158 
159  }
160 
161  return QVariant();
162 }
163 
164 QModelIndex QgsDatabaseTableModel::index( int row, int column, const QModelIndex &parent ) const
165 {
166  if ( hasIndex( row, column, parent ) )
167  {
168  return createIndex( row, column, row );
169  }
170 
171  return QModelIndex();
172 }
173 
175 {
176  if ( allowEmpty == mAllowEmpty )
177  return;
178 
179  if ( allowEmpty )
180  {
181  beginInsertRows( QModelIndex(), 0, 0 );
182  mAllowEmpty = true;
183  endInsertRows();
184  }
185  else
186  {
187  beginRemoveRows( QModelIndex(), 0, 0 );
188  mAllowEmpty = false;
189  endRemoveRows();
190  }
191 }
192 
194 {
195  const QList< QgsAbstractDatabaseProviderConnection::TableProperty > newTables = mConnection->tables( mSchema );
196  const QList< QgsAbstractDatabaseProviderConnection::TableProperty > oldTables = mTables;
197 
198  for ( const QgsAbstractDatabaseProviderConnection::TableProperty &oldTable : oldTables )
199  {
200  if ( !newTables.contains( oldTable ) )
201  {
202  int r = mTables.indexOf( oldTable );
203  beginRemoveRows( QModelIndex(), r + ( mAllowEmpty ? 1 : 0 ), r + ( mAllowEmpty ? 1 : 0 ) );
204  mTables.removeAt( r );
205  endRemoveRows();
206  }
207  }
208 
209  for ( const QgsAbstractDatabaseProviderConnection::TableProperty &newTable : newTables )
210  {
211  if ( !mTables.contains( newTable ) )
212  {
213  beginInsertRows( QModelIndex(), mTables.count() + ( mAllowEmpty ? 1 : 0 ), mTables.count() + ( mAllowEmpty ? 1 : 0 ) );
214  mTables.append( newTable );
215  endInsertRows();
216  }
217  }
218 }
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 iconPoint()
Definition: qgsdataitem.cpp:76
static QIcon iconLine()
Definition: qgsdataitem.cpp:81
static QIcon iconTable()
Definition: qgsdataitem.cpp:91
static QIcon iconPolygon()
Definition: qgsdataitem.cpp:86
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.