Commit 16576305 authored by Henrique Pinto's avatar Henrique Pinto
Browse files

* Add a model for kerfuffle archives. Still incomplete, and probably very buggy

svn path=/branches/work/libarchive-based-ark/ark/; revision=686674
parent 7d473fff
#include "archivemodel.h"
#include "kerfuffle/arch.h"
#include <QList>
#include <KLocale>
class ArchiveDirNode;
class ArchiveNode
{
public:
ArchiveNode( ArchiveDirNode *parent, const ArchiveEntry & entry )
: m_entry( entry ), m_parent( parent )
{
}
virtual ~ArchiveNode() {}
ArchiveEntry entry() const { return m_entry; }
ArchiveDirNode *parent() const { return m_parent; }
int row() const;
virtual bool isDir() const { return false; }
private:
ArchiveEntry m_entry;
ArchiveDirNode *m_parent;
};
class ArchiveDirNode: public ArchiveNode
{
public:
ArchiveDirNode( ArchiveDirNode *parent, const ArchiveEntry & entry )
: ArchiveNode( parent, entry )
{
}
~ArchiveDirNode()
{
qDeleteAll( m_entries );
}
QList<ArchiveNode*>& entries() { return m_entries; }
virtual bool isDir() const { return true; }
private:
QList<ArchiveNode*> m_entries;
};
int ArchiveNode::row() const
{
if ( parent() )
{
return parent()->entries().indexOf( const_cast<ArchiveNode*>( this ) );
}
return 0;
}
ArchiveModel::ArchiveModel( Arch *archive, QObject *parent )
: QAbstractItemModel( parent ), m_archive( archive ),
m_rootNode( new ArchiveDirNode( 0, ArchiveEntry() ) )
{
m_archive->setParent( this );
connect( m_archive, SIGNAL( newEntry( const ArchiveEntry& ) ),
this, SLOT( slotNewEntry( const ArchiveEntry& ) ) );
m_archive->open();
}
ArchiveModel::~ArchiveModel()
{
delete m_archive;
m_archive = 0;
delete m_rootNode;
m_rootNode = 0;
}
QVariant ArchiveModel::data( const QModelIndex &index, int role ) const
{
if ( index.isValid() )
{
ArchiveNode *node = static_cast<ArchiveNode*>( index.internalPointer() );
switch ( role )
{
case Qt::DisplayRole:
return node->entry()[ FileName ];
default:
return QVariant();
}
}
return QVariant();
}
Qt::ItemFlags ArchiveModel::flags( const QModelIndex &index ) const
{
if ( index.isValid() )
{
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
return 0;
}
QVariant ArchiveModel::headerData( int section, Qt::Orientation, int role ) const
{
if ( role == Qt::DisplayRole )
{
switch ( section )
{
case 0:
return i18n( "Name" );
}
}
return QVariant();
}
QModelIndex ArchiveModel::index( int row, int column, const QModelIndex &parent ) const
{
if ( hasIndex( row, column, parent ) )
{
ArchiveDirNode *parentNode = parent.isValid()? static_cast<ArchiveDirNode*>( parent.internalPointer() ) : m_rootNode;
ArchiveNode *item = parentNode->entries().value( row, 0 );
if ( item )
{
return createIndex( row, column, item );
}
}
return QModelIndex();
}
QModelIndex ArchiveModel::parent( const QModelIndex &index ) const
{
if ( index.isValid() )
{
ArchiveNode *item = static_cast<ArchiveNode*>( index.internalPointer() );
if ( item->parent() && ( item->parent() != m_rootNode ) )
{
return createIndex( item->parent()->row(), 0, item->parent() );
}
}
return QModelIndex();
}
int ArchiveModel::rowCount( const QModelIndex &parent ) const
{
kDebug( 1601 ) << k_funcinfo << "parent.column() is " << parent.column() << endl;
if ( parent.column() <= 0 )
{
ArchiveNode *parentNode = parent.isValid()? static_cast<ArchiveNode*>( parent.internalPointer() ) : m_rootNode;
if ( parentNode && parentNode->isDir() )
{
return static_cast<ArchiveDirNode*>( parentNode )->entries().count();
}
}
return 0;
}
int ArchiveModel::columnCount( const QModelIndex &parent ) const
{
if ( parent.isValid() )
{
return static_cast<ArchiveNode*>( parent.internalPointer() )->entry().size();
}
return 1; // TODO: Completely bogus
}
void ArchiveModel::slotNewEntry( const ArchiveEntry& entry )
{
/// 1. Find Parent Node
ArchiveDirNode *parent = m_rootNode; // TODO: Don't make everyone child of the root, obey the hierarchy
QModelIndex parentIndex = QModelIndex();
/// 2. Create an ArchiveNode
beginInsertRows( parentIndex, m_rootNode->entries().count(), m_rootNode->entries().count() );
ArchiveNode *node = new ArchiveNode( parent, entry );
parent->entries().append( node );
kDebug( 1601 ) << "New entry for: " << entry[ FileName ] << endl;
endInsertRows();
}
#ifndef ARCHIVEMODEL_H
#define ARCHIVEMODEL_H
#include <QAbstractItemModel>
#include "kerfuffle/arch.h"
class Arch;
class ArchiveDirNode;
class ArchiveModel: public QAbstractItemModel
{
Q_OBJECT
public:
ArchiveModel( Arch *archive, QObject *parent = 0 );
~ArchiveModel();
QVariant data( const QModelIndex &index, int role ) const;
Qt::ItemFlags flags( const QModelIndex &index ) const;
QVariant headerData( int section, Qt::Orientation orientation,
int role = Qt::DisplayRole ) const;
QModelIndex index( int row, int column,
const QModelIndex &parent = QModelIndex() ) const;
QModelIndex parent( const QModelIndex &index ) const;
int rowCount( const QModelIndex &parent = QModelIndex() ) const;
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
private slots:
void slotNewEntry( const ArchiveEntry& entry );
private:
Arch *m_archive;
ArchiveDirNode *m_rootNode;
};
#endif // ARCHIVEMODEL_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment