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_undo.h"
00022 #include "konq_sound.h"
00023
00024 #include <qclipboard.h>
00025 #include <qlayout.h>
00026 #include <qtimer.h>
00027 #include <qpainter.h>
00028 #include <qtooltip.h>
00029 #include <qlabel.h>
00030 #include <qmovie.h>
00031 #include <qregexp.h>
00032
00033 #include <kapplication.h>
00034 #include <kdebug.h>
00035 #include <kio/previewjob.h>
00036 #include <kfileivi.h>
00037 #include <konq_settings.h>
00038 #include <konq_drag.h>
00039 #include <konq_operations.h>
00040 #include <kglobalsettings.h>
00041 #include <kpropertiesdialog.h>
00042 #include <kipc.h>
00043 #include <kicontheme.h>
00044 #include <kiconeffect.h>
00045 #include <kurldrag.h>
00046 #include <kstandarddirs.h>
00047 #include <kprotocolinfo.h>
00048
00049 #include <assert.h>
00050 #include <unistd.h>
00051
00052 class KFileTip: public QFrame
00053 {
00054 public:
00055 KFileTip( KonqIconViewWidget* parent ) : QFrame( 0, 0, WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WStyle_StaysOnTop | WX11BypassWM ),
00056
00057 m_corner( 0 ),
00058 m_filter( false ),
00059 m_view( parent ),
00060 m_item( 0 ),
00061 m_previewJob( 0 ),
00062 m_ivi( 0 )
00063 {
00064 m_iconLabel = new QLabel(this);
00065 m_textLabel = new QLabel(this);
00066 m_textLabel->setAlignment(Qt::AlignAuto | Qt::AlignTop);
00067
00068 QGridLayout* layout = new QGridLayout(this, 1, 2, 8, 0);
00069 layout->addWidget(m_iconLabel, 0, 0);
00070 layout->addWidget(m_textLabel, 0, 1);
00071 layout->setResizeMode(QLayout::Fixed);
00072
00073 setPalette( QToolTip::palette() );
00074 setMargin( 1 );
00075 setFrameStyle( QFrame::Plain | QFrame::Box );
00076
00077 hide();
00078 }
00079
00080 void setOptions( bool on, bool preview, int num)
00081 {
00082 m_num = num;
00083 m_preview = preview;
00084 m_on = on;
00085 }
00086
00087 void setItem( KFileIVI *ivi );
00088
00089 virtual bool eventFilter( QObject *, QEvent *e );
00090
00091 void gotPreview( const KFileItem*, const QPixmap& );
00092 void gotPreviewResult();
00093
00094 protected:
00095 virtual void drawContents( QPainter *p );
00096 virtual void timerEvent( QTimerEvent * );
00097 virtual void resizeEvent( QResizeEvent * );
00098
00099 private:
00100 void setFilter( bool enable );
00101
00102 void reposition();
00103
00104 QLabel* m_iconLabel;
00105 QLabel* m_textLabel;
00106 int m_num;
00107 bool m_on;
00108 bool m_preview;
00109 QPixmap m_corners[4];
00110 int m_corner;
00111 bool m_filter;
00112 KonqIconViewWidget* m_view;
00113 KFileItem* m_item;
00114 KIO::PreviewJob* m_previewJob;
00115 KFileIVI* m_ivi;
00116 };
00117
00118 void KFileTip::setItem( KFileIVI *ivi )
00119 {
00120 if (!m_on) return;
00121 if (m_ivi == ivi) return;
00122
00123 if ( m_previewJob ) {
00124 m_previewJob->kill();
00125 m_previewJob = 0;
00126 }
00127
00128 m_ivi = ivi;
00129 m_item = ivi ? ivi->item() : 0;
00130
00131 QString text = ivi ? ivi->item()->getToolTipText( m_num ) : QString::null;
00132 if ( !text.isEmpty() ) {
00133 hide();
00134 m_textLabel -> setText( text );
00135
00136 killTimers();
00137 setFilter( true );
00138
00139 if (m_preview) {
00140 m_iconLabel -> setPixmap(*(ivi->pixmap()));
00141 KFileItemList oneItem;
00142 oneItem.append( ivi->item() );
00143
00144 m_previewJob = KIO::filePreview( oneItem, 256, 256, 64, 70, true, true, 0);
00145 connect( m_previewJob, SIGNAL( gotPreview( const KFileItem *, const QPixmap & ) ),
00146 m_view, SLOT( slotToolTipPreview( const KFileItem *, const QPixmap & ) ) );
00147 connect( m_previewJob, SIGNAL( result( KIO::Job * ) ),
00148 m_view, SLOT( slotToolTipPreviewResult() ) );
00149 }
00150
00151 startTimer( 700 );
00152 }
00153 else {
00154 killTimers();
00155 if ( isVisible() ) {
00156 setFilter( false );
00157 hide();
00158 }
00159 }
00160 }
00161
00162 void KFileTip::reposition()
00163 {
00164 if (!m_ivi) return;
00165
00166 QRect rect = m_ivi->rect();
00167 QPoint off = m_view->mapToGlobal( m_view->contentsToViewport( QPoint( 0, 0 ) ) );
00168 rect.moveBy( off.x(), off.y() );
00169
00170 QPoint pos = rect.center();
00171
00172
00173
00174
00175
00176
00177 m_corner = 0;
00178
00179 QRect desk = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(rect.center()));
00180 if (rect.center().x() + width() > desk.right())
00181 {
00182
00183 if (pos.x() - width() < 0) {
00184 pos.setX(0);
00185 m_corner = 4;
00186 } else {
00187 pos.setX( pos.x() - width() );
00188 m_corner = 1;
00189 }
00190 }
00191
00192 if (rect.bottom() + height() > desk.bottom())
00193 {
00194
00195 pos.setY( rect.top() - height() );
00196 m_corner += 2;
00197 }
00198 else pos.setY( rect.bottom() );
00199
00200 move( pos );
00201 update();
00202 }
00203
00204 void KFileTip::gotPreview( const KFileItem* item, const QPixmap& pixmap )
00205 {
00206 m_previewJob = 0;
00207 if (item != m_item) return;
00208
00209 m_iconLabel -> setPixmap(pixmap);
00210 }
00211
00212 void KFileTip::gotPreviewResult()
00213 {
00214 m_previewJob = 0;
00215 }
00216
00217 void KFileTip::drawContents( QPainter *p )
00218 {
00219 static const char * const names[] = {
00220 "arrow_topleft",
00221 "arrow_topright",
00222 "arrow_bottomleft",
00223 "arrow_bottomright"
00224 };
00225
00226 if (m_corner >= 4) {
00227 QFrame::drawContents( p );
00228 return;
00229 }
00230
00231 if ( m_corners[m_corner].isNull())
00232 m_corners[m_corner].load( locate( "data", QString::fromLatin1( "konqueror/pics/%1.png" ).arg( names[m_corner] ) ) );
00233
00234 QPixmap &pix = m_corners[m_corner];
00235
00236 switch ( m_corner )
00237 {
00238 case 0:
00239 p->drawPixmap( 3, 3, pix );
00240 break;
00241 case 1:
00242 p->drawPixmap( width() - pix.width() - 3, 3, pix );
00243 break;
00244 case 2:
00245 p->drawPixmap( 3, height() - pix.height() - 3, pix );
00246 break;
00247 case 3:
00248 p->drawPixmap( width() - pix.width() - 3, height() - pix.height() - 3, pix );
00249 break;
00250 }
00251
00252 QFrame::drawContents( p );
00253 }
00254
00255 void KFileTip::setFilter( bool enable )
00256 {
00257 if ( enable == m_filter ) return;
00258
00259 if ( enable ) {
00260 kapp->installEventFilter( this );
00261 QApplication::setGlobalMouseTracking( true );
00262 }
00263 else {
00264 QApplication::setGlobalMouseTracking( false );
00265 kapp->removeEventFilter( this );
00266 }
00267 m_filter = enable;
00268 }
00269
00270 void KFileTip::timerEvent( QTimerEvent * )
00271 {
00272 killTimers();
00273 if ( !isVisible() ) {
00274 startTimer( 15000 );
00275 reposition();
00276 show();
00277 }
00278 else {
00279 setFilter( false );
00280 hide();
00281 }
00282 }
00283
00284 void KFileTip::resizeEvent( QResizeEvent* event )
00285 {
00286 QFrame::resizeEvent(event);
00287 reposition();
00288 }
00289
00290 bool KFileTip::eventFilter( QObject *, QEvent *e )
00291 {
00292 switch ( e->type() )
00293 {
00294 case QEvent::Leave:
00295 case QEvent::MouseButtonPress:
00296 case QEvent::MouseButtonRelease:
00297 case QEvent::KeyPress:
00298 case QEvent::KeyRelease:
00299 case QEvent::FocusIn:
00300 case QEvent::FocusOut:
00301 case QEvent::Wheel:
00302 killTimers();
00303 setFilter( false );
00304 hide();
00305 default: break;
00306 }
00307
00308 return false;
00309 }
00310
00311 struct KonqIconViewWidgetPrivate
00312 {
00313 KonqIconViewWidgetPrivate() {
00314 pActiveItem = 0;
00315 bSoundPreviews = false;
00316 pSoundItem = 0;
00317 bSoundItemClicked = false;
00318 pSoundPlayer = 0;
00319 pSoundTimer = 0;
00320 pPreviewJob = 0;
00321 bAllowSetWallpaper = false;
00322 updateAfterPreview = false;
00323 gridXspacing = 50;
00324
00325 doAnimations = true;
00326 m_movie = 0L;
00327 m_movieBlocked = 0;
00328 pFileTip = 0;
00329 }
00330 ~KonqIconViewWidgetPrivate() {
00331 delete pSoundPlayer;
00332 delete pSoundTimer;
00333 delete m_movie;
00334 delete pFileTip;
00335
00336 }
00337 KFileIVI *pActiveItem;
00338
00339 KFileIVI *pSoundItem;
00340 KonqSoundPlayer *pSoundPlayer;
00341 QTimer *pSoundTimer;
00342 bool bSoundPreviews;
00343 bool bSoundItemClicked;
00344 bool bAllowSetWallpaper;
00345 bool updateAfterPreview;
00346 int gridXspacing;
00347
00348
00349 bool doAnimations;
00350 QMovie* m_movie;
00351 int m_movieBlocked;
00352 QString movieFileName;
00353
00354 KIO::PreviewJob *pPreviewJob;
00355 KFileTip* pFileTip;
00356 QStringList previewSettings;
00357 };
00358
00359 KonqIconViewWidget::KonqIconViewWidget( QWidget * parent, const char * name, WFlags f, bool kdesktop )
00360 : KIconView( parent, name, f ),
00361 m_rootItem( 0L ), m_size( 0 ) ,
00362 m_bDesktop( kdesktop ),
00363 m_bSetGridX( !kdesktop )
00364 {
00365 d = new KonqIconViewWidgetPrivate;
00366 connect( this, SIGNAL( dropped( QDropEvent *, const QValueList<QIconDragItem> & ) ),
00367 this, SLOT( slotDropped( QDropEvent*, const QValueList<QIconDragItem> & ) ) );
00368
00369 connect( this, SIGNAL( selectionChanged() ),
00370 this, SLOT( slotSelectionChanged() ) );
00371
00372 kapp->addKipcEventMask( KIPC::IconChanged );
00373 connect( kapp, SIGNAL(iconChanged(int)), SLOT(slotIconChanged(int)) );
00374 connect( this, SIGNAL(onItem(QIconViewItem *)), SLOT(slotOnItem(QIconViewItem *)) );
00375 connect( this, SIGNAL(onViewport()), SLOT(slotOnViewport()) );
00376 connect( this, SIGNAL(itemRenamed(QIconViewItem *, const QString &)), SLOT(slotItemRenamed(QIconViewItem *, const QString &)) );
00377
00378
00379 setSelectionMode( QIconView::Extended );
00380 setItemTextPos( QIconView::Bottom );
00381
00382 d->pFileTip = new KFileTip(this);
00383
00384 calculateGridX();
00385 setAutoArrange( true );
00386 setSorting( true, sortDirection() );
00387 readAnimatedIconsConfig();
00388 m_bSortDirsFirst = true;
00389 m_bMousePressed = false;
00390 m_LineupMode = LineupBoth;
00391
00392 slotSelectionChanged();
00393 m_iconPositionGroupPrefix = QString::fromLatin1( "IconPosition::" );
00394 KonqUndoManager::incRef();
00395 }
00396
00397 KonqIconViewWidget::~KonqIconViewWidget()
00398 {
00399 stopImagePreview();
00400 KonqUndoManager::decRef();
00401 delete d;
00402 }
00403
00404 bool KonqIconViewWidget::maySetWallpaper()
00405 {
00406 return d->bAllowSetWallpaper;
00407 }
00408
00409 void KonqIconViewWidget::setMaySetWallpaper(bool b)
00410 {
00411 d->bAllowSetWallpaper = b;
00412 }
00413
00414 void KonqIconViewWidget::focusOutEvent( QFocusEvent * ev )
00415 {
00416
00417
00418
00419 m_bMousePressed = false;
00420 KIconView::focusOutEvent( ev );
00421 }
00422
00423 void KonqIconViewWidget::slotItemRenamed(QIconViewItem *item, const QString &name)
00424 {
00425 kdDebug(1203) << "KonqIconViewWidget::slotItemRenamed" << endl;
00426 KFileIVI *viewItem = static_cast<KFileIVI *>(item);
00427 KFileItem *fileItem = viewItem->item();
00428
00429
00430
00431
00432 viewItem->setText( fileItem->text() );
00433
00434
00435 if( !name.isEmpty() )
00436 {
00437
00438 KonqOperations::rename( this, fileItem->url(), KIO::encodeFileName( name ) );
00439 }
00440 }
00441
00442 void KonqIconViewWidget::slotIconChanged( int group )
00443 {
00444 if (group != KIcon::Desktop)
00445 return;
00446
00447 int size = m_size;
00448 if ( m_size == 0 )
00449 m_size = -1;
00450 setIcons( size );
00451 readAnimatedIconsConfig();
00452 }
00453
00454 void KonqIconViewWidget::readAnimatedIconsConfig()
00455 {
00456 KConfigGroup cfgGroup( KGlobal::config(), "DesktopIcons" );
00457 d->doAnimations = cfgGroup.readBoolEntry( "Animated", true );
00458 d->gridXspacing = cfgGroup.readNumEntry( "GridXSpacing", 50);
00459 }
00460
00461 void KonqIconViewWidget::slotOnItem( QIconViewItem *item )
00462 {
00463
00464 if( d->pActiveItem != 0L && d->pActiveItem != item )
00465 {
00466 if ( d->m_movie && d->pActiveItem->isAnimated() )
00467 {
00468 d->m_movie->pause();
00469 d->pActiveItem->setAnimated( false );
00470 d->pActiveItem->refreshIcon( true );
00471 }
00472 else {
00473 d->pActiveItem->setActive( false );
00474 }
00475 d->pActiveItem = 0L;
00476 d->pFileTip->setItem( 0L );
00477 }
00478
00479
00480 if (d->pSoundPlayer != 0 && static_cast<KFileIVI *>(item) != d->pSoundItem)
00481 {
00482 d->pSoundPlayer->stop();
00483
00484 d->pSoundItem = 0;
00485 if (d->pSoundTimer && d->pSoundTimer->isActive())
00486 d->pSoundTimer->stop();
00487 }
00488
00489 if ( !m_bMousePressed )
00490 {
00491 if( item != d->pActiveItem )
00492 {
00493 d->pActiveItem = static_cast<KFileIVI *>(item);
00494 if ( topLevelWidget() == kapp->activeWindow() )
00495 d->pFileTip->setItem( d->pActiveItem );
00496
00497 if ( d->doAnimations && d->pActiveItem && d->pActiveItem->hasAnimation() )
00498 {
00499
00500
00501 #if 0 // Qt-mng bug, reusing the movie doesn't work currently.
00502 if ( d->m_movie && d->movieFileName == d->pActiveItem->mouseOverAnimation() )
00503 {
00504 d->pActiveItem->setAnimated( true );
00505 if (d->m_movieBlocked) {
00506 kdDebug(1203) << "onitem, but blocked" << endl;
00507 d->m_movie->pause();
00508 }
00509 else {
00510 kdDebug(1203) << "we go ahead.." << endl;
00511 d->m_movieBlocked++;
00512 QTimer::singleShot(300, this, SLOT(slotReenableAnimation()));
00513 d->m_movie->restart();
00514 d->m_movie->unpause();
00515 }
00516 }
00517 else
00518 #endif
00519 {
00520 QMovie movie = KGlobal::iconLoader()->loadMovie( d->pActiveItem->mouseOverAnimation(), KIcon::Desktop, d->pActiveItem->iconSize() );
00521 if ( !movie.isNull() )
00522 {
00523 delete d->m_movie;
00524 d->m_movie = new QMovie( movie );
00525
00526
00527 const QPixmap* pm = backgroundPixmap();
00528 bool hasPixmap = pm && !pm->isNull();
00529 if ( !hasPixmap ) {
00530 pm = viewport()->backgroundPixmap();
00531 hasPixmap = pm && !pm->isNull();
00532 }
00533 if (!hasPixmap && backgroundMode() != NoBackground)
00534 d->m_movie->setBackgroundColor( viewport()->backgroundColor() );
00535 d->m_movie->connectUpdate( this, SLOT( slotMovieUpdate(const QRect &) ) );
00536 d->m_movie->connectStatus( this, SLOT( slotMovieStatus(int) ) );
00537 d->movieFileName = d->pActiveItem->mouseOverAnimation();
00538 d->pActiveItem->setAnimated( true );
00539 }
00540 else
00541 {
00542 d->pActiveItem->setAnimated( false );
00543 if (d->m_movie)
00544 d->m_movie->pause();
00545
00546 d->pActiveItem->setMouseOverAnimation( QString::null );
00547 }
00548 }
00549 }
00550
00551 if (!d->pActiveItem->isAnimated())
00552 {
00553 d->pActiveItem->setActive( true );
00554 }
00555 }
00556 else
00557 {
00558
00559
00560 d->pActiveItem = 0L;
00561 d->pFileTip->setItem( 0L );
00562 }
00563 }
00564 else
00565 {
00566
00567
00568 d->pActiveItem = 0L;
00569 d->pFileTip->setItem( 0L );
00570 }
00571
00572
00573 if (d->bSoundPreviews && d->pSoundPlayer &&
00574 d->pSoundPlayer->mimeTypes().contains(
00575 static_cast<KFileIVI *>(item)->item()->mimetype()))
00576 {
00577 d->pSoundItem = static_cast<KFileIVI *>(item);
00578 d->bSoundItemClicked = false;
00579 if (!d->pSoundTimer)
00580 {
00581 d->pSoundTimer = new QTimer(this);
00582 connect(d->pSoundTimer, SIGNAL(timeout()), SLOT(slotStartSoundPreview()));
00583 }
00584 if (d->pSoundTimer->isActive())
00585 d->pSoundTimer->stop();
00586 d->pSoundTimer->start(500, true);
00587 }
00588 else
00589 {
00590 if (d->pSoundPlayer)
00591 d->pSoundPlayer->stop();
00592 d->pSoundItem = 0;
00593 if (d->pSoundTimer && d->pSoundTimer->isActive())
00594 d->pSoundTimer->stop();
00595 }
00596 }
00597
00598 void KonqIconViewWidget::slotOnViewport()
00599 {
00600 d->pFileTip->setItem( 0L );
00601
00602 if (d->pSoundPlayer)
00603 d->pSoundPlayer->stop();
00604 d->pSoundItem = 0;
00605 if (d->pSoundTimer && d->pSoundTimer->isActive())
00606 d->pSoundTimer->stop();
00607
00608 if (d->pActiveItem == 0L)
00609 return;
00610
00611 if ( d->doAnimations && d->m_movie && d->pActiveItem->isAnimated() )
00612 {
00613 d->pActiveItem->setAnimated( false );
00614 #if 0
00615
00616 if (d->m_movie->running()) {
00617 d->m_movie->pause();
00618 d->m_movieBlocked++;
00619 kdDebug(1203) << "on viewport, blocking" << endl;
00620 QTimer::singleShot(300, this, SLOT(slotReenableAnimation()));
00621 }
00622 #endif
00623 d->pActiveItem->refreshIcon( true );
00624 Q_ASSERT( d->pActiveItem->state() == KIcon::DefaultState );
00625
00626
00627
00628 }
00629 else
00630 {
00631 d->pActiveItem->setActive( false );
00632 }
00633 d->pActiveItem = 0L;
00634 }
00635
00636 void KonqIconViewWidget::slotStartSoundPreview()
00637 {
00638 if (!d->pSoundItem || d->bSoundItemClicked)
00639 return;
00640
00641 d->pSoundPlayer->play(d->pSoundItem->item()->url().url());
00642 }
00643
00644 void KonqIconViewWidget::slotPreview(const KFileItem *item, const QPixmap &pix)
00645 {
00646
00647 for (QIconViewItem *it = firstItem(); it; it = it->nextItem())
00648 {
00649 if (static_cast<KFileIVI *>(it)->item() == item)
00650 static_cast<KFileIVI *>(it)->setThumbnailPixmap(pix);
00651 {
00652 }
00653 d->updateAfterPreview = true;
00654 }
00655 }
00656
00657 void KonqIconViewWidget::slotPreviewResult()
00658 {
00659 d->pPreviewJob = 0;
00660 emit imagePreviewFinished();
00661 if (autoArrange() && d->updateAfterPreview ) {
00662 arrangeItemsInGrid();
00663 d->updateAfterPreview = false;
00664 }
00665 }
00666
00667 void KonqIconViewWidget::slotToolTipPreview(const KFileItem* item, const QPixmap &pix)
00668 {
00669 if (d->pFileTip) d->pFileTip->gotPreview( item, pix );
00670 }
00671
00672 void KonqIconViewWidget::slotToolTipPreviewResult()
00673 {
00674 if (d->pFileTip) d->pFileTip->gotPreviewResult();
00675 }
00676
00677 void KonqIconViewWidget::slotMovieUpdate( const QRect& rect )
00678 {
00679
00680 Q_ASSERT( d );
00681 Q_ASSERT( d->m_movie );
00682
00683 if ( d->pActiveItem && d->m_movie && d->pActiveItem->isAnimated() ) {
00684 const QPixmap &frame = d->m_movie->framePixmap();
00685
00686
00687 int iconSize=d->pActiveItem->iconSize();
00688 if (iconSize==0) iconSize = KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00689 if ( frame.width() != iconSize || frame.height() != iconSize ) {
00690 d->pActiveItem->setAnimated( false );
00691 d->m_movie->pause();
00692
00693 d->pActiveItem->setMouseOverAnimation( QString::null );
00694 d->pActiveItem->setActive( true );
00695 return;
00696 }
00697 d->pActiveItem->setPixmapDirect( frame, false, false );
00698 QRect pixRect = d->pActiveItem->pixmapRect(false);
00699 repaintContents( pixRect.x() + rect.x(), pixRect.y() + rect.y(), rect.width(), rect.height(), false );
00700 }
00701 }
00702
00703 void KonqIconViewWidget::slotMovieStatus( int status )
00704 {
00705 if ( status < 0 ) {
00706
00707 if ( d->pActiveItem && d->pActiveItem->isAnimated() ) {
00708 d->pActiveItem->setAnimated( false );
00709 d->pActiveItem->setMouseOverAnimation( QString::null );
00710 d->pActiveItem->setActive( true );
00711 }
00712 }
00713 }
00714
00715 void KonqIconViewWidget::slotReenableAnimation()
00716 {
00717 if (!--d->m_movieBlocked) {
00718 if ( d->pActiveItem && d->m_movie && d->m_movie->paused()) {
00719 kdDebug(1203) << "reenabled animation" << endl;
00720 d->m_movie->restart();
00721 d->m_movie->unpause();
00722 }
00723 }
00724 }
00725
00726 void KonqIconViewWidget::clear()
00727 {
00728 d->pFileTip->setItem( 0L );
00729 stopImagePreview();
00730 KIconView::clear();
00731 d->pActiveItem = 0L;
00732 }
00733
00734 void KonqIconViewWidget::takeItem( QIconViewItem *item )
00735 {
00736 if ( d->pActiveItem == static_cast<KFileIVI *>(item) )
00737 {
00738 d->pFileTip->setItem( 0L );
00739 d->pActiveItem = 0L;
00740 }
00741
00742 if ( d->pPreviewJob )
00743 d->pPreviewJob->removeItem( static_cast<KFileIVI *>(item)->item() );
00744
00745 KIconView::takeItem( item );
00746 }
00747
00748 void KonqIconViewWidget::setThumbnailPixmap( KFileIVI * item, const QPixmap & pixmap )
00749 {
00750 if ( item )
00751 {
00752 if ( d->pActiveItem == item )
00753 {
00754 d->pFileTip->setItem( 0L );
00755 d->pActiveItem = 0L;
00756 }
00757 item->setThumbnailPixmap( pixmap );
00758 if ( m_bSetGridX && item->width() > gridX() )
00759 {
00760 setGridX( item->width() );
00761 if (autoArrange())
00762 arrangeItemsInGrid();
00763 }
00764 }
00765 }
00766
00767 bool KonqIconViewWidget::initConfig( bool bInit )
00768 {
00769 bool fontChanged = false;
00770 m_pSettings = KonqFMSettings::settings();
00771
00772
00773 QColor normalTextColor = m_pSettings->normalTextColor();
00774 setItemColor( normalTextColor );
00775
00776 if (m_bDesktop)
00777 {
00778 QColor itemTextBg = m_pSettings->itemTextBackground();
00779 if ( itemTextBg.isValid() )
00780 setItemTextBackground( itemTextBg );
00781 else
00782 setItemTextBackground( NoBrush );
00783 }
00784
00785
00786 d->pFileTip->setOptions(m_pSettings->showFileTips() && QToolTip::isGloballyEnabled(),
00787 m_pSettings->showPreviewsInFileTips(),
00788 m_pSettings->numFileTips());
00789
00790
00791 QFont font( m_pSettings->standardFont() );
00792 font.setUnderline( m_pSettings->underlineLink() );
00793 if ( font != KonqIconViewWidget::font() )
00794 {
00795 setFont( font );
00796 if (!bInit)
00797 {
00798
00799
00800 fontChanged = true;
00801 }
00802 }
00803 setWordWrapIconText( m_pSettings->wordWrapText() );
00804
00805 if (!bInit)
00806 updateContents();
00807 return fontChanged;
00808 }
00809
00810 void KonqIconViewWidget::disableSoundPreviews()
00811 {
00812 d->bSoundPreviews = false;
00813
00814 if (d->pSoundPlayer)
00815 d->pSoundPlayer->stop();
00816 d->pSoundItem = 0;
00817 if (d->pSoundTimer && d->pSoundTimer->isActive())
00818 d->pSoundTimer->stop();
00819 }
00820
00821 void KonqIconViewWidget::setIcons( int size, const QStringList& stopImagePreviewFor )
00822 {
00823
00824 bool sizeChanged = (m_size != size);
00825 int oldGridX = gridX();
00826 m_size = size;
00827
00828 if ( sizeChanged )
00829 {
00830 setSpacing( (size > KIcon::SizeSmall) ? 5 : 0 );
00831 }
00832
00833 if ( sizeChanged || !stopImagePreviewFor.isEmpty() )
00834 {
00835 calculateGridX();
00836 }
00837 bool stopAll = !stopImagePreviewFor.isEmpty() && stopImagePreviewFor.first() == "*";
00838
00839 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00840 KFileIVI * ivi = static_cast<KFileIVI *>( it );
00841
00842
00843 if ( !ivi->isThumbnail() ||
00844 stopAll ||
00845 mimeTypeMatch( ivi->item()->mimetype(), stopImagePreviewFor ) )
00846 {
00847 ivi->setIcon( size, ivi->state(), true, false );
00848 }
00849 else
00850 ivi->invalidateThumb( ivi->state(), false );
00851 }
00852
00853 if ( autoArrange() && (oldGridX != gridX() || !stopImagePreviewFor.isEmpty()) )
00854 arrangeItemsInGrid( true );
00855 else
00856 viewport()->update();
00857 }
00858
00859 bool KonqIconViewWidget::mimeTypeMatch( const QString& mimeType, const QStringList& mimeList ) const
00860 {
00861 for (QStringList::ConstIterator mt = mimeList.begin(); mt != mimeList.end(); ++mt)
00862 {
00863 if ( mimeType == *mt )
00864 return true;
00865
00866 QString tmp( mimeType );
00867 if ( (*mt).endsWith("*") && tmp.replace(QRegExp("/.*"), "/*") == (*mt) )
00868 return true;
00869 }
00870 return false;
00871 }
00872
00873 void KonqIconViewWidget::setItemTextPos( ItemTextPos pos )
00874 {
00875 if ( m_bSetGridX )
00876 {
00877 calculateGridX();
00878 if ( itemTextPos() != pos )
00879 {
00880 if ( pos == QIconView::Right )
00881 setGridX( gridX() + 100 );
00882 else
00883 setGridX( gridX() - 100 );
00884 }
00885 }
00886
00887 KIconView::setItemTextPos( pos );
00888 }
00889
00890 void KonqIconViewWidget::calculateGridX()
00891 {
00892 if ( m_bSetGridX )
00893 setGridX( gridXValue() );
00894 }
00895
00896 int KonqIconViewWidget::gridXValue() const
00897 {
00898 int sz = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00899 int newGridX = sz + (!m_bSetGridX ? d->gridXspacing : 50) + (( itemTextPos() == QIconView::Right ) ? 100 : 0);
00900
00901 return newGridX;
00902 }
00903
00904 void KonqIconViewWidget::refreshMimeTypes()
00905 {
00906 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
00907 (static_cast<KFileIVI *>( it ))->item()->refreshMimeType();
00908 setIcons( m_size );
00909 }
00910
00911 void KonqIconViewWidget::setURL( const KURL &kurl )
00912 {
00913 stopImagePreview();
00914 m_url = kurl;
00915 if ( m_url.isLocalFile() )
00916 m_dotDirectoryPath = m_url.path(1).append( ".directory" );
00917 else
00918 m_dotDirectoryPath = QString::null;
00919 }
00920
00921 void KonqIconViewWidget::startImagePreview( const QStringList &, bool force )
00922 {
00923 stopImagePreview();
00924
00925
00926 KConfigGroup group( KGlobal::config(), "PreviewSettings" );
00927 if ( !group.readBoolEntry( url().protocol(), true ) ) {
00928 kdDebug(1203) << "Previews disabled for protocol " << url().protocol() << endl;
00929 emit imagePreviewFinished();
00930 return;
00931 }
00932
00933 if ((d->bSoundPreviews = d->previewSettings.contains( "audio/" )) &&
00934 !d->pSoundPlayer)
00935 {
00936 KLibFactory *factory = KLibLoader::self()->factory("konq_sound");
00937 if (factory)
00938 d->pSoundPlayer = static_cast<KonqSoundPlayer *>(
00939 factory->create(this, 0, "KonqSoundPlayer"));
00940 d->bSoundPreviews = (d->pSoundPlayer != 0L);
00941 }
00942
00943 bool onlyAudio = true;
00944 KFileItemList items;
00945 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
00946 if ( force || !static_cast<KFileIVI *>( it )->hasValidThumbnail() )
00947 items.append( static_cast<KFileIVI *>( it )->item() );
00948
00949 for ( QStringList::ConstIterator it = d->previewSettings.begin(); it != d->previewSettings.end(); ++it ) {
00950 if ( (*it).startsWith( "audio/" ) )
00951 d->bSoundPreviews = true;
00952 else
00953 onlyAudio = false;
00954 }
00955
00956 if ( items.isEmpty() || onlyAudio ) {
00957 emit imagePreviewFinished();
00958 return;
00959 }
00960
00961 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00962 int size;
00963
00964 if ( group.readBoolEntry("BoostSize", false) ) {
00965 if (iconSize < 28)
00966 size = 48;
00967 else if (iconSize < 40)
00968 #if 0 // TMS sizes, enable when KIO::Previewjob uses them
00969 size = 64;
00970 else if (iconSize < 60)
00971 size = 96;
00972 else
00973 size = 128;
00974 #endif
00975 size = 60;
00976 else size = 90;
00977 } else {
00978 size = iconSize;
00979 iconSize /= 2;
00980 }
00981
00982 d->pPreviewJob = KIO::filePreview( items, size, size, iconSize,
00983 m_pSettings->textPreviewIconTransparency(), true ,
00984 true , &(d->previewSettings) );
00985 connect( d->pPreviewJob, SIGNAL( gotPreview( const KFileItem *, const QPixmap & ) ),
00986 this, SLOT( slotPreview( const KFileItem *, const QPixmap & ) ) );
00987 connect( d->pPreviewJob, SIGNAL( result( KIO::Job * ) ),
00988 this, SLOT( slotPreviewResult() ) );
00989 }
00990
00991 void KonqIconViewWidget::stopImagePreview()
00992 {
00993 if (d->pPreviewJob)
00994 {
00995 d->pPreviewJob->kill();
00996 d->pPreviewJob = 0;
00997 if (autoArrange())
00998 arrangeItemsInGrid();
00999 }
01000 }
01001
01002 bool KonqIconViewWidget::isPreviewRunning() const
01003 {
01004 return d->pPreviewJob;
01005 }
01006
01007 KFileItemList KonqIconViewWidget::selectedFileItems()
01008 {
01009 KFileItemList lstItems;
01010
01011 QIconViewItem *it = firstItem();
01012 for (; it; it = it->nextItem() )
01013 if ( it->isSelected() ) {
01014 KFileItem *fItem = (static_cast<KFileIVI *>(it))->item();
01015 lstItems.append( fItem );
01016 }
01017 return lstItems;
01018 }
01019
01020 void KonqIconViewWidget::slotDropped( QDropEvent *ev, const QValueList<QIconDragItem> & )
01021 {
01022
01023 KonqOperations::doDrop( m_rootItem , url(), ev, this );
01024 }
01025
01026 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r )
01027 {
01028 drawBackground(p, r, r.topLeft());
01029 }
01030
01031 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r , const QPoint &pt)
01032 {
01033 const QPixmap *pm = backgroundPixmap();
01034 bool hasPixmap = pm && !pm->isNull();
01035 if ( !hasPixmap ) {
01036 pm = viewport()->backgroundPixmap();
01037 hasPixmap = pm && !pm->isNull();
01038 }
01039
01040 QRect rtgt(r);
01041 rtgt.moveTopLeft(pt);
01042 if (!hasPixmap && backgroundMode() != NoBackground) {
01043 p->fillRect(rtgt, viewport()->backgroundColor());
01044 return;
01045 }
01046
01047 if (hasPixmap) {
01048 int ax = (r.x() + contentsX() + leftMargin()) % pm->width();
01049 int ay = (r.y() + contentsY() + topMargin()) % pm->height();
01050 p->drawTiledPixmap(rtgt, *pm, QPoint(ax, ay));
01051 }
01052 }
01053
01054 QDragObject * KonqIconViewWidget::dragObject()
01055 {
01056 if ( !currentItem() )
01057 return 0;
01058
01059 return konqDragObject( viewport() );
01060 }
01061
01062 KonqIconDrag * KonqIconViewWidget::konqDragObject( QWidget * dragSource )
01063 {
01064
01065
01066 KonqIconDrag * drag = new KonqIconDrag( dragSource );
01067 QIconViewItem *primaryItem = currentItem();
01068
01069 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
01070 if ( it->isSelected() ) {
01071 if (!primaryItem)
01072 primaryItem = it;
01073 QString itemURL = (static_cast<KFileIVI *>(it))->item()->url().url(0, 106);
01074 kdDebug(1203) << "itemURL=" << itemURL << endl;
01075 QIconDragItem id;
01076 id.setData( QCString(itemURL.latin1()) );
01077 drag->append( id,
01078 QRect( it->pixmapRect( FALSE ).topLeft() - m_mousePos,
01079 it->pixmapRect( FALSE ).size() ),
01080 QRect( it->textRect( FALSE ).topLeft() - m_mousePos,
01081 it->textRect( FALSE ).size() ),
01082 itemURL );
01083 }
01084 }
01085
01086 if (primaryItem)
01087 {
01088
01089 QPoint itempos = primaryItem->pixmapRect( FALSE ).topLeft();
01090
01091 drag->setPixmap( *primaryItem->pixmap(), m_mousePos - itempos );
01092 }
01093
01094 return drag;
01095 }
01096
01097 void KonqIconViewWidget::contentsDragEnterEvent( QDragEnterEvent *e )
01098 {
01099 if ( e->provides( "text/uri-list" ) )
01100 {
01101 QByteArray payload = e->encodedData( "text/uri-list" );
01102 if ( !payload.size() )
01103 kdError() << "Empty data !" << endl;
01104
01105
01106 bool ok = KURLDrag::decode( e, m_lstDragURLs );
01107 if( !ok )
01108 kdError() << "Couldn't decode urls dragged !" << endl;
01109 }
01110 KIconView::contentsDragEnterEvent( e );
01111 }
01112
01113 void KonqIconViewWidget::setItemColor( const QColor &c )
01114 {
01115 iColor = c;
01116 }
01117
01118 QColor KonqIconViewWidget::itemColor() const
01119 {
01120 return iColor;
01121 }
01122
01123 void KonqIconViewWidget::disableIcons( const KURL::List & lst )
01124 {
01125 for ( QIconViewItem *kit = firstItem(); kit; kit = kit->nextItem() )
01126 {
01127 bool bFound = false;
01128
01129
01130 for (KURL::List::ConstIterator it = lst.begin(); !bFound && it != lst.end(); ++it)
01131 {
01132 if ( static_cast<KFileIVI *>( kit )->item()->url() == *it )
01133 {
01134 bFound = true;
01135
01136 }
01137 }
01138 static_cast<KFileIVI *>( kit )->setDisabled( bFound );
01139 }
01140 }
01141
01142 void KonqIconViewWidget::slotSelectionChanged()
01143 {
01144
01145 int canCopy = 0;
01146 int canDel = 0;
01147 bool bInTrash = false;
01148 int iCount = 0;
01149
01150 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01151 {
01152 if ( it->isSelected() )
01153 {
01154 iCount++;
01155 canCopy++;
01156
01157 KURL url = ( static_cast<KFileIVI *>( it ) )->item()->url();
01158 if ( url.directory(false) == KGlobalSettings::trashPath() )
01159 bInTrash = true;
01160 if ( KProtocolInfo::supportsDeleting( url ) )
01161 canDel++;
01162 }
01163 }
01164
01165 emit enableAction( "cut", canDel > 0 );
01166 emit enableAction( "copy", canCopy > 0 );
01167 emit enableAction( "trash", canDel > 0 && !bInTrash && m_url.isLocalFile() );
01168 emit enableAction( "del", canDel > 0 );
01169 emit enableAction( "shred", canDel > 0 );
01170 emit enableAction( "properties", iCount > 0 && KPropertiesDialog::canDisplay( selectedFileItems() ) );
01171 emit enableAction( "editMimeType", ( iCount == 1 ) );
01172 emit enableAction( "rename", ( iCount == 1 ) );
01173 }
01174
01175 void KonqIconViewWidget::renameSelectedItem()
01176 {
01177 kdDebug(1203) << " -- KonqIconViewWidget::renameSelectedItem() -- " << endl;
01178 QIconViewItem * item = 0L;
01179 QIconViewItem *it = firstItem();
01180 for (; it; it = it->nextItem() )
01181 if ( it->isSelected() && !item )
01182 {
01183 item = it;
01184 break;
01185 }
01186 if (!item)
01187 {
01188 Q_ASSERT(item);
01189 return;
01190 }
01191 item->rename();
01192 }
01193
01194 void KonqIconViewWidget::cutSelection()
01195 {
01196 kdDebug(1203) << " -- KonqIconViewWidget::cutSelection() -- " << endl;
01197 KonqIconDrag * obj = konqDragObject( );
01198 obj->setMoveSelection( true );
01199 QApplication::clipboard()->setData( obj );
01200 }
01201
01202 void KonqIconViewWidget::copySelection()
01203 {
01204 kdDebug(1203) << " -- KonqIconViewWidget::copySelection() -- " << endl;
01205 KonqIconDrag * obj = konqDragObject( );
01206 QApplication::clipboard()->setData( obj );
01207 }
01208
01209 void KonqIconViewWidget::pasteSelection()
01210 {
01211 paste( url() );
01212 }
01213
01214 void KonqIconViewWidget::paste( const KURL &url )
01215 {
01216 KonqOperations::doPaste( this, url );
01217 }
01218
01219 KURL::List KonqIconViewWidget::selectedUrls()
01220 {
01221 KURL::List lstURLs;
01222
01223 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01224 if ( it->isSelected() )
01225 lstURLs.append( (static_cast<KFileIVI *>( it ))->item()->url() );
01226 return lstURLs;
01227 }
01228
01229 QRect KonqIconViewWidget::iconArea() const
01230 {
01231 return m_IconRect;
01232 }
01233
01234 void KonqIconViewWidget::setIconArea(const QRect &rect)
01235 {
01236 m_IconRect = rect;
01237 }
01238
01239 int KonqIconViewWidget::lineupMode() const
01240 {
01241 return m_LineupMode;
01242 }
01243
01244 void KonqIconViewWidget::setLineupMode(int mode)
01245 {
01246 m_LineupMode = mode;
01247 }
01248
01249 bool KonqIconViewWidget::sortDirectoriesFirst() const
01250 {
01251 return m_bSortDirsFirst;
01252 }
01253
01254 void KonqIconViewWidget::setSortDirectoriesFirst( bool b )
01255 {
01256 m_bSortDirsFirst = b;
01257 }
01258
01259 void KonqIconViewWidget::contentsDropEvent( QDropEvent * ev )
01260 {
01261 QIconViewItem *i = findItem( ev->pos() );
01262
01263
01264 if ( !i && (ev->action() == QDropEvent::Copy || ev->action() == QDropEvent::Link)
01265 && ev->source() && ev->source() == viewport())
01266 {
01267
01268 bool bMovable = itemsMovable();
01269 setItemsMovable(false);
01270 KIconView::contentsDropEvent( ev );
01271 setItemsMovable(bMovable);
01272
01273 QValueList<QIconDragItem> lst;
01274 slotDropped(ev, lst);
01275 }
01276 else
01277 {
01278 KIconView::contentsDropEvent( ev );
01279 emit dropped();
01280 }
01281
01282
01283
01284
01285 }
01286
01287 void KonqIconViewWidget::contentsMousePressEvent( QMouseEvent *e )
01288 {
01289
01290 m_mousePos = e->pos();
01291 m_bMousePressed = true;
01292 if (d->pSoundPlayer)
01293 d->pSoundPlayer->stop();
01294 d->bSoundItemClicked = true;
01295 KIconView::contentsMousePressEvent( e );
01296 }
01297
01298 void KonqIconViewWidget::contentsMouseReleaseEvent( QMouseEvent *e )
01299 {
01300 m_bMousePressed = false;
01301 KIconView::contentsMouseReleaseEvent( e );
01302 }
01303
01304 void KonqIconViewWidget::slotSaveIconPositions()
01305 {
01306 if ( m_dotDirectoryPath.isEmpty() )
01307 return;
01308 if ( !m_bDesktop )
01309 return;
01310 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions" << endl;
01311 KSimpleConfig dotDirectory( m_dotDirectoryPath );
01312 QIconViewItem *it = firstItem();
01313 if ( !it )
01314 return;
01315 while ( it )
01316 {
01317 KFileIVI *ivi = static_cast<KFileIVI *>( it );
01318 KFileItem *item = ivi->item();
01319
01320 dotDirectory.setGroup( QString( m_iconPositionGroupPrefix ).append( item->url().fileName() ) );
01321 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions " << item->url().fileName() << " " << it->x() << " " << it->y() << endl;
01322 dotDirectory.writeEntry( "X", it->x() );
01323 dotDirectory.writeEntry( "Y", it->y() );
01324 dotDirectory.writeEntry( "Exists", true );
01325
01326 it = it->nextItem();
01327 }
01328
01329 QStringList groups = dotDirectory.groupList();
01330 QStringList::ConstIterator gIt = groups.begin();
01331 QStringList::ConstIterator gEnd = groups.end();
01332 for (; gIt != gEnd; ++gIt )
01333 if ( (*gIt).left( m_iconPositionGroupPrefix.length() ) == m_iconPositionGroupPrefix )
01334 {
01335 dotDirectory.setGroup( *gIt );
01336 if ( dotDirectory.hasKey( "Exists" ) )
01337 dotDirectory.deleteEntry( "Exists", false );
01338 else
01339 {
01340 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions deleting group " << *gIt << endl;
01341 dotDirectory.deleteGroup( *gIt );
01342 }
01343 }
01344
01345 dotDirectory.sync();
01346 }
01347
01348
01349
01350
01351 void KonqIconViewWidget::insertInGrid(QIconViewItem *item)
01352 {
01353 if (0L == item)
01354 return;
01355
01356 if (!m_IconRect.isValid())
01357 {
01358 QIconView::insertInGrid(item);
01359 return;
01360 }
01361
01362 QRegion r(m_IconRect);
01363 QIconViewItem *i = firstItem();
01364 int y = -1;
01365 for (; i; i = i->nextItem() )
01366 {
01367 r = r.subtract(i->rect());
01368 y = QMAX(y, i->y() + i->height());
01369 }
01370
01371 QMemArray<QRect> rects = r.rects();
01372 QMemArray<QRect>::Iterator it = rects.begin();
01373 bool foundPlace = FALSE;
01374 for (; it != rects.end(); ++it)
01375 {
01376 QRect rect = *it;
01377 if (rect.width() >= item->width() && rect.height() >= item->height())
01378 {
01379 int sx = 0, sy = 0;
01380 if (rect.width() >= item->width() + spacing())
01381 sx = spacing();
01382 if (rect.height() >= item->height() + spacing())
01383 sy = spacing();
01384 item->move(rect.x() + sx, rect.y() + sy);
01385 foundPlace = true;
01386 break;
01387 }
01388 }
01389
01390 if (!foundPlace)
01391 item->move(m_IconRect.topLeft());
01392
01393
01394 return;
01395 }
01396
01397
01398
01399
01400
01401
01402 class QIVItemBin
01403 {
01404 public:
01405 QIVItemBin() {}
01406 ~QIVItemBin() {}
01407
01408 int count() { return mData.count(); }
01409 void add(QIconViewItem *item) { mData.append(item); }
01410
01411 QIconViewItem *top();
01412 QIconViewItem *bottom();
01413 QIconViewItem *left();
01414 QIconViewItem *right();
01415
01416 private:
01417 QPtrList<QIconViewItem> mData;
01418 };
01419
01420 QIconViewItem *QIVItemBin::top()
01421 {
01422 if (mData.count() == 0)
01423 return 0L;
01424
01425 QIconViewItem *it = mData.first();
01426 QIconViewItem *item = it;
01427 int y = it->y();
01428 for (it=mData.next(); it; it=mData.next())
01429 {
01430 if (it->y() < y)
01431 {
01432 y = it->y();
01433 item = it;
01434 }
01435 }
01436 mData.remove(item);
01437 return item;
01438 }
01439
01440 QIconViewItem *QIVItemBin::bottom()
01441 {
01442 if (mData.count() == 0)
01443 return 0L;
01444
01445 QIconViewItem *it = mData.first();
01446 QIconViewItem *item = it;
01447 int y = it->y();
01448 for (it=mData.next(); it; it=mData.next())
01449 {
01450 if (it->y() > y)
01451 {
01452 y = it->y();
01453 item = it;
01454 }
01455 }
01456 mData.remove(item);
01457 return item;
01458 }
01459
01460 QIconViewItem *QIVItemBin::left()
01461 {
01462 if (mData.count() == 0)
01463 return 0L;
01464
01465 QIconViewItem *it=mData.first();
01466 QIconViewItem *item = it;
01467 int x = it->x();
01468 for (it=mData.next(); it; it=mData.next())
01469 {
01470 if (it->x() < x)
01471 {
01472 x = it->x();
01473 item = it;
01474 }
01475 }
01476 mData.remove(item);
01477 return item;
01478 }
01479
01480 QIconViewItem *QIVItemBin::right()
01481 {
01482 if (mData.count() == 0)
01483 return 0L;
01484
01485 QIconViewItem *it=mData.first();
01486 QIconViewItem *item = it;
01487 int x = it->x();
01488 for (it=mData.next(); it; it=mData.next())
01489 {
01490 if (it->x() > x)
01491 {
01492 x = it->x();
01493 item = it;
01494 }
01495 }
01496 mData.remove(item);
01497 return item;
01498 }
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529 #define MIN3(a,b,c) (QMIN((a),(QMIN((b),(c)))))
01530
01531 void KonqIconViewWidget::lineupIcons()
01532 {
01533 if ( !firstItem() )
01534 {
01535 kdDebug(1203) << "No icons at all ?\n";
01536 return;
01537 }
01538
01539
01540 QValueList<QIconViewItem*> items;
01541 int dy = 0;
01542
01543
01544 QIconViewItem *item;
01545 for (item=firstItem(); item; item=item->nextItem())
01546 {
01547 items.append(item);
01548 dy = QMAX( dy, item->height() );
01549 }
01550
01551
01552 int dx = gridXValue();
01553
01554 dx += spacing();
01555 dy += spacing();
01556
01557 kdDebug(1203) << "dx = " << dx << ", dy = " << dy << "\n";
01558
01559 if ((dx < 15) || (dy < 15))
01560 {
01561 kdWarning(1203) << "Do you really have that fine a grid?\n";
01562 return;
01563 }
01564
01565 int x1, x2, y1, y2;
01566 if (m_IconRect.isValid())
01567 {
01568 x1 = m_IconRect.left(); x2 = m_IconRect.right();
01569 y1 = m_IconRect.top(); y2 = m_IconRect.bottom();
01570 } else
01571 {
01572 x1 = 0; x2 = viewport()->width();
01573 y1 = 0; y2 = viewport()->height();
01574 }
01575
01576 int nx = (x2 - x1) / dx;
01577 int ny = (y2 - y1) / dy;
01578
01579 kdDebug(1203) << "nx = " << nx << " ny = " << ny << "\n";
01580 if ((nx > 150) || (ny > 100))
01581 {
01582 kdDebug(1203) << "Do you really have that fine a grid?\n";
01583 return;
01584 }
01585 if ((nx <= 1) || (ny <= 1))
01586 {
01587 kdDebug(1203) << "Iconview is too small, not doing anything.\n";
01588 return;
01589 }
01590
01591
01592 typedef QIVItemBin *QIVItemPtr;
01593 QIVItemPtr **bins = new QIVItemPtr*[ny];
01594
01595 int i, j;
01596 for (j=0; j<ny; j++)
01597 {
01598 bins[j] = new QIVItemPtr[nx];
01599 for (i=0; i<nx; i++)
01600 bins[j][i] = 0;
01601 }
01602
01603 int left = x1;
01604 int right = x1 + dx;
01605 i = 0;
01606
01607 while (items.count())
01608 {
01609 int max_icon_x = dx;
01610 right = left + dx;
01611
01612 for (QValueList<QIconViewItem*>::Iterator it = items.begin(); it != items.end(); ++it)
01613 {
01614 item = *it;
01615 if (item->x() < right && max_icon_x < item->width() )
01616 max_icon_x = item->width();
01617 }
01618
01619 right = left + max_icon_x;
01620
01621 for (QValueList<QIconViewItem*>::Iterator it = items.begin(); it != items.end();)
01622 {
01623 item = *it;
01624 int mid = item->x() + item->width()/2 - x1;
01625 kdDebug(1203) << "matching " << mid << " left " << left << " right " << right << endl;
01626 if (mid < left || (mid >= left && mid < right)) {
01627 it = items.remove(it);
01628 j = (item->y() + item->height()/2 - y1) / dy;
01629 if (j < 0) j = 0;
01630 else if (j >= ny) j = ny - 1;
01631
01632 kdDebug(1203) << "putting " << item->text() << " " << i << " " << j << endl;
01633 if (bins[j][i] == 0L)
01634 bins[j][i] = new QIVItemBin;
01635 bins[j][i]->add(item);
01636 } else
01637 ++it;
01638 }
01639 kdDebug(1203) << "next round " << items.count() << endl;
01640 i = QMIN(i+1, nx - 1);
01641 left += max_icon_x + spacing();
01642 }
01643
01644
01645 int n, k;
01646 int infinity = 100000, nmoves = 1;
01647 for (n=0; (n < 10) && (nmoves != 0); n++)
01648 {
01649 nmoves = 0;
01650 for (j=0; j<ny; j++)
01651 {
01652 for (i=0; i<nx; i++)
01653 {
01654 if (!bins[j][i] || (bins[j][i]->count() < 2))
01655 continue;
01656
01657 kdDebug(1203) << "calc for " << i << " " << j << endl;
01658
01659 int tf = 0;
01660 for (k=j-1; (k >= 0) && bins[k][i] && bins[k][i]->count(); k--)
01661 tf += bins[k][i]->count();
01662 if (k == -1)
01663 tf += infinity;
01664
01665 int bf = 0;
01666 for (k=j+1; (k < ny) && bins[k][i] && bins[k][i]->count(); k++)
01667 bf += bins[k][i]->count();
01668 if (k == ny)
01669 bf += infinity;
01670
01671 int lf = 0;
01672 for (k=i-1; (k >= 0) && bins[j][k] && bins[j][k]->count(); k--)
01673 lf += bins[j][k]->count();
01674 if (k == -1)
01675 lf += infinity;
01676
01677 int rf = 0;
01678 for (k=i+1; (k < nx) && bins[j][k] && bins[j][k]->count(); k++)
01679 rf += bins[j][k]->count();
01680 if (k == nx)
01681 rf += infinity;
01682
01683
01684 if ( (tf >= infinity) && (bf >= infinity) &&
01685 (lf >= infinity) && (rf >= infinity)
01686 )
01687 continue;
01688
01689
01690 if (m_LineupMode == LineupHorizontal)
01691 {
01692 tf += infinity;
01693 bf += infinity;
01694 } else if (m_LineupMode == LineupVertical)
01695 {
01696 lf += infinity;
01697 rf += infinity;
01698 }
01699
01700
01701 if (tf <= MIN3(bf,lf,rf))
01702 {
01703 if (!bins[j-1][i])
01704 bins[j-1][i] = new QIVItemBin;
01705 bins[j-1][i]->add(bins[j][i]->top());
01706 } else if (bf <= MIN3(tf,lf,rf))
01707 {
01708 if (!bins[j+1][i])
01709 bins[j+1][i] = new QIVItemBin;
01710 bins[j+1][i]->add(bins[j][i]->bottom());
01711 } else if (lf <= MIN3(tf,bf,rf))
01712 {
01713 if (!bins[j][i-1])
01714 bins[j][i-1] = new QIVItemBin;
01715 bins[j][i-1]->add(bins[j][i]->left());
01716 } else
01717 {
01718 if (!bins[j][i+1])
01719 bins[j][i+1] = new QIVItemBin;
01720 bins[j][i+1]->add(bins[j][i]->right());
01721 }
01722
01723 nmoves++;
01724 }
01725 }
01726 kdDebug(1203) << "nmoves = " << nmoves << "\n";
01727 }
01728
01729
01730 n = 0;
01731 QIconViewItem **its = new QIconViewItem*[ny];
01732 for (i=0; i<nx; i++)
01733 {
01734 int max_icon_x = dx;
01735 for (j=0; j<ny; j++)
01736 {
01737 its[j] = 0;
01738 if (!bins[j][i] || !bins[j][i]->count())
01739 continue;
01740
01741 item = its[j] = bins[j][i]->top();
01742 if ( max_icon_x < item->width() )
01743 max_icon_x = item->width();
01744 }
01745
01746 for (j=0; j<ny; j++)
01747 {
01748 if ( its[j] == 0 )
01749 continue;
01750
01751 item = its[j];
01752 int x = x1 + spacing() + ( max_icon_x - item->width() )/2;
01753 int y = y1 + j * dy;
01754 if (item->pos() != QPoint(x, y))
01755 {
01756 kdDebug(1203) << "moving " << item->text() << " " << x << " " << y << endl;
01757 item->move(x, y);
01758 }
01759 if (bins[j][i]->count())
01760 {
01761 kdDebug(1203) << "Lineup incomplete..\n";
01762 item = bins[j][i]->top();
01763 for (k=1; item; k++)
01764 {
01765 x = x1 + i*dx + spacing() + 10*k; y = y1 + j*dy + spacing() + 5*k;
01766 if (item->pos() != QPoint(x, y))
01767 {
01768 item->move(x, y);
01769 }
01770 item = bins[j][i]->top();
01771 }
01772 }
01773 delete bins[j][i];
01774 bins[j][i] = 0;
01775 n++;
01776 }
01777 x1 += max_icon_x + spacing();
01778 }
01779 delete[] its;
01780
01781 updateContents();
01782 for (int j=0; j<ny; j++)
01783 delete [] bins[j];
01784 delete[] bins;
01785 kdDebug(1203) << n << " icons successfully moved.\n";
01786 return;
01787 }
01788
01789 void KonqIconViewWidget::visualActivate(QIconViewItem * item)
01790 {
01791
01792 QRect irect = item->rect();
01793
01794
01795 QRect rect = item->pixmapRect();
01796
01797
01798
01799 rect.moveBy(irect.x(), irect.y());
01800
01801
01802 rect.moveBy( -contentsX(), -contentsY() );
01803
01804 KIconEffect::visualActivate(viewport(), rect);
01805 }
01806
01807 void KonqIconViewWidget::backgroundPixmapChange( const QPixmap & )
01808 {
01809 viewport()->update();
01810 }
01811
01812 void KonqIconViewWidget::setPreviewSettings( const QStringList& settings )
01813 {
01814 d->previewSettings = settings;
01815 }
01816
01817 const QStringList& KonqIconViewWidget::previewSettings()
01818 {
01819 return d->previewSettings;
01820 }
01821
01822 void KonqIconViewWidget::setNewURL( const QString& url )
01823 {
01824 KURL u;
01825 if ( url.startsWith( "/" ) )
01826 u.setPath( url );
01827 else
01828 u = url;
01829 setURL( u );
01830 }
01831
01832 #include "konq_iconviewwidget.moc"
01833
01834