summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opieui/big-screen/.cvsignore8
-rw-r--r--libopie2/opieui/big-screen/IDEAS81
-rw-r--r--libopie2/opieui/big-screen/big-screen.pro2
-rw-r--r--libopie2/opieui/big-screen/obarcollection.h116
-rw-r--r--libopie2/opieui/big-screen/obigscreen_p.h28
-rw-r--r--libopie2/opieui/big-screen/omodalhelper.cpp179
-rw-r--r--libopie2/opieui/big-screen/omodalhelper.h774
-rw-r--r--libopie2/opieui/big-screen/osplitter.cpp638
-rw-r--r--libopie2/opieui/big-screen/osplitter.h150
-rw-r--r--libopie2/opieui/big-screen/owidgetstack.cpp435
-rw-r--r--libopie2/opieui/big-screen/owidgetstack.h132
-rw-r--r--libopie2/opieui/opieui.pro2
12 files changed, 2545 insertions, 0 deletions
diff --git a/libopie2/opieui/big-screen/.cvsignore b/libopie2/opieui/big-screen/.cvsignore
new file mode 100644
index 0000000..1244207
--- a/dev/null
+++ b/libopie2/opieui/big-screen/.cvsignore
@@ -0,0 +1,8 @@
1Makefile*
2obj
3moc*
4*moc
5*.o
6~*
7*base.cpp
8*base.h
diff --git a/libopie2/opieui/big-screen/IDEAS b/libopie2/opieui/big-screen/IDEAS
new file mode 100644
index 0000000..27a4d6e
--- a/dev/null
+++ b/libopie2/opieui/big-screen/IDEAS
@@ -0,0 +1,81 @@
1Now that PDAs get a VGA resolution and Opie runs on Webpads
2and could be used as a Kiosk secure environment the design
3decision that were right for a 320x240/240x320 doesn't necessary
4to be right for bigger screens.
5
6Remember most desktops a few years ago had only a resolution
7of 800x600.
8Then also to remember is that a webpad with 640x480 is different to
9a PDA with the same resolution. The PDA has a much smaller
10physical display.
11
12With higher resolution the feeling of a desktop comes.
13
14Problems with current Opie:
15 -InputMethod use full width but most of the times are not high enough
16 This actually makes it harder to input and looks stupid.
17 -ToolBars only feels strange on bigger screens. Maybe do it like WinCE3 does
18 share the ToolBar with MenuBar if they're too big for the screen allow handles
19 to either show the left or right side. Note that the handle from Qt looks
20 bad and should be patched away
21 -The Escape/Close back to View does not make sense on bigger screens and desktop
22 on a desktop you might even want to show multiple views and detach from the 'system'
23 view
24 -Modality. Dunnow how you get back to the enter dialog without modality in Qt/E fix it?
25 On bigger screen this is not the problem you can move windows. But you should try
26 to be less modal in the future.
27 I've added a small to qpeapplication to iterate over the toplevel widgets 99%
28 ( click on the taskbar to iterate over the widgets first time nothing is changed )
29 , BUT it should be avoided to use modality showMaximized(), exec()
30 INSTEAD we will use a modal helper where one can register to show a dialog for uid
31 type and will get a signal once the settings need to be applied, rejected or discarded.
32 This way you can almost work like with exec(), do not need to care for freeing.
33 Problems sometimes to have more than one dialog in memory is expensive. Allow queueing
34 and reusing this widget ( only set the Record new? )
35 -Viewing on bigger screens you may want to have a seperate viewer widget ( topLevel ) which
36 might also get spon off from the normal operation. The (X) close go back does not make
37 sense on bigger screens and feels strange
38 -Sizing and Auto sizing of widgets
39
40Widgets and Classes
41
42 Toolbar/Action and Popups:
43 While KParts with XMLGUI provide a fantastic technology to change the GUI
44 on the fly. Parsing these GUI descriptions is not an option for PDAs
45 specially not on start up.
46 Instead we will need to use normal object in this case QAction and QPopupMenuss. We
47 will then group these Actions into groups. Each group can have children and one
48 parent. Each group has two attributes one for the menubar and one for the toolbar.
49 Attributes for each might be | together. Always, Never, Auto are the attributes I
50 can think of tonite. Always will place this group always there, Never yeah never,
51 Automatic lets the later described Manager decide. Also one could or MightSpinOff
52 to a group. This way a child group might get spon off if enough place is there.
53 You cann add QAction and QPopupMenus to the group the Group will not take owner ship
54 and you might use your QAction in other places as well.
55 Toplevel groups need to be registered to the manager and this manager will depending
56 on global settings place and control MenuBar and ToolBar/ToolBar.
57 This allows to dynamically create toolbar on the fly
58
59 Modality class:
60 It'll be a template with a QSignal to tell about changes and a method to get to know
61 which action to be applied. It has three template parameters one for the WIdget used
62 and one for the type of uid and the last for the editor widget which
63 at least needs to provide some methods as well.
64 If you need to edit an widget you simply tell the helper about it. If present it'll
65 raise the widget or either queue it or create a new editor depending on a policy
66 one can set manually or get from the system.
67
68 Viewing:
69 We will provide a special OWidgetStack which either is a real QWidgetStack or a QList
70 of toplevel widgets to be raised. One has to see how one can use it with todolist
71 and datebook. specially the switching back and forth need to be handled but with possible
72 no code reordering ( least intrusive )
73 Viewing II:
74 Example Advanced FM has a tabwidget but on a SIMpad it would make perfect sense to use a
75 QSplitter or QVBox. We will provide an OSplitter which either provides the one
76 or the other widget depending on the size
77
78
79These small changes ( replacing Q with O + bit more) should make Opie a better environment for
80bigger screens. The additional library memory is a fair trade off and memory can be recovered
81by other technics \ No newline at end of file
diff --git a/libopie2/opieui/big-screen/big-screen.pro b/libopie2/opieui/big-screen/big-screen.pro
new file mode 100644
index 0000000..f324d3c
--- a/dev/null
+++ b/libopie2/opieui/big-screen/big-screen.pro
@@ -0,0 +1,2 @@
1HEADERS += big-screen/obigscreen_p.h big-screen/osplitter.h big-screen/owidgetstack.h #big-screen/omodalhelper.h
2SOURCES += big-screen/osplitter.cpp big-screen/owidgetstack.cpp #big-screen/omodalhelper.cpp
diff --git a/libopie2/opieui/big-screen/obarcollection.h b/libopie2/opieui/big-screen/obarcollection.h
new file mode 100644
index 0000000..e3a2935
--- a/dev/null
+++ b/libopie2/opieui/big-screen/obarcollection.h
@@ -0,0 +1,116 @@
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#ifndef OBARCOLLECTION_H
30#define OBARCOLLECTION_H
31
32/* QT */
33
34#include <qstring.h>
35#include <qwidget.h>
36
37class QAction;
38class QPopupMenu;
39
40namespace Opie
41{
42
43/*
44 * ### TODO
45 * -Consider Life Updates
46 * -Make ValueBased like Opie-featurelist
47 */
48
49/**
50 * The different screen sizes have different look and feel. On bigger
51 * screens only a QToolBar feels strange. One is at least known to have
52 * a Help-Menu, a File Menu with Quit/Exit but instead of providing two
53 * different ways / two action sets we will group actions to gether and give
54 * them attributes when and where we might want them to be visible.
55 * We can also group actions. For example you could Group All Actions
56 * into the File Group. This means with many actions you would only have more toolbar
57 * actions but many sub menus in File. On bigger screen this would automatically
58 * expand to a full blown MenuBar and ToolButtons.
59 *
60 * @short Grouping of actions for dynamic Bar Generation
61 * @version 0.01
62 * @author hOlgAr
63 */
64class OBarGroup
65{
66public:
67 enum Preference { Allways, Never, IfPlace };
68 OBarGroup( const QString& name, enum Preference groupPreference );
69 ~OBarGroup();
70
71 void add( QAction* action, enum Preference menuPreference,
72 enum Preference toolpreference );
73 void add( const QString&, QPopupMenu* );
74
75 void add( OBarGroup* );
76
77 void remove( QAction* action );
78 void remove( QMap* );
79
80protected:
81 OBarGroup* parent()const;
82
83private:
84};
85
86
87/**
88 * Add your groups in order to the bar manager
89 * and either call createGUI() on it, or tell it
90 * it the mainwindow and it is listening to the show event
91 * and then creates the toolbar
92 */
93class OBarManager : public QObject
94{
95public:
96 OBarManager( QWindow* parent );
97 ~OBarManager();
98
99 void add( OBarGroup*, int pos = -1 );
100 void remove( OBarGroup* );
101
102 bool eventFilter( QObject* , QEvent* );
103
104public slots:
105 void createGUI();
106};
107
108/*
109 * ### TODO GUI merging
110 */
111
112};
113
114#endif
115
116
diff --git a/libopie2/opieui/big-screen/obigscreen_p.h b/libopie2/opieui/big-screen/obigscreen_p.h
new file mode 100644
index 0000000..db8fc83
--- a/dev/null
+++ b/libopie2/opieui/big-screen/obigscreen_p.h
@@ -0,0 +1,28 @@
1#ifndef OPIE_BIG_SCREEN_PRIVATE
2#define OPIE_BIG_SCREEN_PRIVATE
3
4/* QT */
5#include <qstring.h>
6
7class QWidget;
8
9namespace Opie
10{
11
12struct OSplitterContainer
13{
14 bool operator==( const OSplitterContainer& o) const
15 {
16 if (widget != o.widget ) return false;
17 if (icon != o.icon ) return false;
18 if (name != o.name ) return false;
19 return true;
20 }
21 QWidget* widget;
22 QString icon;
23 QString name;
24};
25
26};
27
28#endif
diff --git a/libopie2/opieui/big-screen/omodalhelper.cpp b/libopie2/opieui/big-screen/omodalhelper.cpp
new file mode 100644
index 0000000..19aa64f
--- a/dev/null
+++ b/libopie2/opieui/big-screen/omodalhelper.cpp
@@ -0,0 +1,179 @@
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 "omodalhelper.h"
30
31/* QT */
32#include <qpushbutton.h>
33#include <qvbox.h>
34#include <qlayout.h>
35#include <qlabel.h>
36
37/* Signal handling */
38OModalHelperSignal::OModalHelperSignal( OModalHelperBase* base, QObject* parent )
39 : QObject( parent, "OModal Helper Signal" ), m_base( base )
40{}
41
42OModalHelperSignal::~OModalHelperSignal()
43{
44 /* special the ancestor deletes its creator */
45 delete m_base;
46}
47
48
49/* Helper Controler */
50/*
51 * the dialogs signal will be slotted here
52 * and we will call into m_base
53 */
54OModalHelperControler::OModalHelperControler( OModalHelperBase* base, QObject* parent )
55 : QObject(parent, "OModal Helper Controler" ), m_base( base ), m_dia( 0 ), m_id( -1 )
56{}
57
58TransactionID OModalHelperControler::transactionID()const
59{
60 return m_id;
61}
62
63void OModalHelperControler::setTransactionID( TransactionID id )
64{
65 m_dia = 0;
66 m_id = id;
67}
68
69QDialog* OModalHelperControler::dialog()const
70{
71 return m_dia;
72}
73
74/*
75 * If we're in the New mode we will map the QDialog
76 * to the TransactionID
77 */
78void OModalHelperControler::done( int result )
79{
80 if ( sender() && !sender()->isA("OModalQueuedDialog") )
81 m_dia = static_cast<QDialog*>( sender() );
82
83 m_base->done( result, m_id );
84}
85
86void OModalHelperControler::next()
87{
88 m_base->next( m_id );
89}
90
91void OModalHelperControler::prev()
92{
93 m_base->prev( m_id );
94}
95
96/* The Queued Dialog inclusive QueuedBar */
97struct OModalQueueBar : public QHBox
98{
99 QPushButton* next;
100 QPushButton* prev;
101 QLabel * label;
102
103 OModalQueueBar( QWidget* parent );
104 void setText( const QString& str );
105};
106
107OModalQueueBar::OModalQueueBar( QWidget* parent )
108 : QWidget( parent, "OModal Queue Bar" )
109{
110 prev = new QPushButton( this );
111 prev->setText( OModalQueuedDialog::tr("Prev") );
112
113 label = new QLabel(this);
114
115 next = new QPushButton( this );
116 next->setText( OModalQueuedDialog::tr("Next") );
117}
118
119void OModalQueueBar::setText( const QString& str )
120{
121 label->setText( str );
122}
123
124
125OModalQueuedDialog::OModalQueuedDialog( QDialog* mainWidget )
126 : QDialog(0, "OModal Queued Dialog" )
127{
128 QVBoxLayout *lay = new QVBoxLayout( this );
129
130 m_bar = new OModalQueueBar( this );
131 lay->addWidget( m_bar );
132
133 m_center = mainWidget;
134 m_center->reparent(this, 0, QPoint(0, 0) );
135 lay->addWidget( m_center );
136
137
138 connect(m_bar->next, SIGNAL(clicked() ), this,
139 SIGNAL(next() ) );
140 connect(m_bar->prev, SIGNAL(clicked() ), this,
141 SIGNAL(prev() ) );
142
143}
144
145OModalQueuedDialog::~OModalQueuedDialog()
146{}
147
148QDialog* OModalQueuedDialog::centerDialog()const
149{
150 return m_center;
151}
152
153void OModalQueuedDialog::setQueueBarEnabled( bool b)
154{
155 /* in Qt3 use setEnabled( bool ) */
156 if (b)
157 m_bar->show();
158 else
159 m_bar->hide();
160}
161
162void OModalQueuedDialog::setRecord( int record, int count )
163{
164 if (!record && !count )
165 {
166 hide();
167 return;
168 }
169 else
170 show();
171
172 if ( count > 1 )
173 m_bar->show();
174 else
175 m_bar->hide();
176
177 m_bar->setText( tr("Editing record %1 out of %2",
178 "Shows the current edited record out of an array of records").arg( record ). arg( count ) );
179}
diff --git a/libopie2/opieui/big-screen/omodalhelper.h b/libopie2/opieui/big-screen/omodalhelper.h
new file mode 100644
index 0000000..096cec4
--- a/dev/null
+++ b/libopie2/opieui/big-screen/omodalhelper.h
@@ -0,0 +1,774 @@
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#ifndef OMODALHELPER_H
30#define OMODALHELPER_H
31
32/* QT*/
33#include <qdialog.h>
34#include <qwidget.h>
35#include <qvaluelist.h>
36#include <qmap.h>
37#include <qvariant.h>
38
39typedef int TransactionID;
40
41class QDialog;
42
43namespace Opie
44{
45
46class OModalHelperControler;
47class OModalHelperSignal;
48
49struct OModalHelperBase
50{
51 virtual void done( int status, TransactionID ) = 0;
52 virtual void next( TransactionID ) = 0;
53 virtual void prev( TransactionID ) = 0;
54};
55
56/**
57 * Modality sucks! ;) But it is easy to work with
58 * do exec() on a dialog and you know everything is funky.
59 * You only need to have one Dialog loaded and so on.
60 * This class helps you to work like with modality and help
61 * you to keep things in sync
62 * It's a template class but it sends signals once one Item is ready
63 * the signals contains the status and id of the item and then you
64 * need fetch it.
65 * Handled Records will stay available until the first call to retrieve
66 * either the record via the TransactionID or via the QValueList<Record>. Note
67 * that most functions do not take handled records into account.
68 * Also if you edit an record external you can tell this class and it'll
69 * call the merge() function of your widget to maybe merge in these changes.
70 * It also supports multiple modes. Either it can create new dialogs
71 * for each item or it can queue them depending on your usage. But it is
72 * so smart that if only one item is shown that the queue bar is not shown
73 * See the example for simple usage.
74 *
75 * @short helps to life without modaility
76 * @author hOlgAr
77 * @version 0.01
78 */
79template<class Dialog, class Record, typename Id = int>
80class OModalHelper : private OModalHelperBase
81{
82 friend class OModalHelperSignal;
83 friend class OModalHelperControler;
84public:
85 typedef QValueList<Record> RecordList;
86 typedef QMap<Id, Record> IdMap;
87 typedef QMap<TransactionID, Id> TransactionMap;
88 typedef QMap<QDialog*, TransactionID> DialogMap
89 enum Mode { Queue, New };
90 OModalHelper(enum Mode mode, QObject* parnet );
91
92 bool handles( Id id)const;
93 TransactionID transactionID( Id id)const;
94
95 void suspend( bool = true );
96
97 void cancel();
98 void cancel( TransactionID );
99
100 void connectDone( QObject* rec, const char* slot );
101 void connectAccepted( QObject* rec, const char* slot );
102 void connectRejected( QObject* rec, const char* slot );
103
104 TransactionID handle( Id id, const Record& rec = Record() );
105
106 void edited( Id, int what, const QVariant& data );
107
108 Record record( TransactionID )const;
109 RecordList recordsDone()const;
110private:
111 virtual void done( int, TransactionID );
112 virtual void next( TransactionID );
113 virtual void prev( TransactionID );
114
115 Record nextRecord( TransactionID &, int & )const;
116 Record prevRecord( TransactionID &, int & )const;
117 int pos( TransactionID )const;
118 Dialog* newDialogRecord( const Record& );
119
120private:
121 OModalHelperDialog *queuedDialog()const; // generate or recycle
122 OModalHelperDialog *m_dialog;
123 OModalHelperSignal *m_signal; // our signal
124 OModalHelperControler *m_controler;
125 IdMap m_ids; // maps ids (uids) to a record
126 IdMap m_doneIds;
127 TransactionMap m_transactions; // activate transactions
128 TransactionMap m_done; // done and waiting for getting picked
129 DialogMap m_editing; // only used for New Mode
130 enum Mode m_mode; // the mode we're in
131bool m_disabled :1;
132};
133
134
135
136/* ### FIXME use namespace with Qt3 */
137
138/*
139 * A note on flow. The Signal is used for QT Signals when
140 * a record is done.
141 * There is either one controler and this controler slot will
142 * be connected to a dialog signal.
143 * In Queue we get the next and prev signals and call the Helper.
144 * this then changes the Record of the dialog and sets the transactionId
145 * of the controler.
146 * For the new mode
147 *
148 */
149
150class OModalHelperSignal : public QObject
151{
152 Q_OBJECT
153public:
154 OModalHelperSignal(OModalHelperBase* base, QObject* parent);
155 ~OModalHelperSignal();
156
157signals:
158 done( int status, TransactionID transaction );
159 accepted( TransactionID transaction );
160 rejected( TransactionID transaction );
161
162private:
163 OModalHelperBase* m_base;
164};
165
166
167class OModalHelperControler : public QObject
168{
169 Q_OBJECT
170public:
171 OModalHelperControler( OModalHelperBase* , QObject* parent);
172 virtual TransactionID transactionID()const;
173 void setTransactionID( TransactionID id );
174 QDialog* dialog()const;
175
176public slots:
177 virtual void done(int result );
178 virtual void next();
179 virtual void prev();
180private:
181 QDialog *m_dia;
182 TransactionID m_id;
183 OModalHelperBase *m_base;
184}
185
186struct OModalQueueBar;
187class OModalQueuedDialog : public QDialog
188{
189 Q_OBJECT
190public:
191 OModalQueuedDialog(QDialog *mainWidget);
192 ~OModalQueuedDialog();
193
194 QDialog* centerDialog()const;
195
196 void setQueueBarEnabled( bool = true );
197 void setRecord( int record, int count );
198
199signals:
200 void next();
201 void prev();
202
203private:
204 OModalQueueBar *m_bar;
205 QDialog *m_center;
206};
207
208
209/*
210 * Tcpp Template Implementation
211 */
212
213/**
214 * This is the simple Template c'tor. It takes the mode
215 * this helper should operate in and the parent object.
216 * This helper will be deleted when the parent gets deleted
217 * or you delete it yourself.
218 *
219 * @param mode The mode this dialog should be in
220 * @param parent The parent QObject of this helper.
221 */
222template<class Dialog, class Record, typename Id>
223OModalHelper<Dialog, Record, Id>::OModalHelper( enum Mode mode, QObject* parent )
224{
225 m_disabled = false;
226 m_mode = mode;
227 m_signal = new OModalHelperSignal( this, parent );
228 m_controler = new OModalHelperControler( this, m_signal );
229}
230
231
232/**
233 * This functions looks for your record and sees if it is
234 * handled with this helper. Note that done records
235 * will not be returned.
236 *
237 * @return true if the record is currenlty edited otherwise false
238 *
239 * @param Id The id which might be handled
240 */
241template<class Dialog, class Record, typename Id>
242bool OModalHelper<Dialog, Record, Id>::handles( Id id )const
243{
244 if ( m_transactions.isEmpty() )
245 return false;
246
247 TransactionMap::ConstIterator it = m_transactions.begin();
248 for ( ; it != m_transactions.end(); ++it )
249 if ( it.data() == id )
250 return true;
251
252 return false;
253}
254
255
256/**
257 * just like handles( Id ) but returns the TransactionId
258 */
259template<class Dialog, class Record, typename Id>
260TransactionID OModalHelper<Dialog, Record, Id>::transactionID( Id id)const
261{
262 if ( m_transactions.isEmpty() || !m_ids.contains( id ) )
263 return 0;
264
265 TransactionMap::ConstIterator it = m_transactions.begin();
266 for ( ; it != m_transactions.end(); ++it )
267 if ( it.data() == id )
268 return it.key();
269
270 return 0;
271}
272
273/**
274 * If you're requested to flush your data and you do not want
275 * to call cancel with this method you can disable and enabled
276 * all dialogs.
277 * The state gets saved so if you want to handle a new record the dialog
278 * will be disabled as well.
279 *
280 * @param sus If true setDisabled(TRUE) will be called otherwise FALSE
281 */
282template<class Dialog, class Record, typename Id>
283void OModalHelper<Dialog, Record, Id>::suspend(bool sus)
284{
285 m_disabled = sus;
286 if (m_mode == New )
287 for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it )
288 it.key()->setDisabled( sus );
289 else if (m_dialog )
290 queuedDialog()->setDisabled( sus );
291}
292
293/**
294 * Cancel will cancel all current operations and clear the list
295 * of done operations as well.
296 * This also clears all done operations you did not popped
297 */
298template<class Dialog, class Record, typename Id>
299void OModalHelper<Dialog, Record, Id>::cancel()
300{
301 m_ids.clear();
302 m_doneIds.clear();
303 m_done.clear();
304 m_transactions.clear();
305
306 /* we also need to remove the QDialogs */
307 /* and hide the queue dialog if present */
308 if (m_mode == New && !m_editing.isEmpty() )
309 {
310 for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it )
311 delete it.key();
312
313 m_editing.clear();
314 }
315 else if (m_dialog )
316 queuedDialog()->setRecord( 0, 0 );
317
318 m_controler->setTransactionID( 0 );
319}
320
321
322/**
323 * This cancels editing of the record behind the Transaction Number
324 * Note that if editing is already done it will also be removed from this list
325 */
326template<class Dialog, class Record, typename Id>
327void OModalHelper::cancel( TransactionID tid )
328{
329 /* wrong tid */
330 if (!m_transactions.contains( tid ) && !m_done.contains( tid) )
331 return;
332
333 if (m_mode == New )
334 /* reverse map eek */
335 for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it )
336 if ( it.data() == tid )
337 {
338 it.key()->hide();
339 delete it.key();
340 it = m_editing.remove( it );
341 break;
342 }
343
344 /* now remove from the various maps done and currently editing map*/
345 if (m_transactions.contains( tid ) )
346 m_ids.remove( m_transactions[tid] );
347 if (m_done.contains( tid ) )
348 m_doneIds.remove( m_done[tid ] );
349 m_done.remove( tid );
350 m_transactions.remove( tid );
351
352 next( 0 );
353}
354
355/**
356 * Connect to the done Signal. SIGNAL( done(int, TransactionID ) )
357 * This signal gets emitted whenever a Record was accepted or rejected
358 *
359 * @param rec The object where the slot belongs to
360 * @param slot The slot which should be called. See the needed parameter above
361 */
362template<class Dialog, class Record, typename Id>
363void OModalHelper<Dialog, Record, Id>::connectDone( QObject* rec, const char* slot )
364{
365 QObject::connect(m_signal, SIGNAL(done(int, TransactionID) ),
366 rec, slot );
367}
368
369/**
370 * Connect to the accepted Signal. SIGNAL( accepted(TransactionID ) )
371 * This signal gets emitted whenever a Record was accepted
372 *
373 * @param rec The object where the slot belongs to
374 * @param slot The slot which should be called. See the needed parameter above
375 */
376template<class Dialog, class Record, typename Id>
377void OModalHelper<Dialog, Record, Id>::connectAccepted( QObject* rec, const char* slot )
378{
379 QObject::connect(m_signal, SIGNAL(accepted(TransactionID) ),
380 rec, slot );
381}
382
383/**
384 * Same as the accepted method but this one gets emitted if the dialog
385 * got rejected.
386 * SIGNAL( rejected(TransactionID) )
387 *
388 * @param rec The QObject of the slot
389 * @param slot The slot make sure the signature is correct
390 */
391template<class Dialog, class Record, typename Id>
392void OModalHelper<Dialog, Record, Id>::connectRejected( QObject* rec, const char* slot )
393{
394 QObject::connect(m_signal, SIGNAL(rejected(TransactionID) ),
395 rec, slot );
396}
397
398/**
399 * Tell the helper to handle a record. If the record is currently handled
400 * it will be made active.
401 * Already handled record which are waiting getting popped are not taken into account
402 * Otherwise this helpers make the record editable.
403 * The record supplied needs to have a valid copy operator and constructor.
404 * In the case where the record is already present the parameter gets discarded.
405 * If you want the new record to be taken you need to cancel the Transaction first
406 *
407 * @param id The Identification of the Record. For PIM it would uid()
408 * @param rec The record we want to be edited
409 *
410 * @returns This functions returns the TransactionId assigned to the record
411 *
412 */
413template<class Dialog, class Record, typename Id>
414TransactionID OModalHelper<Dialog, Record, Id>::handle( Id id, const Record& rec )
415{
416 static TransactionID t_id = 0;
417 /*
418 *this method consists out of two parts divided each into New and Queued Mode.
419 * Either we have the dialog already, in this case we need to highlight the widget
420 * Or we need to add it.
421 */
422 TransactionID tid = 0;
423 /* we already have the record lets see if it was done or not */
424 if ( !(tid = transactionID( id ) ) )
425 {
426 if (m_mode == New )
427 {
428 /* lets find the dialog and show it need to reverse map*/
429 for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it )
430 if ( it.data() == tid )
431 it.key()->show();
432 }
433 else if (m_controler->transactionID() != tid )
434 {
435 int po = pos( tid );
436 m_controler->setTransactionID( tid );
437 static_cast<Dialog*>( queuedDialog()->centerDialog() )->setRecord( m_ids[ m_transactions[tid] ] );
438 queuedDialog()->setRecord( po, m_transactions.count() );
439 }
440 }
441 else
442 {
443 tid = ++t_id;
444 m_transactions.insert( tid, id );
445 m_ids.insert( id, rec );
446
447 if (m_mode == New )
448 m_editing.insert( newDialogRecord( rec ), tid );
449 else
450 {
451 m_controler->setTransactionID( tid );
452 static_cast<Dialog*>( queuedDialog()->centerDialog() )->setRecord( rec );
453 queuedDialog()->setRecord( m_transactions.count(), m_transactions.count() );
454 }
455 }
456 return tid;
457}
458
459/**
460 * The goal of this helper is to help you to create non blocking
461 * GUIs. In the example of the todolist you can have the edit dialog
462 * but still change the priority or completion inline even if you currently
463 * edit the record.
464 * Your Dialog needs to have a Method setData(int,const QVariant& ) which will be called
465 * in these cases.
466 * If you edit anything while a record is edited call this function to merge the
467 * change in. Note if the record is not handled here we will ignore the request
468 *
469 */
470template<class Dialog, class Record, typename Id>
471void OModalHelper<Dialog, Record, Id>::edited( Id id, int what, const QVariant& data )
472{
473 int tid;
474 if (!( tid = transactionID( id ) ) )
475 return;
476
477 if (m_mode == New )
478 {
479 for (DialogMap::Iterator it= m_editing.begin(); it != m_editing.end(); ++it )
480 if ( it.data() == tid )
481 it.key()->setData( what, data );
482 }
483 else
484 {
485 int po = pos( tid );
486 Dialog* dia = static_cast<Dialog*>( queuedDialog()->centerDialog() );
487 dia->setRecord( m_ids[id] );
488 dia->setData( what, data );
489 queuedDialog()->setRecord( pos, m_transactions.count() );
490 }
491}
492
493/**
494 * This functions either returns the unedited record the done record
495 * or a new empty Record using Record().
496 * If a done record is retrieved all traces are removed inside this class. This
497 * is what was called popping a record. This means when you call this function
498 * with the same TransactionID an Empty record is retrieved.
499 *
500 */
501template<class Dialog, class Record, typename Id>
502Record OModalHelper<Dialog, Record, Id>::record( TransactionID tid)const
503{
504 if (m_transactions.contains( tid ) )
505 return m_ids[ m_transactions[tid] ];
506 else if (m_done.contains( tid ) )
507 {
508 Record rec = m_doneIds[ m_done[ tid] ];
509 m_doneIds.remove( m_done[ tid ] );
510 m_done.remove( tid );
511 return rec;
512 }
513 else
514 return Record();
515}
516
517/**
518 * Returns all done Records and removes all references to them internally. A 2nd call to this will
519 * only contain done record that where edited past the point
520 */
521template<class Dialog, class Record, typename Id>
522OModalHelper<Dialog,Record,Id>::RecordList OModalHelper<Dialog, Record, Id>::recordsDone()const
523{
524 RecordList list;
525
526 for (IdMap::ConstIterator it = m_doneIds.begin(); it != m_doneIds.end(); ++it )
527 list.append( it.data() );
528
529 /* clean up */
530 m_done.clear();
531 m_doneIds.clear();
532
533 return list;
534}
535
536
537/**
538 * @internal
539 */
540template<class Dialog, class Record, typename Id>
541void OModalHelper<Dialog, Record, Id>::done( int status, TransactionID tid)
542{
543 /* If we're in New mode the transaction Id does not count */
544 Record rec;
545
546 if (m_mode == New )
547 {
548 Dialog *dia = static_cast<Dialog*>( m_controler->dialog() );
549 m_controler->setTransactionID( 0 ); // set the internal dialog to 0l again
550 tid = m_editing[ dia ];
551 m_editing.remove( dia );
552 rec = dia->record();
553 delete dia;
554 }
555 else
556 rec = queuedDialog()->record();
557
558 Id id = m_transactions[ tid ];
559 if (result == QDialog::Accept )
560 {
561 m_doneIds.insert( is, rec );
562 m_done.insert( tid, id );
563 }
564
565 m_transactions.remove( tid );
566 m_ids.remove( id );
567
568
569 if (status == QDialog::Accept )
570 emit m_signal->accepted( tid );
571 else
572 emit m_signal->rejected( tid );
573
574 emit m_signal->done( result, tid );
575
576 next( 0 );
577}
578
579/**
580 * @internal
581 */
582template<class Dialog, class Record, typename Id>
583void OModalHelper<Dialog, Record, Id>::next( TransactionID tid)
584{
585 if (m_mode == New )
586 return;
587
588 if (! (m_transactions.count() ) )
589 {
590 m_controler->setTransactionID( 0 );
591 queuedDialog()->setRecord( 0, 0 );
592 return;
593 }
594
595 int next;
596 Record rec;
597
598 /* save the maybe edited record before switching */
599 Dialog *dia = static_cast<Dialog*>( queuedDialog()->centerDialog() );
600 rec = dia->record();
601 m_ids.replace( m_transactions[tid], rec );
602
603 rec = nextRecord( tid, next );
604 queuedDialog()->setRecord( next, m_transactions.count() );
605 dia->setRecord( rec );
606
607 m_controler->setTransactionID( tid ); // was changed during the next call
608}
609
610/**
611 * @internal
612 */
613/*
614 * code duplication should create a template fcuntion
615 * which takes a pointer to a function ( next, prev ) function
616 */
617template<class Dialog, class Record, typename Id>
618void OModalHelper<Dialog, Record, Id>::prev( TransactionID tid )
619{
620 if (m_mode == New )
621 return;
622
623 if (! (m_transactions.count()) )
624 {
625 m_controler->setTransactionID( 0 );
626 queuedDialog()->setRecord( 0, 0 );
627 return;
628 }
629
630 int prev;
631 Record rec;
632
633 /* save the maybe edited record before switching */
634 Dialog *dia = static_cast<Dialog*>( queuedDialog()->centerDialog() );
635 rec = dia->record();
636 m_ids.replace( m_transactions[tid], rec );
637
638 rec = prevRecord( tid, prev );
639 queuedDialog()->setRecord( prev, m_transactions.count() );
640 dia->setRecord( rec );
641
642 m_controler->setTransactionID( tid ); // was changed during the next call
643}
644
645/**
646 * @internal
647 */
648template<class Dialog, class Record, typename Id>
649Record OModalHelper<Dialog, Record, Id>::nextRecord( TransactionID &tid, int &po )
650{
651 /* if tid is == 0 we will take the first one */
652 /* pos starts at 1 here */
653 /* we know we're only called if there are records */
654 Record rec;
655 TransactionMap::Iterator it;
656 if (!tid )
657 {
658 po = 1;
659 TransactionMap::Iterator it = m_transactions.begin();
660 }
661 else
662 {
663 po = pos( tid );
664 /* if it is the last take the first as next */
665 if ( po == m_transactions.count() )
666 {
667 po = 1;
668 it = m_transactions.begin();
669 }
670 else
671 {
672 /* we know we're not the last and there is one after us */
673 it = m_transactions.find( tid );
674 ++it; ++po;
675 }
676 }
677
678 tid = it.key();
679 rec = m_ids[ tid ];
680 return rec;
681}
682
683/**
684 * @internal
685 */
686template<class Dialog, class Record, typename Id>
687Record OModalHelper<Dialog, Record, Id>::prevRecord( TransactionID& tid, int& pos )
688{
689 /* if tid is == 0 we will take the first one */
690 /* pos starts at 1 here */
691 /* we know we're only called if there are records */
692 Record rec;
693 TransactionMap::Iterator it;
694 if (!tid )
695 {
696 po = 1;
697 TransactionMap::Iterator it = m_transactions.begin();
698 }
699 else
700 {
701 po = pos( tid );
702 /* if it is the last take the first as next */
703 if ( po == 1 )
704 {
705 po = m_transactions.count();
706 it = m_transactions.end();
707 --it;
708 }
709 else
710 {
711 /* we know we're not the first and there is one before us */
712 it = m_transactions.find( tid );
713 --it; --po;
714 }
715 }
716
717 tid = it.key();
718 rec = m_ids[ tid ];
719 return rec;
720}
721
722/**
723 * @internal
724 */
725template<class Dialog, class Record, typename Id>
726int OModalHelper<Dialog, Record, Id>::pos( TransactionID id)const
727{
728 int i = 1;
729 for ( TransactionMap::ConstIterator it = m_transactions.begin(); it != m_transactions.end(); ++it, i++ )
730 if ( it.key() == id )
731 return i;
732
733
734 return 0;
735}
736
737/**
738 * @internal
739 */
740template<class Dialog, class Record, typename Id>
741Dialog* OModalHelper<Dialog, Record, Id>::newDialogRecord( const Record& rec )
742{
743 Dialog* dia = new Dialog;
744 dia->setRecord( rec );
745 dia->setDisabled( m_disabled );
746
747 QObject::connect(dia, SIGNAL(done(int) ),
748 m_controler, SLOT(done(int) ) );
749
750 /* FIXME big screen QPEApplication needs fixed*/
751 dia->show();
752}
753
754template<class Record, class Dialog, typename Id>
755OModalHelperDialog* OModalHelper<Record, Dialog, Id>::queuedDialog()const
756{
757 if (!m_dialog )
758 {
759 m_dialog = new OModalHelperDialog;
760 m_dialog->setEnabled( m_disabled );
761
762 QObject::connect(m_dialog, SIGNAL(done(int) ),
763 m_controler, SLOT(done(int) ) );
764 QObject::connect(m_dialog, SIGNAL(next() ),
765 m_controler, SLOT(next() ) );
766 QObject::connect(m_dialog, SIGNAL(prev() ),
767 m_controler, SLOT(prev() ) );
768 }
769 return m_dialog;
770}
771
772};
773
774#endif
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}
diff --git a/libopie2/opieui/big-screen/osplitter.h b/libopie2/opieui/big-screen/osplitter.h
new file mode 100644
index 0000000..2daae7f
--- a/dev/null
+++ b/libopie2/opieui/big-screen/osplitter.h
@@ -0,0 +1,150 @@
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#ifndef OSPLITTER_H
30#define OSPLITTER_H
31
32#include "obigscreen_p.h"
33
34/* QT */
35#include <qframe.h>
36#include <qlist.h>
37#include <qstring.h>
38#include <qvaluelist.h>
39
40class QHBox;
41
42//template class QValueList<Opie::OSplitterContainer>;
43
44/*
45 * TODO
46 * -check API docu
47 * -one more example
48 * -allow inserting at a position
49 */
50
51namespace Opie
52{
53class OTabWidget;
54
55/**
56 *
57 * If you've widgets that could be placed side by side but you think
58 * on small resolutions is not enough place but it would really make sense
59 * on bigger resolutions this class will help you.
60 * You can add as many widgets you want to it. Set a poliy on which width/height it
61 * should switch the layout.
62 * You can either say to place widgets vertical or horizontal.
63 * This class uses QHBox, QVBox and QTAbWidget internally.
64 * OSplitter takes ownership of the widgets
65 *
66 * @since 1.2
67 *
68 * @short a small dynamically changing its layout to store two or more widgets side by side
69 * @version 0.1
70 * @author zecke
71 */
72class OSplitter : public QFrame
73{
74 Q_OBJECT
75public:
76 typedef QValueList<Opie::OSplitterContainer> ContainerList;
77 OSplitter( Qt::Orientation = Horizontal, QWidget *parent = 0,
78 const char* name = 0, WFlags fl = 0 );
79 ~OSplitter();
80
81 void setLabel( const QString& name );
82 void setIconName( const QString& name );
83 QString label()const;
84 QString iconName()const;
85
86 void setSizeChange( int width_height );
87
88 void addWidget( OSplitter* splitter );
89 void addWidget( QWidget* wid, const QString& icon, const QString& label );
90 void removeWidget( QWidget* );
91 void removeWidget( OSplitter* );
92
93 void setCurrentWidget( QWidget* );
94 void setCurrentWidget( const QString& label );
95 void setCurrentWidget( int );
96 QWidget* currentWidget()const;
97
98
99signals:
100 /**
101 * Emitted if in tab and comes directly from the tab widget
102 *
103 */
104 void currentChanged( QWidget* );
105
106 /**
107 * emitted whenever a border is crossed
108 * true if in small screen mode
109 * false if in bigscreen
110 * this signal is emitted after the layout switch
111 * @param b The layout mode
112 * @param ori The orientation
113 */
114 void sizeChanged( bool b, Orientation ori);
115public:
116 // QSize sizeHint()const;
117 // QSize minimumSizeHint()const;
118
119protected:
120 void resizeEvent( QResizeEvent* );
121
122private:
123 /* true if OTabMode */
124 bool layoutMode()const;
125 // void reparentAll();
126 void setTabWidget( OTabWidget*);
127 void addToTab( const Opie::OSplitterContainer& );
128 void addToBox( const Opie::OSplitterContainer& );
129 void removeFromTab( QWidget* );
130 void changeTab();
131 void changeHBox();
132 void changeVBox();
133 void commonChangeBox();
134 QHBox *m_hbox;
135 OTabWidget *m_tabWidget;
136 OTabWidget *m_parentTab;
137 Orientation m_orient;
138 int m_size_policy;
139
140 ContainerList m_container;
141 QList<OSplitter> m_splitter;
142
143 QString m_icon, m_name;
144
145 struct Private;
146 Private *d;
147};
148};
149
150#endif
diff --git a/libopie2/opieui/big-screen/owidgetstack.cpp b/libopie2/opieui/big-screen/owidgetstack.cpp
new file mode 100644
index 0000000..57e97e3
--- a/dev/null
+++ b/libopie2/opieui/big-screen/owidgetstack.cpp
@@ -0,0 +1,435 @@
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 "owidgetstack.h"
30
31/* QT */
32#include <qapplication.h>
33#include <qwidgetstack.h>
34
35namespace {
36 const int mode_size = 330;
37}
38
39using namespace Opie;
40
41/**
42 * This is the standard widget. For simple usage see the example. Normally this widget
43 * is the central widget of a QMainWindow.
44 * Use removeWidget before you delete a widget yourself. OWidgetStack does not
45 * yet recognize removal of children.
46 *
47 * @param parent The parent widget. It maybe 0 but then you need to take care of deletion.
48 * Or you use QPEApplication::showMainWidget().
49 * @param name Name will be passed on to QObject
50 * @param fl Additional window flags passed to QFrame. see @Qt::WFlags
51 */
52OWidgetStack::OWidgetStack( QWidget* parent, const char* name, WFlags fl)
53 : QFrame( parent, name, fl )
54{
55 m_last = m_mWidget = 0;
56 m_forced = false;
57
58 QApplication::desktop()->installEventFilter( this );
59 setFontPropagation ( AllChildren );
60 setPalettePropagation( AllChildren );
61
62 /* sets m_mode and initializes more */
63 /* if you change this call change switchTop as well */
64 m_stack = 0;
65 switchStack();
66}
67
68/**
69 * The destructor. It deletes also all added widgets.
70 *
71 */
72OWidgetStack::~OWidgetStack() {
73 if (m_mode == BigScreen && !m_list.isEmpty() ) {
74 QMap<int, QWidget*>::Iterator it = m_list.begin();
75 for ( ; it != m_list.end(); ++it )
76 delete it.data();
77 }
78 m_list.clear();
79
80}
81
82/**
83 * return the mode of the desktop. There are currently two modes. SmallScreen
84 * with a normal PDA resolution and BigScreen with resolutions greater than
85 * 330 for width and height.
86 * You can also force the mode this widget is in with forceMode()
87 * Note that NoForce will be never returned from here
88 */
89enum OWidgetStack::Mode OWidgetStack::mode()const {
90 return m_mode;
91}
92
93/**
94 * You can also force one of the modes and then
95 * this widget stops on listening to size changes. You
96 * can revert to the scanning behaviour by setting mode
97 * to NoForce
98 */
99void OWidgetStack::forceMode( enum Mode mode) {
100 m_forced = mode != NoForce;
101
102 /* we need to see which mode we're in */
103 if (!m_forced ) {
104 if ( QApplication::desktop()->width() >=
105 mode_size )
106 mode = BigScreen;
107 else
108 mode = SmallScreen;
109 }
110 switch( mode ) {
111 case NoForce:
112 case SmallScreen:
113 switchStack();
114 break;
115 case BigScreen:
116 switchTop();
117 break;
118
119 }
120
121 m_mode = mode;
122}
123
124/**
125 * Adds a widget to the stack. The first widget added is considered
126 * to be the mainwindow. This is important because if Opie is in
127 * BigScreen mode the sizeHint of the MainWindow will be returned.
128 * In Small Screen the sizeHint of the QWidgetStack is returned.
129 * See QWidgetStack::sizeHint.
130 * This widget takes ownership of the widget and may even reparent.
131 * All windows will be hidden
132 *
133 * @param wid The QWidget to be added
134 * @param id An ID for the Widget. If the ID is duplicated the
135 last set widget will be related to the id
136 *
137 */
138void OWidgetStack::addWidget( QWidget* wid, int id) {
139 if (!wid)
140 return;
141
142 /* set our main widget */
143 if (!m_mWidget)
144 m_mWidget = wid;
145
146 m_list.insert( id, wid );
147
148 /**
149 * adding does not raise any widget
150 * But for our mainwidget we prepare
151 * the right position with the right parent
152 */
153 if (m_mode == SmallScreen )
154 m_stack->addWidget( wid,id );
155 else if ( m_mWidget == wid ) {
156 wid->reparent(this, 0, contentsRect().topLeft() );
157 wid->hide();
158 }else {
159 wid->reparent(0, WType_TopLevel, QPoint(10, 10) );
160 wid->hide();
161 }
162}
163
164
165/**
166 * Remove the widget from the stack it'll be reparented to 0
167 * and ownership is dropped. You need to delete it.
168 * If the removed widget was the mainwindow consider
169 * to call setMainWindow.
170 *
171 * @param wid The QWidget to be removed
172 */
173void OWidgetStack::removeWidget( QWidget* wid) {
174 if (!wid)
175 return;
176
177 if (m_mode == SmallScreen )
178 m_stack->removeWidget( wid );
179
180
181 wid->reparent(0, 0, QPoint(0, 0) );
182 m_list.remove( id(wid) );
183
184 if ( wid == m_mWidget )
185 m_mWidget = 0;
186}
187
188#if 0
189/**
190 * @internal_resons
191 */
192QSizeHint OWidgetStack::sizeHint()const {
193
194}
195
196/**
197 * @internal_reasons
198 */
199QSizeHint OWidgetStack::minimumSizeHint()const {
200
201}
202#endif
203
204/**
205 * This function tries to find the widget with the id.
206 * You supplied a possible id in addWIdget. Note that not
207 * QWidget::winId() is used.
208 *
209 * @param id The id to search for
210 *
211 * @return The widget or null
212 * @see addWidget
213 */
214QWidget* OWidgetStack::widget( int id) const {
215 return m_list[id];
216}
217
218/**
219 * Tries to find the assigned id for the widget
220 * or returns -1 if no widget could be found
221 * @param wid The widget to look for
222 */
223int OWidgetStack::id( QWidget* wid)const{
224 if (m_list.isEmpty() )
225 return -1;
226
227 QMap<int, QWidget*>::ConstIterator it = m_list.begin();
228 for ( ; it != m_list.end(); ++it )
229 if ( it.data() == wid )
230 break;
231
232 /* if not at the end return the key */
233 return it == m_list.end() ? -1 : it.key();
234}
235
236
237/**
238 * This function returns the currently visible
239 * widget. In BigScreen mode the mainwindow
240 * is returned
241 */
242QWidget* OWidgetStack::visibleWidget()const {
243 if (m_mode == SmallScreen )
244 return m_stack->visibleWidget();
245 else
246 return m_mWidget;
247
248}
249
250/**
251 * This method raises the widget wit the specefic id.
252 * Note that in BigScreen mode the widget is made visible
253 * but the other ( previous) visible widget(s) will not
254 * be made invisible. If you need this use hideWidget().
255 *
256 * @param id Raise the widget with id
257 */
258void OWidgetStack::raiseWidget( int id) {
259 return raiseWidget( widget( id ) );
260}
261
262/**
263 * This is an overloaded function and only differs in its parameters.
264 * @see raiseWidget( int )
265 */
266void OWidgetStack::raiseWidget( QWidget* wid) {
267 m_last = wid;
268 if (m_mode == SmallScreen )
269 m_stack->raiseWidget( wid );
270 else {
271 int ide;
272 emit aboutToShow( wid );
273 /* if someone is connected and the widget is actually available */
274 if ( receivers( SIGNAL(aboutToShow(int) ) ) &&
275 ( (ide = id( wid ) ) != -1 ) )
276 emit aboutToShow( ide );
277
278 /* ### FIXME PLACE THE WIDGET right */
279 wid->show();
280 }
281}
282
283/**
284 * This will hide the currently visible widget
285 * and raise the widget specified by the parameter.
286 * Note that this method does not use visibleWIdget but remembers
287 * the last raisedWidget
288 */
289void OWidgetStack::hideWidget( int id) {
290 /* hiding our main widget wouldn't be smart */
291 if ( m_mode == BigScreen && m_last != m_mWidget )
292 m_last->hide();
293 raiseWidget( id );
294}
295
296/**
297 * This is overloaded and only differs in the parameters
298 * it takes.
299 */
300void OWidgetStack::hideWidget( QWidget* wid) {
301 /* still not smart */
302 if ( m_mode == BigScreen && m_last != m_mWidget )
303 m_last->hide();
304
305 raiseWidget( wid );
306}
307
308
309bool OWidgetStack::eventFilter( QObject* obj, QEvent* e) {
310 qWarning(" %s %s", obj->name(), obj->className() );
311 if ( e->type() == QEvent::Resize ) {
312 QResizeEvent *res = static_cast<QResizeEvent*>( e );
313 QSize size = res->size();
314 if ( size.width() >= mode_size )
315 switchTop();
316 else
317 switchStack();
318 }
319 return false;
320}
321
322
323/**
324 * @internal_resons
325 */
326void OWidgetStack::resizeEvent( QResizeEvent* ev ) {
327 QFrame::resizeEvent( ev );
328 if (m_mode == SmallScreen )
329 m_stack->setGeometry( frameRect() );
330 else
331 if (m_mWidget )
332 m_mWidget->setGeometry( frameRect() );
333
334}
335
336/**
337 * setMainWindow gives the OWidgetStack a hint which
338 * window should always stay inside the stack.
339 * Normally the first added widget is considered to be
340 * the mainwindow but you can change this with this
341 * function.
342 * If in BigScreen mode the current mainwindow will be reparented
343 * and hidden. The position will be taken by the new one.
344 * If the old MainWindow was hidden the new window will
345 * also be hidden. If the window was visible the new mainwindow
346 * will be made visible too and the old one hidden. If there
347 * was no mainwindow it will be hidden as well.
348 *
349 * @param wid The new mainwindow
350 */
351void OWidgetStack::setMainWindow( QWidget* wid ) {
352 if (m_mode == BigScreen ) {
353 bool wasVisible = false;
354 if (m_mWidget ) {
355 wasVisible = !m_mWidget->isHidden();
356 /* hidden by default */
357 m_mWidget->reparent(0, WType_TopLevel, QPoint(10, 10) );
358 }
359 wid->reparent(this, 0, frameRect().topLeft() );
360
361 if (wasVisible)
362 wid->show();
363 }
364
365 m_mWidget = wid;
366}
367
368/**
369 * this is an overloaded member and only differs
370 * in the type of arguments.
371 * @see setMainWindow(QWidget*)
372 */
373void OWidgetStack::setMainWindow( int id) {
374 setMainWindow( widget( id ) );
375}
376
377
378/*
379 * this function switches to a stack ;)
380 */
381void OWidgetStack::switchStack() {
382 if (m_stack ) {
383 m_stack->setGeometry( frameRect() );
384 return;
385 }
386
387 m_mode = SmallScreen;
388 m_stack = new QWidgetStack(this);
389
390 connect(m_stack, SIGNAL(aboutToShow(QWidget*) ),
391 this, SIGNAL(aboutToShow(QWidget*) ) );
392 connect(m_stack, SIGNAL(aboutToShow(int) ),
393 this, SIGNAL(aboutToShow(int) ) );
394
395 /* now reparent the widgets... luckily QWidgetSatck does most of the work */
396 if (m_list.isEmpty() )
397 return;
398
399 QMap<int, QWidget*>::Iterator it = m_list.begin();
400 for ( ; it != m_list.end(); ++it )
401 m_stack->addWidget( it.data(), it.key() );
402
403
404}
405
406/*
407 * we will switch to top level mode
408 * reparent the list of widgets and then delete the stack
409 */
410void OWidgetStack::switchTop() {
411 m_mode = BigScreen;
412 /* this works because it is guaranteed that switchStack was called at least once*/
413 if (!m_stack && m_mWidget) {
414 m_mWidget->setGeometry( frameRect() );
415 return;
416 }else if (!m_stack)
417 return;
418
419 if (!m_list.isEmpty() ) {
420 QMap<int, QWidget*>::Iterator it = m_list.begin();
421 for ( ; it != m_list.end(); ++it ) {
422 /* better than reparenting twice */
423 if ( it.data() == m_mWidget ) {
424 m_mWidget->reparent(this, 0, frameRect().topLeft() );
425 m_mWidget->setGeometry( frameRect() );
426 m_mWidget->show();
427 }else
428 /* ### FIXME we need to place the widget better */
429 it.data()->reparent(0, WType_TopLevel, QPoint(10, 10) );
430 }
431 }
432
433 delete m_stack;
434 m_stack = 0;
435}
diff --git a/libopie2/opieui/big-screen/owidgetstack.h b/libopie2/opieui/big-screen/owidgetstack.h
new file mode 100644
index 0000000..53818c8
--- a/dev/null
+++ b/libopie2/opieui/big-screen/owidgetstack.h
@@ -0,0 +1,132 @@
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#ifndef OWIDGETSTACK_H
30#define OWIDGETSTACK_H
31
32/* QT*/
33#include <qframe.h>
34#include <qmap.h>
35
36class QWidgetStack;
37
38namespace Opie
39{
40/**
41 *
42 * OWidgetStack is the answer to the problem of using Opie at different screen
43 * sizes and to have a different behaviour. Most applications use a QWidgetStack
44 * to supply a view on click. And by clicking the (X) you go back but this
45 * behaviour feels strange on bigger screens. It's ok on smaller one because
46 * one can't determine the difference.
47 * This stack reads the default out of the size of the desktop widget but
48 * can be forced to have either the one or the other behaviour.
49 * The first widget added is considered the 'main' widget and its
50 * sizeHint will be taking if in BigScreen mode.
51 * In small screen mode this widget behaves exactly like a QWidgetStack and in BigScreen
52 * mode it'll use the MainWindow as child of this widget and arranges the others as
53 * hidden top level widgets.
54 *
55 * @version 0.1
56 * @author hOlgAr F.
57 * @short Either a true stack or a list of top Level widgets
58 */
59class OWidgetStack : public QFrame {
60 Q_OBJECT
61public:
62 enum Mode { SmallScreen, BigScreen, NoForce };
63 OWidgetStack( QWidget* parent, const char* name = 0, WFlags fl = 0 );
64 ~OWidgetStack();
65
66 enum Mode mode()const;
67 void forceMode( enum Mode );
68
69 void addWidget( QWidget* , int );
70 void removeWidget( QWidget* );
71
72// QSizeHint sizeHint()const;
73// QSizeHint minimumSizeHint()const;
74
75 QWidget *widget( int )const;
76 int id( QWidget* )const;
77
78
79
80 QWidget* visibleWidget() const;
81
82 bool eventFilter( QObject*, QEvent* );
83signals:
84 /**
85 * OWidgetStack monitors the Desktop Widget for
86 * size changes if it recignizes a change size it'll
87 * send a signal and adjust its mode. After the signal
88 * was emitted. During the signal a call to mode() the
89 * old mode will be returned. Note that if a size change happens
90 * but no modeChange no signal will be emitted
91 *
92 *
93 * @param mode The new mode of the desktop
94 */
95 void modeChanged( enum Mode mode);
96
97 /**
98 * These two signals are emitted whenever we're about to
99 * show one of the widgets
100 */
101 void aboutToShow( QWidget* );
102 void aboutToShow( int );
103
104public slots:
105 void raiseWidget( int );
106 void raiseWidget( QWidget* );
107 void hideWidget( int );
108 void hideWidget( QWidget* );
109 void setMainWindow( QWidget* );
110 void setMainWindow( int );
111
112protected:
113 void resizeEvent( QResizeEvent* );
114
115private:
116 void switchStack();
117 void switchTop();
118 QMap<int, QWidget*> m_list;
119 QWidgetStack *m_stack;
120 QWidget *m_mWidget;
121 QWidget *m_last;
122
123 enum Mode m_mode;
124 bool m_forced : 1;
125
126 struct Private;
127 Private *d;
128};
129
130};
131
132#endif
diff --git a/libopie2/opieui/opieui.pro b/libopie2/opieui/opieui.pro
index b9bf203..b07976b 100644
--- a/libopie2/opieui/opieui.pro
+++ b/libopie2/opieui/opieui.pro
@@ -47,6 +47,8 @@ SOURCES = ocheckitem.cpp \
47 otaskbarapplet.cpp \ 47 otaskbarapplet.cpp \
48 oseparator.cpp 48 oseparator.cpp
49 49
50include ( big-screen/big-screen.pro )
51
50INTERFACES = otimepickerbase.ui 52INTERFACES = otimepickerbase.ui
51 53
52TARGET = opieui2 54TARGET = opieui2