kexi

kexidatetableedit.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002   Lucijan Busch <lucijan@gmx.at>
00003    Copyright (C) 2003   Daniel Molkentin <molkentin@kde.org>
00004    Copyright (C) 2003-2004,2006 Jaroslaw Staniek <js@iidea.pl>
00005 
00006    This program is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this program; see the file COPYING.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  */
00021 
00022 #include "kexidatetableedit.h"
00023 
00024 #include <qapplication.h>
00025 #include <qpainter.h>
00026 #include <qvariant.h>
00027 #include <qrect.h>
00028 #include <qpalette.h>
00029 #include <qcolor.h>
00030 #include <qfontmetrics.h>
00031 #include <qdatetime.h>
00032 #include <qcursor.h>
00033 #include <qpoint.h>
00034 #include <qlayout.h>
00035 #include <qtoolbutton.h>
00036 #include <qdatetimeedit.h>
00037 
00038 #include <kdebug.h>
00039 #include <klocale.h>
00040 #include <kglobal.h>
00041 #include <kdatepicker.h>
00042 #include <kdatetbl.h>
00043 #include <klineedit.h>
00044 #include <kpopupmenu.h>
00045 #include <kdatewidget.h>
00046 
00047 #include <kexiutils/utils.h>
00048 
00049 KexiDateFormatter::KexiDateFormatter()
00050 {
00051     // use "short date" format system settings
00053     QString df( KGlobal::locale()->dateFormatShort() );
00054     if (df.length()>2)
00055         m_separator = df.mid(2,1);
00056     else
00057         m_separator = "-";
00058     const int separatorLen = m_separator.length();
00059     QString yearMask("9999");
00060     QString yearDateFormat("yyyy"), 
00061         monthDateFormat("MM"), 
00062         dayDateFormat("dd"); //for setting up m_dateFormat
00063     bool ok = df.length()>=8;
00064     int yearpos, monthpos, daypos; //result of df.find()
00065     if (ok) {//look at % variables
00068         yearpos = df.find("%y", 0, false); //&y or %y
00069         m_longYear = !(yearpos>=0 && df.mid(yearpos+1, 1)=="y"); 
00070         if (!m_longYear) {
00071             yearMask = "99";
00072             yearDateFormat = "yy";
00073         }
00074         monthpos = df.find("%m", 0, true); //%m or %n
00075         m_monthWithLeadingZero = true;
00076         if (monthpos<0) {
00077             monthpos = df.find("%n", 0, false);
00078             m_monthWithLeadingZero = false;
00079             monthDateFormat = "M";
00080         }
00081         daypos = df.find("%d", 0, true);//%d or %e
00082         m_dayWithLeadingZero = true;
00083         if (daypos<0) {
00084             daypos = df.find("%e", 0, false);
00085             m_dayWithLeadingZero = false;
00086             dayDateFormat = "d";
00087         }
00088         ok = (yearpos>=0 && monthpos>=0 && daypos>=0);
00089     }
00090     m_order = QDateEdit::YMD; //default
00091     if (ok) {
00092         if (yearpos<monthpos && monthpos<daypos) {
00093             //will be set in "default: YMD"
00094         }
00095         else if (yearpos<daypos && daypos<monthpos) {
00096             m_order = QDateEdit::YDM;
00099             m_inputMask = QString("%1%299%399").arg(yearMask).arg(m_separator).arg(m_separator);
00100             m_qtFormat = yearDateFormat+m_separator+dayDateFormat+m_separator+monthDateFormat;
00101             m_yearpos = 0;
00102             m_daypos = yearMask.length()+separatorLen;
00103             m_monthpos = m_daypos+2+separatorLen;
00104         }
00105         else if (daypos<monthpos && monthpos<yearpos) {
00106             m_order = QDateEdit::DMY;
00107             m_inputMask = QString("99%199%2%3").arg(m_separator).arg(m_separator).arg(yearMask);
00108             m_qtFormat = dayDateFormat+m_separator+monthDateFormat+m_separator+yearDateFormat;
00109             m_daypos = 0;
00110             m_monthpos = 2+separatorLen;
00111             m_yearpos = m_monthpos+2+separatorLen;
00112         }
00113         else if (monthpos<daypos && daypos<yearpos) {
00114             m_order = QDateEdit::MDY;
00115             m_inputMask = QString("99%199%2%3").arg(m_separator).arg(m_separator).arg(yearMask);
00116             m_qtFormat = monthDateFormat+m_separator+dayDateFormat+m_separator+yearDateFormat;
00117             m_monthpos = 0;
00118             m_daypos = 2+separatorLen;
00119             m_yearpos = m_daypos+2+separatorLen;
00120         }
00121         else
00122             ok = false;
00123     }
00124     if (!ok || m_order == QDateEdit::YMD) {//default: YMD
00125         m_inputMask = QString("%1%299%399").arg(yearMask).arg(m_separator).arg(m_separator);
00126         m_qtFormat = yearDateFormat+m_separator+monthDateFormat+m_separator+dayDateFormat;
00127         m_yearpos = 0;
00128         m_monthpos = yearMask.length()+separatorLen;
00129         m_daypos = m_monthpos+2+separatorLen;
00130     }
00131     m_inputMask += ";_";
00132 }
00133 
00134 KexiDateFormatter::~KexiDateFormatter()
00135 {
00136 }
00137 
00138 QDate KexiDateFormatter::stringToDate( const QString& str ) const
00139 {
00140     bool ok = true;
00141     int year = str.mid(m_yearpos, m_longYear ? 4 : 2).toInt(&ok);
00142     if (!ok)
00143         return QDate();
00144     if (year < 30) {//2000..2029
00145         year = 2000 + year;
00146     }
00147     else if (year < 100) {//1930..1999
00148         year = 1900 + year;
00149     }
00150 
00151     int month = str.mid(m_monthpos, 2).toInt(&ok);
00152     if (!ok)
00153         return QDate();
00154 
00155     int day = str.mid(m_daypos, 2).toInt(&ok);
00156     if (!ok)
00157         return QDate();
00158 
00159     QDate date(year, month, day);
00160     if (!date.isValid())
00161         return QDate();
00162     return date;
00163 }
00164 
00165 QString KexiDateFormatter::dateToString( const QDate& date ) const
00166 {
00167     return date.toString(m_qtFormat);
00168 }
00169 
00170 //------------------------------------------------
00171 
00172 KexiDateTableEdit::KexiDateTableEdit(KexiTableViewColumn &column, QScrollView *parent)
00173  : KexiInputTableEdit(column, parent)
00174 {
00175     setName("KexiDateTableEdit");
00176 
00178 
00179     m_lineedit->setInputMask( m_formatter.inputMask() );
00180 }
00181 
00182 KexiDateTableEdit::~KexiDateTableEdit()
00183 {
00184 }
00185 
00186 void KexiDateTableEdit::setValueInternal(const QVariant& add_, bool removeOld)
00187 {
00188     if (removeOld) {
00189         //new date entering... just fill the line edit
00191         QString add(add_.toString());
00192         m_lineedit->setText(add);
00193         m_lineedit->setCursorPosition(add.length());
00194         return;
00195     }
00196     m_lineedit->setText( m_formatter.dateToString( m_origValue.toDate() ) );
00197     m_lineedit->setCursorPosition(0); //ok?
00198 }
00199 
00200 void KexiDateTableEdit::setupContents( QPainter *p, bool focused, QVariant val, 
00201     QString &txt, int &align, int &x, int &y_offset, int &w, int &h )
00202 {
00203     Q_UNUSED(p);
00204     Q_UNUSED(focused);
00205     Q_UNUSED(x);
00206     Q_UNUSED(w);
00207     Q_UNUSED(h);
00208 #ifdef Q_WS_WIN
00209     y_offset = -1;
00210 #else
00211     y_offset = 0;
00212 #endif
00213     if (val.toDate().isValid())
00214         txt = m_formatter.dateToString(val.toDate());
00215 //      txt = val.toDate().toString(Qt::LocalDate);
00216     align |= AlignLeft;
00217 }
00218 
00219 bool KexiDateTableEdit::valueIsNull()
00220 {
00221     if (m_lineedit->text().replace(m_formatter.separator(),"").stripWhiteSpace().isEmpty())
00222         return true;
00223     return dateValue().isNull();
00224 }
00225 
00226 bool KexiDateTableEdit::valueIsEmpty()
00227 {
00228     return valueIsNull();//js OK? TODO (nonsense?)
00229 }
00230 
00231 QDate KexiDateTableEdit::dateValue() const
00232 {
00233     return m_formatter.stringToDate( m_lineedit->text() );
00234 }
00235 
00236 QVariant KexiDateTableEdit::value()
00237 {
00238     if (m_lineedit->text().replace(m_formatter.separator(),"").stripWhiteSpace().isEmpty())
00239         return QVariant();
00240     return dateValue();
00241 //  ok = true;
00242 //todo  return QVariant(m_edit->date());
00243     //todo use conversion from string
00244 }
00245 
00246 bool KexiDateTableEdit::valueIsValid()
00247 {
00248     if (m_lineedit->text().replace(m_formatter.separator(),"").stripWhiteSpace().isEmpty()) //empty date is valid
00249         return true;
00250     return m_formatter.stringToDate( m_lineedit->text() ).isValid();
00251 }
00252 
00253 /*
00254 void
00255 KexiDateTableEdit::slotDateChanged(QDate date)
00256 {
00257     m_edit->setDate(date);
00258     repaint();
00259 }
00260 
00261 void
00262 KexiDateTableEdit::slotShowDatePicker()
00263 {
00264     QDate date = m_edit->date();
00265 
00266     m_datePicker->setDate(date);
00267     m_datePicker->setFocus();
00268     m_datePicker->show();
00269     m_datePicker->setFocus();
00270 }
00271 
00273 void KexiDateTableEdit::moveToFirstSection()
00274 {
00275     if (!m_dte_date_obj)
00276         return;
00277 #ifdef QDateTimeEditor_HACK
00278     if (m_dte_date)
00279         m_dte_date->setFocusSection(0);
00280 #else
00281 #ifdef Q_WS_WIN //tmp
00282     QKeyEvent ke_left(QEvent::KeyPress, Qt::Key_Left, 0, 0);
00283     for (int i=0; i<8; i++)
00284         QApplication::sendEvent( m_dte_date_obj, &ke_left );
00285 #endif
00286 #endif
00287 }
00288 
00289 bool KexiDateTableEdit::eventFilter( QObject *o, QEvent *e )
00290 {
00291     if (o==m_datePicker) {
00292         kdDebug() << e->type() << endl;
00293         switch (e->type()) {
00294         case QEvent::Hide:
00295             m_datePickerPopupMenu->hide();
00296             break;
00297         case QEvent::KeyPress:
00298         case QEvent::KeyRelease: {
00299             kdDebug() << "ok!" << endl;
00300             QKeyEvent *ke = (QKeyEvent *)e;
00301             if (ke->key()==Key_Enter || ke->key()==Key_Return) {
00302                 //accepting picker
00303                 acceptDate();
00304                 return true;
00305             }
00306             else if (ke->key()==Key_Escape) {
00307                 //cancelling picker
00308                 m_datePickerPopupMenu->hide();
00309                 kdDebug() << "reject" << endl;
00310                 return true;
00311             }
00312             else m_datePickerPopupMenu->setFocus();
00313             break;
00314             }
00315         default:
00316             break;
00317         }
00318     }
00319 #ifdef Q_WS_WIN //tmp
00320     else if (e->type()==QEvent::FocusIn && o->parent() && o->parent()->parent()==m_edit
00321         && m_setNumberOnFocus >= 0 && m_dte_date_obj)
00322     {
00323         // there was a number character passed as 'add' parameter in init():
00324         moveToFirstSection();
00325         QKeyEvent ke(QEvent::KeyPress, int(Qt::Key_0)+m_setNumberOnFocus, 
00326             '0'+m_setNumberOnFocus, 0, QString::number(m_setNumberOnFocus));
00327         QApplication::sendEvent( m_dte_date_obj, &ke );
00328         m_setNumberOnFocus = -1;
00329     }
00330 #endif
00331 #ifdef QDateTimeEditor_HACK
00332     else if (e->type()==QEvent::KeyPress && m_dte_date) {
00333         QKeyEvent *ke = static_cast<QKeyEvent*>(e);
00334         if ((ke->key()==Qt::Key_Right && !m_sentEvent && cursorAtEnd())
00335             || (ke->key()==Qt::Key_Left && !m_sentEvent && cursorAtStart()))
00336         {
00337             //the editor should send this key event:
00338             m_sentEvent = true; //avoid recursion
00339             QApplication::sendEvent( this, ke );
00340             m_sentEvent = false;
00341             ke->ignore();
00342             return true;
00343         }
00344     }
00345 #endif
00346     return false;
00347 }
00348 
00349 void KexiDateTableEdit::acceptDate()
00350 {
00351     m_edit->setDate(m_datePicker->date());
00352     m_datePickerPopupMenu->hide();
00353     kdDebug() << "accept" << endl;
00354 }
00355 
00356 bool KexiDateTableEdit::cursorAtStart()
00357 {
00358 #ifdef QDateTimeEditor_HACK
00359     return m_dte_date && m_edit->hasFocus() && m_dte_date->focusSection()==0;
00360 #else
00361     return false;
00362 #endif
00363 }
00364 
00365 bool KexiDateTableEdit::cursorAtEnd()
00366 {
00367 #ifdef QDateTimeEditor_HACK
00368     return m_dte_date && m_edit->hasFocus() 
00369         && m_dte_date->focusSection()==int(m_dte_date->sectionCount()-1);
00370 #else
00371     return false;
00372 #endif
00373 }
00374 
00375 void KexiDateTableEdit::clear()
00376 {
00377     m_edit->setDate(QDate());
00378 }*/
00379 
00380 KEXI_CELLEDITOR_FACTORY_ITEM_IMPL(KexiDateEditorFactoryItem, KexiDateTableEdit)
00381 
00382 #include "kexidatetableedit.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys