mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 15:20:05 +00:00 
			
		
		
		
	Separating tree model from radar product model
This commit is contained in:
		
							parent
							
								
									782d61e5f0
								
							
						
					
					
						commit
						1ab0d62b1f
					
				
					 7 changed files with 182 additions and 79 deletions
				
			
		|  | @ -45,6 +45,7 @@ public: | |||
|        level2ProductsWidget_ {nullptr}, | ||||
|        level2SettingsWidget_ {nullptr}, | ||||
|        radarSiteDialog_ {nullptr}, | ||||
|        radarProductModel_ {nullptr}, | ||||
|        maps_ {}, | ||||
|        elevationCuts_ {}, | ||||
|        elevationButtonsChanged_ {false}, | ||||
|  | @ -104,6 +105,8 @@ public: | |||
| 
 | ||||
|    ui::RadarSiteDialog* radarSiteDialog_; | ||||
| 
 | ||||
|    std::shared_ptr<model::RadarProductModel> radarProductModel_; | ||||
| 
 | ||||
|    std::vector<map::MapWidget*> maps_; | ||||
|    std::vector<float>           elevationCuts_; | ||||
| 
 | ||||
|  | @ -144,7 +147,7 @@ MainWindow::MainWindow(QWidget* parent) : | |||
|    // Configure Docks
 | ||||
|    ui->resourceExplorerDock->setVisible(false); | ||||
| 
 | ||||
|    ui->resourceTreeView->setModel(new model::RadarProductModel(this)); | ||||
|    p->radarProductModel_ = std::make_shared<model::RadarProductModel>(); | ||||
| 
 | ||||
|    // Configure Map
 | ||||
|    p->ConfigureMapLayout(); | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include <scwx/qt/model/radar_product_model.hpp> | ||||
| #include <scwx/qt/model/tree_model.hpp> | ||||
| #include <scwx/qt/manager/radar_product_manager.hpp> | ||||
| #include <scwx/qt/manager/radar_product_manager_notifier.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
|  | @ -22,38 +23,24 @@ public: | |||
|    explicit RadarProductModelImpl(RadarProductModel* self); | ||||
|    ~RadarProductModelImpl() = default; | ||||
| 
 | ||||
|    void AppendRow(TreeItem* parent, TreeItem* child); | ||||
| 
 | ||||
|    RadarProductModel*         self_; | ||||
|    std::shared_ptr<TreeItem> rootItem_; | ||||
|    std::unique_ptr<TreeModel> model_; | ||||
| }; | ||||
| 
 | ||||
| RadarProductModel::RadarProductModel(QObject* parent) : | ||||
|     TreeModel(parent), p(std::make_unique<RadarProductModelImpl>(this)) | ||||
| RadarProductModel::RadarProductModel() : | ||||
|     p(std::make_unique<RadarProductModelImpl>(this)) | ||||
| { | ||||
| } | ||||
| RadarProductModel::~RadarProductModel() = default; | ||||
| 
 | ||||
| const std::shared_ptr<TreeItem> RadarProductModel::root_item() const | ||||
| QAbstractItemModel* RadarProductModel::model() | ||||
| { | ||||
|    return p->rootItem_; | ||||
| } | ||||
| 
 | ||||
| void RadarProductModelImpl::AppendRow(TreeItem* parent, TreeItem* child) | ||||
| { | ||||
|    const QModelIndex parentIndex = self_->createIndex(parent->row(), 0, parent); | ||||
|    const int         childCount  = parent->child_count(); | ||||
|    const int         first       = childCount; | ||||
|    const int         last        = childCount; | ||||
| 
 | ||||
|    self_->beginInsertRows(parentIndex, first, last); | ||||
|    parent->AppendChild(child); | ||||
|    self_->endInsertRows(); | ||||
|    return p->model_.get(); | ||||
| } | ||||
| 
 | ||||
