/*************************************************************************** * Copyright (c) 2015 Ian Rees * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ # include # include #endif #include #include "Enumeration.h" #include using namespace App; namespace { struct StringCopy : public Enumeration::Object { explicit StringCopy(const char* str) : d(str) { } const char* data() const override { return d.data(); } bool isEqual(const char* str) const override { return d == str; } bool isCustom() const override { return true; } private: std::string d; }; struct StringView : public Enumeration::Object { explicit StringView(const char* str) : d(str) { } const char* data() const override { return d.data(); } bool isEqual(const char* str) const override { return d == str; } bool isCustom() const override { return false; } private: std::string_view d; }; } Enumeration::Enumeration() : _index(0) { } Enumeration::Enumeration(const Enumeration &other) { enumArray = other.enumArray; _index = other._index; } Enumeration::Enumeration(const char *valStr) : _index(0) { enumArray.push_back(std::make_shared(valStr)); setValue(valStr); } Enumeration::Enumeration(const char **list, const char *valStr) : _index(0) { while (list && *list) { enumArray.push_back(std::make_shared(*list)); list++; } setValue(valStr); } Enumeration::~Enumeration() { enumArray.clear(); } void Enumeration::setEnums(const char **plEnums) { std::string oldValue; bool preserve = (isValid() && plEnums != nullptr); if (preserve) { const char* str = getCStr(); if (str) oldValue = str; } enumArray.clear(); while (plEnums && *plEnums) { enumArray.push_back(std::make_shared(*plEnums)); plEnums++; } // set _index if (_index < 0) _index = 0; if (preserve) { setValue(oldValue); } } void Enumeration::setEnums(const std::vector &values) { if (values.empty()) { setEnums(nullptr); return; } std::string oldValue; bool preserve = isValid(); if (preserve) { const char* str = getCStr(); if (str) oldValue = str; } enumArray.clear(); for (std::vector::const_iterator it = values.begin(); it != values.end(); ++it) { enumArray.push_back(std::make_shared(it->c_str())); } // set _index if (_index < 0) _index = 0; if (preserve) { setValue(oldValue); } } void Enumeration::setValue(const char *value) { _index = 0; for (std::size_t i = 0; i < enumArray.size(); i++) { if (enumArray[i]->isEqual(value)) { _index = static_cast(i); break; } } } void Enumeration::setValue(long value, bool checkRange) { if (value >= 0 && value < countItems()) { _index = value; } else { if (checkRange) { throw Base::ValueError("Out of range"); } else { _index = value; } } } bool Enumeration::isValue(const char *value) const { int i = getInt(); if (i == -1) { return false; } else { return enumArray[i]->isEqual(value); } } bool Enumeration::contains(const char *value) const { if (!isValid()) { return false; } for (const auto& it : enumArray) { if (it->isEqual(value)) return true; } return false; } const char * Enumeration::getCStr() const { if (!isValid() || _index < 0 || _index >= countItems()) { return nullptr; } return enumArray[_index]->data(); } int Enumeration::getInt() const { if (!isValid() || _index < 0 || _index >= countItems()) { return -1; } return _index; } std::vector Enumeration::getEnumVector() const { std::vector list; for (const auto& it : enumArray) list.emplace_back(it->data()); return list; } bool Enumeration::hasEnums() const { return (!enumArray.empty()); } bool Enumeration::isValid() const { return (!enumArray.empty() && _index >= 0 && _index < countItems()); } int Enumeration::maxValue() const { int num = -1; if (!enumArray.empty()) num = static_cast(enumArray.size()) - 1; return num; } bool Enumeration::isCustom() const { for (const auto& it : enumArray) { if (it->isCustom()) return true; } return false; } Enumeration & Enumeration::operator=(const Enumeration &other) { if (this == &other) return *this; enumArray = other.enumArray; _index = other._index; return *this; } bool Enumeration::operator==(const Enumeration &other) const { if (_index != other._index || enumArray.size() != other.enumArray.size()) { return false; } for (size_t i = 0; i < enumArray.size(); ++i) { if (enumArray[i]->data() == other.enumArray[i]->data()) continue; if (!enumArray[i]->data() || !other.enumArray[i]->data()) return false; if (!enumArray[i]->isEqual(other.enumArray[i]->data())) return false; } return true; } bool Enumeration::operator==(const char *other) const { if (!getCStr()) { return false; } return (strcmp(getCStr(), other) == 0); } int Enumeration::countItems() const { return static_cast(enumArray.size()); }