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