| RadarProductModelImpl::RadarProductModelImpl(RadarProductModel* self) : | ||||
|     self_ {self}, | ||||
|     rootItem_ {std::make_shared<TreeItem>( | ||||
|     model_ {std::make_unique<TreeModel>( | ||||
|        std::vector<QVariant> {QObject::tr("Product")})} | ||||
| { | ||||
|    connect( | ||||
|  | @ -67,12 +54,13 @@ RadarProductModelImpl::RadarProductModelImpl(RadarProductModel* self) : | |||
|          const QString radarSiteName {QString::fromStdString(radarSite)}; | ||||
| 
 | ||||
|          // Find existing radar site item (e.g., KLSX, KEAX)
 | ||||
|          TreeItem* radarSiteItem = rootItem_->FindChild(0, radarSiteName); | ||||
|          TreeItem* radarSiteItem = | ||||
|             model_->root_item()->FindChild(0, radarSiteName); | ||||
| 
 | ||||
|          if (radarSiteItem == nullptr) | ||||
|          { | ||||
|             radarSiteItem = new TreeItem({radarSiteName}); | ||||
|             AppendRow(rootItem_.get(), radarSiteItem); | ||||
|             model_->AppendRow(model_->root_item(), radarSiteItem); | ||||
|          } | ||||
| 
 | ||||
|          connect( | ||||
|  | @ -93,7 +81,7 @@ RadarProductModelImpl::RadarProductModelImpl(RadarProductModel* self) : | |||
|                { | ||||
|                   // Existing group item was not found, create it
 | ||||
|                   groupItem = new TreeItem({groupName}); | ||||
|                   AppendRow(radarSiteItem, groupItem); | ||||
|                   model_->AppendRow(radarSiteItem, groupItem); | ||||
|                } | ||||
| 
 | ||||
|                TreeItem* productItem = nullptr; | ||||
|  | @ -113,12 +101,12 @@ RadarProductModelImpl::RadarProductModelImpl(RadarProductModel* self) : | |||
|                   { | ||||
|                      // Existing product item was not found, create it
 | ||||
|                      productItem = new TreeItem({productName}); | ||||
|                      AppendRow(groupItem, productItem); | ||||
|                      model_->AppendRow(groupItem, productItem); | ||||
|                   } | ||||
|                } | ||||
| 
 | ||||
|                // Create leaf item for product time
 | ||||
|                AppendRow(productItem, | ||||
|                model_->AppendRow(productItem, | ||||
|                                  new TreeItem {QString::fromStdString( | ||||
|                                     util::TimeString(latestTime))}); | ||||
|             }, | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/qt/model/tree_model.hpp> | ||||
| #include <QAbstractItemModel> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -11,14 +11,13 @@ namespace model | |||
| 
 | ||||
| class RadarProductModelImpl; | ||||
| 
 | ||||
| class RadarProductModel : public TreeModel | ||||
| class RadarProductModel | ||||
| { | ||||
| public: | ||||
|    explicit RadarProductModel(QObject* parent = nullptr); | ||||
|    explicit RadarProductModel(); | ||||
|    ~RadarProductModel(); | ||||
| 
 | ||||
| protected: | ||||
|    const std::shared_ptr<TreeItem> root_item() const override; | ||||
|    QAbstractItemModel* model(); | ||||
| 
 | ||||
| private: | ||||
|    std::unique_ptr<RadarProductModelImpl> p; | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ public: | |||
|    } | ||||
|    ~Impl() { qDeleteAll(childItems_); } | ||||
| 
 | ||||
|    std::vector<TreeItem*> childItems_; | ||||
|    QList<TreeItem*>      childItems_; | ||||
|    std::vector<QVariant> itemData_; | ||||
|    TreeItem*             parentItem_; | ||||
| }; | ||||
|  | @ -38,30 +38,6 @@ 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); | ||||
| } | ||||
| 
 | ||||
| TreeItem* TreeItem::FindChild(int column, const QVariant& data) | ||||
| { | ||||
|    auto it = std::find_if(p->childItems_.begin(), | ||||
|                           p->childItems_.end(), | ||||
|                           [&](auto& item) { | ||||
|                              return (column < item->column_count() && | ||||
|                                      item->data(column) == data); | ||||
|                           }); | ||||
| 
 | ||||
|    TreeItem* item = nullptr; | ||||
|    if (it != p->childItems_.end()) | ||||
|    { | ||||
|       item = *it; | ||||
|    } | ||||
| 
 | ||||
|    return item; | ||||
| } | ||||
| 
 | ||||
| const TreeItem* TreeItem::child(int row) const | ||||
| { | ||||
|    const TreeItem* item = nullptr; | ||||
|  | @ -88,7 +64,9 @@ TreeItem* TreeItem::child(int row) | |||
| 
 | ||||
| std::vector<TreeItem*> TreeItem::children() | ||||
| { | ||||
|    return p->childItems_; | ||||
|    std::vector<TreeItem*> children(p->childItems_.cbegin(), | ||||
|                                    p->childItems_.cend()); | ||||
|    return children; | ||||
| } | ||||
| 
 | ||||
| int TreeItem::child_count() const | ||||
|  | @ -119,10 +97,7 @@ int TreeItem::row() const | |||
| 
 | ||||
|    if (p->parentItem_ != nullptr) | ||||
|    { | ||||
|       const auto& childItems = p->parentItem_->p->childItems_; | ||||
|       row = | ||||
|          std::distance(childItems.cbegin(), | ||||
|                        std::find(childItems.cbegin(), childItems.cend(), this)); | ||||
|       row = p->parentItem_->p->childItems_.indexOf(this); | ||||
|    } | ||||
| 
 | ||||
|    return row; | ||||
|  | @ -133,6 +108,59 @@ const TreeItem* TreeItem::parent_item() const | |||
|    return p->parentItem_; | ||||
| } | ||||
| 
 | ||||
| void TreeItem::AppendChild(TreeItem* item) | ||||
| { | ||||
|    item->p->parentItem_ = this; | ||||
|    p->childItems_.push_back(item); | ||||
| } | ||||
| 
 | ||||
| TreeItem* TreeItem::FindChild(int column, const QVariant& data) | ||||
| { | ||||
|    auto it = std::find_if(p->childItems_.begin(), | ||||
|                           p->childItems_.end(), | ||||
|                           [&](auto& item) { | ||||
|                              return (column < item->column_count() && | ||||
|                                      item->data(column) == data); | ||||
|                           }); | ||||
| 
 | ||||
|    TreeItem* item = nullptr; | ||||
|    if (it != p->childItems_.end()) | ||||
|    { | ||||
|       item = *it; | ||||
|    } | ||||
| 
 | ||||
|    return item; | ||||
| } | ||||
| 
 | ||||
| bool TreeItem::InsertChildren(int position, int count, int columns) | ||||
| { | ||||
|    if (position < 0 || position > p->childItems_.size()) | ||||
|    { | ||||
|       return false; | ||||
|    } | ||||
| 
 | ||||
|    std::vector<QVariant> data(columns); | ||||
| 
 | ||||
|    for (int row = 0; row < count; ++row) | ||||
|    { | ||||
|       TreeItem* item = new TreeItem(data, this); | ||||
|       p->childItems_.insert(position, item); | ||||
|    } | ||||
| 
 | ||||
|    return true; | ||||
| } | ||||
| 
 | ||||
| bool TreeItem::SetData(int column, const QVariant& value) | ||||
| { | ||||
|    if (column < 0 || column >= p->itemData_.size()) | ||||
|    { | ||||
|       return false; | ||||
|    } | ||||
| 
 | ||||
|    p->itemData_[column] = value; | ||||
|    return true; | ||||
| } | ||||
| 
 | ||||
| } // namespace model
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
|  |  | |||
|  | @ -27,9 +27,6 @@ public: | |||
|    TreeItem(TreeItem&&) noexcept; | ||||
|    TreeItem& operator=(TreeItem&&) noexcept; | ||||
| 
 | ||||
