File indexing completed on 2024-05-12 15:27:51
0001 /*************************************************************************** 0002 File : JsonOptionsWidget.cpp 0003 Project : LabPlot 0004 Description : Widget providing options for the import of json data. 0005 -------------------------------------------------------------------- 0006 -------------------------------------------------------------------- 0007 Copyright : (C) 2018 Andrey Cygankov (craftplace.ms@gmail.com) 0008 Copyright : (C) 2018-2020 by Alexander Semke (alexander.semke@web.de) 0009 0010 ***************************************************************************/ 0011 0012 /*************************************************************************** 0013 * * 0014 * This program is free software; you can redistribute it and/or modify * 0015 * it under the terms of the GNU General Public License as published by * 0016 * the Free Software Foundation; either version 2 of the License, or * 0017 * (at your option) any later version. * 0018 * * 0019 * This program is distributed in the hope that it will be useful, * 0020 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0022 * GNU General Public License for more details. * 0023 * * 0024 * You should have received a copy of the GNU General Public License * 0025 * along with this program; if not, write to the Free Software * 0026 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0027 * Boston, MA 02110-1301 USA * 0028 * * 0029 ***************************************************************************/ 0030 0031 #include "JsonOptionsWidget.h" 0032 #include "ImportFileWidget.h" 0033 #include "backend/datasources/filters/QJsonModel.h" 0034 #include "backend/datasources/filters/AbstractFileFilter.h" 0035 #include "backend/datasources/filters/JsonFilter.h" 0036 #include "backend/lib/trace.h" 0037 0038 #include <KLocalizedString> 0039 #include <KFilterDev> 0040 #include <KSharedConfig> 0041 #include <KConfigGroup> 0042 0043 /*! 0044 \class JsonOptionsWidget 0045 \brief Widget providing options for the import of json data 0046 0047 \ingroup kdefrontend 0048 */ 0049 JsonOptionsWidget::JsonOptionsWidget(QWidget* parent, ImportFileWidget* fileWidget) : QWidget(parent), 0050 m_fileWidget(fileWidget), 0051 m_model(new QJsonModel()) { 0052 0053 ui.setupUi(parent); 0054 0055 ui.cbDecimalSeparator->addItem(i18n("Point '.'")); 0056 ui.cbDecimalSeparator->addItem(i18n("Comma ','")); 0057 ui.cbDateTimeFormat->addItems(AbstractColumn::dateTimeFormats()); 0058 0059 setTooltips(); 0060 } 0061 0062 void JsonOptionsWidget::applyFilterSettings(JsonFilter* filter, const QModelIndex& index) const { 0063 Q_ASSERT(filter); 0064 0065 filter->setModel(m_model); 0066 filter->setModelRows(getIndexRows(index)); 0067 0068 QLocale::Language lang; 0069 if (ui.cbDecimalSeparator->currentIndex() == 0) 0070 lang = QLocale::Language::C; 0071 else 0072 lang = QLocale::Language::German; 0073 filter->setNumberFormat(lang); 0074 0075 filter->setDateTimeFormat(ui.cbDateTimeFormat->currentText()); 0076 filter->setCreateIndexEnabled(ui.chbCreateIndex->isChecked()); 0077 filter->setNaNValueToZero(ui.chbConvertNaNToZero->isChecked()); 0078 filter->setImportObjectNames(ui.chbImportObjectNames->isChecked()); 0079 0080 //TODO: change this after implementation other row types 0081 filter->setDataRowType(QJsonValue::Array); 0082 if (!index.isValid()) return; 0083 auto* item = static_cast<QJsonTreeItem*>(index.internalPointer()); 0084 if (item->childCount() < 1) return; 0085 filter->setDataRowType(item->child(0)->type()); 0086 } 0087 0088 void JsonOptionsWidget::clearModel() { 0089 m_model->clear(); 0090 m_filename.clear(); 0091 } 0092 0093 void JsonOptionsWidget::loadSettings() const { 0094 KConfigGroup conf(KSharedConfig::openConfig(), "ImportJson"); 0095 0096 const QChar decimalSeparator = QLocale().decimalPoint(); 0097 int index = (decimalSeparator == '.') ? 0 : 1; 0098 ui.cbDecimalSeparator->setCurrentIndex(conf.readEntry("DecimalSeparator", index)); 0099 0100 ui.cbDateTimeFormat->setCurrentItem(conf.readEntry("DateTimeFormat", "yyyy-MM-dd hh:mm:ss.zzz")); 0101 ui.chbCreateIndex->setChecked(conf.readEntry("CreateIndex", false)); 0102 ui.chbConvertNaNToZero->setChecked(conf.readEntry("ConvertNaNToZero", false)); 0103 ui.chbImportObjectNames->setChecked(conf.readEntry("ParseRowsName", false)); 0104 } 0105 0106 void JsonOptionsWidget::saveSettings() { 0107 KConfigGroup conf(KSharedConfig::openConfig(), "ImportJson"); 0108 0109 conf.writeEntry("DecimalSeparator", ui.cbDecimalSeparator->currentIndex()); 0110 conf.writeEntry("DateTimeFormat", ui.cbDateTimeFormat->currentText()); 0111 conf.writeEntry("CreateIndex", ui.chbCreateIndex->isChecked()); 0112 conf.writeEntry("ConvertNaNToZero", ui.chbConvertNaNToZero->isChecked()); 0113 conf.writeEntry("ParseRowsName", ui.chbImportObjectNames->isChecked()); 0114 } 0115 0116 void JsonOptionsWidget::loadDocument(const QString& filename) { 0117 PERFTRACE("JsonOptionsWidget::loadDocument"); 0118 if (m_filename == filename) return; 0119 else 0120 m_filename = filename; 0121 0122 KFilterDev device(m_filename); 0123 m_model->clear(); 0124 if (!device.open(QIODevice::ReadOnly) || 0125 (device.atEnd() && !device.isSequential()) || // empty file 0126 !m_model->loadJson(device.readAll()) 0127 ) 0128 clearModel(); 0129 } 0130 0131 QAbstractItemModel* JsonOptionsWidget::model() { 0132 return m_model; 0133 } 0134 0135 void JsonOptionsWidget::setTooltips() { 0136 const QString textNumberFormatShort = i18n("This option determines how the imported strings have to be converted to numbers."); 0137 const QString textNumberFormat = textNumberFormatShort + "<br><br>" + i18n( 0138 "For 'C Format', a period is used for the decimal point character and comma is used for the thousands group separator. " 0139 "Valid number representations are:" 0140 "<ul>" 0141 "<li>1234.56</li>" 0142 "<li>1,234.56</li>" 0143 "<li>etc.</li>" 0144 "</ul>" 0145 "When using 'System locale', the system settings will be used. " 0146 "E.g., for the German local the valid number representations are:" 0147 "<ul>" 0148 "<li>1234,56</li>" 0149 "<li>1.234,56</li>" 0150 "<li>etc.</li>" 0151 "</ul>" 0152 ); 0153 0154 ui.lDecimalSeparator->setToolTip(textNumberFormatShort); 0155 ui.lDecimalSeparator->setWhatsThis(textNumberFormat); 0156 ui.cbDecimalSeparator->setToolTip(textNumberFormatShort); 0157 ui.cbDecimalSeparator->setWhatsThis(textNumberFormat); 0158 0159 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."); 0160 const QString textDateTimeFormat = textDateTimeFormatShort + "<br><br>" + i18n( 0161 "Expressions that may be used for the date part of format string:" 0162 "<table>" 0163 "<tr><td>d</td><td>the day as number without a leading zero (1 to 31).</td></tr>" 0164 "<tr><td>dd</td><td>the day as number with a leading zero (01 to 31).</td></tr>" 0165 "<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>" 0166 "<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>" 0167 "<tr><td>M</td><td>the month as number without a leading zero (1 to 12).</td></tr>" 0168 "<tr><td>MM</td><td>the month as number with a leading zero (01 to 12).</td></tr>" 0169 "<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>" 0170 "<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>" 0171 "<tr><td>yy</td><td>the year as two digit number (00 to 99).</td></tr>" 0172 "<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>" 0173 "</table><br><br>" 0174 "Expressions that may be used for the time part of the format string:" 0175 "<table>" 0176 "<tr><td>h</td><td>the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)</td></tr>" 0177 "<tr><td>hh</td><td>the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)</td></tr>" 0178 "<tr><td>H</td><td>the hour without a leading zero (0 to 23, even with AM/PM display)</td></tr>" 0179 "<tr><td>HH</td><td>the hour with a leading zero (00 to 23, even with AM/PM display)</td></tr>" 0180 "<tr><td>m</td><td>the minute without a leading zero (0 to 59)</td></tr>" 0181 "<tr><td>mm</td><td>the minute with a leading zero (00 to 59)</td></tr>" 0182 "<tr><td>s</td><td>the second without a leading zero (0 to 59)</td></tr>" 0183 "<tr><td>ss</td><td>the second with a leading zero (00 to 59)</td></tr>" 0184 "<tr><td>z</td><td>the milliseconds without leading zeroes (0 to 999)</td></tr>" 0185 "<tr><td>zzz</td><td>the milliseconds with leading zeroes (000 to 999)</td></tr>" 0186 "<tr><td>AP or A</td><td>interpret as an AM/PM time. AP must be either 'AM' or 'PM'.</td></tr>" 0187 "<tr><td>ap or a</td><td>Interpret as an AM/PM time. ap must be either 'am' or 'pm'.</td></tr>" 0188 "</table><br><br>" 0189 "Examples are:" 0190 "<table>" 0191 "<tr><td>dd.MM.yyyy</td><td>20.07.1969</td></tr>" 0192 "<tr><td>ddd MMMM d yy</td><td>Sun July 20 69</td></tr>" 0193 "<tr><td>'The day is' dddd</td><td>The day is Sunday</td></tr>" 0194 "</table>"); 0195 0196 ui.lDateTimeFormat->setToolTip(textDateTimeFormatShort); 0197 ui.lDateTimeFormat->setWhatsThis(textDateTimeFormat); 0198 ui.cbDateTimeFormat->setToolTip(textDateTimeFormatShort); 0199 ui.cbDateTimeFormat->setWhatsThis(textDateTimeFormat); 0200 } 0201 0202 QVector<int> JsonOptionsWidget::getIndexRows(const QModelIndex &index) const { 0203 QVector<int> rows; 0204 QModelIndex current = index; 0205 while (current.isValid()) { 0206 rows.prepend(current.row()); 0207 current = current.parent(); 0208 } 0209 return rows; 0210 }