1 /****************************************************************************
3 ** Copyright (C) Qxt Foundation. Some rights reserved.
5 ** This file is part of the QxtGui module of the Qt eXTension library
7 ** This library is free software; you can redistribute it and/or modify it
8 ** under the terms of th Common Public License, version 1.0, as published by
11 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14 ** FITNESS FOR A PARTICULAR PURPOSE.
16 ** You should have received a copy of the CPL along with this file.
17 ** See the LICENSE file and the cpl1.0.txt file included with the source
18 ** distribution for more information. If you did not receive a copy of the
19 ** license, contact the Qxt Foundation.
21 ** <http://libqxt.sourceforge.net> <foundation@libqxt.org>
23 ****************************************************************************/
24 #include "qxtpushbutton.h"
25 #include <QAbstractTextDocumentLayout>
26 #include <QStyleOptionButton>
27 #include <QTextDocument>
28 #include <QStylePainter>
32 static const int Vertical_Mask = 0x02;
34 class QxtPushButtonPrivate : public QxtPrivate<QxtPushButton>
37 QXT_DECLARE_PUBLIC(QxtPushButton);
38 QxtPushButtonPrivate();
40 bool isRichText() const;
41 QStyleOptionButton getStyleOption() const;
45 Qt::TextFormat format;
46 mutable QTextDocument* doc;
49 QxtPushButtonPrivate::QxtPushButtonPrivate() :
50 rot(Qxt::NoRotation), format(Qt::PlainText), doc(0)
53 bool QxtPushButtonPrivate::isRichText() const
55 #if QT_VERSION >= 0x040200
56 bool rich = (format == Qt::RichText) || (format == Qt::AutoText && Qt::mightBeRichText(qxt_p().text()));
59 doc = new QTextDocument(const_cast<QxtPushButton*>(&qxt_p()));
60 doc->setUndoRedoEnabled(false);
62 #else // QT_VERSION < 0x040200
68 QStyleOptionButton QxtPushButtonPrivate::getStyleOption() const
70 QStyleOptionButton option;
71 option.initFrom(&qxt_p());
72 if (rot & Vertical_Mask)
74 QSize size = option.rect.size();
76 option.rect.setSize(size);
78 option.features = QStyleOptionButton::None;
80 option.features |= QStyleOptionButton::Flat;
82 option.features |= QStyleOptionButton::HasMenu;
83 if (qxt_p().autoDefault() || qxt_p().isDefault())
84 option.features |= QStyleOptionButton::AutoDefaultButton;
85 if (qxt_p().isDefault())
86 option.features |= QStyleOptionButton::DefaultButton;
87 if (qxt_p().isDown() || (qxt_p().menu() && qxt_p().menu()->isVisible()))
88 option.state |= QStyle::State_Sunken;
89 if (qxt_p().isChecked())
90 option.state |= QStyle::State_On;
91 if (!qxt_p().isFlat() && !qxt_p().isDown())
92 option.state |= QStyle::State_Raised;
95 option.text = qxt_p().text();
96 option.icon = qxt_p().icon();
97 option.iconSize = qxt_p().iconSize();
103 \class QxtPushButton QxtPushButton
105 \brief An extended QPushButton with rotation and rich text support.
107 QxtPushButton is a QPushButton which can be rotated. In addition, QxtPushButton
108 provides rich text support.
110 \image html qxtpushbutton.png "QxtPushButton in action."
114 Constructs a new QxtPushButton with \a parent.
116 QxtPushButton::QxtPushButton(QWidget* parent) : QPushButton(parent)
118 QXT_INIT_PRIVATE(QxtPushButton);
122 Constructs a new QxtPushButton with \a text and \a parent.
124 QxtPushButton::QxtPushButton(const QString& text, QWidget* parent) : QPushButton(text, parent)
126 QXT_INIT_PRIVATE(QxtPushButton);
130 Constructs a new QxtPushButton with \a icon, \a text and \a parent.
132 \note An icon is not rendered when using rich text.
134 QxtPushButton::QxtPushButton(const QIcon& icon, const QString& text, QWidget* parent) : QPushButton(icon, text, parent)
136 QXT_INIT_PRIVATE(QxtPushButton);
140 Constructs a new QxtPushButton with \a rotation, \a text and \a parent.
142 QxtPushButton::QxtPushButton(Qxt::Rotation rotation, const QString& text, QWidget* parent) : QPushButton(text, parent)
144 QXT_INIT_PRIVATE(QxtPushButton);
145 setRotation(rotation);
149 Destructs the button.
151 QxtPushButton::~QxtPushButton()
155 \property QxtPushButton::rotation
156 \brief This property holds the rotation of the button
158 The button is rotated according to this property.
159 The default value is \b Qxt::NoRotation.
163 Qxt::Rotation QxtPushButton::rotation() const
168 void QxtPushButton::setRotation(Qxt::Rotation rotation)
170 if (qxt_d().rot != rotation)
172 qxt_d().rot = rotation;
175 case Qxt::NoRotation:
176 case Qxt::UpsideDown:
177 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
181 case Qxt::CounterClockwise:
182 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
195 \property QxtPushButton::textFormat
196 \brief This property holds the text format of the button
198 Supported formats are \b Qt::PlainText, \b Qt::RichText and \b Qt::AutoText.
200 The default format is \b Qt::PlainText.
202 \note Rich text requires Qt 4.2 or newer.
206 Qt::TextFormat QxtPushButton::textFormat() const
208 return qxt_d().format;
211 void QxtPushButton::setTextFormat(Qt::TextFormat format)
213 if (qxt_d().format != format)
215 qxt_d().format = format;
216 if (!qxt_d().isRichText())
221 qxt_d().text.clear();
227 QSize QxtPushButton::sizeHint() const
230 if (qxt_d().isRichText())
231 size = qxt_d().doc->documentLayout()->documentSize().toSize();
233 size = QPushButton::sizeHint();
235 if (qxt_d().rot & Vertical_Mask)
240 QSize QxtPushButton::minimumSizeHint() const
243 if (qxt_d().isRichText())
244 size = qxt_d().doc->documentLayout()->documentSize().toSize();
246 size = QPushButton::minimumSizeHint();
248 if (qxt_d().rot & Vertical_Mask)
253 void QxtPushButton::paintEvent(QPaintEvent* event)
257 // the only reliable way to detect text changes
258 if (text() != qxt_d().text)
260 qxt_d().text = text();
261 if (qxt_d().isRichText())
262 qxt_d().doc->setHtml(qxt_d().text);
266 QStylePainter painter(this);
267 painter.rotate(qxt_d().rot);
270 case Qxt::UpsideDown:
271 painter.translate(-width(), -height());
275 painter.translate(0, -width());
278 case Qxt::CounterClockwise:
279 painter.translate(-height(), 0);
287 const QStyleOptionButton option = qxt_d().getStyleOption();
288 painter.drawControl(QStyle::CE_PushButton, option);
290 #if QT_VERSION >= 0x040200
291 if (qxt_d().isRichText())
295 if (option.state & (QStyle::State_On | QStyle::State_Sunken))
297 dx += style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &option, this);
298 dy += style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &option, this);
302 const QSizeF docSize = qxt_d().doc->documentLayout()->documentSize();
303 if (qxt_d().rot & Vertical_Mask)
305 dx += static_cast<int>((height() - docSize.width()) / 2);
306 dy += static_cast<int>((width() - docSize.height()) / 2);
307 painter.translate(dx, dy);
309 QSize size = area.size();
315 dx += static_cast<int>((width() - docSize.width()) / 2);
316 dy += static_cast<int>((height() - docSize.height()) / 2);
317 painter.translate(dx, dy);
319 qxt_d().doc->drawContents(&painter, area);