-rw-r--r-- | libopie/big-screen/omodalhelper.cpp | 7 | ||||
-rw-r--r-- | libopie/big-screen/omodalhelper.h | 377 |
2 files changed, 346 insertions, 38 deletions
diff --git a/libopie/big-screen/omodalhelper.cpp b/libopie/big-screen/omodalhelper.cpp index e3d1c70..c5a47b3 100644 --- a/libopie/big-screen/omodalhelper.cpp +++ b/libopie/big-screen/omodalhelper.cpp | |||
@@ -77,5 +77,5 @@ void OModalHelperControler::done( int result ) { | |||
77 | m_dia = static_cast<QDialog*>( sender() ); | 77 | m_dia = static_cast<QDialog*>( sender() ); |
78 | 78 | ||
79 | m_base->done( m_id ); | 79 | m_base->done( result, m_id ); |
80 | } | 80 | } |
81 | 81 | ||
@@ -156,4 +156,9 @@ void OModalQueuedDialog::setRecord( int record, int count ) { | |||
156 | show(); | 156 | show(); |
157 | 157 | ||
158 | if ( count > 1 ) | ||
159 | m_bar->show(); | ||
160 | else | ||
161 | m_bar->hide(); | ||
162 | |||
158 | m_bar->setText( tr("Editing record %1 out of %2", | 163 | 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 ) ); | 164 | "Shows the current edited record out of an array of records").arg( record ). arg( count ) ); |
diff --git a/libopie/big-screen/omodalhelper.h b/libopie/big-screen/omodalhelper.h index bc20d10..78a2ac9 100644 --- a/libopie/big-screen/omodalhelper.h +++ b/libopie/big-screen/omodalhelper.h | |||
@@ -34,4 +34,5 @@ | |||
34 | #include <qvaluelist.h> | 34 | #include <qvaluelist.h> |
35 | #include <qmap.h> | 35 | #include <qmap.h> |
36 | #include <qvariant.h> | ||
36 | 37 | ||
37 | typedef int TransactionID; | 38 | typedef int TransactionID; |
@@ -42,5 +43,5 @@ class QDialog; | |||
42 | 43 | ||
43 | struct OModalHelperBase { | 44 | struct OModalHelperBase { |
44 | virtual void done( TransactionID ) = 0; | 45 | virtual void done( int status, TransactionID ) = 0; |
45 | virtual void next( TransactionID ) = 0; | 46 | virtual void next( TransactionID ) = 0; |
46 | virtual void prev( TransactionID ) = 0; | 47 | virtual void prev( TransactionID ) = 0; |
@@ -85,4 +86,6 @@ public: | |||
85 | TransactionID transactionID( Id id)const; | 86 | TransactionID transactionID( Id id)const; |
86 | 87 | ||
88 | void suspend( bool = true ); | ||
89 | |||
87 | void cancel(); | 90 | void cancel(); |
88 | void cancel( TransactionID ); | 91 | void cancel( TransactionID ); |
@@ -94,15 +97,17 @@ public: | |||
94 | TransactionID handle( Id id, const Record& rec = Record() ); | 97 | TransactionID handle( Id id, const Record& rec = Record() ); |
95 | 98 | ||
96 | void edited( TransactionID, int what, const QString& data ); | 99 | void edited( Id, int what, const QVariant& data ); |
97 | 100 | ||
98 | Record record( TransactionID )const; | 101 | Record record( TransactionID )const; |
99 | RecordList done()const; | 102 | RecordList recordsDone()const; |
100 | private: | 103 | private: |
101 | virtual void done( TransactionID ); | 104 | virtual void done( int, TransactionID ); |
102 | virtual void next( TransactionID ); | 105 | virtual void next( TransactionID ); |
103 | virtual void prev( TransactionID ); | 106 | virtual void prev( TransactionID ); |
104 | 107 | ||
105 | Record nextRecord( TransactionID, int * )const; | 108 | Record nextRecord( TransactionID &, int & )const; |
106 | Record prevRecord( TransactionID, int * )const; | 109 | Record prevRecord( TransactionID &, int & )const; |
110 | int pos( TransactionID )const; | ||
111 | Dialog* newDialogRecord( const Record& ); | ||
107 | 112 | ||
108 | private: | 113 | private: |
@@ -117,4 +122,5 @@ private: | |||
117 | DialogMap m_editing; // only used for New Mode | 122 | DialogMap m_editing; // only used for New Mode |
118 | enum Mode m_mode; // the mode we're in | 123 | enum Mode m_mode; // the mode we're in |
124 | bool m_disabled :1; | ||
119 | }; | 125 | }; |
120 | 126 | ||
@@ -206,8 +212,8 @@ private: | |||
206 | template<class Dialog, class Record, typename Id> | 212 | template<class Dialog, class Record, typename Id> |
207 | OModalHelper<Dialog, Record, Id>::OModalHelper( enum Mode mode, QObject* parent ) { | 213 | OModalHelper<Dialog, Record, Id>::OModalHelper( enum Mode mode, QObject* parent ) { |
214 | m_disabled = false; | ||
208 | m_mode = mode; | 215 | m_mode = mode; |
209 | m_signal = new OModalHelperSignal( this, parent ); | 216 | m_signal = new OModalHelperSignal( this, parent ); |
210 | m_controler = new OModalHelperControler( this, m_signal ); | 217 | m_controler = new OModalHelperControler( this, m_signal ); |
211 | |||
212 | } | 218 | } |
213 | 219 | ||
@@ -241,13 +247,32 @@ bool OModalHelper<Dialog, Record, Id>::handles( Id id )const { | |||
241 | template<class Dialog, class Record, typename Id> | 247 | template<class Dialog, class Record, typename Id> |
242 | TransactionID OModalHelper<Dialog, Record, Id>::transactionID( Id id)const { | 248 | TransactionID OModalHelper<Dialog, Record, Id>::transactionID( Id id)const { |
243 | if ( m_transactions.isEmpty() ) | 249 | if ( m_transactions.isEmpty() || !m_ids.contains( id ) ) |
244 | return false; | 250 | return 0; |
245 | 251 | ||
246 | TransactionMap::ConstIterator it = m_transactions.begin(); | 252 | TransactionMap::ConstIterator it = m_transactions.begin(); |
247 | for ( ; it != m_transactions.end(); ++it ) | 253 | for ( ; it != m_transactions.end(); ++it ) |
248 | if ( it.data() == id ) | 254 | if ( it.data() == id ) |
249 | return true; | 255 | return it.key(); |
250 | 256 | ||
251 | return false; | 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 ); | ||
252 | } | 277 | } |
253 | 278 | ||
@@ -269,9 +294,10 @@ void OModalHelper<Dialog, Record, Id>::cancel() { | |||
269 | for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it ) | 294 | for (DialogMap::Iterator it = m_editing.begin(); it != m_editing.end(); ++it ) |
270 | delete it.key(); | 295 | delete it.key(); |
296 | |||
271 | m_editing.clear(); | 297 | m_editing.clear(); |
272 | }else if (m_dialog ) | 298 | }else if (m_dialog ) |
273 | queuedDialog()->setRecord( 0, 0 ); | 299 | queuedDialog()->setRecord( 0, 0 ); |
274 | 300 | ||
275 | m_controler->setTransactionID( -1 ); | 301 | m_controler->setTransactionID( 0 ); |
276 | } | 302 | } |
277 | 303 | ||
@@ -296,23 +322,5 @@ void OModalHelper::cancel( TransactionID tid ) { | |||
296 | break; | 322 | break; |
297 | } | 323 | } |
298 | else if ( m_transactions.contains( tid ) ) { | ||
299 | /* need to stop editing from the queue block */ | ||
300 | /* if we're currently editing actiavte the previous */ | ||
301 | #if 0 | ||
302 | if (tid == m_controler->transactionID() ) { | ||
303 | 324 | ||
304 | } | ||
305 | #endif | ||
306 | /* now either activate the previous again or hide */ | ||
307 | if (! m_transactions.count() -1 ) | ||
308 | queuedDialog()->setRecord( 0, 0 ); | ||
309 | else { | ||
310 | int pos; | ||
311 | Record rec = prevRecord( tid, &pos ); | ||
312 | static_cast<Dialog*>( queuedDialog()->centerDialog() )->setRecord( rec ); | ||
313 | queuedDialog()->setRecord( pos, m_transactions.count() ); | ||
314 | m_controler->setTransactionID( tid ); | ||
315 | } | ||
316 | } | ||
317 | /* now remove from the various maps done and currently editing map*/ | 325 | /* now remove from the various maps done and currently editing map*/ |
318 | if (m_transactions.contains( tid ) ) | 326 | if (m_transactions.contains( tid ) ) |
@@ -320,8 +328,8 @@ void OModalHelper::cancel( TransactionID tid ) { | |||
320 | if (m_done.contains( tid ) ) | 328 | if (m_done.contains( tid ) ) |
321 | m_doneIds.remove( m_done[tid ] ); | 329 | m_doneIds.remove( m_done[tid ] ); |
322 | |||
323 | |||
324 | m_done.remove( tid ); | 330 | m_done.remove( tid ); |
325 | m_transactions.remove( tid ); | 331 | m_transactions.remove( tid ); |
332 | |||
333 | next( 0 ); | ||
326 | } | 334 | } |
327 | 335 | ||
@@ -384,5 +392,4 @@ template<class Dialog, class Record, typename Id> | |||
384 | TransactionID OModalHelper<Dialog, Record, Id>::handle( Id id, const Record& rec ) { | 392 | TransactionID OModalHelper<Dialog, Record, Id>::handle( Id id, const Record& rec ) { |
385 | static TransactionID t_id = 0; | 393 | static TransactionID t_id = 0; |
386 | t_id++; | ||
387 | /* | 394 | /* |
388 | *this method consists out of two parts divided each into New and Queued Mode. | 395 | *this method consists out of two parts divided each into New and Queued Mode. |
@@ -392,13 +399,309 @@ TransactionID OModalHelper<Dialog, Record, Id>::handle( Id id, const Record& rec | |||
392 | TransactionID tid = 0; | 399 | TransactionID tid = 0; |
393 | /* we already have the record lets see if it was done or not */ | 400 | /* we already have the record lets see if it was done or not */ |
394 | if ( m_ids.contains( id ) ) { | 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 | } | ||
395 | 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 ); | ||
396 | } | 521 | } |
397 | 522 | ||
398 | /* fall through if the record is in the done list */ | 523 | m_transactions.remove( tid ); |
399 | tid = t_id; | 524 | m_ids.remove( id ); |
525 | |||
400 | 526 | ||
527 | if (status == QDialog::Accept ) | ||
528 | emit m_signal->accepted( tid ); | ||
529 | else | ||
530 | emit m_signal->rejected( tid ); | ||
401 | 531 | ||
402 | return; | 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; | ||
403 | } | 706 | } |
404 | 707 | ||