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