summaryrefslogtreecommitdiff
path: root/libopie/big-screen/omodalhelper.h
Side-by-side diff
Diffstat (limited to 'libopie/big-screen/omodalhelper.h') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/big-screen/omodalhelper.h708
1 files changed, 0 insertions, 708 deletions
diff --git a/libopie/big-screen/omodalhelper.h b/libopie/big-screen/omodalhelper.h
deleted file mode 100644
index 78a2ac9..0000000
--- a/libopie/big-screen/omodalhelper.h
+++ b/dev/null
@@ -1,708 +0,0 @@
-/*
-               =. 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 HAZE_OMODAL_HELPER_H
-#define HAZE_OMODAL_HELPER_H
-
-#include <qdialog.h>
-#include <qwidget.h>
-#include <qvaluelist.h>
-#include <qmap.h>
-#include <qvariant.h>
-
-typedef int TransactionID;
-
-class OModalHelperControler;
-class OModalHelperSignal;
-class QDialog;
-
-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