Mercurial > projects > qtd
comparison demos/browser/modelmenu.d @ 45:71b382c10ef6
add coarse and incomplete QT browser port
author | mandel |
---|---|
date | Sun, 17 May 2009 18:49:59 +0000 |
parents | |
children | 7bfd46c330dc |
comparison
equal
deleted
inserted
replaced
44:3cb15c92ac28 | 45:71b382c10ef6 |
---|---|
1 /**************************************************************************** | |
2 ** | |
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). | |
4 ** Contact: Qt Software Information (qt-info@nokia.com) | |
5 ** | |
6 ** This file is part of the demonstration applications of the Qt Toolkit. | |
7 ** | |
8 ** $QT_BEGIN_LICENSE:LGPL$ | |
9 ** Commercial Usage | |
10 ** Licensees holding valid Qt Commercial licenses may use this file in | |
11 ** accordance with the Qt Commercial License Agreement provided with the | |
12 ** Software or, alternatively, in accordance with the terms contained in | |
13 ** a written agreement between you and Nokia. | |
14 ** | |
15 ** GNU Lesser General Public License Usage | |
16 ** Alternatively, this file may be used under the terms of the GNU Lesser | |
17 ** General Public License version 2.1 as published by the Free Software | |
18 ** Foundation and appearing in the file LICENSE.LGPL included in the | |
19 ** packaging of this file. Please review the following information to | |
20 ** ensure the GNU Lesser General Public License version 2.1 requirements | |
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
22 ** | |
23 ** In addition, as a special exception, Nokia gives you certain | |
24 ** additional rights. These rights are described in the Nokia Qt LGPL | |
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this | |
26 ** package. | |
27 ** | |
28 ** GNU General Public License Usage | |
29 ** Alternatively, this file may be used under the terms of the GNU | |
30 ** General Public License version 3.0 as published by the Free Software | |
31 ** Foundation and appearing in the file LICENSE.GPL included in the | |
32 ** packaging of this file. Please review the following information to | |
33 ** ensure the GNU General Public License version 3.0 requirements will be | |
34 ** met: http://www.gnu.org/copyleft/gpl.html. | |
35 ** | |
36 ** If you are unsure which license is appropriate for your use, please | |
37 ** contact the sales department at qt-sales@nokia.com. | |
38 ** $QT_END_LICENSE$ | |
39 ** | |
40 ****************************************************************************/ | |
41 | |
42 import QtGui.QMenu | |
43 import QtCore.QAbstractItemModel; | |
44 | |
45 import modelmenu; | |
46 | |
47 import QtCore.QAbstractItemModel; | |
48 import qdebug; | |
49 | |
50 | |
51 | |
52 // A QMenu that is dynamically populated from a QAbstractItemModel | |
53 class ModelMenu : public QMenu | |
54 { | |
55 Q_OBJECT | |
56 | |
57 signals: | |
58 void activated(const QModelIndex &index); | |
59 void hovered(const QString &text); | |
60 | |
61 public: | |
62 ModelMenu(QWidget *parent = null) | |
63 { | |
64 super(parent); | |
65 m_maxRows = 7; | |
66 m_firstSeparator = -1; | |
67 m_maxWidth = -1; | |
68 m_hoverRole = 0; | |
69 m_separatorRole = 0; | |
70 m_model = 0; | |
71 connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); | |
72 } | |
73 | |
74 void setModel(QAbstractItemModel *model) | |
75 { | |
76 m_model = model; | |
77 } | |
78 | |
79 QAbstractItemModel *model() const | |
80 { | |
81 return m_model; | |
82 } | |
83 | |
84 void setMaxRows(int max) | |
85 { | |
86 m_maxRows = max; | |
87 } | |
88 | |
89 int maxRows() const | |
90 { | |
91 return m_maxRows; | |
92 } | |
93 | |
94 void setFirstSeparator(int offset) | |
95 { | |
96 m_firstSeparator = offset; | |
97 } | |
98 | |
99 int firstSeparator() const | |
100 { | |
101 return m_firstSeparator; | |
102 } | |
103 | |
104 void setRootIndex(const QModelIndex &index) | |
105 { | |
106 m_root = index; | |
107 } | |
108 QModelIndex rootIndex() const | |
109 { | |
110 return m_root; | |
111 } | |
112 | |
113 void setHoverRole(int role) | |
114 { | |
115 m_hoverRole = role; | |
116 } | |
117 int hoverRole() const | |
118 { | |
119 return m_hoverRole; | |
120 } | |
121 | |
122 void setSeparatorRole(int role) | |
123 { | |
124 m_separatorRole = role; | |
125 } | |
126 | |
127 int separatorRole() const | |
128 { | |
129 return m_separatorRole; | |
130 } | |
131 | |
132 QAction *makeAction(const QIcon &icon, const QString &text, QObject *parent); | |
133 { | |
134 QFontMetrics fm(font()); | |
135 if (-1 == m_maxWidth) | |
136 m_maxWidth = fm.width(QLatin1Char('m')) * 30; | |
137 QString smallText = fm.elidedText(text, Qt.ElideMiddle, m_maxWidth); | |
138 return new QAction(icon, smallText, parent); | |
139 } | |
140 | |
141 protected: | |
142 // add any actions before the tree, return true if any actions are added. | |
143 virtual bool prePopulated() | |
144 { | |
145 return false; | |
146 } | |
147 // add any actions after the tree | |
148 virtual void postPopulated() | |
149 { | |
150 } | |
151 | |
152 // put all of the children of parent into menu up to max | |
153 void createMenu(const QModelIndex &parent, int max, QMenu *parentMenu = null, QMenu *menu = null) | |
154 { | |
155 if (!menu) { | |
156 QString title = parent.data().toString(); | |
157 menu = new QMenu(title, this); | |
158 QIcon icon = qvariant_cast<QIcon>(parent.data(Qt.DecorationRole)); | |
159 menu.setIcon(icon); | |
160 parentMenu.addMenu(menu); | |
161 QVariant v; | |
162 v.setValue(parent); | |
163 menu.menuAction().setData(v); | |
164 connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); | |
165 return; | |
166 } | |
167 | |
168 int end = m_model.rowCount(parent); | |
169 if (max != -1) | |
170 end = qMin(max, end); | |
171 | |
172 connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*))); | |
173 connect(menu, SIGNAL(hovered(QAction*)), this, SLOT(hovered(QAction*))); | |
174 | |
175 for (int i = 0; i < end; ++i) { | |
176 QModelIndex idx = m_model.index(i, 0, parent); | |
177 if (m_model.hasChildren(idx)) { | |
178 createMenu(idx, -1, menu); | |
179 } else { | |
180 if (m_separatorRole != 0 | |
181 && idx.data(m_separatorRole).toBool()) | |
182 addSeparator(); | |
183 else | |
184 menu.addAction(makeAction(idx)); | |
185 } | |
186 if (menu == this && i == m_firstSeparator - 1) | |
187 addSeparator(); | |
188 } | |
189 } | |
190 | |
191 private slots: | |
192 Q_DECLARE_METATYPE(QModelIndex) | |
193 void aboutToShow() | |
194 { | |
195 if (QMenu *menu = qobject_cast<QMenu*>(sender())) { | |
196 QVariant v = menu.menuAction().data(); | |
197 if (v.canConvert<QModelIndex>()) { | |
198 QModelIndex idx = qvariant_cast<QModelIndex>(v); | |
199 createMenu(idx, -1, menu, menu); | |
200 disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); | |
201 return; | |
202 } | |
203 } | |
204 | |
205 clear(); | |
206 if (prePopulated()) | |
207 addSeparator(); | |
208 int max = m_maxRows; | |
209 if (max != -1) | |
210 max += m_firstSeparator; | |
211 createMenu(m_root, max, this, this); | |
212 postPopulated(); | |
213 } | |
214 | |
215 | |
216 void triggered(QAction *action) | |
217 { | |
218 QVariant v = action.data(); | |
219 if (v.canConvert<QModelIndex>()) { | |
220 QModelIndex idx = qvariant_cast<QModelIndex>(v); | |
221 emit activated(idx); | |
222 } | |
223 } | |
224 | |
225 void hovered(QAction *action) | |
226 { | |
227 QVariant v = action.data(); | |
228 if (v.canConvert<QModelIndex>()) { | |
229 QModelIndex idx = qvariant_cast<QModelIndex>(v); | |
230 QString hoveredString = idx.data(m_hoverRole).toString(); | |
231 if (!hoveredString.isEmpty()) | |
232 emit hovered(hoveredString); | |
233 } | |
234 } | |
235 | |
236 private: | |
237 QAction *makeAction(const QModelIndex &index); | |
238 { | |
239 QIcon icon = qvariant_cast<QIcon>(index.data(Qt.DecorationRole)); | |
240 QAction *action = makeAction(icon, index.data().toString(), this); | |
241 QVariant v; | |
242 v.setValue(index); | |
243 action.setData(v); | |
244 return action; | |
245 } | |
246 | |
247 int m_maxRows; | |
248 int m_firstSeparator; | |
249 int m_maxWidth; | |
250 int m_hoverRole; | |
251 int m_separatorRole; | |
252 QAbstractItemModel *m_model; | |
253 QPersistentModelIndex m_root; | |
254 } |