1 /***************************************************************************
2                          qgsspatialitetablemodel.cpp  -  description
3                          -------------------
4     begin                : Dec 2008
5     copyright            : (C) 2008 by Sandro Furieri
6     email                : a.furieri@lqt.it
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "qgsspatialitetablemodel.h"
19 #include "qgsapplication.h"
20 #include "qgsdataitem.h" // for icons
21 
QgsSpatiaLiteTableModel()22 QgsSpatiaLiteTableModel::QgsSpatiaLiteTableModel()
23 {
24   QStringList headerLabels;
25   headerLabels << tr( "Table" );
26   headerLabels << tr( "Type" );
27   headerLabels << tr( "Geometry column" );
28   headerLabels << tr( "Sql" );
29   setHorizontalHeaderLabels( headerLabels );
30 }
31 
addTableEntry(const QString & type,const QString & tableName,const QString & geometryColName,const QString & sql)32 void QgsSpatiaLiteTableModel::addTableEntry( const QString &type, const QString &tableName, const QString &geometryColName, const QString &sql )
33 {
34   //is there already a root item ?
35   QStandardItem *dbItem = nullptr;
36   QList < QStandardItem * >dbItems = findItems( mSqliteDb, Qt::MatchExactly, 0 );
37 
38   //there is already an item
39   if ( !dbItems.isEmpty() )
40   {
41     dbItem = dbItems.at( 0 );
42   }
43   else                        //create a new toplevel item
44   {
45     dbItem = new QStandardItem( mSqliteDb );
46     dbItem->setFlags( Qt::ItemIsEnabled );
47     invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), dbItem );
48   }
49 
50   //path to icon for specified type
51   QgsWkbTypes::Type wkbType = qgisTypeFromDbType( type );
52   QIcon iconFile = iconForType( wkbType );
53 
54   QList < QStandardItem * >childItemList;
55   QStandardItem *typeItem = new QStandardItem( QIcon( iconFile ), type );
56   typeItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
57   QStandardItem *tableItem = new QStandardItem( tableName );
58   tableItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
59   QStandardItem *geomItem = new QStandardItem( geometryColName );
60   geomItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
61   QStandardItem *sqlItem = new QStandardItem( sql );
62   sqlItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
63 
64 
65   childItemList.push_back( tableItem );
66   childItemList.push_back( typeItem );
67   childItemList.push_back( geomItem );
68   childItemList.push_back( sqlItem );
69 
70   dbItem->appendRow( childItemList );
71   ++mTableCount;
72 }
73 
setSql(const QModelIndex & index,const QString & sql)74 void QgsSpatiaLiteTableModel::setSql( const QModelIndex &index, const QString &sql )
75 {
76   if ( !index.isValid() || !index.parent().isValid() )
77   {
78     return;
79   }
80 
81   //find out table name
82   QModelIndex tableSibling = index.sibling( index.row(), 0 );
83   QModelIndex geomSibling = index.sibling( index.row(), 2 );
84 
85   if ( !tableSibling.isValid() || !geomSibling.isValid() )
86   {
87     return;
88   }
89 
90   QModelIndex sqlIndex = index.sibling( index.row(), 3 );
91   if ( sqlIndex.isValid() )
92   {
93     itemFromIndex( sqlIndex )->setText( sql );
94   }
95 }
96 
setGeometryTypesForTable(const QString & table,const QString & attribute,const QString & type)97 void QgsSpatiaLiteTableModel::setGeometryTypesForTable( const QString &table, const QString &attribute, const QString &type )
98 {
99   bool typeIsEmpty = type.isEmpty();  //true means the table has no valid geometry entry and the item for this table should be removed
100   QStringList typeList = type.split( ',' );
101 
102   //find schema item and table item
103   QStandardItem *dbItem = nullptr;
104   QList < QStandardItem * >dbItems = findItems( mSqliteDb, Qt::MatchExactly, 0 );
105 
106   if ( dbItems.empty() )
107   {
108     return;
109   }
110   dbItem = dbItems.at( 0 );
111   int numChildren = dbItem->rowCount();
112 
113   QModelIndex currentChildIndex;
114   QModelIndex currentTableIndex;
115   QModelIndex currentTypeIndex;
116   QModelIndex currentGeomColumnIndex;
117 
118   for ( int i = 0; i < numChildren; ++i )
119   {
120     currentChildIndex = indexFromItem( dbItem->child( i, 0 ) );
121     if ( !currentChildIndex.isValid() )
122     {
123       continue;
124     }
125     currentTableIndex = currentChildIndex.sibling( i, 1 );
126     currentTypeIndex = currentChildIndex.sibling( i, 2 );
127     currentGeomColumnIndex = currentChildIndex.sibling( i, 3 );
128     QString geomColText = itemFromIndex( currentGeomColumnIndex )->text();
129 
130     if ( !currentTypeIndex.isValid() || !currentTableIndex.isValid() || !currentGeomColumnIndex.isValid() )
131     {
132       continue;
133     }
134 
135     if ( itemFromIndex( currentTableIndex )->text() == table &&
136          ( geomColText == attribute || geomColText.startsWith( attribute + " AS " ) ) )
137     {
138       if ( typeIsEmpty )
139       {
140         removeRow( i, indexFromItem( dbItem ) );
141         return;
142       }
143 
144       QgsWkbTypes::Type wkbType = qgisTypeFromDbType( typeList.at( 0 ) );
145       QIcon myIcon = iconForType( wkbType );
146       itemFromIndex( currentTypeIndex )->setText( typeList.at( 0 ) ); //todo: add other rows
147       itemFromIndex( currentTypeIndex )->setIcon( myIcon );
148       if ( !geomColText.contains( QLatin1String( " AS " ) ) )
149       {
150         itemFromIndex( currentGeomColumnIndex )->setText( geomColText + " AS " + typeList.at( 0 ) );
151       }
152 
153       for ( int j = 1; j < typeList.size(); ++j )
154       {
155         //todo: add correct type
156         addTableEntry( typeList.at( j ), table, geomColText + " AS " + typeList.at( j ), QString() );
157       }
158     }
159   }
160 }
161 
iconForType(QgsWkbTypes::Type type) const162 QIcon QgsSpatiaLiteTableModel::iconForType( QgsWkbTypes::Type type ) const
163 {
164   if ( type == QgsWkbTypes::Point || type == QgsWkbTypes::Point25D || type == QgsWkbTypes::MultiPoint || type == QgsWkbTypes::MultiPoint25D )
165   {
166     return QgsLayerItem::iconPoint();
167   }
168   else if ( type == QgsWkbTypes::LineString || type == QgsWkbTypes::LineString25D || type == QgsWkbTypes::MultiLineString
169             || type == QgsWkbTypes::MultiLineString25D )
170   {
171     return QgsLayerItem::iconLine();
172   }
173   else if ( type == QgsWkbTypes::Polygon || type == QgsWkbTypes::Polygon25D || type == QgsWkbTypes::MultiPolygon
174             || type == QgsWkbTypes::MultiPolygon25D )
175   {
176     return QgsLayerItem::iconPolygon();
177   }
178   else
179     return QIcon();
180 }
181 
displayStringForType(QgsWkbTypes::Type type) const182 QString QgsSpatiaLiteTableModel::displayStringForType( QgsWkbTypes::Type type ) const
183 {
184   if ( type == QgsWkbTypes::Point || type == QgsWkbTypes::Point25D )
185   {
186     return tr( "Point" );
187   }
188   else if ( type == QgsWkbTypes::MultiPoint || type == QgsWkbTypes::MultiPoint25D )
189   {
190     return tr( "Multipoint" );
191   }
192   else if ( type == QgsWkbTypes::LineString || type == QgsWkbTypes::LineString25D )
193   {
194     return tr( "Line" );
195   }
196   else if ( type == QgsWkbTypes::MultiLineString || type == QgsWkbTypes::MultiLineString25D )
197   {
198     return tr( "Multiline" );
199   }
200   else if ( type == QgsWkbTypes::Polygon || type == QgsWkbTypes::Polygon25D )
201   {
202     return tr( "Polygon" );
203   }
204   else if ( type == QgsWkbTypes::MultiPolygon || type == QgsWkbTypes::MultiPolygon25D )
205   {
206     return tr( "Multipolygon" );
207   }
208   return QStringLiteral( "Unknown" );
209 }
210 
qgisTypeFromDbType(const QString & dbType) const211 QgsWkbTypes::Type QgsSpatiaLiteTableModel::qgisTypeFromDbType( const QString &dbType ) const
212 {
213   if ( dbType == QLatin1String( "POINT" ) )
214   {
215     return QgsWkbTypes::Point;
216   }
217   else if ( dbType == QLatin1String( "MULTIPOINT" ) )
218   {
219     return QgsWkbTypes::MultiPoint;
220   }
221   else if ( dbType == QLatin1String( "LINESTRING" ) )
222   {
223     return QgsWkbTypes::LineString;
224   }
225   else if ( dbType == QLatin1String( "MULTILINESTRING" ) )
226   {
227     return QgsWkbTypes::MultiLineString;
228   }
229   else if ( dbType == QLatin1String( "POLYGON" ) )
230   {
231     return QgsWkbTypes::Polygon;
232   }
233   else if ( dbType == QLatin1String( "MULTIPOLYGON" ) )
234   {
235     return QgsWkbTypes::MultiPolygon;
236   }
237   return QgsWkbTypes::Unknown;
238 }
239