File indexing completed on 2022-09-27 12:24:09

0001 /*
0002     SPDX-FileCopyrightText: 2007 Johannes Simon <johannes.simon@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "exportdialog.h"
0007 
0008 #include "kalziumutils.h"
0009 
0010 #include "kalzium_debug.h"
0011 #include <QDialogButtonBox>
0012 #include <QFont>
0013 #include <QPushButton>
0014 #include <QVBoxLayout>
0015 
0016 #include <KConfigGroup>
0017 #include <KGuiItem>
0018 #include <KHelpClient>
0019 #include <KLocalizedString>
0020 #include <KMessageBox>
0021 
0022 static const char HTML_HEADER[] =
0023     "<html>"
0024     "\n<head>"
0025     "\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>"
0026     "\n<style type=\"text/css\">"
0027     "\nbody {"
0028     "\n   font-family:arial;"
0029     "\n}"
0030     "\n.property {"
0031     "\n   font-style:italic;"
0032     "\n}"
0033     "\nth {"
0034     "\n   font-weight:bold;"
0035     "\n   text-align:left;"
0036     "\n   background-color:#F0F0F0;"
0037     "\n}"
0038     "\n</style>"
0039     "\n</head>"
0040     "\n<body>";
0041 
0042 static const char HTML_FOOTER[] =
0043     "\n</body>"
0044     "\n</html>";
0045 
0046 static const char XML_HEADER[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
0047 
0048 ElementListEntry::ElementListEntry(Element *element)
0049     : QListWidgetItem()
0050 {
0051     m_atomicNum = element->dataAsVariant(ChemicalDataObject::atomicNumber).toInt();
0052     m_name = element->dataAsString(ChemicalDataObject::name);
0053     m_element = element;
0054 
0055     setText(m_name);
0056 }
0057 
0058 ElementListEntry::~ElementListEntry() = default;
0059 
0060 PropertyListEntry::PropertyListEntry(const QString &name, ChemicalDataObject::BlueObelisk type)
0061     : QListWidgetItem()
0062 {
0063     setText(name);
0064     m_type = type;
0065 }
0066 
0067 PropertyListEntry::~PropertyListEntry() = default;
0068 
0069 ExportDialog::ExportDialog(QWidget *parent)
0070     : QDialog(parent)
0071 {
0072     qCDebug(KALZIUM_LOG) << "ExportDialog::ExportDialog";
0073     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Help, this);
0074     auto mainWidget = new QWidget(this);
0075     auto mainLayout = new QVBoxLayout(this);
0076     mainLayout->addWidget(mainWidget);
0077     auto user1Button = new QPushButton;
0078     buttonBox->addButton(user1Button, QDialogButtonBox::ActionRole);
0079     connect(buttonBox, &QDialogButtonBox::accepted, this, &ExportDialog::accept);
0080     connect(buttonBox, &QDialogButtonBox::rejected, this, &ExportDialog::reject);
0081     mainLayout->addWidget(buttonBox);
0082     qCDebug(KALZIUM_LOG) << "ExportDialog: setButtons";
0083     ui.setupUi(mainWidget);
0084     qCDebug(KALZIUM_LOG) << "ExportDialog: ui.setupUi(mainWidget)";
0085     KGuiItem::assign(user1Button, KGuiItem(i18n("OK")));
0086     qCDebug(KALZIUM_LOG) << "ExportDialog: setButtonGuiItem(User1, KGuiItem(i18n(\"OK\")));";
0087     ui.targetFile->setMode(KFile::File | KFile::Directory | KFile::LocalOnly);
0088     qCDebug(KALZIUM_LOG) << "ui.targetFile->setMode(KFile::File | KFile::Directory | KFile::LocalOnly);";
0089 
0090     setWindowTitle(i18nc("@title:window", "Export Chemical Data"));
0091     qCDebug(KALZIUM_LOG) << "ui.targetFile->setMode(KFile::File | KFile::Directory | KFile::LocalOnly);";
0092 
0093     populateElementList();
0094     qCDebug(KALZIUM_LOG) << "ui.targetFile->setMode(KFile::File | KFile::Directory | KFile::LocalOnly);";
0095 
0096     ui.formatList->addItem(QStringLiteral(".html (formatted html document)"), "html");
0097     ui.formatList->addItem(QStringLiteral(".xml (raw element data)"), "xml");
0098     ui.formatList->addItem(QStringLiteral(".csv (comma-separated data)"), "csv");
0099     qCDebug(KALZIUM_LOG) << "ui.formatList->addItem(...);";
0100 
0101     connect(user1Button, &QPushButton::clicked, this, &ExportDialog::slotOkClicked);
0102     qCDebug(KALZIUM_LOG) << "connect(user1Button, SIGNAL(clicked()), this, SLOT(slotOkClicked()));";
0103     connect(buttonBox, &QDialogButtonBox::helpRequested, this, &ExportDialog::slotHelpRequested);
0104     qCDebug(KALZIUM_LOG) << "KHelpClient::invokeHelp(QString(), \"kalzium\");";
0105 }
0106 
0107 ExportDialog::~ExportDialog()
0108 {
0109     delete m_outputStream;
0110 }
0111 
0112 void ExportDialog::populateElementList()
0113 {
0114     // Add descriptive headers
0115     auto header1 = new QListWidgetItem(i18n("Elements"));
0116     auto header2 = new QListWidgetItem(i18n("Properties"));
0117     header1->setFlags(Qt::ItemIsEnabled);
0118     header2->setFlags(Qt::ItemIsEnabled);
0119     QFont font;
0120     font.setBold(true);
0121     header1->setFont(font);
0122     header2->setFont(font);
0123     ui.elementListWidget->addItem(header1);
0124     ui.propertyListWidget->addItem(header2);
0125 
0126     // Add elements
0127     foreach (Element *element, KalziumDataObject::instance()->ElementList) {
0128         auto entry = new ElementListEntry(element);
0129         ui.elementListWidget->addItem(entry);
0130     }
0131 
0132     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Atomic Number"), ChemicalDataObject::atomicNumber));
0133     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Symbol"), ChemicalDataObject::symbol));
0134     // ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Name"), ChemicalDataObject::name));
0135     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Mass"), ChemicalDataObject::mass));
0136     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Exact Mass"), ChemicalDataObject::exactMass));
0137     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Ionization"), ChemicalDataObject::ionization));
0138     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Electron Affinity"), ChemicalDataObject::electronAffinity));
0139     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Electronegativity"), ChemicalDataObject::electronegativityPauling));
0140     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Covalent Radius"), ChemicalDataObject::radiusCovalent));
0141     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Van der Waals Radius"), ChemicalDataObject::radiusVDW));
0142     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Melting Point"), ChemicalDataObject::meltingpoint));
0143     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Boiling Point"), ChemicalDataObject::boilingpoint));
0144     ui.propertyListWidget->addItem(new PropertyListEntry(i18n("Family"), ChemicalDataObject::family));
0145 }
0146 
0147 void ExportDialog::slotOkClicked()
0148 {
0149     QString format = ui.formatList->itemData(ui.formatList->currentIndex(), Qt::UserRole).toString();
0150     QString filename = ui.targetFile->url().toLocalFile();
0151     if (!filename.endsWith(format)) {
0152         filename += '.' + format;
0153     }
0154     QFile outputFile(filename);
0155     if (outputFile.exists()) {
0156         if (KMessageBox::questionYesNo(this, i18n("File already exists. Do you want to overwrite it?")) == KMessageBox::No) {
0157             return;
0158         }
0159     }
0160     if (!outputFile.open(QIODevice::WriteOnly)) {
0161         KMessageBox::error(this, i18n("Could not open file for writing."));
0162         return;
0163     }
0164 
0165     delete m_outputStream;
0166     m_outputStream = new QTextStream(&outputFile);
0167     if (format == QLatin1String("html")) {
0168         exportToHtml();
0169     } else if (format == QLatin1String("xml")) {
0170         exportToXml();
0171     } else {
0172         exportToCsv();
0173     }
0174 
0175     // close the dialog
0176     done(0);
0177 }
0178 
0179 void ExportDialog::slotHelpRequested()
0180 {
0181     KHelpClient::invokeHelp(QString(), QStringLiteral("kalzium"));
0182 }
0183 
0184 void ExportDialog::exportToHtml()
0185 {
0186     *m_outputStream << HTML_HEADER << "<table>\n";
0187     foreach (QListWidgetItem *element, ui.elementListWidget->selectedItems()) {
0188         *m_outputStream << "<tr>\n<th colspan=\"2\">" << ((ElementListEntry *)element)->m_element->dataAsString(ChemicalDataObject::name) << "</th>\n</tr>\n";
0189         foreach (QListWidgetItem *property, ui.propertyListWidget->selectedItems()) {
0190             *m_outputStream << "<tr>\n<td class=\"property\">" << ((PropertyListEntry *)property)->text() << "</td>\n<td class=\"value\">"
0191                             << KalziumUtils::prettyUnit(((ElementListEntry *)element)->m_element, ((PropertyListEntry *)property)->m_type) << "</td>\n</tr>\n";
0192         }
0193     }
0194     *m_outputStream << "</table>\n" << HTML_FOOTER;
0195 }
0196 
0197 void ExportDialog::exportToXml()
0198 {
0199     *m_outputStream << XML_HEADER << "<elements>\n";
0200     foreach (QListWidgetItem *element, ui.elementListWidget->selectedItems()) {
0201         *m_outputStream << "  <element name=\"" << ((ElementListEntry *)element)->m_element->dataAsString(ChemicalDataObject::name) << "\">\n";
0202         foreach (QListWidgetItem *property, ui.propertyListWidget->selectedItems()) {
0203             *m_outputStream << "    <property name=\"" << ((PropertyListEntry *)property)->text() << "\">"
0204                             << KalziumUtils::prettyUnit(((ElementListEntry *)element)->m_element, ((PropertyListEntry *)property)->m_type) << "</property>\n";
0205         }
0206         *m_outputStream << "  </element>\n";
0207     }
0208     *m_outputStream << "</elements>\n";
0209 }
0210 
0211 void ExportDialog::exportToCsv()
0212 {
0213     *m_outputStream << "Name";
0214     foreach (QListWidgetItem *property, ui.propertyListWidget->selectedItems()) {
0215         *m_outputStream << ", \"" << ((PropertyListEntry *)property)->text() << "\"";
0216     }
0217     *m_outputStream << "\n";
0218     foreach (QListWidgetItem *element, ui.elementListWidget->selectedItems()) {
0219         *m_outputStream << "\"" << ((ElementListEntry *)element)->m_element->dataAsString(ChemicalDataObject::name) << "\"";
0220         foreach (QListWidgetItem *property, ui.propertyListWidget->selectedItems()) {
0221             *m_outputStream << ", \"" << KalziumUtils::prettyUnit(((ElementListEntry *)element)->m_element, ((PropertyListEntry *)property)->m_type) << "\"";
0222         }
0223         *m_outputStream << "\n";
0224     }
0225 }