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 Apr 29 21:20:28 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003