00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 <qclipboard.h>
00027 #include <qlayout.h>
00028 #include <qtimer.h>
00029 #include <qpainter.h>
00030 #include <qtooltip.h>
00031 #include <qlabel.h>
00032 #include <qmovie.h>
00033 #include <qregexp.h>
00034 #include <qcursor.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
00086 }
00087 KFileIVI *pActiveItem;
00088
00089 KFileIVI *pSoundItem;
00090 KonqSoundPlayer *pSoundPlayer;
00091 QTimer *pSoundTimer;
00092 bool bSoundPreviews;
00093 bool bSoundItemClicked;
00094 bool bAllowSetWallpaper;
00095 bool bCaseInsensitive;
00096 bool bBoostPreview;
00097
00098
00099 bool doAnimations;
00100 QMovie* m_movie;
00101 int m_movieBlocked;
00102 QString movieFileName;
00103
00104 KIO::PreviewJob *pPreviewJob;
00105 KonqFileTip* pFileTip;
00106 QStringList previewSettings;
00107 bool renameItem;
00108 bool firstClick;
00109 bool releaseMouseEvent;
00110 QPoint mousePos;
00111 int mouseState;
00112 QTimer *pActivateDoubleClick;
00113 QStringList* pPreviewMimeTypes;
00114 bool bProgramsURLdrag;
00115 };
00116
00117 KonqIconViewWidget::KonqIconViewWidget( QWidget * parent, const char * name, WFlags f, bool kdesktop )
00118 : KIconView( parent, name, f ),
00119 m_rootItem( 0L ), m_size( 0 ) ,
00120 m_bDesktop( kdesktop ),
00121 m_bSetGridX( !kdesktop )
00122 {
00123 d = new KonqIconViewWidgetPrivate;
00124 connect( this, SIGNAL( dropped( QDropEvent *, const QValueList<QIconDragItem> & ) ),
00125 this, SLOT( slotDropped( QDropEvent*, const QValueList<QIconDragItem> & ) ) );
00126
00127 connect( this, SIGNAL( selectionChanged() ),
00128 this, SLOT( slotSelectionChanged() ) );
00129
00130 kapp->addKipcEventMask( KIPC::IconChanged );
00131 connect( kapp, SIGNAL(iconChanged(int)), SLOT(slotIconChanged(int)) );
00132 connect( this, SIGNAL(onItem(QIconViewItem *)), SLOT(slotOnItem(QIconViewItem *)) );
00133 connect( this, SIGNAL(onViewport()), SLOT(slotOnViewport()) );
00134 connect( this, SIGNAL(itemRenamed(QIconViewItem *, const QString &)), SLOT(slotItemRenamed(QIconViewItem *, const QString &)) );
00135
00136 m_pSettings = KonqFMSettings::settings();
00137 d->bBoostPreview = boostPreview();
00138
00139
00140 setSelectionMode( QIconView::Extended );
00141 setItemTextPos( QIconView::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
00153 slotSelectionChanged();
00154 m_iconPositionGroupPrefix = QString::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( QFocusEvent * ev )
00176 {
00177
00178
00179
00180 m_bMousePressed = false;
00181
00182
00183
00184
00185
00186
00187 slotOnViewport();
00188
00189 KIconView::focusOutEvent( ev );
00190 }
00191
00192 void KonqIconViewWidget::slotItemRenamed(QIconViewItem *item, const QString &name)
00193 {
00194 kdDebug(1203) << "KonqIconViewWidget::slotItemRenamed" << endl;
00195 KFileIVI *viewItem = static_cast<KFileIVI *>(item);
00196 KFileItem *fileItem = viewItem->item();
00197
00198
00199
00200
00201 viewItem->setText( fileItem->text() );
00202 kdDebug(1203)<<" fileItem->text() ;"<<fileItem->text()<<endl;
00203
00204 if( !name.isEmpty() )
00205 {
00206
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
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;
00224 setIcons( size );
00225 readAnimatedIconsConfig();
00226 }
00227
00228 void KonqIconViewWidget::readAnimatedIconsConfig()
00229 {
00230 KConfigGroup cfgGroup( KGlobal::config(), "DesktopIcons" );
00231 d->doAnimations = cfgGroup.readBoolEntry( "Animated", true );
00232 }
00233
00234 void KonqIconViewWidget::slotOnItem( QIconViewItem *_item )
00235 {
00236 KFileIVI* item = static_cast<KFileIVI *>( _item );
00237
00238 if( d->pActiveItem != 0L && d->pActiveItem != item )
00239 {
00240 if ( d->m_movie && d->pActiveItem->isAnimated() )
00241 {
00242 d->m_movie->pause();
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
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
00275
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 QTimer::singleShot(300, this, SLOT(slotReenableAnimation()));
00288 d->m_movie->restart();
00289 d->m_movie->unpause();
00290 }
00291 }
00292 else
00293 #endif
00294 {
00295 QMovie 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 QMovie( movie );
00300
00301
00302 const QPixmap* 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, SLOT( slotMovieUpdate(const QRect &) ) );
00311 d->m_movie->connectStatus( this, 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
00321 d->pActiveItem->setMouseOverAnimation( QString::null );
00322 }
00323 }
00324 }
00325
00326 if (d->pActiveItem && !d->pActiveItem->isAnimated())
00327 {
00328 d->pActiveItem->setActive( true );
00329 }
00330 }
00331 else
00332 {
00333
00334
00335 d->pActiveItem = 0L;
00336 d->pFileTip->setItem( 0L );
00337 }
00338 }
00339 else
00340 {
00341
00342
00343 d->pActiveItem = 0L;
00344 d->pFileTip->setItem( 0L );
00345 }
00346
00347
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 QTimer(this);
00359 connect(d->pSoundTimer, SIGNAL(timeout()), 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
00393 if (d->m_movie->running()) {
00394 d->m_movie->pause();
00395 d->m_movieBlocked++;
00396 kdDebug(1203) << "on viewport, blocking" << endl;
00397 QTimer::singleShot(300, this, SLOT(slotReenableAnimation()));
00398 }
00399 #endif
00400 d->pActiveItem->refreshIcon( true );
00401 Q_ASSERT( d->pActiveItem->state() == KIcon::DefaultState );
00402
00403
00404
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 QPixmap &pix)
00423 {
00424
00425 for (QIconViewItem *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 QPixmap 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 QPixmap &)
00450 {
00451
00452 }
00453
00454 void KonqIconViewWidget::slotToolTipPreviewResult()
00455 {
00456
00457 }
00458
00459 void KonqIconViewWidget::slotMovieUpdate( const QRect& rect )
00460 {
00461
00462 Q_ASSERT( d );
00463 Q_ASSERT( d->m_movie );
00464
00465 if ( d->pActiveItem && d->m_movie && d->pActiveItem->isAnimated() ) {
00466 const QPixmap &frame = d->m_movie->framePixmap();
00467
00468
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
00475 d->pActiveItem->setMouseOverAnimation( QString::null );
00476 d->pActiveItem->setActive( true );
00477 return;
00478 }
00479 d->pActiveItem->setPixmapDirect( frame, false, false );
00480 QRect 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
00489 if ( d->pActiveItem && d->pActiveItem->isAnimated() ) {
00490 d->pActiveItem->setAnimated( false );
00491 d->pActiveItem->setMouseOverAnimation( QString::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();
00512 KIconView::clear();
00513 d->pActiveItem = 0L;
00514 }
00515
00516 void KonqIconViewWidget::takeItem( QIconViewItem *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
00531 void KonqIconViewWidget::setThumbnailPixmap( KFileIVI * item, const QPixmap & 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
00555 QColor normalTextColor = m_pSettings->normalTextColor();
00556 setItemColor( normalTextColor );
00557
00558 if (m_bDesktop)
00559 {
00560 QColor itemTextBg = m_pSettings->itemTextBackground();
00561 if ( itemTextBg.isValid() )
00562 setItemTextBackground( itemTextBg );
00563 else
00564 setItemTextBackground( NoBrush );
00565 }
00566
00567 bool on = m_pSettings->showFileTips() && QToolTip::isGloballyEnabled();
00568 d->pFileTip->setOptions(on,
00569 m_pSettings->showPreviewsInFileTips(),
00570 m_pSettings->numFileTips());
00571
00572
00573 setShowToolTips(!on);
00574
00575
00576 QFont 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
00586
00587 fontChanged = true;
00588 }
00589 }
00590
00591 setIconTextHeight( m_pSettings->iconTextHeight() );
00592
00593 if ( (itemTextPos() == QIconView::Right) && (maxItemWidth() != gridXValue()) )
00594 {
00595 int size = m_size;
00596 m_size = -1;
00597 setIcons( size );
00598 }
00599 else if ( d->bBoostPreview != boostPreview() )
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 QStringList& stopImagePreviewFor )
00626 {
00627
00628 bool sizeChanged = (m_size != size);
00629 int oldGridX = gridX();
00630 m_size = size;
00631
00632
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
00641 setSpacing( ( m_bDesktop || ( realSize > KIcon::SizeSmall ) ) ?
00642 QMAX( 5, QFontMetrics(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
00652
00653
00654
00655 bool prevUpdatesState = viewport()->isUpdatesEnabled();
00656 viewport()->setUpdatesEnabled( false );
00657
00658
00659 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00660 KFileIVI * ivi = static_cast<KFileIVI *>( it );
00661
00662
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
00676 viewport()->setUpdatesEnabled( prevUpdatesState );
00677
00678 if ( ( sizeChanged || previewSizeChanged || oldGridX != gridX() ||
00679 !stopImagePreviewFor.isEmpty() ) && autoArrange() )
00680 arrangeItemsInGrid( true );
00681 else
00682 viewport()->update();
00683 }
00684
00685 bool KonqIconViewWidget::mimeTypeMatch( const QString& mimeType, const QStringList& mimeList ) const
00686 {
00687 for (QStringList::ConstIterator mt = mimeList.begin(); mt != mimeList.end(); ++mt)
00688 {
00689 if ( mimeType == *mt )
00690 return true;
00691
00692 QString tmp( mimeType );
00693 if ( (*mt).endsWith("*") && tmp.replace(QRegExp("/.*"), "/*") == (*mt) )
00694 return true;
00695 }
00696 return false;
00697 }
00698
00699 void KonqIconViewWidget::setItemTextPos( ItemTextPos pos )
00700 {
00701
00702 int sz = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00703
00704 if ( m_bSetGridX )
00705 if ( pos == QIconView::Bottom )
00706 setGridX( QMAX( sz + 50, previewIconSize( sz ) + 13 ) );
00707 else
00708 {
00709 setMaxItemWidth( QMAX( sz, previewIconSize( sz ) ) + m_pSettings->iconTextWidth() );
00710 setGridX( -1 );
00711 }
00712
00713 KIconView::setItemTextPos( pos );
00714 }
00715
00716 void KonqIconViewWidget::gridValues( int* x, int* y, int* dx, int* dy,
00717 int* nx, int* ny )
00718 {
00719 int previewSize = previewIconSize( m_size );
00720 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00721
00722
00723
00724
00725
00726
00727
00728
00729 *dx = spacing() + QMAX( QMAX( iconSize, previewSize ), m_pSettings->iconTextWidth() );
00730 int textHeight = iconTextHeight() * fontMetrics().height();
00731 *dy = spacing() + QMAX( iconSize, previewSize ) + 2 + textHeight + spacing();
00732
00733
00734 int w, h;
00735 if ( m_IconRect.isValid() ) {
00736 *x = m_IconRect.left(); w = m_IconRect.width();
00737 *y = m_IconRect.top(); h = m_IconRect.height();
00738 }
00739 else {
00740 *x = 0; w = viewport()->width();
00741 *y = 0; h = viewport()->height();
00742 }
00743
00744 *nx = w / *dx;
00745 *ny = h / *dy;
00746
00747
00748
00749 *dx = w / *nx;
00750 *dy = h / *ny;
00751 kdDebug(1203) << "x=" << *x << " y=" << *y << " spacing=" << spacing() << " iconSize=" << iconSize
00752 << " w=" << w << " h=" << h
00753 << " nx=" << *nx << " ny=" << *ny
00754 << " dx=" << *dx << " dy=" << *dy << endl;
00755 }
00756
00757 void KonqIconViewWidget::calculateGridX()
00758 {
00759 if ( m_bSetGridX )
00760 if ( itemTextPos() == QIconView::Bottom )
00761 setGridX( gridXValue() );
00762 else
00763 {
00764 setMaxItemWidth( gridXValue() );
00765 setGridX( -1 );
00766 }
00767 }
00768
00769 int KonqIconViewWidget::gridXValue() const
00770 {
00771
00772 int sz = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00773 int newGridX;
00774
00775 if ( itemTextPos() == QIconView::Bottom )
00776 newGridX = QMAX( sz + 50, previewIconSize( sz ) + 13 );
00777 else
00778 newGridX = QMAX( sz, previewIconSize( sz ) ) + m_pSettings->iconTextWidth();
00779
00780
00781 return newGridX;
00782 }
00783
00784 void KonqIconViewWidget::refreshMimeTypes()
00785 {
00786 updatePreviewMimeTypes();
00787 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
00788 (static_cast<KFileIVI *>( it ))->item()->refreshMimeType();
00789 setIcons( m_size );
00790 }
00791
00792 void KonqIconViewWidget::setURL( const KURL &kurl )
00793 {
00794 stopImagePreview();
00795 m_url = kurl;
00796
00797 d->pFileTip->setPreview( KGlobalSettings::showFilePreview(m_url) );
00798
00799 if ( m_url.isLocalFile() )
00800 m_dotDirectoryPath = m_url.path(1).append( ".directory" );
00801 else
00802 m_dotDirectoryPath = QString::null;
00803 }
00804
00805 void KonqIconViewWidget::startImagePreview( const QStringList &, bool force )
00806 {
00807 stopImagePreview();
00808
00809
00810 if ( !KGlobalSettings::showFilePreview( url() ) ) {
00811 kdDebug(1203) << "Previews disabled for protocol " << url().protocol() << endl;
00812 emit imagePreviewFinished();
00813 return;
00814 }
00815
00816 if ((d->bSoundPreviews = d->previewSettings.contains( "audio/" )) &&
00817 !d->pSoundPlayer)
00818 {
00819 KLibFactory *factory = KLibLoader::self()->factory("konq_sound");
00820 if (factory)
00821 d->pSoundPlayer = static_cast<KonqSoundPlayer *>(
00822 factory->create(this, 0, "KonqSoundPlayer"));
00823 d->bSoundPreviews = (d->pSoundPlayer != 0L);
00824 }
00825
00826 KFileItemList items;
00827 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
00828 if ( force || !static_cast<KFileIVI *>( it )->hasValidThumbnail() )
00829 items.append( static_cast<KFileIVI *>( it )->item() );
00830
00831 bool onlyAudio = true;
00832 for ( QStringList::ConstIterator it = d->previewSettings.begin(); it != d->previewSettings.end(); ++it ) {
00833 if ( (*it).startsWith( "audio/" ) )
00834 d->bSoundPreviews = true;
00835 else
00836 onlyAudio = false;
00837 }
00838
00839 if ( items.isEmpty() || onlyAudio ) {
00840 emit imagePreviewFinished();
00841 return;
00842 }
00843
00844 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00845 int size;
00846
00847 d->bBoostPreview = boostPreview();
00848 size = previewIconSize( iconSize );
00849
00850 if ( !d->bBoostPreview )
00851 iconSize /= 2;
00852
00853 d->pPreviewJob = KIO::filePreview( items, size, size, iconSize,
00854 m_pSettings->textPreviewIconTransparency(), true ,
00855 true , &(d->previewSettings) );
00856 connect( d->pPreviewJob, SIGNAL( gotPreview( const KFileItem *, const QPixmap & ) ),
00857 this, SLOT( slotPreview( const KFileItem *, const QPixmap & ) ) );
00858 connect( d->pPreviewJob, SIGNAL( result( KIO::Job * ) ),
00859 this, SLOT( slotPreviewResult() ) );
00860 }
00861
00862 void KonqIconViewWidget::stopImagePreview()
00863 {
00864 if (d->pPreviewJob)
00865 {
00866 d->pPreviewJob->kill();
00867 d->pPreviewJob = 0;
00868
00869
00870 }
00871 }
00872
00873 bool KonqIconViewWidget::isPreviewRunning() const
00874 {
00875 return d->pPreviewJob;
00876 }
00877
00878 KFileItemList KonqIconViewWidget::selectedFileItems()
00879 {
00880 KFileItemList lstItems;
00881
00882 QIconViewItem *it = firstItem();
00883 for (; it; it = it->nextItem() )
00884 if ( it->isSelected() ) {
00885 KFileItem *fItem = (static_cast<KFileIVI *>(it))->item();
00886 lstItems.append( fItem );
00887 }
00888 return lstItems;
00889 }
00890
00891 void KonqIconViewWidget::slotDropped( QDropEvent *ev, const QValueList<QIconDragItem> & )
00892 {
00893
00894 KonqOperations::doDrop( m_rootItem , url(), ev, this );
00895 }
00896
00897 void KonqIconViewWidget::slotAboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)
00898 {
00899
00900 }
00901
00902 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r )
00903 {
00904 drawBackground(p, r, r.topLeft());
00905 }
00906
00907 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r , const QPoint &pt)
00908 {
00909 const QPixmap *pm = backgroundPixmap();
00910 bool hasPixmap = pm && !pm->isNull();
00911 if ( !hasPixmap ) {
00912 pm = viewport()->backgroundPixmap();
00913 hasPixmap = pm && !pm->isNull();
00914 }
00915
00916 QRect rtgt(r);
00917 rtgt.moveTopLeft(pt);
00918 if (!hasPixmap && backgroundMode() != NoBackground) {
00919 p->fillRect(rtgt, viewport()->backgroundColor());
00920 return;
00921 }
00922
00923 if (hasPixmap) {
00924 int ax = (r.x() + contentsX() + leftMargin()) % pm->width();
00925 int ay = (r.y() + contentsY() + topMargin()) % pm->height();
00926 p->drawTiledPixmap(rtgt, *pm, QPoint(ax, ay));
00927 }
00928 }
00929
00930 QDragObject * KonqIconViewWidget::dragObject()
00931 {
00932 if ( !currentItem() )
00933 return 0;
00934
00935 return konqDragObject( viewport() );
00936 }
00937
00938 KonqIconDrag * KonqIconViewWidget::konqDragObject( QWidget * dragSource )
00939 {
00940
00941
00942 KonqIconDrag * drag = new KonqIconDrag( dragSource );
00943 QIconViewItem *primaryItem = currentItem();
00944
00945 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00946 if ( it->isSelected() ) {
00947 if (!primaryItem)
00948 primaryItem = it;
00949 KURL url = (static_cast<KFileIVI *>(it))->item()->url();
00950 QString itemURL = KURLDrag::urlToString(url);
00951 kdDebug(1203) << "itemURL=" << itemURL << endl;
00952 QIconDragItem id;
00953 id.setData( QCString(itemURL.latin1()) );
00954 drag->append( id,
00955 QRect( it->pixmapRect(false).topLeft() - m_mousePos,
00956 it->pixmapRect().size() ),
00957 QRect( it->textRect(false).topLeft() - m_mousePos,
00958 it->textRect().size() ),
00959 itemURL );
00960 }
00961 }
00962
00963 if (primaryItem)
00964 drag->setPixmap( *primaryItem->pixmap(), m_mousePos - primaryItem->pixmapRect(false).topLeft() );
00965
00966 return drag;
00967 }
00968
00969 void KonqIconViewWidget::contentsDragEnterEvent( QDragEnterEvent *e )
00970 {
00971 if ( e->provides( "text/uri-list" ) )
00972 {
00973 QByteArray payload = e->encodedData( "text/uri-list" );
00974 if ( !payload.size() )
00975 kdError() << "Empty data !" << endl;
00976
00977
00978 bool ok = KURLDrag::decode( e, m_lstDragURLs );
00979 if( !ok )
00980 kdError() << "Couldn't decode urls dragged !" << endl;
00981 }
00982
00983 KURL::List uriList;
00984 if ( KURLDrag::decode(e, uriList) )
00985 {
00986 if ( uriList.first().protocol() == "programs" )
00987 {
00988 e->ignore();
00989 emit dragEntered( false );
00990 d->bProgramsURLdrag = true;
00991 return;
00992 }
00993 }
00994
00995 KIconView::contentsDragEnterEvent( e );
00996 emit dragEntered( true );
00997 }
00998
00999 void KonqIconViewWidget::contentsDragMoveEvent( QDragMoveEvent *e )
01000 {
01001 if ( d->bProgramsURLdrag ) {
01002 emit dragMove( false );
01003 e->ignore();
01004 cancelPendingHeldSignal();
01005 return;
01006 }
01007
01008 #ifdef KFILEITEM_HAS_ISWRITABLE
01009 QIconViewItem *item = findItem( e->pos() );
01010 if ( !item && m_rootItem && !m_rootItem->isWritable() ) {
01011 emit dragMove( false );
01012 e->ignore();
01013 cancelPendingHeldSignal();
01014 return;
01015 }
01016 #endif
01017 emit dragMove( true );
01018 KIconView::contentsDragMoveEvent( e );
01019 }
01020
01021 void KonqIconViewWidget::contentsDragLeaveEvent( QDragLeaveEvent *e )
01022 {
01023 d->bProgramsURLdrag = false;
01024 QIconView::contentsDragLeaveEvent(e);
01025 emit dragLeft();
01026 }
01027
01028
01029 void KonqIconViewWidget::setItemColor( const QColor &c )
01030 {
01031 iColor = c;
01032 }
01033
01034 QColor KonqIconViewWidget::itemColor() const
01035 {
01036 return iColor;
01037 }
01038
01039 void KonqIconViewWidget::disableIcons( const KURL::List & lst )
01040 {
01041 for ( QIconViewItem *kit = firstItem(); kit; kit = kit->nextItem() )
01042 {
01043 bool bFound = false;
01044
01045
01046 for (KURL::List::ConstIterator it = lst.begin(); !bFound && it != lst.end(); ++it)
01047 {
01048 if ( static_cast<KFileIVI *>( kit )->item()->url() == *it )
01049 {
01050 bFound = true;
01051
01052 }
01053 }
01054 static_cast<KFileIVI *>( kit )->setDisabled( bFound );
01055 }
01056 }
01057
01058 void KonqIconViewWidget::slotSelectionChanged()
01059 {
01060
01061 int canCopy = 0;
01062 int canDel = 0;
01063 int canTrash = 0;
01064 bool bInTrash = false;
01065 int iCount = 0;
01066
01067 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01068 {
01069 if ( it->isSelected() )
01070 {
01071 iCount++;
01072 canCopy++;
01073
01074 KFileItem *item = ( static_cast<KFileIVI *>( it ) )->item();
01075 KURL url = item->url();
01076 QString local_path = item->localPath();
01077
01078 if ( url.directory(false) == KGlobalSettings::trashPath() )
01079 bInTrash = true;
01080 if ( KProtocolInfo::supportsDeleting( url ) )
01081 canDel++;
01082 if ( !local_path.isEmpty() )
01083 canTrash++;
01084 }
01085 }
01086
01087 emit enableAction( "cut", canDel > 0 );
01088 emit enableAction( "copy", canCopy > 0 );
01089 emit enableAction( "trash", canDel > 0 && !bInTrash && canTrash==canDel );
01090 emit enableAction( "del", canDel > 0 );
01091 emit enableAction( "properties", iCount > 0 && KPropertiesDialog::canDisplay( selectedFileItems() ) );
01092 emit enableAction( "editMimeType", ( iCount == 1 ) );
01093 emit enableAction( "rename", ( iCount == 1) && !bInTrash );
01094 }
01095
01096 void KonqIconViewWidget::renameCurrentItem()
01097 {
01098 if ( currentItem() )
01099 currentItem()->rename();
01100 }
01101
01102 void KonqIconViewWidget::renameSelectedItem()
01103 {
01104 kdDebug(1203) << " -- KonqIconViewWidget::renameSelectedItem() -- " << endl;
01105 QIconViewItem * item = 0L;
01106 QIconViewItem *it = firstItem();
01107 for (; it; it = it->nextItem() )
01108 if ( it->isSelected() && !item )
01109 {
01110 item = it;
01111 break;
01112 }
01113 if (!item)
01114 {
01115 Q_ASSERT(item);
01116 return;
01117 }
01118 item->rename();
01119 }
01120
01121 void KonqIconViewWidget::cutSelection()
01122 {
01123 kdDebug(1203) << " -- KonqIconViewWidget::cutSelection() -- " << endl;
01124 KonqIconDrag * obj = konqDragObject( );
01125 obj->setMoveSelection( true );
01126 QApplication::clipboard()->setData( obj );
01127 }
01128
01129 void KonqIconViewWidget::copySelection()
01130 {
01131 kdDebug(1203) << " -- KonqIconViewWidget::copySelection() -- " << endl;
01132 KonqIconDrag * obj = konqDragObject( );
01133 QApplication::clipboard()->setData( obj );
01134 }
01135
01136 void KonqIconViewWidget::pasteSelection()
01137 {
01138 paste( url() );
01139 }
01140
01141 void KonqIconViewWidget::paste( const KURL &url )
01142 {
01143 KonqOperations::doPaste( this, url );
01144 }
01145
01146 KURL::List KonqIconViewWidget::selectedUrls()
01147 {
01148 KURL::List lstURLs;
01149
01150 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01151 if ( it->isSelected() )
01152 lstURLs.append( (static_cast<KFileIVI *>( it ))->item()->url() );
01153 return lstURLs;
01154 }
01155
01156 QRect KonqIconViewWidget::iconArea() const
01157 {
01158 return m_IconRect;
01159 }
01160
01161 void KonqIconViewWidget::setIconArea(const QRect &rect)
01162 {
01163 m_IconRect = rect;
01164 }
01165
01166 int KonqIconViewWidget::lineupMode() const
01167 {
01168 return m_LineupMode;
01169 }
01170
01171 void KonqIconViewWidget::setLineupMode(int mode)
01172 {
01173 m_LineupMode = mode;
01174 }
01175
01176 bool KonqIconViewWidget::sortDirectoriesFirst() const
01177 {
01178 return m_bSortDirsFirst;
01179 }
01180
01181 void KonqIconViewWidget::setSortDirectoriesFirst( bool b )
01182 {
01183 m_bSortDirsFirst = b;
01184 }
01185
01186 void KonqIconViewWidget::contentsMouseMoveEvent( QMouseEvent *e )
01187 {
01188 if ( (d->pSoundPlayer && d->pSoundPlayer->isPlaying()) || (d->pSoundTimer && d->pSoundTimer->isActive()))
01189 {
01190
01191
01192
01193 if ( QApplication::widgetAt( QCursor::pos() ) != topLevelWidget() )
01194 {
01195 if (d->pSoundPlayer)
01196 d->pSoundPlayer->stop();
01197 d->pSoundItem = 0;
01198 if (d->pSoundTimer && d->pSoundTimer->isActive())
01199 d->pSoundTimer->stop();
01200 }
01201 }
01202 d->renameItem= false;
01203 QIconView::contentsMouseMoveEvent( e );
01204 }
01205
01206 void KonqIconViewWidget::contentsDropEvent( QDropEvent * ev )
01207 {
01208 QIconViewItem *i = findItem( ev->pos() );
01209
01210 #ifdef KFILEITEM_HAS_ISWRITABLE
01211 if ( !i && m_rootItem && !m_rootItem->isWritable() ) {
01212 ev->accept( false );
01213 return;
01214 }
01215 #endif
01216
01217
01218
01219 if ( !i && (ev->action() == QDropEvent::Copy || ev->action() == QDropEvent::Link)
01220 && ev->source() && ev->source() == viewport())
01221 {
01222
01223 bool bMovable = itemsMovable();
01224 setItemsMovable(false);
01225 KIconView::contentsDropEvent( ev );
01226 setItemsMovable(bMovable);
01227
01228 QValueList<QIconDragItem> lst;
01229 slotDropped(ev, lst);
01230 }
01231 else
01232 {
01233 KIconView::contentsDropEvent( ev );
01234 emit dropped();
01235 }
01236
01237
01238
01239
01240
01241
01242
01243
01244 emit dragFinished();
01245 }
01246
01247 void KonqIconViewWidget::doubleClickTimeout()
01248 {
01249 d->renameItem= true;
01250 mousePressChangeValue();
01251 if ( d->releaseMouseEvent )
01252 {
01253 QMouseEvent e( QEvent::MouseButtonPress,d->mousePos , 1, d->mouseState);
01254 QIconViewItem* item = findItem( e.pos() );
01255 KURL url;
01256 if ( item )
01257 {
01258 url= ( static_cast<KFileIVI *>( item ) )->item()->url();
01259 bool brenameTrash =false;
01260 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath())))
01261 brenameTrash = true;
01262
01263 if ( url.isLocalFile() && !brenameTrash && d->renameItem && m_pSettings->renameIconDirectly() && e.button() == LeftButton && item->textRect( false ).contains(e.pos()))
01264 {
01265 if( d->pActivateDoubleClick->isActive () )
01266 d->pActivateDoubleClick->stop();
01267 item->rename();
01268 m_bMousePressed = false;
01269 }
01270 }
01271 }
01272 else
01273 {
01274 QMouseEvent e( QEvent::MouseMove,d->mousePos , 1, d->mouseState);
01275 KIconView::contentsMousePressEvent( &e );
01276 }
01277 if( d->pActivateDoubleClick->isActive() )
01278 d->pActivateDoubleClick->stop();
01279
01280 d->releaseMouseEvent = false;
01281 d->renameItem= false;
01282 }
01283
01284 void KonqIconViewWidget::wheelEvent(QWheelEvent* e)
01285 {
01286
01287 d->pFileTip->setItem( 0 );
01288
01289 if (e->state() == ControlButton)
01290 {
01291 if (e->delta() >= 0)
01292 {
01293 emit incIconSize();
01294 }
01295 else
01296 {
01297 emit decIconSize();
01298 }
01299 e->accept();
01300 return;
01301 }
01302
01303 KIconView::wheelEvent(e);
01304 }
01305
01306 void KonqIconViewWidget::leaveEvent( QEvent *e )
01307 {
01308
01309 d->pFileTip->setItem( 0 );
01310
01311 KIconView::leaveEvent(e);
01312 }
01313
01314 void KonqIconViewWidget::mousePressChangeValue()
01315 {
01316
01317 m_bMousePressed = true;
01318 if (d->pSoundPlayer)
01319 d->pSoundPlayer->stop();
01320 d->bSoundItemClicked = true;
01321 d->firstClick = false;
01322
01323
01324
01325 d->pFileTip->setItem( 0 );
01326 }
01327
01328 void KonqIconViewWidget::contentsMousePressEvent( QMouseEvent *e )
01329 {
01330 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ())
01331 d->pActivateDoubleClick->stop();
01332 QIconViewItem* item = findItem( e->pos() );
01333 m_mousePos = e->pos();
01334 KURL url;
01335 if ( item )
01336 {
01337 url = ( static_cast<KFileIVI *>( item ) )->item()->url();
01338 bool brenameTrash =false;
01339 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath())))
01340 brenameTrash = true;
01341 if ( !brenameTrash && !KGlobalSettings::singleClick() && m_pSettings->renameIconDirectly() && e->button() == LeftButton && item->textRect( false ).contains(e->pos())&& !d->firstClick && url.isLocalFile() && (!url.protocol().find("device", 0, false)==0))
01342 {
01343 d->firstClick = true;
01344 d->mousePos = e->pos();
01345 d->mouseState = e->state();
01346 if (!d->pActivateDoubleClick)
01347 {
01348 d->pActivateDoubleClick = new QTimer(this);
01349 connect(d->pActivateDoubleClick, SIGNAL(timeout()), this, SLOT(doubleClickTimeout()));
01350 }
01351 if( d->pActivateDoubleClick->isActive () )
01352 d->pActivateDoubleClick->stop();
01353 else
01354 d->pActivateDoubleClick->start(QApplication::doubleClickInterval());
01355 d->releaseMouseEvent = false;
01356 return;
01357 }
01358 else
01359 d->renameItem= false;
01360 }
01361 else
01362 d->renameItem= false;
01363 mousePressChangeValue();
01364 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive())
01365 d->pActivateDoubleClick->stop();
01366 KIconView::contentsMousePressEvent( e );
01367
01368 }
01369
01370 void KonqIconViewWidget::contentsMouseReleaseEvent( QMouseEvent *e )
01371 {
01372 KIconView::contentsMouseReleaseEvent( e );
01373 if(d->releaseMouseEvent && d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ())
01374 d->pActivateDoubleClick->stop();
01375 slotSelectionChanged();
01376 d->releaseMouseEvent = true;
01377 m_bMousePressed = false;
01378 }
01379
01380 void KonqIconViewWidget::slotSaveIconPositions()
01381 {
01382
01383
01384
01385
01386
01387
01388
01389 if ( m_dotDirectoryPath.isEmpty() )
01390 return;
01391 if ( !m_bDesktop )
01392 return;
01393 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions" << endl;
01394 KSimpleConfig dotDirectory( m_dotDirectoryPath );
01395 QIconViewItem *it = firstItem();
01396 if ( !it )
01397 return;
01398 while ( it )
01399 {
01400 KFileIVI *ivi = static_cast<KFileIVI *>( it );
01401 KFileItem *item = ivi->item();
01402
01403 dotDirectory.setGroup( QString( m_iconPositionGroupPrefix ).append( item->url().fileName() ) );
01404 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions " << item->url().fileName() << " " << it->x() << " " << it->y() << endl;
01405 dotDirectory.writeEntry( QString( "X %1" ).arg( width() ), it->x() );
01406 dotDirectory.writeEntry( QString( "Y %1" ).arg( height() ), it->y() );
01407 dotDirectory.writeEntry( "Exists", true );
01408
01409 it = it->nextItem();
01410 }
01411
01412 QStringList groups = dotDirectory.groupList();
01413 QStringList::ConstIterator gIt = groups.begin();
01414 QStringList::ConstIterator gEnd = groups.end();
01415 for (; gIt != gEnd; ++gIt )
01416 if ( (*gIt).left( m_iconPositionGroupPrefix.length() ) == m_iconPositionGroupPrefix )
01417 {
01418 dotDirectory.setGroup( *gIt );
01419 if ( dotDirectory.hasKey( "Exists" ) )
01420 dotDirectory.deleteEntry( "Exists", false );
01421 else
01422 {
01423 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions deleting group " << *gIt << endl;
01424 dotDirectory.deleteGroup( *gIt );
01425 }
01426 }
01427
01428 dotDirectory.sync();
01429
01430
01431
01432
01433
01434
01435
01436 }
01437
01438
01439
01440
01441 void KonqIconViewWidget::insertInGrid(QIconViewItem *item)
01442 {
01443 if (0L == item)
01444 return;
01445
01446 if (!m_IconRect.isValid())
01447 {
01448 QIconView::insertInGrid(item);
01449 return;
01450 }
01451
01452 QRegion r(m_IconRect);
01453 QIconViewItem *i = firstItem();
01454 int y = -1;
01455 for (; i; i = i->nextItem() )
01456 {
01457 r = r.subtract(i->rect());
01458 y = QMAX(y, i->y() + i->height());
01459 }
01460
01461 QMemArray<QRect> rects = r.rects();
01462 QMemArray<QRect>::Iterator it = rects.begin();
01463 bool foundPlace = FALSE;
01464 for (; it != rects.end(); ++it)
01465 {
01466 QRect rect = *it;
01467 if (rect.width() >= item->width() && rect.height() >= item->height())
01468 {
01469 int sx = 0, sy = 0;
01470 if (rect.width() >= item->width() + spacing())
01471 sx = spacing();
01472 if (rect.height() >= item->height() + spacing())
01473 sy = spacing();
01474 item->move(rect.x() + sx, rect.y() + sy);
01475 foundPlace = true;
01476 break;
01477 }
01478 }
01479
01480 if (!foundPlace)
01481 item->move(m_IconRect.topLeft());
01482
01483
01484 return;
01485 }
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515 void KonqIconViewWidget::lineupIcons()
01516 {
01517
01518
01519
01520
01521 int x0, y0, dx, dy, nx, ny;
01522 gridValues( &x0, &y0, &dx, &dy, &nx, &ny );
01523
01524 int itemWidth = dx - spacing();
01525 bool newItemWidth = false;
01526 if ( maxItemWidth() != itemWidth ) {
01527 newItemWidth = true;
01528 setMaxItemWidth( itemWidth );
01529 setFont( font() );
01530 }
01531
01532 if ( !firstItem() ) {
01533 kdDebug(1203) << "No icons at all ?\n";
01534 return;
01535 }
01536
01537 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01538
01539 typedef QValueList<QIconViewItem*> Bin;
01540 Bin*** bins = new Bin**[nx];
01541 int i;
01542 int j;
01543 for ( i = 0; i < nx ; i++ ) {
01544 bins[i] = new Bin*[ny];
01545 for ( j = 0; j < ny; j++ )
01546 bins[i][j] = 0L;
01547 }
01548
01549
01550 int textHeight = iconTextHeight() * fontMetrics().height();
01551
01552 for ( QIconViewItem* item = firstItem(); item; item = item->nextItem() ) {
01553 int x = item->x() + item->width() / 2 - x0;
01554 int y = item->pixmapRect( false ).bottom() - iconSize / 2
01555 - ( dy - ( iconSize + textHeight ) ) / 2 - y0;
01556 int posX = QMIN( nx-1, QMAX( 0, x / dx ) );
01557 int posY = QMIN( ny-1, QMAX( 0, y / dy ) );
01558
01559 if ( !bins[posX][posY] )
01560 bins[posX][posY] = new Bin;
01561 bins[posX][posY]->prepend( item );
01562 }
01563
01564
01565 int n, k;
01566 const int infinity = 10000;
01567 int nmoves = 1;
01568 for ( n = 0; n < 30 && nmoves > 0; n++ ) {
01569 nmoves = 0;
01570 for ( i = 0; i < nx; i++ ) {
01571 for ( j = 0; j < ny; j++ ) {
01572 if ( !bins[i][j] || ( bins[i][j]->count() <= 1 ) )
01573 continue;
01574
01575
01576 int tf = 0, bf = 0, lf = 0, rf = 0;
01577 for ( k = j-1; k >= 0 && bins[i][k] && bins[i][k]->count(); k-- )
01578 tf += bins[i][k]->count();
01579 if ( k == -1 )
01580 tf += infinity;
01581
01582 for ( k = j+1; k < ny && bins[i][k] && bins[i][k]->count(); k++ )
01583 bf += bins[i][k]->count();
01584 if ( k == ny )
01585 bf += infinity;
01586
01587 for ( k = i-1; k >= 0 && bins[k][j] && bins[k][j]->count(); k-- )
01588 lf += bins[k][j]->count();
01589 if ( k == -1 )
01590 lf += infinity;
01591
01592 for ( k = i+1; k < nx && bins[k][j] && bins[k][j]->count(); k++ )
01593 rf += bins[k][j]->count();
01594 if ( k == nx )
01595 rf += infinity;
01596
01597
01598 if ( tf >= infinity && bf >= infinity &&
01599 lf >= infinity && rf >= infinity )
01600 continue;
01601
01602
01603 if ( m_LineupMode == LineupHorizontal ) {
01604 tf += infinity;
01605 bf += infinity;
01606 }
01607 else if ( m_LineupMode == LineupVertical ) {
01608 lf += infinity;
01609 rf += infinity;
01610 }
01611
01612
01613 QIconViewItem* movedItem;
01614 Bin* items = bins[i][j];
01615
01616 int mini = QMIN( QMIN( tf, bf ), QMIN( lf, rf ) );
01617 if ( tf == mini ) {
01618
01619 Bin::iterator it = items->begin();
01620 movedItem = *it;
01621 for ( ++it; it != items->end(); ++it ) {
01622 if ( (*it)->y() < movedItem->y() )
01623 movedItem = *it;
01624 }
01625 items->remove( movedItem );
01626 if ( !bins[i][j-1] )
01627 bins[i][j-1] = new Bin;
01628 bins[i][j-1]->prepend( movedItem );
01629 }
01630 else if ( bf ==mini ) {
01631
01632 Bin::iterator it = items->begin();
01633 movedItem = *it;
01634 for ( ++it; it != items->end(); ++it ) {
01635 if ( (*it)->y() > movedItem->y() )
01636 movedItem = *it;
01637 }
01638 items->remove( movedItem );
01639 if ( !bins[i][j+1] )
01640 bins[i][j+1] = new Bin;
01641 bins[i][j+1]->prepend( movedItem );
01642 }
01643 else if ( lf == mini )
01644 {
01645
01646 Bin::iterator it = items->begin();
01647 movedItem = *it;
01648 for ( ++it; it != items->end(); ++it ) {
01649 if ( (*it)->x() < movedItem->x() )
01650 movedItem = *it;
01651 }
01652 items->remove( movedItem );
01653 if ( !bins[i-1][j] )
01654 bins[i-1][j] = new Bin;
01655 bins[i-1][j]->prepend( movedItem );
01656 }
01657 else {
01658
01659 Bin::iterator it = items->begin();
01660 movedItem = *it;
01661 for ( ++it; it != items->end(); ++it ) {
01662 if ( (*it)->x() > movedItem->x() )
01663 movedItem = *it;
01664 }
01665 items->remove( movedItem );
01666 if ( !bins[i+1][j] )
01667 bins[i+1][j] = new Bin;
01668 bins[i+1][j]->prepend( movedItem );
01669 }
01670 nmoves++;
01671 }
01672 }
01673 }
01674
01675
01676 QRegion repaintRegion;
01677 QValueList<QIconViewItem*> movedItems;
01678
01679 for ( i = 0; i < nx; i++ ) {
01680 for ( j = 0; j < ny; j++ ) {
01681 Bin* bin = bins[i][j];
01682 if ( !bin )
01683 continue;
01684 if ( !bin->isEmpty() ) {
01685 QIconViewItem* item = bin->first();
01686 int newX = x0 + i*dx + spacing() +
01687 QMAX(0, ( (dx-spacing()) - item->width() ) / 2);
01688
01689 int newY = y0 + j*dy + dy - spacing() - ( item->pixmapRect().bottom() + 2 + textHeight );
01690 if ( item->x() != newX || item->y() != newY ) {
01691 QRect oldRect = item->rect();
01692 movedItems.prepend( item );
01693 item->move( newX, newY );
01694 if ( item->rect() != oldRect )
01695 repaintRegion = repaintRegion.unite( oldRect );
01696 }
01697 }
01698 delete bin;
01699 bins[i][j] = 0L;
01700 }
01701 }
01702
01703
01704 if ( newItemWidth )
01705 updateContents();
01706 else {
01707
01708 QMemArray<QRect> rects = repaintRegion.rects();
01709 for ( uint l = 0; l < rects.count(); l++ ) {
01710 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << ","
01711 << rects[l].y() << ")\n";
01712 repaintContents( rects[l], false );
01713 }
01714
01715 while ( !movedItems.isEmpty() ) {
01716 repaintItem( movedItems.first() );
01717 movedItems.remove( movedItems.first() );
01718 }
01719 }
01720
01721 for ( i = 0; i < nx ; i++ ) {
01722 delete [] bins[i];
01723 }
01724 delete [] bins;
01725 }
01726
01727 void KonqIconViewWidget::lineupIcons( QIconView::Arrangement arrangement )
01728 {
01729 int x0, y0, dx, dy, nxmax, nymax;
01730 gridValues( &x0, &y0, &dx, &dy, &nxmax, &nymax );
01731 int textHeight = iconTextHeight() * fontMetrics().height();
01732
01733 QRegion repaintRegion;
01734 QValueList<QIconViewItem*> movedItems;
01735 int nx = 0, ny = 0;
01736
01737 QIconViewItem* item;
01738 for ( item = firstItem(); item; item = item->nextItem() ) {
01739 int newX = x0 + nx*dx + spacing() +
01740 QMAX(0, ( (dx-spacing()) - item->width() ) / 2);
01741
01742 int newY = y0 + ny*dy + dy - spacing() - ( item->pixmapRect().bottom() + 2 + textHeight );
01743 if ( item->x() != newX || item->y() != newY ) {
01744 QRect oldRect = item->rect();
01745 movedItems.prepend( item );
01746 item->move( newX, newY );
01747 if ( item->rect() != oldRect )
01748 repaintRegion = repaintRegion.unite( oldRect );
01749 }
01750 if ( arrangement == QIconView::LeftToRight ) {
01751 nx++;
01752 if ( nx >= nxmax ) {
01753 ny++;
01754 nx = 0;
01755 }
01756 }
01757 else {
01758 ny++;
01759 if ( ny >= nymax ) {
01760 nx++;
01761 ny = 0;
01762 }
01763 }
01764 }
01765
01766
01767 QMemArray<QRect> rects = repaintRegion.rects();
01768 for ( uint l = 0; l < rects.count(); l++ ) {
01769 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << ","
01770 << rects[l].y() << ")\n";
01771 repaintContents( rects[l], false );
01772 }
01773
01774 while ( !movedItems.isEmpty() ) {
01775 repaintItem( movedItems.first() );
01776 movedItems.remove( movedItems.first() );
01777 }
01778 }
01779
01780 int KonqIconViewWidget::largestPreviewIconSize( int size ) const
01781 {
01782 int iconSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01783
01784 if (iconSize < 28)
01785 return 48;
01786 if (iconSize < 40)
01787 return 64;
01788 if (iconSize < 60)
01789 return 96;
01790 if (iconSize < 120)
01791 return 128;
01792
01793 return 192;
01794 }
01795
01796 int KonqIconViewWidget::previewIconSize( int size ) const
01797 {
01798 int iconSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01799
01800 if (!d->bBoostPreview)
01801 return iconSize;
01802
01803 return largestPreviewIconSize( iconSize );
01804 }
01805
01806 void KonqIconViewWidget::visualActivate(QIconViewItem * item)
01807 {
01808
01809 QRect irect = item->rect();
01810
01811
01812 QRect rect = item->pixmapRect();
01813
01814
01815
01816 rect.moveBy(irect.x(), irect.y());
01817
01818
01819 rect.moveBy( -contentsX(), -contentsY() );
01820
01821 KIconEffect::visualActivate(viewport(), rect);
01822 }
01823
01824 void KonqIconViewWidget::backgroundPixmapChange( const QPixmap & )
01825 {
01826 viewport()->update();
01827 }
01828
01829 void KonqIconViewWidget::setPreviewSettings( const QStringList& settings )
01830 {
01831 d->previewSettings = settings;
01832 updatePreviewMimeTypes();
01833
01834 int size = m_size;
01835 m_size = -1;
01836 setIcons( size );
01837 }
01838
01839 const QStringList& KonqIconViewWidget::previewSettings()
01840 {
01841 return d->previewSettings;
01842 }
01843
01844 void KonqIconViewWidget::setNewURL( const QString& url )
01845 {
01846 KURL u;
01847 if ( url.startsWith( "/" ) )
01848 u.setPath( url );
01849 else
01850 u = url;
01851 setURL( u );
01852 }
01853
01854 void KonqIconViewWidget::setCaseInsensitiveSort( bool b )
01855 {
01856 d->bCaseInsensitive = b;
01857 }
01858
01859 bool KonqIconViewWidget::caseInsensitiveSort() const
01860 {
01861 return d->bCaseInsensitive;
01862 }
01863
01864 bool KonqIconViewWidget::canPreview( KFileItem* item )
01865 {
01866 if ( !KGlobalSettings::showFilePreview( url() ) )
01867 return false;
01868
01869 if ( d->pPreviewMimeTypes == 0L )
01870 updatePreviewMimeTypes();
01871
01872 return mimeTypeMatch( item->mimetype(), *( d->pPreviewMimeTypes ) );
01873 }
01874
01875 void KonqIconViewWidget::updatePreviewMimeTypes()
01876 {
01877 if ( d->pPreviewMimeTypes == 0L )
01878 d->pPreviewMimeTypes = new QStringList;
01879 else
01880 d->pPreviewMimeTypes->clear();
01881
01882
01883 KTrader::OfferList plugins = KTrader::self()->query("ThumbCreator");
01884 KTrader::OfferList::ConstIterator it;
01885
01886 for ( it = plugins.begin(); it != plugins.end(); ++it ) {
01887 if ( d->previewSettings.contains((*it)->desktopEntryName()) ) {
01888 QStringList mimeTypes = (*it)->property("MimeTypes").toStringList();
01889 for (QStringList::ConstIterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt)
01890 d->pPreviewMimeTypes->append(*mt);
01891 }
01892 }
01893 }
01894
01895 #include "konq_iconviewwidget.moc"
01896
01897