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 if( *nx == 0 )
00749 *nx = 1;
00750 if( *ny == 0 )
00751 *ny = 1;
00752
00753 *dx = w / *nx;
00754 *dy = h / *ny;
00755 kdDebug(1203) << "x=" << *x << " y=" << *y << " spacing=" << spacing() << " iconSize=" << iconSize
00756 << " w=" << w << " h=" << h
00757 << " nx=" << *nx << " ny=" << *ny
00758 << " dx=" << *dx << " dy=" << *dy << endl;
00759 }
00760
00761 void KonqIconViewWidget::calculateGridX()
00762 {
00763 if ( m_bSetGridX )
00764 if ( itemTextPos() == QIconView::Bottom )
00765 setGridX( gridXValue() );
00766 else
00767 {
00768 setMaxItemWidth( gridXValue() );
00769 setGridX( -1 );
00770 }
00771 }
00772
00773 int KonqIconViewWidget::gridXValue() const
00774 {
00775
00776 int sz = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00777 int newGridX;
00778
00779 if ( itemTextPos() == QIconView::Bottom )
00780 newGridX = QMAX( sz + 50, previewIconSize( sz ) + 13 );
00781 else
00782 newGridX = QMAX( sz, previewIconSize( sz ) ) + m_pSettings->iconTextWidth();
00783
00784
00785 return newGridX;
00786 }
00787
00788 void KonqIconViewWidget::refreshMimeTypes()
00789 {
00790 updatePreviewMimeTypes();
00791 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
00792 (static_cast<KFileIVI *>( it ))->item()->refreshMimeType();
00793 setIcons( m_size );
00794 }
00795
00796 void KonqIconViewWidget::setURL( const KURL &kurl )
00797 {
00798 stopImagePreview();
00799 m_url = kurl;
00800
00801 d->pFileTip->setPreview( KGlobalSettings::showFilePreview(m_url) );
00802
00803 if ( m_url.isLocalFile() )
00804 m_dotDirectoryPath = m_url.path(1).append( ".directory" );
00805 else
00806 m_dotDirectoryPath = QString::null;
00807 }
00808
00809 void KonqIconViewWidget::startImagePreview( const QStringList &, bool force )
00810 {
00811 stopImagePreview();
00812
00813
00814 if ( !KGlobalSettings::showFilePreview( url() ) ) {
00815 kdDebug(1203) << "Previews disabled for protocol " << url().protocol() << endl;
00816 emit imagePreviewFinished();
00817 return;
00818 }
00819
00820 if ((d->bSoundPreviews = d->previewSettings.contains( "audio/" )) &&
00821 !d->pSoundPlayer)
00822 {
00823 KLibFactory *factory = KLibLoader::self()->factory("konq_sound");
00824 if (factory)
00825 d->pSoundPlayer = static_cast<KonqSoundPlayer *>(
00826 factory->create(this, 0, "KonqSoundPlayer"));
00827 d->bSoundPreviews = (d->pSoundPlayer != 0L);
00828 }
00829
00830 KFileItemList items;
00831 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
00832 if ( force || !static_cast<KFileIVI *>( it )->hasValidThumbnail() )
00833 items.append( static_cast<KFileIVI *>( it )->item() );
00834
00835 bool onlyAudio = true;
00836 for ( QStringList::ConstIterator it = d->previewSettings.begin(); it != d->previewSettings.end(); ++it ) {
00837 if ( (*it).startsWith( "audio/" ) )
00838 d->bSoundPreviews = true;
00839 else
00840 onlyAudio = false;
00841 }
00842
00843 if ( items.isEmpty() || onlyAudio ) {
00844 emit imagePreviewFinished();
00845 return;
00846 }
00847
00848 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00849 int size;
00850
00851 d->bBoostPreview = boostPreview();
00852 size = previewIconSize( iconSize );
00853
00854 if ( !d->bBoostPreview )
00855 iconSize /= 2;
00856
00857 d->pPreviewJob = KIO::filePreview( items, size, size, iconSize,
00858 m_pSettings->textPreviewIconTransparency(), true ,
00859 true , &(d->previewSettings) );
00860 connect( d->pPreviewJob, SIGNAL( gotPreview( const KFileItem *, const QPixmap & ) ),
00861 this, SLOT( slotPreview( const KFileItem *, const QPixmap & ) ) );
00862 connect( d->pPreviewJob, SIGNAL( result( KIO::Job * ) ),
00863 this, SLOT( slotPreviewResult() ) );
00864 }
00865
00866 void KonqIconViewWidget::stopImagePreview()
00867 {
00868 if (d->pPreviewJob)
00869 {
00870 d->pPreviewJob->kill();
00871 d->pPreviewJob = 0;
00872
00873
00874 }
00875 }
00876
00877 bool KonqIconViewWidget::isPreviewRunning() const
00878 {
00879 return d->pPreviewJob;
00880 }
00881
00882 KFileItemList KonqIconViewWidget::selectedFileItems()
00883 {
00884 KFileItemList lstItems;
00885
00886 QIconViewItem *it = firstItem();
00887 for (; it; it = it->nextItem() )
00888 if ( it->isSelected() ) {
00889 KFileItem *fItem = (static_cast<KFileIVI *>(it))->item();
00890 lstItems.append( fItem );
00891 }
00892 return lstItems;
00893 }
00894
00895 void KonqIconViewWidget::slotDropped( QDropEvent *ev, const QValueList<QIconDragItem> & )
00896 {
00897
00898 KonqOperations::doDrop( m_rootItem , url(), ev, this );
00899 }
00900
00901 void KonqIconViewWidget::slotAboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)
00902 {
00903
00904 }
00905
00906 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r )
00907 {
00908 drawBackground(p, r, r.topLeft());
00909 }
00910
00911 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r , const QPoint &pt)
00912 {
00913 const QPixmap *pm = backgroundPixmap();
00914 bool hasPixmap = pm && !pm->isNull();
00915 if ( !hasPixmap ) {
00916 pm = viewport()->backgroundPixmap();
00917 hasPixmap = pm && !pm->isNull();
00918 }
00919
00920 QRect rtgt(r);
00921 rtgt.moveTopLeft(pt);
00922 if (!hasPixmap && backgroundMode() != NoBackground) {
00923 p->fillRect(rtgt, viewport()->backgroundColor());
00924 return;
00925 }
00926
00927 if (hasPixmap) {
00928 int ax = (r.x() + contentsX() + leftMargin()) % pm->width();
00929 int ay = (r.y() + contentsY() + topMargin()) % pm->height();
00930 p->drawTiledPixmap(rtgt, *pm, QPoint(ax, ay));
00931 }
00932 }
00933
00934 QDragObject * KonqIconViewWidget::dragObject()
00935 {
00936 if ( !currentItem() )
00937 return 0;
00938
00939 return konqDragObject( viewport() );
00940 }
00941
00942 KonqIconDrag * KonqIconViewWidget::konqDragObject( QWidget * dragSource )
00943 {
00944
00945
00946 KonqIconDrag * drag = new KonqIconDrag( dragSource );
00947 QIconViewItem *primaryItem = currentItem();
00948
00949 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00950 if ( it->isSelected() ) {
00951 if (!primaryItem)
00952 primaryItem = it;
00953 KURL url = (static_cast<KFileIVI *>(it))->item()->url();
00954 QString itemURL = KURLDrag::urlToString(url);
00955 kdDebug(1203) << "itemURL=" << itemURL << endl;
00956 QIconDragItem id;
00957 id.setData( QCString(itemURL.latin1()) );
00958 drag->append( id,
00959 QRect( it->pixmapRect(false).topLeft() - m_mousePos,
00960 it->pixmapRect().size() ),
00961 QRect( it->textRect(false).topLeft() - m_mousePos,
00962 it->textRect().size() ),
00963 itemURL );
00964 }
00965 }
00966
00967 if (primaryItem)
00968 drag->setPixmap( *primaryItem->pixmap(), m_mousePos - primaryItem->pixmapRect(false).topLeft() );
00969
00970 return drag;
00971 }
00972
00973 void KonqIconViewWidget::contentsDragEnterEvent( QDragEnterEvent *e )
00974 {
00975 if ( e->provides( "text/uri-list" ) )
00976 {
00977 QByteArray payload = e->encodedData( "text/uri-list" );
00978 if ( !payload.size() )
00979 kdError() << "Empty data !" << endl;
00980
00981
00982 bool ok = KURLDrag::decode( e, m_lstDragURLs );
00983 if( !ok )
00984 kdError() << "Couldn't decode urls dragged !" << endl;
00985 }
00986
00987 KURL::List uriList;
00988 if ( KURLDrag::decode(e, uriList) )
00989 {
00990 if ( uriList.first().protocol() == "programs" )
00991 {
00992 e->ignore();
00993 emit dragEntered( false );
00994 d->bProgramsURLdrag = true;
00995 return;
00996 }
00997 }
00998
00999 KIconView::contentsDragEnterEvent( e );
01000 emit dragEntered( true );
01001 }
01002
01003 void KonqIconViewWidget::contentsDragMoveEvent( QDragMoveEvent *e )
01004 {
01005 if ( d->bProgramsURLdrag ) {
01006 emit dragMove( false );
01007 e->ignore();
01008 cancelPendingHeldSignal();
01009 return;
01010 }
01011
01012 #ifdef KFILEITEM_HAS_ISWRITABLE
01013 QIconViewItem *item = findItem( e->pos() );
01014 if ( !item && m_rootItem && !m_rootItem->isWritable() ) {
01015 emit dragMove( false );
01016 e->ignore();
01017 cancelPendingHeldSignal();
01018 return;
01019 }
01020 #endif
01021 emit dragMove( true );
01022 KIconView::contentsDragMoveEvent( e );
01023 }
01024
01025 void KonqIconViewWidget::contentsDragLeaveEvent( QDragLeaveEvent *e )
01026 {
01027 d->bProgramsURLdrag = false;
01028 QIconView::contentsDragLeaveEvent(e);
01029 emit dragLeft();
01030 }
01031
01032
01033 void KonqIconViewWidget::setItemColor( const QColor &c )
01034 {
01035 iColor = c;
01036 }
01037
01038 QColor KonqIconViewWidget::itemColor() const
01039 {
01040 return iColor;
01041 }
01042
01043 void KonqIconViewWidget::disableIcons( const KURL::List & lst )
01044 {
01045 for ( QIconViewItem *kit = firstItem(); kit; kit = kit->nextItem() )
01046 {
01047 bool bFound = false;
01048
01049
01050 for (KURL::List::ConstIterator it = lst.begin(); !bFound && it != lst.end(); ++it)
01051 {
01052 if ( static_cast<KFileIVI *>( kit )->item()->url() == *it )
01053 {
01054 bFound = true;
01055
01056 }
01057 }
01058 static_cast<KFileIVI *>( kit )->setDisabled( bFound );
01059 }
01060 }
01061
01062 void KonqIconViewWidget::slotSelectionChanged()
01063 {
01064
01065 int canCopy = 0;
01066 int canDel = 0;
01067 int canTrash = 0;
01068 bool bInTrash = false;
01069 int iCount = 0;
01070
01071 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01072 {
01073 if ( it->isSelected() )
01074 {
01075 iCount++;
01076 canCopy++;
01077
01078 KFileItem *item = ( static_cast<KFileIVI *>( it ) )->item();
01079 KURL url = item->url();
01080 QString local_path = item->localPath();
01081
01082 if ( url.directory(false) == KGlobalSettings::trashPath() )
01083 bInTrash = true;
01084 if ( KProtocolInfo::supportsDeleting( url ) )
01085 canDel++;
01086 if ( !local_path.isEmpty() )
01087 canTrash++;
01088 }
01089 }
01090
01091 emit enableAction( "cut", canDel > 0 );
01092 emit enableAction( "copy", canCopy > 0 );
01093 emit enableAction( "trash", canDel > 0 && !bInTrash && canTrash==canDel );
01094 emit enableAction( "del", canDel > 0 );
01095 emit enableAction( "properties", iCount > 0 && KPropertiesDialog::canDisplay( selectedFileItems() ) );
01096 emit enableAction( "editMimeType", ( iCount == 1 ) );
01097 emit enableAction( "rename", ( iCount == 1) && !bInTrash );
01098 }
01099
01100 void KonqIconViewWidget::renameCurrentItem()
01101 {
01102 if ( currentItem() )
01103 currentItem()->rename();
01104 }
01105
01106 void KonqIconViewWidget::renameSelectedItem()
01107 {
01108 kdDebug(1203) << " -- KonqIconViewWidget::renameSelectedItem() -- " << endl;
01109 QIconViewItem * item = 0L;
01110 QIconViewItem *it = firstItem();
01111 for (; it; it = it->nextItem() )
01112 if ( it->isSelected() && !item )
01113 {
01114 item = it;
01115 break;
01116 }
01117 if (!item)
01118 {
01119 Q_ASSERT(item);
01120 return;
01121 }
01122 item->rename();
01123 }
01124
01125 void KonqIconViewWidget::cutSelection()
01126 {
01127 kdDebug(1203) << " -- KonqIconViewWidget::cutSelection() -- " << endl;
01128 KonqIconDrag * obj = konqDragObject( );
01129 obj->setMoveSelection( true );
01130 QApplication::clipboard()->setData( obj );
01131 }
01132
01133 void KonqIconViewWidget::copySelection()
01134 {
01135 kdDebug(1203) << " -- KonqIconViewWidget::copySelection() -- " << endl;
01136 KonqIconDrag * obj = konqDragObject( );
01137 QApplication::clipboard()->setData( obj );
01138 }
01139
01140 void KonqIconViewWidget::pasteSelection()
01141 {
01142 paste( url() );
01143 }
01144
01145 void KonqIconViewWidget::paste( const KURL &url )
01146 {
01147 KonqOperations::doPaste( this, url );
01148 }
01149
01150 KURL::List KonqIconViewWidget::selectedUrls()
01151 {
01152 KURL::List lstURLs;
01153
01154 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01155 if ( it->isSelected() )
01156 lstURLs.append( (static_cast<KFileIVI *>( it ))->item()->url() );
01157 return lstURLs;
01158 }
01159
01160 QRect KonqIconViewWidget::iconArea() const
01161 {
01162 return m_IconRect;
01163 }
01164
01165 void KonqIconViewWidget::setIconArea(const QRect &rect)
01166 {
01167 m_IconRect = rect;
01168 }
01169
01170 int KonqIconViewWidget::lineupMode() const
01171 {
01172 return m_LineupMode;
01173 }
01174
01175 void KonqIconViewWidget::setLineupMode(int mode)
01176 {
01177 m_LineupMode = mode;
01178 }
01179
01180 bool KonqIconViewWidget::sortDirectoriesFirst() const
01181 {
01182 return m_bSortDirsFirst;
01183 }
01184
01185 void KonqIconViewWidget::setSortDirectoriesFirst( bool b )
01186 {
01187 m_bSortDirsFirst = b;
01188 }
01189
01190 void KonqIconViewWidget::contentsMouseMoveEvent( QMouseEvent *e )
01191 {
01192 if ( (d->pSoundPlayer && d->pSoundPlayer->isPlaying()) || (d->pSoundTimer && d->pSoundTimer->isActive()))
01193 {
01194
01195
01196
01197 if ( QApplication::widgetAt( QCursor::pos() ) != topLevelWidget() )
01198 {
01199 if (d->pSoundPlayer)
01200 d->pSoundPlayer->stop();
01201 d->pSoundItem = 0;
01202 if (d->pSoundTimer && d->pSoundTimer->isActive())
01203 d->pSoundTimer->stop();
01204 }
01205 }
01206 d->renameItem= false;
01207 QIconView::contentsMouseMoveEvent( e );
01208 }
01209
01210 void KonqIconViewWidget::contentsDropEvent( QDropEvent * ev )
01211 {
01212 QIconViewItem *i = findItem( ev->pos() );
01213
01214 #ifdef KFILEITEM_HAS_ISWRITABLE
01215 if ( !i && m_rootItem && !m_rootItem->isWritable() ) {
01216 ev->accept( false );
01217 return;
01218 }
01219 #endif
01220
01221
01222
01223 if ( !i && (ev->action() == QDropEvent::Copy || ev->action() == QDropEvent::Link)
01224 && ev->source() && ev->source() == viewport())
01225 {
01226
01227 bool bMovable = itemsMovable();
01228 setItemsMovable(false);
01229 KIconView::contentsDropEvent( ev );
01230 setItemsMovable(bMovable);
01231
01232 QValueList<QIconDragItem> lst;
01233 slotDropped(ev, lst);
01234 }
01235 else
01236 {
01237 KIconView::contentsDropEvent( ev );
01238 emit dropped();
01239 }
01240
01241
01242
01243
01244
01245
01246
01247
01248 emit dragFinished();
01249 }
01250
01251 void KonqIconViewWidget::doubleClickTimeout()
01252 {
01253 d->renameItem= true;
01254 mousePressChangeValue();
01255 if ( d->releaseMouseEvent )
01256 {
01257 QMouseEvent e( QEvent::MouseButtonPress,d->mousePos , 1, d->mouseState);
01258 QIconViewItem* item = findItem( e.pos() );
01259 KURL url;
01260 if ( item )
01261 {
01262 url= ( static_cast<KFileIVI *>( item ) )->item()->url();
01263 bool brenameTrash =false;
01264 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath())))
01265 brenameTrash = true;
01266
01267 if ( url.isLocalFile() && !brenameTrash && d->renameItem && m_pSettings->renameIconDirectly() && e.button() == LeftButton && item->textRect( false ).contains(e.pos()))
01268 {
01269 if( d->pActivateDoubleClick->isActive () )
01270 d->pActivateDoubleClick->stop();
01271 item->rename();
01272 m_bMousePressed = false;
01273 }
01274 }
01275 }
01276 else
01277 {
01278 QMouseEvent e( QEvent::MouseMove,d->mousePos , 1, d->mouseState);
01279 KIconView::contentsMousePressEvent( &e );
01280 }
01281 if( d->pActivateDoubleClick->isActive() )
01282 d->pActivateDoubleClick->stop();
01283
01284 d->releaseMouseEvent = false;
01285 d->renameItem= false;
01286 }
01287
01288 void KonqIconViewWidget::wheelEvent(QWheelEvent* e)
01289 {
01290
01291 d->pFileTip->setItem( 0 );
01292
01293 if (e->state() == ControlButton)
01294 {
01295 if (e->delta() >= 0)
01296 {
01297 emit incIconSize();
01298 }
01299 else
01300 {
01301 emit decIconSize();
01302 }
01303 e->accept();
01304 return;
01305 }
01306
01307 KIconView::wheelEvent(e);
01308 }
01309
01310 void KonqIconViewWidget::leaveEvent( QEvent *e )
01311 {
01312
01313 d->pFileTip->setItem( 0 );
01314
01315 KIconView::leaveEvent(e);
01316 }
01317
01318 void KonqIconViewWidget::mousePressChangeValue()
01319 {
01320
01321 m_bMousePressed = true;
01322 if (d->pSoundPlayer)
01323 d->pSoundPlayer->stop();
01324 d->bSoundItemClicked = true;
01325 d->firstClick = false;
01326
01327
01328
01329 d->pFileTip->setItem( 0 );
01330 }
01331
01332 void KonqIconViewWidget::contentsMousePressEvent( QMouseEvent *e )
01333 {
01334 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ())
01335 d->pActivateDoubleClick->stop();
01336 QIconViewItem* item = findItem( e->pos() );
01337 m_mousePos = e->pos();
01338 KURL url;
01339 if ( item )
01340 {
01341 url = ( static_cast<KFileIVI *>( item ) )->item()->url();
01342 bool brenameTrash =false;
01343 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath())))
01344 brenameTrash = true;
01345 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))
01346 {
01347 d->firstClick = true;
01348 d->mousePos = e->pos();
01349 d->mouseState = e->state();
01350 if (!d->pActivateDoubleClick)
01351 {
01352 d->pActivateDoubleClick = new QTimer(this);
01353 connect(d->pActivateDoubleClick, SIGNAL(timeout()), this, SLOT(doubleClickTimeout()));
01354 }
01355 if( d->pActivateDoubleClick->isActive () )
01356 d->pActivateDoubleClick->stop();
01357 else
01358 d->pActivateDoubleClick->start(QApplication::doubleClickInterval());
01359 d->releaseMouseEvent = false;
01360 return;
01361 }
01362 else
01363 d->renameItem= false;
01364 }
01365 else
01366 d->renameItem= false;
01367 mousePressChangeValue();
01368 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive())
01369 d->pActivateDoubleClick->stop();
01370 KIconView::contentsMousePressEvent( e );
01371
01372 }
01373
01374 void KonqIconViewWidget::contentsMouseReleaseEvent( QMouseEvent *e )
01375 {
01376 KIconView::contentsMouseReleaseEvent( e );
01377 if(d->releaseMouseEvent && d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ())
01378 d->pActivateDoubleClick->stop();
01379 slotSelectionChanged();
01380 d->releaseMouseEvent = true;
01381 m_bMousePressed = false;
01382 }
01383
01384 void KonqIconViewWidget::slotSaveIconPositions()
01385 {
01386
01387
01388
01389
01390
01391
01392
01393 if ( m_dotDirectoryPath.isEmpty() )
01394 return;
01395 if ( !m_bDesktop )
01396 return;
01397 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions" << endl;
01398 KSimpleConfig dotDirectory( m_dotDirectoryPath );
01399 QIconViewItem *it = firstItem();
01400 if ( !it )
01401 return;
01402 while ( it )
01403 {
01404 KFileIVI *ivi = static_cast<KFileIVI *>( it );
01405 KFileItem *item = ivi->item();
01406
01407 dotDirectory.setGroup( QString( m_iconPositionGroupPrefix ).append( item->url().fileName() ) );
01408 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions " << item->url().fileName() << " " << it->x() << " " << it->y() << endl;
01409 dotDirectory.writeEntry( QString( "X %1" ).arg( width() ), it->x() );
01410 dotDirectory.writeEntry( QString( "Y %1" ).arg( height() ), it->y() );
01411 dotDirectory.writeEntry( "Exists", true );
01412
01413 it = it->nextItem();
01414 }
01415
01416 QStringList groups = dotDirectory.groupList();
01417 QStringList::ConstIterator gIt = groups.begin();
01418 QStringList::ConstIterator gEnd = groups.end();
01419 for (; gIt != gEnd; ++gIt )
01420 if ( (*gIt).left( m_iconPositionGroupPrefix.length() ) == m_iconPositionGroupPrefix )
01421 {
01422 dotDirectory.setGroup( *gIt );
01423 if ( dotDirectory.hasKey( "Exists" ) )
01424 dotDirectory.deleteEntry( "Exists", false );
01425 else
01426 {
01427 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions deleting group " << *gIt << endl;
01428 dotDirectory.deleteGroup( *gIt );
01429 }
01430 }
01431
01432 dotDirectory.sync();
01433
01434
01435
01436
01437
01438
01439
01440 }
01441
01442
01443
01444
01445 void KonqIconViewWidget::insertInGrid(QIconViewItem *item)
01446 {
01447 if (0L == item)
01448 return;
01449
01450 if (!m_IconRect.isValid())
01451 {
01452 QIconView::insertInGrid(item);
01453 return;
01454 }
01455
01456 QRegion r(m_IconRect);
01457 QIconViewItem *i = firstItem();
01458 int y = -1;
01459 for (; i; i = i->nextItem() )
01460 {
01461 r = r.subtract(i->rect());
01462 y = QMAX(y, i->y() + i->height());
01463 }
01464
01465 QMemArray<QRect> rects = r.rects();
01466 QMemArray<QRect>::Iterator it = rects.begin();
01467 bool foundPlace = FALSE;
01468 for (; it != rects.end(); ++it)
01469 {
01470 QRect rect = *it;
01471 if (rect.width() >= item->width() && rect.height() >= item->height())
01472 {
01473 int sx = 0, sy = 0;
01474 if (rect.width() >= item->width() + spacing())
01475 sx = spacing();
01476 if (rect.height() >= item->height() + spacing())
01477 sy = spacing();
01478 item->move(rect.x() + sx, rect.y() + sy);
01479 foundPlace = true;
01480 break;
01481 }
01482 }
01483
01484 if (!foundPlace)
01485 item->move(m_IconRect.topLeft());
01486
01487
01488 return;
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
01516
01517
01518
01519 void KonqIconViewWidget::lineupIcons()
01520 {
01521
01522
01523
01524
01525 int x0, y0, dx, dy, nx, ny;
01526 gridValues( &x0, &y0, &dx, &dy, &nx, &ny );
01527
01528 int itemWidth = dx - spacing();
01529 bool newItemWidth = false;
01530 if ( maxItemWidth() != itemWidth ) {
01531 newItemWidth = true;
01532 setMaxItemWidth( itemWidth );
01533 setFont( font() );
01534 }
01535
01536 if ( !firstItem() ) {
01537 kdDebug(1203) << "No icons at all ?\n";
01538 return;
01539 }
01540
01541 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01542
01543 typedef QValueList<QIconViewItem*> Bin;
01544 Bin*** bins = new Bin**[nx];
01545 int i;
01546 int j;
01547 for ( i = 0; i < nx ; i++ ) {
01548 bins[i] = new Bin*[ny];
01549 for ( j = 0; j < ny; j++ )
01550 bins[i][j] = 0L;
01551 }
01552
01553
01554 int textHeight = iconTextHeight() * fontMetrics().height();
01555
01556 for ( QIconViewItem* item = firstItem(); item; item = item->nextItem() ) {
01557 int x = item->x() + item->width() / 2 - x0;
01558 int y = item->pixmapRect( false ).bottom() - iconSize / 2
01559 - ( dy - ( iconSize + textHeight ) ) / 2 - y0;
01560 int posX = QMIN( nx-1, QMAX( 0, x / dx ) );
01561 int posY = QMIN( ny-1, QMAX( 0, y / dy ) );
01562
01563 if ( !bins[posX][posY] )
01564 bins[posX][posY] = new Bin;
01565 bins[posX][posY]->prepend( item );
01566 }
01567
01568
01569 int n, k;
01570 const int infinity = 10000;
01571 int nmoves = 1;
01572 for ( n = 0; n < 30 && nmoves > 0; n++ ) {
01573 nmoves = 0;
01574 for ( i = 0; i < nx; i++ ) {
01575 for ( j = 0; j < ny; j++ ) {
01576 if ( !bins[i][j] || ( bins[i][j]->count() <= 1 ) )
01577 continue;
01578
01579
01580 int tf = 0, bf = 0, lf = 0, rf = 0;
01581 for ( k = j-1; k >= 0 && bins[i][k] && bins[i][k]->count(); k-- )
01582 tf += bins[i][k]->count();
01583 if ( k == -1 )
01584 tf += infinity;
01585
01586 for ( k = j+1; k < ny && bins[i][k] && bins[i][k]->count(); k++ )
01587 bf += bins[i][k]->count();
01588 if ( k == ny )
01589 bf += infinity;
01590
01591 for ( k = i-1; k >= 0 && bins[k][j] && bins[k][j]->count(); k-- )
01592 lf += bins[k][j]->count();
01593 if ( k == -1 )
01594 lf += infinity;
01595
01596 for ( k = i+1; k < nx && bins[k][j] && bins[k][j]->count(); k++ )
01597 rf += bins[k][j]->count();
01598 if ( k == nx )
01599 rf += infinity;
01600
01601
01602 if ( tf >= infinity && bf >= infinity &&
01603 lf >= infinity && rf >= infinity )
01604 continue;
01605
01606
01607 if ( m_LineupMode == LineupHorizontal ) {
01608 tf += infinity;
01609 bf += infinity;
01610 }
01611 else if ( m_LineupMode == LineupVertical ) {
01612 lf += infinity;
01613 rf += infinity;
01614 }
01615
01616
01617 QIconViewItem* movedItem;
01618 Bin* items = bins[i][j];
01619
01620 int mini = QMIN( QMIN( tf, bf ), QMIN( lf, rf ) );
01621 if ( tf == mini ) {
01622
01623 Bin::iterator it = items->begin();
01624 movedItem = *it;
01625 for ( ++it; it != items->end(); ++it ) {
01626 if ( (*it)->y() < movedItem->y() )
01627 movedItem = *it;
01628 }
01629 items->remove( movedItem );
01630 if ( !bins[i][j-1] )
01631 bins[i][j-1] = new Bin;
01632 bins[i][j-1]->prepend( movedItem );
01633 }
01634 else if ( bf ==mini ) {
01635
01636 Bin::iterator it = items->begin();
01637 movedItem = *it;
01638 for ( ++it; it != items->end(); ++it ) {
01639 if ( (*it)->y() > movedItem->y() )
01640 movedItem = *it;
01641 }
01642 items->remove( movedItem );
01643 if ( !bins[i][j+1] )
01644 bins[i][j+1] = new Bin;
01645 bins[i][j+1]->prepend( movedItem );
01646 }
01647 else if ( lf == mini )
01648 {
01649
01650 Bin::iterator it = items->begin();
01651 movedItem = *it;
01652 for ( ++it; it != items->end(); ++it ) {
01653 if ( (*it)->x() < movedItem->x() )
01654 movedItem = *it;
01655 }
01656 items->remove( movedItem );
01657 if ( !bins[i-1][j] )
01658 bins[i-1][j] = new Bin;
01659 bins[i-1][j]->prepend( movedItem );
01660 }
01661 else {
01662
01663 Bin::iterator it = items->begin();
01664 movedItem = *it;
01665 for ( ++it; it != items->end(); ++it ) {
01666 if ( (*it)->x() > movedItem->x() )
01667 movedItem = *it;
01668 }
01669 items->remove( movedItem );
01670 if ( !bins[i+1][j] )
01671 bins[i+1][j] = new Bin;
01672 bins[i+1][j]->prepend( movedItem );
01673 }
01674 nmoves++;
01675 }
01676 }
01677 }
01678
01679
01680 QRegion repaintRegion;
01681 QValueList<QIconViewItem*> movedItems;
01682
01683 for ( i = 0; i < nx; i++ ) {
01684 for ( j = 0; j < ny; j++ ) {
01685 Bin* bin = bins[i][j];
01686 if ( !bin )
01687 continue;
01688 if ( !bin->isEmpty() ) {
01689 QIconViewItem* item = bin->first();
01690 int newX = x0 + i*dx + spacing() +
01691 QMAX(0, ( (dx-spacing()) - item->width() ) / 2);
01692
01693 int newY = y0 + j*dy + dy - spacing() - ( item->pixmapRect().bottom() + 2 + textHeight );
01694 if ( item->x() != newX || item->y() != newY ) {
01695 QRect oldRect = item->rect();
01696 movedItems.prepend( item );
01697 item->move( newX, newY );
01698 if ( item->rect() != oldRect )
01699 repaintRegion = repaintRegion.unite( oldRect );
01700 }
01701 }
01702 delete bin;
01703 bins[i][j] = 0L;
01704 }
01705 }
01706
01707
01708 if ( newItemWidth )
01709 updateContents();
01710 else {
01711
01712 QMemArray<QRect> rects = repaintRegion.rects();
01713 for ( uint l = 0; l < rects.count(); l++ ) {
01714 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << ","
01715 << rects[l].y() << ")\n";
01716 repaintContents( rects[l], false );
01717 }
01718
01719 while ( !movedItems.isEmpty() ) {
01720 repaintItem( movedItems.first() );
01721 movedItems.remove( movedItems.first() );
01722 }
01723 }
01724
01725 for ( i = 0; i < nx ; i++ ) {
01726 delete [] bins[i];
01727 }
01728 delete [] bins;
01729 }
01730
01731 void KonqIconViewWidget::lineupIcons( QIconView::Arrangement arrangement )
01732 {
01733 int x0, y0, dx, dy, nxmax, nymax;
01734 gridValues( &x0, &y0, &dx, &dy, &nxmax, &nymax );
01735 int textHeight = iconTextHeight() * fontMetrics().height();
01736
01737 QRegion repaintRegion;
01738 QValueList<QIconViewItem*> movedItems;
01739 int nx = 0, ny = 0;
01740
01741 QIconViewItem* item;
01742 for ( item = firstItem(); item; item = item->nextItem() ) {
01743 int newX = x0 + nx*dx + spacing() +
01744 QMAX(0, ( (dx-spacing()) - item->width() ) / 2);
01745
01746 int newY = y0 + ny*dy + dy - spacing() - ( item->pixmapRect().bottom() + 2 + textHeight );
01747 if ( item->x() != newX || item->y() != newY ) {
01748 QRect oldRect = item->rect();
01749 movedItems.prepend( item );
01750 item->move( newX, newY );
01751 if ( item->rect() != oldRect )
01752 repaintRegion = repaintRegion.unite( oldRect );
01753 }
01754 if ( arrangement == QIconView::LeftToRight ) {
01755 nx++;
01756 if ( nx >= nxmax ) {
01757 ny++;
01758 nx = 0;
01759 }
01760 }
01761 else {
01762 ny++;
01763 if ( ny >= nymax ) {
01764 nx++;
01765 ny = 0;
01766 }
01767 }
01768 }
01769
01770
01771 QMemArray<QRect> rects = repaintRegion.rects();
01772 for ( uint l = 0; l < rects.count(); l++ ) {
01773 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << ","
01774 << rects[l].y() << ")\n";
01775 repaintContents( rects[l], false );
01776 }
01777
01778 while ( !movedItems.isEmpty() ) {
01779 repaintItem( movedItems.first() );
01780 movedItems.remove( movedItems.first() );
01781 }
01782 }
01783
01784 int KonqIconViewWidget::largestPreviewIconSize( int size ) const
01785 {
01786 int iconSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01787
01788 if (iconSize < 28)
01789 return 48;
01790 if (iconSize < 40)
01791 return 64;
01792 if (iconSize < 60)
01793 return 96;
01794 if (iconSize < 120)
01795 return 128;
01796
01797 return 192;
01798 }
01799
01800 int KonqIconViewWidget::previewIconSize( int size ) const
01801 {
01802 int iconSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01803
01804 if (!d->bBoostPreview)
01805 return iconSize;
01806
01807 return largestPreviewIconSize( iconSize );
01808 }
01809
01810 void KonqIconViewWidget::visualActivate(QIconViewItem * item)
01811 {
01812
01813 QRect irect = item->rect();
01814
01815
01816 QRect rect = item->pixmapRect();
01817
01818
01819
01820 rect.moveBy(irect.x(), irect.y());
01821
01822
01823 rect.moveBy( -contentsX(), -contentsY() );
01824
01825 KIconEffect::visualActivate(viewport(), rect);
01826 }
01827
01828 void KonqIconViewWidget::backgroundPixmapChange( const QPixmap & )
01829 {
01830 viewport()->update();
01831 }
01832
01833 void KonqIconViewWidget::setPreviewSettings( const QStringList& settings )
01834 {
01835 d->previewSettings = settings;
01836 updatePreviewMimeTypes();
01837
01838 int size = m_size;
01839 m_size = -1;
01840 setIcons( size );
01841 }
01842
01843 const QStringList& KonqIconViewWidget::previewSettings()
01844 {
01845 return d->previewSettings;
01846 }
01847
01848 void KonqIconViewWidget::setNewURL( const QString& url )
01849 {
01850 KURL u;
01851 if ( url.startsWith( "/" ) )
01852 u.setPath( url );
01853 else
01854 u = url;
01855 setURL( u );
01856 }
01857
01858 void KonqIconViewWidget::setCaseInsensitiveSort( bool b )
01859 {
01860 d->bCaseInsensitive = b;
01861 }
01862
01863 bool KonqIconViewWidget::caseInsensitiveSort() const
01864 {
01865 return d->bCaseInsensitive;
01866 }
01867
01868 bool KonqIconViewWidget::canPreview( KFileItem* item )
01869 {
01870 if ( !KGlobalSettings::showFilePreview( url() ) )
01871 return false;
01872
01873 if ( d->pPreviewMimeTypes == 0L )
01874 updatePreviewMimeTypes();
01875
01876 return mimeTypeMatch( item->mimetype(), *( d->pPreviewMimeTypes ) );
01877 }
01878
01879 void KonqIconViewWidget::updatePreviewMimeTypes()
01880 {
01881 if ( d->pPreviewMimeTypes == 0L )
01882 d->pPreviewMimeTypes = new QStringList;
01883 else
01884 d->pPreviewMimeTypes->clear();
01885
01886
01887 KTrader::OfferList plugins = KTrader::self()->query("ThumbCreator");
01888 KTrader::OfferList::ConstIterator it;
01889
01890 for ( it = plugins.begin(); it != plugins.end(); ++it ) {
01891 if ( d->previewSettings.contains((*it)->desktopEntryName()) ) {
01892 QStringList mimeTypes = (*it)->property("MimeTypes").toStringList();
01893 for (QStringList::ConstIterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt)
01894 d->pPreviewMimeTypes->append(*mt);
01895 }
01896 }
01897 }
01898
01899 #include "konq_iconviewwidget.moc"
01900
01901