diff options
Diffstat (limited to 'konqueror/listview/konq_listviewitems.cc')
-rw-r--r-- | konqueror/listview/konq_listviewitems.cc | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/konqueror/listview/konq_listviewitems.cc b/konqueror/listview/konq_listviewitems.cc new file mode 100644 index 000000000..f946856c4 --- /dev/null +++ b/konqueror/listview/konq_listviewitems.cc @@ -0,0 +1,449 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_listview.h" +#include <konq_settings.h> +#include <kdebug.h> +#include <klocale.h> +#include <assert.h> +#include <stdio.h> +#include <qpainter.h> +#include <qheader.h> +#include <kiconloader.h> + +static QString retrieveExtraEntry( KFileItem* fileitem, int numExtra ) +{ + /// ######## SLOOOOW + KIO::UDSEntry::ConstIterator it = fileitem->entry().begin(); + const KIO::UDSEntry::ConstIterator end = fileitem->entry().end(); + int n = 0; + for( ; it != end; ++it ) + { + if ((*it).m_uds == KIO::UDS_EXTRA) + { + ++n; + if ( n == numExtra ) + { + return (*it).m_str; + } + } + } + return QString::null; +} + + +/************************************************************** + * + * KonqListViewItem + * + **************************************************************/ +KonqListViewItem::KonqListViewItem( KonqBaseListViewWidget *_listViewWidget, + KonqListViewItem * _parent, KFileItem* _fileitem ) + : KonqBaseListViewItem( _listViewWidget, _parent, _fileitem ), + m_pixmaps( listView()->columns() ) +{ + updateContents(); +} + +KonqListViewItem::KonqListViewItem( KonqBaseListViewWidget *_listViewWidget, KFileItem* _fileitem ) + : KonqBaseListViewItem( _listViewWidget, _fileitem ), + m_pixmaps( listView()->columns() ) +{ + updateContents(); +} + +KonqListViewItem::~KonqListViewItem() +{ + for ( QValueVector<QPixmap*>::iterator + it = m_pixmaps.begin(), itEnd = m_pixmaps.end(); + it != itEnd; ++it ) + delete *it; +} + +void KonqListViewItem::updateContents() +{ + // Set the pixmap + setDisabled( m_bDisabled ); + + // Set the text of each column + setText( 0, m_fileitem->text() ); + + // The order is: .dir (0), dir (1), .file (2), file (3) + sortChar = S_ISDIR( m_fileitem->mode() ) ? 1 : 3; + if ( m_fileitem->text()[0] == '.' ) + --sortChar; + + //now we have the first column, so let's do the rest + + int numExtra = 1; + for ( unsigned int i=0; i<m_pListViewWidget->NumberOfAtoms; i++ ) + { + ColumnInfo *tmpColumn=&m_pListViewWidget->columnConfigInfo()[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case KIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case KIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case KIO::UDS_FILE_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + break; + case KIO::UDS_MIME_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + break; + case KIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case KIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case KIO::UDS_SIZE: + if ( m_pListViewWidget->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatNumber( m_fileitem->size(),0)+" "); + else + setText(tmpColumn->displayInColumn,KIO::convertSize(m_fileitem->size())+" "); + break; + case KIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + { + QDateTime dt; + time_t _time = m_fileitem->time( tmpColumn->udsId ); + if ( _time != 0 ) + { + dt.setTime_t( _time ); + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatDateTime(dt)); + } + } + break; + case KIO::UDS_EXTRA: + { + const QString entryStr = retrieveExtraEntry( m_fileitem, numExtra ); + if ( tmpColumn->type == QVariant::DateTime ) + { + QDateTime dt = QDateTime::fromString( entryStr, Qt::ISODate ); + setText(tmpColumn->displayInColumn, + KGlobal::locale()->formatDateTime(dt)); + } + else // if ( tmpColumn->type == QVariant::String ) + setText(tmpColumn->displayInColumn, entryStr); + ++numExtra; + break; + } + default: + break; + }; + }; + }; +} + +void KonqListViewItem::setDisabled( bool disabled ) +{ + KonqBaseListViewItem::setDisabled( disabled ); + int iconSize = m_pListViewWidget->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqListViewItem::setActive( bool active ) +{ + if ( m_bActive == active ) + return; + + //#### Optimize away repaint if possible, like the iconview does? + KonqBaseListViewItem::setActive( active ); + int iconSize = m_pListViewWidget->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqListViewItem::setPixmap( int column, const QPixmap& pm ) +{ + if ( column < 0 ) + return; + + const QPixmap *current = pixmap( column ); + + if ( ( pm.isNull() && !current ) || + ( current && pm.serialNumber() == current->serialNumber() ) ) + return; + + int oldWidth = current ? current->width() : 0; + int oldHeight = current ? current->height() : 0; + + if ( (int)m_pixmaps.size() <= column ) + m_pixmaps.resize( column+1 ); + + delete current; + m_pixmaps[column] = pm.isNull() ? 0 : new QPixmap( pm ); + + int newWidth = pm.isNull() ? 0 : pm.width(); + int newHeight = pm.isNull() ? 0 : pm.height(); + + // If the height or width have changed then we're going to have to repaint + // this whole thing. Fortunately since most of the calls are coming from + // setActive() this is the uncommon case. + + if ( oldWidth != newWidth || oldHeight != newHeight ) + { + setup(); + widthChanged( column ); + invalidateHeight(); + return; + } + + // If we're just replacing the icon with another one its size -- i.e. a + // "highlighted" icon, don't bother repainting the whole widget. + + QListView *lv = m_pListViewWidget; + + int decorationWidth = lv->treeStepSize() * ( depth() + ( lv->rootIsDecorated() ? 1 : 0 ) ); + int x = lv->header()->sectionPos( column ) + decorationWidth + lv->itemMargin(); + int y = lv->itemPos( this ); + int w = newWidth; + int h = height(); + lv->repaintContents( x, y, w, h ); +} + +const QPixmap* KonqListViewItem::pixmap( int column ) const +{ + bool ok; + if ((int)m_pixmaps.count() <= column) + return 0; + + QPixmap *pm = m_pixmaps.at( column, &ok ); + if( !ok ) + return 0; + return pm; +} + +int KonqBaseListViewItem::compare( QListViewItem* item, int col, bool ascending ) const +{ + KonqListViewItem* k = static_cast<KonqListViewItem*>( item ); + if ( sortChar != k->sortChar ) + // Dirs are always first, even when sorting in descending order + return !ascending ? k->sortChar - sortChar : sortChar - k->sortChar; + + int numExtra = 0; + for ( unsigned int i=0; i<m_pListViewWidget->NumberOfAtoms; i++ ) + { + ColumnInfo *cInfo = &m_pListViewWidget->columnConfigInfo()[i]; + if ( cInfo->udsId == KIO::UDS_EXTRA ) + ++numExtra; + if ( col == cInfo->displayInColumn ) + { + switch ( cInfo->udsId ) + { + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + { + time_t t1 = m_fileitem->time( cInfo->udsId ); + time_t t2 = k->m_fileitem->time( cInfo->udsId ); + return ( t1 > t2 ) ? 1 : ( t1 < t2 ) ? -1 : 0; + } + case KIO::UDS_SIZE: + { + KIO::filesize_t s1 = m_fileitem->size(); + KIO::filesize_t s2 = k->m_fileitem->size(); + return ( s1 > s2 ) ? 1 : ( s1 < s2 ) ? -1 : 0; + } + case KIO::UDS_EXTRA: + { + if ( cInfo->type & QVariant::DateTime ) { + const QString entryStr1 = retrieveExtraEntry( m_fileitem, numExtra ); + QDateTime dt1 = QDateTime::fromString( entryStr1, Qt::ISODate ); + const QString entryStr2 = retrieveExtraEntry( k->m_fileitem, numExtra ); + QDateTime dt2 = QDateTime::fromString( entryStr2, Qt::ISODate ); + return ( dt1 > dt2 ) ? 1 : ( dt1 < dt2 ) ? -1 : 0; + } + } + default: + break; + } + break; + } + } + if ( m_pListViewWidget->caseInsensitiveSort() ) + return text( col ).lower().localeAwareCompare( k->text( col ).lower() ); + else { + return m_pListViewWidget->m_pSettings->caseSensitiveCompare( text( col ), k->text( col ) ); + } +} + +void KonqListViewItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) +{ + QColorGroup cg( _cg ); + + if ( _column == 0 ) + { + _painter->setFont( m_pListViewWidget->itemFont() ); + } + + cg.setColor( QColorGroup::Text, m_pListViewWidget->itemColor() ); + + KListView *lv = static_cast< KListView* >( listView() ); + const QPixmap *pm = lv->viewport()->paletteBackgroundPixmap(); + if ( _column == 0 && isSelected() && !lv->allColumnsShowFocus() ) + { + int newWidth = width( lv->fontMetrics(), lv, _column ); + if ( newWidth > _width ) + newWidth = _width; + if ( pm && !pm->isNull() ) + { + cg.setBrush( QColorGroup::Base, QBrush( backgroundColor(_column), *pm ) ); + QPoint o = _painter->brushOrigin(); + _painter->setBrushOrigin( o.x() - lv->contentsX(), o.y() - lv->contentsY() ); + const QColorGroup::ColorRole crole = + QPalette::backgroundRoleFromMode( lv->viewport()->backgroundMode() ); + _painter->fillRect( newWidth, 0, _width - newWidth, height(), cg.brush( crole ) ); + _painter->setBrushOrigin( o ); + } + else + { + _painter->fillRect( newWidth, 0, _width - newWidth, height(), backgroundColor(_column) ); + } + + _width = newWidth; + } + + KListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +void KonqListViewItem::paintFocus( QPainter * _painter, const QColorGroup & cg, const QRect & _r ) +{ + QRect r( _r ); + QListView *lv = static_cast< QListView * >( listView() ); + r.setWidth( width( lv->fontMetrics(), lv, 0 ) ); + if ( r.right() > lv->header()->sectionRect( 0 ).right() ) + r.setRight( lv->header()->sectionRect( 0 ).right() ); + QListViewItem::paintFocus( _painter, cg, r ); +} + +const char* KonqBaseListViewItem::makeAccessString( const mode_t mode) +{ + static char buffer[ 12 ]; + + char uxbit,gxbit,oxbit; + + if ( (mode & (S_IXUSR|S_ISUID)) == (S_IXUSR|S_ISUID) ) + uxbit = 's'; + else if ( (mode & (S_IXUSR|S_ISUID)) == S_ISUID ) + uxbit = 'S'; + else if ( (mode & (S_IXUSR|S_ISUID)) == S_IXUSR ) + uxbit = 'x'; + else + uxbit = '-'; + + if ( (mode & (S_IXGRP|S_ISGID)) == (S_IXGRP|S_ISGID) ) + gxbit = 's'; + else if ( (mode & (S_IXGRP|S_ISGID)) == S_ISGID ) + gxbit = 'S'; + else if ( (mode & (S_IXGRP|S_ISGID)) == S_IXGRP ) + gxbit = 'x'; + else + gxbit = '-'; + + if ( (mode & (S_IXOTH|S_ISVTX)) == (S_IXOTH|S_ISVTX) ) + oxbit = 't'; + else if ( (mode & (S_IXOTH|S_ISVTX)) == S_ISVTX ) + oxbit = 'T'; + else if ( (mode & (S_IXOTH|S_ISVTX)) == S_IXOTH ) + oxbit = 'x'; + else + oxbit = '-'; + + buffer[0] = ((( mode & S_IRUSR ) == S_IRUSR ) ? 'r' : '-' ); + buffer[1] = ((( mode & S_IWUSR ) == S_IWUSR ) ? 'w' : '-' ); + buffer[2] = uxbit; + buffer[3] = ((( mode & S_IRGRP ) == S_IRGRP ) ? 'r' : '-' ); + buffer[4] = ((( mode & S_IWGRP ) == S_IWGRP ) ? 'w' : '-' ); + buffer[5] = gxbit; + buffer[6] = ((( mode & S_IROTH ) == S_IROTH ) ? 'r' : '-' ); + buffer[7] = ((( mode & S_IWOTH ) == S_IWOTH ) ? 'w' : '-' ); + buffer[8] = oxbit; + buffer[9] = 0; + + return buffer; +} + +KonqBaseListViewItem::KonqBaseListViewItem(KonqBaseListViewWidget *_listViewWidget, KFileItem* _fileitem) +:KListViewItem(_listViewWidget) +,sortChar(0) +,m_bDisabled(false) +,m_bActive(false) +,m_fileitem(_fileitem) +,m_pListViewWidget(_listViewWidget) +{} + +KonqBaseListViewItem::KonqBaseListViewItem(KonqBaseListViewWidget *_listViewWidget, KonqBaseListViewItem *_parent, KFileItem* _fileitem) +:KListViewItem(_parent) +,sortChar(0) +,m_bDisabled(false) +,m_bActive(false) +,m_fileitem(_fileitem) +,m_pListViewWidget(_listViewWidget) +{} + +KonqBaseListViewItem::~KonqBaseListViewItem() +{ + if (m_pListViewWidget->m_activeItem == this) + m_pListViewWidget->m_activeItem = 0; + if (m_pListViewWidget->m_dragOverItem == this) + m_pListViewWidget->m_dragOverItem = 0; + + if (m_pListViewWidget->m_selected) + m_pListViewWidget->m_selected->removeRef(this); +} + +QRect KonqBaseListViewItem::rect() const +{ + QRect r = m_pListViewWidget->itemRect(this); + return QRect( m_pListViewWidget->viewportToContents( r.topLeft() ), QSize( r.width(), r.height() ) ); +} + +void KonqBaseListViewItem::mimetypeFound() +{ + // Update icon + setDisabled( m_bDisabled ); + uint done = 0; + KonqBaseListViewWidget * lv = m_pListViewWidget; + for (unsigned int i=0; i<m_pListViewWidget->NumberOfAtoms && done < 2; i++) + { + ColumnInfo *tmpColumn=&lv->columnConfigInfo()[i]; + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_FILE_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimeComment()); + done++; + } + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_MIME_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimetype()); + done++; + } + } +} + |