kurlbar.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2001,2002,2003 Carsten Pfeiffer <pfeiffer@kde.org> 00003 00004 library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation, version 2. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include <unistd.h> 00020 00021 #include <qapplication.h> 00022 #include <qcheckbox.h> 00023 #include <qdrawutil.h> 00024 #include <qfontmetrics.h> 00025 #include <qlabel.h> 00026 #include <qgrid.h> 00027 #include <qpainter.h> 00028 #include <qpopupmenu.h> 00029 #include <qstyle.h> 00030 #include <qvbox.h> 00031 #include <qwhatsthis.h> 00032 00033 #include <kaboutdata.h> 00034 #include <kconfig.h> 00035 #include <kdebug.h> 00036 #include <kglobal.h> 00037 #include <kicondialog.h> 00038 #include <kiconloader.h> 00039 #include <kinstance.h> 00040 #include <klineedit.h> 00041 #include <klocale.h> 00042 #include <kmimetype.h> 00043 #include <kprotocolinfo.h> 00044 #include <kstringhandler.h> 00045 #include <kurldrag.h> 00046 #include <kurlrequester.h> 00047 00048 #include "kurlbar.h" 00049 00054 class KURLBarToolTip : public QToolTip 00055 { 00056 public: 00057 KURLBarToolTip( QListBox *view ) : QToolTip( view ), m_view( view ) {} 00058 00059 protected: 00060 virtual void maybeTip( const QPoint& point ) { 00061 QListBoxItem *item = m_view->itemAt( point ); 00062 if ( item ) { 00063 QString text = static_cast<KURLBarItem*>( item )->toolTip(); 00064 if ( !text.isEmpty() ) 00065 tip( m_view->itemRect( item ), text ); 00066 } 00067 } 00068 00069 private: 00070 QListBox *m_view; 00071 }; 00072 00073 00076 00077 class KURLBarItem::KURLBarItemPrivate 00078 { 00079 public: 00080 KURLBarItemPrivate() 00081 { 00082 isPersistent = true; 00083 } 00084 00085 bool isPersistent; 00086 }; 00087 00088 KURLBarItem::KURLBarItem( KURLBar *parent, 00089 const KURL& url, bool persistent, const QString& description, 00090 const QString& icon, KIcon::Group group ) 00091 : QListBoxPixmap( KIconLoader::unknown() /*, parent->listBox()*/ ), 00092 m_url( url ), 00093 m_pixmap( 0L ), 00094 m_parent( parent ), 00095 m_appLocal( true ) 00096 { 00097 init( icon, group, description, persistent ); 00098 } 00099 00100 KURLBarItem::KURLBarItem( KURLBar *parent, 00101 const KURL& url, const QString& description, 00102 const QString& icon, KIcon::Group group ) 00103 : QListBoxPixmap( KIconLoader::unknown() /*, parent->listBox()*/ ), 00104 m_url( url ), 00105 m_pixmap( 0L ), 00106 m_parent( parent ), 00107 m_appLocal( true ) 00108 { 00109 init( icon, group, description, true /*persistent*/ ); 00110 } 00111 00112 void KURLBarItem::init( const QString& icon, KIcon::Group group, 00113 const QString& description, bool persistent ) 00114 { 00115 d = new KURLBarItemPrivate; 00116 d->isPersistent = persistent; 00117 00118 setCustomHighlighting( true ); 00119 setIcon( icon, group ); 00120 setDescription( description ); 00121 } 00122 00123 KURLBarItem::~KURLBarItem() 00124 { 00125 delete d; 00126 } 00127 00128 void KURLBarItem::setURL( const KURL& url ) 00129 { 00130 m_url = url; 00131 if ( m_description.isEmpty() ) 00132 setText( url.fileName() ); 00133 } 00134 00135 void KURLBarItem::setIcon( const QString& icon, KIcon::Group group ) 00136 { 00137 m_icon = icon; 00138 m_group = group; 00139 00140 if ( icon.isEmpty() ) 00141 m_pixmap = KMimeType::pixmapForURL( m_url, 0, group, iconSize() ); 00142 else 00143 m_pixmap = KGlobal::iconLoader()->loadIcon( icon, group, iconSize(), 00144 KIcon::DefaultState ); 00145 } 00146 00147 void KURLBarItem::setDescription( const QString& desc ) 00148 { 00149 m_description = desc; 00150 setText( desc.isEmpty() ? m_url.fileName() : desc ); 00151 } 00152 00153 void KURLBarItem::setApplicationLocal( bool local ) 00154 { 00155 if ( !local && !isPersistent() ) 00156 { 00157 kdWarning() << "KURLBar: dynamic (non-persistent) items can not be global." << endl; 00158 return; 00159 } 00160 00161 m_appLocal = local; 00162 } 00163 00164 void KURLBarItem::setToolTip( const QString& tip ) 00165 { 00166 m_toolTip = tip; 00167 } 00168 00169 QString KURLBarItem::toolTip() const 00170 { 00171 return m_toolTip.isEmpty() ? m_url.prettyURL() : m_toolTip; 00172 } 00173 00174 int KURLBarItem::iconSize() const 00175 { 00176 return m_parent->iconSize(); 00177 } 00178 00179 void KURLBarItem::paint( QPainter *p ) 00180 { 00181 QListBox *box = listBox(); 00182 int w = width( box ); 00183 static const int margin = KDialog::spacingHint(); 00184 00185 // draw sunken selection 00186 if ( isCurrent() || isSelected() ) { 00187 int h = height( box ); 00188 00189 QBrush brush = box->colorGroup().brush( QColorGroup::Highlight ); 00190 p->fillRect( 0, 0, w, h, brush ); 00191 QPen pen = p->pen(); 00192 QPen oldPen = pen; 00193 pen.setColor( box->colorGroup().mid() ); 00194 p->setPen( pen ); 00195 00196 p->drawPoint( 0, 0 ); 00197 p->drawPoint( 0, h - 1 ); 00198 p->drawPoint( w - 1, 0 ); 00199 p->drawPoint( w - 1, h - 1 ); 00200 00201 p->setPen( oldPen ); 00202 } 00203 00204 if ( m_parent->iconSize() < KIcon::SizeMedium ) { 00205 // small icon -> draw icon next to text 00206 00207 // ### mostly cut & paste of QListBoxPixmap::paint() until Qt 3.1 00208 // (where it will properly use pixmap() instead of the internal pixmap) 00209 const QPixmap *pm = pixmap(); 00210 int yPos = QMAX( 0, (height(box) - pm->height())/2 ); 00211 00212 p->drawPixmap( margin, yPos, *pm ); 00213 if ( !text().isEmpty() ) { 00214 QFontMetrics fm = p->fontMetrics(); 00215 if ( pm->height() < fm.height() ) 00216 yPos = fm.ascent() + fm.leading()/2; 00217 else 00218 yPos = pm->height()/2 - fm.height()/2 + fm.ascent(); 00219 00220 yPos += margin; 00221 int stringWidth = box->width() - pm->width() - 2 - (margin * 2); 00222 QString visibleText = KStringHandler::rPixelSqueeze( text(), fm, stringWidth ); 00223 int xPos = pm->width() + margin + 2; 00224 00225 if ( isCurrent() || isSelected() ) { 00226 p->setPen( box->colorGroup().highlight().dark(115) ); 00227 p->drawText( xPos + ( QApplication::reverseLayout() ? -1 : 1), 00228 yPos + 1, visibleText ); 00229 p->setPen( box->colorGroup().highlightedText() ); 00230 } 00231 00232 p->drawText( xPos, yPos, visibleText ); 00233 } 00234 // end cut & paste (modulo pixmap centering) 00235 } 00236 00237 else { 00238 // big icons -> draw text below icon 00239 int y = margin; 00240 const QPixmap *pm = pixmap(); 00241 00242 if ( !pm->isNull() ) { 00243 int x = (w - pm->width()) / 2; 00244 x = QMAX( x, margin ); 00245 p->drawPixmap( x, y, *pm ); 00246 } 00247 00248 if ( !text().isEmpty() ) { 00249 QFontMetrics fm = p->fontMetrics(); 00250 y += pm->height() + fm.height() - fm.descent(); 00251 00252 int stringWidth = box->width() - (margin * 2); 00253 QString visibleText = KStringHandler::rPixelSqueeze( text(), fm, stringWidth ); 00254 int x = (w - fm.width( visibleText )) / 2; 00255 x = QMAX( x, margin ); 00256 00257 if ( isCurrent() || isSelected() ) { 00258 p->setPen( box->colorGroup().highlight().dark(115) ); 00259 p->drawText( x + ( QApplication::reverseLayout() ? -1 : 1), 00260 y + 1, visibleText ); 00261 p->setPen( box->colorGroup().highlightedText() ); 00262 } 00263 00264 p->drawText( x, y, visibleText ); 00265 } 00266 } 00267 } 00268 00269 QSize KURLBarItem::sizeHint() const 00270 { 00271 int wmin = 0; 00272 int hmin = 0; 00273 const KURLBarListBox *lb =static_cast<const KURLBarListBox*>(listBox()); 00274 00275 if ( m_parent->iconSize() < KIcon::SizeMedium ) { 00276 wmin = QListBoxPixmap::width( lb ) + KDialog::spacingHint() * 2; 00277 hmin = QListBoxPixmap::height( lb ) + KDialog::spacingHint() * 2; 00278 } 00279 else { 00280 wmin = QMAX(lb->fontMetrics().width(text()), pixmap()->width()) + KDialog::spacingHint() * 2; 00281 hmin = lb->fontMetrics().lineSpacing() + pixmap()->height() + KDialog::spacingHint() * 2; 00282 } 00283 00284 if ( lb->isVertical() ) 00285 wmin = QMIN( wmin, lb->viewport()->sizeHint().width() ); 00286 else 00287 hmin = QMIN( hmin, lb->viewport()->sizeHint().height() ); 00288 00289 return QSize( wmin, hmin ); 00290 } 00291 00292 int KURLBarItem::width( const QListBox *lb ) const 00293 { 00294 if ( static_cast<const KURLBarListBox *>( lb )->isVertical() ) 00295 return QMAX( sizeHint().width(), lb->viewport()->width() ); 00296 else 00297 return sizeHint().width(); 00298 } 00299 00300 int KURLBarItem::height( const QListBox *lb ) const 00301 { 00302 if ( static_cast<const KURLBarListBox *>( lb )->isVertical() ) 00303 return sizeHint().height(); 00304 else 00305 return QMAX( sizeHint().height(), lb->viewport()->height() ); 00306 } 00307 00308 bool KURLBarItem::isPersistent() const 00309 { 00310 return d->isPersistent; 00311 } 00312 00315 00316 class KURLBar::KURLBarPrivate 00317 { 00318 public: 00319 KURLBarPrivate() 00320 { 00321 currentURL.setPath( QDir::homeDirPath() ); 00322 defaultIconSize = 0; 00323 } 00324 00325 int defaultIconSize; 00326 KURL currentURL; 00327 }; 00328 00329 00330 KURLBar::KURLBar( bool useGlobalItems, QWidget *parent, const char *name, WFlags f ) 00331 : QFrame( parent, name, f ), 00332 m_activeItem( 0L ), 00333 m_useGlobal( useGlobalItems ), 00334 m_isModified( false ), 00335 m_isImmutable( false ), 00336 m_listBox( 0L ), 00337 m_iconSize( KIcon::SizeMedium ) 00338 { 00339 d = new KURLBarPrivate(); 00340 00341 setListBox( 0L ); 00342 setSizePolicy( QSizePolicy( isVertical() ? 00343 QSizePolicy::Maximum : 00344 QSizePolicy::Preferred, 00345 isVertical() ? 00346 QSizePolicy::Preferred : 00347 QSizePolicy::Maximum )); 00348 QWhatsThis::add(this, i18n("<qt>The <b>Quick Access</b> panel provides easy access to commonly used file locations.<p>" 00349 "Clicking on one of the shortcut entries will take you to that location.<p>" 00350 "By right clicking on an entry you can add, edit and remove shortcuts.</qt>")); 00351 } 00352 00353 KURLBar::~KURLBar() 00354 { 00355 delete d; 00356 } 00357 00358 KURLBarItem * KURLBar::insertItem(const KURL& url, const QString& description, 00359 bool applicationLocal, 00360 const QString& icon, KIcon::Group group ) 00361 { 00362 KURLBarItem *item = new KURLBarItem(this, url, description, icon, group); 00363 item->setApplicationLocal( applicationLocal ); 00364 m_listBox->insertItem( item ); 00365 return item; 00366 } 00367 00368 KURLBarItem * KURLBar::insertDynamicItem(const KURL& url, const QString& description, 00369 const QString& icon, KIcon::Group group ) 00370 { 00371 KURLBarItem *item = new KURLBarItem(this, url, false, description, icon, group); 00372 m_listBox->insertItem( item ); 00373 return item; 00374 } 00375 00376 void KURLBar::setOrientation( Qt::Orientation orient ) 00377 { 00378 m_listBox->setOrientation( orient ); 00379 setSizePolicy( QSizePolicy( isVertical() ? 00380 QSizePolicy::Maximum : 00381 QSizePolicy::Preferred, 00382 isVertical() ? 00383 QSizePolicy::Preferred : 00384 QSizePolicy::Maximum )); 00385 } 00386 00387 Qt::Orientation KURLBar::orientation() const 00388 { 00389 return m_listBox->orientation(); 00390 } 00391 00392 void KURLBar::setListBox( KURLBarListBox *view ) 00393 { 00394 delete m_listBox; 00395 00396 if ( !view ) { 00397 m_listBox = new KURLBarListBox( this, "urlbar listbox" ); 00398 setOrientation( Vertical ); 00399 } 00400 else { 00401 m_listBox = view; 00402 if ( m_listBox->parentWidget() != this ) 00403 m_listBox->reparent( this, QPoint(0,0) ); 00404 m_listBox->resize( width(), height() ); 00405 } 00406 00407 m_listBox->setSelectionMode( KListBox::Single ); 00408 paletteChange( palette() ); 00409 m_listBox->setFocusPolicy( TabFocus ); 00410 00411 connect( m_listBox, SIGNAL( mouseButtonClicked( int, QListBoxItem *, const QPoint & ) ), 00412 SLOT( slotSelected( int, QListBoxItem * ))); 00413 connect( m_listBox, SIGNAL( dropped( QDropEvent * )), 00414 this, SLOT( slotDropped( QDropEvent * ))); 00415 connect( m_listBox, SIGNAL( contextMenuRequested( QListBoxItem *, 00416 const QPoint& )), 00417 SLOT( slotContextMenuRequested( QListBoxItem *, const QPoint& ))); 00418 connect( m_listBox, SIGNAL( returnPressed( QListBoxItem * ) ), 00419 SLOT( slotSelected( QListBoxItem * ) )); 00420 } 00421 00422 void KURLBar::setIconSize( int size ) 00423 { 00424 if ( size == m_iconSize ) 00425 return; 00426 00427 m_iconSize = size; 00428 00429 // reload the icons with the new size 00430 KURLBarItem *item = static_cast<KURLBarItem*>( m_listBox->firstItem() ); 00431 while ( item ) { 00432 item->setIcon( item->icon(), item->iconGroup() ); 00433 item = static_cast<KURLBarItem*>( item->next() ); 00434 } 00435 00436 resize( sizeHint() ); 00437 updateGeometry(); 00438 } 00439 00440 void KURLBar::clear() 00441 { 00442 m_listBox->clear(); 00443 } 00444 00445 void KURLBar::resizeEvent( QResizeEvent *e ) 00446 { 00447 QFrame::resizeEvent( e ); 00448 m_listBox->resize( width(), height() ); 00449 } 00450 00451 void KURLBar::paletteChange( const QPalette & ) 00452 { 00453 QPalette pal = palette(); 00454 QColor gray = pal.color( QPalette::Normal, QColorGroup::Background ); 00455 QColor selectedTextColor = pal.color( QPalette::Normal, QColorGroup::BrightText ); 00456 QColor foreground = pal.color( QPalette::Normal, QColorGroup::Foreground ); 00457 pal.setColor( QPalette::Normal, QColorGroup::Base, gray ); 00458 pal.setColor( QPalette::Normal, QColorGroup::HighlightedText, selectedTextColor ); 00459 pal.setColor( QPalette::Normal, QColorGroup::Text, foreground ); 00460 pal.setColor( QPalette::Inactive, QColorGroup::Base, gray ); 00461 pal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, selectedTextColor ); 00462 pal.setColor( QPalette::Inactive, QColorGroup::Text, foreground ); 00463 00464 setPalette( pal ); 00465 } 00466 00467 QSize KURLBar::sizeHint() const 00468 { 00469 return m_listBox->sizeHint(); 00470 00471 #if 0 00472 // this code causes vertical and or horizontal scrollbars appearing 00473 // depending on the text, font, moonphase and earth rotation. Just using 00474 // m_listBox->sizeHint() fixes this (although the widget can then be 00475 // resized to a smaller size so that scrollbars appear). 00476 int w = 0; 00477 int h = 0; 00478 KURLBarItem *item; 00479 bool vertical = isVertical(); 00480 00481 for ( item = static_cast<KURLBarItem*>( m_listBox->firstItem() ); 00482 item; 00483 item = static_cast<KURLBarItem*>( item->next() ) ) { 00484 00485 QSize sh = item->sizeHint(); 00486 00487 if ( vertical ) { 00488 w = QMAX( w, sh.width() ); 00489 h += sh.height(); 00490 } 00491 else { 00492 w += sh.width(); 00493 h = QMAX( h, sh.height() ); 00494 } 00495 } 00496 00497 // if ( vertical && m_listBox->verticalScrollBar()->isVisible() ) 00498 // w += m_listBox->verticalScrollBar()->width(); 00499 // else if ( !vertical && m_listBox->horizontalScrollBar()->isVisible() ) 00500 // h += m_listBox->horizontalScrollBar()->height(); 00501 00502 if ( w == 0 && h == 0 ) 00503 return QSize( 100, 200 ); 00504 else 00505 return QSize( 6 + w, h ); 00506 #endif 00507 } 00508 00509 QSize KURLBar::minimumSizeHint() const 00510 { 00511 QSize s = sizeHint(); // ### 00512 int w = s.width() + m_listBox->verticalScrollBar()->width(); 00513 int h = s.height() + m_listBox->horizontalScrollBar()->height(); 00514 return QSize( w, h ); 00515 } 00516 00517 void KURLBar::slotSelected( int button, QListBoxItem *item ) 00518 { 00519 if ( button != Qt::LeftButton ) 00520 return; 00521 00522 slotSelected( item ); 00523 } 00524 00525 void KURLBar::slotSelected( QListBoxItem *item ) 00526 { 00527 if ( item && item != m_activeItem ) 00528 m_activeItem = static_cast<KURLBarItem*>( item ); 00529 00530 if ( m_activeItem ) { 00531 m_listBox->setCurrentItem( m_activeItem ); 00532 emit activated( m_activeItem->url() ); 00533 } 00534 } 00535 00536 void KURLBar::setCurrentItem( const KURL& url ) 00537 { 00538 d->currentURL = url; 00539 00540 QString u = url.url(-1); 00541 00542 if ( m_activeItem && m_activeItem->url().url(-1) == u ) 00543 return; 00544 00545 bool hasURL = false; 00546 QListBoxItem *item = m_listBox->firstItem(); 00547 while ( item ) { 00548 if ( static_cast<KURLBarItem*>( item )->url().url(-1) == u ) { 00549 m_activeItem = static_cast<KURLBarItem*>( item ); 00550 m_listBox->setCurrentItem( item ); 00551 m_listBox->setSelected( item, true ); 00552 hasURL = true; 00553 break; 00554 } 00555 item = item->next(); 00556 } 00557 00558 if ( !hasURL ) { 00559 m_activeItem = 0L; 00560 m_listBox->clearSelection(); 00561 } 00562 } 00563 00564 KURLBarItem * KURLBar::currentItem() const 00565 { 00566 QListBoxItem *item = m_listBox->item( m_listBox->currentItem() ); 00567 if ( item ) 00568 return static_cast<KURLBarItem *>( item ); 00569 return 0L; 00570 } 00571 00572 KURL KURLBar::currentURL() const 00573 { 00574 KURLBarItem *item = currentItem(); 00575 return item ? item->url() : KURL(); 00576 } 00577 00578 void KURLBar::readConfig( KConfig *appConfig, const QString& itemGroup ) 00579 { 00580 m_isImmutable = appConfig->groupIsImmutable( itemGroup ); 00581 KConfigGroupSaver cs( appConfig, itemGroup ); 00582 d->defaultIconSize = m_iconSize; 00583 m_iconSize = appConfig->readNumEntry( "Speedbar IconSize", m_iconSize ); 00584 00585 if ( m_useGlobal ) { // read global items 00586 KConfig *globalConfig = KGlobal::config(); 00587 KConfigGroupSaver cs( globalConfig, (QString)(itemGroup +" (Global)")); 00588 int num = globalConfig->readNumEntry( "Number of Entries" ); 00589 for ( int i = 0; i < num; i++ ) { 00590 readItem( i, globalConfig, false ); 00591 } 00592 } 00593 00594 // read application local items 00595 int num = appConfig->readNumEntry( "Number of Entries" ); 00596 for ( int i = 0; i < num; i++ ) { 00597 readItem( i, appConfig, true ); 00598 } 00599 } 00600 00601 void KURLBar::readItem( int i, KConfig *config, bool applicationLocal ) 00602 { 00603 QString number = QString::number( i ); 00604 KURL url = KURL::fromPathOrURL( config->readPathEntry( QString("URL_") + number )); 00605 if ( !url.isValid() || !KProtocolInfo::isKnownProtocol( url )) 00606 return; // nothing we could do. 00607 00608 insertItem( url, 00609 config->readEntry( QString("Description_") + number ), 00610 applicationLocal, 00611 config->readEntry( QString("Icon_") + number ), 00612 static_cast<KIcon::Group>( 00613 config->readNumEntry( QString("IconGroup_") + number )) ); 00614 } 00615 00616 void KURLBar::writeConfig( KConfig *config, const QString& itemGroup ) 00617 { 00618 KConfigGroupSaver cs1( config, itemGroup ); 00619 if(!config->hasDefault("Speedbar IconSize") && m_iconSize == d->defaultIconSize ) 00620 config->revertToDefault("Speedbar IconSize"); 00621 else 00622 config->writeEntry( "Speedbar IconSize", m_iconSize ); 00623 00624 if ( !m_isModified ) 00625 return; 00626 00627 int i = 0; 00628 int numLocal = 0; 00629 KURLBarItem *item = static_cast<KURLBarItem*>( m_listBox->firstItem() ); 00630 00631 while ( item ) 00632 { 00633 if ( item->isPersistent() ) // we only save persistent items 00634 { 00635 if ( item->applicationLocal() ) 00636 { 00637 writeItem( item, numLocal, config, false ); 00638 numLocal++; 00639 } 00640 00641 i++; 00642 } 00643 item = static_cast<KURLBarItem*>( item->next() ); 00644 } 00645 config->writeEntry("Number of Entries", numLocal); 00646 00647 00648 // write the global entries to kdeglobals, if any 00649 bool haveGlobalEntries = (i > numLocal); 00650 if ( m_useGlobal && haveGlobalEntries ) { 00651 config->setGroup( itemGroup + " (Global)" ); 00652 00653 int numGlobals = 0; 00654 item = static_cast<KURLBarItem*>( m_listBox->firstItem() ); 00655 00656 while ( item ) 00657 { 00658 if ( item->isPersistent() ) // we only save persistent items 00659 { 00660 if ( !item->applicationLocal() ) 00661 { 00662 writeItem( item, numGlobals, config, true ); 00663 numGlobals++; 00664 } 00665 } 00666 00667 item = static_cast<KURLBarItem*>( item->next() ); 00668 } 00669 config->writeEntry("Number of Entries", numGlobals, true, true); 00670 } 00671 00672 m_isModified = false; 00673 } 00674 00675 void KURLBar::writeItem( KURLBarItem *item, int i, KConfig *config, 00676 bool global ) 00677 { 00678 if ( !item->isPersistent() ) 00679 return; 00680 00681 QString Description = "Description_"; 00682 QString URL = "URL_"; 00683 QString Icon = "Icon_"; 00684 QString IconGroup = "IconGroup_"; 00685 00686 QString number = QString::number( i ); 00687 config->writePathEntry( URL + number, item->url().prettyURL(), true, global ); 00688 00689 config->writeEntry( Description + number, item->description(),true,global); 00690 config->writeEntry( Icon + number, item->icon(), true, global ); 00691 config->writeEntry( IconGroup + number, item->iconGroup(), true, global ); 00692 } 00693 00694 00695 void KURLBar::slotDropped( QDropEvent *e ) 00696 { 00697 KURL::List urls; 00698 if ( KURLDrag::decode( e, urls ) ) { 00699 KURL url; 00700 QString description; 00701 QString icon; 00702 bool appLocal = false; 00703 00704 KURL::List::Iterator it = urls.begin(); 00705 for ( ; it != urls.end(); ++it ) { 00706 (void) insertItem( *it, description, appLocal, icon ); 00707 m_isModified = true; 00708 updateGeometry(); 00709 } 00710 } 00711 } 00712 00713 void KURLBar::slotContextMenuRequested( QListBoxItem *_item, const QPoint& pos ) 00714 { 00715 if (m_isImmutable) 00716 return; 00717 00718 KURLBarItem *item = dynamic_cast<KURLBarItem*>( _item ); 00719 00720 static const int IconSize = 10; 00721 static const int AddItem = 20; 00722 static const int EditItem = 30; 00723 static const int RemoveItem = 40; 00724 00725 KURL lastURL = m_activeItem ? m_activeItem->url() : KURL(); 00726 00727 bool smallIcons = m_iconSize < KIcon::SizeMedium; 00728 QPopupMenu *popup = new QPopupMenu(); 00729 popup->insertItem( smallIcons ? 00730 i18n("&Large Icons") : i18n("&Small Icons"), 00731 IconSize ); 00732 popup->insertSeparator(); 00733 00734 if (item != 0L && item->isPersistent()) 00735 { 00736 popup->insertItem(SmallIconSet("edit"), i18n("&Edit Entry..."), EditItem); 00737 popup->insertSeparator(); 00738 } 00739 00740 popup->insertItem(SmallIconSet("filenew"), i18n("&Add Entry..."), AddItem); 00741 00742 if (item != 0L && item->isPersistent()) 00743 { 00744 popup->insertItem( SmallIconSet("editdelete"), i18n("&Remove Entry"), 00745 RemoveItem ); 00746 } 00747 00748 int result = popup->exec( pos ); 00749 switch ( result ) { 00750 case IconSize: 00751 setIconSize( smallIcons ? KIcon::SizeMedium : KIcon::SizeSmallMedium ); 00752 m_listBox->triggerUpdate( true ); 00753 break; 00754 case AddItem: 00755 addNewItem(); 00756 break; 00757 case EditItem: 00758 editItem( static_cast<KURLBarItem *>( item ) ); 00759 break; 00760 case RemoveItem: 00761 delete item; 00762 m_isModified = true; 00763 break; 00764 default: // abort 00765 break; 00766 } 00767 00768 // reset current item 00769 m_activeItem = 0L; 00770 setCurrentItem( lastURL ); 00771 } 00772 00773 bool KURLBar::addNewItem() 00774 { 00775 KURLBarItem *item = new KURLBarItem( this, d->currentURL, 00776 i18n("Enter a description") ); 00777 if ( editItem( item ) ) { 00778 m_listBox->insertItem( item ); 00779 return true; 00780 } 00781 00782 delete item; 00783 return false; 00784 } 00785 00786 bool KURLBar::editItem( KURLBarItem *item ) 00787 { 00788 if ( !item || !item->isPersistent() ) // should never happen tho 00789 return false; 00790 00791 KURL url = item->url(); 00792 QString description = item->description(); 00793 QString icon = item->icon(); 00794 bool appLocal = item->applicationLocal(); 00795 00796 if ( KURLBarItemDialog::getInformation( m_useGlobal, 00797 url, description, 00798 icon, appLocal, 00799 m_iconSize, this )) 00800 { 00801 item->setURL( url ); 00802 item->setDescription( description ); 00803 item->setIcon( icon ); 00804 item->setApplicationLocal( appLocal ); 00805 m_listBox->triggerUpdate( true ); 00806 m_isModified = true; 00807 updateGeometry(); 00808 return true; 00809 } 00810 00811 return false; 00812 } 00813 00816 00817 00818 KURLBarListBox::KURLBarListBox( QWidget *parent, const char *name ) 00819 : KListBox( parent, name ) 00820 { 00821 m_toolTip = new KURLBarToolTip( this ); 00822 setAcceptDrops( true ); 00823 viewport()->setAcceptDrops( true ); 00824 } 00825 00826 KURLBarListBox::~KURLBarListBox() 00827 { 00828 delete m_toolTip; 00829 } 00830 00831 void KURLBarListBox::paintEvent( QPaintEvent* ) 00832 { 00833 QPainter p(this); 00834 p.setPen( colorGroup().mid() ); 00835 p.drawRect( 0, 0, width(), height() ); 00836 } 00837 00838 QDragObject * KURLBarListBox::dragObject() 00839 { 00840 KURL::List urls; 00841 KURLBarItem *item = static_cast<KURLBarItem*>( firstItem() ); 00842 00843 while ( item ) { 00844 if ( item->isSelected() ) 00845 urls.append( item->url() ); 00846 item = static_cast<KURLBarItem*>( item->next() ); 00847 } 00848 00849 if ( !urls.isEmpty() ) // ### use custom drag-object with description etc.? 00850 return new KURLDrag( urls, this, "urlbar drag" ); 00851 00852 return 0L; 00853 } 00854 00855 void KURLBarListBox::contentsDragEnterEvent( QDragEnterEvent *e ) 00856 { 00857 e->accept( KURLDrag::canDecode( e )); 00858 } 00859 00860 void KURLBarListBox::contentsDropEvent( QDropEvent *e ) 00861 { 00862 emit dropped( e ); 00863 } 00864 00865 void KURLBarListBox::contextMenuEvent( QContextMenuEvent *e ) 00866 { 00867 if (e) 00868 { 00869 emit contextMenuRequested( itemAt( e->globalPos() ), e->globalPos() ); 00870 e->consume(); // Consume the event to avoid multiple contextMenuEvent calls... 00871 } 00872 } 00873 00874 void KURLBarListBox::setOrientation( Qt::Orientation orient ) 00875 { 00876 if ( orient == Vertical ) { 00877 setColumnMode( 1 ); 00878 setRowMode( Variable ); 00879 } 00880 else { 00881 setRowMode( 1 ); 00882 setColumnMode( Variable ); 00883 } 00884 00885 m_orientation = orient; 00886 } 00887 00890 00891 00892 bool KURLBarItemDialog::getInformation( bool allowGlobal, KURL& url, 00893 QString& description, QString& icon, 00894 bool& appLocal, int iconSize, 00895 QWidget *parent ) 00896 { 00897 KURLBarItemDialog *dialog = new KURLBarItemDialog( allowGlobal, url, 00898 description, icon, 00899 appLocal, 00900 iconSize, parent ); 00901 if ( dialog->exec() == QDialog::Accepted ) { 00902 // set the return parameters 00903 url = dialog->url(); 00904 description = dialog->description(); 00905 icon = dialog->icon(); 00906 appLocal = dialog->applicationLocal(); 00907 00908 delete dialog; 00909 return true; 00910 } 00911 00912 delete dialog; 00913 return false; 00914 } 00915 00916 KURLBarItemDialog::KURLBarItemDialog( bool allowGlobal, const KURL& url, 00917 const QString& description, 00918 QString icon, bool appLocal, 00919 int iconSize, 00920 QWidget *parent, const char *name ) 00921 : KDialogBase( parent, name, true, 00922 i18n("Edit Quick Access Entry"), Ok | Cancel, Ok, true ) 00923 { 00924 QVBox *box = new QVBox( this ); 00925 QString text = i18n("<qt><b>Please provide a description, URL and icon for this Quick Access entry.</b></br></qt>"); 00926 QLabel *label = new QLabel( text, box ); 00927 box->setSpacing( spacingHint() ); 00928 00929 QGrid *grid = new QGrid( 2, box ); 00930 grid->setSpacing( spacingHint() ); 00931 00932 QString whatsThisText = i18n("<qt>This is the text that will appear in the Quick Access panel.<p>" 00933 "The description should consist of one or two words " 00934 "that will help you remember what this entry refers to.</qt>"); 00935 label = new QLabel( i18n("&Description:"), grid ); 00936 m_edit = new KLineEdit( grid, "description edit" ); 00937 m_edit->setText( description.isEmpty() ? url.fileName() : description ); 00938 label->setBuddy( m_edit ); 00939 QWhatsThis::add( label, whatsThisText ); 00940 QWhatsThis::add( m_edit, whatsThisText ); 00941 00942 whatsThisText = i18n("<qt>This is the location associated with the entry. Any valid URL may be used. For example:<p>" 00943 "%1<br>http://www.kde.org<br>ftp://ftp.kde.org/pub/kde/stable<p>" 00944 "By clicking on the button next to the text edit box you can browse to an " 00945 "appropriate URL.</qt>").arg(QDir::homeDirPath()); 00946 label = new QLabel( i18n("&URL:"), grid ); 00947 m_urlEdit = new KURLRequester( url.prettyURL(), grid ); 00948 m_urlEdit->setMode( KFile::Directory ); 00949 label->setBuddy( m_urlEdit ); 00950 QWhatsThis::add( label, whatsThisText ); 00951 QWhatsThis::add( m_urlEdit, whatsThisText ); 00952 00953 whatsThisText = i18n("<qt>This is the icon that will appear in the Quick Access panel.<p>" 00954 "Click on the button to select a different icon.</qt>"); 00955 label = new QLabel( i18n("Choose an &icon:"), grid ); 00956 m_iconButton = new KIconButton( grid, "icon button" ); 00957 m_iconButton->setIconSize( iconSize ); 00958 if ( icon.isEmpty() ) 00959 icon = KMimeType::iconForURL( url ); 00960 m_iconButton->setIcon( icon ); 00961 label->setBuddy( m_iconButton ); 00962 QWhatsThis::add( label, whatsThisText ); 00963 QWhatsThis::add( m_iconButton, whatsThisText ); 00964 00965 if ( allowGlobal ) { 00966 QString appName; 00967 if ( KGlobal::instance()->aboutData() ) 00968 appName = KGlobal::instance()->aboutData()->programName(); 00969 if ( appName.isEmpty() ) 00970 appName = QString::fromLatin1( KGlobal::instance()->instanceName() ); 00971 m_appLocal = new QCheckBox( i18n("&Only show when using this application (%1)").arg( appName ), box ); 00972 m_appLocal->setChecked( appLocal ); 00973 QWhatsThis::add( m_appLocal, 00974 i18n("<qt>Select this setting if you want this " 00975 "entry to show only when using the current application (%1).<p>" 00976 "If this setting is not selected, the entry will be available in all " 00977 "applications.</qt>") 00978 .arg(appName)); 00979 } 00980 else 00981 m_appLocal = 0L; 00982 connect(m_urlEdit->lineEdit(),SIGNAL(textChanged ( const QString & )),this,SLOT(urlChanged(const QString & ))); 00983 m_edit->setFocus(); 00984 setMainWidget( box ); 00985 } 00986 00987 KURLBarItemDialog::~KURLBarItemDialog() 00988 { 00989 } 00990 00991 void KURLBarItemDialog::urlChanged(const QString & text ) 00992 { 00993 enableButtonOK( !text.isEmpty() ); 00994 } 00995 00996 KURL KURLBarItemDialog::url() const 00997 { 00998 QString text = m_urlEdit->url(); 00999 KURL u; 01000 if ( text.at(0) == '/' ) 01001 u.setPath( text ); 01002 else 01003 u = text; 01004 01005 return u; 01006 } 01007 01008 QString KURLBarItemDialog::description() const 01009 { 01010 return m_edit->text(); 01011 } 01012 01013 QString KURLBarItemDialog::icon() const 01014 { 01015 return m_iconButton->icon(); 01016 } 01017 01018 bool KURLBarItemDialog::applicationLocal() const 01019 { 01020 if ( !m_appLocal ) 01021 return true; 01022 01023 return m_appLocal->isChecked(); 01024 } 01025 01026 void KURLBarItem::virtual_hook( int, void* ) 01027 { /*BASE::virtual_hook( id, data );*/ } 01028 01029 void KURLBar::virtual_hook( int, void* ) 01030 { /*BASE::virtual_hook( id, data );*/ } 01031 01032 void KURLBarListBox::virtual_hook( int id, void* data ) 01033 { KListBox::virtual_hook( id, data ); } 01034 01035 01036 #include "kurlbar.moc"