245 lines
8.1 KiB
C++
245 lines
8.1 KiB
C++
/* *********************************************************************** *
|
|
* XINX *
|
|
* Copyright (C) 2009 by Ulrich Van Den Hekke *
|
|
* ulrich.vdh@shadoware.org *
|
|
* *
|
|
* 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 3 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. If not, see <http://www.gnu.org/licenses/>. *
|
|
* *********************************************************************** */
|
|
|
|
// Xinx header
|
|
#include "categoryitemmodel.h"
|
|
#include "snipetmanager.h"
|
|
|
|
// Qt header
|
|
#include <QIcon>
|
|
#include <QColor>
|
|
#include <QFont>
|
|
#include <QVariant>
|
|
#include <QSqlRecord>
|
|
#include <QSqlError>
|
|
|
|
/* CategoryItemModel */
|
|
|
|
CategoryItemModel::CategoryItemModel( QSqlDatabase db, QObject * parent ) : QAbstractProxyModel( parent ), m_db( db ) {
|
|
// This will be automatically deleted.
|
|
m_sourceModel = new QSqlQueryModel( this );
|
|
setSourceModel( m_sourceModel );
|
|
|
|
createMapping();
|
|
}
|
|
|
|
CategoryItemModel::~CategoryItemModel() {
|
|
qDeleteAll( m_sourcesIndexMapping );
|
|
}
|
|
|
|
void CategoryItemModel::select() {
|
|
// Set the query used all snipet
|
|
m_sourceModel->setQuery(
|
|
"SELECT id, parent_id, name "
|
|
"FROM categories "
|
|
"ORDER BY name", m_db
|
|
);
|
|
|
|
// Define name for header column
|
|
m_sourceModel->setHeaderData( list_id, Qt::Horizontal, tr("Id") );
|
|
m_sourceModel->setHeaderData( list_parentid, Qt::Horizontal, tr("Parent") );
|
|
m_sourceModel->setHeaderData( list_name, Qt::Horizontal, tr("Name") );
|
|
|
|
// Initialize the mapping
|
|
createMapping();
|
|
|
|
// Reset the layout
|
|
reset();
|
|
}
|
|
|
|
/*! \internal
|
|
Create the mapping of all index in the table.
|
|
*/
|
|
void CategoryItemModel::createMapping() {
|
|
qDeleteAll( m_sourcesIndexMapping );
|
|
m_sourcesIndexMapping.clear();
|
|
m_categoryIdMapping.clear();
|
|
|
|
int source_rows = m_sourceModel->rowCount();
|
|
for( int i = -1; i < source_rows; ++i ) {
|
|
Mapping * m = new Mapping;
|
|
IndexMap::const_iterator it = IndexMap::const_iterator( m_sourcesIndexMapping.insert( i, m ) );
|
|
m->index = i;
|
|
m->parrentId = 0;
|
|
m->parentIndex = 0;
|
|
|
|
if( i >= 0 ) {
|
|
QSqlRecord record = m_sourceModel->record( i );
|
|
m_categoryIdMapping[ record.value( list_id ).toInt() ] = i;
|
|
m->id = record.value( list_id ).toInt();
|
|
} else { // Create the root Item
|
|
m->id = 0;
|
|
m_categoryIdMapping[ 0 ] = -1;
|
|
}
|
|
}
|
|
|
|
for( int i = 0; i < source_rows; ++i ) {
|
|
QSqlRecord record = m_sourceModel->record( i );
|
|
|
|
int parentCategoryId = record.value( list_parentid ).toInt();
|
|
int parentCategoryIndex = m_categoryIdMapping.value( parentCategoryId, -2 );
|
|
Q_ASSERT( parentCategoryIndex > -2 );
|
|
Mapping * mapping = m_sourcesIndexMapping.value( i );
|
|
mapping->parentIndex = parentCategoryIndex;
|
|
mapping->parrentId = parentCategoryId;
|
|
|
|
Mapping * categoryMapping = m_sourcesIndexMapping.value( parentCategoryIndex );
|
|
categoryMapping->source_rows.append( i );
|
|
}
|
|
}
|
|
|
|
int CategoryItemModel::proxyColumnToSource( int proxyColumn ) const {
|
|
if( proxyColumn == 0 )
|
|
return list_name;
|
|
return -1;
|
|
}
|
|
|
|
int CategoryItemModel::sourceColumnToProxy( int sourceColumn ) const {
|
|
if( sourceColumn == list_name )
|
|
return 0;
|
|
return -1;
|
|
}
|
|
|
|
/// For the given source index, this method return the corresponding index in the proxy
|
|
QModelIndex CategoryItemModel::mapFromSource ( const QModelIndex & sourceIndex ) const {
|
|
if( ! sourceIndex.isValid() ) return QModelIndex();
|
|
if( sourceIndex.model() != m_sourceModel ) {
|
|
qWarning( "CategoryItemModel: index from wrong model passed to mapFromSource" );
|
|
return QModelIndex();
|
|
}
|
|
|
|
int row = sourceIndex.row();
|
|
IndexMap::const_iterator it = m_sourcesIndexMapping.constFind( row );
|
|
Q_ASSERT( it != m_sourcesIndexMapping.constEnd() );
|
|
|
|
int parentRow = it.value()->parentIndex;
|
|
IndexMap::const_iterator parentIt = m_sourcesIndexMapping.constFind( parentRow );
|
|
Q_ASSERT( parentIt != m_sourcesIndexMapping.constEnd() );
|
|
|
|
Mapping * m = parentIt.value();
|
|
|
|
int proxyRow = m->source_rows.indexOf( row ), proxyColumn = sourceColumnToProxy( sourceIndex.column() );
|
|
if( proxyColumn == -1 ) return QModelIndex();
|
|
|
|
return createIndex( proxyRow, proxyColumn, *parentIt );
|
|
}
|
|
|
|
QModelIndex CategoryItemModel::mapToSource ( const QModelIndex & proxyIndex ) const {
|
|
if( ! proxyIndex.isValid() ) return QModelIndex();
|
|
if( proxyIndex.model() != this ) {
|
|
qWarning( "CategoryItemModel: index from wrong model passed to mapToSource" );
|
|
return QModelIndex();
|
|
}
|
|
|
|
Mapping * m = static_cast<Mapping*>( proxyIndex.internalPointer() );
|
|
|
|
int sourceColumn = proxyColumnToSource( proxyIndex.column() );
|
|
if( sourceColumn == -1 ) return QModelIndex();
|
|
|
|
int sourceRow = m->source_rows.at( proxyIndex.row() );
|
|
|
|
return m_sourceModel->index( sourceRow, sourceColumn );
|
|
}
|
|
|
|
QModelIndex CategoryItemModel::index( int row, int column, const QModelIndex & parent ) const {
|
|
if( ( row < 0 ) || ( column < 0 ) ) return QModelIndex();
|
|
|
|
IndexMap::const_iterator it = m_sourcesIndexMapping.constFind( -1 );
|
|
|
|
QModelIndex sourceParent = mapToSource( parent );
|
|
if( sourceParent.isValid() ) {
|
|
it = m_sourcesIndexMapping.constFind( sourceParent.row() );
|
|
}
|
|
|
|
Q_ASSERT( it != m_sourcesIndexMapping.constEnd() );
|
|
if( it.value()->source_rows.count() <= row )
|
|
return QModelIndex();
|
|
|
|
return createIndex( row, column, *it );
|
|
}
|
|
|
|
QModelIndex CategoryItemModel::index( int categoryId ) {
|
|
int sourceRow = m_categoryIdMapping.value( categoryId, -1 );
|
|
if( sourceRow >= 0 ) {
|
|
Mapping * m = m_sourcesIndexMapping.value( sourceRow );
|
|
|
|
int parentRow = m->parentIndex;
|
|
IndexMap::const_iterator parentIt = m_sourcesIndexMapping.constFind( parentRow );
|
|
Q_ASSERT( parentIt != m_sourcesIndexMapping.constEnd() );
|
|
|
|
Mapping * parrentMapping = parentIt.value();
|
|
|
|
int proxyRow = parrentMapping->source_rows.indexOf( m->index );
|
|
|
|
return createIndex( proxyRow, 0, *parentIt );
|
|
}
|
|
return QModelIndex();
|
|
}
|
|
|
|
QModelIndex CategoryItemModel::parent( const QModelIndex & index ) const {
|
|
if( ! index.isValid() ) return QModelIndex();
|
|
|
|
Mapping * m = static_cast<Mapping*>( index.internalPointer() );
|
|
|
|
int sourceRow = m->index;
|
|
if( sourceRow == -1 ) return QModelIndex();
|
|
|
|
QModelIndex sourceParent = m_sourceModel->index( sourceRow, proxyColumnToSource( 0 ) );
|
|
QModelIndex proxyParent = mapFromSource( sourceParent );
|
|
|
|
return proxyParent;
|
|
}
|
|
|
|
int CategoryItemModel::rowCount( const QModelIndex & index ) const {
|
|
if( index.column() > 0 ) return 0;
|
|
if( ! index.isValid() ) {
|
|
Mapping * rootMapping = m_sourcesIndexMapping.value( -1 );
|
|
return rootMapping->source_rows.count();
|
|
} else {
|
|
Mapping * parrentMapping = static_cast<Mapping*>( index.internalPointer() );
|
|
int sourceRowIndex = parrentMapping->source_rows.at( index.row() );
|
|
Mapping * rowMapping = m_sourcesIndexMapping.value( sourceRowIndex );
|
|
|
|
return rowMapping->source_rows.count();
|
|
}
|
|
}
|
|
|
|
int CategoryItemModel::columnCount( const QModelIndex & index ) const {
|
|
Q_UNUSED( index );
|
|
|
|
return 1;
|
|
}
|
|
|
|
QVariant CategoryItemModel::data( const QModelIndex & index, int role ) const {
|
|
if( ! index.isValid() ) return QVariant();
|
|
|
|
if( role == Qt::DecorationRole ) {
|
|
if( index.column() == 0 ) {
|
|
return QIcon( ":/images/folder.png" );
|
|
}
|
|
} else if( role == CategoryItemModel::CategoryIdRole ) {
|
|
QModelIndex sourceIndex = mapToSource( index );
|
|
QSqlRecord record = m_sourceModel->record( sourceIndex.row() );
|
|
return record.value( list_id );
|
|
}
|
|
|
|
return QAbstractProxyModel::data( index, role );
|
|
}
|
|
|