Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "qxtpushbutton.h"
00026 #include <QAbstractTextDocumentLayout>
00027 #include <QStyleOptionButton>
00028 #include <QTextDocument>
00029 #include <QStylePainter>
00030 #include <QStyle>
00031 #include <QMenu>
00032
00033 static const int Vertical_Mask = 0x02;
00034
00035 class QxtPushButtonPrivate : public QxtPrivate<QxtPushButton>
00036 {
00037 public:
00038 QXT_DECLARE_PUBLIC(QxtPushButton);
00039 QxtPushButtonPrivate();
00040
00041 bool isRichText() const;
00042 QStyleOptionButton getStyleOption() const;
00043
00044 QString text;
00045 Qxt::Rotation rot;
00046 Qt::TextFormat format;
00047 mutable QTextDocument* doc;
00048 };
00049
00050 QxtPushButtonPrivate::QxtPushButtonPrivate() :
00051 rot(Qxt::NoRotation), format(Qt::PlainText), doc(0)
00052 {}
00053
00054 bool QxtPushButtonPrivate::isRichText() const
00055 {
00056 #if QT_VERSION >= 0x040200
00057 bool rich = (format == Qt::RichText) || (format == Qt::AutoText && Qt::mightBeRichText(qxt_p().text()));
00058 if (rich && !doc)
00059 {
00060 doc = new QTextDocument(const_cast<QxtPushButton*>(&qxt_p()));
00061 doc->setUndoRedoEnabled(false);
00062 }
00063 #else // QT_VERSION < 0x040200
00064 bool rich = false;
00065 #endif // QT_VERSION
00066 return rich;
00067 }
00068
00069 QStyleOptionButton QxtPushButtonPrivate::getStyleOption() const
00070 {
00071 QStyleOptionButton option;
00072 option.initFrom(&qxt_p());
00073 if (rot & Vertical_Mask)
00074 {
00075 QSize size = option.rect.size();
00076 size.transpose();
00077 option.rect.setSize(size);
00078 }
00079 option.features = QStyleOptionButton::None;
00080 if (qxt_p().isFlat())
00081 option.features |= QStyleOptionButton::Flat;
00082 if (qxt_p().menu())
00083 option.features |= QStyleOptionButton::HasMenu;
00084 if (qxt_p().autoDefault() || qxt_p().isDefault())
00085 option.features |= QStyleOptionButton::AutoDefaultButton;
00086 if (qxt_p().isDefault())
00087 option.features |= QStyleOptionButton::DefaultButton;
00088 if (qxt_p().isDown() || (qxt_p().menu() && qxt_p().menu()->isVisible()))
00089 option.state |= QStyle::State_Sunken;
00090 if (qxt_p().isChecked())
00091 option.state |= QStyle::State_On;
00092 if (!qxt_p().isFlat() && !qxt_p().isDown())
00093 option.state |= QStyle::State_Raised;
00094 if (!isRichText())
00095 {
00096 option.text = qxt_p().text();
00097 option.icon = qxt_p().icon();
00098 option.iconSize = qxt_p().iconSize();
00099 }
00100 return option;
00101 }
00102
00117 QxtPushButton::QxtPushButton(QWidget* parent) : QPushButton(parent)
00118 {
00119 QXT_INIT_PRIVATE(QxtPushButton);
00120 }
00121
00125 QxtPushButton::QxtPushButton(const QString& text, QWidget* parent) : QPushButton(text, parent)
00126 {
00127 QXT_INIT_PRIVATE(QxtPushButton);
00128 }
00129
00135 QxtPushButton::QxtPushButton(const QIcon& icon, const QString& text, QWidget* parent) : QPushButton(icon, text, parent)
00136 {
00137 QXT_INIT_PRIVATE(QxtPushButton);
00138 }
00139
00143 QxtPushButton::QxtPushButton(Qxt::Rotation rotation, const QString& text, QWidget* parent) : QPushButton(text, parent)
00144 {
00145 QXT_INIT_PRIVATE(QxtPushButton);
00146 setRotation(rotation);
00147 }
00148
00152 QxtPushButton::~QxtPushButton()
00153 {}
00154
00164 Qxt::Rotation QxtPushButton::rotation() const
00165 {
00166 return qxt_d().rot;
00167 }
00168
00169 void QxtPushButton::setRotation(Qxt::Rotation rotation)
00170 {
00171 if (qxt_d().rot != rotation)
00172 {
00173 qxt_d().rot = rotation;
00174 switch (rotation)
00175 {
00176 case Qxt::NoRotation:
00177 case Qxt::UpsideDown:
00178 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00179 break;
00180
00181 case Qxt::Clockwise:
00182 case Qxt::CounterClockwise:
00183 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
00184 break;
00185
00186 default:
00187
00188 break;
00189 }
00190 updateGeometry();
00191 update();
00192 }
00193 }
00194
00207 Qt::TextFormat QxtPushButton::textFormat() const
00208 {
00209 return qxt_d().format;
00210 }
00211
00212 void QxtPushButton::setTextFormat(Qt::TextFormat format)
00213 {
00214 if (qxt_d().format != format)
00215 {
00216 qxt_d().format = format;
00217 if (!qxt_d().isRichText())
00218 {
00219 delete qxt_d().doc;
00220 qxt_d().doc = 0;
00221 }
00222 qxt_d().text.clear();
00223 update();
00224 updateGeometry();
00225 }
00226 }
00227
00231 QSize QxtPushButton::sizeHint() const
00232 {
00233 QSize size;
00234 if (qxt_d().isRichText())
00235 size = qxt_d().doc->documentLayout()->documentSize().toSize();
00236 else
00237 size = QPushButton::sizeHint();
00238
00239 if (qxt_d().rot & Vertical_Mask)
00240 size.transpose();
00241 return size;
00242 }
00243
00247 QSize QxtPushButton::minimumSizeHint() const
00248 {
00249 return sizeHint();
00250 }
00251
00255 void QxtPushButton::paintEvent(QPaintEvent* event)
00256 {
00257 Q_UNUSED(event);
00258
00259
00260 if (text() != qxt_d().text)
00261 {
00262 qxt_d().text = text();
00263 if (qxt_d().isRichText())
00264 qxt_d().doc->setHtml(qxt_d().text);
00265 updateGeometry();
00266 }
00267
00268 QStylePainter painter(this);
00269 painter.rotate(qxt_d().rot);
00270 switch (qxt_d().rot)
00271 {
00272 case Qxt::UpsideDown:
00273 painter.translate(-width(), -height());
00274 break;
00275
00276 case Qxt::Clockwise:
00277 painter.translate(0, -width());
00278 break;
00279
00280 case Qxt::CounterClockwise:
00281 painter.translate(-height(), 0);
00282 break;
00283
00284 default:
00285
00286 break;
00287 }
00288
00289 const QStyleOptionButton option = qxt_d().getStyleOption();
00290 painter.drawControl(QStyle::CE_PushButton, option);
00291
00292 #if QT_VERSION >= 0x040200
00293 if (qxt_d().isRichText())
00294 {
00295 int dx = 0;
00296 int dy = 0;
00297 if (option.state & (QStyle::State_On | QStyle::State_Sunken))
00298 {
00299 dx += style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &option, this);
00300 dy += style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &option, this);
00301 }
00302
00303 QRect area = rect();
00304 const QSizeF docSize = qxt_d().doc->documentLayout()->documentSize();
00305 if (qxt_d().rot & Vertical_Mask)
00306 {
00307 dx += static_cast<int>((height() - docSize.width()) / 2);
00308 dy += static_cast<int>((width() - docSize.height()) / 2);
00309 painter.translate(dx, dy);
00310
00311 QSize size = area.size();
00312 size.transpose();
00313 area.setSize(size);
00314 }
00315 else
00316 {
00317 dx += static_cast<int>((width() - docSize.width()) / 2);
00318 dy += static_cast<int>((height() - docSize.height()) / 2);
00319 painter.translate(dx, dy);
00320 }
00321 qxt_d().doc->drawContents(&painter, area);
00322 }
00323 #endif // QT_VERSION
00324 }