forked from sqlitebrowser/sqlitebrowser
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add custom model for tree view in Database Structure tab
Use a custom model for the tree view in the "Database Structure" tab in the main window, i.e. change from a QTreeWidget to a QTreeView and do all the item management stuff manually. This might add some code and complexity but also offers some more flexibility for us.
- Loading branch information
1 parent
afc53f7
commit 64a9387
Showing
6 changed files
with
220 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
#include "DbStructureModel.h" | ||
#include "sqlitedb.h" | ||
#include <QTreeWidgetItem> | ||
|
||
DbStructureModel::DbStructureModel(QObject* parent) | ||
: QAbstractItemModel(parent) | ||
{ | ||
// Create root item and use its columns to store the header strings | ||
QStringList header; | ||
header << tr("Name") << tr("Object") << tr("Type") << tr("Schema"); | ||
rootItem = new QTreeWidgetItem(header); | ||
} | ||
|
||
DbStructureModel::~DbStructureModel() | ||
{ | ||
delete rootItem; | ||
} | ||
|
||
int DbStructureModel::columnCount(const QModelIndex&) const | ||
{ | ||
return rootItem->columnCount(); | ||
} | ||
|
||
QVariant DbStructureModel::data(const QModelIndex& index, int role) const | ||
{ | ||
if(!index.isValid()) | ||
return QVariant(); | ||
|
||
// Get the item the index points at | ||
QTreeWidgetItem* item = static_cast<QTreeWidgetItem*>(index.internalPointer()); | ||
|
||
// Depending on the role either return the text or the icon | ||
if(role == Qt::DisplayRole) | ||
return item->text(index.column()); | ||
else if(role == Qt::DecorationRole) | ||
return item->icon(index.column()); | ||
else | ||
return QVariant(); | ||
} | ||
|
||
Qt::ItemFlags DbStructureModel::flags(const QModelIndex &index) const | ||
{ | ||
if(!index.isValid()) | ||
return 0; | ||
|
||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable; | ||
} | ||
|
||
QVariant DbStructureModel::headerData(int section, Qt::Orientation orientation, int role) const | ||
{ | ||
// Get the header string from the root item | ||
if(orientation == Qt::Horizontal && role == Qt::DisplayRole) | ||
return rootItem->data(section, role); | ||
|
||
return QVariant(); | ||
} | ||
|
||
QModelIndex DbStructureModel::index(int row, int column, const QModelIndex& parent) const | ||
{ | ||
if(!hasIndex(row, column, parent)) | ||
return QModelIndex(); | ||
|
||
QTreeWidgetItem *parentItem; | ||
if(!parent.isValid()) | ||
parentItem = rootItem; | ||
else | ||
parentItem = static_cast<QTreeWidgetItem*>(parent.internalPointer()); | ||
|
||
QTreeWidgetItem* childItem = parentItem->child(row); | ||
if(childItem) | ||
return createIndex(row, column, childItem); | ||
else | ||
return QModelIndex(); | ||
} | ||
|
||
QModelIndex DbStructureModel::parent(const QModelIndex& index) const | ||
{ | ||
if(!index.isValid()) | ||
return QModelIndex(); | ||
|
||
QTreeWidgetItem* childItem = static_cast<QTreeWidgetItem*>(index.internalPointer()); | ||
QTreeWidgetItem* parentItem = childItem->parent(); | ||
|
||
if(parentItem == rootItem) | ||
return QModelIndex(); | ||
else | ||
return createIndex(0, 0, parentItem); | ||
} | ||
|
||
int DbStructureModel::rowCount(const QModelIndex& parent) const | ||
{ | ||
if(parent.column() > 0) | ||
return 0; | ||
|
||
if(!parent.isValid()) | ||
return rootItem->childCount(); | ||
else | ||
return static_cast<QTreeWidgetItem*>(parent.internalPointer())->childCount(); | ||
} | ||
|
||
void DbStructureModel::reloadData(DBBrowserDB* db) | ||
{ | ||
// Remove all data except for the root item | ||
while(rootItem->childCount()) | ||
{ | ||
delete rootItem->child(0); | ||
rootItem->removeChild(rootItem->child(0)); | ||
} | ||
|
||
// Create the nodes for tables, indices, views and triggers | ||
QMap<QString, QTreeWidgetItem*> typeToParentItem; | ||
QTreeWidgetItem* itemTables = new QTreeWidgetItem(rootItem); | ||
itemTables->setIcon(0, QIcon(QString(":/icons/table"))); | ||
itemTables->setText(0, tr("Tables (%1)").arg(db->objMap.values("table").count())); | ||
typeToParentItem.insert("table", itemTables); | ||
QTreeWidgetItem* itemIndices = new QTreeWidgetItem(rootItem); | ||
itemIndices->setIcon(0, QIcon(QString(":/icons/index"))); | ||
itemIndices->setText(0, tr("Indices (%1)").arg(db->objMap.values("index").count())); | ||
typeToParentItem.insert("index", itemIndices); | ||
QTreeWidgetItem* itemViews = new QTreeWidgetItem(rootItem); | ||
itemViews->setIcon(0, QIcon(QString(":/icons/view"))); | ||
itemViews->setText(0, tr("Views (%1)").arg(db->objMap.values("view").count())); | ||
typeToParentItem.insert("view", itemViews); | ||
QTreeWidgetItem* itemTriggers = new QTreeWidgetItem(rootItem); | ||
itemTriggers->setIcon(0, QIcon(QString(":/icons/trigger"))); | ||
itemTriggers->setText(0, tr("Triggers (%1)").arg(db->objMap.values("trigger").count())); | ||
typeToParentItem.insert("trigger", itemTriggers); | ||
|
||
// Add the actual table objects | ||
for(objectMap::ConstIterator it=db->objMap.begin();it!=db->objMap.end();++it) | ||
{ | ||
// Object node | ||
QTreeWidgetItem *tableItem = new QTreeWidgetItem(typeToParentItem.value((*it).gettype())); | ||
tableItem->setIcon(0, QIcon(QString(":/icons/%1").arg((*it).gettype()))); | ||
tableItem->setText(0, (*it).getname()); | ||
tableItem->setText(1, (*it).gettype()); | ||
tableItem->setText(3, (*it).getsql()); | ||
|
||
// If it is a table or view add the field Nodes | ||
if((*it).gettype() == "table" || (*it).gettype() == "view") | ||
{ | ||
for(int i=0;i<(*it).fldmap.size();i++) | ||
{ | ||
QTreeWidgetItem *fldItem = new QTreeWidgetItem(tableItem); | ||
fldItem->setText(0, (*it).fldmap.at(i)->name()); | ||
fldItem->setText(1, "field"); | ||
fldItem->setText(2, (*it).fldmap.at(i)->type()); | ||
fldItem->setIcon(0, QIcon(":/icons/field")); | ||
} | ||
} | ||
} | ||
|
||
// Refresh the view | ||
reset(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#ifndef __DBSTRUCTUREMODEL_H__ | ||
#define __DBSTRUCTUREMODEL_H__ | ||
|
||
#include <QAbstractItemModel> | ||
class DBBrowserDB; | ||
class QTreeWidgetItem; | ||
|
||
class DbStructureModel : public QAbstractItemModel | ||
{ | ||
Q_OBJECT | ||
|
||
public: | ||
explicit DbStructureModel(QObject* parent = 0); | ||
~DbStructureModel(); | ||
|
||
void reloadData(DBBrowserDB* db); | ||
|
||
QVariant data(const QModelIndex& index, int role) const; | ||
Qt::ItemFlags flags(const QModelIndex& index) const; | ||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; | ||
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; | ||
QModelIndex parent(const QModelIndex& index) const; | ||
int rowCount(const QModelIndex& parent = QModelIndex()) const; | ||
int columnCount(const QModelIndex& = QModelIndex()) const; | ||
|
||
private: | ||
QTreeWidgetItem* rootItem; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.