Diffstat (limited to 'libopie2/qt3/opieui/ojanuswidget.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/qt3/opieui/ojanuswidget.cpp | 1116 |
1 files changed, 1116 insertions, 0 deletions
diff --git a/libopie2/qt3/opieui/ojanuswidget.cpp b/libopie2/qt3/opieui/ojanuswidget.cpp new file mode 100644 index 0000000..0a037ff --- a/dev/null +++ b/libopie2/qt3/opieui/ojanuswidget.cpp @@ -0,0 +1,1116 @@ +/* + This file is part of the Opie Project + + Originally part of the KDE project + (C) 1999-2000 Espen Sand (espensa@online.no) + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. 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 +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +/* QT */ + +#include <qbitmap.h> +#include <qgrid.h> +#include <qhbox.h> +#include <qheader.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qobjectlist.h> +#include <qpixmap.h> +#include <qlistview.h> +#include <qsplitter.h> +#include <qtabwidget.h> +#include <qvbox.h> +#include <qwidgetstack.h> +#include <qpainter.h> +#include <qtimer.h> +#include <qstyle.h> + +/* OPIE */ + +#include <opie2/odialog.h> +#include <opie2/oseparator.h> +#include <opie2/ojanuswidget.h> + +/*====================================================================================== + * IconListItem + *======================================================================================*/ + +class OJanusWidget::IconListItem : public QListBoxItem +{ + public: + IconListItem( QListBox *listbox, const QPixmap &pixmap, + const QString &text ); + virtual int height( const QListBox *lb ) const; + virtual int width( const QListBox *lb ) const; + int expandMinimumWidth( int width ); + + protected: + const QPixmap &defaultPixmap(); + void paint( QPainter *painter ); + + private: + QPixmap mPixmap; + int mMinimumWidth; +}; + +template class QPtrList<QListViewItem>; + +/*====================================================================================== + * OJanusWidget + *======================================================================================*/ + +OJanusWidget::OJanusWidget( QWidget *parent, const char *name, int face ) + : QWidget( parent, name, 0 ), + mValid(false), mPageList(0), + mTitleList(0), mFace(face), mTitleLabel(0), mActivePageWidget(0), + mShowIconsInTreeList(false), d(0) +{ + QVBoxLayout *topLayout = new QVBoxLayout( this ); + + if( mFace == TreeList || mFace == IconList ) + { + mPageList = new QPtrList<QWidget>; + mTitleList = new QStringList(); + + QFrame *page; + if( mFace == TreeList ) + { + QSplitter *splitter = new QSplitter( this ); + topLayout->addWidget( splitter, 10 ); + mTreeListResizeMode = QSplitter::KeepSize; + + mTreeList = new QListView( splitter ); + mTreeList->addColumn( QString::fromLatin1("") ); + mTreeList->header()->hide(); + mTreeList->setRootIsDecorated(true); + mTreeList->setSorting( -1 ); + connect( mTreeList, SIGNAL(selectionChanged()), SLOT(slotShowPage()) ); + connect( mTreeList, SIGNAL(clicked(QListViewItem *)), SLOT(slotItemClicked(QListViewItem *))); + + // + // Page area. Title at top with a separator below and a pagestack using + // all available space at bottom. + // + QFrame *p = new QFrame( splitter ); + + QHBoxLayout *hbox = new QHBoxLayout( p, 0, 0 ); + hbox->addSpacing( ODialog::spacingHint() ); + + page = new QFrame( p ); + hbox->addWidget( page, 10 ); + } + else + { + QHBoxLayout *hbox = new QHBoxLayout( topLayout ); + mIconList = new IconListBox( this ); + + QFont listFont( mIconList->font() ); + listFont.setBold( true ); + mIconList->setFont( listFont ); + + mIconList->verticalScrollBar()->installEventFilter( this ); + hbox->addWidget( mIconList ); + connect( mIconList, SIGNAL(selectionChanged()), SLOT(slotShowPage())); + hbox->addSpacing( ODialog::spacingHint() ); + page = new QFrame( this ); + hbox->addWidget( page, 10 ); + } + + // + // Rest of page area. Title at top with a separator below and a + // pagestack using all available space at bottom. + // + + QVBoxLayout *vbox = new QVBoxLayout( page, 0, ODialog::spacingHint() ); + + mTitleLabel = new QLabel( QString::fromLatin1("Empty page"), page, "OJanusWidgetTitleLabel" ); + vbox->addWidget( mTitleLabel ); + + QFont titleFont( mTitleLabel->font() ); + titleFont.setBold( true ); + mTitleLabel->setFont( titleFont ); + + mTitleSep = new OSeparator( page ); + mTitleSep->setFrameStyle( QFrame::HLine|QFrame::Plain ); + vbox->addWidget( mTitleSep ); + + mPageStack = new QWidgetStack( page ); + connect(mPageStack, SIGNAL(aboutToShow(QWidget *)), + this, SIGNAL(aboutToShowPage(QWidget *))); + vbox->addWidget( mPageStack, 10 ); + } + else if( mFace == Tabbed ) + { + mPageList = new QPtrList<QWidget>; + + mTabControl = new QTabWidget( this ); + mTabControl->setMargin (ODialog::marginHint()); + topLayout->addWidget( mTabControl, 10 ); + } + else if( mFace == Swallow ) + { + mSwallowPage = new QWidget( this ); + topLayout->addWidget( mSwallowPage, 10 ); + } + else + { + mFace = Plain; + mPlainPage = new QFrame( this ); + topLayout->addWidget( mPlainPage, 10 ); + } + + /* FIXME: Revise for Opie + if ( kapp ) + connect(kapp,SIGNAL(kdisplayFontChanged()),SLOT(slotFontChanged())); + */ + + mValid = true; + + setSwallowedWidget(0); // Set default size if 'mFace' is Swallow. +} + + +OJanusWidget::~OJanusWidget() +{ + delete mPageList; + mPageList = 0; + delete mTitleList; + mTitleList = 0; +} + + +bool OJanusWidget::isValid() const +{ + return( mValid ); +} + + +QFrame *OJanusWidget::plainPage() +{ + return( mPlainPage ); +} + + +int OJanusWidget::face() const +{ + return( mFace ); +} + +QWidget *OJanusWidget::FindParent() +{ + if( mFace == Tabbed ) { + return mTabControl; + } + else { + return this; + } +} + +QFrame *OJanusWidget::addPage( const QStringList &items, const QString &header, + const QPixmap &pixmap ) +{ + if( mValid == false ) + { + qDebug( "addPage: Invalid object" ); + return( 0 ); + } + + QFrame *page = new QFrame( FindParent(), "page" ); + addPageWidget( page, items, header, pixmap ); + + return page; +} + +void OJanusWidget::pageGone( QObject *obj ) +{ + removePage( static_cast<QWidget*>( obj ) ); +} + +void OJanusWidget::slotReopen( QListViewItem * item ) +{ + if( item ) + item->setOpen( true ); +} + +QFrame *OJanusWidget::addPage( const QString &itemName, const QString &header, + const QPixmap &pixmap ) +{ + QStringList items; + items << itemName; + return addPage(items, header, pixmap); +} + + + +QVBox *OJanusWidget::addVBoxPage( const QStringList &items, + const QString &header, + const QPixmap &pixmap ) +{ + if( mValid == false ) + { + qDebug( "addPage: Invalid object" ); + return( 0 ); + } + + QVBox *page = new QVBox(FindParent() , "page" ); + page->setSpacing( ODialog::spacingHint() ); + addPageWidget( page, items, header, pixmap ); + + return page; +} + +QVBox *OJanusWidget::addVBoxPage( const QString &itemName, + const QString &header, + const QPixmap &pixmap ) +{ + QStringList items; + items << itemName; + return addVBoxPage(items, header, pixmap); +} + +QHBox *OJanusWidget::addHBoxPage( const QStringList &items, + const QString &header, + const QPixmap &pixmap ) +{ + if( mValid == false ) { + qDebug( "addPage: Invalid object" ); + return( 0 ); + } + + QHBox *page = new QHBox(FindParent(), "page"); + page->setSpacing( ODialog::spacingHint() ); + addPageWidget( page, items, header, pixmap ); + + return page; +} + +QHBox *OJanusWidget::addHBoxPage( const QString &itemName, + const QString &header, + const QPixmap &pixmap ) +{ + QStringList items; + items << itemName; + return addHBoxPage(items, header, pixmap); +} + +QGrid *OJanusWidget::addGridPage( int n, Orientation dir, + const QStringList &items, + const QString &header, + const QPixmap &pixmap ) +{ + if( mValid == false ) + { + qDebug( "addPage: Invalid object" ); + return( 0 ); + } + + QGrid *page = new QGrid( n, dir, FindParent(), "page" ); + page->setSpacing( ODialog::spacingHint() ); + addPageWidget( page, items, header, pixmap ); + + return page; +} + + +QGrid *OJanusWidget::addGridPage( int n, Orientation dir, + const QString &itemName, + const QString &header, + const QPixmap &pixmap ) +{ + QStringList items; + items << itemName; + return addGridPage(n, dir, items, header, pixmap); +} + +void OJanusWidget::InsertTreeListItem(const QStringList &items, const QPixmap &pixmap, QFrame *page) +{ + bool isTop = true; + QListViewItem *curTop = 0, *child, *last, *newChild; + unsigned int index = 1; + QStringList curPath; + + for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it, index++ ) { + QString name = (*it); + bool isPath = ( index != items.count() ); + + // Find the first child. + if (isTop) { + child = mTreeList->firstChild(); + } + else { + child = curTop->firstChild(); + } + + // Now search for a child with the current Name, and if it we doesn't + // find it, then remember the location of the last child. + for (last = 0; child && child->text(0) != name ; last = child, child = child->nextSibling()); + + if (last == 0 && child == 0) { + // This node didn't have any children at all, lets just insert the + // new child. + if (isTop) + newChild = new QListViewItem(mTreeList, name); + else + newChild = new QListViewItem(curTop, name); + + } + else if (child != 0) { + // we found the given name in this child. + if (!isPath) { + qDebug( "The element inserted was already in the TreeList box!" ); + return; + } + else { + // Ok we found the folder + newChild = child; + } + } + else { + // the node had some children, but we didn't find the given name + if (isTop) + newChild = new QListViewItem(mTreeList, last, name); + else + newChild = new QListViewItem(curTop, last, name); + } + + // Now make the element expandable if it is a path component, and make + // ready for next loop + if (isPath) { + newChild->setExpandable(true); + curTop = newChild; + isTop = false; + curPath << name; + + QString key = curPath.join("_/_"); + if (mFolderIconMap.contains(key)) { + QPixmap p = mFolderIconMap[key]; + newChild->setPixmap(0,p); + } + } + else { + if (mShowIconsInTreeList) { + newChild->setPixmap(0, pixmap); + } + mTreeListToPageStack.insert(newChild, page); + } + } +} + +void OJanusWidget::addPageWidget( QFrame *page, const QStringList &items, + const QString &header,const QPixmap &pixmap ) +{ + connect(page, SIGNAL(destroyed(QObject*)), SLOT(pageGone(QObject*))); + + if( mFace == Tabbed ) + { + mTabControl->addTab (page, items.last()); + mPageList->append (page); + } + else if( mFace == TreeList || mFace == IconList ) + { + mPageList->append( page ); + mPageStack->addWidget( page, 0 ); + + if (items.count() == 0) { + qDebug( "Invalid QStringList, with zero items" ); + return; + } + + if( mFace == TreeList ) + { + InsertTreeListItem(items, pixmap, page); + } + else // mFace == IconList + { + QString itemName = items.last(); + IconListItem *item = new IconListItem( mIconList, pixmap, itemName ); + // + // 2000-06-01 Espen Sand: If I do this with Qt 2.1.1 all sorts of + // strange things happen. With Qt <= 2.1 it worked but now I must + // either specify the listbox in the constructor on the item + // or as below, not both. + // mIconList->insertItem( item ); + // + mIconListToPageStack.insert(item, page); + mIconList->invalidateHeight(); + mIconList->invalidateWidth(); + + if (mIconList->isVisible()) + mIconList->updateWidth(); + } + + // + // Make sure the title label is sufficiently wide + // + QString lastName = items.last(); + const QString &title = (header != QString::null ? header : lastName); + QRect r = mTitleLabel->fontMetrics().boundingRect( title ); + if( mTitleLabel->minimumWidth() < r.width() ) + { + mTitleLabel->setMinimumWidth( r.width() ); + } + mTitleList->append( title ); + + if( mTitleList->count() == 1 ) + { + showPage(0); + } + } + else + { + qDebug( "OJanusWidget::addPageWidget: can only add a page in Tabbed, TreeList or IconList modes" ); + } + +} + +void OJanusWidget::setFolderIcon(const QStringList &path, const QPixmap &pixmap) +{ + QString key = path.join("_/_"); + mFolderIconMap.insert(key,pixmap); +} + + + +bool OJanusWidget::setSwallowedWidget( QWidget *widget ) +{ + if( mFace != Swallow || mValid == false ) + { + return( false ); + } + + // + // Remove current layout and make a new. + // + if( mSwallowPage->layout() != 0 ) + { + delete mSwallowPage->layout(); + } + QGridLayout *gbox = new QGridLayout( mSwallowPage, 1, 1, 0 ); + + // + // Hide old children + // + QObjectList *l = (QObjectList*)mSwallowPage->children(); // silence please + for( uint i=0; i < l->count(); i++ ) + { + QObject *o = l->at(i); + if( o->isWidgetType() ) + { + ((QWidget*)o)->hide(); + } + } + + // + // Add new child or make default size + // + if( widget == 0 ) + { + gbox->addRowSpacing(0,100); + gbox->addColSpacing(0,100); + mSwallowPage->setMinimumSize(100,100); + } + else + { + if( widget->parent() != mSwallowPage ) + { + widget->reparent( mSwallowPage, 0, QPoint(0,0) ); + } + gbox->addWidget(widget, 0, 0 ); + gbox->activate(); + mSwallowPage->setMinimumSize( widget->minimumSize() ); + } + + return( true ); +} + +bool OJanusWidget::slotShowPage() +{ + if( mValid == false ) + { + return( false ); + } + + if( mFace == TreeList ) + { + QListViewItem *node = mTreeList->selectedItem(); + if( node == 0 ) { return( false ); } + + QWidget *stackItem = mTreeListToPageStack[node]; + return showPage(stackItem); + } + else if( mFace == IconList ) + { + QListBoxItem *node = mIconList->item( mIconList->currentItem() ); + if( node == 0 ) { return( false ); } + QWidget *stackItem = mIconListToPageStack[node]; + return showPage(stackItem); + } + + return( false ); +} + + +bool OJanusWidget::showPage( int index ) +{ + if( mPageList == 0 || mValid == false ) + { + return( false ); + } + else + { + return showPage(mPageList->at(index)); + } +} + + +bool OJanusWidget::showPage( QWidget *w ) +{ + if( w == 0 || mValid == false ) + { + return( false ); + } + + if( mFace == TreeList || mFace == IconList ) + { + mPageStack->raiseWidget( w ); + mActivePageWidget = w; + + int index = mPageList->findRef( w ); + mTitleLabel->setText( *mTitleList->at(index) ); + if( mFace == TreeList ) + { + QMap<QListViewItem *, QWidget *>::Iterator it; + for (it = mTreeListToPageStack.begin(); it != mTreeListToPageStack.end(); ++it){ + QListViewItem *key = it.key(); + QWidget *val = it.data(); + if (val == w) { + mTreeList->setSelected(key, true ); + break; + } + } + } + else + { + QMap<QListBoxItem *, QWidget *>::Iterator it; + for (it = mIconListToPageStack.begin(); it != mIconListToPageStack.end(); ++it){ + QListBoxItem *key = it.key(); + QWidget *val = it.data(); + if (val == w) { + mIconList->setSelected( key, true ); + break; + } + } + + // + // 2000-02-13 Espen Sand + // Don't ask me why (because I don't know). If I select a page + // with the mouse the page is not updated until it receives an + // event. It seems this event get lost if the mouse is not moved + // when released. The timer ensures the update + // + QTimer::singleShot( 0, mActivePageWidget, SLOT(update()) ); + } + } + else if( mFace == Tabbed ) + { + mTabControl->showPage(w); + mActivePageWidget = w; + } + else + { + return( false ); + } + + return( true ); +} + + +int OJanusWidget::activePageIndex() const +{ + if( mFace == TreeList) { + QListViewItem *node = mTreeList->selectedItem(); + if( node == 0 ) { return -1; } + QWidget *stackItem = mTreeListToPageStack[node]; + return mPageList->findRef(stackItem); + } + else if (mFace == IconList) { + QListBoxItem *node = mIconList->item( mIconList->currentItem() ); + if( node == 0 ) { return( false ); } + QWidget *stackItem = mIconListToPageStack[node]; + return mPageList->findRef(stackItem); + } + else if( mFace == Tabbed ) { + QWidget *widget = mTabControl->currentPage(); + return( widget == 0 ? -1 : mPageList->findRef( widget ) ); + } + else { + return( -1 ); + } +} + + +int OJanusWidget::pageIndex( QWidget *widget ) const +{ + if( widget == 0 ) + { + return( -1 ); + } + else if( mFace == TreeList || mFace == IconList ) + { + return( mPageList->findRef( widget ) ); + } + else if( mFace == Tabbed ) + { + // + // The user gets the real page widget with addVBoxPage(), addHBoxPage() + // and addGridPage() but not with addPage() which returns a child of + // the toplevel page. addPage() returns a QFrame so I check for that. + // + if( widget->isA("QFrame") ) + { + return( mPageList->findRef( widget->parentWidget() ) ); + } + else + { + return( mPageList->findRef( widget ) ); + } + } + else + { + return( -1 ); + } +} + +void OJanusWidget::slotFontChanged() +{ +#ifdef FIXME + + if ( mTitleLabel != 0 ) + { + mTitleLabel->setFont( KGlobalSettings::generalFont() ); + QFont titleFont( mTitleLabel->font() ); + titleFont.setBold( true ); + mTitleLabel->setFont( titleFont ); + } +#endif + + if( mFace == IconList ) + { + QFont listFont( mIconList->font() ); + listFont.setBold( true ); + mIconList->setFont( listFont ); + mIconList->invalidateHeight(); + mIconList->invalidateWidth(); + } +} + +// makes the treelist behave like the list of kcontrol +void OJanusWidget::slotItemClicked(QListViewItem *it) +{ + if(it && (it->childCount()>0)) + it->setOpen(!it->isOpen()); +} + +void OJanusWidget::setFocus() +{ + if( mValid == false ) { return; } + if( mFace == TreeList ) + { + mTreeList->setFocus(); + } + if( mFace == IconList ) + { + mIconList->setFocus(); + } + else if( mFace == Tabbed ) + { + mTabControl->setFocus(); + } + else if( mFace == Swallow ) + { + mSwallowPage->setFocus(); + } + else if( mFace == Plain ) + { + mPlainPage->setFocus(); + } +} + + +QSize OJanusWidget::minimumSizeHint() const +{ + if( mFace == TreeList || mFace == IconList ) + { + QSize s1( ODialog::spacingHint(), ODialog::spacingHint()*2 ); + QSize s2(0,0); + QSize s3(0,0); + QSize s4( mPageStack->sizeHint() ); + + if( mFace == TreeList ) + { +#if QT_VERSION < 300 + s1.rwidth() += style().splitterWidth(); +#else + s1.rwidth() += style().pixelMetric( QStyle::PM_SplitterWidth ); +#endif + s2 = mTreeList->minimumSize(); + } + else + { + mIconList->updateMinimumHeight(); + mIconList->updateWidth(); + s2 = mIconList->minimumSize(); + } + + if( mTitleLabel->isVisible() == true ) + { + s3 += mTitleLabel->sizeHint(); + s3.rheight() += mTitleSep->minimumSize().height(); + } + + // + // Select the tallest item. It has only effect in IconList mode + // + int h1 = s1.rheight() + s3.rheight() + s4.height(); + int h2 = QMAX( h1, s2.rheight() ); + + return( QSize( s1.width()+s2.width()+QMAX(s3.width(),s4.width()), h2 ) ); + } + else if( mFace == Tabbed ) + { + return( mTabControl->sizeHint() ); + } + else if( mFace == Swallow ) + { + return( mSwallowPage->minimumSize() ); + } + else if( mFace == Plain ) + { + return( mPlainPage->sizeHint() ); + } + else + { + return( QSize( 100, 100 ) ); // Should never happen though. + } + +} + + +QSize OJanusWidget::sizeHint() const +{ + return( minimumSizeHint() ); +} + + +void OJanusWidget::setTreeListAutoResize( bool state ) +{ + if( mFace == TreeList ) + { + mTreeListResizeMode = state == false ? + QSplitter::KeepSize : QSplitter::Stretch; + QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget()); + splitter->setResizeMode( mTreeList, mTreeListResizeMode ); + } +} + + +void OJanusWidget::setIconListAllVisible( bool state ) +{ + if( mFace == IconList ) + { + mIconList->setShowAll( state ); + } +} + +void OJanusWidget::setShowIconsInTreeList( bool state ) +{ + mShowIconsInTreeList = state; +} + +void OJanusWidget::setRootIsDecorated( bool state ) +{ + if( mFace == TreeList ) { + mTreeList->setRootIsDecorated(state); + } +} + +void OJanusWidget::unfoldTreeList( bool persist ) +{ + if( mFace == TreeList ) + { + if( persist ) + connect( mTreeList, SIGNAL( collapsed( QListViewItem * ) ), this, SLOT( slotReopen( QListViewItem * ) ) ); + else + disconnect( mTreeList, SIGNAL( collapsed( QListViewItem * ) ), this, SLOT( slotReopen( QListViewItem * ) ) ); + + for( QListViewItem * item = mTreeList->firstChild(); item; item = item->itemBelow() ) + item->setOpen( true ); + } +} + +void OJanusWidget::showEvent( QShowEvent * ) +{ + if( mFace == TreeList ) + { + QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget()); + splitter->setResizeMode( mTreeList, mTreeListResizeMode ); + } +} + + +// +// 2000-13-02 Espen Sand +// It should be obvious that this eventfilter must only be +// be installed on the vertical scrollbar of the mIconList. +// +bool OJanusWidget::eventFilter( QObject *o, QEvent *e ) +{ + if( e->type() == QEvent::Show ) + { + IconListItem *item = (IconListItem*)mIconList->item(0); + if( item != 0 ) + { + int lw = item->width( mIconList ); + int sw = mIconList->verticalScrollBar()->sizeHint().width(); + mIconList->setFixedWidth( lw+sw+mIconList->frameWidth()*2 ); + } + } + else if( e->type() == QEvent::Hide ) + { + IconListItem *item = (IconListItem*)mIconList->item(0); + if( item != 0 ) + { + int lw = item->width( mIconList ); + mIconList->setFixedWidth( lw+mIconList->frameWidth()*2 ); + } + } + return QWidget::eventFilter( o, e ); +} + + + +// +// Code for the icon list box +// + + +OJanusWidget::IconListBox::IconListBox( QWidget *parent, const char *name, + WFlags f ) + :QListBox( parent, name, f ), mShowAll(false), mHeightValid(false), + mWidthValid(false) +{ +} + + +void OJanusWidget::IconListBox::updateMinimumHeight() +{ + if( mShowAll == true && mHeightValid == false ) + { + int h = frameWidth()*2; + for( QListBoxItem *i = item(0); i != 0; i = i->next() ) + { + h += i->height( this ); + } + setMinimumHeight( h ); + mHeightValid = true; + } +} + + +void OJanusWidget::IconListBox::updateWidth() +{ + if( mWidthValid == false ) + { + int maxWidth = 10; + for( QListBoxItem *i = item(0); i != 0; i = i->next() ) + { + int w = ((IconListItem *)i)->width(this); + maxWidth = QMAX( w, maxWidth ); + } + + for( QListBoxItem *i = item(0); i != 0; i = i->next() ) + { + ((IconListItem *)i)->expandMinimumWidth( maxWidth ); + } + + if( verticalScrollBar()->isVisible() ) + { + maxWidth += verticalScrollBar()->sizeHint().width(); + } + + setFixedWidth( maxWidth + frameWidth()*2 ); + mWidthValid = true; + } +} + + +void OJanusWidget::IconListBox::invalidateHeight() +{ + mHeightValid = false; +} + + +void OJanusWidget::IconListBox::invalidateWidth() +{ + mWidthValid = false; +} + + +void OJanusWidget::IconListBox::setShowAll( bool showAll ) +{ + mShowAll = showAll; + mHeightValid = false; +} + + + +OJanusWidget::IconListItem::IconListItem( QListBox *listbox, const QPixmap &pixmap, + const QString &text ) + : QListBoxItem( listbox ) +{ + mPixmap = pixmap; + if( mPixmap.isNull() == true ) + { + mPixmap = defaultPixmap(); + } + setText( text ); + mMinimumWidth = 0; +} + + +int OJanusWidget::IconListItem::expandMinimumWidth( int width ) +{ + mMinimumWidth = QMAX( mMinimumWidth, width ); + return( mMinimumWidth ); +} + + +const QPixmap &OJanusWidget::IconListItem::defaultPixmap() +{ + static QPixmap *pix=0; + if( pix == 0 ) + { + pix = new QPixmap( 32, 32 ); + QPainter p( pix ); + p.eraseRect( 0, 0, pix->width(), pix->height() ); + p.setPen( Qt::red ); + p.drawRect ( 0, 0, pix->width(), pix->height() ); + p.end(); + + QBitmap mask( pix->width(), pix->height(), true ); + mask.fill( Qt::black ); + p.begin( &mask ); + p.setPen( Qt::white ); + p.drawRect ( 0, 0, pix->width(), pix->height() ); + p.end(); + + pix->setMask( mask ); + } + return( *pix ); +} + + +void OJanusWidget::IconListItem::paint( QPainter *painter ) +{ + QFontMetrics fm = painter->fontMetrics(); + //int wt = fm.boundingRect(text()).width(); + int wp = mPixmap.width(); + int ht = fm.lineSpacing(); + int hp = mPixmap.height(); + + painter->drawPixmap( (mMinimumWidth-wp)/2, 5, mPixmap ); + if( text().isEmpty() == false ) + { + painter->drawText( 0, hp+7, mMinimumWidth, ht, Qt::AlignCenter, text() ); + } +} + +int OJanusWidget::IconListItem::height( const QListBox *lb ) const +{ + if( text().isEmpty() == true ) + { + return( mPixmap.height() ); + } + else + { + return( mPixmap.height() + lb->fontMetrics().lineSpacing()+10 ); + } +} + + +int OJanusWidget::IconListItem::width( const QListBox *lb ) const +{ + int wt = lb->fontMetrics().boundingRect(text()).width()+10; + int wp = mPixmap.width() + 10; + int w = QMAX( wt, wp ); + return( QMAX( w, mMinimumWidth ) ); +} + +// Just remove the page from our stack of widgets. Do not modify the given widget in +// any way. No memory leak occurs as parent is not changed. +// Make this virtual in KDE 4.0. +// Ravikiran Rajagopal <ravi@ee.eng.ohio-state.edu> +void OJanusWidget::removePage( QWidget *page ) +{ + if (!mPageList || !mPageList->containsRef(page)) + return; + + int index = mPageList->findRef( page ); + if ( mTitleList ) + mTitleList->remove(mTitleList->at(index)); + + mPageList->removeRef(page); + + if ( mFace == TreeList ) + { + QMap<QListViewItem*, QWidget *>::Iterator i; + for( i = mTreeListToPageStack.begin(); i != mTreeListToPageStack.end(); ++i ) + if (i.data()==page) + { + delete i.key(); + mPageStack->removeWidget(page); + mTreeListToPageStack.remove(i); + break; + } + } + else if ( mFace == IconList ) + { + QMap<QListBoxItem*, QWidget *>::Iterator i; + for( i = mIconListToPageStack.begin(); i != mIconListToPageStack.end(); ++i ) + if (i.data()==page) + { + delete i.key(); + mPageStack->removeWidget(page); + mIconListToPageStack.remove(i); + break; + } + } + else // Tabbed + { + mTabControl->removePage(page); + } +} |