Plasma
label.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright 2008 Aaron Seigo <aseigo@kde.org> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU Library General Public License as 00006 * published by the Free Software Foundation; either version 2, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details 00013 * 00014 * You should have received a copy of the GNU Library General Public 00015 * License along with this program; if not, write to the 00016 * Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "label.h" 00021 00022 #include <QApplication> 00023 #include <QDir> 00024 #include <QGraphicsSceneMouseEvent> 00025 #include <QLabel> 00026 #include <QMenu> 00027 #include <QPainter> 00028 #include <QStyleOptionGraphicsItem> 00029 00030 #include <kcolorscheme.h> 00031 #include <kglobalsettings.h> 00032 #include <kmimetype.h> 00033 00034 #include "private/themedwidgetinterface_p.h" 00035 #include "svg.h" 00036 #include "theme.h" 00037 00038 namespace Plasma 00039 { 00040 00041 class LabelPrivate : public ThemedWidgetInterface<Label> 00042 { 00043 public: 00044 LabelPrivate(Label *label) 00045 : ThemedWidgetInterface<Label>(label), 00046 svg(0), 00047 textSelectable(false) 00048 { 00049 } 00050 00051 ~LabelPrivate() 00052 { 00053 delete svg; 00054 } 00055 00056 void setPixmap() 00057 { 00058 if (imagePath.isEmpty()) { 00059 delete svg; 00060 svg = 0; 00061 return; 00062 } 00063 00064 KMimeType::Ptr mime = KMimeType::findByPath(absImagePath); 00065 QPixmap pm(q->size().toSize()); 00066 00067 if (mime->is("image/svg+xml") || mime->is("image/svg+xml-compressed")) { 00068 if (!svg || svg->imagePath() != absImagePath) { 00069 delete svg; 00070 svg = new Svg(); 00071 svg->setImagePath(imagePath); 00072 QObject::connect(svg, SIGNAL(repaintNeeded()), q, SLOT(setPixmap())); 00073 } 00074 00075 QPainter p(&pm); 00076 svg->paint(&p, pm.rect()); 00077 } else { 00078 delete svg; 00079 svg = 0; 00080 pm = QPixmap(absImagePath); 00081 } 00082 00083 static_cast<QLabel*>(q->widget())->setPixmap(pm); 00084 } 00085 00086 QString imagePath; 00087 QString absImagePath; 00088 Svg *svg; 00089 bool textSelectable : 1; 00090 }; 00091 00092 Label::Label(QGraphicsWidget *parent) 00093 : QGraphicsProxyWidget(parent), 00094 d(new LabelPrivate(this)) 00095 { 00096 QLabel *native = new QLabel; 00097 native->setWindowFlags(native->windowFlags()|Qt::BypassGraphicsProxyWidget); 00098 connect(native, SIGNAL(linkActivated(QString)), this, SIGNAL(linkActivated(QString))); 00099 connect(native, SIGNAL(linkHovered(QString)), this, SIGNAL(linkHovered(QString))); 00100 00101 native->setAttribute(Qt::WA_NoSystemBackground); 00102 native->setWordWrap(true); 00103 setWidget(native); 00104 native->setWindowIcon(QIcon()); 00105 d->initTheming(); 00106 } 00107 00108 Label::~Label() 00109 { 00110 delete d; 00111 } 00112 00113 void Label::setText(const QString &text) 00114 { 00115 static_cast<QLabel*>(widget())->setText(text); 00116 updateGeometry(); 00117 } 00118 00119 QString Label::text() const 00120 { 00121 return static_cast<QLabel*>(widget())->text(); 00122 } 00123 00124 void Label::setImage(const QString &path) 00125 { 00126 if (d->imagePath == path) { 00127 return; 00128 } 00129 00130 delete d->svg; 00131 d->svg = 0; 00132 d->imagePath = path; 00133 00134 bool absolutePath = !path.isEmpty() && 00135 #ifdef Q_WS_WIN 00136 !QDir::isRelativePath(path) 00137 #else 00138 (path[0] == '/' || path.startsWith(QLatin1String(":/"))) 00139 #endif 00140 ; 00141 00142 if (absolutePath) { 00143 d->absImagePath = path; 00144 } else { 00145 //TODO: package support 00146 d->absImagePath = Theme::defaultTheme()->imagePath(path); 00147 } 00148 00149 d->setPixmap(); 00150 } 00151 00152 QString Label::image() const 00153 { 00154 return d->imagePath; 00155 } 00156 00157 void Label::setScaledContents(bool scaled) 00158 { 00159 static_cast<QLabel*>(widget())->setScaledContents(scaled); 00160 } 00161 00162 bool Label::hasScaledContents() const 00163 { 00164 return static_cast<QLabel*>(widget())->hasScaledContents(); 00165 } 00166 00167 void Label::setTextSelectable(bool enable) 00168 { 00169 if (enable) { 00170 nativeWidget()->setTextInteractionFlags(Qt::TextBrowserInteraction); 00171 } else { 00172 nativeWidget()->setTextInteractionFlags(Qt::LinksAccessibleByMouse); 00173 } 00174 00175 d->textSelectable = enable; 00176 } 00177 00178 bool Label::textSelectable() const 00179 { 00180 return d->textSelectable; 00181 } 00182 00183 void Label::setAlignment(Qt::Alignment alignment) 00184 { 00185 nativeWidget()->setAlignment(alignment); 00186 } 00187 00188 Qt::Alignment Label::alignment() const 00189 { 00190 return nativeWidget()->alignment(); 00191 } 00192 00193 void Label::setWordWrap(bool wrap) 00194 { 00195 nativeWidget()->setWordWrap(wrap); 00196 } 00197 00198 bool Label::wordWrap() const 00199 { 00200 return nativeWidget()->wordWrap(); 00201 } 00202 00203 void Label::setStyleSheet(const QString &stylesheet) 00204 { 00205 widget()->setStyleSheet(stylesheet); 00206 } 00207 00208 QString Label::styleSheet() 00209 { 00210 return widget()->styleSheet(); 00211 } 00212 00213 QLabel *Label::nativeWidget() const 00214 { 00215 return static_cast<QLabel*>(widget()); 00216 } 00217 00218 void Label::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data) 00219 { 00220 Q_UNUSED(sourceName); 00221 00222 QStringList texts; 00223 foreach (const QVariant &v, data) { 00224 if (v.canConvert(QVariant::String)) { 00225 texts << v.toString(); 00226 } 00227 } 00228 00229 setText(texts.join(" ")); 00230 } 00231 00232 void Label::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) 00233 { 00234 if (d->textSelectable || nativeWidget()->text().contains("<a ", Qt::CaseInsensitive)){ 00235 QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()), 00236 event->pos().toPoint(), event->screenPos(), event->modifiers()); 00237 QApplication::sendEvent(nativeWidget(), &contextMenuEvent); 00238 }else{ 00239 event->ignore(); 00240 } 00241 } 00242 00243 void Label::resizeEvent(QGraphicsSceneResizeEvent *event) 00244 { 00245 d->setPixmap(); 00246 QGraphicsProxyWidget::resizeEvent(event); 00247 } 00248 00249 void Label::mousePressEvent(QGraphicsSceneMouseEvent *event) 00250 { 00251 QGraphicsProxyWidget::mousePressEvent(event); 00252 //FIXME: when QTextControl accept()s mouse press events (as of Qt 4.6.2, it processes them 00253 //but never marks them as accepted) the following event->accept() can be removed 00254 if (d->textSelectable) { 00255 event->accept(); 00256 } 00257 } 00258 00259 void Label::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 00260 { 00261 if (d->textSelectable) { 00262 QGraphicsProxyWidget::mouseMoveEvent(event); 00263 } 00264 } 00265 00266 void Label::paint(QPainter *painter, 00267 const QStyleOptionGraphicsItem *option, 00268 QWidget *widget) 00269 { 00270 QLabel *native = nativeWidget(); 00271 QFontMetrics fm = native->font(); 00272 00273 //indirect painting still used for fade out 00274 if (native->wordWrap() || native->text().isEmpty() || size().width() >= fm.width(native->text())) { 00275 QGraphicsProxyWidget::paint(painter, option, widget); 00276 } else { 00277 const int gradientLength = 25; 00278 QPixmap buffer(contentsRect().size().toSize()); 00279 buffer.fill(Qt::transparent); 00280 00281 QPainter buffPainter(&buffer); 00282 00283 QGraphicsProxyWidget::paint(&buffPainter, option, widget); 00284 00285 QLinearGradient gr; 00286 00287 buffPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); 00288 buffPainter.setPen(Qt::NoPen); 00289 00290 if (option->direction == Qt::LeftToRight) { 00291 gr.setStart(size().width()-gradientLength, 0); 00292 gr.setFinalStop(size().width(), 0); 00293 gr.setColorAt(0, Qt::black); 00294 gr.setColorAt(1, Qt::transparent); 00295 buffPainter.setBrush(gr); 00296 00297 buffPainter.drawRect(QRect(gr.start().toPoint(), QSize(gradientLength, size().height()))); 00298 } else { 00299 gr.setStart(0, 0); 00300 gr.setFinalStop(gradientLength, 0); 00301 gr.setColorAt(0, Qt::transparent); 00302 gr.setColorAt(1, Qt::black); 00303 buffPainter.setBrush(gr); 00304 00305 buffPainter.drawRect(QRect(0, 0, gradientLength, size().height())); 00306 } 00307 00308 buffPainter.end(); 00309 painter->drawPixmap(contentsRect(), buffer, buffer.rect()); 00310 } 00311 } 00312 00313 void Label::changeEvent(QEvent *event) 00314 { 00315 d->changeEvent(event); 00316 QGraphicsProxyWidget::changeEvent(event); 00317 } 00318 00319 bool Label::event(QEvent *event) 00320 { 00321 d->event(event); 00322 return QGraphicsProxyWidget::event(event); 00323 } 00324 00325 QVariant Label::itemChange(GraphicsItemChange change, const QVariant & value) 00326 { 00327 if (change == QGraphicsItem::ItemCursorHasChanged) { 00328 nativeWidget()->setCursor(cursor()); 00329 } 00330 00331 return QGraphicsWidget::itemChange(change, value); 00332 } 00333 00334 QSizeF Label::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const 00335 { 00336 if (sizePolicy().verticalPolicy() == QSizePolicy::Fixed) { 00337 return QGraphicsProxyWidget::sizeHint(Qt::PreferredSize, constraint); 00338 } else { 00339 return QGraphicsProxyWidget::sizeHint(which, constraint); 00340 } 00341 } 00342 00343 } // namespace Plasma 00344 00345 #include <label.moc> 00346
KDE 4.6 API Reference