summaryrefslogtreecommitdiff
path: root/libopie2/opieui/big-screen/osplitter.cpp
Unidiff
Diffstat (limited to 'libopie2/opieui/big-screen/osplitter.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opieui/big-screen/osplitter.cpp638
1 files changed, 638 insertions, 0 deletions
diff --git a/libopie2/opieui/big-screen/osplitter.cpp b/libopie2/opieui/big-screen/osplitter.cpp
new file mode 100644
index 0000000..89f3793
--- a/dev/null
+++ b/libopie2/opieui/big-screen/osplitter.cpp
@@ -0,0 +1,638 @@
1/*
2               =. This file is part of the OPIE Project
3             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
4           .>+-=
5 _;:,     .>    :=|. This library is free software; you can
6.> <`_,   >  .   <= redistribute it and/or modify it under
7:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
8.="- .-=="i,     .._ License as published by the Free Software
9 - .   .-<_>     .<> Foundation; either version 2 of the License,
10     ._= =}       : or (at your option) any later version.
11    .%`+i>       _;_.
12    .i_,=:_.      -<s. This library is distributed in the hope that
13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
14    : ..    .:,     . . . without even the implied warranty of
15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
17..}^=.=       =       ; Library General Public License for more
18++=   -.     .`     .: details.
19 :     =  ...= . :.=-
20 -.   .:....=;==+<; You should have received a copy of the GNU
21  -_. . .   )=.  = Library General Public License along with
22    --        :-=` this library; see the file COPYING.LIB.
23 If not, write to the Free Software Foundation,
24 Inc., 59 Temple Place - Suite 330,
25 Boston, MA 02111-1307, USA.
26
27*/
28
29#include "osplitter.h"
30
31/* OPIE */
32#include <opie2/otabwidget.h>
33
34/* QT */
35#include <qvaluelist.h>
36#include <qvbox.h>
37
38using namespace Opie;
39
40/**
41 *
42 * This is the constructor of OSplitter
43 * You might want to call setSizeChange to tell
44 * OSplitter to change its layout when a specefic
45 * mark was crossed. OSplitter sets a default value.
46 *
47 * You cann add widget with addWidget to the OSplitter.
48 * OSplitter supports also grouping of Splitters where they
49 * can share one OTabBar in small screen mode. This can be used
50 * for email clients like vies but see the example.
51 *
52 * @param orient The orientation wether to layout horizontal or vertical
53 * @param parent The parent of this widget
54 * @param name The name passed on to QObject
55 * @param fl Additional widgets flags passed to QWidget
56 *
57 * @short single c'tor of the OSplitter
58 */
59OSplitter::OSplitter( Orientation orient, QWidget* parent, const char* name, WFlags fl )
60 : QFrame( parent, name, fl )
61{
62 m_orient = orient;
63 m_hbox = 0;
64 m_size_policy = 330;
65 setFontPropagation( AllChildren );
66 setPalettePropagation( AllChildren );
67
68 /* start by default with the tab widget */
69 m_tabWidget = 0;
70 m_parentTab = 0;
71 changeTab();
72
73}
74
75
76/**
77 * Destructor destructs this object and cleans up. All child
78 * widgets will be deleted
79 * @see addWidget
80 */
81OSplitter::~OSplitter()
82{
83 qWarning("Deleted Splitter");
84 m_splitter.setAutoDelete( true );
85 m_splitter.clear();
86
87 delete m_hbox;
88 delete m_tabWidget;
89}
90
91
92/**
93 * Sets the label for the Splitter. This label will be used
94 * if a parent splitter is arranged as TabWidget but
95 * this splitter is in fullscreen mode. Then a tab with OSplitter::label()
96 * and iconName() gets added.
97 *
98 * @param name The name of the Label
99 */
100void OSplitter::setLabel( const QString& name )
101{
102 m_name = name;
103}
104
105/**
106 * @see setLabel but this is for the icon retrieved by Resource
107 *
108 * @param name The name of the icon in example ( "zoom" )
109 */
110void OSplitter::setIconName( const QString& name )
111{
112 m_icon = name;
113}
114
115
116/**
117 * returns the iconName
118 * @see setIconName
119 */
120QString OSplitter::iconName()const
121{
122 return m_icon;
123}
124
125/**
126 * returns the label set with setLabel
127 * @see setLabel
128 */
129QString OSplitter::label()const
130{
131 return m_name;
132}
133
134/**
135 * This function sets the size change policy of the splitter.
136 * If this size marked is crossed the splitter will relayout.
137 * Note: that depending on the set Orientation it'll either look
138 * at the width or height.
139 * Note: If you want to from side to side view to tabbed view you need
140 * to make sure that the size you supply is not smaller than the minimum
141 * size of your added widgets. Note that if you use widgets like QComboBoxes
142 * you need to teach them to accept smaller sizes as well @see QWidget::setSizePolicy
143 *
144 * @param width_height The mark that will be watched. Interpreted depending on the Orientation of the Splitter.
145 * @return void
146 */
147void OSplitter::setSizeChange( int width_height )
148{
149 m_size_policy = width_height;
150 QSize sz(width(), height() );
151 QResizeEvent ev(sz, sz );
152 resizeEvent(&ev);
153}
154
155/**
156 * This functions allows to add another OSplitter and to share
157 * the OTabBar in small screen mode. The ownerships gets transfered.
158 * OSplitters are always added after normal widget items
159 */
160void OSplitter::addWidget( OSplitter* split )
161{
162 m_splitter.append( split );
163
164 /*
165 * set tab widget
166 */
167 if (m_tabWidget )
168 setTabWidget( m_parentTab );
169 else
170 {
171 Opie::OSplitterContainer con;
172 con.widget =split;
173 addToBox( con );
174 }
175}
176
177/*
178 * If in a tab it should be removed
179 * and if in a hbox the reparent kills it too
180 */
181/**
182 * This removes the splitter again. You currently need to call this
183 * before you delete or otherwise you can get mem corruption
184 * or other weird behaviour.
185 * Owner ship gets transfered back to you it's current parent
186 * is 0
187 */
188void OSplitter::removeWidget( OSplitter* split)
189{
190 split->setTabWidget( 0 );
191 split->reparent( 0, 0, QPoint(0, 0) );
192}
193
194/**
195 * Adds a widget to the Splitter. The widgets gets inserted
196 * at the end of either the Box or TabWidget.
197 * Ownership gets transfered and the widgets gets reparented.
198 * Note: icon and label is only available on small screensizes
199 * if size is smaller than the mark
200 * Warning: No null checking of the widget is done. Only on debug
201 * a message will be outputtet
202 *
203 * @param wid The widget which will be added
204 * @param icon The icon of the possible Tab
205 * @param label The label of the possible Tab
206 */
207void OSplitter::addWidget( QWidget* wid, const QString& icon, const QString& label )
208{
209#ifdef DEBUG
210 if (!wid )
211 {
212 qWarning("Widget is not valid!");
213 return;
214 }
215#endif
216 Opie::OSplitterContainer cont;
217 cont.widget = wid;
218 cont.icon =icon;
219 cont.name = label;
220
221 m_container.append( cont );
222
223 /*
224 *
225 */
226 if (!m_splitter.isEmpty() && (m_tabWidget || m_parentTab ) )
227 setTabWidget( m_parentTab );
228 else
229 {
230 if (m_hbox )
231 addToBox( cont );
232 else
233 addToTab( cont );
234 }
235}
236
237
238/**
239 * Removes the widget from the tab widgets if necessary.
240 * OSplitter drops ownership of this widget and the widget
241 * will be reparented i tto 0.
242 * The widget will not be deleted.
243 *
244 * @param w The widget to be removed
245 */
246void OSplitter::removeWidget( QWidget* w)
247{
248 ContainerList::Iterator it;
249 for ( it = m_container.begin(); it != m_container.end(); ++it )
250 if ( (*it).widget == w )
251 break;
252
253 if (it == m_container.end() )
254 return;
255
256
257 /* only tab needs to be removed.. box recognizes it */
258 if ( !m_hbox )
259 removeFromTab( w );
260
261
262 /* Find reparent it and remove it from our list */
263
264 w->reparent( 0, 0, QPoint(0, 0));
265 it = m_container.remove( it );
266
267}
268
269
270/**
271 * This method will give focus to the widget. If in a tabwidget
272 * the tabbar will be changed
273 *
274 * @param w The widget which will be set the current one
275 */
276void OSplitter::setCurrentWidget( QWidget* w)
277{
278 if (m_tabWidget )
279 m_tabWidget->setCurrentTab( w );
280 // else
281 // m_hbox->setFocus( w );
282
283}
284
285/**
286 * This is an overloaded member function and only differs in the
287 * argument it takes.
288 * Searches list of widgets for label. It'll pick the first label it finds
289 *
290 * @param label Label to look for. First match will be taken
291 */
292void OSplitter::setCurrentWidget( const QString& label )
293{
294 ContainerList::Iterator it;
295 for (it = m_container.begin(); it != m_container.end(); ++it )
296 {
297 if ( (*it).name == label )
298 {
299 setCurrentWidget( (*it).widget );
300 break;
301 }
302 }
303}
304
305/**
306 * This will only work when the TabWidget is active
307 * If everything is visible this signal is kindly ignored
308 * @see OTabWidget::setCurrentTab(int)
309 *
310 * @param tab The tab to make current
311 */
312void OSplitter::setCurrentWidget( int tab )
313{
314 if (m_tabWidget )
315 m_tabWidget->setCurrentTab( tab );
316}
317
318/**
319 * return the currently activated widget if in tab widget mode
320 * or null because all widgets are visible
321 */
322QWidget* OSplitter::currentWidget() const
323{
324 if (m_tabWidget)
325 return m_tabWidget->currentWidget();
326 else if (m_parentTab )
327 return m_parentTab->currentWidget();
328
329 return 0l;
330}
331/* wrong */
332#if 0
333/**
334 * @reimplented for internal reasons
335 * returns the sizeHint of one of its sub widgets
336 */
337QSize OSplitter::sizeHint()const
338{
339 if (m_parentTab )
340 return QFrame::sizeHint();
341
342 if (m_hbox )
343 return m_hbox->sizeHint();
344 else
345 return m_tabWidget->sizeHint();
346}
347
348QSize OSplitter::minimumSizeHint()const
349{
350 if (m_parentTab )
351 return QFrame::minimumSizeHint();
352 if (m_hbox)
353 return m_hbox->sizeHint();
354 else
355 return m_tabWidget->sizeHint();
356}
357#endif
358
359/**
360 * @reimplemented for internal reasons
361 */
362void OSplitter::resizeEvent( QResizeEvent* res )
363{
364 QFrame::resizeEvent( res );
365 /*
366 *
367 */
368 // qWarning("Old size was width = %d height = %d", res->oldSize().width(), res->oldSize().height() );
369 bool mode = true;
370 qWarning("New size is width = %d height = %d %s", res->size().width(), res->size().height(), name() );
371 if ( res->size().width() > m_size_policy &&
372 m_orient == Horizontal )
373 {
374 changeHBox();
375 mode = false;
376 }
377 else if ( (res->size().width() <= m_size_policy &&
378 m_orient == Horizontal ) ||
379 (res->size().height() <= m_size_policy &&
380 m_orient == Vertical ) )
381 {
382 changeTab();
383 }
384 else if ( res->size().height() > m_size_policy &&
385 m_orient == Vertical )
386 {
387 qWarning("Changng to vbox %s", name() );
388 changeVBox();
389 mode = false;
390 }
391
392 emit sizeChanged(mode, m_orient );
393}
394
395/*
396 * Adds a container to a tab either the parent tab
397 * or our own
398 */
399void OSplitter::addToTab( const Opie::OSplitterContainer& con )
400{
401 QWidget *wid = con.widget;
402 // not needed widgetstack will reparent as well wid.reparent(m_tabWidget, wid->getWFlags(), QPoint(0, 0) );
403 if (m_parentTab )
404 m_parentTab->addTab( wid, con.icon, con.name );
405 else
406 m_tabWidget->addTab( wid, con.icon, con.name );
407}
408
409
410/*
411 * adds a container to the box
412 */
413void OSplitter::addToBox( const Opie::OSplitterContainer& con )
414{
415 QWidget* wid = con.widget;
416 wid->reparent(m_hbox, 0, QPoint(0, 0) );
417}
418
419
420/*
421 * Removes a widget from the tab
422 */
423void OSplitter::removeFromTab( QWidget* wid )
424{
425 if (m_parentTab )
426 m_parentTab->removePage( wid );
427 else
428 m_tabWidget->removePage( wid );
429}
430
431/*
432 * switches over to a OTabWidget layout
433 * it is recursive
434 */
435void OSplitter::changeTab()
436{
437 /* if we're the owner of the tab widget */
438 if (m_tabWidget )
439 {
440 raise();
441 show();
442 m_tabWidget->setGeometry( frameRect() );
443 return;
444 }
445
446 qWarning(" New Tab Widget %s", name() );
447 /*
448 * and add all widgets this will reparent them
449 * delete m_hbox set it to 0
450 *
451 */
452 OTabWidget *tab;
453 if ( m_parentTab )
454 {
455 hide();
456 tab = m_parentTab;
457 /* expensive but needed cause we're called from setTabWidget and resizeEvent*/
458 if (!m_container.isEmpty() )
459 {
460 ContainerList::Iterator it = m_container.begin();
461 for (; it != m_container.end(); ++it )
462 m_parentTab->removePage( (*it).widget );
463 }
464 }
465 else
466 tab = m_tabWidget = new OTabWidget( this );
467
468 connect(tab, SIGNAL(currentChanged(QWidget*) ),
469 this, SIGNAL(currentChanged(QWidget*) ) );
470
471 for ( ContainerList::Iterator it = m_container.begin(); it != m_container.end(); ++it )
472 {
473 qWarning("Widget is %s", (*it).name.latin1() );
474 addToTab( (*it) );
475 }
476
477 for ( OSplitter* split = m_splitter.first(); split; split = m_splitter.next() )
478 {
479 split->reparent(this, 0, QPoint(0, 0) );
480 split->setTabWidget( tab );
481 }
482
483
484 delete m_hbox;
485 m_hbox = 0;
486 if (!m_tabWidget )
487 return;
488
489 m_tabWidget->setGeometry( frameRect() );
490 m_tabWidget->show();
491
492}
493
494/*
495 * changes over to a box
496 * this is recursive as well
497 */
498void OSplitter::changeHBox()
499{
500 if (m_hbox )
501 {
502 m_hbox->setGeometry( frameRect() );
503 return;
504 }
505
506 qWarning("new HBox %s", name() );
507 m_hbox = new QHBox( this );
508 commonChangeBox();
509}
510
511void OSplitter::changeVBox()
512{
513 if (m_hbox )
514 {
515 m_hbox->setGeometry( frameRect() );
516 return;
517 }
518
519 qWarning("New VBOX %s", name() );
520 m_hbox = new QVBox( this );
521
522 commonChangeBox();
523
524}
525
526/*
527 * common box code
528 * first remove and add children
529 * the other splitters
530 * it is recursive as well due the call to setTabWidget
531 */
532void OSplitter::commonChangeBox()
533{
534 qWarning(" Name of Splitters is %s", name() );
535
536 for (ContainerList::Iterator it = m_container.begin(); it != m_container.end(); ++it )
537 {
538 /* only if parent tab.. m_tabWidgets gets deleted and would do that as well */
539 if (m_parentTab )
540 removeFromTab( (*it).widget );
541 qWarning("Adding to box %s", (*it).name.latin1() );
542 addToBox( (*it) );
543 }
544 for ( OSplitter* split = m_splitter.first(); split; split = m_splitter.next() )
545 {
546 /* tell them the world had changed */
547 split->setTabWidget( 0 );
548 Opie::OSplitterContainer con;
549 con.widget = split;
550 // con.widget = split->m_tabWidget ? static_cast<QWidget*>(split->m_tabWidget)
551 // : static_cast<QWidget*>(split->m_hbox);
552 addToBox( con );
553 }
554
555
556
557 if (m_parentTab )
558 m_parentTab->addTab(m_hbox, iconName(), label() );
559 else
560 {
561 qWarning(" setting Box geometry for %s", name() );
562 m_hbox->setGeometry( frameRect() );
563 m_hbox->show();
564 delete m_tabWidget;
565 m_tabWidget = 0;
566 show(); // also show this widget
567 }
568}
569
570/*
571 * sets the tabwidget, removes tabs, and relayouts the widget
572 */
573void OSplitter::setTabWidget( OTabWidget* wid)
574{
575 /* clean up cause m_parentTab will not be available for us */
576 if ( m_parentTab )
577 {
578 if (m_hbox )
579 m_parentTab->removePage( m_hbox );
580 else if (!m_container.isEmpty() )
581 {
582 ContainerList::Iterator it = m_container.begin();
583 for ( ; it != m_container.end(); ++it )
584 m_parentTab->removePage( (*it).widget );
585 }
586 }
587 /* the parent Splitter changed so either make us indepent or dep */
588
589 m_parentTab = wid;
590
591 QWidget *tab = m_tabWidget;
592 QWidget *box = m_hbox;
593 m_hbox = 0; m_tabWidget = 0;
594
595 if ( layoutMode() )
596 changeTab();
597 else if (m_orient == Horizontal )
598 changeHBox();
599 else
600 changeVBox();
601
602 /* our own crap is added and children from change* */
603 delete tab;
604 delete box;
605}
606
607#if 0
608void OSplitter::reparentAll()
609{
610 if (m_container.isEmpty() )
611 return;
612
613 ContainerList::Iterator it = m_container.begin();
614 for ( ; it != m_container.end(); ++it )
615 (*it).wid->reparent(0, 0, QPoint(0, 0) );
616
617
618}
619#endif
620
621/**
622 * @internal
623 */
624bool OSplitter::layoutMode()const
625{
626 if ( size().width() > m_size_policy &&
627 m_orient == Horizontal )
628 {
629 return false;
630 }
631 else if ( size().height() > m_size_policy &&
632 m_orient == Vertical )
633 {
634 return false;
635 }
636
637 return true;
638}