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 hasLinks(false) 00049 { 00050 } 00051 00052 ~LabelPrivate() 00053 { 00054 delete svg; 00055 } 00056 00057 void setPixmap() 00058 { 00059 if (imagePath.isEmpty()) { 00060 delete svg; 00061 svg = 0; 00062 return; 00063 } 00064 00065 KMimeType::Ptr mime = KMimeType::findByPath(absImagePath); 00066 QPixmap pm(q->size().toSize()); 00067 00068 if (mime->is("image/svg+xml") || mime->is("image/svg+xml-compressed")) { 00069 if (!svg || svg->imagePath() != absImagePath) { 00070 delete svg; 00071 svg = new Svg(); 00072 svg->setImagePath(imagePath); 00073 QObject::connect(svg, SIGNAL(repaintNeeded()), q, SLOT(setPixmap())); 00074 } 00075 00076 QPainter p(&pm); 00077 svg->paint(&p, pm.rect()); 00078 } else { 00079 delete svg; 00080 svg = 0; 00081 pm = QPixmap(absImagePath); 00082 } 00083 00084 static_cast<QLabel*>(q->widget())->setPixmap(pm); 00085 } 00086 00087 QString imagePath; 00088 QString absImagePath; 00089 Svg *svg; 00090 bool textSelectable : 1; 00091 bool hasLinks : 1; 00092 }; 00093 00094 Label::Label(QGraphicsWidget *parent) 00095 : QGraphicsProxyWidget(parent), 00096 d(new LabelPrivate(this)) 00097 { 00098 QLabel *native = new QLabel; 00099 00100 native->setWindowFlags(native->windowFlags()|Qt::BypassGraphicsProxyWidget); 00101 native->setAttribute(Qt::WA_NoSystemBackground); 00102 native->setWordWrap(true); 00103 native->setWindowIcon(QIcon()); 00104 00105 connect(native, SIGNAL(linkActivated(QString)), this, SIGNAL(linkActivated(QString))); 00106 connect(native, SIGNAL(linkHovered(QString)), this, SIGNAL(linkHovered(QString))); 00107 00108 setWidget(native); 00109 d->initTheming(); 00110 } 00111 00112 Label::~Label() 00113 { 00114 delete d; 00115 } 00116 00117 void Label::setText(const QString &text) 00118 { 00119 d->hasLinks = text.contains("<a ", Qt::CaseInsensitive); 00120 static_cast<QLabel*>(widget())->setText(text); 00121 updateGeometry(); 00122 } 00123 00124 QString Label::text() const 00125 { 00126 return static_cast<QLabel*>(widget())->text(); 00127 } 00128 00129 void Label::setImage(const QString &path) 00130 { 00131 if (d->imagePath == path) { 00132 return; 00133 } 00134 00135 delete d->svg; 00136 d->svg = 0; 00137 d->imagePath = path; 00138 00139 bool absolutePath = !path.isEmpty() && 00140 #ifdef Q_WS_WIN 00141 !QDir::isRelativePath(path) 00142 #else 00143 (path[0] == '/' || path.startsWith(QLatin1String(":/"))) 00144 #endif 00145 ; 00146 00147 if (absolutePath) { 00148 d->absImagePath = path; 00149 } else { 00150 //TODO: package support 00151 d->absImagePath = Theme::defaultTheme()->imagePath(path); 00152 } 00153 00154 d->setPixmap(); 00155 } 00156 00157 QString Label::image() const 00158 { 00159 return d->imagePath; 00160 } 00161 00162 void Label::setScaledContents(bool scaled) 00163 { 00164 static_cast<QLabel*>(widget())->setScaledContents(scaled); 00165 } 00166 00167 bool Label::hasScaledContents() const 00168 { 00169 return static_cast<QLabel*>(widget())->hasScaledContents(); 00170 } 00171 00172 void Label::setTextSelectable(bool enable) 00173 { 00174 if (enable) { 00175 nativeWidget()->setTextInteractionFlags(Qt::TextBrowserInteraction); 00176 } else { 00177 nativeWidget()->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard); 00178 } 00179 00180 d->textSelectable = enable; 00181 } 00182 00183 bool Label::textSelectable() const 00184 { 00185 return d->textSelectable; 00186 } 00187 00188 void Label::setAlignment(Qt::Alignment alignment) 00189 { 00190 nativeWidget()->setAlignment(alignment); 00191 } 00192 00193 Qt::Alignment Label::alignment() const 00194 { 00195 return nativeWidget()->alignment(); 00196 } 00197 00198 void Label::setWordWrap(bool wrap) 00199 { 00200 nativeWidget()->setWordWrap(wrap); 00201 } 00202 00203 bool Label::wordWrap() const 00204 { 00205 return nativeWidget()->wordWrap(); 00206 } 00207 00208 void Label::setStyleSheet(const QString &stylesheet) 00209 { 00210 widget()->setStyleSheet(stylesheet); 00211 } 00212 00213 QString Label::styleSheet() 00214 { 00215 return widget()->styleSheet(); 00216 } 00217 00218 QLabel *Label::nativeWidget() const 00219 { 00220 return static_cast<QLabel*>(widget()); 00221 } 00222 00223 void Label::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data) 00224 { 00225 Q_UNUSED(sourceName); 00226 00227 QStringList texts; 00228 foreach (const QVariant &v, data) { 00229 if (v.canConvert(QVariant::String)) { 00230 texts << v.toString(); 00231 } 00232 } 00233 00234 setText(texts.join(" ")); 00235 } 00236 00237 void Label::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) 00238 { 00239 if (d->textSelectable || d->hasLinks){ 00240 QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()), 00241 event->pos().toPoint(), event->screenPos(), event->modifiers()); 00242 QApplication::sendEvent(nativeWidget(), &contextMenuEvent); 00243 }else{ 00244 event->ignore(); 00245 } 00246 } 00247 00248 void Label::resizeEvent(QGraphicsSceneResizeEvent *event) 00249 { 00250 d->setPixmap(); 00251 QGraphicsProxyWidget::resizeEvent(event); 00252 } 00253 00254 void Label::mousePressEvent(QGraphicsSceneMouseEvent *event) 00255 { 00256 QGraphicsProxyWidget::mousePressEvent(event); 00257 //FIXME: when QTextControl accept()s mouse press events (as of Qt 4.6.2, it processes them 00258 //but never marks them as accepted) the following event->accept() can be removed 00259 if (d->textSelectable || d->hasLinks) { 00260 event->accept(); 00261 } 00262 } 00263 00264 void Label::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 00265 { 00266 if (d->textSelectable) { 00267 QGraphicsProxyWidget::mouseMoveEvent(event); 00268 } 00269 } 00270 00271 void Label::paint(QPainter *painter, 00272 const QStyleOptionGraphicsItem *option, 00273 QWidget *widget) 00274 { 00275 QLabel *native = nativeWidget(); 00276 QFontMetrics fm = native->font(); 00277 00278 //indirect painting still used for fade out 00279 if (native->wordWrap() || native->text().isEmpty() || size().width() >= fm.width(native->text())) { 00280 QGraphicsProxyWidget::paint(painter, option, widget); 00281 } else { 00282 const int gradientLength = 25; 00283 QPixmap buffer(contentsRect().size().toSize()); 00284 buffer.fill(Qt::transparent); 00285 00286 QPainter buffPainter(&buffer); 00287 00288 QGraphicsProxyWidget::paint(&buffPainter, option, widget); 00289 00290 QLinearGradient gr; 00291 00292 buffPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); 00293 buffPainter.setPen(Qt::NoPen); 00294 00295 if (option->direction == Qt::LeftToRight) { 00296 gr.setStart(size().width()-gradientLength, 0); 00297 gr.setFinalStop(size().width(), 0); 00298 gr.setColorAt(0, Qt::black); 00299 gr.setColorAt(1, Qt::transparent); 00300 buffPainter.setBrush(gr); 00301 00302 buffPainter.drawRect(QRect(gr.start().toPoint(), QSize(gradientLength, size().height()))); 00303 } else { 00304 gr.setStart(0, 0); 00305 gr.setFinalStop(gradientLength, 0); 00306 gr.setColorAt(0, Qt::transparent); 00307 gr.setColorAt(1, Qt::black); 00308 buffPainter.setBrush(gr); 00309 00310 buffPainter.drawRect(QRect(0, 0, gradientLength, size().height())); 00311 } 00312 00313 buffPainter.end(); 00314 painter->drawPixmap(contentsRect(), buffer, buffer.rect()); 00315 } 00316 } 00317 00318 void Label::changeEvent(QEvent *event) 00319 { 00320 d->changeEvent(event); 00321 QGraphicsProxyWidget::changeEvent(event); 00322 } 00323 00324 bool Label::event(QEvent *event) 00325 { 00326 d->event(event); 00327 return QGraphicsProxyWidget::event(event); 00328 } 00329 00330 QVariant Label::itemChange(GraphicsItemChange change, const QVariant & value) 00331 { 00332 if (change == QGraphicsItem::ItemCursorHasChanged) { 00333 nativeWidget()->setCursor(cursor()); 00334 } 00335 00336 return QGraphicsWidget::itemChange(change, value); 00337 } 00338 00339 QSizeF Label::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const 00340 { 00341 if (sizePolicy().verticalPolicy() == QSizePolicy::Fixed) { 00342 return QGraphicsProxyWidget::sizeHint(Qt::PreferredSize, constraint); 00343 } else { 00344 return QGraphicsProxyWidget::sizeHint(which, constraint); 00345 } 00346 } 00347 00348 } // namespace Plasma 00349 00350 #include <label.moc> 00351
KDE 4.7 API Reference