File indexing completed on 2024-06-02 03:49:30

0001 /*
0002     File                 : BatchEditValueLabelsDialog.cpp
0003     Project              : LabPlot
0004     Description          : Dialog to modify multiply value labels in a batch mode
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2021 Alexander Semke <alexander.semke@web.de>
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "BatchEditValueLabelsDialog.h"
0011 #include "backend/core/Settings.h"
0012 #include "backend/core/column/Column.h"
0013 #include "backend/core/datatypes/DateTime2StringFilter.h"
0014 #include "backend/lib/macros.h"
0015 
0016 #include <QDialogButtonBox>
0017 #include <QLabel>
0018 #include <QPushButton>
0019 #include <QTextEdit>
0020 #include <QVBoxLayout>
0021 #include <QWindow>
0022 
0023 #include <KLocalizedString>
0024 
0025 #include <KWindowConfig>
0026 
0027 /*!
0028     \class BatchEditValueLabelsDialog
0029     \brief Dialog to add a new the value label
0030 
0031     \ingroup kdefrontend
0032  */
0033 BatchEditValueLabelsDialog::BatchEditValueLabelsDialog(QWidget* parent)
0034     : QDialog(parent)
0035     , teValueLabels(new QTextEdit()) {
0036     setWindowTitle(i18nc("@title:window", "Edit Value Labels"));
0037 
0038     auto* layout = new QVBoxLayout(this);
0039 
0040     auto* label = new QLabel(i18n("Value Labels:"));
0041     layout->addWidget(label);
0042 
0043     layout->addWidget(teValueLabels);
0044 
0045     auto* btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0046     connect(btnBox, &QDialogButtonBox::accepted, this, &BatchEditValueLabelsDialog::save);
0047     connect(btnBox, &QDialogButtonBox::accepted, this, &BatchEditValueLabelsDialog::accept);
0048     connect(btnBox, &QDialogButtonBox::rejected, this, &BatchEditValueLabelsDialog::reject);
0049     layout->addWidget(btnBox);
0050 
0051     // restore saved settings if available
0052     KConfigGroup conf = Settings::group(QLatin1String("BatchEditValueLabelsDialog"));
0053 
0054     create(); // ensure there's a window created
0055     if (conf.exists()) {
0056         KWindowConfig::restoreWindowSize(windowHandle(), conf);
0057         resize(windowHandle()->size()); // workaround for QTBUG-40584
0058     } else
0059         resize(QSize(200, 0).expandedTo(minimumSize()));
0060 }
0061 
0062 BatchEditValueLabelsDialog::~BatchEditValueLabelsDialog() {
0063     // save the current settings
0064     KConfigGroup conf = Settings::group(QLatin1String("BatchEditValueLabelsDialog"));
0065     KWindowConfig::saveWindowSize(windowHandle(), conf);
0066 }
0067 
0068 void BatchEditValueLabelsDialog::setColumns(const QList<Column*>& columns) {
0069     m_columns = columns;
0070 
0071     if (m_columns.isEmpty())
0072         return;
0073 
0074     m_column = m_columns.first();
0075 
0076     // show the available value labels for the first columm
0077     if (m_column->valueLabelsInitialized()) {
0078         QString text;
0079 
0080         switch (m_column->labelsMode()) {
0081         case AbstractColumn::ColumnMode::Double: {
0082             const auto* labels = m_column->valueLabels();
0083             if (!labels)
0084                 return;
0085             auto it = labels->constBegin();
0086             while (it != labels->constEnd()) {
0087                 if (!text.isEmpty())
0088                     text += QLatin1Char('\n');
0089                 text += QString::number(it->value) + QLatin1String(" = ") + it->label;
0090                 ++it;
0091             }
0092             break;
0093         }
0094         case AbstractColumn::ColumnMode::Integer: {
0095             const auto* labels = m_column->intValueLabels();
0096             if (!labels)
0097                 return;
0098             auto it = labels->constBegin();
0099             while (it != labels->constEnd()) {
0100                 if (!text.isEmpty())
0101                     text += QLatin1Char('\n');
0102                 text += QString::number(it->value) + QLatin1String(" = ") + it->label;
0103                 ++it;
0104             }
0105             break;
0106         }
0107         case AbstractColumn::ColumnMode::BigInt: {
0108             const auto* labels = m_column->bigIntValueLabels();
0109             if (!labels)
0110                 return;
0111             auto it = labels->constBegin();
0112             while (it != labels->constEnd()) {
0113                 if (!text.isEmpty())
0114                     text += QLatin1Char('\n');
0115                 text += QString::number(it->value) + QLatin1String(" = ") + it->label;
0116                 ++it;
0117             }
0118             break;
0119         }
0120         case AbstractColumn::ColumnMode::Text: {
0121             const auto* labels = m_column->textValueLabels();
0122             if (!labels)
0123                 return;
0124             auto it = labels->constBegin();
0125             while (it != labels->constEnd()) {
0126                 if (!text.isEmpty())
0127                     text += QLatin1Char('\n');
0128                 text += it->value + QLatin1String(" = ") + it->label;
0129                 ++it;
0130             }
0131             break;
0132         }
0133         case AbstractColumn::ColumnMode::Month:
0134         case AbstractColumn::ColumnMode::Day:
0135         case AbstractColumn::ColumnMode::DateTime: {
0136             const auto* labels = m_column->dateTimeValueLabels();
0137             if (!labels)
0138                 return;
0139             const auto* filter = static_cast<DateTime2StringFilter*>(m_column->outputFilter());
0140             const auto& dateTimeFormat = filter->format();
0141             auto it = labels->constBegin();
0142             while (it != labels->constEnd()) {
0143                 if (!text.isEmpty())
0144                     text += QLatin1Char('\n');
0145                 text += it->value.toString(dateTimeFormat) + QLatin1String(" = ") + it->label;
0146                 ++it;
0147             }
0148             break;
0149         }
0150         }
0151 
0152         teValueLabels->setText(text);
0153     } else {
0154         QString text = i18n("Provide the list of value-label pairs like in the following example:");
0155         text += QLatin1String("\n1 = true\n0 = false");
0156         teValueLabels->setPlaceholderText(text);
0157     }
0158 }
0159 
0160 void BatchEditValueLabelsDialog::save() const {
0161     // remove all already available labels first
0162     for (auto* column : m_columns)
0163         column->valueLabelsRemoveAll();
0164 
0165     // add new labels
0166     const auto numberLocale = QLocale();
0167     QString label;
0168     QString valueStr;
0169     bool ok;
0170     const auto mode = m_column->columnMode();
0171     const QString& text = teValueLabels->toPlainText();
0172     const auto& lines = text.split(QLatin1Char('\n'));
0173 
0174     for (const auto& line : lines) {
0175         auto pair = line.split(QLatin1Char('='));
0176         if (pair.size() != 2)
0177             continue;
0178 
0179         valueStr = pair.at(0).simplified();
0180         label = pair.at(1).simplified();
0181         if (valueStr.isEmpty() || label.isEmpty())
0182             continue;
0183 
0184         switch (mode) {
0185         case AbstractColumn::ColumnMode::Double: {
0186             double value = numberLocale.toDouble(valueStr, &ok);
0187             if (!ok)
0188                 continue;
0189             for (auto* col : m_columns)
0190                 col->addValueLabel(value, label);
0191             break;
0192         }
0193         case AbstractColumn::ColumnMode::Integer: {
0194             int value = numberLocale.toInt(valueStr, &ok);
0195             if (!ok)
0196                 continue;
0197             for (auto* col : m_columns)
0198                 col->addValueLabel(value, label);
0199             break;
0200         }
0201         case AbstractColumn::ColumnMode::BigInt: {
0202             qint64 value = numberLocale.toLongLong(valueStr, &ok);
0203             if (!ok)
0204                 continue;
0205             for (auto* col : m_columns)
0206                 col->addValueLabel(value, label);
0207             break;
0208         }
0209         case AbstractColumn::ColumnMode::Text: {
0210             for (auto* col : m_columns)
0211                 col->addValueLabel(valueStr, label);
0212             break;
0213         }
0214         case AbstractColumn::ColumnMode::Month:
0215         case AbstractColumn::ColumnMode::Day:
0216         case AbstractColumn::ColumnMode::DateTime: {
0217             const auto* filter = static_cast<DateTime2StringFilter*>(m_column->outputFilter());
0218             const QDateTime& value = QDateTime::fromString(valueStr, filter->format());
0219             if (!value.isValid())
0220                 continue;
0221             for (auto* col : m_columns)
0222                 col->addValueLabel(value, label);
0223             break;
0224         }
0225         }
0226     }
0227 }