-rw-r--r-- | libopie/big-screen/omodalhelper.cpp | 160 | ||||
-rw-r--r-- | libopie/big-screen/omodalhelper.h | 121 |
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 */ | ||
38 | OModalHelperSignal::OModalHelperSignal( OModalHelperBase* base, QObject* parent ) | ||
39 | : QObject( parent, "OModal Helper Signal" ), m_base( base ) { | ||
40 | } | ||
41 | |||
42 | OModalHelperSignal::~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 | */ | ||
53 | OModalHelperControler::OModalHelperControler( OModalHelperBase* base, QObject* parent ) | ||
54 | : QObject(parent, "OModal Helper Controler" ), m_base( base ), m_dia( 0 ), m_id( -1 ) | ||
55 | { | ||
56 | } | ||
57 | |||
58 | TransactionID OModalHelperControler::transactionID()const { | ||
59 | return m_id; | ||
60 | } | ||
61 | |||
62 | void OModalHelperControler::setTransactionID( TransactionID id ) { | ||
63 | m_dia = 0; | ||
64 | m_id = id; | ||
65 | } | ||
66 | |||
67 | QDialog* 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 | */ | ||
75 | void 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 | |||
82 | void OModalHelperControler::next() { | ||
83 | m_base->next( m_id ); | ||
84 | } | ||
85 | |||
86 | void OModalHelperControler::prev() { | ||
87 | m_base->prev( m_id ); | ||
88 | } | ||
89 | |||
90 | /* The Queued Dialog inclusive QueuedBar */ | ||
91 | struct 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 | |||
100 | OModalQueueBar::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 | |||
111 | void OModalQueueBar::setText( const QString& str ) { | ||
112 | label->setText( str ); | ||
113 | } | ||
114 | |||
115 | |||
116 | OModalQueuedDialog::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 | |||
136 | OModalQueuedDialog::~OModalQueuedDialog() { | ||
137 | } | ||
138 | |||
139 | QDialog* OModalQueuedDialog::centerDialog()const { | ||
140 | return m_center; | ||
141 | } | ||
142 | |||
143 | void 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 | |||
151 | void 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 | |||
@@ -53,9 +53,12 @@ struct OModalHelperBase { | |||
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 |
@@ -78,8 +81,9 @@ public: | |||
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 | ||
@@ -93,11 +97,11 @@ public: | |||
93 | 97 | ||
94 | Record record( TransactionID )const; | 98 | Record record( TransactionID )const; |
95 | RecordList done()const; | 99 | RecordList done()const; |
96 | private: | 100 | private: |
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 | ||
@@ -106,8 +110,9 @@ private: | |||
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 |
@@ -132,8 +137,9 @@ private: | |||
132 | class OModalHelperSignal : public QObject { | 137 | class OModalHelperSignal : public QObject { |
133 | Q_OBJECT | 138 | Q_OBJECT |
134 | public: | 139 | public: |
135 | OModalHelperSignal(OModalHelperBase* base, QObject* parent); | 140 | OModalHelperSignal(OModalHelperBase* base, QObject* parent); |
141 | ~OModalHelperSignal(); | ||
136 | 142 | ||
137 | signals: | 143 | signals: |
138 | done( int status, TransactionID transaction ); | 144 | done( int status, TransactionID transaction ); |
139 | accepted( TransactionID transaction ); | 145 | accepted( TransactionID transaction ); |
@@ -152,28 +158,36 @@ public: | |||
152 | void setTransactionID( TransactionID id ); | 158 | void setTransactionID( TransactionID id ); |
153 | QDialog* dialog()const; | 159 | QDialog* dialog()const; |
154 | 160 | ||
155 | public slots: | 161 | public slots: |
156 | virtual done(int result ); | 162 | virtual void done(int result ); |
163 | virtual void next(); | ||
164 | virtual void prev(); | ||
157 | private: | 165 | private: |
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 | ||
163 | class OModalQueueBar; | 171 | struct OModalQueueBar; |
164 | class OModalQueuedDialog : public QDialog { | 172 | class OModalQueuedDialog : public QDialog { |
165 | Q_OBJECT | 173 | Q_OBJECT |
166 | public: | 174 | public: |
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 | |||
183 | signals: | ||
184 | void next(); | ||
185 | void prev(); | ||
186 | |||
174 | private: | 187 | private: |
175 | OModalQueueBar *m_bar; | 188 | OModalQueueBar *m_bar; |
189 | QDialog *m_center; | ||
176 | }; | 190 | }; |
177 | 191 | ||
178 | 192 | ||
179 | /* | 193 | /* |
@@ -193,16 +207,16 @@ template<class Dialog, class Record, typename Id> | |||
193 | OModalHelper<Dialog, Record, Id>::OModalHelper( enum Mode mode, QObject* parent ) { | 207 | OModalHelper<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 |
@@ -219,15 +233,34 @@ bool OModalHelper<Dialog, Record, Id>::handles( Id id )const { | |||
219 | 233 | ||
220 | return false; | 234 | return false; |
221 | } | 235 | } |
222 | 236 | ||
237 | |||
238 | /** | ||
239 | * just like handles( Id ) but returns the TransactionId | ||
240 | */ | ||
241 | template<class Dialog, class Record, typename Id> | ||
242 | TransactionID 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 | */ |
227 | template<class Dialog, class Record, typename Id> | 259 | template<class Dialog, class Record, typename Id> |
228 | void OModalHelper<Dialog, Record, Id>::cancel() { | 260 | void 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 */ |
@@ -238,9 +271,9 @@ void OModalHelper<Dialog, Record, Id>::cancel() { | |||
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 | /** |
@@ -277,12 +310,17 @@ void OModalHelper::cancel( TransactionID tid ) { | |||
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 | } |
@@ -300,21 +338,68 @@ void OModalHelper<Dialog, Record, Id>::connectDone( QObject* rec, const char* sl | |||
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 | */ |
310 | template<class Dialog, class Record, typename Id> | 348 | template<class Dialog, class Record, typename Id> |
311 | void OModalHelper<Dialog, Record, Id>::( QObject* rec, const char* slot ) { | 349 | void 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 | */ | ||
362 | template<class Dialog, class Record, typename Id> | ||
363 | void 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 | */ | ||
316 | template<class Dialog, class Record, typename Id> | 383 | template<class Dialog, class Record, typename Id> |
317 | void OModalHelper<Dialog, Record, Id>::( QObject* rec, const char* slot ) { | 384 | TransactionID 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 |