author | mickeyl <mickeyl> | 2003-03-28 15:11:52 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-03-28 15:11:52 (UTC) |
commit | 11304d02942e9fa493e4e80943a828f9c65f6772 (patch) (unidiff) | |
tree | a0223c10c067e1afc70d15c2b82be3f3c15e41ae /libopie2/qt3/opieui/ojanuswidget.cpp | |
parent | b271d575fa05cf570a1a829136517761bd47e69b (diff) | |
download | opie-11304d02942e9fa493e4e80943a828f9c65f6772.zip opie-11304d02942e9fa493e4e80943a828f9c65f6772.tar.gz opie-11304d02942e9fa493e4e80943a828f9c65f6772.tar.bz2 |
skeleton and the start of libopie2, please read README, ROADMAP and STATUS and comment...
Diffstat (limited to 'libopie2/qt3/opieui/ojanuswidget.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/qt3/opieui/ojanuswidget.cpp | 1116 |
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 | |||
62 | class 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 | |||
80 | template class QPtrList<QListViewItem>; | ||
81 | |||
82 | /*====================================================================================== | ||
83 | * OJanusWidget | ||
84 | *======================================================================================*/ | ||
85 | |||
86 | OJanusWidget::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 | |||
197 | OJanusWidget::~OJanusWidget() | ||
198 | { | ||
199 | delete mPageList; | ||
200 | mPageList = 0; | ||
201 | delete mTitleList; | ||
202 | mTitleList = 0; | ||
203 | } | ||
204 | |||
205 | |||
206 | bool OJanusWidget::isValid() const | ||
207 | { | ||
208 | return( mValid ); | ||
209 | } | ||
210 | |||
211 | |||
212 | QFrame *OJanusWidget::plainPage() | ||
213 | { | ||
214 | return( mPlainPage ); | ||
215 | } | ||
216 | |||
217 | |||
218 | int OJanusWidget::face() const | ||
219 | { | ||
220 | return( mFace ); | ||
221 | } | ||
222 | |||
223 | QWidget *OJanusWidget::FindParent() | ||
224 | { | ||
225 | if( mFace == Tabbed ) { | ||
226 | return mTabControl; | ||
227 | } | ||
228 | else { | ||
229 | return this; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | QFrame *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 | |||
248 | void OJanusWidget::pageGone( QObject *obj ) | ||
249 | { | ||
250 | removePage( static_cast<QWidget*>( obj ) ); | ||
251 | } | ||
252 | |||
253 | void OJanusWidget::slotReopen( QListViewItem * item ) | ||
254 | { | ||
255 | if( item ) | ||
256 | item->setOpen( true ); | ||
257 | } | ||
258 | |||
259 | QFrame *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 | |||
269 | QVBox *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 | |||
286 | QVBox *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 | |||
295 | QHBox *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 | |||
311 | QHBox *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 | |||
320 | QGrid *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 | |||
339 | QGrid *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 | |||
349 | void 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 | |||
423 | void 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 | |||
490 | void OJanusWidget::setFolderIcon(const QStringList &path, const QPixmap &pixmap) | ||
491 | { | ||
492 | QString key = path.join("_/_"); | ||
493 | mFolderIconMap.insert(key,pixmap); | ||
494 | } | ||
495 | |||
496 | |||
497 | |||
498 | bool 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 | |||
550 | bool 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 | |||
577 | bool 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 | |||
590 | bool 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 | |||
652 | int 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 | |||
676 | int 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 | |||
708 | void 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 | ||
732 | void OJanusWidget::slotItemClicked(QListViewItem *it) | ||
733 | { | ||
734 | if(it && (it->childCount()>0)) | ||
735 | it->setOpen(!it->isOpen()); | ||
736 | } | ||
737 | |||
738 | void 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 | |||
764 | QSize 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 | |||
823 | QSize OJanusWidget::sizeHint() const | ||
824 | { | ||
825 | return( minimumSizeHint() ); | ||
826 | } | ||
827 | |||
828 | |||
829 | void 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 | |||
841 | void OJanusWidget::setIconListAllVisible( bool state ) | ||
842 | { | ||
843 | if( mFace == IconList ) | ||
844 | { | ||
845 | mIconList->setShowAll( state ); | ||
846 | } | ||
847 | } | ||
848 | |||
849 | void OJanusWidget::setShowIconsInTreeList( bool state ) | ||
850 | { | ||
851 | mShowIconsInTreeList = state; | ||
852 | } | ||
853 | |||
854 | void OJanusWidget::setRootIsDecorated( bool state ) | ||
855 | { | ||
856 | if( mFace == TreeList ) { | ||
857 | mTreeList->setRootIsDecorated(state); | ||
858 | } | ||
859 | } | ||
860 | |||
861 | void 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 | |||
875 | void 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 | // | ||
890 | bool 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 | |||
921 | OJanusWidget::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 | |||
929 | void 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 | |||
944 | void 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 | |||
971 | void OJanusWidget::IconListBox::invalidateHeight() | ||
972 | { | ||
973 | mHeightValid = false; | ||
974 | } | ||
975 | |||
976 | |||
977 | void OJanusWidget::IconListBox::invalidateWidth() | ||
978 | { | ||
979 | mWidthValid = false; | ||
980 | } | ||
981 | |||
982 | |||
983 | void OJanusWidget::IconListBox::setShowAll( bool showAll ) | ||
984 | { | ||
985 | mShowAll = showAll; | ||
986 | mHeightValid = false; | ||
987 | } | ||
988 | |||
989 | |||
990 | |||
991 | OJanusWidget::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 | |||
1005 | int OJanusWidget::IconListItem::expandMinimumWidth( int width ) | ||
1006 | { | ||
1007 | mMinimumWidth = QMAX( mMinimumWidth, width ); | ||
1008 | return( mMinimumWidth ); | ||
1009 | } | ||
1010 | |||
1011 | |||
1012 | const 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 | |||
1037 | void 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 | |||
1052 | int 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 | |||
1065 | int 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> | ||
1077 | void 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 | } | ||