UEFITool/common/treemodel.cpp

443 lines
12 KiB
C++
Raw Normal View History

2013-10-08 15:07:03 +08:00
/* treemodel.cpp
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
2013-10-08 15:07:03 +08:00
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
2013-10-08 15:07:03 +08:00
*/
#include "treeitem.h"
#include "treemodel.h"
TreeModel::TreeModel(QObject *parent)
2013-10-08 15:07:03 +08:00
: QAbstractItemModel(parent)
{
rootItem = new TreeItem(Types::Root);
2013-10-08 15:07:03 +08:00
}
TreeModel::~TreeModel()
{
delete rootItem;
2013-10-08 15:07:03 +08:00
}
int TreeModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
else
return rootItem->columnCount();
}
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole && role != Qt::UserRole)
return QVariant();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if (role == Qt::DisplayRole)
return item->data(index.column());
else
return item->info();
}
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
int role) const
2013-10-08 15:07:03 +08:00
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch (section)
{
case 0:
return tr("Name");
case 1:
return tr("Action");
case 2:
return tr("Type");
case 3:
return tr("Subtype");
case 4:
return tr("Text");
}
}
2013-10-08 15:07:03 +08:00
return QVariant();
}
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
const
2013-10-08 15:07:03 +08:00
{
if (!hasIndex(row, column, parent))
return QModelIndex();
TreeItem *parentItem;
if (!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
TreeItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QModelIndex TreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
if (childItem == rootItem)
return QModelIndex();
2013-10-08 15:07:03 +08:00
TreeItem *parentItem = childItem->parent();
if (parentItem == rootItem)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
int TreeModel::rowCount(const QModelIndex &parent) const
{
TreeItem *parentItem;
if (parent.column() > 0)
return 0;
if (!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
return parentItem->childCount();
}
UINT8 TreeModel::type(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->type();
}
UINT8 TreeModel::subtype(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->subtype();
}
QByteArray TreeModel::header(const QModelIndex &index) const
{
if (!index.isValid())
return QByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->header();
}
bool TreeModel::hasEmptyHeader(const QModelIndex &index) const
{
if (!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyHeader();
}
QByteArray TreeModel::body(const QModelIndex &index) const
{
if (!index.isValid())
return QByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->body();
}
bool TreeModel::hasEmptyBody(const QModelIndex &index) const
{
if (!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyBody();
}
QByteArray TreeModel::parsingData(const QModelIndex &index) const
{
if (!index.isValid())
return QByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->parsingData();
}
bool TreeModel::hasEmptyParsingData(const QModelIndex &index) const
{
if (!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyParsingData();
}
QString TreeModel::name(const QModelIndex &index) const
{
if (!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->name();
}
QString TreeModel::text(const QModelIndex &index) const
{
if (!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->text();
}
QString TreeModel::info(const QModelIndex &index) const
{
if (!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->info();
}
UINT8 TreeModel::action(const QModelIndex &index) const
{
if (!index.isValid())
return Actions::NoAction;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->action();
}
bool TreeModel::fixed(const QModelIndex &index) const
{
if (!index.isValid())
return false;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->fixed();
}
bool TreeModel::compressed(const QModelIndex &index) const
{
if (!index.isValid())
return false;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->compressed();
}
void TreeModel::setFixed(const QModelIndex &index, const bool fixed)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setFixed(fixed);
if (!item->parent())
return;
if (fixed) {
if (item->compressed() && item->parent()->compressed() == FALSE) {
item->setFixed(item->parent()->fixed());
return;
}
if (item->parent()->type() != Types::Root)
item->parent()->setFixed(fixed);
}
emit dataChanged(index, index);
}
void TreeModel::setCompressed(const QModelIndex &index, const bool compressed)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setCompressed(compressed);
emit dataChanged(index, index);
}
void TreeModel::setSubtype(const QModelIndex & index, const UINT8 subtype)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setSubtype(subtype);
emit dataChanged(index, index);
}
void TreeModel::setName(const QModelIndex &index, const QString &data)
2013-10-08 15:07:03 +08:00
{
if (!index.isValid())
return;
2013-10-08 15:07:03 +08:00
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setName(data);
emit dataChanged(index, index);
}
void TreeModel::setType(const QModelIndex &index, const UINT8 data)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setType(data);
emit dataChanged(index, index);
}
void TreeModel::setText(const QModelIndex &index, const QString &data)
2013-10-08 15:07:03 +08:00
{
if (!index.isValid())
return;
2013-10-08 15:07:03 +08:00
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setText(data);
emit dataChanged(index, index);
}
void TreeModel::setInfo(const QModelIndex &index, const QString &data)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setInfo(data);
emit dataChanged(index, index);
}
void TreeModel::addInfo(const QModelIndex &index, const QString &data, const bool append)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->addInfo(data, (BOOLEAN)append);
emit dataChanged(index, index);
}
void TreeModel::setAction(const QModelIndex &index, const UINT8 action)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setAction(action);
// On insert action, set insert action for children
if (action == Actions::Insert)
for (int i = 0; i < item->childCount(); i++)
setAction(index.child(i, 0), Actions::Insert);
// Set rebuild action for parent, if it has no action now
if (index.parent().isValid() && this->type(index.parent()) != Types::Root
&& this->action(index.parent()) == Actions::NoAction)
setAction(index.parent(), Actions::Rebuild);
emit dataChanged(index, index);
}
void TreeModel::setParsingData(const QModelIndex &index, const QByteArray &data)
2013-10-08 15:07:03 +08:00
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setParsingData(data);
emit dataChanged(this->index(0, 0), index);
}
QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype,
const QString & name, const QString & text, const QString & info,
const QByteArray & header, const QByteArray & body,
const bool fixed, const QByteArray & parsingData,
const QModelIndex & parent, const UINT8 mode)
{
TreeItem *item = 0;
TreeItem *parentItem = 0;
int parentColumn = 0;
2013-10-08 15:07:03 +08:00
if (!parent.isValid())
parentItem = rootItem;
else
{
if (mode == CREATE_MODE_BEFORE || mode == CREATE_MODE_AFTER) {
item = static_cast<TreeItem*>(parent.internalPointer());
parentItem = item->parent();
parentColumn = parent.parent().column();
}
else {
parentItem = static_cast<TreeItem*>(parent.internalPointer());
parentColumn = parent.column();
}
}
TreeItem *newItem = new TreeItem(type, subtype, name, text, info, header, body, fixed, this->compressed(parent), parsingData, parentItem);
if (mode == CREATE_MODE_APPEND) {
emit layoutAboutToBeChanged();
parentItem->appendChild(newItem);
}
else if (mode == CREATE_MODE_PREPEND) {
emit layoutAboutToBeChanged();
parentItem->prependChild(newItem);
}
else if (mode == CREATE_MODE_BEFORE) {
emit layoutAboutToBeChanged();
parentItem->insertChildBefore(item, newItem);
}
else if (mode == CREATE_MODE_AFTER) {
emit layoutAboutToBeChanged();
parentItem->insertChildAfter(item, newItem);
}
else {
delete newItem;
return QModelIndex();
}
emit layoutChanged();
QModelIndex created = createIndex(newItem->row(), parentColumn, newItem);
setFixed(created, fixed); // Non-trivial logic requires additional call
return created;
}
QModelIndex TreeModel::findParentOfType(const QModelIndex& index, UINT8 type) const
{
if (!index.isValid())
return QModelIndex();
TreeItem *item;
QModelIndex parent = index;
for (item = static_cast<TreeItem*>(parent.internalPointer());
item != NULL && item != rootItem && item->type() != type;
item = static_cast<TreeItem*>(parent.internalPointer()))
parent = parent.parent();
if (item != NULL && item != rootItem)
return parent;
return QModelIndex();
}