File indexing completed on 2024-04-28 04:41:51
0001 /*************************************************************************** 0002 * Copyright (C) 2017 by Emmanuel Lepage Vallee * 0003 * Author : Emmanuel Lepage Vallee <emmanuel.lepage@kde.org> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 3 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0017 **************************************************************************/ 0018 #include "comboboxview.h" 0019 0020 // Qt 0021 #include <QQmlEngine> 0022 #include <QQmlContext> 0023 #include <QQuickWindow> 0024 0025 class ComboBoxViewPrivate final : public QObject 0026 { 0027 Q_OBJECT 0028 public: 0029 QItemSelectionModel* m_pSelectionModel {nullptr}; 0030 QQuickItem* m_pItem {nullptr}; 0031 0032 ComboBoxView* q_ptr; 0033 0034 public Q_SLOTS: 0035 void slotWindowChanged(QQuickWindow *window); 0036 void slotActivated(int index); 0037 void slotCurrentChanged(const QModelIndex& idx); 0038 void slotResize(); 0039 }; 0040 0041 ComboBoxView::ComboBoxView(QQuickItem* parent) : QQuickItem(parent), 0042 d_ptr(new ComboBoxViewPrivate) 0043 { 0044 d_ptr->q_ptr = this; 0045 0046 connect(this, &QQuickItem::windowChanged, 0047 d_ptr, &ComboBoxViewPrivate::slotWindowChanged); 0048 0049 setHeight(40); 0050 } 0051 0052 ComboBoxView::~ComboBoxView() 0053 { 0054 if (d_ptr->m_pItem) 0055 delete d_ptr->m_pItem; 0056 0057 delete d_ptr; 0058 } 0059 0060 QItemSelectionModel* ComboBoxView::selectionModel() const 0061 { 0062 return d_ptr->m_pSelectionModel; 0063 } 0064 0065 void ComboBoxView::setSelectionModel(QItemSelectionModel* s) 0066 { 0067 if (s && d_ptr->m_pSelectionModel && d_ptr->m_pSelectionModel != s) 0068 disconnect(d_ptr->m_pSelectionModel, &QItemSelectionModel::currentChanged, 0069 d_ptr, &ComboBoxViewPrivate::slotCurrentChanged); 0070 0071 d_ptr->m_pSelectionModel = s; 0072 0073 if (s && d_ptr->m_pItem) { 0074 d_ptr->blockSignals(true); 0075 d_ptr->m_pItem->setProperty("model", QVariant::fromValue(s->model())); 0076 if (s->currentIndex().isValid()) 0077 d_ptr->m_pItem->setProperty("currentIndex", s->currentIndex().row()); 0078 d_ptr->blockSignals(false); 0079 } 0080 0081 connect(d_ptr->m_pSelectionModel, &QItemSelectionModel::currentChanged, 0082 d_ptr, &ComboBoxViewPrivate::slotCurrentChanged); 0083 } 0084 0085 void ComboBoxViewPrivate::slotWindowChanged(QQuickWindow *window) 0086 { 0087 if (!window) 0088 return; 0089 0090 if (!m_pItem) { 0091 QQmlEngine *engine = QQmlEngine::contextForObject(q_ptr)->engine(); 0092 0093 Q_ASSERT(engine); 0094 0095 QQmlComponent cbb(engine, q_ptr); 0096 cbb.setData("import QtQuick 2.4; import QtQuick.Controls 2.0;"\ 0097 "ComboBox {textRole: \"display\"; anchors.fill: parent;}", {}); 0098 m_pItem = qobject_cast<QQuickItem*>(cbb.create()); 0099 0100 if (m_pSelectionModel) 0101 q_ptr->setSelectionModel(m_pSelectionModel); 0102 0103 connect(m_pItem, SIGNAL(activated(int)), 0104 this, SLOT(slotActivated(int))); 0105 0106 connect(m_pItem, SIGNAL(implicitWidthChanged()), 0107 this, SLOT(slotResize())); 0108 0109 q_ptr->setHeight(m_pItem->height()); 0110 m_pItem->setParentItem(q_ptr); 0111 engine->setObjectOwnership(m_pItem, QQmlEngine::CppOwnership); 0112 slotResize(); 0113 } 0114 } 0115 0116 void ComboBoxViewPrivate::slotResize() 0117 { 0118 q_ptr->setImplicitWidth(m_pItem->implicitWidth()); 0119 q_ptr->setImplicitHeight(m_pItem->implicitHeight()); 0120 } 0121 0122 void ComboBoxViewPrivate::slotActivated(int index) 0123 { 0124 if (!m_pSelectionModel) 0125 return; 0126 0127 auto m = m_pSelectionModel->model(); 0128 0129 Q_ASSERT(m); 0130 Q_ASSERT(index >= 0 && index < m->rowCount()); 0131 0132 if (m_pSelectionModel) 0133 m_pSelectionModel->setCurrentIndex( 0134 m->index(index, 0),QItemSelectionModel::ClearAndSelect 0135 ); 0136 0137 slotResize(); 0138 } 0139 0140 void ComboBoxViewPrivate::slotCurrentChanged(const QModelIndex& idx) 0141 { 0142 if (!m_pItem) 0143 return; 0144 0145 if (!idx.isValid()) 0146 return; 0147 0148 m_pItem->setProperty("currentIndex", idx.row()); 0149 } 0150 0151 #include <comboboxview.moc>