|    void      AppendChild(TreeItem* child); | ||||
|    TreeItem* FindChild(int column, const QVariant& data); | ||||
| 
 | ||||
|    const TreeItem*        child(int row) const; | ||||
|    TreeItem*              child(int row); | ||||
|    std::vector<TreeItem*> children(); | ||||
|  | @ -39,6 +36,11 @@ public: | |||
|    int                    row() const; | ||||
|    const TreeItem*        parent_item() const; | ||||
| 
 | ||||
|    void      AppendChild(TreeItem* child); | ||||
|    TreeItem* FindChild(int column, const QVariant& data); | ||||
|    bool      InsertChildren(int position, int count, int columns); | ||||
|    bool      SetData(int column, const QVariant& value); | ||||
| 
 | ||||
| private: | ||||
|    class Impl; | ||||
|    std::unique_ptr<Impl> p; | ||||
|  |  | |||
|  | @ -12,21 +12,42 @@ static const std::string logPrefix_ = "scwx::qt::model::tree_model"; | |||
| class TreeModelImpl | ||||
| { | ||||
| public: | ||||
|    explicit TreeModelImpl(TreeModel* self) : self_ {self} {}; | ||||
|    explicit TreeModelImpl(TreeModel*                   self, | ||||
|                           const std::vector<QVariant>& headerData) : | ||||
|        self_ {self}, rootItem_ {std::make_unique<TreeItem>(headerData)} {}; | ||||
|    ~TreeModelImpl() = default; | ||||
| 
 | ||||
|    const TreeItem* item(const QModelIndex& index) const; | ||||
|    TreeItem*       item(const QModelIndex& index); | ||||
| 
 | ||||
|    TreeModel*                self_; | ||||
|    std::unique_ptr<TreeItem> rootItem_; | ||||
| }; | ||||
| 
 | ||||
