File indexing completed on 2024-04-21 03:42:04

0001 /*
0002     KmPlot - a math. function plotter for the KDE-Desktop
0003 
0004     SPDX-FileCopyrightText: 1998, 1999, 2000, 2002 Klaus-Dieter Möller <kd.moeller@t-online.de>
0005     SPDX-FileCopyrightText: 2006 David Saxton <david@bluehaze.org>
0006 
0007     This file is part of the KDE Project.
0008     KmPlot is part of the KDE-EDU Project.
0009 
0010     SPDX-License-Identifier: GPL-2.0-or-later
0011 
0012 */
0013 
0014 #include "constants.h"
0015 #include "xparser.h"
0016 
0017 #include <KConfig>
0018 
0019 // BEGIN class Constant
0020 Constant::Constant()
0021 {
0022     // By default, have both types
0023     // This minimizes loss of information
0024     type = Document | Global;
0025 }
0026 // END class Constant
0027 
0028 // BEGIN class Constants
0029 Constants::Constants()
0030 {
0031 }
0032 
0033 Constants::~Constants()
0034 {
0035 }
0036 
0037 Value Constants::value(const QString &name) const
0038 {
0039     return m_constants[name].value;
0040 }
0041 
0042 bool Constants::have(const QString &name) const
0043 {
0044     return m_constants.contains(name);
0045 }
0046 
0047 void Constants::remove(const QString &name)
0048 {
0049     if (m_constants.remove(name) > 0)
0050         emit constantsChanged();
0051 }
0052 
0053 void Constants::add(const QString &name, const Constant &constant)
0054 {
0055     m_constants[name] = constant;
0056     emit constantsChanged();
0057 }
0058 
0059 ConstantList Constants::list(int type) const
0060 {
0061     ConstantList list;
0062 
0063     for (ConstantList::const_iterator it = m_constants.begin(); it != m_constants.end(); ++it) {
0064         if (type & it.value().type)
0065             list.insert(it.key(), it.value());
0066     }
0067 
0068     return list;
0069 }
0070 
0071 bool Constants::isValidName(const QString &name) const
0072 {
0073     // Don't allow empty names
0074     if (name.isEmpty())
0075         return false;
0076 
0077     // Don't allow constants names that are already used by a function
0078     if (XParser::self()->predefinedFunctions(true).contains(name) || XParser::self()->userFunctions().contains(name))
0079         return false;
0080 
0081     // special cases: don't allow predefined constants either
0082     if (name == QLatin1String("pi") || name == PiSymbol || name == QLatin1String("e") || name == InfinitySymbol)
0083         return false;
0084 
0085     // Now make sure that the constant name contains only letters
0086     for (int i = 0; i < name.length(); ++i) {
0087         if (!name.at(i).isLetter())
0088             return false;
0089     }
0090 
0091     // All ok!
0092     return true;
0093 }
0094 
0095 QString Constants::generateUniqueName() const
0096 {
0097     QString name;
0098     int at = 0;
0099     while (true) {
0100         at++;
0101         name.resize(at);
0102         for (char c = 'A'; c <= 'Z'; ++c) {
0103             name[at - 1] = c;
0104             if (isValidName(name) && !have(name))
0105                 return name;
0106         }
0107     }
0108 }
0109 
0110 void Constants::load()
0111 {
0112     /// \todo Need more robust way of exchanging constants with kcalc
0113 
0114     KConfig conf(QStringLiteral("kcalcrc"), KConfig::SimpleConfig);
0115     KConfigGroup group = conf.group("UserConstants");
0116     QString tmp;
0117 
0118     for (int i = 0;; i++) {
0119         tmp.setNum(i);
0120         QString name = group.readEntry("nameConstant" + tmp, QStringLiteral(" "));
0121         QString expression = group.readEntry("expressionConstant" + tmp, QStringLiteral(" "));
0122         QString value = group.readEntry("valueConstant" + tmp, QStringLiteral(" "));
0123 
0124         if (name == QLatin1String(" "))
0125             return;
0126 
0127         if (name.isEmpty())
0128             continue;
0129 
0130         if (expression == QLatin1String(" ")) {
0131             // Old config file
0132             expression = value;
0133         }
0134 
0135         if (!isValidName(name) || have(name))
0136             name = generateUniqueName();
0137 
0138         Constant constant;
0139         constant.value = expression;
0140         constant.type = Constant::Global;
0141 
0142         add(name, constant);
0143     }
0144 }
0145 
0146 void Constants::save()
0147 {
0148     KConfig conf(QStringLiteral("kcalcrc"), KConfig::SimpleConfig);
0149     conf.deleteGroup("Constants");
0150 
0151     // remove any previously saved constants
0152     conf.deleteGroup("UserConstants");
0153 
0154     KConfigGroup group = conf.group("UserConstants");
0155     QString tmp;
0156 
0157     ConstantList global = list(Constant::Global);
0158 
0159     int i = 0;
0160     for (ConstantList::iterator it = global.begin(); it != global.end(); ++it) {
0161         tmp.setNum(i);
0162         group.writeEntry("nameConstant" + tmp, it.key());
0163         group.writeEntry("expressionConstant" + tmp, it.value().value.expression());
0164         group.writeEntry("valueConstant" + tmp, it.value().value.value());
0165 
0166         i++;
0167     }
0168 }
0169 // END class Constants
0170 
0171 #include "moc_constants.cpp"