summaryrefslogtreecommitdiff
path: root/libopie/orecurrancewidget.cpp
Unidiff
Diffstat (limited to 'libopie/orecurrancewidget.cpp') (more/less context) (ignore 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}