summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Bache-Wiig <jens.bache-wiig@nokia.com>2012-01-23 11:39:30 +0100
committerJens Bache-Wiig <jens.bache-wiig@nokia.com>2012-01-23 14:16:40 +0100
commitacc70f6b41c5d1da6e072e8f3422aa7c8c807e7c (patch)
tree37cec71885a599e4a42aba498809bf583d89df24
parent563fdbc4d7805c9d9c1d2abde1d52b39e58b4329 (diff)
Add support for native model in ComboBox and ContextMenu
This adds some basic support for C++ item models. I also added a textRole property to be consistent with other model based components.
-rw-r--r--components/ComboBox.qml3
-rw-r--r--components/ContextMenu.qml47
-rw-r--r--src/qtmenu.cpp83
-rw-r--r--src/qtmenu.h44
4 files changed, 130 insertions, 47 deletions
diff --git a/components/ComboBox.qml b/components/ComboBox.qml
index c55171120..37ebb915f 100644
--- a/components/ComboBox.qml
+++ b/components/ComboBox.qml
@@ -83,10 +83,13 @@ Custom.BasicButton {
width: implicitWidth
height: implicitHeight
+
implicitWidth: Math.max(80, backgroundItem.implicitWidth)
implicitHeight: backgroundItem.implicitHeight
+
onWidthChanged: popup.setMinimumWidth(width)
checkable: false
+
onPressedChanged: if (pressed) popup.visible = true
ContextMenu {
diff --git a/components/ContextMenu.qml b/components/ContextMenu.qml
index a439d4a8f..08d779588 100644
--- a/components/ContextMenu.qml
+++ b/components/ContextMenu.qml
@@ -2,12 +2,12 @@ import QtQuick 1.1
Menu {
id: root
- property ListModel model
property string selectedText: itemTextAt(selectedIndex)
property string hoveredText: itemTextAt(hoveredIndex)
property int x
property int y
property bool visible
+ property string textRole
// 'centerSelectedText' means that the menu will be positioned
// so that the selected text' top left corner will be at x, y.
@@ -16,7 +16,10 @@ Menu {
visible: false
onMenuClosed: visible = false
onModelChanged: if (Component.status === Component.Ready && model != undefined) rebuildMenu()
- Component.onCompleted: if (model != undefined) rebuildMenu()
+
+ Component.onCompleted: if (model !== undefined) rebuildMenu()
+
+ onRebuildMenu: rebuildMenu()
onHoveredIndexChanged: {
if (hoveredIndex < menuItems.length)
@@ -40,11 +43,45 @@ Menu {
function rebuildMenu()
{
clearMenuItems();
+
for (var i=0; i<menuItems.length; ++i)
addMenuItem(menuItems[i].text)
- if (model != undefined) {
- for (var j=0; j<model.count; ++j)
- addMenuItem(model.get(j).text)
+
+ var nativeModel = root.modelCount() !== -1
+
+ if (model !== undefined) {
+ var modelCount = nativeModel ? root.modelCount() : model.count;
+ for (var j = 0 ; j < modelCount; ++j) {
+ var textValue
+ if (nativeModel) {
+ textValue = root.modelTextAt(j);
+ } else {
+ if (textRole !== "")
+ textValue = model.get(j)[textRole]
+ else if (model.count > 0 && root.model.get && root.model.get(0)) {
+ // ListModel with one role
+ var listElement = root.model.get(0)
+ var oneRole = true
+ var roleName = ""
+ var roleCount = 0
+ for (var i in listElement) {
+ roleName = i
+ ++roleCount
+ if (roleCount > 1) {
+ oneRole = false
+ root.enabled = false
+ console.log("When multiple roles used, provide textRole for the ComboBox.")
+ break
+ }
+ }
+ if (oneRole) {
+ root.textRole = roleName
+ textValue = root.model.get(j)[textRole]
+ }
+ }
+ }
+ addMenuItem(textValue)
+ }
}
}
}
diff --git a/src/qtmenu.cpp b/src/qtmenu.cpp
index 6200968df..ce1775ad0 100644
--- a/src/qtmenu.cpp
+++ b/src/qtmenu.cpp
@@ -28,49 +28,49 @@
#include "qdebug.h"
#include <qapplication.h>
#include <qmenubar.h>
-
+#include <qabstractitemmodel.h>
#include "qtoplevelwindow.h"
QtMenu::QtMenu(QObject *parent)
: QtMenuBase(parent),
dummy(0),
- _selectedIndex(0),
- _highlightedIndex(0)
+ m_selectedIndex(0),
+ m_highlightedIndex(0)
{
- _qmenu = new QMenu(0);
- connect(_qmenu, SIGNAL(aboutToHide()), this, SIGNAL(menuClosed()));
+ m_qmenu = new QMenu(0);
+ connect(m_qmenu, SIGNAL(aboutToHide()), this, SIGNAL(menuClosed()));
}
QtMenu::~QtMenu()
{
- delete _qmenu;
+ delete m_qmenu;
}
void QtMenu::setText(const QString &text)
{
- _qmenu->setTitle(text);
+ m_qmenu->setTitle(text);
}
QString QtMenu::text() const
{
- return _qmenu->title();
+ return m_qmenu->title();
}
void QtMenu::setSelectedIndex(int index)
{
- _selectedIndex = index;
- QList<QAction *> actionList = _qmenu->actions();
- if (_selectedIndex >= 0 && _selectedIndex < actionList.size())
- _qmenu->setActiveAction(actionList[_selectedIndex]);
+ m_selectedIndex = index;
+ QList<QAction *> actionList = m_qmenu->actions();
+ if (m_selectedIndex >= 0 && m_selectedIndex < actionList.size())
+ m_qmenu->setActiveAction(actionList[m_selectedIndex]);
emit selectedIndexChanged();
}
void QtMenu::setHoveredIndex(int index)
{
- _highlightedIndex = index;
- QList<QAction *> actionList = _qmenu->actions();
- if (_highlightedIndex >= 0 && _highlightedIndex < actionList.size())
- _qmenu->setActiveAction(actionList[_highlightedIndex]);
+ m_highlightedIndex = index;
+ QList<QAction *> actionList = m_qmenu->actions();
+ if (m_highlightedIndex >= 0 && m_highlightedIndex < actionList.size())
+ m_qmenu->setActiveAction(actionList[m_highlightedIndex]);
emit hoveredIndexChanged();
}
@@ -81,14 +81,14 @@ QDeclarativeListProperty<QtMenuBase> QtMenu::menuItems()
void QtMenu::showPopup(qreal x, qreal y, int atActionIndex)
{
- if (_qmenu->isVisible())
+ if (m_qmenu->isVisible())
return;
// If atActionIndex is valid, x and y is specified from the
// the position of the corresponding QAction:
QAction *atAction = 0;
- if (atActionIndex >= 0 && atActionIndex < _qmenu->actions().size())
- atAction = _qmenu->actions()[atActionIndex];
+ if (atActionIndex >= 0 && atActionIndex < m_qmenu->actions().size())
+ atAction = m_qmenu->actions()[atActionIndex];
// x,y are in view coordinates, QMenu expects screen coordinates
// ### activeWindow hack
@@ -102,40 +102,40 @@ void QtMenu::showPopup(qreal x, qreal y, int atActionIndex)
QPoint screenPosition = window->mapToGlobal(QPoint(x, y+menuBarHeight));
- setHoveredIndex(_selectedIndex);
- _qmenu->popup(screenPosition, atAction);
+ setHoveredIndex(m_selectedIndex);
+ m_qmenu->popup(screenPosition, atAction);
}
void QtMenu::hidePopup()
{
- _qmenu->close();
+ m_qmenu->close();
}
QAction* QtMenu::action()
{
- return _qmenu->menuAction();
+ return m_qmenu->menuAction();
}
Q_INVOKABLE void QtMenu::clearMenuItems()
{
- _qmenu->clear();
- foreach (QtMenuBase *item, _qmenuItems) {
+ m_qmenu->clear();
+ foreach (QtMenuBase *item, m_qmenuItems) {
delete item;
}
- _qmenuItems.clear();
+ m_qmenuItems.clear();
}
void QtMenu::addMenuItem(const QString &text)
{
QtMenuItem *menuItem = new QtMenuItem(this);
menuItem->setText(text);
- _qmenuItems.append(menuItem);
- _qmenu->addAction(menuItem->action());
+ m_qmenuItems.append(menuItem);
+ m_qmenu->addAction(menuItem->action());
connect(menuItem->action(), SIGNAL(triggered()), this, SLOT(emitSelected()));
connect(menuItem->action(), SIGNAL(hovered()), this, SLOT(emitHovered()));
- if (_qmenu->actions().size() == 1)
+ if (m_qmenu->actions().size() == 1)
// Inform QML that the selected action (0) now has changed contents:
emit selectedIndexChanged();
}
@@ -145,7 +145,7 @@ void QtMenu::emitSelected()
QAction *act = qobject_cast<QAction *>(sender());
if (!act)
return;
- _selectedIndex = _qmenu->actions().indexOf(act);
+ m_selectedIndex = m_qmenu->actions().indexOf(act);
emit selectedIndexChanged();
}
@@ -154,25 +154,42 @@ void QtMenu::emitHovered()
QAction *act = qobject_cast<QAction *>(sender());
if (!act)
return;
- _highlightedIndex = _qmenu->actions().indexOf(act);
+ m_highlightedIndex = m_qmenu->actions().indexOf(act);
emit hoveredIndexChanged();
}
QString QtMenu::itemTextAt(int index) const
{
- QList<QAction *> actionList = _qmenu->actions();
+ QList<QAction *> actionList = m_qmenu->actions();
if (index >= 0 && index < actionList.size())
return actionList[index]->text();
else
return "";
}
+QString QtMenu::modelTextAt(int index) const
+{
+ if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(m_model.value<QObject*>())) {
+ return model->data(model->index(index, 0)).toString();
+ }
+ return "";
+}
+
+int QtMenu::modelCount() const
+{
+ if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(m_model.value<QObject*>())) {
+ return model->rowCount();
+ }
+ return -1;
+}
+
+
void QtMenu::append_qmenuItem(QDeclarativeListProperty<QtMenuBase> *list, QtMenuBase *menuItem)
{
QtMenu *menu = qobject_cast<QtMenu *>(list->object);
if (menu) {
menuItem->setParent(menu);
- menu->_qmenuItems.append(menuItem);
+ menu->m_qmenuItems.append(menuItem);
menu->qmenu()->addAction(menuItem->action());
}
}
diff --git a/src/qtmenu.h b/src/qtmenu.h
index c9cfd68e1..2c1f9fede 100644
--- a/src/qtmenu.h
+++ b/src/qtmenu.h
@@ -30,12 +30,16 @@
#include <QtGui/qmenu.h>
#include <QtDeclarative/qdeclarative.h>
#include <QtDeclarative/QDeclarativeListProperty>
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/QVariant>
#include "qtmenuitem.h"
class QtMenu : public QtMenuBase
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText)
+ Q_PROPERTY(bool hasNativeModel READ hasNativeModel)
+ Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(int selectedIndex READ selectedIndex WRITE setSelectedIndex NOTIFY selectedIndexChanged)
Q_PROPERTY(int hoveredIndex READ hoveredIndex WRITE setHoveredIndex NOTIFY hoveredIndexChanged)
Q_PROPERTY(QDeclarativeListProperty<QtMenuBase> menuItems READ menuItems)
@@ -47,28 +51,48 @@ public:
void setText(const QString &text);
QString text() const;
- int selectedIndex() const { return _selectedIndex; }
+ int selectedIndex() const { return m_selectedIndex; }
void setSelectedIndex(int index);
- int hoveredIndex() const { return _highlightedIndex; }
+ int hoveredIndex() const { return m_highlightedIndex; }
void setHoveredIndex(int index);
QDeclarativeListProperty<QtMenuBase> menuItems();
- QMenu* qmenu() { return _qmenu; }
+ QMenu* qmenu() { return m_qmenu; }
QAction* action();
- Q_INVOKABLE int minimumWidth() const { return _qmenu->minimumWidth(); }
- Q_INVOKABLE void setMinimumWidth(int w) { _qmenu->setMinimumWidth(w); }
+ Q_INVOKABLE int minimumWidth() const { return m_qmenu->minimumWidth(); }
+ Q_INVOKABLE void setMinimumWidth(int w) { m_qmenu->setMinimumWidth(w); }
Q_INVOKABLE void showPopup(qreal x, qreal y, int atActionIndex = -1);
Q_INVOKABLE void hidePopup();
Q_INVOKABLE void clearMenuItems();
Q_INVOKABLE void addMenuItem(const QString &text);
Q_INVOKABLE QString itemTextAt(int index) const;
+ Q_INVOKABLE QString modelTextAt(int index) const;
+ Q_INVOKABLE int modelCount() const;
+ QVariant model() const { return m_model; }
+ bool hasNativeModel() const { return m_hasNativeModel; }
+
+public slots:
+
+ void setModel(const QVariant arg) {
+ if (m_model != arg) {
+ if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(arg.value<QObject*>())) {
+ connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SIGNAL(rebuildMenu()));
+ }
+ m_model = arg;
+ emit modelChanged(m_model);
+ }
+ }
+
+public:
Q_SIGNALS:
void menuClosed();
void selectedIndexChanged();
void hoveredIndexChanged();
+ void modelChanged(const QVariant&);
+ void rebuldMenu();
private Q_SLOTS:
void emitSelected();
@@ -79,10 +103,12 @@ private:
private:
QWidget *dummy;
- QMenu *_qmenu;
- QList<QtMenuBase *> _qmenuItems;
- int _selectedIndex;
- int _highlightedIndex;
+ QMenu *m_qmenu;
+ QList<QtMenuBase *> m_qmenuItems;
+ int m_selectedIndex;
+ int m_highlightedIndex;
+ bool m_hasNativeModel;
+ QVariant m_model;
};
QML_DECLARE_TYPE(QtMenu)