diff --git a/src/backend/datasources/filters/QJsonModel.cpp b/src/backend/datasources/filters/QJsonModel.cpp index 70a025bbf..d4d512366 100644 --- a/src/backend/datasources/filters/QJsonModel.cpp +++ b/src/backend/datasources/filters/QJsonModel.cpp @@ -1,390 +1,392 @@ /* * The MIT License (MIT) * * Copyright (c) 2011 SCHUTZ Sacha * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "QJsonModel.h" #include #include #include QJsonTreeItem::QJsonTreeItem(QJsonTreeItem *parent) { mParent = parent; } QJsonTreeItem::~QJsonTreeItem() { qDeleteAll(mChilds); } void QJsonTreeItem::appendChild(QJsonTreeItem *item) { mChilds.append(item); } QJsonTreeItem *QJsonTreeItem::child(int row) { return mChilds.value(row); } QJsonTreeItem *QJsonTreeItem::parent() { return mParent; } int QJsonTreeItem::childCount() const { return mChilds.count(); } int QJsonTreeItem::row() const { if (mParent) return mParent->mChilds.indexOf(const_cast(this)); return 0; } void QJsonTreeItem::setKey(const QString &key) { mKey = key; } void QJsonTreeItem::setValue(const QString &value) { mValue = value; } void QJsonTreeItem::setType(const QJsonValue::Type &type) { mType = type; } QString QJsonTreeItem::key() const { return mKey; } QString QJsonTreeItem::value() const { return mValue; } QJsonValue::Type QJsonTreeItem::type() const { return mType; } QJsonTreeItem* QJsonTreeItem::load(const QJsonValue& value, QJsonTreeItem* parent) { QJsonTreeItem * rootItem = new QJsonTreeItem(parent); rootItem->setKey("root"); if ( value.isObject()) { //Get all QJsonValue childs for (QString key : value.toObject().keys()){ QJsonValue v = value.toObject().value(key); QJsonTreeItem * child = load(v,rootItem); child->setKey(key); child->setType(v.type()); rootItem->appendChild(child); } } else if ( value.isArray()) { //Get all QJsonValue childs int index = 0; for (QJsonValue v : value.toArray()){ QJsonTreeItem * child = load(v,rootItem); child->setKey(QString::number(index)); child->setType(v.type()); rootItem->appendChild(child); ++index; } } else { rootItem->setValue(value.toVariant().toString()); rootItem->setType(value.type()); } return rootItem; } //========================================================================= QJsonModel::QJsonModel(QObject *parent) : QAbstractItemModel(parent) { mRootItem = new QJsonTreeItem; mHeaders.append("key"); mHeaders.append("value"); } QJsonModel::~QJsonModel() { delete mRootItem; } void QJsonModel::clear() { beginResetModel(); delete mRootItem; mRootItem = new QJsonTreeItem; endResetModel(); } bool QJsonModel::load(const QString &fileName) { QFile file(fileName); bool success = false; if (file.open(QIODevice::ReadOnly)) { success = load(&file); file.close(); } else success = false; return success; } bool QJsonModel::load(QIODevice *device) { return loadJson(device->readAll()); } bool QJsonModel::loadJson(const QByteArray &json) { auto const& jdoc = QJsonDocument::fromJson(json); return loadJson(jdoc); } bool QJsonModel::loadJson(const QJsonDocument &jdoc) { if (!jdoc.isNull()) { beginResetModel(); delete mRootItem; if (jdoc.isArray()) { mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.array())); mRootItem->setType(QJsonValue::Array); } else { mRootItem = QJsonTreeItem::load(QJsonValue(jdoc.object())); mRootItem->setType(QJsonValue::Object); } endResetModel(); return true; } qDebug()<(index.internalPointer()); if (role == Qt::DisplayRole) { if (index.column() == 0) return QString("%1").arg(item->key()); if (index.column() == 1) return QString("%1").arg(item->value()); } else if (Qt::EditRole == role) { if (index.column() == 1) { return QString("%1").arg(item->value()); } } else if (role == Qt::DecorationRole) { //TODO: add icons for array and object if (item->type() == QJsonValue::Array) return QIcon(); else if (item->type() == QJsonValue::Object) return QIcon(); else return QIcon(); } - - return QVariant(); - } bool QJsonModel::setData(const QModelIndex &index, const QVariant &value, int role) { int col = index.column(); if (Qt::EditRole == role) { if (col == 1) { QJsonTreeItem *item = static_cast(index.internalPointer()); item->setValue(value.toString()); emit dataChanged(index, index, {Qt::EditRole}); return true; } } return false; } QVariant QJsonModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) { return mHeaders.value(section); } else return QVariant(); } QModelIndex QJsonModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); QJsonTreeItem *parentItem; if (!parent.isValid()) parentItem = mRootItem; else parentItem = static_cast(parent.internalPointer()); QJsonTreeItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); } QModelIndex QJsonModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); QJsonTreeItem *childItem = static_cast(index.internalPointer()); QJsonTreeItem *parentItem = childItem->parent(); if (parentItem == mRootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem); } int QJsonModel::rowCount(const QModelIndex &parent) const { QJsonTreeItem *parentItem; if (parent.column() > 0) return 0; if (!parent.isValid()) parentItem = mRootItem; else parentItem = static_cast(parent.internalPointer()); return parentItem->childCount(); } int QJsonModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) return 2; } Qt::ItemFlags QJsonModel::flags(const QModelIndex &index) const { int col = index.column(); if (col == 1) { return Qt::ItemIsEditable | QAbstractItemModel::flags(index); } else { return QAbstractItemModel::flags(index); } } QJsonDocument QJsonModel::json() const { auto v = genJson(mRootItem); QJsonDocument doc; if (v.isObject()) { doc = QJsonDocument(v.toObject()); } else { doc = QJsonDocument(v.toArray()); } return doc; } QJsonValue QJsonModel::genJson(QJsonTreeItem * item) const { auto type = item->type(); int nchild = item->childCount(); if (QJsonValue::Object == type) { QJsonObject jo; for (int i = 0; i < nchild; ++i) { auto ch = item->child(i); auto key = ch->key(); jo.insert(key, genJson(ch)); } return jo; } else if (QJsonValue::Array == type) { QJsonArray arr; for (int i = 0; i < nchild; ++i) { auto ch = item->child(i); arr.append(genJson(ch)); } return arr; } else { QJsonValue va(item->value()); return va; } } QJsonDocument QJsonModel::genJsonByIndex(const QModelIndex &index) const { if (!index.isValid()) return QJsonDocument(); QJsonTreeItem *item = static_cast(index.internalPointer()); +<<<<<<< HEAD:src/backend/datasources/filters/QJsonModel.cpp return QJsonDocument::fromVariant(genJson(item).toVariant()); -} \ No newline at end of file +} +======= + return genJson(item); +} +>>>>>>> 3c486aa9bea8b90e164b0b1965f870de345ac151:src/kdefrontend/datasources/QJsonModel.cpp diff --git a/src/kdefrontend/datasources/JsonOptionsWidget.cpp b/src/kdefrontend/datasources/JsonOptionsWidget.cpp index 98706a16b..d42d3874c 100644 --- a/src/kdefrontend/datasources/JsonOptionsWidget.cpp +++ b/src/kdefrontend/datasources/JsonOptionsWidget.cpp @@ -1,171 +1,173 @@ #include "ImportFileWidget.h" #include "JsonOptionsWidget.h" #include "backend/datasources/filters/QJsonModel.h" #include "backend/datasources/filters/AbstractFileFilter.h" #include "backend/datasources/filters/JsonFilter.h" #include #include #include #include + /*! \class JsonOptionsWidget \brief Widget providing options for the import of json data \ingroup kdefrontend */ JsonOptionsWidget::JsonOptionsWidget(QWidget* parent, ImportFileWidget* fileWidget) : QWidget(parent), m_fileWidget(fileWidget), m_model(new QJsonModel()) { + ui.setupUi(parent); ui.tvJson->setModel(m_model); ui.tvJson->header()->setSectionResizeMode(QHeaderView::ResizeToContents); ui.tvJson->setAlternatingRowColors(true); ui.cbDataRowType->addItems(JsonFilter::dataRowTypes()); ui.cbNumberFormat->addItems(AbstractFileFilter::numberFormats()); ui.cbDateTimeFormat->addItems(AbstractColumn::dateTimeFormats()); connect(ui.chbUseRootEl, &QCheckBox::stateChanged, [=](int state) { ui.tvJson->setEnabled(state == 0); }); connect(ui.tvJson, &QAbstractItemView::clicked, this, &JsonOptionsWidget::indexChanged); setTooltips(); } void JsonOptionsWidget::applyFilterSettings(JsonFilter* filter) const { Q_ASSERT(filter); if(ui.chbUseRootEl->isChecked()) filter->setModelRows(QVector()); else filter->setModelRows(getIndexRows(ui.tvJson->currentIndex())); //TODO: change this after implementation other row types filter->setDataRowType(ui.cbDataRowType->currentIndex() == 0 ? QJsonValue::Array : QJsonValue::Object); filter->setNumberFormat( QLocale::Language(ui.cbNumberFormat->currentIndex())); filter->setDateTimeFormat(ui.cbDateTimeFormat->currentText()); filter->setCreateIndexEnabled(ui.chbCreateIndex->isChecked()); filter->setNaNValueToZero(ui.chbConvertNaNToZero->isChecked()); } void JsonOptionsWidget::clear() { m_model->clear(); } void JsonOptionsWidget::loadSettings() const { KConfigGroup conf(KSharedConfig::openConfig(), "ImportJson"); //TODO: change this after implementation other row types ui.cbDataRowType->setCurrentIndex(conf.readEntry("DataRowType", 0)); ui.cbNumberFormat->setCurrentIndex(conf.readEntry("NumberFormat", (int)QLocale::AnyLanguage)); ui.cbDateTimeFormat->setCurrentItem(conf.readEntry("DateTimeFormat", "yyyy-MM-dd hh:mm:ss.zzz")); ui.chbCreateIndex->setChecked(conf.readEntry("CreateIndex", false)); ui.chbConvertNaNToZero->setChecked(conf.readEntry("ConvertNaNToZero", false)); } void JsonOptionsWidget::saveSettings() { KConfigGroup conf(KSharedConfig::openConfig(), "ImportJson"); conf.writeEntry("DataRowType", ui.cbDataRowType->currentIndex()); conf.writeEntry("NumberFormat", ui.cbNumberFormat->currentIndex()); conf.writeEntry("DateTimeFormat", ui.cbDateTimeFormat->currentText()); conf.writeEntry("CreateIndex", ui.chbCreateIndex->isChecked()); conf.writeEntry("ConvertNaNToZero", ui.chbConvertNaNToZero->isChecked()); } void JsonOptionsWidget::loadDocument(QString filename) { if(m_filename == filename) return; else m_filename = filename; KFilterDev device(m_filename); if (!device.open(QIODevice::ReadOnly)) return; if (device.atEnd() && !device.isSequential()) // empty file return; m_model->loadJson(device.readAll()); } void JsonOptionsWidget::indexChanged() { m_fileWidget->refreshPreview(); } void JsonOptionsWidget::setTooltips() { const QString textNumberFormatShort = i18n("This option determines how the imported strings have to be converted to numbers."); const QString textNumberFormat = textNumberFormatShort + "

" + i18n( "For 'C Format', a period is used for the decimal point character and comma is used for the thousands group separator. " "Valid number representations are:" "
    " "
  • 1234.56
  • " "
  • 1,234.56
  • " "
  • etc.
  • " "
" "When using 'System locale', the system settings will be used. " "E.g., for the German local the valid number representations are:" "
    " "
  • 1234,56
  • " "
  • 1.234,56
  • " "
  • etc.
  • " "
" ); ui.lNumberFormat->setToolTip(textNumberFormatShort); ui.lNumberFormat->setWhatsThis(textNumberFormat); ui.cbNumberFormat->setToolTip(textNumberFormatShort); ui.cbNumberFormat->setWhatsThis(textNumberFormat); 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."); const QString textDateTimeFormat = textDateTimeFormatShort + "

