konq_iconviewwidget.cc
00001 /* This file is part of the KDE projects 00002 Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 00003 Copyright (C) 2000 - 2005 David Faure <faure@kde.org> 00004 00005 This program is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; see the file COPYING. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 #include "konq_iconviewwidget.h" 00021 #include "konq_operations.h" 00022 #include "konq_undo.h" 00023 #include "konq_sound.h" 00024 #include "konq_filetip.h" 00025 00026 #include <tqclipboard.h> 00027 #include <tqlayout.h> 00028 #include <tqtimer.h> 00029 #include <tqpainter.h> 00030 #include <tqtooltip.h> 00031 #include <tqlabel.h> 00032 #include <tqmovie.h> 00033 #include <tqregexp.h> 00034 #include <tqcursor.h> 00035 00036 #include <kapplication.h> 00037 #include <kdebug.h> 00038 #include <kio/previewjob.h> 00039 #include <kfileivi.h> 00040 #include <konq_settings.h> 00041 #include <konq_drag.h> 00042 #include <kglobalsettings.h> 00043 #include <kpropertiesdialog.h> 00044 #include <kipc.h> 00045 #include <kicontheme.h> 00046 #include <kiconeffect.h> 00047 #include <kurldrag.h> 00048 #include <kstandarddirs.h> 00049 #include <kprotocolinfo.h> 00050 #include <ktrader.h> 00051 00052 #include <assert.h> 00053 #include <unistd.h> 00054 #include <klocale.h> 00055 00056 00057 struct KonqIconViewWidgetPrivate 00058 { 00059 KonqIconViewWidgetPrivate() { 00060 pActiveItem = 0; 00061 bSoundPreviews = false; 00062 pSoundItem = 0; 00063 bSoundItemClicked = false; 00064 pSoundPlayer = 0; 00065 pSoundTimer = 0; 00066 pPreviewJob = 0; 00067 bAllowSetWallpaper = false; 00068 00069 doAnimations = true; 00070 m_movie = 0L; 00071 m_movieBlocked = 0; 00072 pFileTip = 0; 00073 pActivateDoubleClick = 0L; 00074 bCaseInsensitive = true; 00075 pPreviewMimeTypes = 0L; 00076 bProgramsURLdrag = false; 00077 } 00078 ~KonqIconViewWidgetPrivate() { 00079 delete pSoundPlayer; 00080 delete pSoundTimer; 00081 delete m_movie; 00082 delete pFileTip; 00083 delete pActivateDoubleClick; 00084 delete pPreviewMimeTypes; 00085 //delete pPreviewJob; done by stopImagePreview 00086 } 00087 KFileIVI *pActiveItem; 00088 // Sound preview 00089 KFileIVI *pSoundItem; 00090 KonqSoundPlayer *pSoundPlayer; 00091 TQTimer *pSoundTimer; 00092 bool bSoundPreviews; 00093 bool bSoundItemClicked; 00094 bool bAllowSetWallpaper; 00095 bool bCaseInsensitive; 00096 bool bBoostPreview; 00097 00098 // Animated icons support 00099 bool doAnimations; 00100 TQMovie* m_movie; 00101 int m_movieBlocked; 00102 TQString movieFileName; 00103 00104 KIO::PreviewJob *pPreviewJob; 00105 KonqFileTip* pFileTip; 00106 TQStringList previewSettings; 00107 bool renameItem; 00108 bool firstClick; 00109 bool releaseMouseEvent; 00110 TQPoint mousePos; 00111 int mouseState; 00112 TQTimer *pActivateDoubleClick; 00113 TQStringList* pPreviewMimeTypes; 00114 bool bProgramsURLdrag; 00115 }; 00116 00117 KonqIconViewWidget::KonqIconViewWidget( TQWidget * parent, const char * name, WFlags f, bool kdesktop ) 00118 : KIconView( parent, name, f ), 00119 m_rootItem( 0L ), m_size( 0 ) /* default is DesktopIcon size */, 00120 m_bDesktop( kdesktop ), 00121 m_bSetGridX( !kdesktop ) /* No line breaking on the desktop */ 00122 { 00123 d = new KonqIconViewWidgetPrivate; 00124 connect( this, TQT_SIGNAL( dropped( TQDropEvent *, const TQValueList<TQIconDragItem> & ) ), 00125 this, TQT_SLOT( slotDropped( TQDropEvent*, const TQValueList<TQIconDragItem> & ) ) ); 00126 00127 connect( this, TQT_SIGNAL( selectionChanged() ), 00128 this, TQT_SLOT( slotSelectionChanged() ) ); 00129 00130 kapp->addKipcEventMask( KIPC::IconChanged ); 00131 connect( kapp, TQT_SIGNAL(iconChanged(int)), TQT_SLOT(slotIconChanged(int)) ); 00132 connect( this, TQT_SIGNAL(onItem(TQIconViewItem *)), TQT_SLOT(slotOnItem(TQIconViewItem *)) ); 00133 connect( this, TQT_SIGNAL(onViewport()), TQT_SLOT(slotOnViewport()) ); 00134 connect( this, TQT_SIGNAL(itemRenamed(TQIconViewItem *, const TQString &)), TQT_SLOT(slotItemRenamed(TQIconViewItem *, const TQString &)) ); 00135 00136 m_pSettings = KonqFMSettings::settings(); // already needed in setItemTextPos(), calculateGridX() 00137 d->bBoostPreview = boostPreview(); 00138 00139 // hardcoded settings 00140 setSelectionMode( TQIconView::Extended ); 00141 setItemTextPos( TQIconView::Bottom ); 00142 d->releaseMouseEvent = false; 00143 d->pFileTip = new KonqFileTip(this); 00144 d->firstClick = false; 00145 calculateGridX(); 00146 setAutoArrange( true ); 00147 setSorting( true, sortDirection() ); 00148 readAnimatedIconsConfig(); 00149 m_bSortDirsFirst = true; 00150 m_bMousePressed = false; 00151 m_LineupMode = LineupBoth; 00152 // emit our signals 00153 slotSelectionChanged(); 00154 m_iconPositionGroupPrefix = TQString::fromLatin1( "IconPosition::" ); 00155 KonqUndoManager::incRef(); 00156 } 00157 00158 KonqIconViewWidget::~KonqIconViewWidget() 00159 { 00160 stopImagePreview(); 00161 KonqUndoManager::decRef(); 00162 delete d; 00163 } 00164 00165 bool KonqIconViewWidget::maySetWallpaper() 00166 { 00167 return d->bAllowSetWallpaper; 00168 } 00169 00170 void KonqIconViewWidget::setMaySetWallpaper(bool b) 00171 { 00172 d->bAllowSetWallpaper = b; 00173 } 00174 00175 void KonqIconViewWidget::focusOutEvent( TQFocusEvent * ev ) 00176 { 00177 // We can't possibly have the mouse pressed and still lose focus. 00178 // Well, we can, but when we regain focus we should assume the mouse is 00179 // not down anymore or the slotOnItem code will break with highlighting! 00180 m_bMousePressed = false; 00181 00182 // This will ensure that tooltips don't pop up and the mouseover icon 00183 // effect will go away if the mouse goes out of the view without 00184 // first moving into an empty portion of the view 00185 // Fixes part of #86968, and #85204 00186 // Matt Newell 2004-09-24 00187 slotOnViewport(); 00188 00189 KIconView::focusOutEvent( ev ); 00190 } 00191 00192 void KonqIconViewWidget::slotItemRenamed(TQIconViewItem *item, const TQString &name) 00193 { 00194 kdDebug(1203) << "KonqIconViewWidget::slotItemRenamed" << endl; 00195 KFileIVI *viewItem = static_cast<KFileIVI *>(item); 00196 KFileItem *fileItem = viewItem->item(); 00197 00198 // The correct behavior is to show the old name until the rename has successfully 00199 // completed. Unfortunately, KIconView forces us to allow the text to be changed 00200 // before we try the rename, so set it back to the pre-rename state. 00201 viewItem->setText( fileItem->text() ); 00202 kdDebug(1203)<<" fileItem->text() ;"<<fileItem->text()<<endl; 00203 // Don't do anything if the user renamed to a blank name. 00204 if( !name.isEmpty() ) 00205 { 00206 // Actually attempt the rename. If it succeeds, KDirLister will update the name. 00207 KURL oldurl( fileItem->url() ); 00208 KURL newurl( oldurl ); 00209 newurl.setPath( newurl.directory(false) + KIO::encodeFileName( name ) ); 00210 kdDebug(1203)<<" newurl :"<<newurl<<endl; 00211 // We use url()+name so that it also works if the name is a relative path (#51176) 00212 KonqOperations::rename( this, oldurl, newurl ); 00213 } 00214 } 00215 00216 void KonqIconViewWidget::slotIconChanged( int group ) 00217 { 00218 if (group != KIcon::Desktop) 00219 return; 00220 00221 int size = m_size; 00222 if ( m_size == 0 ) 00223 m_size = -1; // little trick to force grid change in setIcons 00224 setIcons( size ); // force re-determining all icons 00225 readAnimatedIconsConfig(); 00226 } 00227 00228 void KonqIconViewWidget::readAnimatedIconsConfig() 00229 { 00230 KConfigGroup cfgGroup( KGlobal::config(), "DesktopIcons" ); 00231 d->doAnimations = cfgGroup.readBoolEntry( "Animated", true /*default*/ ); 00232 } 00233 00234 void KonqIconViewWidget::slotOnItem( TQIconViewItem *_item ) 00235 { 00236 KFileIVI* item = static_cast<KFileIVI *>( _item ); 00237 // Reset icon of previous item 00238 if( d->pActiveItem != 0L && d->pActiveItem != item ) 00239 { 00240 if ( d->m_movie && d->pActiveItem->isAnimated() ) 00241 { 00242 d->m_movie->pause(); // we'll see below what we do with it 00243 d->pActiveItem->setAnimated( false ); 00244 d->pActiveItem->refreshIcon( true ); 00245 } 00246 else { 00247 d->pActiveItem->setActive( false ); 00248 } 00249 d->pActiveItem = 0L; 00250 d->pFileTip->setItem( 0L ); 00251 } 00252 00253 // Stop sound 00254 if (d->pSoundPlayer != 0 && item != d->pSoundItem) 00255 { 00256 d->pSoundPlayer->stop(); 00257 00258 d->pSoundItem = 0; 00259 if (d->pSoundTimer && d->pSoundTimer->isActive()) 00260 d->pSoundTimer->stop(); 00261 } 00262 00263 if ( !m_bMousePressed ) 00264 { 00265 if( item != d->pActiveItem ) 00266 { 00267 d->pActiveItem = item; 00268 d->pFileTip->setItem( d->pActiveItem->item(), 00269 item->rect(), 00270 item->pixmap() ); 00271 00272 if ( d->doAnimations && d->pActiveItem && d->pActiveItem->hasAnimation() ) 00273 { 00274 //kdDebug(1203) << "Playing animation for: " << d->pActiveItem->mouseOverAnimation() << endl; 00275 // Check if cached movie can be used 00276 #if 0 // Qt-mng bug, reusing the movie doesn't work currently. 00277 if ( d->m_movie && d->movieFileName == d->pActiveItem->mouseOverAnimation() ) 00278 { 00279 d->pActiveItem->setAnimated( true ); 00280 if (d->m_movieBlocked) { 00281 kdDebug(1203) << "onitem, but blocked" << endl; 00282 d->m_movie->pause(); 00283 } 00284 else { 00285 kdDebug(1203) << "we go ahead.." << endl; 00286 d->m_movieBlocked++; 00287 TQTimer::singleShot(300, this, TQT_SLOT(slotReenableAnimation())); 00288 d->m_movie->restart(); 00289 d->m_movie->unpause(); 00290 } 00291 } 00292 else 00293 #endif 00294 { 00295 TQMovie movie = KGlobal::iconLoader()->loadMovie( d->pActiveItem->mouseOverAnimation(), KIcon::Desktop, d->pActiveItem->iconSize() ); 00296 if ( !movie.isNull() ) 00297 { 00298 delete d->m_movie; 00299 d->m_movie = new TQMovie( movie ); // shallow copy, don't worry 00300 // Fix alpha-channel - currently only if no background pixmap, 00301 // the bg pixmap case requires to uncomment the code at qmovie.cpp:404 00302 const TQPixmap* pm = backgroundPixmap(); 00303 bool hasPixmap = pm && !pm->isNull(); 00304 if ( !hasPixmap ) { 00305 pm = viewport()->backgroundPixmap(); 00306 hasPixmap = pm && !pm->isNull(); 00307 } 00308 if (!hasPixmap && backgroundMode() != NoBackground) 00309 d->m_movie->setBackgroundColor( viewport()->backgroundColor() ); 00310 d->m_movie->connectUpdate( this, TQT_SLOT( slotMovieUpdate(const TQRect &) ) ); 00311 d->m_movie->connectStatus( TQT_TQOBJECT(this), TQT_SLOT( slotMovieStatus(int) ) ); 00312 d->movieFileName = d->pActiveItem->mouseOverAnimation(); 00313 d->pActiveItem->setAnimated( true ); 00314 } 00315 else 00316 { 00317 d->pActiveItem->setAnimated( false ); 00318 if (d->m_movie) 00319 d->m_movie->pause(); 00320 // No movie available, remember it 00321 d->pActiveItem->setMouseOverAnimation( TQString::null ); 00322 } 00323 } 00324 } // animations 00325 // Only do the normal "mouseover" effect if no animation is in use 00326 if (d->pActiveItem && !d->pActiveItem->isAnimated()) 00327 { 00328 d->pActiveItem->setActive( true ); 00329 } 00330 } 00331 else // No change in current item 00332 { 00333 // No effect. If we want to underline on hover, we should 00334 // force the IVI to repaint here, though! 00335 d->pActiveItem = 0L; 00336 d->pFileTip->setItem( 0L ); 00337 } 00338 } // bMousePressed 00339 else 00340 { 00341 // All features disabled during mouse clicking, e.g. rectangular 00342 // selection 00343 d->pActiveItem = 0L; 00344 d->pFileTip->setItem( 0L ); 00345 } 00346 00347 // ## shouldn't this be disabled during rectangular selection too ? 00348 if (d->bSoundPreviews && d->pSoundPlayer && 00349 d->pSoundPlayer->mimeTypes().contains( 00350 item->item()->mimetype()) 00351 && KGlobalSettings::showFilePreview(item->item()->url()) 00352 && topLevelWidget() == kapp->activeWindow()) 00353 { 00354 d->pSoundItem = item; 00355 d->bSoundItemClicked = false; 00356 if (!d->pSoundTimer) 00357 { 00358 d->pSoundTimer = new TQTimer(this); 00359 connect(d->pSoundTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotStartSoundPreview())); 00360 } 00361 if (d->pSoundTimer->isActive()) 00362 d->pSoundTimer->stop(); 00363 d->pSoundTimer->start(500, true); 00364 } 00365 else 00366 { 00367 if (d->pSoundPlayer) 00368 d->pSoundPlayer->stop(); 00369 d->pSoundItem = 0; 00370 if (d->pSoundTimer && d->pSoundTimer->isActive()) 00371 d->pSoundTimer->stop(); 00372 } 00373 } 00374 00375 void KonqIconViewWidget::slotOnViewport() 00376 { 00377 d->pFileTip->setItem( 0L ); 00378 00379 if (d->pSoundPlayer) 00380 d->pSoundPlayer->stop(); 00381 d->pSoundItem = 0; 00382 if (d->pSoundTimer && d->pSoundTimer->isActive()) 00383 d->pSoundTimer->stop(); 00384 00385 if (d->pActiveItem == 0L) 00386 return; 00387 00388 if ( d->doAnimations && d->m_movie && d->pActiveItem->isAnimated() ) 00389 { 00390 d->pActiveItem->setAnimated( false ); 00391 #if 0 00392 // Aborting before the end of the animation ? 00393 if (d->m_movie->running()) { 00394 d->m_movie->pause(); 00395 d->m_movieBlocked++; 00396 kdDebug(1203) << "on viewport, blocking" << endl; 00397 TQTimer::singleShot(300, this, TQT_SLOT(slotReenableAnimation())); 00398 } 00399 #endif 00400 d->pActiveItem->refreshIcon( true ); 00401 Q_ASSERT( d->pActiveItem->state() == KIcon::DefaultState ); 00402 //delete d->m_movie; 00403 //d->m_movie = 0L; 00404 // TODO a timer to delete the movie after some time if unused? 00405 } 00406 else 00407 { 00408 d->pActiveItem->setActive( false ); 00409 } 00410 d->pActiveItem = 0L; 00411 } 00412 00413 void KonqIconViewWidget::slotStartSoundPreview() 00414 { 00415 if (!d->pSoundItem || d->bSoundItemClicked) 00416 return; 00417 00418 d->pSoundPlayer->play(d->pSoundItem->item()->url().url()); 00419 } 00420 00421 00422 void KonqIconViewWidget::slotPreview(const KFileItem *item, const TQPixmap &pix) 00423 { 00424 // ### slow. Idea: move KonqKfmIconView's m_itemDict into this class 00425 for (TQIconViewItem *it = firstItem(); it; it = it->nextItem()) 00426 { 00427 KFileIVI* current = static_cast<KFileIVI *>(it); 00428 if (current->item() == item) 00429 { 00430 if (item->overlays() & KIcon::HiddenOverlay) { 00431 TQPixmap p(pix); 00432 00433 KIconEffect::semiTransparent(p); 00434 current->setThumbnailPixmap(p); 00435 } else { 00436 current->setThumbnailPixmap(pix); 00437 } 00438 break; 00439 } 00440 } 00441 } 00442 00443 void KonqIconViewWidget::slotPreviewResult() 00444 { 00445 d->pPreviewJob = 0; 00446 emit imagePreviewFinished(); 00447 } 00448 00449 void KonqIconViewWidget::slotToolTipPreview(const KFileItem* , const TQPixmap &) 00450 { 00451 // unused - remove for KDE4 00452 } 00453 00454 void KonqIconViewWidget::slotToolTipPreviewResult() 00455 { 00456 // unused - remove for KDE4 00457 } 00458 00459 void KonqIconViewWidget::slotMovieUpdate( const TQRect& rect ) 00460 { 00461 //kdDebug(1203) << "KonqIconViewWidget::slotMovieUpdate " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << endl; 00462 Q_ASSERT( d ); 00463 Q_ASSERT( d->m_movie ); 00464 // seems stopAnimation triggers one last update 00465 if ( d->pActiveItem && d->m_movie && d->pActiveItem->isAnimated() ) { 00466 const TQPixmap &frame = d->m_movie->framePixmap(); 00467 // This can happen if the icon was scaled to the desired size, so KIconLoader 00468 // will happily return a movie with different dimensions than the icon 00469 int iconSize=d->pActiveItem->iconSize(); 00470 if (iconSize==0) iconSize = KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00471 if ( frame.width() != iconSize || frame.height() != iconSize ) { 00472 d->pActiveItem->setAnimated( false ); 00473 d->m_movie->pause(); 00474 // No movie available, remember it 00475 d->pActiveItem->setMouseOverAnimation( TQString::null ); 00476 d->pActiveItem->setActive( true ); 00477 return; 00478 } 00479 d->pActiveItem->setPixmapDirect( frame, false, false /*no redraw*/ ); 00480 TQRect pixRect = d->pActiveItem->pixmapRect(false); 00481 repaintContents( pixRect.x() + rect.x(), pixRect.y() + rect.y(), rect.width(), rect.height(), false ); 00482 } 00483 } 00484 00485 void KonqIconViewWidget::slotMovieStatus( int status ) 00486 { 00487 if ( status < 0 ) { 00488 // Error playing the MNG -> forget about it and do normal iconeffect 00489 if ( d->pActiveItem && d->pActiveItem->isAnimated() ) { 00490 d->pActiveItem->setAnimated( false ); 00491 d->pActiveItem->setMouseOverAnimation( TQString::null ); 00492 d->pActiveItem->setActive( true ); 00493 } 00494 } 00495 } 00496 00497 void KonqIconViewWidget::slotReenableAnimation() 00498 { 00499 if (!--d->m_movieBlocked) { 00500 if ( d->pActiveItem && d->m_movie && d->m_movie->paused()) { 00501 kdDebug(1203) << "reenabled animation" << endl; 00502 d->m_movie->restart(); 00503 d->m_movie->unpause(); 00504 } 00505 } 00506 } 00507 00508 void KonqIconViewWidget::clear() 00509 { 00510 d->pFileTip->setItem( 0L ); 00511 stopImagePreview(); // Just in case 00512 KIconView::clear(); 00513 d->pActiveItem = 0L; 00514 } 00515 00516 void KonqIconViewWidget::takeItem( TQIconViewItem *item ) 00517 { 00518 if ( d->pActiveItem == static_cast<KFileIVI *>(item) ) 00519 { 00520 d->pFileTip->setItem( 0L ); 00521 d->pActiveItem = 0L; 00522 } 00523 00524 if ( d->pPreviewJob ) 00525 d->pPreviewJob->removeItem( static_cast<KFileIVI *>(item)->item() ); 00526 00527 KIconView::takeItem( item ); 00528 } 00529 00530 // Currently unused - remove in KDE 4.0 00531 void KonqIconViewWidget::setThumbnailPixmap( KFileIVI * item, const TQPixmap & pixmap ) 00532 { 00533 if ( item ) 00534 { 00535 if ( d->pActiveItem == item ) 00536 { 00537 d->pFileTip->setItem( 0L ); 00538 d->pActiveItem = 0L; 00539 } 00540 item->setThumbnailPixmap( pixmap ); 00541 if ( m_bSetGridX && item->width() > gridX() ) 00542 { 00543 setGridX( item->width() ); 00544 if (autoArrange()) 00545 arrangeItemsInGrid(); 00546 } 00547 } 00548 } 00549 00550 bool KonqIconViewWidget::initConfig( bool bInit ) 00551 { 00552 bool fontChanged = false; 00553 00554 // Color settings 00555 TQColor normalTextColor = m_pSettings->normalTextColor(); 00556 setItemColor( normalTextColor ); 00557 00558 if (m_bDesktop) 00559 { 00560 TQColor itemTextBg = m_pSettings->itemTextBackground(); 00561 if ( itemTextBg.isValid() ) 00562 setItemTextBackground( itemTextBg ); 00563 else 00564 setItemTextBackground( Qt::NoBrush ); 00565 } 00566 00567 bool on = m_pSettings->showFileTips() && TQToolTip::isGloballyEnabled(); 00568 d->pFileTip->setOptions(on, 00569 m_pSettings->showPreviewsInFileTips(), 00570 m_pSettings->numFileTips()); 00571 00572 // if the user wants our own tooltip, don't show the one from Qts ListView 00573 setShowToolTips(!on); 00574 00575 // Font settings 00576 TQFont font( m_pSettings->standardFont() ); 00577 if (!m_bDesktop) 00578 font.setUnderline( m_pSettings->underlineLink() ); 00579 00580 if ( font != KonqIconViewWidget::font() ) 00581 { 00582 setFont( font ); 00583 if (!bInit) 00584 { 00585 // TQIconView doesn't do it by default... but if the font is made much 00586 // bigger, we really need to give more space between the icons 00587 fontChanged = true; 00588 } 00589 } 00590 00591 setIconTextHeight( m_pSettings->iconTextHeight() ); 00592 00593 if ( (itemTextPos() == TQIconView::Right) && (maxItemWidth() != gridXValue()) ) 00594 { 00595 int size = m_size; 00596 m_size = -1; // little trick to force grid change in setIcons 00597 setIcons( size ); // force re-determining all icons 00598 } 00599 else if ( d->bBoostPreview != boostPreview() ) // Update icons if settings for preview icon size have changed 00600 setIcons(m_size); 00601 else if (!bInit) 00602 updateContents(); 00603 return fontChanged; 00604 } 00605 00606 bool KonqIconViewWidget::boostPreview() const 00607 { 00608 if ( m_bDesktop ) return false; 00609 00610 KConfigGroup group( KGlobal::config(), "PreviewSettings" ); 00611 return group.readBoolEntry( "BoostSize", false ); 00612 } 00613 00614 void KonqIconViewWidget::disableSoundPreviews() 00615 { 00616 d->bSoundPreviews = false; 00617 00618 if (d->pSoundPlayer) 00619 d->pSoundPlayer->stop(); 00620 d->pSoundItem = 0; 00621 if (d->pSoundTimer && d->pSoundTimer->isActive()) 00622 d->pSoundTimer->stop(); 00623 } 00624 00625 void KonqIconViewWidget::setIcons( int size, const TQStringList& stopImagePreviewFor ) 00626 { 00627 // size has changed? 00628 bool sizeChanged = (m_size != size); 00629 int oldGridX = gridX(); 00630 m_size = size; 00631 00632 // boost preview option has changed? 00633 bool boost = boostPreview(); 00634 bool previewSizeChanged = ( d->bBoostPreview != boost ); 00635 d->bBoostPreview = boost; 00636 00637 if ( sizeChanged || previewSizeChanged ) 00638 { 00639 int realSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00640 // choose spacing depending on font, but min 5 (due to KFileIVI move limit) 00641 setSpacing( ( m_bDesktop || ( realSize > KIcon::SizeSmall ) ) ? 00642 QMAX( 5, TQFontMetrics(font()).width('n') ) : 0 ); 00643 } 00644 00645 if ( sizeChanged || previewSizeChanged || !stopImagePreviewFor.isEmpty() ) 00646 { 00647 calculateGridX(); 00648 } 00649 bool stopAll = !stopImagePreviewFor.isEmpty() && stopImagePreviewFor.first() == "*"; 00650 00651 // Disable repaints that can be triggered by ivi->setIcon(). Since icons are 00652 // resized in-place, if the icon size is increasing it can happens that the right 00653 // or bottom icons exceed the size of the viewport.. here we prevent the repaint 00654 // event that will be triggered in that case. 00655 bool prevUpdatesState = viewport()->isUpdatesEnabled(); 00656 viewport()->setUpdatesEnabled( false ); 00657 00658 // Do this even if size didn't change, since this is used by refreshMimeTypes... 00659 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) { 00660 KFileIVI * ivi = static_cast<KFileIVI *>( it ); 00661 // Set a normal icon for files that are not thumbnails, and for files 00662 // that are thumbnails but for which it should be stopped 00663 if ( !ivi->isThumbnail() || 00664 sizeChanged || 00665 previewSizeChanged || 00666 stopAll || 00667 mimeTypeMatch( ivi->item()->mimetype(), stopImagePreviewFor ) ) 00668 { 00669 ivi->setIcon( size, ivi->state(), true, false ); 00670 } 00671 else 00672 ivi->invalidateThumb( ivi->state(), true ); 00673 } 00674 00675 // Restore viewport update to previous state 00676 viewport()->setUpdatesEnabled( prevUpdatesState ); 00677 00678 if ( ( sizeChanged || previewSizeChanged || oldGridX != gridX() || 00679 !stopImagePreviewFor.isEmpty() ) && autoArrange() ) 00680 arrangeItemsInGrid( true ); // take new grid into account and repaint 00681 else 00682 viewport()->update(); //Repaint later.. 00683 } 00684 00685 bool KonqIconViewWidget::mimeTypeMatch( const TQString& mimeType, const TQStringList& mimeList ) const 00686 { 00687 // Code duplication from KIO::PreviewJob 00688 KMimeType::Ptr mime = KMimeType::mimeType( mimeType ); 00689 for (TQStringList::ConstIterator mt = mimeList.begin(); mt != mimeList.end(); ++mt) 00690 { 00691 if ( mime->is( *mt ) ) 00692 return true; 00693 // Support for *mt == "image/*" 00694 TQString tmp( mimeType ); 00695 if ( (*mt).endsWith("*") && tmp.replace(TQRegExp("/.*"), "/*") == (*mt) ) 00696 return true; 00697 if ( (*mt) == "text/plain" ) 00698 { 00699 TQVariant textProperty = mime->property( "X-KDE-text" ); 00700 if ( textProperty.type() == TQVariant::Bool && textProperty.toBool() ) 00701 return true; 00702 } 00703 } 00704 return false; 00705 } 00706 00707 void KonqIconViewWidget::setItemTextPos( ItemTextPos pos ) 00708 { 00709 // can't call gridXValue() because this already would need the new itemTextPos() 00710 int sz = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00711 00712 if ( m_bSetGridX ) 00713 if ( pos == TQIconView::Bottom ) 00714 setGridX( QMAX( sz + 50, previewIconSize( sz ) + 13 ) ); 00715 else 00716 { 00717 setMaxItemWidth( QMAX( sz, previewIconSize( sz ) ) + m_pSettings->iconTextWidth() ); 00718 setGridX( -1 ); 00719 } 00720 00721 KIconView::setItemTextPos( pos ); 00722 } 00723 00724 void KonqIconViewWidget::gridValues( int* x, int* y, int* dx, int* dy, 00725 int* nx, int* ny ) 00726 { 00727 int previewSize = previewIconSize( m_size ); 00728 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00729 00730 // Grid size 00731 // as KFileIVI limits to move an icon to x >= 5, y >= 5, we define a grid cell as: 00732 // spacing() must be >= 5 (currently set to 5 in setIcons()) 00733 // horizontal: left spacing() + <width> 00734 // vertical : top spacing(), <height>, bottom spacing() 00735 // The doubled space in y-direction gives a better visual separation and makes it clearer 00736 // to which item the text belongs 00737 *dx = spacing() + QMAX( QMAX( iconSize, previewSize ), m_pSettings->iconTextWidth() ); 00738 int textHeight = iconTextHeight() * fontMetrics().height(); 00739 *dy = spacing() + QMAX( iconSize, previewSize ) + 2 + textHeight + spacing(); 00740 00741 // Icon Area 00742 int w, h; 00743 if ( m_IconRect.isValid() ) { // w and h must be != 0, otherwise we would get a div by zero 00744 *x = m_IconRect.left(); w = m_IconRect.width(); 00745 *y = m_IconRect.top(); h = m_IconRect.height(); 00746 } 00747 else { 00748 *x = 0; w = viewport()->width(); 00749 *y = 0; h = viewport()->height(); 00750 } 00751 00752 // bug:110775 avoid div by zero (happens e.g. when iconTextHeight or iconTextWidth are very large) 00753 if ( *dx > w ) 00754 *dx = w; 00755 00756 if ( *dy > h ) 00757 *dy = h; 00758 00759 *nx = w / *dx; 00760 *ny = h / *dy; 00761 // TODO: Check that items->count() <= nx * ny 00762 00763 // Let have exactly nx columns and ny rows 00764 if(*nx && *ny) { 00765 *dx = w / *nx; 00766 *dy = h / *ny; 00767 } 00768 kdDebug(1203) << "x=" << *x << " y=" << *y << " spacing=" << spacing() << " iconSize=" << iconSize 00769 << " w=" << w << " h=" << h 00770 << " nx=" << *nx << " ny=" << *ny 00771 << " dx=" << *dx << " dy=" << *dy << endl; 00772 } 00773 00774 void KonqIconViewWidget::calculateGridX() 00775 { 00776 if ( m_bSetGridX ) 00777 if ( itemTextPos() == TQIconView::Bottom ) 00778 setGridX( gridXValue() ); 00779 else 00780 { 00781 setMaxItemWidth( gridXValue() ); 00782 setGridX( -1 ); 00783 } 00784 } 00785 00786 int KonqIconViewWidget::gridXValue() const 00787 { 00788 // this method is only used in konqi as filemanager (not desktop) 00789 int sz = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00790 int newGridX; 00791 00792 if ( itemTextPos() == TQIconView::Bottom ) 00793 newGridX = QMAX( sz + 50, previewIconSize( sz ) + 13 ); 00794 else 00795 newGridX = QMAX( sz, previewIconSize( sz ) ) + m_pSettings->iconTextWidth(); 00796 00797 //kdDebug(1203) << "gridXValue: " << newGridX << " sz=" << sz << endl; 00798 return newGridX; 00799 } 00800 00801 void KonqIconViewWidget::refreshMimeTypes() 00802 { 00803 updatePreviewMimeTypes(); 00804 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) 00805 (static_cast<KFileIVI *>( it ))->item()->refreshMimeType(); 00806 setIcons( m_size ); 00807 } 00808 00809 void KonqIconViewWidget::setURL( const KURL &kurl ) 00810 { 00811 stopImagePreview(); 00812 m_url = kurl; 00813 00814 d->pFileTip->setPreview( KGlobalSettings::showFilePreview(m_url) ); 00815 00816 if ( m_url.isLocalFile() ) 00817 m_dotDirectoryPath = m_url.path(1).append( ".directory" ); 00818 else 00819 m_dotDirectoryPath = TQString::null; 00820 } 00821 00822 void KonqIconViewWidget::startImagePreview( const TQStringList &, bool force ) 00823 { 00824 stopImagePreview(); // just in case 00825 00826 // Check config 00827 if ( !KGlobalSettings::showFilePreview( url() ) ) { 00828 kdDebug(1203) << "Previews disabled for protocol " << url().protocol() << endl; 00829 emit imagePreviewFinished(); 00830 return; 00831 } 00832 00833 if ((d->bSoundPreviews = d->previewSettings.contains( "audio/" )) && 00834 !d->pSoundPlayer) 00835 { 00836 KLibFactory *factory = KLibLoader::self()->factory("konq_sound"); 00837 if (factory) 00838 d->pSoundPlayer = static_cast<KonqSoundPlayer *>( 00839 factory->create(TQT_TQOBJECT(this), 0, "KonqSoundPlayer")); 00840 d->bSoundPreviews = (d->pSoundPlayer != 0L); 00841 } 00842 00843 KFileItemList items; 00844 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) 00845 if ( force || !static_cast<KFileIVI *>( it )->hasValidThumbnail() ) 00846 items.append( static_cast<KFileIVI *>( it )->item() ); 00847 00848 bool onlyAudio = true; 00849 for ( TQStringList::ConstIterator it = d->previewSettings.begin(); it != d->previewSettings.end(); ++it ) { 00850 if ( (*it).startsWith( "audio/" ) ) 00851 d->bSoundPreviews = true; 00852 else 00853 onlyAudio = false; 00854 } 00855 00856 if ( items.isEmpty() || onlyAudio ) { 00857 emit imagePreviewFinished(); 00858 return; // don't start the preview job if not really necessary 00859 } 00860 00861 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00862 int size; 00863 00864 d->bBoostPreview = boostPreview(); 00865 size = previewIconSize( iconSize ); 00866 00867 if ( !d->bBoostPreview ) 00868 iconSize /= 2; 00869 00870 d->pPreviewJob = KIO::filePreview( items, size, size, iconSize, 00871 m_pSettings->textPreviewIconTransparency(), true /* scale */, 00872 true /* save */, &(d->previewSettings) ); 00873 connect( d->pPreviewJob, TQT_SIGNAL( gotPreview( const KFileItem *, const TQPixmap & ) ), 00874 this, TQT_SLOT( slotPreview( const KFileItem *, const TQPixmap & ) ) ); 00875 connect( d->pPreviewJob, TQT_SIGNAL( result( KIO::Job * ) ), 00876 this, TQT_SLOT( slotPreviewResult() ) ); 00877 } 00878 00879 void KonqIconViewWidget::stopImagePreview() 00880 { 00881 if (d->pPreviewJob) 00882 { 00883 d->pPreviewJob->kill(); 00884 d->pPreviewJob = 0; 00885 // Now that previews are updated in-place, calling 00886 // arrangeItemsInGrid() here is not needed anymore 00887 } 00888 } 00889 00890 bool KonqIconViewWidget::isPreviewRunning() const 00891 { 00892 return d->pPreviewJob; 00893 } 00894 00895 KFileItemList KonqIconViewWidget::selectedFileItems() 00896 { 00897 KFileItemList lstItems; 00898 00899 TQIconViewItem *it = firstItem(); 00900 for (; it; it = it->nextItem() ) 00901 if ( it->isSelected() ) { 00902 KFileItem *fItem = (static_cast<KFileIVI *>(it))->item(); 00903 lstItems.append( fItem ); 00904 } 00905 return lstItems; 00906 } 00907 00908 void KonqIconViewWidget::slotDropped( TQDropEvent *ev, const TQValueList<TQIconDragItem> & ) 00909 { 00910 // Drop on background 00911 KURL dirURL = url(); 00912 if ( m_rootItem ) { 00913 bool dummy; 00914 dirURL = m_rootItem->mostLocalURL(dummy); 00915 } 00916 KonqOperations::doDrop( m_rootItem /* may be 0L */, dirURL, ev, this ); 00917 } 00918 00919 void KonqIconViewWidget::slotAboutToCreate(const TQPoint &, const TQValueList<KIO::CopyInfo> &) 00920 { 00921 // Do nothing :-) 00922 } 00923 00924 void KonqIconViewWidget::drawBackground( TQPainter *p, const TQRect &r ) 00925 { 00926 drawBackground(p, r, r.topLeft()); 00927 } 00928 00929 void KonqIconViewWidget::drawBackground( TQPainter *p, const TQRect &r , const TQPoint &pt) 00930 { 00931 const TQPixmap *pm = backgroundPixmap(); 00932 bool hasPixmap = pm && !pm->isNull(); 00933 if ( !hasPixmap ) { 00934 pm = viewport()->backgroundPixmap(); 00935 hasPixmap = pm && !pm->isNull(); 00936 } 00937 00938 TQRect rtgt(r); 00939 rtgt.moveTopLeft(pt); 00940 if (!hasPixmap && backgroundMode() != NoBackground) { 00941 p->fillRect(rtgt, viewport()->backgroundColor()); 00942 return; 00943 } 00944 00945 if (hasPixmap) { 00946 int ax = (r.x() + contentsX() + leftMargin()) % pm->width(); 00947 int ay = (r.y() + contentsY() + topMargin()) % pm->height(); 00948 p->drawTiledPixmap(rtgt, *pm, TQPoint(ax, ay)); 00949 } 00950 } 00951 00952 TQDragObject * KonqIconViewWidget::dragObject() 00953 { 00954 if ( !currentItem() ) 00955 return 0; 00956 00957 return konqDragObject( viewport() ); 00958 } 00959 00960 KonqIconDrag * KonqIconViewWidget::konqDragObject( TQWidget * dragSource ) 00961 { 00962 //kdDebug(1203) << "KonqIconViewWidget::konqDragObject" << endl; 00963 00964 KonqIconDrag2 * drag = new KonqIconDrag2( dragSource ); 00965 TQIconViewItem *primaryItem = currentItem(); 00966 // Append all items to the drag object 00967 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) { 00968 if ( it->isSelected() ) { 00969 if (!primaryItem) 00970 primaryItem = it; 00971 KFileItem* fileItem = (static_cast<KFileIVI *>(it))->item(); 00972 KURL url = fileItem->url(); 00973 bool dummy; 00974 KURL mostLocalURL = fileItem->mostLocalURL(dummy); 00975 TQString itemURL = KURLDrag::urlToString(url); 00976 kdDebug(1203) << "itemURL=" << itemURL << endl; 00977 TQIconDragItem id; 00978 id.setData( TQCString(itemURL.latin1()) ); 00979 drag->append( id, 00980 TQRect( it->pixmapRect(false).topLeft() - m_mousePos, 00981 it->pixmapRect().size() ), 00982 TQRect( it->textRect(false).topLeft() - m_mousePos, 00983 it->textRect().size() ), 00984 itemURL, mostLocalURL ); 00985 } 00986 } 00987 00988 if (primaryItem) 00989 drag->setPixmap( *primaryItem->pixmap(), m_mousePos - primaryItem->pixmapRect(false).topLeft() ); 00990 00991 return drag; 00992 } 00993 00994 void KonqIconViewWidget::contentsDragEnterEvent( TQDragEnterEvent *e ) 00995 { 00996 if ( e->provides( "text/uri-list" ) ) 00997 { 00998 TQByteArray payload = e->encodedData( "text/uri-list" ); 00999 if ( !payload.size() ) 01000 kdError() << "Empty data !" << endl; 01001 // Cache the URLs, since we need them every time we move over a file 01002 // (see KFileIVI) 01003 bool ok = KURLDrag::decode( e, m_lstDragURLs ); 01004 if( !ok ) 01005 kdError() << "Couldn't decode urls dragged !" << endl; 01006 } 01007 01008 KURL::List uriList; 01009 if ( KURLDrag::decode(e, uriList) ) 01010 { 01011 if ( uriList.first().protocol() == "programs" ) 01012 { 01013 e->ignore(); 01014 emit dragEntered( false ); 01015 d->bProgramsURLdrag = true; 01016 return; 01017 } 01018 } 01019 01020 KIconView::contentsDragEnterEvent( e ); 01021 emit dragEntered( true /*accepted*/ ); 01022 } 01023 01024 void KonqIconViewWidget::contentsDragMoveEvent( TQDragMoveEvent *e ) 01025 { 01026 if ( d->bProgramsURLdrag ) { 01027 emit dragMove( false ); 01028 e->ignore(); 01029 cancelPendingHeldSignal(); 01030 return; 01031 } 01032 01033 TQIconViewItem *item = findItem( e->pos() ); 01034 if ( e->source() != viewport() && 01035 !item && m_rootItem && !m_rootItem->isWritable() ) { 01036 emit dragMove( false ); 01037 e->ignore(); 01038 cancelPendingHeldSignal(); 01039 return; 01040 } 01041 emit dragMove( true ); 01042 KIconView::contentsDragMoveEvent( e ); 01043 } 01044 01045 void KonqIconViewWidget::contentsDragLeaveEvent( TQDragLeaveEvent *e ) 01046 { 01047 d->bProgramsURLdrag = false; 01048 KIconView::contentsDragLeaveEvent(e); 01049 emit dragLeft(); 01050 } 01051 01052 01053 void KonqIconViewWidget::setItemColor( const TQColor &c ) 01054 { 01055 iColor = c; 01056 } 01057 01058 TQColor KonqIconViewWidget::itemColor() const 01059 { 01060 return iColor; 01061 } 01062 01063 void KonqIconViewWidget::disableIcons( const KURL::List & lst ) 01064 { 01065 for ( TQIconViewItem *kit = firstItem(); kit; kit = kit->nextItem() ) 01066 { 01067 bool bFound = false; 01068 // Wow. This is ugly. Matching two lists together.... 01069 // Some sorting to optimise this would be a good idea ? 01070 for (KURL::List::ConstIterator it = lst.begin(); !bFound && it != lst.end(); ++it) 01071 { 01072 if ( static_cast<KFileIVI *>( kit )->item()->url() == *it ) 01073 { 01074 bFound = true; 01075 // maybe remove "it" from lst here ? 01076 } 01077 } 01078 static_cast<KFileIVI *>( kit )->setDisabled( bFound ); 01079 } 01080 } 01081 01082 void KonqIconViewWidget::slotSelectionChanged() 01083 { 01084 // This code is very related to ListViewBrowserExtension::updateActions 01085 int canCopy = 0; 01086 int canDel = 0; 01087 int canTrash = 0; 01088 bool bInTrash = false; 01089 int iCount = 0; 01090 01091 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) 01092 { 01093 if ( it->isSelected() ) 01094 { 01095 iCount++; 01096 canCopy++; 01097 01098 KFileItem *item = ( static_cast<KFileIVI *>( it ) )->item(); 01099 KURL url = item->url(); 01100 TQString local_path = item->localPath(); 01101 01102 if ( url.directory(false) == KGlobalSettings::trashPath() ) 01103 bInTrash = true; 01104 if ( KProtocolInfo::supportsDeleting( url ) ) 01105 canDel++; 01106 if ( !local_path.isEmpty() ) 01107 canTrash++; 01108 } 01109 } 01110 01111 emit enableAction( "cut", canDel > 0 ); 01112 emit enableAction( "copy", canCopy > 0 ); 01113 emit enableAction( "trash", canDel > 0 && !bInTrash && canTrash==canDel ); 01114 emit enableAction( "del", canDel > 0 ); 01115 emit enableAction( "properties", iCount > 0 && KPropertiesDialog::canDisplay( selectedFileItems() ) ); 01116 emit enableAction( "editMimeType", ( iCount == 1 ) ); 01117 emit enableAction( "rename", ( iCount == 1) && !bInTrash ); 01118 } 01119 01120 void KonqIconViewWidget::renameCurrentItem() 01121 { 01122 if ( currentItem() ) 01123 currentItem()->rename(); 01124 } 01125 01126 void KonqIconViewWidget::renameSelectedItem() 01127 { 01128 kdDebug(1203) << " -- KonqIconViewWidget::renameSelectedItem() -- " << endl; 01129 TQIconViewItem * item = 0L; 01130 TQIconViewItem *it = firstItem(); 01131 for (; it; it = it->nextItem() ) 01132 if ( it->isSelected() && !item ) 01133 { 01134 item = it; 01135 break; 01136 } 01137 if (!item) 01138 { 01139 Q_ASSERT(item); 01140 return; 01141 } 01142 item->rename(); 01143 } 01144 01145 void KonqIconViewWidget::cutSelection() 01146 { 01147 kdDebug(1203) << " -- KonqIconViewWidget::cutSelection() -- " << endl; 01148 KonqIconDrag * obj = konqDragObject( /* no parent ! */ ); 01149 obj->setMoveSelection( true ); 01150 TQApplication::clipboard()->setData( obj ); 01151 } 01152 01153 void KonqIconViewWidget::copySelection() 01154 { 01155 kdDebug(1203) << " -- KonqIconViewWidget::copySelection() -- " << endl; 01156 KonqIconDrag * obj = konqDragObject( /* no parent ! */ ); 01157 TQApplication::clipboard()->setData( obj ); 01158 } 01159 01160 void KonqIconViewWidget::pasteSelection() 01161 { 01162 paste( url() ); 01163 } 01164 01165 void KonqIconViewWidget::paste( const KURL &url ) 01166 { 01167 KonqOperations::doPaste( this, url ); 01168 } 01169 01170 KURL::List KonqIconViewWidget::selectedUrls() 01171 { 01172 return selectedUrls( UserVisibleUrls ); 01173 } 01174 01175 KURL::List KonqIconViewWidget::selectedUrls( UrlFlags flags ) const 01176 { 01177 KURL::List lstURLs; 01178 bool dummy; 01179 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) 01180 if ( it->isSelected() ) { 01181 KFileItem* item = (static_cast<KFileIVI *>( it ))->item(); 01182 lstURLs.append( flags == MostLocalUrls ? item->mostLocalURL( dummy ) : item->url() ); 01183 } 01184 return lstURLs; 01185 } 01186 01187 TQRect KonqIconViewWidget::iconArea() const 01188 { 01189 return m_IconRect; 01190 } 01191 01192 void KonqIconViewWidget::setIconArea(const TQRect &rect) 01193 { 01194 m_IconRect = rect; 01195 } 01196 01197 int KonqIconViewWidget::lineupMode() const 01198 { 01199 return m_LineupMode; 01200 } 01201 01202 void KonqIconViewWidget::setLineupMode(int mode) 01203 { 01204 m_LineupMode = mode; 01205 } 01206 01207 bool KonqIconViewWidget::sortDirectoriesFirst() const 01208 { 01209 return m_bSortDirsFirst; 01210 } 01211 01212 void KonqIconViewWidget::setSortDirectoriesFirst( bool b ) 01213 { 01214 m_bSortDirsFirst = b; 01215 } 01216 01217 void KonqIconViewWidget::contentsMouseMoveEvent( TQMouseEvent *e ) 01218 { 01219 if ( (d->pSoundPlayer && d->pSoundPlayer->isPlaying()) || (d->pSoundTimer && d->pSoundTimer->isActive())) 01220 { 01221 // The following call is SO expensive (the ::widgetAt call eats up to 80% 01222 // of the mouse move cpucycles!), so it's mandatory to place that function 01223 // under strict checks, such as d->pSoundPlayer->isPlaying() 01224 if ( TQApplication::widgetAt( TQCursor::pos() ) != topLevelWidget() ) 01225 { 01226 if (d->pSoundPlayer) 01227 d->pSoundPlayer->stop(); 01228 d->pSoundItem = 0; 01229 if (d->pSoundTimer && d->pSoundTimer->isActive()) 01230 d->pSoundTimer->stop(); 01231 } 01232 } 01233 d->renameItem= false; 01234 KIconView::contentsMouseMoveEvent( e ); 01235 } 01236 01237 void KonqIconViewWidget::contentsDropEvent( TQDropEvent * ev ) 01238 { 01239 TQIconViewItem *i = findItem( ev->pos() ); 01240 KURL::List uriList; 01241 01242 if ( ev->source() != viewport() && 01243 !i && m_rootItem && !m_rootItem->isWritable() ) { 01244 ev->accept( false ); 01245 return; 01246 } 01247 01248 // Short-circuit TQIconView if Ctrl is pressed, so that it's possible 01249 // to drop a file into its own parent widget to copy it. 01250 if ( !i && (ev->action() == TQDropEvent::Copy || ev->action() == TQDropEvent::Link) 01251 && ev->source() && ev->source() == viewport() 01252 && KURLDrag::decode(ev, uriList) && !uriList.isEmpty() 01253 && uriList.first().upURL().url(1) == url().url(1)) 01254 { 01255 // First we need to call TQIconView though, to clear the drag shape 01256 bool bMovable = itemsMovable(); 01257 setItemsMovable(false); // hack ? call it what you want :-) 01258 KIconView::contentsDropEvent( ev ); 01259 setItemsMovable(bMovable); 01260 01261 TQValueList<TQIconDragItem> lst; 01262 slotDropped(ev, lst); 01263 } 01264 else 01265 { 01266 KIconView::contentsDropEvent( ev ); 01267 emit dropped(); // What is this for ? (David) KDE4: remove 01268 } 01269 // Don't do this here, it's too early ! 01270 // slotSaveIconPositions(); 01271 // If we want to save after the new file gets listed, though, 01272 // we could reimplement contentsDropEvent in KDIconView and set m_bNeedSave. Bah. 01273 01274 // This signal is sent last because we need to ensure it is 01275 // taken in account when all the slots triggered by the dropped() signal 01276 // are executed. This way we know that the Drag and Drop is truely finished 01277 emit dragFinished(); 01278 } 01279 01280 void KonqIconViewWidget::doubleClickTimeout() 01281 { 01282 d->renameItem= true; 01283 mousePressChangeValue(); 01284 if ( d->releaseMouseEvent ) 01285 { 01286 TQMouseEvent e( TQEvent::MouseButtonPress,d->mousePos , 1, d->mouseState); 01287 TQIconViewItem* item = findItem( e.pos() ); 01288 KURL url; 01289 if ( item ) 01290 { 01291 url= ( static_cast<KFileIVI *>( item ) )->item()->url(); 01292 bool brenameTrash =false; 01293 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath()))) 01294 brenameTrash = true; 01295 01296 if ( url.isLocalFile() && !brenameTrash && d->renameItem && m_pSettings->renameIconDirectly() && e.button() == Qt::LeftButton && item->textRect( false ).contains(e.pos())) 01297 { 01298 if( d->pActivateDoubleClick->isActive () ) 01299 d->pActivateDoubleClick->stop(); 01300 item->rename(); 01301 m_bMousePressed = false; 01302 } 01303 } 01304 } 01305 else 01306 { 01307 TQMouseEvent e( TQEvent::MouseMove,d->mousePos , 1, d->mouseState); 01308 KIconView::contentsMousePressEvent( &e ); 01309 } 01310 if( d->pActivateDoubleClick->isActive() ) 01311 d->pActivateDoubleClick->stop(); 01312 01313 d->releaseMouseEvent = false; 01314 d->renameItem= false; 01315 } 01316 01317 void KonqIconViewWidget::wheelEvent(TQWheelEvent* e) 01318 { 01319 // when scrolling with mousewheel, stop possible pending filetip 01320 d->pFileTip->setItem( 0 ); 01321 01322 if (e->state() == ControlButton) 01323 { 01324 if (e->delta() >= 0) 01325 { 01326 emit incIconSize(); 01327 } 01328 else 01329 { 01330 emit decIconSize(); 01331 } 01332 e->accept(); 01333 return; 01334 } 01335 01336 KIconView::wheelEvent(e); 01337 } 01338 01339 void KonqIconViewWidget::leaveEvent( TQEvent *e ) 01340 { 01341 // when leaving the widget, stop possible pending filetip and icon effect 01342 slotOnViewport(); 01343 01344 KIconView::leaveEvent(e); 01345 } 01346 01347 void KonqIconViewWidget::mousePressChangeValue() 01348 { 01349 //kdDebug(1203) << "KonqIconViewWidget::contentsMousePressEvent" << endl; 01350 m_bMousePressed = true; 01351 if (d->pSoundPlayer) 01352 d->pSoundPlayer->stop(); 01353 d->bSoundItemClicked = true; 01354 d->firstClick = false; 01355 01356 // Once we click on the item, we don't want a tooltip 01357 // Fixes part of #86968 01358 d->pFileTip->setItem( 0 ); 01359 } 01360 01361 void KonqIconViewWidget::contentsMousePressEvent( TQMouseEvent *e ) 01362 { 01363 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ()) 01364 d->pActivateDoubleClick->stop(); 01365 TQIconViewItem* item = findItem( e->pos() ); 01366 m_mousePos = e->pos(); 01367 KURL url; 01368 if ( item ) 01369 { 01370 url = ( static_cast<KFileIVI *>( item ) )->item()->url(); 01371 bool brenameTrash =false; 01372 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath()))) 01373 brenameTrash = true; 01374 if ( !brenameTrash && !KGlobalSettings::singleClick() && m_pSettings->renameIconDirectly() && e->button() == Qt::LeftButton && item->textRect( false ).contains(e->pos())&& !d->firstClick && url.isLocalFile() && (!url.protocol().find("device", 0, false)==0)) 01375 { 01376 d->firstClick = true; 01377 d->mousePos = e->pos(); 01378 d->mouseState = e->state(); 01379 if (!d->pActivateDoubleClick) 01380 { 01381 d->pActivateDoubleClick = new TQTimer(this); 01382 connect(d->pActivateDoubleClick, TQT_SIGNAL(timeout()), this, TQT_SLOT(doubleClickTimeout())); 01383 } 01384 if( d->pActivateDoubleClick->isActive () ) 01385 d->pActivateDoubleClick->stop(); 01386 else 01387 d->pActivateDoubleClick->start(TQApplication::doubleClickInterval()); 01388 d->releaseMouseEvent = false; 01389 return; 01390 } 01391 else 01392 d->renameItem= false; 01393 } 01394 else 01395 d->renameItem= false; 01396 mousePressChangeValue(); 01397 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive()) 01398 d->pActivateDoubleClick->stop(); 01399 KIconView::contentsMousePressEvent( e ); 01400 01401 } 01402 01403 void KonqIconViewWidget::contentsMouseReleaseEvent( TQMouseEvent *e ) 01404 { 01405 KIconView::contentsMouseReleaseEvent( e ); 01406 if(d->releaseMouseEvent && d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ()) 01407 d->pActivateDoubleClick->stop(); 01408 slotSelectionChanged(); 01409 d->releaseMouseEvent = true; 01410 m_bMousePressed = false; 01411 } 01412 01413 void KonqIconViewWidget::slotSaveIconPositions() 01414 { 01415 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01416 // This code is currently not used but left in for compatibility reasons. 01417 // It can be removed in KDE 4.0 01418 // Saving of desktop icon positions is now done in KDIconView::saveIconPositions() 01419 // in kdebase/kdesktop/kdiconview.cc 01420 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01421 01422 if ( m_dotDirectoryPath.isEmpty() ) 01423 return; 01424 if ( !m_bDesktop ) 01425 return; // Currently not available in Konqueror 01426 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions" << endl; 01427 KSimpleConfig dotDirectory( m_dotDirectoryPath ); 01428 TQIconViewItem *it = firstItem(); 01429 if ( !it ) 01430 return; // No more icons. Maybe we're closing and they've been removed already 01431 while ( it ) 01432 { 01433 KFileIVI *ivi = static_cast<KFileIVI *>( it ); 01434 KFileItem *item = ivi->item(); 01435 01436 dotDirectory.setGroup( TQString( m_iconPositionGroupPrefix ).append( item->url().fileName() ) ); 01437 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions " << item->url().fileName() << " " << it->x() << " " << it->y() << endl; 01438 dotDirectory.writeEntry( TQString( "X %1" ).arg( width() ), it->x() ); 01439 dotDirectory.writeEntry( TQString( "Y %1" ).arg( height() ), it->y() ); 01440 dotDirectory.writeEntry( "Exists", true ); 01441 01442 it = it->nextItem(); 01443 } 01444 01445 TQStringList groups = dotDirectory.groupList(); 01446 TQStringList::ConstIterator gIt = groups.begin(); 01447 TQStringList::ConstIterator gEnd = groups.end(); 01448 for (; gIt != gEnd; ++gIt ) 01449 if ( (*gIt).left( m_iconPositionGroupPrefix.length() ) == m_iconPositionGroupPrefix ) 01450 { 01451 dotDirectory.setGroup( *gIt ); 01452 if ( dotDirectory.hasKey( "Exists" ) ) 01453 dotDirectory.deleteEntry( "Exists", false ); 01454 else 01455 { 01456 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions deleting group " << *gIt << endl; 01457 dotDirectory.deleteGroup( *gIt ); 01458 } 01459 } 01460 01461 dotDirectory.sync(); 01462 01463 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01464 // This code is currently not used but left in for compatibility reasons. 01465 // It can be removed in KDE 4.0 01466 // Saving of desktop icon positions is now done in KDIconView::saveIconPositions() 01467 // in kdebase/kdesktop/kdiconview.cc 01468 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01469 } 01470 01471 // Adapted version of TQIconView::insertInGrid, that works relative to 01472 // m_IconRect, instead of the entire viewport. 01473 01474 void KonqIconViewWidget::insertInGrid(TQIconViewItem *item) 01475 { 01476 if (0L == item) 01477 return; 01478 01479 if (!m_IconRect.isValid()) 01480 { 01481 KIconView::insertInGrid(item); 01482 return; 01483 } 01484 01485 TQRegion r(m_IconRect); 01486 TQIconViewItem *i = firstItem(); 01487 int y = -1; 01488 for (; i; i = i->nextItem() ) 01489 { 01490 r = r.subtract(i->rect()); 01491 y = QMAX(y, i->y() + i->height()); 01492 } 01493 01494 TQMemArray<TQRect> rects = r.rects(); 01495 TQMemArray<TQRect>::Iterator it = rects.begin(); 01496 bool foundPlace = FALSE; 01497 for (; it != rects.end(); ++it) 01498 { 01499 TQRect rect = *it; 01500 if (rect.width() >= item->width() && rect.height() >= item->height()) 01501 { 01502 int sx = 0, sy = 0; 01503 if (rect.width() >= item->width() + spacing()) 01504 sx = spacing(); 01505 if (rect.height() >= item->height() + spacing()) 01506 sy = spacing(); 01507 item->move(rect.x() + sx, rect.y() + sy); 01508 foundPlace = true; 01509 break; 01510 } 01511 } 01512 01513 if (!foundPlace) 01514 item->move(m_IconRect.topLeft()); 01515 01516 //item->dirty = false; 01517 return; 01518 } 01519 01520 01521 /* 01522 * The algorithm used for lineing up the icons could be called 01523 * "beating flat the icon field". Imagine the icon field to be some height 01524 * field on a regular grid, with the height being the number of icons in 01525 * each grid element. Now imagine slamming on the field with a shovel or 01526 * some other flat surface. The high peaks will be flattened and spread out 01527 * over their adjacent areas. This is basically what the algorithm tries to 01528 * simulate. 01529 * 01530 * First, the icons are binned to a grid of the desired size. If all bins 01531 * are containing at most one icon, we're done, of course. We just have to 01532 * move all icons to the center of each grid element. 01533 * For each bin which has more than one icon in it, we calculate 4 01534 * "friction coefficients", one for each cardinal direction. The friction 01535 * coefficient of a direction is the number of icons adjacent in that 01536 * direction. The idea is that this number is somewhat a measure in which 01537 * direction the icons should flow: icons flow in the direction of lowest 01538 * friction coefficient. We move a maximum of one icon per bin and loop over 01539 * all bins. This procedure is repeated some maximum number of times or until 01540 * no icons are moved anymore. 01541 * 01542 * I don't know if this algorithm is good or bad, I don't even know if it will 01543 * work all the time. It seems a correct thing to do, however, and it seems to 01544 * work particularly well. In any case, the number of runs is limited so there 01545 * can be no races. 01546 */ 01547 01548 void KonqIconViewWidget::lineupIcons() 01549 { 01550 // even if there are no items yet, calculate the maxItemWidth to have the correct 01551 // item rect when we insert new items 01552 01553 // Create a grid of (ny x nx) bins. 01554 int x0, y0, dx, dy, nx, ny; 01555 gridValues( &x0, &y0, &dx, &dy, &nx, &ny ); 01556 01557 int itemWidth = dx - spacing(); 01558 bool newItemWidth = false; 01559 if ( maxItemWidth() != itemWidth ) { 01560 newItemWidth = true; 01561 setMaxItemWidth( itemWidth ); 01562 setFont( font() ); // Force calcRect() 01563 } 01564 01565 if ( !firstItem() ) { 01566 kdDebug(1203) << "No icons at all ?\n"; 01567 return; 01568 } 01569 01570 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 01571 01572 typedef TQValueList<TQIconViewItem*> Bin; 01573 Bin*** bins = new Bin**[nx]; 01574 int i; 01575 int j; 01576 for ( i = 0; i < nx ; i++ ) { 01577 bins[i] = new Bin*[ny]; 01578 for ( j = 0; j < ny; j++ ) 01579 bins[i][j] = 0L; 01580 } 01581 01582 // Insert items into grid 01583 int textHeight = iconTextHeight() * fontMetrics().height(); 01584 01585 for ( TQIconViewItem* item = firstItem(); item; item = item->nextItem() ) { 01586 int x = item->x() + item->width() / 2 - x0; 01587 int y = item->pixmapRect( false ).bottom() - iconSize / 2 01588 - ( dy - ( iconSize + textHeight ) ) / 2 - y0; 01589 int posX = QMIN( nx-1, QMAX( 0, x / dx ) ); 01590 int posY = QMIN( ny-1, QMAX( 0, y / dy ) ); 01591 01592 if ( !bins[posX][posY] ) 01593 bins[posX][posY] = new Bin; 01594 bins[posX][posY]->prepend( item ); 01595 } 01596 01597 // The shuffle code 01598 int n, k; 01599 const int infinity = 10000; 01600 int nmoves = 1; 01601 for ( n = 0; n < 30 && nmoves > 0; n++ ) { 01602 nmoves = 0; 01603 for ( i = 0; i < nx; i++ ) { 01604 for ( j = 0; j < ny; j++ ) { 01605 if ( !bins[i][j] || ( bins[i][j]->count() <= 1 ) ) 01606 continue; 01607 01608 // Calculate the 4 "friction coefficients". 01609 int tf = 0, bf = 0, lf = 0, rf = 0; 01610 for ( k = j-1; k >= 0 && bins[i][k] && bins[i][k]->count(); k-- ) 01611 tf += bins[i][k]->count(); 01612 if ( k == -1 ) 01613 tf += infinity; 01614 01615 for ( k = j+1; k < ny && bins[i][k] && bins[i][k]->count(); k++ ) 01616 bf += bins[i][k]->count(); 01617 if ( k == ny ) 01618 bf += infinity; 01619 01620 for ( k = i-1; k >= 0 && bins[k][j] && bins[k][j]->count(); k-- ) 01621 lf += bins[k][j]->count(); 01622 if ( k == -1 ) 01623 lf += infinity; 01624 01625 for ( k = i+1; k < nx && bins[k][j] && bins[k][j]->count(); k++ ) 01626 rf += bins[k][j]->count(); 01627 if ( k == nx ) 01628 rf += infinity; 01629 01630 // If we are stuck between walls, continue 01631 if ( tf >= infinity && bf >= infinity && 01632 lf >= infinity && rf >= infinity ) 01633 continue; 01634 01635 // Is there a preferred lineup direction? 01636 if ( m_LineupMode == LineupHorizontal ) { 01637 tf += infinity; 01638 bf += infinity; 01639 } 01640 else if ( m_LineupMode == LineupVertical ) { 01641 lf += infinity; 01642 rf += infinity; 01643 } 01644 01645 // Move one item in the direction of the least friction 01646 TQIconViewItem* movedItem; 01647 Bin* items = bins[i][j]; 01648 01649 int mini = QMIN( QMIN( tf, bf ), QMIN( lf, rf ) ); 01650 if ( tf == mini ) { 01651 // move top item in (i,j) to (i,j-1) 01652 Bin::iterator it = items->begin(); 01653 movedItem = *it; 01654 for ( ++it; it != items->end(); ++it ) { 01655 if ( (*it)->y() < movedItem->y() ) 01656 movedItem = *it; 01657 } 01658 items->remove( movedItem ); 01659 if ( !bins[i][j-1] ) 01660 bins[i][j-1] = new Bin; 01661 bins[i][j-1]->prepend( movedItem ); 01662 } 01663 else if ( bf ==mini ) { 01664 // move bottom item in (i,j) to (i,j+1) 01665 Bin::iterator it = items->begin(); 01666 movedItem = *it; 01667 for ( ++it; it != items->end(); ++it ) { 01668 if ( (*it)->y() > movedItem->y() ) 01669 movedItem = *it; 01670 } 01671 items->remove( movedItem ); 01672 if ( !bins[i][j+1] ) 01673 bins[i][j+1] = new Bin; 01674 bins[i][j+1]->prepend( movedItem ); 01675 } 01676 else if ( lf == mini ) 01677 { 01678 // move left item in (i,j) to (i-1,j) 01679 Bin::iterator it = items->begin(); 01680 movedItem = *it; 01681 for ( ++it; it != items->end(); ++it ) { 01682 if ( (*it)->x() < movedItem->x() ) 01683 movedItem = *it; 01684 } 01685 items->remove( movedItem ); 01686 if ( !bins[i-1][j] ) 01687 bins[i-1][j] = new Bin; 01688 bins[i-1][j]->prepend( movedItem ); 01689 } 01690 else { 01691 // move right item in (i,j) to (i+1,j) 01692 Bin::iterator it = items->begin(); 01693 movedItem = *it; 01694 for ( ++it; it != items->end(); ++it ) { 01695 if ( (*it)->x() > movedItem->x() ) 01696 movedItem = *it; 01697 } 01698 items->remove( movedItem ); 01699 if ( !bins[i+1][j] ) 01700 bins[i+1][j] = new Bin; 01701 bins[i+1][j]->prepend( movedItem ); 01702 } 01703 nmoves++; 01704 } 01705 } 01706 } 01707 01708 // Perform the actual moving 01709 TQRegion repaintRegion; 01710 TQValueList<TQIconViewItem*> movedItems; 01711 01712 for ( i = 0; i < nx; i++ ) { 01713 for ( j = 0; j < ny; j++ ) { 01714 Bin* bin = bins[i][j]; 01715 if ( !bin ) 01716 continue; 01717 if ( !bin->isEmpty() ) { 01718 TQIconViewItem* item = bin->first(); 01719 int newX = x0 + i*dx + spacing() + 01720 QMAX(0, ( (dx-spacing()) - item->width() ) / 2); // pixmap can be larger as iconsize 01721 // align all icons vertically to their text 01722 int newY = y0 + j*dy + dy - spacing() - ( item->pixmapRect().bottom() + 2 + textHeight ); 01723 if ( item->x() != newX || item->y() != newY ) { 01724 TQRect oldRect = item->rect(); 01725 movedItems.prepend( item ); 01726 item->move( newX, newY ); 01727 if ( item->rect() != oldRect ) 01728 repaintRegion = repaintRegion.unite( oldRect ); 01729 } 01730 } 01731 delete bin; 01732 bins[i][j] = 0L; 01733 } 01734 } 01735 01736 // repaint 01737 if ( newItemWidth ) 01738 updateContents(); 01739 else { 01740 // Repaint only repaintRegion... 01741 TQMemArray<TQRect> rects = repaintRegion.rects(); 01742 for ( uint l = 0; l < rects.count(); l++ ) { 01743 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << "," 01744 << rects[l].y() << ")\n"; 01745 repaintContents( rects[l], false ); 01746 } 01747 // Repaint icons that were moved 01748 while ( !movedItems.isEmpty() ) { 01749 repaintItem( movedItems.first() ); 01750 movedItems.remove( movedItems.first() ); 01751 } 01752 } 01753 01754 for ( i = 0; i < nx ; i++ ) { 01755 delete [] bins[i]; 01756 } 01757 delete [] bins; 01758 } 01759 01760 void KonqIconViewWidget::lineupIcons( TQIconView::Arrangement arrangement ) 01761 { 01762 int x0, y0, dx, dy, nxmax, nymax; 01763 gridValues( &x0, &y0, &dx, &dy, &nxmax, &nymax ); 01764 int textHeight = iconTextHeight() * fontMetrics().height(); 01765 01766 TQRegion repaintRegion; 01767 TQValueList<TQIconViewItem*> movedItems; 01768 int nx = 0, ny = 0; 01769 01770 TQIconViewItem* item; 01771 for ( item = firstItem(); item; item = item->nextItem() ) { 01772 int newX = x0 + nx*dx + spacing() + 01773 QMAX(0, ( (dx-spacing()) - item->width() ) / 2); // icon can be larger as defined 01774 // align all icons vertically to their text 01775 int newY = y0 + ny*dy + dy - spacing() - ( item->pixmapRect().bottom() + 2 + textHeight ); 01776 if ( item->x() != newX || item->y() != newY ) { 01777 TQRect oldRect = item->rect(); 01778 movedItems.prepend( item ); 01779 item->move( newX, newY ); 01780 if ( item->rect() != oldRect ) 01781 repaintRegion = repaintRegion.unite( oldRect ); 01782 } 01783 if ( arrangement == TQIconView::LeftToRight ) { 01784 nx++; 01785 if ( nx >= nxmax ) { 01786 ny++; 01787 nx = 0; 01788 } 01789 } 01790 else { 01791 ny++; 01792 if ( ny >= nymax ) { 01793 nx++; 01794 ny = 0; 01795 } 01796 } 01797 } 01798 01799 // Repaint only repaintRegion... 01800 TQMemArray<TQRect> rects = repaintRegion.rects(); 01801 for ( uint l = 0; l < rects.count(); l++ ) { 01802 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << "," 01803 << rects[l].y() << ")\n"; 01804 repaintContents( rects[l], false ); 01805 } 01806 // Repaint icons that were moved 01807 while ( !movedItems.isEmpty() ) { 01808 repaintItem( movedItems.first() ); 01809 movedItems.remove( movedItems.first() ); 01810 } 01811 } 01812 01813 int KonqIconViewWidget::largestPreviewIconSize( int size ) const 01814 { 01815 int iconSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 01816 01817 if (iconSize < 28) 01818 return 48; 01819 if (iconSize < 40) 01820 return 64; 01821 if (iconSize < 60) 01822 return 96; 01823 if (iconSize < 120) 01824 return 128; 01825 01826 return 192; 01827 } 01828 01829 int KonqIconViewWidget::previewIconSize( int size ) const 01830 { 01831 int iconSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 01832 01833 if (!d->bBoostPreview) 01834 return iconSize; 01835 01836 return largestPreviewIconSize( iconSize ); 01837 } 01838 01839 void KonqIconViewWidget::visualActivate(TQIconViewItem * item) 01840 { 01841 // Rect of the TQIconViewItem. 01842 TQRect irect = item->rect(); 01843 01844 // Rect of the QIconViewItem's pixmap area. 01845 TQRect rect = item->pixmapRect(); 01846 01847 // Adjust to correct position. If this isn't done, the fact that the 01848 // text may be wider than the pixmap puts us off-centre. 01849 rect.moveBy(irect.x(), irect.y()); 01850 01851 // Adjust for scrolling (David) 01852 rect.moveBy( -contentsX(), -contentsY() ); 01853 01854 if (KGlobalSettings::showKonqIconActivationEffect() == true) { 01855 KIconEffect::visualActivate(viewport(), rect, item->pixmap()); 01856 } 01857 } 01858 01859 void KonqIconViewWidget::backgroundPixmapChange( const TQPixmap & ) 01860 { 01861 viewport()->update(); 01862 } 01863 01864 void KonqIconViewWidget::setPreviewSettings( const TQStringList& settings ) 01865 { 01866 d->previewSettings = settings; 01867 updatePreviewMimeTypes(); 01868 01869 int size = m_size; 01870 m_size = -1; // little trick to force grid change in setIcons 01871 setIcons( size ); // force re-determining all icons 01872 } 01873 01874 const TQStringList& KonqIconViewWidget::previewSettings() 01875 { 01876 return d->previewSettings; 01877 } 01878 01879 void KonqIconViewWidget::setNewURL( const TQString& url ) 01880 { 01881 KURL u; 01882 if ( url.startsWith( "/" ) ) 01883 u.setPath( url ); 01884 else 01885 u = url; 01886 setURL( u ); 01887 } 01888 01889 void KonqIconViewWidget::setCaseInsensitiveSort( bool b ) 01890 { 01891 d->bCaseInsensitive = b; 01892 } 01893 01894 bool KonqIconViewWidget::caseInsensitiveSort() const 01895 { 01896 return d->bCaseInsensitive; 01897 } 01898 01899 bool KonqIconViewWidget::canPreview( KFileItem* item ) 01900 { 01901 if ( !KGlobalSettings::showFilePreview( url() ) ) 01902 return false; 01903 01904 if ( d->pPreviewMimeTypes == 0L ) 01905 updatePreviewMimeTypes(); 01906 01907 return mimeTypeMatch( item->mimetype(), *( d->pPreviewMimeTypes ) ); 01908 } 01909 01910 void KonqIconViewWidget::updatePreviewMimeTypes() 01911 { 01912 if ( d->pPreviewMimeTypes == 0L ) 01913 d->pPreviewMimeTypes = new TQStringList; 01914 else 01915 d->pPreviewMimeTypes->clear(); 01916 01917 // Load the list of plugins to determine which mimetypes are supported 01918 KTrader::OfferList plugins = KTrader::self()->query("ThumbCreator"); 01919 KTrader::OfferList::ConstIterator it; 01920 01921 for ( it = plugins.begin(); it != plugins.end(); ++it ) { 01922 if ( d->previewSettings.contains((*it)->desktopEntryName()) ) { 01923 TQStringList mimeTypes = (*it)->property("MimeTypes").toStringList(); 01924 for (TQStringList::ConstIterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt) 01925 d->pPreviewMimeTypes->append(*mt); 01926 } 01927 } 01928 } 01929 01930 #include "konq_iconviewwidget.moc" 01931 01932 /* vim: set et sw=4 ts=8 softtabstop=4: */