• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • libkonq
 

libkonq

tdefileivi.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., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "tdefileivi.h"
00021 #include "kivdirectoryoverlay.h"
00022 #include "kivfreespaceoverlay.h"
00023 #include "konq_iconviewwidget.h"
00024 #include "konq_operations.h"
00025 #include "konq_settings.h"
00026 
00027 #include <tqpainter.h>
00028 
00029 #include <kurldrag.h>
00030 #include <kiconeffect.h>
00031 #include <tdefileitem.h>
00032 #include <kdebug.h>
00033 #include <krun.h>
00034 #include <kservice.h>
00035 
00036 #undef Bool
00037 
00041 struct KFileIVI::Private
00042 {
00043     TQIconSet icons; // Icon states (cached to prevent re-applying icon effects
00044             // every time)
00045     TQPixmap  thumb; // Raw unprocessed thumbnail
00046     TQString m_animatedIcon; // Name of animation
00047     bool m_animated;        // Animation currently running ?
00048     KIVDirectoryOverlay* m_directoryOverlay;
00049     KIVFreeSpaceOverlay* m_freeSpaceOverlay;
00050     TQPixmap m_overlay;
00051     TQString m_overlayName;
00052     int m_progress;
00053 };
00054 
00055 KFileIVI::KFileIVI( KonqIconViewWidget *iconview, KFileItem* fileitem, int size )
00056     : TDEIconViewItem( iconview, fileitem->text() ),
00057     m_size( size ), m_state( TDEIcon::DefaultState ),
00058     m_bDisabled( false ), m_bThumbnail( false ), m_fileitem( fileitem )
00059 {
00060     d = new KFileIVI::Private;
00061 
00062     updatePixmapSize();
00063     setPixmap( m_fileitem->pixmap( m_size, m_state ) );
00064     setDropEnabled( S_ISDIR( m_fileitem->mode() ) );
00065 
00066     // Cache entry for the icon effects
00067     d->icons.reset( *pixmap(), TQIconSet::Large );
00068     d->m_animated = false;
00069 
00070     // iconName() requires the mimetype to be known
00071     if ( fileitem->isMimeTypeKnown() )
00072     {
00073         TQString icon = fileitem->iconName();
00074         if ( !icon.isEmpty() )
00075             setMouseOverAnimation( icon );
00076         else
00077             setMouseOverAnimation( "unknown" );
00078     }
00079     d->m_progress = -1;
00080     d->m_directoryOverlay = 0;
00081     d->m_freeSpaceOverlay = 0;
00082 }
00083 
00084 KFileIVI::~KFileIVI()
00085 {
00086     delete d->m_directoryOverlay;
00087     delete d->m_freeSpaceOverlay;
00088     delete d;
00089 }
00090 
00091 void KFileIVI::invalidateThumb( int state, bool redraw )
00092 {
00093     TQIconSet::Mode mode;
00094     switch( state )
00095     {
00096     case TDEIcon::DisabledState:
00097         mode = TQIconSet::Disabled;
00098         break;
00099     case TDEIcon::ActiveState:
00100         mode = TQIconSet::Active;
00101         break;
00102     case TDEIcon::DefaultState:
00103     default:
00104         mode = TQIconSet::Normal;
00105         break;
00106     }
00107     d->icons = TQIconSet();
00108     d->icons.setPixmap( TDEGlobal::iconLoader()->iconEffect()->
00109             apply( d->thumb, TDEIcon::Desktop, state ),
00110             TQIconSet::Large, mode );
00111     m_state = state;
00112 
00113     TQIconViewItem::setPixmap( d->icons.pixmap( TQIconSet::Large, mode ),
00114                   false, redraw );
00115 }
00116 
00117 void KFileIVI::setIcon( int size, int state, bool recalc, bool redraw )
00118 {
00119     m_size = size;
00120     m_bThumbnail = false;
00121     if ( m_bDisabled )
00122       m_state = TDEIcon::DisabledState;
00123     else
00124       m_state = state;
00125 
00126     if ( d->m_overlayName.isNull() )
00127         d->m_overlay = TQPixmap();
00128     else {
00129         int halfSize;
00130         if (m_size == 0) {
00131             halfSize = IconSize(TDEIcon::Desktop) / 2;
00132         } else {
00133             halfSize = m_size / 2;
00134         }
00135         d->m_overlay = DesktopIcon(d->m_overlayName, halfSize);
00136     }
00137 
00138     setPixmapDirect(m_fileitem->pixmap( m_size, m_state ) , recalc, redraw );
00139 }
00140 
00141 void KFileIVI::setOverlay( const TQString& iconName )
00142 {
00143     d->m_overlayName = iconName;
00144 
00145     refreshIcon(true);
00146 }
00147 
00148 void KFileIVI::setOverlayProgressBar( const int progress )
00149 {
00150     d->m_progress = progress;
00151 
00152     refreshIcon(true);
00153 }
00154 
00155 KIVDirectoryOverlay* KFileIVI::setShowDirectoryOverlay( bool show )
00156 {
00157     if ( !m_fileitem->isDir() || m_fileitem->iconName() != "folder" )
00158         return 0;
00159 
00160     if (show) {
00161         if (!d->m_directoryOverlay)
00162             d->m_directoryOverlay = new KIVDirectoryOverlay(this);
00163         return d->m_directoryOverlay;
00164     } else {
00165         delete d->m_directoryOverlay;
00166         d->m_directoryOverlay = 0;
00167         setOverlay(TQString());
00168         return 0;
00169     }
00170 }
00171 
00172 bool KFileIVI::showDirectoryOverlay(  )
00173 {
00174     return (bool)d->m_directoryOverlay;
00175 }
00176 
00177 KIVFreeSpaceOverlay* KFileIVI::setShowFreeSpaceOverlay( bool show )
00178 {
00179     if ( !m_fileitem->mimetype().startsWith("media/") ) {
00180         return 0;
00181     }
00182 
00183     if (show) {
00184         if (!d->m_freeSpaceOverlay)
00185             d->m_freeSpaceOverlay = new KIVFreeSpaceOverlay(this);
00186         return d->m_freeSpaceOverlay;
00187     } else {
00188         delete d->m_freeSpaceOverlay;
00189         d->m_freeSpaceOverlay = 0;
00190         setOverlayProgressBar(-1);
00191         return 0;
00192     }
00193 }
00194 
00195 bool KFileIVI::showFreeSpaceOverlay(  )
00196 {
00197     return (bool)d->m_freeSpaceOverlay;
00198 }
00199 
00200 void KFileIVI::setPixmapDirect( const TQPixmap& pixmap, bool recalc, bool redraw )
00201 {
00202     TQIconSet::Mode mode;
00203     switch( m_state )
00204     {
00205     case TDEIcon::DisabledState:
00206         mode = TQIconSet::Disabled;
00207         break;
00208     case TDEIcon::ActiveState:
00209         mode = TQIconSet::Active;
00210         break;
00211     case TDEIcon::DefaultState:
00212     default:
00213         mode = TQIconSet::Normal;
00214         break;
00215     }
00216 
00217     // We cannot just reset() the iconset here, because setIcon can be
00218     // called with any state and not just normal state. So we just
00219     // create a dummy empty iconset as base object.
00220     d->icons = TQIconSet();
00221     d->icons.setPixmap( pixmap, TQIconSet::Large, mode );
00222 
00223     updatePixmapSize();
00224     TQIconViewItem::setPixmap( d->icons.pixmap( TQIconSet::Large, mode ),
00225                   recalc, redraw );
00226 }
00227 
00228 void KFileIVI::setDisabled( bool disabled )
00229 {
00230     if ( m_bDisabled != disabled )
00231     {
00232         m_bDisabled = disabled;
00233         bool active = ( m_state == TDEIcon::ActiveState );
00234         setEffect( m_bDisabled ? TDEIcon::DisabledState : 
00235                    ( active ? TDEIcon::ActiveState : TDEIcon::DefaultState ) );
00236     }
00237 }
00238 
00239 void KFileIVI::setThumbnailPixmap( const TQPixmap & pixmap )
00240 {
00241     m_bThumbnail = true;
00242     d->thumb = pixmap;
00243     // TQIconSet::reset() doesn't seem to clear the other generated pixmaps,
00244     // so we just create a blank TQIconSet here
00245     d->icons = TQIconSet();
00246     d->icons.setPixmap( TDEGlobal::iconLoader()->iconEffect()->
00247             apply( pixmap, TDEIcon::Desktop, TDEIcon::DefaultState ),
00248             TQIconSet::Large, TQIconSet::Normal );
00249 
00250     m_state = TDEIcon::DefaultState;
00251 
00252     // Recalc when setting this pixmap!
00253     updatePixmapSize();
00254     TQIconViewItem::setPixmap( d->icons.pixmap( TQIconSet::Large,
00255                   TQIconSet::Normal ), true );
00256 }
00257 
00258 void KFileIVI::setActive( bool active )
00259 {
00260     if ( active )
00261         setEffect( TDEIcon::ActiveState );
00262     else
00263         setEffect( m_bDisabled ? TDEIcon::DisabledState : TDEIcon::DefaultState );
00264 }
00265 
00266 void KFileIVI::setEffect( int state )
00267 {
00268     TQIconSet::Mode mode;
00269     switch( state )
00270     {
00271     case TDEIcon::DisabledState:
00272         mode = TQIconSet::Disabled;
00273         break;
00274     case TDEIcon::ActiveState:
00275         mode = TQIconSet::Active;
00276         break;
00277     case TDEIcon::DefaultState:
00278     default:
00279         mode = TQIconSet::Normal;
00280         break;
00281     }
00282     // Do not update if the fingerprint is identical (prevents flicker)!
00283 
00284     TDEIconEffect *effect = TDEGlobal::iconLoader()->iconEffect();
00285 
00286     bool haveEffect = effect->hasEffect( TDEIcon::Desktop, m_state ) !=
00287                       effect->hasEffect( TDEIcon::Desktop, state );
00288 
00289                 //kdDebug(1203) << "desktop;defaultstate=" <<
00290                 //      effect->fingerprint(TDEIcon::Desktop, TDEIcon::DefaultState) <<
00291                 //      endl;
00292                 //kdDebug(1203) << "desktop;activestate=" <<
00293                 //      effect->fingerprint(TDEIcon::Desktop, TDEIcon::ActiveState) <<
00294                 //      endl;
00295 
00296     if( haveEffect &&
00297         effect->fingerprint( TDEIcon::Desktop, m_state ) !=
00298     effect->fingerprint( TDEIcon::Desktop, state ) )
00299     {
00300     // Effects on are not applied until they are first accessed to
00301     // save memory. Do this now when needed
00302     if( m_bThumbnail )
00303     {
00304         if( d->icons.isGenerated( TQIconSet::Large, mode ) )
00305         d->icons.setPixmap( effect->apply( d->thumb, TDEIcon::Desktop, state ),
00306                     TQIconSet::Large, mode );
00307     }
00308     else
00309     {
00310         if( d->icons.isGenerated( TQIconSet::Large, mode ) )
00311         d->icons.setPixmap( m_fileitem->pixmap( m_size, state ),
00312                     TQIconSet::Large, mode );
00313     }
00314     TQIconViewItem::setPixmap( d->icons.pixmap( TQIconSet::Large, mode ) );
00315     }
00316     m_state = state;
00317 }
00318 
00319 void KFileIVI::refreshIcon( bool redraw )
00320 {
00321     if (!isThumbnail()) {
00322         setIcon( m_size, m_state, true, redraw );
00323     }
00324 }
00325 
00326 void KFileIVI::invalidateThumbnail()
00327 {
00328     d->thumb = TQPixmap();
00329 }
00330 
00331 bool KFileIVI::isThumbnailInvalid() const
00332 {
00333     return d->thumb.isNull();
00334 }
00335 
00336 bool KFileIVI::acceptDrop( const TQMimeSource *mime ) const
00337 {
00338     if ( mime->provides( "text/uri-list" ) ) // We're dragging URLs
00339     {
00340         if ( m_fileitem->acceptsDrops() ) // Directory, executables, ...
00341             return true;
00342 
00343         // Use cache
00344         KURL::List uris = ( static_cast<KonqIconViewWidget*>(iconView()) )->dragURLs();
00345 
00346         // Check if we want to drop something on itself
00347         // (Nothing will happen, but it's a convenient way to move icons)
00348         KURL::List::Iterator it = uris.begin();
00349         for ( ; it != uris.end() ; it++ )
00350         {
00351             if ( m_fileitem->url().equals( *it, true /*ignore trailing slashes*/ ) )
00352                 return true;
00353         }
00354     }
00355     return TQIconViewItem::acceptDrop( mime );
00356 }
00357 
00358 void KFileIVI::setKey( const TQString &key )
00359 {
00360     TQString theKey = key;
00361 
00362     TQVariant sortDirProp = iconView()->property( "sortDirectoriesFirst" );
00363 
00364     bool isdir = ( S_ISDIR( m_fileitem->mode() ) && ( !sortDirProp.isValid() || ( sortDirProp.type() == TQVariant::Bool && sortDirProp.toBool() ) ) );
00365 
00366     // The order is: .dir (0), dir (1), .file (2), file (3)
00367     int sortChar = isdir ? 1 : 3;
00368     if ( m_fileitem->text()[0] == '.' )
00369         --sortChar;
00370 
00371     if ( !iconView()->sortDirection() ) // reverse sorting
00372         sortChar = 3 - sortChar;
00373 
00374     theKey.prepend( TQChar( sortChar + '0' ) );
00375 
00376     TQIconViewItem::setKey( theKey );
00377 }
00378 
00379 void KFileIVI::dropped( TQDropEvent *e, const TQValueList<TQIconDragItem> & )
00380 {
00381     KonqOperations::doDrop( item(), item()->url(), e, iconView() );
00382 }
00383 
00384 void KFileIVI::returnPressed()
00385 {
00386     if ( static_cast<KonqIconViewWidget*>(iconView())->isDesktop() ) {
00387         KURL url = m_fileitem->url();
00388         if (url.protocol() == "media") {
00389             // The user reasonably expects to be placed within the media:/ tree
00390             // when opening a media device from the desktop
00391             KService::Ptr service = KService::serviceByDesktopName("konqueror");
00392             if (service) {
00393                 // HACK
00394                 // There doesn't seem to be a way to prevent KRun from resolving the URL to its
00395                 // local path, so simpy launch Konqueror with the correct arguments instead...
00396                 KRun::runCommand("konqueror " + url.url(), "konqueror", service->icon());
00397             }
00398             else {
00399                 (void) new KRun( url, m_fileitem->mode(), m_fileitem->isLocalFile() );
00400             }
00401         }
00402         else {
00403             // When clicking on a link to e.g. $HOME from the desktop, we want to open $HOME
00404             // Symlink resolution must only happen on the desktop though (#63014)
00405             if ( m_fileitem->isLink() && url.isLocalFile() ) {
00406                 url = KURL( url, m_fileitem->linkDest() );
00407             }
00408 
00409             (void) new KRun( url, m_fileitem->mode(), m_fileitem->isLocalFile() );
00410         }
00411     }
00412     else {
00413         m_fileitem->run();
00414     }
00415 }
00416 
00417 
00418 void KFileIVI::paintItem( TQPainter *p, const TQColorGroup &c )
00419 {
00420     TQColorGroup cg = updateColors(c);
00421     paintFontUpdate( p );
00422 
00423     //*** TEMPORARY CODE - MUST BE MADE CONFIGURABLE FIRST - Martijn
00424     // SET UNDERLINE ON HOVER ONLY
00425     /*if ( ( ( KonqIconViewWidget* ) iconView() )->m_pActiveItem == this )
00426     {
00427         TQFont f( p->font() );
00428         f.setUnderline( TRUE );
00429         p->setFont( f );
00430     }*/
00431 
00432     TDEIconViewItem::paintItem( p, cg );
00433     paintOverlay(p);
00434     paintOverlayProgressBar(p);
00435 
00436 }
00437 
00438 void KFileIVI::paintOverlay( TQPainter *p ) const
00439 {
00440     if ( !d->m_overlay.isNull() ) {
00441         TQRect rect = pixmapRect(true);
00442         p->drawPixmap(x() + rect.x() , y() + pixmapRect().height() - d->m_overlay.height(), d->m_overlay);
00443     }
00444 }
00445 
00446 void KFileIVI::paintOverlayProgressBar( TQPainter *p ) const
00447 {
00448     if (d->m_progress != -1) {
00449 //         // Pie chart
00450 //         TQRect rect = pixmapRect(true);
00451 //         rect.setX(x() + rect.x());
00452 //         rect.setY(y() + rect.y() + ((pixmapRect().height()*3)/4));
00453 //         rect.setWidth(pixmapRect().width()/4);
00454 //         rect.setHeight(pixmapRect().height()/4);
00455 //
00456 //         p->save();
00457 //
00458 //         p->setPen(TQPen::NoPen);
00459 //         p->setBrush(TQt::red);
00460 //         p->drawEllipse(rect);
00461 //         p->setBrush(TQt::green);
00462 //         p->drawPie(rect, 1440, (((100-d->m_progress)*5760)/100));
00463 
00464 //         // Horizontal progress bar
00465 //         TQRect rect = pixmapRect(true);
00466 //         int verticalOffset = 0;
00467 //         int usedBarWidth = ((d->m_progress*pixmapRect().width())/100);
00468 //         int endPosition = x() + rect.x() + usedBarWidth;
00469 // 
00470 //         p->save();
00471 // 
00472 //         p->setPen(TQPen::NoPen);
00473 //         p->setBrush(TQt::red);
00474 //         p->drawRect(TQRect(x() + rect.x(), y() + rect.y() + (pixmapRect().height() - verticalOffset), usedBarWidth, 1));
00475 //         p->setBrush(TQt::green);
00476 //         p->drawRect(TQRect(endPosition, y() + rect.y() + (pixmapRect().height() - verticalOffset), pixmapRect().width() - usedBarWidth, 1));
00477 
00478         // Vertical progress bar
00479         TQRect rect = pixmapRect(true);
00480         int horizontalOffset = 0;
00481         int usedBarHeight = (((100-d->m_progress)*pixmapRect().height())/100);
00482         int endPosition = y() + rect.y() + usedBarHeight;
00483 
00484         p->save();
00485 
00486         p->setPen(TQPen::NoPen);
00487         p->setBrush(TQt::green);
00488         p->drawRect(TQRect(x() + rect.x() + (pixmapRect().width() - horizontalOffset), y() + rect.y(), 1, usedBarHeight));
00489         p->setBrush(TQt::red);
00490         p->drawRect(TQRect(x() + rect.x() + (pixmapRect().width() - horizontalOffset), endPosition, 1, pixmapRect().height() - usedBarHeight));
00491 
00492         p->restore();
00493     }
00494 }
00495 
00496 void KFileIVI::paintFontUpdate( TQPainter *p ) const
00497 {
00498     if ( m_fileitem->isLink() )
00499     {
00500         TQFont f( p->font() );
00501         f.setItalic( TRUE );
00502         p->setFont( f );
00503     }
00504 }
00505 
00506 TQColorGroup KFileIVI::updateColors( const TQColorGroup &c ) const
00507 {
00508     TQColorGroup cg( c );
00509     cg.setColor( TQColorGroup::Text, static_cast<KonqIconViewWidget*>(iconView())->itemColor() );
00510     return cg;
00511 }
00512 
00513 bool KFileIVI::move( int x, int y )
00514 {
00515     if ( static_cast<KonqIconViewWidget*>(iconView())->isDesktop() ) {
00516     if ( x < 5 )
00517         x = 5;
00518     if ( x > iconView()->viewport()->width() - ( width() + 5 ) )
00519         x = iconView()->viewport()->width() - ( width() + 5 );
00520     if ( y < 5 )
00521         y = 5;
00522     if ( y > iconView()->viewport()->height() - ( height() + 5 ) )
00523         y = iconView()->viewport()->height() - ( height() + 5 );
00524     }
00525     return TQIconViewItem::move( x, y );
00526 }
00527 
00528 bool KFileIVI::hasAnimation() const
00529 {
00530     return !d->m_animatedIcon.isEmpty() && !m_bThumbnail;
00531 }
00532 
00533 void KFileIVI::setMouseOverAnimation( const TQString& movieFileName )
00534 {
00535     if ( !movieFileName.isEmpty() )
00536     {
00537         //kdDebug(1203) << "TDEIconViewItem::setMouseOverAnimation " << movieFileName << endl;
00538         d->m_animatedIcon = movieFileName;
00539     }
00540 }
00541 
00542 TQString KFileIVI::mouseOverAnimation() const
00543 {
00544     return d->m_animatedIcon;
00545 }
00546 
00547 bool KFileIVI::isAnimated() const
00548 {
00549     return d->m_animated;
00550 }
00551 
00552 void KFileIVI::setAnimated( bool a )
00553 {
00554     d->m_animated = a;
00555 }
00556 
00557 int KFileIVI::compare( TQIconViewItem *i ) const
00558 {
00559     KonqIconViewWidget* view = static_cast<KonqIconViewWidget*>(iconView());
00560     if ( view->caseInsensitiveSort() )
00561         return key().localeAwareCompare( i->key() );
00562     else
00563         return view->m_pSettings->caseSensitiveCompare( key(), i->key() );
00564 }
00565 
00566 void KFileIVI::updatePixmapSize()
00567 {
00568     int size = m_size ? m_size :
00569         TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop );
00570 
00571     KonqIconViewWidget* view = static_cast<KonqIconViewWidget*>( iconView() );
00572 
00573     bool mimeDetermined = false;
00574     if ( m_fileitem->isMimeTypeKnown() ) {
00575         mimeDetermined = true;
00576     }
00577 
00578     if (mimeDetermined) {
00579         bool changed = false;
00580         if ( view && view->canPreview( item() ) ) {
00581             int previewSize = view->previewIconSize( size );
00582             if (previewSize != size) {
00583                 setPixmapSize( TQSize( previewSize, previewSize ) );
00584                 changed = true;
00585             }
00586         }
00587         else {
00588             TQSize pixSize = TQSize( size, size );
00589             if ( pixSize != pixmapSize() ) {
00590                 setPixmapSize( pixSize );
00591                 changed = true;
00592             }
00593         }
00594         if (changed) {
00595             view->adjustItems();
00596         }
00597     }
00598     else {
00599         TQSize pixSize = TQSize( size, size );
00600         if ( pixSize != pixmapSize() ) {
00601             setPixmapSize( pixSize );
00602         }
00603     }
00604 }
00605 
00606 void KFileIVI::mimeTypeAndIconDetermined()
00607 {
00608     updatePixmapSize();
00609 }
00610 
00611 /* vim: set noet sw=4 ts=8 softtabstop=4: */

libkonq

Skip menu "libkonq"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

libkonq

Skip menu "libkonq"
  • kate
  • libkonq
  • twin
  •   lib
Generated for libkonq by doxygen 1.6.3
This website is maintained by Timothy Pearson.