" + i18n( "Expressions that may be used for the date part of format string:" "" "" "" "" "" "" "" "" "" "" "" "
dthe day as number without a leading zero (1 to 31).
ddthe day as number with a leading zero (01 to 31).
dddthe abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses the system locale to localize the name.
ddddthe long localized day name (e.g. 'Monday' to 'Sunday'). Uses the system locale to localize the name.
Mthe month as number without a leading zero (1 to 12).
MMthe month as number with a leading zero (01 to 12).
MMMthe abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses the system locale to localize the name.
MMMMthe long localized month name (e.g. 'January' to 'December'). Uses the system locale to localize the name.
yythe year as two digit number (00 to 99).
yyyythe year as four digit number. If the year is negative, a minus sign is prepended in addition.


" "Expressions that may be used for the time part of the format string:" "" "" "" "" "" "" "" "" "" "" "" "" "" "
hthe hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
hhthe hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
Hthe hour without a leading zero (0 to 23, even with AM/PM display)
HHthe hour with a leading zero (00 to 23, even with AM/PM display)
mthe minute without a leading zero (0 to 59)
mmthe minute with a leading zero (00 to 59)
sthe second without a leading zero (0 to 59)
ssthe second with a leading zero (00 to 59)
zthe milliseconds without leading zeroes (0 to 999)
zzzthe milliseconds with leading zeroes (000 to 999)
AP or Ainterpret as an AM/PM time. AP must be either 'AM' or 'PM'.
ap or aInterpret as an AM/PM time. ap must be either 'am' or 'pm'.


" "Examples are:" "" "" "" "" "
dd.MM.yyyy20.07.1969
ddd MMMM d yySun July 20 69
'The day is' ddddThe day is Sunday
"); ui.lDateTimeFormat->setToolTip(textDateTimeFormatShort); ui.lDateTimeFormat->setWhatsThis(textDateTimeFormat); ui.cbDateTimeFormat->setToolTip(textDateTimeFormatShort); ui.cbDateTimeFormat->setWhatsThis(textDateTimeFormat); } QVector JsonOptionsWidget::getIndexRows(const QModelIndex &index) const { QVector rows; QModelIndex current = index; while(current.isValid()){ rows.prepend(current.row()); current = current.parent(); } return rows; } \ No newline at end of file