Logo Search packages:      
Sourcecode: dc-qt version File versions  Download package

userfilemodel.h

//
// C++ Interface: UserFileModel
//
// Description:
//
//
// Author: Mikael Gransell <mikael.gransell@bredband.net>, (C) 2005
//
// Copyright: See COPYING file that comes with this distribution
//
//

#ifndef USER_FILE_TREE_MODEL_H_
#define USER_FILE_TREE_MODEL_H_

#include <boost/shared_ptr.hpp>

#include <QtGui>
#include <QAbstractItemModel>
#include <QPointer>

#include "global.h"
#include "util.h"

class QFileIconProvider;

class UserFileModel : public QAbstractItemModel {
    Q_OBJECT
public:
    class TreeItem {
    public:

        /**
        * The columns that are available fo the items in the list.
        */
        enum eUserTreeColumns
        {
            FILE_COLUMN = 0,
            SIZE_COLUMN,
            TTH_COLUMN
        };

        /**
        * Ctor. Creates a node with n as name.
        * @param n This is the name of the item.
        * @param parent Pointer to this items parent node.
        */
        TreeItem(const QString& n, TreeItem *parent = 0) : parentItem( parent ), name( n ), size( 0 ), tth("") {
            if ( parent ) {
                parent->appendChild( this );
            }
        }

        /**
        * Ctor. Creates a node with an empty name
        * @param parent Pointer to this items parent node.
        */
        TreeItem( TreeItem* parent = 0 ) : parentItem( parent ) {
            if ( parent ) {
                parent->appendChild( this );
            }
        }

        /**
        * Dtor.
        * Remove all children.
        */
        ~TreeItem() {
            qDeleteAll( childItems );
        }

        /**
        * Adds a child to the list.
        * @param child The new child.
        */
        void appendChild(TreeItem *child) {
            childItems.append( child );
        }

        /**
        * Get the child at row row, i.e. at positioin row in the child list.
        * @param row The row of the child that we want.
        * @return Pointer to the child.
        */
        TreeItem *child(int row) {
            return childItems.value( row );
        }

        /**
        * Get the amount of children.
        * @return The number of children.
        */
        int childCount() const {
            return childItems.count();
        }

        /**
        * Get the number of columns for this item.
        * @return Number of columns.
        */
        int columnCount() const {
            return 2;
        }

        /**
        * Get the data that corresponds to the column.
        * @param column The column we want data for.
        */
        QVariant data(int column) const {
            QVariant ret;
            switch( column ) {
                  case FILE_COLUMN:
                ret = name;
                break;

                  case SIZE_COLUMN:
                ret = Util::bytesToStr( size );
                break;

                  case TTH_COLUMN:
                ret = tth;
                break;

            default:
                ret = "";
            }

            return ret;
        }

        /**
        * The row of this item.
        */
        int row() const {
            if( !parentItem ) {
                return 0;
            }
            return parentItem->childItems.indexOf( const_cast<TreeItem*>(this) );
        }

        /**
        * Get the parent of this item.
        * @return Pointer to the parent.
        */
        TreeItem *parent() {
            return parentItem;
        }

        /**
        * Return the calculated size of this item.
        * @return The size.
        */
        qint64 getSize() const {
            return size;
        }

        /**
         * Return name of the item
         */
        const QString& getName() const {
            return name;
        }

        /**
         * Return the full name of the item, i.e. the entire path
         */
        QString getFullName() const {
            // If we are not the root item we return the full path of our parent with our name appended.
            return parentItem ? parentItem->getFullName() + "/" + name : "";
        }
            
            /**
             * Return tth for this item.
             */
            const QString& getTTH() const
            {
                  return tth;
            }

        /**
         * If this is a directory or not
         * @return true if this is a directory
         */
        bool isDir() const {
            return childCount() != 0;
        }

        /**
        * Calculate the size of this node. This is either 
        * based on the size that was set while the tree was 
        * parsed, i.e. this item is a leaf, or on the sum 
        * of all of this items child nodes, i.e. this item 
        * is a directory.
        * @return The size that we have calculated.
        */
        qint64 calculateSize() {
            // The size is already calculated, i.e. we are a leaf or this method has already been called.
            if( !size ) {
                // Calculate the size of al children and sum them up.
                for( int i = 0; i < childItems.size(); i++ ) {
                    size += childItems[i]->calculateSize();
                }
            }
            return size;
        }

        void setSize( qint64 s ) {
            size = s;
        }

        void setName( const QString& n ) {
            name = n;
        }

        void setTTH( const QString& t ) {
            tth = t;
        }

    private:
        /**
        * List of child items.
        */
        QList<TreeItem*> childItems;

        /**
        * Pointer to our parent.
        */
        TreeItem *parentItem;

        /**
        * The name of the item. This will be either a directory name or a file name.
        */
        QString name;

        /**
        * Size of the item. This will either be the size of a file, or if 
        * the item is a directory, the size of all its chlidren.
        */
        qint64 size;

        /**
        TTH for the item
        */
        QString tth;
    };


    UserFileModel( int uid, const QString& fileTree ) : 
            userId( uid ) 
      {
        setTree( fileTree );
            
            // Create an icon provider that will suply the list wiht icons
            m_pIconProvider = new QFileIconProvider();
    }

    virtual ~UserFileModel() 
      {
            // Delete the root item. This should delete all childrem too
            delete root;
            
            // Delete icon provider
            delete m_pIconProvider;
      }
    virtual QVariant data( const QModelIndex &index, int role ) const;

    virtual Qt::ItemFlags flags( const QModelIndex &index ) const;

    virtual QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;

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

    virtual QModelIndex parent( const QModelIndex &index ) const;

    virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;

    virtual int columnCount( const QModelIndex &parent = QModelIndex() ) const;

    TreeItem* getItem( const QModelIndex &index ) const;

      int getUserId() const;

public slots:
    /**
     * This is the big as method that builds the tree based on the string that we get from the backend.
     * This string is based on the Newick format of string representation of a tree. This is very much 
     * like Lisp syntax.
     * @param tree The string representation of the tree.
     * @param user Name of the user, this will act as the root of the tree.
     * @return true if everything wen't as expected.
     */
    bool setTree( const QString& tree );

protected:
    void handleSubTree( const QString& tree, TreeItem* parent ) const;
    void addFile( const QString& file, TreeItem* parent ) const;

private:
    /**
     * Root of the tree. This node should be the user.
     */
    TreeItem* root;
      
      /**
       * Provides icons for the items in the list.
       */
      QFileIconProvider* m_pIconProvider;
      
      /// Holds the id of the user that this model is associated with
      const int userId;
};

typedef boost::shared_ptr<UserFileModel> UserFileModelPtr;

#endif

Generated by  Doxygen 1.6.0   Back to index