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
00166
int dateFrameHeight = mDateFrame->sizeHint().height();
00167
if ( popupPoint.y() + height() + dateFrameHeight > desk.bottom() ) {
00168 popupPoint.setY( popupPoint.y() - dateFrameHeight );
00169 }
else {
00170 popupPoint.setY( popupPoint.y() + height() );
00171 }
00172
int dateFrameWidth = mDateFrame->sizeHint().width();
00173
if ( popupPoint.x() + dateFrameWidth > desk.right() ) {
00174 popupPoint.setX( desk.right() - dateFrameWidth );
00175 }
00176
00177
if ( popupPoint.x() < desk.left() ) popupPoint.setX( desk.left() );
00178
if ( popupPoint.y() < desk.top() ) popupPoint.setY( desk.top() );
00179
00180 mDateFrame->move( popupPoint );
00181
00182
QDate date;
00183 readDate(date);
00184
if (date.isValid()) {
00185 mDatePicker->setDate( date );
00186 }
else {
00187 mDatePicker->setDate( defaultValue );
00188 }
00189
00190 mDateFrame->show();
00191
00192
00193
00194
QListBox *lb = listBox();
00195
if (lb) {
00196 lb->setCurrentItem(0);
00197
QKeyEvent* keyEvent =
new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, 0, 0);
00198 QApplication::postEvent(lb, keyEvent);
00199 }
00200 }
00201
00202
void KDateEdit::dateSelected(
QDate newDate)
00203 {
00204
if ((mHandleInvalid || newDate.isValid()) &&
validate(newDate)) {
00205
setDate(newDate);
00206 emit
dateChanged(newDate);
00207 mDateFrame->hide();
00208 }
00209 }
00210
00211
void KDateEdit::dateEntered(
QDate newDate)
00212 {
00213
if ((mHandleInvalid || newDate.isValid()) &&
validate(newDate)) {
00214
setDate(newDate);
00215 emit
dateChanged(newDate);
00216 }
00217 }
00218
00219
void KDateEdit::lineEnterPressed()
00220 {
00221
QDate date;
00222
if (readDate(date) && (mHandleInvalid || date.isValid()) &&
validate(date))
00223 {
00224
00225
00226
setDate(date);
00227 emit(
dateChanged(date));
00228 }
00229
else {
00230
00231 KNotifyClient::beep();
00232
setDate(value);
00233 emit
invalidDateEntered();
00234 }
00235 }
00236
00237 bool KDateEdit::inputIsValid()
const
00238
{
00239
QDate date;
00240
return readDate(date) && date.isValid();
00241 }
00242
00243
00244
00245
00246
00247
00248
bool KDateEdit::readDate(
QDate& result)
const
00249
{
00250
QString text = currentText();
00251
00252
if (text.isEmpty()) {
00253 result =
QDate();
00254 }
00255
else if (mKeywordMap.contains(text.lower()))
00256 {
00257
QDate today = QDate::currentDate();
00258
int i = mKeywordMap[text.lower()];
00259
if (i >= 100)
00260 {
00261
00262
00263
00264
00265
00266
00267
00268
00269 i -= 100;
00270
int currentDay = today.dayOfWeek();
00271
if (i >= currentDay)
00272 i -= currentDay;
00273
else
00274 i += 7 - currentDay;
00275 }
00276 result = today.addDays(i);
00277 }
00278
else
00279 {
00280 result = KGlobal::locale()->readDate(text);
00281
return result.isValid();
00282 }
00283
00284
return true;
00285 }
00286
00287
00288
00289
00290
bool KDateEdit::eventFilter(
QObject *obj,
QEvent *e)
00291 {
00292
if (obj == lineEdit()) {
00293
00294
00295
if ((e->type() == QEvent::FocusOut) && mTextChanged)
00296 {
00297 lineEnterPressed();
00298 mTextChanged =
false;
00299 }
00300
else if (e->type() == QEvent::KeyPress)
00301 {
00302
00303
QKeyEvent* ke = (
QKeyEvent*)e;
00304
00305
if (ke->key() == Qt::Key_Return)
00306 {
00307 lineEnterPressed();
00308
return true;
00309 }
00310
00311
int step = 0;
00312
if (ke->key() == Qt::Key_Up)
00313 step = 1;
00314
else if (ke->key() == Qt::Key_Down)
00315 step = -1;
00316
if (step && !mReadOnly)
00317 {
00318
QDate date;
00319
if (readDate(date) && date.isValid()) {
00320 date = date.addDays(step);
00321
if (
validate(date)) {
00322
setDate(date);
00323 emit(
dateChanged(date));
00324
return true;
00325 }
00326 }
00327 }
00328 }
00329 }
00330
else {
00331
00332
switch (e->type()) {
00333
case QEvent::MouseButtonDblClick:
00334
case QEvent::MouseButtonPress: {
00335
QMouseEvent *me = (
QMouseEvent*)e;
00336
if (!mDateFrame->rect().contains(me->pos())) {
00337
QPoint globalPos = mDateFrame->mapToGlobal(me->pos());
00338
if (QApplication::widgetAt(globalPos,
true) ==
this) {
00339
00340
00341 mDiscardNextMousePress =
true;
00342 }
00343 }
00344
break;
00345 }
00346
default:
00347
break;
00348 }
00349 }
00350
00351
return false;
00352 }
00353
00354
void KDateEdit::mousePressEvent(
QMouseEvent *e)
00355 {
00356
if (e->button() == Qt::LeftButton && mDiscardNextMousePress) {
00357 mDiscardNextMousePress =
false;
00358
return;
00359 }
00360 QComboBox::mousePressEvent(e);
00361 }
00362
00363
void KDateEdit::slotTextChanged(
const QString &)
00364 {
00365 mTextChanged =
true;
00366 }