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