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 <tdeapplication.h> 00037 #include <kdebug.h> 00038 #include <tdeio/previewjob.h> 00039 #include <tdefileivi.h> 00040 #include <konq_settings.h> 00041 #include <konq_drag.h> 00042 #include <tdeglobalsettings.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 <tdelocale.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 TDEIO::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 : TDEIconView( 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 TDEIconView::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, TDEIconView 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) + TDEIO::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 != TDEIcon::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 TDEConfigGroup cfgGroup( TDEGlobal::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 = TDEGlobal::iconLoader()->loadMovie( d->pActiveItem->mouseOverAnimation(), TDEIcon::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 && TDEGlobalSettings::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() == TDEIcon::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() & TDEIcon::HiddenOverlay) { 00431 TQPixmap p(pix); 00432 00433 TDEIconEffect::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 TDEIconLoader 00468 // will happily return a movie with different dimensions than the icon 00469 int iconSize=d->pActiveItem->iconSize(); 00470 if (iconSize==0) iconSize = TDEGlobal::iconLoader()->currentSize( TDEIcon::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 TDEIconView::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 TDEIconView::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 TDEConfigGroup group( TDEGlobal::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 : TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop ); 00640 // choose spacing depending on font, but min 5 (due to KFileIVI move limit) 00641 setSpacing( ( m_bDesktop || ( realSize > TDEIcon::SizeSmall ) ) ? 00642 TQMAX( 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 TDEIO::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-TDE-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 : TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop ); 00711 00712 if ( m_bSetGridX ) { 00713 if ( pos == TQIconView::Bottom ) { 00714 setGridX( TQMAX( sz + 50, previewIconSize( sz ) + 13 ) ); 00715 } 00716 else 00717 { 00718 setMaxItemWidth( TQMAX( sz, previewIconSize( sz ) ) + m_pSettings->iconTextWidth() ); 00719 setGridX( -1 ); 00720 } 00721 } 00722 00723 TDEIconView::setItemTextPos( pos ); 00724 } 00725 00726 void KonqIconViewWidget::gridValues( int* x, int* y, int* dx, int* dy, 00727 int* nx, int* ny ) 00728 { 00729 int previewSize = previewIconSize( m_size ); 00730 int iconSize = m_size ? m_size : TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop ); 00731 00732 // Grid size 00733 // as KFileIVI limits to move an icon to x >= 5, y >= 5, we define a grid cell as: 00734 // spacing() must be >= 5 (currently set to 5 in setIcons()) 00735 // horizontal: left spacing() + <width> 00736 // vertical : top spacing(), <height>, bottom spacing() 00737 // The doubled space in y-direction gives a better visual separation and makes it clearer 00738 // to which item the text belongs 00739 *dx = spacing() + TQMAX( TQMAX( iconSize, previewSize ), m_pSettings->iconTextWidth() ); 00740 int textHeight = iconTextHeight() * fontMetrics().height(); 00741 *dy = spacing() + TQMAX( iconSize, previewSize ) + 2 + textHeight + spacing(); 00742 00743 // Icon Area 00744 int w, h; 00745 if ( m_IconRect.isValid() ) { // w and h must be != 0, otherwise we would get a div by zero 00746 *x = m_IconRect.left(); w = m_IconRect.width(); 00747 *y = m_IconRect.top(); h = m_IconRect.height(); 00748 } 00749 else { 00750 *x = 0; w = viewport()->width(); 00751 *y = 0; h = viewport()->height(); 00752 } 00753 00754 // bug:110775 avoid div by zero (happens e.g. when iconTextHeight or iconTextWidth are very large) 00755 if ( *dx > w ) 00756 *dx = w; 00757 00758 if ( *dy > h ) 00759 *dy = h; 00760 00761 *nx = w / *dx; 00762 *ny = h / *dy; 00763 // TODO: Check that items->count() <= nx * ny 00764 00765 // Let have exactly nx columns and ny rows 00766 if(*nx && *ny) { 00767 *dx = w / *nx; 00768 *dy = h / *ny; 00769 } 00770 kdDebug(1203) << "x=" << *x << " y=" << *y << " spacing=" << spacing() << " iconSize=" << iconSize 00771 << " w=" << w << " h=" << h 00772 << " nx=" << *nx << " ny=" << *ny 00773 << " dx=" << *dx << " dy=" << *dy << endl; 00774 } 00775 00776 void KonqIconViewWidget::calculateGridX() 00777 { 00778 if ( m_bSetGridX ) { 00779 if ( itemTextPos() == TQIconView::Bottom ) { 00780 setGridX( gridXValue() ); 00781 } 00782 else 00783 { 00784 setMaxItemWidth( gridXValue() ); 00785 setGridX( -1 ); 00786 } 00787 } 00788 } 00789 00790 int KonqIconViewWidget::gridXValue() const 00791 { 00792 // this method is only used in konqi as filemanager (not desktop) 00793 int sz = m_size ? m_size : TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop ); 00794 int newGridX; 00795 00796 if ( itemTextPos() == TQIconView::Bottom ) 00797 newGridX = TQMAX( sz + 50, previewIconSize( sz ) + 13 ); 00798 else 00799 newGridX = TQMAX( sz, previewIconSize( sz ) ) + m_pSettings->iconTextWidth(); 00800 00801 //kdDebug(1203) << "gridXValue: " << newGridX << " sz=" << sz << endl; 00802 return newGridX; 00803 } 00804 00805 void KonqIconViewWidget::refreshMimeTypes() 00806 { 00807 updatePreviewMimeTypes(); 00808 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) 00809 (static_cast<KFileIVI *>( it ))->item()->refreshMimeType(); 00810 setIcons( m_size ); 00811 } 00812 00813 void KonqIconViewWidget::setURL( const KURL &kurl ) 00814 { 00815 stopImagePreview(); 00816 m_url = kurl; 00817 00818 d->pFileTip->setPreview( TDEGlobalSettings::showFilePreview(m_url) ); 00819 00820 if ( m_url.isLocalFile() ) 00821 m_dotDirectoryPath = m_url.path(1).append( ".directory" ); 00822 else 00823 m_dotDirectoryPath = TQString::null; 00824 } 00825 00826 void KonqIconViewWidget::startImagePreview( const TQStringList &, bool force ) 00827 { 00828 stopImagePreview(); // just in case 00829 00830 // Check config 00831 if ( !TDEGlobalSettings::showFilePreview( url() ) ) { 00832 kdDebug(1203) << "Previews disabled for protocol " << url().protocol() << endl; 00833 emit imagePreviewFinished(); 00834 return; 00835 } 00836 00837 if ((d->bSoundPreviews = d->previewSettings.contains( "audio/" )) && 00838 !d->pSoundPlayer) 00839 { 00840 KLibFactory *factory = KLibLoader::self()->factory("konq_sound"); 00841 if (factory) 00842 d->pSoundPlayer = static_cast<KonqSoundPlayer *>( 00843 factory->create(TQT_TQOBJECT(this), 0, "KonqSoundPlayer")); 00844 d->bSoundPreviews = (d->pSoundPlayer != 0L); 00845 } 00846 00847 KFileItemList items; 00848 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) 00849 if ( force || !static_cast<KFileIVI *>( it )->hasValidThumbnail() ) 00850 items.append( static_cast<KFileIVI *>( it )->item() ); 00851 00852 bool onlyAudio = true; 00853 for ( TQStringList::ConstIterator it = d->previewSettings.begin(); it != d->previewSettings.end(); ++it ) { 00854 if ( (*it).startsWith( "audio/" ) ) 00855 d->bSoundPreviews = true; 00856 else 00857 onlyAudio = false; 00858 } 00859 00860 if ( items.isEmpty() || onlyAudio ) { 00861 emit imagePreviewFinished(); 00862 return; // don't start the preview job if not really necessary 00863 } 00864 00865 int iconSize = m_size ? m_size : TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop ); 00866 int size; 00867 00868 d->bBoostPreview = boostPreview(); 00869 size = previewIconSize( iconSize ); 00870 00871 if ( !d->bBoostPreview ) 00872 iconSize /= 2; 00873 00874 d->pPreviewJob = TDEIO::filePreview( items, size, size, iconSize, 00875 m_pSettings->textPreviewIconTransparency(), true /* scale */, 00876 true /* save */, &(d->previewSettings) ); 00877 connect( d->pPreviewJob, TQT_SIGNAL( gotPreview( const KFileItem *, const TQPixmap & ) ), 00878 this, TQT_SLOT( slotPreview( const KFileItem *, const TQPixmap & ) ) ); 00879 connect( d->pPreviewJob, TQT_SIGNAL( result( TDEIO::Job * ) ), 00880 this, TQT_SLOT( slotPreviewResult() ) ); 00881 } 00882 00883 void KonqIconViewWidget::stopImagePreview() 00884 { 00885 if (d->pPreviewJob) 00886 { 00887 d->pPreviewJob->kill(); 00888 d->pPreviewJob = 0; 00889 // Now that previews are updated in-place, calling 00890 // arrangeItemsInGrid() here is not needed anymore 00891 } 00892 } 00893 00894 bool KonqIconViewWidget::isPreviewRunning() const 00895 { 00896 return d->pPreviewJob; 00897 } 00898 00899 KFileItemList KonqIconViewWidget::selectedFileItems() 00900 { 00901 KFileItemList lstItems; 00902 00903 TQIconViewItem *it = firstItem(); 00904 for (; it; it = it->nextItem() ) 00905 if ( it->isVisible() && it->isSelected() ) { 00906 KFileItem *fItem = (static_cast<KFileIVI *>(it))->item(); 00907 lstItems.append( fItem ); 00908 } 00909 return lstItems; 00910 } 00911 00912 void KonqIconViewWidget::slotDropped( TQDropEvent *ev, const TQValueList<TQIconDragItem> & ) 00913 { 00914 // Drop on background 00915 KURL dirURL = url(); 00916 if ( m_rootItem ) { 00917 bool dummy; 00918 dirURL = m_rootItem->mostLocalURL(dummy); 00919 } 00920 KonqOperations::doDrop( m_rootItem /* may be 0L */, dirURL, ev, this ); 00921 } 00922 00923 void KonqIconViewWidget::slotAboutToCreate(const TQPoint &, const TQValueList<TDEIO::CopyInfo> &) 00924 { 00925 // Do nothing :-) 00926 } 00927 00928 void KonqIconViewWidget::drawBackground( TQPainter *p, const TQRect &r ) 00929 { 00930 drawBackground(p, r, r.topLeft()); 00931 } 00932 00933 void KonqIconViewWidget::drawBackground( TQPainter *p, const TQRect &r , const TQPoint &pt) 00934 { 00935 const TQPixmap *pm = backgroundPixmap(); 00936 bool hasPixmap = pm && !pm->isNull(); 00937 if ( !hasPixmap ) { 00938 pm = viewport()->backgroundPixmap(); 00939 hasPixmap = pm && !pm->isNull(); 00940 } 00941 00942 TQRect rtgt(r); 00943 rtgt.moveTopLeft(pt); 00944 if (!hasPixmap && backgroundMode() != NoBackground) { 00945 p->fillRect(rtgt, viewport()->backgroundColor()); 00946 return; 00947 } 00948 00949 if (hasPixmap) { 00950 int ax = (r.x() + contentsX() + leftMargin()) % pm->width(); 00951 int ay = (r.y() + contentsY() + topMargin()) % pm->height(); 00952 p->drawTiledPixmap(rtgt, *pm, TQPoint(ax, ay)); 00953 } 00954 } 00955 00956 TQDragObject * KonqIconViewWidget::dragObject() 00957 { 00958 if ( !currentItem() ) 00959 return 0; 00960 00961 return konqDragObject( viewport() ); 00962 } 00963 00964 KonqIconDrag * KonqIconViewWidget::konqDragObject( TQWidget * dragSource ) 00965 { 00966 //kdDebug(1203) << "KonqIconViewWidget::konqDragObject" << endl; 00967 00968 KonqIconDrag2 * drag = new KonqIconDrag2( dragSource ); 00969 TQIconViewItem *primaryItem = currentItem(); 00970 // Append all items to the drag object 00971 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) { 00972 if ( it->isVisible() && it->isSelected() ) { 00973 if (!primaryItem) 00974 primaryItem = it; 00975 KFileItem* fileItem = (static_cast<KFileIVI *>(it))->item(); 00976 KURL url = fileItem->url(); 00977 bool dummy; 00978 KURL mostLocalURL = fileItem->mostLocalURL(dummy); 00979 TQString itemURL = KURLDrag::urlToString(url); 00980 kdDebug(1203) << "itemURL=" << itemURL << endl; 00981 TQIconDragItem id; 00982 id.setData( TQCString(itemURL.latin1()) ); 00983 drag->append( id, 00984 TQRect( it->pixmapRect(false).topLeft() - m_mousePos, 00985 it->pixmapRect().size() ), 00986 TQRect( it->textRect(false).topLeft() - m_mousePos, 00987 it->textRect().size() ), 00988 itemURL, mostLocalURL ); 00989 } 00990 } 00991 00992 if (primaryItem) 00993 drag->setPixmap( *primaryItem->pixmap(), m_mousePos - primaryItem->pixmapRect(false).topLeft() ); 00994 00995 return drag; 00996 } 00997 00998 void KonqIconViewWidget::contentsDragEnterEvent( TQDragEnterEvent *e ) 00999 { 01000 if ( e->provides( "text/uri-list" ) ) 01001 { 01002 TQByteArray payload = e->encodedData( "text/uri-list" ); 01003 if ( !payload.size() ) 01004 kdError() << "Empty data !" << endl; 01005 // Cache the URLs, since we need them every time we move over a file 01006 // (see KFileIVI) 01007 bool ok = KURLDrag::decode( e, m_lstDragURLs ); 01008 if( !ok ) 01009 kdError() << "Couldn't decode urls dragged !" << endl; 01010 } 01011 01012 KURL::List uriList; 01013 if ( KURLDrag::decode(e, uriList) ) 01014 { 01015 if ( uriList.first().protocol() == "programs" ) 01016 { 01017 e->ignore(); 01018 emit dragEntered( false ); 01019 d->bProgramsURLdrag = true; 01020 return; 01021 } 01022 } 01023 01024 TDEIconView::contentsDragEnterEvent( e ); 01025 emit dragEntered( true /*accepted*/ ); 01026 } 01027 01028 void KonqIconViewWidget::contentsDragMoveEvent( TQDragMoveEvent *e ) 01029 { 01030 if ( d->bProgramsURLdrag ) { 01031 emit dragMove( false ); 01032 e->ignore(); 01033 cancelPendingHeldSignal(); 01034 return; 01035 } 01036 01037 TQIconViewItem *item = findItem( e->pos() ); 01038 if ( e->source() != viewport() && 01039 !item && m_rootItem && !m_rootItem->isWritable() ) { 01040 emit dragMove( false ); 01041 e->ignore(); 01042 cancelPendingHeldSignal(); 01043 return; 01044 } 01045 emit dragMove( true ); 01046 TDEIconView::contentsDragMoveEvent( e ); 01047 } 01048 01049 void KonqIconViewWidget::contentsDragLeaveEvent( TQDragLeaveEvent *e ) 01050 { 01051 d->bProgramsURLdrag = false; 01052 TDEIconView::contentsDragLeaveEvent(e); 01053 emit dragLeft(); 01054 } 01055 01056 01057 void KonqIconViewWidget::setItemColor( const TQColor &c ) 01058 { 01059 iColor = c; 01060 } 01061 01062 TQColor KonqIconViewWidget::itemColor() const 01063 { 01064 return iColor; 01065 } 01066 01067 void KonqIconViewWidget::disableIcons( const KURL::List & lst ) 01068 { 01069 for ( TQIconViewItem *kit = firstItem(); kit; kit = kit->nextItem() ) 01070 { 01071 bool bFound = false; 01072 // Wow. This is ugly. Matching two lists together.... 01073 // Some sorting to optimise this would be a good idea ? 01074 for (KURL::List::ConstIterator it = lst.begin(); !bFound && it != lst.end(); ++it) 01075 { 01076 if ( static_cast<KFileIVI *>( kit )->item()->url() == *it ) 01077 { 01078 bFound = true; 01079 // maybe remove "it" from lst here ? 01080 } 01081 } 01082 static_cast<KFileIVI *>( kit )->setDisabled( bFound ); 01083 } 01084 } 01085 01086 void KonqIconViewWidget::slotSelectionChanged() 01087 { 01088 // This code is very related to ListViewBrowserExtension::updateActions 01089 int canCopy = 0; 01090 int canDel = 0; 01091 int canTrash = 0; 01092 bool bInTrash = false; 01093 int iCount = 0; 01094 01095 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) 01096 { 01097 if ( it->isVisible() && it->isSelected() ) 01098 { 01099 iCount++; 01100 canCopy++; 01101 01102 KFileItem *item = ( static_cast<KFileIVI *>( it ) )->item(); 01103 KURL url = item->url(); 01104 TQString local_path = item->localPath(); 01105 01106 if ( url.directory(false) == TDEGlobalSettings::trashPath() ) { 01107 bInTrash = true; 01108 } 01109 if ( KProtocolInfo::supportsDeleting( url ) ) { 01110 canDel++; 01111 } 01112 if ( !local_path.isEmpty() ) { 01113 canTrash++; 01114 } 01115 } 01116 } 01117 01118 emit enableAction( "cut", canDel > 0 ); 01119 emit enableAction( "copy", canCopy > 0 ); 01120 emit enableAction( "trash", canDel > 0 && !bInTrash && canTrash==canDel ); 01121 emit enableAction( "del", canDel > 0 ); 01122 emit enableAction( "properties", iCount > 0 && KPropertiesDialog::canDisplay( selectedFileItems() ) ); 01123 emit enableAction( "editMimeType", ( iCount == 1 ) ); 01124 emit enableAction( "rename", ( iCount == 1) && !bInTrash ); 01125 } 01126 01127 void KonqIconViewWidget::renameCurrentItem() 01128 { 01129 if ( currentItem() ) 01130 currentItem()->rename(); 01131 } 01132 01133 void KonqIconViewWidget::renameSelectedItem() 01134 { 01135 kdDebug(1203) << " -- KonqIconViewWidget::renameSelectedItem() -- " << endl; 01136 TQIconViewItem * item = 0L; 01137 TQIconViewItem *it = firstItem(); 01138 for (; it; it = it->nextItem() ) 01139 if ( it->isVisible() && it->isSelected() && !item ) 01140 { 01141 item = it; 01142 break; 01143 } 01144 if (!item) 01145 { 01146 Q_ASSERT(item); 01147 return; 01148 } 01149 item->rename(); 01150 } 01151 01152 void KonqIconViewWidget::cutSelection() 01153 { 01154 kdDebug(1203) << " -- KonqIconViewWidget::cutSelection() -- " << endl; 01155 KonqIconDrag * obj = konqDragObject( /* no parent ! */ ); 01156 obj->setMoveSelection( true ); 01157 TQApplication::clipboard()->setData( obj ); 01158 } 01159 01160 void KonqIconViewWidget::copySelection() 01161 { 01162 kdDebug(1203) << " -- KonqIconViewWidget::copySelection() -- " << endl; 01163 KonqIconDrag * obj = konqDragObject( /* no parent ! */ ); 01164 TQApplication::clipboard()->setData( obj ); 01165 } 01166 01167 void KonqIconViewWidget::pasteSelection() 01168 { 01169 paste( url() ); 01170 } 01171 01172 void KonqIconViewWidget::paste( const KURL &url ) 01173 { 01174 KonqOperations::doPaste( this, url ); 01175 } 01176 01177 KURL::List KonqIconViewWidget::selectedUrls() 01178 { 01179 return selectedUrls( UserVisibleUrls ); 01180 } 01181 01182 KURL::List KonqIconViewWidget::selectedUrls( UrlFlags flags ) const 01183 { 01184 KURL::List lstURLs; 01185 bool dummy; 01186 for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) 01187 if ( it->isVisible() && it->isSelected() ) { 01188 KFileItem* item = (static_cast<KFileIVI *>( it ))->item(); 01189 lstURLs.append( flags == MostLocalUrls ? item->mostLocalURL( dummy ) : item->url() ); 01190 } 01191 return lstURLs; 01192 } 01193 01194 TQRect KonqIconViewWidget::iconArea() const 01195 { 01196 return m_IconRect; 01197 } 01198 01199 void KonqIconViewWidget::setIconArea(const TQRect &rect) 01200 { 01201 m_IconRect = rect; 01202 } 01203 01204 int KonqIconViewWidget::lineupMode() const 01205 { 01206 return m_LineupMode; 01207 } 01208 01209 void KonqIconViewWidget::setLineupMode(int mode) 01210 { 01211 m_LineupMode = mode; 01212 } 01213 01214 bool KonqIconViewWidget::sortDirectoriesFirst() const 01215 { 01216 return m_bSortDirsFirst; 01217 } 01218 01219 void KonqIconViewWidget::setSortDirectoriesFirst( bool b ) 01220 { 01221 m_bSortDirsFirst = b; 01222 } 01223 01224 void KonqIconViewWidget::contentsMouseMoveEvent( TQMouseEvent *e ) 01225 { 01226 if ( (d->pSoundPlayer && d->pSoundPlayer->isPlaying()) || (d->pSoundTimer && d->pSoundTimer->isActive())) 01227 { 01228 // The following call is SO expensive (the ::widgetAt call eats up to 80% 01229 // of the mouse move cpucycles!), so it's mandatory to place that function 01230 // under strict checks, such as d->pSoundPlayer->isPlaying() 01231 if ( TQApplication::widgetAt( TQCursor::pos() ) != topLevelWidget() ) 01232 { 01233 if (d->pSoundPlayer) 01234 d->pSoundPlayer->stop(); 01235 d->pSoundItem = 0; 01236 if (d->pSoundTimer && d->pSoundTimer->isActive()) 01237 d->pSoundTimer->stop(); 01238 } 01239 } 01240 d->renameItem= false; 01241 TDEIconView::contentsMouseMoveEvent( e ); 01242 } 01243 01244 void KonqIconViewWidget::contentsDropEvent( TQDropEvent * ev ) 01245 { 01246 TQIconViewItem *i = findItem( ev->pos() ); 01247 KURL::List uriList; 01248 01249 if ( ev->source() != viewport() && 01250 !i && m_rootItem && !m_rootItem->isWritable() ) { 01251 ev->accept( false ); 01252 return; 01253 } 01254 01255 // Short-circuit TQIconView if Ctrl is pressed, so that it's possible 01256 // to drop a file into its own parent widget to copy it. 01257 if ( !i && (ev->action() == TQDropEvent::Copy || ev->action() == TQDropEvent::Link) 01258 && ev->source() && ev->source() == viewport() 01259 && KURLDrag::decode(ev, uriList) && !uriList.isEmpty() 01260 && uriList.first().upURL().url(1) == url().url(1)) 01261 { 01262 // First we need to call TQIconView though, to clear the drag shape 01263 bool bMovable = itemsMovable(); 01264 setItemsMovable(false); // hack ? call it what you want :-) 01265 TDEIconView::contentsDropEvent( ev ); 01266 setItemsMovable(bMovable); 01267 01268 TQValueList<TQIconDragItem> lst; 01269 slotDropped(ev, lst); 01270 } 01271 else 01272 { 01273 TDEIconView::contentsDropEvent( ev ); 01274 emit dropped(); // What is this for ? (David) KDE4: remove 01275 } 01276 // Don't do this here, it's too early ! 01277 // slotSaveIconPositions(); 01278 // If we want to save after the new file gets listed, though, 01279 // we could reimplement contentsDropEvent in KDIconView and set m_bNeedSave. Bah. 01280 01281 // This signal is sent last because we need to ensure it is 01282 // taken in account when all the slots triggered by the dropped() signal 01283 // are executed. This way we know that the Drag and Drop is truely finished 01284 emit dragFinished(); 01285 } 01286 01287 void KonqIconViewWidget::doubleClickTimeout() 01288 { 01289 d->renameItem= true; 01290 mousePressChangeValue(); 01291 if ( d->releaseMouseEvent ) 01292 { 01293 TQMouseEvent e( TQEvent::MouseButtonPress,d->mousePos , 1, d->mouseState); 01294 TQIconViewItem* item = findItem( e.pos() ); 01295 KURL url; 01296 if ( item ) 01297 { 01298 url= ( static_cast<KFileIVI *>( item ) )->item()->url(); 01299 bool brenameTrash =false; 01300 if ( url.isLocalFile() && (url.directory(false) == TDEGlobalSettings::trashPath() || url.path(1).startsWith(TDEGlobalSettings::trashPath()))) 01301 brenameTrash = true; 01302 01303 if ( url.isLocalFile() && !brenameTrash && d->renameItem && m_pSettings->renameIconDirectly() && e.button() == Qt::LeftButton && item->textRect( false ).contains(e.pos())) 01304 { 01305 if( d->pActivateDoubleClick->isActive () ) 01306 d->pActivateDoubleClick->stop(); 01307 item->rename(); 01308 m_bMousePressed = false; 01309 } 01310 } 01311 } 01312 else 01313 { 01314 TQMouseEvent e( TQEvent::MouseMove,d->mousePos , 1, d->mouseState); 01315 TDEIconView::contentsMousePressEvent( &e ); 01316 } 01317 if( d->pActivateDoubleClick->isActive() ) 01318 d->pActivateDoubleClick->stop(); 01319 01320 d->releaseMouseEvent = false; 01321 d->renameItem= false; 01322 } 01323 01324 void KonqIconViewWidget::wheelEvent(TQWheelEvent* e) 01325 { 01326 // when scrolling with mousewheel, stop possible pending filetip 01327 d->pFileTip->setItem( 0 ); 01328 01329 if (e->state() == ControlButton) 01330 { 01331 if (e->delta() >= 0) 01332 { 01333 emit incIconSize(); 01334 } 01335 else 01336 { 01337 emit decIconSize(); 01338 } 01339 e->accept(); 01340 return; 01341 } 01342 01343 TDEIconView::wheelEvent(e); 01344 } 01345 01346 void KonqIconViewWidget::leaveEvent( TQEvent *e ) 01347 { 01348 // when leaving the widget, stop possible pending filetip and icon effect 01349 slotOnViewport(); 01350 01351 TDEIconView::leaveEvent(e); 01352 } 01353 01354 void KonqIconViewWidget::mousePressChangeValue() 01355 { 01356 //kdDebug(1203) << "KonqIconViewWidget::contentsMousePressEvent" << endl; 01357 m_bMousePressed = true; 01358 if (d->pSoundPlayer) 01359 d->pSoundPlayer->stop(); 01360 d->bSoundItemClicked = true; 01361 d->firstClick = false; 01362 01363 // Once we click on the item, we don't want a tooltip 01364 // Fixes part of #86968 01365 d->pFileTip->setItem( 0 ); 01366 } 01367 01368 void KonqIconViewWidget::contentsMousePressEvent( TQMouseEvent *e ) 01369 { 01370 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ()) 01371 d->pActivateDoubleClick->stop(); 01372 TQIconViewItem* item = findItem( e->pos() ); 01373 m_mousePos = e->pos(); 01374 KURL url; 01375 if ( item ) 01376 { 01377 url = ( static_cast<KFileIVI *>( item ) )->item()->url(); 01378 bool brenameTrash =false; 01379 if ( url.isLocalFile() && (url.directory(false) == TDEGlobalSettings::trashPath() || url.path(1).startsWith(TDEGlobalSettings::trashPath()))) 01380 brenameTrash = true; 01381 if ( !brenameTrash && !TDEGlobalSettings::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)) 01382 { 01383 d->firstClick = true; 01384 d->mousePos = e->pos(); 01385 d->mouseState = e->state(); 01386 if (!d->pActivateDoubleClick) 01387 { 01388 d->pActivateDoubleClick = new TQTimer(this); 01389 connect(d->pActivateDoubleClick, TQT_SIGNAL(timeout()), this, TQT_SLOT(doubleClickTimeout())); 01390 } 01391 if( d->pActivateDoubleClick->isActive () ) 01392 d->pActivateDoubleClick->stop(); 01393 else 01394 d->pActivateDoubleClick->start(TQApplication::doubleClickInterval()); 01395 d->releaseMouseEvent = false; 01396 return; 01397 } 01398 else 01399 d->renameItem= false; 01400 } 01401 else 01402 d->renameItem= false; 01403 mousePressChangeValue(); 01404 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive()) 01405 d->pActivateDoubleClick->stop(); 01406 TDEIconView::contentsMousePressEvent( e ); 01407 01408 } 01409 01410 void KonqIconViewWidget::contentsMouseReleaseEvent( TQMouseEvent *e ) 01411 { 01412 TDEIconView::contentsMouseReleaseEvent( e ); 01413 if(d->releaseMouseEvent && d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ()) 01414 d->pActivateDoubleClick->stop(); 01415 slotSelectionChanged(); 01416 d->releaseMouseEvent = true; 01417 m_bMousePressed = false; 01418 } 01419 01420 void KonqIconViewWidget::slotSaveIconPositions() 01421 { 01422 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01423 // This code is currently not used but left in for compatibility reasons. 01424 // It can be removed in KDE 4.0 01425 // Saving of desktop icon positions is now done in KDIconView::saveIconPositions() 01426 // in tdebase/kdesktop/kdiconview.cc 01427 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01428 01429 printf("WARNING: Strongly deprecated method KonqIconViewWidget::slotSaveIconPositions() called!\n"); fflush(stdout); 01430 01431 if ( m_dotDirectoryPath.isEmpty() ) 01432 return; 01433 if ( !m_bDesktop ) 01434 return; // Currently not available in Konqueror 01435 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions" << endl; 01436 KSimpleConfig dotDirectory( m_dotDirectoryPath ); 01437 TQIconViewItem *it = firstItem(); 01438 if ( !it ) 01439 return; // No more icons. Maybe we're closing and they've been removed already 01440 while ( it ) 01441 { 01442 KFileIVI *ivi = static_cast<KFileIVI *>( it ); 01443 KFileItem *item = ivi->item(); 01444 01445 dotDirectory.setGroup( TQString( m_iconPositionGroupPrefix ).append( item->url().fileName() ) ); 01446 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions " << item->url().fileName() << " " << it->x() << " " << it->y() << endl; 01447 dotDirectory.writeEntry( TQString( "X %1" ).arg( width() ), it->x() ); 01448 dotDirectory.writeEntry( TQString( "Y %1" ).arg( height() ), it->y() ); 01449 dotDirectory.writeEntry( "Exists", true ); 01450 01451 it = it->nextItem(); 01452 } 01453 01454 TQStringList groups = dotDirectory.groupList(); 01455 TQStringList::ConstIterator gIt = groups.begin(); 01456 TQStringList::ConstIterator gEnd = groups.end(); 01457 for (; gIt != gEnd; ++gIt ) 01458 if ( (*gIt).left( m_iconPositionGroupPrefix.length() ) == m_iconPositionGroupPrefix ) 01459 { 01460 dotDirectory.setGroup( *gIt ); 01461 if ( dotDirectory.hasKey( "Exists" ) ) 01462 dotDirectory.deleteEntry( "Exists", false ); 01463 else 01464 { 01465 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions deleting group " << *gIt << endl; 01466 dotDirectory.deleteGroup( *gIt ); 01467 } 01468 } 01469 01470 dotDirectory.sync(); 01471 01472 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01473 // This code is currently not used but left in for compatibility reasons. 01474 // It can be removed in KDE 4.0 01475 // Saving of desktop icon positions is now done in KDIconView::saveIconPositions() 01476 // in tdebase/kdesktop/kdiconview.cc 01477 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 01478 } 01479 01480 // Adapted version of TQIconView::insertInGrid, that works relative to 01481 // m_IconRect, instead of the entire viewport. 01482 01483 void KonqIconViewWidget::insertInGrid(TQIconViewItem *item) 01484 { 01485 if (0L == item) 01486 return; 01487 01488 if (!m_IconRect.isValid()) 01489 { 01490 TDEIconView::insertInGrid(item); 01491 return; 01492 } 01493 01494 TQRegion r(m_IconRect); 01495 TQIconViewItem *i = firstItem(); 01496 int y = -1; 01497 for (; i; i = i->nextItem() ) 01498 { 01499 r = r.subtract(i->rect()); 01500 y = TQMAX(y, i->y() + i->height()); 01501 } 01502 01503 TQMemArray<TQRect> rects = r.rects(); 01504 TQMemArray<TQRect>::Iterator it = rects.begin(); 01505 bool foundPlace = FALSE; 01506 for (; it != rects.end(); ++it) 01507 { 01508 TQRect rect = *it; 01509 if (rect.width() >= item->width() && rect.height() >= item->height()) 01510 { 01511 int sx = 0, sy = 0; 01512 if (rect.width() >= item->width() + spacing()) 01513 sx = spacing(); 01514 if (rect.height() >= item->height() + spacing()) 01515 sy = spacing(); 01516 item->move(rect.x() + sx, rect.y() + sy); 01517 foundPlace = true; 01518 break; 01519 } 01520 } 01521 01522 if (!foundPlace) 01523 item->move(m_IconRect.topLeft()); 01524 01525 //item->dirty = false; 01526 return; 01527 } 01528 01529 01530 /* 01531 * The algorithm used for lineing up the icons could be called 01532 * "beating flat the icon field". Imagine the icon field to be some height 01533 * field on a regular grid, with the height being the number of icons in 01534 * each grid element. Now imagine slamming on the field with a shovel or 01535 * some other flat surface. The high peaks will be flattened and spread out 01536 * over their adjacent areas. This is basically what the algorithm tries to 01537 * simulate. 01538 * 01539 * First, the icons are binned to a grid of the desired size. If all bins 01540 * are containing at most one icon, we're done, of course. We just have to 01541 * move all icons to the center of each grid element. 01542 * For each bin which has more than one icon in it, we calculate 4 01543 * "friction coefficients", one for each cardinal direction. The friction 01544 * coefficient of a direction is the number of icons adjacent in that 01545 * direction. The idea is that this number is somewhat a measure in which 01546 * direction the icons should flow: icons flow in the direction of lowest 01547 * friction coefficient. We move a maximum of one icon per bin and loop over 01548 * all bins. This procedure is repeated some maximum number of times or until 01549 * no icons are moved anymore. 01550 * 01551 * I don't know if this algorithm is good or bad, I don't even know if it will 01552 * work all the time. It seems a correct thing to do, however, and it seems to 01553 * work particularly well. In any case, the number of runs is limited so there 01554 * can be no races. 01555 */ 01556 01557 void KonqIconViewWidget::lineupIcons() 01558 { 01559 // even if there are no items yet, calculate the maxItemWidth to have the correct 01560 // item rect when we insert new items 01561 01562 // Create a grid of (ny x nx) bins. 01563 int x0, y0, dx, dy, nx, ny; 01564 gridValues( &x0, &y0, &dx, &dy, &nx, &ny ); 01565 01566 int itemWidth = dx - spacing(); 01567 bool newItemWidth = false; 01568 if ( maxItemWidth() != itemWidth ) { 01569 newItemWidth = true; 01570 setMaxItemWidth( itemWidth ); 01571 setFont( font() ); // Force calcRect() 01572 } 01573 01574 if ( !firstItem() ) { 01575 kdDebug(1203) << "No icons at all ?\n"; 01576 return; 01577 } 01578 01579 int iconSize = m_size ? m_size : TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop ); 01580 01581 typedef TQValueList<TQIconViewItem*> Bin; 01582 Bin*** bins = new Bin**[nx]; 01583 int i; 01584 int j; 01585 for ( i = 0; i < nx ; i++ ) { 01586 bins[i] = new Bin*[ny]; 01587 for ( j = 0; j < ny; j++ ) 01588 bins[i][j] = 0L; 01589 } 01590 01591 // Insert items into grid 01592 int textHeight = iconTextHeight() * fontMetrics().height(); 01593 01594 for ( TQIconViewItem* item = firstItem(); item; item = item->nextItem() ) { 01595 int x = item->x() + item->width() / 2 - x0; 01596 int y = item->pixmapRect( false ).bottom() - iconSize / 2 01597 - ( dy - ( iconSize + textHeight ) ) / 2 - y0; 01598 int posX = TQMIN( nx-1, TQMAX( 0, x / dx ) ); 01599 int posY = TQMIN( ny-1, TQMAX( 0, y / dy ) ); 01600 01601 if ( !bins[posX][posY] ) 01602 bins[posX][posY] = new Bin; 01603 bins[posX][posY]->prepend( item ); 01604 } 01605 01606 // The shuffle code 01607 int n, k; 01608 const int infinity = 10000; 01609 int nmoves = 1; 01610 for ( n = 0; n < 30 && nmoves > 0; n++ ) { 01611 nmoves = 0; 01612 for ( i = 0; i < nx; i++ ) { 01613 for ( j = 0; j < ny; j++ ) { 01614 if ( !bins[i][j] || ( bins[i][j]->count() <= 1 ) ) 01615 continue; 01616 01617 // Calculate the 4 "friction coefficients". 01618 int tf = 0, bf = 0, lf = 0, rf = 0; 01619 for ( k = j-1; k >= 0 && bins[i][k] && bins[i][k]->count(); k-- ) 01620 tf += bins[i][k]->count(); 01621 if ( k == -1 ) 01622 tf += infinity; 01623 01624 for ( k = j+1; k < ny && bins[i][k] && bins[i][k]->count(); k++ ) 01625 bf += bins[i][k]->count(); 01626 if ( k == ny ) 01627 bf += infinity; 01628 01629 for ( k = i-1; k >= 0 && bins[k][j] && bins[k][j]->count(); k-- ) 01630 lf += bins[k][j]->count(); 01631 if ( k == -1 ) 01632 lf += infinity; 01633 01634 for ( k = i+1; k < nx && bins[k][j] && bins[k][j]->count(); k++ ) 01635 rf += bins[k][j]->count(); 01636 if ( k == nx ) 01637 rf += infinity; 01638 01639 // If we are stuck between walls, continue 01640 if ( tf >= infinity && bf >= infinity && 01641 lf >= infinity && rf >= infinity ) 01642 continue; 01643 01644 // Is there a preferred lineup direction? 01645 if ( m_LineupMode == LineupHorizontal ) { 01646 tf += infinity; 01647 bf += infinity; 01648 } 01649 else if ( m_LineupMode == LineupVertical ) { 01650 lf += infinity; 01651 rf += infinity; 01652 } 01653 01654 // Move one item in the direction of the least friction 01655 TQIconViewItem* movedItem; 01656 Bin* items = bins[i][j]; 01657 01658 int mini = TQMIN( TQMIN( tf, bf ), TQMIN( lf, rf ) ); 01659 if ( tf == mini ) { 01660 // move top item in (i,j) to (i,j-1) 01661 Bin::iterator it = items->begin(); 01662 movedItem = *it; 01663 for ( ++it; it != items->end(); ++it ) { 01664 if ( (*it)->y() < movedItem->y() ) 01665 movedItem = *it; 01666 } 01667 items->remove( movedItem ); 01668 if ( !bins[i][j-1] ) 01669 bins[i][j-1] = new Bin; 01670 bins[i][j-1]->prepend( movedItem ); 01671 } 01672 else if ( bf ==mini ) { 01673 // move bottom item in (i,j) to (i,j+1) 01674 Bin::iterator it = items->begin(); 01675 movedItem = *it; 01676 for ( ++it; it != items->end(); ++it ) { 01677 if ( (*it)->y() > movedItem->y() ) 01678 movedItem = *it; 01679 } 01680 items->remove( movedItem ); 01681 if ( !bins[i][j+1] ) 01682 bins[i][j+1] = new Bin; 01683 bins[i][j+1]->prepend( movedItem ); 01684 } 01685 else if ( lf == mini ) 01686 { 01687 // move left item in (i,j) to (i-1,j) 01688 Bin::iterator it = items->begin(); 01689 movedItem = *it; 01690 for ( ++it; it != items->end(); ++it ) { 01691 if ( (*it)->x() < movedItem->x() ) 01692 movedItem = *it; 01693 } 01694 items->remove( movedItem ); 01695 if ( !bins[i-1][j] ) 01696 bins[i-1][j] = new Bin; 01697 bins[i-1][j]->prepend( movedItem ); 01698 } 01699 else { 01700 // move right item in (i,j) to (i+1,j) 01701 Bin::iterator it = items->begin(); 01702 movedItem = *it; 01703 for ( ++it; it != items->end(); ++it ) { 01704 if ( (*it)->x() > movedItem->x() ) 01705 movedItem = *it; 01706 } 01707 items->remove( movedItem ); 01708 if ( !bins[i+1][j] ) 01709 bins[i+1][j] = new Bin; 01710 bins[i+1][j]->prepend( movedItem ); 01711 } 01712 nmoves++; 01713 } 01714 } 01715 } 01716 01717 // Perform the actual moving 01718 TQRegion repaintRegion; 01719 TQValueList<TQIconViewItem*> movedItems; 01720 01721 for ( i = 0; i < nx; i++ ) { 01722 for ( j = 0; j < ny; j++ ) { 01723 Bin* bin = bins[i][j]; 01724 if ( !bin ) 01725 continue; 01726 if ( !bin->isEmpty() ) { 01727 TQIconViewItem* item = bin->first(); 01728 int newX = x0 + i*dx + spacing() + 01729 TQMAX(0, ( (dx-spacing()) - item->width() ) / 2); // pixmap can be larger as iconsize 01730 // align all icons vertically to their text 01731 int newY = y0 + j*dy + dy - spacing() - ( item->pixmapRect().bottom() + 2 + textHeight ); 01732 if ( item->x() != newX || item->y() != newY ) { 01733 TQRect oldRect = item->rect(); 01734 movedItems.prepend( item ); 01735 item->move( newX, newY ); 01736 if ( item->rect() != oldRect ) 01737 repaintRegion = repaintRegion.unite( oldRect ); 01738 } 01739 } 01740 delete bin; 01741 bins[i][j] = 0L; 01742 } 01743 } 01744 01745 // repaint 01746 if ( newItemWidth ) 01747 updateContents(); 01748 else { 01749 // Repaint only repaintRegion... 01750 TQMemArray<TQRect> rects = repaintRegion.rects(); 01751 for ( uint l = 0; l < rects.count(); l++ ) { 01752 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << "," 01753 << rects[l].y() << ")\n"; 01754 repaintContents( rects[l], false ); 01755 } 01756 // Repaint icons that were moved 01757 while ( !movedItems.isEmpty() ) { 01758 repaintItem( movedItems.first() ); 01759 movedItems.remove( movedItems.first() ); 01760 } 01761 } 01762 01763 for ( i = 0; i < nx ; i++ ) { 01764 delete [] bins[i]; 01765 } 01766 delete [] bins; 01767 } 01768 01769 void KonqIconViewWidget::lineupIcons( TQIconView::Arrangement arrangement ) 01770 { 01771 int x0, y0, dx, dy, nxmax, nymax; 01772 gridValues( &x0, &y0, &dx, &dy, &nxmax, &nymax ); 01773 int textHeight = iconTextHeight() * fontMetrics().height(); 01774 01775 TQRegion repaintRegion; 01776 TQValueList<TQIconViewItem*> movedItems; 01777 int nx = 0, ny = 0; 01778 01779 TQIconViewItem* item; 01780 for ( item = firstItem(); item; item = item->nextItem() ) { 01781 int newX = x0 + nx*dx + spacing() + 01782 TQMAX(0, ( (dx-spacing()) - item->width() ) / 2); // icon can be larger as defined 01783 // align all icons vertically to their text 01784 int newY = y0 + ny*dy + dy - spacing() - ( item->pixmapRect().bottom() + 2 + textHeight ); 01785 if ( item->x() != newX || item->y() != newY ) { 01786 TQRect oldRect = item->rect(); 01787 movedItems.prepend( item ); 01788 item->move( newX, newY ); 01789 if ( item->rect() != oldRect ) 01790 repaintRegion = repaintRegion.unite( oldRect ); 01791 } 01792 if ( arrangement == TQIconView::LeftToRight ) { 01793 nx++; 01794 if ( nx >= nxmax ) { 01795 ny++; 01796 nx = 0; 01797 } 01798 } 01799 else { 01800 ny++; 01801 if ( ny >= nymax ) { 01802 nx++; 01803 ny = 0; 01804 } 01805 } 01806 } 01807 01808 // Repaint only repaintRegion... 01809 TQMemArray<TQRect> rects = repaintRegion.rects(); 01810 for ( uint l = 0; l < rects.count(); l++ ) { 01811 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << "," 01812 << rects[l].y() << ")\n"; 01813 repaintContents( rects[l], false ); 01814 } 01815 // Repaint icons that were moved 01816 while ( !movedItems.isEmpty() ) { 01817 repaintItem( movedItems.first() ); 01818 movedItems.remove( movedItems.first() ); 01819 } 01820 } 01821 01822 int KonqIconViewWidget::largestPreviewIconSize( int size ) const 01823 { 01824 int iconSize = size ? size : TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop ); 01825 01826 if (iconSize < 28) 01827 return 48; 01828 if (iconSize < 40) 01829 return 64; 01830 if (iconSize < 60) 01831 return 96; 01832 if (iconSize < 120) 01833 return 128; 01834 01835 return 192; 01836 } 01837 01838 int KonqIconViewWidget::previewIconSize( int size ) const 01839 { 01840 int iconSize = size ? size : TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop ); 01841 01842 if (!d->bBoostPreview) 01843 return iconSize; 01844 01845 return largestPreviewIconSize( iconSize ); 01846 } 01847 01848 void KonqIconViewWidget::visualActivate(TQIconViewItem * item) 01849 { 01850 // Rect of the TQIconViewItem. 01851 TQRect irect = item->rect(); 01852 01853 // Rect of the QIconViewItem's pixmap area. 01854 TQRect rect = item->pixmapRect(); 01855 01856 // Adjust to correct position. If this isn't done, the fact that the 01857 // text may be wider than the pixmap puts us off-centre. 01858 rect.moveBy(irect.x(), irect.y()); 01859 01860 // Adjust for scrolling (David) 01861 rect.moveBy( -contentsX(), -contentsY() ); 01862 01863 if (TDEGlobalSettings::showKonqIconActivationEffect() == true) { 01864 TDEIconEffect::visualActivate(viewport(), rect, item->pixmap()); 01865 } 01866 } 01867 01868 void KonqIconViewWidget::backgroundPixmapChange( const TQPixmap & ) 01869 { 01870 viewport()->update(); 01871 } 01872 01873 void KonqIconViewWidget::setPreviewSettings( const TQStringList& settings ) 01874 { 01875 d->previewSettings = settings; 01876 updatePreviewMimeTypes(); 01877 01878 int size = m_size; 01879 m_size = -1; // little trick to force grid change in setIcons 01880 setIcons( size ); // force re-determining all icons 01881 } 01882 01883 const TQStringList& KonqIconViewWidget::previewSettings() 01884 { 01885 return d->previewSettings; 01886 } 01887 01888 void KonqIconViewWidget::setNewURL( const TQString& url ) 01889 { 01890 KURL u; 01891 if ( url.startsWith( "/" ) ) 01892 u.setPath( url ); 01893 else 01894 u = url; 01895 setURL( u ); 01896 } 01897 01898 void KonqIconViewWidget::setCaseInsensitiveSort( bool b ) 01899 { 01900 d->bCaseInsensitive = b; 01901 } 01902 01903 bool KonqIconViewWidget::caseInsensitiveSort() const 01904 { 01905 return d->bCaseInsensitive; 01906 } 01907 01908 bool KonqIconViewWidget::canPreview( KFileItem* item ) 01909 { 01910 if ( !TDEGlobalSettings::showFilePreview( url() ) ) 01911 return false; 01912 01913 if ( d->pPreviewMimeTypes == 0L ) 01914 updatePreviewMimeTypes(); 01915 01916 return mimeTypeMatch( item->mimetype(), *( d->pPreviewMimeTypes ) ); 01917 } 01918 01919 void KonqIconViewWidget::updatePreviewMimeTypes() 01920 { 01921 if ( d->pPreviewMimeTypes == 0L ) 01922 d->pPreviewMimeTypes = new TQStringList; 01923 else 01924 d->pPreviewMimeTypes->clear(); 01925 01926 // Load the list of plugins to determine which mimetypes are supported 01927 TDETrader::OfferList plugins = TDETrader::self()->query("ThumbCreator"); 01928 TDETrader::OfferList::ConstIterator it; 01929 01930 for ( it = plugins.begin(); it != plugins.end(); ++it ) { 01931 if ( d->previewSettings.contains((*it)->desktopEntryName()) ) { 01932 TQStringList mimeTypes = (*it)->property("MimeTypes").toStringList(); 01933 for (TQStringList::ConstIterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt) 01934 d->pPreviewMimeTypes->append(*mt); 01935 } 01936 } 01937 } 01938 01939 #include "konq_iconviewwidget.moc" 01940 01941 /* vim: set et sw=4 ts=8 softtabstop=4: */