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