summaryrefslogtreecommitdiffstats
path: root/kexi/widget/utils/kexidatetimeformatter.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/widget/utils/kexidatetimeformatter.cpp
downloadkoffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz
koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kexi/widget/utils/kexidatetimeformatter.cpp')
-rw-r--r--kexi/widget/utils/kexidatetimeformatter.cpp367
1 files changed, 367 insertions, 0 deletions
diff --git a/kexi/widget/utils/kexidatetimeformatter.cpp b/kexi/widget/utils/kexidatetimeformatter.cpp
new file mode 100644
index 00000000..d8f642ca
--- /dev/null
+++ b/kexi/widget/utils/kexidatetimeformatter.cpp
@@ -0,0 +1,367 @@
+/* This file is part of the KDE project
+ Copyright (C) 2006 Jaroslaw Staniek <[email protected]>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "kexidatetimeformatter.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kdatepicker.h>
+#include <kdatetbl.h>
+#include <klineedit.h>
+#include <kpopupmenu.h>
+#include <kdatewidget.h>
+
+KexiDateFormatter::KexiDateFormatter()
+{
+ // use "short date" format system settings
+//! @todo allow to override the format using column property and/or global app settings
+ QString df( KGlobal::locale()->dateFormatShort() );
+ if (df.length()>2)
+ m_separator = df.mid(2,1);
+ else
+ m_separator = "-";
+ const int separatorLen = m_separator.length();
+ QString yearMask("9999");
+ QString yearDateFormat("yyyy"),
+ monthDateFormat("MM"),
+ dayDateFormat("dd"); //for setting up m_dateFormat
+ bool ok = df.length()>=8;
+ int yearpos, monthpos, daypos; //result of df.find()
+ if (ok) {//look at % variables
+//! @todo more variables are possible here, see void KLocale::setDateFormatShort() docs
+//! http://developer.kde.org/documentation/library/3.5-api/kdelibs-apidocs/kdecore/html/classKLocale.html#a59
+ yearpos = df.find("%y", 0, false); //&y or %y
+ m_longYear = !(yearpos>=0 && df.mid(yearpos+1, 1)=="y");
+ if (!m_longYear) {
+ yearMask = "99";
+ yearDateFormat = "yy";
+ }
+ monthpos = df.find("%m", 0, true); //%m or %n
+ m_monthWithLeadingZero = true;
+ if (monthpos<0) {
+ monthpos = df.find("%n", 0, false);
+ m_monthWithLeadingZero = false;
+ monthDateFormat = "M";
+ }
+ daypos = df.find("%d", 0, true);//%d or %e
+ m_dayWithLeadingZero = true;
+ if (daypos<0) {
+ daypos = df.find("%e", 0, false);
+ m_dayWithLeadingZero = false;
+ dayDateFormat = "d";
+ }
+ ok = (yearpos>=0 && monthpos>=0 && daypos>=0);
+ }
+ m_order = QDateEdit::YMD; //default
+ if (ok) {
+ if (yearpos<monthpos && monthpos<daypos) {
+ //will be set in "default: YMD"
+ }
+ else if (yearpos<daypos && daypos<monthpos) {
+ m_order = QDateEdit::YDM;
+//! @todo use QRegExp (to replace %Y by %1, etc.) instead of hardcoded "%1%299%399"
+//! because df may contain also other characters
+ m_inputMask = QString("%1%299%399").arg(yearMask).arg(m_separator).arg(m_separator);
+ m_qtFormat = yearDateFormat+m_separator+dayDateFormat+m_separator+monthDateFormat;
+ m_yearpos = 0;
+ m_daypos = yearMask.length()+separatorLen;
+ m_monthpos = m_daypos+2+separatorLen;
+ }
+ else if (daypos<monthpos && monthpos<yearpos) {
+ m_order = QDateEdit::DMY;
+ m_inputMask = QString("99%199%2%3").arg(m_separator).arg(m_separator).arg(yearMask);
+ m_qtFormat = dayDateFormat+m_separator+monthDateFormat+m_separator+yearDateFormat;
+ m_daypos = 0;
+ m_monthpos = 2+separatorLen;
+ m_yearpos = m_monthpos+2+separatorLen;
+ }
+ else if (monthpos<daypos && daypos<yearpos) {
+ m_order = QDateEdit::MDY;
+ m_inputMask = QString("99%199%2%3").arg(m_separator).arg(m_separator).arg(yearMask);
+ m_qtFormat = monthDateFormat+m_separator+dayDateFormat+m_separator+yearDateFormat;
+ m_monthpos = 0;
+ m_daypos = 2+separatorLen;
+ m_yearpos = m_daypos+2+separatorLen;
+ }
+ else
+ ok = false;
+ }
+ if (!ok || m_order == QDateEdit::YMD) {//default: YMD
+ m_inputMask = QString("%1%299%399").arg(yearMask).arg(m_separator).arg(m_separator);
+ m_qtFormat = yearDateFormat+m_separator+monthDateFormat+m_separator+dayDateFormat;
+ m_yearpos = 0;
+ m_monthpos = yearMask.length()+separatorLen;
+ m_daypos = m_monthpos+2+separatorLen;
+ }
+ m_inputMask += ";_";
+}
+
+KexiDateFormatter::~KexiDateFormatter()
+{
+}
+
+QDate KexiDateFormatter::stringToDate( const QString& str ) const
+{
+ bool ok = true;
+ int year = str.mid(m_yearpos, m_longYear ? 4 : 2).toInt(&ok);
+ if (!ok)
+ return QDate();
+ if (year < 30) {//2000..2029
+ year = 2000 + year;
+ }
+ else if (year < 100) {//1930..1999
+ year = 1900 + year;
+ }
+
+ int month = str.mid(m_monthpos, 2).toInt(&ok);
+ if (!ok)
+ return QDate();
+
+ int day = str.mid(m_daypos, 2).toInt(&ok);
+ if (!ok)
+ return QDate();
+
+ QDate date(year, month, day);
+ if (!date.isValid())
+ return QDate();
+ return date;
+}
+
+QVariant KexiDateFormatter::stringToVariant( const QString& str ) const
+{
+ if (isEmpty(str))
+ return QVariant();
+ const QDate date( stringToDate( str ) );
+ if (date.isValid())
+ return date;
+ return QVariant();
+}
+
+bool KexiDateFormatter::isEmpty( const QString& str ) const
+{
+ QString s(str);
+ return s.replace(m_separator,"").stripWhiteSpace().isEmpty();
+}
+
+QString KexiDateFormatter::dateToString( const QDate& date ) const
+{
+ return date.toString(m_qtFormat);
+}
+
+//------------------------------------------------
+
+KexiTimeFormatter::KexiTimeFormatter()
+: m_hmsRegExp( new QRegExp("(\\d*):(\\d*):(\\d*).*( am| pm){,1}", false/*!CS*/) )
+ , m_hmRegExp( new QRegExp("(\\d*):(\\d*).*( am| pm){,1}", false/*!CS*/) )
+{
+ QString tf( KGlobal::locale()->timeFormat() );
+ //m_hourpos, m_minpos, m_secpos; are result of tf.find()
+ QString hourVariable, minVariable, secVariable;
+
+ //detect position of HOUR section: find %H or %k or %I or %l
+ m_24h = true;
+ m_hoursWithLeadingZero = true;
+ m_hourpos = tf.find("%H", 0, true);
+ if (m_hourpos>=0) {
+ m_24h = true;
+ m_hoursWithLeadingZero = true;
+ }
+ else {
+ m_hourpos = tf.find("%k", 0, true);
+ if (m_hourpos>=0) {
+ m_24h = true;
+ m_hoursWithLeadingZero = false;
+ }
+ else {
+ m_hourpos = tf.find("%I", 0, true);
+ if (m_hourpos>=0) {
+ m_24h = false;
+ m_hoursWithLeadingZero = true;
+ }
+ else {
+ m_hourpos = tf.find("%l", 0, true);
+ if (m_hourpos>=0) {
+ m_24h = false;
+ m_hoursWithLeadingZero = false;
+ }
+ }
+ }
+ }
+ m_minpos = tf.find("%M", 0, true);
+ m_secpos = tf.find("%S", 0, true); //can be -1
+ m_ampmpos = tf.find("%p", 0, true); //can be -1
+
+ if (m_hourpos<0 || m_minpos<0) {
+ //set default: hr and min are needed, sec are optional
+ tf = "%H:%M:%S";
+ m_24h = true;
+ m_hoursWithLeadingZero = false;
+ m_hourpos = 0;
+ m_minpos = 3;
+ m_secpos = m_minpos + 3;
+ m_ampmpos = -1;
+ }
+ hourVariable = tf.mid(m_hourpos, 2);
+
+ m_inputMask = tf;
+// m_inputMask.replace( hourVariable, "00" );
+// m_inputMask.replace( "%M", "00" );
+// m_inputMask.replace( "%S", "00" ); //optional
+ m_inputMask.replace( hourVariable, "99" );
+ m_inputMask.replace( "%M", "99" );
+ m_inputMask.replace( "%S", "00" ); //optional
+ m_inputMask.replace( "%p", "AA" ); //am or pm
+ m_inputMask += ";_";
+
+ m_outputFormat = tf;
+}
+
+KexiTimeFormatter::~KexiTimeFormatter()
+{
+ delete m_hmsRegExp;
+ delete m_hmRegExp;
+}
+
+QTime KexiTimeFormatter::stringToTime( const QString& str ) const
+{
+ int hour, min, sec;
+ bool pm = false;
+
+ bool tryWithoutSeconds = true;
+ if (m_secpos>=0) {
+ if (-1 != m_hmsRegExp->search(str)) {
+ hour = m_hmsRegExp->cap(1).toInt();
+ min = m_hmsRegExp->cap(2).toInt();
+ sec = m_hmsRegExp->cap(3).toInt();
+ if (m_ampmpos >= 0 && m_hmsRegExp->numCaptures()>3)
+ pm = m_hmsRegExp->cap(4).stripWhiteSpace().lower()=="pm";
+ tryWithoutSeconds = false;
+ }
+ }
+ if (tryWithoutSeconds) {
+ if (-1 == m_hmRegExp->search(str))
+ return QTime(99,0,0);
+ hour = m_hmRegExp->cap(1).toInt();
+ min = m_hmRegExp->cap(2).toInt();
+ sec = 0;
+ if (m_ampmpos >= 0 && m_hmRegExp->numCaptures()>2)
+ pm = m_hmsRegExp->cap(4).lower()=="pm";
+ }
+
+ if (pm && hour < 12)
+ hour += 12; //PM
+ return QTime(hour, min, sec);
+}
+
+QVariant KexiTimeFormatter::stringToVariant( const QString& str )
+{
+ if (isEmpty( str ))
+ return QVariant();
+ const QTime time( stringToTime( str ) );
+ if (time.isValid())
+ return time;
+ return QVariant();
+}
+
+bool KexiTimeFormatter::isEmpty( const QString& str ) const
+{
+ QString s(str);
+ return s.replace(':',"").stripWhiteSpace().isEmpty();
+}
+
+QString KexiTimeFormatter::timeToString( const QTime& time ) const
+{
+ if (!time.isValid())
+ return QString::null;
+
+ QString s(m_outputFormat);
+ if (m_24h) {
+ if (m_hoursWithLeadingZero)
+ s.replace( "%H", QString::fromLatin1(time.hour()<10 ? "0" : "") + QString::number(time.hour()) );
+ else
+ s.replace( "%k", QString::number(time.hour()) );
+ }
+ else {
+ int time12 = (time.hour()>12) ? (time.hour()-12) : time.hour();
+ if (m_hoursWithLeadingZero)
+ s.replace( "%I", QString::fromLatin1(time12<10 ? "0" : "") + QString::number(time12) );
+ else
+ s.replace( "%l", QString::number(time12) );
+ }
+ s.replace( "%M", QString::fromLatin1(time.minute()<10 ? "0" : "") + QString::number(time.minute()) );
+ if (m_secpos>=0)
+ s.replace( "%S", QString::fromLatin1(time.second()<10 ? "0" : "") + QString::number(time.second()) );
+ if (m_ampmpos>=0)
+ s.replace( "%p", KGlobal::locale()->translate( time.hour()>=12 ? "pm" : "am") );
+ return s;
+}
+
+//------------------------------------------------
+
+QString dateTimeInputMask(const KexiDateFormatter& dateFormatter, const KexiTimeFormatter& timeFormatter)
+{
+ QString mask(dateFormatter.inputMask());
+ mask.truncate(dateFormatter.inputMask().length()-2);
+ return mask + " " + timeFormatter.inputMask();
+}
+
+QDateTime stringToDateTime(
+ const KexiDateFormatter& dateFormatter, const KexiTimeFormatter& timeFormatter, const QString& str)
+{
+ QString s( str.stripWhiteSpace() );
+ const int timepos = s.find(" ");
+ const bool emptyTime = timepos >= 0 && timeFormatter.isEmpty(s.mid(timepos+1)); //.replace(':',"").stripWhiteSpace().isEmpty();
+ if (emptyTime)
+ s = s.left(timepos);
+ if (timepos>0 && !emptyTime) {
+ return QDateTime(
+ dateFormatter.stringToDate( s.left(timepos) ),
+ timeFormatter.stringToTime( s.mid(timepos+1) )
+ );
+ }
+ else {
+ return QDateTime(
+ dateFormatter.stringToDate( s ),
+ QTime(0,0,0)
+ );
+ }
+}
+
+bool dateTimeIsEmpty( const KexiDateFormatter& dateFormatter, const KexiTimeFormatter& timeFormatter,
+ const QString& str )
+{
+ int timepos = str.find(" ");
+ const bool emptyTime = timepos >= 0 && timeFormatter.isEmpty(str.mid(timepos+1)); //s.mid(timepos+1).replace(':',"").stripWhiteSpace().isEmpty();
+ return (timepos >= 0 && dateFormatter.isEmpty(str.left(timepos)) //s.left(timepos).replace(m_dateFormatter.separator(), "").stripWhiteSpace().isEmpty()
+ && emptyTime);
+}
+
+bool dateTimeIsValid( const KexiDateFormatter& dateFormatter,
+ const KexiTimeFormatter& timeFormatter, const QString& str )
+{
+ int timepos = str.find(" ");
+ const bool emptyTime = timepos >= 0 && timeFormatter.isEmpty(str.mid(timepos+1)); //s.mid(timepos+1).replace(':',"").stripWhiteSpace().isEmpty();
+ if (timepos >= 0 && dateFormatter.isEmpty(str.left(timepos)) // s.left(timepos).replace(m_dateFormatter.separator(), "").stripWhiteSpace().isEmpty()
+ && emptyTime)
+ //empty date/time is valid
+ return true;
+ return timepos>=0 && dateFormatter.stringToDate( str.left(timepos) ).isValid()
+ && (emptyTime /*date without time is also valid*/ || timeFormatter.stringToTime( str.mid(timepos+1) ).isValid());
+}