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