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