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