kfileiconview.cpp
00001 // -*- c++ -*- 00002 /* This file is part of the KDE libraries 00003 Copyright (C) 1997 Stephan Kulow <coolo@kde.org> 00004 2000,2001,2002 Carsten Pfeiffer <pfeiffer@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 #include <tqt.h> 00022 00023 #include <tqfontmetrics.h> 00024 #include <tqkeycode.h> 00025 #include <tqlabel.h> 00026 #include <tqpainter.h> 00027 #include <tqpixmap.h> 00028 #include <tqregexp.h> 00029 #include <tqtimer.h> 00030 #include <tqtooltip.h> 00031 00032 #include <kaction.h> 00033 #include <kapplication.h> 00034 #include <klocale.h> 00035 #include <kfileitem.h> 00036 #include <kiconeffect.h> 00037 #include <kglobalsettings.h> 00038 #include <kurldrag.h> 00039 #include <kio/previewjob.h> 00040 00041 #include "kfileiconview.h" 00042 #include "config-kfile.h" 00043 00044 #define DEFAULT_PREVIEW_SIZE 60 00045 #define DEFAULT_SHOW_PREVIEWS false 00046 #define DEFAULT_VIEW_MODE "SmallColumns" 00047 00048 KFileIconViewItem::~KFileIconViewItem() 00049 { 00050 fileInfo()->removeExtraData( iconView() ); 00051 } 00052 00053 class KFileIconView::KFileIconViewPrivate 00054 { 00055 public: 00056 KFileIconViewPrivate( KFileIconView *parent ) { 00057 previewIconSize = 60; 00058 job = 0; 00059 dropItem = 0; 00060 00061 noArrangement = false; 00062 ignoreMaximumSize = false; 00063 smallColumns = new KRadioAction( i18n("Small Icons"), 0, TQT_TQOBJECT(parent), 00064 TQT_SLOT( slotSmallColumns() ), 00065 parent->actionCollection(), 00066 "small columns" ); 00067 00068 largeRows = new KRadioAction( i18n("Large Icons"), 0, TQT_TQOBJECT(parent), 00069 TQT_SLOT( slotLargeRows() ), 00070 parent->actionCollection(), 00071 "large rows" ); 00072 00073 smallColumns->setExclusiveGroup(TQString::fromLatin1("IconView mode")); 00074 largeRows->setExclusiveGroup(TQString::fromLatin1("IconView mode")); 00075 00076 previews = new KToggleAction( i18n("Thumbnail Previews"), 0, 00077 parent->actionCollection(), 00078 "show previews" ); 00079 zoomIn = KStdAction::zoomIn( TQT_TQOBJECT(parent), TQT_SLOT( zoomIn() ), 00080 parent->actionCollection(), "zoomIn" ); 00081 zoomOut = KStdAction::zoomOut( TQT_TQOBJECT(parent), TQT_SLOT( zoomOut() ), 00082 parent->actionCollection(), "zoomOut" ); 00083 00084 previews->setGroup("previews"); 00085 zoomIn->setGroup("previews"); 00086 zoomOut->setGroup("previews"); 00087 00088 connect( previews, TQT_SIGNAL( toggled( bool )), 00089 parent, TQT_SLOT( slotPreviewsToggled( bool ))); 00090 00091 connect( &previewTimer, TQT_SIGNAL( timeout() ), 00092 parent, TQT_SLOT( showPreviews() )); 00093 connect( &autoOpenTimer, TQT_SIGNAL( timeout() ), 00094 parent, TQT_SLOT( slotAutoOpen() )); 00095 } 00096 00097 ~KFileIconViewPrivate() { 00098 if ( job ) 00099 job->kill(); 00100 } 00101 00102 KRadioAction *smallColumns, *largeRows; 00103 KAction *zoomIn, *zoomOut; 00104 KToggleAction *previews; 00105 KIO::PreviewJob *job; 00106 KFileIconViewItem *dropItem; 00107 TQTimer previewTimer; 00108 TQTimer autoOpenTimer; 00109 TQStringList previewMimeTypes; 00110 int previewIconSize; 00111 bool noArrangement :1; 00112 bool ignoreMaximumSize :1; 00113 }; 00114 00115 KFileIconView::KFileIconView(TQWidget *parent, const char *name) 00116 : KIconView(parent, name), KFileView() 00117 { 00118 d = new KFileIconViewPrivate( this ); 00119 00120 setViewName( i18n("Icon View") ); 00121 00122 toolTip = 0; 00123 setResizeMode( Adjust ); 00124 setMaxItemWidth( 300 ); 00125 setWordWrapIconText( false ); 00126 setArrangement( TopToBottom ); 00127 setAutoArrange( true ); 00128 setItemsMovable( false ); 00129 setMode( KIconView::Select ); 00130 KIconView::setSorting( true ); 00131 // as long as TQIconView only shows tooltips when the cursor is over the 00132 // icon (and not the text), we have to create our own tooltips 00133 setShowToolTips( false ); 00134 slotSmallColumns(); 00135 d->smallColumns->setChecked( true ); 00136 00137 connect( this, TQT_SIGNAL( returnPressed(TQIconViewItem *) ), 00138 TQT_SLOT( slotActivate( TQIconViewItem *) ) ); 00139 00140 // we want single click _and_ double click (as convenience) 00141 connect( this, TQT_SIGNAL( clicked(TQIconViewItem *, const TQPoint&) ), 00142 TQT_SLOT( selected( TQIconViewItem *) ) ); 00143 connect( this, TQT_SIGNAL( doubleClicked(TQIconViewItem *, const TQPoint&) ), 00144 TQT_SLOT( slotActivate( TQIconViewItem *) ) ); 00145 00146 connect( this, TQT_SIGNAL( onItem( TQIconViewItem * ) ), 00147 TQT_SLOT( showToolTip( TQIconViewItem * ) ) ); 00148 connect( this, TQT_SIGNAL( onViewport() ), 00149 TQT_SLOT( removeToolTip() ) ); 00150 connect( this, TQT_SIGNAL( contextMenuRequested(TQIconViewItem*,const TQPoint&)), 00151 TQT_SLOT( slotActivateMenu( TQIconViewItem*, const TQPoint& ) ) ); 00152 00153 KFile::SelectionMode sm = KFileView::selectionMode(); 00154 switch ( sm ) { 00155 case KFile::Multi: 00156 TQIconView::setSelectionMode( TQIconView::Multi ); 00157 break; 00158 case KFile::Extended: 00159 TQIconView::setSelectionMode( TQIconView::Extended ); 00160 break; 00161 case KFile::NoSelection: 00162 TQIconView::setSelectionMode( TQIconView::NoSelection ); 00163 break; 00164 default: // fall through 00165 case KFile::Single: 00166 TQIconView::setSelectionMode( TQIconView::Single ); 00167 break; 00168 } 00169 00170 if ( sm == KFile::Multi || sm == KFile::Extended ) 00171 connect( this, TQT_SIGNAL( selectionChanged() ), 00172 TQT_SLOT( slotSelectionChanged() )); 00173 else 00174 connect( this, TQT_SIGNAL( selectionChanged( TQIconViewItem * )), 00175 TQT_SLOT( highlighted( TQIconViewItem * ))); 00176 00177 viewport()->installEventFilter( this ); 00178 00179 // for mimetype resolving 00180 m_resolver = new KMimeTypeResolver<KFileIconViewItem,KFileIconView>(this); 00181 } 00182 00183 KFileIconView::~KFileIconView() 00184 { 00185 delete m_resolver; 00186 removeToolTip(); 00187 delete d; 00188 } 00189 00190 void KFileIconView::readConfig( KConfig *kc, const TQString& group ) 00191 { 00192 TQString gr = group.isEmpty() ? TQString("KFileIconView") : group; 00193 KConfigGroupSaver cs( kc, gr ); 00194 TQString small = TQString::fromLatin1("SmallColumns"); 00195 d->previewIconSize = kc->readNumEntry( "Preview Size", DEFAULT_PREVIEW_SIZE ); 00196 d->previews->setChecked( kc->readBoolEntry( "ShowPreviews", DEFAULT_SHOW_PREVIEWS ) ); 00197 00198 if ( kc->readEntry("ViewMode", DEFAULT_VIEW_MODE ) == small ) { 00199 d->smallColumns->setChecked( true ); 00200 slotSmallColumns(); 00201 } 00202 else { 00203 d->largeRows->setChecked( true ); 00204 slotLargeRows(); 00205 } 00206 00207 if ( d->previews->isChecked() ) 00208 showPreviews(); 00209 } 00210 00211 void KFileIconView::writeConfig( KConfig *kc, const TQString& group ) 00212 { 00213 TQString gr = group.isEmpty() ? TQString("KFileIconView") : group; 00214 KConfigGroupSaver cs( kc, gr ); 00215 00216 TQString viewMode = d->smallColumns->isChecked() ? 00217 TQString::fromLatin1("SmallColumns") : 00218 TQString::fromLatin1("LargeRows"); 00219 if(!kc->hasDefault( "ViewMode" ) && viewMode == DEFAULT_VIEW_MODE ) 00220 kc->revertToDefault( "ViewMode" ); 00221 else 00222 kc->writeEntry( "ViewMode", viewMode ); 00223 00224 int previewsIconSize = d->previewIconSize; 00225 if(!kc->hasDefault( "Preview Size" ) && previewsIconSize == DEFAULT_PREVIEW_SIZE ) 00226 kc->revertToDefault( "Preview Size" ); 00227 else 00228 kc->writeEntry( "Preview Size", previewsIconSize ); 00229 00230 bool showPreviews = d->previews->isChecked(); 00231 if(!kc->hasDefault( "ShowPreviews" ) && showPreviews == DEFAULT_SHOW_PREVIEWS ) 00232 kc->revertToDefault( "ShowPreviews" ); 00233 else 00234 kc->writeEntry( "ShowPreviews", showPreviews ); 00235 } 00236 00237 void KFileIconView::removeToolTip() 00238 { 00239 delete toolTip; 00240 toolTip = 0; 00241 } 00242 00243 void KFileIconView::showToolTip( TQIconViewItem *item ) 00244 { 00245 delete toolTip; 00246 toolTip = 0; 00247 00248 if ( !item ) 00249 return; 00250 00251 int w = maxItemWidth() - ( itemTextPos() == TQIconView::Bottom ? 0 : 00252 item->pixmapRect().width() ) - 4; 00253 if ( fontMetrics().width( item->text() ) >= w ) { 00254 toolTip = new TQLabel( TQString::fromLatin1(" %1 ").arg(item->text()), 0, 00255 "myToolTip", 00256 (WFlags)(WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM) ); 00257 toolTip->setFrameStyle( TQFrame::Plain | TQFrame::Box ); 00258 toolTip->setLineWidth( 1 ); 00259 toolTip->setAlignment( AlignLeft | AlignTop ); 00260 toolTip->move( TQCursor::pos() + TQPoint( 14, 14 ) ); 00261 toolTip->adjustSize(); 00262 TQRect screen = TQApplication::desktop()->screenGeometry( 00263 TQApplication::desktop()->screenNumber(TQCursor::pos())); 00264 if (toolTip->x()+toolTip->width() > screen.right()) { 00265 toolTip->move(toolTip->x()+screen.right()-toolTip->x()-toolTip->width(), toolTip->y()); 00266 } 00267 if (toolTip->y()+toolTip->height() > screen.bottom()) { 00268 toolTip->move(toolTip->x(), screen.bottom()-toolTip->y()-toolTip->height()+toolTip->y()); 00269 } 00270 toolTip->setFont( TQToolTip::font() ); 00271 toolTip->setPalette( TQToolTip::palette(), true ); 00272 toolTip->show(); 00273 } 00274 } 00275 00276 void KFileIconView::slotActivateMenu( TQIconViewItem* item, const TQPoint& pos ) 00277 { 00278 if ( !item ) { 00279 sig->activateMenu( 0, pos ); 00280 return; 00281 } 00282 KFileIconViewItem *i = (KFileIconViewItem*) item; 00283 sig->activateMenu( i->fileInfo(), pos ); 00284 } 00285 00286 void KFileIconView::hideEvent( TQHideEvent *e ) 00287 { 00288 removeToolTip(); 00289 KIconView::hideEvent( e ); 00290 } 00291 00292 void KFileIconView::keyPressEvent( TQKeyEvent *e ) 00293 { 00294 KIconView::keyPressEvent( e ); 00295 00296 // ignore Ctrl-Return so that the dialog can catch it. 00297 if ( (e->state() & ControlButton) && 00298 (e->key() == Key_Return || e->key() == Key_Enter) ) 00299 e->ignore(); 00300 } 00301 00302 void KFileIconView::setSelected( const KFileItem *info, bool enable ) 00303 { 00304 KFileIconViewItem *item = viewItem( info ); 00305 if ( item ) 00306 KIconView::setSelected( item, enable, true ); 00307 } 00308 00309 void KFileIconView::selectAll() 00310 { 00311 if (KFileView::selectionMode() == KFile::NoSelection || 00312 KFileView::selectionMode() == KFile::Single) 00313 return; 00314 00315 KIconView::selectAll( true ); 00316 } 00317 00318 void KFileIconView::clearSelection() 00319 { 00320 KIconView::clearSelection(); 00321 } 00322 00323 void KFileIconView::invertSelection() 00324 { 00325 KIconView::invertSelection(); 00326 } 00327 00328 void KFileIconView::clearView() 00329 { 00330 m_resolver->m_lstPendingMimeIconItems.clear(); 00331 00332 KIconView::clear(); 00333 stopPreview(); 00334 } 00335 00336 void KFileIconView::insertItem( KFileItem *i ) 00337 { 00338 KFileView::insertItem( i ); 00339 00340 TQIconView* qview = static_cast<TQIconView*>( this ); 00341 // Since creating and initializing an item leads to a repaint, 00342 // we disable updates on the IconView for a while. 00343 qview->setUpdatesEnabled( false ); 00344 KFileIconViewItem *item = new KFileIconViewItem( qview, i ); 00345 initItem( item, i, true ); 00346 qview->setUpdatesEnabled( true ); 00347 00348 if ( !i->isMimeTypeKnown() ) 00349 m_resolver->m_lstPendingMimeIconItems.append( item ); 00350 00351 i->setExtraData( this, item ); 00352 } 00353 00354 void KFileIconView::slotActivate( TQIconViewItem *item ) 00355 { 00356 if ( !item ) 00357 return; 00358 const KFileItem *fi = ( (KFileIconViewItem*)item )->fileInfo(); 00359 if ( fi ) 00360 sig->activate( fi ); 00361 } 00362 00363 void KFileIconView::selected( TQIconViewItem *item ) 00364 { 00365 if ( !item || (KApplication::keyboardMouseState() & (ShiftButton | ControlButton)) != 0 ) 00366 return; 00367 00368 if ( KGlobalSettings::singleClick() ) { 00369 const KFileItem *fi = ( (KFileIconViewItem*)item )->fileInfo(); 00370 if ( fi && (fi->isDir() || !onlyDoubleClickSelectsFiles()) ) 00371 sig->activate( fi ); 00372 } 00373 } 00374 00375 void KFileIconView::setCurrentItem( const KFileItem *item ) 00376 { 00377 KFileIconViewItem *it = viewItem( item ); 00378 if ( it ) 00379 KIconView::setCurrentItem( it ); 00380 } 00381 00382 KFileItem * KFileIconView::currentFileItem() const 00383 { 00384 KFileIconViewItem *current = static_cast<KFileIconViewItem*>( currentItem() ); 00385 if ( current ) 00386 return current->fileInfo(); 00387 00388 return 0L; 00389 } 00390 00391 void KFileIconView::highlighted( TQIconViewItem *item ) 00392 { 00393 if ( !item ) 00394 return; 00395 const KFileItem *fi = ( (KFileIconViewItem*)item )->fileInfo(); 00396 if ( fi ) 00397 sig->highlightFile( fi ); 00398 } 00399 00400 void KFileIconView::setSelectionMode( KFile::SelectionMode sm ) 00401 { 00402 disconnect( TQT_SIGNAL( selectionChanged() ), this ); 00403 disconnect( TQT_SIGNAL( selectionChanged( TQIconViewItem * )), this ); 00404 00405 KFileView::setSelectionMode( sm ); 00406 switch ( KFileView::selectionMode() ) { 00407 case KFile::Multi: 00408 TQIconView::setSelectionMode( TQIconView::Multi ); 00409 break; 00410 case KFile::Extended: 00411 TQIconView::setSelectionMode( TQIconView::Extended ); 00412 break; 00413 case KFile::NoSelection: 00414 TQIconView::setSelectionMode( TQIconView::NoSelection ); 00415 break; 00416 default: // fall through 00417 case KFile::Single: 00418 TQIconView::setSelectionMode( TQIconView::Single ); 00419 break; 00420 } 00421 00422 if ( sm == KFile::Multi || sm == KFile::Extended ) 00423 connect( this, TQT_SIGNAL( selectionChanged() ), 00424 TQT_SLOT( slotSelectionChanged() )); 00425 else 00426 connect( this, TQT_SIGNAL( selectionChanged( TQIconViewItem * )), 00427 TQT_SLOT( highlighted( TQIconViewItem * ))); 00428 } 00429 00430 bool KFileIconView::isSelected( const KFileItem *i ) const 00431 { 00432 KFileIconViewItem *item = viewItem( i ); 00433 return (item && item->isSelected()); 00434 } 00435 00436 void KFileIconView::updateView( bool b ) 00437 { 00438 if ( !b ) 00439 return; // eh? 00440 00441 KFileIconViewItem *item = static_cast<KFileIconViewItem*>(TQIconView::firstItem()); 00442 if ( item ) { 00443 do { 00444 if ( d->previews->isChecked() ) { 00445 if ( canPreview( item->fileInfo() ) ) 00446 item->setPixmapSize( TQSize( d->previewIconSize, d->previewIconSize ) ); 00447 } 00448 else { 00449 // unset pixmap size (used for previews) 00450 if ( !item->pixmapSize().isNull() ) 00451 item->setPixmapSize( TQSize( 0, 0 ) ); 00452 } 00453 // recalculate item parameters but avoid an in-place repaint 00454 item->setPixmap( (item->fileInfo())->pixmap( myIconSize ), true, false ); 00455 item = static_cast<KFileIconViewItem *>(item->nextItem()); 00456 } while ( item != 0L ); 00457 } 00458 } 00459 00460 void KFileIconView::updateView( const KFileItem *i ) 00461 { 00462 KFileIconViewItem *item = viewItem( i ); 00463 if ( item ) 00464 initItem( item, i, true ); 00465 } 00466 00467 void KFileIconView::removeItem( const KFileItem *i ) 00468 { 00469 if ( !i ) 00470 return; 00471 00472 if ( d->job ) 00473 d->job->removeItem( i ); 00474 00475 KFileIconViewItem *item = viewItem( i ); 00476 m_resolver->m_lstPendingMimeIconItems.remove( item ); 00477 delete item; 00478 00479 KFileView::removeItem( i ); 00480 } 00481 00482 void KFileIconView::setIconSize( int size ) 00483 { 00484 myIconSize = size; 00485 updateIcons(); 00486 } 00487 00488 void KFileIconView::setPreviewSize( int size ) 00489 { 00490 if ( size < 30 ) 00491 size = 30; // minimum 00492 00493 d->previewIconSize = size; 00494 if ( d->previews->isChecked() ) 00495 showPreviews(); 00496 } 00497 00498 void KFileIconView::setIgnoreMaximumSize(bool ignoreSize) 00499 { 00500 d->ignoreMaximumSize = ignoreSize; 00501 } 00502 00503 void KFileIconView::updateIcons() 00504 { 00505 updateView( true ); 00506 arrangeItemsInGrid(); 00507 } 00508 00509 void KFileIconView::ensureItemVisible( const KFileItem *i ) 00510 { 00511 KFileIconViewItem *item = viewItem( i ); 00512 if ( item ) 00513 KIconView::ensureItemVisible( item ); 00514 } 00515 00516 void KFileIconView::slotSelectionChanged() 00517 { 00518 sig->highlightFile( 0L ); 00519 } 00520 00521 void KFileIconView::slotSmallColumns() 00522 { 00523 // setItemTextPos(), setArrangement(), setWordWrapIconText() and 00524 // setIconSize() all call arrangeItemsInGrid() :( Prevent this. 00525 d->noArrangement = true; // stop arrangeItemsInGrid()! 00526 00527 // Make sure to uncheck previews if selected 00528 if ( d->previews->isChecked() ) 00529 { 00530 stopPreview(); 00531 d->previews->setChecked( false ); 00532 } 00533 setGridX( -1 ); 00534 setMaxItemWidth( 300 ); 00535 setItemTextPos( Right ); 00536 setArrangement( TopToBottom ); 00537 setWordWrapIconText( false ); 00538 setSpacing( 0 ); 00539 00540 d->noArrangement = false; // now we can arrange 00541 setIconSize( KIcon::SizeSmall ); 00542 } 00543 00544 void KFileIconView::slotLargeRows() 00545 { 00546 // setItemTextPos(), setArrangement(), setWordWrapIconText() and 00547 // setIconSize() all call arrangeItemsInGrid() :( Prevent this. 00548 d->noArrangement = true; // stop arrangeItemsInGrid()! 00549 00550 setGridX( KGlobal::iconLoader()->currentSize( KIcon::Desktop ) + 50 ); 00551 setItemTextPos( Bottom ); 00552 setArrangement( LeftToRight ); 00553 setWordWrapIconText( true ); 00554 setSpacing( 5 ); // default in QIconView 00555 00556 d->noArrangement = false; // now we can arrange 00557 setIconSize( KIcon::SizeMedium ); 00558 } 00559 00560 void KFileIconView::stopPreview() 00561 { 00562 if ( d->job ) { 00563 d->job->kill(); 00564 d->job = 0L; 00565 } 00566 } 00567 00568 void KFileIconView::slotPreviewsToggled( bool on ) 00569 { 00570 if ( on ) 00571 showPreviews(); 00572 else { 00573 stopPreview(); 00574 slotLargeRows(); 00575 } 00576 } 00577 00578 void KFileIconView::showPreviews() 00579 { 00580 if ( d->previewMimeTypes.isEmpty() ) 00581 d->previewMimeTypes = KIO::PreviewJob::supportedMimeTypes(); 00582 00583 stopPreview(); 00584 d->previews->setChecked( true ); 00585 00586 if ( !d->largeRows->isChecked() ) { 00587 d->largeRows->setChecked( true ); 00588 slotLargeRows(); // also sets the icon size and updates the grid 00589 } 00590 else { 00591 updateIcons(); 00592 } 00593 00594 d->job = KIO::filePreview(*items(), d->previewIconSize,d->previewIconSize); 00595 d->job->setIgnoreMaximumSize(d->ignoreMaximumSize); 00596 00597 connect( d->job, TQT_SIGNAL( result( KIO::Job * )), 00598 this, TQT_SLOT( slotPreviewResult( KIO::Job * ))); 00599 connect( d->job, TQT_SIGNAL( gotPreview( const KFileItem*, const TQPixmap& )), 00600 TQT_SLOT( gotPreview( const KFileItem*, const TQPixmap& ) )); 00601 // connect( d->job, TQT_SIGNAL( failed( const KFileItem* )), 00602 // this, TQT_SLOT( slotFailed( const KFileItem* ) )); 00603 } 00604 00605 void KFileIconView::slotPreviewResult( KIO::Job *job ) 00606 { 00607 if ( job == d->job ) 00608 d->job = 0L; 00609 } 00610 00611 void KFileIconView::gotPreview( const KFileItem *item, const TQPixmap& pix ) 00612 { 00613 KFileIconViewItem *it = viewItem( item ); 00614 if ( it ) { 00615 if( item->overlays() & KIcon::HiddenOverlay ) 00616 { 00617 TQPixmap p( pix ); 00618 00619 KIconEffect::semiTransparent( p ); 00620 it->setPixmap( p ); 00621 } 00622 else { 00623 it->setPixmap( pix ); 00624 } 00625 } 00626 } 00627 00628 bool KFileIconView::canPreview( const KFileItem *item ) const 00629 { 00630 TQStringList::Iterator it = d->previewMimeTypes.begin(); 00631 TQRegExp r; 00632 r.setWildcard( true ); 00633 00634 for ( ; it != d->previewMimeTypes.end(); ++it ) { 00635 TQString type = *it; 00636 // the "mimetype" can be "image/*" 00637 if ( type.at( type.length() - 1 ) == '*' ) { 00638 r.setPattern( type ); 00639 if ( r.search( item->mimetype() ) != -1 ) 00640 return true; 00641 } 00642 else 00643 if ( item->mimetype() == type ) 00644 return true; 00645 } 00646 00647 return false; 00648 } 00649 00650 KFileItem * KFileIconView::firstFileItem() const 00651 { 00652 KFileIconViewItem *item = static_cast<KFileIconViewItem*>( firstItem() ); 00653 if ( item ) 00654 return item->fileInfo(); 00655 return 0L; 00656 } 00657 00658 KFileItem * KFileIconView::nextItem( const KFileItem *fileItem ) const 00659 { 00660 if ( fileItem ) { 00661 KFileIconViewItem *item = viewItem( fileItem ); 00662 if ( item && item->nextItem() ) 00663 return ((KFileIconViewItem*) item->nextItem())->fileInfo(); 00664 } 00665 return 0L; 00666 } 00667 00668 KFileItem * KFileIconView::prevItem( const KFileItem *fileItem ) const 00669 { 00670 if ( fileItem ) { 00671 KFileIconViewItem *item = viewItem( fileItem ); 00672 if ( item && item->prevItem() ) 00673 return ((KFileIconViewItem*) item->prevItem())->fileInfo(); 00674 } 00675 return 0L; 00676 } 00677 00678 void KFileIconView::setSorting( TQDir::SortSpec spec ) 00679 { 00680 KFileView::setSorting( spec ); 00681 KFileItemListIterator it( *items() ); 00682 00683 KFileItem *item; 00684 00685 if ( spec & TQDir::Time ) { 00686 for ( ; (item = it.current()); ++it ) 00687 // warning, time_t is often signed -> cast it 00688 viewItem(item)->setKey( sortingKey( (unsigned long)item->time( KIO::UDS_MODIFICATION_TIME ), item->isDir(), spec )); 00689 } 00690 00691 else if ( spec & TQDir::Size ) { 00692 for ( ; (item = it.current()); ++it ) 00693 viewItem(item)->setKey( sortingKey( item->size(), item->isDir(), 00694 spec )); 00695 } 00696 else { // Name or Unsorted 00697 for ( ; (item = it.current()); ++it ) 00698 viewItem(item)->setKey( sortingKey( item->text(), item->isDir(), 00699 spec )); 00700 } 00701 00702 KIconView::setSorting( true, !isReversed() ); 00703 sort( !isReversed() ); 00704 } 00705 00706 // 00707 // mimetype determination on demand 00708 // 00709 void KFileIconView::mimeTypeDeterminationFinished() 00710 { 00711 // anything to do? 00712 } 00713 00714 void KFileIconView::determineIcon( KFileIconViewItem *item ) 00715 { 00716 (void) item->fileInfo()->determineMimeType(); 00717 updateView( item->fileInfo() ); 00718 } 00719 00720 void KFileIconView::listingCompleted() 00721 { 00722 arrangeItemsInGrid(); 00723 00724 // TQIconView doesn't set the current item automatically, so we have to do 00725 // that. We don't want to emit selectionChanged() tho. 00726 if ( !currentItem() ) { 00727 bool block = signalsBlocked(); 00728 blockSignals( true ); 00729 TQIconViewItem *item = viewItem( firstFileItem() ); 00730 KIconView::setCurrentItem( item ); 00731 KIconView::setSelected( item, false ); 00732 blockSignals( block ); 00733 } 00734 00735 m_resolver->start( d->previews->isChecked() ? 0 : 10 ); 00736 } 00737 00738 // need to remove our tooltip, eventually 00739 bool KFileIconView::eventFilter( TQObject *o, TQEvent *e ) 00740 { 00741 if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(viewport()) || TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) ) { 00742 int type = e->type(); 00743 if ( type == TQEvent::Leave || 00744 type == TQEvent::FocusOut ) 00745 removeToolTip(); 00746 } 00747 00748 return KIconView::eventFilter( o, e ); 00749 } 00750 00752 00753 // ### workaround for Qt3 Bug 00754 void KFileIconView::showEvent( TQShowEvent *e ) 00755 { 00756 KIconView::showEvent( e ); 00757 } 00758 00759 00760 void KFileIconView::initItem( KFileIconViewItem *item, const KFileItem *i, 00761 bool updateTextAndPixmap ) 00762 { 00763 if ( d->previews->isChecked() && canPreview( i ) ) 00764 item->setPixmapSize( TQSize( d->previewIconSize, d->previewIconSize ) ); 00765 00766 if ( updateTextAndPixmap ) 00767 { 00768 // this causes a repaint of the item, which we want to avoid during 00769 // directory listing, when all items are created. We want to paint all 00770 // items at once, not every single item in that case. 00771 item->setText( i->text() , false, false ); 00772 item->setPixmap( i->pixmap( myIconSize ) ); 00773 } 00774 00775 // see also setSorting() 00776 TQDir::SortSpec spec = KFileView::sorting(); 00777 00778 if ( spec & TQDir::Time ) 00779 // warning, time_t is often signed -> cast it 00780 item->setKey( sortingKey( (unsigned long) i->time( KIO::UDS_MODIFICATION_TIME ), 00781 i->isDir(), spec )); 00782 else if ( spec & TQDir::Size ) 00783 item->setKey( sortingKey( i->size(), i->isDir(), spec )); 00784 00785 else // Name or Unsorted 00786 item->setKey( sortingKey( i->text(), i->isDir(), spec )); 00787 00788 //qDebug("** key for: %s: %s", i->text().latin1(), item->key().latin1()); 00789 00790 if ( d->previews->isChecked() ) 00791 d->previewTimer.start( 10, true ); 00792 } 00793 00794 void KFileIconView::arrangeItemsInGrid( bool update ) 00795 { 00796 if ( d->noArrangement ) 00797 return; 00798 00799 KIconView::arrangeItemsInGrid( update ); 00800 } 00801 00802 void KFileIconView::zoomIn() 00803 { 00804 setPreviewSize( d->previewIconSize + 30 ); 00805 } 00806 00807 void KFileIconView::zoomOut() 00808 { 00809 setPreviewSize( d->previewIconSize - 30 ); 00810 } 00811 00812 TQDragObject *KFileIconView::dragObject() 00813 { 00814 // create a list of the URL:s that we want to drag 00815 KURL::List urls; 00816 KFileItemListIterator it( * KFileView::selectedItems() ); 00817 for ( ; it.current(); ++it ){ 00818 urls.append( (*it)->url() ); 00819 } 00820 TQPixmap pixmap; 00821 if( urls.count() > 1 ) 00822 pixmap = DesktopIcon( "kmultiple", iconSize() ); 00823 if( pixmap.isNull() ) 00824 pixmap = currentFileItem()->pixmap( iconSize() ); 00825 00826 TQPoint hotspot; 00827 hotspot.setX( pixmap.width() / 2 ); 00828 hotspot.setY( pixmap.height() / 2 ); 00829 TQDragObject* myDragObject = new KURLDrag( urls, widget() ); 00830 myDragObject->setPixmap( pixmap, hotspot ); 00831 return myDragObject; 00832 } 00833 00834 void KFileIconView::slotAutoOpen() 00835 { 00836 d->autoOpenTimer.stop(); 00837 if( !d->dropItem ) 00838 return; 00839 00840 KFileItem *fileItem = d->dropItem->fileInfo(); 00841 if (!fileItem) 00842 return; 00843 00844 if( fileItem->isFile() ) 00845 return; 00846 00847 if ( fileItem->isDir() || fileItem->isLink()) 00848 sig->activate( fileItem ); 00849 } 00850 00851 bool KFileIconView::acceptDrag(TQDropEvent* e) const 00852 { 00853 return KURLDrag::canDecode( e ) && 00854 (e->source()!=const_cast<KFileIconView*>(this)) && 00855 ( e->action() == TQDropEvent::Copy 00856 || e->action() == TQDropEvent::Move 00857 || e->action() == TQDropEvent::Link ); 00858 } 00859 00860 void KFileIconView::contentsDragEnterEvent( TQDragEnterEvent *e ) 00861 { 00862 if ( ! acceptDrag( e ) ) { // can we decode this ? 00863 e->ignore(); // No 00864 return; 00865 } 00866 e->acceptAction(); // Yes 00867 00868 if ((dropOptions() & AutoOpenDirs) == 0) 00869 return; 00870 00871 KFileIconViewItem *item = dynamic_cast<KFileIconViewItem*>(findItem( contentsToViewport( e->pos() ) )); 00872 if ( item ) { // are we over an item ? 00873 d->dropItem = item; 00874 d->autoOpenTimer.start( autoOpenDelay() ); // restart timer 00875 } 00876 else 00877 { 00878 d->dropItem = 0; 00879 d->autoOpenTimer.stop(); 00880 } 00881 } 00882 00883 void KFileIconView::contentsDragMoveEvent( TQDragMoveEvent *e ) 00884 { 00885 if ( ! acceptDrag( e ) ) { // can we decode this ? 00886 e->ignore(); // No 00887 return; 00888 } 00889 e->acceptAction(); // Yes 00890 00891 if ((dropOptions() & AutoOpenDirs) == 0) 00892 return; 00893 00894 KFileIconViewItem *item = dynamic_cast<KFileIconViewItem*>(findItem( contentsToViewport( e->pos() ) )); 00895 if ( item ) { // are we over an item ? 00896 if (d->dropItem != item) 00897 { 00898 d->dropItem = item; 00899 d->autoOpenTimer.start( autoOpenDelay() ); // restart timer 00900 } 00901 } 00902 else 00903 { 00904 d->dropItem = 0; 00905 d->autoOpenTimer.stop(); 00906 } 00907 } 00908 00909 void KFileIconView::contentsDragLeaveEvent( TQDragLeaveEvent * ) 00910 { 00911 d->dropItem = 0; 00912 d->autoOpenTimer.stop(); 00913 } 00914 00915 void KFileIconView::contentsDropEvent( TQDropEvent *e ) 00916 { 00917 d->dropItem = 0; 00918 d->autoOpenTimer.stop(); 00919 00920 if ( ! acceptDrag( e ) ) { // can we decode this ? 00921 e->ignore(); // No 00922 return; 00923 } 00924 e->acceptAction(); // Yes 00925 00926 KFileIconViewItem *item = dynamic_cast<KFileIconViewItem*>(findItem( contentsToViewport( e->pos() ) )); 00927 KFileItem * fileItem = 0; 00928 if (item) 00929 fileItem = item->fileInfo(); 00930 00931 emit dropped(e, fileItem); 00932 00933 KURL::List urls; 00934 if (KURLDrag::decode( e, urls ) && !urls.isEmpty()) 00935 { 00936 emit dropped(e, urls, fileItem ? fileItem->url() : KURL()); 00937 sig->dropURLs(fileItem, e, urls); 00938 } 00939 } 00940 00941 void KFileIconView::virtual_hook( int id, void* data ) 00942 { KIconView::virtual_hook( id, data ); 00943 KFileView::virtual_hook( id, data ); } 00944 00945 #include "kfileiconview.moc"