00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <qevent.h>
00023 #include <qkeycode.h>
00024 #include <qheader.h>
00025 #include <qpainter.h>
00026 #include <qpixmap.h>
00027
00028 #include <kapplication.h>
00029 #include <kfileitem.h>
00030 #include <kglobal.h>
00031 #include <kglobalsettings.h>
00032 #include <kicontheme.h>
00033 #include <klocale.h>
00034 #include <kdebug.h>
00035
00036 #include "kfiledetailview.h"
00037 #include "config-kfile.h"
00038
00039 #define COL_NAME 0
00040 #define COL_SIZE 1
00041 #define COL_DATE 2
00042 #define COL_PERM 3
00043 #define COL_OWNER 4
00044 #define COL_GROUP 5
00045
00046 KFileDetailView::KFileDetailView(QWidget *parent, const char *name)
00047 : KListView(parent, name), KFileView()
00048 {
00049 m_sortingCol = COL_NAME;
00050 m_blockSortingSignal = false;
00051 setViewName( i18n("Detailed View") );
00052
00053 addColumn( i18n( "Name" ) );
00054 addColumn( i18n( "Size" ) );
00055 addColumn( i18n( "Date" ) );
00056 addColumn( i18n( "Permissions" ) );
00057 addColumn( i18n( "Owner" ) );
00058 addColumn( i18n( "Group" ) );
00059 setShowSortIndicator( TRUE );
00060 setAllColumnsShowFocus( TRUE );
00061
00062 connect( header(), SIGNAL( sectionClicked(int)),
00063 SLOT(slotSortingChanged(int) ));
00064
00065
00066 connect( this, SIGNAL( returnPressed(QListViewItem *) ),
00067 SLOT( slotActivate( QListViewItem *) ) );
00068
00069 connect( this, SIGNAL( clicked(QListViewItem *, const QPoint&, int)),
00070 SLOT( selected( QListViewItem *) ) );
00071 connect( this, SIGNAL( doubleClicked(QListViewItem *, const QPoint&, int)),
00072 SLOT( slotActivate( QListViewItem *) ) );
00073
00074 connect( this, SIGNAL(contextMenuRequested( QListViewItem *,
00075 const QPoint &, int )),
00076 this, SLOT( slotActivateMenu( QListViewItem *, const QPoint& )));
00077
00078 KFile::SelectionMode sm = KFileView::selectionMode();
00079 switch ( sm ) {
00080 case KFile::Multi:
00081 QListView::setSelectionMode( QListView::Multi );
00082 break;
00083 case KFile::Extended:
00084 QListView::setSelectionMode( QListView::Extended );
00085 break;
00086 case KFile::NoSelection:
00087 QListView::setSelectionMode( QListView::NoSelection );
00088 break;
00089 default:
00090 case KFile::Single:
00091 QListView::setSelectionMode( QListView::Single );
00092 break;
00093 }
00094
00095
00096 if ( sm == KFile::Multi || sm == KFile::Extended )
00097 connect( this, SIGNAL( selectionChanged() ),
00098 SLOT( slotSelectionChanged() ));
00099 else
00100 connect( this, SIGNAL( selectionChanged( QListViewItem * ) ),
00101 SLOT( highlighted( QListViewItem * ) ));
00102
00103 setSorting( sorting() );
00104
00105
00106 m_resolver =
00107 new KMimeTypeResolver<KFileListViewItem,KFileDetailView>( this );
00108 }
00109
00110 KFileDetailView::~KFileDetailView()
00111 {
00112 delete m_resolver;
00113 }
00114
00115 void KFileDetailView::setSelected( const KFileItem *info, bool enable )
00116 {
00117 if ( !info )
00118 return;
00119
00120
00121 KFileListViewItem *item = (KFileListViewItem*)info->extraData( this );
00122
00123 if ( item )
00124 KListView::setSelected( item, enable );
00125 }
00126
00127 void KFileDetailView::setCurrentItem( const KFileItem *item )
00128 {
00129 if ( !item )
00130 return;
00131 KFileListViewItem *it = (KFileListViewItem*) item->extraData( this );
00132 if ( it )
00133 KListView::setCurrentItem( it );
00134 }
00135
00136 KFileItem * KFileDetailView::currentFileItem() const
00137 {
00138 KFileListViewItem *current = static_cast<KFileListViewItem*>( currentItem() );
00139 if ( current )
00140 return current->fileInfo();
00141
00142 return 0L;
00143 }
00144
00145 void KFileDetailView::clearSelection()
00146 {
00147 KListView::clearSelection();
00148 }
00149
00150 void KFileDetailView::selectAll()
00151 {
00152 if (KFileView::selectionMode() == KFile::NoSelection ||
00153 KFileView::selectionMode() == KFile::Single)
00154 return;
00155
00156 KListView::selectAll( true );
00157 }
00158
00159 void KFileDetailView::invertSelection()
00160 {
00161 KListView::invertSelection();
00162 }
00163
00164 void KFileDetailView::slotActivateMenu (QListViewItem *item,const QPoint& pos )
00165 {
00166 if ( !item ) {
00167 sig->activateMenu( 0, pos );
00168 return;
00169 }
00170 KFileListViewItem *i = (KFileListViewItem*) item;
00171 sig->activateMenu( i->fileInfo(), pos );
00172 }
00173
00174 void KFileDetailView::clearView()
00175 {
00176 m_resolver->m_lstPendingMimeIconItems.clear();
00177 KListView::clear();
00178 }
00179
00180 void KFileDetailView::insertItem( KFileItem *i )
00181 {
00182 KFileView::insertItem( i );
00183
00184 KFileListViewItem *item = new KFileListViewItem( (QListView*) this, i );
00185
00186 setSortingKey( item, i );
00187
00188 i->setExtraData( this, item );
00189
00190 if ( !i->isMimeTypeKnown() )
00191 m_resolver->m_lstPendingMimeIconItems.append( item );
00192 }
00193
00194 void KFileDetailView::slotActivate( QListViewItem *item )
00195 {
00196 if ( !item )
00197 return;
00198
00199 const KFileItem *fi = ( (KFileListViewItem*)item )->fileInfo();
00200 if ( fi )
00201 sig->activate( fi );
00202 }
00203
00204 void KFileDetailView::selected( QListViewItem *item )
00205 {
00206 if ( !item )
00207 return;
00208
00209 if ( KGlobalSettings::singleClick() ) {
00210 const KFileItem *fi = ( (KFileListViewItem*)item )->fileInfo();
00211 if ( fi && (fi->isDir() || !onlyDoubleClickSelectsFiles()) )
00212 sig->activate( fi );
00213 }
00214 }
00215
00216 void KFileDetailView::highlighted( QListViewItem *item )
00217 {
00218 if ( !item )
00219 return;
00220
00221 const KFileItem *fi = ( (KFileListViewItem*)item )->fileInfo();
00222 if ( fi )
00223 sig->highlightFile( fi );
00224 }
00225
00226
00227 void KFileDetailView::setSelectionMode( KFile::SelectionMode sm )
00228 {
00229 disconnect( this, SIGNAL( selectionChanged() ));
00230 disconnect( this, SIGNAL( selectionChanged( QListViewItem * ) ));
00231
00232 KFileView::setSelectionMode( sm );
00233
00234 switch ( KFileView::selectionMode() ) {
00235 case KFile::Multi:
00236 QListView::setSelectionMode( QListView::Multi );
00237 break;
00238 case KFile::Extended:
00239 QListView::setSelectionMode( QListView::Extended );
00240 break;
00241 case KFile::NoSelection:
00242 QListView::setSelectionMode( QListView::NoSelection );
00243 break;
00244 default:
00245 case KFile::Single:
00246 QListView::setSelectionMode( QListView::Single );
00247 break;
00248 }
00249
00250 if ( sm == KFile::Multi || sm == KFile::Extended )
00251 connect( this, SIGNAL( selectionChanged() ),
00252 SLOT( slotSelectionChanged() ));
00253 else
00254 connect( this, SIGNAL( selectionChanged( QListViewItem * )),
00255 SLOT( highlighted( QListViewItem * )));
00256 }
00257
00258 bool KFileDetailView::isSelected( const KFileItem *i ) const
00259 {
00260 if ( !i )
00261 return false;
00262
00263 KFileListViewItem *item = (KFileListViewItem*) i->extraData( this );
00264 return (item && item->isSelected());
00265 }
00266
00267
00268 void KFileDetailView::updateView( bool b )
00269 {
00270 if ( !b )
00271 return;
00272
00273 QListViewItemIterator it( (QListView*)this );
00274 for ( ; it.current(); ++it ) {
00275 KFileListViewItem *item=static_cast<KFileListViewItem *>(it.current());
00276 item->setPixmap( 0, item->fileInfo()->pixmap(KIcon::SizeSmall) );
00277 }
00278 }
00279
00280 void KFileDetailView::updateView( const KFileItem *i )
00281 {
00282 if ( !i )
00283 return;
00284
00285 KFileListViewItem *item = (KFileListViewItem*) i->extraData( this );
00286 if ( !item )
00287 return;
00288
00289 item->init();
00290 setSortingKey( item, i );
00291
00292
00293 }
00294
00295 void KFileDetailView::setSortingKey( KFileListViewItem *item,
00296 const KFileItem *i )
00297 {
00298
00299 QDir::SortSpec spec = KFileView::sorting();
00300
00301 if ( spec & QDir::Time )
00302 item->setKey( sortingKey( i->time( KIO::UDS_MODIFICATION_TIME ),
00303 i->isDir(), spec ));
00304 else if ( spec & QDir::Size )
00305 item->setKey( sortingKey( i->size(), i->isDir(), spec ));
00306
00307 else
00308 item->setKey( sortingKey( i->text(), i->isDir(), spec ));
00309 }
00310
00311
00312 void KFileDetailView::removeItem( const KFileItem *i )
00313 {
00314 if ( !i )
00315 return;
00316
00317 KFileListViewItem *item = (KFileListViewItem*) i->extraData( this );
00318 m_resolver->m_lstPendingMimeIconItems.remove( item );
00319 delete item;
00320
00321 KFileView::removeItem( i );
00322 }
00323
00324 void KFileDetailView::slotSortingChanged( int col )
00325 {
00326 QDir::SortSpec sort = sorting();
00327 int sortSpec = -1;
00328 bool reversed = col == m_sortingCol && (sort & QDir::Reversed) == 0;
00329 m_sortingCol = col;
00330
00331 switch( col ) {
00332 case COL_NAME:
00333 sortSpec = (sort & ~QDir::SortByMask | QDir::Name);
00334 break;
00335 case COL_SIZE:
00336 sortSpec = (sort & ~QDir::SortByMask | QDir::Size);
00337 break;
00338 case COL_DATE:
00339 sortSpec = (sort & ~QDir::SortByMask | QDir::Time);
00340 break;
00341
00342
00343
00344 case COL_OWNER:
00345 case COL_GROUP:
00346 case COL_PERM:
00347
00348 sortSpec = (sort & ~QDir::SortByMask);
00349 break;
00350 default:
00351 break;
00352 }
00353
00354 if ( reversed )
00355 sortSpec |= QDir::Reversed;
00356 else
00357 sortSpec &= ~QDir::Reversed;
00358
00359 if ( sort & QDir::IgnoreCase )
00360 sortSpec |= QDir::IgnoreCase;
00361 else
00362 sortSpec &= ~QDir::IgnoreCase;
00363
00364
00365 KFileView::setSorting( static_cast<QDir::SortSpec>( sortSpec ) );
00366
00367 KFileItem *item;
00368 KFileItemListIterator it( *items() );
00369
00370 if ( sortSpec & QDir::Time ) {
00371 for ( ; (item = it.current()); ++it )
00372 viewItem(item)->setKey( sortingKey( item->time( KIO::UDS_MODIFICATION_TIME ), item->isDir(), sortSpec ));
00373 }
00374
00375 else if ( sortSpec & QDir::Size ) {
00376 for ( ; (item = it.current()); ++it )
00377 viewItem(item)->setKey( sortingKey( item->size(), item->isDir(),
00378 sortSpec ));
00379 }
00380 else {
00381 for ( ; (item = it.current()); ++it ) {
00382 KFileListViewItem *i = viewItem( item );
00383 i->setKey( sortingKey( i->text(m_sortingCol), item->isDir(),
00384 sortSpec ));
00385 }
00386 }
00387
00388 KListView::setSorting( m_sortingCol, !reversed );
00389 KListView::sort();
00390
00391 if ( !m_blockSortingSignal )
00392 sig->changeSorting( static_cast<QDir::SortSpec>( sortSpec ) );
00393 }
00394
00395
00396 void KFileDetailView::setSorting( QDir::SortSpec spec )
00397 {
00398 int col = 0;
00399 if ( spec & QDir::Time )
00400 col = COL_DATE;
00401 else if ( spec & QDir::Size )
00402 col = COL_SIZE;
00403 else if ( spec & QDir::Unsorted )
00404 col = m_sortingCol;
00405 else
00406 col = COL_NAME;
00407
00408
00409 if ( spec & QDir::Reversed )
00410 spec = (QDir::SortSpec) (spec & ~QDir::Reversed);
00411 else
00412 spec = (QDir::SortSpec) (spec | QDir::Reversed);
00413
00414 m_sortingCol = col;
00415 KFileView::setSorting( (QDir::SortSpec) spec );
00416
00417
00418
00419 m_blockSortingSignal = true;
00420 slotSortingChanged( col );
00421 m_blockSortingSignal = false;
00422 }
00423
00424 void KFileDetailView::ensureItemVisible( const KFileItem *i )
00425 {
00426 if ( !i )
00427 return;
00428
00429 KFileListViewItem *item = (KFileListViewItem*) i->extraData( this );
00430
00431 if ( item )
00432 KListView::ensureItemVisible( item );
00433 }
00434
00435
00436 void KFileDetailView::slotSelectionChanged()
00437 {
00438 sig->highlightFile( 0L );
00439 }
00440
00441 KFileItem * KFileDetailView::firstFileItem() const
00442 {
00443 KFileListViewItem *item = static_cast<KFileListViewItem*>( firstChild() );
00444 if ( item )
00445 return item->fileInfo();
00446 return 0L;
00447 }
00448
00449 KFileItem * KFileDetailView::nextItem( const KFileItem *fileItem ) const
00450 {
00451 if ( fileItem ) {
00452 KFileListViewItem *item = viewItem( fileItem );
00453 if ( item && item->itemBelow() )
00454 return ((KFileListViewItem*) item->itemBelow())->fileInfo();
00455 else
00456 return 0L;
00457 }
00458 else
00459 return firstFileItem();
00460 }
00461
00462 KFileItem * KFileDetailView::prevItem( const KFileItem *fileItem ) const
00463 {
00464 if ( fileItem ) {
00465 KFileListViewItem *item = viewItem( fileItem );
00466 if ( item && item->itemAbove() )
00467 return ((KFileListViewItem*) item->itemAbove())->fileInfo();
00468 else
00469 return 0L;
00470 }
00471 else
00472 return firstFileItem();
00473 }
00474
00475 void KFileDetailView::keyPressEvent( QKeyEvent *e )
00476 {
00477 KListView::keyPressEvent( e );
00478
00479 if ( e->key() == Key_Return || e->key() == Key_Enter ) {
00480 if ( e->state() & ControlButton )
00481 e->ignore();
00482 else
00483 e->accept();
00484 }
00485 }
00486
00487
00488
00489
00490 void KFileDetailView::mimeTypeDeterminationFinished()
00491 {
00492
00493 }
00494
00495 void KFileDetailView::determineIcon( KFileListViewItem *item )
00496 {
00497 (void) item->fileInfo()->determineMimeType();
00498 updateView( item->fileInfo() );
00499 }
00500
00501 void KFileDetailView::listingCompleted()
00502 {
00503 m_resolver->start();
00504 }
00506
00507
00508 void KFileListViewItem::init()
00509 {
00510 KFileListViewItem::setPixmap( COL_NAME, inf->pixmap(KIcon::SizeSmall));
00511
00512 setText( COL_NAME, inf->text() );
00513 setText( COL_SIZE, KGlobal::locale()->formatNumber( inf->size(), 0));
00514 setText( COL_DATE, inf->timeString() );
00515 setText( COL_PERM, inf->permissionsString() );
00516 setText( COL_OWNER, inf->user() );
00517 setText( COL_GROUP, inf->group() );
00518 }
00519
00520
00521 void KFileDetailView::virtual_hook( int id, void* data )
00522 { KListView::virtual_hook( id, data );
00523 KFileView::virtual_hook( id, data ); }
00524
00525 #include "kfiledetailview.moc"