Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

dateentryimpl.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003 
00004                              Copyright (C) Opie Team <opie-devel@handhelds.org>
00005               =.
00006             .=l.
00007            .>+-=
00008  _;:,     .>    :=|.         This program is free software; you can
00009 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00010 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00011 .="- .-=="i,     .._         License as published by the Free Software
00012  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00013      ._= =}       :          or (at your option) any later version.
00014     .%`+i>       _;_.
00015     .i_,=:_.      -<s.       This program is distributed in the hope that
00016      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00017     : ..    .:,     . . .    without even the implied warranty of
00018     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00019   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00020 ..}^=.=       =       ;      Library General Public License for more
00021 ++=   -.     .`     .:       details.
00022 :     =  ...= . :.=-
00023  -.   .:....=;==+<;          You should have received a copy of the GNU
00024   -_. . .   )=.  =           Library General Public License along with
00025     --        :-=`           this library; see the file COPYING.LIB.
00026                              If not, write to the Free Software Foundation,
00027                              Inc., 59 Temple Place - Suite 330,
00028                              Boston, MA 02111-1307, USA.
00029 */
00030 
00031 #include "namespace_hack.h"
00032 #include "dateentryimpl.h"
00033 #include "repeatentry.h"
00034 
00035 #include <opie2/odebug.h>
00036 #include <opie2/otimepicker.h>
00037 
00038 #include <qpe/qpeapplication.h>
00039 #include <qpe/categoryselect.h>
00040 #include <qpe/datebookmonth.h>
00041 #include <qpe/tzselect.h>
00042 
00043 #include <qlineedit.h>
00044 #include <qspinbox.h>
00045 
00046 #include "onoteedit.h"
00047 
00048 #include <stdlib.h>
00049 #include <stdio.h>
00050 
00051 /*
00052  *  Constructs a DateEntry which is a child of 'parent', with the
00053  *  name 'name' and widget flags set to 'f'
00054  *
00055  *  The dialog will by default be modeless, unless you set 'modal' to
00056  *  TRUE to construct a modal dialog.
00057  */
00058 
00059 DateEntry::DateEntry( bool startOnMonday, const QDateTime &start,
00060                       const QDateTime &end, bool whichClock, QWidget* parent,
00061                       const char* name )
00062     : DateEntryBase( parent, name ),
00063       ampm( whichClock ),
00064       startWeekOnMonday( startOnMonday ),
00065       m_showStart(true)
00066 {
00067     init();
00068     setDates(start,end);
00069     setFocusProxy(comboDescription);
00070 }
00071 
00072 bool DateEntry::eventFilter(QObject *obj, QEvent *ev )
00073 {
00074   if( ev->type() == QEvent::FocusIn ){
00075     if( obj == comboStart ){
00076       timePickerStart->setHour(startTime.hour());
00077       timePickerStart->setMinute(startTime.minute());
00078       TimePickerLabel->setText( tr("Start Time" ) );
00079       m_showStart= true;
00080     }else if( obj == comboEnd ){
00081       timePickerStart->setHour(endTime.hour());
00082       timePickerStart->setMinute(endTime.minute());
00083       TimePickerLabel->setText( tr("End Time") );
00084       m_showStart = false;
00085     }
00086   } else if( ev->type() == QEvent::FocusOut ){
00087 //    if( obj == comboEnd ){
00088 //      QString s;
00089 //      s.sprintf("%.2d:%.2d",endTime.hour(), endTime.minute());
00090 //      comboEnd->setText(s);
00091 //    }
00092 //    else if( obj == comboStart ){
00093 //      QString s;
00094 //      s.sprintf("%.2d:%.2d",startTime.hour(), startTime.minute());
00095 //      comboStart->setText(s);
00096 //    }
00097   }
00098 
00099   return false;
00100 }
00101 
00102 static void addOrPick( QComboBox* combo, const QString& t )
00103 {
00104     // Pick an  item if one excists
00105     for (int i=0; i<combo->count(); i++) {
00106         if ( combo->text(i) == t ) {
00107             combo->setCurrentItem(i);
00108             return;
00109         }
00110     }
00111 
00112     // Else add one
00113     combo->insertItem(t);
00114     combo->setCurrentItem(combo->count()-1);
00115 }
00116 
00117 DateEntry::DateEntry( bool startOnMonday, const Event &event, bool whichClock,
00118                       QWidget* parent,  const char* name )
00119     : DateEntryBase( parent, name ),
00120       ampm( whichClock ),
00121       startWeekOnMonday( startOnMonday ),
00122       m_showStart(true)
00123 
00124 {
00125     init();
00126     setDates(event.start(),event.end());
00127     comboCategory->setCategories( event.categories(), "Calendar", tr("Calendar") );
00128     if(!event.description().isEmpty())
00129         addOrPick( comboDescription, event.description() );
00130     if(!event.location().isEmpty())
00131         addOrPick( comboLocation, event.location() );
00132     checkAlarm->setChecked( event.hasAlarm() );
00133     checkAllDay->setChecked( event.type() == Event::AllDay );
00134     if(!event.notes().isEmpty()) noteStr=event.notes();
00135     else noteStr="";
00136     spinAlarm->setValue(event.alarmTime());
00137     if ( event.alarmSound() != Event::Silent )
00138         comboSound->setCurrentItem( 1 );
00139     if ( event.hasRepeat() ) {
00140         rp = event.repeatPattern();
00141         cmdRepeat->setText( tr("Repeat...") );
00142     }
00143     setRepeatLabel();
00144 }
00145 
00146 void DateEntry::setDates( const QDateTime& s, const QDateTime& e )
00147 {
00148     startDate = s.date();
00149     endDate = e.date();
00150     startTime = s.time();
00151     endTime = e.time();
00152 
00153     startDateChanged( s.date().year(), s.date().month(), s.date().day() );
00154     endDateChanged( e.date().year(), e.date().month(), e.date().day() );
00155 
00156     updateTimeEdit(true,true);
00157 }
00158 
00159 void DateEntry::updateTimeEdit(bool s, bool e) {
00160 
00161     // Comboboxes
00162     QString strStart, strEnd;
00163     int shour, ehour;
00164     if ( ampm ) {
00165         shour = startTime.hour();
00166         ehour = endTime.hour();
00167         if ( shour >= 12 ) {
00168             if ( shour > 12 )
00169                 shour -= 12;
00170             strStart.sprintf( "%d:%02d PM", shour, startTime.minute() );
00171         } else {
00172             if ( shour == 0 )
00173                 shour = 12;
00174             strStart.sprintf( "%d:%02d AM", shour, startTime.minute() );
00175         }
00176         if ( ehour == 24 && endTime.minute() == 0 ) {
00177             strEnd  = "11:59 PM"; // or "midnight"
00178         } else if ( ehour >= 12 ) {
00179             if ( ehour > 12 )
00180                 ehour -= 12;
00181             strEnd.sprintf( "%d:%02d PM", ehour, endTime.minute() );
00182         } else {
00183             if ( ehour == 0 )
00184                 ehour = 12;
00185             strEnd.sprintf( "%d:%02d AM", ehour, endTime.minute() );
00186         }
00187     } else {
00188         strStart.sprintf( "%02d:%02d", startTime.hour(), startTime.minute() );
00189         strEnd.sprintf( "%02d:%02d", endTime.hour(), endTime.minute() );
00190     }
00191 
00192     if (s) comboStart->setText(strStart);
00193     if (e) comboEnd->setText(strEnd);
00194 }
00195 
00196 void DateEntry::init()
00197 {
00198     comboDescription->setInsertionPolicy(QComboBox::AtCurrent);
00199     comboLocation->setInsertionPolicy(QComboBox::AtCurrent);
00200 
00201     initCombos();
00202     QPopupMenu *m1 = new QPopupMenu( this );
00203     startPicker = new DateBookMonth( m1, 0, TRUE );
00204     m1->insertItem( startPicker );
00205     buttonStart->setPopup( m1 );
00206     connect( startPicker, SIGNAL( dateClicked(int,int,int) ),
00207              this, SLOT( startDateChanged(int,int,int) ) );
00208 
00209     //Let start button change both start and end dates
00210     connect( startPicker, SIGNAL( dateClicked(int,int,int) ),
00211              this, SLOT( endDateChanged(int,int,int) ) );
00212     connect( qApp, SIGNAL( clockChanged(bool) ),
00213              this, SLOT( slotChangeClock(bool) ) );
00214     connect( qApp, SIGNAL(weekChanged(bool)),
00215              this, SLOT(slotChangeStartOfWeek(bool)) );
00216 
00217     connect( editNote, SIGNAL(clicked()),
00218              this, SLOT(slotEditNote()) );
00219 
00220     QPopupMenu *m2 = new QPopupMenu( this );
00221     endPicker = new DateBookMonth( m2, 0, TRUE );
00222     m2->insertItem( endPicker );
00223     buttonEnd->setPopup( m2 );
00224     connect( endPicker, SIGNAL( dateClicked(int,int,int) ),
00225              this, SLOT( endDateChanged(int,int,int) ) );
00226 
00227     connect(timePickerStart, SIGNAL( timeChanged(const QTime&) ),
00228             this, SLOT( startTimePicked(const QTime&) ));
00229     // install eventFilters
00230     comboEnd->installEventFilter( this );
00231     comboStart->installEventFilter( this );
00232 }
00233 
00234 /*
00235  *  Destroys the object and frees any allocated resources
00236  */
00237 DateEntry::~DateEntry()
00238 {
00239     // no need to delete child widgets, Qt does it all for us
00240         //cout << "Del: " << comboStart->currentText() << endl;
00241 }
00242 
00243 /*
00244  * public slot
00245  */
00246 
00247 void DateEntry::slotEditNote() {
00248   QString s;
00249   s = "<B>"+ TimeString::longDateString( startDate ) + "</B>";
00250 //  s.sprintf("<B>%d/%d</B> ", startDate.day(), startDate.month());
00251   NoteEntry noteDlg(s+comboDescription->currentText(), noteStr,
00252                     this,0,TRUE);
00253 
00254   if ( QPEApplication::execDialog( &noteDlg ) ) {
00255     noteStr=noteDlg.note->text();
00256   }
00257 
00258 }
00259 
00260 void DateEntry::endDateChanged( int y, int m, int d )
00261 {
00262     endDate.setYMD( y, m, d );
00263     if ( endDate < startDate ) {
00264         endDate = startDate;
00265     }
00266 
00267     buttonEnd->setText( TimeString::shortDate( endDate ) );
00268 
00269     endPicker->setDate( endDate.year(), endDate.month(), endDate.day() );
00270 }
00271 
00272 static QTime parseTime( const QString& s, bool ampm )
00273 {
00274     QTime tmpTime;
00275     QStringList l = QStringList::split( ':', s );
00276     int hour = l[0].toInt();
00277     if ( ampm ) {
00278         int i=0;
00279         while (i<int(l[1].length()) && l[1][i]>='0' && l[1][i]<='9')
00280             i++;
00281         QString digits = l[1].left(i);
00282         if ( l[1].contains( "PM", FALSE ) ) {
00283             if ( hour != 12 )
00284                 hour += 12;
00285         } else {
00286             if ( hour == 12 )
00287                 hour = 0;
00288         }
00289         l[1] = digits;
00290     }
00291     int minute = l[1].toInt();
00292     if ( minute > 59 )
00293         minute = 59;
00294     else if ( minute < 0 )
00295         minute = 0;
00296     if ( hour > 23 ) {
00297         hour = 23;
00298         minute = 59;
00299     } else if ( hour < 0 )
00300         hour = 0;
00301     tmpTime.setHMS( hour, minute, 0 );
00302     return tmpTime;
00303 }
00304 
00305 /*
00306  * public slot
00307  */
00308 void DateEntry::endTimeChanged( const QString &s )
00309 {
00310   endTimeChanged( parseTime(s,ampm) );
00311 }
00312 
00313 void DateEntry::endTimeChanged( const QTime &t ) {
00314     if ( endDate > startDate || t >= startTime ) {
00315         endTime = t;
00316     } else {
00317         endTime = startTime;
00318         //comboEnd->setCurrentItem( comboStart->currentItem() );
00319     }
00320     timePickerStart->setHour(endTime.hour());
00321     timePickerStart->setMinute(endTime.minute());
00322 }
00323 
00324 /*
00325  * public slot
00326  */
00327 void DateEntry::startDateChanged( int y, int m, int d )
00328 {
00329     QDate prev = startDate;
00330     startDate.setYMD( y, m, d );
00331     if ( rp.type == Event::Weekly &&
00332          startDate.dayOfWeek() != prev.dayOfWeek() ) {
00333         // if we change the start of a weekly repeating event
00334         // set the repeating day appropriately
00335         char mask = 1 << (prev.dayOfWeek()-1);
00336         rp.days &= (~mask);
00337         rp.days |= 1 << (startDate.dayOfWeek()-1);
00338     }
00339 
00340     buttonStart->setText( TimeString::shortDate( startDate ) );
00341 
00342     // our pickers must be reset...
00343     startPicker->setDate( y, m, d );
00344     endPicker->setDate( y, m, d );
00345 }
00346 
00347 /*
00348  * public slot
00349  */
00350 void DateEntry::startTimeEdited( const QString &s )
00351 {
00352     startTimeChanged(parseTime(s,ampm));
00353     updateTimeEdit(false,true);
00354     timePickerStart->setHour(startTime.hour());
00355     timePickerStart->setMinute(startTime.minute());
00356 }
00357 
00358 void DateEntry::startTimeChanged( const QTime &t )
00359 {
00360     int duration=startTime.secsTo(endTime);
00361     startTime = t;
00362     endTime=t.addSecs(duration);
00363 }
00364 void DateEntry::startTimePicked( const QTime &t ) {
00365   if(m_showStart ){
00366     startTimeChanged(t);
00367     updateTimeEdit(true,true);
00368   }else{
00369     endTimeChanged(t);
00370     updateTimeEdit(false, true );
00371   }
00372 }
00373 
00374 /*
00375  * public slot
00376  */
00377 void DateEntry::typeChanged( const QString &s )
00378 {
00379     bool b = s != "All Day";
00380     buttonStart->setEnabled( b );
00381     comboStart->setEnabled( b );
00382     comboEnd->setEnabled( b );
00383 }
00384 
00385 void DateEntry::slotRepeat()
00386 {
00387     // Work around for compiler Bug..
00388     RepeatEntry *e;
00389 
00390     // it is better in my opinion to just grab this from the mother,
00391     // since, this dialog doesn't need to keep track of it...
00392     if ( rp.type != Event::NoRepeat )
00393         e = new RepeatEntry( startWeekOnMonday, rp, startDate, this);
00394     else
00395         e = new RepeatEntry( startWeekOnMonday, startDate, this );
00396 
00397     if ( QPEApplication::execDialog( e ) ) {
00398         rp = e->repeatPattern();
00399         setRepeatLabel();
00400     }
00401     // deleting sounds like a nice idea...
00402     delete e;
00403 }
00404 
00405 void DateEntry::slotChangeStartOfWeek( bool onMonday )
00406 {
00407     startWeekOnMonday = onMonday;
00408 }
00409 
00410 Event DateEntry::event()
00411 {
00412     Event ev;
00413     Event::SoundTypeChoice st;
00414     ev.setDescription( comboDescription->currentText() );
00415     ev.setLocation( comboLocation->currentText() );
00416     ev.setCategories( comboCategory->currentCategories() );
00417     ev.setType( checkAllDay->isChecked() ? Event::AllDay : Event::Normal );
00418     if ( startDate > endDate ) {
00419         QDate tmp = endDate;
00420         endDate = startDate;
00421         startDate = tmp;
00422     }
00423 
00424     // This is now done in the changed slots
00425     //    startTime = parseTime( comboStart->text(), ampm );
00426     //endTime = parseTime( comboEnd->text(), ampm );
00427 
00428     if ( startTime > endTime && endDate == startDate ) {
00429         QTime tmp = endTime;
00430         endTime = startTime;
00431         startTime = tmp;
00432     }
00433     // don't set the time if theres no need too
00434     if ( ev.type() == Event::AllDay ) {
00435         startTime.setHMS( 0, 0, 0 );
00436         endTime.setHMS( 23, 59, 59 );
00437     }
00438 
00439     // adjust start and end times based on timezone
00440     QDateTime start( startDate, startTime );
00441     QDateTime end( endDate, endTime );
00442     time_t start_utc, end_utc;
00443 
00444 //      odebug << "tz: " << timezone->currentZone() << oendl;
00445 
00446     // get real timezone
00447     QString realTZ;
00448     realTZ = QString::fromLocal8Bit( getenv("TZ") );
00449 
00450     // set timezone
00451     if ( setenv( "TZ", timezone->currentZone(), true ) != 0 )
00452         owarn << "There was a problem setting the timezone." << oendl;
00453 
00454     // convert to UTC based on selected TZ (calling tzset internally)
00455     start_utc = TimeConversion::toUTC( start );
00456     end_utc = TimeConversion::toUTC( end );
00457 
00458     // done playing around... put it all back
00459     unsetenv( "TZ" );
00460     if ( !realTZ.isNull() )
00461         if ( setenv( "TZ", realTZ, true ) != 0 )
00462                         owarn << "There was a problem setting the timezone." << oendl;
00463 
00464     // convert UTC to local time (calling tzset internally)
00465     ev.setStart( TimeConversion::fromUTC( start_utc ) );
00466     ev.setEnd( TimeConversion::fromUTC( end_utc ) );
00467 
00468     // we only have one type of sound at the moment... LOUD!!!
00469     if ( comboSound->currentItem() != 0 )
00470         st = Event::Loud;
00471     else
00472         st = Event::Silent;
00473     ev.setAlarm( checkAlarm->isChecked(), spinAlarm->value(), st );
00474     if ( rp.type != Event::NoRepeat )
00475         ev.setRepeat( TRUE, rp );
00476     ev.setNotes( noteStr );
00477 
00478                 //cout << "Start: " << comboStart->currentText() << endl;
00479 
00480     return ev;
00481 }
00482 
00483 void DateEntry::setRepeatLabel()
00484 {
00485 
00486     switch( rp.type ) {
00487         case Event::Daily:
00488             cmdRepeat->setText( tr("Daily...") );
00489             break;
00490         case Event::Weekly:
00491             cmdRepeat->setText( tr("Weekly...") );
00492             break;
00493         case Event::MonthlyDay:
00494         case Event::MonthlyDate:
00495             cmdRepeat->setText( tr("Monthly...") );
00496             break;
00497         case Event::Yearly:
00498             cmdRepeat->setText( tr("Yearly...") );
00499             break;
00500         default:
00501             cmdRepeat->setText( tr("No Repeat...") );
00502     }
00503 }
00504 
00505 void DateEntry::setAlarmEnabled( bool alarmPreset, int presetTime, Event::SoundTypeChoice sound )
00506 {
00507     checkAlarm->setChecked( alarmPreset );
00508     spinAlarm->setValue( presetTime );
00509     if ( sound != Event::Silent )
00510         comboSound->setCurrentItem( 1 );
00511     else
00512         comboSound->setCurrentItem( 0 );
00513 }
00514 
00515 void DateEntry::initCombos()
00516 {
00517     /*
00518     comboStart->clear();
00519     comboEnd->clear();
00520     if ( ampm ) {
00521         for ( int i = 0; i < 24; i++ ) {
00522             if ( i == 0 ) {
00523                 comboStart->insertItem( "12:00 AM" );
00524                 comboStart->insertItem( "12:30 AM" );
00525                 comboEnd->insertItem( "12:00 AM" );
00526                 comboEnd->insertItem( "12:30 AM" );
00527             } else if ( i == 12 ) {
00528                 comboStart->insertItem( "12:00 PM" );
00529                 comboStart->insertItem( "12:30 PM" );
00530                 comboEnd->insertItem( "12:00 PM" );
00531                 comboEnd->insertItem( "12:30 PM" );
00532             } else if ( i > 12 ) {
00533                 comboStart->insertItem( QString::number( i - 12 ) + ":00 PM" );
00534                 comboStart->insertItem( QString::number( i - 12 ) + ":30 PM" );
00535                 comboEnd->insertItem( QString::number( i - 12 ) + ":00 PM" );
00536                 comboEnd->insertItem( QString::number( i - 12 ) + ":30 PM" );
00537             } else {
00538                 comboStart->insertItem( QString::number( i) + ":00 AM" );
00539                 comboStart->insertItem( QString::number( i ) + ":30 AM" );
00540                 comboEnd->insertItem( QString::number( i ) + ":00 AM" );
00541                 comboEnd->insertItem( QString::number( i ) + ":30 AM" );
00542             }
00543         }
00544     } else {
00545         for ( int i = 0; i < 24; i++ ) {
00546             if ( i < 10 ) {
00547                 comboStart->insertItem( QString("0")
00548                                         + QString::number(i) + ":00" );
00549                 comboStart->insertItem( QString("0")
00550                                         + QString::number(i) + ":30" );
00551                 comboEnd->insertItem( QString("0")
00552                                       + QString::number(i) + ":00" );
00553                 comboEnd->insertItem( QString("0")
00554                                       + QString::number(i) + ":30" );
00555             } else {
00556                 comboStart->insertItem( QString::number(i) + ":00" );
00557                 comboStart->insertItem( QString::number(i) + ":30" );
00558                 comboEnd->insertItem( QString::number(i) + ":00" );
00559                 comboEnd->insertItem( QString::number(i) + ":30" );
00560             }
00561         }
00562     }
00563     */
00564 }
00565 
00566 void DateEntry::slotChangeClock( bool whichClock )
00567 {
00568     ampm = whichClock;
00569     initCombos();
00570     setDates( QDateTime( startDate, startTime ), QDateTime( endDate, endTime ) );
00571 }
00572 

Generated on Sat Nov 5 16:15:48 2005 for OPIE by  doxygen 1.4.2