From 9eb92d0f3b52316ddd2e34e84c94ca44b58ac3fe Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Thu, 8 Dec 2016 23:19:16 +0100 Subject: Simplify and safeguard memory management of TreeItem(Model) --- src/library/autodj/autodjfeature.cpp | 8 +-- src/library/banshee/bansheefeature.cpp | 22 +++----- src/library/baseplaylistfeature.cpp | 2 +- src/library/browse/browsefeature.cpp | 30 ++++------- src/library/cratefeature.cpp | 6 +-- src/library/itunes/itunesfeature.cpp | 6 +-- src/library/mixxxlibraryfeature.cpp | 8 +-- src/library/playlistfeature.cpp | 4 +- src/library/rhythmbox/rhythmboxfeature.cpp | 6 +-- src/library/setlogfeature.cpp | 4 +- src/library/traktor/traktorfeature.cpp | 8 +-- src/library/treeitem.cpp | 25 +++++---- src/library/treeitem.h | 19 ++++--- src/library/treeitemmodel.cpp | 82 +++++++++++++++--------------- src/library/treeitemmodel.h | 36 ++++++++----- 15 files changed, 136 insertions(+), 130 deletions(-) (limited to 'src/library') diff --git a/src/library/autodj/autodjfeature.cpp b/src/library/autodj/autodjfeature.cpp index f21d4d6210..9c21ab98e1 100644 --- a/src/library/autodj/autodjfeature.cpp +++ b/src/library/autodj/autodjfeature.cpp @@ -56,14 +56,14 @@ AutoDJFeature::AutoDJFeature(Library* pLibrary, // Create the "Crates" tree-item under the root item. - TreeItem* root = new TreeItem(this); - m_pCratesTreeItem = root->appendChild(new TreeItem(this, tr("Crates"))); + auto pRootItem = std::make_unique(this); + m_pCratesTreeItem = pRootItem->appendChild(tr("Crates")); m_pCratesTreeItem->setIcon(QIcon(":/images/library/ic_library_crates.png")); // Create tree-items under "Crates". constructCrateChildModel(); - m_childModel.setRootItem(root); + m_childModel.setRootItem(std::move(pRootItem)); // Be notified when the status of crates changes. connect(&m_crateDao, SIGNAL(added(int)), @@ -323,7 +323,7 @@ void AutoDJFeature::constructCrateChildModel() { m_crateList.append(qMakePair(id, name)); // Create the TreeItem for this crate. - m_pCratesTreeItem->appendChild(new TreeItem(this, name)); + m_pCratesTreeItem->appendChild(name); } } diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp index 884c79947c..3973ad7d6d 100644 --- a/src/library/banshee/bansheefeature.cpp +++ b/src/library/banshee/bansheefeature.cpp @@ -91,25 +91,19 @@ void BansheeFeature::activate() { m_isActivated = true; - TreeItem* playlist_root = new TreeItem(this); - - QList list = m_connection.getPlaylists(); - - struct BansheeDbConnection::Playlist playlist; - foreach (playlist, list) { + auto pRootItem = std::make_unique(this); + QList playlists = m_connection.getPlaylists(); + for (const BansheeDbConnection::Playlist& playlist: playlists) { qDebug() << playlist.name; // append the playlist to the child model - playlist_root->appendChild( - new TreeItem(this, playlist.name, playlist.playlistId)); + pRootItem->appendChild(playlist.name, playlist.playlistId); } + m_childModel.setRootItem(std::move(pRootItem)); - if (playlist_root) { - m_childModel.setRootItem(playlist_root); - if (m_isActivated) { - activate(); - } - qDebug() << "Banshee library loaded: success"; + if (m_isActivated) { + activate(); } + qDebug() << "Banshee library loaded: success"; //calls a slot in the sidebarmodel such that 'isLoading' is removed from the feature title. m_title = tr("Banshee"); diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 03994d3678..3a40d0bf48 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -700,7 +700,7 @@ void BasePlaylistFeature::slotTrackSelected(TrackPointer pTrack) { } m_playlistDao.getPlaylistsTrackIsIn(trackId, &m_playlistsSelectedTrackIsIn); - TreeItem* rootItem = m_childModel.getItem(QModelIndex()); + TreeItem* rootItem = m_childModel.getRootItem(); if (rootItem == nullptr) { return; } diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 617ecc4312..548114c3cc 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -54,15 +54,13 @@ BrowseFeature::BrowseFeature(QObject* parent, m_proxyModel.setDynamicSortFilter(true); // The invisible root item of the child model - TreeItem* rootItem = new TreeItem(this); + auto pRootItem = std::make_unique(this); - m_pQuickLinkItem = rootItem->appendChild( - new TreeItem(this, tr("Quick Links"), QUICK_LINK_NODE)); + m_pQuickLinkItem = pRootItem->appendChild(tr("Quick Links"), QUICK_LINK_NODE); // Create the 'devices' shortcut #if defined(__WINDOWS__) - TreeItem* devices_link = rootItem->appendChild( - new TreeItem(this, tr("Devices"), DEVICE_NODE)); + TreeItem* devices_link = pRootItem->appendChild(tr("Devices"), DEVICE_NODE); // show drive letters QFileInfoList drives = QDir::drives(); // show drive letters @@ -82,23 +80,18 @@ BrowseFeature::BrowseFeature(QObject* parent, } TreeItem* driveLetter = devices_link->appendChild( - new TreeItem( - this , - display_path, // Displays C: - drive.filePath())); // Displays C:/ + display_path, // Displays C: + drive.filePath()); // Displays C:/ } #elif defined(__APPLE__) // Apple hides the base Linux file structure But all devices are mounted at // /Volumes - TreeItem* devices_link = rootItem->appendChild( - new TreeItem(this, tr("Devices"), "/Volumes/")); + pRootItem->appendChild(tr("Devices"), "/Volumes/"); #else // LINUX - TreeItem* devices_link = rootItem->appendChild( - new TreeItem(this, tr("Removable Devices"), "/media/")); + pRootItem->appendChild(tr("Removable Devices"), "/media/"); // show root directory on UNIX-based operating systems - TreeItem* root_folder_item = rootItem->appendChild( - new TreeItem(this, QDir::rootPath(), QDir::rootPath())); + pRootItem->appendChild(QDir::rootPath(), QDir::rootPath()); #endif // Just a word about how the TreeItem objects are used for the BrowseFeature: @@ -118,12 +111,11 @@ BrowseFeature::BrowseFeature(QObject* parent, foreach (QString quickLinkPath, m_quickLinkList) { QString name = extractNameFromPath(quickLinkPath); qDebug() << "Appending Quick Link: " << name << "---" << quickLinkPath; - m_pQuickLinkItem->appendChild( - new TreeItem(this, name, quickLinkPath)); + m_pQuickLinkItem->appendChild(name, quickLinkPath); } // initialize the model - m_childModel.setRootItem(rootItem); + m_childModel.setRootItem(std::move(pRootItem)); } BrowseFeature::~BrowseFeature() { @@ -141,7 +133,7 @@ void BrowseFeature::slotAddQuickLink() { QVariant vpath = m_pLastRightClickedItem->getData(); QString spath = vpath.toString(); QString name = extractNameFromPath(spath); - m_pQuickLinkItem->appendChild(new TreeItem(this, name, vpath)); + m_pQuickLinkItem->appendChild(name, vpath); m_quickLinkList.append(spath); saveQuickLinks(); } diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index d82043ceb0..49c4560b8e 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -94,8 +94,8 @@ CrateFeature::CrateFeature(Library* pLibrary, this, SLOT(slotCrateTableChanged(int))); // construct child model - TreeItem *rootItem = new TreeItem(this); - m_childModel.setRootItem(rootItem); + auto pRootItem = std::make_unique(this); + m_childModel.setRootItem(std::move(pRootItem)); constructChildModel(-1); connect(pLibrary, SIGNAL(trackSelected(TrackPointer)), @@ -823,7 +823,7 @@ void CrateFeature::slotTrackSelected(TrackPointer pTrack) { TrackId trackId(pTrack ? pTrack->getId() : TrackId()); m_crateDao.getCratesTrackIsIn(trackId, &m_cratesSelectedTrackIsIn); - TreeItem* rootItem = m_childModel.getItem(QModelIndex()); + TreeItem* rootItem = m_childModel.getRootItem(); if (rootItem == nullptr) { return; } diff --git a/src/library/itunes/itunesfeature.cpp b/src/library/itunes/itunesfeature.cpp index 254a8e50f3..7646fc5a86 100644 --- a/src/library/itunes/itunesfeature.cpp +++ b/src/library/itunes/itunesfeature.cpp @@ -684,7 +684,7 @@ void ITunesFeature::parsePlaylist(QXmlStreamReader &xml, QSqlQuery &query_insert return; } //append the playlist to the child model - root->appendChild(new TreeItem(this, playlistname)); + root->appendChild(playlistname); } // When processing playlist entries, playlist name and id have // already been processed and persisted @@ -732,9 +732,9 @@ void ITunesFeature::clearTable(QString table_name) { } void ITunesFeature::onTrackCollectionLoaded() { - TreeItem* root = m_future.result(); + std::unique_ptr root(m_future.result()); if (root) { - m_childModel.setRootItem(root); + m_childModel.setRootItem(std::move(root)); // Tell the rhythmbox track source that it should re-build its index. m_trackSource->buildIndex(); diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index b83c3f8a18..4a905b4327 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -108,11 +108,11 @@ MixxxLibraryFeature::MixxxLibraryFeature(Library* pLibrary, // These rely on the 'default' track source being present. m_pLibraryTableModel = new LibraryTableModel(this, pTrackCollection, "mixxx.db.model.library"); - TreeItem* pRootItem = new TreeItem(this); - pRootItem->appendChild(new TreeItem(this, kMissingTitle)); - pRootItem->appendChild(new TreeItem(this, kHiddenTitle)); + auto pRootItem = std::make_unique(this); + pRootItem->appendChild(kMissingTitle); + pRootItem->appendChild(kHiddenTitle); - m_childModel.setRootItem(pRootItem); + m_childModel.setRootItem(std::move(pRootItem)); } MixxxLibraryFeature::~MixxxLibraryFeature() { diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index 8cb747b0e2..7ad8f3fc03 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -27,8 +27,8 @@ PlaylistFeature::PlaylistFeature(QObject* parent, "mixxx.db.model.playlist"); //construct child model - TreeItem *rootItem = new TreeItem(this); - m_childModel.setRootItem(rootItem); + auto pRootItem = std::make_unique(this); + m_childModel.setRootItem(std::move(pRootItem)); constructChildModel(-1); } diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index 0998b1e2c8..81dbc2029e 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -233,7 +233,7 @@ TreeItem* RhythmboxFeature::importPlaylists() { QString playlist_name = attr.value("name").toString(); //Construct the childmodel - rootItem->appendChild(new TreeItem(this, playlist_name)); + rootItem->appendChild(playlist_name); //Execute SQL statement query_insert_to_playlists.bindValue(":name", playlist_name); @@ -434,9 +434,9 @@ void RhythmboxFeature::clearTable(QString table_name) { } void RhythmboxFeature::onTrackCollectionLoaded() { - TreeItem* root = m_track_future.result(); + std::unique_ptr root(m_track_future.result()); if (root) { - m_childModel.setRootItem(root); + m_childModel.setRootItem(std::move(root)); // Tell the rhythmbox track source that it should re-build its index. m_trackSource->buildIndex(); diff --git a/src/library/setlogfeature.cpp b/src/library/setlogfeature.cpp index 38ab9ae478..18dbbdef4f 100644 --- a/src/library/setlogfeature.cpp +++ b/src/library/setlogfeature.cpp @@ -21,8 +21,8 @@ SetlogFeature::SetlogFeature(QObject* parent, true); //show all tracks //construct child model - TreeItem *rootItem = new TreeItem(this); - m_childModel.setRootItem(rootItem); + auto pRootItem = std::make_unique(this); + m_childModel.setRootItem(std::move(pRootItem)); constructChildModel(-1); m_pJoinWithPreviousAction = new QAction(tr("Join with previous"), this); diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index a0c461d90c..09a045e435 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -410,14 +410,14 @@ TreeItem* TraktorFeature::parsePlaylists(QXmlStreamReader &xml) { current_path += name; //qDebug() << "Folder: " +current_path << " has parent " << parent->getData().toString(); map.insert(current_path, "FOLDER"); - parent = parent->appendChild(new TreeItem(this, name, current_path)); + parent = parent->appendChild(name, current_path); } else if (type == "PLAYLIST") { current_path += delimiter; current_path += name; //qDebug() << "Playlist: " +current_path << " has parent " << parent->getData().toString(); map.insert(current_path, "PLAYLIST"); - parent->appendChild(new TreeItem(this, name, current_path)); + parent->appendChild(name, current_path); // process all the entries within the playlist 'name' having path 'current_path' parsePlaylistEntries(xml, current_path, query_insert_to_playlists, @@ -598,9 +598,9 @@ QString TraktorFeature::getTraktorMusicDatabase() { } void TraktorFeature::onTrackCollectionLoaded() { - TreeItem* root = m_future.result(); + std::unique_ptr root(m_future.result()); if (root) { - m_childModel.setRootItem(root); + m_childModel.setRootItem(std::move(root)); // Tell the traktor track source that it should re-build its index. m_trackSource->buildIndex(); diff --git a/src/library/treeitem.cpp b/src/library/treeitem.cpp index f0695c9fb8..6736909b26 100644 --- a/src/library/treeitem.cpp +++ b/src/library/treeitem.cpp @@ -61,13 +61,22 @@ TreeItem* TreeItem::child(int row) const { return m_children[row]; } -TreeItem* TreeItem::appendChild(TreeItem* pChild) { +void TreeItem::appendChild(TreeItem* pChild) { DEBUG_ASSERT(feature() != nullptr); DEBUG_ASSERT(pChild != nullptr); DEBUG_ASSERT(pChild->feature() == feature()); DEBUG_ASSERT(!pChild->hasParent()); m_children.append(pChild); pChild->m_pParent = this; +} + +TreeItem* TreeItem::appendChild( + const QString& label, + const QVariant& data) { + auto pNewChild = std::make_unique(feature(), label, data); + TreeItem* pChild = pNewChild.get(); + appendChild(pChild); // transfer ownership + pNewChild.release(); // release ownership (afterwards) return pChild; } @@ -77,19 +86,17 @@ void TreeItem::removeChild(int row) { delete m_children.takeAt(row); } -void TreeItem::insertChildren(const QList& children, int row, int count) { +void TreeItem::insertChildren(QList& children, int row, int count) { DEBUG_ASSERT(feature() != nullptr); DEBUG_ASSERT(count >= 0); DEBUG_ASSERT(count <= children.size()); DEBUG_ASSERT(row >= 0); DEBUG_ASSERT(row <= m_children.size()); - for (int offset = 0; offset < count; ++offset) { - TreeItem* pChild = children[offset]; - DEBUG_ASSERT(pChild != nullptr); - DEBUG_ASSERT(pChild->feature() == feature()); - DEBUG_ASSERT(!pChild->hasParent()); - m_children.insert(row + offset, pChild); - pChild->m_pParent = this; + for (int counter = 0; counter < count; ++counter) { + DEBUG_ASSERT(!children.empty()); + TreeItem* pChild = children.front(); + appendChild(pChild); + children.pop_front(); } } diff --git a/src/library/treeitem.h b/src/library/treeitem.h index 856546b30e..b7b85c7a6c 100644 --- a/src/library/treeitem.h +++ b/src/library/treeitem.h @@ -7,6 +7,9 @@ #include "library/libraryfeature.h" +#include "util/memory.h" + + class TreeItem final { public: static const int kInvalidRow = -1; @@ -58,14 +61,16 @@ class TreeItem final { } TreeItem* child(int row) const; - /** appends a child item to this object **/ - TreeItem* appendChild(TreeItem* pChild); - /** remove a child item at the given index **/ + // single child items + TreeItem* appendChild( + std::unique_ptr pChild); + TreeItem* appendChild( + const QString& label, + const QVariant& data = QVariant()); void removeChild(int row); - /** for dynamic resizing models **/ - void insertChildren(const QList& children, int row, int count); - /** Removes children from the child list starting at index **/ + // multiple child items + void insertChildren(QList& children, int row, int count); // take ownership void removeChildren(int row, int count); @@ -102,6 +107,8 @@ class TreeItem final { } private: + void appendChild(TreeItem* pChild); + LibraryFeature* m_pFeature; TreeItem* m_pParent; diff --git a/src/library/treeitemmodel.cpp b/src/library/treeitemmodel.cpp index d0ce94c6e0..c76b31d8bc 100644 --- a/src/library/treeitemmodel.cpp +++ b/src/library/treeitemmodel.cpp @@ -28,11 +28,10 @@ */ TreeItemModel::TreeItemModel(QObject *parent) : QAbstractItemModel(parent), - m_pRootItem(new TreeItem()) { + m_pRootItem(std::make_unique()) { } TreeItemModel::~TreeItemModel() { - delete m_pRootItem; } //Our Treeview Model supports exactly a single column @@ -42,11 +41,9 @@ int TreeItemModel::columnCount(const QModelIndex &parent) const { } QVariant TreeItemModel::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - return QVariant(); - - if (role != Qt::DisplayRole && role != kDataRole && role != kBoldRole) + if (!index.isValid()) { return QVariant(); + } TreeItem *item = static_cast(index.internalPointer()); @@ -67,7 +64,7 @@ bool TreeItemModel::setData(const QModelIndex &a_rIndex, const QVariant &a_rValue, int a_iRole) { // Get the item referred to by this index. TreeItem *pItem = static_cast(a_rIndex.internalPointer()); - if (pItem == NULL) { + if (pItem == nullptr) { return false; } @@ -91,10 +88,11 @@ bool TreeItemModel::setData(const QModelIndex &a_rIndex, } Qt::ItemFlags TreeItemModel::flags(const QModelIndex &index) const { - if (!index.isValid()) + if (index.isValid()) { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } else { return 0; - - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } } QVariant TreeItemModel::headerData(int section, Qt::Orientation orientation, int role) const { @@ -105,52 +103,50 @@ QVariant TreeItemModel::headerData(int section, Qt::Orientation orientation, int } QModelIndex TreeItemModel::index(int row, int column, const QModelIndex &parent) const { - if (!hasIndex(row, column, parent)) + if (!hasIndex(row, column, parent)) { return QModelIndex(); + } - TreeItem *parentItem = NULL; - - if (!parent.isValid()) - parentItem = m_pRootItem; - else + TreeItem *parentItem; + if (parent.isValid()) { parentItem = static_cast(parent.internalPointer()); + } else { + parentItem = getRootItem(); + } TreeItem *childItem = parentItem->child(row); - if (childItem) + if (childItem) { return createIndex(row, column, childItem); - else + } else { return QModelIndex(); + } } -QModelIndex TreeItemModel::parent(const QModelIndex &index) const { - if (!index.isValid()) +QModelIndex TreeItemModel::parent(const QModelIndex& index) const { + if (!index.isValid()) { return QModelIndex(); + } TreeItem *childItem = static_cast(index.internalPointer()); TreeItem *parentItem = childItem->parent(); - - if (parentItem == m_pRootItem) + if (parentItem == getRootItem()) { return QModelIndex(); - - return createIndex(parentItem->parentRow(), 0, parentItem); + } else { + return createIndex(parentItem->parentRow(), 0, parentItem); + } } -int TreeItemModel::rowCount(const QModelIndex &parent) const { - if (parent.column() > 0) +int TreeItemModel::rowCount(const QModelIndex& parent) const { + if (parent.column() > 0) { return 0; - - TreeItem *parentItem = NULL; - //qDebug() << "parent data: " << parent.getData(); - if (!parent.isValid()) { - parentItem = m_pRootItem; } - else{ - parentItem = static_cast(parent.internalPointer()); + TreeItem* parentItem; + if (parent.isValid()) { + parentItem = static_cast(parent.internalPointer()); + } else { + parentItem = getRootItem(); } - - //qDebug() << "TreeItem data: " << parent.internalPointer(); - return parentItem->childRows(); } @@ -158,10 +154,10 @@ int TreeItemModel::rowCount(const QModelIndex &parent) const { * Populates the model and notifies the view. * Call this method first, before you do call any other methods. */ -void TreeItemModel::setRootItem(TreeItem *item) { - delete m_pRootItem; - m_pRootItem = item; +TreeItem* TreeItemModel::setRootItem(std::unique_ptr pRootItem) { + m_pRootItem = std::move(pRootItem); reset(); + return getRootItem(); } /** @@ -196,10 +192,12 @@ bool TreeItemModel::removeRows(int position, int rows, const QModelIndex &parent TreeItem* TreeItemModel::getItem(const QModelIndex &index) const { if (index.isValid()) { - TreeItem *item = static_cast(index.internalPointer()); - if (item) return item; + TreeItem* pItem = static_cast(index.internalPointer()); + if (pItem != nullptr) { + return pItem; + } } - return m_pRootItem; + return getRootItem(); } void TreeItemModel::triggerRepaint() { diff --git a/src/library/treeitemmodel.h b/src/library/treeitemmodel.h index 2d834971ac..2072c0a32d 100644 --- a/src/library/treeitemmodel.h +++ b/src/library/treeitemmodel.h @@ -6,6 +6,8 @@ #include #include +#include "util/memory.h" + class TreeItem; class TreeItemModel : public QAbstractItemModel { @@ -14,23 +16,29 @@ class TreeItemModel : public QAbstractItemModel { static const int kDataRole = Qt::UserRole; static const int kBoldRole = Qt::UserRole + 1; - TreeItemModel(QObject *parent = 0); - virtual ~TreeItemModel(); + explicit TreeItemModel(QObject *parent = 0); + ~TreeItemModel() override; - virtual QVariant data(const QModelIndex &index, int role) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) 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; // Tell the compiler we don't mean to shadow insertRows. + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()) override; + bool setData(const QModelIndex &a_rIndex, const QVariant &a_rValue, + int a_iRole = Qt::EditRole) override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + using QAbstractItemModel::insertRows; virtual bool insertRows(QList &data, int position, int rows, const QModelIndex &parent = QModelIndex()); - virtual bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); - virtual bool setData(const QModelIndex &a_rIndex, const QVariant &a_rValue, - int a_iRole = Qt::EditRole); - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - void setRootItem(TreeItem *item); + + TreeItem* setRootItem(std::unique_ptr pRootItem); + TreeItem* getRootItem() const { + return m_pRootItem.get(); + } + // Return the underlying TreeItem. // If the index is invalid, the root item is returned. TreeItem* getItem(const QModelIndex &index) const; @@ -38,7 +46,7 @@ class TreeItemModel : public QAbstractItemModel { void triggerRepaint(); private: - TreeItem *m_pRootItem; + std::unique_ptr m_pRootItem; }; #endif -- cgit v1.2.3