libkdepim
kdateedit.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <qapplication.h>
00026 #include <qlineedit.h>
00027 #include <qlistbox.h>
00028 #include <qvalidator.h>
00029
00030 #include <kcalendarsystem.h>
00031 #include <kglobal.h>
00032 #include <kglobalsettings.h>
00033 #include <klocale.h>
00034
00035 #include "kdateedit.h"
00036
00037 class DateValidator : public QValidator
00038 {
00039 public:
00040 DateValidator( const QStringList &keywords, QWidget* parent, const char* name = 0 )
00041 : QValidator( parent, name ), mKeywords( keywords )
00042 {}
00043
00044 virtual State validate( QString &str, int& ) const
00045 {
00046 int length = str.length();
00047
00048
00049 if ( length <= 0 )
00050 return Intermediate;
00051
00052 if ( mKeywords.contains( str.lower() ) )
00053 return Acceptable;
00054
00055 bool ok = false;
00056 KGlobal::locale()->readDate( str, &ok );
00057 if ( ok )
00058 return Acceptable;
00059 else
00060 return Intermediate;
00061 }
00062
00063 private:
00064 QStringList mKeywords;
00065 };
00066
00067 KDateEdit::KDateEdit( QWidget *parent, const char *name )
00068 : QComboBox( true, parent, name ),
00069 mReadOnly( false ),
00070 mDiscardNextMousePress( false )
00071 {
00072
00073 setMaxCount( 1 );
00074
00075 mDate = QDate::currentDate();
00076 QString today = KGlobal::locale()->formatDate( mDate, true );
00077
00078 insertItem( today );
00079 setCurrentItem( 0 );
00080 changeItem( today, 0 );
00081 setMinimumSize( sizeHint() );
00082
00083 connect( lineEdit(), SIGNAL( returnPressed() ),
00084 this, SLOT( lineEnterPressed() ) );
00085 connect( this, SIGNAL( textChanged( const QString& ) ),
00086 SLOT( slotTextChanged( const QString& ) ) );
00087
00088 mPopup = new KDatePickerPopup( KDatePickerPopup::DatePicker | KDatePickerPopup::Words );
00089 mPopup->hide();
00090 mPopup->installEventFilter( this );
00091
00092 connect( mPopup, SIGNAL( dateChanged( QDate ) ),
00093 SLOT( dateSelected( QDate ) ) );
00094
00095
00096 setupKeywords();
00097 lineEdit()->installEventFilter( this );
00098
00099 setValidator( new DateValidator( mKeywordMap.keys(), this ) );
00100
00101 mTextChanged = false;
00102 }
00103
00104 KDateEdit::~KDateEdit()
00105 {
00106 delete mPopup;
00107 mPopup = 0;
00108 }
00109
00110 void KDateEdit::setDate( const QDate& date )
00111 {
00112 assignDate( date );
00113 updateView();
00114 }
00115
00116 QDate KDateEdit::date() const
00117 {
00118 return mDate;
00119 }
00120
00121 void KDateEdit::setReadOnly( bool readOnly )
00122 {
00123 mReadOnly = readOnly;
00124 lineEdit()->setReadOnly( readOnly );
00125 }
00126
00127 bool KDateEdit::isReadOnly() const
00128 {
00129 return mReadOnly;
00130 }
00131
00132 void KDateEdit::popup()
00133 {
00134 if ( mReadOnly )
00135 return;
00136
00137 QRect desk = KGlobalSettings::desktopGeometry( this );
00138
00139 QPoint popupPoint = mapToGlobal( QPoint( 0,0 ) );
00140
00141 int dateFrameHeight = mPopup->sizeHint().height();
00142 if ( popupPoint.y() + height() + dateFrameHeight > desk.bottom() )
00143 popupPoint.setY( popupPoint.y() - dateFrameHeight );
00144 else
00145 popupPoint.setY( popupPoint.y() + height() );
00146
00147 int dateFrameWidth = mPopup->sizeHint().width();
00148 if ( popupPoint.x() + dateFrameWidth > desk.right() )
00149 popupPoint.setX( desk.right() - dateFrameWidth );
00150
00151 if ( popupPoint.x() < desk.left() )
00152 popupPoint.setX( desk.left() );
00153
00154 if ( popupPoint.y() < desk.top() )
00155 popupPoint.setY( desk.top() );
00156
00157 if ( mDate.isValid() )
00158 mPopup->setDate( mDate );
00159 else
00160 mPopup->setDate( QDate::currentDate() );
00161
00162 mPopup->popup( popupPoint );
00163
00164
00165
00166
00167 QDate date = parseDate();
00168 assignDate( date );
00169 updateView();
00170
00171 QListBox *lb = listBox();
00172 if (lb) {
00173 lb->setCurrentItem(0);
00174 QKeyEvent* keyEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, 0, 0);
00175 QApplication::postEvent(lb, keyEvent);
00176 }
00177 }
00178
00179 void KDateEdit::dateSelected( QDate date )
00180 {
00181 if (assignDate( date ) ) {
00182 updateView();
00183 emit dateChanged( date );
00184 emit dateEntered( date );
00185
00186 if ( date.isValid() ) {
00187 mPopup->hide();
00188 }
00189 }
00190 }
00191
00192 void KDateEdit::lineEnterPressed()
00193 {
00194 bool replaced = false;
00195
00196 QDate date = parseDate( &replaced );
00197
00198 if (assignDate( date ) ) {
00199 if ( replaced )
00200 updateView();
00201
00202 emit dateChanged( date );
00203 emit dateEntered( date );
00204 }
00205 }
00206
00207 QDate KDateEdit::parseDate( bool *replaced ) const
00208 {
00209 QString text = currentText();
00210 QDate result;
00211
00212 if ( replaced )
00213 (*replaced) = false;
00214
00215 if ( text.isEmpty() )
00216 result = QDate();
00217 else if ( mKeywordMap.contains( text.lower() ) ) {
00218 QDate today = QDate::currentDate();
00219 int i = mKeywordMap[ text.lower() ];
00220 if ( i >= 100 ) {
00221
00222
00223
00224
00225
00226
00227
00228
00229 i -= 100;
00230 int currentDay = today.dayOfWeek();
00231 if ( i >= currentDay )
00232 i -= currentDay;
00233 else
00234 i += 7 - currentDay;
00235 }
00236
00237 result = today.addDays( i );
00238 if ( replaced )
00239 (*replaced) = true;
00240 } else {
00241 result = KGlobal::locale()->readDate( text );
00242 }
00243
00244 return result;
00245 }
00246
00247 bool KDateEdit::eventFilter( QObject *object, QEvent *event )
00248 {
00249 if ( object == lineEdit() ) {
00250
00251
00252 if ( (event->type() == QEvent::FocusOut) && mTextChanged ) {
00253 lineEnterPressed();
00254 mTextChanged = false;
00255 } else if ( event->type() == QEvent::KeyPress ) {
00256
00257 QKeyEvent* keyEvent = (QKeyEvent*)event;
00258
00259 if ( keyEvent->key() == Qt::Key_Return ) {
00260 lineEnterPressed();
00261 return true;
00262 }
00263
00264 int step = 0;
00265 if ( keyEvent->key() == Qt::Key_Up )
00266 step = 1;
00267 else if ( keyEvent->key() == Qt::Key_Down )
00268 step = -1;
00269
00270 if ( step && !mReadOnly ) {
00271 QDate date = parseDate();
00272 if ( date.isValid() ) {
00273 date = date.addDays( step );
00274 if ( assignDate( date ) ) {
00275 updateView();
00276 emit dateChanged( date );
00277 emit dateEntered( date );
00278 return true;
00279 }
00280 }
00281 }
00282 }
00283 } else {
00284
00285 switch ( event->type() ) {
00286 case QEvent::MouseButtonDblClick:
00287 case QEvent::MouseButtonPress: {
00288 QMouseEvent *mouseEvent = (QMouseEvent*)event;
00289 if ( !mPopup->rect().contains( mouseEvent->pos() ) ) {
00290 QPoint globalPos = mPopup->mapToGlobal( mouseEvent->pos() );
00291 if ( QApplication::widgetAt( globalPos, true ) == this ) {
00292
00293
00294 mDiscardNextMousePress = true;
00295 }
00296 }
00297
00298 break;
00299 }
00300 default:
00301 break;
00302 }
00303 }
00304
00305 return false;
00306 }
00307
00308 void KDateEdit::mousePressEvent( QMouseEvent *event )
00309 {
00310 if ( event->button() == Qt::LeftButton && mDiscardNextMousePress ) {
00311 mDiscardNextMousePress = false;
00312 return;
00313 }
00314
00315 QComboBox::mousePressEvent( event );
00316 }
00317
00318 void KDateEdit::slotTextChanged( const QString& )
00319 {
00320 QDate date = parseDate();
00321
00322 if ( assignDate( date ) )
00323 emit dateChanged( date );
00324
00325 mTextChanged = true;
00326 }
00327
00328 void KDateEdit::setupKeywords()
00329 {
00330
00331
00332 mKeywordMap.insert( i18n( "tomorrow" ), 1 );
00333 mKeywordMap.insert( i18n( "today" ), 0 );
00334 mKeywordMap.insert( i18n( "yesterday" ), -1 );
00335
00336 QString dayName;
00337 for ( int i = 1; i <= 7; ++i ) {
00338 dayName = KGlobal::locale()->calendar()->weekDayName( i ).lower();
00339 mKeywordMap.insert( dayName, i + 100 );
00340 }
00341 }
00342
00343 bool KDateEdit::assignDate( const QDate& date )
00344 {
00345 mDate = date;
00346 mTextChanged = false;
00347 return true;
00348 }
00349
00350 void KDateEdit::updateView()
00351 {
00352 QString dateString;
00353 if ( mDate.isValid() )
00354 dateString = KGlobal::locale()->formatDate( mDate, true );
00355
00356
00357
00358 bool blocked = signalsBlocked();
00359 blockSignals( true );
00360 changeItem( dateString, 0 );
00361 blockSignals( blocked );
00362 }
00363
00364 #include "kdateedit.moc"
|