libkonq Library API Documentation

kfileivi.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1999, 2000, 2001, 2002 David Faure <faure@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include "kfileivi.h"
00021 #include "kivdirectoryoverlay.h"
00022 #include "konq_iconviewwidget.h"
00023 #include "konq_operations.h"
00024 #include "konq_settings.h"
00025 
00026 #include <qpainter.h>
00027 
00028 #include <kurldrag.h>
00029 #include <kiconeffect.h>
00030 #include <kfileitem.h>
00031 #include <kdebug.h>
00032 
00033 #undef Bool
00034 
00038 struct KFileIVI::Private
00039 {
00040     QIconSet icons; // Icon states (cached to prevent re-applying icon effects
00041             // every time)
00042     QPixmap  thumb; // Raw unprocessed thumbnail
00043     QString m_animatedIcon; // Name of animation
00044     bool m_animated;        // Animation currently running ?
00045     KIVDirectoryOverlay* m_directoryOverlay;
00046     QPixmap m_overlay;
00047     QString m_overlayName;
00048 };
00049 
00050 KFileIVI::KFileIVI( KonqIconViewWidget *iconview, KFileItem* fileitem, int size )
00051     : KIconViewItem( iconview, fileitem->text() ),
00052     m_size( size ), m_state( KIcon::DefaultState ),
00053     m_bDisabled( false ), m_bThumbnail( false ), m_fileitem( fileitem )
00054 {
00055     d = new KFileIVI::Private;
00056 
00057     updatePixmapSize();
00058     setPixmap( m_fileitem->pixmap( m_size, m_state ) );
00059     setDropEnabled( S_ISDIR( m_fileitem->mode() ) );
00060 
00061     // Cache entry for the icon effects
00062     d->icons.reset( *pixmap(), QIconSet::Large );
00063     d->m_animated = false;
00064 
00065     // iconName() requires the mimetype to be known
00066     if ( fileitem->isMimeTypeKnown() )
00067     {
00068         QString icon = fileitem->iconName();
00069         if ( !icon.isEmpty() )
00070             setMouseOverAnimation( icon );
00071         else
00072             setMouseOverAnimation( "unknown" );
00073     }
00074     d->m_directoryOverlay = 0;
00075 }
00076 
00077 KFileIVI::~KFileIVI()
00078 {
00079     delete d->m_directoryOverlay;
00080     delete d;
00081 }
00082 
00083 void KFileIVI::invalidateThumb( int state, bool redraw )
00084 {
00085     QIconSet::Mode mode;
00086     switch( state )
00087     {
00088     case KIcon::DisabledState:
00089         mode = QIconSet::Disabled;
00090         break;
00091     case KIcon::ActiveState:
00092         mode = QIconSet::Active;
00093         break;
00094     case KIcon::DefaultState:
00095     default:
00096         mode = QIconSet::Normal;
00097         break;
00098     }
00099     d->icons = QIconSet();
00100     d->icons.setPixmap( KGlobal::iconLoader()->iconEffect()->
00101             apply( d->thumb, KIcon::Desktop, state ),
00102             QIconSet::Large, mode );
00103     m_state = state;
00104 
00105     QIconViewItem::setPixmap( d->icons.pixmap( QIconSet::Large, mode ),
00106                   false, redraw );
00107 }
00108 
00109 void KFileIVI::setIcon( int size, int state, bool recalc, bool redraw )
00110 {
00111     m_size = size;
00112     m_bThumbnail = false;
00113     if ( m_bDisabled )
00114       m_state = KIcon::DisabledState;
00115     else
00116       m_state = state;
00117 
00118     if ( d->m_overlayName.isNull() )
00119         d->m_overlay = QPixmap();
00120     else {
00121         int halfSize;
00122         if (m_size == 0) {
00123             halfSize = IconSize(KIcon::Desktop) / 2;
00124         } else {
00125             halfSize = m_size / 2;
00126         }
00127         d->m_overlay = DesktopIcon(d->m_overlayName, halfSize);
00128     }
00129 
00130     setPixmapDirect(m_fileitem->pixmap( m_size, m_state ) , recalc, redraw );
00131 }
00132 
00133 void KFileIVI::setOverlay( const QString& iconName )
00134 {
00135     d->m_overlayName = iconName;
00136 
00137     refreshIcon(true);
00138 }
00139 
00140 KIVDirectoryOverlay* KFileIVI::setShowDirectoryOverlay( bool show )
00141 {
00142     if ( !m_fileitem->isDir() || m_fileitem->iconName() != "folder" )
00143         return 0;
00144 
00145     if (show) {
00146         if (!d->m_directoryOverlay)
00147             d->m_directoryOverlay = new KIVDirectoryOverlay(this);
00148         return d->m_directoryOverlay;
00149     } else {
00150         delete d->m_directoryOverlay;
00151         d->m_directoryOverlay = 0;
00152         setOverlay(QString());
00153         return 0;
00154     }
00155 }
00156 
00157 bool KFileIVI::showDirectoryOverlay(  )
00158 {
00159     return (bool)d->m_directoryOverlay;
00160 }
00161 
00162 void KFileIVI::setPixmapDirect( const QPixmap& pixmap, bool recalc, bool redraw )
00163 {
00164     QIconSet::Mode mode;
00165     switch( m_state )
00166     {
00167     case KIcon::DisabledState:
00168         mode = QIconSet::Disabled;
00169         break;
00170     case KIcon::ActiveState:
00171         mode = QIconSet::Active;
00172         break;
00173     case KIcon::DefaultState:
00174     default:
00175         mode = QIconSet::Normal;
00176         break;
00177     }
00178 
00179     // We cannot just reset() the iconset here, because setIcon can be
00180     // called with any state and not just normal state. So we just
00181     // create a dummy empty iconset as base object.
00182     d->icons = QIconSet();
00183     d->icons.setPixmap( pixmap, QIconSet::Large, mode );
00184 
00185     updatePixmapSize();
00186     QIconViewItem::setPixmap( d->icons.pixmap( QIconSet::Large, mode ),
00187                   recalc, redraw );
00188 }
00189 
00190 void KFileIVI::setDisabled( bool disabled )
00191 {
00192     if ( m_bDisabled != disabled )
00193     {
00194         m_bDisabled = disabled;
00195         bool active = ( m_state == KIcon::ActiveState );
00196         setEffect( m_bDisabled ? KIcon::DisabledState : 
00197                    ( active ? KIcon::ActiveState : KIcon::DefaultState ) );
00198     }
00199 }
00200 
00201 void KFileIVI::setThumbnailPixmap( const QPixmap & pixmap )
00202 {
00203     m_bThumbnail = true;
00204     d->thumb = pixmap;
00205     // QIconSet::reset() doesn't seem to clear the other generated pixmaps,
00206     // so we just create a blank QIconSet here
00207     d->icons = QIconSet();
00208     d->icons.setPixmap( KGlobal::iconLoader()->iconEffect()->
00209             apply( pixmap, KIcon::Desktop, KIcon::DefaultState ),
00210             QIconSet::Large, QIconSet::Normal );
00211 
00212     m_state = KIcon::DefaultState;
00213 
00214     // Recalc when setting this pixmap!
00215     updatePixmapSize();
00216     QIconViewItem::setPixmap( d->icons.pixmap( QIconSet::Large,
00217                   QIconSet::Normal ), true );
00218 }
00219 
00220 void KFileIVI::setActive( bool active )
00221 {
00222     if ( active )
00223         setEffect( KIcon::ActiveState );
00224     else
00225         setEffect( m_bDisabled ? KIcon::DisabledState : KIcon::DefaultState );
00226 }
00227 
00228 void KFileIVI::setEffect( int state )
00229 {
00230     QIconSet::Mode mode;
00231     switch( state )
00232     {
00233     case KIcon::DisabledState:
00234         mode = QIconSet::Disabled;
00235         break;
00236     case KIcon::ActiveState:
00237         mode = QIconSet::Active;
00238         break;
00239     case KIcon::DefaultState:
00240     default:
00241         mode = QIconSet::Normal;
00242         break;
00243     }
00244     // Do not update if the fingerprint is identical (prevents flicker)!
00245 
00246     KIconEffect *effect = KGlobal::iconLoader()->iconEffect();
00247 
00248     bool haveEffect = effect->hasEffect( KIcon::Desktop, m_state ) !=
00249                       effect->hasEffect( KIcon::Desktop, state );
00250 
00251                 //kdDebug(1203) << "desktop;defaultstate=" <<
00252                 //      effect->fingerprint(KIcon::Desktop, KIcon::DefaultState) <<
00253                 //      endl;
00254                 //kdDebug(1203) << "desktop;activestate=" <<
00255                 //      effect->fingerprint(KIcon::Desktop, KIcon::ActiveState) <<
00256                 //      endl;
00257 
00258     if( haveEffect &&
00259         effect->fingerprint( KIcon::Desktop, m_state ) !=
00260     effect->fingerprint( KIcon::Desktop, state ) )
00261     {
00262     // Effects on are not applied until they are first accessed to
00263     // save memory. Do this now when needed
00264     if( m_bThumbnail )
00265     {
00266         if( d->icons.isGenerated( QIconSet::Large, mode ) )
00267         d->icons.setPixmap( effect->apply( d->thumb, KIcon::Desktop, state ),
00268                     QIconSet::Large, mode );
00269     }
00270     else
00271     {
00272         if( d->icons.isGenerated( QIconSet::Large, mode ) )
00273         d->icons.setPixmap( m_fileitem->pixmap( m_size, state ),
00274                     QIconSet::Large, mode );
00275     }
00276     QIconViewItem::setPixmap( d->icons.pixmap( QIconSet::Large, mode ) );
00277     }
00278     m_state = state;
00279 }
00280 
00281 void KFileIVI::refreshIcon( bool redraw )
00282 {
00283     if (!isThumbnail())
00284         setIcon( m_size, m_state, true, redraw );
00285 }
00286 
00287 void KFileIVI::invalidateThumbnail()
00288 {
00289     d->thumb = QPixmap();
00290 }
00291 
00292 bool KFileIVI::isThumbnailInvalid() const
00293 {
00294     return d->thumb.isNull();
00295 }
00296 
00297 bool KFileIVI::acceptDrop( const QMimeSource *mime ) const
00298 {
00299     if ( mime->provides( "text/uri-list" ) ) // We're dragging URLs
00300     {
00301         if ( m_fileitem->acceptsDrops() ) // Directory, executables, ...
00302             return true;
00303 
00304         // Use cache
00305         KURL::List uris = ( static_cast<KonqIconViewWidget*>(iconView()) )->dragURLs();
00306 
00307         // Check if we want to drop something on itself
00308         // (Nothing will happen, but it's a convenient way to move icons)
00309         KURL::List::Iterator it = uris.begin();
00310         for ( ; it != uris.end() ; it++ )
00311         {
00312             if ( m_fileitem->url().equals( *it, true /*ignore trailing slashes*/ ) )
00313                 return true;
00314         }
00315     }
00316     return QIconViewItem::acceptDrop( mime );
00317 }
00318 
00319 void KFileIVI::setKey( const QString &key )
00320 {
00321     QString theKey = key;
00322 
00323     QVariant sortDirProp = iconView()->property( "sortDirectoriesFirst" );
00324 
00325     bool isdir = ( S_ISDIR( m_fileitem->mode() ) && ( !sortDirProp.isValid() || ( sortDirProp.type() == QVariant::Bool && sortDirProp.toBool() ) ) );
00326 
00327     // The order is: .dir (0), dir (1), .file (2), file (3)
00328     int sortChar = isdir ? 1 : 3;
00329     if ( m_fileitem->text()[0] == '.' )
00330         --sortChar;
00331 
00332     if ( !iconView()->sortDirection() ) // reverse sorting
00333         sortChar = 3 - sortChar;
00334 
00335     theKey.prepend( QChar( sortChar + '0' ) );
00336 
00337     QIconViewItem::setKey( theKey );
00338 }
00339 
00340 void KFileIVI::dropped( QDropEvent *e, const QValueList<QIconDragItem> & )
00341 {
00342     KonqOperations::doDrop( item(), item()->url(), e, iconView() );
00343 }
00344 
00345 void KFileIVI::returnPressed()
00346 {
00347     m_fileitem->run();
00348 }
00349 
00350 
00351 void KFileIVI::paintItem( QPainter *p, const QColorGroup &c )
00352 {
00353     QColorGroup cg = updateColors(c);
00354     paintFontUpdate( p );
00355 
00356     //*** TEMPORARY CODE - MUST BE MADE CONFIGURABLE FIRST - Martijn
00357     // SET UNDERLINE ON HOVER ONLY
00358     /*if ( ( ( KonqIconViewWidget* ) iconView() )->m_pActiveItem == this )
00359     {
00360         QFont f( p->font() );
00361         f.setUnderline( TRUE );
00362         p->setFont( f );
00363     }*/
00364 
00365     KIconViewItem::paintItem( p, cg );
00366     paintOverlay(p);
00367 
00368 }
00369 
00370 void KFileIVI::paintOverlay( QPainter *p ) const
00371 {
00372     if ( !d->m_overlay.isNull() ) {
00373         QRect rect = pixmapRect(true);
00374         p->drawPixmap(x() + rect.x() , y() + pixmapRect().height() - d->m_overlay.height(), d->m_overlay);
00375     }
00376 }
00377 
00378 void KFileIVI::paintFontUpdate( QPainter *p ) const
00379 {
00380     if ( m_fileitem->isLink() )
00381     {
00382         QFont f( p->font() );
00383         f.setItalic( TRUE );
00384         p->setFont( f );
00385     }
00386 }
00387 
00388 QColorGroup KFileIVI::updateColors( const QColorGroup &c ) const
00389 {
00390     QColorGroup cg( c );
00391     cg.setColor( QColorGroup::Text, static_cast<KonqIconViewWidget*>(iconView())->itemColor() );
00392     return cg;
00393 }
00394 
00395 bool KFileIVI::move( int x, int y )
00396 {
00397     if ( static_cast<KonqIconViewWidget*>(iconView())->isDesktop() ) {
00398     if ( x < 5 )
00399         x = 5;
00400     if ( x > iconView()->viewport()->width() - ( width() + 5 ) )
00401         x = iconView()->viewport()->width() - ( width() + 5 );
00402     if ( y < 5 )
00403         y = 5;
00404     if ( y > iconView()->viewport()->height() - ( height() + 5 ) )
00405         y = iconView()->viewport()->height() - ( height() + 5 );
00406     }
00407     return QIconViewItem::move( x, y );
00408 }
00409 
00410 bool KFileIVI::hasAnimation() const
00411 {
00412     return !d->m_animatedIcon.isEmpty() && !m_bThumbnail;
00413 }
00414 
00415 void KFileIVI::setMouseOverAnimation( const QString& movieFileName )
00416 {
00417     if ( !movieFileName.isEmpty() )
00418     {
00419         //kdDebug(1203) << "KIconViewItem::setMouseOverAnimation " << movieFileName << endl;
00420         d->m_animatedIcon = movieFileName;
00421     }
00422 }
00423 
00424 QString KFileIVI::mouseOverAnimation() const
00425 {
00426     return d->m_animatedIcon;
00427 }
00428 
00429 bool KFileIVI::isAnimated() const
00430 {
00431     return d->m_animated;
00432 }
00433 
00434 void KFileIVI::setAnimated( bool a )
00435 {
00436     d->m_animated = a;
00437 }
00438 
00439 int KFileIVI::compare( QIconViewItem *i ) const
00440 {
00441     KonqIconViewWidget* view = static_cast<KonqIconViewWidget*>(iconView());
00442     if ( view->caseInsensitiveSort() )
00443         return key().localeAwareCompare( i->key() );
00444     else
00445         return view->m_pSettings->caseSensitiveCompare( key(), i->key() );
00446 }
00447 
00448 void KFileIVI::updatePixmapSize()
00449 {
00450     int size = m_size ? m_size :
00451         KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00452 
00453     KonqIconViewWidget* view = static_cast<KonqIconViewWidget*>( iconView() );
00454 
00455     if ( view && view->canPreview( item() ) ) { 
00456         int previewSize = view->previewIconSize( size );
00457         setPixmapSize( QSize( previewSize, previewSize ) );
00458     }
00459     else {
00460         QSize pixSize = QSize( size, size );
00461         if ( pixSize != pixmapSize() )
00462             setPixmapSize( pixSize );
00463     }
00464 }
00465 
00466 /* vim: set noet sw=4 ts=8 softtabstop=4: */
KDE Logo
This file is part of the documentation for libkonq Library Version 3.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jun 14 16:46:11 2006 by doxygen 1.4.4 written by Dimitri van Heesch, © 1997-2003