xref: /OK3568_Linux_fs/app/forlinx/flapp/src/plugins/allwinner/browser/modelmenu.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the demonstration applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL21$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** $QT_END_LICENSE$
31 **
32 ****************************************************************************/
33 
34 #include "modelmenu.h"
35 
36 #include <QtCore/QAbstractItemModel>
37 #include <qdebug.h>
38 
ModelMenu(QWidget * parent)39 ModelMenu::ModelMenu(QWidget * parent)
40     : QMenu(parent)
41     , m_maxRows(7)
42     , m_firstSeparator(-1)
43     , m_maxWidth(-1)
44     , m_hoverRole(0)
45     , m_separatorRole(0)
46     , m_model(0)
47 {
48     connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
49 }
50 
prePopulated()51 bool ModelMenu::prePopulated()
52 {
53     return false;
54 }
55 
postPopulated()56 void ModelMenu::postPopulated()
57 {
58 }
59 
setModel(QAbstractItemModel * model)60 void ModelMenu::setModel(QAbstractItemModel *model)
61 {
62     m_model = model;
63 }
64 
model() const65 QAbstractItemModel *ModelMenu::model() const
66 {
67     return m_model;
68 }
69 
setMaxRows(int max)70 void ModelMenu::setMaxRows(int max)
71 {
72     m_maxRows = max;
73 }
74 
maxRows() const75 int ModelMenu::maxRows() const
76 {
77     return m_maxRows;
78 }
79 
setFirstSeparator(int offset)80 void ModelMenu::setFirstSeparator(int offset)
81 {
82     m_firstSeparator = offset;
83 }
84 
firstSeparator() const85 int ModelMenu::firstSeparator() const
86 {
87     return m_firstSeparator;
88 }
89 
setRootIndex(const QModelIndex & index)90 void ModelMenu::setRootIndex(const QModelIndex &index)
91 {
92     m_root = index;
93 }
94 
rootIndex() const95 QModelIndex ModelMenu::rootIndex() const
96 {
97     return m_root;
98 }
99 
setHoverRole(int role)100 void ModelMenu::setHoverRole(int role)
101 {
102     m_hoverRole = role;
103 }
104 
hoverRole() const105 int ModelMenu::hoverRole() const
106 {
107     return m_hoverRole;
108 }
109 
setSeparatorRole(int role)110 void ModelMenu::setSeparatorRole(int role)
111 {
112     m_separatorRole = role;
113 }
114 
separatorRole() const115 int ModelMenu::separatorRole() const
116 {
117     return m_separatorRole;
118 }
119 
Q_DECLARE_METATYPE(QModelIndex)120 Q_DECLARE_METATYPE(QModelIndex)
121 void ModelMenu::aboutToShow()
122 {
123     if (QMenu *menu = qobject_cast<QMenu*>(sender())) {
124         QVariant v = menu->menuAction()->data();
125         if (v.canConvert<QModelIndex>()) {
126             QModelIndex idx = qvariant_cast<QModelIndex>(v);
127             createMenu(idx, -1, menu, menu);
128             disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
129             return;
130         }
131     }
132 
133     clear();
134     if (prePopulated())
135         addSeparator();
136     int max = m_maxRows;
137     if (max != -1)
138         max += m_firstSeparator;
139     createMenu(m_root, max, this, this);
140     postPopulated();
141 }
142 
createMenu(const QModelIndex & parent,int max,QMenu * parentMenu,QMenu * menu)143 void ModelMenu::createMenu(const QModelIndex &parent, int max, QMenu *parentMenu, QMenu *menu)
144 {
145     if (!menu) {
146         QString title = parent.data().toString();
147         menu = new QMenu(title, this);
148         QIcon icon = qvariant_cast<QIcon>(parent.data(Qt::DecorationRole));
149         menu->setIcon(icon);
150         parentMenu->addMenu(menu);
151         QVariant v;
152         v.setValue(parent);
153         menu->menuAction()->setData(v);
154         connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
155         return;
156     }
157 
158     int end = m_model->rowCount(parent);
159     if (max != -1)
160         end = qMin(max, end);
161 
162     connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*)));
163     connect(menu, SIGNAL(hovered(QAction*)), this, SLOT(hovered(QAction*)));
164 
165     for (int i = 0; i < end; ++i) {
166         QModelIndex idx = m_model->index(i, 0, parent);
167         if (m_model->hasChildren(idx)) {
168             createMenu(idx, -1, menu);
169         } else {
170             if (m_separatorRole != 0
171                 && idx.data(m_separatorRole).toBool())
172                 addSeparator();
173             else
174                 menu->addAction(makeAction(idx));
175         }
176         if (menu == this && i == m_firstSeparator - 1)
177             addSeparator();
178     }
179 }
180 
makeAction(const QModelIndex & index)181 QAction *ModelMenu::makeAction(const QModelIndex &index)
182 {
183     QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
184     QAction *action = makeAction(icon, index.data().toString(), this);
185     QVariant v;
186     v.setValue(index);
187     action->setData(v);
188     return action;
189 }
190 
makeAction(const QIcon & icon,const QString & text,QObject * parent)191 QAction *ModelMenu::makeAction(const QIcon &icon, const QString &text, QObject *parent)
192 {
193     QFontMetrics fm(font());
194     if (-1 == m_maxWidth)
195         m_maxWidth = fm.width(QLatin1Char('m')) * 30;
196     QString smallText = fm.elidedText(text, Qt::ElideMiddle, m_maxWidth);
197     return new QAction(icon, smallText, parent);
198 }
199 
triggered(QAction * action)200 void ModelMenu::triggered(QAction *action)
201 {
202     QVariant v = action->data();
203     if (v.canConvert<QModelIndex>()) {
204         QModelIndex idx = qvariant_cast<QModelIndex>(v);
205         emit activated(idx);
206     }
207 }
208 
hovered(QAction * action)209 void ModelMenu::hovered(QAction *action)
210 {
211     QVariant v = action->data();
212     if (v.canConvert<QModelIndex>()) {
213         QModelIndex idx = qvariant_cast<QModelIndex>(v);
214         QString hoveredString = idx.data(m_hoverRole).toString();
215         if (!hoveredString.isEmpty())
216             emit hovered(hoveredString);
217     }
218 }
219 
220