[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-pim
Subject:    [Kde-pim] [Patch] KDateEdit
From:       Mike Pilone <mpilone () slac ! com>
Date:       2002-05-07 14:58:03
[Download RAW message or body]

Here is a patch to kdateedit.{h,cpp} in korganizer. This patch adds some 
documentation and the ability to use words as dates. The word list includes 
tomorrow, yesturday, today, and the days of the week. The word list is not 
nearly as complete as what Rik recommended, but this list is fairly easy to 
implement and translate!

If the patch looks good, I recommend we apply it and then move KDateEdit to 
kdelibs/kdeui.

-mike

-- 
Mike Pilone <mpilone@slac.com>        http://www.slac.com/mpilone/personal/
GPG Fingerprint = 856C 8B36 ECF7 9156 4611  7C6B C265 05C4 162F C3B5

See http://www.slac.com/mpilone/personal/mpilone_pub_key.gpg for full key.
See http://www.gnupg.org for GPG information.
["kdateedit-mp1.diff" (text/x-diff)]

Index: kdateedit.cpp
===================================================================
RCS file: /home/kdecvs/kde/kdepim/korganizer/kdateedit.cpp,v
retrieving revision 1.11
diff -u -b -r1.11 kdateedit.cpp
--- kdateedit.cpp	7 Apr 2002 17:11:38 -0000	1.11
+++ kdateedit.cpp	7 May 2002 15:29:26 -0000
@@ -26,6 +26,7 @@
 #include <qpixmap.h>
 #include <qlineedit.h>
 #include <qpushbutton.h>
+#include <qevent.h>
 
 #include <kdebug.h>
 #include <klocale.h>
@@ -43,6 +44,7 @@
   mDateEdit = new QLineEdit(this);
   mDateEdit->setText(KGlobal::locale()->formatDate(QDate::currentDate(),true));
   setFocusProxy(mDateEdit);
+  mDateEdit->installEventFilter(this);
 
   QPixmap pixmap = SmallIcon("smallcal");
   mDateButton = new QPushButton(this);
@@ -57,12 +59,41 @@
   mDatePicker = new KDatePicker(mDateFrame,QDate::currentDate());
 
   connect(mDateEdit,SIGNAL(returnPressed()),SLOT(lineEnterPressed()));
+  connect(mDateEdit,SIGNAL(textChanged(const QString &)),
+          SLOT(textChanged(const QString &)));
 
   connect(mDateButton,SIGNAL(clicked()),SLOT(toggleDatePicker()));
 
   connect(mDatePicker,SIGNAL(dateSelected(QDate)),SLOT(setDate(QDate)));
   connect(mDatePicker,SIGNAL(dateSelected(QDate)),SIGNAL(dateChanged(QDate)));
   connect(mDatePicker,SIGNAL(dateSelected(QDate)),mDateFrame,SLOT(hide()));
+  
+  // Create the keyword list. This will be used to match against when the user
+  // enters information.
+  mKeywordMap[i18n("tomorrow")] = 1;
+  mKeywordMap[i18n("today")] = 0;
+  mKeywordMap[i18n("yesturday")] = -1;
+  
+  /*
+   * This loop uses some math tricks to figure out the offset in days
+   * to the next date the given day of the week occurs. There
+   * are two cases, that the new day is >= the current day, which means
+   * the new day has not occured yet or that the new day < the current day,
+   * which means the new day is already passed (so we need to find the
+   * day in the next week).
+   */
+  QString dayName;
+  int currentDay = QDate::currentDate().dayOfWeek();
+  for (int i = 1; i <= 7; ++i)
+  {
+    dayName = KGlobal::locale()->weekDayName(i).lower();
+    if (i >= currentDay)
+      mKeywordMap[dayName] = i - currentDay;
+    else
+      mKeywordMap[dayName] = 7 - currentDay + i;
+  }
+  
+  mTextChanged = false;
 }
 
 KDateEdit::~KDateEdit()
@@ -75,7 +106,14 @@
   if (!newDate.isValid())
     return;
 
-  mDateEdit->setText(KGlobal::locale()->formatDate(newDate,true));
+  mTextChanged = false;
+  
+  // We do not want to generate a signal here, since we explicity setting
+  // the date
+  bool b = mDateEdit->signalsBlocked();
+  mDateEdit->blockSignals(true);
+  mDateEdit->setText(KGlobal::locale()->formatDate( newDate, true ));
+  mDateEdit->blockSignals(b);
 }
 
 void KDateEdit::setEnabled(bool on)
@@ -84,9 +122,9 @@
   mDateButton->setEnabled(on);
 }
 