| TreeModel::TreeModel(QObject* parent) : | ||||
|     QAbstractItemModel(parent), p(std::make_unique<TreeModelImpl>(this)) | ||||
| TreeModel::TreeModel(const std::vector<QVariant>& headerData, QObject* parent) : | ||||
|     QAbstractItemModel(parent), | ||||
|     p(std::make_unique<TreeModelImpl>(this, headerData)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| TreeModel::TreeModel(std::initializer_list<QVariant> headerData, | ||||
|                      QObject*                        parent) : | ||||
|     TreeModel(std::vector<QVariant> {headerData}, parent) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| TreeModel::~TreeModel() = default; | ||||
| 
 | ||||
| const TreeItem* TreeModel::root_item() const | ||||
| { | ||||
|    return p->rootItem_.get(); | ||||
| } | ||||
| 
 | ||||
| TreeItem* TreeModel::root_item() | ||||
| { | ||||
|    return p->rootItem_.get(); | ||||
| } | ||||
| 
 | ||||
| int TreeModel::rowCount(const QModelIndex& parent) const | ||||
| { | ||||
|    const TreeItem* parentItem = p->item(parent); | ||||
|  | @ -110,7 +131,7 @@ QModelIndex TreeModel::parent(const QModelIndex& index) const | |||
|    const TreeItem* childItem  = p->item(index); | ||||
|    const TreeItem* parentItem = childItem ? childItem->parent_item() : nullptr; | ||||
| 
 | ||||
|    if (parentItem == root_item().get() || parentItem == nullptr) | ||||
|    if (parentItem == p->rootItem_.get() || parentItem == nullptr) | ||||
|    { | ||||
|       return QModelIndex(); | ||||
|    } | ||||
|  | @ -118,6 +139,58 @@ QModelIndex TreeModel::parent(const QModelIndex& index) const | |||
|    return createIndex(parentItem->row(), 0, parentItem); | ||||
| } | ||||
| 
 | ||||
| bool TreeModel::insertRows(int row, int count, const QModelIndex& parent) | ||||
| { | ||||
|    TreeItem* parentItem = p->item(parent); | ||||
|    if (parentItem == nullptr) | ||||
|    { | ||||
|       return false; | ||||
|    } | ||||
| 
 | ||||
|    beginInsertRows(parent, row, row + count - 1); | ||||
|    bool result = parentItem->InsertChildren(row, count, columnCount(parent)); | ||||
|    endInsertRows(); | ||||
| 
 | ||||
|    return result; | ||||
| } | ||||
| 
 | ||||
| bool TreeModel::setData(const QModelIndex& index, | ||||
|                         const QVariant&    value, | ||||
|                         int                role) | ||||
| { | ||||
|    if (!index.isValid() || role != Qt::EditRole) | ||||
|    { | ||||
|       return false; | ||||
|    } | ||||
| 
 | ||||
|    TreeItem* item = p->item(index); | ||||
|    if (item == nullptr) | ||||
|    { | ||||
|       return false; | ||||
|    } | ||||
| 
 | ||||
|    bool result = item->SetData(index.column(), value); | ||||
| 
 | ||||
|    if (result) | ||||
|    { | ||||
|       emit dataChanged(index, index); | ||||
|    } | ||||
| 
 | ||||
|    return result; | ||||
| } | ||||
| 
 | ||||
| void TreeModel::AppendRow(TreeItem* parent, TreeItem* child) | ||||
| { | ||||
|    const QModelIndex parentIndex = createIndex(parent->row(), 0, parent); | ||||
|    const int         childCount  = parent->child_count(); | ||||
|    const int         first       = childCount; | ||||
|    const int         last        = childCount; | ||||
| 
 | ||||
|    beginInsertRows(parentIndex, first, last); | ||||
|    parent->AppendChild(child); | ||||
|    endInsertRows(); | ||||
| } | ||||
| 
 | ||||
| const TreeItem* TreeModelImpl::item(const QModelIndex& index) const | ||||
| { | ||||
|    if (index.isValid()) | ||||
|  | @ -129,7 +202,7 @@ const TreeItem* TreeModelImpl::item(const QModelIndex& index) const | |||
|          return item; | ||||
|       } | ||||
|    } | ||||
|    return self_->root_item().get(); | ||||
|    return rootItem_.get(); | ||||
| } | ||||
| 
 | ||||
