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