File indexing completed on 2024-11-03 11:23:25

0001 /***************************************************************************
0002  *   Copyright (C) 2003-2005 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "cnitem.h"
0012 #include "colorutils.h"
0013 
0014 #include <KLocalizedString>
0015 
0016 #include <cmath>
0017 
0018 #include <ktechlab_debug.h>
0019 
0020 using namespace std;
0021 
0022 Variant::Variant(const QString &id, Type::Value type)
0023     : QObject()
0024     , m_id(id)
0025 {
0026     m_type = type;
0027     m_bSetDefault = false;
0028     m_bHidden = false;
0029     m_bAdvanced = false;
0030     m_minValue = 1e-6;
0031     m_maxValue = 1e9;
0032     m_minAbsValue = 1e-6;
0033     m_colorScheme = ColorUtils::QtStandard;
0034     if (type == Type::Color) {
0035         // this value is taken from ColorCombo and should ideally be put somewhere...
0036         m_defaultValue = "#f62a2a";
0037         m_value = "#f62a2a";
0038     }
0039 }
0040 
0041 Variant::~Variant()
0042 {
0043 }
0044 
0045 void Variant::setType(Type::Value type)
0046 {
0047     m_type = type;
0048 }
0049 
0050 void Variant::appendAllowed(const QString &id, const QString &i18nName)
0051 {
0052     m_allowed[id] = i18nName;
0053 }
0054 
0055 void Variant::setAllowed(const QStringList &allowed)
0056 {
0057     m_allowed.clear();
0058     QStringList::const_iterator end = allowed.end();
0059     for (QStringList::const_iterator it = allowed.begin(); it != end; ++it)
0060         m_allowed[*it] = *it;
0061 }
0062 
0063 void Variant::appendAllowed(const QString &allowed)
0064 {
0065     m_allowed[allowed] = allowed;
0066 }
0067 
0068 void Variant::setMinValue(double value)
0069 {
0070     m_minValue = value;
0071     if (std::abs(value) < m_minAbsValue && value != 0.) {
0072         m_minAbsValue = std::abs(value);
0073     }
0074 }
0075 
0076 void Variant::setMaxValue(double value)
0077 {
0078     m_maxValue = value;
0079     if (std::abs(value) < m_minAbsValue && value != 0.) {
0080         m_minAbsValue = std::abs(value);
0081     }
0082 }
0083 
0084 QString Variant::displayString() const
0085 {
0086     switch (type()) {
0087     case Variant::Type::Double: {
0088         double numValue = m_value.toDouble();
0089         return QString::number(numValue / CNItem::getMultiplier(numValue)) + " " + CNItem::getNumberMag(numValue) + m_unit;
0090     }
0091 
0092     case Variant::Type::Int:
0093         return m_value.toString() + " " + m_unit;
0094 
0095     case Variant::Type::Bool:
0096         return m_value.toBool() ? i18n("True") : i18n("False");
0097 
0098     case Variant::Type::Select:
0099         return m_allowed[m_value.toString()];
0100 
0101     default:
0102         return m_value.toString();
0103     }
0104 }
0105 
0106 void Variant::setValue(QVariant val)
0107 {
0108     qCDebug(KTL_LOG) << "val=" << val << " old=" << m_value;
0109     if (type() == Variant::Type::Select && !m_allowed.contains(val.toString())) {
0110         // Our value is being set to an i18n name, not the actual string id.
0111         // So change val to the id (if it exists)
0112 
0113         QString i18nName = val.toString();
0114 
0115         QStringMap::iterator end = m_allowed.end();
0116         for (QStringMap::iterator it = m_allowed.begin(); it != end; ++it) {
0117             if (it.value() == i18nName) {
0118                 val = it.key();
0119                 break;
0120             }
0121         }
0122     }
0123 
0124     if (!m_bSetDefault) {
0125         m_defaultValue = val;
0126         m_bSetDefault = true;
0127     }
0128 
0129     if (m_value == val)
0130         return;
0131 
0132     const QVariant old = m_value;
0133     m_value = val;
0134     emit(valueChanged(val, old));
0135 
0136     switch (type()) {
0137     case Variant::Type::String:
0138     case Variant::Type::FileName:
0139     case Variant::Type::PenCapStyle:
0140     case Variant::Type::PenStyle:
0141     case Variant::Type::Port:
0142     case Variant::Type::Pin:
0143     case Variant::Type::VarName:
0144     case Variant::Type::Combo:
0145     case Variant::Type::Select:
0146     case Variant::Type::SevenSegment:
0147     case Variant::Type::KeyPad:
0148     case Variant::Type::Multiline:
0149     case Variant::Type::RichText: {
0150         QString dispString = displayString();
0151         qCDebug(KTL_LOG) << "dispString=" << dispString << " value=" << m_value;
0152         emit valueChanged(dispString);
0153         emit valueChangedStrAndTrue(dispString, true);
0154     } break;
0155 
0156     case Variant::Type::Int:
0157         emit valueChanged(value().toInt());
0158         break;
0159 
0160     case Variant::Type::Double:
0161         emit valueChanged(value().toDouble());
0162         break;
0163 
0164     case Variant::Type::Color:
0165         emit valueChanged(value().value<QColor>());
0166         break;
0167 
0168     case Variant::Type::Bool:
0169         emit valueChanged(value().toBool());
0170         break;
0171 
0172     case Variant::Type::Raw:
0173     case Variant::Type::None:
0174         break;
0175     }
0176     qCDebug(KTL_LOG) << "result m_value=" << m_value;
0177 }
0178 
0179 void Variant::setMinAbsValue(double val)
0180 {
0181     m_minAbsValue = val;
0182 }
0183 
0184 bool Variant::changed() const
0185 {
0186     // Have to handle double slightly differently due inperfect storage of real
0187     // numbers
0188     if (type() == Type::Double) {
0189         double cur = value().toDouble();
0190         double def = defaultValue().toDouble();
0191 
0192         double diff = abs(cur - def);
0193         if (diff == 0)
0194             return false;
0195 
0196         // denom cannot be zero
0197         double denom = max(abs(cur), abs(def));
0198 
0199         // not changed if within 1e-4% of each other's value
0200         return ((diff / denom) > 1e-6);
0201     }
0202     return value() != defaultValue();
0203 }
0204 
0205 #include "moc_variant.cpp"