• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.8.5 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

kmessagewidget.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002  *
00003  * Copyright (c) 2011 Aurélien Gâteau <agateau@kde.org>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00018  * 02110-1301  USA
00019  */
00020 #include "kmessagewidget.h"
00021 
00022 #include <kaction.h>
00023 #include <kcolorscheme.h>
00024 #include <kdebug.h>
00025 #include <kglobalsettings.h>
00026 #include <kicon.h>
00027 #include <kiconloader.h>
00028 #include <kstandardaction.h>
00029 
00030 #include <QEvent>
00031 #include <QGridLayout>
00032 #include <QHBoxLayout>
00033 #include <QLabel>
00034 #include <QPainter>
00035 #include <QShowEvent>
00036 #include <QTimeLine>
00037 #include <QToolButton>
00038 
00039 //---------------------------------------------------------------------
00040 // KMessageWidgetPrivate
00041 //---------------------------------------------------------------------
00042 class KMessageWidgetPrivate
00043 {
00044 public:
00045     void init(KMessageWidget*);
00046 
00047     KMessageWidget* q;
00048     QFrame* content;
00049     QLabel* iconLabel;
00050     QLabel* textLabel;
00051     QToolButton* closeButton;
00052     QTimeLine* timeLine;
00053 
00054     KMessageWidget::MessageType messageType;
00055     bool wordWrap;
00056     QList<QToolButton*> buttons;
00057     QPixmap contentSnapShot;
00058 
00059     void createLayout();
00060     void updateSnapShot();
00061     void updateLayout();
00062     void slotTimeLineChanged(qreal);
00063     void slotTimeLineFinished();
00064 };
00065 
00066 void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
00067 {
00068     q = q_ptr;
00069 
00070     q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00071 
00072     timeLine = new QTimeLine(500, q);
00073     QObject::connect(timeLine, SIGNAL(valueChanged(qreal)), q, SLOT(slotTimeLineChanged(qreal)));
00074     QObject::connect(timeLine, SIGNAL(finished()), q, SLOT(slotTimeLineFinished()));
00075 
00076     content = new QFrame(q);
00077     content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00078 
00079     wordWrap = false;
00080 
00081     iconLabel = new QLabel(content);
00082     iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00083 
00084     textLabel = new QLabel(content);
00085     textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00086     textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
00087 
00088     KAction* closeAction = KStandardAction::close(q, SLOT(animatedHide()), q);
00089 
00090     closeButton = new QToolButton(content);
00091     closeButton->setAutoRaise(true);
00092     closeButton->setDefaultAction(closeAction);
00093 
00094     q->setMessageType(KMessageWidget::Information);
00095 }
00096 
00097 void KMessageWidgetPrivate::createLayout()
00098 {
00099     delete content->layout();
00100 
00101     content->resize(q->size());
00102 
00103     qDeleteAll(buttons);
00104     buttons.clear();
00105 
00106     Q_FOREACH(QAction* action, q->actions()) {
00107         QToolButton* button = new QToolButton(content);
00108         button->setDefaultAction(action);
00109         button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
00110         buttons.append(button);
00111     }
00112 
00113     // AutoRaise reduces visual clutter, but we don't want to turn it on if
00114     // there are other buttons, otherwise the close button will look different
00115     // from the others.
00116     closeButton->setAutoRaise(buttons.isEmpty());
00117 
00118     if (wordWrap) {
00119         QGridLayout* layout = new QGridLayout(content);
00120         // Set alignment to make sure icon does not move down if text wraps
00121         layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
00122         layout->addWidget(textLabel, 0, 1);
00123 
00124         QHBoxLayout* buttonLayout = new QHBoxLayout;
00125         buttonLayout->addStretch();
00126         Q_FOREACH(QToolButton* button, buttons) {
00127             // For some reason, calling show() is necessary if wordwrap is true,
00128             // otherwise the buttons do not show up. It is not needed if
00129             // wordwrap is false.
00130             button->show();
00131             buttonLayout->addWidget(button);
00132         }
00133         buttonLayout->addWidget(closeButton);
00134         layout->addItem(buttonLayout, 1, 0, 1, 2);
00135     } else {
00136         QHBoxLayout* layout = new QHBoxLayout(content);
00137         layout->addWidget(iconLabel);
00138         layout->addWidget(textLabel);
00139 
00140         Q_FOREACH(QToolButton* button, buttons) {
00141             layout->addWidget(button);
00142         }
00143 
00144         layout->addWidget(closeButton);
00145     };
00146 
00147     if (q->isVisible()) {
00148         q->setFixedHeight(content->sizeHint().height());
00149     }
00150     q->updateGeometry();
00151 }
00152 
00153 void KMessageWidgetPrivate::updateLayout()
00154 {
00155     if (content->layout()) {
00156         createLayout();
00157     }
00158 }
00159 
00160 void KMessageWidgetPrivate::updateSnapShot()
00161 {
00162     contentSnapShot = QPixmap(content->size());
00163     contentSnapShot.fill(Qt::transparent);
00164     content->render(&contentSnapShot, QPoint(), QRegion(), QWidget::DrawChildren);
00165 }
00166 
00167 void KMessageWidgetPrivate::slotTimeLineChanged(qreal value)
00168 {
00169     q->setFixedHeight(qMin(value * 2, qreal(1.0)) * content->height());
00170     q->update();
00171 }
00172 
00173 void KMessageWidgetPrivate::slotTimeLineFinished()
00174 {
00175     if (timeLine->direction() == QTimeLine::Forward) {
00176         // Show
00177         content->move(0, 0);
00178     } else {
00179         // Hide
00180         q->hide();
00181     }
00182 }
00183 
00184 
00185 //---------------------------------------------------------------------
00186 // KMessageWidget
00187 //---------------------------------------------------------------------
00188 KMessageWidget::KMessageWidget(QWidget* parent)
00189     : QFrame(parent)
00190     , d(new KMessageWidgetPrivate)
00191 {
00192     d->init(this);
00193 }
00194 
00195 KMessageWidget::KMessageWidget(const QString& text, QWidget* parent)
00196     : QFrame(parent)
00197     , d(new KMessageWidgetPrivate)
00198 {
00199     d->init(this);
00200     setText(text);
00201 }
00202 
00203 KMessageWidget::~KMessageWidget()
00204 {
00205     delete d;
00206 }
00207 
00208 QString KMessageWidget::text() const
00209 {
00210     return d->textLabel->text();
00211 }
00212 
00213 void KMessageWidget::setText(const QString& text)
00214 {
00215     d->textLabel->setText(text);
00216     updateGeometry();
00217 }
00218 
00219 KMessageWidget::MessageType KMessageWidget::messageType() const
00220 {
00221     return d->messageType;
00222 }
00223 
00224 static void getColorsFromColorScheme(KColorScheme::BackgroundRole bgRole, QColor* bg, QColor* fg)
00225 {
00226     KColorScheme scheme(QPalette::Active, KColorScheme::Window);
00227     *bg = scheme.background(bgRole).color();
00228     *fg = scheme.foreground().color();
00229 }
00230 
00231 void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
00232 {
00233     d->messageType = type;
00234     KIcon icon;
00235     QColor bg0, bg1, bg2, border, fg;
00236     switch (type) {
00237     case Positive:
00238         icon = KIcon("dialog-ok");
00239         getColorsFromColorScheme(KColorScheme::PositiveBackground, &bg1, &fg);
00240         break;
00241     case Information:
00242         icon = KIcon("dialog-information");
00243         // There is no "information" background role in KColorScheme, use the
00244         // colors of highlighted items instead
00245         bg1 = palette().highlight().color();
00246         fg = palette().highlightedText().color();
00247         break;
00248     case Warning:
00249         icon = KIcon("dialog-warning");
00250         getColorsFromColorScheme(KColorScheme::NeutralBackground, &bg1, &fg);
00251         break;
00252     case Error:
00253         icon = KIcon("dialog-error");
00254         getColorsFromColorScheme(KColorScheme::NegativeBackground, &bg1, &fg);
00255         break;
00256     }
00257 
00258     // Colors
00259     bg0 = bg1.lighter(110);
00260     bg2 = bg1.darker(110);
00261     border = KColorScheme::shade(bg1, KColorScheme::DarkShade);
00262 
00263     d->content->setStyleSheet(
00264         QString(".QFrame {"
00265             "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
00266             "    stop: 0 %1,"
00267             "    stop: 0.1 %2,"
00268             "    stop: 1.0 %3);"
00269             "border-radius: 5px;"
00270             "border: 1px solid %4;"
00271             "}"
00272             ".QLabel { color: %5; }"
00273             )
00274         .arg(bg0.name())
00275         .arg(bg1.name())
00276         .arg(bg2.name())
00277         .arg(border.name())
00278         .arg(fg.name())
00279         );
00280 
00281     // Icon
00282     const int size = KIconLoader::global()->currentSize(KIconLoader::MainToolbar);
00283     d->iconLabel->setPixmap(icon.pixmap(size));
00284 }
00285 
00286 QSize KMessageWidget::sizeHint() const
00287 {
00288     ensurePolished();
00289     return d->content->sizeHint();
00290 }
00291 
00292 QSize KMessageWidget::minimumSizeHint() const
00293 {
00294     ensurePolished();
00295     return d->content->minimumSizeHint();
00296 }
00297 
00298 bool KMessageWidget::event(QEvent* event)
00299 {
00300     if (event->type() == QEvent::Polish && !d->content->layout()) {
00301         d->createLayout();
00302     }
00303     return QFrame::event(event);
00304 }
00305 
00306 void KMessageWidget::resizeEvent(QResizeEvent* event)
00307 {
00308     QFrame::resizeEvent(event);
00309     if (d->timeLine->state() == QTimeLine::NotRunning) {
00310         int contentHeight = d->content->heightForWidth(width());
00311         if (contentHeight == -1) {
00312             contentHeight = d->content->sizeHint().height();
00313         }
00314         d->content->resize(width(), contentHeight);
00315     }
00316 }
00317 
00318 int KMessageWidget::heightForWidth(int width) const
00319 {
00320     ensurePolished();
00321     return d->content->heightForWidth(width);
00322 }
00323 
00324 void KMessageWidget::paintEvent(QPaintEvent* event)
00325 {
00326     QFrame::paintEvent(event);
00327     if (d->timeLine->state() == QTimeLine::Running) {
00328         QPainter painter(this);
00329         painter.setOpacity(d->timeLine->currentValue() * d->timeLine->currentValue());
00330         painter.drawPixmap(0, 0, d->contentSnapShot);
00331     }
00332 }
00333 
00334 void KMessageWidget::showEvent(QShowEvent* event)
00335 {
00336     // Keep this method here to avoid breaking binary compatibility:
00337     // QFrame::showEvent() used to be reimplemented.
00338     QFrame::showEvent(event);
00339 }
00340 
00341 bool KMessageWidget::wordWrap() const
00342 {
00343     return d->wordWrap;
00344 }
00345 
00346 void KMessageWidget::setWordWrap(bool wordWrap)
00347 {
00348     d->wordWrap = wordWrap;
00349     d->textLabel->setWordWrap(wordWrap);
00350     d->updateLayout();
00351 }
00352 
00353 bool KMessageWidget::isCloseButtonVisible() const
00354 {
00355     return d->closeButton->isVisible();
00356 }
00357 
00358 void KMessageWidget::setCloseButtonVisible(bool show)
00359 {
00360     d->closeButton->setVisible(show);
00361 }
00362 
00363 void KMessageWidget::addAction(QAction* action)
00364 {
00365     QFrame::addAction(action);
00366     d->updateLayout();
00367 }
00368 
00369 void KMessageWidget::removeAction(QAction* action)
00370 {
00371     QFrame::removeAction(action);
00372     d->updateLayout();
00373 }
00374 
00375 void KMessageWidget::animatedShow()
00376 {
00377     if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
00378         show();
00379         return;
00380     }
00381 
00382     if (isVisible()) {
00383         return;
00384     }
00385 
00386     QFrame::show();
00387     setFixedHeight(0);
00388     int wantedHeight = d->content->sizeHint().height();
00389     d->content->setGeometry(0, -wantedHeight, width(), wantedHeight);
00390 
00391     d->updateSnapShot();
00392 
00393     d->timeLine->setDirection(QTimeLine::Forward);
00394     if (d->timeLine->state() == QTimeLine::NotRunning) {
00395         d->timeLine->start();
00396     }
00397 }
00398 
00399 void KMessageWidget::animatedHide()
00400 {
00401     if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
00402         hide();
00403         return;
00404     }
00405 
00406     if (!isVisible()) {
00407         return;
00408     }
00409 
00410     d->content->move(0, -d->content->height());
00411     d->updateSnapShot();
00412 
00413     d->timeLine->setDirection(QTimeLine::Backward);
00414     if (d->timeLine->state() == QTimeLine::NotRunning) {
00415         d->timeLine->start();
00416     }
00417 }
00418 
00419 #include "kmessagewidget.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed Nov 28 2012 09:48:21 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.8.5 API Reference

Skip menu "kdelibs-4.8.5 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal