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