Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ojanuswidget.cpp

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

Generated on Sat Nov 5 16:16:29 2005 for OPIE by  doxygen 1.4.2