File indexing completed on 2024-05-12 15:27:45

0001 /***************************************************************************
0002     File                 : AsciiOptionsWidget.h
0003     Project              : LabPlot
0004     Description          : widget providing options for the import of ascii data
0005     --------------------------------------------------------------------
0006     Copyright            : (C) 2009-2017 Stefan Gerlach (stefan.gerlach@uni.kn)
0007     Copyright            : (C) 2009-2019 Alexander Semke (alexander.semke@web.de)
0008 
0009  ***************************************************************************/
0010 
0011 /***************************************************************************
0012  *                                                                         *
0013  *  This program is free software; you can redistribute it and/or modify   *
0014  *  it under the terms of the GNU General Public License as published by   *
0015  *  the Free Software Foundation; either version 2 of the License, or      *
0016  *  (at your option) any later version.                                    *
0017  *                                                                         *
0018  *  This program is distributed in the hope that it will be useful,        *
0019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0021  *  GNU General Public License for more details.                           *
0022  *                                                                         *
0023  *   You should have received a copy of the GNU General Public License     *
0024  *   along with this program; if not, write to the Free Software           *
0025  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0026  *   Boston, MA  02110-1301  USA                                           *
0027  *                                                                         *
0028  ***************************************************************************/
0029 
0030 #include "AsciiOptionsWidget.h"
0031 #include "backend/datasources/filters/AbstractFileFilter.h"
0032 #include "backend/datasources/filters/AsciiFilter.h"
0033 #include "backend/lib/macros.h"
0034 
0035 #include <KLocalizedString>
0036 #include <KSharedConfig>
0037 #include <KConfigGroup>
0038 
0039 /*!
0040 \class AsciiOptionsWidget
0041 \brief Widget providing options for the import of ascii data
0042 
0043 \ingroup kdefrontend
0044 */
0045 AsciiOptionsWidget::AsciiOptionsWidget(QWidget* parent) : QWidget(parent) {
0046     ui.setupUi(parent);
0047 
0048     ui.cbSeparatingCharacter->addItems(AsciiFilter::separatorCharacters());
0049     ui.cbCommentCharacter->addItems(AsciiFilter::commentCharacters());
0050     ui.cbDecimalSeparator->addItem(i18n("Point '.'"));
0051     ui.cbDecimalSeparator->addItem(i18n("Comma ','"));
0052     ui.cbDateTimeFormat->addItems(AbstractColumn::dateTimeFormats());
0053 
0054     const QString textNumberFormatShort = i18n("This option determines how the imported strings have to be converted to numbers.");
0055     const QString textNumberFormat = textNumberFormatShort + "<br><br>" + i18n(
0056                                          "When point character is used for the decimal separator, the valid number representations are:"
0057                                          "<ul>"
0058                                          "<li>1234.56</li>"
0059                                          "<li>1,234.56</li>"
0060                                          "<li>etc.</li>"
0061                                          "</ul>"
0062                                          "For comma as the decimal separator, the valid number representations are:"
0063                                          "<ul>"
0064                                          "<li>1234,56</li>"
0065                                          "<li>1.234,56</li>"
0066                                          "<li>etc.</li>"
0067                                          "</ul>"
0068                                      );
0069 
0070     ui.lDecimalSeparator->setToolTip(textNumberFormatShort);
0071     ui.lDecimalSeparator->setWhatsThis(textNumberFormat);
0072     ui.cbDecimalSeparator->setToolTip(textNumberFormatShort);
0073     ui.cbDecimalSeparator->setWhatsThis(textNumberFormat);
0074 
0075     //only available for live data, will be activated explicitely
0076     ui.chbCreateTimestamp->setVisible(false);
0077 
0078     const QString textDateTimeFormatShort = i18n("This option determines how the imported strings have to be converted to calendar date, i.e. year, month, and day numbers in the Gregorian calendar and to time.");
0079     const QString textDateTimeFormat = textDateTimeFormatShort + "<br><br>" + i18n(
0080                                            "Expressions that may be used for the date part of format string:"
0081                                            "<table>"
0082                                            "<tr><td>d</td><td>the day as number without a leading zero (1 to 31).</td></tr>"
0083                                            "<tr><td>dd</td><td>the day as number with a leading zero (01 to 31).</td></tr>"
0084                                            "<tr><td>ddd</td><td>the abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses the system locale to localize the name.</td></tr>"
0085                                            "<tr><td>dddd</td><td>the long localized day name (e.g. 'Monday' to 'Sunday'). Uses the system locale to localize the name.</td></tr>"
0086                                            "<tr><td>M</td><td>the month as number without a leading zero (1 to 12).</td></tr>"
0087                                            "<tr><td>MM</td><td>the month as number with a leading zero (01 to 12).</td></tr>"
0088                                            "<tr><td>MMM</td><td>the abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses the system locale to localize the name.</td></tr>"
0089                                            "<tr><td>MMMM</td><td>the long localized month name (e.g. 'January' to 'December'). Uses the system locale to localize the name.</td></tr>"
0090                                            "<tr><td>yy</td><td>the year as two digit number (00 to 99).</td></tr>"
0091                                            "<tr><td>yyyy</td><td>the year as four digit number. If the year is negative, a minus sign is prepended in addition.</td></tr>"
0092                                            "</table><br><br>"
0093                                            "Expressions that may be used for the time part of the format string:"
0094                                            "<table>"
0095                                            "<tr><td>h</td><td>the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)</td></tr>"
0096                                            "<tr><td>hh</td><td>the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)</td></tr>"
0097                                            "<tr><td>H</td><td>the hour without a leading zero (0 to 23, even with AM/PM display)</td></tr>"
0098                                            "<tr><td>HH</td><td>the hour with a leading zero (00 to 23, even with AM/PM display)</td></tr>"
0099                                            "<tr><td>m</td><td>the minute without a leading zero (0 to 59)</td></tr>"
0100                                            "<tr><td>mm</td><td>the minute with a leading zero (00 to 59)</td></tr>"
0101                                            "<tr><td>s</td><td>the second without a leading zero (0 to 59)</td></tr>"
0102                                            "<tr><td>ss</td><td>the second with a leading zero (00 to 59)</td></tr>"
0103                                            "<tr><td>z</td><td>the milliseconds without leading zeroes (0 to 999)</td></tr>"
0104                                            "<tr><td>zzz</td><td>the milliseconds with leading zeroes (000 to 999)</td></tr>"
0105                                            "<tr><td>AP or A</td><td>interpret as an AM/PM time. AP must be either 'AM' or 'PM'.</td></tr>"
0106                                            "<tr><td>ap or a</td><td>Interpret as an AM/PM time. ap must be either 'am' or 'pm'.</td></tr>"
0107                                            "</table><br><br>"
0108                                            "Examples are:"
0109                                            "<table>"
0110                                            "<tr><td>dd.MM.yyyy</td><td>20.07.1969</td></tr>"
0111                                            "<tr><td>ddd MMMM d yy</td><td>Sun July 20 69</td></tr>"
0112                                            "<tr><td>'The day is' dddd</td><td>The day is Sunday</td></tr>"
0113                                            "</table>");
0114 
0115     ui.lDateTimeFormat->setToolTip(textDateTimeFormatShort);
0116     ui.lDateTimeFormat->setWhatsThis(textDateTimeFormat);
0117     ui.cbDateTimeFormat->setToolTip(textDateTimeFormatShort);
0118     ui.cbDateTimeFormat->setWhatsThis(textDateTimeFormat);
0119 
0120     connect(ui.chbHeader, &QCheckBox::stateChanged, this, &AsciiOptionsWidget::headerChanged);
0121 }
0122 
0123 void AsciiOptionsWidget::showAsciiHeaderOptions(bool visible) {
0124     DEBUG("AsciiOptionsWidget::showAsciiHeaderOptions(" << visible << ")");
0125     ui.chbHeader->setVisible(visible);
0126     if (visible) {
0127         ui.lVectorNames->setVisible(!ui.chbHeader->isChecked());
0128         ui.kleVectorNames->setVisible(!ui.chbHeader->isChecked());
0129     } else {
0130         ui.lVectorNames->setVisible(false);
0131         ui.kleVectorNames->setVisible(false);
0132     }
0133 }
0134 
0135 void AsciiOptionsWidget::showTimestampOptions(bool visible) {
0136     ui.chbCreateTimestamp->setVisible(visible);
0137 }
0138 
0139 /*!
0140   Shows a text field for the vector names if the option "Use the first row..." was not selected.
0141   Hides it otherwise.
0142 */
0143 void AsciiOptionsWidget::headerChanged(int state) {
0144     bool visible = (state != Qt::Checked);
0145     ui.kleVectorNames->setVisible(visible);
0146     ui.lVectorNames->setVisible(visible);
0147 }
0148 
0149 void AsciiOptionsWidget::applyFilterSettings(AsciiFilter* filter) const {
0150     Q_ASSERT(filter);
0151     filter->setCommentCharacter( ui.cbCommentCharacter->currentText() );
0152     filter->setSeparatingCharacter( ui.cbSeparatingCharacter->currentText() );
0153 
0154     //TODO: use general setting for decimal separator?
0155     QLocale::Language lang;
0156     if (ui.cbDecimalSeparator->currentIndex() == 0)
0157         lang = QLocale::Language::C;
0158     else
0159         lang = QLocale::Language::German;
0160     filter->setNumberFormat(lang);
0161     filter->setDateTimeFormat(ui.cbDateTimeFormat->currentText());
0162     filter->setCreateIndexEnabled( ui.chbCreateIndex->isChecked() );
0163 
0164     //save the timestamp option only if it's visible, i.e. live source is used.
0165     //use the default setting in the filter (false) otherwise for non-live source
0166     if (ui.chbCreateTimestamp->isVisible())
0167         filter->setCreateTimestampEnabled( ui.chbCreateTimestamp->isChecked() );
0168 
0169     filter->setSimplifyWhitespacesEnabled( ui.chbSimplifyWhitespaces->isChecked() );
0170     filter->setNaNValueToZero( ui.chbConvertNaNToZero->isChecked() );
0171     filter->setRemoveQuotesEnabled( ui.chbRemoveQuotes->isChecked() );
0172     filter->setSkipEmptyParts( ui.chbSkipEmptyParts->isChecked() );
0173     filter->setVectorNames( ui.kleVectorNames->text() );
0174     filter->setHeaderEnabled( ui.chbHeader->isChecked() );
0175 }
0176 
0177 void AsciiOptionsWidget::setSeparatingCharacter(QLatin1Char character) {
0178     ui.cbSeparatingCharacter->setCurrentItem(QString(character));
0179 }
0180 
0181 void AsciiOptionsWidget::loadSettings() const {
0182     KConfigGroup conf(KSharedConfig::openConfig(), "ImportAscii");
0183 
0184     ui.cbCommentCharacter->setCurrentText(conf.readEntry("CommentCharacter", "#"));
0185     ui.cbSeparatingCharacter->setCurrentItem(conf.readEntry("SeparatingCharacter", "auto"));
0186 
0187     //TODO: use general setting for decimal separator?
0188     const QChar decimalSeparator = QLocale().decimalPoint();
0189     int index = (decimalSeparator == '.') ? 0 : 1;
0190     ui.cbDecimalSeparator->setCurrentIndex(conf.readEntry("DecimalSeparator", index));
0191 
0192     ui.cbDateTimeFormat->setCurrentText(conf.readEntry("DateTimeFormat", "yyyy-MM-dd hh:mm:ss.zzz"));
0193     ui.chbCreateIndex->setChecked(conf.readEntry("CreateIndex", false));
0194     ui.chbCreateTimestamp->setChecked(conf.readEntry("CreateTimestamp", true));
0195     ui.chbSimplifyWhitespaces->setChecked(conf.readEntry("SimplifyWhitespaces", true));
0196     ui.chbConvertNaNToZero->setChecked(conf.readEntry("ConvertNaNToZero", false));
0197     ui.chbRemoveQuotes->setChecked(conf.readEntry("RemoveQuotes", false));
0198     ui.chbSkipEmptyParts->setChecked(conf.readEntry("SkipEmptyParts", false));
0199     ui.chbHeader->setChecked(conf.readEntry("UseFirstRow", true));
0200     ui.kleVectorNames->setText(conf.readEntry("Names", ""));
0201 }
0202 
0203 void AsciiOptionsWidget::saveSettings() {
0204     KConfigGroup conf(KSharedConfig::openConfig(), "ImportAscii");
0205 
0206     conf.writeEntry("CommentCharacter", ui.cbCommentCharacter->currentText());
0207     conf.writeEntry("SeparatingCharacter", ui.cbSeparatingCharacter->currentText());
0208     conf.writeEntry("DecimalSeparator", ui.cbDecimalSeparator->currentIndex());
0209     conf.writeEntry("DateTimeFormat", ui.cbDateTimeFormat->currentText());
0210     conf.writeEntry("CreateIndex", ui.chbCreateIndex->isChecked());
0211     conf.writeEntry("CreateTimestamp", ui.chbCreateTimestamp->isChecked());
0212     conf.writeEntry("SimplifyWhitespaces", ui.chbSimplifyWhitespaces->isChecked());
0213     conf.writeEntry("ConvertNaNToZero", ui.chbConvertNaNToZero->isChecked());
0214     conf.writeEntry("RemoveQuotes", ui.chbRemoveQuotes->isChecked());
0215     conf.writeEntry("SkipEmptyParts", ui.chbSkipEmptyParts->isChecked());
0216     conf.writeEntry("UseFirstRow", ui.chbHeader->isChecked());
0217     conf.writeEntry("Names", ui.kleVectorNames->text());
0218 }