Diffstat (limited to 'libopie/big-screen/omodalhelper.h') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie/big-screen/omodalhelper.h | 708 |
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 @@ | |||
1 | /* | ||
2 | =. This file is part of the OPIE Project | ||
3 | .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org> | ||
4 | .>+-= | ||
5 | _;:, .> :=|. This library is free software; you can | ||
6 | .> <`_, > . <= redistribute it and/or modify it under | ||
7 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | ||
8 | .="- .-=="i, .._ License as published by the Free Software | ||
9 | - . .-<_> .<> Foundation; either version 2 of the License, | ||
10 | ._= =} : or (at your option) any later version. | ||
11 | .%`+i> _;_. | ||
12 | .i_,=:_. -<s. This library is distributed in the hope that | ||
13 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | ||
14 | : .. .:, . . . without even the implied warranty of | ||
15 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | ||
16 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | ||
17 | ..}^=.= = ; Library General Public License for more | ||
18 | ++= -. .` .: details. | ||
19 | : = ...= . :.=- | ||
20 | -. .:....=;==+<; You should have received a copy of the GNU | ||
21 | -_. . . )=. = Library General Public License along with | ||
22 | -- :-=` this library; see the file COPYING.LIB. | ||
23 | If not, write to the Free Software Foundation, | ||
24 | Inc., 59 Temple Place - Suite 330, | ||
25 | Boston, MA 02111-1307, USA. | ||
26 | |||
27 | */ | ||
28 | |||
29 | #ifndef HAZE_OMODAL_HELPER_H | ||
30 | #define HAZE_OMODAL_HELPER_H | ||
31 | |||
32 | #include <qdialog.h> | ||
33 | #include <qwidget.h> | ||
34 | #include <qvaluelist.h> | ||
35 | #include <qmap.h> | ||
36 | #include <qvariant.h> | ||
37 | |||
38 | typedef int TransactionID; | ||
39 | |||
40 | class OModalHelperControler; | ||
41 | class OModalHelperSignal; | ||
42 | class QDialog; | ||
43 | |||
44 | struct OModalHelperBase { | ||
45 | virtual void done( int status, TransactionID ) = 0; | ||
46 | virtual void next( TransactionID ) = 0; | ||
47 | virtual void prev( TransactionID ) = 0; | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * Modality sucks! ;) But it is easy to work with | ||
52 | * do exec() on a dialog and you know everything is funky. | ||
53 | * You only need to have one Dialog loaded and so on. | ||
54 | * This class helps you to work like with modality and help | ||
55 | * you to keep things in sync | ||
56 | * It's a template class but it sends signals once one Item is ready | ||
57 | * the signals contains the status and id of the item and then you | ||
58 | * need fetch it. | ||
59 | * Handled Records will stay available until the first call to retrieve | ||
60 | * either the record via the TransactionID or via the QValueList<Record>. Note | ||
61 | * that most functions do not take handled records into account. | ||
62 | * Also if you edit an record external you can tell this class and it'll | ||
63 | * call the merge() function of your widget to maybe merge in these changes. | ||
64 | * It also supports multiple modes. Either it can create new dialogs | ||
65 | * for each item or it can queue them depending on your usage. But it is | ||
66 | * so smart that if only one item is shown that the queue bar is not shown | ||
67 | * See the example for simple usage. | ||
68 | * | ||
69 | * @short helps to life without modaility | ||
70 | * @author hOlgAr | ||
71 | * @version 0.01 | ||
72 | */ | ||
73 | template<class Dialog, class Record, typename Id = int> | ||
74 | class OModalHelper : private OModalHelperBase{ | ||
75 | friend class OModalHelperSignal; | ||
76 | friend class OModalHelperControler; | ||
77 | public: | ||
78 | typedef QValueList<Record> RecordList; | ||
79 | typedef QMap<Id, Record> IdMap; | ||
80 | typedef QMap<TransactionID, Id> TransactionMap; | ||
81 | typedef QMap<QDialog*, TransactionID> DialogMap | ||
82 | enum Mode { Queue, New }; | ||
83 | OModalHelper(enum Mode mode, QObject* parnet ); | ||
84 | |||
85 | bool handles( Id id)const; | ||
86 | TransactionID transactionID( Id id)const; | ||
87 | |||
88 | void suspend( bool = true ); | ||
89 | |||
90 | void cancel(); | ||
91 | void cancel( TransactionID ); | ||
92 | |||
93 | void connectDone( QObject* rec, const char* slot ); | ||
94 | void connectAccepted( QObject* rec, const char* slot ); | ||
95 | void connectRejected( QObject* rec, const char* slot ); | ||
96 | |||
97 | TransactionID handle( Id id, const Record& rec = Record() ); | ||
98 | |||
99 | void edited( Id, int what, const QVariant& data ); | ||
100 | |||
101 | Record record( TransactionID )const; | ||
102 | RecordList recordsDone()const; | ||
103 | private: | ||
104 | virtual void done( int, TransactionID ); | ||
105 | virtual void next( TransactionID ); | ||
106 | virtual void prev( TransactionID ); | ||
107 | |||
108 | Record nextRecord( TransactionID &, int & )const; | ||
109 | Record prevRecord( TransactionID &, int & )const; | ||
110 | int pos( TransactionID )const; | ||
111 | Dialog* newDialogRecord( const Record& ); | ||
112 | |||
113 | private: | ||
114 | OModalHelperDialog *queuedDialog()const; // generate or recycle | ||
115 | OModalHelperDialog *m_dialog; | ||
116 | OModalHelperSignal *m_signal; // our signal | ||
117 | OModalHelperControler *m_controler; | ||
118 | IdMap m_ids; // maps ids (uids) to a record | ||
119 | IdMap m_doneIds; | ||
120 | TransactionMap m_transactions; // activate transactions | ||
121 | TransactionMap m_done; // done and waiting for getting picked | ||
122 | DialogMap m_editing; // only used for New Mode | ||
123 | enum Mode m_mode; // the mode we're in | ||
124 | bool m_disabled :1; | ||
125 | }; | ||
126 | |||
127 | |||
128 | |||
129 | /* ### FIXME use namespace with Qt3 */ | ||
130 | |||
131 | /* | ||
132 | * A note on flow. The Signal is used for QT Signals when | ||
133 | * a record is done. | ||
134 | * There is either one controler and this controler slot will | ||
135 | * be connected to a dialog signal. | ||
136 | * In Queue we get the next and prev signals and call the Helper. | ||
137 | * this then changes the Record of the dialog and sets the transactionId | ||
138 | * of the controler. | ||
139 | * For the new mode | ||
140 | * | ||
141 | */ | ||
142 | |||
143 | class OModalHelperSignal : public QObject { | ||
144 | Q_OBJECT | ||
145 | public: | ||
146 | OModalHelperSignal(OModalHelperBase* base, QObject* parent); | ||
147 | ~OModalHelperSignal(); | ||
148 | |||
149 | signals: | ||
150 | done( int status, TransactionID transaction ); | ||
151 | accepted( TransactionID transaction ); | ||
152 | rejected( TransactionID transaction ); | ||
153 | |||
154 | private: | ||
155 | OModalHelperBase* m_base; | ||
156 | }; | ||
157 | |||
158 | |||
159 | class OModalHelperControler : public QObject { | ||
160 | Q_OBJECT | ||
161 | public: | ||
162 | OModalHelperControler( OModalHelperBase* , QObject* parent); | ||
163 | virtual TransactionID transactionID()const; | ||
164 | void setTransactionID( TransactionID id ); | ||
165 | QDialog* dialog()const; | ||
166 | |||
167 | public slots: | ||
168 | virtual void done(int result ); | ||
169 | virtual void next(); | ||
170 | virtual void prev(); | ||
171 | private: | ||
172 | QDialog *m_dia; | ||
173 | TransactionID m_id; | ||
174 | OModalHelperBase *m_base; | ||
175 | } | ||
176 | |||
177 | struct OModalQueueBar; | ||
178 | class OModalQueuedDialog : public QDialog { | ||
179 | Q_OBJECT | ||
180 | public: | ||
181 | OModalQueuedDialog(QDialog *mainWidget); | ||
182 | ~OModalQueuedDialog(); | ||
183 | |||
184 | QDialog* centerDialog()const; | ||
185 | |||
186 | void setQueueBarEnabled( bool = true ); | ||
187 | void setRecord( int record, int count ); | ||
188 | |||
189 | signals: | ||
190 | void next(); | ||
191 | void prev(); | ||
192 | |||
193 | private: | ||
194 | OModalQueueBar *m_bar; | ||
195 | QDialog *m_center; | ||
196 | }; | ||
197 | |||
198 | |||
199 | /* | ||
200 | * Tcpp Template Implementation | ||
201 | */ | ||
202 | |||
203 | /** | ||
204 | * This is the simple Template c'tor. It takes the mode | ||
205 | * this helper should operate in and the parent object. | ||
206 | * This helper will be deleted when the parent gets deleted | ||
207 | * or you delete it yourself. | ||
208 | * | ||
209 | * @param mode The mode this dialog should be in | ||
210 | * @param parent The parent QObject of this helper. | ||
211 | */ | ||
212 | template<class Dialog, class Record, typename Id> | ||
213 | OModalHelper<Dialog, Record, Id>::OModalHelper( enum Mode mode, QObject* parent ) { | ||
214 | m_disabled = false; | ||
215 | m_mode = mode; | ||
216 | m_signal = new OModalHelperSignal( this, parent ); | ||
217 | m_controler = new OModalHelperControler( this, m_signal ); | ||
218 | } | ||
219 | |||
220 | |||
221 | /** | ||
222 | * This functions looks for your record and sees if it is | ||
223 | * handled with this helper. Note that done records | ||
224 | * will not be returned. | ||
225 | * | ||
226 | * @return true if the record is currenlty edited otherwise false | ||
227 | * | ||
228 | * @param Id The id which might be handled | ||
229 | */ | ||
230 | template<class Dialog, class Record, typename Id> | ||
231 | bool OModalHelper<Dialog, Record, Id>::handles( Id id )const { | ||
232 | if ( m_transactions.isEmpty() ) | ||
233 | return false; | ||
234 | |||
235 | TransactionMap::ConstIterator it = m_transactions.begin(); | ||
236 | for ( ; it != m_transactions.end(); ++it ) | ||
237 | if ( it.data() == id ) | ||
238 | return true; | ||
239 | |||
240 | return false; | ||
241 | } | ||
242 | |||
243 | |||
244 | /** | ||
245 | * just like handles( Id ) but returns the TransactionId | ||
246 | */ | ||
247 | template<class Dialog, class Record, typename Id> | ||
248 | TransactionID OModalHelper<Dialog, Record, Id>::transactionID( Id id)const { | ||
249 | if ( m_transactions.isEmpty() || !m_ids.contains( id ) ) | ||
250 | return 0; | ||
251 | |||
252 | TransactionMap::ConstIterator it = m_transactions.begin(); | ||
253 | for ( ; it != m_transactions.end(); ++it ) | ||
254 | if ( it.data() == id ) | ||
255 | return it.key(); | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * If you're requested to flush your data and you do not want | ||
262 | * to call cancel with this method you can disable and enabled | ||
263 | * all dialogs. | ||
264 | * The state gets saved so if you want to handle a new record the dialog | ||
265 | * will be disabled as well. | ||
266 | * | ||
267 | * @param sus If true setDisabled(TRUE) will be called otherwise FALSE | ||
268 | */ | ||
269 | template<class Dialog, class Record, typename Id> | ||
270 | void OModalHelper<Dialog, Record, Id>::suspend(bool sus) { | ||
271 | m_disabled = sus; | ||
272 | if (m_mode == New ) | ||
273 | for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it ) | ||
274 | it.key()->setDisabled( sus ); | ||
275 | else if (m_dialog ) | ||
276 | queuedDialog()->setDisabled( sus ); | ||
277 | } | ||
278 | |||
279 | /** | ||
280 | * Cancel will cancel all current operations and clear the list | ||
281 | * of done operations as well. | ||
282 | * This also clears all done operations you did not popped | ||
283 | */ | ||
284 | template<class Dialog, class Record, typename Id> | ||
285 | void OModalHelper<Dialog, Record, Id>::cancel() { | ||
286 | m_ids.clear(); | ||
287 | m_doneIds.clear(); | ||
288 | m_done.clear(); | ||
289 | m_transactions.clear(); | ||
290 | |||
291 | /* we also need to remove the QDialogs */ | ||
292 | /* and hide the queue dialog if present */ | ||
293 | if (m_mode == New && !m_editing.isEmpty() ) { | ||
294 | for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it ) | ||
295 | delete it.key(); | ||
296 | |||
297 | m_editing.clear(); | ||
298 | }else if (m_dialog ) | ||
299 | queuedDialog()->setRecord( 0, 0 ); | ||
300 | |||
301 | m_controler->setTransactionID( 0 ); | ||
302 | } | ||
303 | |||
304 | |||
305 | /** | ||
306 | * This cancels editing of the record behind the Transaction Number | ||
307 | * Note that if editing is already done it will also be removed from this list | ||
308 | */ | ||
309 | template<class Dialog, class Record, typename Id> | ||
310 | void OModalHelper::cancel( TransactionID tid ) { | ||
311 | /* wrong tid */ | ||
312 | if (!m_transactions.contains( tid ) && !m_done.contains( tid) ) | ||
313 | return; | ||
314 | |||
315 | if (m_mode == New ) | ||
316 | /* reverse map eek */ | ||
317 | for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it ) | ||
318 | if ( it.data() == tid ) { | ||
319 | it.key()->hide(); | ||
320 | delete it.key(); | ||
321 | it = m_editing.remove( it ); | ||
322 | break; | ||
323 | } | ||
324 | |||
325 | /* now remove from the various maps done and currently editing map*/ | ||
326 | if (m_transactions.contains( tid ) ) | ||
327 | m_ids.remove( m_transactions[tid] ); | ||
328 | if (m_done.contains( tid ) ) | ||
329 | m_doneIds.remove( m_done[tid ] ); | ||
330 | m_done.remove( tid ); | ||
331 | m_transactions.remove( tid ); | ||
332 | |||
333 | next( 0 ); | ||
334 | } | ||
335 | |||
336 | /** | ||
337 | * Connect to the done Signal. SIGNAL( done(int, TransactionID ) ) | ||
338 | * This signal gets emitted whenever a Record was accepted or rejected | ||
339 | * | ||
340 | * @param rec The object where the slot belongs to | ||
341 | * @param slot The slot which should be called. See the needed parameter above | ||
342 | */ | ||
343 | template<class Dialog, class Record, typename Id> | ||
344 | void OModalHelper<Dialog, Record, Id>::connectDone( QObject* rec, const char* slot ) { | ||
345 | QObject::connect(m_signal, SIGNAL(done(int, TransactionID) ), | ||
346 | rec, slot ); | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * Connect to the accepted Signal. SIGNAL( accepted(TransactionID ) ) | ||
351 | * This signal gets emitted whenever a Record was accepted | ||
352 | * | ||
353 | * @param rec The object where the slot belongs to | ||
354 | * @param slot The slot which should be called. See the needed parameter above | ||
355 | */ | ||
356 | template<class Dialog, class Record, typename Id> | ||
357 | void OModalHelper<Dialog, Record, Id>::connectAccepted( QObject* rec, const char* slot ) { | ||
358 | QObject::connect(m_signal, SIGNAL(accepted(TransactionID) ), | ||
359 | rec, slot ); | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * Same as the accepted method but this one gets emitted if the dialog | ||
364 | * got rejected. | ||
365 | * SIGNAL( rejected(TransactionID) ) | ||
366 | * | ||
367 | * @param rec The QObject of the slot | ||
368 | * @param slot The slot make sure the signature is correct | ||
369 | */ | ||
370 | template<class Dialog, class Record, typename Id> | ||
371 | void OModalHelper<Dialog, Record, Id>::connectRejected( QObject* rec, const char* slot ) { | ||
372 | QObject::connect(m_signal, SIGNAL(rejected(TransactionID) ), | ||
373 | rec, slot ); | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * Tell the helper to handle a record. If the record is currently handled | ||
378 | * it will be made active. | ||
379 | * Already handled record which are waiting getting popped are not taken into account | ||
380 | * Otherwise this helpers make the record editable. | ||
381 | * The record supplied needs to have a valid copy operator and constructor. | ||
382 | * In the case where the record is already present the parameter gets discarded. | ||
383 | * If you want the new record to be taken you need to cancel the Transaction first | ||
384 | * | ||
385 | * @param id The Identification of the Record. For PIM it would uid() | ||
386 | * @param rec The record we want to be edited | ||
387 | * | ||
388 | * @returns This functions returns the TransactionId assigned to the record | ||
389 | * | ||
390 | */ | ||
391 | template<class Dialog, class Record, typename Id> | ||
392 | TransactionID OModalHelper<Dialog, Record, Id>::handle( Id id, const Record& rec ) { | ||
393 | static TransactionID t_id = 0; | ||
394 | /* | ||
395 | *this method consists out of two parts divided each into New and Queued Mode. | ||
396 | * Either we have the dialog already, in this case we need to highlight the widget | ||
397 | * Or we need to add it. | ||
398 | */ | ||
399 | TransactionID tid = 0; | ||
400 | /* we already have the record lets see if it was done or not */ | ||
401 | if ( !(tid = transactionID( id ) ) ) { | ||
402 | if (m_mode == New ) { | ||
403 | /* lets find the dialog and show it need to reverse map*/ | ||
404 | for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it ) | ||
405 | if ( it.data() == tid ) | ||
406 | it.key()->show(); | ||
407 | }else if (m_controler->transactionID() != tid ) { | ||
408 | int po = pos( tid ); | ||
409 | m_controler->setTransactionID( tid ); | ||
410 | static_cast<Dialog*>( queuedDialog()->centerDialog() )->setRecord( m_ids[ m_transactions[tid] ] ); | ||
411 | queuedDialog()->setRecord( po, m_transactions.count() ); | ||
412 | } | ||
413 | }else { | ||
414 | tid = ++t_id; | ||
415 | m_transactions.insert( tid, id ); | ||
416 | m_ids.insert( id, rec ); | ||
417 | |||
418 | if (m_mode == New ) | ||
419 | m_editing.insert( newDialogRecord( rec ), tid ); | ||
420 | else{ | ||
421 | m_controler->setTransactionID( tid ); | ||
422 | static_cast<Dialog*>( queuedDialog()->centerDialog() )->setRecord( rec ); | ||
423 | queuedDialog()->setRecord( m_transactions.count(), m_transactions.count() ); | ||
424 | } | ||
425 | } | ||
426 | return tid; | ||
427 | } | ||
428 | |||
429 | /** | ||
430 | * The goal of this helper is to help you to create non blocking | ||
431 | * GUIs. In the example of the todolist you can have the edit dialog | ||
432 | * but still change the priority or completion inline even if you currently | ||
433 | * edit the record. | ||
434 | * Your Dialog needs to have a Method setData(int,const QVariant& ) which will be called | ||
435 | * in these cases. | ||
436 | * If you edit anything while a record is edited call this function to merge the | ||
437 | * change in. Note if the record is not handled here we will ignore the request | ||
438 | * | ||
439 | */ | ||
440 | template<class Dialog, class Record, typename Id> | ||
441 | void OModalHelper<Dialog, Record, Id>::edited( Id id, int what, const QVariant& data ) { | ||
442 | int tid; | ||
443 | if (!( tid = transactionID( id ) ) ) | ||
444 | return; | ||
445 | |||
446 | if (m_mode == New ) { | ||
447 | for (DialogMap::Iterator it= m_editing.begin(); it != m_editing.end(); ++it ) | ||
448 | if ( it.data() == tid ) | ||
449 | it.key()->setData( what, data ); | ||
450 | }else{ | ||
451 | int po = pos( tid ); | ||
452 | Dialog* dia = static_cast<Dialog*>( queuedDialog()->centerDialog() ); | ||
453 | dia->setRecord( m_ids[id] ); | ||
454 | dia->setData( what, data ); | ||
455 | queuedDialog()->setRecord( pos, m_transactions.count() ); | ||
456 | } | ||
457 | } | ||
458 | |||
459 | /** | ||
460 | * This functions either returns the unedited record the done record | ||
461 | * or a new empty Record using Record(). | ||
462 | * If a done record is retrieved all traces are removed inside this class. This | ||
463 | * is what was called popping a record. This means when you call this function | ||
464 | * with the same TransactionID an Empty record is retrieved. | ||
465 | * | ||
466 | */ | ||
467 | template<class Dialog, class Record, typename Id> | ||
468 | Record OModalHelper<Dialog, Record, Id>::record( TransactionID tid)const { | ||
469 | if (m_transactions.contains( tid ) ) | ||
470 | return m_ids[ m_transactions[tid] ]; | ||
471 | else if (m_done.contains( tid ) ) { | ||
472 | Record rec = m_doneIds[ m_done[ tid] ]; | ||
473 | m_doneIds.remove( m_done[ tid ] ); | ||
474 | m_done.remove( tid ); | ||
475 | return rec; | ||
476 | }else | ||
477 | return Record(); | ||
478 | } | ||
479 | |||
480 | /** | ||
481 | * Returns all done Records and removes all references to them internally. A 2nd call to this will | ||
482 | * only contain done record that where edited past the point | ||
483 | */ | ||
484 | template<class Dialog, class Record, typename Id> | ||
485 | OModalHelper<Dialog,Record,Id>::RecordList OModalHelper<Dialog, Record, Id>::recordsDone()const { | ||
486 | RecordList list; | ||
487 | |||
488 | for (IdMap::ConstIterator it = m_doneIds.begin(); it != m_doneIds.end(); ++it ) | ||
489 | list.append( it.data() ); | ||
490 | |||
491 | /* clean up */ | ||
492 | m_done.clear(); | ||
493 | m_doneIds.clear(); | ||
494 | |||
495 | return list; | ||
496 | } | ||
497 | |||
498 | |||
499 | /** | ||
500 | * @internal | ||
501 | */ | ||
502 | template<class Dialog, class Record, typename Id> | ||
503 | void OModalHelper<Dialog, Record, Id>::done( int status, TransactionID tid) { | ||
504 | /* If we're in New mode the transaction Id does not count */ | ||
505 | Record rec; | ||
506 | |||
507 | if (m_mode == New ) { | ||
508 | Dialog *dia = static_cast<Dialog*>( m_controler->dialog() ); | ||
509 | m_controler->setTransactionID( 0 ); // set the internal dialog to 0l again | ||
510 | tid = m_editing[ dia ]; | ||
511 | m_editing.remove( dia ); | ||
512 | rec = dia->record(); | ||
513 | delete dia; | ||
514 | }else | ||
515 | rec = queuedDialog()->record(); | ||
516 | |||
517 | Id id = m_transactions[ tid ]; | ||
518 | if (result == QDialog::Accept ) { | ||
519 | m_doneIds.insert( is, rec ); | ||
520 | m_done.insert( tid, id ); | ||
521 | } | ||
522 | |||
523 | m_transactions.remove( tid ); | ||
524 | m_ids.remove( id ); | ||
525 | |||
526 | |||
527 | if (status == QDialog::Accept ) | ||
528 | emit m_signal->accepted( tid ); | ||
529 | else | ||
530 | emit m_signal->rejected( tid ); | ||
531 | |||
532 | emit m_signal->done( result, tid ); | ||
533 | |||
534 | next( 0 ); | ||
535 | } | ||
536 | |||
537 | /** | ||
538 | * @internal | ||
539 | */ | ||
540 | template<class Dialog, class Record, typename Id> | ||
541 | void OModalHelper<Dialog, Record, Id>::next( TransactionID tid) { | ||
542 | if (m_mode == New ) | ||
543 | return; | ||
544 | |||
545 | if (! (m_transactions.count() ) ) { | ||
546 | m_controler->setTransactionID( 0 ); | ||
547 | queuedDialog()->setRecord( 0, 0 ); | ||
548 | return; | ||
549 | } | ||
550 | |||
551 | int next; | ||
552 | Record rec; | ||
553 | |||
554 | /* save the maybe edited record before switching */ | ||
555 | Dialog *dia = static_cast<Dialog*>( queuedDialog()->centerDialog() ); | ||
556 | rec = dia->record(); | ||
557 | m_ids.replace( m_transactions[tid], rec ); | ||
558 | |||
559 | rec = nextRecord( tid, next ); | ||
560 | queuedDialog()->setRecord( next, m_transactions.count() ); | ||
561 | dia->setRecord( rec ); | ||
562 | |||
563 | m_controler->setTransactionID( tid ); // was changed during the next call | ||
564 | } | ||
565 | |||
566 | /** | ||
567 | * @internal | ||
568 | */ | ||
569 | /* | ||
570 | * code duplication should create a template fcuntion | ||
571 | * which takes a pointer to a function ( next, prev ) function | ||
572 | */ | ||
573 | template<class Dialog, class Record, typename Id> | ||
574 | void OModalHelper<Dialog, Record, Id>::prev( TransactionID tid ) { | ||
575 | if (m_mode == New ) | ||
576 | return; | ||
577 | |||
578 | if (! (m_transactions.count()) ) { | ||
579 | m_controler->setTransactionID( 0 ); | ||
580 | queuedDialog()->setRecord( 0, 0 ); | ||
581 | return; | ||
582 | } | ||
583 | |||
584 | int prev; | ||
585 | Record rec; | ||
586 | |||
587 | /* save the maybe edited record before switching */ | ||
588 | Dialog *dia = static_cast<Dialog*>( queuedDialog()->centerDialog() ); | ||
589 | rec = dia->record(); | ||
590 | m_ids.replace( m_transactions[tid], rec ); | ||
591 | |||
592 | rec = prevRecord( tid, prev ); | ||
593 | queuedDialog()->setRecord( prev, m_transactions.count() ); | ||
594 | dia->setRecord( rec ); | ||
595 | |||
596 | m_controler->setTransactionID( tid ); // was changed during the next call | ||
597 | } | ||
598 | |||
599 | /** | ||
600 | * @internal | ||
601 | */ | ||
602 | template<class Dialog, class Record, typename Id> | ||
603 | Record OModalHelper<Dialog, Record, Id>::nextRecord( TransactionID &tid, int &po ) { | ||
604 | /* if tid is == 0 we will take the first one */ | ||
605 | /* pos starts at 1 here */ | ||
606 | /* we know we're only called if there are records */ | ||
607 | Record rec; | ||
608 | TransactionMap::Iterator it; | ||
609 | if (!tid ) { | ||
610 | po = 1; | ||
611 | TransactionMap::Iterator it = m_transactions.begin(); | ||
612 | }else{ | ||
613 | po = pos( tid ); | ||
614 | /* if it is the last take the first as next */ | ||
615 | if ( po == m_transactions.count() ) { | ||
616 | po = 1; | ||
617 | it = m_transactions.begin(); | ||
618 | }else { | ||
619 | /* we know we're not the last and there is one after us */ | ||
620 | it = m_transactions.find( tid ); | ||
621 | ++it; ++po; | ||
622 | } | ||
623 | } | ||
624 | |||
625 | tid = it.key(); | ||
626 | rec = m_ids[ tid ]; | ||
627 | return rec; | ||
628 | } | ||
629 | |||
630 | /** | ||
631 | * @internal | ||
632 | */ | ||
633 | template<class Dialog, class Record, typename Id> | ||
634 | Record OModalHelper<Dialog, Record, Id>::prevRecord( TransactionID& tid, int& pos ) { | ||
635 | /* if tid is == 0 we will take the first one */ | ||
636 | /* pos starts at 1 here */ | ||
637 | /* we know we're only called if there are records */ | ||
638 | Record rec; | ||
639 | TransactionMap::Iterator it; | ||
640 | if (!tid ) { | ||
641 | po = 1; | ||
642 | TransactionMap::Iterator it = m_transactions.begin(); | ||
643 | }else{ | ||
644 | po = pos( tid ); | ||
645 | /* if it is the last take the first as next */ | ||
646 | if ( po == 1 ) { | ||
647 | po = m_transactions.count(); | ||
648 | it = m_transactions.end(); | ||
649 | --it; | ||
650 | }else { | ||
651 | /* we know we're not the first and there is one before us */ | ||
652 | it = m_transactions.find( tid ); | ||
653 | --it; --po; | ||
654 | } | ||
655 | } | ||
656 | |||
657 | tid = it.key(); | ||
658 | rec = m_ids[ tid ]; | ||
659 | return rec; | ||
660 | } | ||
661 | |||
662 | /** | ||
663 | * @internal | ||
664 | */ | ||
665 | template<class Dialog, class Record, typename Id> | ||
666 | int OModalHelper<Dialog, Record, Id>::pos( TransactionID id)const { | ||
667 | int i = 1; | ||
668 | for ( TransactionMap::ConstIterator it = m_transactions.begin(); it != m_transactions.end(); ++it, i++ ) | ||
669 | if ( it.key() == id ) | ||
670 | return i; | ||
671 | |||
672 | |||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | /** | ||
677 | * @internal | ||
678 | */ | ||
679 | template<class Dialog, class Record, typename Id> | ||
680 | Dialog* OModalHelper<Dialog, Record, Id>::newDialogRecord( const Record& rec ) { | ||
681 | Dialog* dia = new Dialog; | ||
682 | dia->setRecord( rec ); | ||
683 | dia->setDisabled( m_disabled ); | ||
684 | |||
685 | QObject::connect(dia, SIGNAL(done(int) ), | ||
686 | m_controler, SLOT(done(int) ) ); | ||
687 | |||
688 | /* FIXME big screen QPEApplication needs fixed*/ | ||
689 | dia->show(); | ||
690 | } | ||
691 | |||
692 | template<class Record, class Dialog, typename Id> | ||
693 | OModalHelperDialog* OModalHelper<Record, Dialog, Id>::queuedDialog()const{ | ||
694 | if (!m_dialog ) { | ||
695 | m_dialog = new OModalHelperDialog; | ||
696 | m_dialog->setEnabled( m_disabled ); | ||
697 | |||
698 | QObject::connect(m_dialog, SIGNAL(done(int) ), | ||
699 | m_controler, SLOT(done(int) ) ); | ||
700 | QObject::connect(m_dialog, SIGNAL(next() ), | ||
701 | m_controler, SLOT(next() ) ); | ||
702 | QObject::connect(m_dialog, SIGNAL(prev() ), | ||
703 | m_controler, SLOT(prev() ) ); | ||
704 | } | ||
705 | return m_dialog; | ||
706 | } | ||
707 | |||
708 | #endif | ||