-QDate KDateEdit::getDate() const
+QDate KDateEdit::date() const
 {
-  QDate date = KGlobal::locale()->readDate(mDateEdit->text());
+  QDate date = readDate();
 
   if (date.isValid()) {
     return date;
@@ -111,7 +149,7 @@
     	
     mDateFrame->setGeometry(tmpPoint.x()-207, tmpPoint.y(), 200, 200);
 
-    QDate date = KGlobal::locale()->readDate(mDateEdit->text());
+    QDate date = readDate();
     if(date.isValid()) {
       mDatePicker->setDate(date);
     } else {
@@ -124,17 +162,58 @@
 
 void KDateEdit::lineEnterPressed()
 {
-  QDate date = KGlobal::locale()->readDate(mDateEdit->text());
+  QDate date = readDate();
+
+  if(date.isValid()) 
+  {
+    // Update the edit. This is needed if the user has entered a 
+    // word rather than the actual date.
+    setDate(date);
 
-  if(date.isValid()) {
     emit(dateChanged(date));
-  } else {
+  }
+  else
+  {
     KNotifyClient::beep();
   }
 }
 
 bool KDateEdit::inputIsValid()
 {
-  QDate date = KGlobal::locale()->readDate(mDateEdit->text());
-  return date.isValid();
+  return readDate().isValid();
+}
+
+QDate KDateEdit::readDate() const
+{
+  QString text = mDateEdit->text();
+  QDate date;
+  
+  if (mKeywordMap.contains(text.lower()))
+  {
+    date = QDate::currentDate().addDays(mKeywordMap[text.lower()]);
+  }
+  else
+  {
+    date = KGlobal::locale()->readDate(text);
+  }
+  
+  return date;
+}
+
+bool KDateEdit::eventFilter(QObject *, QEvent *e)
+{
+  // We only process the focus out event if the text has changed
+  // since we got focus
+  if ((e->type() == QEvent::FocusOut) && mTextChanged)
+  {
+    lineEnterPressed();
+    mTextChanged = false;
+  }
+    
+  return false;
+}
+
+void KDateEdit::textChanged(const QString &)
+{
+  mTextChanged = true;
 }
Index: kdateedit.h
===================================================================
RCS file: /home/kdecvs/kde/kdepim/korganizer/kdateedit.h,v
retrieving revision 1.6
diff -u -b -r1.6 kdateedit.h
--- kdateedit.h	16 Jan 2002 16:57:02 -0000	1.6
+++ kdateedit.h	7 May 2002 15:29:26 -0000
@@ -29,9 +29,24 @@
 
 class QLineEdit;
 class QPushButton;
+class QObject;
+class QEvent;
 class KDatePicker;
 class KDateValidator;
 
+/** 
+* A date editing widget that consists of a line edit followed by
+* a small push button. The line edit contains the date in text form, 
+* and the push button will display a 'popup' style date picker.
+*
+* This widget also supports advanced features like allowing the user
+* to type in the day name to get the date. The following keywords
+* are supported (in the native language): tomorrow, yesturday, today,
+* monday, tuesday, wednesday, thursday, friday, saturday, sunday.
+*
+* @author Cornelius Schumacher <schumacher@kde.org>
+* @author Mike Pilone <mpilone@slac.com>
+*/
 class KDateEdit : public QHBox
 {
     Q_OBJECT
@@ -39,21 +54,61 @@
     KDateEdit(QWidget *parent=0, const char *name=0);
     virtual ~KDateEdit();
 
+    /** @return True if the date in the text edit is valid,
+    * false otherwise. This will not modify the display of the date,
+    * but only check for validity.
+    */
     bool inputIsValid();
 
+    /** @return The date entered. This will not
+    * modify the display of the date, but only return it.
+    */
+    QDate date() const;
+    
+    /** Checks for a focus out event. The display of the date is updated
+    * to display the proper date when the focus leaves.
+    */
+    virtual bool eventFilter(QObject *o, QEvent *e);
+    
   signals:
+    /** This signal is emitted whenever the user modifies the date. This
+    * may not get emitted until the user presses enter in the line edit or
+    * focus leaves the widget (ie: the user confirms their selection).
+    */
     void dateChanged(QDate);
 
   public slots:
+    /** Sets the date.
+    *
+    * @param date The new date to display. This date must be valid or
+    * it will not be displayed.
+    */
     void setDate(QDate date);
-    QDate getDate() const;
+    
+    /** Sets the date edit to be enabled or disabled (grayed out)
+    * 
+    * @param on Enabled if true, disabled if false
+    */
     void setEnabled(bool on);
 
   protected slots:
     void toggleDatePicker();
     void lineEnterPressed();
+    void textChanged(const QString &);
  
   private:
+    /** Reads the text from the line edit. If the text is a keyword, the
+    * word will be translated to a date. If the text is not a keyword, the
+    * text will be interpreted as a date.
+    */
+    QDate readDate() const;
+    
+    /** Maps the text that the user can enter to the offset in days from
+    * today. For example, the text 'tomorrow' is mapped to +1.
+    */
+    QMap<QString, int> mKeywordMap;
+    bool mTextChanged;
+    
     QPushButton *mDateButton;
     QLineEdit *mDateEdit;
     KDatePicker *mDatePicker;

_______________________________________________
kde-pim mailing list
kde-pim@mail.kde.org
http://mail.kde.org/mailman/listinfo/kde-pim
kde-pim home page at http://pim.kde.org/

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic