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