Index: kexi/plugins/importexport/csv/kexicsvimportoptionsdlg.h =================================================================== --- kexi/plugins/importexport/csv/kexicsvimportoptionsdlg.h (revision 805879) +++ kexi/plugins/importexport/csv/kexicsvimportoptionsdlg.h (working copy) @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2005 Jaroslaw Staniek + Copyright (C) 2005-2008 Jaroslaw Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -24,6 +24,7 @@ #include class KexiCharacterEncodingComboBox; +class QComboBox; //! @short CSV Options class KexiCSVImportOptions @@ -32,12 +33,21 @@ KexiCSVImportOptions(); ~KexiCSVImportOptions(); + //! Date format values + enum DateFormat { + AutoDateFormat = 0, //!< auto + DMY = 1, //!< day-month-year + YMD = 2, //!< year-month-day + MDY = 3 //!< month-day-year + }; + bool operator== ( const KexiCSVImportOptions & opt ) const; bool operator!= ( const KexiCSVImportOptions & opt ) const; QString encoding; - bool defaultEncodingExplicitySet; - bool stripWhiteSpaceInTextValuesChecked; + DateFormat dateFormat; + bool defaultEncodingExplicitySet : 1; + bool stripWhiteSpaceInTextValuesChecked : 1; }; //! @short CSV Options dialog @@ -57,6 +67,7 @@ KexiCharacterEncodingComboBox *m_encodingComboBox; QCheckBox *m_chkAlwaysUseThisEncoding; QCheckBox *m_chkStripWhiteSpaceInTextValues; + QComboBox *m_comboDateFormat; }; #endif Index: kexi/plugins/importexport/csv/kexicsvimportdialog.cpp =================================================================== --- kexi/plugins/importexport/csv/kexicsvimportdialog.cpp (revision 805879) +++ kexi/plugins/importexport/csv/kexicsvimportdialog.cpp (working copy) @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2005-2006 Jaroslaw Staniek + Copyright (C) 2005-2008 Jaroslaw Staniek This work is based on kspread/dialogs/kspread_dlg_csv.cc and will be merged back with KOffice libraries. @@ -299,7 +299,9 @@ m_dateRegExp = QRegExp("(\\d{1,4})([/\\-\\.])(\\d{1,2})([/\\-\\.])(\\d{1,4})"); m_timeRegExp1 = QRegExp("(\\d{1,2}):(\\d{1,2}):(\\d{1,2})"); m_timeRegExp2 = QRegExp("(\\d{1,2}):(\\d{1,2})"); - m_fpNumberRegExp = QRegExp("[\\-]{0,1}\\d*[,\\.]\\d+"); + m_fpNumberRegExp1 = QRegExp("[\\-]{0,1}\\d*[,\\.]\\d+"); + // E notation, e.g. 0.1e2, 0.1e+2, 0.1e-2, 0.1E2, 0.1E+2, 0.1E-2 + m_fpNumberRegExp2 = QRegExp("[\\-]{0,1}\\d*[,\\.]\\d+[Ee][+-]{0,1}\\d+"); QString caption( i18n("Open CSV Data File") ); if (m_mode == File) { @@ -974,9 +976,7 @@ //detect type because it's 1st row or all prev. rows were not text //-FP number? (trying before "number" type is a must) if (!found && (row==1 || type==_NUMBER_TYPE || type==_FP_NUMBER_TYPE || type==_NO_TYPE_YET)) { - bool ok = text.isEmpty() || m_fpNumberRegExp.exactMatch(text); - //if (!ok) - // text.toDouble(&ok); + bool ok = text.isEmpty() || m_fpNumberRegExp1.exactMatch(text) || m_fpNumberRegExp2.exactMatch(text); if (ok && (row==1 || type==_NUMBER_TYPE || type==_FP_NUMBER_TYPE || type==_NO_TYPE_YET)) { m_detectedTypes[col]=_FP_NUMBER_TYPE; found = true; //yes @@ -1064,13 +1064,22 @@ //dddd - dd - dddd //1 2 3 4 5 <- pos const int d1 = m_dateRegExp.cap(1).toInt(), d3 = m_dateRegExp.cap(3).toInt(), d5 = m_dateRegExp.cap(5).toInt(); - if (m_dateRegExp.cap(2)=="/") //probably separator for american format mm/dd/yyyy - date = QDate(d5, d1, d3); - else { - if (d5 > 31) //d5 == year - date = QDate(d5, d3, d1); - else //d1 == year - date = QDate(d1, d3, d5); + switch (m_options.dateFormat) { + case KexiCSVImportOptions::DMY: date = QDate(d5, d3, d1); break; + case KexiCSVImportOptions::YMD: date = QDate(d1, d3, d5); break; + case KexiCSVImportOptions::MDY: date = QDate(d5, d1, d3); break; + case KexiCSVImportOptions::AutoDateFormat: + if (m_dateRegExp.cap(2) == "/") { //probably separator for american format mm/dd/yyyy + date = QDate(d5, d1, d3); + } + else { + if (d5 > 31) //d5 == year + date = QDate(d5, d3, d1); + else //d1 == year + date = QDate(d1, d3, d5); + } + break; + default:; } return date.isValid(); } @@ -1090,6 +1099,9 @@ void KexiCSVImportDialog::setText(int row, int col, const QString& text, bool inGUI) { if (!inGUI) { + if (row==1 && m_1stRowForFieldNames->isChecked()) + return; // do not care about this value if it contains column names (these were already used) + //save text directly to database buffer if (col==1) { //1st col m_importingStatement->clearArguments(); @@ -1117,11 +1129,15 @@ QDate date; if (parseDate(text, date)) *m_importingStatement << date; + else + *m_importingStatement << QVariant(); } else if (detectedType==_TIME_TYPE) { QTime time; if (parseTime(text, time)) *m_importingStatement << time; + else + *m_importingStatement << QVariant(); } else if (detectedType==_DATETIME_TYPE) { QStringList dateTimeList( QStringList::split(" ", text) ); @@ -1136,8 +1152,14 @@ QTime time; if (parseTime(timePart, time)) *m_importingStatement << QDateTime(date, time); + else + *m_importingStatement << QVariant(); } + else + *m_importingStatement << QVariant(); } + else + *m_importingStatement << QVariant(); } else //_TEXT_TYPE and the rest *m_importingStatement << (m_options.stripWhiteSpaceInTextValuesChecked ? text.stripWhiteSpace() : text); @@ -1452,9 +1474,9 @@ KexiDB::Field::Type fieldType; if (detectedType==_DATE_TYPE) fieldType = KexiDB::Field::Date; - if (detectedType==_TIME_TYPE) + else if (detectedType==_TIME_TYPE) fieldType = KexiDB::Field::Time; - if (detectedType==_DATETIME_TYPE) + else if (detectedType==_DATETIME_TYPE) fieldType = KexiDB::Field::DateTime; else if (detectedType==_NUMBER_TYPE) fieldType = KexiDB::Field::Integer; Index: kexi/plugins/importexport/csv/kexicsvimportoptionsdlg.cpp =================================================================== --- kexi/plugins/importexport/csv/kexicsvimportoptionsdlg.cpp (revision 805879) +++ kexi/plugins/importexport/csv/kexicsvimportoptionsdlg.cpp (working copy) @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2005-2006 Jaroslaw Staniek + Copyright (C) 2005-2008 Jaroslaw Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -32,10 +33,33 @@ #include #include +KexiCSVImportOptions::DateFormat dateFormatFromString( const QString& s ) +{ + QString str( s.lower().stripWhiteSpace() ); + if (str == "dmy") + return KexiCSVImportOptions::DMY; + if (str == "ymd") + return KexiCSVImportOptions::YMD; + if (str == "mdy") + return KexiCSVImportOptions::MDY; + return KexiCSVImportOptions::AutoDateFormat; +} + +QString dateFormatToString( KexiCSVImportOptions::DateFormat format ) +{ + switch (format) { + case KexiCSVImportOptions::DMY: return "DMY"; + case KexiCSVImportOptions::YMD: return "YMD"; + case KexiCSVImportOptions::MDY: return "MDY"; + default: break; + } + return QString::null; +} + KexiCSVImportOptions::KexiCSVImportOptions() { - kapp->config()->setGroup("ImportExport"); - encoding = kapp->config()->readEntry("DefaultEncodingForImportingCSVFiles"); + KConfigGroup cg( kapp->config(), "ImportExport" ); + encoding = cg.readEntry("DefaultEncodingForImportingCSVFiles"); if (encoding.isEmpty()) { encoding = QString::fromLatin1(KGlobal::locale()->encoding()); defaultEncodingExplicitySet = false; @@ -43,8 +67,9 @@ else defaultEncodingExplicitySet = true; - stripWhiteSpaceInTextValuesChecked - = kapp->config()->readBoolEntry("StripBlanksOffOfTextValuesWhenImportingCSVFiles", true); + dateFormat = dateFormatFromString( cg.readEntry("DateFormatWhenImportingCSVFiles") ); + + stripWhiteSpaceInTextValuesChecked = cg.readBoolEntry("StripBlanksOffOfTextValuesWhenImportingCSVFiles", true); } KexiCSVImportOptions::~KexiCSVImportOptions() @@ -55,7 +80,8 @@ { return defaultEncodingExplicitySet==opt.defaultEncodingExplicitySet && stripWhiteSpaceInTextValuesChecked==opt.stripWhiteSpaceInTextValuesChecked - && encoding==opt.encoding; + && encoding==opt.encoding + && dateFormat==opt.dateFormat; } bool KexiCSVImportOptions::operator!= ( const KexiCSVImportOptions & opt ) const @@ -78,32 +104,54 @@ false ) { - QGridLayout *lyr = new QGridLayout( plainPage(), 5, 3, - KDialogBase::marginHint(), KDialogBase::spacingHint()); + QGridLayout *lyr = new QGridLayout( plainPage(), 4, 3, + 0, KDialogBase::spacingHint()); - m_encodingComboBox = new KexiCharacterEncodingComboBox(plainPage(), options.encoding); - lyr->addWidget( m_encodingComboBox, 0, 1 ); +//! @todo fix i18n here + QGroupBox* textEncodingGroupBox = new QGroupBox( + i18n("Text encoding:").replace(":", "") /* a hack to avoid adding new string */, plainPage() ); + lyr->addMultiCellWidget( textEncodingGroupBox, 0, 0, 0, 1 ); + QVBoxLayout* textEncodingGroupBoxLyr = new QVBoxLayout( textEncodingGroupBox, KDialogBase::spacingHint(), KDialogBase::spacingHint() ); + textEncodingGroupBoxLyr->addItem( new QSpacerItem( 20, 15, QSizePolicy::Fixed, QSizePolicy::Fixed ) ); - QLabel* lbl = new QLabel( m_encodingComboBox, i18n("Text encoding:"), plainPage()); + m_encodingComboBox = new KexiCharacterEncodingComboBox(textEncodingGroupBox, options.encoding); + textEncodingGroupBoxLyr->addWidget( m_encodingComboBox ); + +/* QLabel* lbl = new QLabel( m_encodingComboBox, i18n("Text encoding:"), plainPage()); lyr->addWidget( lbl, 0, 0 ); - lyr->addItem( new QSpacerItem( 20, KDialogBase::spacingHint(), QSizePolicy::Fixed, QSizePolicy::Fixed ), 2, 1 ); - lyr->addItem( new QSpacerItem( 121, KDialogBase::spacingHint(), QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 ); + lyr->addItem( new QSpacerItem( 20, KDialogBase::spacingHint(), QSizePolicy::Fixed, QSizePolicy::Fixed ), 2, 1 );*/ + lyr->addItem( new QSpacerItem( 20, KDialogBase::spacingHint(), QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 ); m_chkAlwaysUseThisEncoding = new QCheckBox( - i18n("Always use this encoding when importing CSV data files"), plainPage()); - lyr->addWidget( m_chkAlwaysUseThisEncoding, 1, 1 ); + i18n("Always use this encoding when importing CSV data files"), textEncodingGroupBox); + textEncodingGroupBoxLyr->addWidget( m_chkAlwaysUseThisEncoding ); + m_comboDateFormat = new QComboBox( plainPage() ); + m_comboDateFormat->setName( "m_comboDateFormat" ); +// m_comboDateFormat->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); + m_comboDateFormat->insertItem( i18n("Date format: Auto", "Auto") ); + QString year( i18n("year") ), month( i18n("month") ), day( i18n("day") ); + QString mask( i18n("\"month, year, day\" mask", "%1, %2, %3 (e.g. %4-%5-%6)") ); + m_comboDateFormat->insertItem( mask.arg(day).arg(month).arg(year).arg(30).arg(12).arg(2008) ); + m_comboDateFormat->insertItem( mask.arg(year).arg(month).arg(day).arg(2008).arg(12).arg(30) ); + m_comboDateFormat->insertItem( mask.arg(month).arg(day).arg(year).arg(12).arg(30).arg(2008) ); + lyr->addWidget( m_comboDateFormat, 1, 1 ); + + QLabel* lblDateFormat = new QLabel( m_comboDateFormat, i18n("Date format:"), plainPage()); + lyr->addWidget( lblDateFormat, 1, 0 ); + m_chkStripWhiteSpaceInTextValues = new QCheckBox( i18n("Strip leading and trailing blanks off of text values"), plainPage()); - lyr->addWidget( m_chkStripWhiteSpaceInTextValues, 3, 1 ); - lyr->addItem( new QSpacerItem( 20, KDialogBase::spacingHint(), QSizePolicy::Minimum, QSizePolicy::Expanding ), 4, 1 ); + lyr->addMultiCellWidget( m_chkStripWhiteSpaceInTextValues, 2, 2, 0, 1 ); + lyr->addItem( new QSpacerItem( 30, KDialogBase::spacingHint(), QSizePolicy::Minimum, QSizePolicy::Expanding ), 3, 0 ); //update widgets if (options.defaultEncodingExplicitySet) { m_encodingComboBox->setSelectedEncoding(options.encoding); m_chkAlwaysUseThisEncoding->setChecked(true); } + m_comboDateFormat->setCurrentItem( (int)options.dateFormat ); m_chkStripWhiteSpaceInTextValues->setChecked(options.stripWhiteSpaceInTextValuesChecked); adjustSize(); @@ -124,14 +172,21 @@ void KexiCSVImportOptionsDialog::accept() { - kapp->config()->setGroup("ImportExport"); + KConfigGroup cg( kapp->config(), "ImportExport" ); if (m_chkAlwaysUseThisEncoding->isChecked()) - kapp->config()->writeEntry("DefaultEncodingForImportingCSVFiles", + cg.writeEntry("DefaultEncodingForImportingCSVFiles", m_encodingComboBox->selectedEncoding()); else - kapp->config()->deleteEntry("DefaultEncodingForImportingCSVFiles"); + cg.deleteEntry("DefaultEncodingForImportingCSVFiles"); - kapp->config()->writeEntry("StripBlanksOffOfTextValuesWhenImportingCSVFiles", + const KexiCSVImportOptions::DateFormat dateFormat + = (KexiCSVImportOptions::DateFormat)m_comboDateFormat->currentItem(); + if (dateFormat == KexiCSVImportOptions::AutoDateFormat) + cg.deleteEntry("DateFormatWhenImportingCSVFiles"); + else + cg.writeEntry("DateFormatWhenImportingCSVFiles", dateFormatToString( dateFormat )); + + cg.writeEntry("StripBlanksOffOfTextValuesWhenImportingCSVFiles", m_chkStripWhiteSpaceInTextValues->isChecked()); KDialogBase::accept(); Index: kexi/plugins/importexport/csv/kexicsvimportdialog.h =================================================================== --- kexi/plugins/importexport/csv/kexicsvimportdialog.h (revision 805879) +++ kexi/plugins/importexport/csv/kexicsvimportdialog.h (working copy) @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2005-2006 Jaroslaw Staniek + Copyright (C) 2005-2008 Jaroslaw Staniek This work is based on kspread/dialogs/kspread_dlg_csv.cc and will be merged back with KOffice libraries. @@ -186,7 +186,7 @@ //! (only for numeric type) QPtrVector< QValueList > m_uniquenessTest; - QRegExp m_dateRegExp, m_timeRegExp1, m_timeRegExp2, m_fpNumberRegExp; + QRegExp m_dateRegExp, m_timeRegExp1, m_timeRegExp2, m_fpNumberRegExp1, m_fpNumberRegExp2; QValueVector m_typeNames, m_columnNames; QBitArray m_changedColumnNames; bool m_columnsAdjusted : 1; //!< to call adjustColumn() only once