#include "selectabledbobjmodel.h"#include "dbtree/dbtreeitem.h"#include "dbtree/dbtreemodel.h"#include <QDebug>#include <QTreeView>SelectableDbObjModel::SelectableDbObjModel(QObject *parent) :QSortFilterProxyModel(parent){}QVariant SelectableDbObjModel::data(const QModelIndex& index, int role) const{if (role != Qt::CheckStateRole)return QSortFilterProxyModel::data(index, role);return getStateFromChilds(index);}bool SelectableDbObjModel::setData(const QModelIndex& index, const QVariant& value, int role){if (role != Qt::CheckStateRole)return QSortFilterProxyModel::setData(index, value, role);Qt::CheckState checked = static_cast<Qt::CheckState>(value.toInt());setRecurrently(index, checked);emit dataChanged(index, index, {Qt::CheckStateRole});return true;}Qt::ItemFlags SelectableDbObjModel::flags(const QModelIndex& index) const{Qt::ItemFlags flags = QSortFilterProxyModel::flags(index);DbTreeItem* item = getItemForProxyIndex(index);switch (item->getType()){case DbTreeItem::Type::TABLE:case DbTreeItem::Type::VIRTUAL_TABLE:case DbTreeItem::Type::INDEX:case DbTreeItem::Type::TRIGGER:case DbTreeItem::Type::VIEW:case DbTreeItem::Type::DB:case DbTreeItem::Type::TABLES:case DbTreeItem::Type::INDEXES:case DbTreeItem::Type::TRIGGERS:case DbTreeItem::Type::VIEWS:{flags |= Qt::ItemIsUserCheckable;if (index.child(0, 0).isValid())flags |= Qt::ItemIsTristate;break;}case DbTreeItem::Type::DIR:case DbTreeItem::Type::COLUMNS:case DbTreeItem::Type::COLUMN:case DbTreeItem::Type::ITEM_PROTOTYPE:break;}return flags;}QString SelectableDbObjModel::getDbName() const{return dbName;}void SelectableDbObjModel::setDbName(const QString& value){beginResetModel();dbName = value;checkedObjects.clear();endResetModel();}QStringList SelectableDbObjModel::getCheckedObjects() const{return checkedObjects.toList();}void SelectableDbObjModel::setCheckedObjects(const QStringList& value){checkedObjects = value.toSet();}void SelectableDbObjModel::setRootChecked(bool checked){QModelIndex idx = index(0, 0);if (!idx.isValid())return;setData(idx, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);}DbTreeItem* SelectableDbObjModel::getItemForIndex(const QModelIndex& index) const{return getItemForProxyIndex(index);}bool SelectableDbObjModel::filterAcceptsRow(int srcRow, const QModelIndex& srcParent) const{QModelIndex idx = sourceModel()->index(srcRow, 0, srcParent);DbTreeItem* item = dynamic_cast<DbTreeItem*>(dynamic_cast<DbTreeModel*>(sourceModel())->itemFromIndex(idx));DbTreeItem* dbItem = item->getPathToParentItem(DbTreeItem::Type::DB).last();// These 3 conditions could be written as one OR-ed, but this is easier to debug which one fails this way.if (!dbItem)return false;if (item->getType() == DbTreeItem::Type::DIR)return checkRecurrentlyForDb(item);if (!dbItem->getDb())return false;if (dbItem->getDb()->getName() != dbName)return false;switch (item->getType()){case DbTreeItem::Type::TABLE:case DbTreeItem::Type::VIRTUAL_TABLE:case DbTreeItem::Type::INDEX:case DbTreeItem::Type::TRIGGER:case DbTreeItem::Type::VIEW:case DbTreeItem::Type::DB:return true;case DbTreeItem::Type::TABLES:case DbTreeItem::Type::INDEXES:case DbTreeItem::Type::TRIGGERS:case DbTreeItem::Type::VIEWS:return item->rowCount() > 0;case DbTreeItem::Type::DIR:case DbTreeItem::Type::COLUMNS:case DbTreeItem::Type::COLUMN:case DbTreeItem::Type::ITEM_PROTOTYPE:return false;}return false;}DbTreeItem* SelectableDbObjModel::getItemForProxyIndex(const QModelIndex& index) const{QModelIndex srcIdx = mapToSource(index);DbTreeItem* item = dynamic_cast<DbTreeItem*>(dynamic_cast<DbTreeModel*>(sourceModel())->itemFromIndex(srcIdx));return item;}Qt::CheckState SelectableDbObjModel::getStateFromChilds(const QModelIndex& index) const{DbTreeItem* item = getItemForProxyIndex(index);if (!item)return Qt::Unchecked;if (!index.child(0, 0).isValid()){if (isObject(item) && checkedObjects.contains(item->text()))return Qt::Checked;elsereturn Qt::Unchecked;}int total = 0;int checked = 0;int partial = 0;Qt::CheckState state;QModelIndex child;for (int i = 0; (child = index.child(i, 0)).isValid(); i++){if (!child.flags().testFlag(Qt::ItemIsUserCheckable))continue;total++;state = static_cast<Qt::CheckState>(child.data(Qt::CheckStateRole).toInt());if (state == Qt::Checked || state == Qt::PartiallyChecked){checked++;if (state == Qt::PartiallyChecked)partial++;}}if (total == checked){if (partial > 0)return Qt::PartiallyChecked;elsereturn Qt::Checked;}if (checked == 0){if (isObject(item) && checkedObjects.contains(item->text()))return Qt::PartiallyChecked;elsereturn Qt::Unchecked;}return Qt::PartiallyChecked;}void SelectableDbObjModel::setRecurrently(const QModelIndex& index, Qt::CheckState checked){DbTreeItem* item = getItemForProxyIndex(index);if (!item)return;if (checked && isObject(item))checkedObjects << item->text();elsecheckedObjects.remove(item->text());if (!index.child(0, 0).isValid())return;// Limiting checked to 'checked/unchecked', cause recurrent marking cannot set partially checked, it makes no sensechecked = (checked > 0 ? Qt::Checked : Qt::Unchecked);QModelIndex child;for (int i = 0; (child = index.child(i, 0)).isValid(); i++)setData(child, checked, Qt::CheckStateRole);}bool SelectableDbObjModel::isObject(DbTreeItem* item) const{switch (item->getType()){case DbTreeItem::Type::TABLE:case DbTreeItem::Type::INDEX:case DbTreeItem::Type::TRIGGER:case DbTreeItem::Type::VIEW:case DbTreeItem::Type::VIRTUAL_TABLE:return true;default:break;}return false;}bool SelectableDbObjModel::checkRecurrentlyForDb(DbTreeItem* item) const{return item->findItem(DbTreeItem::Type::DB, dbName) != nullptr;}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。