Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |

# Listviews

This examples shows how to work with listviews (hierarchical and multi-column). It also shows how to subclass listview items for special reasons. It looks and works like the main window of a mail client.

Header file:

    /****************************************************************************
    ** $Id: qt/listviews.h   3.3.8   edited Jan 11 14:37 $
    **
    ** Copyright (C) 1992-2007 Trolltech ASA.  All rights reserved.
    **
    ** This file is part of an example program for TQt.  This example
    ** program may be used, distributed and modified without limitation.
    **
    *****************************************************************************/

    #ifndef LISTVIEWS_H
    #define LISTVIEWS_H

    #include <ntqsplitter.h>
    #include <ntqstring.h>
    #include <ntqobject.h>
    #include <ntqdatetime.h>
    #include <ntqptrlist.h>
    #include <ntqlistview.h>

    class TQListView;
    class TQLabel;
    class TQPainter;
    class TQColorGroup;
    class TQObjectList;
    class TQPopupMenu;

    // -----------------------------------------------------------------

    class MessageHeader
    {
    public:
        MessageHeader( const TQString &_sender, const TQString &_subject, const TQDateTime &_datetime )
            : msender( _sender ), msubject( _subject ), mdatetime( _datetime )
        {}

        MessageHeader( const MessageHeader &mh );
        MessageHeader &operator=( const MessageHeader &mh );

        TQString sender() { return msender; }
        TQString subject() { return msubject; }
        TQDateTime datetime() { return mdatetime; }

    protected:
        TQString msender, msubject;
        TQDateTime mdatetime;

    };

    // -----------------------------------------------------------------

    class Message
    {
    public:
        enum State { Read = 0,
                     Unread};

        Message( const MessageHeader &mh, const TQString &_body )
            : mheader( mh ), mbody( _body ), mstate( Unread )
        {}

        Message( const Message &m )
            : mheader( m.mheader ), mbody( m.mbody ), mstate( m.mstate )
        {}

        MessageHeader header() { return mheader; }
        TQString body() { return mbody; }

        void setState( const State &s ) { mstate = s; }
        State state() { return mstate; }

    protected:
        MessageHeader mheader;
        TQString mbody;
        State mstate;

    };

    // -----------------------------------------------------------------

    class Folder : public TQObject
    {
        TQ_OBJECT

    public:
        Folder( Folder *parent, const TQString &name );
        ~Folder()
        {}

        void addMessage( Message *m )
        { lstMessages.append( m ); }

        TQString folderName() { return fName; }

        Message *firstMessage() { return lstMessages.first(); }
        Message *nextMessage() { return lstMessages.next(); }

    protected:
        TQString fName;
        TQPtrList<Message> lstMessages;

    };

    // -----------------------------------------------------------------

    class FolderListItem : public TQListViewItem
    {
    public:
        FolderListItem( TQListView *parent, Folder *f );
        FolderListItem( FolderListItem *parent, Folder *f );

        void insertSubFolders( const TQObjectList *lst );

        Folder *folder() { return myFolder; }

    protected:
        Folder *myFolder;

    };

    // -----------------------------------------------------------------

    class MessageListItem : public TQListViewItem
    {
    public:
        MessageListItem( TQListView *parent, Message *m );

        virtual void paintCell( TQPainter *p, const TQColorGroup &cg,
                                int column, int width, int alignment );

        Message *message() { return myMessage; }

    protected:
        Message *myMessage;

    };

    // -----------------------------------------------------------------

    class ListViews : public TQSplitter
    {
        TQ_OBJECT

    public:
        ListViews( TQWidget *parent = 0, const char *name = 0 );
        ~ListViews()
        {}

    protected:
        void initFolders();
        void initFolder( Folder *folder, unsigned int &count );
        void setupFolders();

        TQListView *messages, *folders;
        TQLabel *message;
        TQPopupMenu* menu;

        TQPtrList<Folder> lstFolders;

    protected slots:
        void slotFolderChanged( TQListViewItem* );
        void slotMessageChanged();
        void slotRMB( TQListViewItem*, const TQPoint &, int );

    };

    #endif

