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