summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/big-screen/omodalhelper.cpp160
-rw-r--r--libopie/big-screen/omodalhelper.h121
2 files changed, 263 insertions, 18 deletions
diff --git a/libopie/big-screen/omodalhelper.cpp b/libopie/big-screen/omodalhelper.cpp
new file mode 100644
index 0000000..e3d1c70
--- a/dev/null
+++ b/libopie/big-screen/omodalhelper.cpp
@@ -0,0 +1,160 @@
1/*
2               =. This file is part of the OPIE Project
3             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
4           .>+-=
5 _;:,     .>    :=|. This library is free software; you can
6.> <`_,   >  .   <= redistribute it and/or modify it under
7:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
8.="- .-=="i,     .._ License as published by the Free Software
9 - .   .-<_>     .<> Foundation; either version 2 of the License,
10     ._= =}       : or (at your option) any later version.
11    .%`+i>       _;_.
12    .i_,=:_.      -<s. This library is distributed in the hope that
13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
14    : ..    .:,     . . . without even the implied warranty of
15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
17..}^=.=       =       ; Library General Public License for more
18++=   -.     .`     .: details.
19 :     =  ...= . :.=-
20 -.   .:....=;==+<; You should have received a copy of the GNU
21  -_. . .   )=.  = Library General Public License along with
22    --        :-=` this library; see the file COPYING.LIB.
23 If not, write to the Free Software Foundation,
24 Inc., 59 Temple Place - Suite 330,
25 Boston, MA 02111-1307, USA.
26
27*/
28
29#include <qpushbutton.h>
30#include <qvbox.h>
31#include <qlayout.h>
32#include <qlabel.h>
33
34#include "omodalhelper.h"
35
36
37/* SIgnal handling */
38OModalHelperSignal::OModalHelperSignal( OModalHelperBase* base, QObject* parent )
39 : QObject( parent, "OModal Helper Signal" ), m_base( base ) {
40}
41
42OModalHelperSignal::~OModalHelperSignal() {
43 /* special the ancestor deletes its creator */
44 delete m_base;
45}
46
47
48/* Helper Controler */
49/*
50 * the dialogs signal will be slotted here
51 * and we will call into m_base
52 */
53OModalHelperControler::OModalHelperControler( OModalHelperBase* base, QObject* parent )
54 : QObject(parent, "OModal Helper Controler" ), m_base( base ), m_dia( 0 ), m_id( -1 )
55{
56}
57
58TransactionID OModalHelperControler::transactionID()const {
59 return m_id;
60}
61
62void OModalHelperControler::setTransactionID( TransactionID id ) {
63 m_dia = 0;
64 m_id = id;
65}
66
67QDialog* OModalHelperControler::dialog()const {
68 return m_dia;
69}
70
71/*
72 * If we're in the New mode we will map the QDialog
73 * to the TransactionID
74 */
75void OModalHelperControler::done( int result ) {
76 if ( sender() && !sender()->isA("OModalQueuedDialog") )
77 m_dia = static_cast<QDialog*>( sender() );
78
79 m_base->done( m_id );
80}
81
82void OModalHelperControler::next() {
83 m_base->next( m_id );
84}
85
86void OModalHelperControler::prev() {
87 m_base->prev( m_id );
88}
89
90/* The Queued Dialog inclusive QueuedBar */
91struct OModalQueueBar : public QHBox {
92 QPushButton* next;
93 QPushButton* prev;
94 QLabel * label;
95
96 OModalQueueBar( QWidget* parent );
97 void setText( const QString& str );
98};
99
100OModalQueueBar::OModalQueueBar( QWidget* parent )
101 : QWidget( parent, "OModal Queue Bar" ) {
102 prev = new QPushButton( this );
103 prev->setText( OModalQueuedDialog::tr("Prev") );
104
105 label = new QLabel(this);
106
107 next = new QPushButton( this );
108 next->setText( OModalQueuedDialog::tr("Next") );
109}
110
111void OModalQueueBar::setText( const QString& str ) {
112 label->setText( str );
113}
114
115
116OModalQueuedDialog::OModalQueuedDialog( QDialog* mainWidget )
117 : QDialog(0, "OModal Queued Dialog" )
118{
119 QVBoxLayout *lay = new QVBoxLayout( this );
120
121 m_bar = new OModalQueueBar( this );
122 lay->addWidget( m_bar );
123
124 m_center = mainWidget;
125 m_center->reparent(this, 0, QPoint(0, 0) );
126 lay->addWidget( m_center );
127
128
129 connect(m_bar->next, SIGNAL(clicked() ), this,
130 SIGNAL(next() ) );
131 connect(m_bar->prev, SIGNAL(clicked() ), this,
132 SIGNAL(prev() ) );
133
134}
135
136OModalQueuedDialog::~OModalQueuedDialog() {
137}
138
139QDialog* OModalQueuedDialog::centerDialog()const {
140 return m_center;
141}
142
143void OModalQueuedDialog::setQueueBarEnabled( bool b) {
144 /* in Qt3 use setEnabled( bool ) */
145 if (b)
146 m_bar->show();
147 else
148 m_bar->hide();
149}
150
151void OModalQueuedDialog::setRecord( int record, int count ) {
152 if (!record && !count ) {
153 hide();
154 return;
155 }else
156 show();
157
158 m_bar->setText( tr("Editing record %1 out of %2",
159 "Shows the current edited record out of an array of records").arg( record ). arg( count ) );
160}
diff --git a/libopie/big-screen/omodalhelper.h b/libopie/big-screen/omodalhelper.h
index c483403..bc20d10 100644
--- a/libopie/big-screen/omodalhelper.h
+++ b/libopie/big-screen/omodalhelper.h
@@ -49,17 +49,20 @@ struct OModalHelperBase {
49/** 49/**
50 * Modality sucks! ;) But it is easy to work with 50 * Modality sucks! ;) But it is easy to work with
51 * do exec() on a dialog and you know everything is funky. 51 * do exec() on a dialog and you know everything is funky.
52 * You only need to have one Dialog loaded and so on. 52 * You only need to have one Dialog loaded and so on.
53 * This class helps you to work like with modality and help 53 * This class helps you to work like with modality and help
54 * you to keep things in sync 54 * you to keep things in sync
55 * It's a template class but it sends signals once one Item is ready 55 * It's a template class but it sends signals once one Item is ready
56 * the signals contains the status and id of the item and then you 56 * the signals contains the status and id of the item and then you
57 * can fetch it. 57 * need fetch it.
58 * Handled Records will stay available until the first call to retrieve
59 * either the record via the TransactionID or via the QValueList<Record>. Note
60 * that most functions do not take handled records into account.
58 * Also if you edit an record external you can tell this class and it'll 61 * Also if you edit an record external you can tell this class and it'll
59 * call the merge() function of your widget to maybe merge in these changes. 62 * call the merge() function of your widget to maybe merge in these changes.
60 * It also supports multiple modes. Either it can create new dialogs 63 * It also supports multiple modes. Either it can create new dialogs
61 * for each item or it can queue them depending on your usage. But it is 64 * for each item or it can queue them depending on your usage. But it is
62 * so smart that if only one item is shown that the queue bar is not shown 65 * so smart that if only one item is shown that the queue bar is not shown
63 * See the example for simple usage. 66 * See the example for simple usage.
64 * 67 *
65 * @short helps to life without modaility 68 * @short helps to life without modaility
@@ -74,44 +77,46 @@ public:
74 typedef QValueList<Record> RecordList; 77 typedef QValueList<Record> RecordList;
75 typedef QMap<Id, Record> IdMap; 78 typedef QMap<Id, Record> IdMap;
76 typedef QMap<TransactionID, Id> TransactionMap; 79 typedef QMap<TransactionID, Id> TransactionMap;
77 typedef QMap<QDialog*, TransactionID> DialogMap 80 typedef QMap<QDialog*, TransactionID> DialogMap
78 enum Mode { Queue, New }; 81 enum Mode { Queue, New };
79 OModalHelper(enum Mode mode, QObject* parnet ); 82 OModalHelper(enum Mode mode, QObject* parnet );
80 83
81 bool handles( Id id)const; 84 bool handles( Id id)const;
85 TransactionID transactionID( Id id)const;
82 86
83 void cancel(); 87 void cancel();
84 void cancel( TransactionID ); 88 void cancel( TransactionID );
85 89
86 void connectDone( QObject* rec, const char* slot ); 90 void connectDone( QObject* rec, const char* slot );
87 void connectAccepted( QObject* rec, const char* slot ); 91 void connectAccepted( QObject* rec, const char* slot );
88 void connectRejected( QObject* rec, const char* slot ); 92 void connectRejected( QObject* rec, const char* slot );
89 93
90 TransactionID handle( Id id, const Record& rec = Record() ); 94 TransactionID handle( Id id, const Record& rec = Record() );
91 95
92 void edited( TransactionID, int what, const QString& data ); 96 void edited( TransactionID, int what, const QString& data );
93 97
94 Record record( TransactionID )const; 98 Record record( TransactionID )const;
95 RecordList done()const; 99 RecordList done()const;
96private: 100private:
97 virtual void done( TransactionID, QDialog* ); 101 virtual void done( TransactionID );
98 virtual void next( TransactionID, OModalHelperControler * ); 102 virtual void next( TransactionID );
99 virtual void prev( TransactionID, OModalHelperControler * ); 103 virtual void prev( TransactionID );
100 104
101 Record nextRecord( TransactionID, int * )const; 105 Record nextRecord( TransactionID, int * )const;
102 Record prevRecord( TransactionID, int * )const; 106 Record prevRecord( TransactionID, int * )const;
103 107
104private: 108private:
105 OModalHelperDialog *queuedDialog()const; // generate or recycle 109 OModalHelperDialog *queuedDialog()const; // generate or recycle
106 OModalHelperDialog *m_dialog; 110 OModalHelperDialog *m_dialog;
107 OModalHelperSignal *m_signal; // our signal 111 OModalHelperSignal *m_signal; // our signal
108 OModalHelperControler *m_controler; 112 OModalHelperControler *m_controler;
109 IdMap m_ids; // maps ids (uids) to a record 113 IdMap m_ids; // maps ids (uids) to a record
114 IdMap m_doneIds;
110 TransactionMap m_transactions; // activate transactions 115 TransactionMap m_transactions; // activate transactions
111 TransactionMap m_done; // done and waiting for getting picked 116 TransactionMap m_done; // done and waiting for getting picked
112 DialogMap m_editing; // only used for New Mode 117 DialogMap m_editing; // only used for New Mode
113 enum Mode m_mode; // the mode we're in 118 enum Mode m_mode; // the mode we're in
114}; 119};
115 120
116 121
117 122
@@ -128,16 +133,17 @@ private:
128 * For the new mode 133 * For the new mode
129 * 134 *
130 */ 135 */
131 136
132class OModalHelperSignal : public QObject { 137class OModalHelperSignal : public QObject {
133 Q_OBJECT 138 Q_OBJECT
134public: 139public:
135 OModalHelperSignal(OModalHelperBase* base, QObject* parent); 140 OModalHelperSignal(OModalHelperBase* base, QObject* parent);
141 ~OModalHelperSignal();
136 142
137signals: 143signals:
138 done( int status, TransactionID transaction ); 144 done( int status, TransactionID transaction );
139 accepted( TransactionID transaction ); 145 accepted( TransactionID transaction );
140 rejected( TransactionID transaction ); 146 rejected( TransactionID transaction );
141 147
142private: 148private:
143 OModalHelperBase* m_base; 149 OModalHelperBase* m_base;
@@ -148,36 +154,44 @@ class OModalHelperControler : public QObject {
148 Q_OBJECT 154 Q_OBJECT
149public: 155public:
150 OModalHelperControler( OModalHelperBase* , QObject* parent); 156 OModalHelperControler( OModalHelperBase* , QObject* parent);
151 virtual TransactionID transactionID()const; 157 virtual TransactionID transactionID()const;
152 void setTransactionID( TransactionID id ); 158 void setTransactionID( TransactionID id );
153 QDialog* dialog()const; 159 QDialog* dialog()const;
154 160
155public slots: 161public slots:
156 virtual done(int result ); 162 virtual void done(int result );
163 virtual void next();
164 virtual void prev();
157private: 165private:
158 QDialog *m_dia; 166 QDialog *m_dia;
159 TransactionID m_id; 167 TransactionID m_id;
160 OModalHelperBase *m_base; 168 OModalHelperBase *m_base;
161} 169}
162 170
163class OModalQueueBar; 171struct OModalQueueBar;
164class OModalQueuedDialog : public QDialog { 172class OModalQueuedDialog : public QDialog {
165 Q_OBJECT 173 Q_OBJECT
166public: 174public:
167 OModalQueuedDialog(QWidget *mainWidget); 175 OModalQueuedDialog(QDialog *mainWidget);
168 ~OModalQueuedDialog(); 176 ~OModalQueuedDialog();
169 177
170 QDialog* centerDialog()const; 178 QDialog* centerDialog()const;
171 179
172 void setQueueBarEnabled( bool = true ); 180 void setQueueBarEnabled( bool = true );
173 void setRecord( int record, int count ); 181 void setRecord( int record, int count );
182
183signals:
184 void next();
185 void prev();
186
174private: 187private:
175 OModalQueueBar *m_bar; 188 OModalQueueBar *m_bar;
189 QDialog *m_center;
176}; 190};
177 191
178 192
179/* 193/*
180 * Tcpp Template Implementation 194 * Tcpp Template Implementation
181 */ 195 */
182 196
183/** 197/**
@@ -189,24 +203,24 @@ private:
189 * @param mode The mode this dialog should be in 203 * @param mode The mode this dialog should be in
190 * @param parent The parent QObject of this helper. 204 * @param parent The parent QObject of this helper.
191 */ 205 */
192template<class Dialog, class Record, typename Id> 206template<class Dialog, class Record, typename Id>
193OModalHelper<Dialog, Record, Id>::OModalHelper( enum Mode mode, QObject* parent ) { 207OModalHelper<Dialog, Record, Id>::OModalHelper( enum Mode mode, QObject* parent ) {
194 m_mode = mode; 208 m_mode = mode;
195 m_signal = new OModalHelperSignal( this, parent ); 209 m_signal = new OModalHelperSignal( this, parent );
196 m_controler = new OModalHelperControler( this, m_signal ); 210 m_controler = new OModalHelperControler( this, m_signal );
211
197} 212}
198 213
199 214
200/** 215/**
201 * This functions looks for your record and sees if it is 216 * This functions looks for your record and sees if it is
202 * handled with this helper. Note that done and edited records 217 * handled with this helper. Note that done records
203 * will not be returned. But if you edit an already edited record 218 * will not be returned.
204 * the done record will be used
205 * 219 *
206 * @return true if the record is currenlty edited otherwise false 220 * @return true if the record is currenlty edited otherwise false
207 * 221 *
208 * @param Id The id which might be handled 222 * @param Id The id which might be handled
209 */ 223 */
210template<class Dialog, class Record, typename Id> 224template<class Dialog, class Record, typename Id>
211bool OModalHelper<Dialog, Record, Id>::handles( Id id )const { 225bool OModalHelper<Dialog, Record, Id>::handles( Id id )const {
212 if ( m_transactions.isEmpty() ) 226 if ( m_transactions.isEmpty() )
@@ -215,36 +229,55 @@ bool OModalHelper<Dialog, Record, Id>::handles( Id id )const {
215 TransactionMap::ConstIterator it = m_transactions.begin(); 229 TransactionMap::ConstIterator it = m_transactions.begin();
216 for ( ; it != m_transactions.end(); ++it ) 230 for ( ; it != m_transactions.end(); ++it )
217 if ( it.data() == id ) 231 if ( it.data() == id )
218 return true; 232 return true;
219 233
220 return false; 234 return false;
221} 235}
222 236
237
238/**
239 * just like handles( Id ) but returns the TransactionId
240 */
241template<class Dialog, class Record, typename Id>
242TransactionID OModalHelper<Dialog, Record, Id>::transactionID( Id id)const {
243 if ( m_transactions.isEmpty() )
244 return false;
245
246 TransactionMap::ConstIterator it = m_transactions.begin();
247 for ( ; it != m_transactions.end(); ++it )
248 if ( it.data() == id )
249 return true;
250
251 return false;
252}
253
223/** 254/**
224 * Cancel will cancel all current operations and clear the list 255 * Cancel will cancel all current operations and clear the list
225 * of done operations as well. 256 * of done operations as well.
257 * This also clears all done operations you did not popped
226 */ 258 */
227template<class Dialog, class Record, typename Id> 259template<class Dialog, class Record, typename Id>
228void OModalHelper<Dialog, Record, Id>::cancel() { 260void OModalHelper<Dialog, Record, Id>::cancel() {
229 m_ids.clear(); 261 m_ids.clear();
262 m_doneIds.clear();
230 m_done.clear(); 263 m_done.clear();
231 m_transactions.clear(); 264 m_transactions.clear();
232 265
233 /* we also need to remove the QDialogs */ 266 /* we also need to remove the QDialogs */
234 /* and hide the queue dialog if present */ 267 /* and hide the queue dialog if present */
235 if (m_mode == New && !m_editing.isEmpty() ) { 268 if (m_mode == New && !m_editing.isEmpty() ) {
236 for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it ) 269 for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it )
237 delete it.key(); 270 delete it.key();
238 m_editing.clear(); 271 m_editing.clear();
239 }else if (m_dialog ) 272 }else if (m_dialog )
240 queuedDialog()->setRecord( 0, 0 ); 273 queuedDialog()->setRecord( 0, 0 );
241 274
242 275 m_controler->setTransactionID( -1 );
243} 276}
244 277
245 278
246/** 279/**
247 * This cancels editing of the record behind the Transaction Number 280 * This cancels editing of the record behind the Transaction Number
248 * Note that if editing is already done it will also be removed from this list 281 * Note that if editing is already done it will also be removed from this list
249 */ 282 */
250template<class Dialog, class Record, typename Id> 283template<class Dialog, class Record, typename Id>
@@ -273,20 +306,25 @@ void OModalHelper::cancel( TransactionID tid ) {
273 /* now either activate the previous again or hide */ 306 /* now either activate the previous again or hide */
274 if (! m_transactions.count() -1 ) 307 if (! m_transactions.count() -1 )
275 queuedDialog()->setRecord( 0, 0 ); 308 queuedDialog()->setRecord( 0, 0 );
276 else { 309 else {
277 int pos; 310 int pos;
278 Record rec = prevRecord( tid, &pos ); 311 Record rec = prevRecord( tid, &pos );
279 static_cast<Dialog*>( queuedDialog()->centerDialog() )->setRecord( rec ); 312 static_cast<Dialog*>( queuedDialog()->centerDialog() )->setRecord( rec );
280 queuedDialog()->setRecord( pos, m_transactions.count() ); 313 queuedDialog()->setRecord( pos, m_transactions.count() );
314 m_controler->setTransactionID( tid );
281 } 315 }
282 } 316 }
283 /* now remove from the various maps */ 317 /* now remove from the various maps done and currently editing map*/
284 m_ids.remove( m_transactions.contains( tid ) ? m_transactions[tid] : m_done[tid ] ); 318 if (m_transactions.contains( tid ) )
319 m_ids.remove( m_transactions[tid] );
320 if (m_done.contains( tid ) )
321 m_doneIds.remove( m_done[tid ] );
322
285 323
286 m_done.remove( tid ); 324 m_done.remove( tid );
287 m_transactions.remove( tid ); 325 m_transactions.remove( tid );
288} 326}
289 327
290/** 328/**
291 * Connect to the done Signal. SIGNAL( done(int, TransactionID ) ) 329 * Connect to the done Signal. SIGNAL( done(int, TransactionID ) )
292 * This signal gets emitted whenever a Record was accepted or rejected 330 * This signal gets emitted whenever a Record was accepted or rejected
@@ -296,25 +334,72 @@ void OModalHelper::cancel( TransactionID tid ) {
296 */ 334 */
297template<class Dialog, class Record, typename Id> 335template<class Dialog, class Record, typename Id>
298void OModalHelper<Dialog, Record, Id>::connectDone( QObject* rec, const char* slot ) { 336void OModalHelper<Dialog, Record, Id>::connectDone( QObject* rec, const char* slot ) {
299 QObject::connect(m_signal, SIGNAL(done(int, TransactionID) ), 337 QObject::connect(m_signal, SIGNAL(done(int, TransactionID) ),
300 rec, slot ); 338 rec, slot );
301} 339}
302 340
303/** 341/**
304 * Connect to the accepted Signal. SIGNAL( done(int, TransactionID ) ) 342 * Connect to the accepted Signal. SIGNAL( accepted(TransactionID ) )
305 * This signal gets emitted whenever a Record was accepted or rejected 343 * This signal gets emitted whenever a Record was accepted
306 * 344 *
307 * @param rec The object where the slot belongs to 345 * @param rec The object where the slot belongs to
308 * @param slot The slot which should be called. See the needed parameter above 346 * @param slot The slot which should be called. See the needed parameter above
309 */ 347 */
310template<class Dialog, class Record, typename Id> 348template<class Dialog, class Record, typename Id>
311void OModalHelper<Dialog, Record, Id>::( QObject* rec, const char* slot ) { 349void OModalHelper<Dialog, Record, Id>::connectAccepted( QObject* rec, const char* slot ) {
312 350 QObject::connect(m_signal, SIGNAL(accepted(TransactionID) ),
351 rec, slot );
313} 352}
314 353
354/**
355 * Same as the accepted method but this one gets emitted if the dialog
356 * got rejected.
357 * SIGNAL( rejected(TransactionID) )
358 *
359 * @param rec The QObject of the slot
360 * @param slot The slot make sure the signature is correct
361 */
362template<class Dialog, class Record, typename Id>
363void OModalHelper<Dialog, Record, Id>::connectRejected( QObject* rec, const char* slot ) {
364 QObject::connect(m_signal, SIGNAL(rejected(TransactionID) ),
365 rec, slot );
366}
315 367
368/**
369 * Tell the helper to handle a record. If the record is currently handled
370 * it will be made active.
371 * Already handled record which are waiting getting popped are not taken into account
372 * Otherwise this helpers make the record editable.
373 * The record supplied needs to have a valid copy operator and constructor.
374 * In the case where the record is already present the parameter gets discarded.
375 * If you want the new record to be taken you need to cancel the Transaction first
376 *
377 * @param id The Identification of the Record. For PIM it would uid()
378 * @param rec The record we want to be edited
379 *
380 * @returns This functions returns the TransactionId assigned to the record
381 *
382 */
316template<class Dialog, class Record, typename Id> 383template<class Dialog, class Record, typename Id>
317void OModalHelper<Dialog, Record, Id>::( QObject* rec, const char* slot ) { 384TransactionID OModalHelper<Dialog, Record, Id>::handle( Id id, const Record& rec ) {
385 static TransactionID t_id = 0;
386 t_id++;
387 /*
388 *this method consists out of two parts divided each into New and Queued Mode.
389 * Either we have the dialog already, in this case we need to highlight the widget
390 * Or we need to add it.
391 */
392 TransactionID tid = 0;
393 /* we already have the record lets see if it was done or not */
394 if ( m_ids.contains( id ) ) {
318 395
396 }
397
398 /* fall through if the record is in the done list */
399 tid = t_id;
400
401
402 return;
319} 403}
404
320#endif 405#endif