Implementation:

    /****************************************************************************
    ** $Id: qt/listviews.cpp   3.3.8   edited Jan 11 14:37 $
    **
    ** Copyright (C) 1992-2007 Trolltech ASA.  All rights reserved.
    **
    ** This file is part of an example program for TQt.  This example
    ** program may be used, distributed and modified without limitation.
    **
    *****************************************************************************/

    #include "listviews.h"

    #include <ntqlabel.h>
    #include <ntqpainter.h>
    #include <ntqpalette.h>
    #include <ntqobjectlist.h>
    #include <ntqpopupmenu.h>
    #include <ntqheader.h>
    #include <ntqregexp.h>

    // -----------------------------------------------------------------

    MessageHeader::MessageHeader( const MessageHeader &mh )
    {
        msender = mh.msender;
        msubject = mh.msubject;
        mdatetime = mh.mdatetime;
    }

    MessageHeader &MessageHeader::operator=( const MessageHeader &mh )
    {
        msender = mh.msender;
        msubject = mh.msubject;
        mdatetime = mh.mdatetime;

        return *this;
    }

    // -----------------------------------------------------------------

    Folder::Folder( Folder *parent, const TQString &name )
        : TQObject( parent, name ), fName( name )
    {
        lstMessages.setAutoDelete( TRUE );
    }

    // -----------------------------------------------------------------

    FolderListItem::FolderListItem( TQListView *parent, Folder *f )
        : TQListViewItem( parent )
    {
        myFolder = f;
        setText( 0, f->folderName() );

        if ( myFolder->children() )
            insertSubFolders( myFolder->children() );
    }

    FolderListItem::FolderListItem( FolderListItem *parent, Folder *f )
        : TQListViewItem( parent )
    {
        myFolder = f;

        setText( 0, f->folderName() );

        if ( myFolder->children() )
            insertSubFolders( myFolder->children() );
    }

    void FolderListItem::insertSubFolders( const TQObjectList *lst )
    {
        Folder *f;
        for ( f = ( Folder* )( ( TQObjectList* )lst )->first(); f; f = ( Folder* )( ( TQObjectList* )lst )->next() )
            (void)new FolderListItem( this, f );
    }

    // -----------------------------------------------------------------

    MessageListItem::MessageListItem( TQListView *parent, Message *m )
        : TQListViewItem( parent )
    {
        myMessage = m;
        setText( 0, myMessage->header().sender() );
        setText( 1, myMessage->header().subject() );
        setText( 2, myMessage->header().datetime().toString() );
    }

    void MessageListItem::paintCell( TQPainter *p, const TQColorGroup &cg,
                                     int column, int width, int alignment )
    {
        TQColorGroup _cg( cg );
        TQColor c = _cg.text();

        if ( myMessage->state() == Message::Unread )
            _cg.setColor( TQColorGroup::Text, TQt::red );

        TQListViewItem::paintCell( p, _cg, column, width, alignment );

        _cg.setColor( TQColorGroup::Text, c );
    }

    // -----------------------------------------------------------------

    ListViews::ListViews( TQWidget *parent, const char *name )
        : TQSplitter( TQt::Horizontal, parent, name )
    {
        lstFolders.setAutoDelete( TRUE );

        folders = new TQListView( this );
        folders->header()->setClickEnabled( FALSE );
        folders->addColumn( "Folder" );

        initFolders();
        setupFolders();

        folders->setRootIsDecorated( TRUE );
        setResizeMode( folders, TQSplitter::KeepSize );

        TQSplitter *vsplitter = new TQSplitter( TQt::Vertical, this );

        messages = new TQListView( vsplitter );
        messages->addColumn( "Sender" );
        messages->addColumn( "Subject" );
        messages->addColumn( "Date" );
        messages->setColumnAlignment( 1, TQt::AlignRight );
        messages->setAllColumnsShowFocus( TRUE );
        messages->setShowSortIndicator( TRUE );
        menu = new TQPopupMenu( messages );
        for( int i = 1; i <= 10; i++ )
            menu->insertItem( TQString( "Context Item %1" ).arg( i ) );
        connect(messages, SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint& , int ) ),
                this, SLOT( slotRMB( TQListViewItem *, const TQPoint &, int ) ) );
        vsplitter->setResizeMode( messages, TQSplitter::KeepSize );

        message = new TQLabel( vsplitter );
        message->setAlignment( TQt::AlignTop );
        message->setBackgroundMode( PaletteBase );

        connect( folders, SIGNAL( selectionChanged( TQListViewItem* ) ),
                 this, SLOT( slotFolderChanged( TQListViewItem* ) ) );
        connect( messages, SIGNAL( selectionChanged() ),
                 this, SLOT( slotMessageChanged() ) );
        connect( messages, SIGNAL( currentChanged( TQListViewItem * ) ),
                 this, SLOT( slotMessageChanged() ) );

        messages->setSelectionMode( TQListView::Extended );
        // some preparations
        folders->firstChild()->setOpen( TRUE );
        folders->firstChild()->firstChild()->setOpen( TRUE );
        folders->setCurrentItem( folders->firstChild()->firstChild()->firstChild() );
        folders->setSelected( folders->firstChild()->firstChild()->firstChild(), TRUE );

        messages->setSelected( messages->firstChild(), TRUE );
        messages->setCurrentItem( messages->firstChild() );
        message->setMargin( 5 );

        TQValueList<int> lst;
        lst.append( 170 );
        setSizes( lst );
    }

    void ListViews::initFolders()
    {
        unsigned int mcount = 1;

        for ( unsigned int i = 1; i < 20; i++ ) {
            TQString str;
            str = TQString( "Folder %1" ).arg( i );
            Folder *f = new Folder( 0, str );
            for ( unsigned int j = 1; j < 5; j++ ) {
                TQString str2;
                str2 = TQString( "Sub Folder %1" ).arg( j );
                Folder *f2 = new Folder( f, str2 );
                for ( unsigned int k = 1; k < 3; k++ ) {
                    TQString str3;
                    str3 = TQString( "Sub Sub Folder %1" ).arg( k );
                    Folder *f3 = new Folder( f2, str3 );
                    initFolder( f3, mcount );
                }
            }
            lstFolders.append( f );
        }
    }

    void ListViews::initFolder( Folder *folder, unsigned int &count )
    {
        for ( unsigned int i = 0; i < 15; i++, count++ ) {
            TQString str;
            str = TQString( "Message %1  " ).arg( count );
            TQDateTime dt = TQDateTime::currentDateTime();
            dt = dt.addSecs( 60 * count );
            MessageHeader mh( "Trolltech <info@trolltech.com>  ", str, dt );

            TQString body;
            body = TQString( "This is the message number %1 of this application, \n"
                            "which shows how to use TQListViews, TQListViewItems, \n"
                            "TQSplitters and so on. The code should show how easy\n"
                            "this can be done in TQt." ).arg( count );
            Message *msg = new Message( mh, body );
            folder->addMessage( msg );
        }
    }

    void ListViews::setupFolders()
    {
        folders->clear();

        for ( Folder* f = lstFolders.first(); f; f = lstFolders.next() )
            (void)new FolderListItem( folders, f );
    }

    void ListViews::slotRMB( TQListViewItem* Item, const TQPoint & point, int )
    {
        if( Item )
            menu->popup( point );
    }

    void ListViews::slotFolderChanged( TQListViewItem *i )
    {
        if ( !i )
            return;
        messages->clear();
        message->setText( "" );

        FolderListItem *item = ( FolderListItem* )i;

        for ( Message* msg = item->folder()->firstMessage(); msg;
              msg = item->folder()->nextMessage() )
            (void)new MessageListItem( messages, msg );
    }

    void ListViews::slotMessageChanged()
    {
        TQListViewItem *i = messages->currentItem();
        if ( !i )
            return;

        if ( !i->isSelected() ) {
            message->setText( "" );
            return;
        }

        MessageListItem *item = ( MessageListItem* )i;
        Message *msg = item->message();

        TQString text;
        TQString tmp = msg->header().sender();
        tmp = tmp.replace( "<", "&lt;" );
        tmp = tmp.replace( ">", "&gt;" );
        text = TQString( "<b><i>From:</i></b> <a href=\"mailto:info@trolltech.com\">%1</a><br>"
                        "<b><i>Subject:</i></b> <big><big><b>%2</b></big></big><br>"
                        "<b><i>Date:</i></b> %3<br><br>"
                        "%4" ).
               arg( tmp ).arg( msg->header().subject() ).
               arg( msg->header().datetime().toString() ).arg( msg->body() );

        message->setText( text );

        msg->setState( Message::Read );
    }

Main:

    /****************************************************************************
    ** $Id: qt/main.cpp   3.3.8   edited Jan 11 14:37 $
    **
    ** Copyright (C) 1992-2007 Trolltech ASA.  All rights reserved.
    **
    ** This file is part of an example program for TQt.  This example
    ** program may be used, distributed and modified without limitation.
    **
    *****************************************************************************/

    #include "listviews.h"
    #include <ntqapplication.h>

    int main( int argc, char **argv )
    {
        TQApplication a( argc, argv );

        ListViews listViews;
        listViews.resize( 640, 480 );
        listViews.setCaption( "TQt Example - Listview" );
        a.setMainWidget( &listViews );
        listViews.show();

        return a.exec();
    }

See also Examples.