diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf index 993db3896f0..0c4d237c0e2 100644 Binary files a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf and b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf differ 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);