| TreeItem* TreeModelImpl::item(const QModelIndex& index) | ||||
|  | @ -142,7 +215,7 @@ TreeItem* TreeModelImpl::item(const QModelIndex& index) | |||
|          return item; | ||||
|       } | ||||
|    } | ||||
|    return self_->root_item().get(); | ||||
|    return rootItem_.get(); | ||||
| } | ||||
| 
 | ||||
| } // namespace model
 | ||||
|  |  | |||
|  | @ -16,9 +16,15 @@ class TreeModelImpl; | |||
| class TreeModel : public QAbstractItemModel | ||||
| { | ||||
| public: | ||||
|    explicit TreeModel(QObject* parent = nullptr); | ||||
|    explicit TreeModel(const std::vector<QVariant>& headerData, | ||||
|                       QObject*                     parent = nullptr); | ||||
|    explicit TreeModel(std::initializer_list<QVariant> headerData, | ||||
|                       QObject*                        parent = nullptr); | ||||
|    virtual ~TreeModel(); | ||||
| 
 | ||||
|    const TreeItem* root_item() const; | ||||
|    TreeItem*       root_item(); | ||||
| 
 | ||||
|    int rowCount(const QModelIndex& parent = QModelIndex()) const override; | ||||
|    int columnCount(const QModelIndex& parent = QModelIndex()) const override; | ||||
| 
 | ||||
|  | @ -33,8 +39,12 @@ public: | |||
|                        const QModelIndex& parent = QModelIndex()) const override; | ||||
|    QModelIndex   parent(const QModelIndex& index) const override; | ||||
| 
 | ||||
| protected: | ||||
|    virtual const std::shared_ptr<TreeItem> root_item() const = 0; | ||||
|    bool insertRows(int row, int count, const QModelIndex& parent) override; | ||||
|    bool setData(const QModelIndex& index, | ||||
|                 const QVariant&    value, | ||||
|                 int                role = Qt::EditRole) override; | ||||
| 
 | ||||
|    void AppendRow(TreeItem* parent, TreeItem* child); | ||||
| 
 | ||||
| private: | ||||
|    friend class TreeModelImpl; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat