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