libkonq Library API Documentation

konq_iconviewwidget.cc

00001 /* This file is part of the KDE projects 00002 Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 00003 Copyright (C) 2000, 2001, 2002 David Faure <david@mandrakesoft.com> 00004 00005 This program is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This program 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 General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; see the file COPYING. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 00019 */ 00020 #include "konq_iconviewwidget.h" 00021 #include "konq_undo.h" 00022 #include "konq_sound.h" 00023 00024 #include <qclipboard.h> 00025 #include <qlayout.h> 00026 #include <qtimer.h> 00027 #include <qpainter.h> 00028 #include <qtooltip.h> 00029 #include <qlabel.h> 00030 #include <qmovie.h> 00031 #include <qregexp.h> 00032 00033 #include <kapplication.h> 00034 #include <kdebug.h> 00035 #include <kio/previewjob.h> 00036 #include <kfileivi.h> 00037 #include <konq_settings.h> 00038 #include <konq_drag.h> 00039 #include <konq_operations.h> 00040 #include <kglobalsettings.h> 00041 #include <kpropertiesdialog.h> 00042 #include <kipc.h> 00043 #include <kicontheme.h> 00044 #include <kiconeffect.h> 00045 #include <kurldrag.h> 00046 #include <kstandarddirs.h> 00047 #include <kprotocolinfo.h> 00048 00049 #include <assert.h> 00050 #include <unistd.h> 00051 00052 class KFileTip: public QFrame 00053 { 00054 public: 00055 KFileTip( KonqIconViewWidget* parent ) : QFrame( 0, 0, WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WStyle_StaysOnTop | WX11BypassWM ), 00056 00057 m_corner( 0 ), 00058 m_filter( false ), 00059 m_view( parent ), 00060 m_item( 0 ), 00061 m_previewJob( 0 ), 00062 m_ivi( 0 ) 00063 { 00064 m_iconLabel = new QLabel(this); 00065 m_textLabel = new QLabel(this); 00066 m_textLabel->setAlignment(Qt::AlignAuto | Qt::AlignTop); 00067 00068 QGridLayout* layout = new QGridLayout(this, 1, 2, 8, 0); 00069 layout->addWidget(m_iconLabel, 0, 0); 00070 layout->addWidget(m_textLabel, 0, 1); 00071 layout->setResizeMode(QLayout::Fixed); 00072 00073 setPalette( QToolTip::palette() ); 00074 setMargin( 1 ); 00075 setFrameStyle( QFrame::Plain | QFrame::Box ); 00076 00077 hide(); 00078 } 00079 ~KFileTip(); 00080 00081 void setPreview(bool on) 00082 { 00083 m_preview = on; 00084 if(on) 00085 m_iconLabel->show(); 00086 else 00087 m_iconLabel->hide(); 00088 } 00089 00090 void setOptions( bool on, bool preview, int num) 00091 { 00092 m_num = num; 00093 setPreview(preview); 00094 m_on = on; 00095 } 00096 00097 void setItem( KFileIVI *ivi ); 00098 00099 virtual bool eventFilter( QObject *, QEvent *e ); 00100 00101 void gotPreview( const KFileItem*, const QPixmap& ); 00102 void gotPreviewResult(); 00103 00104 protected: 00105 virtual void drawContents( QPainter *p ); 00106 virtual void timerEvent( QTimerEvent * ); 00107 virtual void resizeEvent( QResizeEvent * ); 00108 00109 private: 00110 void setFilter( bool enable ); 00111 00112 void reposition(); 00113 00114 QLabel* m_iconLabel; 00115 QLabel* m_textLabel; 00116 int m_num; 00117 bool m_on; 00118 bool m_preview; 00119 QPixmap m_corners[4]; 00120 int m_corner; 00121 bool m_filter; 00122 KonqIconViewWidget* m_view; 00123 KFileItem* m_item; 00124 KIO::PreviewJob* m_previewJob; 00125 KFileIVI* m_ivi; 00126 }; 00127 00128 KFileTip::~KFileTip() 00129 { 00130 if ( m_previewJob ) { 00131 m_previewJob->kill(); 00132 m_previewJob = 0; 00133 } 00134 } 00135 00136 void KFileTip::setItem( KFileIVI *ivi ) 00137 { 00138 if (!m_on) return; 00139 if (m_ivi == ivi) return; 00140 00141 if ( m_previewJob ) { 00142 m_previewJob->kill(); 00143 m_previewJob = 0; 00144 } 00145 00146 m_ivi = ivi; 00147 m_item = ivi ? ivi->item() : 0; 00148 00149 QString text = ivi ? ivi->item()->getToolTipText( m_num ) : QString::null; 00150 if ( !text.isEmpty() ) { 00151 hide(); 00152 m_textLabel -> setText( text ); 00153 00154 killTimers(); 00155 setFilter( true ); 00156 00157 if (m_preview) { 00158 m_iconLabel -> setPixmap(*(ivi->pixmap())); 00159 KFileItemList oneItem; 00160 oneItem.append( ivi->item() ); 00161 00162 m_previewJob = KIO::filePreview( oneItem, 256, 256, 64, 70, true, true, 0); 00163 connect( m_previewJob, SIGNAL( gotPreview( const KFileItem *, const QPixmap & ) ), 00164 m_view, SLOT( slotToolTipPreview( const KFileItem *, const QPixmap & ) ) ); 00165 connect( m_previewJob, SIGNAL( result( KIO::Job * ) ), 00166 m_view, SLOT( slotToolTipPreviewResult() ) ); 00167 } 00168 00169 startTimer( 700 ); 00170 } 00171 else { 00172 killTimers(); 00173 if ( isVisible() ) { 00174 setFilter( false ); 00175 hide(); 00176 } 00177 } 00178 } 00179 00180 void KFileTip::reposition() 00181 { 00182 if (!m_ivi) return; 00183 00184 QRect rect = m_ivi->rect(); 00185 QPoint off = m_view->mapToGlobal( m_view->contentsToViewport( QPoint( 0, 0 ) ) ); 00186 rect.moveBy( off.x(), off.y() ); 00187 00188 QPoint pos = rect.center(); 00189 // m_corner: 00190 // 0: upperleft 00191 // 1: upperright 00192 // 2: lowerleft 00193 // 3: lowerright 00194 // 4+: none 00195 m_corner = 0; 00196 // should the tooltip be shown to the left or to the right of the ivi ? 00197 QRect desk = KGlobalSettings::desktopGeometry(rect.center()); 00198 if (rect.center().x() + width() > desk.right()) 00199 { 00200 // to the left 00201 if (pos.x() - width() < 0) { 00202 pos.setX(0); 00203 m_corner = 4; 00204 } else { 00205 pos.setX( pos.x() - width() ); 00206 m_corner = 1; 00207 } 00208 } 00209 // should the tooltip be shown above or below the ivi ? 00210 if (rect.bottom() + height() > desk.bottom()) 00211 { 00212 // above 00213 pos.setY( rect.top() - height() ); 00214 m_corner += 2; 00215 } 00216 else pos.setY( rect.bottom() ); 00217 00218 move( pos ); 00219 update(); 00220 } 00221 00222 void KFileTip::gotPreview( const KFileItem* item, const QPixmap& pixmap ) 00223 { 00224 m_previewJob = 0; 00225 if (item != m_item) return; 00226 00227 m_iconLabel -> setPixmap(pixmap); 00228 } 00229 00230 void KFileTip::gotPreviewResult() 00231 { 00232 m_previewJob = 0; 00233 } 00234 00235 void KFileTip::drawContents( QPainter *p ) 00236 { 00237 static const char * const names[] = { 00238 "arrow_topleft", 00239 "arrow_topright", 00240 "arrow_bottomleft", 00241 "arrow_bottomright" 00242 }; 00243 00244 if (m_corner >= 4) { // 4 is empty, so don't draw anything 00245 QFrame::drawContents( p ); 00246 return; 00247 } 00248 00249 if ( m_corners[m_corner].isNull()) 00250 m_corners[m_corner].load( locate( "data", QString::fromLatin1( "konqueror/pics/%1.png" ).arg( names[m_corner] ) ) ); 00251 00252 QPixmap &pix = m_corners[m_corner]; 00253 00254 switch ( m_corner ) 00255 { 00256 case 0: 00257 p->drawPixmap( 3, 3, pix ); 00258 break; 00259 case 1: 00260 p->drawPixmap( width() - pix.width() - 3, 3, pix ); 00261 break; 00262 case 2: 00263 p->drawPixmap( 3, height() - pix.height() - 3, pix ); 00264 break; 00265 case 3: 00266 p->drawPixmap( width() - pix.width() - 3, height() - pix.height() - 3, pix ); 00267 break; 00268 } 00269 00270 QFrame::drawContents( p ); 00271 } 00272 00273 void KFileTip::setFilter( bool enable ) 00274 { 00275 if ( enable == m_filter ) return; 00276 00277 if ( enable ) { 00278 kapp->installEventFilter( this ); 00279 QApplication::setGlobalMouseTracking( true ); 00280 } 00281 else { 00282 QApplication::setGlobalMouseTracking( false ); 00283 kapp->removeEventFilter( this ); 00284 } 00285 m_filter = enable; 00286 } 00287 00288 void KFileTip::timerEvent( QTimerEvent * ) 00289 { 00290 killTimers(); 00291 if ( !isVisible() ) { 00292 startTimer( 15000 ); 00293 reposition(); 00294 show(); 00295 } 00296 else { 00297 setFilter( false ); 00298 hide(); 00299 } 00300 } 00301 00302 void KFileTip::resizeEvent( QResizeEvent* event ) 00303 { 00304 QFrame::resizeEvent(event); 00305 reposition(); 00306 } 00307 00308 bool KFileTip::eventFilter( QObject *, QEvent *e ) 00309 { 00310 switch ( e->type() ) 00311 { 00312 case QEvent::Leave: 00313 case QEvent::MouseButtonPress: 00314 case QEvent::MouseButtonRelease: 00315 case QEvent::KeyPress: 00316 case QEvent::KeyRelease: 00317 case QEvent::FocusIn: 00318 case QEvent::FocusOut: 00319 case QEvent::Wheel: 00320 killTimers(); 00321 setFilter( false ); 00322 hide(); 00323 default: break; 00324 } 00325 00326 return false; 00327 } 00328 00329 struct KonqIconViewWidgetPrivate 00330 { 00331 KonqIconViewWidgetPrivate() { 00332 pActiveItem = 0; 00333 bSoundPreviews = false; 00334 pSoundItem = 0; 00335 bSoundItemClicked = false; 00336 pSoundPlayer = 0; 00337 pSoundTimer = 0; 00338 pPreviewJob = 0; 00339 bAllowSetWallpaper = false; 00340 gridXspacing = 50; 00341 00342 doAnimations = true; 00343 m_movie = 0L; 00344 m_movieBlocked = 0; 00345 pFileTip = 0; 00346 pActivateDoubleClick = 0L; 00347 bCaseInsensitive = true; 00348 } 00349 ~KonqIconViewWidgetPrivate() { 00350 delete pSoundPlayer; 00351 delete pSoundTimer; 00352 delete m_movie; 00353 delete pFileTip; 00354 delete pActivateDoubleClick; 00355 //delete pPreviewJob; done by stopImagePreview 00356 } 00357 KFileIVI *pActiveItem; 00358 // Sound preview 00359 KFileIVI *pSoundItem; 00360 KonqSoundPlayer *pSoundPlayer; 00361 QTimer *pSoundTimer; 00362 bool bSoundPreviews; 00363 bool bSoundItemClicked; 00364 bool bAllowSetWallpaper; 00365 bool bCaseInsensitive; 00366 int gridXspacing; 00367 00368 QTimer* rearrangeIconsTimer; 00369 00370 // Animated icons support 00371 bool doAnimations; 00372 QMovie* m_movie; 00373 int m_movieBlocked; 00374 QString movieFileName; 00375 00376 KIO::PreviewJob *pPreviewJob; 00377 KFileTip* pFileTip; 00378 QStringList previewSettings; 00379 bool renameItem; 00380 bool firstClick; 00381 bool releaseMouseEvent; 00382 QPoint mousePos; 00383 int mouseState; 00384 QTimer *pActivateDoubleClick; 00385 }; 00386 00387 KonqIconViewWidget::KonqIconViewWidget( QWidget * parent, const char * name, WFlags f, bool kdesktop ) 00388 : KIconView( parent, name, f ), 00389 m_rootItem( 0L ), m_size( 0 ) /* default is DesktopIcon size */, 00390 m_bDesktop( kdesktop ), 00391 m_bSetGridX( !kdesktop ) /* No line breaking on the desktop */ 00392 { 00393 d = new KonqIconViewWidgetPrivate; 00394 d->rearrangeIconsTimer = new QTimer( this ); 00395 connect( this, SIGNAL( dropped( QDropEvent *, const QValueList<QIconDragItem> & ) ), 00396 this, SLOT( slotDropped( QDropEvent*, const QValueList<QIconDragItem> & ) ) ); 00397 00398 connect( this, SIGNAL( selectionChanged() ), 00399 this, SLOT( slotSelectionChanged() ) ); 00400 00401 kapp->addKipcEventMask( KIPC::IconChanged ); 00402 connect( kapp, SIGNAL(iconChanged(int)), SLOT(slotIconChanged(int)) ); 00403 connect( this, SIGNAL(onItem(QIconViewItem *)), SLOT(slotOnItem(QIconViewItem *)) ); 00404 connect( this, SIGNAL(onViewport()), SLOT(slotOnViewport()) ); 00405 connect( this, SIGNAL(itemRenamed(QIconViewItem *, const QString &)), SLOT(slotItemRenamed(QIconViewItem *, const QString &)) ); 00406 00407 connect( d->rearrangeIconsTimer, SIGNAL( timeout() ), SLOT( slotRearrangeIcons() ) ); 00408 00409 // hardcoded settings 00410 setSelectionMode( QIconView::Extended ); 00411 setItemTextPos( QIconView::Bottom ); 00412 d->releaseMouseEvent = false; 00413 d->pFileTip = new KFileTip(this); 00414 d->firstClick = false; 00415 calculateGridX(); 00416 setAutoArrange( true ); 00417 setSorting( true, sortDirection() ); 00418 readAnimatedIconsConfig(); 00419 m_bSortDirsFirst = true; 00420 m_bMousePressed = false; 00421 m_LineupMode = LineupBoth; 00422 // emit our signals 00423 slotSelectionChanged(); 00424 m_iconPositionGroupPrefix = QString::fromLatin1( "IconPosition::" ); 00425 KonqUndoManager::incRef(); 00426 } 00427 00428 KonqIconViewWidget::~KonqIconViewWidget() 00429 { 00430 stopImagePreview(); 00431 KonqUndoManager::decRef(); 00432 delete d; 00433 } 00434 00435 bool KonqIconViewWidget::maySetWallpaper() 00436 { 00437 return d->bAllowSetWallpaper; 00438 } 00439 00440 void KonqIconViewWidget::setMaySetWallpaper(bool b) 00441 { 00442 d->bAllowSetWallpaper = b; 00443 } 00444 00445 void KonqIconViewWidget::focusOutEvent( QFocusEvent * ev ) 00446 { 00447 // We can't possibly have the mouse pressed and still lose focus. 00448 // Well, we can, but when we regain focus we should assume the mouse is 00449 // not down anymore or the slotOnItem code will break with highlighting! 00450 m_bMousePressed = false; 00451 KIconView::focusOutEvent( ev ); 00452 } 00453 00454 void KonqIconViewWidget::slotItemRenamed(QIconViewItem *item, const QString &name) 00455 { 00456 kdDebug(1203) << "KonqIconViewWidget::slotItemRenamed" << endl; 00457 KFileIVI *viewItem = static_cast<KFileIVI *>(item); 00458 KFileItem *fileItem = viewItem->item(); 00459 00460 // The correct behavior is to show the old name until the rename has successfully 00461 // completed. Unfortunately, KIconView forces us to allow the text to be changed 00462 // before we try the rename, so set it back to the pre-rename state. 00463 viewItem->setText( fileItem->text() ); 00464 kdDebug(1203)<<" fileItem->text() ;"<<fileItem->text()<<endl; 00465 // Don't do anything if the user renamed to a blank name. 00466 if( !name.isEmpty() ) 00467 { 00468 // Actually attempt the rename. If it succeeds, KDirLister will update the name. 00469 KURL oldurl( fileItem->url() ); 00470 KURL newurl( url() ); 00471 newurl.setPath( url().path(1) + KIO::encodeFileName( name ) ); 00472 kdDebug(1203)<<" newurl :"<<newurl.url()<<endl; 00473 // We use url()+name so that it also works if the name is a relative path (#51176) 00474 KonqOperations::rename( this, oldurl, newurl ); 00475 } 00476 } 00477 00478 void KonqIconViewWidget::slotIconChanged( int group ) 00479 { 00480 if (group != KIcon::Desktop) 00481 return; 00482 00483 int size = m_size; 00484 if ( m_size == 0 ) 00485 m_size = -1; // little trick to force grid change in setIcons 00486 setIcons( size ); // force re-determining all icons 00487 readAnimatedIconsConfig(); 00488 } 00489 00490 void KonqIconViewWidget::readAnimatedIconsConfig() 00491 { 00492 KConfigGroup cfgGroup( KGlobal::config(), "DesktopIcons" ); 00493 d->doAnimations = cfgGroup.readBoolEntry( "Animated", true /*default*/ ); 00494 d->gridXspacing = cfgGroup.readNumEntry( "GridXSpacing", 50); 00495 } 00496 00497 void KonqIconViewWidget::slotOnItem( QIconViewItem *_item ) 00498 { 00499 KFileIVI* item = static_cast<KFileIVI *>( _item ); 00500 // Reset icon of previous item 00501 if( d->pActiveItem != 0L && d->pActiveItem != item ) 00502 { 00503 if ( d->m_movie && d->pActiveItem->isAnimated() ) 00504 { 00505 d->m_movie->pause(); // we'll see below what we do with it 00506 d->pActiveItem->setAnimated( false ); 00507 d->pActiveItem->refreshIcon( true ); 00508 } 00509 else { 00510 d->pActiveItem->setActive( false ); 00511 } 00512 d->pActiveItem = 0L; 00513 d->pFileTip->setItem( 0L ); 00514 } 00515 00516 // Stop sound 00517 if (d->pSoundPlayer != 0 && item != d->pSoundItem) 00518 { 00519 d->pSoundPlayer->stop(); 00520 00521 d->pSoundItem = 0; 00522 if (d->pSoundTimer && d->pSoundTimer->isActive()) 00523 d->pSoundTimer->stop(); 00524 } 00525 00526 if ( !m_bMousePressed ) 00527 { 00528 if( item != d->pActiveItem ) 00529 { 00530 d->pActiveItem = item; 00531 if ( topLevelWidget() == kapp->activeWindow() ) 00532 d->pFileTip->setItem( d->pActiveItem ); 00533 00534 if ( d->doAnimations && d->pActiveItem && d->pActiveItem->hasAnimation() ) 00535 { 00536 //kdDebug(1203) << "Playing animation for: " << d->pActiveItem->mouseOverAnimation() << endl; 00537 // Check if cached movie can be used 00538 #if 0 // Qt-mng bug, reusing the movie doesn't work currently. 00539 if ( d->m_movie && d->movieFileName == d->pActiveItem->mouseOverAnimation() ) 00540 { 00541 d->pActiveItem->setAnimated( true ); 00542 if (d->m_movieBlocked) { 00543 kdDebug(1203) << "onitem, but blocked" << endl; 00544 d->m_movie->pause(); 00545 } 00546 else { 00547 kdDebug(1203) << "we go ahead.." << endl; 00548 d->m_movieBlocked++; 00549 QTimer::singleShot(300, this, SLOT(slotReenableAnimation())); 00550 d->m_movie->restart(); 00551 d->m_movie->unpause(); 00552 } 00553 } 00554 else 00555 #endif 00556 { 00557 QMovie movie = KGlobal::iconLoader()->loadMovie( d->pActiveItem->mouseOverAnimation(), KIcon::Desktop, d->pActiveItem->iconSize() ); 00558 if ( !movie.isNull() ) 00559 { 00560 delete d->m_movie; 00561 d->m_movie = new QMovie( movie ); // shallow copy, don't worry 00562 // Fix alpha-channel - currently only if no background pixmap, 00563 // the bg pixmap case requires to uncomment the code at qmovie.cpp:404 00564 const QPixmap* pm = backgroundPixmap(); 00565 bool hasPixmap = pm && !pm->isNull(); 00566 if ( !hasPixmap ) { 00567 pm = viewport()->backgroundPixmap(); 00568 hasPixmap = pm && !pm->isNull(); 00569 } 00570 if (!hasPixmap && backgroundMode() != NoBackground) 00571 d->m_movie->setBackgroundColor( viewport()->backgroundColor() ); 00572 d->m_movie->connectUpdate( this, SLOT( slotMovieUpdate(const QRect &) ) ); 00573 d->m_movie->connectStatus( this, SLOT( slotMovieStatus(int) ) ); 00574 d->movieFileName = d->pActiveItem->mouseOverAnimation(); 00575 d->pActiveItem->setAnimated( true ); 00576 } 00577 else 00578 { 00579 d->pActiveItem->setAnimated( false ); 00580 if (d->m_movie) 00581 d->m_movie->pause(); 00582 // No movie available, remember it 00583 d->pActiveItem->setMouseOverAnimation( QString::null ); 00584 } 00585 } 00586 } // animations 00587 // Only do the normal "mouseover" effect if no animation is in use 00588 if (d->pActiveItem && !d->pActiveItem->isAnimated()) 00589 { 00590 d->pActiveItem->setActive( true ); 00591 } 00592 } 00593 else // No change in current item 00594 { 00595 // No effect. If we want to underline on hover, we should 00596 // force the IVI to repaint here, though! 00597 d->pActiveItem = 0L; 00598 d->pFileTip->setItem( 0L ); 00599 } 00600 } // bMousePressed 00601 else 00602 { 00603 // All features disabled during mouse clicking, e.g. rectangular 00604 // selection 00605 d->pActiveItem = 0L; 00606 d->pFileTip->setItem( 0L ); 00607 } 00608 00609 // ## shouldn't this be disabled during rectangular selection too ? 00610 if (d->bSoundPreviews && d->pSoundPlayer && 00611 d->pSoundPlayer->mimeTypes().contains( 00612 item->item()->mimetype()) 00613 && KGlobalSettings::showFilePreview(item->item()->url())) 00614 { 00615 d->pSoundItem = item; 00616 d->bSoundItemClicked = false; 00617 if (!d->pSoundTimer) 00618 { 00619 d->pSoundTimer = new QTimer(this); 00620 connect(d->pSoundTimer, SIGNAL(timeout()), SLOT(slotStartSoundPreview())); 00621 } 00622 if (d->pSoundTimer->isActive()) 00623 d->pSoundTimer->stop(); 00624 d->pSoundTimer->start(500, true); 00625 } 00626 else 00627 { 00628 if (d->pSoundPlayer) 00629 d->pSoundPlayer->stop(); 00630 d->pSoundItem = 0; 00631 if (d->pSoundTimer && d->pSoundTimer->isActive()) 00632 d->pSoundTimer->stop(); 00633 } 00634 } 00635 00636 void KonqIconViewWidget::slotOnViewport() 00637 { 00638 d->pFileTip->setItem( 0L ); 00639 00640 if (d->pSoundPlayer) 00641 d->pSoundPlayer->stop(); 00642 d->pSoundItem = 0; 00643 if (d->pSoundTimer && d->pSoundTimer->isActive()) 00644 d->pSoundTimer->stop(); 00645 00646 if (d->pActiveItem == 0L) 00647 return; 00648 00649 if ( d->doAnimations && d->m_movie && d->pActiveItem->isAnimated() ) 00650 { 00651 d->pActiveItem->setAnimated( false ); 00652 #if 0 00653 // Aborting before the end of the animation ? 00654 if (d->m_movie->running()) { 00655 d->m_movie->pause(); 00656 d->m_movieBlocked++; 00657 kdDebug(1203) << "on viewport, blocking" << endl; 00658 QTimer::singleShot(300, this, SLOT(slotReenableAnimation())); 00659 } 00660 #endif 00661 d->pActiveItem->refreshIcon( true ); 00662 Q_ASSERT( d->pActiveItem->state() == KIcon::DefaultState ); 00663 //delete d->m_movie; 00664 //d->m_movie = 0L; 00665 // TODO a timer to delete the movie after some time if unused? 00666 } 00667 else 00668 { 00669 d->pActiveItem->setActive( false ); 00670 } 00671 d->pActiveItem = 0L; 00672 } 00673 00674 void KonqIconViewWidget::slotStartSoundPreview() 00675 { 00676 if (!d->pSoundItem || d->bSoundItemClicked) 00677 return; 00678 00679 d->pSoundPlayer->play(d->pSoundItem->item()->url().url()); 00680 } 00681 00682 00683 void KonqIconViewWidget::slotPreview(const KFileItem *item, const QPixmap &pix) 00684 { 00685 // ### slow. Idea: move KonqKfmIconView's m_itemDict into this class 00686 for (QIconViewItem *it = firstItem(); it; it = it->nextItem()) 00687 { 00688 KFileIVI* current = static_cast<KFileIVI *>(it); 00689 if (current->item() == item) 00690 { 00691 bool needsUpdate = ( !current->pixmap() || current->pixmap()->width() < pix.width() || current->pixmap()->height() < pix.height() ); 00692 if(item->overlays() & KIcon::HiddenOverlay) 00693 { 00694 QPixmap p(pix); 00695 00696 KIconEffect::semiTransparent(p); 00697 current->setThumbnailPixmap(p); 00698 } else { 00699 current->setThumbnailPixmap(pix); 00700 } 00701 if ( needsUpdate 00702 && autoArrange() 00703 && !d->rearrangeIconsTimer->isActive() ) { 00704 d->rearrangeIconsTimer->start( 500, true ); 00705 } 00706 } 00707 } 00708 } 00709 00710 void KonqIconViewWidget::slotPreviewResult() 00711 { 00712 d->pPreviewJob = 0; 00713 if ( d->rearrangeIconsTimer->isActive() ) { 00714 d->rearrangeIconsTimer->stop(); 00715 slotRearrangeIcons(); 00716 } 00717 emit imagePreviewFinished(); 00718 } 00719 00720 void KonqIconViewWidget::slotToolTipPreview(const KFileItem* item, const QPixmap &pix) 00721 { 00722 if (d->pFileTip) d->pFileTip->gotPreview( item, pix ); 00723 } 00724 00725 void KonqIconViewWidget::slotToolTipPreviewResult() 00726 { 00727 if (d->pFileTip) d->pFileTip->gotPreviewResult(); 00728 } 00729 00730 void KonqIconViewWidget::slotMovieUpdate( const QRect& rect ) 00731 { 00732 //kdDebug(1203) << "KonqIconViewWidget::slotMovieUpdate " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << endl; 00733 Q_ASSERT( d ); 00734 Q_ASSERT( d->m_movie ); 00735 // seems stopAnimation triggers one last update 00736 if ( d->pActiveItem && d->m_movie && d->pActiveItem->isAnimated() ) { 00737 const QPixmap &frame = d->m_movie->framePixmap(); 00738 // This can happen if the icon was scaled to the desired size, so KIconLoader 00739 // will happily return a movie with different dimensions than the icon 00740 int iconSize=d->pActiveItem->iconSize(); 00741 if (iconSize==0) iconSize = KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00742 if ( frame.width() != iconSize || frame.height() != iconSize ) { 00743 d->pActiveItem->setAnimated( false ); 00744 d->m_movie->pause(); 00745 // No movie available, remember it 00746 d->pActiveItem->setMouseOverAnimation( QString::null ); 00747 d->pActiveItem->setActive( true ); 00748 return; 00749 } 00750 d->pActiveItem->setPixmapDirect( frame, false, false /*no redraw*/ ); 00751 QRect pixRect = d->pActiveItem->pixmapRect(false); 00752 repaintContents( pixRect.x() + rect.x(), pixRect.y() + rect.y(), rect.width(), rect.height(), false ); 00753 } 00754 } 00755 00756 void KonqIconViewWidget::slotMovieStatus( int status ) 00757 { 00758 if ( status < 0 ) { 00759 // Error playing the MNG -> forget about it and do normal iconeffect 00760 if ( d->pActiveItem && d->pActiveItem->isAnimated() ) { 00761 d->pActiveItem->setAnimated( false ); 00762 d->pActiveItem->setMouseOverAnimation( QString::null ); 00763 d->pActiveItem->setActive( true ); 00764 } 00765 } 00766 } 00767 00768 void KonqIconViewWidget::slotReenableAnimation() 00769 { 00770 if (!--d->m_movieBlocked) { 00771 if ( d->pActiveItem && d->m_movie && d->m_movie->paused()) { 00772 kdDebug(1203) << "reenabled animation" << endl; 00773 d->m_movie->restart(); 00774 d->m_movie->unpause(); 00775 } 00776 } 00777 } 00778 00779 void KonqIconViewWidget::clear() 00780 { 00781 d->pFileTip->setItem( 0L ); 00782 stopImagePreview(); // Just in case 00783 KIconView::clear(); 00784 d->pActiveItem = 0L; 00785 } 00786 00787 void KonqIconViewWidget::takeItem( QIconViewItem *item ) 00788 { 00789 if ( d->pActiveItem == static_cast<KFileIVI *>(item) ) 00790 { 00791 d->pFileTip->setItem( 0L ); 00792 d->pActiveItem = 0L; 00793 } 00794 00795 if ( d->pPreviewJob ) 00796 d->pPreviewJob->removeItem( static_cast<KFileIVI *>(item)->item() ); 00797 00798 KIconView::takeItem( item ); 00799 } 00800 00801 // Currently unused - remove in KDE 4.0 00802 void KonqIconViewWidget::setThumbnailPixmap( KFileIVI * item, const QPixmap & pixmap ) 00803 { 00804 if ( item ) 00805 { 00806 if ( d->pActiveItem == item ) 00807 { 00808 d->pFileTip->setItem( 0L ); 00809 d->pActiveItem = 0L; 00810 } 00811 item->setThumbnailPixmap( pixmap ); 00812 if ( m_bSetGridX && item->width() > gridX() ) 00813 { 00814 setGridX( item->width() ); 00815 if (autoArrange()) 00816 arrangeItemsInGrid(); 00817 } 00818 } 00819 } 00820 00821 bool KonqIconViewWidget::initConfig( bool bInit ) 00822 { 00823 bool fontChanged = false; 00824 m_pSettings = KonqFMSettings::settings(); 00825 00826 // Color settings 00827 QColor normalTextColor = m_pSettings->normalTextColor(); 00828 setItemColor( normalTextColor ); 00829 00830 if (m_bDesktop) 00831 { 00832 QColor itemTextBg = m_pSettings->itemTextBackground(); 00833 if ( itemTextBg.isValid() ) 00834 setItemTextBackground( itemTextBg ); 00835 else 00836 setItemTextBackground( NoBrush ); 00837 } 00838 00839 00840 d->pFileTip->setOptions(m_pSettings->showFileTips() && QToolTip::isGloballyEnabled(), 00841 m_pSettings->showPreviewsInFileTips(), 00842 m_pSettings->numFileTips()); 00843 00844 // Font settings 00845 QFont font( m_pSettings->standardFont() ); 00846 if (!m_bDesktop) 00847 font.setUnderline( m_pSettings->underlineLink() ); 00848 00849 if ( font != KonqIconViewWidget::font() ) 00850 { 00851 setFont( font ); 00852 if (!bInit) 00853 { 00854 // QIconView doesn't do it by default... but if the font is made much 00855 // bigger, we really need to give more space between the icons 00856 fontChanged = true; 00857 } 00858 } 00859 setWordWrapIconText( m_pSettings->wordWrapText() ); 00860 00861 if (!bInit) 00862 updateContents(); 00863 return fontChanged; 00864 } 00865 00866 void KonqIconViewWidget::disableSoundPreviews() 00867 { 00868 d->bSoundPreviews = false; 00869 00870 if (d->pSoundPlayer) 00871 d->pSoundPlayer->stop(); 00872 d->pSoundItem = 0; 00873 if (d->pSoundTimer && d->pSoundTimer->isActive()) 00874 d->pSoundTimer->stop(); 00875 } 00876 00877 void KonqIconViewWidget::setIcons( int size, const QStringList& stopImagePreviewFor ) 00878 { 00879 //kdDebug(1203) << "KonqIconViewWidget::setIcons( " << size << " , " << stopImagePreviewFor.join(",") << ")" << endl; 00880 bool sizeChanged = (m_size != size); 00881 int oldGridX = gridX(); 00882 m_size = size; 00883 00884 if ( sizeChanged ) 00885 { 00886 setSpacing( (size > KIcon::SizeSmall) ? 5 : 0 ); 00887 } 00888 00889 if ( sizeChanged || !stopImagePreviewFor.isEmpty() ) 00890 { 00891 calculateGridX(); 00892 } 00893 bool stopAll = !stopImagePreviewFor.isEmpty() && stopImagePreviewFor.first() == "*"; 00894 // Do this even if size didn't change, since this is used by refreshMimeTypes... 00895 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) { 00896 KFileIVI * ivi = static_cast<KFileIVI *>( it ); 00897 // Set a normal icon for files that are not thumbnails, and for files 00898 // that are thumbnails but for which it should be stopped 00899 if ( !ivi->isThumbnail() || 00900 stopAll || 00901 mimeTypeMatch( ivi->item()->mimetype(), stopImagePreviewFor ) ) 00902 { 00903 ivi->setIcon( size, ivi->state(), true, false ); 00904 } 00905 else 00906 ivi->invalidateThumb( ivi->state(), false ); 00907 } 00908 00909 if ( autoArrange() && (oldGridX != gridX() || !stopImagePreviewFor.isEmpty()) ) 00910 arrangeItemsInGrid( true ); // take new grid into account and repaint 00911 else 00912 viewport()->update(); //Repaint later.. 00913 } 00914 00915 bool KonqIconViewWidget::mimeTypeMatch( const QString& mimeType, const QStringList& mimeList ) const 00916 { 00917 for (QStringList::ConstIterator mt = mimeList.begin(); mt != mimeList.end(); ++mt) 00918 { 00919 if ( mimeType == *mt ) 00920 return true; 00921 // Support for *mt == "image/*" 00922 QString tmp( mimeType ); 00923 if ( (*mt).endsWith("*") && tmp.replace(QRegExp("/.*"), "/*") == (*mt) ) 00924 return true; 00925 } 00926 return false; 00927 } 00928 00929 void KonqIconViewWidget::setItemTextPos( ItemTextPos pos ) 00930 { 00931 if ( m_bSetGridX ) 00932 { 00933 calculateGridX(); 00934 if ( itemTextPos() != pos ) 00935 { 00936 if ( pos == QIconView::Right ) 00937 setGridX( gridX() + 100 ); 00938 else 00939 setGridX( gridX() - 100 ); 00940 } 00941 } 00942 00943 KIconView::setItemTextPos( pos ); 00944 } 00945 00946 void KonqIconViewWidget::calculateGridX() 00947 { 00948 if ( m_bSetGridX ) 00949 setGridX( gridXValue() ); 00950 } 00951 00952 int KonqIconViewWidget::gridXValue() const 00953 { 00954 int sz = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00955 int newGridX = sz + (!m_bSetGridX ? d->gridXspacing : 50) + (( itemTextPos() == QIconView::Right ) ? 100 : 0); 00956 //kdDebug(1203) << "gridXValue: " << newGridX << " sz=" << sz << endl; 00957 return newGridX; 00958 } 00959 00960 void KonqIconViewWidget::refreshMimeTypes() 00961 { 00962 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) 00963 (static_cast<KFileIVI *>( it ))->item()->refreshMimeType(); 00964 setIcons( m_size ); 00965 } 00966 00967 void KonqIconViewWidget::setURL( const KURL &kurl ) 00968 { 00969 stopImagePreview(); 00970 m_url = kurl; 00971 00972 d->pFileTip->setPreview( KGlobalSettings::showFilePreview(m_url) ); 00973 00974 if ( m_url.isLocalFile() ) 00975 m_dotDirectoryPath = m_url.path(1).append( ".directory" ); 00976 else 00977 m_dotDirectoryPath = QString::null; 00978 } 00979 00980 void KonqIconViewWidget::startImagePreview( const QStringList &, bool force ) 00981 { 00982 stopImagePreview(); // just in case 00983 00984 // Check config 00985 if ( !KGlobalSettings::showFilePreview( url() ) ) { 00986 kdDebug(1203) << "Previews disabled for protocol " << url().protocol() << endl; 00987 emit imagePreviewFinished(); 00988 return; 00989 } 00990 00991 if ((d->bSoundPreviews = d->previewSettings.contains( "audio/" )) && 00992 !d->pSoundPlayer) 00993 { 00994 KLibFactory *factory = KLibLoader::self()->factory("konq_sound"); 00995 if (factory) 00996 d->pSoundPlayer = static_cast<KonqSoundPlayer *>( 00997 factory->create(this, 0, "KonqSoundPlayer")); 00998 d->bSoundPreviews = (d->pSoundPlayer != 0L); 00999 } 01000 01001 KFileItemList items; 01002 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) 01003 if ( force || !static_cast<KFileIVI *>( it )->hasValidThumbnail() ) 01004 items.append( static_cast<KFileIVI *>( it )->item() ); 01005 01006 bool onlyAudio = true; 01007 for ( QStringList::ConstIterator it = d->previewSettings.begin(); it != d->previewSettings.end(); ++it ) { 01008 if ( (*it).startsWith( "audio/" ) ) 01009 d->bSoundPreviews = true; 01010 else 01011 onlyAudio = false; 01012 } 01013 01014 if ( items.isEmpty() || onlyAudio ) { 01015 emit imagePreviewFinished(); 01016 return; // don't start the preview job if not really necessary 01017 } 01018 01019 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 01020 int size; 01021 01022 KConfigGroup group( KGlobal::config(), "PreviewSettings" ); 01023 if ( group.readBoolEntry("BoostSize", false) ) { 01024 if (iconSize < 28) 01025 size = 48; 01026 else if (iconSize < 40) 01027 size = 64; 01028 else if (iconSize < 60) 01029 size = 96; 01030 else 01031 size = 128; 01032 } else { 01033 size = iconSize; 01034 iconSize /= 2; 01035 } 01036 01037 d->pPreviewJob = KIO::filePreview( items, size, size, iconSize, 01038 m_pSettings->textPreviewIconTransparency(), true /* scale */, 01039 true /* save */, &(d->previewSettings) ); 01040 connect( d->pPreviewJob, SIGNAL( gotPreview( const KFileItem *, const QPixmap & ) ), 01041 this, SLOT( slotPreview( const KFileItem *, const QPixmap & ) ) ); 01042 connect( d->pPreviewJob, SIGNAL( result( KIO::Job * ) ), 01043 this, SLOT( slotPreviewResult() ) ); 01044 } 01045 01046 void KonqIconViewWidget::stopImagePreview() 01047 { 01048 if (d->pPreviewJob) 01049 { 01050 d->pPreviewJob->kill(); 01051 d->pPreviewJob = 0; 01052 if (autoArrange()) 01053 arrangeItemsInGrid(); 01054 } 01055 } 01056 01057 bool KonqIconViewWidget::isPreviewRunning() const 01058 { 01059 return d->pPreviewJob; 01060 } 01061 01062 KFileItemList KonqIconViewWidget::selectedFileItems() 01063 { 01064 KFileItemList lstItems; 01065 01066 QIconViewItem *it = firstItem(); 01067 for (; it; it = it->nextItem() ) 01068 if ( it->isSelected() ) { 01069 KFileItem *fItem = (static_cast<KFileIVI *>(it))->item(); 01070 lstItems.append( fItem ); 01071 } 01072 return lstItems; 01073 } 01074 01075 void KonqIconViewWidget::slotDropped( QDropEvent *ev, const QValueList<QIconDragItem> & ) 01076 { 01077 // Drop on background 01078 KonqOperations::doDrop( m_rootItem /* may be 0L */, url(), ev, this ); 01079 } 01080 01081 void KonqIconViewWidget::slotAboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &) 01082 { 01083 // Do nothing :-) 01084 } 01085 01086 void KonqIconViewWidget::slotRearrangeIcons() 01087 { 01088 // We cannot actually call arrangeItemsInGrid directly as a slot because it has a default parameter. 01089 arrangeItemsInGrid(); 01090 } 01091 01092 01093 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r ) 01094 { 01095 drawBackground(p, r, r.topLeft()); 01096 } 01097 01098 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r , const QPoint &pt) 01099 { 01100 const QPixmap *pm = backgroundPixmap(); 01101 bool hasPixmap = pm && !pm->isNull(); 01102 if ( !hasPixmap ) { 01103 pm = viewport()->backgroundPixmap(); 01104 hasPixmap = pm && !pm->isNull(); 01105 } 01106 01107 QRect rtgt(r); 01108 rtgt.moveTopLeft(pt); 01109 if (!hasPixmap && backgroundMode() != NoBackground) { 01110 p->fillRect(rtgt, viewport()->backgroundColor()); 01111 return; 01112 } 01113 01114 if (hasPixmap) { 01115 int ax = (r.x() + contentsX() + leftMargin()) % pm->width(); 01116 int ay = (r.y() + contentsY() + topMargin()) % pm->height(); 01117 p->drawTiledPixmap(rtgt, *pm, QPoint(ax, ay)); 01118 } 01119 } 01120 01121 QDragObject * KonqIconViewWidget::dragObject() 01122 { 01123 if ( !currentItem() ) 01124 return 0; 01125 01126 return konqDragObject( viewport() ); 01127 } 01128 01129 KonqIconDrag * KonqIconViewWidget::konqDragObject( QWidget * dragSource ) 01130 { 01131 //kdDebug(1203) << "KonqIconViewWidget::konqDragObject" << endl; 01132 01133 QPoint offset(-10,-10); 01134 KonqIconDrag * drag = new KonqIconDrag( dragSource ); 01135 QIconViewItem *primaryItem = currentItem(); 01136 // Append all items to the drag object 01137 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) { 01138 if ( it->isSelected() ) { 01139 if (!primaryItem) 01140 primaryItem = it; 01141 KURL url = (static_cast<KFileIVI *>(it))->item()->url(); 01142 QString itemURL = KURLDrag::urlToString(url); 01143 kdDebug(1203) << "itemURL=" << itemURL << endl; 01144 QIconDragItem id; 01145 id.setData( QCString(itemURL.latin1()) ); 01146 drag->append( id, 01147 QRect( it->pixmapRect(false).topLeft() - m_mousePos - offset, 01148 it->pixmapRect().size() ), 01149 QRect( it->textRect(false).topLeft() - m_mousePos - offset, 01150 it->textRect().size() ), 01151 itemURL ); 01152 } 01153 } 01154 01155 if (primaryItem) 01156 { 01157 // Set pixmap, with the correct offset 01158 drag->setPixmap( *primaryItem->pixmap(), m_mousePos - primaryItem->pixmapRect(false).topLeft() + offset ); 01159 } 01160 01161 return drag; 01162 } 01163 01164 void KonqIconViewWidget::contentsDragEnterEvent( QDragEnterEvent *e ) 01165 { 01166 if ( e->provides( "text/uri-list" ) ) 01167 { 01168 QByteArray payload = e->encodedData( "text/uri-list" ); 01169 if ( !payload.size() ) 01170 kdError() << "Empty data !" << endl; 01171 // Cache the URLs, since we need them every time we move over a file 01172 // (see KFileIVI) 01173 bool ok = KURLDrag::decode( e, m_lstDragURLs ); 01174 if( !ok ) 01175 kdError() << "Couldn't decode urls dragged !" << endl; 01176 } 01177 KIconView::contentsDragEnterEvent( e ); 01178 } 01179 01180 void KonqIconViewWidget::setItemColor( const QColor &c ) 01181 { 01182 iColor = c; 01183 } 01184 01185 QColor KonqIconViewWidget::itemColor() const 01186 { 01187 return iColor; 01188 } 01189 01190 void KonqIconViewWidget::disableIcons( const KURL::List & lst ) 01191 { 01192 for ( QIconViewItem *kit = firstItem(); kit; kit = kit->nextItem() ) 01193 { 01194 bool bFound = false; 01195 // Wow. This is ugly. Matching two lists together.... 01196 // Some sorting to optimise this would be a good idea ? 01197 for (KURL::List::ConstIterator it = lst.begin(); !bFound && it != lst.end(); ++it) 01198 { 01199 if ( static_cast<KFileIVI *>( kit )->item()->url() == *it ) 01200 { 01201 bFound = true; 01202 // maybe remove "it" from lst here ? 01203 } 01204 } 01205 static_cast<KFileIVI *>( kit )->setDisabled( bFound ); 01206 } 01207 } 01208 01209 void KonqIconViewWidget::slotSelectionChanged() 01210 { 01211 // This code is very related to ListViewBrowserExtension::updateActions 01212 int canCopy = 0; 01213 int canDel = 0; 01214 bool bInTrash = false; 01215 int iCount = 0; 01216 01217 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) 01218 { 01219 if ( it->isSelected() ) 01220 { 01221 iCount++; 01222 canCopy++; 01223 01224 KURL url = ( static_cast<KFileIVI *>( it ) )->item()->url(); 01225 if ( url.directory(false) == KGlobalSettings::trashPath() ) 01226 bInTrash = true; 01227 if ( KProtocolInfo::supportsDeleting( url ) ) 01228 canDel++; 01229 } 01230 } 01231 01232 emit enableAction( "cut", canDel > 0 ); 01233 emit enableAction( "copy", canCopy > 0 ); 01234 emit enableAction( "trash", canDel > 0 && !bInTrash && m_url.isLocalFile() ); 01235 emit enableAction( "del", canDel > 0 ); 01236 emit enableAction( "properties", iCount > 0 && KPropertiesDialog::canDisplay( selectedFileItems() ) ); 01237 emit enableAction( "editMimeType", ( iCount == 1 ) ); 01238 emit enableAction( "rename", ( iCount == 1 ) && !bInTrash ); 01239 } 01240 01241 void KonqIconViewWidget::renameSelectedItem() 01242 { 01243 kdDebug(1203) << " -- KonqIconViewWidget::renameSelectedItem() -- " << endl; 01244 QIconViewItem * item = 0L; 01245 QIconViewItem *it = firstItem(); 01246 for (; it; it = it->nextItem() ) 01247 if ( it->isSelected() && !item ) 01248 { 01249 item = it; 01250 break; 01251 } 01252 if (!item) 01253 { 01254 Q_ASSERT(item); 01255 return; 01256 } 01257 item->rename(); 01258 } 01259 01260 void KonqIconViewWidget::cutSelection() 01261 { 01262 kdDebug(1203) << " -- KonqIconViewWidget::cutSelection() -- " << endl; 01263 KonqIconDrag * obj = konqDragObject( /* no parent ! */ ); 01264 obj->setMoveSelection( true ); 01265 QApplication::clipboard()->setData( obj ); 01266 } 01267 01268 void KonqIconViewWidget::copySelection() 01269 { 01270 kdDebug(1203) << " -- KonqIconViewWidget::copySelection() -- " << endl; 01271 KonqIconDrag * obj = konqDragObject( /* no parent ! */ ); 01272 QApplication::clipboard()->setData( obj ); 01273 } 01274 01275 void KonqIconViewWidget::pasteSelection() 01276 { 01277 paste( url() ); 01278 } 01279 01280 void KonqIconViewWidget::paste( const KURL &url ) 01281 { 01282 KonqOperations::doPaste( this, url ); 01283 } 01284 01285 KURL::List KonqIconViewWidget::selectedUrls() 01286 { 01287 KURL::List lstURLs; 01288 01289 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) 01290 if ( it->isSelected() ) 01291 lstURLs.append( (static_cast<KFileIVI *>( it ))->item()->url() ); 01292 return lstURLs; 01293 } 01294 01295 QRect KonqIconViewWidget::iconArea() const 01296 { 01297 return m_IconRect; 01298 } 01299 01300 void KonqIconViewWidget::setIconArea(const QRect &rect) 01301 { 01302 m_IconRect = rect; 01303 } 01304 01305 int KonqIconViewWidget::lineupMode() const 01306 { 01307 return m_LineupMode; 01308 } 01309 01310 void KonqIconViewWidget::setLineupMode(int mode) 01311 { 01312 m_LineupMode = mode; 01313 } 01314 01315 bool KonqIconViewWidget::sortDirectoriesFirst() const 01316 { 01317 return m_bSortDirsFirst; 01318 } 01319 01320 void KonqIconViewWidget::setSortDirectoriesFirst( bool b ) 01321 { 01322 m_bSortDirsFirst = b; 01323 } 01324 01325 void KonqIconViewWidget::contentsMouseMoveEvent( QMouseEvent *e ) 01326 { 01327 d->renameItem= false; 01328 QIconView::contentsMouseMoveEvent( e ); 01329 } 01330 01331 void KonqIconViewWidget::contentsDropEvent( QDropEvent * ev ) 01332 { 01333 QIconViewItem *i = findItem( ev->pos() ); 01334 // Short-circuit QIconView if Ctrl is pressed, so that it's possible 01335 // to drop a file into its own parent widget to copy it. 01336 if ( !i && (ev->action() == QDropEvent::Copy || ev->action() == QDropEvent::Link) 01337 && ev->source() && ev->source() == viewport()) 01338 { 01339 // First we need to call QIconView though, to clear the drag shape 01340 bool bMovable = itemsMovable(); 01341 setItemsMovable(false); // hack ? call it what you want :-) 01342 KIconView::contentsDropEvent( ev ); 01343 setItemsMovable(bMovable); 01344 01345 QValueList<QIconDragItem> lst; 01346 slotDropped(ev, lst); 01347 } 01348 else 01349 { 01350 KIconView::contentsDropEvent( ev ); 01351 emit dropped(); // What is this for ? (David) 01352 } 01353 // Don't do this here, it's too early ! 01354 // slotSaveIconPositions(); 01355 // If we want to save after the new file gets listed, though, 01356 // we could reimplement contentsDropEvent in KDIconView and set m_bNeedSave. Bah. 01357 } 01358 01359 void KonqIconViewWidget::doubleClickTimeout() 01360 { 01361 d->renameItem= true; 01362 mousePressChangeValue(); 01363 if ( d->releaseMouseEvent ) 01364 { 01365 QMouseEvent e( QEvent::MouseButtonPress,d->mousePos , 1, d->mouseState); 01366 QIconViewItem* item = findItem( e.pos() ); 01367 KURL url; 01368 if ( item ) 01369 { 01370 url= ( static_cast<KFileIVI *>( item ) )->item()->url(); 01371 bool brenameTrash =false; 01372 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath()))) 01373 brenameTrash = true; 01374 01375 if ( url.isLocalFile() && !brenameTrash && d->renameItem && m_pSettings->renameIconDirectly() && e.button() == LeftButton && item->textRect( false ).contains(e.pos())) 01376 { 01377 if( d->pActivateDoubleClick->isActive () ) 01378 d->pActivateDoubleClick->stop(); 01379 item->rename(); 01380 m_bMousePressed = false; 01381 } 01382 } 01383 } 01384 else 01385 { 01386 QMouseEvent e( QEvent::MouseMove,d->mousePos , 1, d->mouseState); 01387 KIconView::contentsMousePressEvent( &e ); 01388 } 01389 if( d->pActivateDoubleClick->isActive() ) 01390 d->pActivateDoubleClick->stop(); 01391 01392 d->releaseMouseEvent = false; 01393 d->renameItem= false; 01394 } 01395 01396 void KonqIconViewWidget::wheelEvent(QWheelEvent* e) 01397 { 01398 if (e->state() == ControlButton) 01399 { 01400 if (e->delta() >= 0) 01401 { 01402 emit incIconSize(); 01403 } 01404 else 01405 { 01406 emit decIconSize(); 01407 } 01408 e->accept(); 01409 return; 01410 } 01411 01412 KIconView::wheelEvent(e); 01413 } 01414 01415 void KonqIconViewWidget::mousePressChangeValue() 01416 { 01417 //kdDebug(1203) << "KonqIconViewWidget::contentsMousePressEvent" << endl; 01418 m_bMousePressed = true; 01419 if (d->pSoundPlayer) 01420 d->pSoundPlayer->stop(); 01421 d->bSoundItemClicked = true; 01422 d->firstClick = false; 01423 } 01424 01425 void KonqIconViewWidget::contentsMousePressEvent( QMouseEvent *e ) 01426 { 01427 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ()) 01428 d->pActivateDoubleClick->stop(); 01429 QIconViewItem* item = findItem( e->pos() ); 01430 m_mousePos = e->pos(); 01431 KURL url; 01432 if ( item ) 01433 { 01434 url = ( static_cast<KFileIVI *>( item ) )->item()->url(); 01435 bool brenameTrash =false; 01436 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath()))) 01437 brenameTrash = true; 01438 if ( !brenameTrash && !KGlobalSettings::singleClick() && m_pSettings->renameIconDirectly() && e->button() == LeftButton && item->textRect( false ).contains(e->pos())&& !d->firstClick && url.isLocalFile() && (!url.protocol().find("device", 0, false)==0)) 01439 { 01440 d->firstClick = true; 01441 d->mousePos = e->pos(); 01442 d->mouseState = e->state(); 01443 if (!d->pActivateDoubleClick) 01444 { 01445 d->pActivateDoubleClick = new QTimer(this); 01446 connect(d->pActivateDoubleClick, SIGNAL(timeout()), this, SLOT(doubleClickTimeout())); 01447 } 01448 if( d->pActivateDoubleClick->isActive () ) 01449 d->pActivateDoubleClick->stop(); 01450 else 01451 d->pActivateDoubleClick->start(QApplication::doubleClickInterval()); 01452 d->releaseMouseEvent = false; 01453 return; 01454 } 01455 else 01456 d->renameItem= false; 01457 } 01458 else 01459 d->renameItem= false; 01460 mousePressChangeValue(); 01461 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive()) 01462 d->pActivateDoubleClick->stop(); 01463 KIconView::contentsMousePressEvent( e ); 01464 01465 } 01466 01467 void KonqIconViewWidget::contentsMouseReleaseEvent( QMouseEvent *e ) 01468 { 01469 KIconView::contentsMouseReleaseEvent( e ); 01470 if(d->releaseMouseEvent && d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ()) 01471 d->pActivateDoubleClick->stop(); 01472 d->releaseMouseEvent = true; 01473 m_bMousePressed = false; 01474 } 01475 01476 void KonqIconViewWidget::slotSaveIconPositions() 01477 { 01478 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01479 // This code is currently not used but left in for compatibility reasons. 01480 // It can be removed in KDE 4.0 01481 // Saving of desktop icon positions is now done in KDIconView::saveIconPositions() 01482 // in kdebase/kdesktop/kdiconview.cc 01483 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01484 01485 if ( m_dotDirectoryPath.isEmpty() ) 01486 return; 01487 if ( !m_bDesktop ) 01488 return; // Currently not available in Konqueror 01489 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions" << endl; 01490 KSimpleConfig dotDirectory( m_dotDirectoryPath ); 01491 QIconViewItem *it = firstItem(); 01492 if ( !it ) 01493 return; // No more icons. Maybe we're closing and they've been removed already 01494 while ( it ) 01495 { 01496 KFileIVI *ivi = static_cast<KFileIVI *>( it ); 01497 KFileItem *item = ivi->item(); 01498 01499 dotDirectory.setGroup( QString( m_iconPositionGroupPrefix ).append( item->url().fileName() ) ); 01500 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions " << item->url().fileName() << " " << it->x() << " " << it->y() << endl; 01501 dotDirectory.writeEntry( QString( "X %1" ).arg( width() ), it->x() ); 01502 dotDirectory.writeEntry( QString( "Y %1" ).arg( height() ), it->y() ); 01503 dotDirectory.writeEntry( "Exists", true ); 01504 01505 it = it->nextItem(); 01506 } 01507 01508 QStringList groups = dotDirectory.groupList(); 01509 QStringList::ConstIterator gIt = groups.begin(); 01510 QStringList::ConstIterator gEnd = groups.end(); 01511 for (; gIt != gEnd; ++gIt ) 01512 if ( (*gIt).left( m_iconPositionGroupPrefix.length() ) == m_iconPositionGroupPrefix ) 01513 { 01514 dotDirectory.setGroup( *gIt ); 01515 if ( dotDirectory.hasKey( "Exists" ) ) 01516 dotDirectory.deleteEntry( "Exists", false ); 01517 else 01518 { 01519 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions deleting group " << *gIt << endl; 01520 dotDirectory.deleteGroup( *gIt ); 01521 } 01522 } 01523 01524 dotDirectory.sync(); 01525 01526 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01527 // This code is currently not used but left in for compatibility reasons. 01528 // It can be removed in KDE 4.0 01529 // Saving of desktop icon positions is now done in KDIconView::saveIconPositions() 01530 // in kdebase/kdesktop/kdiconview.cc 01531 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01532 } 01533 01534 // Adapted version of QIconView::insertInGrid, that works relative to 01535 // m_IconRect, instead of the entire viewport. 01536 01537 void KonqIconViewWidget::insertInGrid(QIconViewItem *item) 01538 { 01539 if (0L == item) 01540 return; 01541 01542 if (!m_IconRect.isValid()) 01543 { 01544 QIconView::insertInGrid(item); 01545 return; 01546 } 01547 01548 QRegion r(m_IconRect); 01549 QIconViewItem *i = firstItem(); 01550 int y = -1; 01551 for (; i; i = i->nextItem() ) 01552 { 01553 r = r.subtract(i->rect()); 01554 y = QMAX(y, i->y() + i->height()); 01555 } 01556 01557 QMemArray<QRect> rects = r.rects(); 01558 QMemArray<QRect>::Iterator it = rects.begin(); 01559 bool foundPlace = FALSE; 01560 for (; it != rects.end(); ++it) 01561 { 01562 QRect rect = *it; 01563 if (rect.width() >= item->width() && rect.height() >= item->height()) 01564 { 01565 int sx = 0, sy = 0; 01566 if (rect.width() >= item->width() + spacing()) 01567 sx = spacing(); 01568 if (rect.height() >= item->height() + spacing()) 01569 sy = spacing(); 01570 item->move(rect.x() + sx, rect.y() + sy); 01571 foundPlace = true; 01572 break; 01573 } 01574 } 01575 01576 if (!foundPlace) 01577 item->move(m_IconRect.topLeft()); 01578 01579 //item->dirty = false; 01580 return; 01581 } 01582 01583 01584 /* 01585 * Utility class QIVItemBin is used by KonqIconViewWidget::lineupIcons(). 01586 */ 01587 01588 class QIVItemBin 01589 { 01590 public: 01591 QIVItemBin() {} 01592 ~QIVItemBin() {} 01593 01594 int count() { return mData.count(); } 01595 void add(QIconViewItem *item) { mData.append(item); } 01596 01597 QIconViewItem *top(); 01598 QIconViewItem *bottom(); 01599 QIconViewItem *left(); 01600 QIconViewItem *right(); 01601 01602 private: 01603 QPtrList<QIconViewItem> mData; 01604 }; 01605 01606 QIconViewItem *QIVItemBin::top() 01607 { 01608 if (mData.count() == 0) 01609 return 0L; 01610 01611 QIconViewItem *it = mData.first(); 01612 QIconViewItem *item = it; 01613 int y = it->y(); 01614 for (it=mData.next(); it; it=mData.next()) 01615 { 01616 if (it->y() < y) 01617 { 01618 y = it->y(); 01619 item = it; 01620 } 01621 } 01622 mData.remove(item); 01623 return item; 01624 } 01625 01626 QIconViewItem *QIVItemBin::bottom() 01627 { 01628 if (mData.count() == 0) 01629 return 0L; 01630 01631 QIconViewItem *it = mData.first(); 01632 QIconViewItem *item = it; 01633 int y = it->y(); 01634 for (it=mData.next(); it; it=mData.next()) 01635 { 01636 if (it->y() > y) 01637 { 01638 y = it->y(); 01639 item = it; 01640 } 01641 } 01642 mData.remove(item); 01643 return item; 01644 } 01645 01646 QIconViewItem *QIVItemBin::left() 01647 { 01648 if (mData.count() == 0) 01649 return 0L; 01650 01651 QIconViewItem *it=mData.first(); 01652 QIconViewItem *item = it; 01653 int x = it->x(); 01654 for (it=mData.next(); it; it=mData.next()) 01655 { 01656 if (it->x() < x) 01657 { 01658 x = it->x(); 01659 item = it; 01660 } 01661 } 01662 mData.remove(item); 01663 return item; 01664 } 01665 01666 QIconViewItem *QIVItemBin::right() 01667 { 01668 if (mData.count() == 0) 01669 return 0L; 01670 01671 QIconViewItem *it=mData.first(); 01672 QIconViewItem *item = it; 01673 int x = it->x(); 01674 for (it=mData.next(); it; it=mData.next()) 01675 { 01676 if (it->x() > x) 01677 { 01678 x = it->x(); 01679 item = it; 01680 } 01681 } 01682 mData.remove(item); 01683 return item; 01684 } 01685 01686 01687 /* 01688 * The algorithm used for lineing up the icons could be called 01689 * "beating flat the icon field". Imagine the icon field to be some height 01690 * field on a regular grid, with the height being the number of icons in 01691 * each grid element. Now imagine slamming on the field with a shovel or 01692 * some other flat surface. The high peaks will be flattened and spread out 01693 * over their adjacent areas. This is basically what the algorithm tries to 01694 * simulate. 01695 * 01696 * First, the icons are binned to a grid of the desired size. If all bins 01697 * are containing at most one icon, we're done, of course. We just have to 01698 * move all icons to the center of each grid element. 01699 * For each bin which has more than one icon in it, we calculate 4 01700 * "friction coefficients", one for each cardinal direction. The friction 01701 * coefficient of a direction is the number of icons adjacent in that 01702 * direction. The idea is that this number is somewhat a measure in which 01703 * direction the icons should flow: icons flow in the direction of lowest 01704 * friction coefficient. We move a maximum of one icon per bin and loop over 01705 * all bins. This procedure is repeated some maximum number of times or until 01706 * no icons are moved anymore. 01707 * 01708 * I don't know if this algorithm is good or bad, I don't even know if it will 01709 * work all the time. It seems a correct thing to do, however, and it seems to 01710 * work particularly well. In any case, the number of runs is limited so there 01711 * can be no races. 01712 */ 01713 01714 #define MIN3(a,b,c) (kMin((a),(kMin((b),(c))))) 01715 01716 void KonqIconViewWidget::lineupIcons() 01717 { 01718 if ( !firstItem() ) 01719 { 01720 kdDebug(1203) << "No icons at all ?\n"; 01721 return; 01722 } 01723 01724 // Make a list of items, and look at the highest one 01725 QValueList<QIconViewItem*> items; 01726 int dy = 0; 01727 01728 // Put each ivi in its corresponding bin. 01729 QIconViewItem *item; 01730 for (item=firstItem(); item; item=item->nextItem()) 01731 { 01732 items.append(item); 01733 dy = QMAX( dy, item->height() ); 01734 } 01735 01736 // For dx, use what used to be the gridX 01737 int dx = gridXValue(); 01738 01739 dx += spacing(); 01740 dy += spacing(); 01741 01742 kdDebug(1203) << "dx = " << dx << ", dy = " << dy << "\n"; 01743 01744 if ((dx < 15) || (dy < 15)) 01745 { 01746 kdWarning(1203) << "Do you really have that fine a grid?\n"; 01747 return; 01748 } 01749 01750 int x1, x2, y1, y2; 01751 if (m_IconRect.isValid()) 01752 { 01753 x1 = m_IconRect.left(); x2 = m_IconRect.right(); 01754 y1 = m_IconRect.top(); y2 = m_IconRect.bottom(); 01755 } else 01756 { 01757 x1 = 0; x2 = viewport()->width(); 01758 y1 = 0; y2 = viewport()->height(); 01759 } 01760 01761 int nx = (x2 - x1) / dx; 01762 int ny = (y2 - y1) / dy; 01763 01764 kdDebug(1203) << "nx = " << nx << " ny = " << ny << "\n"; 01765 if ((nx > 150) || (ny > 100)) 01766 { 01767 kdDebug(1203) << "Do you really have that fine a grid?\n"; 01768 return; 01769 } 01770 if ((nx <= 1) || (ny <= 1)) 01771 { 01772 kdDebug(1203) << "Iconview is too small, not doing anything.\n"; 01773 return; 01774 } 01775 01776 // Create a grid of (ny x nx) bins. 01777 typedef QIVItemBin *QIVItemPtr; 01778 QIVItemPtr **bins = new QIVItemPtr*[ny]; 01779 01780 int i, j; 01781 for (j=0; j<ny; j++) 01782 { 01783 bins[j] = new QIVItemPtr[nx]; 01784 for (i=0; i<nx; i++) 01785 bins[j][i] = 0; 01786 } 01787 01788 int left = x1; 01789 int right = x1 + dx; 01790 i = 0; 01791 01792 while (items.count()) 01793 { 01794 int max_icon_x = dx; 01795 right = left + dx; 01796 01797 for (QValueList<QIconViewItem*>::Iterator it = items.begin(); it != items.end(); ++it) 01798 { 01799 item = *it; 01800 if (item->x() < right && max_icon_x < item->width() ) 01801 max_icon_x = item->width(); 01802 } 01803 01804 right = left + max_icon_x; 01805 01806 for (QValueList<QIconViewItem*>::Iterator it = items.begin(); it != items.end();) 01807 { 01808 item = *it; 01809 int mid = item->x() + item->width()/2 - x1; 01810 kdDebug(1203) << "matching " << mid << " left " << left << " right " << right << endl; 01811 if (mid < left || (mid >= left && mid < right)) { 01812 it = items.remove(it); 01813 j = (item->y() + item->height()/2 - y1) / dy; 01814 if (j < 0) j = 0; 01815 else if (j >= ny) j = ny - 1; 01816 01817 kdDebug(1203) << "putting " << item->text() << " " << i << " " << j << endl; 01818 if (bins[j][i] == 0L) 01819 bins[j][i] = new QIVItemBin; 01820 bins[j][i]->add(item); 01821 } else 01822 ++it; 01823 } 01824 kdDebug(1203) << "next round " << items.count() << endl; 01825 i = QMIN(i+1, nx - 1); 01826 left += max_icon_x + spacing(); 01827 } 01828 01829 // The shuffle code 01830 int n, k; 01831 int infinity = 100000, nmoves = 1; 01832 for (n=0; (n < 10) && (nmoves != 0); n++) 01833 { 01834 nmoves = 0; 01835 for (j=0; j<ny; j++) 01836 { 01837 for (i=0; i<nx; i++) 01838 { 01839 if (!bins[j][i] || (bins[j][i]->count() < 2)) 01840 continue; 01841 01842 kdDebug(1203) << "calc for " << i << " " << j << endl; 01843 // Calculate the 4 "friction coefficients". 01844 int tf = 0; 01845 for (k=j-1; (k >= 0) && bins[k][i] && bins[k][i]->count(); k--) 01846 tf += bins[k][i]->count(); 01847 if (k == -1) 01848 tf += infinity; 01849 01850 int bf = 0; 01851 for (k=j+1; (k < ny) && bins[k][i] && bins[k][i]->count(); k++) 01852 bf += bins[k][i]->count(); 01853 if (k == ny) 01854 bf += infinity; 01855 01856 int lf = 0; 01857 for (k=i-1; (k >= 0) && bins[j][k] && bins[j][k]->count(); k--) 01858 lf += bins[j][k]->count(); 01859 if (k == -1) 01860 lf += infinity; 01861 01862 int rf = 0; 01863 for (k=i+1; (k < nx) && bins[j][k] && bins[j][k]->count(); k++) 01864 rf += bins[j][k]->count(); 01865 if (k == nx) 01866 rf += infinity; 01867 01868 // If we are stuck between walls, continue 01869 if ( (tf >= infinity) && (bf >= infinity) && 01870 (lf >= infinity) && (rf >= infinity) 01871 ) 01872 continue; 01873 01874 // Is there a preferred lineup direction? 01875 if (m_LineupMode == LineupHorizontal) 01876 { 01877 tf += infinity; 01878 bf += infinity; 01879 } else if (m_LineupMode == LineupVertical) 01880 { 01881 lf += infinity; 01882 rf += infinity; 01883 } 01884 01885 // Move one item in the direction of the least friction. 01886 if (tf <= MIN3(bf,lf,rf)) 01887 { 01888 if (!bins[j-1][i]) 01889 bins[j-1][i] = new QIVItemBin; 01890 bins[j-1][i]->add(bins[j][i]->top()); 01891 } else if (bf <= MIN3(tf,lf,rf)) 01892 { 01893 if (!bins[j+1][i]) 01894 bins[j+1][i] = new QIVItemBin; 01895 bins[j+1][i]->add(bins[j][i]->bottom()); 01896 } else if (lf <= MIN3(tf,bf,rf)) 01897 { 01898 if (!bins[j][i-1]) 01899 bins[j][i-1] = new QIVItemBin; 01900 bins[j][i-1]->add(bins[j][i]->left()); 01901 } else 01902 { 01903 if (!bins[j][i+1]) 01904 bins[j][i+1] = new QIVItemBin; 01905 bins[j][i+1]->add(bins[j][i]->right()); 01906 } 01907 01908 nmoves++; 01909 } 01910 } 01911 kdDebug(1203) << "nmoves = " << nmoves << "\n"; 01912 } 01913 01914 // Perform the actual moving 01915 n = 0; 01916 QIconViewItem **its = new QIconViewItem*[ny]; 01917 for (i=0; i<nx; i++) 01918 { 01919 int max_icon_x = dx; 01920 for (j=0; j<ny; j++) 01921 { 01922 its[j] = 0; 01923 if (!bins[j][i] || !bins[j][i]->count()) 01924 continue; 01925 01926 item = its[j] = bins[j][i]->top(); 01927 if ( max_icon_x < item->width() ) 01928 max_icon_x = item->width(); 01929 } 01930 01931 for (j=0; j<ny; j++) 01932 { 01933 if ( its[j] == 0 ) 01934 continue; 01935 01936 item = its[j]; 01937 int x = x1 + spacing() + ( max_icon_x - item->width() )/2; 01938 int y = y1 + j * dy; 01939 if (item->pos() != QPoint(x, y)) 01940 { 01941 kdDebug(1203) << "moving " << item->text() << " " << x << " " << y << endl; 01942 item->move(x, y); 01943 } 01944 if (bins[j][i]->count()) 01945 { 01946 kdDebug(1203) << "Lineup incomplete..\n"; 01947 item = bins[j][i]->top(); 01948 for (k=1; item; k++) 01949 { 01950 x = x1 + i*dx + spacing() + 10*k; y = y1 + j*dy + spacing() + 5*k; 01951 if (item->pos() != QPoint(x, y)) 01952 { 01953 item->move(x, y); 01954 } 01955 item = bins[j][i]->top(); 01956 } 01957 } 01958 delete bins[j][i]; 01959 bins[j][i] = 0; 01960 n++; 01961 } 01962 x1 += max_icon_x + spacing(); 01963 } 01964 delete[] its; 01965 01966 updateContents(); 01967 for (int j=0; j<ny; j++) 01968 delete [] bins[j]; 01969 delete[] bins; 01970 kdDebug(1203) << n << " icons successfully moved.\n"; 01971 return; 01972 } 01973 01974 void KonqIconViewWidget::visualActivate(QIconViewItem * item) 01975 { 01976 // Rect of the QIconViewItem. 01977 QRect irect = item->rect(); 01978 01979 // Rect of the QIconViewItem's pixmap area. 01980 QRect rect = item->pixmapRect(); 01981 01982 // Adjust to correct position. If this isn't done, the fact that the 01983 // text may be wider than the pixmap puts us off-centre. 01984 rect.moveBy(irect.x(), irect.y()); 01985 01986 // Adjust for scrolling (David) 01987 rect.moveBy( -contentsX(), -contentsY() ); 01988 01989 KIconEffect::visualActivate(viewport(), rect); 01990 } 01991 01992 void KonqIconViewWidget::backgroundPixmapChange( const QPixmap & ) 01993 { 01994 viewport()->update(); 01995 } 01996 01997 void KonqIconViewWidget::setPreviewSettings( const QStringList& settings ) 01998 { 01999 d->previewSettings = settings; 02000 } 02001 02002 const QStringList& KonqIconViewWidget::previewSettings() 02003 { 02004 return d->previewSettings; 02005 } 02006 02007 void KonqIconViewWidget::setNewURL( const QString& url ) 02008 { 02009 KURL u; 02010 if ( url.startsWith( "/" ) ) 02011 u.setPath( url ); 02012 else 02013 u = url; 02014 setURL( u ); 02015 } 02016 02017 void KonqIconViewWidget::setCaseInsensitiveSort( bool b ) 02018 { 02019 d->bCaseInsensitive = b; 02020 } 02021 02022 bool KonqIconViewWidget::caseInsensitiveSort() const 02023 { 02024 return d->bCaseInsensitive; 02025 } 02026 02027 #include "konq_iconviewwidget.moc" 02028 02029 /* vim: set et sw=4 ts=8 softtabstop=4: */
KDE Logo
This file is part of the documentation for libkonq Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 16 15:59:26 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003