kurllabel.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1998 Kurt Granroth <granroth@kde.org> 00003 Copyright (C) 2000 Peter Putzer <putzer@kde.org> 00004 Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 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 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include <qcolor.h> 00022 #include <qtimer.h> 00023 #include <qtooltip.h> 00024 #include <qpixmap.h> 00025 #include <qpainter.h> 00026 #include <qstyle.h> 00027 #include <qapplication.h> 00028 00029 #include <kcursor.h> 00030 #include <kglobalsettings.h> 00031 00032 #include "kurllabel.h" 00033 00034 class KURLLabel::Private 00035 { 00036 public: 00037 Private (const QString& url, KURLLabel* label) 00038 : URL (url), 00039 LinkColor (KGlobalSettings::linkColor()), 00040 HighlightedLinkColor (Qt::red), 00041 Tip(url), 00042 Cursor (0L), 00043 Underline (true), 00044 UseTips (false), 00045 Glow (true), 00046 Float (false), 00047 RealUnderline (true), 00048 MousePressed(false), 00049 WasInsideRect(false), 00050 MarginAltered(false), 00051 Timer (new QTimer (label)) 00052 { 00053 connect (Timer, SIGNAL (timeout ()), label, SLOT (updateColor ())); 00054 } 00055 00056 ~Private () 00057 { 00058 delete Cursor; 00059 } 00060 00061 QString URL; 00062 QPixmap AltPixmap; 00063 00064 QColor LinkColor; 00065 QColor HighlightedLinkColor; 00066 00067 QString Tip; 00068 QCursor* Cursor; 00069 bool Underline:1; 00070 bool UseTips:1; 00071 bool Glow:1; 00072 bool Float:1; 00073 bool RealUnderline:1; 00074 bool MousePressed:1; 00075 bool WasInsideRect:1; 00076 bool MarginAltered:1; 00077 QPixmap RealPixmap; 00078 00079 QTimer* Timer; 00080 }; 00081 00082 KURLLabel::KURLLabel (const QString& url, const QString& text, 00083 QWidget* parent, const char* name) 00084 : QLabel (!text.isNull() ? text : url, parent, name), 00085 d (new Private (url, this)) 00086 { 00087 setFont (font()); 00088 setUseCursor (true); 00089 setLinkColor (d->LinkColor); 00090 setFocusPolicy( QWidget::StrongFocus ); //better accessibility 00091 setMouseTracking (true); 00092 } 00093 00094 KURLLabel::KURLLabel (QWidget* parent, const char* name) 00095 : QLabel (parent, name), 00096 d (new Private (QString::null, this)) 00097 { 00098 setFont (font()); 00099 setUseCursor (true); 00100 setLinkColor (d->LinkColor); 00101 setFocusPolicy( QWidget::StrongFocus ); //better accessibility 00102 setMouseTracking (true); 00103 } 00104 00105 KURLLabel::~KURLLabel () 00106 { 00107 delete d; 00108 } 00109 00110 void KURLLabel::mouseReleaseEvent (QMouseEvent* e) 00111 { 00112 QLabel::mouseReleaseEvent (e); 00113 if (!d->MousePressed) 00114 return; 00115 d->MousePressed = false; 00116 QRect r( activeRect() ); 00117 if (!r.contains(e->pos())) 00118 return; 00119 00120 setLinkColor (d->HighlightedLinkColor); 00121 d->Timer->start (300); 00122 00123 switch (e->button()) 00124 { 00125 case LeftButton: 00126 emit leftClickedURL (); 00127 emit leftClickedURL (d->URL); 00128 break; 00129 00130 case MidButton: 00131 emit middleClickedURL (); 00132 emit middleClickedURL (d->URL); 00133 break; 00134 00135 case RightButton: 00136 emit rightClickedURL (); 00137 emit rightClickedURL (d->URL); 00138 break; 00139 00140 default: 00141 ; // nothing 00142 } 00143 } 00144 00145 void KURLLabel::setFont (const QFont& f) 00146 { 00147 QFont newFont = f; 00148 newFont.setUnderline (d->Underline); 00149 00150 QLabel::setFont (newFont); 00151 } 00152 00153 void KURLLabel::setUnderline (bool on) 00154 { 00155 d->Underline = on; 00156 00157 setFont (font()); 00158 } 00159 00160 void KURLLabel::updateColor () 00161 { 00162 d->Timer->stop(); 00163 00164 QRect r( activeRect() ); 00165 if (!(d->Glow || d->Float) || !r.contains (mapFromGlobal(QCursor::pos()))) 00166 setLinkColor (d->LinkColor); 00167 } 00168 00169 void KURLLabel::setLinkColor (const QColor& col) 00170 { 00171 QPalette p = palette(); 00172 p.setColor (QColorGroup::Foreground, col); 00173 setPalette (p); 00174 00175 update(); 00176 } 00177 00178 void KURLLabel::setURL (const QString& url) 00179 { 00180 if ( d->Tip == d->URL ) { // update the tip as well 00181 d->Tip = url; 00182 setUseTips( d->UseTips ); 00183 } 00184 00185 d->URL = url; 00186 } 00187 00188 const QString& KURLLabel::url () const 00189 { 00190 return d->URL; 00191 } 00192 00193 void KURLLabel::unsetCursor () 00194 { 00195 delete d->Cursor; 00196 d->Cursor = 0; 00197 } 00198 00199 void KURLLabel::setCursor ( const QCursor& cursor ) 00200 { 00201 delete d->Cursor; 00202 d->Cursor = new QCursor( cursor ); 00203 } 00204 00205 void KURLLabel::setUseCursor (bool on, QCursor* cursor) 00206 { 00207 if (on) 00208 { 00209 if (cursor) 00210 KURLLabel::setCursor (*cursor); 00211 else 00212 KURLLabel::setCursor (KCursor::handCursor()); 00213 } 00214 else 00215 KURLLabel::unsetCursor (); 00216 } 00217 00218 bool KURLLabel::useCursor () const 00219 { 00220 return d->Cursor; 00221 } 00222 00223 void KURLLabel::setUseTips (bool on) 00224 { 00225 d->UseTips = on; 00226 00227 if (on) { 00228 QToolTip::add (this, activeRect(), d->Tip); 00229 } else 00230 QToolTip::remove (this); 00231 } 00232 00233 void KURLLabel::setTipText (const QString& tip) 00234 { 00235 d->Tip = tip; 00236 00237 setUseTips (d->UseTips); 00238 } 00239 00240 bool KURLLabel::useTips () const 00241 { 00242 return d->UseTips; 00243 } 00244 00245 const QString& KURLLabel::tipText () const 00246 { 00247 return d->Tip; 00248 } 00249 00250 void KURLLabel::setHighlightedColor (const QColor& highcolor) 00251 { 00252 d->LinkColor = highcolor; 00253 00254 if (!d->Timer->isActive()) 00255 setLinkColor (highcolor); 00256 } 00257 00258 void KURLLabel::setHighlightedColor (const QString& highcolor) 00259 { 00260 setHighlightedColor (QColor (highcolor)); 00261 } 00262 00263 void KURLLabel::setSelectedColor (const QColor& selcolor) 00264 { 00265 d->HighlightedLinkColor = selcolor; 00266 00267 if (d->Timer->isActive()) 00268 setLinkColor (selcolor); 00269 } 00270 00271 void KURLLabel::setSelectedColor (const QString& selcolor) 00272 { 00273 setSelectedColor (QColor (selcolor)); 00274 } 00275 00276 void KURLLabel::setGlow (bool glow) 00277 { 00278 d->Glow = glow; 00279 } 00280 00281 void KURLLabel::setFloat (bool do_float) 00282 { 00283 d->Float = do_float; 00284 } 00285 00286 bool KURLLabel::isGlowEnabled () const 00287 { 00288 return d->Glow; 00289 } 00290 00291 bool KURLLabel::isFloatEnabled () const 00292 { 00293 return d->Float; 00294 } 00295 00296 void KURLLabel::setAltPixmap (const QPixmap& altPix) 00297 { 00298 d->AltPixmap = altPix; 00299 } 00300 00301 const QPixmap* KURLLabel::altPixmap () const 00302 { 00303 return &d->AltPixmap; 00304 } 00305 00306 void KURLLabel::enterEvent (QEvent* e) 00307 { 00308 QLabel::enterEvent (e); 00309 00310 QRect r( activeRect() ); 00311 if (!r.contains( static_cast<QMouseEvent*>(e)->pos() )) 00312 return; 00313 00314 if (!d->AltPixmap.isNull() && pixmap()) 00315 { 00316 d->RealPixmap = *pixmap(); 00317 setPixmap (d->AltPixmap); 00318 } 00319 00320 if (d->Glow || d->Float) 00321 { 00322 d->Timer->stop(); 00323 00324 setLinkColor (d->HighlightedLinkColor); 00325 00326 d->RealUnderline = d->Underline; 00327 00328 if (d->Float) 00329 setUnderline (true); 00330 } 00331 00332 emit enteredURL (); 00333 emit enteredURL (d->URL); 00334 } 00335 00336 void KURLLabel::leaveEvent (QEvent* e) 00337 { 00338 QLabel::leaveEvent (e); 00339 00340 if (!d->AltPixmap.isNull() && pixmap()) 00341 setPixmap (d->RealPixmap); 00342 00343 if ((d->Glow || d->Float) && !d->Timer->isActive()) 00344 setLinkColor (d->LinkColor); 00345 00346 setUnderline (d->RealUnderline); 00347 00348 emit leftURL (); 00349 emit leftURL (d->URL); 00350 } 00351 00352 bool KURLLabel::event (QEvent *e) 00353 { 00354 if (e && e->type() == QEvent::ParentPaletteChange) 00355 { 00356 // use parentWidget() unless you are a toplevel widget, then try qAapp 00357 QPalette p = parentWidget() ? parentWidget()->palette() : qApp->palette(); 00358 p.setBrush(QColorGroup::Base, p.brush(QPalette::Normal, QColorGroup::Background)); 00359 p.setColor(QColorGroup::Foreground, palette().active().foreground()); 00360 setPalette(p); 00361 d->LinkColor = KGlobalSettings::linkColor(); 00362 setLinkColor(d->LinkColor); 00363 return true; 00364 } 00365 else if (e->type() == QEvent::Paint) { 00366 const bool result = QLabel::event(e); 00367 if (result && hasFocus()) { 00368 QPainter p(this); 00369 QRect r( activeRect() ); 00370 style().drawPrimitive( QStyle::PE_FocusRect, &p, r, colorGroup() ); 00371 } 00372 return result; 00373 } 00374 else if (e->type() == QEvent::KeyPress) { 00375 QKeyEvent* ke = static_cast<QKeyEvent*>(e); 00376 if (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return) { 00377 setLinkColor (d->HighlightedLinkColor); 00378 d->Timer->start (300); 00379 emit leftClickedURL (); 00380 emit leftClickedURL (d->URL); 00381 ke->accept(); 00382 return true; 00383 } 00384 } 00385 else if (e->type() == QEvent::MouseButtonPress) { 00386 QRect r( activeRect() ); 00387 d->MousePressed = r.contains(static_cast<QMouseEvent*>(e)->pos()); 00388 } 00389 else if (e->type() == QEvent::MouseMove) { 00390 if (d->Cursor) { 00391 QRect r( activeRect() ); 00392 bool inside = r.contains(static_cast<QMouseEvent*>(e)->pos()); 00393 if (d->WasInsideRect != inside) { 00394 if (inside) 00395 QLabel::setCursor(*d->Cursor); 00396 else 00397 QLabel::unsetCursor(); 00398 d->WasInsideRect = inside; 00399 } 00400 } 00401 } 00402 return QLabel::event(e); 00403 } 00404 00405 QRect KURLLabel::activeRect() const 00406 { 00407 QRect r( contentsRect() ); 00408 if (text().isEmpty() || (!d->MarginAltered && sizePolicy() == QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed))) 00409 return r; //fixed size is sometimes used with pixmap 00410 int hAlign = QApplication::horizontalAlignment( alignment() ); 00411 int indentX = (hAlign && indent()>0) ? indent() : 0; 00412 QFontMetrics fm(font()); 00413 r.setWidth( QMIN(fm.width(text()), r.width())); 00414 if ( hAlign & AlignLeft ) 00415 r.moveLeft(r.left() + indentX); 00416 if ( hAlign & AlignCenter ) 00417 r.moveLeft((contentsRect().width()-r.width())/2+margin()); 00418 if ( hAlign & AlignRight ) 00419 r.moveLeft(contentsRect().width()-r.width()-indentX+margin()); 00420 int add = QMIN(3, margin()); 00421 r = QRect(r.left()-add, r.top()-add, r.width()+2*add, r.height()+2*add); 00422 return r; 00423 } 00424 00425 void KURLLabel::setMargin( int margin ) 00426 { 00427 QLabel::setMargin(margin); 00428 d->MarginAltered = true; 00429 } 00430 00431 void KURLLabel::setFocusPolicy( FocusPolicy policy ) 00432 { 00433 QLabel::setFocusPolicy(policy); 00434 if (!d->MarginAltered) { 00435 QLabel::setMargin(policy == NoFocus ? 0 : 3); //better default : better look when focused 00436 } 00437 } 00438 00439 void KURLLabel::setSizePolicy ( QSizePolicy policy ) 00440 { 00441 QLabel::setSizePolicy(policy); 00442 if (!d->MarginAltered && policy.horData()==QSizePolicy::Fixed && policy.verData()==QSizePolicy::Fixed) { 00443 QLabel::setMargin(0); //better default : better look when fixed size 00444 } 00445 } 00446 00447 void KURLLabel::virtual_hook( int, void* ) 00448 { /*BASE::virtual_hook( id, data );*/ } 00449 00450 #include "kurllabel.moc"