kdeui Library API Documentation

kjanuswidget.cpp

00001 /*  This file is part of the KDE Libraries
00002  *  Copyright (C) 1999-2000 Espen Sand (espensa@online.no)
00003  *
00004  *  This library is free software; you can redistribute it and/or
00005  *  modify it under the terms of the GNU Library General Public
00006  *  License as published by the Free Software Foundation; either
00007  *  version 2 of the License, or (at your option) any later version.
00008  *
00009  *  This library is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  *  Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Library General Public License
00015  *  along with this library; see the file COPYING.LIB.  If not, write to
00016  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  *  Boston, MA 02111-1307, USA.
00018  */
00019 
00020 #include <qbitmap.h>
00021 #include <qgrid.h>
00022 #include <qhbox.h>
00023 #include <qheader.h>
00024 #include <qlabel.h>
00025 #include <qlayout.h>
00026 #include <qobjectlist.h>
00027 #include <qpixmap.h>
00028 #include <qsplitter.h>
00029 #include <qtabwidget.h>
00030 #include <qvbox.h>
00031 #include <qwidgetstack.h>
00032 #include <qpainter.h>
00033 #include <qstyle.h>
00034 
00035 #include <kapplication.h>
00036 #include <kdialog.h> // Access to some static members
00037 #include <klocale.h>
00038 #include <kglobal.h>
00039 #include <kglobalsettings.h>
00040 #include <kseparator.h>
00041 #include <kdebug.h>
00042 #include "kjanuswidget.h"
00043 #include <klistview.h>
00044 
00045 class KJanusWidget::IconListItem : public QListBoxItem
00046 {
00047   public:
00048     IconListItem( QListBox *listbox, const QPixmap &pixmap,
00049                    const QString &text );
00050     virtual int height( const QListBox *lb ) const;
00051     virtual int width( const QListBox *lb ) const;
00052     int expandMinimumWidth( int width );
00053 
00054   protected:
00055     const QPixmap &defaultPixmap();
00056     void paint( QPainter *painter );
00057 
00058   private:
00059     QPixmap mPixmap;
00060     int mMinimumWidth;
00061 };
00062 
00063 // Added to make sure that the indices returned by KJanusWidget::pageIndex()
00064 // remain constant and safe to store.
00065 // Ravi <ravi@ee.eng.ohio-state.edu> Sun Feb 23 2003
00066 class KJanusWidget::KJanusWidgetPrivate
00067 {
00068 public:
00069   KJanusWidgetPrivate() : mNextPageIndex(0) { }
00070 
00071   int mNextPageIndex; // The next page index.
00072 
00073   // Dictionary for multipage modes.
00074   QMap<int,QWidget*> mIntToPage;
00075   // Reverse dictionary. Used because showPage() may be performance critical.
00076   QMap<QWidget*,int> mPageToInt;
00077   // Dictionary of title string associated with page.
00078   QMap<int, QString> mIntToTitle;
00079 };
00080 
00081 template class QPtrList<QListViewItem>;
00082 
00083 
00084 KJanusWidget::KJanusWidget( QWidget *parent, const char *name, int face )
00085   : QWidget( parent, name, 0 ),
00086     mValid(false), mPageList(0),
00087     mTitleList(0), mFace(face), mTitleLabel(0), mActivePageWidget(0),
00088     mShowIconsInTreeList(false), d(0)
00089 {
00090   QVBoxLayout *topLayout = new QVBoxLayout( this );
00091 
00092   if( mFace == TreeList || mFace == IconList )
00093   {
00094     d = new KJanusWidgetPrivate;
00095 
00096     QFrame *page;
00097     if( mFace == TreeList )
00098     {
00099       QSplitter *splitter = new QSplitter( this );
00100       topLayout->addWidget( splitter, 10 );
00101       mTreeListResizeMode = QSplitter::KeepSize;
00102 
00103       mTreeList = new KListView( splitter );
00104       mTreeList->addColumn( QString::fromLatin1("") );
00105       mTreeList->header()->hide();
00106       mTreeList->setRootIsDecorated(true);
00107       mTreeList->setSorting( -1 );
00108       connect( mTreeList, SIGNAL(selectionChanged()), SLOT(slotShowPage()) );
00109       connect( mTreeList, SIGNAL(clicked(QListViewItem *)), SLOT(slotItemClicked(QListViewItem *)));
00110 
00111       //
00112       // Page area. Title at top with a separator below and a pagestack using
00113       // all available space at bottom.
00114       //
00115       QFrame *p = new QFrame( splitter );
00116 
00117       QHBoxLayout *hbox = new QHBoxLayout( p, 0, 0 );
00118       hbox->addSpacing( KDialog::spacingHint() );
00119 
00120       page = new QFrame( p );
00121       hbox->addWidget( page, 10 );
00122     }
00123     else
00124     {
00125       QHBoxLayout *hbox = new QHBoxLayout( topLayout );
00126       mIconList = new IconListBox( this );
00127 
00128       QFont listFont( mIconList->font() );
00129       listFont.setBold( true );
00130       mIconList->setFont( listFont );
00131 
00132       mIconList->verticalScrollBar()->installEventFilter( this );
00133       hbox->addWidget( mIconList );
00134       connect( mIconList, SIGNAL(selectionChanged()), SLOT(slotShowPage()));
00135       hbox->addSpacing( KDialog::spacingHint() );
00136       page = new QFrame( this );
00137       hbox->addWidget( page, 10 );
00138     }
00139 
00140     //
00141     // Rest of page area. Title at top with a separator below and a
00142     // pagestack using all available space at bottom.
00143     //
00144 
00145     QVBoxLayout *vbox = new QVBoxLayout( page, 0, KDialog::spacingHint() );
00146 
00147     mTitleLabel = new QLabel( QString::fromLatin1("Empty page"), page, "KJanusWidgetTitleLabel" );
00148     vbox->addWidget( mTitleLabel );
00149 
00150     QFont titleFont( mTitleLabel->font() );
00151     titleFont.setBold( true );
00152     mTitleLabel->setFont( titleFont );
00153 
00154     mTitleSep = new KSeparator( page );
00155     mTitleSep->setFrameStyle( QFrame::HLine|QFrame::Plain );
00156     vbox->addWidget( mTitleSep );
00157 
00158     mPageStack = new QWidgetStack( page );
00159     connect(mPageStack, SIGNAL(aboutToShow(QWidget *)),
00160             this, SIGNAL(aboutToShowPage(QWidget *)));
00161     vbox->addWidget( mPageStack, 10 );
00162   }
00163   else if( mFace == Tabbed )
00164   {
00165     d = new KJanusWidgetPrivate;
00166 
00167     mTabControl = new QTabWidget( this );
00168     mTabControl->setMargin (KDialog::marginHint());
00169     topLayout->addWidget( mTabControl, 10 );
00170   }
00171   else if( mFace == Swallow )
00172   {
00173     mSwallowPage = new QWidget( this );
00174     topLayout->addWidget( mSwallowPage, 10 );
00175   }
00176   else
00177   {
00178     mFace = Plain;
00179     mPlainPage = new QFrame( this );
00180     topLayout->addWidget( mPlainPage, 10 );
00181   }
00182 
00183   if ( kapp )
00184     connect(kapp,SIGNAL(kdisplayFontChanged()),SLOT(slotFontChanged()));
00185   mValid = true;
00186 
00187   setSwallowedWidget(0); // Set default size if 'mFace' is Swallow.
00188 }
00189 
00190 
00191 KJanusWidget::~KJanusWidget()
00192 {
00193   delete d;
00194 }
00195 
00196 
00197 bool KJanusWidget::isValid() const
00198 {
00199   return( mValid );
00200 }
00201 
00202 
00203 QFrame *KJanusWidget::plainPage()
00204 {
00205   return( mPlainPage );
00206 }
00207 
00208 
00209 int KJanusWidget::face() const
00210 {
00211   return( mFace );
00212 }
00213 
00214 QWidget *KJanusWidget::FindParent()
00215 {
00216   if( mFace == Tabbed ) {
00217     return mTabControl;
00218   }
00219   else {
00220     return this;
00221   }
00222 }
00223 
00224 QFrame *KJanusWidget::addPage( const QStringList &items, const QString &header,
00225                                const QPixmap &pixmap )
00226 {
00227   if( mValid == false )
00228   {
00229     kdDebug() << "addPage: Invalid object" << endl;
00230     return( 0 );
00231   }
00232 
00233   QFrame *page = new QFrame( FindParent(), "page" );
00234   addPageWidget( page, items, header, pixmap );
00235 
00236   return page;
00237 }
00238 
00239 void KJanusWidget::pageGone( QObject *obj )
00240 {
00241   removePage( static_cast<QWidget*>( obj ) );
00242 }
00243 
00244 QFrame *KJanusWidget::addPage( const QString &itemName, const QString &header,
00245                                const QPixmap &pixmap )
00246 {
00247   QStringList items;
00248   items << itemName;
00249   return addPage(items, header, pixmap);
00250 }
00251 
00252 
00253 
00254 QVBox *KJanusWidget::addVBoxPage( const QStringList &items,
00255                                   const QString &header,
00256                                   const QPixmap &pixmap )
00257 {
00258   if( mValid == false )
00259   {
00260     kdDebug() << "addPage: Invalid object" << endl;
00261     return( 0 );
00262   }
00263 
00264   QVBox *page = new QVBox(FindParent() , "page" );
00265   page->setSpacing( KDialog::spacingHint() );
00266   addPageWidget( page, items, header, pixmap );
00267 
00268   return page;
00269 }
00270 
00271 QVBox *KJanusWidget::addVBoxPage( const QString &itemName,
00272                                   const QString &header,
00273                                   const QPixmap &pixmap )
00274 {
00275   QStringList items;
00276   items << itemName;
00277   return addVBoxPage(items, header, pixmap);
00278 }
00279 
00280 QHBox *KJanusWidget::addHBoxPage( const QStringList &items,
00281                                   const QString &header,
00282                                   const QPixmap &pixmap )
00283 {
00284   if( mValid == false ) {
00285     kdDebug() << "addPage: Invalid object" << endl;
00286     return( 0 );
00287   }
00288 
00289   QHBox *page = new QHBox(FindParent(), "page");
00290   page->setSpacing( KDialog::spacingHint() );
00291   addPageWidget( page, items, header, pixmap );
00292 
00293   return page;
00294 }
00295 
00296 QHBox *KJanusWidget::addHBoxPage( const QString &itemName,
00297                                   const QString &header,
00298                                   const QPixmap &pixmap )
00299 {
00300   QStringList items;
00301   items << itemName;
00302   return addHBoxPage(items, header, pixmap);
00303 }
00304 
00305 QGrid *KJanusWidget::addGridPage( int n, Orientation dir,
00306                                   const QStringList &items,
00307                                   const QString &header,
00308                                   const QPixmap &pixmap )
00309 {
00310   if( mValid == false )
00311   {
00312     kdDebug() << "addPage: Invalid object" << endl;
00313     return( 0 );
00314   }
00315 
00316   QGrid *page = new QGrid( n, dir, FindParent(), "page" );
00317   page->setSpacing( KDialog::spacingHint() );
00318   addPageWidget( page, items, header, pixmap );
00319 
00320   return page;
00321 }
00322 
00323 
00324 QGrid *KJanusWidget::addGridPage( int n, Orientation dir,
00325                                   const QString &itemName,
00326                                   const QString &header,
00327                                   const QPixmap &pixmap )
00328 {
00329   QStringList items;
00330   items << itemName;
00331   return addGridPage(n, dir, items, header, pixmap);
00332 }
00333 
00334 void KJanusWidget::InsertTreeListItem(const QStringList &items, const QPixmap &pixmap, QFrame *page)
00335 {
00336   bool isTop = true;
00337   QListViewItem *curTop = 0, *child, *last, *newChild;
00338   unsigned int index = 1;
00339   QStringList curPath;
00340 
00341   for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it, index++ ) {
00342     QString name = (*it);
00343     bool isPath = ( index != items.count() );
00344 
00345     // Find the first child.
00346     if (isTop) {
00347       child = mTreeList->firstChild();
00348     }
00349     else {
00350       child = curTop->firstChild();
00351     }
00352 
00353     // Now search for a child with the current Name, and if it we doesn't
00354     // find it, then remember the location of the last child.
00355     for (last = 0; child && child->text(0) != name ; last = child, child = child->nextSibling());
00356 
00357     if (last == 0 && child == 0) {
00358       // This node didn't have any children at all, lets just insert the
00359       // new child.
00360       if (isTop)
00361         newChild = new QListViewItem(mTreeList, name);
00362       else
00363         newChild = new QListViewItem(curTop, name);
00364 
00365     }
00366     else if (child != 0) {
00367       // we found the given name in this child.
00368       if (!isPath) {
00369         kdDebug() << "The element inserted was already in the TreeList box!" << endl;
00370         return;
00371       }
00372       else {
00373         // Ok we found the folder
00374         newChild  = child;
00375       }
00376     }
00377     else {
00378       // the node had some children, but we didn't find the given name
00379       if (isTop)
00380         newChild = new QListViewItem(mTreeList, last, name);
00381       else
00382         newChild = new QListViewItem(curTop, last, name);
00383     }
00384 
00385     // Now make the element expandable if it is a path component, and make
00386     // ready for next loop
00387     if (isPath) {
00388       newChild->setExpandable(true);
00389       curTop = newChild;
00390       isTop = false;
00391       curPath << name;
00392 
00393       QString key = curPath.join("_/_");
00394       if (mFolderIconMap.contains(key)) {
00395         QPixmap p = mFolderIconMap[key];
00396         newChild->setPixmap(0,p);
00397       }
00398     }
00399     else {
00400       if (mShowIconsInTreeList) {
00401         newChild->setPixmap(0, pixmap);
00402       }
00403       mTreeListToPageStack.insert(newChild, page);
00404     }
00405   }
00406 }
00407 
00408 void KJanusWidget::addPageWidget( QFrame *page, const QStringList &items,
00409                                   const QString &header,const QPixmap &pixmap )
00410 {
00411   connect(page, SIGNAL(destroyed(QObject*)), SLOT(pageGone(QObject*)));
00412 
00413   if( mFace == Tabbed )
00414   {
00415     mTabControl->addTab (page, items.last());
00416     d->mIntToPage[d->mNextPageIndex] = static_cast<QWidget*>(page);
00417     d->mPageToInt[static_cast<QWidget*>(page)] = d->mNextPageIndex;
00418     d->mNextPageIndex++;
00419   }
00420   else if( mFace == TreeList || mFace == IconList )
00421   {
00422     d->mIntToPage[d->mNextPageIndex] = static_cast<QWidget*>(page);
00423     d->mPageToInt[static_cast<QWidget*>(page)] = d->mNextPageIndex;
00424     mPageStack->addWidget( page, 0 );
00425 
00426     if (items.count() == 0) {
00427       kdDebug() << "Invalid QStringList, with zero items" << endl;
00428       return;
00429     }
00430 
00431     if( mFace == TreeList )
00432     {
00433       InsertTreeListItem(items, pixmap, page);
00434     }
00435     else // mFace == IconList
00436     {
00437       QString itemName = items.last();
00438       IconListItem *item = new IconListItem( mIconList, pixmap, itemName );
00439       //
00440       // 2000-06-01 Espen Sand: If I do this with Qt 2.1.1 all sorts of
00441       // strange things happen. With Qt <= 2.1 it worked but now I must
00442       // either specify the listbox in the constructor on the item
00443       // or as below, not both.
00444       // mIconList->insertItem( item );
00445       //
00446       mIconListToPageStack.insert(item, page);
00447       mIconList->invalidateHeight();
00448       mIconList->invalidateWidth();
00449 
00450       if (mIconList->isVisible())
00451         mIconList->updateWidth();
00452     }
00453 
00454     //
00455     // Make sure the title label is sufficiently wide
00456     //
00457     QString lastName = items.last();
00458     const QString &title = (header != QString::null ? header : lastName);
00459     QRect r = mTitleLabel->fontMetrics().boundingRect( title );
00460     if( mTitleLabel->minimumWidth() < r.width() )
00461     {
00462       mTitleLabel->setMinimumWidth( r.width() );
00463     }
00464     d->mIntToTitle[d->mNextPageIndex] = title;
00465     if( d->mIntToTitle.count() == 1 )
00466     {
00467       showPage(0);
00468     }
00469     d->mNextPageIndex++;
00470   }
00471   else
00472   {
00473     kdDebug() << "KJanusWidget::addPageWidget: can only add a page in Tabbed, TreeList or IconList modes" << endl;
00474   }
00475 
00476 }
00477 
00478 void KJanusWidget::setFolderIcon(const QStringList &path, const QPixmap &pixmap)
00479 {
00480   QString key = path.join("_/_");
00481   mFolderIconMap.insert(key,pixmap);
00482 }
00483 
00484 
00485 
00486 bool KJanusWidget::setSwallowedWidget( QWidget *widget )
00487 {
00488   if( mFace != Swallow || mValid == false )
00489   {
00490     return( false );
00491   }
00492 
00493   //
00494   // Remove current layout and make a new.
00495   //
00496   if( mSwallowPage->layout() != 0 )
00497   {
00498     delete mSwallowPage->layout();
00499   }
00500   QGridLayout *gbox = new QGridLayout( mSwallowPage, 1, 1, 0 );
00501 
00502   //
00503   // Hide old children
00504   //
00505   QObjectList *l = (QObjectList*)mSwallowPage->children(); // silence please
00506   for( uint i=0; i < l->count(); i++ )
00507   {
00508     QObject *o = l->at(i);
00509     if( o->isWidgetType() )
00510     {
00511       ((QWidget*)o)->hide();
00512     }
00513   }
00514 
00515   //
00516   // Add new child or make default size
00517   //
00518   if( widget == 0 )
00519   {
00520     gbox->addRowSpacing(0,100);
00521     gbox->addColSpacing(0,100);
00522     mSwallowPage->setMinimumSize(100,100);
00523   }
00524   else
00525   {
00526     if( widget->parent() != mSwallowPage )
00527     {
00528       widget->reparent( mSwallowPage, 0, QPoint(0,0) );
00529     }
00530     gbox->addWidget(widget, 0, 0 );
00531     gbox->activate();
00532     mSwallowPage->setMinimumSize( widget->minimumSize() );
00533   }
00534 
00535   return( true );
00536 }
00537 
00538 bool KJanusWidget::slotShowPage()
00539 {
00540   if( mValid == false )
00541   {
00542     return( false );
00543   }
00544 
00545   if( mFace == TreeList )
00546   {
00547     QListViewItem *node = mTreeList->selectedItem();
00548     if( node == 0 ) { return( false ); }
00549 
00550     QWidget *stackItem = mTreeListToPageStack[node];
00551     return showPage(d->mPageToInt[stackItem]);
00552   }
00553   else if( mFace == IconList )
00554   {
00555     QListBoxItem *node = mIconList->item( mIconList->currentItem() );
00556     if( node == 0 ) { return( false ); }
00557     QWidget *stackItem = mIconListToPageStack[node];
00558     return showPage(d->mPageToInt[stackItem]);
00559   }
00560 
00561   return( false );
00562 }
00563 
00564 
00565 bool KJanusWidget::showPage( int index )
00566 {
00567   if( d == 0 || mValid == false )
00568   {
00569     return( false );
00570   }
00571   else
00572   {
00573     return showPage(d->mIntToPage[index]);
00574   }
00575 }
00576 
00577 
00578 bool KJanusWidget::showPage( QWidget *w )
00579 {
00580   if( w == 0 || mValid == false )
00581   {
00582     return( false );
00583   }
00584 
00585   if( mFace == TreeList || mFace == IconList )
00586   {
00587     mPageStack->raiseWidget( w );
00588     mActivePageWidget = w;
00589 
00590     int index = d->mPageToInt[w];
00591     mTitleLabel->setText( d->mIntToTitle[index] );
00592     if( mFace == TreeList )
00593     {
00594       QMap<QListViewItem *, QWidget *>::Iterator it;
00595       for (it = mTreeListToPageStack.begin(); it != mTreeListToPageStack.end(); ++it){
00596         QListViewItem *key = it.key();
00597         QWidget *val = it.data();
00598         if (val == w) {
00599           mTreeList->setSelected(key, true );
00600           break;
00601         }
00602       }
00603     }
00604     else
00605     {
00606       QMap<QListBoxItem *, QWidget *>::Iterator it;
00607       for (it = mIconListToPageStack.begin(); it != mIconListToPageStack.end(); ++it){
00608         QListBoxItem *key = it.key();
00609         QWidget *val = it.data();
00610         if (val == w) {
00611           mIconList->setSelected( key, true );
00612           break;
00613         }
00614       }
00615     }
00616   }
00617   else if( mFace == Tabbed )
00618   {
00619     mTabControl->showPage(w);
00620     mActivePageWidget = w;
00621   }
00622   else
00623   {
00624     return( false );
00625   }
00626 
00627   return( true );
00628 }
00629 
00630 
00631 int KJanusWidget::activePageIndex() const
00632 {
00633   if( mFace == TreeList) {
00634     QListViewItem *node = mTreeList->selectedItem();
00635     if( node == 0 ) { return -1; }
00636     QWidget *stackItem = mTreeListToPageStack[node];
00637     return d->mPageToInt[stackItem];
00638   }
00639   else if (mFace == IconList) {
00640     QListBoxItem *node = mIconList->item( mIconList->currentItem() );
00641     if( node == 0 ) { return( false ); }
00642     QWidget *stackItem = mIconListToPageStack[node];
00643     return d->mPageToInt[stackItem];
00644   }
00645   else if( mFace == Tabbed ) {
00646     QWidget *widget = mTabControl->currentPage();
00647     return( widget == 0 ? -1 : d->mPageToInt[widget] );
00648   }
00649   else {
00650     return( -1 );
00651   }
00652 }
00653 
00654 
00655 int KJanusWidget::pageIndex( QWidget *widget ) const
00656 {
00657   if( widget == 0 )
00658   {
00659     return( -1 );
00660   }
00661   else if( mFace == TreeList || mFace == IconList )
00662   {
00663     return( d->mPageToInt[widget] );
00664   }
00665   else if( mFace == Tabbed )
00666   {
00667     //
00668     // The user gets the real page widget with addVBoxPage(), addHBoxPage()
00669     // and addGridPage() but not with addPage() which returns a child of
00670     // the toplevel page. addPage() returns a QFrame so I check for that.
00671     //
00672     if( widget->isA("QFrame") )
00673     {
00674       return( d->mPageToInt[widget->parentWidget()] );
00675     }
00676     else
00677     {
00678       return( d->mPageToInt[widget] );
00679     }
00680   }
00681   else
00682   {
00683     return( -1 );
00684   }
00685 }
00686 
00687 void KJanusWidget::slotFontChanged()
00688 {
00689   if( mTitleLabel != 0 )
00690   {
00691     mTitleLabel->setFont( KGlobalSettings::generalFont() );
00692     QFont titleFont( mTitleLabel->font() );
00693     titleFont.setBold( true );
00694     mTitleLabel->setFont( titleFont );
00695   }
00696 
00697   if( mFace == IconList )
00698   {
00699     QFont listFont( mIconList->font() );
00700     listFont.setBold( true );
00701     mIconList->setFont( listFont );
00702     mIconList->invalidateHeight();
00703     mIconList->invalidateWidth();
00704   }
00705 }
00706 
00707 // makes the treelist behave like the list of kcontrol
00708 void KJanusWidget::slotItemClicked(QListViewItem *it)
00709 {
00710   if(it && (it->childCount()>0))
00711     it->setOpen(!it->isOpen());
00712 }
00713 
00714 void KJanusWidget::setFocus()
00715 {
00716   if( mValid == false ) { return; }
00717   if( mFace == TreeList )
00718   {
00719     mTreeList->setFocus();
00720   }
00721   if( mFace == IconList )
00722   {
00723     mIconList->setFocus();
00724   }
00725   else if( mFace == Tabbed )
00726   {
00727     mTabControl->setFocus();
00728   }
00729   else if( mFace == Swallow )
00730   {
00731     mSwallowPage->setFocus();
00732   }
00733   else if( mFace == Plain )
00734   {
00735     mPlainPage->setFocus();
00736   }
00737 }
00738 
00739 
00740 QSize KJanusWidget::minimumSizeHint() const
00741 {
00742   if( mFace == TreeList || mFace == IconList )
00743   {
00744     QSize s1( KDialog::spacingHint(), KDialog::spacingHint()*2 );
00745     QSize s2(0,0);
00746     QSize s3(0,0);
00747     QSize s4( mPageStack->sizeHint() );
00748 
00749     if( mFace == TreeList )
00750     {
00751 #if QT_VERSION < 300
00752       s1.rwidth() += style().splitterWidth();
00753 #else
00754       s1.rwidth() += style().pixelMetric( QStyle::PM_SplitterWidth );
00755 #endif
00756       s2 = mTreeList->minimumSize();
00757     }
00758     else
00759     {
00760       mIconList->updateMinimumHeight();
00761       mIconList->updateWidth();
00762       s2 = mIconList->minimumSize();
00763     }
00764 
00765     if( mTitleLabel->isVisible() == true )
00766     {
00767       s3 += mTitleLabel->sizeHint();
00768       s3.rheight() += mTitleSep->minimumSize().height();
00769     }
00770 
00771     //
00772     // Select the tallest item. It has only effect in IconList mode
00773     //
00774     int h1 = s1.rheight() + s3.rheight() + s4.height();
00775     int h2 = QMAX( h1, s2.rheight() );
00776 
00777     return( QSize( s1.width()+s2.width()+QMAX(s3.width(),s4.width()), h2 ) );
00778   }
00779   else if( mFace == Tabbed )
00780   {
00781     return( mTabControl->sizeHint() );
00782   }
00783   else if( mFace == Swallow )
00784   {
00785     return( mSwallowPage->minimumSize() );
00786   }
00787   else if( mFace == Plain )
00788   {
00789     return( mPlainPage->sizeHint() );
00790   }
00791   else
00792   {
00793     return( QSize( 100, 100 ) ); // Should never happen though.
00794   }
00795 
00796 }
00797 
00798 
00799 QSize KJanusWidget::sizeHint() const
00800 {
00801   return( minimumSizeHint() );
00802 }
00803 
00804 
00805 void KJanusWidget::setTreeListAutoResize( bool state )
00806 {
00807   if( mFace == TreeList )
00808   {
00809     mTreeListResizeMode = state == false ?
00810       QSplitter::KeepSize : QSplitter::Stretch;
00811     QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget());
00812     splitter->setResizeMode( mTreeList, mTreeListResizeMode );
00813   }
00814 }
00815 
00816 
00817 void KJanusWidget::setIconListAllVisible( bool state )
00818 {
00819   if( mFace == IconList )
00820   {
00821     mIconList->setShowAll( state );
00822   }
00823 }
00824 
00825 void KJanusWidget::setShowIconsInTreeList( bool state )
00826 {
00827   mShowIconsInTreeList = state;
00828 }
00829 
00830 void KJanusWidget::setRootIsDecorated( bool state )
00831 {
00832   if( mFace == TreeList ) {
00833     mTreeList->setRootIsDecorated(state);
00834   }
00835 }
00836 
00837 
00838 void KJanusWidget::showEvent( QShowEvent * )
00839 {
00840   if( mFace == TreeList )
00841   {
00842     QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget());
00843     splitter->setResizeMode( mTreeList, mTreeListResizeMode );
00844   }
00845 }
00846 
00847 
00848 //
00849 // 2000-13-02 Espen Sand
00850 // It should be obvious that this eventfilter must only be
00851 // be installed on the vertical scrollbar of the mIconList.
00852 //
00853 bool KJanusWidget::eventFilter( QObject *o, QEvent *e )
00854 {
00855   if( e->type() == QEvent::Show )
00856   {
00857     IconListItem *item = (IconListItem*)mIconList->item(0);
00858     if( item != 0 )
00859     {
00860       int lw = item->width( mIconList );
00861       int sw = mIconList->verticalScrollBar()->sizeHint().width();
00862       mIconList->setFixedWidth( lw+sw+mIconList->frameWidth()*2 );
00863     }
00864   }
00865   else if( e->type() == QEvent::Hide )
00866   {
00867     IconListItem *item = (IconListItem*)mIconList->item(0);
00868     if( item != 0 )
00869     {
00870       int lw = item->width( mIconList );
00871       mIconList->setFixedWidth( lw+mIconList->frameWidth()*2 );
00872     }
00873   }
00874   return QWidget::eventFilter( o, e );
00875 }
00876 
00877 
00878 
00879 //
00880 // Code for the icon list box
00881 //
00882 
00883 
00884 KJanusWidget::IconListBox::IconListBox( QWidget *parent, const char *name,
00885                                         WFlags f )
00886   :KListBox( parent, name, f ), mShowAll(false), mHeightValid(false),
00887    mWidthValid(false)
00888 {
00889 }
00890 
00891 
00892 void KJanusWidget::IconListBox::updateMinimumHeight()
00893 {
00894   if( mShowAll == true && mHeightValid == false )
00895   {
00896     int h = frameWidth()*2;
00897     for( QListBoxItem *i = item(0); i != 0; i = i->next() )
00898     {
00899       h += i->height( this );
00900     }
00901     setMinimumHeight( h );
00902     mHeightValid = true;
00903   }
00904 }
00905 
00906 
00907 void KJanusWidget::IconListBox::updateWidth()
00908 {
00909   if( mWidthValid == false )
00910   {
00911     int maxWidth = 10;
00912     for( QListBoxItem *i = item(0); i != 0; i = i->next() )
00913     {
00914       int w = ((IconListItem *)i)->width(this);
00915       maxWidth = QMAX( w, maxWidth );
00916     }
00917 
00918     for( QListBoxItem *i = item(0); i != 0; i = i->next() )
00919     {
00920       ((IconListItem *)i)->expandMinimumWidth( maxWidth );
00921     }
00922 
00923     if( verticalScrollBar()->isVisible() )
00924     {
00925       maxWidth += verticalScrollBar()->sizeHint().width();
00926     }
00927 
00928     setFixedWidth( maxWidth + frameWidth()*2 );
00929     mWidthValid = true;
00930   }
00931 }
00932 
00933 
00934 void KJanusWidget::IconListBox::invalidateHeight()
00935 {
00936   mHeightValid = false;
00937 }
00938 
00939 
00940 void KJanusWidget::IconListBox::invalidateWidth()
00941 {
00942   mWidthValid = false;
00943 }
00944 
00945 
00946 void KJanusWidget::IconListBox::setShowAll( bool showAll )
00947 {
00948   mShowAll = showAll;
00949   mHeightValid = false;
00950 }
00951 
00952 
00953 
00954 KJanusWidget::IconListItem::IconListItem( QListBox *listbox, const QPixmap &pixmap,
00955                                           const QString &text )
00956   : QListBoxItem( listbox )
00957 {
00958   mPixmap = pixmap;
00959   if( mPixmap.isNull() == true )
00960   {
00961     mPixmap = defaultPixmap();
00962   }
00963   setText( text );
00964   mMinimumWidth = 0;
00965 }
00966 
00967 
00968 int KJanusWidget::IconListItem::expandMinimumWidth( int width )
00969 {
00970   mMinimumWidth = QMAX( mMinimumWidth, width );
00971   return( mMinimumWidth );
00972 }
00973 
00974 
00975 const QPixmap &KJanusWidget::IconListItem::defaultPixmap()
00976 {
00977   static QPixmap *pix=0;
00978   if( pix == 0 )
00979   {
00980     pix = new QPixmap( 32, 32 );
00981     QPainter p( pix );
00982     p.eraseRect( 0, 0, pix->width(), pix->height() );
00983     p.setPen( Qt::red );
00984     p.drawRect ( 0, 0, pix->width(), pix->height() );
00985     p.end();
00986 
00987     QBitmap mask( pix->width(), pix->height(), true );
00988     mask.fill( Qt::black );
00989     p.begin( &mask );
00990     p.setPen( Qt::white );
00991     p.drawRect ( 0, 0, pix->width(), pix->height() );
00992     p.end();
00993 
00994     pix->setMask( mask );
00995   }
00996   return( *pix );
00997 }
00998 
00999 
01000 void KJanusWidget::IconListItem::paint( QPainter *painter )
01001 {
01002   QFontMetrics fm = painter->fontMetrics();
01003   //int wt = fm.boundingRect(text()).width();
01004   int wp = mPixmap.width();
01005   int ht = fm.lineSpacing();
01006   int hp = mPixmap.height();
01007 
01008   painter->drawPixmap( (mMinimumWidth-wp)/2, 5, mPixmap );
01009   if( text().isEmpty() == false )
01010   {
01011     painter->drawText( 0, hp+7, mMinimumWidth, ht, Qt::AlignCenter, text() );
01012   }
01013 }
01014 
01015 int KJanusWidget::IconListItem::height( const QListBox *lb ) const
01016 {
01017   if( text().isEmpty() == true )
01018   {
01019     return( mPixmap.height() );
01020   }
01021   else
01022   {
01023     return( mPixmap.height() + lb->fontMetrics().lineSpacing()+10 );
01024   }
01025 }
01026 
01027 
01028 int KJanusWidget::IconListItem::width( const QListBox *lb ) const
01029 {
01030   int wt = lb->fontMetrics().boundingRect(text()).width()+10;
01031   int wp = mPixmap.width() + 10;
01032   int w  = QMAX( wt, wp );
01033   return( QMAX( w, mMinimumWidth ) );
01034 }
01035 
01036 
01037 void KJanusWidget::virtual_hook( int, void* )
01038 { /*BASE::virtual_hook( id, data );*/ }
01039 
01040 // Just remove the page from our stack of widgets. Do not modify the given widget in
01041 // any way. No memory leak occurs as parent is not changed.
01042 // Make this virtual in KDE 4.0.
01043 // Ravikiran Rajagopal <ravi@ee.eng.ohio-state.edu>
01044 void KJanusWidget::removePage( QWidget *page )
01045 {
01046   if (!d || !d->mPageToInt.contains(page))
01047     return;
01048 
01049   int index = d->mPageToInt[page];
01050 
01051   if ( mFace == TreeList )
01052   {
01053     QMap<QListViewItem*, QWidget *>::Iterator i;
01054     for( i = mTreeListToPageStack.begin(); i != mTreeListToPageStack.end(); ++i )
01055       if (i.data()==page)
01056       {
01057         delete i.key();
01058         mPageStack->removeWidget(page);
01059         mTreeListToPageStack.remove(i);
01060         d->mIntToTitle.remove(index);
01061         d->mPageToInt.remove(page);
01062         d->mIntToPage.remove(index);
01063                 break;
01064       }
01065   }
01066   else if ( mFace == IconList )
01067   {
01068     QMap<QListBoxItem*, QWidget *>::Iterator i;
01069     for( i = mIconListToPageStack.begin(); i != mIconListToPageStack.end(); ++i )
01070       if (i.data()==page)
01071       {
01072         delete i.key();
01073         mPageStack->removeWidget(page);
01074         mIconListToPageStack.remove(i);
01075         d->mIntToTitle.remove(index);
01076         d->mPageToInt.remove(page);
01077         d->mIntToPage.remove(index);
01078                 break;
01079       }
01080   }
01081   else // Tabbed
01082   {
01083     mTabControl->removePage(page);
01084     d->mPageToInt.remove(page);
01085     d->mIntToPage.remove(index);
01086   }
01087 }
01088 
01089 #include "kjanuswidget.moc"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:56:56 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001