#include "ModelTree.h"
#include "Common.h"
#include "DaRecord.h"
#include "ScopeTailed.h"
/*最重要的就是对interpointer()这个内部指针的运用
与QTableView不同的是多了parent()和index()函数的重写,这也是关键之处
*/
ModelTree::ModelTree()
{
header_ <<....;
}
ModelTree::~ModelTree()
{
}
bool ModelTree::loadRoots()
{
beginResetModel();
mode_ = FULL;
root_.children_.clear();
root_.spbm_ = "0";
ScopeTailed endReset([this](){endResetModel(); });
DaRecord da;
if (!da.expandItem(root_))
return false;
return true;
}
void ModelTree::loadResult(RecordTree &root)
{
beginResetModel();
mode_ = RESULT;
root_ = root;
root_.buildTree();
endResetModel();
}
QVariant ModelTree::headerData(int section, Qt::Orientation orientation, int role /* = Qt::DisplayRole */) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return header_[section];
return QVariant();
}
int ModelTree::columnCount(const QModelIndex &parent /* = QModelIndex() */) const
{
return header_.count();
}
QVariant ModelTree::data(const QModelIndex &index, int role /* = Qt::DisplayRole */) const
{
if (role==Qt::DisplayRole && index.isValid())
{
RecordTree *pRec = static_cast<RecordTree*>(index.internalPointer());
switch (index.column())
{
case 0:return pRec->spmc_;
case 1:return pRec->spbm_;
case 2:return pRec->zs_;
case 3:return pRec->slv_.toString();
}
}
return QVariant();
}
int ModelTree::rowCount(const QModelIndex &parent /* = QModelIndex() */) const
{
if (!parent.isValid())
return root_.children_.count();
RecordTree *pRec = static_cast<RecordTree*>(parent.internalPointer());
if (mode_==FULL && !pRec->expanded_)
{
DaRecord da;
da.expandItem(*pRec);
}
return pRec->children_.count();
}
QModelIndex ModelTree::index(int row, int column, const QModelIndex &parent /* = QModelIndex() */) const
{
if (!parent.isValid())
{
if (row < root_.children_.count())
return createIndex(row, column, const_cast<RecordTree*>(&root_.children_[row]));
else
return QModelIndex();
}
RecordTree *pRec = static_cast<RecordTree*>(parent.internalPointer());
return createIndex(row, column, &pRec->children_[row]);
}
QModelIndex ModelTree::parent(const QModelIndex &index) const
{
RecordTree *rec = static_cast<RecordTree*>(index.internalPointer());
if (rec->parent_ == &root_)
return QModelIndex();
return createIndex(rec->parent_->rowIndex_, 0, rec->parent_);
}
//数据层
#pragma once
#include <QString>
#include <QList>
#include "Common.h"
#include "DatabaseAccess.h"
class RecordTree
{
public:
RecordTree();
~RecordTree();
public:
QString spbm_;
QString spmc_;
QString pid_;
QString zs_;
Currency slv_;
bool nodeType_; //1为父节点 0没有子节点
QList<RecordTree> children_;
bool expanded_ = false;
int rowIndex_ = 0;
RecordTree *parent_ = nullptr;
//创建一个树结构的数据
void buildTree()
{
for (int i = 0; i < children_.count(); i++)
{
RecordTree &child = children_[i];
child.parent_ = this;
child.rowIndex_ = i;
child.buildTree();
}
}
//根据所传来的字段找到这个树结构的数据
RecordTree *search(QString spbm)
{
if (spbm_ == spbm)
return this;
for (RecordTree &child : children_)
{
RecordTree *result = child.search(spbm);
if (result)
return result;
}
return nullptr;
}
};
//从数据库中得到树结构的数据
#include "DaRecord.h"
#include "Global.h"
#include "Database.h"
DaRecord::DaRecord()
{
setDatabase(global<Database>()->db());
}
DaRecord::~DaRecord()
{
}
bool DaRecord::selectByPid(QString &pid, QList<RecordTree> &commodity)
{
QString condition = QString("pid='%1'").arg(pid);
if (!selectBy(condition, commodity))
return false;
return true;
}
bool DaRecord::expandItemImpl(RecordTree &root)
{
QList<RecordTree> treeList;
if (!selectByPid(root.spbm_, treeList))
return false;
for (RecordTree &res : treeList)
{
res.parent_ = &root;
res.rowIndex_ = root.children_.count();
root.children_ << res;
}
root.expanded_ = true;
return true;
}
bool DaRecord::expandItem(RecordTree &root)
{
if (!expandItemImpl(root))
return false;
for (RecordTree &res : root.children_)
if (!expandItemImpl(res))
return false;
return true;
}
bool DaRecord::selectBySpbm(QString &spbm, RecordTree &res)
{
QString selectSql = QString("spbm='%1'").arg(spbm);
QList<RecordTree> resList;
if (!selectBy(selectSql, resList))
return false;
res = resList.first();
return true;
}
bool DaRecord::selectBykeyword(QString &keyword, QList<RecordTree> &commomdity)
{
QString condition = QString("spmc like '%%1% or zs like '%%2%'").arg(keyword).arg(keyword);
if (!selectBy(condition, commomdity))
return false;
return true;
}
//...(查找项目)
bool DaRecord::searchItem(QString &keyword, RecordTree &root)
{
QList<RecordTree> commoditys;
if (!selectBykeyword(keyword, commoditys))
return false;
for (auto &cur : commoditys)
{
RecordTree *parent = nullptr;
while (cur.pid_ != "0")
{
parent = root.search(cur.spbm_);
if (!parent)
{
RecordTree newParent;
if (!selectBySpbm(cur.pid_, newParent))
return false;
root.children_ << cur;
cur = newParent;
}
else
{
parent->children_ << cur;
break;
}
}
if (!parent)
root.children_ << cur;
}
return true;
}