qcommandlinkbutton.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/widgets/qcommandlinkbutton.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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 QtWidgets module 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 "qcommandlinkbutton.h"-
35#include "qstylepainter.h"-
36#include "qstyleoption.h"-
37#include "qtextdocument.h"-
38#include "qtextlayout.h"-
39#include "qcolor.h"-
40#include "qfont.h"-
41#include <qmath.h>-
42-
43#include "private/qpushbutton_p.h"-
44-
45QT_BEGIN_NAMESPACE-
46-
47/*!-
48 \class QCommandLinkButton-
49 \since 4.4-
50 \brief The QCommandLinkButton widget provides a Vista style command link button.-
51-
52 \ingroup basicwidgets-
53 \inmodule QtWidgets-
54-
55 The command link is a new control that was introduced by Windows Vista. It's-
56 intended use is similar to that of a radio button in that it is used to choose-
57 between a set of mutually exclusive options. Command link buttons should not-
58 be used by themselves but rather as an alternative to radio buttons in-
59 Wizards and dialogs and makes pressing the "next" button redundant.-
60 The appearance is generally similar to that of a flat pushbutton, but-
61 it allows for a descriptive text in addition to the normal button text.-
62 By default it will also carry an arrow icon, indicating that pressing the-
63 control will open another window or page.-
64-
65 \sa QPushButton, QRadioButton-
66*/-
67-
68/*!-
69 \property QCommandLinkButton::description-
70 \brief A descriptive label to complement the button text-
71-
72 Setting this property will set a descriptive text on the-
73 button, complementing the text label. This will usually-
74 be displayed in a smaller font than the primary text.-
75*/-
76-
77/*!-
78 \property QCommandLinkButton::flat-
79 \brief This property determines whether the button is displayed as a flat-
80 panel or with a border.-
81-
82 By default, this property is set to false.-
83-
84 \sa QPushButton::flat-
85*/-
86-
87class QCommandLinkButtonPrivate : public QPushButtonPrivate-
88{-
89 Q_DECLARE_PUBLIC(QCommandLinkButton)-
90-
91public:-
92 QCommandLinkButtonPrivate()-
93 : QPushButtonPrivate(){}
never executed: end of block
0
94-
95 void init();-
96 qreal titleSize() const;-
97 bool usingVistaStyle() const;-
98-
99 QFont titleFont() const;-
100 QFont descriptionFont() const;-
101-
102 QRect titleRect() const;-
103 QRect descriptionRect() const;-
104-
105 int textOffset() const;-
106 int descriptionOffset() const;-
107 int descriptionHeight(int width) const;-
108 QColor mergedColors(const QColor &a, const QColor &b, int value) const;-
109-
110 int topMargin() const { return 10; }
never executed: return 10;
0
111 int leftMargin() const { return 7; }
never executed: return 7;
0
112 int rightMargin() const { return 4; }
never executed: return 4;
0
113 int bottomMargin() const { return 10; }
never executed: return 10;
0
114-
115 QString description;-
116 QColor currentColor;-
117};-
118-
119// Mix colors a and b with a ratio in the range [0-255]-
120QColor QCommandLinkButtonPrivate::mergedColors(const QColor &a, const QColor &b, int value = 50) const-
121{-
122 Q_ASSERT(value >= 0);-
123 Q_ASSERT(value <= 255);-
124 QColor tmp = a;-
125 tmp.setRed((tmp.red() * value) / 255 + (b.red() * (255 - value)) / 255);-
126 tmp.setGreen((tmp.green() * value) / 255 + (b.green() * (255 - value)) / 255);-
127 tmp.setBlue((tmp.blue() * value) / 255 + (b.blue() * (255 - value)) / 255);-
128 return tmp;
never executed: return tmp;
0
129}-
130-
131QFont QCommandLinkButtonPrivate::titleFont() const-
132{-
133 Q_Q(const QCommandLinkButton);-
134 QFont font = q->font();-
135 if (usingVistaStyle()) {
usingVistaStyle()Description
TRUEnever evaluated
FALSEnever evaluated
0
136 font.setPointSizeF(12.0);-
137 } else {
never executed: end of block
0
138 font.setBold(true);-
139 font.setPointSizeF(9.0);-
140 }
never executed: end of block
0
141-
142 // Note the font will be resolved against-
143 // QPainters font, so we need to restore the mask-
144 int resolve_mask = font.resolve_mask;-
145 QFont modifiedFont = q->font().resolve(font);-
146 modifiedFont.detach();-
147 modifiedFont.resolve_mask = resolve_mask;-
148 return modifiedFont;
never executed: return modifiedFont;
0
149}-
150-
151QFont QCommandLinkButtonPrivate::descriptionFont() const-
152{-
153 Q_Q(const QCommandLinkButton);-
154 QFont font = q->font();-
155 font.setPointSizeF(9.0);-
156-
157 // Note the font will be resolved against-
158 // QPainters font, so we need to restore the mask-
159 int resolve_mask = font.resolve_mask;-
160 QFont modifiedFont = q->font().resolve(font);-
161 modifiedFont.detach();-
162 modifiedFont.resolve_mask = resolve_mask;-
163 return modifiedFont;
never executed: return modifiedFont;
0
164}-
165-
166QRect QCommandLinkButtonPrivate::titleRect() const-
167{-
168 Q_Q(const QCommandLinkButton);-
169 QRect r = q->rect().adjusted(textOffset(), topMargin(), -rightMargin(), 0);-
170 if (description.isEmpty())
description.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
171 {-
172 QFontMetrics fm(titleFont());-
173 r.setTop(r.top() + qMax(0, (q->icon().actualSize(q->iconSize()).height()-
174 - fm.height()) / 2));-
175 }
never executed: end of block
0
176-
177 return r;
never executed: return r;
0
178}-
179-
180QRect QCommandLinkButtonPrivate::descriptionRect() const-
181{-
182 Q_Q(const QCommandLinkButton);-
183 return q->rect().adjusted(textOffset(), descriptionOffset(),
never executed: return q->rect().adjusted(textOffset(), descriptionOffset(), -rightMargin(), -bottomMargin());
0
184 -rightMargin(), -bottomMargin());
never executed: return q->rect().adjusted(textOffset(), descriptionOffset(), -rightMargin(), -bottomMargin());
0
185}-
186-
187int QCommandLinkButtonPrivate::textOffset() const-
188{-
189 Q_Q(const QCommandLinkButton);-
190 return q->icon().actualSize(q->iconSize()).width() + leftMargin() + 6;
never executed: return q->icon().actualSize(q->iconSize()).width() + leftMargin() + 6;
0
191}-
192-
193int QCommandLinkButtonPrivate::descriptionOffset() const-
194{-
195 QFontMetrics fm(titleFont());-
196 return topMargin() + fm.height();
never executed: return topMargin() + fm.height();
0
197}-
198-
199bool QCommandLinkButtonPrivate::usingVistaStyle() const-
200{-
201 Q_Q(const QCommandLinkButton);-
202 //### This is a hack to detect if we are indeed running Vista style themed and not in classic-
203 // When we add api to query for this, we should change this implementation to use it.-
204 return q->style()->inherits("QWindowsVistaStyle")
never executed: return q->style()->inherits("QWindowsVistaStyle") && !q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal);
q->style()->in...wsVistaStyle")Description
TRUEnever evaluated
FALSEnever evaluated
0
205 && !q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal);
never executed: return q->style()->inherits("QWindowsVistaStyle") && !q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal);
!q->style()->p...iftHorizontal)Description
TRUEnever evaluated
FALSEnever evaluated
0
206}-
207-
208void QCommandLinkButtonPrivate::init()-
209{-
210 Q_Q(QCommandLinkButton);-
211 QPushButtonPrivate::init();-
212 q->setAttribute(Qt::WA_Hover);-
213-
214 QSizePolicy policy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::PushButton);-
215 policy.setHeightForWidth(true);-
216 q->setSizePolicy(policy);-
217-
218 q->setIconSize(QSize(20, 20));-
219 QStyleOptionButton opt;-
220 q->initStyleOption(&opt);-
221 q->setIcon(q->style()->standardIcon(QStyle::SP_CommandLink, &opt));-
222}
never executed: end of block
0
223-
224// Calculates the height of the description text based on widget width-
225int QCommandLinkButtonPrivate::descriptionHeight(int widgetWidth) const-
226{-
227 // Calc width of actual paragraph-
228 int lineWidth = widgetWidth - textOffset() - rightMargin();-
229-
230 qreal descriptionheight = 0;-
231 if (!description.isEmpty()) {
!description.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
232 QTextLayout layout(description);-
233 layout.setFont(descriptionFont());-
234 layout.beginLayout();-
235 while (true) {-
236 QTextLine line = layout.createLine();-
237 if (!line.isValid())
!line.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
238 break;
never executed: break;
0
239 line.setLineWidth(lineWidth);-
240 line.setPosition(QPointF(0, descriptionheight));-
241 descriptionheight += line.height();-
242 }
never executed: end of block
0
243 layout.endLayout();-
244 }
never executed: end of block
0
245 return qCeil(descriptionheight);
never executed: return qCeil(descriptionheight);
0
246}-
247-
248/*!-
249 \reimp-
250 */-
251QSize QCommandLinkButton::minimumSizeHint() const-
252{-
253 Q_D(const QCommandLinkButton);-
254 QSize size = sizeHint();-
255 int minimumHeight = qMax(d->descriptionOffset() + d->bottomMargin(),-
256 icon().actualSize(iconSize()).height() + d->topMargin());-
257 size.setHeight(minimumHeight);-
258 return size;
never executed: return size;
0
259}-
260-
261/*!-
262 Constructs a command link with no text and a \a parent.-
263*/-
264-
265QCommandLinkButton::QCommandLinkButton(QWidget *parent)-
266: QPushButton(*new QCommandLinkButtonPrivate, parent)-
267{-
268 Q_D(QCommandLinkButton);-
269 d->init();-
270}
never executed: end of block
0
271-
272/*!-
273 Constructs a command link with the parent \a parent and the text \a-
274 text.-
275*/-
276-
277QCommandLinkButton::QCommandLinkButton(const QString &text, QWidget *parent)-
278 : QPushButton(*new QCommandLinkButtonPrivate, parent)-
279{-
280 Q_D(QCommandLinkButton);-
281 setText(text);-
282 d->init();-
283}
never executed: end of block
0
284-
285/*!-
286 Constructs a command link with a \a text, a \a description, and a \a parent.-
287*/-
288QCommandLinkButton::QCommandLinkButton(const QString &text, const QString &description, QWidget *parent)-
289 : QPushButton(*new QCommandLinkButtonPrivate, parent)-
290{-
291 Q_D(QCommandLinkButton);-
292 setText(text);-
293 setDescription(description);-
294 d->init();-
295}
never executed: end of block
0
296-
297/*!-
298 Destructor.-
299*/-
300QCommandLinkButton::~QCommandLinkButton()-
301{-
302}-
303-
304/*! \reimp */-
305bool QCommandLinkButton::event(QEvent *e)-
306{-
307 return QPushButton::event(e);
never executed: return QPushButton::event(e);
0
308}-
309-
310/*! \reimp */-
311QSize QCommandLinkButton::sizeHint() const-
312{-
313// Standard size hints from UI specs-
314// Without note: 135, 41-
315// With note: 135, 60-
316 Q_D(const QCommandLinkButton);-
317-
318 QSize size = QPushButton::sizeHint();-
319 QFontMetrics fm(d->titleFont());-
320 int textWidth = qMax(fm.width(text()), 135);-
321 int buttonWidth = textWidth + d->textOffset() + d->rightMargin();-
322 int heightWithoutDescription = d->descriptionOffset() + d->bottomMargin();-
323-
324 size.setWidth(qMax(size.width(), buttonWidth));-
325 size.setHeight(qMax(d->description.isEmpty() ? 41 : 60,-
326 heightWithoutDescription + d->descriptionHeight(buttonWidth)));-
327 return size;
never executed: return size;
0
328}-
329-
330/*! \reimp */-
331int QCommandLinkButton::heightForWidth(int width) const-
332{-
333 Q_D(const QCommandLinkButton);-
334 int heightWithoutDescription = d->descriptionOffset() + d->bottomMargin();-
335 // find the width available for the description area-
336 return qMax(heightWithoutDescription + d->descriptionHeight(width),
never executed: return qMax(heightWithoutDescription + d->descriptionHeight(width), icon().actualSize(iconSize()).height() + d->topMargin() + d->bottomMargin());
0
337 icon().actualSize(iconSize()).height() + d->topMargin() +
never executed: return qMax(heightWithoutDescription + d->descriptionHeight(width), icon().actualSize(iconSize()).height() + d->topMargin() + d->bottomMargin());
0
338 d->bottomMargin());
never executed: return qMax(heightWithoutDescription + d->descriptionHeight(width), icon().actualSize(iconSize()).height() + d->topMargin() + d->bottomMargin());
0
339}-
340-
341/*! \reimp */-
342void QCommandLinkButton::paintEvent(QPaintEvent *)-
343{-
344 Q_D(QCommandLinkButton);-
345 QStylePainter p(this);-
346 p.save();-
347-
348 QStyleOptionButton option;-
349 initStyleOption(&option);-
350-
351 //Enable command link appearance on Vista-
352 option.features |= QStyleOptionButton::CommandLinkButton;-
353 option.text = QString();-
354 option.icon = QIcon(); //we draw this ourselves-
355 QSize pixmapSize = icon().actualSize(iconSize());-
356-
357 int vOffset = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical) : 0;
isDown()Description
TRUEnever evaluated
FALSEnever evaluated
0
358 int hOffset = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal) : 0;
isDown()Description
TRUEnever evaluated
FALSEnever evaluated
0
359-
360 //Draw icon-
361 p.drawControl(QStyle::CE_PushButton, option);-
362 if (!icon().isNull())
!icon().isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
363 p.drawPixmap(d->leftMargin() + hOffset, d->topMargin() + vOffset,
never executed: p.drawPixmap(d->leftMargin() + hOffset, d->topMargin() + vOffset, icon().pixmap(pixmapSize, isEnabled() ? QIcon::Normal : QIcon::Disabled, isChecked() ? QIcon::On : QIcon::Off));
0
364 icon().pixmap(pixmapSize, isEnabled() ? QIcon::Normal : QIcon::Disabled,
never executed: p.drawPixmap(d->leftMargin() + hOffset, d->topMargin() + vOffset, icon().pixmap(pixmapSize, isEnabled() ? QIcon::Normal : QIcon::Disabled, isChecked() ? QIcon::On : QIcon::Off));
0
365 isChecked() ? QIcon::On : QIcon::Off));
never executed: p.drawPixmap(d->leftMargin() + hOffset, d->topMargin() + vOffset, icon().pixmap(pixmapSize, isEnabled() ? QIcon::Normal : QIcon::Disabled, isChecked() ? QIcon::On : QIcon::Off));
0
366-
367 //Draw title-
368 QColor textColor = palette().buttonText().color();-
369 if (isEnabled() && d->usingVistaStyle()) {
isEnabled()Description
TRUEnever evaluated
FALSEnever evaluated
d->usingVistaStyle()Description
TRUEnever evaluated
FALSEnever evaluated
0
370 textColor = QColor(21, 28, 85);-
371 if (underMouse() && !isDown())
underMouse()Description
TRUEnever evaluated
FALSEnever evaluated
!isDown()Description
TRUEnever evaluated
FALSEnever evaluated
0
372 textColor = QColor(7, 64, 229);
never executed: textColor = QColor(7, 64, 229);
0
373 //A simple text color transition-
374 d->currentColor = d->mergedColors(textColor, d->currentColor, 60);-
375 option.palette.setColor(QPalette::ButtonText, d->currentColor);-
376 }
never executed: end of block
0
377-
378 int textflags = Qt::TextShowMnemonic;-
379 if (!style()->styleHint(QStyle::SH_UnderlineShortcut, &option, this))
!style()->styl...&option, this)Description
TRUEnever evaluated
FALSEnever evaluated
0
380 textflags |= Qt::TextHideMnemonic;
never executed: textflags |= Qt::TextHideMnemonic;
0
381-
382 p.setFont(d->titleFont());-
383 p.drawItemText(d->titleRect().translated(hOffset, vOffset),-
384 textflags, option.palette, isEnabled(), text(), QPalette::ButtonText);-
385-
386 //Draw description-
387 textflags |= Qt::TextWordWrap | Qt::ElideRight;-
388 p.setFont(d->descriptionFont());-
389 p.drawItemText(d->descriptionRect().translated(hOffset, vOffset), textflags,-
390 option.palette, isEnabled(), description(), QPalette::ButtonText);-
391 p.restore();-
392}
never executed: end of block
0
393-
394void QCommandLinkButton::setDescription(const QString &description)-
395{-
396 Q_D(QCommandLinkButton);-
397 d->description = description;-
398 updateGeometry();-
399 update();-
400}
never executed: end of block
0
401-
402QString QCommandLinkButton::description() const-
403{-
404 Q_D(const QCommandLinkButton);-
405 return d->description;
never executed: return d->description;
0
406}-
407-
408QT_END_NAMESPACE-
409-
410#include "moc_qcommandlinkbutton.cpp"-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9