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