kio Library API Documentation

kfiledetailview.cpp

00001 // -*- c++ -*-
00002 /* This file is part of the KDE libraries
00003    Copyright (C) 1997 Stephan Kulow <coolo@kde.org>
00004                  2000, 2001 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., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, USA.
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: // fall through
00090     case KFile::Single:
00091     QListView::setSelectionMode( QListView::Single );
00092     break;
00093     }
00094 
00095     // for highlighting
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     // we can only hope that this casts works
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: // fall through
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     //item->repaint(); // only repaints if visible
00293 }
00294 
00295 void KFileDetailView::setSortingKey( KFileListViewItem *item,
00296                                      const KFileItem *i )
00297 {
00298     // see also setSorting()
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 // Name or Unsorted
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         // the following columns have no equivalent in QDir, so we set it
00343         // to QDir::Unsorted and remember the column (m_sortingCol)
00344         case COL_OWNER:
00345         case COL_GROUP:
00346         case COL_PERM:
00347             // grmbl, QDir::Unsorted == SortByMask.
00348             sortSpec = (sort & ~QDir::SortByMask);// | QDir::Unsorted;
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 { // Name or Unsorted -> use column text
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     // inversed, because slotSortingChanged will reverse it
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     // don't emit sortingChanged() when called via setSorting()
00419     m_blockSortingSignal = true; // can't use blockSignals()
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 // we're in multiselection mode
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 // mimetype determination on demand
00489 //
00490 void KFileDetailView::mimeTypeDeterminationFinished()
00491 {
00492     // anything to do?
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"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:21:29 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001