mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 16:10:04 +00:00
Refactoring generic tree model behavior
This commit is contained in:
parent
1ba60f0da1
commit
98f8bab79a
7 changed files with 348 additions and 236 deletions
|
|
@ -73,8 +73,12 @@ set(SRC_MAP source/scwx/qt/map/color_table_layer.cpp
|
|||
source/scwx/qt/map/overlay_layer.cpp
|
||||
source/scwx/qt/map/radar_product_layer.cpp
|
||||
source/scwx/qt/map/radar_range_layer.cpp)
|
||||
set(HDR_MODEL source/scwx/qt/model/radar_product_model.hpp)
|
||||
set(SRC_MODEL source/scwx/qt/model/radar_product_model.cpp)
|
||||
set(HDR_MODEL source/scwx/qt/model/radar_product_model.hpp
|
||||
source/scwx/qt/model/tree_item.hpp
|
||||
source/scwx/qt/model/tree_model.hpp)
|
||||
set(SRC_MODEL source/scwx/qt/model/radar_product_model.cpp
|
||||
source/scwx/qt/model/tree_item.cpp
|
||||
source/scwx/qt/model/tree_model.cpp)
|
||||
set(HDR_REQUEST source/scwx/qt/request/nexrad_file_request.hpp)
|
||||
set(SRC_REQUEST source/scwx/qt/request/nexrad_file_request.cpp)
|
||||
set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp
|
||||
|
|
|
|||
|
|
@ -11,241 +11,30 @@ namespace model
|
|||
static const std::string logPrefix_ = "scwx::qt::model::radar_product_model";
|
||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||
|
||||
class RadarProductModelItem
|
||||
{
|
||||
public:
|
||||
explicit RadarProductModelItem(const std::vector<QVariant>& data,
|
||||
RadarProductModelItem* parent = nullptr);
|
||||
~RadarProductModelItem();
|
||||
|
||||
void AppendChild(RadarProductModelItem* child);
|
||||
|
||||
const RadarProductModelItem* child(int row) const;
|
||||
int child_count() const;
|
||||
int column_count() const;
|
||||
QVariant data(int column) const;
|
||||
int row() const;
|
||||
const RadarProductModelItem* parent_item() const;
|
||||
|
||||
private:
|
||||
std::vector<RadarProductModelItem*> childItems_;
|
||||
std::vector<QVariant> itemData_;
|
||||
RadarProductModelItem* parentItem_;
|
||||
};
|
||||
|
||||
class RadarProductModelImpl
|
||||
{
|
||||
public:
|
||||
explicit RadarProductModelImpl() :
|
||||
rootItem_ {std::make_shared<RadarProductModelItem>(
|
||||
rootItem_ {std::make_shared<TreeItem>(
|
||||
std::vector<QVariant> {QObject::tr("Name"), QObject::tr("Info")})}
|
||||
{
|
||||
rootItem_->AppendChild(new RadarProductModelItem(
|
||||
rootItem_->AppendChild(new TreeItem(
|
||||
std::vector<QVariant> {QObject::tr("MyItem"), QObject::tr("Data")}));
|
||||
}
|
||||
~RadarProductModelImpl() = default;
|
||||
|
||||
std::shared_ptr<RadarProductModelItem> rootItem_;
|
||||
std::shared_ptr<TreeItem> rootItem_;
|
||||
};
|
||||
|
||||
RadarProductModel::RadarProductModel(QObject* parent) :
|
||||
QAbstractTableModel(parent), p(std::make_unique<RadarProductModelImpl>())
|
||||
TreeModel(parent), p(std::make_unique<RadarProductModelImpl>())
|
||||
{
|
||||
}
|
||||
RadarProductModel::~RadarProductModel() = default;
|
||||
|
||||
int RadarProductModel::rowCount(const QModelIndex& parent) const
|
||||
const std::shared_ptr<TreeItem> RadarProductModel::root_item() const
|
||||
{
|
||||
const RadarProductModelItem* parentItem;
|
||||
|
||||
if (parent.isValid())
|
||||
{
|
||||
parentItem = static_cast<const RadarProductModelItem*>(
|
||||
parent.constInternalPointer());
|
||||
}
|
||||
else
|
||||
{
|
||||
parentItem = p->rootItem_.get();
|
||||
}
|
||||
|
||||
return parentItem->child_count();
|
||||
}
|
||||
|
||||
int RadarProductModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
const RadarProductModelItem* parentItem;
|
||||
|
||||
if (parent.isValid())
|
||||
{
|
||||
parentItem = static_cast<const RadarProductModelItem*>(
|
||||
parent.constInternalPointer());
|
||||
}
|
||||
else
|
||||
{
|
||||
parentItem = p->rootItem_.get();
|
||||
}
|
||||
|
||||
return parentItem->column_count();
|
||||
}
|
||||
|
||||
QVariant RadarProductModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid() || role != Qt::DisplayRole)
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const RadarProductModelItem* item =
|
||||
static_cast<const RadarProductModelItem*>(index.internalPointer());
|
||||
|
||||
return item->data(index.column());
|
||||
}
|
||||
|
||||
Qt::ItemFlags RadarProductModel::flags(const QModelIndex& index) const
|
||||
{
|
||||
Qt::ItemFlags flags;
|
||||
|
||||
if (!index.isValid())
|
||||
{
|
||||
flags = Qt::NoItemFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = QAbstractItemModel::flags(index);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
QVariant RadarProductModel::headerData(int section,
|
||||
Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
{
|
||||
return p->rootItem_->data(section);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
RadarProductModel::index(int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
const RadarProductModelItem* parentItem;
|
||||
|
||||
if (!parent.isValid())
|
||||
{
|
||||
parentItem = p->rootItem_.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
parentItem = static_cast<const RadarProductModelItem*>(
|
||||
parent.constInternalPointer());
|
||||
}
|
||||
|
||||
const RadarProductModelItem* childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
{
|
||||
return createIndex(row, column, childItem);
|
||||
}
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex RadarProductModel::parent(const QModelIndex& index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
const RadarProductModelItem* childItem =
|
||||
static_cast<const RadarProductModelItem*>(index.constInternalPointer());
|
||||
const RadarProductModelItem* parentItem = childItem->parent_item();
|
||||
|
||||
if (parentItem == p->rootItem_.get())
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
return createIndex(parentItem->row(), 0, parentItem);
|
||||
}
|
||||
|
||||
RadarProductModelItem::RadarProductModelItem(const std::vector<QVariant>& data,
|
||||
RadarProductModelItem* parent) :
|
||||
childItems_ {}, itemData_ {data}, parentItem_ {parent}
|
||||
{
|
||||
}
|
||||
|
||||
RadarProductModelItem::~RadarProductModelItem()
|
||||
{
|
||||
qDeleteAll(childItems_);
|
||||
}
|
||||
|
||||
void RadarProductModelItem::AppendChild(RadarProductModelItem* item)
|
||||
{
|
||||
item->parentItem_ = this;
|
||||
childItems_.push_back(item);
|
||||
}
|
||||
|
||||
const RadarProductModelItem* RadarProductModelItem::child(int row) const
|
||||
{
|
||||
const RadarProductModelItem* item = nullptr;
|
||||
|
||||
if (0 <= row && row < childItems_.size())
|
||||
{
|
||||
item = childItems_[row];
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
int RadarProductModelItem::child_count() const
|
||||
{
|
||||
return static_cast<int>(childItems_.size());
|
||||
}
|
||||
|
||||
int RadarProductModelItem::column_count() const
|
||||
{
|
||||
return static_cast<int>(itemData_.size());
|
||||
}
|
||||
|
||||
QVariant RadarProductModelItem::data(int column) const
|
||||
{
|
||||
if (0 <= column && column < itemData_.size())
|
||||
{
|
||||
return itemData_[column];
|
||||
}
|
||||
else
|
||||
{
|
||||
return QVariant("Hello world");
|
||||
}
|
||||
}
|
||||
|
||||
int RadarProductModelItem::row() const
|
||||
{
|
||||
int row = 0;
|
||||
|
||||
if (parentItem_ != nullptr)
|
||||
{
|
||||
const auto& childItems = parentItem_->childItems_;
|
||||
row =
|
||||
std::distance(childItems.cbegin(),
|
||||
std::find(childItems.cbegin(), childItems.cend(), this));
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
const RadarProductModelItem* RadarProductModelItem::parent_item() const
|
||||
{
|
||||
return parentItem_;
|
||||
return p->rootItem_;
|
||||
}
|
||||
|
||||
} // namespace model
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <scwx/qt/model/tree_model.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -13,25 +11,14 @@ namespace model
|
|||
|
||||
class RadarProductModelImpl;
|
||||
|
||||
class RadarProductModel : public QAbstractTableModel
|
||||
class RadarProductModel : public TreeModel
|
||||
{
|
||||
public:
|
||||
explicit RadarProductModel(QObject* parent = nullptr);
|
||||
~RadarProductModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex& index,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
QVariant headerData(int section,
|
||||
Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
QModelIndex index(int row,
|
||||
int column,
|
||||
const QModelIndex& parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex& index) const override;
|
||||
protected:
|
||||
const std::shared_ptr<TreeItem> root_item() const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<RadarProductModelImpl> p;
|
||||
|
|
|
|||
98
scwx-qt/source/scwx/qt/model/tree_item.cpp
Normal file
98
scwx-qt/source/scwx/qt/model/tree_item.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#include <scwx/qt/model/tree_item.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::model::tree_item";
|
||||
|
||||
class TreeItem::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl(const std::vector<QVariant>& data, TreeItem* parent) :
|
||||
childItems_ {}, itemData_ {data}, parentItem_ {parent}
|
||||
{
|
||||
}
|
||||
~Impl() { qDeleteAll(childItems_); }
|
||||
|
||||
std::vector<TreeItem*> childItems_;
|
||||
std::vector<QVariant> itemData_;
|
||||
TreeItem* parentItem_;
|
||||
};
|
||||
|
||||
TreeItem::TreeItem(const std::vector<QVariant>& data, TreeItem* parent) :
|
||||
p {std::make_unique<Impl>(data, parent)}
|
||||
{
|
||||
}
|
||||
|
||||
TreeItem::~TreeItem() {}
|
||||
|
||||
TreeItem::TreeItem(TreeItem&&) noexcept = default;
|
||||
TreeItem& TreeItem::operator=(TreeItem&&) noexcept = default;
|
||||
|
||||
void TreeItem::AppendChild(TreeItem* item)
|
||||
{
|
||||
item->p->parentItem_ = this;
|
||||
p->childItems_.push_back(item);
|
||||
}
|
||||
|
||||
const TreeItem* TreeItem::child(int row) const
|
||||
{
|
||||
const TreeItem* item = nullptr;
|
||||
|
||||
if (0 <= row && row < p->childItems_.size())
|
||||
{
|
||||
item = p->childItems_[row];
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
int TreeItem::child_count() const
|
||||
{
|
||||
return static_cast<int>(p->childItems_.size());
|
||||
}
|
||||
|
||||
int TreeItem::column_count() const
|
||||
{
|
||||
return static_cast<int>(p->itemData_.size());
|
||||
}
|
||||
|
||||
QVariant TreeItem::data(int column) const
|
||||
{
|
||||
if (0 <= column && column < p->itemData_.size())
|
||||
{
|
||||
return p->itemData_[column];
|
||||
}
|
||||
else
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
int TreeItem::row() const
|
||||
{
|
||||
int row = 0;
|
||||
|
||||
if (p->parentItem_ != nullptr)
|
||||
{
|
||||
const auto& childItems = p->parentItem_->p->childItems_;
|
||||
row =
|
||||
std::distance(childItems.cbegin(),
|
||||
std::find(childItems.cbegin(), childItems.cend(), this));
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
const TreeItem* TreeItem::parent_item() const
|
||||
{
|
||||
return p->parentItem_;
|
||||
}
|
||||
|
||||
} // namespace model
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
44
scwx-qt/source/scwx/qt/model/tree_item.hpp
Normal file
44
scwx-qt/source/scwx/qt/model/tree_item.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
|
||||
class TreeItem
|
||||
{
|
||||
public:
|
||||
explicit TreeItem(const std::vector<QVariant>& data,
|
||||
TreeItem* parent = nullptr);
|
||||
virtual ~TreeItem();
|
||||
|
||||
TreeItem(const TreeItem&) = delete;
|
||||
TreeItem& operator=(const TreeItem&) = delete;
|
||||
|
||||
TreeItem(TreeItem&&) noexcept;
|
||||
TreeItem& operator=(TreeItem&&) noexcept;
|
||||
|
||||
void AppendChild(TreeItem* child);
|
||||
|
||||
const TreeItem* child(int row) const;
|
||||
int child_count() const;
|
||||
int column_count() const;
|
||||
QVariant data(int column) const;
|
||||
int row() const;
|
||||
const TreeItem* parent_item() const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> p;
|
||||
};
|
||||
|
||||
} // namespace model
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
145
scwx-qt/source/scwx/qt/model/tree_model.cpp
Normal file
145
scwx-qt/source/scwx/qt/model/tree_model.cpp
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#include <scwx/qt/model/tree_model.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::model::tree_model";
|
||||
|
||||
class TreeModelImpl
|
||||
{
|
||||
public:
|
||||
explicit TreeModelImpl() = default;
|
||||
~TreeModelImpl() = default;
|
||||
};
|
||||
|
||||
TreeModel::TreeModel(QObject* parent) :
|
||||
QAbstractTableModel(parent), p(std::make_unique<TreeModelImpl>())
|
||||
{
|
||||
}
|
||||
TreeModel::~TreeModel() = default;
|
||||
|
||||
int TreeModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
const TreeItem* parentItem;
|
||||
|
||||
if (parent.isValid())
|
||||
{
|
||||
parentItem = static_cast<const TreeItem*>(parent.constInternalPointer());
|
||||
}
|
||||
else
|
||||
{
|
||||
parentItem = root_item().get();
|
||||
}
|
||||
|
||||
return parentItem->child_count();
|
||||
}
|
||||
|
||||
int TreeModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
const TreeItem* parentItem;
|
||||
|
||||
if (parent.isValid())
|
||||
{
|
||||
parentItem = static_cast<const TreeItem*>(parent.constInternalPointer());
|
||||
}
|
||||
else
|
||||
{
|
||||
parentItem = root_item().get();
|
||||
}
|
||||
|
||||
return parentItem->column_count();
|
||||
}
|
||||
|
||||
QVariant TreeModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid() || role != Qt::DisplayRole)
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const TreeItem* item = static_cast<const TreeItem*>(index.internalPointer());
|
||||
|
||||
return item->data(index.column());
|
||||
}
|
||||
|
||||
Qt::ItemFlags TreeModel::flags(const QModelIndex& index) const
|
||||
{
|
||||
Qt::ItemFlags flags;
|
||||
|
||||
if (!index.isValid())
|
||||
{
|
||||
flags = Qt::NoItemFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = QAbstractItemModel::flags(index);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
QVariant
|
||||
TreeModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
{
|
||||
return root_item()->data(section);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
TreeModel::index(int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
const TreeItem* parentItem;
|
||||
|
||||
if (!parent.isValid())
|
||||
{
|
||||
parentItem = root_item().get();
|
||||
}
|
||||
else
|
||||
{
|
||||
parentItem = static_cast<const TreeItem*>(parent.constInternalPointer());
|
||||
}
|
||||
|
||||
const TreeItem* childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
{
|
||||
return createIndex(row, column, childItem);
|
||||
}
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex TreeModel::parent(const QModelIndex& index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
const TreeItem* childItem =
|
||||
static_cast<const TreeItem*>(index.constInternalPointer());
|
||||
const TreeItem* parentItem = childItem->parent_item();
|
||||
|
||||
if (parentItem == root_item().get())
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
return createIndex(parentItem->row(), 0, parentItem);
|
||||
}
|
||||
|
||||
} // namespace model
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
45
scwx-qt/source/scwx/qt/model/tree_model.hpp
Normal file
45
scwx-qt/source/scwx/qt/model/tree_model.hpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#include <scwx/qt/model/tree_item.hpp>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
|
||||
class TreeModelImpl;
|
||||
|
||||
class TreeModel : public QAbstractTableModel
|
||||
{
|
||||
public:
|
||||
explicit TreeModel(QObject* parent = nullptr);
|
||||
virtual ~TreeModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex& index,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
QVariant headerData(int section,
|
||||
Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
QModelIndex index(int row,
|
||||
int column,
|
||||
const QModelIndex& parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex& index) const override;
|
||||
|
||||
protected:
|
||||
virtual const std::shared_ptr<TreeItem> root_item() const = 0;
|
||||
|
||||
private:
|
||||
std::unique_ptr<TreeModelImpl> p;
|
||||
};
|
||||
|
||||
} // namespace model
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
Loading…
Add table
Add a link
Reference in a new issue