Logo Search packages:      
Sourcecode: webissues version File versions  Download package

tableitemmodel.h

/**************************************************************************
* This file is part of the WebIssues program
* Copyright (C) 2006 Michał Męciński
* Copyright (C) 2007 WebIssues Team
*
* 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.
**************************************************************************/

#ifndef TABLEITEMMODEL_H
#define TABLEITEMMODEL_H

#include <QAbstractItemModel>
#include <QList>

#include "abstracttablemodel.h"

namespace RDB
{
class UniqueIndexBase;
class ForeignIndexBase;
}

namespace WebIssues
{

class AbstractRowFilter;

/**
* Item model for a tree view providing items from data tables.
*
* This model connects one or more AbstractTableModel instances to provide
* an item model for a list of rows with nested rows from other tables.
*
* The top level items can be either all rows from a table or rows matching
* the given foreign key value. They can be additionally filtered using
* an AbstractRowFilter.
*
* Child items are rows from another table whose foreign key match
* the primary key of their parent item. Child tables can be nested
* to any level.
*
* The list of columns for the entire model is stored in the ColumnList
* structure.
*
* The model automatically updates itself when table models emit update
* signals.
*/
00051 class TableItemModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    enum Roles
    {
        RowIdRole = Qt::UserRole,
        LevelRole,
        ColumnRole
    };

public:
    /**
    * Constructor.
    *
    * @param parent The parent object.
    */
    TableItemModel( QObject* parent );

    /**
    * Destructor.
    */
    ~TableItemModel();

public:
    /**
    * Set the list of columns for this model.
    */
    void setColumns( const QList<Column>& columns );

    /**
    * Return the list of columns of this model.
    */
00084     const QList<Column>& columns() const { return m_columns; }

    /**
    * Set the filter for top level rows.
    *
    * @param filter The row filter or @c NULL to disable filtering.
    */
    void setRowFilter( AbstractRowFilter* filter );

    /**
    * Set the top level table model.
    *
    * This method creates top level items using all rows of a table.
    *
    * @param model The model for the top level table.
    *
    * @param index The primary index of the table.
    */
    void setRootTableModel( AbstractTableModel* model, const RDB::UniqueIndexBase* index );

    /**
    * Set the top level table model.
    *
    * This method creates top level items using table rows matching a given value
    * of a foreign key.
    *
    * @param model The model for the top level table.
    *
    * @param index The foreign index of the table.
    *
    * @param parentId The value of the foreign key to match.
    */
    void setRootTableModel( AbstractTableModel* model, const RDB::ForeignIndexBase* index, int parentId );

    /**
    * Return the top level table model.
    */
    AbstractTableModel* rootTableModel() const;

    /**
    * Add a nested child table model.
    *
    * This method adds a new level of child items using rows from the given table
    * whose foreign key match the primary key of their parent items.
    *
    * @param model The model for the child table to add.
    *
    * @param index The foreign index of the table.
    */
    void addChildTableModel( AbstractTableModel* model, const RDB::ForeignIndexBase* index );

    /**
    * Return the total number of top level rows.
    *
    * The number of rows includes rows that were filtered out.
    */
00140     int totalCount() const { return m_totalCount; }

    /**
    * Return the column by which the data is sorted.
    */
00145     Column sortColumn() const { return m_sortColumn; }

    /**
    * Return the sort order of the data.
    */
00150     Qt::SortOrder sortOrder() const { return m_sortOrder; }

public: // overrides
    int columnCount( const QModelIndex& parent ) const;
    QVariant headerData( int section, Qt::Orientation orientation, int role ) const;

    int rowCount( const QModelIndex& parent ) const;
    QModelIndex index( int row, int column, const QModelIndex& parent ) const;
    QModelIndex parent( const QModelIndex& index ) const;

    QVariant data( const QModelIndex& index, int role ) const;

    void sort( int column, Qt::SortOrder order );

private:
    struct Item
    {
        int m_id;
        int m_childGroup;
    };

    struct ItemGroup
    {
        int m_level;
        QList<Item> m_items;
    };

    struct CellIndex
    {
        int m_level;
        int m_id;
        int m_column;
    };

    class CompareItems
    {
    public:
        CompareItems( AbstractTableModel* model, Column column, Qt::SortOrder order );

        bool operator()( const Item& item1, const Item& item2 );

    private:
        AbstractTableModel* m_model;
        Column m_column;
        Qt::SortOrder m_order;
    };

private:
    void attachTableModel( AbstractTableModel* model );

    void buildAllIndexes();
    void buildRootIndex();
    void buildChildIndexes( int group );

    int addGroup( int level );
    void addItemToGroup( int group, int id );

    void sortAllGroups();
    void sortGroup( int group );

    CellIndex cellAt( const QModelIndex& index );
    QModelIndex findCell( const CellIndex& cell );

private slots:
    void updateTable();
    void updateRows();
    void updateRow( int id );

private:
    QList<Column> m_columns;

    Column m_sortColumn;
    Qt::SortOrder m_sortOrder;

    AbstractRowFilter* m_filter;

    QList<AbstractTableModel*> m_models;

    const RDB::UniqueIndexBase* m_uniqueIndex;
    const RDB::ForeignIndexBase* m_foreignIndex;
    int m_parentId;

    QList<const RDB::ForeignIndexBase*> m_childIndexes;

    QList<ItemGroup> m_itemGroups;

    int m_totalCount;
};

}

#endif

Generated by  Doxygen 1.6.0   Back to index