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