vcl/inc/qt5/QtInstanceTreeView.hxx | 20 - vcl/qt5/QtInstanceTreeView.cxx | 433 ++++++++++++++++++------------------- 2 files changed, 225 insertions(+), 228 deletions(-)
New commits: commit c059fc8ab8b1641faddd5746efc9c887540c4f2e Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Sat Apr 26 17:54:59 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sun Apr 27 07:25:02 2025 +0200 tdf#130857 qt weld: Keep col index in QtInstanceTreeView::copy_iterator The model index retrieved via QtInstanceTreeView::modelIndex may have an adjusted column number if the toggle button feature is enabled. However, if copying an iterator, the copy should be equivalent to the source, so use the unmodified QModelIndex from the source instead. While the weld::TreeIter as used in LO doesn't have a concept of columns but references a row (and the column index is passed as an extra param to methods where needed), not modifying the column set in the QModelIndex can still be relevant as QtInstanceTreeIter::equal directly compares the model indices of the two iters, so the copy wouldn't be considered equal if the column index is different. Change-Id: I3050daf17e7453cc62b1071647527ce888fd8a82 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184674 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/qt5/QtInstanceTreeView.cxx b/vcl/qt5/QtInstanceTreeView.cxx index 6caf5d5137cc..d8b39479e879 100644 --- a/vcl/qt5/QtInstanceTreeView.cxx +++ b/vcl/qt5/QtInstanceTreeView.cxx @@ -326,7 +326,8 @@ std::unique_ptr<weld::TreeIter> QtInstanceTreeView::make_iterator(const weld::Tr void QtInstanceTreeView::copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const { - static_cast<QtInstanceTreeIter&>(rDest).setModelIndex(modelIndex(rSource)); + const QModelIndex aModelIndex = static_cast<const QtInstanceTreeIter&>(rSource).modelIndex(); + static_cast<QtInstanceTreeIter&>(rDest).setModelIndex(aModelIndex); } bool QtInstanceTreeView::get_selected(weld::TreeIter* pIter) const commit e51e4438b4c7c05de08048f82870ff46f3a54c50 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Sat Apr 26 17:50:54 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sun Apr 27 07:24:54 2025 +0200 tdf#130857 qt weld: Support non-top-level TreeView items Drop the assert on `pParent` being null in QtInstanceTreeView::insert and instead implement handling for parent items. In most of the cases, the corresponding QAbstractItemModel methods have an optional (defaulting to `QModelIndex()`) param to specify the parent. Pass that param instead of using the default. This builds on top of this previous commit whose commit messages has some more details: Change-Id: Id829ce3a1052f0d8915f0b03a0b0786e2f3586dd Author: Michael Weghorn <m.wegh...@posteo.de> Date: Sat Apr 26 17:00:01 2025 +0200 tdf#130857 qt weld: Move TreeView method logic to overload for iters Change-Id: Ibb1a119e3fc6f0fa878babbe526990df42d78336 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184673 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/vcl/inc/qt5/QtInstanceTreeView.hxx b/vcl/inc/qt5/QtInstanceTreeView.hxx index 26e974c72add..c0684bafdb87 100644 --- a/vcl/inc/qt5/QtInstanceTreeView.hxx +++ b/vcl/inc/qt5/QtInstanceTreeView.hxx @@ -201,11 +201,11 @@ public: using QtInstanceWidget::get_sensitive; private: - QModelIndex modelIndex(int nRow, int nCol = 0) const; + QModelIndex modelIndex(int nRow, int nCol = 0, + const QModelIndex& rParentIndex = QModelIndex()) const; QModelIndex modelIndex(const weld::TreeIter& rIter, int nCol = 0) const; - QtInstanceTreeIter treeIter(int nRow) const; + QtInstanceTreeIter treeIter(int nRow, const QModelIndex& rParentIndex = QModelIndex()) const; QStandardItem* itemFromIndex(const QModelIndex& rIndex) const; - QModelIndex toggleButtonModelIndex(int nRow) const; QModelIndex toggleButtonModelIndex(const weld::TreeIter& rIter) const; QModelIndex firstTextColumnModelIndex(const weld::TreeIter& rIter) const; static QAbstractItemView::SelectionMode mapSelectionMode(SelectionMode eMode); diff --git a/vcl/qt5/QtInstanceTreeView.cxx b/vcl/qt5/QtInstanceTreeView.cxx index 42ec94c8d756..6caf5d5137cc 100644 --- a/vcl/qt5/QtInstanceTreeView.cxx +++ b/vcl/qt5/QtInstanceTreeView.cxx @@ -42,22 +42,21 @@ void QtInstanceTreeView::insert(const weld::TreeIter* pParent, int nPos, const O VirtualDevice* pImageSurface, bool bChildrenOnDemand, weld::TreeIter* pRet) { - // Only specific subset of parameters handled so far; - // assert only these are used at the moment and implement remaining cases - // when needed to support more dialogs, then adjust/remove asserts below - assert(!pParent && "Not implemented yet"); assert(!bChildrenOnDemand && "Not implemented yet"); // avoid -Werror=unused-parameter for release build - (void)pParent; (void)bChildrenOnDemand; SolarMutexGuard g; GetQtInstance().RunInMainThread([&] { + const QModelIndex aParentIndex + = pParent ? static_cast<const QtInstanceTreeIter*>(pParent)->modelIndex() + : QModelIndex(); + if (nPos == -1) - nPos = m_pModel->rowCount(); - m_pModel->insertRow(nPos); + nPos = m_pModel->rowCount(aParentIndex); + m_pModel->insertRow(nPos, aParentIndex); - const QModelIndex aIndex = modelIndex(nPos); + const QModelIndex aIndex = modelIndex(nPos, 0, aParentIndex); QStandardItem* pItem = itemFromIndex(aIndex); if (pStr) pItem->setText(toQString(*pStr)); @@ -70,7 +69,7 @@ void QtInstanceTreeView::insert(const weld::TreeIter* pParent, int nPos, const O pItem->setIcon(toQPixmap(*pImageSurface)); if (m_bExtraToggleButtonColumnEnabled) - itemFromIndex(toggleButtonModelIndex(nPos))->setCheckable(true); + itemFromIndex(toggleButtonModelIndex(QtInstanceTreeIter(aIndex)))->setCheckable(true); if (pRet) static_cast<QtInstanceTreeIter*>(pRet)->setModelIndex(aIndex); @@ -971,9 +970,10 @@ QAbstractItemView::SelectionMode QtInstanceTreeView::mapSelectionMode(SelectionM } } -QModelIndex QtInstanceTreeView::modelIndex(int nRow, int nCol) const +QModelIndex QtInstanceTreeView::modelIndex(int nRow, int nCol, + const QModelIndex& rParentIndex) const { - return modelIndex(treeIter(nRow), nCol); + return modelIndex(treeIter(nRow, rParentIndex), nCol); } QModelIndex QtInstanceTreeView::modelIndex(const weld::TreeIter& rIter, int nCol) const @@ -985,9 +985,9 @@ QModelIndex QtInstanceTreeView::modelIndex(const weld::TreeIter& rIter, int nCol return m_pModel->index(aModelIndex.row(), nCol, aModelIndex.parent()); } -QtInstanceTreeIter QtInstanceTreeView::treeIter(int nRow) const +QtInstanceTreeIter QtInstanceTreeView::treeIter(int nRow, const QModelIndex& rParentIndex) const { - return QtInstanceTreeIter(m_pModel->index(nRow, 0)); + return QtInstanceTreeIter(m_pModel->index(nRow, 0, rParentIndex)); } QStandardItem* QtInstanceTreeView::itemFromIndex(const QModelIndex& rIndex) const @@ -996,11 +996,6 @@ QStandardItem* QtInstanceTreeView::itemFromIndex(const QModelIndex& rIndex) cons return m_pSourceModel->itemFromIndex(aSourceIndex); } -QModelIndex QtInstanceTreeView::toggleButtonModelIndex(int nRow) const -{ - return toggleButtonModelIndex(treeIter(nRow)); -} - QModelIndex QtInstanceTreeView::toggleButtonModelIndex(const weld::TreeIter& rIter) const { assert(m_bExtraToggleButtonColumnEnabled && "Special toggle button column is not enabled"); commit ed8a7a64a7f4d86c02dc3d3080179a6c80aa38db Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Sat Apr 26 17:00:01 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sun Apr 27 07:24:48 2025 +0200 tdf#130857 qt weld: Move TreeView method logic to overload for iters weld::TreeView has a lot of methods that have two overloads where one takes a row index and the other takes a weld::TreeIter. In order to have to implement the logic in only one place, QtInstanceTreeView so far implemented the logic in the overload taking the row index, and the overload taking the weld::TreeIter would forward to the overload taking the row index. This was fine so far. As long the hierarchical structure of "actual" trees wasn't supported and all instances of QtInstanceTreeView where therefore just tables where all tree view items are top level items (s.a. the assert on `pParent` being null in QtInstanceTreeView::insert). However, in order to support non-top-level items, i.e. items that are children of other items, the approach needs to change because the row-index based overload only handles top-level items while a weld::TreeIter can also represent non-toplevel items. In order to prepare for that, switch the approach to be the other way around: Move the logic from the overload taking a row index to the overload taking a weld::TreeIter and let the one taking a row index call the one taking a weld::TreeIter instead. Introduce new helper method QtInstanceTreeView::treeIter to retrieve a TreeIter for a given (top-level) row index and adjust/add other helper methods as needed now. While at it, already start passing the QModelIndex::parent() [1] as an additional param to some of the called methods (instead of using the default, which would indicate they are top-level items). While this doesn't make any difference yet (as long as all items are top-level items), it helps prepare for supporting non-top-level items in the future. No change of behavior in any of the already supported dialogs is intended by this change. [1] https://doc.qt.io/qt-6/qmodelindex.html#parent Change-Id: Id829ce3a1052f0d8915f0b03a0b0786e2f3586dd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184672 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/vcl/inc/qt5/QtInstanceTreeView.hxx b/vcl/inc/qt5/QtInstanceTreeView.hxx index cbf83c755969..26e974c72add 100644 --- a/vcl/inc/qt5/QtInstanceTreeView.hxx +++ b/vcl/inc/qt5/QtInstanceTreeView.hxx @@ -9,6 +9,7 @@ #pragma once +#include "QtInstanceTreeIter.hxx" #include "QtInstanceWidget.hxx" #include <QtCore/QSortFilterProxyModel> @@ -64,12 +65,12 @@ public: virtual void set_image(int nRow, VirtualDevice& rImage, int nCol = -1) override; virtual void set_image(int nRow, const css::uno::Reference<css::graphic::XGraphic>& rImage, int nCol = -1) override; - virtual void set_text_emphasis(int row, bool bOn, int col) override; - virtual bool get_text_emphasis(int row, int col) const override; - virtual void set_text_align(int row, double fAlign, int col) override; + virtual void set_text_emphasis(int nRow, bool bOn, int nCol) override; + virtual bool get_text_emphasis(int nRow, int nCol) const override; + virtual void set_text_align(int nRow, double fAlign, int nCol) override; virtual void swap(int nPos1, int nPos2) override; virtual std::vector<int> get_selected_rows() const override; - virtual void set_font_color(int pos, const Color& rColor) override; + virtual void set_font_color(int nPos, const Color& rColor) override; virtual void scroll_to_row(int nRow) override; virtual bool is_selected(int nPos) const override; virtual int get_cursor_index() const override; @@ -110,7 +111,7 @@ public: virtual void set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int nCol) override; virtual bool get_text_emphasis(const weld::TreeIter& rIter, int nCol) const override; virtual void set_text_align(const weld::TreeIter& rIter, double fAlign, int nCol) override; - virtual void set_toggle(const weld::TreeIter& rIter, TriState bOn, int nCol = -1) override; + virtual void set_toggle(const weld::TreeIter& rIter, TriState eState, int nCol = -1) override; virtual TriState get_toggle(const weld::TreeIter& rIter, int nCol = -1) const override; virtual OUString get_text(const weld::TreeIter& rIter, int nCol = -1) const override; virtual void set_id(const weld::TreeIter& rIter, const OUString& rId) override; @@ -202,10 +203,11 @@ public: private: QModelIndex modelIndex(int nRow, int nCol = 0) const; QModelIndex modelIndex(const weld::TreeIter& rIter, int nCol = 0) const; - static int rowIndex(const weld::TreeIter& rIter); + QtInstanceTreeIter treeIter(int nRow) const; QStandardItem* itemFromIndex(const QModelIndex& rIndex) const; QModelIndex toggleButtonModelIndex(int nRow) const; - QModelIndex firstTextColumnModelIndex(int nRow) const; + QModelIndex toggleButtonModelIndex(const weld::TreeIter& rIter) const; + QModelIndex firstTextColumnModelIndex(const weld::TreeIter& rIter) const; static QAbstractItemView::SelectionMode mapSelectionMode(SelectionMode eMode); static Qt::CheckState toQtCheckState(TriState eTristate); diff --git a/vcl/qt5/QtInstanceTreeView.cxx b/vcl/qt5/QtInstanceTreeView.cxx index 545c23b24c8d..42ec94c8d756 100644 --- a/vcl/qt5/QtInstanceTreeView.cxx +++ b/vcl/qt5/QtInstanceTreeView.cxx @@ -10,8 +10,6 @@ #include <QtInstanceTreeView.hxx> #include <QtInstanceTreeView.moc> -#include <QtInstanceTreeIter.hxx> - #include <vcl/qt/QtUtils.hxx> #include <QtWidgets/QHeaderView> @@ -148,188 +146,74 @@ int QtInstanceTreeView::get_selected_index() const return nIndex; } -void QtInstanceTreeView::select(int nPos) -{ - SolarMutexGuard g; - GetQtInstance().RunInMainThread([&] { - QItemSelectionModel::SelectionFlags eFlags - = QItemSelectionModel::Select | QItemSelectionModel::Rows; - if (m_pTreeView->selectionMode() == QAbstractItemView::SingleSelection) - eFlags |= QItemSelectionModel::Clear; - - m_pSelectionModel->select(modelIndex(nPos), eFlags); - }); -} - -void QtInstanceTreeView::unselect(int nPos) -{ - SolarMutexGuard g; - GetQtInstance().RunInMainThread( - [&] { m_pSelectionModel->select(modelIndex(nPos), QItemSelectionModel::Deselect); }); -} +void QtInstanceTreeView::select(int nPos) { select(treeIter(nPos)); } -void QtInstanceTreeView::remove(int nPos) -{ - SolarMutexGuard g; +void QtInstanceTreeView::unselect(int nPos) { unselect(treeIter(nPos)); } - GetQtInstance().RunInMainThread([&] { m_pModel->removeRow(nPos); }); -} +void QtInstanceTreeView::remove(int nPos) { remove(treeIter(nPos)); } OUString QtInstanceTreeView::get_text(int nRow, int nCol) const { - SolarMutexGuard g; - - OUString sText; - GetQtInstance().RunInMainThread([&] { - const QModelIndex aIndex - = nCol == -1 ? firstTextColumnModelIndex(nRow) : modelIndex(nRow, nCol); - const QVariant aData = m_pModel->data(aIndex); - if (aData.canConvert<QString>()) - sText = toOUString(aData.toString()); - }); - - return sText; + return get_text(treeIter(nRow), nCol); } void QtInstanceTreeView::set_text(int nRow, const OUString& rText, int nCol) { - SolarMutexGuard g; - - GetQtInstance().RunInMainThread([&] { - const QModelIndex aIndex - = nCol == -1 ? firstTextColumnModelIndex(nRow) : modelIndex(nRow, nCol); - m_pModel->setData(aIndex, toQString(rText)); - }); + set_text(treeIter(nRow), rText, nCol); } void QtInstanceTreeView::set_sensitive(int nRow, bool bSensitive, int nCol) { - SolarMutexGuard g; - - GetQtInstance().RunInMainThread([&] { - // column index -1 means "all columns" - if (nCol == -1) - { - for (int i = 0; i < m_pModel->columnCount(); ++i) - set_sensitive(nRow, bSensitive, i); - return; - } - - QStandardItem* pItem = itemFromIndex(modelIndex(nRow, nCol)); - if (pItem) - { - if (bSensitive) - pItem->setFlags(pItem->flags() | Qt::ItemIsEnabled); - else - pItem->setFlags(pItem->flags() & ~Qt::ItemIsEnabled); - } - }); + set_sensitive(treeIter(nRow), bSensitive, nCol); } bool QtInstanceTreeView::get_sensitive(int nRow, int nCol) const { - SolarMutexGuard g; - - bool bSensitive = false; - GetQtInstance().RunInMainThread([&] { - QStandardItem* pItem = itemFromIndex(modelIndex(nRow, nCol)); - if (pItem) - bSensitive = pItem->flags() & Qt::ItemIsEnabled; - }); - - return bSensitive; + return get_sensitive(treeIter(nRow), nCol); } -void QtInstanceTreeView::set_id(int nRow, const OUString& rId) -{ - SolarMutexGuard g; - - GetQtInstance().RunInMainThread([&] { - QModelIndex aIndex = modelIndex(nRow); - m_pModel->setData(aIndex, toQString(rId), ROLE_ID); - }); -} +void QtInstanceTreeView::set_id(int nRow, const OUString& rId) { set_id(treeIter(nRow), rId); } void QtInstanceTreeView::set_toggle(int nRow, TriState eState, int nCol) { - SolarMutexGuard g; - - GetQtInstance().RunInMainThread([&] { - QModelIndex aIndex = nCol == -1 ? toggleButtonModelIndex(nRow) : modelIndex(nRow, nCol); - itemFromIndex(aIndex)->setCheckState(toQtCheckState(eState)); - }); + set_toggle(treeIter(nRow), eState, nCol); } TriState QtInstanceTreeView::get_toggle(int nRow, int nCol) const { - SolarMutexGuard g; - - TriState eState = TRISTATE_INDET; - GetQtInstance().RunInMainThread([&] { - QModelIndex aIndex = nCol == -1 ? toggleButtonModelIndex(nRow) : modelIndex(nRow, nCol); - eState = toVclTriState(itemFromIndex(aIndex)->checkState()); - }); - - return eState; + return get_toggle(treeIter(nRow), nCol); } void QtInstanceTreeView::set_image(int nRow, const OUString& rImage, int nCol) { - assert(nCol != -1 && "Special column -1 not handled yet"); - - SolarMutexGuard g; - - GetQtInstance().RunInMainThread([&] { - if (rImage.isEmpty()) - return; - QModelIndex aIndex = modelIndex(nRow, nCol); - QIcon aIcon = loadQPixmapIcon(rImage); - m_pModel->setData(aIndex, aIcon, Qt::DecorationRole); - }); + set_image(treeIter(nRow), rImage, nCol); } void QtInstanceTreeView::set_image(int nRow, VirtualDevice& rImage, int nCol) { - assert(nCol != -1 && "Special column -1 not handled yet"); - - SolarMutexGuard g; - - GetQtInstance().RunInMainThread([&] { - QModelIndex aIndex = modelIndex(nRow, nCol); - QIcon aIcon = toQPixmap(rImage); - m_pModel->setData(aIndex, aIcon, Qt::DecorationRole); - }); + set_image(treeIter(nRow), rImage, nCol); } void QtInstanceTreeView::set_image(int nRow, const css::uno::Reference<css::graphic::XGraphic>& rImage, int nCol) { - assert(nCol != -1 && "Special column -1 not handled yet"); - - SolarMutexGuard g; - - GetQtInstance().RunInMainThread([&] { - QModelIndex aIndex = modelIndex(nRow, nCol); - QIcon aIcon = toQPixmap(rImage); - m_pModel->setData(aIndex, aIcon, Qt::DecorationRole); - }); + set_image(treeIter(nRow), rImage, nCol); } -void QtInstanceTreeView::set_text_emphasis(int, bool, int) +void QtInstanceTreeView::set_text_emphasis(int nRow, bool bOn, int nCol) { - assert(false && "Not implemented yet"); + return set_text_emphasis(treeIter(nRow), bOn, nCol); } -bool QtInstanceTreeView::get_text_emphasis(int, int) const +bool QtInstanceTreeView::get_text_emphasis(int nRow, int nCol) const { - assert(false && "Not implemented yet"); - return false; + return get_text_emphasis(treeIter(nRow), nCol); } -void QtInstanceTreeView::set_text_align(int, double, int) +void QtInstanceTreeView::set_text_align(int nRow, double fAlign, int nCol) { - assert(false && "Not implemented yet"); + return set_text_align(treeIter(nRow), fAlign, nCol); } void QtInstanceTreeView::swap(int nPos1, int nPos2) @@ -373,26 +257,14 @@ std::vector<int> QtInstanceTreeView::get_selected_rows() const return aSelectedRows; } -void QtInstanceTreeView::set_font_color(int, const Color&) +void QtInstanceTreeView::set_font_color(int nPos, const Color& rColor) { - assert(false && "Not implemented yet"); -} - -void QtInstanceTreeView::scroll_to_row(int nRow) -{ - SolarMutexGuard g; - GetQtInstance().RunInMainThread([&] { m_pTreeView->scrollTo(modelIndex(nRow)); }); + set_font_color(treeIter(nPos), rColor); } -bool QtInstanceTreeView::is_selected(int nPos) const -{ - SolarMutexGuard g; +void QtInstanceTreeView::scroll_to_row(int nRow) { scroll_to_row(treeIter(nRow)); } - bool bSelected = false; - GetQtInstance().RunInMainThread([&] { bSelected = m_pSelectionModel->isRowSelected(nPos); }); - - return bSelected; -} +bool QtInstanceTreeView::is_selected(int nPos) const { return is_selected(treeIter(nPos)); } int QtInstanceTreeView::get_cursor_index() const { @@ -409,13 +281,7 @@ int QtInstanceTreeView::get_cursor_index() const return nIndex; } -void QtInstanceTreeView::set_cursor(int nPos) -{ - SolarMutexGuard g; - - GetQtInstance().RunInMainThread( - [&] { m_pSelectionModel->setCurrentIndex(modelIndex(nPos), QItemSelectionModel::Select); }); -} +void QtInstanceTreeView::set_cursor(int nPos) { set_cursor(treeIter(nPos)); } int QtInstanceTreeView::find_text(const OUString& rText) const { @@ -432,19 +298,7 @@ int QtInstanceTreeView::find_text(const OUString& rText) const return nIndex; } -OUString QtInstanceTreeView::get_id(int nPos) const -{ - SolarMutexGuard g; - - OUString sId; - GetQtInstance().RunInMainThread([&] { - QVariant aRoleData = m_pModel->data(modelIndex(nPos), ROLE_ID); - if (aRoleData.canConvert<QString>()) - sId = toOUString(aRoleData.toString()); - }); - - return sId; -} +OUString QtInstanceTreeView::get_id(int nPos) const { return get_id(treeIter(nPos)); } int QtInstanceTreeView::find_id(const OUString& rId) const { @@ -499,7 +353,14 @@ bool QtInstanceTreeView::get_cursor(weld::TreeIter*) const return false; } -void QtInstanceTreeView::set_cursor(const weld::TreeIter& rIter) { set_cursor(rowIndex(rIter)); } +void QtInstanceTreeView::set_cursor(const weld::TreeIter& rIter) +{ + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + m_pSelectionModel->setCurrentIndex(modelIndex(rIter), QItemSelectionModel::Select); + }); +} bool QtInstanceTreeView::get_iter_first(weld::TreeIter& rIter) const { @@ -575,11 +436,37 @@ int QtInstanceTreeView::iter_n_children(const weld::TreeIter&) const return -1; } -void QtInstanceTreeView::remove(const weld::TreeIter& rIter) { remove(rowIndex(rIter)); } +void QtInstanceTreeView::remove(const weld::TreeIter& rIter) +{ + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + const QModelIndex aIndex = modelIndex(rIter); + m_pModel->removeRow(aIndex.row(), aIndex.parent()); + }); +} + +void QtInstanceTreeView::select(const weld::TreeIter& rIter) +{ + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + QItemSelectionModel::SelectionFlags eFlags + = QItemSelectionModel::Select | QItemSelectionModel::Rows; + if (m_pTreeView->selectionMode() == QAbstractItemView::SingleSelection) + eFlags |= QItemSelectionModel::Clear; + + m_pSelectionModel->select(modelIndex(rIter), eFlags); + }); +} -void QtInstanceTreeView::select(const weld::TreeIter& rIter) { select(rowIndex(rIter)); } +void QtInstanceTreeView::unselect(const weld::TreeIter& rIter) +{ + SolarMutexGuard g; -void QtInstanceTreeView::unselect(const weld::TreeIter& rIter) { unselect(rowIndex(rIter)); } + GetQtInstance().RunInMainThread( + [&] { m_pSelectionModel->select(modelIndex(rIter), QItemSelectionModel::Deselect); }); +} void QtInstanceTreeView::set_extra_row_indent(const weld::TreeIter&, int) { @@ -588,89 +475,194 @@ void QtInstanceTreeView::set_extra_row_indent(const weld::TreeIter&, int) void QtInstanceTreeView::set_text(const weld::TreeIter& rIter, const OUString& rStr, int nCol) { - set_text(rowIndex(rIter), rStr, nCol); + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + const QModelIndex aIndex + = nCol == -1 ? firstTextColumnModelIndex(rIter) : modelIndex(rIter, nCol); + m_pModel->setData(aIndex, toQString(rStr)); + }); } void QtInstanceTreeView::set_sensitive(const weld::TreeIter& rIter, bool bSensitive, int nCol) { - set_sensitive(rowIndex(rIter), bSensitive, nCol); + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + // column index -1 means "all columns" + if (nCol == -1) + { + for (int i = 0; i < m_pModel->columnCount(); ++i) + set_sensitive(rIter, bSensitive, i); + return; + } + + QStandardItem* pItem = itemFromIndex(modelIndex(rIter, nCol)); + if (pItem) + { + if (bSensitive) + pItem->setFlags(pItem->flags() | Qt::ItemIsEnabled); + else + pItem->setFlags(pItem->flags() & ~Qt::ItemIsEnabled); + } + }); } bool QtInstanceTreeView::get_sensitive(const weld::TreeIter& rIter, int nCol) const { - return get_sensitive(rowIndex(rIter), nCol); + SolarMutexGuard g; + + bool bSensitive = false; + GetQtInstance().RunInMainThread([&] { + QStandardItem* pItem = itemFromIndex(modelIndex(rIter, nCol)); + if (pItem) + bSensitive = pItem->flags() & Qt::ItemIsEnabled; + }); + + return bSensitive; } -void QtInstanceTreeView::set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int nCol) +void QtInstanceTreeView::set_text_emphasis(const weld::TreeIter&, bool, int) { - set_text_emphasis(rowIndex(rIter), bOn, nCol); + assert(false && "Not implemented yet"); } -bool QtInstanceTreeView::get_text_emphasis(const weld::TreeIter& rIter, int nCol) const +bool QtInstanceTreeView::get_text_emphasis(const weld::TreeIter&, int) const { - return get_text_emphasis(rowIndex(rIter), nCol); + assert(false && "Not implemented yet"); + return false; } -void QtInstanceTreeView::set_text_align(const weld::TreeIter& rIter, double fAlign, int nCol) +void QtInstanceTreeView::set_text_align(const weld::TreeIter&, double, int) { - return set_text_align(rowIndex(rIter), fAlign, nCol); + assert(false && "Not implemented yet"); } -void QtInstanceTreeView::set_toggle(const weld::TreeIter& rIter, TriState bOn, int nCol) +void QtInstanceTreeView::set_toggle(const weld::TreeIter& rIter, TriState eState, int nCol) { - set_toggle(rowIndex(rIter), bOn, nCol); + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + QModelIndex aIndex = nCol == -1 ? toggleButtonModelIndex(rIter) : modelIndex(rIter, nCol); + itemFromIndex(aIndex)->setCheckState(toQtCheckState(eState)); + }); } TriState QtInstanceTreeView::get_toggle(const weld::TreeIter& rIter, int nCol) const { - return get_toggle(rowIndex(rIter), nCol); + SolarMutexGuard g; + + TriState eState = TRISTATE_INDET; + GetQtInstance().RunInMainThread([&] { + QModelIndex aIndex = nCol == -1 ? toggleButtonModelIndex(rIter) : modelIndex(rIter, nCol); + eState = toVclTriState(itemFromIndex(aIndex)->checkState()); + }); + + return eState; } OUString QtInstanceTreeView::get_text(const weld::TreeIter& rIter, int nCol) const { - return get_text(rowIndex(rIter), nCol); + SolarMutexGuard g; + + OUString sText; + GetQtInstance().RunInMainThread([&] { + const QModelIndex aIndex + = nCol == -1 ? firstTextColumnModelIndex(rIter) : modelIndex(rIter, nCol); + const QVariant aData = m_pModel->data(aIndex); + if (aData.canConvert<QString>()) + sText = toOUString(aData.toString()); + }); + + return sText; } void QtInstanceTreeView::set_id(const weld::TreeIter& rIter, const OUString& rId) { - set_id(rowIndex(rIter), rId); + SolarMutexGuard g; + + GetQtInstance().RunInMainThread( + [&] { m_pModel->setData(modelIndex(rIter), toQString(rId), ROLE_ID); }); } OUString QtInstanceTreeView::get_id(const weld::TreeIter& rIter) const { - return get_id(rowIndex(rIter)); + SolarMutexGuard g; + + OUString sId; + GetQtInstance().RunInMainThread([&] { + QVariant aRoleData = m_pModel->data(modelIndex(rIter), ROLE_ID); + if (aRoleData.canConvert<QString>()) + sId = toOUString(aRoleData.toString()); + }); + + return sId; } void QtInstanceTreeView::set_image(const weld::TreeIter& rIter, const OUString& rImage, int nCol) { - set_image(rowIndex(rIter), rImage, nCol); + assert(nCol != -1 && "Special column -1 not handled yet"); + + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + if (rImage.isEmpty()) + return; + QModelIndex aIndex = modelIndex(rIter, nCol); + QIcon aIcon = loadQPixmapIcon(rImage); + m_pModel->setData(aIndex, aIcon, Qt::DecorationRole); + }); } void QtInstanceTreeView::set_image(const weld::TreeIter& rIter, VirtualDevice& rImage, int nCol) { - set_image(rowIndex(rIter), rImage, nCol); + assert(nCol != -1 && "Special column -1 not handled yet"); + + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + QModelIndex aIndex = modelIndex(rIter, nCol); + QIcon aIcon = toQPixmap(rImage); + m_pModel->setData(aIndex, aIcon, Qt::DecorationRole); + }); } void QtInstanceTreeView::set_image(const weld::TreeIter& rIter, const css::uno::Reference<css::graphic::XGraphic>& rImage, int nCol) { - set_image(rowIndex(rIter), rImage, nCol); + assert(nCol != -1 && "Special column -1 not handled yet"); + + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + QModelIndex aIndex = modelIndex(rIter, nCol); + QIcon aIcon = toQPixmap(rImage); + m_pModel->setData(aIndex, aIcon, Qt::DecorationRole); + }); } -void QtInstanceTreeView::set_font_color(const weld::TreeIter& rIter, const Color& rColor) +void QtInstanceTreeView::set_font_color(const weld::TreeIter&, const Color&) { - set_font_color(rowIndex(rIter), rColor); + assert(false && "Not implemented yet"); } void QtInstanceTreeView::scroll_to_row(const weld::TreeIter& rIter) { - scroll_to_row(rowIndex(rIter)); + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { m_pTreeView->scrollTo(modelIndex(rIter)); }); } bool QtInstanceTreeView::is_selected(const weld::TreeIter& rIter) const { - return is_selected(rowIndex(rIter)); + SolarMutexGuard g; + + bool bSelected = false; + GetQtInstance().RunInMainThread( + [&] { bSelected = m_pSelectionModel->isSelected(modelIndex(rIter)); }); + + return bSelected; } void QtInstanceTreeView::move_subtree(weld::TreeIter&, const weld::TreeIter*, int) @@ -981,20 +973,21 @@ QAbstractItemView::SelectionMode QtInstanceTreeView::mapSelectionMode(SelectionM QModelIndex QtInstanceTreeView::modelIndex(int nRow, int nCol) const { - if (m_bExtraToggleButtonColumnEnabled) - nCol += 1; - return m_pModel->index(nRow, nCol); + return modelIndex(treeIter(nRow), nCol); } QModelIndex QtInstanceTreeView::modelIndex(const weld::TreeIter& rIter, int nCol) const { - return modelIndex(rowIndex(rIter), nCol); + if (m_bExtraToggleButtonColumnEnabled) + nCol += 1; + + QModelIndex aModelIndex = static_cast<const QtInstanceTreeIter&>(rIter).modelIndex(); + return m_pModel->index(aModelIndex.row(), nCol, aModelIndex.parent()); } -int QtInstanceTreeView::rowIndex(const weld::TreeIter& rIter) +QtInstanceTreeIter QtInstanceTreeView::treeIter(int nRow) const { - QModelIndex aModelIndex = static_cast<const QtInstanceTreeIter&>(rIter).modelIndex(); - return aModelIndex.row(); + return QtInstanceTreeIter(m_pModel->index(nRow, 0)); } QStandardItem* QtInstanceTreeView::itemFromIndex(const QModelIndex& rIndex) const @@ -1004,18 +997,24 @@ QStandardItem* QtInstanceTreeView::itemFromIndex(const QModelIndex& rIndex) cons } QModelIndex QtInstanceTreeView::toggleButtonModelIndex(int nRow) const +{ + return toggleButtonModelIndex(treeIter(nRow)); +} + +QModelIndex QtInstanceTreeView::toggleButtonModelIndex(const weld::TreeIter& rIter) const { assert(m_bExtraToggleButtonColumnEnabled && "Special toggle button column is not enabled"); + const QModelIndex aIndex = modelIndex(rIter); // Special toggle button column is always the first one - return m_pModel->index(nRow, 0); + return m_pModel->index(aIndex.row(), 0, aIndex.parent()); } -QModelIndex QtInstanceTreeView::firstTextColumnModelIndex(int nRow) const +QModelIndex QtInstanceTreeView::firstTextColumnModelIndex(const weld::TreeIter& rIter) const { for (int i = 0; i < m_pModel->columnCount(); i++) { - const QModelIndex aIndex = modelIndex(nRow, i); + const QModelIndex aIndex = modelIndex(rIter, i); QVariant data = m_pModel->data(aIndex, Qt::DisplayRole); if (data.canConvert<QString>()) return aIndex;