/*
* filelistview.cc
*
* Copyright (c) 2002, 2003 Frerich Raabe <raabe@kde.org>
*
* 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. For licensing and distribution details, check the
* accompanying file 'COPYING'.
*/
#include "filelistview.h"
#include "portmgr.h"
#include <kdebug.h>
#include <klocale.h>
#include <kmdcodec.h>
#include <kopenwith.h>
#include <kpropertiesdialog.h>
#include <qfile.h>
#include <qpopupmenu.h>
using namespace Barry;
FileList::FileList( QWidget *parent ): KListView( parent, "FileList" ),
m_checkTimer( 0 ),
m_curItem( 0 )
{
setRootIsDecorated( true );
setAllColumnsShowFocus( true );
setShowSortIndicator( true );
addColumn( i18n( "Filename" ) );
connect( this, SIGNAL( contextMenu( KListView *, QListViewItem *, const QPoint & ) ),
this, SLOT( showContextMenu( KListView *, QListViewItem *, const QPoint & ) ) );
}
FileList::~FileList()
{
delete m_checkTimer;
}
void FileList::setFileList( const Port &port )
{
if ( m_port == port )
return;
m_port = port;
delete m_checkTimer; // Maybe we were busy checking the file statuses...
m_checkTimer = 0;
clear();
if ( columns() == 2 )
removeColumn( 1 );
QStringList files = port.installed() ? port.installedFiles() : port.files();
QStringList::ConstIterator it = files.begin();
QStringList::ConstIterator end = files.end();
for ( ; it != end; ++it )
new KListViewItem( this, *it );
if ( !files.empty() && port.installed() )
startFileCheck();
}
void FileList::showContextMenu( KListView *, QListViewItem *item, const QPoint &p )
{
const bool fileExists = QFile::exists( item->text( 0 ) );
QPopupMenu *menu = new QPopupMenu( this );
int i = menu->insertItem( i18n( "Properties..." ), this, SLOT( showProperties() ) );
menu->setItemEnabled( i, fileExists );
i = menu->insertItem( i18n( "View file" ), this, SLOT( openFile() ) );
menu->setItemEnabled( i, fileExists );
menu->exec( p );
}
void FileList::showProperties()
{
new KPropertiesDialog( KURL( selectedItem()->text( 0 ) ) );
}
void FileList::openFile()
{
KMimeType::Ptr mime = KMimeType::findByURL( selectedItem()->text( 0 ), 0, true );
KURL fileURL = KURL( selectedItem()->text( 0 ) );
/* application shouldn't get passed to KRun since that will execute the
* respective file. Instead, we open a "Open with" dialog to let the user
* decide (most likely, an editor will be chosen). */
if ( mime->name().startsWith( QString::fromLatin1( "application/" ) ) ) {
KFileOpenWithHandler *openWithHandler = new KFileOpenWithHandler;
openWithHandler->displayOpenWithDialog( fileURL );
} else {
new KRun( fileURL );
}
}
void FileList::startFileCheck()
{
addColumn( i18n( "Status" ) );
readFileChecksums();
m_curItem = firstChild();
m_checkTimer = new QTimer( this );
connect( m_checkTimer, SIGNAL( timeout() ), this, SLOT( checkFile() ) );
m_checkTimer->start( 0 );
}
void FileList::checkFile()
{
if ( !m_curItem ) {
delete m_checkTimer;
m_checkTimer = 0;
return;
}
if ( QFile::exists( m_curItem->text( 0 ) ) ) {
QFile f( m_curItem->text( 0 ) );
if ( !f.open( IO_ReadOnly ) ) {
kdWarning() << "Could not open " << m_curItem->text( 0 ) << " for reading." << endl;
m_curItem->setText( 1, i18n( "Unknown" ) );
} else {
KMD5 md5( f.readAll() );
if ( m_checksumMap[ m_curItem->text( 0 ) ] != md5.hexDigest() ) {
m_curItem->setText( 1, i18n( "Checksum mismatch!" ) );
} else {
m_curItem->setText( 1, i18n( "OK" ) );
}
}
} else {
m_curItem->setText( 1, i18n( "Missing" ) );
}
m_curItem = m_curItem->nextSibling();
}
/* Maybe the code in here, at least the part which filters out the filenames
* from the +CONTENTS file, should get moved into "Port::installedFiles()".
* I'm not going to do that until there aren't at least two usages of that
* code.
*/
void FileList::readFileChecksums()
{
const QString pkgName = QString::fromLatin1( "%1-%2" )
.arg( m_port.name() )
.arg( m_port.installedVersion() );
const QString contentsFileName = PortMgr::self().pkgRootDir() + QString::fromLatin1( "/" ) +
pkgName + QString::fromLatin1( "/+CONTENTS" );
QFile contentsFile( contentsFileName );
if ( !contentsFile.open( IO_ReadOnly ) ) {
kdWarning() << "Could not open " << contentsFileName << endl;
return;
}
QTextStream stream( &contentsFile );
while ( !stream.atEnd() ) {
QString line = stream.readLine();
if ( line[ 0 ] == '@' || line[ 0 ] == '+' )
continue;
QString filename = m_port.prefix() + QString::fromLatin1( "/" ) + line;
if ( stream.atEnd() ) {
kdWarning() << "Unexpected end of " << contentsFileName << endl;
return;
}
line = stream.readLine();
if ( !line.startsWith( QString::fromLatin1( "@comment MD5:" ) ) ) {
kdWarning() << "Expected MD5 sum, got " << line << endl;
return;
}
QString md5 = line.mid( 13 );
m_checksumMap[ filename ] = md5;
}
}
#include "filelistview.moc"
// vim:ts=4:sw=4:noet:list
syntax highlighted by Code2HTML, v. 0.9.1