|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (developer.feedback@nokia.com) |
|
6 ** |
|
7 ** This file is part of the HbCore module of the UI Extensions for Mobile. |
|
8 ** |
|
9 ** GNU Lesser General Public License Usage |
|
10 ** This file may be used under the terms of the GNU Lesser General Public |
|
11 ** License version 2.1 as published by the Free Software Foundation and |
|
12 ** appearing in the file LICENSE.LGPL included in the packaging of this file. |
|
13 ** Please review the following information to ensure the GNU Lesser General |
|
14 ** Public License version 2.1 requirements will be met: |
|
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
16 ** |
|
17 ** In addition, as a special exception, Nokia gives you certain additional |
|
18 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
20 ** |
|
21 ** If you have questions regarding the use of this file, please contact |
|
22 ** Nokia at developer.feedback@nokia.com. |
|
23 ** |
|
24 ****************************************************************************/ |
|
25 |
|
26 #include <QApplication> |
|
27 #include <QGraphicsWidget> |
|
28 #include <QPainter> |
|
29 #include <QDebug> |
|
30 #include <hbtextitem.h> |
|
31 #ifdef HB_EFFECTS |
|
32 #include <hbeffect.h> |
|
33 #include <hbeffectinternal_p.h> |
|
34 #endif |
|
35 #include "hbstyleoption.h" |
|
36 #include "hbfontspec.h" |
|
37 #include "hbwidgetbase.h" |
|
38 #include "hbwidgetbase_p.h" |
|
39 #include "hbevent.h" |
|
40 |
|
41 |
|
42 /*! |
|
43 \class HbWidgetBase |
|
44 |
|
45 \brief HbWidgetBase is a common base for all Hb widgets and primitives. |
|
46 It contains common functionality shared between these two types. |
|
47 |
|
48 Currently HbWidgetBase offers the following functionality: |
|
49 - Layout direction locking |
|
50 */ |
|
51 |
|
52 HbWidgetBasePrivate::HbWidgetBasePrivate() : |
|
53 mApiProtectionFlags(0), |
|
54 attributes(0) |
|
55 { |
|
56 q_ptr = 0; |
|
57 } |
|
58 |
|
59 HbWidgetBasePrivate::~HbWidgetBasePrivate() |
|
60 { |
|
61 } |
|
62 |
|
63 void HbWidgetBasePrivate::init() |
|
64 { |
|
65 Q_Q( HbWidgetBase ); |
|
66 QGraphicsItem *item = q->parentItem(); |
|
67 if ( item ) { |
|
68 handleInsidePopup(item); |
|
69 } |
|
70 } |
|
71 |
|
72 void HbWidgetBasePrivate::handleInsidePopup(const QGraphicsItem *parent) |
|
73 { |
|
74 Q_Q( HbWidgetBase ); |
|
75 if( parent |
|
76 && parent->isWidget()) { |
|
77 const HbWidgetBase *widgetBase = qobject_cast<const HbWidgetBase*>(static_cast<const QGraphicsWidget*>(parent)); |
|
78 if (widgetBase) { |
|
79 if (q->testAttribute(Hb::InsidePopup) != widgetBase->testAttribute(Hb::InsidePopup)) { |
|
80 setInsidePopup(widgetBase->testAttribute(Hb::InsidePopup)); |
|
81 } |
|
82 } |
|
83 } |
|
84 } |
|
85 |
|
86 void HbWidgetBasePrivate::setInsidePopup(bool insidePopup) |
|
87 { |
|
88 Q_Q( HbWidgetBase ); |
|
89 q->setAttribute(Hb::InsidePopup, insidePopup ? true : false); |
|
90 if (insidePopup) { |
|
91 q->setProperty("insidePopup", true); |
|
92 } else { |
|
93 q->setProperty("insidePopup", QVariant()); |
|
94 } |
|
95 |
|
96 QList<QGraphicsItem *> items = q->childItems(); |
|
97 int count = items.count(); |
|
98 for (int i=0; i< count; i++) { |
|
99 QGraphicsItem *item = items.at(i); |
|
100 if ( item |
|
101 && item->isWidget()) { |
|
102 HbWidgetBase *childWidgetBase = qobject_cast<HbWidgetBase*>(static_cast<QGraphicsWidget*>(item)); |
|
103 if ( childWidgetBase |
|
104 && q->testAttribute(Hb::InsidePopup) != childWidgetBase->testAttribute(Hb::InsidePopup)) { |
|
105 childWidgetBase->d_func()->setInsidePopup(insidePopup); |
|
106 } |
|
107 } |
|
108 } |
|
109 } |
|
110 |
|
111 /* |
|
112 Returns if the HW key navigation is enabled or not. |
|
113 */ |
|
114 bool HbWidgetBasePrivate::keyNavigation() const |
|
115 { |
|
116 return false; |
|
117 } |
|
118 |
|
119 /*! |
|
120 Constructs an HbWidgetBase with the parent item and window flags. |
|
121 This constructor creates a new HbWidgetBasePrivate instance and |
|
122 installs it to the widget. |
|
123 */ |
|
124 HbWidgetBase::HbWidgetBase( QGraphicsItem *parent, Qt::WindowFlags wFlags ): |
|
125 QGraphicsWidget(parent, wFlags), d_ptr( new HbWidgetBasePrivate ) |
|
126 { |
|
127 Q_D( HbWidgetBase ); |
|
128 d->q_ptr = this; |
|
129 d->init(); |
|
130 } |
|
131 |
|
132 /*! |
|
133 Constructs an HbWidgetBase with the given private object, parent item and window flags. |
|
134 This given HbWidgetBasePrivate instance is installed in the widget and deleted in its destructor. |
|
135 */ |
|
136 HbWidgetBase::HbWidgetBase(HbWidgetBasePrivate &dd, QGraphicsItem *parent, Qt::WindowFlags wFlags): |
|
137 QGraphicsWidget(parent, wFlags), d_ptr( &dd ) |
|
138 { |
|
139 Q_D( HbWidgetBase ); |
|
140 d->q_ptr = this; |
|
141 d->init(); |
|
142 } |
|
143 |
|
144 |
|
145 /*! |
|
146 Destroys the widget. |
|
147 */ |
|
148 HbWidgetBase::~HbWidgetBase() |
|
149 { |
|
150 #ifdef HB_EFFECTS |
|
151 //Cancel the effect and do not send the callback notification |
|
152 HbEffect::enable(this); // remove from disabled list |
|
153 HbEffect::cancel(this, QString(), true, false, false); |
|
154 #endif |
|
155 delete d_ptr; |
|
156 } |
|
157 |
|
158 /*! |
|
159 * \reimp |
|
160 * Handles font changes. |
|
161 * Remeber to call old implmentation when reimplementing this method. |
|
162 */ |
|
163 bool HbWidgetBase::event(QEvent *e) |
|
164 { |
|
165 if (e->type() == HbEvent::ThemeChanged) { |
|
166 changeEvent(e); |
|
167 } |
|
168 |
|
169 // This class will be rebased to QGraphicsWidget |
|
170 // that is why direct ancestor is not called |
|
171 return QGraphicsWidget::event(e); |
|
172 } |
|
173 |
|
174 /*! |
|
175 * \reimp |
|
176 * Function handles attribute Hb::InsidePopup. |
|
177 */ |
|
178 QVariant HbWidgetBase::itemChange(GraphicsItemChange change, const QVariant &value) |
|
179 { |
|
180 Q_D(HbWidgetBase); |
|
181 |
|
182 if( change == QGraphicsItem::ItemParentChange) { |
|
183 d->handleInsidePopup(value.value<QGraphicsItem *>()); |
|
184 } |
|
185 return QGraphicsWidget::itemChange(change, value); |
|
186 } |
|
187 |
|
188 /*! |
|
189 Returns the fontSpec property of the widget. |
|
190 |
|
191 The font specification defines the font with a font role and optional other |
|
192 parameters. |
|
193 |
|
194 \sa setFontSpec(), effectiveFontSpec() |
|
195 */ |
|
196 HbFontSpec HbWidgetBase::fontSpec() const |
|
197 { |
|
198 Q_D(const HbWidgetBase); |
|
199 return d->fontSpec; |
|
200 } |
|
201 |
|
202 /*! |
|
203 Sets the \a fontSpec property of the widget. |
|
204 |
|
205 The font specification defines the font with a font role and optional other |
|
206 parameters. Setting fontSpec property also sets the font property to a font |
|
207 matching the specification. |
|
208 |
|
209 \note If the font property of the widget is changed directly, the fontSpec |
|
210 property is cleared. |
|
211 |
|
212 \sa fontSpec(), effectiveFontSpec() |
|
213 */ |
|
214 void HbWidgetBase::setFontSpec(const HbFontSpec &fontSpec) |
|
215 { |
|
216 Q_D(HbWidgetBase); |
|
217 d->fontSpec = fontSpec; |
|
218 |
|
219 QFont oldFont = font(); |
|
220 setFont(fontSpec.font()); |
|
221 |
|
222 // Work-around for Qt "setFont over-optimized" problem. |
|
223 if ( oldFont != font() ) { |
|
224 QGraphicsLayoutItem::updateGeometry(); |
|
225 } |
|
226 } |
|
227 |
|
228 /*! |
|
229 Returns the effective fontSpec of the widget. This may be different |
|
230 than the set fontSpec. |
|
231 |
|
232 FontSpec may be inherited from the parent item if it's not explicitly |
|
233 set to this widget. |
|
234 |
|
235 Font may be overriden by setFont in which case the originally set |
|
236 fontSpec may not be effective anymore. In this case Undefined fontSpec |
|
237 is returned. |
|
238 |
|
239 \sa fontSpec(), setFontSpec() |
|
240 */ |
|
241 HbFontSpec HbWidgetBase::effectiveFontSpec() const |
|
242 { |
|
243 Q_D(const HbWidgetBase); |
|
244 HbFontSpec spec = d->fontSpec; |
|
245 QGraphicsItem* parent = parentItem(); |
|
246 while (spec.role() == HbFontSpec::Undefined && parent) { |
|
247 if (parent->isWidget()) { |
|
248 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(parent); |
|
249 HbWidgetBase *widgetBase = qobject_cast<HbWidgetBase *>(widget); |
|
250 if ( widgetBase ) { |
|
251 spec = widgetBase->fontSpec(); |
|
252 } |
|
253 } |
|
254 parent = parent->parentItem(); |
|
255 } |
|
256 |
|
257 if (spec.role() != HbFontSpec::Undefined) { |
|
258 QFont fontSpecFont = spec.font().resolve(QApplication::font()); |
|
259 if (font() != fontSpecFont) { |
|
260 spec = HbFontSpec(); |
|
261 } |
|
262 } |
|
263 |
|
264 return spec; |
|
265 } |
|
266 |
|
267 /*! |
|
268 See the class documentation for QGraphicsWidget for a complete list of |
|
269 which attributes are supported, and what they are for. |
|
270 |
|
271 \sa testAttribute() |
|
272 */ |
|
273 void HbWidgetBase::setAttribute(Qt::WidgetAttribute attribute, bool on) |
|
274 { |
|
275 QGraphicsWidget::setAttribute(attribute, on); |
|
276 } |
|
277 |
|
278 /*! |
|
279 See the class documentation for QGraphicsWidget. |
|
280 |
|
281 \sa setAttribute() |
|
282 */ |
|
283 bool HbWidgetBase::testAttribute(Qt::WidgetAttribute attribute) const |
|
284 { |
|
285 return QGraphicsWidget::testAttribute(attribute); |
|
286 } |
|
287 |
|
288 /*! |
|
289 If \a on is true, this function enables \a attribute; otherwise |
|
290 \a attribute is disabled. |
|
291 |
|
292 See Hb namespace reference for a complete list of |
|
293 which attributes are supported, and what they are for. |
|
294 |
|
295 \sa testAttribute() |
|
296 */ |
|
297 void HbWidgetBase::setAttribute(Hb::WidgetAttribute attribute, bool on) |
|
298 { |
|
299 Q_D(HbWidgetBase); |
|
300 int bit = d->attributeToBitIndex(attribute); |
|
301 if (bit == -1) { |
|
302 return; |
|
303 } |
|
304 |
|
305 int k = (1 << bit); |
|
306 Q_UNUSED(k); |
|
307 if ( on ) |
|
308 d->attributes |= (1 << bit); |
|
309 else |
|
310 d->attributes &= ~(1 << bit); |
|
311 } |
|
312 |
|
313 /*! |
|
314 Returns true if \a attribute is enabled for this widget; otherwise, |
|
315 returns false. |
|
316 |
|
317 \sa setAttribute() |
|
318 */ |
|
319 bool HbWidgetBase::testAttribute(Hb::WidgetAttribute attribute) const |
|
320 { |
|
321 Q_D(const HbWidgetBase); |
|
322 bool res; |
|
323 int bit = d->attributeToBitIndex(attribute); |
|
324 if (bit == -1) |
|
325 return false; |
|
326 res = (d->attributes & (1 << bit)) != 0; |
|
327 return res; |
|
328 } |
|
329 |
|
330 /* |
|
331 * \reimp |
|
332 * Initializes the style options common for all widgets within the library. |
|
333 * |
|
334 * This function sets the following style \a option parameters; state, direction, rect |
|
335 * and boundingRect. |
|
336 * |
|
337 * The state style option consists of flags. If this widget is enabled the flag |
|
338 * QStyle::State_Enabled is set. If this widget is active the flag QStyle::State_Active |
|
339 * will be set. |
|
340 * |
|
341 * Derived implementations should create a base call to this method. |
|
342 * This function does not call the base class implementation. |
|
343 */ |
|
344 void HbWidgetBase::initStyleOption(HbStyleOption *option) const |
|
345 { |
|
346 // This function does not call the base class implementation because it is doing |
|
347 // time consuming operations (isUnderMouse() and hasFocus()) that are not needed |
|
348 // in this library. |
|
349 Q_ASSERT(option); |
|
350 |
|
351 option->state = QStyle::State_None; |
|
352 if (isEnabled()) |
|
353 option->state |= QStyle::State_Enabled; |
|
354 |
|
355 if (QGraphicsWidget *w = window()) { |
|
356 if (w->isActiveWindow()) |
|
357 option->state |= QStyle::State_Active; |
|
358 } |
|
359 |
|
360 option->direction = layoutDirection(); |
|
361 option->rect = rect().toRect(); |
|
362 option->boundingRect = boundingRect(); |
|
363 } |
|
364 |
|
365 |
|
366 |