kio Library API Documentation

kfileiconview.cpp

00001 // -*- c++ -*-
00002 /* This file is part of the KDE libraries
00003    Copyright (C) 1997 Stephan Kulow <coolo@kde.org>
00004                  2000,2001,2002 Carsten Pfeiffer <pfeiffer@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.   If not, write to
00018    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, USA.
00020 */
00021 
00022 #include <qfontmetrics.h>
00023 #include <qkeycode.h>
00024 #include <qlabel.h>
00025 #include <qpainter.h>
00026 #include <qpixmap.h>
00027 #include <qregexp.h>
00028 #include <qtimer.h>
00029 #include <qtooltip.h>
00030 
00031 #include <kaction.h>
00032 #include <kapplication.h>
00033 #include <klocale.h>
00034 #include <kfileitem.h>
00035 #include <kiconeffect.h>
00036 #include <kglobalsettings.h>
00037 #include <kurldrag.h>
00038 #include <kio/previewjob.h>
00039 
00040 #include "kfileiconview.h"
00041 #include "config-kfile.h"
00042 
00043 KFileIconViewItem::~KFileIconViewItem()
00044 {
00045     fileInfo()->removeExtraData( iconView() );
00046 }
00047 
00048 class KFileIconView::KFileIconViewPrivate
00049 {
00050 public:
00051     KFileIconViewPrivate( KFileIconView *parent ) {
00052         previewIconSize = 60;
00053         job = 0;
00054         dropItem = 0;
00055 
00056         noArrangement = false;
00057     smallColumns = new KRadioAction( i18n("Small Icons"), 0, parent,
00058                      SLOT( slotSmallColumns() ),
00059                      parent->actionCollection(),
00060                      "small columns" );
00061 
00062     largeRows = new KRadioAction( i18n("Large Icons"), 0, parent,
00063                       SLOT( slotLargeRows() ),
00064                       parent->actionCollection(),
00065                       "large rows" );
00066 
00067     smallColumns->setExclusiveGroup(QString::fromLatin1("IconView mode"));
00068     largeRows->setExclusiveGroup(QString::fromLatin1("IconView mode"));
00069 
00070         previews = new KToggleAction( i18n("Thumbnail Previews"), 0,
00071                                       parent->actionCollection(),
00072                                       "show previews" );
00073         zoomIn = KStdAction::zoomIn( parent, SLOT( zoomIn() ),
00074                                      parent->actionCollection(), "zoomIn" );
00075         zoomOut = KStdAction::zoomOut( parent, SLOT( zoomOut() ),
00076                                      parent->actionCollection(), "zoomOut" );
00077 
00078         previews->setGroup("previews");
00079         zoomIn->setGroup("previews");
00080         zoomOut->setGroup("previews");
00081 
00082         connect( previews, SIGNAL( toggled( bool )),
00083                  parent, SLOT( slotPreviewsToggled( bool )));
00084 
00085         connect( &previewTimer, SIGNAL( timeout() ),
00086                  parent, SLOT( showPreviews() ));
00087         connect( &autoOpenTimer, SIGNAL( timeout() ),
00088                  parent, SLOT( slotAutoOpen() ));
00089     }
00090 
00091     ~KFileIconViewPrivate() {
00092         if ( job )
00093             job->kill();
00094     }
00095 
00096     KRadioAction *smallColumns, *largeRows;
00097     KAction *zoomIn, *zoomOut;
00098     KToggleAction *previews;
00099     KIO::PreviewJob *job;
00100     KFileIconViewItem *dropItem;
00101     QTimer previewTimer;
00102     QTimer autoOpenTimer;
00103     QStringList previewMimeTypes;
00104     int previewIconSize;
00105     bool noArrangement :1;
00106 };
00107 
00108 KFileIconView::KFileIconView(QWidget *parent, const char *name)
00109     : KIconView(parent, name), KFileView()
00110 {
00111     d = new KFileIconViewPrivate( this );
00112 
00113     setViewName( i18n("Icon View") );
00114 
00115     toolTip = 0;
00116     setResizeMode( Adjust );
00117     setMaxItemWidth( 300 );
00118     setWordWrapIconText( false );
00119     setArrangement( TopToBottom );
00120     setAutoArrange( true );
00121     setItemsMovable( false );
00122     setMode( KIconView::Select );
00123     KIconView::setSorting( true );
00124     // as long as QIconView only shows tooltips when the cursor is over the
00125     // icon (and not the text), we have to create our own tooltips
00126     setShowToolTips( false );
00127     slotSmallColumns();
00128     d->smallColumns->setChecked( true );
00129 
00130     connect( this, SIGNAL( returnPressed(QIconViewItem *) ),
00131          SLOT( slotActivate( QIconViewItem *) ) );
00132 
00133     // we want single click _and_ double click (as convenience)
00134     connect( this, SIGNAL( clicked(QIconViewItem *, const QPoint&) ),
00135          SLOT( selected( QIconViewItem *) ) );
00136     connect( this, SIGNAL( doubleClicked(QIconViewItem *, const QPoint&) ),
00137          SLOT( slotActivate( QIconViewItem *) ) );
00138 
00139     connect( this, SIGNAL( onItem( QIconViewItem * ) ),
00140          SLOT( showToolTip( QIconViewItem * ) ) );
00141     connect( this, SIGNAL( onViewport() ),
00142          SLOT( removeToolTip() ) );
00143     connect( this, SIGNAL( contextMenuRequested(QIconViewItem*,const QPoint&)),
00144          SLOT( slotActivateMenu( QIconViewItem*, const QPoint& ) ) );
00145 
00146     KFile::SelectionMode sm = KFileView::selectionMode();
00147     switch ( sm ) {
00148     case KFile::Multi:
00149     QIconView::setSelectionMode( QIconView::Multi );
00150     break;
00151     case KFile::Extended:
00152     QIconView::setSelectionMode( QIconView::Extended );
00153     break;
00154     case KFile::NoSelection:
00155     QIconView::setSelectionMode( QIconView::NoSelection );
00156     break;
00157     default: // fall through
00158     case KFile::Single:
00159     QIconView::setSelectionMode( QIconView::Single );
00160     break;
00161     }
00162 
00163     if ( sm == KFile::Multi || sm == KFile::Extended )
00164     connect( this, SIGNAL( selectionChanged() ),
00165          SLOT( slotSelectionChanged() ));
00166     else
00167     connect( this, SIGNAL( selectionChanged( QIconViewItem * )),
00168          SLOT( highlighted( QIconViewItem * )));
00169 
00170     viewport()->installEventFilter( this );
00171 
00172     // for mimetype resolving
00173     m_resolver = new KMimeTypeResolver<KFileIconViewItem,KFileIconView>(this);
00174 }
00175 
00176 KFileIconView::~KFileIconView()
00177 {
00178     delete m_resolver;
00179     removeToolTip();
00180     delete d;
00181 }
00182 
00183 void KFileIconView::readConfig( KConfig *kc, const QString& group )
00184 {
00185     QString gr = group.isEmpty() ? QString("KFileIconView") : group;
00186     KConfigGroupSaver cs( kc, gr );
00187     QString small = QString::fromLatin1("SmallColumns");
00188     d->previewIconSize = kc->readNumEntry( "Preview Size", 60 );
00189     d->previews->setChecked( kc->readBoolEntry( "ShowPreviews", false ) );
00190 
00191     if ( kc->readEntry("ViewMode", small ) == small ) {
00192     d->smallColumns->setChecked( true );
00193     slotSmallColumns();
00194     }
00195     else {
00196     d->largeRows->setChecked( true );
00197     slotLargeRows();
00198     }
00199 
00200     if ( d->previews->isChecked() )
00201         showPreviews();
00202 }
00203 
00204 void KFileIconView::writeConfig( KConfig *kc, const QString& group )
00205 {
00206     QString gr = group.isEmpty() ? QString("KFileIconView") : group;
00207     KConfigGroupSaver cs( kc, gr );
00208     kc->writeEntry( "ViewMode", d->smallColumns->isChecked() ?
00209             QString::fromLatin1("SmallColumns") :
00210             QString::fromLatin1("LargeRows") );
00211     kc->writeEntry( "Preview Size", d->previewIconSize );
00212     kc->writeEntry( "ShowPreviews", d->previews->isChecked() );
00213 }
00214 
00215 void KFileIconView::removeToolTip()
00216 {
00217     delete toolTip;
00218     toolTip = 0;
00219 }
00220 
00221 void KFileIconView::showToolTip( QIconViewItem *item )
00222 {
00223     delete toolTip;
00224     toolTip = 0;
00225 
00226     if ( !item )
00227     return;
00228 
00229     int w = maxItemWidth() - ( itemTextPos() == QIconView::Bottom ? 0 :
00230                    item->pixmapRect().width() ) - 4;
00231     if ( fontMetrics().width( item->text() ) >= w ) {
00232     toolTip = new QLabel( QString::fromLatin1(" %1 ").arg(item->text()), 0,
00233                   "myToolTip",
00234                   WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM );
00235     toolTip->setFrameStyle( QFrame::Plain | QFrame::Box );
00236     toolTip->setLineWidth( 1 );
00237     toolTip->setAlignment( AlignLeft | AlignTop );
00238     toolTip->move( QCursor::pos() + QPoint( 14, 14 ) );
00239     toolTip->adjustSize();
00240     QRect screen = QApplication::desktop()->screenGeometry(
00241             QApplication::desktop()->screenNumber(QCursor::pos()));
00242     if (toolTip->x()+toolTip->width() > screen.right()) {
00243         toolTip->move(toolTip->x()+screen.right()-toolTip->x()-toolTip->width(), toolTip->y());
00244     }
00245     if (toolTip->y()+toolTip->height() > screen.bottom()) {
00246         toolTip->move(toolTip->x(), screen.bottom()-toolTip->y()-toolTip->height()+toolTip->y());
00247     }
00248     toolTip->setFont( QToolTip::font() );
00249     toolTip->setPalette( QToolTip::palette(), true );
00250     toolTip->show();
00251     }
00252 }
00253 
00254 void KFileIconView::slotActivateMenu( QIconViewItem* item, const QPoint& pos )
00255 {
00256     if ( !item ) {
00257     sig->activateMenu( 0, pos );
00258     return;
00259     }
00260     KFileIconViewItem *i = (KFileIconViewItem*) item;
00261     sig->activateMenu( i->fileInfo(), pos );
00262 }
00263 
00264 void KFileIconView::hideEvent( QHideEvent *e )
00265 {
00266     removeToolTip();
00267     KIconView::hideEvent( e );
00268 }
00269 
00270 void KFileIconView::keyPressEvent( QKeyEvent *e )
00271 {
00272     KIconView::keyPressEvent( e );
00273 
00274     // ignore Ctrl-Return so that the dialog can catch it.
00275     if ( (e->state() & ControlButton) &&
00276          (e->key() == Key_Return || e->key() == Key_Enter) )
00277         e->ignore();
00278 }
00279 
00280 void KFileIconView::setSelected( const KFileItem *info, bool enable )
00281 {
00282     KFileIconViewItem *item = viewItem( info );
00283     if ( item )
00284         KIconView::setSelected( item, enable, true );
00285 }
00286 
00287 void KFileIconView::selectAll()
00288 {
00289     if (KFileView::selectionMode() == KFile::NoSelection ||
00290         KFileView::selectionMode() == KFile::Single)
00291     return;
00292 
00293     KIconView::selectAll( true );
00294 }
00295 
00296 void KFileIconView::clearSelection()
00297 {
00298     KIconView::clearSelection();
00299 }
00300 
00301 void KFileIconView::invertSelection()
00302 {
00303     KIconView::invertSelection();
00304 }
00305 
00306 void KFileIconView::clearView()
00307 {
00308     m_resolver->m_lstPendingMimeIconItems.clear();
00309 
00310     KIconView::clear();
00311     stopPreview();
00312 }
00313 
00314 void KFileIconView::insertItem( KFileItem *i )
00315 {
00316     KFileView::insertItem( i );
00317 
00318     QIconView* qview = static_cast<QIconView*>( this );
00319     // Since creating and initializing an item leads to a repaint, 
00320     // we disable updates on the IconView for a while.
00321     qview->setUpdatesEnabled( false );
00322     KFileIconViewItem *item = new KFileIconViewItem( qview, i );
00323     initItem( item, i, true );
00324     qview->setUpdatesEnabled( true );
00325 
00326     if ( !i->isMimeTypeKnown() )
00327         m_resolver->m_lstPendingMimeIconItems.append( item );
00328 
00329     i->setExtraData( this, item );
00330 }
00331 
00332 void KFileIconView::slotActivate( QIconViewItem *item )
00333 {
00334     if ( !item )
00335     return;
00336     const KFileItem *fi = ( (KFileIconViewItem*)item )->fileInfo();
00337     if ( fi )
00338     sig->activate( fi );
00339 }
00340 
00341 void KFileIconView::selected( QIconViewItem *item )
00342 {
00343     if ( !item || (KApplication::keyboardModifiers() & (KApplication::ShiftModifier | KApplication::ControlModifier)) != 0 )
00344     return;
00345 
00346     if ( KGlobalSettings::singleClick() ) {
00347     const KFileItem *fi = ( (KFileIconViewItem*)item )->fileInfo();
00348     if ( fi && (fi->isDir() || !onlyDoubleClickSelectsFiles()) )
00349         sig->activate( fi );
00350     }
00351 }
00352 
00353 void KFileIconView::setCurrentItem( const KFileItem *item )
00354 {
00355     KFileIconViewItem *it = viewItem( item );
00356     if ( it )
00357         KIconView::setCurrentItem( it );
00358 }
00359 
00360 KFileItem * KFileIconView::currentFileItem() const
00361 {
00362     KFileIconViewItem *current = static_cast<KFileIconViewItem*>( currentItem() );
00363     if ( current )
00364         return current->fileInfo();
00365 
00366     return 0L;
00367 }
00368 
00369 void KFileIconView::highlighted( QIconViewItem *item )
00370 {
00371     if ( !item )
00372     return;
00373     const KFileItem *fi = ( (KFileIconViewItem*)item )->fileInfo();
00374     if ( fi )
00375     sig->highlightFile( fi );
00376 }
00377 
00378 void KFileIconView::setSelectionMode( KFile::SelectionMode sm )
00379 {
00380     disconnect( SIGNAL( selectionChanged() ), this );
00381     disconnect( SIGNAL( selectionChanged( QIconViewItem * )), this );
00382 
00383     KFileView::setSelectionMode( sm );
00384     switch ( KFileView::selectionMode() ) {
00385     case KFile::Multi:
00386     QIconView::setSelectionMode( QIconView::Multi );
00387     break;
00388     case KFile::Extended:
00389     QIconView::setSelectionMode( QIconView::Extended );
00390     break;
00391     case KFile::NoSelection:
00392     QIconView::setSelectionMode( QIconView::NoSelection );
00393     break;
00394     default: // fall through
00395     case KFile::Single:
00396     QIconView::setSelectionMode( QIconView::Single );
00397     break;
00398     }
00399 
00400     if ( sm == KFile::Multi || sm == KFile::Extended )
00401     connect( this, SIGNAL( selectionChanged() ),
00402          SLOT( slotSelectionChanged() ));
00403     else
00404     connect( this, SIGNAL( selectionChanged( QIconViewItem * )),
00405          SLOT( highlighted( QIconViewItem * )));
00406 }
00407 
00408 bool KFileIconView::isSelected( const KFileItem *i ) const
00409 {
00410     KFileIconViewItem *item = viewItem( i );
00411     return (item && item->isSelected());
00412 }
00413 
00414 void KFileIconView::updateView( bool b )
00415 {
00416     if ( !b )
00417         return; // eh?
00418 
00419     KFileIconViewItem *item = static_cast<KFileIconViewItem*>(QIconView::firstItem());
00420     if ( item ) {
00421         do {
00422             if ( d->previews->isChecked() ) {
00423                 if ( canPreview( item->fileInfo() ) )
00424                     item->setPixmapSize( QSize( d->previewIconSize, d->previewIconSize ) );
00425             }
00426             else {
00427                 // unset pixmap size (used for previews)
00428                 if ( !item->pixmapSize().isNull() )
00429                     item->setPixmapSize( QSize( 0, 0 ) );
00430             }
00431             // recalculate item parameters but avoid an in-place repaint
00432             item->setPixmap( (item->fileInfo())->pixmap( myIconSize ), true, false );
00433             item = static_cast<KFileIconViewItem *>(item->nextItem());
00434         } while ( item != 0L );
00435     }
00436 }
00437 
00438 void KFileIconView::updateView( const KFileItem *i )
00439 {
00440     KFileIconViewItem *item = viewItem( i );
00441     if ( item )
00442         initItem( item, i, true );
00443 }
00444 
00445 void KFileIconView::removeItem( const KFileItem *i )
00446 {
00447     if ( !i )
00448     return;
00449 
00450     KFileIconViewItem *item = viewItem( i );
00451     m_resolver->m_lstPendingMimeIconItems.remove( item );
00452     delete item;
00453 
00454     KFileView::removeItem( i );
00455 }
00456 
00457 void KFileIconView::setIconSize( int size )
00458 {
00459     myIconSize = size;
00460     updateIcons();
00461 }
00462 
00463 void KFileIconView::setPreviewSize( int size )
00464 {
00465     if ( size < 30 )
00466         size = 30; // minimum
00467 
00468     d->previewIconSize = size;
00469     if ( d->previews->isChecked() )
00470         showPreviews();
00471 }
00472 
00473 void KFileIconView::updateIcons()
00474 {
00475     updateView( true );
00476     arrangeItemsInGrid();
00477 }
00478 
00479 void KFileIconView::ensureItemVisible( const KFileItem *i )
00480 {
00481     KFileIconViewItem *item = viewItem( i );
00482     if ( item )
00483     KIconView::ensureItemVisible( item );
00484 }
00485 
00486 void KFileIconView::slotSelectionChanged()
00487 {
00488     sig->highlightFile( 0L );
00489 }
00490 
00491 void KFileIconView::slotSmallColumns()
00492 {
00493     // setItemTextPos(), setArrangement(), setWordWrapIconText() and
00494     // setIconSize() all call arrangeItemsInGrid() :( Prevent this.
00495     d->noArrangement = true; // stop arrangeItemsInGrid()!
00496 
00497     // Make sure to uncheck previews if selected
00498     if ( d->previews->isChecked() )
00499     {
00500         stopPreview();
00501         d->previews->setChecked( false );
00502     }
00503     setGridX( -1 );
00504     setMaxItemWidth( 300 );
00505     setItemTextPos( Right );
00506     setArrangement( TopToBottom );
00507     setWordWrapIconText( false );
00508     setSpacing( 0 );
00509 
00510     d->noArrangement = false; // now we can arrange
00511     setIconSize( KIcon::SizeSmall );
00512 }
00513 
00514 void KFileIconView::slotLargeRows()
00515 {
00516     // setItemTextPos(), setArrangement(), setWordWrapIconText() and
00517     // setIconSize() all call arrangeItemsInGrid() :( Prevent this.
00518     d->noArrangement = true; // stop arrangeItemsInGrid()!
00519 
00520     setGridX( KGlobal::iconLoader()->currentSize( KIcon::Desktop ) + 50 );
00521     setItemTextPos( Bottom );
00522     setArrangement( LeftToRight );
00523     setWordWrapIconText( true );
00524     setSpacing( 5 ); // default in QIconView
00525 
00526     d->noArrangement = false; // now we can arrange
00527     setIconSize( KIcon::SizeMedium );
00528 }
00529 
00530 void KFileIconView::stopPreview()
00531 {
00532     if ( d->job ) {
00533         d->job->kill();
00534         d->job = 0L;
00535     }
00536 }
00537 
00538 void KFileIconView::slotPreviewsToggled( bool on )
00539 {
00540     if ( on )
00541         showPreviews();
00542     else {
00543         stopPreview();
00544         slotLargeRows();
00545     }
00546 }
00547 
00548 void KFileIconView::showPreviews()
00549 {
00550     if ( d->previewMimeTypes.isEmpty() )
00551         d->previewMimeTypes = KIO::PreviewJob::supportedMimeTypes();
00552 
00553     stopPreview();
00554     d->previews->setChecked( true );
00555 
00556     if ( !d->largeRows->isChecked() ) {
00557         d->largeRows->setChecked( true );
00558         slotLargeRows(); // also sets the icon size and updates the grid
00559     }
00560     else {
00561         updateIcons();
00562     }
00563 
00564     d->job = KIO::filePreview(*items(), d->previewIconSize,d->previewIconSize);
00565 
00566     connect( d->job, SIGNAL( result( KIO::Job * )),
00567              this, SLOT( slotPreviewResult( KIO::Job * )));
00568     connect( d->job, SIGNAL( gotPreview( const KFileItem*, const QPixmap& )),
00569              SLOT( gotPreview( const KFileItem*, const QPixmap& ) ));
00570 //     connect( d->job, SIGNAL( failed( const KFileItem* )),
00571 //              this, SLOT( slotFailed( const KFileItem* ) ));
00572 }
00573 
00574 void KFileIconView::slotPreviewResult( KIO::Job *job )
00575 {
00576     if ( job == d->job )
00577         d->job = 0L;
00578 }
00579 
00580 void KFileIconView::gotPreview( const KFileItem *item, const QPixmap& pix )
00581 {
00582     KFileIconViewItem *it = viewItem( item );
00583     if ( it )
00584         if( item->overlays() & KIcon::HiddenOverlay )
00585         {
00586             QPixmap p( pix );
00587 
00588             KIconEffect::semiTransparent( p );
00589             it->setPixmap( p );
00590         }
00591         else
00592             it->setPixmap( pix );
00593 }
00594 
00595 bool KFileIconView::canPreview( const KFileItem *item ) const
00596 {
00597     QStringList::Iterator it = d->previewMimeTypes.begin();
00598     QRegExp r;
00599     r.setWildcard( true );
00600 
00601     for ( ; it != d->previewMimeTypes.end(); ++it ) {
00602         QString type = *it;
00603         // the "mimetype" can be "image/*"
00604         if ( type.at( type.length() - 1 ) == '*' ) {
00605             r.setPattern( type );
00606             if ( r.search( item->mimetype() ) != -1 )
00607                 return true;
00608         }
00609         else
00610             if ( item->mimetype() == type )
00611                 return true;
00612     }
00613 
00614     return false;
00615 }
00616 
00617 KFileItem * KFileIconView::firstFileItem() const
00618 {
00619     KFileIconViewItem *item = static_cast<KFileIconViewItem*>( firstItem() );
00620     if ( item )
00621         return item->fileInfo();
00622     return 0L;
00623 }
00624 
00625 KFileItem * KFileIconView::nextItem( const KFileItem *fileItem ) const
00626 {
00627     if ( fileItem ) {
00628         KFileIconViewItem *item = viewItem( fileItem );
00629         if ( item && item->nextItem() )
00630             return ((KFileIconViewItem*) item->nextItem())->fileInfo();
00631     }
00632     return 0L;
00633 }
00634 
00635 KFileItem * KFileIconView::prevItem( const KFileItem *fileItem ) const
00636 {
00637     if ( fileItem ) {
00638         KFileIconViewItem *item = viewItem( fileItem );
00639         if ( item && item->prevItem() )
00640             return ((KFileIconViewItem*) item->prevItem())->fileInfo();
00641     }
00642     return 0L;
00643 }
00644 
00645 void KFileIconView::setSorting( QDir::SortSpec spec )
00646 {
00647     KFileView::setSorting( spec );
00648     KFileItemListIterator it( *items() );
00649 
00650     KFileItem *item;
00651 
00652     if ( spec & QDir::Time ) {
00653         for ( ; (item = it.current()); ++it )
00654             // warning, time_t is often signed -> cast it
00655             viewItem(item)->setKey( sortingKey( (unsigned long)item->time( KIO::UDS_MODIFICATION_TIME ), item->isDir(), spec ));
00656     }
00657 
00658     else if ( spec & QDir::Size ) {
00659         for ( ; (item = it.current()); ++it )
00660             viewItem(item)->setKey( sortingKey( item->size(), item->isDir(),
00661                                                 spec ));
00662     }
00663     else { // Name or Unsorted
00664         for ( ; (item = it.current()); ++it )
00665             viewItem(item)->setKey( sortingKey( item->text(), item->isDir(),
00666                                                 spec ));
00667     }
00668 
00669     KIconView::setSorting( true, !isReversed() );
00670     sort( !isReversed() );
00671 }
00672 
00673 //
00674 // mimetype determination on demand
00675 //
00676 void KFileIconView::mimeTypeDeterminationFinished()
00677 {
00678     // anything to do?
00679 }
00680 
00681 void KFileIconView::determineIcon( KFileIconViewItem *item )
00682 {
00683     (void) item->fileInfo()->determineMimeType();
00684     updateView( item->fileInfo() );
00685 }
00686 
00687 void KFileIconView::listingCompleted()
00688 {
00689     arrangeItemsInGrid();
00690     
00691     // QIconView doesn't set the current item automatically, so we have to do
00692     // that. We don't want to emit selectionChanged() tho.
00693     if ( !currentItem() ) {
00694         bool block = signalsBlocked();
00695         blockSignals( true );
00696         QIconViewItem *item = viewItem( firstFileItem() );
00697         KIconView::setCurrentItem( item );
00698         KIconView::setSelected( item, false );
00699         blockSignals( block );
00700     }
00701 
00702     m_resolver->start( d->previews->isChecked() ? 0 : 10 );
00703 }
00704 
00705 // need to remove our tooltip, eventually
00706 bool KFileIconView::eventFilter( QObject *o, QEvent *e )
00707 {
00708     if ( o == viewport() || o == this ) {
00709         int type = e->type();
00710         if ( type == QEvent::Leave ||
00711              type == QEvent::FocusOut )
00712             removeToolTip();
00713     }
00714 
00715     return KIconView::eventFilter( o, e );
00716 }
00717 
00719 
00720 // ### workaround for Qt3 Bug
00721 void KFileIconView::showEvent( QShowEvent *e )
00722 {
00723     KIconView::showEvent( e );
00724 }
00725 
00726 
00727 void KFileIconView::initItem( KFileIconViewItem *item, const KFileItem *i,
00728                               bool updateTextAndPixmap )
00729 {
00730     if ( d->previews->isChecked() && canPreview( i ) )
00731         item->setPixmapSize( QSize( d->previewIconSize, d->previewIconSize ) );
00732 
00733     if ( updateTextAndPixmap )
00734     {
00735         // this causes a repaint of the item, which we want to avoid during
00736         // directory listing, when all items are created. We want to paint all
00737         // items at once, not every single item in that case.
00738         item->setText( i->text() , false, false );
00739         item->setPixmap( i->pixmap( myIconSize ) );
00740     }
00741 
00742     // see also setSorting()
00743     QDir::SortSpec spec = KFileView::sorting();
00744 
00745     if ( spec & QDir::Time )
00746         // warning, time_t is often signed -> cast it
00747         item->setKey( sortingKey( (unsigned long) i->time( KIO::UDS_MODIFICATION_TIME ),
00748                                   i->isDir(), spec ));
00749     else if ( spec & QDir::Size )
00750         item->setKey( sortingKey( i->size(), i->isDir(), spec ));
00751 
00752     else // Name or Unsorted
00753         item->setKey( sortingKey( i->text(), i->isDir(), spec ));
00754 
00755     //qDebug("** key for: %s: %s", i->text().latin1(), item->key().latin1());
00756 
00757     if ( d->previews->isChecked() )
00758         d->previewTimer.start( 10, true );
00759 }
00760 
00761 void KFileIconView::arrangeItemsInGrid( bool update )
00762 {
00763     if ( d->noArrangement )
00764         return;
00765 
00766     KIconView::arrangeItemsInGrid( update );
00767 }
00768 
00769 void KFileIconView::zoomIn()
00770 {
00771     setPreviewSize( d->previewIconSize + 30 );
00772 }
00773 
00774 void KFileIconView::zoomOut()
00775 {
00776     setPreviewSize( d->previewIconSize - 30 );
00777 }
00778 
00779 QDragObject *KFileIconView::dragObject()
00780 {
00781     // create a list of the URL:s that we want to drag
00782     KURL::List urls;
00783     KFileItemListIterator it( * KFileView::selectedItems() );
00784     for ( ; it.current(); ++it ){
00785         urls.append( (*it)->url() );
00786     }
00787     QPixmap pixmap;
00788     if( urls.count() > 1 )
00789         pixmap = DesktopIcon( "kmultiple", iconSize() );
00790     if( pixmap.isNull() )
00791         pixmap = currentFileItem()->pixmap( iconSize() );
00792 
00793     QPoint hotspot;
00794     hotspot.setX( pixmap.width() / 2 );
00795     hotspot.setY( pixmap.height() / 2 );
00796     QDragObject* myDragObject = new KURLDrag( urls, widget() );
00797     myDragObject->setPixmap( pixmap, hotspot );
00798     return myDragObject;
00799 }
00800 
00801 void KFileIconView::slotAutoOpen()
00802 {
00803     d->autoOpenTimer.stop();
00804     if( !d->dropItem )
00805         return;
00806 
00807     KFileItem *fileItem = d->dropItem->fileInfo();
00808     if (!fileItem)
00809         return;
00810 
00811     if( fileItem->isFile() )
00812         return;
00813 
00814     if ( fileItem->isDir() || fileItem->isLink())
00815         sig->activate( fileItem );
00816 }
00817 
00818 bool KFileIconView::acceptDrag(QDropEvent* e) const
00819 {
00820    return KURLDrag::canDecode( e ) &&
00821        (e->source()!=const_cast<KFileIconView*>(this)) &&
00822        ( e->action() == QDropEvent::Copy
00823       || e->action() == QDropEvent::Move
00824       || e->action() == QDropEvent::Link );
00825 }
00826 
00827 void KFileIconView::contentsDragEnterEvent( QDragEnterEvent *e )
00828 {
00829     if ( ! acceptDrag( e ) ) { // can we decode this ?
00830         e->ignore();            // No
00831         return;
00832     }
00833     e->acceptAction();     // Yes
00834 
00835     if ((dropOptions() & AutoOpenDirs) == 0)
00836        return;
00837 
00838     KFileIconViewItem *item = dynamic_cast<KFileIconViewItem*>(findItem( contentsToViewport( e->pos() ) ));
00839     if ( item ) {  // are we over an item ?
00840        d->dropItem = item;
00841        d->autoOpenTimer.start( autoOpenDelay() ); // restart timer
00842     }
00843     else
00844     {
00845        d->dropItem = 0;
00846        d->autoOpenTimer.stop();
00847     }
00848 }
00849 
00850 void KFileIconView::contentsDragMoveEvent( QDragMoveEvent *e )
00851 {
00852     if ( ! acceptDrag( e ) ) { // can we decode this ?
00853         e->ignore();            // No
00854         return;
00855     }
00856     e->acceptAction();     // Yes
00857 
00858     if ((dropOptions() & AutoOpenDirs) == 0)
00859        return;
00860 
00861     KFileIconViewItem *item = dynamic_cast<KFileIconViewItem*>(findItem( contentsToViewport( e->pos() ) ));
00862     if ( item ) {  // are we over an item ?
00863        if (d->dropItem != item)
00864        {
00865            d->dropItem = item;
00866            d->autoOpenTimer.start( autoOpenDelay() ); // restart timer
00867        }
00868     }
00869     else
00870     {
00871        d->dropItem = 0;
00872        d->autoOpenTimer.stop();
00873     }
00874 }
00875 
00876 void KFileIconView::contentsDragLeaveEvent( QDragLeaveEvent * )
00877 {
00878     d->dropItem = 0;
00879     d->autoOpenTimer.stop();
00880 }
00881 
00882 void KFileIconView::contentsDropEvent( QDropEvent *e )
00883 {
00884     d->dropItem = 0;
00885     d->autoOpenTimer.stop();
00886 
00887     if ( ! acceptDrag( e ) ) { // can we decode this ?
00888         e->ignore();            // No
00889         return;
00890     }
00891     e->acceptAction();     // Yes
00892 
00893     KFileIconViewItem *item = dynamic_cast<KFileIconViewItem*>(findItem( contentsToViewport( e->pos() ) ));
00894     KFileItem * fileItem = 0;
00895     if (item)
00896         fileItem = item->fileInfo();
00897 
00898     emit dropped(e, fileItem);
00899 
00900     KURL::List urls;
00901     if (KURLDrag::decode( e, urls ) && !urls.isEmpty())
00902     {
00903         emit dropped(e, urls, fileItem ? fileItem->url() : KURL());
00904         sig->dropURLs(fileItem, e, urls);
00905     }
00906 }
00907 
00908 void KFileIconView::virtual_hook( int id, void* data )
00909 { KIconView::virtual_hook( id, data );
00910   KFileView::virtual_hook( id, data ); }
00911 
00912 #include "kfileiconview.moc"
KDE Logo
This file is part of the documentation for kio Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Jul 22 10:17:15 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003