summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2004-01-15 15:32:10 (UTC)
committer mickeyl <mickeyl>2004-01-15 15:32:10 (UTC)
commit84bb8c9046007fe2adfaa016aded88b961c65e62 (patch) (side-by-side diff)
tree8d7a57903b8c66ed28943a7d112cef93dd94111c
parentac1e2b945965ee8caabd658e90f9e234fc622619 (diff)
downloadopie-84bb8c9046007fe2adfaa016aded88b961c65e62.zip
opie-84bb8c9046007fe2adfaa016aded88b961c65e62.tar.gz
opie-84bb8c9046007fe2adfaa016aded88b961c65e62.tar.bz2
libopie1 (bigscreen) --> libopie2/opieui
Diffstat (more/less context) (show 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 @@
+Makefile*
+obj
+moc*
+*moc
+*.o
+~*
+*base.cpp
+*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 @@
+Now that PDAs get a VGA resolution and Opie runs on Webpads
+and could be used as a Kiosk secure environment the design
+decision that were right for a 320x240/240x320 doesn't necessary
+to be right for bigger screens.
+
+Remember most desktops a few years ago had only a resolution
+of 800x600.
+Then also to remember is that a webpad with 640x480 is different to
+a PDA with the same resolution. The PDA has a much smaller
+physical display.
+
+With higher resolution the feeling of a desktop comes.
+
+Problems with current Opie:
+ -InputMethod use full width but most of the times are not high enough
+ This actually makes it harder to input and looks stupid.
+ -ToolBars only feels strange on bigger screens. Maybe do it like WinCE3 does
+ share the ToolBar with MenuBar if they're too big for the screen allow handles
+ to either show the left or right side. Note that the handle from Qt looks
+ bad and should be patched away
+ -The Escape/Close back to View does not make sense on bigger screens and desktop
+ on a desktop you might even want to show multiple views and detach from the 'system'
+ view
+ -Modality. Dunnow how you get back to the enter dialog without modality in Qt/E fix it?
+ On bigger screen this is not the problem you can move windows. But you should try
+ to be less modal in the future.
+ I've added a small to qpeapplication to iterate over the toplevel widgets 99%
+ ( click on the taskbar to iterate over the widgets first time nothing is changed )
+ , BUT it should be avoided to use modality showMaximized(), exec()
+ INSTEAD we will use a modal helper where one can register to show a dialog for uid
+ type and will get a signal once the settings need to be applied, rejected or discarded.
+ This way you can almost work like with exec(), do not need to care for freeing.
+ Problems sometimes to have more than one dialog in memory is expensive. Allow queueing
+ and reusing this widget ( only set the Record new? )
+ -Viewing on bigger screens you may want to have a seperate viewer widget ( topLevel ) which
+ might also get spon off from the normal operation. The (X) close go back does not make
+ sense on bigger screens and feels strange
+ -Sizing and Auto sizing of widgets
+
+Widgets and Classes
+
+ Toolbar/Action and Popups:
+ While KParts with XMLGUI provide a fantastic technology to change the GUI
+ on the fly. Parsing these GUI descriptions is not an option for PDAs
+ specially not on start up.
+ Instead we will need to use normal object in this case QAction and QPopupMenuss. We
+ will then group these Actions into groups. Each group can have children and one
+ parent. Each group has two attributes one for the menubar and one for the toolbar.
+ Attributes for each might be | together. Always, Never, Auto are the attributes I
+ can think of tonite. Always will place this group always there, Never yeah never,
+ Automatic lets the later described Manager decide. Also one could or MightSpinOff
+ to a group. This way a child group might get spon off if enough place is there.
+ You cann add QAction and QPopupMenus to the group the Group will not take owner ship
+ and you might use your QAction in other places as well.
+ Toplevel groups need to be registered to the manager and this manager will depending
+ on global settings place and control MenuBar and ToolBar/ToolBar.
+ This allows to dynamically create toolbar on the fly
+
+ Modality class:
+ It'll be a template with a QSignal to tell about changes and a method to get to know
+ which action to be applied. It has three template parameters one for the WIdget used
+ and one for the type of uid and the last for the editor widget which
+ at least needs to provide some methods as well.
+ If you need to edit an widget you simply tell the helper about it. If present it'll
+ raise the widget or either queue it or create a new editor depending on a policy
+ one can set manually or get from the system.
+
+ Viewing:
+ We will provide a special OWidgetStack which either is a real QWidgetStack or a QList
+ of toplevel widgets to be raised. One has to see how one can use it with todolist
+ and datebook. specially the switching back and forth need to be handled but with possible
+ no code reordering ( least intrusive )
+ Viewing II:
+ Example Advanced FM has a tabwidget but on a SIMpad it would make perfect sense to use a
+ QSplitter or QVBox. We will provide an OSplitter which either provides the one
+ or the other widget depending on the size
+
+
+These small changes ( replacing Q with O + bit more) should make Opie a better environment for
+bigger screens. The additional library memory is a fair trade off and memory can be recovered
+by 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 @@
+HEADERS += big-screen/obigscreen_p.h big-screen/osplitter.h big-screen/owidgetstack.h #big-screen/omodalhelper.h
+SOURCES += 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 @@
+/*
+               =. This file is part of the OPIE Project
+             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
+           .>+-=
+ _;:,     .>    :=|. This library is free software; you can
+.> <`_,   >  .   <= redistribute it and/or modify it under
+:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
+.="- .-=="i,     .._ License as published by the Free Software
+ - .   .-<_>     .<> Foundation; either version 2 of the License,
+     ._= =}       : or (at your option) any later version.
+    .%`+i>       _;_.
+    .i_,=:_.      -<s. This library is distributed in the hope that
+     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
+    : ..    .:,     . . . without even the implied warranty of
+    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
+  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
+..}^=.=       =       ; Library General Public License for more
+++=   -.     .`     .: details.
+ :     =  ...= . :.=-
+ -.   .:....=;==+<; You should have received a copy of the GNU
+  -_. . .   )=.  = Library General Public License along with
+    --        :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef OBARCOLLECTION_H
+#define OBARCOLLECTION_H
+
+/* QT */
+
+#include <qstring.h>
+#include <qwidget.h>
+
+class QAction;
+class QPopupMenu;
+
+namespace Opie
+{
+
+/*
+ * ### TODO
+ * -Consider Life Updates
+ * -Make ValueBased like Opie-featurelist
+ */
+
+/**
+ * The different screen sizes have different look and feel. On bigger
+ * screens only a QToolBar feels strange. One is at least known to have
+ * a Help-Menu, a File Menu with Quit/Exit but instead of providing two
+ * different ways / two action sets we will group actions to gether and give
+ * them attributes when and where we might want them to be visible.
+ * We can also group actions. For example you could Group All Actions
+ * into the File Group. This means with many actions you would only have more toolbar
+ * actions but many sub menus in File. On bigger screen this would automatically
+ * expand to a full blown MenuBar and ToolButtons.
+ *
+ * @short Grouping of actions for dynamic Bar Generation
+ * @version 0.01
+ * @author hOlgAr
+ */
+class OBarGroup
+{
+public:
+ enum Preference { Allways, Never, IfPlace };
+ OBarGroup( const QString& name, enum Preference groupPreference );
+ ~OBarGroup();
+
+ void add( QAction* action, enum Preference menuPreference,
+ enum Preference toolpreference );
+ void add( const QString&, QPopupMenu* );
+
+ void add( OBarGroup* );
+
+ void remove( QAction* action );
+ void remove( QMap* );
+
+protected:
+ OBarGroup* parent()const;
+
+private:
+};
+
+
+/**
+ * Add your groups in order to the bar manager
+ * and either call createGUI() on it, or tell it
+ * it the mainwindow and it is listening to the show event
+ * and then creates the toolbar
+ */
+class OBarManager : public QObject
+{
+public:
+ OBarManager( QWindow* parent );
+ ~OBarManager();
+
+ void add( OBarGroup*, int pos = -1 );
+ void remove( OBarGroup* );
+
+ bool eventFilter( QObject* , QEvent* );
+
+public slots:
+ void createGUI();
+};
+
+/*
+ * ### TODO GUI merging
+ */
+
+};
+
+#endif
+
+
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 @@
+#ifndef OPIE_BIG_SCREEN_PRIVATE
+#define OPIE_BIG_SCREEN_PRIVATE
+
+/* QT */
+#include <qstring.h>
+
+class QWidget;
+
+namespace Opie
+{
+
+struct OSplitterContainer
+{
+ bool operator==( const OSplitterContainer& o) const
+ {
+ if (widget != o.widget ) return false;
+ if (icon != o.icon ) return false;
+ if (name != o.name ) return false;
+ return true;
+ }
+ QWidget* widget;
+ QString icon;
+ QString name;
+};
+
+};
+
+#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 @@
+/*
+               =. This file is part of the OPIE Project
+             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
+           .>+-=
+ _;:,     .>    :=|. This library is free software; you can
+.> <`_,   >  .   <= redistribute it and/or modify it under
+:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
+.="- .-=="i,     .._ License as published by the Free Software
+ - .   .-<_>     .<> Foundation; either version 2 of the License,
+     ._= =}       : or (at your option) any later version.
+    .%`+i>       _;_.
+    .i_,=:_.      -<s. This library is distributed in the hope that
+     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
+    : ..    .:,     . . . without even the implied warranty of
+    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
+  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
+..}^=.=       =       ; Library General Public License for more
+++=   -.     .`     .: details.
+ :     =  ...= . :.=-
+ -.   .:....=;==+<; You should have received a copy of the GNU
+  -_. . .   )=.  = Library General Public License along with
+    --        :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "omodalhelper.h"
+
+/* QT */
+#include <qpushbutton.h>
+#include <qvbox.h>
+#include <qlayout.h>
+#include <qlabel.h>
+
+/* Signal handling */
+OModalHelperSignal::OModalHelperSignal( OModalHelperBase* base, QObject* parent )
+ : QObject( parent, "OModal Helper Signal" ), m_base( base )
+{}
+
+OModalHelperSignal::~OModalHelperSignal()
+{
+ /* special the ancestor deletes its creator */
+ delete m_base;
+}
+
+
+/* Helper Controler */
+/*
+ * the dialogs signal will be slotted here
+ * and we will call into m_base
+ */
+OModalHelperControler::OModalHelperControler( OModalHelperBase* base, QObject* parent )
+ : QObject(parent, "OModal Helper Controler" ), m_base( base ), m_dia( 0 ), m_id( -1 )
+{}
+
+TransactionID OModalHelperControler::transactionID()const
+{
+ return m_id;
+}
+
+void OModalHelperControler::setTransactionID( TransactionID id )
+{
+ m_dia = 0;
+ m_id = id;
+}
+
+QDialog* OModalHelperControler::dialog()const
+{
+ return m_dia;
+}
+
+/*
+ * If we're in the New mode we will map the QDialog
+ * to the TransactionID
+ */
+void OModalHelperControler::done( int result )
+{
+ if ( sender() && !sender()->isA("OModalQueuedDialog") )
+ m_dia = static_cast<QDialog*>( sender() );
+
+ m_base->done( result, m_id );
+}
+
+void OModalHelperControler::next()
+{
+ m_base->next( m_id );
+}
+
+void OModalHelperControler::prev()
+{
+ m_base->prev( m_id );
+}
+
+/* The Queued Dialog inclusive QueuedBar */
+struct OModalQueueBar : public QHBox
+{
+ QPushButton* next;
+ QPushButton* prev;
+ QLabel * label;
+
+ OModalQueueBar( QWidget* parent );
+ void setText( const QString& str );
+};
+
+OModalQueueBar::OModalQueueBar( QWidget* parent )
+ : QWidget( parent, "OModal Queue Bar" )
+{
+ prev = new QPushButton( this );
+ prev->setText( OModalQueuedDialog::tr("Prev") );
+
+ label = new QLabel(this);
+
+ next = new QPushButton( this );
+ next->setText( OModalQueuedDialog::tr("Next") );
+}
+
+void OModalQueueBar::setText( const QString& str )
+{
+ label->setText( str );
+}
+
+
+OModalQueuedDialog::OModalQueuedDialog( QDialog* mainWidget )
+ : QDialog(0, "OModal Queued Dialog" )
+{
+ QVBoxLayout *lay = new QVBoxLayout( this );
+
+ m_bar = new OModalQueueBar( this );
+ lay->addWidget( m_bar );
+
+ m_center = mainWidget;
+ m_center->reparent(this, 0, QPoint(0, 0) );
+ lay->addWidget( m_center );
+
+
+ connect(m_bar->next, SIGNAL(clicked() ), this,
+ SIGNAL(next() ) );
+ connect(m_bar->prev, SIGNAL(clicked() ), this,
+ SIGNAL(prev() ) );
+
+}
+
+OModalQueuedDialog::~OModalQueuedDialog()
+{}
+
+QDialog* OModalQueuedDialog::centerDialog()const
+{
+ return m_center;
+}
+
+void OModalQueuedDialog::setQueueBarEnabled( bool b)
+{
+ /* in Qt3 use setEnabled( bool ) */
+ if (b)
+ m_bar->show();
+ else
+ m_bar->hide();
+}
+
+void OModalQueuedDialog::setRecord( int record, int count )
+{
+ if (!record && !count )
+ {
+ hide();
+ return;
+ }
+ else
+ show();
+
+ if ( count > 1 )
+ m_bar->show();
+ else
+ m_bar->hide();
+
+ m_bar->setText( tr("Editing record %1 out of %2",
+ "Shows the current edited record out of an array of records").arg( record ). arg( count ) );
+}
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 @@
+/*
+               =. This file is part of the OPIE Project
+             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
+           .>+-=
+ _;:,     .>    :=|. This library is free software; you can
+.> <`_,   >  .   <= redistribute it and/or modify it under
+:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
+.="- .-=="i,     .._ License as published by the Free Software
+ - .   .-<_>     .<> Foundation; either version 2 of the License,
+     ._= =}       : or (at your option) any later version.
+    .%`+i>       _;_.
+    .i_,=:_.      -<s. This library is distributed in the hope that
+     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
+    : ..    .:,     . . . without even the implied warranty of
+    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
+  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
+..}^=.=       =       ; Library General Public License for more
+++=   -.     .`     .: details.
+ :     =  ...= . :.=-
+ -.   .:....=;==+<; You should have received a copy of the GNU
+  -_. . .   )=.  = Library General Public License along with
+    --        :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef OMODALHELPER_H
+#define OMODALHELPER_H
+
+/* QT*/
+#include <qdialog.h>
+#include <qwidget.h>
+#include <qvaluelist.h>
+#include <qmap.h>
+#include <qvariant.h>
+
+typedef int TransactionID;
+
+class QDialog;
+
+namespace Opie
+{
+
+class OModalHelperControler;
+class OModalHelperSignal;
+
+struct OModalHelperBase
+{
+ virtual void done( int status, TransactionID ) = 0;
+ virtual void next( TransactionID ) = 0;
+ virtual void prev( TransactionID ) = 0;
+};
+
+/**
+ * Modality sucks! ;) But it is easy to work with
+ * do exec() on a dialog and you know everything is funky.
+ * You only need to have one Dialog loaded and so on.
+ * This class helps you to work like with modality and help
+ * you to keep things in sync
+ * It's a template class but it sends signals once one Item is ready
+ * the signals contains the status and id of the item and then you
+ * need fetch it.
+ * Handled Records will stay available until the first call to retrieve
+ * either the record via the TransactionID or via the QValueList<Record>. Note
+ * that most functions do not take handled records into account.
+ * Also if you edit an record external you can tell this class and it'll
+ * call the merge() function of your widget to maybe merge in these changes.
+ * It also supports multiple modes. Either it can create new dialogs
+ * for each item or it can queue them depending on your usage. But it is
+ * so smart that if only one item is shown that the queue bar is not shown
+ * See the example for simple usage.
+ *
+ * @short helps to life without modaility
+ * @author hOlgAr
+ * @version 0.01
+ */
+template<class Dialog, class Record, typename Id = int>
+class OModalHelper : private OModalHelperBase
+{
+ friend class OModalHelperSignal;
+ friend class OModalHelperControler;
+public:
+ typedef QValueList<Record> RecordList;
+ typedef QMap<Id, Record> IdMap;
+ typedef QMap<TransactionID, Id> TransactionMap;
+ typedef QMap<QDialog*, TransactionID> DialogMap
+ enum Mode { Queue, New };
+ OModalHelper(enum Mode mode, QObject* parnet );
+
+ bool handles( Id id)const;
+ TransactionID transactionID( Id id)const;
+
+ void suspend( bool = true );
+
+ void cancel();
+ void cancel( TransactionID );
+
+ void connectDone( QObject* rec, const char* slot );
+ void connectAccepted( QObject* rec, const char* slot );
+ void connectRejected( QObject* rec, const char* slot );
+
+ TransactionID handle( Id id, const Record& rec = Record() );
+
+ void edited( Id, int what, const QVariant& data );
+
+ Record record( TransactionID )const;
+ RecordList recordsDone()const;
+private:
+ virtual void done( int, TransactionID );
+ virtual void next( TransactionID );
+ virtual void prev( TransactionID );
+
+ Record nextRecord( TransactionID &, int & )const;
+ Record prevRecord( TransactionID &, int & )const;
+ int pos( TransactionID )const;
+ Dialog* newDialogRecord( const Record& );
+
+private:
+ OModalHelperDialog *queuedDialog()const; // generate or recycle
+ OModalHelperDialog *m_dialog;
+ OModalHelperSignal *m_signal; // our signal
+ OModalHelperControler *m_controler;
+ IdMap m_ids; // maps ids (uids) to a record
+ IdMap m_doneIds;
+ TransactionMap m_transactions; // activate transactions
+ TransactionMap m_done; // done and waiting for getting picked
+ DialogMap m_editing; // only used for New Mode
+ enum Mode m_mode; // the mode we're in
+bool m_disabled :1;
+};
+
+
+
+/* ### FIXME use namespace with Qt3 */
+
+/*
+ * A note on flow. The Signal is used for QT Signals when
+ * a record is done.
+ * There is either one controler and this controler slot will
+ * be connected to a dialog signal.
+ * In Queue we get the next and prev signals and call the Helper.
+ * this then changes the Record of the dialog and sets the transactionId
+ * of the controler.
+ * For the new mode
+ *
+ */
+
+class OModalHelperSignal : public QObject
+{
+ Q_OBJECT
+public:
+ OModalHelperSignal(OModalHelperBase* base, QObject* parent);
+ ~OModalHelperSignal();
+
+signals:
+ done( int status, TransactionID transaction );
+ accepted( TransactionID transaction );
+ rejected( TransactionID transaction );
+
+private:
+ OModalHelperBase* m_base;
+};
+
+
+class OModalHelperControler : public QObject
+{
+ Q_OBJECT
+public:
+ OModalHelperControler( OModalHelperBase* , QObject* parent);
+ virtual TransactionID transactionID()const;
+ void setTransactionID( TransactionID id );
+ QDialog* dialog()const;
+
+public slots:
+ virtual void done(int result );
+ virtual void next();
+ virtual void prev();
+private:
+ QDialog *m_dia;
+ TransactionID m_id;
+ OModalHelperBase *m_base;
+}
+
+struct OModalQueueBar;
+class OModalQueuedDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ OModalQueuedDialog(QDialog *mainWidget);
+ ~OModalQueuedDialog();
+
+ QDialog* centerDialog()const;
+
+ void setQueueBarEnabled( bool = true );
+ void setRecord( int record, int count );
+
+signals:
+ void next();
+ void prev();
+
+private:
+ OModalQueueBar *m_bar;
+ QDialog *m_center;
+};
+
+
+/*
+ * Tcpp Template Implementation
+ */
+
+/**
+ * This is the simple Template c'tor. It takes the mode
+ * this helper should operate in and the parent object.
+ * This helper will be deleted when the parent gets deleted
+ * or you delete it yourself.
+ *
+ * @param mode The mode this dialog should be in
+ * @param parent The parent QObject of this helper.
+ */
+template<class Dialog, class Record, typename Id>
+OModalHelper<Dialog, Record, Id>::OModalHelper( enum Mode mode, QObject* parent )
+{
+ m_disabled = false;
+ m_mode = mode;
+ m_signal = new OModalHelperSignal( this, parent );
+ m_controler = new OModalHelperControler( this, m_signal );
+}
+
+
+/**
+ * This functions looks for your record and sees if it is
+ * handled with this helper. Note that done records
+ * will not be returned.
+ *
+ * @return true if the record is currenlty edited otherwise false
+ *
+ * @param Id The id which might be handled
+ */
+template<class Dialog, class Record, typename Id>
+bool OModalHelper<Dialog, Record, Id>::handles( Id id )const
+{
+ if ( m_transactions.isEmpty() )
+ return false;
+
+ TransactionMap::ConstIterator it = m_transactions.begin();
+ for ( ; it != m_transactions.end(); ++it )
+ if ( it.data() == id )
+ return true;
+
+ return false;
+}
+
+
+/**
+ * just like handles( Id ) but returns the TransactionId
+ */
+template<class Dialog, class Record, typename Id>
+TransactionID OModalHelper<Dialog, Record, Id>::transactionID( Id id)const
+{
+ if ( m_transactions.isEmpty() || !m_ids.contains( id ) )
+ return 0;
+
+ TransactionMap::ConstIterator it = m_transactions.begin();
+ for ( ; it != m_transactions.end(); ++it )
+ if ( it.data() == id )
+ return it.key();
+
+ return 0;
+}
+
+/**
+ * If you're requested to flush your data and you do not want
+ * to call cancel with this method you can disable and enabled
+ * all dialogs.
+ * The state gets saved so if you want to handle a new record the dialog
+ * will be disabled as well.
+ *
+ * @param sus If true setDisabled(TRUE) will be called otherwise FALSE
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper<Dialog, Record, Id>::suspend(bool sus)
+{
+ m_disabled = sus;
+ if (m_mode == New )
+ for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it )
+ it.key()->setDisabled( sus );
+ else if (m_dialog )
+ queuedDialog()->setDisabled( sus );
+}
+
+/**
+ * Cancel will cancel all current operations and clear the list
+ * of done operations as well.
+ * This also clears all done operations you did not popped
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper<Dialog, Record, Id>::cancel()
+{
+ m_ids.clear();
+ m_doneIds.clear();
+ m_done.clear();
+ m_transactions.clear();
+
+ /* we also need to remove the QDialogs */
+ /* and hide the queue dialog if present */
+ if (m_mode == New && !m_editing.isEmpty() )
+ {
+ for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it )
+ delete it.key();
+
+ m_editing.clear();
+ }
+ else if (m_dialog )
+ queuedDialog()->setRecord( 0, 0 );
+
+ m_controler->setTransactionID( 0 );
+}
+
+
+/**
+ * This cancels editing of the record behind the Transaction Number
+ * Note that if editing is already done it will also be removed from this list
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper::cancel( TransactionID tid )
+{
+ /* wrong tid */
+ if (!m_transactions.contains( tid ) && !m_done.contains( tid) )
+ return;
+
+ if (m_mode == New )
+ /* reverse map eek */
+ for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it )
+ if ( it.data() == tid )
+ {
+ it.key()->hide();
+ delete it.key();
+ it = m_editing.remove( it );
+ break;
+ }
+
+ /* now remove from the various maps done and currently editing map*/
+ if (m_transactions.contains( tid ) )
+ m_ids.remove( m_transactions[tid] );
+ if (m_done.contains( tid ) )
+ m_doneIds.remove( m_done[tid ] );
+ m_done.remove( tid );
+ m_transactions.remove( tid );
+
+ next( 0 );
+}
+
+/**
+ * Connect to the done Signal. SIGNAL( done(int, TransactionID ) )
+ * This signal gets emitted whenever a Record was accepted or rejected
+ *
+ * @param rec The object where the slot belongs to
+ * @param slot The slot which should be called. See the needed parameter above
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper<Dialog, Record, Id>::connectDone( QObject* rec, const char* slot )
+{
+ QObject::connect(m_signal, SIGNAL(done(int, TransactionID) ),
+ rec, slot );
+}
+
+/**
+ * Connect to the accepted Signal. SIGNAL( accepted(TransactionID ) )
+ * This signal gets emitted whenever a Record was accepted
+ *
+ * @param rec The object where the slot belongs to
+ * @param slot The slot which should be called. See the needed parameter above
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper<Dialog, Record, Id>::connectAccepted( QObject* rec, const char* slot )
+{
+ QObject::connect(m_signal, SIGNAL(accepted(TransactionID) ),
+ rec, slot );
+}
+
+/**
+ * Same as the accepted method but this one gets emitted if the dialog
+ * got rejected.
+ * SIGNAL( rejected(TransactionID) )
+ *
+ * @param rec The QObject of the slot
+ * @param slot The slot make sure the signature is correct
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper<Dialog, Record, Id>::connectRejected( QObject* rec, const char* slot )
+{
+ QObject::connect(m_signal, SIGNAL(rejected(TransactionID) ),
+ rec, slot );
+}
+
+/**
+ * Tell the helper to handle a record. If the record is currently handled
+ * it will be made active.
+ * Already handled record which are waiting getting popped are not taken into account
+ * Otherwise this helpers make the record editable.
+ * The record supplied needs to have a valid copy operator and constructor.
+ * In the case where the record is already present the parameter gets discarded.
+ * If you want the new record to be taken you need to cancel the Transaction first
+ *
+ * @param id The Identification of the Record. For PIM it would uid()
+ * @param rec The record we want to be edited
+ *
+ * @returns This functions returns the TransactionId assigned to the record
+ *
+ */
+template<class Dialog, class Record, typename Id>
+TransactionID OModalHelper<Dialog, Record, Id>::handle( Id id, const Record& rec )
+{
+ static TransactionID t_id = 0;
+ /*
+ *this method consists out of two parts divided each into New and Queued Mode.
+ * Either we have the dialog already, in this case we need to highlight the widget
+ * Or we need to add it.
+ */
+ TransactionID tid = 0;
+ /* we already have the record lets see if it was done or not */
+ if ( !(tid = transactionID( id ) ) )
+ {
+ if (m_mode == New )
+ {
+ /* lets find the dialog and show it need to reverse map*/
+ for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it )
+ if ( it.data() == tid )
+ it.key()->show();
+ }
+ else if (m_controler->transactionID() != tid )
+ {
+ int po = pos( tid );
+ m_controler->setTransactionID( tid );
+ static_cast<Dialog*>( queuedDialog()->centerDialog() )->setRecord( m_ids[ m_transactions[tid] ] );
+ queuedDialog()->setRecord( po, m_transactions.count() );
+ }
+ }
+ else
+ {
+ tid = ++t_id;
+ m_transactions.insert( tid, id );
+ m_ids.insert( id, rec );
+
+ if (m_mode == New )
+ m_editing.insert( newDialogRecord( rec ), tid );
+ else
+ {
+ m_controler->setTransactionID( tid );
+ static_cast<Dialog*>( queuedDialog()->centerDialog() )->setRecord( rec );
+ queuedDialog()->setRecord( m_transactions.count(), m_transactions.count() );
+ }
+ }
+ return tid;
+}
+
+/**
+ * The goal of this helper is to help you to create non blocking
+ * GUIs. In the example of the todolist you can have the edit dialog
+ * but still change the priority or completion inline even if you currently
+ * edit the record.
+ * Your Dialog needs to have a Method setData(int,const QVariant& ) which will be called
+ * in these cases.
+ * If you edit anything while a record is edited call this function to merge the
+ * change in. Note if the record is not handled here we will ignore the request
+ *
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper<Dialog, Record, Id>::edited( Id id, int what, const QVariant& data )
+{
+ int tid;
+ if (!( tid = transactionID( id ) ) )
+ return;
+
+ if (m_mode == New )
+ {
+ for (DialogMap::Iterator it= m_editing.begin(); it != m_editing.end(); ++it )
+ if ( it.data() == tid )
+ it.key()->setData( what, data );
+ }
+ else
+ {
+ int po = pos( tid );
+ Dialog* dia = static_cast<Dialog*>( queuedDialog()->centerDialog() );
+ dia->setRecord( m_ids[id] );
+ dia->setData( what, data );
+ queuedDialog()->setRecord( pos, m_transactions.count() );
+ }
+}
+
+/**
+ * This functions either returns the unedited record the done record
+ * or a new empty Record using Record().
+ * If a done record is retrieved all traces are removed inside this class. This
+ * is what was called popping a record. This means when you call this function
+ * with the same TransactionID an Empty record is retrieved.
+ *
+ */
+template<class Dialog, class Record, typename Id>
+Record OModalHelper<Dialog, Record, Id>::record( TransactionID tid)const
+{
+ if (m_transactions.contains( tid ) )
+ return m_ids[ m_transactions[tid] ];
+ else if (m_done.contains( tid ) )
+ {
+ Record rec = m_doneIds[ m_done[ tid] ];
+ m_doneIds.remove( m_done[ tid ] );
+ m_done.remove( tid );
+ return rec;
+ }
+ else
+ return Record();
+}
+
+/**
+ * Returns all done Records and removes all references to them internally. A 2nd call to this will
+ * only contain done record that where edited past the point
+ */
+template<class Dialog, class Record, typename Id>
+OModalHelper<Dialog,Record,Id>::RecordList OModalHelper<Dialog, Record, Id>::recordsDone()const
+{
+ RecordList list;
+
+ for (IdMap::ConstIterator it = m_doneIds.begin(); it != m_doneIds.end(); ++it )
+ list.append( it.data() );
+
+ /* clean up */
+ m_done.clear();
+ m_doneIds.clear();
+
+ return list;
+}
+
+
+/**
+ * @internal
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper<Dialog, Record, Id>::done( int status, TransactionID tid)
+{
+ /* If we're in New mode the transaction Id does not count */
+ Record rec;
+
+ if (m_mode == New )
+ {
+ Dialog *dia = static_cast<Dialog*>( m_controler->dialog() );
+ m_controler->setTransactionID( 0 ); // set the internal dialog to 0l again
+ tid = m_editing[ dia ];
+ m_editing.remove( dia );
+ rec = dia->record();
+ delete dia;
+ }
+ else
+ rec = queuedDialog()->record();
+
+ Id id = m_transactions[ tid ];
+ if (result == QDialog::Accept )
+ {
+ m_doneIds.insert( is, rec );
+ m_done.insert( tid, id );
+ }
+
+ m_transactions.remove( tid );
+ m_ids.remove( id );
+
+
+ if (status == QDialog::Accept )
+ emit m_signal->accepted( tid );
+ else
+ emit m_signal->rejected( tid );
+
+ emit m_signal->done( result, tid );
+
+ next( 0 );
+}
+
+/**
+ * @internal
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper<Dialog, Record, Id>::next( TransactionID tid)
+{
+ if (m_mode == New )
+ return;
+
+ if (! (m_transactions.count() ) )
+ {
+ m_controler->setTransactionID( 0 );
+ queuedDialog()->setRecord( 0, 0 );
+ return;
+ }
+
+ int next;
+ Record rec;
+
+ /* save the maybe edited record before switching */
+ Dialog *dia = static_cast<Dialog*>( queuedDialog()->centerDialog() );
+ rec = dia->record();
+ m_ids.replace( m_transactions[tid], rec );
+
+ rec = nextRecord( tid, next );
+ queuedDialog()->setRecord( next, m_transactions.count() );
+ dia->setRecord( rec );
+
+ m_controler->setTransactionID( tid ); // was changed during the next call
+}
+
+/**
+ * @internal
+ */
+/*
+ * code duplication should create a template fcuntion
+ * which takes a pointer to a function ( next, prev ) function
+ */
+template<class Dialog, class Record, typename Id>
+void OModalHelper<Dialog, Record, Id>::prev( TransactionID tid )
+{
+ if (m_mode == New )
+ return;
+
+ if (! (m_transactions.count()) )
+ {
+ m_controler->setTransactionID( 0 );
+ queuedDialog()->setRecord( 0, 0 );
+ return;
+ }
+
+ int prev;
+ Record rec;
+
+ /* save the maybe edited record before switching */
+ Dialog *dia = static_cast<Dialog*>( queuedDialog()->centerDialog() );
+ rec = dia->record();
+ m_ids.replace( m_transactions[tid], rec );
+
+ rec = prevRecord( tid, prev );
+ queuedDialog()->setRecord( prev, m_transactions.count() );
+ dia->setRecord( rec );
+
+ m_controler->setTransactionID( tid ); // was changed during the next call
+}
+
+/**
+ * @internal
+ */
+template<class Dialog, class Record, typename Id>
+Record OModalHelper<Dialog, Record, Id>::nextRecord( TransactionID &tid, int &po )
+{
+ /* if tid is == 0 we will take the first one */
+ /* pos starts at 1 here */
+ /* we know we're only called if there are records */
+ Record rec;
+ TransactionMap::Iterator it;
+ if (!tid )
+ {
+ po = 1;
+ TransactionMap::Iterator it = m_transactions.begin();
+ }
+ else
+ {
+ po = pos( tid );
+ /* if it is the last take the first as next */
+ if ( po == m_transactions.count() )
+ {
+ po = 1;
+ it = m_transactions.begin();
+ }
+ else
+ {
+ /* we know we're not the last and there is one after us */
+ it = m_transactions.find( tid );
+ ++it; ++po;
+ }
+ }
+
+ tid = it.key();
+ rec = m_ids[ tid ];
+ return rec;
+}
+
+/**
+ * @internal
+ */
+template<class Dialog, class Record, typename Id>
+Record OModalHelper<Dialog, Record, Id>::prevRecord( TransactionID& tid, int& pos )
+{
+ /* if tid is == 0 we will take the first one */
+ /* pos starts at 1 here */
+ /* we know we're only called if there are records */
+ Record rec;
+ TransactionMap::Iterator it;
+ if (!tid )
+ {
+ po = 1;
+ TransactionMap::Iterator it = m_transactions.begin();
+ }
+ else
+ {
+ po = pos( tid );
+ /* if it is the last take the first as next */
+ if ( po == 1 )
+ {
+ po = m_transactions.count();
+ it = m_transactions.end();
+ --it;
+ }
+ else
+ {
+ /* we know we're not the first and there is one before us */
+ it = m_transactions.find( tid );
+ --it; --po;
+ }
+ }
+
+ tid = it.key();
+ rec = m_ids[ tid ];
+ return rec;
+}
+
+/**
+ * @internal
+ */
+template<class Dialog, class Record, typename Id>
+int OModalHelper<Dialog, Record, Id>::pos( TransactionID id)const
+{
+ int i = 1;
+ for ( TransactionMap::ConstIterator it = m_transactions.begin(); it != m_transactions.end(); ++it, i++ )
+ if ( it.key() == id )
+ return i;
+
+
+ return 0;
+}
+
+/**
+ * @internal
+ */
+template<class Dialog, class Record, typename Id>
+Dialog* OModalHelper<Dialog, Record, Id>::newDialogRecord( const Record& rec )
+{
+ Dialog* dia = new Dialog;
+ dia->setRecord( rec );
+ dia->setDisabled( m_disabled );
+
+ QObject::connect(dia, SIGNAL(done(int) ),
+ m_controler, SLOT(done(int) ) );
+
+ /* FIXME big screen QPEApplication needs fixed*/
+ dia->show();
+}
+
+template<class Record, class Dialog, typename Id>
+OModalHelperDialog* OModalHelper<Record, Dialog, Id>::queuedDialog()const
+{
+ if (!m_dialog )
+ {
+ m_dialog = new OModalHelperDialog;
+ m_dialog->setEnabled( m_disabled );
+
+ QObject::connect(m_dialog, SIGNAL(done(int) ),
+ m_controler, SLOT(done(int) ) );
+ QObject::connect(m_dialog, SIGNAL(next() ),
+ m_controler, SLOT(next() ) );
+ QObject::connect(m_dialog, SIGNAL(prev() ),
+ m_controler, SLOT(prev() ) );
+ }
+ return m_dialog;
+}
+
+};
+
+#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 @@
+/*
+               =. This file is part of the OPIE Project
+             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
+           .>+-=
+ _;:,     .>    :=|. This library is free software; you can
+.> <`_,   >  .   <= redistribute it and/or modify it under
+:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
+.="- .-=="i,     .._ License as published by the Free Software
+ - .   .-<_>     .<> Foundation; either version 2 of the License,
+     ._= =}       : or (at your option) any later version.
+    .%`+i>       _;_.
+    .i_,=:_.      -<s. This library is distributed in the hope that
+     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
+    : ..    .:,     . . . without even the implied warranty of
+    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
+  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
+..}^=.=       =       ; Library General Public License for more
+++=   -.     .`     .: details.
+ :     =  ...= . :.=-
+ -.   .:....=;==+<; You should have received a copy of the GNU
+  -_. . .   )=.  = Library General Public License along with
+    --        :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "osplitter.h"
+
+/* OPIE */
+#include <opie2/otabwidget.h>
+
+/* QT */
+#include <qvaluelist.h>
+#include <qvbox.h>
+
+using namespace Opie;
+
+/**
+ *
+ * This is the constructor of OSplitter
+ * You might want to call setSizeChange to tell
+ * OSplitter to change its layout when a specefic
+ * mark was crossed. OSplitter sets a default value.
+ *
+ * You cann add widget with addWidget to the OSplitter.
+ * OSplitter supports also grouping of Splitters where they
+ * can share one OTabBar in small screen mode. This can be used
+ * for email clients like vies but see the example.
+ *
+ * @param orient The orientation wether to layout horizontal or vertical
+ * @param parent The parent of this widget
+ * @param name The name passed on to QObject
+ * @param fl Additional widgets flags passed to QWidget
+ *
+ * @short single c'tor of the OSplitter
+ */
+OSplitter::OSplitter( Orientation orient, QWidget* parent, const char* name, WFlags fl )
+ : QFrame( parent, name, fl )
+{
+ m_orient = orient;
+ m_hbox = 0;
+ m_size_policy = 330;
+ setFontPropagation( AllChildren );
+ setPalettePropagation( AllChildren );
+
+ /* start by default with the tab widget */
+ m_tabWidget = 0;
+ m_parentTab = 0;
+ changeTab();
+
+}
+
+
+/**
+ * Destructor destructs this object and cleans up. All child
+ * widgets will be deleted
+ * @see addWidget
+ */
+OSplitter::~OSplitter()
+{
+ qWarning("Deleted Splitter");
+ m_splitter.setAutoDelete( true );
+ m_splitter.clear();
+
+ delete m_hbox;
+ delete m_tabWidget;
+}
+
+
+/**
+ * Sets the label for the Splitter. This label will be used
+ * if a parent splitter is arranged as TabWidget but
+ * this splitter is in fullscreen mode. Then a tab with OSplitter::label()
+ * and iconName() gets added.
+ *
+ * @param name The name of the Label
+ */
+void OSplitter::setLabel( const QString& name )
+{
+ m_name = name;
+}
+
+/**
+ * @see setLabel but this is for the icon retrieved by Resource
+ *
+ * @param name The name of the icon in example ( "zoom" )
+ */
+void OSplitter::setIconName( const QString& name )
+{
+ m_icon = name;
+}
+
+
+/**
+ * returns the iconName
+ * @see setIconName
+ */
+QString OSplitter::iconName()const
+{
+ return m_icon;
+}
+
+/**
+ * returns the label set with setLabel
+ * @see setLabel
+ */
+QString OSplitter::label()const
+{
+ return m_name;
+}
+
+/**
+ * This function sets the size change policy of the splitter.
+ * If this size marked is crossed the splitter will relayout.
+ * Note: that depending on the set Orientation it'll either look
+ * at the width or height.
+ * Note: If you want to from side to side view to tabbed view you need
+ * to make sure that the size you supply is not smaller than the minimum
+ * size of your added widgets. Note that if you use widgets like QComboBoxes
+ * you need to teach them to accept smaller sizes as well @see QWidget::setSizePolicy
+ *
+ * @param width_height The mark that will be watched. Interpreted depending on the Orientation of the Splitter.
+ * @return void
+ */
+void OSplitter::setSizeChange( int width_height )
+{
+ m_size_policy = width_height;
+ QSize sz(width(), height() );
+ QResizeEvent ev(sz, sz );
+ resizeEvent(&ev);
+}
+
+/**
+ * This functions allows to add another OSplitter and to share
+ * the OTabBar in small screen mode. The ownerships gets transfered.
+ * OSplitters are always added after normal widget items
+ */
+void OSplitter::addWidget( OSplitter* split )
+{
+ m_splitter.append( split );
+
+ /*
+ * set tab widget
+ */
+ if (m_tabWidget )
+ setTabWidget( m_parentTab );
+ else
+ {
+ Opie::OSplitterContainer con;
+ con.widget =split;
+ addToBox( con );
+ }
+}
+
+/*
+ * If in a tab it should be removed
+ * and if in a hbox the reparent kills it too
+ */
+/**
+ * This removes the splitter again. You currently need to call this
+ * before you delete or otherwise you can get mem corruption
+ * or other weird behaviour.
+ * Owner ship gets transfered back to you it's current parent
+ * is 0
+ */
+void OSplitter::removeWidget( OSplitter* split)
+{
+ split->setTabWidget( 0 );
+ split->reparent( 0, 0, QPoint(0, 0) );
+}
+
+/**
+ * Adds a widget to the Splitter. The widgets gets inserted
+ * at the end of either the Box or TabWidget.
+ * Ownership gets transfered and the widgets gets reparented.
+ * Note: icon and label is only available on small screensizes
+ * if size is smaller than the mark
+ * Warning: No null checking of the widget is done. Only on debug
+ * a message will be outputtet
+ *
+ * @param wid The widget which will be added
+ * @param icon The icon of the possible Tab
+ * @param label The label of the possible Tab
+ */
+void OSplitter::addWidget( QWidget* wid, const QString& icon, const QString& label )
+{
+#ifdef DEBUG
+ if (!wid )
+ {
+ qWarning("Widget is not valid!");
+ return;
+ }
+#endif
+ Opie::OSplitterContainer cont;
+ cont.widget = wid;
+ cont.icon =icon;
+ cont.name = label;
+
+ m_container.append( cont );
+
+ /*
+ *
+ */
+ if (!m_splitter.isEmpty() && (m_tabWidget || m_parentTab ) )
+ setTabWidget( m_parentTab );
+ else
+ {
+ if (m_hbox )
+ addToBox( cont );
+ else
+ addToTab( cont );
+ }
+}
+
+
+/**
+ * Removes the widget from the tab widgets if necessary.
+ * OSplitter drops ownership of this widget and the widget
+ * will be reparented i tto 0.
+ * The widget will not be deleted.
+ *
+ * @param w The widget to be removed
+ */
+void OSplitter::removeWidget( QWidget* w)
+{
+ ContainerList::Iterator it;
+ for ( it = m_container.begin(); it != m_container.end(); ++it )
+ if ( (*it).widget == w )
+ break;
+
+ if (it == m_container.end() )
+ return;
+
+
+ /* only tab needs to be removed.. box recognizes it */
+ if ( !m_hbox )
+ removeFromTab( w );
+
+
+ /* Find reparent it and remove it from our list */
+
+ w->reparent( 0, 0, QPoint(0, 0));
+ it = m_container.remove( it );
+
+}
+
+
+/**
+ * This method will give focus to the widget. If in a tabwidget
+ * the tabbar will be changed
+ *
+ * @param w The widget which will be set the current one
+ */
+void OSplitter::setCurrentWidget( QWidget* w)
+{
+ if (m_tabWidget )
+ m_tabWidget->setCurrentTab( w );
+ // else
+ // m_hbox->setFocus( w );
+
+}
+
+/**
+ * This is an overloaded member function and only differs in the
+ * argument it takes.
+ * Searches list of widgets for label. It'll pick the first label it finds
+ *
+ * @param label Label to look for. First match will be taken
+ */
+void OSplitter::setCurrentWidget( const QString& label )
+{
+ ContainerList::Iterator it;
+ for (it = m_container.begin(); it != m_container.end(); ++it )
+ {
+ if ( (*it).name == label )
+ {
+ setCurrentWidget( (*it).widget );
+ break;
+ }
+ }
+}
+
+/**
+ * This will only work when the TabWidget is active
+ * If everything is visible this signal is kindly ignored
+ * @see OTabWidget::setCurrentTab(int)
+ *
+ * @param tab The tab to make current
+ */
+void OSplitter::setCurrentWidget( int tab )
+{
+ if (m_tabWidget )
+ m_tabWidget->setCurrentTab( tab );
+}
+
+/**
+ * return the currently activated widget if in tab widget mode
+ * or null because all widgets are visible
+ */
+QWidget* OSplitter::currentWidget() const
+{
+ if (m_tabWidget)
+ return m_tabWidget->currentWidget();
+ else if (m_parentTab )
+ return m_parentTab->currentWidget();
+
+ return 0l;
+}
+/* wrong */
+#if 0
+/**
+ * @reimplented for internal reasons
+ * returns the sizeHint of one of its sub widgets
+ */
+QSize OSplitter::sizeHint()const
+{
+ if (m_parentTab )
+ return QFrame::sizeHint();
+
+ if (m_hbox )
+ return m_hbox->sizeHint();
+ else
+ return m_tabWidget->sizeHint();
+}
+
+QSize OSplitter::minimumSizeHint()const
+{
+ if (m_parentTab )
+ return QFrame::minimumSizeHint();
+ if (m_hbox)
+ return m_hbox->sizeHint();
+ else
+ return m_tabWidget->sizeHint();
+}
+#endif
+
+/**
+ * @reimplemented for internal reasons
+ */
+void OSplitter::resizeEvent( QResizeEvent* res )
+{
+ QFrame::resizeEvent( res );
+ /*
+ *
+ */
+ // qWarning("Old size was width = %d height = %d", res->oldSize().width(), res->oldSize().height() );
+ bool mode = true;
+ qWarning("New size is width = %d height = %d %s", res->size().width(), res->size().height(), name() );
+ if ( res->size().width() > m_size_policy &&
+ m_orient == Horizontal )
+ {
+ changeHBox();
+ mode = false;
+ }
+ else if ( (res->size().width() <= m_size_policy &&
+ m_orient == Horizontal ) ||
+ (res->size().height() <= m_size_policy &&
+ m_orient == Vertical ) )
+ {
+ changeTab();
+ }
+ else if ( res->size().height() > m_size_policy &&
+ m_orient == Vertical )
+ {
+ qWarning("Changng to vbox %s", name() );
+ changeVBox();
+ mode = false;
+ }
+
+ emit sizeChanged(mode, m_orient );
+}
+
+/*
+ * Adds a container to a tab either the parent tab
+ * or our own
+ */
+void OSplitter::addToTab( const Opie::OSplitterContainer& con )
+{
+ QWidget *wid = con.widget;
+ // not needed widgetstack will reparent as well wid.reparent(m_tabWidget, wid->getWFlags(), QPoint(0, 0) );
+ if (m_parentTab )
+ m_parentTab->addTab( wid, con.icon, con.name );
+ else
+ m_tabWidget->addTab( wid, con.icon, con.name );
+}
+
+
+/*
+ * adds a container to the box
+ */
+void OSplitter::addToBox( const Opie::OSplitterContainer& con )
+{
+ QWidget* wid = con.widget;
+ wid->reparent(m_hbox, 0, QPoint(0, 0) );
+}
+
+
+/*
+ * Removes a widget from the tab
+ */
+void OSplitter::removeFromTab( QWidget* wid )
+{
+ if (m_parentTab )
+ m_parentTab->removePage( wid );
+ else
+ m_tabWidget->removePage( wid );
+}
+
+/*
+ * switches over to a OTabWidget layout
+ * it is recursive
+ */
+void OSplitter::changeTab()
+{
+ /* if we're the owner of the tab widget */
+ if (m_tabWidget )
+ {
+ raise();
+ show();
+ m_tabWidget->setGeometry( frameRect() );
+ return;
+ }
+
+ qWarning(" New Tab Widget %s", name() );
+ /*
+ * and add all widgets this will reparent them
+ * delete m_hbox set it to 0
+ *
+ */
+ OTabWidget *tab;
+ if ( m_parentTab )
+ {
+ hide();
+ tab = m_parentTab;
+ /* expensive but needed cause we're called from setTabWidget and resizeEvent*/
+ if (!m_container.isEmpty() )
+ {
+ ContainerList::Iterator it = m_container.begin();
+ for (; it != m_container.end(); ++it )
+ m_parentTab->removePage( (*it).widget );
+ }
+ }
+ else
+ tab = m_tabWidget = new OTabWidget( this );
+
+ connect(tab, SIGNAL(currentChanged(QWidget*) ),
+ this, SIGNAL(currentChanged(QWidget*) ) );
+
+ for ( ContainerList::Iterator it = m_container.begin(); it != m_container.end(); ++it )
+ {
+ qWarning("Widget is %s", (*it).name.latin1() );
+ addToTab( (*it) );
+ }
+
+ for ( OSplitter* split = m_splitter.first(); split; split = m_splitter.next() )
+ {
+ split->reparent(this, 0, QPoint(0, 0) );
+ split->setTabWidget( tab );
+ }
+
+
+ delete m_hbox;
+ m_hbox = 0;
+ if (!m_tabWidget )
+ return;
+
+ m_tabWidget->setGeometry( frameRect() );
+ m_tabWidget->show();
+
+}
+
+/*
+ * changes over to a box
+ * this is recursive as well
+ */
+void OSplitter::changeHBox()
+{
+ if (m_hbox )
+ {
+ m_hbox->setGeometry( frameRect() );
+ return;
+ }
+
+ qWarning("new HBox %s", name() );
+ m_hbox = new QHBox( this );
+ commonChangeBox();
+}
+
+void OSplitter::changeVBox()
+{
+ if (m_hbox )
+ {
+ m_hbox->setGeometry( frameRect() );
+ return;
+ }
+
+ qWarning("New VBOX %s", name() );
+ m_hbox = new QVBox( this );
+
+ commonChangeBox();
+
+}
+
+/*
+ * common box code
+ * first remove and add children
+ * the other splitters
+ * it is recursive as well due the call to setTabWidget
+ */
+void OSplitter::commonChangeBox()
+{
+ qWarning(" Name of Splitters is %s", name() );
+
+ for (ContainerList::Iterator it = m_container.begin(); it != m_container.end(); ++it )
+ {
+ /* only if parent tab.. m_tabWidgets gets deleted and would do that as well */
+ if (m_parentTab )
+ removeFromTab( (*it).widget );
+ qWarning("Adding to box %s", (*it).name.latin1() );
+ addToBox( (*it) );
+ }
+ for ( OSplitter* split = m_splitter.first(); split; split = m_splitter.next() )
+ {
+ /* tell them the world had changed */
+ split->setTabWidget( 0 );
+ Opie::OSplitterContainer con;
+ con.widget = split;
+ // con.widget = split->m_tabWidget ? static_cast<QWidget*>(split->m_tabWidget)
+ // : static_cast<QWidget*>(split->m_hbox);
+ addToBox( con );
+ }
+
+
+
+ if (m_parentTab )
+ m_parentTab->addTab(m_hbox, iconName(), label() );
+ else
+ {
+ qWarning(" setting Box geometry for %s", name() );
+ m_hbox->setGeometry( frameRect() );
+ m_hbox->show();
+ delete m_tabWidget;
+ m_tabWidget = 0;
+ show(); // also show this widget
+ }
+}
+
+/*
+ * sets the tabwidget, removes tabs, and relayouts the widget
+ */
+void OSplitter::setTabWidget( OTabWidget* wid)
+{
+ /* clean up cause m_parentTab will not be available for us */
+ if ( m_parentTab )
+ {
+ if (m_hbox )
+ m_parentTab->removePage( m_hbox );
+ else if (!m_container.isEmpty() )
+ {
+ ContainerList::Iterator it = m_container.begin();
+ for ( ; it != m_container.end(); ++it )
+ m_parentTab->removePage( (*it).widget );
+ }
+ }
+ /* the parent Splitter changed so either make us indepent or dep */
+
+ m_parentTab = wid;
+
+ QWidget *tab = m_tabWidget;
+ QWidget *box = m_hbox;
+ m_hbox = 0; m_tabWidget = 0;
+
+ if ( layoutMode() )
+ changeTab();
+ else if (m_orient == Horizontal )
+ changeHBox();
+ else
+ changeVBox();
+
+ /* our own crap is added and children from change* */
+ delete tab;
+ delete box;
+}
+
+#if 0
+void OSplitter::reparentAll()
+{
+ if (m_container.isEmpty() )
+ return;
+
+ ContainerList::Iterator it = m_container.begin();
+ for ( ; it != m_container.end(); ++it )
+ (*it).wid->reparent(0, 0, QPoint(0, 0) );
+
+
+}
+#endif
+
+/**
+ * @internal
+ */
+bool OSplitter::layoutMode()const
+{
+ if ( size().width() > m_size_policy &&
+ m_orient == Horizontal )
+ {
+ return false;
+ }
+ else if ( size().height() > m_size_policy &&
+ m_orient == Vertical )
+ {
+ return false;
+ }
+
+ return true;
+}
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 @@
+/*
+               =. This file is part of the OPIE Project
+             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
+           .>+-=
+ _;:,     .>    :=|. This library is free software; you can
+.> <`_,   >  .   <= redistribute it and/or modify it under
+:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
+.="- .-=="i,     .._ License as published by the Free Software
+ - .   .-<_>     .<> Foundation; either version 2 of the License,
+     ._= =}       : or (at your option) any later version.
+    .%`+i>       _;_.
+    .i_,=:_.      -<s. This library is distributed in the hope that
+     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
+    : ..    .:,     . . . without even the implied warranty of
+    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
+  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
+..}^=.=       =       ; Library General Public License for more
+++=   -.     .`     .: details.
+ :     =  ...= . :.=-
+ -.   .:....=;==+<; You should have received a copy of the GNU
+  -_. . .   )=.  = Library General Public License along with
+    --        :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef OSPLITTER_H
+#define OSPLITTER_H
+
+#include "obigscreen_p.h"
+
+/* QT */
+#include <qframe.h>
+#include <qlist.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+
+class QHBox;
+
+//template class QValueList<Opie::OSplitterContainer>;
+
+/*
+ * TODO
+ * -check API docu
+ * -one more example
+ * -allow inserting at a position
+ */
+
+namespace Opie
+{
+class OTabWidget;
+
+/**
+ *
+ * If you've widgets that could be placed side by side but you think
+ * on small resolutions is not enough place but it would really make sense
+ * on bigger resolutions this class will help you.
+ * You can add as many widgets you want to it. Set a poliy on which width/height it
+ * should switch the layout.
+ * You can either say to place widgets vertical or horizontal.
+ * This class uses QHBox, QVBox and QTAbWidget internally.
+ * OSplitter takes ownership of the widgets
+ *
+ * @since 1.2
+ *
+ * @short a small dynamically changing its layout to store two or more widgets side by side
+ * @version 0.1
+ * @author zecke
+ */
+class OSplitter : public QFrame
+{
+ Q_OBJECT
+public:
+ typedef QValueList<Opie::OSplitterContainer> ContainerList;
+ OSplitter( Qt::Orientation = Horizontal, QWidget *parent = 0,
+ const char* name = 0, WFlags fl = 0 );
+ ~OSplitter();
+
+ void setLabel( const QString& name );
+ void setIconName( const QString& name );
+ QString label()const;
+ QString iconName()const;
+
+ void setSizeChange( int width_height );
+
+ void addWidget( OSplitter* splitter );
+ void addWidget( QWidget* wid, const QString& icon, const QString& label );
+ void removeWidget( QWidget* );
+ void removeWidget( OSplitter* );
+
+ void setCurrentWidget( QWidget* );
+ void setCurrentWidget( const QString& label );
+ void setCurrentWidget( int );
+ QWidget* currentWidget()const;
+
+
+signals:
+ /**
+ * Emitted if in tab and comes directly from the tab widget
+ *
+ */
+ void currentChanged( QWidget* );
+
+ /**
+ * emitted whenever a border is crossed
+ * true if in small screen mode
+ * false if in bigscreen
+ * this signal is emitted after the layout switch
+ * @param b The layout mode
+ * @param ori The orientation
+ */
+ void sizeChanged( bool b, Orientation ori);
+public:
+ // QSize sizeHint()const;
+ // QSize minimumSizeHint()const;
+
+protected:
+ void resizeEvent( QResizeEvent* );
+
+private:
+ /* true if OTabMode */
+ bool layoutMode()const;
+ // void reparentAll();
+ void setTabWidget( OTabWidget*);
+ void addToTab( const Opie::OSplitterContainer& );
+ void addToBox( const Opie::OSplitterContainer& );
+ void removeFromTab( QWidget* );
+ void changeTab();
+ void changeHBox();
+ void changeVBox();
+ void commonChangeBox();
+ QHBox *m_hbox;
+ OTabWidget *m_tabWidget;
+ OTabWidget *m_parentTab;
+ Orientation m_orient;
+ int m_size_policy;
+
+ ContainerList m_container;
+ QList<OSplitter> m_splitter;
+
+ QString m_icon, m_name;
+
+ struct Private;
+ Private *d;
+};
+};
+
+#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 @@
+/*
+               =. This file is part of the OPIE Project
+             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
+           .>+-=
+ _;:,     .>    :=|. This library is free software; you can
+.> <`_,   >  .   <= redistribute it and/or modify it under
+:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
+.="- .-=="i,     .._ License as published by the Free Software
+ - .   .-<_>     .<> Foundation; either version 2 of the License,
+     ._= =}       : or (at your option) any later version.
+    .%`+i>       _;_.
+    .i_,=:_.      -<s. This library is distributed in the hope that
+     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
+    : ..    .:,     . . . without even the implied warranty of
+    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
+  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
+..}^=.=       =       ; Library General Public License for more
+++=   -.     .`     .: details.
+ :     =  ...= . :.=-
+ -.   .:....=;==+<; You should have received a copy of the GNU
+  -_. . .   )=.  = Library General Public License along with
+    --        :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "owidgetstack.h"
+
+/* QT */
+#include <qapplication.h>
+#include <qwidgetstack.h>
+
+namespace {
+ const int mode_size = 330;
+}
+
+using namespace Opie;
+
+/**
+ * This is the standard widget. For simple usage see the example. Normally this widget
+ * is the central widget of a QMainWindow.
+ * Use removeWidget before you delete a widget yourself. OWidgetStack does not
+ * yet recognize removal of children.
+ *
+ * @param parent The parent widget. It maybe 0 but then you need to take care of deletion.
+ * Or you use QPEApplication::showMainWidget().
+ * @param name Name will be passed on to QObject
+ * @param fl Additional window flags passed to QFrame. see @Qt::WFlags
+ */
+OWidgetStack::OWidgetStack( QWidget* parent, const char* name, WFlags fl)
+ : QFrame( parent, name, fl )
+{
+ m_last = m_mWidget = 0;
+ m_forced = false;
+
+ QApplication::desktop()->installEventFilter( this );
+ setFontPropagation ( AllChildren );
+ setPalettePropagation( AllChildren );
+
+ /* sets m_mode and initializes more */
+ /* if you change this call change switchTop as well */
+ m_stack = 0;
+ switchStack();
+}
+
+/**
+ * The destructor. It deletes also all added widgets.
+ *
+ */
+OWidgetStack::~OWidgetStack() {
+ if (m_mode == BigScreen && !m_list.isEmpty() ) {
+ QMap<int, QWidget*>::Iterator it = m_list.begin();
+ for ( ; it != m_list.end(); ++it )
+ delete it.data();
+ }
+ m_list.clear();
+
+}
+
+/**
+ * return the mode of the desktop. There are currently two modes. SmallScreen
+ * with a normal PDA resolution and BigScreen with resolutions greater than
+ * 330 for width and height.
+ * You can also force the mode this widget is in with forceMode()
+ * Note that NoForce will be never returned from here
+ */
+enum OWidgetStack::Mode OWidgetStack::mode()const {
+ return m_mode;
+}
+
+/**
+ * You can also force one of the modes and then
+ * this widget stops on listening to size changes. You
+ * can revert to the scanning behaviour by setting mode
+ * to NoForce
+ */
+void OWidgetStack::forceMode( enum Mode mode) {
+ m_forced = mode != NoForce;
+
+ /* we need to see which mode we're in */
+ if (!m_forced ) {
+ if ( QApplication::desktop()->width() >=
+ mode_size )
+ mode = BigScreen;
+ else
+ mode = SmallScreen;
+ }
+ switch( mode ) {
+ case NoForce:
+ case SmallScreen:
+ switchStack();
+ break;
+ case BigScreen:
+ switchTop();
+ break;
+
+ }
+
+ m_mode = mode;
+}
+
+/**
+ * Adds a widget to the stack. The first widget added is considered
+ * to be the mainwindow. This is important because if Opie is in
+ * BigScreen mode the sizeHint of the MainWindow will be returned.
+ * In Small Screen the sizeHint of the QWidgetStack is returned.
+ * See QWidgetStack::sizeHint.
+ * This widget takes ownership of the widget and may even reparent.
+ * All windows will be hidden
+ *
+ * @param wid The QWidget to be added
+ * @param id An ID for the Widget. If the ID is duplicated the
+ last set widget will be related to the id
+ *
+ */
+void OWidgetStack::addWidget( QWidget* wid, int id) {
+ if (!wid)
+ return;
+
+ /* set our main widget */
+ if (!m_mWidget)
+ m_mWidget = wid;
+
+ m_list.insert( id, wid );
+
+ /**
+ * adding does not raise any widget
+ * But for our mainwidget we prepare
+ * the right position with the right parent
+ */
+ if (m_mode == SmallScreen )
+ m_stack->addWidget( wid,id );
+ else if ( m_mWidget == wid ) {
+ wid->reparent(this, 0, contentsRect().topLeft() );
+ wid->hide();
+ }else {
+ wid->reparent(0, WType_TopLevel, QPoint(10, 10) );
+ wid->hide();
+ }
+}
+
+
+/**
+ * Remove the widget from the stack it'll be reparented to 0
+ * and ownership is dropped. You need to delete it.
+ * If the removed widget was the mainwindow consider
+ * to call setMainWindow.
+ *
+ * @param wid The QWidget to be removed
+ */
+void OWidgetStack::removeWidget( QWidget* wid) {
+ if (!wid)
+ return;
+
+ if (m_mode == SmallScreen )
+ m_stack->removeWidget( wid );
+
+
+ wid->reparent(0, 0, QPoint(0, 0) );
+ m_list.remove( id(wid) );
+
+ if ( wid == m_mWidget )
+ m_mWidget = 0;
+}
+
+#if 0
+/**
+ * @internal_resons
+ */
+QSizeHint OWidgetStack::sizeHint()const {
+
+}
+
+/**
+ * @internal_reasons
+ */
+QSizeHint OWidgetStack::minimumSizeHint()const {
+
+}
+#endif
+
+/**
+ * This function tries to find the widget with the id.
+ * You supplied a possible id in addWIdget. Note that not
+ * QWidget::winId() is used.
+ *
+ * @param id The id to search for
+ *
+ * @return The widget or null
+ * @see addWidget
+ */
+QWidget* OWidgetStack::widget( int id) const {
+ return m_list[id];
+}
+
+/**
+ * Tries to find the assigned id for the widget
+ * or returns -1 if no widget could be found
+ * @param wid The widget to look for
+ */
+int OWidgetStack::id( QWidget* wid)const{
+ if (m_list.isEmpty() )
+ return -1;
+
+ QMap<int, QWidget*>::ConstIterator it = m_list.begin();
+ for ( ; it != m_list.end(); ++it )
+ if ( it.data() == wid )
+ break;
+
+ /* if not at the end return the key */
+ return it == m_list.end() ? -1 : it.key();
+}
+
+
+/**
+ * This function returns the currently visible
+ * widget. In BigScreen mode the mainwindow
+ * is returned
+ */
+QWidget* OWidgetStack::visibleWidget()const {
+ if (m_mode == SmallScreen )
+ return m_stack->visibleWidget();
+ else
+ return m_mWidget;
+
+}
+
+/**
+ * This method raises the widget wit the specefic id.
+ * Note that in BigScreen mode the widget is made visible
+ * but the other ( previous) visible widget(s) will not
+ * be made invisible. If you need this use hideWidget().
+ *
+ * @param id Raise the widget with id
+ */
+void OWidgetStack::raiseWidget( int id) {
+ return raiseWidget( widget( id ) );
+}
+
+/**
+ * This is an overloaded function and only differs in its parameters.
+ * @see raiseWidget( int )
+ */
+void OWidgetStack::raiseWidget( QWidget* wid) {
+ m_last = wid;
+ if (m_mode == SmallScreen )
+ m_stack->raiseWidget( wid );
+ else {
+ int ide;
+ emit aboutToShow( wid );
+ /* if someone is connected and the widget is actually available */
+ if ( receivers( SIGNAL(aboutToShow(int) ) ) &&
+ ( (ide = id( wid ) ) != -1 ) )
+ emit aboutToShow( ide );
+
+ /* ### FIXME PLACE THE WIDGET right */
+ wid->show();
+ }
+}
+
+/**
+ * This will hide the currently visible widget
+ * and raise the widget specified by the parameter.
+ * Note that this method does not use visibleWIdget but remembers
+ * the last raisedWidget
+ */
+void OWidgetStack::hideWidget( int id) {
+ /* hiding our main widget wouldn't be smart */
+ if ( m_mode == BigScreen && m_last != m_mWidget )
+ m_last->hide();
+ raiseWidget( id );
+}
+
+/**
+ * This is overloaded and only differs in the parameters
+ * it takes.
+ */
+void OWidgetStack::hideWidget( QWidget* wid) {
+ /* still not smart */
+ if ( m_mode == BigScreen && m_last != m_mWidget )
+ m_last->hide();
+
+ raiseWidget( wid );
+}
+
+
+bool OWidgetStack::eventFilter( QObject* obj, QEvent* e) {
+ qWarning(" %s %s", obj->name(), obj->className() );
+ if ( e->type() == QEvent::Resize ) {
+ QResizeEvent *res = static_cast<QResizeEvent*>( e );
+ QSize size = res->size();
+ if ( size.width() >= mode_size )
+ switchTop();
+ else
+ switchStack();
+ }
+ return false;
+}
+
+
+/**
+ * @internal_resons
+ */
+void OWidgetStack::resizeEvent( QResizeEvent* ev ) {
+ QFrame::resizeEvent( ev );
+ if (m_mode == SmallScreen )
+ m_stack->setGeometry( frameRect() );
+ else
+ if (m_mWidget )
+ m_mWidget->setGeometry( frameRect() );
+
+}
+
+/**
+ * setMainWindow gives the OWidgetStack a hint which
+ * window should always stay inside the stack.
+ * Normally the first added widget is considered to be
+ * the mainwindow but you can change this with this
+ * function.
+ * If in BigScreen mode the current mainwindow will be reparented
+ * and hidden. The position will be taken by the new one.
+ * If the old MainWindow was hidden the new window will
+ * also be hidden. If the window was visible the new mainwindow
+ * will be made visible too and the old one hidden. If there
+ * was no mainwindow it will be hidden as well.
+ *
+ * @param wid The new mainwindow
+ */
+void OWidgetStack::setMainWindow( QWidget* wid ) {
+ if (m_mode == BigScreen ) {
+ bool wasVisible = false;
+ if (m_mWidget ) {
+ wasVisible = !m_mWidget->isHidden();
+ /* hidden by default */
+ m_mWidget->reparent(0, WType_TopLevel, QPoint(10, 10) );
+ }
+ wid->reparent(this, 0, frameRect().topLeft() );
+
+ if (wasVisible)
+ wid->show();
+ }
+
+ m_mWidget = wid;
+}
+
+/**
+ * this is an overloaded member and only differs
+ * in the type of arguments.
+ * @see setMainWindow(QWidget*)
+ */
+void OWidgetStack::setMainWindow( int id) {
+ setMainWindow( widget( id ) );
+}
+
+
+/*
+ * this function switches to a stack ;)
+ */
+void OWidgetStack::switchStack() {
+ if (m_stack ) {
+ m_stack->setGeometry( frameRect() );
+ return;
+ }
+
+ m_mode = SmallScreen;
+ m_stack = new QWidgetStack(this);
+
+ connect(m_stack, SIGNAL(aboutToShow(QWidget*) ),
+ this, SIGNAL(aboutToShow(QWidget*) ) );
+ connect(m_stack, SIGNAL(aboutToShow(int) ),
+ this, SIGNAL(aboutToShow(int) ) );
+
+ /* now reparent the widgets... luckily QWidgetSatck does most of the work */
+ if (m_list.isEmpty() )
+ return;
+
+ QMap<int, QWidget*>::Iterator it = m_list.begin();
+ for ( ; it != m_list.end(); ++it )
+ m_stack->addWidget( it.data(), it.key() );
+
+
+}
+
+/*
+ * we will switch to top level mode
+ * reparent the list of widgets and then delete the stack
+ */
+void OWidgetStack::switchTop() {
+ m_mode = BigScreen;
+ /* this works because it is guaranteed that switchStack was called at least once*/
+ if (!m_stack && m_mWidget) {
+ m_mWidget->setGeometry( frameRect() );
+ return;
+ }else if (!m_stack)
+ return;
+
+ if (!m_list.isEmpty() ) {
+ QMap<int, QWidget*>::Iterator it = m_list.begin();
+ for ( ; it != m_list.end(); ++it ) {
+ /* better than reparenting twice */
+ if ( it.data() == m_mWidget ) {
+ m_mWidget->reparent(this, 0, frameRect().topLeft() );
+ m_mWidget->setGeometry( frameRect() );
+ m_mWidget->show();
+ }else
+ /* ### FIXME we need to place the widget better */
+ it.data()->reparent(0, WType_TopLevel, QPoint(10, 10) );
+ }
+ }
+
+ delete m_stack;
+ m_stack = 0;
+}
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 @@
+/*
+               =. This file is part of the OPIE Project
+             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
+           .>+-=
+ _;:,     .>    :=|. This library is free software; you can
+.> <`_,   >  .   <= redistribute it and/or modify it under
+:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
+.="- .-=="i,     .._ License as published by the Free Software
+ - .   .-<_>     .<> Foundation; either version 2 of the License,
+     ._= =}       : or (at your option) any later version.
+    .%`+i>       _;_.
+    .i_,=:_.      -<s. This library is distributed in the hope that
+     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
+    : ..    .:,     . . . without even the implied warranty of
+    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
+  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
+..}^=.=       =       ; Library General Public License for more
+++=   -.     .`     .: details.
+ :     =  ...= . :.=-
+ -.   .:....=;==+<; You should have received a copy of the GNU
+  -_. . .   )=.  = Library General Public License along with
+    --        :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef OWIDGETSTACK_H
+#define OWIDGETSTACK_H
+
+/* QT*/
+#include <qframe.h>
+#include <qmap.h>
+
+class QWidgetStack;
+
+namespace Opie
+{
+/**
+ *
+ * OWidgetStack is the answer to the problem of using Opie at different screen
+ * sizes and to have a different behaviour. Most applications use a QWidgetStack
+ * to supply a view on click. And by clicking the (X) you go back but this
+ * behaviour feels strange on bigger screens. It's ok on smaller one because
+ * one can't determine the difference.
+ * This stack reads the default out of the size of the desktop widget but
+ * can be forced to have either the one or the other behaviour.
+ * The first widget added is considered the 'main' widget and its
+ * sizeHint will be taking if in BigScreen mode.
+ * In small screen mode this widget behaves exactly like a QWidgetStack and in BigScreen
+ * mode it'll use the MainWindow as child of this widget and arranges the others as
+ * hidden top level widgets.
+ *
+ * @version 0.1
+ * @author hOlgAr F.
+ * @short Either a true stack or a list of top Level widgets
+ */
+class OWidgetStack : public QFrame {
+ Q_OBJECT
+public:
+ enum Mode { SmallScreen, BigScreen, NoForce };
+ OWidgetStack( QWidget* parent, const char* name = 0, WFlags fl = 0 );
+ ~OWidgetStack();
+
+ enum Mode mode()const;
+ void forceMode( enum Mode );
+
+ void addWidget( QWidget* , int );
+ void removeWidget( QWidget* );
+
+// QSizeHint sizeHint()const;
+// QSizeHint minimumSizeHint()const;
+
+ QWidget *widget( int )const;
+ int id( QWidget* )const;
+
+
+
+ QWidget* visibleWidget() const;
+
+ bool eventFilter( QObject*, QEvent* );
+signals:
+ /**
+ * OWidgetStack monitors the Desktop Widget for
+ * size changes if it recignizes a change size it'll
+ * send a signal and adjust its mode. After the signal
+ * was emitted. During the signal a call to mode() the
+ * old mode will be returned. Note that if a size change happens
+ * but no modeChange no signal will be emitted
+ *
+ *
+ * @param mode The new mode of the desktop
+ */
+ void modeChanged( enum Mode mode);
+
+ /**
+ * These two signals are emitted whenever we're about to
+ * show one of the widgets
+ */
+ void aboutToShow( QWidget* );
+ void aboutToShow( int );
+
+public slots:
+ void raiseWidget( int );
+ void raiseWidget( QWidget* );
+ void hideWidget( int );
+ void hideWidget( QWidget* );
+ void setMainWindow( QWidget* );
+ void setMainWindow( int );
+
+protected:
+ void resizeEvent( QResizeEvent* );
+
+private:
+ void switchStack();
+ void switchTop();
+ QMap<int, QWidget*> m_list;
+ QWidgetStack *m_stack;
+ QWidget *m_mWidget;
+ QWidget *m_last;
+
+ enum Mode m_mode;
+ bool m_forced : 1;
+
+ struct Private;
+ Private *d;
+};
+
+};
+
+#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
@@ -48,4 +48,6 @@ SOURCES = ocheckitem.cpp \
oseparator.cpp
+include ( big-screen/big-screen.pro )
+
INTERFACES = otimepickerbase.ui