summaryrefslogtreecommitdiff
path: root/libopie2/qt3/opieui/ojanuswidget.cpp
Unidiff
Diffstat (limited to 'libopie2/qt3/opieui/ojanuswidget.cpp') (more/less context) (show whitespace changes)
-rw-r--r--libopie2/qt3/opieui/ojanuswidget.cpp1116
1 files changed, 1116 insertions, 0 deletions
diff --git a/libopie2/qt3/opieui/ojanuswidget.cpp b/libopie2/qt3/opieui/ojanuswidget.cpp
new file mode 100644
index 0000000..0a037ff
--- a/dev/null
+++ b/libopie2/qt3/opieui/ojanuswidget.cpp
@@ -0,0 +1,1116 @@
1/*
2                 This file is part of the Opie Project
3
4 Originally part of the KDE project
5 (C) 1999-2000 Espen Sand (espensa@online.no)
6 =.
7 .=l.
8           .>+-=
9 _;:,     .>    :=|. This program is free software; you can
10.> <`_,   >  .   <= redistribute it and/or modify it under
11:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
12.="- .-=="i,     .._ License as published by the Free Software
13 - .   .-<_>     .<> Foundation; either version 2 of the License,
14     ._= =}       : or (at your option) any later version.
15    .%`+i>       _;_.
16    .i_,=:_.      -<s. This program is distributed in the hope that
17     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
18    : ..    .:,     . . . without even the implied warranty of
19    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
20  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
21..}^=.=       =       ; Library General Public License for more
22++=   -.     .`     .: details.
23 :     =  ...= . :.=-
24 -.   .:....=;==+<; You should have received a copy of the GNU
25  -_. . .   )=.  = Library General Public License along with
26    --        :-=` this library; see the file COPYING.LIB.
27 If not, write to the Free Software Foundation,
28 Inc., 59 Temple Place - Suite 330,
29 Boston, MA 02111-1307, USA.
30
31*/
32
33/* QT */
34
35#include <qbitmap.h>
36#include <qgrid.h>
37#include <qhbox.h>
38#include <qheader.h>
39#include <qlabel.h>
40#include <qlayout.h>
41#include <qobjectlist.h>
42#include <qpixmap.h>
43#include <qlistview.h>
44#include <qsplitter.h>
45#include <qtabwidget.h>
46#include <qvbox.h>
47#include <qwidgetstack.h>
48#include <qpainter.h>
49#include <qtimer.h>
50#include <qstyle.h>
51
52/* OPIE */
53
54#include <opie2/odialog.h>
55#include <opie2/oseparator.h>
56#include <opie2/ojanuswidget.h>
57
58/*======================================================================================
59 * IconListItem
60 *======================================================================================*/
61
62class OJanusWidget::IconListItem : public QListBoxItem
63{
64 public:
65 IconListItem( QListBox *listbox, const QPixmap &pixmap,
66 const QString &text );
67 virtual int height( const QListBox *lb ) const;
68 virtual int width( const QListBox *lb ) const;
69 int expandMinimumWidth( int width );
70
71 protected:
72 const QPixmap &defaultPixmap();
73 void paint( QPainter *painter );
74
75 private:
76 QPixmap mPixmap;
77 int mMinimumWidth;
78};
79
80template class QPtrList<QListViewItem>;
81
82/*======================================================================================
83 * OJanusWidget
84 *======================================================================================*/
85
86OJanusWidget::OJanusWidget( QWidget *parent, const char *name, int face )
87 : QWidget( parent, name, 0 ),
88 mValid(false), mPageList(0),
89 mTitleList(0), mFace(face), mTitleLabel(0), mActivePageWidget(0),
90 mShowIconsInTreeList(false), d(0)
91{
92 QVBoxLayout *topLayout = new QVBoxLayout( this );
93
94 if( mFace == TreeList || mFace == IconList )
95 {
96 mPageList = new QPtrList<QWidget>;
97 mTitleList = new QStringList();
98
99 QFrame *page;
100 if( mFace == TreeList )
101 {
102 QSplitter *splitter = new QSplitter( this );
103 topLayout->addWidget( splitter, 10 );
104 mTreeListResizeMode = QSplitter::KeepSize;
105
106 mTreeList = new QListView( splitter );
107 mTreeList->addColumn( QString::fromLatin1("") );
108 mTreeList->header()->hide();
109 mTreeList->setRootIsDecorated(true);
110 mTreeList->setSorting( -1 );
111 connect( mTreeList, SIGNAL(selectionChanged()), SLOT(slotShowPage()) );
112 connect( mTreeList, SIGNAL(clicked(QListViewItem *)), SLOT(slotItemClicked(QListViewItem *)));
113
114 //
115 // Page area. Title at top with a separator below and a pagestack using
116 // all available space at bottom.
117 //
118 QFrame *p = new QFrame( splitter );
119
120 QHBoxLayout *hbox = new QHBoxLayout( p, 0, 0 );
121 hbox->addSpacing( ODialog::spacingHint() );
122
123 page = new QFrame( p );
124 hbox->addWidget( page, 10 );
125 }
126 else
127 {
128 QHBoxLayout *hbox = new QHBoxLayout( topLayout );
129 mIconList = new IconListBox( this );
130
131 QFont listFont( mIconList->font() );
132 listFont.setBold( true );
133 mIconList->setFont( listFont );
134
135 mIconList->verticalScrollBar()->installEventFilter( this );
136 hbox->addWidget( mIconList );
137 connect( mIconList, SIGNAL(selectionChanged()), SLOT(slotShowPage()));
138 hbox->addSpacing( ODialog::spacingHint() );
139 page = new QFrame( this );
140 hbox->addWidget( page, 10 );
141 }
142
143 //
144 // Rest of page area. Title at top with a separator below and a
145 // pagestack using all available space at bottom.
146 //
147
148 QVBoxLayout *vbox = new QVBoxLayout( page, 0, ODialog::spacingHint() );
149
150 mTitleLabel = new QLabel( QString::fromLatin1("Empty page"), page, "OJanusWidgetTitleLabel" );
151 vbox->addWidget( mTitleLabel );
152
153 QFont titleFont( mTitleLabel->font() );
154 titleFont.setBold( true );
155 mTitleLabel->setFont( titleFont );
156
157 mTitleSep = new OSeparator( page );
158 mTitleSep->setFrameStyle( QFrame::HLine|QFrame::Plain );
159 vbox->addWidget( mTitleSep );
160
161 mPageStack = new QWidgetStack( page );
162 connect(mPageStack, SIGNAL(aboutToShow(QWidget *)),
163 this, SIGNAL(aboutToShowPage(QWidget *)));
164 vbox->addWidget( mPageStack, 10 );
165 }
166 else if( mFace == Tabbed )
167 {
168 mPageList = new QPtrList<QWidget>;
169
170 mTabControl = new QTabWidget( this );
171 mTabControl->setMargin (ODialog::marginHint());
172 topLayout->addWidget( mTabControl, 10 );
173 }
174 else if( mFace == Swallow )
175 {
176 mSwallowPage = new QWidget( this );
177 topLayout->addWidget( mSwallowPage, 10 );
178 }
179 else
180 {
181 mFace = Plain;
182 mPlainPage = new QFrame( this );
183 topLayout->addWidget( mPlainPage, 10 );
184 }
185
186 /* FIXME: Revise for Opie
187 if ( kapp )
188 connect(kapp,SIGNAL(kdisplayFontChanged()),SLOT(slotFontChanged()));
189 */
190
191 mValid = true;
192
193 setSwallowedWidget(0); // Set default size if 'mFace' is Swallow.
194}
195
196
197OJanusWidget::~OJanusWidget()
198{
199 delete mPageList;
200 mPageList = 0;
201 delete mTitleList;
202 mTitleList = 0;
203}
204
205
206bool OJanusWidget::isValid() const
207{
208 return( mValid );
209}
210
211
212QFrame *OJanusWidget::plainPage()
213{
214 return( mPlainPage );
215}
216
217
218int OJanusWidget::face() const
219{
220 return( mFace );
221}
222
223QWidget *OJanusWidget::FindParent()
224{
225 if( mFace == Tabbed ) {
226 return mTabControl;
227 }
228 else {
229 return this;
230 }
231}
232
233QFrame *OJanusWidget::addPage( const QStringList &items, const QString &header,
234 const QPixmap &pixmap )
235{
236 if( mValid == false )
237 {
238 qDebug( "addPage: Invalid object" );
239 return( 0 );
240 }
241
242 QFrame *page = new QFrame( FindParent(), "page" );
243 addPageWidget( page, items, header, pixmap );
244
245 return page;
246}
247
248void OJanusWidget::pageGone( QObject *obj )
249{
250 removePage( static_cast<QWidget*>( obj ) );
251}
252
253void OJanusWidget::slotReopen( QListViewItem * item )
254{
255 if( item )
256 item->setOpen( true );
257}
258
259QFrame *OJanusWidget::addPage( const QString &itemName, const QString &header,
260 const QPixmap &pixmap )
261{
262 QStringList items;
263 items << itemName;
264 return addPage(items, header, pixmap);
265}
266
267
268
269QVBox *OJanusWidget::addVBoxPage( const QStringList &items,
270 const QString &header,
271 const QPixmap &pixmap )
272{
273 if( mValid == false )
274 {
275 qDebug( "addPage: Invalid object" );
276 return( 0 );
277 }
278
279 QVBox *page = new QVBox(FindParent() , "page" );
280 page->setSpacing( ODialog::spacingHint() );
281 addPageWidget( page, items, header, pixmap );
282
283 return page;
284}
285
286QVBox *OJanusWidget::addVBoxPage( const QString &itemName,
287 const QString &header,
288 const QPixmap &pixmap )
289{
290 QStringList items;
291 items << itemName;
292 return addVBoxPage(items, header, pixmap);
293}
294
295QHBox *OJanusWidget::addHBoxPage( const QStringList &items,
296 const QString &header,
297 const QPixmap &pixmap )
298{
299 if( mValid == false ) {
300 qDebug( "addPage: Invalid object" );
301 return( 0 );
302 }
303
304 QHBox *page = new QHBox(FindParent(), "page");
305 page->setSpacing( ODialog::spacingHint() );
306 addPageWidget( page, items, header, pixmap );
307
308 return page;
309}
310
311QHBox *OJanusWidget::addHBoxPage( const QString &itemName,
312 const QString &header,
313 const QPixmap &pixmap )
314{
315 QStringList items;
316 items << itemName;
317 return addHBoxPage(items, header, pixmap);
318}
319
320QGrid *OJanusWidget::addGridPage( int n, Orientation dir,
321 const QStringList &items,
322 const QString &header,
323 const QPixmap &pixmap )
324{
325 if( mValid == false )
326 {
327 qDebug( "addPage: Invalid object" );
328 return( 0 );
329 }
330
331 QGrid *page = new QGrid( n, dir, FindParent(), "page" );
332 page->setSpacing( ODialog::spacingHint() );
333 addPageWidget( page, items, header, pixmap );
334
335 return page;
336}
337
338
339QGrid *OJanusWidget::addGridPage( int n, Orientation dir,
340 const QString &itemName,
341 const QString &header,
342 const QPixmap &pixmap )
343{
344 QStringList items;
345 items << itemName;
346 return addGridPage(n, dir, items, header, pixmap);
347}
348
349void OJanusWidget::InsertTreeListItem(const QStringList &items, const QPixmap &pixmap, QFrame *page)
350{
351 bool isTop = true;
352 QListViewItem *curTop = 0, *child, *last, *newChild;
353 unsigned int index = 1;
354 QStringList curPath;
355
356 for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it, index++ ) {
357 QString name = (*it);
358 bool isPath = ( index != items.count() );
359
360 // Find the first child.
361 if (isTop) {
362 child = mTreeList->firstChild();
363 }
364 else {
365 child = curTop->firstChild();
366 }
367
368 // Now search for a child with the current Name, and if it we doesn't
369 // find it, then remember the location of the last child.
370 for (last = 0; child && child->text(0) != name ; last = child, child = child->nextSibling());
371
372 if (last == 0 && child == 0) {
373 // This node didn't have any children at all, lets just insert the
374 // new child.
375 if (isTop)
376 newChild = new QListViewItem(mTreeList, name);
377 else
378 newChild = new QListViewItem(curTop, name);
379
380 }
381 else if (child != 0) {
382 // we found the given name in this child.
383 if (!isPath) {
384 qDebug( "The element inserted was already in the TreeList box!" );
385 return;
386 }
387 else {
388 // Ok we found the folder
389 newChild = child;
390 }
391 }
392 else {
393 // the node had some children, but we didn't find the given name
394 if (isTop)
395 newChild = new QListViewItem(mTreeList, last, name);
396 else
397 newChild = new QListViewItem(curTop, last, name);
398 }
399
400 // Now make the element expandable if it is a path component, and make
401 // ready for next loop
402 if (isPath) {
403 newChild->setExpandable(true);
404 curTop = newChild;
405 isTop = false;
406 curPath << name;
407
408 QString key = curPath.join("_/_");
409 if (mFolderIconMap.contains(key)) {
410 QPixmap p = mFolderIconMap[key];
411 newChild->setPixmap(0,p);
412 }
413 }
414 else {
415 if (mShowIconsInTreeList) {
416 newChild->setPixmap(0, pixmap);
417 }
418 mTreeListToPageStack.insert(newChild, page);
419 }
420 }
421}
422
423void OJanusWidget::addPageWidget( QFrame *page, const QStringList &items,
424 const QString &header,const QPixmap &pixmap )
425{
426 connect(page, SIGNAL(destroyed(QObject*)), SLOT(pageGone(QObject*)));
427
428 if( mFace == Tabbed )
429 {
430 mTabControl->addTab (page, items.last());
431 mPageList->append (page);
432 }
433 else if( mFace == TreeList || mFace == IconList )
434 {
435 mPageList->append( page );
436 mPageStack->addWidget( page, 0 );
437
438 if (items.count() == 0) {
439 qDebug( "Invalid QStringList, with zero items" );
440 return;
441 }
442
443 if( mFace == TreeList )
444 {
445 InsertTreeListItem(items, pixmap, page);
446 }
447 else // mFace == IconList
448 {
449 QString itemName = items.last();
450 IconListItem *item = new IconListItem( mIconList, pixmap, itemName );
451 //
452 // 2000-06-01 Espen Sand: If I do this with Qt 2.1.1 all sorts of
453 // strange things happen. With Qt <= 2.1 it worked but now I must
454 // either specify the listbox in the constructor on the item
455 // or as below, not both.
456 // mIconList->insertItem( item );
457 //
458 mIconListToPageStack.insert(item, page);
459 mIconList->invalidateHeight();
460 mIconList->invalidateWidth();
461
462 if (mIconList->isVisible())
463 mIconList->updateWidth();
464 }
465
466 //
467 // Make sure the title label is sufficiently wide
468 //
469 QString lastName = items.last();
470 const QString &title = (header != QString::null ? header : lastName);
471 QRect r = mTitleLabel->fontMetrics().boundingRect( title );
472 if( mTitleLabel->minimumWidth() < r.width() )
473 {
474 mTitleLabel->setMinimumWidth( r.width() );
475 }
476 mTitleList->append( title );
477
478 if( mTitleList->count() == 1 )
479 {
480 showPage(0);
481 }
482 }
483 else
484 {
485 qDebug( "OJanusWidget::addPageWidget: can only add a page in Tabbed, TreeList or IconList modes" );
486 }
487
488}
489
490void OJanusWidget::setFolderIcon(const QStringList &path, const QPixmap &pixmap)
491{
492 QString key = path.join("_/_");
493 mFolderIconMap.insert(key,pixmap);
494}
495
496
497
498bool OJanusWidget::setSwallowedWidget( QWidget *widget )
499{
500 if( mFace != Swallow || mValid == false )
501 {
502 return( false );
503 }
504
505 //
506 // Remove current layout and make a new.
507 //
508 if( mSwallowPage->layout() != 0 )
509 {
510 delete mSwallowPage->layout();
511 }
512 QGridLayout *gbox = new QGridLayout( mSwallowPage, 1, 1, 0 );
513
514 //
515 // Hide old children
516 //
517 QObjectList *l = (QObjectList*)mSwallowPage->children(); // silence please
518 for( uint i=0; i < l->count(); i++ )
519 {
520 QObject *o = l->at(i);
521 if( o->isWidgetType() )
522 {
523 ((QWidget*)o)->hide();
524 }
525 }
526
527 //
528 // Add new child or make default size
529 //
530 if( widget == 0 )
531 {
532 gbox->addRowSpacing(0,100);
533 gbox->addColSpacing(0,100);
534 mSwallowPage->setMinimumSize(100,100);
535 }
536 else
537 {
538 if( widget->parent() != mSwallowPage )
539 {
540 widget->reparent( mSwallowPage, 0, QPoint(0,0) );
541 }
542 gbox->addWidget(widget, 0, 0 );
543 gbox->activate();
544 mSwallowPage->setMinimumSize( widget->minimumSize() );
545 }
546
547 return( true );
548}
549
550bool OJanusWidget::slotShowPage()
551{
552 if( mValid == false )
553 {
554 return( false );
555 }
556
557 if( mFace == TreeList )
558 {
559 QListViewItem *node = mTreeList->selectedItem();
560 if( node == 0 ) { return( false ); }
561
562 QWidget *stackItem = mTreeListToPageStack[node];
563 return showPage(stackItem);
564 }
565 else if( mFace == IconList )
566 {
567 QListBoxItem *node = mIconList->item( mIconList->currentItem() );
568 if( node == 0 ) { return( false ); }
569 QWidget *stackItem = mIconListToPageStack[node];
570 return showPage(stackItem);
571 }
572
573 return( false );
574}
575
576
577bool OJanusWidget::showPage( int index )
578{
579 if( mPageList == 0 || mValid == false )
580 {
581 return( false );
582 }
583 else
584 {
585 return showPage(mPageList->at(index));
586 }
587}
588
589
590bool OJanusWidget::showPage( QWidget *w )
591{
592 if( w == 0 || mValid == false )
593 {
594 return( false );
595 }
596
597 if( mFace == TreeList || mFace == IconList )
598 {
599 mPageStack->raiseWidget( w );
600 mActivePageWidget = w;
601
602 int index = mPageList->findRef( w );
603 mTitleLabel->setText( *mTitleList->at(index) );
604 if( mFace == TreeList )
605 {
606 QMap<QListViewItem *, QWidget *>::Iterator it;
607 for (it = mTreeListToPageStack.begin(); it != mTreeListToPageStack.end(); ++it){
608 QListViewItem *key = it.key();
609 QWidget *val = it.data();
610 if (val == w) {
611 mTreeList->setSelected(key, true );
612 break;
613 }
614 }
615 }
616 else
617 {
618 QMap<QListBoxItem *, QWidget *>::Iterator it;
619 for (it = mIconListToPageStack.begin(); it != mIconListToPageStack.end(); ++it){
620 QListBoxItem *key = it.key();
621 QWidget *val = it.data();
622 if (val == w) {
623 mIconList->setSelected( key, true );
624 break;
625 }
626 }
627
628 //
629 // 2000-02-13 Espen Sand
630 // Don't ask me why (because I don't know). If I select a page
631 // with the mouse the page is not updated until it receives an
632 // event. It seems this event get lost if the mouse is not moved
633 // when released. The timer ensures the update
634 //
635 QTimer::singleShot( 0, mActivePageWidget, SLOT(update()) );
636 }
637 }
638 else if( mFace == Tabbed )
639 {
640 mTabControl->showPage(w);
641 mActivePageWidget = w;
642 }
643 else
644 {
645 return( false );
646 }
647
648 return( true );
649}
650
651
652int OJanusWidget::activePageIndex() const
653{
654 if( mFace == TreeList) {
655 QListViewItem *node = mTreeList->selectedItem();
656 if( node == 0 ) { return -1; }
657 QWidget *stackItem = mTreeListToPageStack[node];
658 return mPageList->findRef(stackItem);
659 }
660 else if (mFace == IconList) {
661 QListBoxItem *node = mIconList->item( mIconList->currentItem() );
662 if( node == 0 ) { return( false ); }
663 QWidget *stackItem = mIconListToPageStack[node];
664 return mPageList->findRef(stackItem);
665 }
666 else if( mFace == Tabbed ) {
667 QWidget *widget = mTabControl->currentPage();
668 return( widget == 0 ? -1 : mPageList->findRef( widget ) );
669 }
670 else {
671 return( -1 );
672 }
673}
674
675
676int OJanusWidget::pageIndex( QWidget *widget ) const
677{
678 if( widget == 0 )
679 {
680 return( -1 );
681 }
682 else if( mFace == TreeList || mFace == IconList )
683 {
684 return( mPageList->findRef( widget ) );
685 }
686 else if( mFace == Tabbed )
687 {
688 //
689 // The user gets the real page widget with addVBoxPage(), addHBoxPage()
690 // and addGridPage() but not with addPage() which returns a child of
691 // the toplevel page. addPage() returns a QFrame so I check for that.
692 //
693 if( widget->isA("QFrame") )
694 {
695 return( mPageList->findRef( widget->parentWidget() ) );
696 }
697 else
698 {
699 return( mPageList->findRef( widget ) );
700 }
701 }
702 else
703 {
704 return( -1 );
705 }
706}
707
708void OJanusWidget::slotFontChanged()
709{
710#ifdef FIXME
711
712 if ( mTitleLabel != 0 )
713 {
714 mTitleLabel->setFont( KGlobalSettings::generalFont() );
715 QFont titleFont( mTitleLabel->font() );
716 titleFont.setBold( true );
717 mTitleLabel->setFont( titleFont );
718 }
719#endif
720
721 if( mFace == IconList )
722 {
723 QFont listFont( mIconList->font() );
724 listFont.setBold( true );
725 mIconList->setFont( listFont );
726 mIconList->invalidateHeight();
727 mIconList->invalidateWidth();
728 }
729}
730
731// makes the treelist behave like the list of kcontrol
732void OJanusWidget::slotItemClicked(QListViewItem *it)
733{
734 if(it && (it->childCount()>0))
735 it->setOpen(!it->isOpen());
736}
737
738void OJanusWidget::setFocus()
739{
740 if( mValid == false ) { return; }
741 if( mFace == TreeList )
742 {
743 mTreeList->setFocus();
744 }
745 if( mFace == IconList )
746 {
747 mIconList->setFocus();
748 }
749 else if( mFace == Tabbed )
750 {
751 mTabControl->setFocus();
752 }
753 else if( mFace == Swallow )
754 {
755 mSwallowPage->setFocus();
756 }
757 else if( mFace == Plain )
758 {
759 mPlainPage->setFocus();
760 }
761}
762
763
764QSize OJanusWidget::minimumSizeHint() const
765{
766 if( mFace == TreeList || mFace == IconList )
767 {
768 QSize s1( ODialog::spacingHint(), ODialog::spacingHint()*2 );
769 QSize s2(0,0);
770 QSize s3(0,0);
771 QSize s4( mPageStack->sizeHint() );
772
773 if( mFace == TreeList )
774 {
775#if QT_VERSION < 300
776 s1.rwidth() += style().splitterWidth();
777#else
778 s1.rwidth() += style().pixelMetric( QStyle::PM_SplitterWidth );
779#endif
780 s2 = mTreeList->minimumSize();
781 }
782 else
783 {
784 mIconList->updateMinimumHeight();
785 mIconList->updateWidth();
786 s2 = mIconList->minimumSize();
787 }
788
789 if( mTitleLabel->isVisible() == true )
790 {
791 s3 += mTitleLabel->sizeHint();
792 s3.rheight() += mTitleSep->minimumSize().height();
793 }
794
795 //
796 // Select the tallest item. It has only effect in IconList mode
797 //
798 int h1 = s1.rheight() + s3.rheight() + s4.height();
799 int h2 = QMAX( h1, s2.rheight() );
800
801 return( QSize( s1.width()+s2.width()+QMAX(s3.width(),s4.width()), h2 ) );
802 }
803 else if( mFace == Tabbed )
804 {
805 return( mTabControl->sizeHint() );
806 }
807 else if( mFace == Swallow )
808 {
809 return( mSwallowPage->minimumSize() );
810 }
811 else if( mFace == Plain )
812 {
813 return( mPlainPage->sizeHint() );
814 }
815 else
816 {
817 return( QSize( 100, 100 ) ); // Should never happen though.
818 }
819
820}
821
822
823QSize OJanusWidget::sizeHint() const
824{
825 return( minimumSizeHint() );
826}
827
828
829void OJanusWidget::setTreeListAutoResize( bool state )
830{
831 if( mFace == TreeList )
832 {
833 mTreeListResizeMode = state == false ?
834 QSplitter::KeepSize : QSplitter::Stretch;
835 QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget());
836 splitter->setResizeMode( mTreeList, mTreeListResizeMode );
837 }
838}
839
840
841void OJanusWidget::setIconListAllVisible( bool state )
842{
843 if( mFace == IconList )
844 {
845 mIconList->setShowAll( state );
846 }
847}
848
849void OJanusWidget::setShowIconsInTreeList( bool state )
850{
851 mShowIconsInTreeList = state;
852}
853
854void OJanusWidget::setRootIsDecorated( bool state )
855{
856 if( mFace == TreeList ) {
857 mTreeList->setRootIsDecorated(state);
858 }
859}
860
861void OJanusWidget::unfoldTreeList( bool persist )
862{
863 if( mFace == TreeList )
864 {
865 if( persist )
866 connect( mTreeList, SIGNAL( collapsed( QListViewItem * ) ), this, SLOT( slotReopen( QListViewItem * ) ) );
867 else
868 disconnect( mTreeList, SIGNAL( collapsed( QListViewItem * ) ), this, SLOT( slotReopen( QListViewItem * ) ) );
869
870 for( QListViewItem * item = mTreeList->firstChild(); item; item = item->itemBelow() )
871 item->setOpen( true );
872 }
873}
874
875void OJanusWidget::showEvent( QShowEvent * )
876{
877 if( mFace == TreeList )
878 {
879 QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget());
880 splitter->setResizeMode( mTreeList, mTreeListResizeMode );
881 }
882}
883
884
885//
886// 2000-13-02 Espen Sand
887// It should be obvious that this eventfilter must only be
888// be installed on the vertical scrollbar of the mIconList.
889//
890bool OJanusWidget::eventFilter( QObject *o, QEvent *e )
891{
892 if( e->type() == QEvent::Show )
893 {
894 IconListItem *item = (IconListItem*)mIconList->item(0);
895 if( item != 0 )
896 {
897 int lw = item->width( mIconList );
898 int sw = mIconList->verticalScrollBar()->sizeHint().width();
899 mIconList->setFixedWidth( lw+sw+mIconList->frameWidth()*2 );
900 }
901 }
902 else if( e->type() == QEvent::Hide )
903 {
904 IconListItem *item = (IconListItem*)mIconList->item(0);
905 if( item != 0 )
906 {
907 int lw = item->width( mIconList );
908 mIconList->setFixedWidth( lw+mIconList->frameWidth()*2 );
909 }
910 }
911 return QWidget::eventFilter( o, e );
912}
913
914
915
916//
917// Code for the icon list box
918//
919
920
921OJanusWidget::IconListBox::IconListBox( QWidget *parent, const char *name,
922 WFlags f )
923 :QListBox( parent, name, f ), mShowAll(false), mHeightValid(false),
924 mWidthValid(false)
925{
926}
927
928
929void OJanusWidget::IconListBox::updateMinimumHeight()
930{
931 if( mShowAll == true && mHeightValid == false )
932 {
933 int h = frameWidth()*2;
934 for( QListBoxItem *i = item(0); i != 0; i = i->next() )
935 {
936 h += i->height( this );
937 }
938 setMinimumHeight( h );
939 mHeightValid = true;
940 }
941}
942
943
944void OJanusWidget::IconListBox::updateWidth()
945{
946 if( mWidthValid == false )
947 {
948 int maxWidth = 10;
949 for( QListBoxItem *i = item(0); i != 0; i = i->next() )
950 {
951 int w = ((IconListItem *)i)->width(this);
952 maxWidth = QMAX( w, maxWidth );
953 }
954
955 for( QListBoxItem *i = item(0); i != 0; i = i->next() )
956 {
957 ((IconListItem *)i)->expandMinimumWidth( maxWidth );
958 }
959
960 if( verticalScrollBar()->isVisible() )
961 {
962 maxWidth += verticalScrollBar()->sizeHint().width();
963 }
964
965 setFixedWidth( maxWidth + frameWidth()*2 );
966 mWidthValid = true;
967 }
968}
969
970
971void OJanusWidget::IconListBox::invalidateHeight()
972{
973 mHeightValid = false;
974}
975
976
977void OJanusWidget::IconListBox::invalidateWidth()
978{
979 mWidthValid = false;
980}
981
982
983void OJanusWidget::IconListBox::setShowAll( bool showAll )
984{
985 mShowAll = showAll;
986 mHeightValid = false;
987}
988
989
990
991OJanusWidget::IconListItem::IconListItem( QListBox *listbox, const QPixmap &pixmap,
992 const QString &text )
993 : QListBoxItem( listbox )
994{
995 mPixmap = pixmap;
996 if( mPixmap.isNull() == true )
997 {
998 mPixmap = defaultPixmap();
999 }
1000 setText( text );
1001 mMinimumWidth = 0;
1002}
1003
1004
1005int OJanusWidget::IconListItem::expandMinimumWidth( int width )
1006{
1007 mMinimumWidth = QMAX( mMinimumWidth, width );
1008 return( mMinimumWidth );
1009}
1010
1011
1012const QPixmap &OJanusWidget::IconListItem::defaultPixmap()
1013{
1014 static QPixmap *pix=0;
1015 if( pix == 0 )
1016 {
1017 pix = new QPixmap( 32, 32 );
1018 QPainter p( pix );
1019 p.eraseRect( 0, 0, pix->width(), pix->height() );
1020 p.setPen( Qt::red );
1021 p.drawRect ( 0, 0, pix->width(), pix->height() );
1022 p.end();
1023
1024 QBitmap mask( pix->width(), pix->height(), true );
1025 mask.fill( Qt::black );
1026 p.begin( &mask );
1027 p.setPen( Qt::white );
1028 p.drawRect ( 0, 0, pix->width(), pix->height() );
1029 p.end();
1030
1031 pix->setMask( mask );
1032 }
1033 return( *pix );
1034}
1035
1036
1037void OJanusWidget::IconListItem::paint( QPainter *painter )
1038{
1039 QFontMetrics fm = painter->fontMetrics();
1040 //int wt = fm.boundingRect(text()).width();
1041 int wp = mPixmap.width();
1042 int ht = fm.lineSpacing();
1043 int hp = mPixmap.height();
1044
1045 painter->drawPixmap( (mMinimumWidth-wp)/2, 5, mPixmap );
1046 if( text().isEmpty() == false )
1047 {
1048 painter->drawText( 0, hp+7, mMinimumWidth, ht, Qt::AlignCenter, text() );
1049 }
1050}
1051
1052int OJanusWidget::IconListItem::height( const QListBox *lb ) const
1053{
1054 if( text().isEmpty() == true )
1055 {
1056 return( mPixmap.height() );
1057 }
1058 else
1059 {
1060 return( mPixmap.height() + lb->fontMetrics().lineSpacing()+10 );
1061 }
1062}
1063
1064
1065int OJanusWidget::IconListItem::width( const QListBox *lb ) const
1066{
1067 int wt = lb->fontMetrics().boundingRect(text()).width()+10;
1068 int wp = mPixmap.width() + 10;
1069 int w = QMAX( wt, wp );
1070 return( QMAX( w, mMinimumWidth ) );
1071}
1072
1073// Just remove the page from our stack of widgets. Do not modify the given widget in
1074// any way. No memory leak occurs as parent is not changed.
1075// Make this virtual in KDE 4.0.
1076// Ravikiran Rajagopal <ravi@ee.eng.ohio-state.edu>
1077void OJanusWidget::removePage( QWidget *page )
1078{
1079 if (!mPageList || !mPageList->containsRef(page))
1080 return;
1081
1082 int index = mPageList->findRef( page );
1083 if ( mTitleList )
1084 mTitleList->remove(mTitleList->at(index));
1085
1086 mPageList->removeRef(page);
1087
1088 if ( mFace == TreeList )
1089 {
1090 QMap<QListViewItem*, QWidget *>::Iterator i;
1091 for( i = mTreeListToPageStack.begin(); i != mTreeListToPageStack.end(); ++i )
1092 if (i.data()==page)
1093 {
1094 delete i.key();
1095 mPageStack->removeWidget(page);
1096 mTreeListToPageStack.remove(i);
1097 break;
1098 }
1099 }
1100 else if ( mFace == IconList )
1101 {
1102 QMap<QListBoxItem*, QWidget *>::Iterator i;
1103 for( i = mIconListToPageStack.begin(); i != mIconListToPageStack.end(); ++i )
1104 if (i.data()==page)
1105 {
1106 delete i.key();
1107 mPageStack->removeWidget(page);
1108 mIconListToPageStack.remove(i);
1109 break;
1110 }
1111 }
1112 else // Tabbed
1113 {
1114 mTabControl->removePage(page);
1115 }
1116}