From f66e2f508f6a4a67740a207162dda9460b90cfe2 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Mon, 9 Nov 2020 17:38:16 +0100 Subject: [PATCH] QmlDesigner: Fix navigator selection issue * Fix navigator selection issue caused by clicking on icon columns of a locked item * Fix visibility icon in icon font * Remove redundant selection behavior call Change-Id: I03c97b22d92bcf0760b2b9ec627609624a0b3695 Reviewed-by: Thomas Hartmann --- .../imports/StudioTheme/icons.ttf | Bin 15684 -> 15660 bytes .../navigator/iconcheckboxitemdelegate.cpp | 75 +++++++++++++++--- .../navigator/iconcheckboxitemdelegate.h | 6 ++ .../navigator/navigatortreemodel.cpp | 15 ++-- .../components/navigator/navigatorview.cpp | 1 - .../components/navigator/navigatorwidget.cpp | 4 +- 6 files changed, 80 insertions(+), 21 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf index 993db3896f0773b72ade1d40f20f3d2293e960e4..0c4d237c0e2df47eed767b977dea24d02a37dd59 100644 GIT binary patch delta 678 zcmX?7wWdmffsuiMftR6yftew|%`L=t;)K$x3=Fmc6D92HIT#oiIMQ<}(~kW$zr(=5 zGKGObFCrr~F-6X7H%RUd0|SFuMn-BP*RTJR7#J8u7#J8-GIC2QghV*q7#J9LFfcHj z$;nSn6yxCf!@$6NhJk_MSZ-oP0mB-GMGOp#77Ppw3VDgSsmJpezA!Kty1Odzpbj%k%&P1G@*5Vz`<26F~`26u+&$r5^UjI5K*^_1!v z&GlH6mDt72jE%%ZMcA2-@ba?h=UeSmIF=IcF(o5Tot=Y&O)uYShy3xBc$4g~5Nl)6 ze@1~`&Z_!W0U{yUsUilU;f1Z7jK<31;?Y%{Mk->P9P{Oc4MW3=&D;ZBRP`+bMHy{{ z1UU3VWST!vy}_9R8#aeNf6Pp)=`)*$DwS@ zH!)X0Oxf5*K12~L2vx(t#vsFB#C(QHje&uIkwKNgmcgCDpMimsQB_HgSzXOk&BWY} z)!0amSzOFeOoW|}RaK6~$c`E8RX!FLB{fqMkbgzgl-$@v#Ei^L7$5)J#u)9|mz<&^ zz{JkZChHKKTy2BK|EDdYA0AemQyd;@C@iKE8CqDaugZ9E@>+dqa}F6RGgAd! zb6;gaCU#MFb{T6k6NMil8aCPr3Od$WBBH8x+KQrTnnnt<0xc~A1B?2N-HeUhHnSV- XU}3bJe89wx(Q@;D6DtmGq^Jb|tiq(j delta 714 zcmZ2eb)-syfsuiMftR6yftew|%`L=tV%^$G1_oP=i4ykp3JeSk9O*fgX<3QMu?!3> zQy3WZ3Nlg?Q{+@WtzlqbxWmA}V3v`Qn#lF*|0D(mMiB-E29=E5k_sUaPHP4R#vKd{ z3}ma&Ij7Ka@Y?atEaf{89SV}boh5sL6KFM^9L6yOR!GXbpA#SpSo*X0FWOF^G zdS-Jy7G))NaWi8hF;NkA=A8lpZ2I|DI~9(l#CuH6j8kW4XJ^yTv)UnlJSAQ)Ho)7? zNLA>cvA>tIs=if#NJw_7h(TC*VGBF6v9h>$bQPzOir6M)7c*5}VZ+eyB6IfuXH|X6 zKvBjpAps8k5V<8vo3!+8z12C{Mc6s?L+Zf-LW=4->MBCFaAxpj2xVa4WK>bo zV^&u)RWmU+F}GtgHj-l&7ZVi|VHaWNV^)=8HL_zd*JD#w;$seDQBpHC0eN0TO^HoJ z%*f1y@$tWHj0?K@l2cR!nAq8wxI`^1LW0tbT;U=DDk;f-rwFLoy9dU_#07fTstfSS zo0zz{25FcThlT4i?wdSUU)r9Lkz3SI(@05N$HG@hh>?+9gq@L5NXggYjDUinrmC2j zil%{*0I#&BvYM2jqPDHZyg*CKz`&w@V>e@CH-^pc^>?r^8ckkdV#jHuYiOuzWME`4 Rxxh4Fv%Tpfc5bBT2LPPNsF45w diff --git a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp index 9c3aab36870..953dfdf1937 100644 --- a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp @@ -96,26 +96,75 @@ void IconCheckboxItemDelegate::paint(QPainter *painter, if (!(styleOption.state & QStyle::State_MouseOver) && !checked) return; - if (rowIsPropertyRole(modelIndex.model(), modelIndex)) - return; // Do not paint icons for property rows + if (rowIsPropertyRole(modelIndex.model(), modelIndex) || getModelNode(modelIndex).isRootNode()) + return; // Do not paint icons for property rows or root node - if (!getModelNode(modelIndex).isRootNode()) { - QWindow *window = dynamic_cast(painter->device())->window()->windowHandle(); - QTC_ASSERT(window, return); + QWindow *window = dynamic_cast(painter->device())->window()->windowHandle(); + QTC_ASSERT(window, return); - const QRect iconRect(styleOption.rect.left() + 2, styleOption.rect.top() + 2, 16, 16); - const QIcon &icon = isChecked(modelIndex) ? m_checkedIcon : m_uncheckedIcon; - const QPixmap iconPixmap = icon.pixmap(window, iconRect.size()); + const QSize iconSize(16, 16); + const QPoint iconPosition(styleOption.rect.left() + (styleOption.rect.width() - iconSize.width()) / 2, + styleOption.rect.top() + 2 + delegateMargin); - painter->save(); + const QIcon &icon = isChecked(modelIndex) ? m_checkedIcon : m_uncheckedIcon; + const QPixmap iconPixmap = icon.pixmap(window, iconSize); - if (isThisOrAncestorLocked(modelIndex)) - painter->setOpacity(0.5); + painter->save(); - painter->drawPixmap(iconRect.topLeft() + QPoint(0, delegateMargin), iconPixmap); + if (isThisOrAncestorLocked(modelIndex)) + painter->setOpacity(0.5); - painter->restore(); + painter->drawPixmap(iconPosition, iconPixmap); + + painter->restore(); +} + + +bool IconCheckboxItemDelegate::editorEvent(QEvent *event, + QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index) +{ + Q_ASSERT(event); + Q_ASSERT(model); + + // make sure that the item is checkable + Qt::ItemFlags flags = model->flags(index); + if (!(flags & Qt::ItemIsUserCheckable) || !(option.state & QStyle::State_Enabled) + || !(flags & Qt::ItemIsEnabled)) + return false; + + // make sure that we have a check state + QVariant value = index.data(Qt::CheckStateRole); + if (!value.isValid()) + return false; + + // make sure that we have the right event type + if ((event->type() == QEvent::MouseButtonRelease) + || (event->type() == QEvent::MouseButtonDblClick) + || (event->type() == QEvent::MouseButtonPress)) { + QMouseEvent *me = static_cast(event); + if (me->button() != Qt::LeftButton || !option.rect.contains(me->pos())) + return false; + + if ((event->type() == QEvent::MouseButtonPress) + || (event->type() == QEvent::MouseButtonDblClick)) + return true; + + } else if (event->type() == QEvent::KeyPress) { + if (static_cast(event)->key() != Qt::Key_Space + && static_cast(event)->key() != Qt::Key_Select) + return false; + } else { + return false; } + + Qt::CheckState state = static_cast(value.toInt()); + if (flags & Qt::ItemIsUserTristate) + state = ((Qt::CheckState)((state + 1) % 3)); + else + state = (state == Qt::Checked) ? Qt::Unchecked : Qt::Checked; + return model->setData(index, state, Qt::CheckStateRole); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.h b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.h index 3d98ffc84f7..4f77e42c97a 100644 --- a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.h +++ b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.h @@ -45,6 +45,12 @@ public: const QStyleOptionViewItem &option, const QModelIndex &index) const override; +protected: + bool editorEvent(QEvent *event, + QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index) override; + private: const QIcon m_checkedIcon; const QIcon m_uncheckedIcon; diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 65315b7bb89..46bbfadb247 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -278,19 +278,24 @@ Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const return flags; } + const ModelNode modelNode = modelNodeForIndex(index); + if (index.column() == ColumnType::Alias || index.column() == ColumnType::Visibility - || index.column() == ColumnType::Lock) - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren; + || index.column() == ColumnType::Lock) { + if (ModelNode::isThisOrAncestorLocked(modelNode)) + return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; + else + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; + } - const ModelNode modelNode = modelNodeForIndex(index); if (ModelNode::isThisOrAncestorLocked(modelNode)) return Qt::NoItemFlags; if (index.column() == ColumnType::Name) - return Qt::ItemIsEditable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled; + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled; - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren; + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; } void static appendForcedNodes(const NodeListProperty &property, QList &list) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index c2ed5c72065..d095dc8501b 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -145,7 +145,6 @@ void NavigatorView::modelAttached(Model *model) treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Visibility, 26); treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Lock, 26); treeView->setIndentation(20); - treeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_currentModelInterface->setFilter(false); diff --git a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp index 649b53b5ffa..d3ea5047fa0 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp @@ -46,8 +46,8 @@ namespace QmlDesigner { NavigatorWidget::NavigatorWidget(NavigatorView *view) - : m_treeView(new NavigatorTreeView), - m_navigatorView(view) + : m_treeView(new NavigatorTreeView) + , m_navigatorView(view) { m_treeView->setDragEnabled(true); m_treeView->setAcceptDrops(true);