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