summaryrefslogtreecommitdiff
path: root/libopie/orecurrancewidget.cpp
authorzecke <zecke>2002-10-20 12:15:51 (UTC)
committer zecke <zecke>2002-10-20 12:15:51 (UTC)
commit82689364fd558ccd28253961204e6b3eb9e32b03 (patch) (unidiff)
treeaec5a649346194aa76aaadd9c7418b700ac4d3d3 /libopie/orecurrancewidget.cpp
parent7948b5910a098d05f4cc7d0fb14b0f216bf41358 (diff)
downloadopie-82689364fd558ccd28253961204e6b3eb9e32b03.zip
opie-82689364fd558ccd28253961204e6b3eb9e32b03.tar.gz
opie-82689364fd558ccd28253961204e6b3eb9e32b03.tar.bz2
Added ORecur which is a base class for Recurrance extracted from TT Event class
and a widget where you can set the Recurrance This will be used at least in Todolist and Datebook and in the common classes of OTodo and OEvent Fixed the SQL in multiple ways it's summary not description for example
Diffstat (limited to 'libopie/orecurrancewidget.cpp') (more/less context) (show whitespace changes)
-rw-r--r--libopie/orecurrancewidget.cpp556
1 files changed, 556 insertions, 0 deletions
diff --git a/libopie/orecurrancewidget.cpp b/libopie/orecurrancewidget.cpp
new file mode 100644
index 0000000..53cee65
--- a/dev/null
+++ b/libopie/orecurrancewidget.cpp
@@ -0,0 +1,556 @@
1#include <qapplication.h>
2#include <qlabel.h>
3#include <qpopupmenu.h>
4#include <qspinbox.h>
5
6#include <qpe/timestring.h>
7
8#include "orecurrancewidget.h"
9
10// Global Templates for use in setting up the repeat label...
11const QString strDayTemplate = QObject::tr("Every");
12const QString strYearTemplate = QObject::tr("%1 %2 every ");
13const QString strMonthDateTemplate = QObject::tr("The %1 every ");
14const QString strMonthDayTemplate = QObject::tr("The %1 %1 of every");
15const QString strWeekTemplate = QObject::tr("Every ");
16const QString dayLabel[] = { QObject::tr("Monday"),
17 QObject::tr("Tuesday"),
18 QObject::tr("Wednesday"),
19 QObject::tr("Thursday"),
20 QObject::tr("Friday"),
21 QObject::tr("Saturday"),
22 QObject::tr("Sunday") };
23
24
25 static QString numberPlacing( int x );// return the proper word format for
26 // x (1st, 2nd, etc)
27static int week( const QDate &dt ); // what week in the month is dt?
28
29
30ORecurranceWidget::ORecurranceWidget( bool startOnMonday,
31 const QDate& newStart,
32 QWidget* parent,
33 const char* name,
34 bool modal,
35 WFlags fl )
36 : ORecurranceBase( parent, name, modal, fl ),
37 start( newStart ),
38 currInterval( None ),
39 startWeekOnMonday( startOnMonday )
40{
41 init();
42 fraType->setButton( currInterval );
43 chkNoEnd->setChecked( TRUE );
44 setupNone();
45}
46ORecurranceWidget::ORecurranceWidget( bool startOnMonday,
47 const ORecur& rp, const QDate& startDate,
48 QWidget* parent, const char* name,
49 bool modal, WFlags fl)
50 : ORecurranceBase( parent, name, modal, fl ),
51 start( startDate ),
52 end( rp.endDate() ),
53 startWeekOnMonday( startOnMonday )
54{
55 // do some stuff with the repeat pattern
56 init();
57 switch ( rp.type() ) {
58 default:
59 case ORecur::NoRepeat:
60 currInterval = None;
61 setupNone();
62 break;
63 case ORecur::Daily:
64 currInterval = Day;
65 setupDaily();
66 break;
67 case ORecur::Weekly:
68 currInterval = Week;
69 setupWeekly();
70 int day, buttons;
71 for ( day = 0x01, buttons = 0; buttons < 7;
72 day = day << 1, buttons++ ) {
73 if ( rp.days() & day ) {
74 if ( startWeekOnMonday )
75 fraExtra->setButton( buttons );
76 else {
77 if ( buttons == 7 )
78 fraExtra->setButton( 0 );
79 else
80 fraExtra->setButton( buttons + 1 );
81 }
82 }
83 }
84 slotWeekLabel();
85 break;
86 case ORecur::MonthlyDay:
87 currInterval = Month;
88 setupMonthly();
89 fraExtra->setButton( 0 );
90 slotMonthLabel( 0 );
91 break;
92 case ORecur::MonthlyDate:
93 currInterval = Month;
94 setupMonthly();
95 fraExtra->setButton( 1 );
96 slotMonthLabel( 1 );
97 break;
98 case ORecur::Yearly:
99 currInterval = Year;
100 setupYearly();
101 break;
102 }
103 fraType->setButton( currInterval );
104 spinFreq->setValue( rp.frequency() );
105 if ( !rp.hasEndDate() ) {
106 cmdEnd->setText( tr("No End Date") );
107 chkNoEnd->setChecked( TRUE );
108 } else
109 cmdEnd->setText( TimeString::shortDate( end ) );
110}
111ORecurranceWidget::~ORecurranceWidget() {
112
113}
114ORecur ORecurranceWidget::recurrance()const {
115 QListIterator<QToolButton> it( listRTypeButtons );
116 QListIterator<QToolButton> itExtra( listExtra );
117 ORecur rpTmp;
118 int i;
119 for ( i = 0; *it; ++it, i++ ) {
120 if ( (*it)->isOn() ) {
121 switch ( i ) {
122 case None:
123 rpTmp.setType( ORecur::NoRepeat );
124 break;
125 case Day:
126 rpTmp.setType( ORecur::Daily );
127 break;
128 case Week:{
129 rpTmp.setType( ORecur::Weekly );
130 int day;
131 int day2 = 0;
132 for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
133 if ( (*itExtra)->isOn() ) {
134 if ( startWeekOnMonday )
135 day2 |= day;
136 else {
137 if ( day == 1 )
138 day2 |= Event::SUN;
139 else
140 day2 |= day >> 1;
141 }
142 }
143 }
144 rpTmp.setDays( day2 );
145 }
146 break;
147 case Month:
148 if ( cmdExtra1->isOn() )
149 rpTmp.setType( ORecur::MonthlyDay );
150 else if ( cmdExtra2->isOn() )
151 rpTmp.setType( ORecur::MonthlyDate );
152 // figure out the montly day...
153 rpTmp.setPosition( week( start ) );
154 break;
155 case Year:
156 rpTmp.setType( ORecur::Yearly );
157 break;
158 }
159 break; // no need to keep looking!
160 }
161 }
162 rpTmp.setFrequency(spinFreq->value() );
163 rpTmp.setHasEndDate( !chkNoEnd->isChecked() );
164 if ( rpTmp.hasEndDate() ) {
165 rpTmp.setEndDate( end );
166 }
167 // timestamp it...
168 rpTmp.setCreateTime( time( NULL ) );
169 return rpTmp;
170}
171QDate ORecurranceWidget::endDate()const {
172 return end;
173}
174void ORecurranceWidget::slotSetRType(int rtype) {
175 // now call the right function based on the type...
176 currInterval = static_cast<repeatButtons>(rtype);
177 switch ( currInterval ) {
178 case None:
179 setupNone();
180 break;
181 case Day:
182 setupDaily();
183 break;
184 case Week:
185 setupWeekly();
186 slotWeekLabel();
187 break;
188 case Month:
189 setupMonthly();
190 cmdExtra2->setOn( TRUE );
191 slotMonthLabel( 1 );
192 break;
193 case Year:
194 setupYearly();
195 break;
196 }
197}
198void ORecurranceWidget::endDateChanged(int y, int m, int d) {
199 end.setYMD( y, m, d );
200 if ( end < start )
201 end = start;
202 cmdEnd->setText( TimeString::shortDate( end ) );
203 repeatPicker->setDate( end.year(), end.month(), end.day() );
204}
205void ORecurranceWidget::slotNoEnd( bool unused) {
206 // if the item was toggled, then go ahead and set it to the maximum date
207 if ( unused ) {
208 end.setYMD( 3000, 12, 31 );
209 cmdEnd->setText( tr("No End Date") );
210 } else {
211 end = start;
212 cmdEnd->setText( TimeString::shortDate(end) );
213 }
214}
215void ORecurranceWidget::setupRepeatLabel( const QString& s) {
216 lblVar1->setText( s );
217}
218void ORecurranceWidget::setupRepeatLabel( int x) {
219 // change the spelling based on the value of x
220 QString strVar2;
221
222 if ( x > 1 )
223 lblVar1->show();
224 else
225 lblVar1->hide();
226
227 switch ( currInterval ) {
228 case None:
229 break;
230 case Day:
231 if ( x > 1 )
232 strVar2 = tr( "days" );
233 else
234 strVar2 = tr( "day" );
235 break;
236 case Week:
237 if ( x > 1 )
238 strVar2 = tr( "weeks" );
239 else
240 strVar2 = tr( "week" );
241 break;
242 case Month:
243 if ( x > 1 )
244 strVar2 = tr( "months" );
245 else
246 strVar2 = tr( "month" );
247 break;
248 case Year:
249 if ( x > 1 )
250 strVar2 = tr( "years" );
251 else
252 strVar2 = tr( "year" );
253 break;
254 }
255 if ( !strVar2.isNull() )
256 lblVar2->setText( strVar2 );
257}
258void ORecurranceWidget::slotWeekLabel() {
259 QString str;
260 QListIterator<QToolButton> it( listExtra );
261 unsigned int i;
262 unsigned int keepMe;
263 bool bNeedCarriage = FALSE;
264 // don't do something we'll regret!!!
265 if ( currInterval != Week )
266 return;
267
268 if ( startWeekOnMonday )
269 keepMe = start.dayOfWeek() - 1;
270 else
271 keepMe = start.dayOfWeek() % 7;
272
273 QStringList list;
274 for ( i = 0; *it; ++it, i++ ) {
275 // a crazy check, if you are repeating weekly, the current day
276 // must be selected!!!
277 if ( i == keepMe && !( (*it)->isOn() ) )
278 (*it)->setOn( TRUE );
279 if ( (*it)->isOn() ) {
280 if ( startWeekOnMonday )
281 list.append( dayLabel[i] );
282 else {
283 if ( i == 0 )
284 list.append( dayLabel[6] );
285 else
286 list.append( dayLabel[i - 1] );
287 }
288 }
289 }
290 QStringList::Iterator itStr;
291 for ( i = 0, itStr = list.begin(); itStr != list.end(); ++itStr, i++ ) {
292 if ( i == 3 )
293 bNeedCarriage = TRUE;
294 else
295 bNeedCarriage = FALSE;
296 if ( str.isNull() )
297 str = *itStr;
298 else if ( i == list.count() - 1 ) {
299 if ( i < 2 )
300 str += tr(" and ") + *itStr;
301 else {
302 if ( bNeedCarriage )
303 str += tr( ",\nand " ) + *itStr;
304 else
305 str += tr( ", and " ) + *itStr;
306 }
307 } else {
308 if ( bNeedCarriage )
309 str += ",\n" + *itStr;
310 else
311 str += ", " + *itStr;
312 }
313 }
314 str = str.prepend( "on " );
315 lblWeekVar->setText( str );
316}
317void ORecurranceWidget::slotMonthLabel(int type) {
318 QString str;
319 if ( currInterval != Month || type > 1 )
320 return;
321 if ( type == 1 )
322 str = strMonthDateTemplate.arg( numberPlacing(start.day()) );
323 else
324 str = strMonthDayTemplate.arg( numberPlacing(week(start)))
325 .arg( dayLabel[start.dayOfWeek() - 1] );
326 lblRepeat->setText( str );
327}
328void ORecurranceWidget::slotChangeStartOfWeek( bool onMonday ) {
329 startWeekOnMonday = onMonday;
330 // we need to make this unintrusive as possible...
331 int saveSpin = spinFreq->value();
332 char days = 0;
333 int day;
334 QListIterator<QToolButton> itExtra( listExtra );
335 for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
336 if ( (*itExtra)->isOn() ) {
337 if ( !startWeekOnMonday )
338 days |= day;
339 else {
340 if ( day == 1 )
341 days |= ORecur::SUN;
342 else
343 days |= day >> 1;
344 }
345 }
346 }
347 setupWeekly();
348 spinFreq->setValue( saveSpin );
349 int buttons;
350 for ( day = 0x01, buttons = 0; buttons < 7;
351 day = day << 1, buttons++ ) {
352 if ( days & day ) {
353 if ( startWeekOnMonday )
354 fraExtra->setButton( buttons );
355 else {
356 if ( buttons == 7 )
357 fraExtra->setButton( 0 );
358 else
359 fraExtra->setButton( buttons + 1 );
360 }
361 }
362 }
363 slotWeekLabel();
364}
365void ORecurranceWidget::setupNone() {
366 lblRepeat->setText( tr("No Repeat") );
367 lblVar1->hide();
368 lblVar2->hide();
369 hideExtras();
370 cmdEnd->hide();
371 lblFreq->hide();
372 lblEvery->hide();
373 lblFreq->hide();
374 spinFreq->hide();
375 lblEnd->hide();
376 lblWeekVar->hide();
377}
378void ORecurranceWidget::setupDaily() {
379 hideExtras();
380 lblWeekVar->hide();
381 spinFreq->setValue( 1 );
382 lblFreq->setText( tr("day(s)") );
383 lblVar2->show();
384 showRepeatStuff();
385 lblRepeat->setText( strDayTemplate );
386 setupRepeatLabel( 1 );
387}
388void ORecurranceWidget::setupWeekly() {
389// reshow the buttons...
390 fraExtra->setTitle( tr("Repeat On") );
391 fraExtra->setExclusive( FALSE );
392 fraExtra->show();
393 if ( startWeekOnMonday ) {
394 cmdExtra1->setText( tr("Mon") );
395 cmdExtra2->setText( tr("Tue") );
396 cmdExtra3->setText( tr("Wed") );
397 cmdExtra4->setText( tr("Thu") );
398 cmdExtra5->setText( tr("Fri") );
399 cmdExtra6->setText( tr("Sat") );
400 cmdExtra7->setText( tr("Sun") );
401 } else {
402 cmdExtra1->setText( tr("Sun") );
403 cmdExtra2->setText( tr("Mon") );
404 cmdExtra3->setText( tr("Tue") );
405 cmdExtra4->setText( tr("Wed") );
406 cmdExtra5->setText( tr("Thu") );
407 cmdExtra6->setText( tr("Fri") );
408 cmdExtra7->setText( tr("Sat") );
409 }
410 // I hope clustering these improve performance....
411 cmdExtra1->setOn( FALSE );
412 cmdExtra2->setOn( FALSE );
413 cmdExtra3->setOn( FALSE );
414 cmdExtra4->setOn( FALSE );
415 cmdExtra5->setOn( FALSE );
416 cmdExtra6->setOn( FALSE );
417 cmdExtra7->setOn( FALSE );
418
419 cmdExtra1->show();
420 cmdExtra2->show();
421 cmdExtra3->show();
422 cmdExtra4->show();
423 cmdExtra5->show();
424 cmdExtra6->show();
425 cmdExtra7->show();
426
427 lblWeekVar->show();
428 spinFreq->setValue( 1 );
429 // might as well set the day too...
430 if ( startWeekOnMonday ) {
431 fraExtra->setButton( start.dayOfWeek() - 1 );
432 } else {
433 fraExtra->setButton( start.dayOfWeek() % 7 );
434 }
435 lblFreq->setText( tr("week(s)") );
436 lblVar2->show();
437 showRepeatStuff();
438 setupRepeatLabel( 1 );
439}
440void ORecurranceWidget::setupMonthly() {
441 hideExtras();
442 lblWeekVar->hide();
443 fraExtra->setTitle( tr("Repeat By") );
444 fraExtra->setExclusive( TRUE );
445 fraExtra->show();
446 cmdExtra1->setText( tr("Day") );
447 cmdExtra1->show();
448 cmdExtra2->setText( tr("Date") );
449 cmdExtra2->show();
450 spinFreq->setValue( 1 );
451 lblFreq->setText( tr("month(s)") );
452 lblVar2->show();
453 showRepeatStuff();
454 setupRepeatLabel( 1 );
455}
456void ORecurranceWidget::setupYearly() {
457hideExtras();
458 lblWeekVar->hide();
459 spinFreq->setValue( 1 );
460 lblFreq->setText( tr("year(s)") );
461 lblFreq->show();
462 lblFreq->show();
463 showRepeatStuff();
464 lblVar2->show();
465 QString strEvery = strYearTemplate.arg( start.monthName(start.month()) ).arg( numberPlacing(start.day()) );
466 lblRepeat->setText( strEvery );
467 setupRepeatLabel( 1 );
468
469}
470void ORecurranceWidget::init() {
471 QPopupMenu *m1 = new QPopupMenu( this );
472 repeatPicker = new DateBookMonth( m1, 0, TRUE );
473 m1->insertItem( repeatPicker );
474 cmdEnd->setPopup( m1 );
475 cmdEnd->setPopupDelay( 0 );
476
477 QObject::connect( repeatPicker, SIGNAL(dateClicked(int, int, int)),
478 this, SLOT(endDateChanged(int, int, int)) );
479 QObject::connect( qApp, SIGNAL(weekChanged(bool)),
480 this, SLOT(slotChangeStartOfWeek(bool)) );
481
482 listRTypeButtons.setAutoDelete( TRUE );
483 listRTypeButtons.append( cmdNone );
484 listRTypeButtons.append( cmdDay );
485 listRTypeButtons.append( cmdWeek );
486 listRTypeButtons.append( cmdMonth );
487 listRTypeButtons.append( cmdYear );
488
489 listExtra.setAutoDelete( TRUE );
490 listExtra.append( cmdExtra1 );
491 listExtra.append( cmdExtra2 );
492 listExtra.append( cmdExtra3 );
493 listExtra.append( cmdExtra4 );
494 listExtra.append( cmdExtra5 );
495 listExtra.append( cmdExtra6 );
496 listExtra.append( cmdExtra7 );
497}
498void ORecurranceWidget::hideExtras() {
499 // hide the extra buttons...
500 fraExtra->hide();
501 chkNoEnd->hide();
502 QListIterator<QToolButton> it( listExtra );
503 for ( ; *it; ++it ) {
504 (*it)->hide();
505 (*it)->setOn( FALSE );
506 }
507}
508void ORecurranceWidget::showRepeatStuff() {
509 cmdEnd->show();
510 chkNoEnd->show();
511 lblFreq->show();
512 lblEvery->show();
513 lblFreq->show();
514 spinFreq->show();
515 lblEnd->show();
516 lblRepeat->setText( tr("Every") );
517}
518
519
520static int week( const QDate &start )
521{
522 // figure out the week...
523 int stop = start.day(),
524 sentinel = start.dayOfWeek(),
525 dayOfWeek = QDate( start.year(), start.month(), 1 ).dayOfWeek(),
526 week = 1,
527 i;
528 for ( i = 1; i < stop; i++ ) {
529 if ( dayOfWeek++ == sentinel )
530 week++;
531 if ( dayOfWeek > 7 )
532 dayOfWeek = 0;
533 }
534 return week;
535}
536
537static QString numberPlacing( int x )
538{
539 // I hope this works in other languages besides english...
540 QString str = QString::number( x );
541 switch ( x % 10 ) {
542 case 1:
543 str += QWidget::tr( "st" );
544 break;
545 case 2:
546 str += QWidget::tr( "nd" );
547 break;
548 case 3:
549 str += QWidget::tr( "rd" );
550 break;
551 default:
552 str += QWidget::tr( "th" );
553 break;
554 }
555 return str;
556}