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 KIconView::focusOutEvent( ev );
00473 }
00474
00475 void KonqIconViewWidget::slotItemRenamed(QIconViewItem *item, const QString &name)
00476 {
00477 kdDebug(1203) << "KonqIconViewWidget::slotItemRenamed" << endl;
00478 KFileIVI *viewItem = static_cast<KFileIVI *>(item);
00479 KFileItem *fileItem = viewItem->item();
00480
00481
00482
00483
00484 viewItem->setText( fileItem->text() );
00485 kdDebug(1203)<<" fileItem->text() ;"<<fileItem->text()<<endl;
00486
00487 if( !name.isEmpty() )
00488 {
00489
00490 KURL oldurl( fileItem->url() );
00491 KURL newurl( url() );
00492 newurl.setPath( url().path(1) + KIO::encodeFileName( name ) );
00493 kdDebug(1203)<<" newurl :"<<newurl.url()<<endl;
00494
00495 KonqOperations::rename( this, oldurl, newurl );
00496 }
00497 }
00498
00499 void KonqIconViewWidget::slotIconChanged( int group )
00500 {
00501 if (group != KIcon::Desktop)
00502 return;
00503
00504 int size = m_size;
00505 if ( m_size == 0 )
00506 m_size = -1;
00507 setIcons( size );
00508 readAnimatedIconsConfig();
00509 }
00510
00511 void KonqIconViewWidget::readAnimatedIconsConfig()
00512 {
00513 KConfigGroup cfgGroup( KGlobal::config(), "DesktopIcons" );
00514 d->doAnimations = cfgGroup.readBoolEntry( "Animated", true );
00515 d->gridXspacing = cfgGroup.readNumEntry( "GridXSpacing", 50);
00516 }
00517
00518 void KonqIconViewWidget::slotOnItem( QIconViewItem *_item )
00519 {
00520 KFileIVI* item = static_cast<KFileIVI *>( _item );
00521
00522 if( d->pActiveItem != 0L && d->pActiveItem != item )
00523 {
00524 if ( d->m_movie && d->pActiveItem->isAnimated() )
00525 {
00526 d->m_movie->pause();
00527 d->pActiveItem->setAnimated( false );
00528 d->pActiveItem->refreshIcon( true );
00529 }
00530 else {
00531 d->pActiveItem->setActive( false );
00532 }
00533 d->pActiveItem = 0L;
00534 d->pFileTipTimer->stop();
00535 d->pFileTip->setItem( 0L );
00536 }
00537
00538
00539 if (d->pSoundPlayer != 0 && item != d->pSoundItem)
00540 {
00541 d->pSoundPlayer->stop();
00542
00543 d->pSoundItem = 0;
00544 if (d->pSoundTimer && d->pSoundTimer->isActive())
00545 d->pSoundTimer->stop();
00546 }
00547
00548 if ( !m_bMousePressed )
00549 {
00550 if( item != d->pActiveItem )
00551 {
00552 d->pActiveItem = item;
00553 if ( topLevelWidget() == kapp->activeWindow() )
00554 d->pFileTipTimer->start( 400, true );
00555
00556 if ( d->doAnimations && d->pActiveItem && d->pActiveItem->hasAnimation() )
00557 {
00558
00559
00560 #if 0 // Qt-mng bug, reusing the movie doesn't work currently.
00561 if ( d->m_movie && d->movieFileName == d->pActiveItem->mouseOverAnimation() )
00562 {
00563 d->pActiveItem->setAnimated( true );
00564 if (d->m_movieBlocked) {
00565 kdDebug(1203) << "onitem, but blocked" << endl;
00566 d->m_movie->pause();
00567 }
00568 else {
00569 kdDebug(1203) << "we go ahead.." << endl;
00570 d->m_movieBlocked++;
00571 QTimer::singleShot(300, this, SLOT(slotReenableAnimation()));
00572 d->m_movie->restart();
00573 d->m_movie->unpause();
00574 }
00575 }
00576 else
00577 #endif
00578 {
00579 QMovie movie = KGlobal::iconLoader()->loadMovie( d->pActiveItem->mouseOverAnimation(), KIcon::Desktop, d->pActiveItem->iconSize() );
00580 if ( !movie.isNull() )
00581 {
00582 delete d->m_movie;
00583 d->m_movie = new QMovie( movie );
00584
00585
00586 const QPixmap* pm = backgroundPixmap();
00587 bool hasPixmap = pm && !pm->isNull();
00588 if ( !hasPixmap ) {
00589 pm = viewport()->backgroundPixmap();
00590 hasPixmap = pm && !pm->isNull();
00591 }
00592 if (!hasPixmap && backgroundMode() != NoBackground)
00593 d->m_movie->setBackgroundColor( viewport()->backgroundColor() );
00594 d->m_movie->connectUpdate( this, SLOT( slotMovieUpdate(const QRect &) ) );
00595 d->m_movie->connectStatus( this, SLOT( slotMovieStatus(int) ) );
00596 d->movieFileName = d->pActiveItem->mouseOverAnimation();
00597 d->pActiveItem->setAnimated( true );
00598 }
00599 else
00600 {
00601 d->pActiveItem->setAnimated( false );
00602 if (d->m_movie)
00603 d->m_movie->pause();
00604
00605 d->pActiveItem->setMouseOverAnimation( QString::null );
00606 }
00607 }
00608 }
00609
00610 if (d->pActiveItem && !d->pActiveItem->isAnimated())
00611 {
00612 d->pActiveItem->setActive( true );
00613 }
00614 }
00615 else
00616 {
00617
00618
00619 d->pActiveItem = 0L;
00620 d->pFileTipTimer->stop();
00621 d->pFileTip->setItem( 0L );
00622 }
00623 }
00624 else
00625 {
00626
00627
00628 d->pActiveItem = 0L;
00629 d->pFileTipTimer->stop();
00630 d->pFileTip->setItem( 0L );
00631 }
00632
00633
00634 if (d->bSoundPreviews && d->pSoundPlayer &&
00635 d->pSoundPlayer->mimeTypes().contains(
00636 item->item()->mimetype())
00637 && KGlobalSettings::showFilePreview(item->item()->url())
00638 && topLevelWidget() == kapp->activeWindow())
00639 {
00640 d->pSoundItem = item;
00641 d->bSoundItemClicked = false;
00642 if (!d->pSoundTimer)
00643 {
00644 d->pSoundTimer = new QTimer(this);
00645 connect(d->pSoundTimer, SIGNAL(timeout()), SLOT(slotStartSoundPreview()));
00646 }
00647 if (d->pSoundTimer->isActive())
00648 d->pSoundTimer->stop();
00649 d->pSoundTimer->start(500, true);
00650 }
00651 else
00652 {
00653 if (d->pSoundPlayer)
00654 d->pSoundPlayer->stop();
00655 d->pSoundItem = 0;
00656 if (d->pSoundTimer && d->pSoundTimer->isActive())
00657 d->pSoundTimer->stop();
00658 }
00659 }
00660
00661 void KonqIconViewWidget::slotOnViewport()
00662 {
00663 d->pFileTipTimer->stop();
00664 d->pFileTip->setItem( 0L );
00665
00666 if (d->pSoundPlayer)
00667 d->pSoundPlayer->stop();
00668 d->pSoundItem = 0;
00669 if (d->pSoundTimer && d->pSoundTimer->isActive())
00670 d->pSoundTimer->stop();
00671
00672 if (d->pActiveItem == 0L)
00673 return;
00674
00675 if ( d->doAnimations && d->m_movie && d->pActiveItem->isAnimated() )
00676 {
00677 d->pActiveItem->setAnimated( false );
00678 #if 0
00679
00680 if (d->m_movie->running()) {
00681 d->m_movie->pause();
00682 d->m_movieBlocked++;
00683 kdDebug(1203) << "on viewport, blocking" << endl;
00684 QTimer::singleShot(300, this, SLOT(slotReenableAnimation()));
00685 }
00686 #endif
00687 d->pActiveItem->refreshIcon( true );
00688 Q_ASSERT( d->pActiveItem->state() == KIcon::DefaultState );
00689
00690
00691
00692 }
00693 else
00694 {
00695 d->pActiveItem->setActive( false );
00696 }
00697 d->pActiveItem = 0L;
00698 }
00699
00700 void KonqIconViewWidget::slotStartSoundPreview()
00701 {
00702 if (!d->pSoundItem || d->bSoundItemClicked)
00703 return;
00704
00705 d->pSoundPlayer->play(d->pSoundItem->item()->url().url());
00706 }
00707
00708
00709 void KonqIconViewWidget::slotPreview(const KFileItem *item, const QPixmap &pix)
00710 {
00711
00712 for (QIconViewItem *it = firstItem(); it; it = it->nextItem())
00713 {
00714 KFileIVI* current = static_cast<KFileIVI *>(it);
00715 if (current->item() == item)
00716 {
00717 if (item->overlays() & KIcon::HiddenOverlay) {
00718 QPixmap p(pix);
00719
00720 KIconEffect::semiTransparent(p);
00721 current->setThumbnailPixmap(p);
00722 } else {
00723 current->setThumbnailPixmap(pix);
00724 }
00725 break;
00726 }
00727 }
00728 }
00729
00730 void KonqIconViewWidget::slotPreviewResult()
00731 {
00732 d->pPreviewJob = 0;
00733 emit imagePreviewFinished();
00734 }
00735
00736 void KonqIconViewWidget::slotStartTooltip()
00737 {
00738 if ( d->pActiveItem )
00739 d->pFileTip->setItem( d->pActiveItem );
00740 }
00741
00742 void KonqIconViewWidget::slotToolTipPreview(const KFileItem* item, const QPixmap &pix)
00743 {
00744 d->pFileTip->gotPreview( item, pix );
00745 }
00746
00747 void KonqIconViewWidget::slotToolTipPreviewResult()
00748 {
00749 d->pFileTip->gotPreviewResult();
00750 }
00751
00752 void KonqIconViewWidget::slotMovieUpdate( const QRect& rect )
00753 {
00754
00755 Q_ASSERT( d );
00756 Q_ASSERT( d->m_movie );
00757
00758 if ( d->pActiveItem && d->m_movie && d->pActiveItem->isAnimated() ) {
00759 const QPixmap &frame = d->m_movie->framePixmap();
00760
00761
00762 int iconSize=d->pActiveItem->iconSize();
00763 if (iconSize==0) iconSize = KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00764 if ( frame.width() != iconSize || frame.height() != iconSize ) {
00765 d->pActiveItem->setAnimated( false );
00766 d->m_movie->pause();
00767
00768 d->pActiveItem->setMouseOverAnimation( QString::null );
00769 d->pActiveItem->setActive( true );
00770 return;
00771 }
00772 d->pActiveItem->setPixmapDirect( frame, false, false );
00773 QRect pixRect = d->pActiveItem->pixmapRect(false);
00774 repaintContents( pixRect.x() + rect.x(), pixRect.y() + rect.y(), rect.width(), rect.height(), false );
00775 }
00776 }
00777
00778 void KonqIconViewWidget::slotMovieStatus( int status )
00779 {
00780 if ( status < 0 ) {
00781
00782 if ( d->pActiveItem && d->pActiveItem->isAnimated() ) {
00783 d->pActiveItem->setAnimated( false );
00784 d->pActiveItem->setMouseOverAnimation( QString::null );
00785 d->pActiveItem->setActive( true );
00786 }
00787 }
00788 }
00789
00790 void KonqIconViewWidget::slotReenableAnimation()
00791 {
00792 if (!--d->m_movieBlocked) {
00793 if ( d->pActiveItem && d->m_movie && d->m_movie->paused()) {
00794 kdDebug(1203) << "reenabled animation" << endl;
00795 d->m_movie->restart();
00796 d->m_movie->unpause();
00797 }
00798 }
00799 }
00800
00801 void KonqIconViewWidget::clear()
00802 {
00803 d->pFileTipTimer->stop();
00804 d->pFileTip->setItem( 0L );
00805 stopImagePreview();
00806 KIconView::clear();
00807 d->pActiveItem = 0L;
00808 }
00809
00810 void KonqIconViewWidget::takeItem( QIconViewItem *item )
00811 {
00812 if ( d->pActiveItem == static_cast<KFileIVI *>(item) )
00813 {
00814 d->pFileTipTimer->stop();
00815 d->pFileTip->setItem( 0L );
00816 d->pActiveItem = 0L;
00817 }
00818
00819 if ( d->pPreviewJob )
00820 d->pPreviewJob->removeItem( static_cast<KFileIVI *>(item)->item() );
00821
00822 KIconView::takeItem( item );
00823 }
00824
00825
00826 void KonqIconViewWidget::setThumbnailPixmap( KFileIVI * item, const QPixmap & pixmap )
00827 {
00828 if ( item )
00829 {
00830 if ( d->pActiveItem == item )
00831 {
00832 d->pFileTipTimer->stop();
00833 d->pFileTip->setItem( 0L );
00834 d->pActiveItem = 0L;
00835 }
00836 item->setThumbnailPixmap( pixmap );
00837 if ( m_bSetGridX && item->width() > gridX() )
00838 {
00839 setGridX( item->width() );
00840 if (autoArrange())
00841 arrangeItemsInGrid();
00842 }
00843 }
00844 }
00845
00846 bool KonqIconViewWidget::initConfig( bool bInit )
00847 {
00848 bool fontChanged = false;
00849 m_pSettings = KonqFMSettings::settings();
00850
00851
00852 QColor normalTextColor = m_pSettings->normalTextColor();
00853 setItemColor( normalTextColor );
00854
00855 if (m_bDesktop)
00856 {
00857 QColor itemTextBg = m_pSettings->itemTextBackground();
00858 if ( itemTextBg.isValid() )
00859 setItemTextBackground( itemTextBg );
00860 else
00861 setItemTextBackground( NoBrush );
00862 }
00863
00864
00865 d->pFileTip->setOptions(m_pSettings->showFileTips() && QToolTip::isGloballyEnabled(),
00866 m_pSettings->showPreviewsInFileTips(),
00867 m_pSettings->numFileTips());
00868
00869
00870 QFont font( m_pSettings->standardFont() );
00871 if (!m_bDesktop)
00872 font.setUnderline( m_pSettings->underlineLink() );
00873
00874 if ( font != KonqIconViewWidget::font() )
00875 {
00876 setFont( font );
00877 if (!bInit)
00878 {
00879
00880
00881 fontChanged = true;
00882 }
00883 }
00884
00885 setIconTextHeight( m_bDesktop ? 2 : m_pSettings->iconTextHeight() );
00886
00887
00888 if ( d->bBoostPreview != boostPreview() )
00889 setIcons(m_size);
00890 else if (!bInit)
00891 updateContents();
00892 return fontChanged;
00893 }
00894
00895 bool KonqIconViewWidget::boostPreview() const
00896 {
00897 if ( m_bDesktop ) {
00898 int size = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00899 int mini = spacing() + QMAX( 0, largestPreviewIconSize( size ) - size );
00900 if ( d->desktopGridSpacing.x() < mini ||
00901 d->desktopGridSpacing.y() < mini )
00902 return false;
00903 }
00904
00905 KConfigGroup group( KGlobal::config(), "PreviewSettings" );
00906 return group.readBoolEntry( "BoostSize", false );
00907 }
00908
00909 void KonqIconViewWidget::disableSoundPreviews()
00910 {
00911 d->bSoundPreviews = false;
00912
00913 if (d->pSoundPlayer)
00914 d->pSoundPlayer->stop();
00915 d->pSoundItem = 0;
00916 if (d->pSoundTimer && d->pSoundTimer->isActive())
00917 d->pSoundTimer->stop();
00918 }
00919
00920 void KonqIconViewWidget::setIcons( int size, const QStringList& stopImagePreviewFor )
00921 {
00922
00923 bool sizeChanged = (m_size != size);
00924 int oldGridX = gridX();
00925 m_size = size;
00926
00927
00928 bool boost = boostPreview();
00929 bool previewSizeChanged = ( d->bBoostPreview != boost );
00930 d->bBoostPreview = boost;
00931
00932 if ( sizeChanged || previewSizeChanged )
00933 {
00934 int realSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
00935 setSpacing( ( realSize > KIcon::SizeSmall ) ? 5 : 0 );
00936 }
00937
00938 if ( sizeChanged || previewSizeChanged || !stopImagePreviewFor.isEmpty() )
00939 {
00940 calculateGridX();
00941 }
00942 bool stopAll = !stopImagePreviewFor.isEmpty() && stopImagePreviewFor.first() == "*";
00943
00944
00945
00946
00947
00948 bool prevUpdatesState = viewport()->isUpdatesEnabled();
00949 viewport()->setUpdatesEnabled( false );
00950
00951
00952 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00953 KFileIVI * ivi = static_cast<KFileIVI *>( it );
00954
00955
00956 if ( !ivi->isThumbnail() ||
00957 sizeChanged ||
00958 previewSizeChanged ||
00959 stopAll ||
00960 mimeTypeMatch( ivi->item()->mimetype(), stopImagePreviewFor ) )
00961 {
00962 ivi->setIcon( size, ivi->state(), true, false );
00963 }
00964 else
00965 ivi->invalidateThumb( ivi->state(), true );
00966 }
00967
00968
00969 viewport()->setUpdatesEnabled( prevUpdatesState );
00970
00971 if ( ( sizeChanged || previewSizeChanged || oldGridX != gridX() ||
00972 !stopImagePreviewFor.isEmpty() ) && autoArrange() )
00973 arrangeItemsInGrid( true );
00974 else
00975 viewport()->update();
00976 }
00977
00978 bool KonqIconViewWidget::mimeTypeMatch( const QString& mimeType, const QStringList& mimeList ) const
00979 {
00980 for (QStringList::ConstIterator mt = mimeList.begin(); mt != mimeList.end(); ++mt)
00981 {
00982 if ( mimeType == *mt )
00983 return true;
00984
00985 QString tmp( mimeType );
00986 if ( (*mt).endsWith("*") && tmp.replace(QRegExp("/.*"), "/*") == (*mt) )
00987 return true;
00988 }
00989 return false;
00990 }
00991
00992 void KonqIconViewWidget::setItemTextPos( ItemTextPos pos )
00993 {
00994 if ( m_bSetGridX )
00995 {
00996 calculateGridX();
00997 if ( itemTextPos() != pos )
00998 {
00999 if ( pos == QIconView::Right )
01000 setGridX( gridX() + 100 );
01001 else
01002 setGridX( gridX() - 100 );
01003 }
01004 }
01005
01006 KIconView::setItemTextPos( pos );
01007 }
01008
01009 void KonqIconViewWidget::gridValues( int* x, int* y, int* dx, int* dy,
01010 int* nx, int* ny )
01011 {
01012 int previewSize = previewIconSize( m_size );
01013 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01014
01015
01016 *dx = QMAX( iconSize + d->desktopGridSpacing.x(),
01017 previewSize + spacing() );
01018 int textHeight = QMIN( iconTextHeight(), 2 ) * fontMetrics().height();
01019 *dy = textHeight + 2 +
01020 QMAX( iconSize + d->desktopGridSpacing.y(), previewSize );
01021
01022
01023 int x1, x2, y1, y2;
01024 int yOffset = QMAX( 0, *dy - ( previewSize + textHeight ) );
01025 if ( m_IconRect.isValid() ) {
01026 *x = x1 = m_IconRect.left(); x2 = m_IconRect.right();
01027 y1 = m_IconRect.top(); y2 = m_IconRect.bottom();
01028 }
01029 else {
01030 *x = x1 = 0; x2 = viewport()->width();
01031 y1 = 0; y2 = viewport()->height();
01032 }
01033 *y = y1 -= yOffset / 2;
01034 y2 -= yOffset / 2;
01035
01036 *nx = (x2 - x1) / *dx;
01037 *ny = (y2 - y1) / *dy;
01038
01039
01040
01041 *dx = (x2 - x1) / *nx;
01042 *dy = (y2 - y1) / *ny;
01043 kdDebug(1203) << "dx = " << *dx << ", dy = " << *dy << "\n";
01044 }
01045
01046 void KonqIconViewWidget::calculateGridX()
01047 {
01048 if ( m_bSetGridX )
01049 setGridX( gridXValue() );
01050 }
01051
01052 int KonqIconViewWidget::gridXValue() const
01053 {
01054 int sz = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01055 bool horizontal = (itemTextPos() == QIconView::Right);
01056 int newGridX = sz + (!m_bSetGridX ? d->gridXspacing : 50) + ( horizontal ? 100 : 0);
01057 newGridX = QMAX( newGridX, (horizontal ? 2 : 1) * previewIconSize( sz ) + 13 );
01058
01059 return newGridX;
01060 }
01061
01062 void KonqIconViewWidget::refreshMimeTypes()
01063 {
01064 updatePreviewMimeTypes();
01065 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01066 (static_cast<KFileIVI *>( it ))->item()->refreshMimeType();
01067 setIcons( m_size );
01068 }
01069
01070 void KonqIconViewWidget::setURL( const KURL &kurl )
01071 {
01072 stopImagePreview();
01073 m_url = kurl;
01074
01075 d->pFileTip->setPreview( KGlobalSettings::showFilePreview(m_url) );
01076
01077 if ( m_url.isLocalFile() )
01078 m_dotDirectoryPath = m_url.path(1).append( ".directory" );
01079 else
01080 m_dotDirectoryPath = QString::null;
01081 }
01082
01083 void KonqIconViewWidget::startImagePreview( const QStringList &, bool force )
01084 {
01085 stopImagePreview();
01086
01087
01088 if ( !KGlobalSettings::showFilePreview( url() ) ) {
01089 kdDebug(1203) << "Previews disabled for protocol " << url().protocol() << endl;
01090 emit imagePreviewFinished();
01091 return;
01092 }
01093
01094 if ((d->bSoundPreviews = d->previewSettings.contains( "audio/" )) &&
01095 !d->pSoundPlayer)
01096 {
01097 KLibFactory *factory = KLibLoader::self()->factory("konq_sound");
01098 if (factory)
01099 d->pSoundPlayer = static_cast<KonqSoundPlayer *>(
01100 factory->create(this, 0, "KonqSoundPlayer"));
01101 d->bSoundPreviews = (d->pSoundPlayer != 0L);
01102 }
01103
01104 KFileItemList items;
01105 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01106 if ( force || !static_cast<KFileIVI *>( it )->hasValidThumbnail() )
01107 items.append( static_cast<KFileIVI *>( it )->item() );
01108
01109 bool onlyAudio = true;
01110 for ( QStringList::ConstIterator it = d->previewSettings.begin(); it != d->previewSettings.end(); ++it ) {
01111 if ( (*it).startsWith( "audio/" ) )
01112 d->bSoundPreviews = true;
01113 else
01114 onlyAudio = false;
01115 }
01116
01117 if ( items.isEmpty() || onlyAudio ) {
01118 emit imagePreviewFinished();
01119 return;
01120 }
01121
01122 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01123 int size;
01124
01125 d->bBoostPreview = boostPreview();
01126 size = previewIconSize( iconSize );
01127
01128 if ( !d->bBoostPreview )
01129 iconSize /= 2;
01130
01131 d->pPreviewJob = KIO::filePreview( items, size, size, iconSize,
01132 m_pSettings->textPreviewIconTransparency(), true ,
01133 true , &(d->previewSettings) );
01134 connect( d->pPreviewJob, SIGNAL( gotPreview( const KFileItem *, const QPixmap & ) ),
01135 this, SLOT( slotPreview( const KFileItem *, const QPixmap & ) ) );
01136 connect( d->pPreviewJob, SIGNAL( result( KIO::Job * ) ),
01137 this, SLOT( slotPreviewResult() ) );
01138 }
01139
01140 void KonqIconViewWidget::stopImagePreview()
01141 {
01142 if (d->pPreviewJob)
01143 {
01144 d->pPreviewJob->kill();
01145 d->pPreviewJob = 0;
01146
01147
01148 }
01149 }
01150
01151 bool KonqIconViewWidget::isPreviewRunning() const
01152 {
01153 return d->pPreviewJob;
01154 }
01155
01156 KFileItemList KonqIconViewWidget::selectedFileItems()
01157 {
01158 KFileItemList lstItems;
01159
01160 QIconViewItem *it = firstItem();
01161 for (; it; it = it->nextItem() )
01162 if ( it->isSelected() ) {
01163 KFileItem *fItem = (static_cast<KFileIVI *>(it))->item();
01164 lstItems.append( fItem );
01165 }
01166 return lstItems;
01167 }
01168
01169 void KonqIconViewWidget::slotDropped( QDropEvent *ev, const QValueList<QIconDragItem> & )
01170 {
01171
01172 KonqOperations::doDrop( m_rootItem , url(), ev, this );
01173 }
01174
01175 void KonqIconViewWidget::slotAboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)
01176 {
01177
01178 }
01179
01180 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r )
01181 {
01182 drawBackground(p, r, r.topLeft());
01183 }
01184
01185 void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r , const QPoint &pt)
01186 {
01187 const QPixmap *pm = backgroundPixmap();
01188 bool hasPixmap = pm && !pm->isNull();
01189 if ( !hasPixmap ) {
01190 pm = viewport()->backgroundPixmap();
01191 hasPixmap = pm && !pm->isNull();
01192 }
01193
01194 QRect rtgt(r);
01195 rtgt.moveTopLeft(pt);
01196 if (!hasPixmap && backgroundMode() != NoBackground) {
01197 p->fillRect(rtgt, viewport()->backgroundColor());
01198 return;
01199 }
01200
01201 if (hasPixmap) {
01202 int ax = (r.x() + contentsX() + leftMargin()) % pm->width();
01203 int ay = (r.y() + contentsY() + topMargin()) % pm->height();
01204 p->drawTiledPixmap(rtgt, *pm, QPoint(ax, ay));
01205 }
01206 }
01207
01208 QDragObject * KonqIconViewWidget::dragObject()
01209 {
01210 if ( !currentItem() )
01211 return 0;
01212
01213 return konqDragObject( viewport() );
01214 }
01215
01216 KonqIconDrag * KonqIconViewWidget::konqDragObject( QWidget * dragSource )
01217 {
01218
01219
01220 QPoint offset(-10,-10);
01221 KonqIconDrag * drag = new KonqIconDrag( dragSource );
01222 QIconViewItem *primaryItem = currentItem();
01223
01224 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
01225 if ( it->isSelected() ) {
01226 if (!primaryItem)
01227 primaryItem = it;
01228 KURL url = (static_cast<KFileIVI *>(it))->item()->url();
01229 QString itemURL = KURLDrag::urlToString(url);
01230 kdDebug(1203) << "itemURL=" << itemURL << endl;
01231 QIconDragItem id;
01232 id.setData( QCString(itemURL.latin1()) );
01233 drag->append( id,
01234 QRect( it->pixmapRect(false).topLeft() - m_mousePos - offset,
01235 it->pixmapRect().size() ),
01236 QRect( it->textRect(false).topLeft() - m_mousePos - offset,
01237 it->textRect().size() ),
01238 itemURL );
01239 }
01240 }
01241
01242 if (primaryItem)
01243 {
01244
01245 drag->setPixmap( *primaryItem->pixmap(), m_mousePos - primaryItem->pixmapRect(false).topLeft() + offset );
01246 }
01247
01248 return drag;
01249 }
01250
01251 void KonqIconViewWidget::contentsDragEnterEvent( QDragEnterEvent *e )
01252 {
01253 if ( e->provides( "text/uri-list" ) )
01254 {
01255 QByteArray payload = e->encodedData( "text/uri-list" );
01256 if ( !payload.size() )
01257 kdError() << "Empty data !" << endl;
01258
01259
01260 bool ok = KURLDrag::decode( e, m_lstDragURLs );
01261 if( !ok )
01262 kdError() << "Couldn't decode urls dragged !" << endl;
01263 }
01264 KIconView::contentsDragEnterEvent( e );
01265 emit dragEntered();
01266 }
01267
01268 void KonqIconViewWidget::contentsDragLeaveEvent( QDragLeaveEvent *e )
01269 {
01270 QIconView::contentsDragLeaveEvent(e);
01271 emit dragLeft();
01272 }
01273
01274
01275 void KonqIconViewWidget::setItemColor( const QColor &c )
01276 {
01277 iColor = c;
01278 }
01279
01280 QColor KonqIconViewWidget::itemColor() const
01281 {
01282 return iColor;
01283 }
01284
01285 void KonqIconViewWidget::disableIcons( const KURL::List & lst )
01286 {
01287 for ( QIconViewItem *kit = firstItem(); kit; kit = kit->nextItem() )
01288 {
01289 bool bFound = false;
01290
01291
01292 for (KURL::List::ConstIterator it = lst.begin(); !bFound && it != lst.end(); ++it)
01293 {
01294 if ( static_cast<KFileIVI *>( kit )->item()->url() == *it )
01295 {
01296 bFound = true;
01297
01298 }
01299 }
01300 static_cast<KFileIVI *>( kit )->setDisabled( bFound );
01301 }
01302 }
01303
01304 void KonqIconViewWidget::slotSelectionChanged()
01305 {
01306
01307 int canCopy = 0;
01308 int canDel = 0;
01309 bool bInTrash = false;
01310 int iCount = 0;
01311
01312 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01313 {
01314 if ( it->isSelected() )
01315 {
01316 iCount++;
01317 canCopy++;
01318
01319 KURL url = ( static_cast<KFileIVI *>( it ) )->item()->url();
01320 if ( url.directory(false) == KGlobalSettings::trashPath() )
01321 bInTrash = true;
01322 if ( KProtocolInfo::supportsDeleting( url ) )
01323 canDel++;
01324 }
01325 }
01326
01327 emit enableAction( "cut", canDel > 0 );
01328 emit enableAction( "copy", canCopy > 0 );
01329 emit enableAction( "trash", canDel > 0 && !bInTrash && m_url.isLocalFile() );
01330 emit enableAction( "del", canDel > 0 );
01331 emit enableAction( "properties", iCount > 0 && KPropertiesDialog::canDisplay( selectedFileItems() ) );
01332 emit enableAction( "editMimeType", ( iCount == 1 ) );
01333 emit enableAction( "rename", ( iCount == 1 ) && !bInTrash );
01334 }
01335
01336 void KonqIconViewWidget::renameCurrentItem()
01337 {
01338 if ( currentItem() )
01339 currentItem()->rename();
01340 }
01341
01342 void KonqIconViewWidget::renameSelectedItem()
01343 {
01344 kdDebug(1203) << " -- KonqIconViewWidget::renameSelectedItem() -- " << endl;
01345 QIconViewItem * item = 0L;
01346 QIconViewItem *it = firstItem();
01347 for (; it; it = it->nextItem() )
01348 if ( it->isSelected() && !item )
01349 {
01350 item = it;
01351 break;
01352 }
01353 if (!item)
01354 {
01355 Q_ASSERT(item);
01356 return;
01357 }
01358 item->rename();
01359 }
01360
01361 void KonqIconViewWidget::cutSelection()
01362 {
01363 kdDebug(1203) << " -- KonqIconViewWidget::cutSelection() -- " << endl;
01364 KonqIconDrag * obj = konqDragObject( );
01365 obj->setMoveSelection( true );
01366 QApplication::clipboard()->setData( obj );
01367 }
01368
01369 void KonqIconViewWidget::copySelection()
01370 {
01371 kdDebug(1203) << " -- KonqIconViewWidget::copySelection() -- " << endl;
01372 KonqIconDrag * obj = konqDragObject( );
01373 QApplication::clipboard()->setData( obj );
01374 }
01375
01376 void KonqIconViewWidget::pasteSelection()
01377 {
01378 paste( url() );
01379 }
01380
01381 void KonqIconViewWidget::paste( const KURL &url )
01382 {
01383 KonqOperations::doPaste( this, url );
01384 }
01385
01386 KURL::List KonqIconViewWidget::selectedUrls()
01387 {
01388 KURL::List lstURLs;
01389
01390 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
01391 if ( it->isSelected() )
01392 lstURLs.append( (static_cast<KFileIVI *>( it ))->item()->url() );
01393 return lstURLs;
01394 }
01395
01396 QRect KonqIconViewWidget::iconArea() const
01397 {
01398 return m_IconRect;
01399 }
01400
01401 void KonqIconViewWidget::setIconArea(const QRect &rect)
01402 {
01403 m_IconRect = rect;
01404 }
01405
01406 int KonqIconViewWidget::lineupMode() const
01407 {
01408 return m_LineupMode;
01409 }
01410
01411 void KonqIconViewWidget::setLineupMode(int mode)
01412 {
01413 m_LineupMode = mode;
01414 }
01415
01416 bool KonqIconViewWidget::sortDirectoriesFirst() const
01417 {
01418 return m_bSortDirsFirst;
01419 }
01420
01421 void KonqIconViewWidget::setSortDirectoriesFirst( bool b )
01422 {
01423 m_bSortDirsFirst = b;
01424 }
01425
01426 void KonqIconViewWidget::contentsMouseMoveEvent( QMouseEvent *e )
01427 {
01428 if ( (d->pSoundPlayer && d->pSoundPlayer->isPlaying()) || (d->pSoundTimer && d->pSoundTimer->isActive()))
01429 {
01430
01431
01432
01433 if ( QApplication::widgetAt( QCursor::pos() ) != topLevelWidget() )
01434 {
01435 if (d->pSoundPlayer)
01436 d->pSoundPlayer->stop();
01437 d->pSoundItem = 0;
01438 if (d->pSoundTimer && d->pSoundTimer->isActive())
01439 d->pSoundTimer->stop();
01440 }
01441 }
01442 d->renameItem= false;
01443 QIconView::contentsMouseMoveEvent( e );
01444 }
01445
01446 void KonqIconViewWidget::contentsDropEvent( QDropEvent * ev )
01447 {
01448 QIconViewItem *i = findItem( ev->pos() );
01449
01450
01451 if ( !i && (ev->action() == QDropEvent::Copy || ev->action() == QDropEvent::Link)
01452 && ev->source() && ev->source() == viewport())
01453 {
01454
01455 bool bMovable = itemsMovable();
01456 setItemsMovable(false);
01457 KIconView::contentsDropEvent( ev );
01458 setItemsMovable(bMovable);
01459
01460 QValueList<QIconDragItem> lst;
01461 slotDropped(ev, lst);
01462 }
01463 else
01464 {
01465 KIconView::contentsDropEvent( ev );
01466 emit dropped();
01467 }
01468
01469
01470
01471
01472
01473
01474
01475
01476 emit dragFinished();
01477 }
01478
01479 void KonqIconViewWidget::doubleClickTimeout()
01480 {
01481 d->renameItem= true;
01482 mousePressChangeValue();
01483 if ( d->releaseMouseEvent )
01484 {
01485 QMouseEvent e( QEvent::MouseButtonPress,d->mousePos , 1, d->mouseState);
01486 QIconViewItem* item = findItem( e.pos() );
01487 KURL url;
01488 if ( item )
01489 {
01490 url= ( static_cast<KFileIVI *>( item ) )->item()->url();
01491 bool brenameTrash =false;
01492 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath())))
01493 brenameTrash = true;
01494
01495 if ( url.isLocalFile() && !brenameTrash && d->renameItem && m_pSettings->renameIconDirectly() && e.button() == LeftButton && item->textRect( false ).contains(e.pos()))
01496 {
01497 if( d->pActivateDoubleClick->isActive () )
01498 d->pActivateDoubleClick->stop();
01499 item->rename();
01500 m_bMousePressed = false;
01501 }
01502 }
01503 }
01504 else
01505 {
01506 QMouseEvent e( QEvent::MouseMove,d->mousePos , 1, d->mouseState);
01507 KIconView::contentsMousePressEvent( &e );
01508 }
01509 if( d->pActivateDoubleClick->isActive() )
01510 d->pActivateDoubleClick->stop();
01511
01512 d->releaseMouseEvent = false;
01513 d->renameItem= false;
01514 }
01515
01516 void KonqIconViewWidget::wheelEvent(QWheelEvent* e)
01517 {
01518 if (e->state() == ControlButton)
01519 {
01520 if (e->delta() >= 0)
01521 {
01522 emit incIconSize();
01523 }
01524 else
01525 {
01526 emit decIconSize();
01527 }
01528 e->accept();
01529 return;
01530 }
01531
01532 KIconView::wheelEvent(e);
01533 }
01534
01535 void KonqIconViewWidget::mousePressChangeValue()
01536 {
01537
01538 m_bMousePressed = true;
01539 if (d->pSoundPlayer)
01540 d->pSoundPlayer->stop();
01541 d->bSoundItemClicked = true;
01542 d->firstClick = false;
01543 }
01544
01545 void KonqIconViewWidget::contentsMousePressEvent( QMouseEvent *e )
01546 {
01547 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ())
01548 d->pActivateDoubleClick->stop();
01549 QIconViewItem* item = findItem( e->pos() );
01550 m_mousePos = e->pos();
01551 KURL url;
01552 if ( item )
01553 {
01554 url = ( static_cast<KFileIVI *>( item ) )->item()->url();
01555 bool brenameTrash =false;
01556 if ( url.isLocalFile() && (url.directory(false) == KGlobalSettings::trashPath() || url.path(1).startsWith(KGlobalSettings::trashPath())))
01557 brenameTrash = true;
01558 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))
01559 {
01560 d->firstClick = true;
01561 d->mousePos = e->pos();
01562 d->mouseState = e->state();
01563 if (!d->pActivateDoubleClick)
01564 {
01565 d->pActivateDoubleClick = new QTimer(this);
01566 connect(d->pActivateDoubleClick, SIGNAL(timeout()), this, SLOT(doubleClickTimeout()));
01567 }
01568 if( d->pActivateDoubleClick->isActive () )
01569 d->pActivateDoubleClick->stop();
01570 else
01571 d->pActivateDoubleClick->start(QApplication::doubleClickInterval());
01572 d->releaseMouseEvent = false;
01573 return;
01574 }
01575 else
01576 d->renameItem= false;
01577 }
01578 else
01579 d->renameItem= false;
01580 mousePressChangeValue();
01581 if(d->pActivateDoubleClick && d->pActivateDoubleClick->isActive())
01582 d->pActivateDoubleClick->stop();
01583 KIconView::contentsMousePressEvent( e );
01584
01585 }
01586
01587 void KonqIconViewWidget::contentsMouseReleaseEvent( QMouseEvent *e )
01588 {
01589 KIconView::contentsMouseReleaseEvent( e );
01590 if(d->releaseMouseEvent && d->pActivateDoubleClick && d->pActivateDoubleClick->isActive ())
01591 d->pActivateDoubleClick->stop();
01592 slotSelectionChanged();
01593 d->releaseMouseEvent = true;
01594 m_bMousePressed = false;
01595 }
01596
01597 void KonqIconViewWidget::slotSaveIconPositions()
01598 {
01599
01600
01601
01602
01603
01604
01605
01606 if ( m_dotDirectoryPath.isEmpty() )
01607 return;
01608 if ( !m_bDesktop )
01609 return;
01610 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions" << endl;
01611 KSimpleConfig dotDirectory( m_dotDirectoryPath );
01612 QIconViewItem *it = firstItem();
01613 if ( !it )
01614 return;
01615 while ( it )
01616 {
01617 KFileIVI *ivi = static_cast<KFileIVI *>( it );
01618 KFileItem *item = ivi->item();
01619
01620 dotDirectory.setGroup( QString( m_iconPositionGroupPrefix ).append( item->url().fileName() ) );
01621 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions " << item->url().fileName() << " " << it->x() << " " << it->y() << endl;
01622 dotDirectory.writeEntry( QString( "X %1" ).arg( width() ), it->x() );
01623 dotDirectory.writeEntry( QString( "Y %1" ).arg( height() ), it->y() );
01624 dotDirectory.writeEntry( "Exists", true );
01625
01626 it = it->nextItem();
01627 }
01628
01629 QStringList groups = dotDirectory.groupList();
01630 QStringList::ConstIterator gIt = groups.begin();
01631 QStringList::ConstIterator gEnd = groups.end();
01632 for (; gIt != gEnd; ++gIt )
01633 if ( (*gIt).left( m_iconPositionGroupPrefix.length() ) == m_iconPositionGroupPrefix )
01634 {
01635 dotDirectory.setGroup( *gIt );
01636 if ( dotDirectory.hasKey( "Exists" ) )
01637 dotDirectory.deleteEntry( "Exists", false );
01638 else
01639 {
01640 kdDebug(1214) << "KonqIconViewWidget::slotSaveIconPositions deleting group " << *gIt << endl;
01641 dotDirectory.deleteGroup( *gIt );
01642 }
01643 }
01644
01645 dotDirectory.sync();
01646
01647
01648
01649
01650
01651
01652
01653 }
01654
01655
01656
01657
01658 void KonqIconViewWidget::insertInGrid(QIconViewItem *item)
01659 {
01660 if (0L == item)
01661 return;
01662
01663 if (!m_IconRect.isValid())
01664 {
01665 QIconView::insertInGrid(item);
01666 return;
01667 }
01668
01669 QRegion r(m_IconRect);
01670 QIconViewItem *i = firstItem();
01671 int y = -1;
01672 for (; i; i = i->nextItem() )
01673 {
01674 r = r.subtract(i->rect());
01675 y = QMAX(y, i->y() + i->height());
01676 }
01677
01678 QMemArray<QRect> rects = r.rects();
01679 QMemArray<QRect>::Iterator it = rects.begin();
01680 bool foundPlace = FALSE;
01681 for (; it != rects.end(); ++it)
01682 {
01683 QRect rect = *it;
01684 if (rect.width() >= item->width() && rect.height() >= item->height())
01685 {
01686 int sx = 0, sy = 0;
01687 if (rect.width() >= item->width() + spacing())
01688 sx = spacing();
01689 if (rect.height() >= item->height() + spacing())
01690 sy = spacing();
01691 item->move(rect.x() + sx, rect.y() + sy);
01692 foundPlace = true;
01693 break;
01694 }
01695 }
01696
01697 if (!foundPlace)
01698 item->move(m_IconRect.topLeft());
01699
01700
01701 return;
01702 }
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732 void KonqIconViewWidget::lineupIcons()
01733 {
01734 if ( !firstItem() ) {
01735 kdDebug(1203) << "No icons at all ?\n";
01736 return;
01737 }
01738
01739
01740 QValueList<QIconViewItem*> items;
01741 for ( QIconViewItem* item = firstItem(); item; item = item->nextItem() )
01742 items.append(item);
01743
01744 int iconSize = m_size ? m_size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01745
01746
01747 int x0, y0, dx, dy, nx, ny;
01748 gridValues( &x0, &y0, &dx, &dy, &nx, &ny );
01749 typedef QValueList<QIconViewItem*> Bin;
01750 Bin* bins[nx][ny];
01751 int i;
01752 int j;
01753 for ( i = 0; i < nx ; i++ ) {
01754 for ( j = 0; j < ny; j++ )
01755 bins[i][j] = 0L;
01756 }
01757
01758
01759 int textHeight = QMIN( iconTextHeight(), 2 ) * fontMetrics().height();
01760 QValueList<QIconViewItem*>::Iterator it;
01761 for ( it = items.begin(); it != items.end(); it++ ) {
01762 QIconViewItem* item = *it;
01763 int x = item->x() + item->width() / 2 - x0;
01764 int y = item->pixmapRect( false ).bottom() - iconSize / 2
01765 - ( dy - ( iconSize + textHeight ) ) / 2 - y0;
01766 int posX = QMIN( nx-1, QMAX( 0, x / dx ) );
01767 int posY = QMIN( ny-1, QMAX( 0, y / dy ) );
01768
01769 if ( !bins[posX][posY] )
01770 bins[posX][posY] = new Bin;
01771 bins[posX][posY]->prepend( item );
01772 }
01773
01774
01775 int n, k;
01776 const int infinity = 10000;
01777 int nmoves = 1;
01778 for ( n = 0; n < 30 && nmoves > 0; n++ ) {
01779 nmoves = 0;
01780 for ( i = 0; i < nx; i++ ) {
01781 for ( j = 0; j < ny; j++ ) {
01782 if ( !bins[i][j] || ( bins[i][j]->count() <= 1 ) )
01783 continue;
01784
01785
01786 int tf = 0, bf = 0, lf = 0, rf = 0;
01787 for ( k = j-1; k >= 0 && bins[i][k] && bins[i][k]->count(); k-- )
01788 tf += bins[i][k]->count();
01789 if ( k == -1 )
01790 tf += infinity;
01791
01792 for ( k = j+1; k < ny && bins[i][k] && bins[i][k]->count(); k++ )
01793 bf += bins[i][k]->count();
01794 if ( k == ny )
01795 bf += infinity;
01796
01797 for ( k = i-1; k >= 0 && bins[k][j] && bins[k][j]->count(); k-- )
01798 lf += bins[k][j]->count();
01799 if ( k == -1 )
01800 lf += infinity;
01801
01802 for ( k = i+1; k < nx && bins[k][j] && bins[k][j]->count(); k++ )
01803 rf += bins[k][j]->count();
01804 if ( k == nx )
01805 rf += infinity;
01806
01807
01808 if ( tf >= infinity && bf >= infinity &&
01809 lf >= infinity && rf >= infinity )
01810 continue;
01811
01812
01813 if ( m_LineupMode == LineupHorizontal ) {
01814 tf += infinity;
01815 bf += infinity;
01816 }
01817 else if ( m_LineupMode == LineupVertical ) {
01818 lf += infinity;
01819 rf += infinity;
01820 }
01821
01822
01823 QIconViewItem* movedItem;
01824 Bin* items = bins[i][j];
01825
01826 int mini = QMIN( QMIN( tf, bf ), QMIN( lf, rf ) );
01827 if ( tf == mini ) {
01828
01829 Bin::iterator it = items->begin();
01830 movedItem = *it;
01831 for ( ++it; it != items->end(); ++it ) {
01832 if ( (*it)->y() < movedItem->y() )
01833 movedItem = *it;
01834 }
01835 items->remove( movedItem );
01836 if ( !bins[i][j-1] )
01837 bins[i][j-1] = new Bin;
01838 bins[i][j-1]->prepend( movedItem );
01839 }
01840 else if ( bf ==mini ) {
01841
01842 Bin::iterator it = items->begin();
01843 movedItem = *it;
01844 for ( ++it; it != items->end(); ++it ) {
01845 if ( (*it)->y() > movedItem->y() )
01846 movedItem = *it;
01847 }
01848 items->remove( movedItem );
01849 if ( !bins[i][j+1] )
01850 bins[i][j+1] = new Bin;
01851 bins[i][j+1]->prepend( movedItem );
01852 }
01853 else if ( lf == mini )
01854 {
01855
01856 Bin::iterator it = items->begin();
01857 movedItem = *it;
01858 for ( ++it; it != items->end(); ++it ) {
01859 if ( (*it)->x() < movedItem->x() )
01860 movedItem = *it;
01861 }
01862 items->remove( movedItem );
01863 if ( !bins[i-1][j] )
01864 bins[i-1][j] = new Bin;
01865 bins[i-1][j]->prepend( movedItem );
01866 }
01867 else {
01868
01869 Bin::iterator it = items->begin();
01870 movedItem = *it;
01871 for ( ++it; it != items->end(); ++it ) {
01872 if ( (*it)->x() > movedItem->x() )
01873 movedItem = *it;
01874 }
01875 items->remove( movedItem );
01876 if ( !bins[i+1][j] )
01877 bins[i+1][j] = new Bin;
01878 bins[i+1][j]->prepend( movedItem );
01879 }
01880 nmoves++;
01881 }
01882 }
01883 }
01884
01885
01886 QRegion repaintRegion;
01887 QValueList<QIconViewItem*> movedItems;
01888
01889 for ( i = 0; i < nx; i++ ) {
01890 for ( j = 0; j < ny; j++ ) {
01891 Bin* bin = bins[i][j];
01892 if ( !bin )
01893 continue;
01894 if ( !bin->isEmpty() ) {
01895 QIconViewItem* item = bin->first();
01896 int newX = x0 + i*dx + ( dx - item->width() ) / 2;
01897 int newY = y0 + j*dy + dy - ( item->pixmapRect().bottom() + textHeight + 2 );
01898 if ( item->x() != newX || item->y() != newY ) {
01899 QRect oldRect = item->rect();
01900 movedItems.prepend( item );
01901 item->move( newX, newY );
01902 if ( item->rect() != oldRect )
01903 repaintRegion = repaintRegion.unite( oldRect );
01904 }
01905 }
01906 delete bin;
01907 bins[i][j] = 0L;
01908 }
01909 }
01910
01911
01912 int itemWidth = dx - 2 * spacing();
01913 if ( maxItemWidth() != itemWidth ) {
01914 setMaxItemWidth( itemWidth );
01915 setFont( font() );
01916 updateContents();
01917 }
01918 else {
01919
01920 QMemArray<QRect> rects = repaintRegion.rects();
01921 for ( uint l = 0; l < rects.count(); l++ ) {
01922 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << ","
01923 << rects[l].y() << ")\n";
01924 repaintContents( rects[l], false );
01925 }
01926
01927 while ( !movedItems.isEmpty() ) {
01928 repaintItem( movedItems.first() );
01929 movedItems.remove( movedItems.first() );
01930 }
01931 }
01932 }
01933
01934 void KonqIconViewWidget::lineupIcons( QIconView::Arrangement arrangement )
01935 {
01936 int x0, y0, dx, dy, nxmax, nymax;
01937 gridValues( &x0, &y0, &dx, &dy, &nxmax, &nymax );
01938 int textHeight = QMIN( iconTextHeight(), 2 ) * fontMetrics().height();
01939
01940 QRegion repaintRegion;
01941 QValueList<QIconViewItem*> movedItems;
01942 int nx = 0, ny = 0;
01943
01944 QIconViewItem* item;
01945 for ( item = firstItem(); item; item = item->nextItem() ) {
01946 int newX = x0 + nx * dx + ( dx - item->width() ) / 2;
01947 int newY = y0 + ny * dy + dy - ( item->pixmapRect().bottom() + textHeight + 2 );
01948 if ( item->x() != newX || item->y() != newY ) {
01949 QRect oldRect = item->rect();
01950 movedItems.prepend( item );
01951 item->move( newX, newY );
01952 if ( item->rect() != oldRect )
01953 repaintRegion = repaintRegion.unite( oldRect );
01954 }
01955 if ( arrangement == QIconView::LeftToRight ) {
01956 nx++;
01957 if ( nx >= nxmax ) {
01958 ny++;
01959 nx = 0;
01960 }
01961 }
01962 else {
01963 ny++;
01964 if ( ny >= nymax ) {
01965 nx++;
01966 ny = 0;
01967 }
01968 }
01969 }
01970
01971
01972 QMemArray<QRect> rects = repaintRegion.rects();
01973 for ( uint l = 0; l < rects.count(); l++ ) {
01974 kdDebug( 1203 ) << "Repainting (" << rects[l].x() << ","
01975 << rects[l].y() << ")\n";
01976 repaintContents( rects[l], false );
01977 }
01978
01979 while ( !movedItems.isEmpty() ) {
01980 repaintItem( movedItems.first() );
01981 movedItems.remove( movedItems.first() );
01982 }
01983 }
01984
01985 int KonqIconViewWidget::largestPreviewIconSize( int size ) const
01986 {
01987 int iconSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
01988
01989 if (iconSize < 28)
01990 return 48;
01991 if (iconSize < 40)
01992 return 64;
01993 if (iconSize < 60)
01994 return 96;
01995 if (iconSize < 120)
01996 return 128;
01997
01998 return 192;
01999 }
02000
02001 int KonqIconViewWidget::previewIconSize( int size ) const
02002 {
02003 int iconSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop );
02004
02005 if (!d->bBoostPreview)
02006 return iconSize;
02007
02008 return largestPreviewIconSize( iconSize );
02009 }
02010
02011 void KonqIconViewWidget::visualActivate(QIconViewItem * item)
02012 {
02013
02014 QRect irect = item->rect();
02015
02016
02017 QRect rect = item->pixmapRect();
02018
02019
02020
02021 rect.moveBy(irect.x(), irect.y());
02022
02023
02024 rect.moveBy( -contentsX(), -contentsY() );
02025
02026 KIconEffect::visualActivate(viewport(), rect);
02027 }
02028
02029 void KonqIconViewWidget::backgroundPixmapChange( const QPixmap & )
02030 {
02031 viewport()->update();
02032 }
02033
02034 void KonqIconViewWidget::setPreviewSettings( const QStringList& settings )
02035 {
02036 d->previewSettings = settings;
02037 updatePreviewMimeTypes();
02038
02039 int size = m_size;
02040 m_size = -1;
02041 setIcons( size );
02042 }
02043
02044 const QStringList& KonqIconViewWidget::previewSettings()
02045 {
02046 return d->previewSettings;
02047 }
02048
02049 void KonqIconViewWidget::setNewURL( const QString& url )
02050 {
02051 KURL u;
02052 if ( url.startsWith( "/" ) )
02053 u.setPath( url );
02054 else
02055 u = url;
02056 setURL( u );
02057 }
02058
02059 void KonqIconViewWidget::setCaseInsensitiveSort( bool b )
02060 {
02061 d->bCaseInsensitive = b;
02062 }
02063
02064 bool KonqIconViewWidget::caseInsensitiveSort() const
02065 {
02066 return d->bCaseInsensitive;
02067 }
02068
02069 bool KonqIconViewWidget::canPreview( KFileItem* item )
02070 {
02071 if ( !KGlobalSettings::showFilePreview( url() ) )
02072 return false;
02073
02074 if ( d->pPreviewMimeTypes == 0L )
02075 updatePreviewMimeTypes();
02076
02077 return mimeTypeMatch( item->mimetype(), *( d->pPreviewMimeTypes ) );
02078 }
02079
02080 void KonqIconViewWidget::updatePreviewMimeTypes()
02081 {
02082 if ( d->pPreviewMimeTypes == 0L )
02083 d->pPreviewMimeTypes = new QStringList;
02084 else
02085 d->pPreviewMimeTypes->clear();
02086
02087
02088 KTrader::OfferList plugins = KTrader::self()->query("ThumbCreator");
02089 KTrader::OfferList::ConstIterator it;
02090
02091 for ( it = plugins.begin(); it != plugins.end(); ++it ) {
02092 if ( d->previewSettings.contains((*it)->desktopEntryName()) ) {
02093 QStringList mimeTypes = (*it)->property("MimeTypes").toStringList();
02094 for (QStringList::ConstIterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt)
02095 d->pPreviewMimeTypes->append(*mt);
02096 }
02097 }
02098 }
02099
02100 #include "konq_iconviewwidget.moc"
02101
02102