mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 02:40:05 +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/overlay_layer.cpp | ||||||
|             source/scwx/qt/map/radar_product_layer.cpp |             source/scwx/qt/map/radar_product_layer.cpp | ||||||
|             source/scwx/qt/map/radar_range_layer.cpp) |             source/scwx/qt/map/radar_range_layer.cpp) | ||||||
| set(HDR_MODEL source/scwx/qt/model/radar_product_model.hpp) | set(HDR_MODEL source/scwx/qt/model/radar_product_model.hpp | ||||||
| set(SRC_MODEL source/scwx/qt/model/radar_product_model.cpp) |               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(HDR_REQUEST source/scwx/qt/request/nexrad_file_request.hpp) | ||||||
| set(SRC_REQUEST source/scwx/qt/request/nexrad_file_request.cpp) | set(SRC_REQUEST source/scwx/qt/request/nexrad_file_request.cpp) | ||||||
| set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp | 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 std::string logPrefix_ = "scwx::qt::model::radar_product_model"; | ||||||
| static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | 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 | class RadarProductModelImpl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit RadarProductModelImpl() : |    explicit RadarProductModelImpl() : | ||||||
|        rootItem_ {std::make_shared<RadarProductModelItem>( |        rootItem_ {std::make_shared<TreeItem>( | ||||||
|           std::vector<QVariant> {QObject::tr("Name"), QObject::tr("Info")})} |           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")})); |          std::vector<QVariant> {QObject::tr("MyItem"), QObject::tr("Data")})); | ||||||
|    } |    } | ||||||
|    ~RadarProductModelImpl() = default; |    ~RadarProductModelImpl() = default; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<RadarProductModelItem> rootItem_; |    std::shared_ptr<TreeItem> rootItem_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| RadarProductModel::RadarProductModel(QObject* parent) : | RadarProductModel::RadarProductModel(QObject* parent) : | ||||||
|     QAbstractTableModel(parent), p(std::make_unique<RadarProductModelImpl>()) |     TreeModel(parent), p(std::make_unique<RadarProductModelImpl>()) | ||||||
| { | { | ||||||
| } | } | ||||||
| RadarProductModel::~RadarProductModel() = default; | RadarProductModel::~RadarProductModel() = default; | ||||||
| 
 | 
 | ||||||
| int RadarProductModel::rowCount(const QModelIndex& parent) const | const std::shared_ptr<TreeItem> RadarProductModel::root_item() const | ||||||
| { | { | ||||||
|    const RadarProductModelItem* parentItem; |    return p->rootItem_; | ||||||
| 
 |  | ||||||
|    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_; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace model
 | } // namespace model
 | ||||||
|  |  | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <memory> | #include <scwx/qt/model/tree_model.hpp> | ||||||
| 
 |  | ||||||
| #include <QAbstractTableModel> |  | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
|  | @ -13,25 +11,14 @@ namespace model | ||||||
| 
 | 
 | ||||||
| class RadarProductModelImpl; | class RadarProductModelImpl; | ||||||
| 
 | 
 | ||||||
| class RadarProductModel : public QAbstractTableModel | class RadarProductModel : public TreeModel | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit RadarProductModel(QObject* parent = nullptr); |    explicit RadarProductModel(QObject* parent = nullptr); | ||||||
|    ~RadarProductModel(); |    ~RadarProductModel(); | ||||||
| 
 | 
 | ||||||
|    int rowCount(const QModelIndex& parent = QModelIndex()) const override; | protected: | ||||||
|    int columnCount(const QModelIndex& parent = QModelIndex()) const override; |    const std::shared_ptr<TreeItem> root_item() 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; |  | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|    std::unique_ptr<RadarProductModelImpl> p; |    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
	
	 Dan Paulat
						Dan Paulat