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