File indexing completed on 2024-04-28 05:32:12

0001 #ifndef oxygenoption_h
0002 #define oxygenoption_h
0003 /*
0004 * this file is part of the oxygen gtk engine
0005 * SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0006 *
0007 * inspired notably from kdelibs/kdeui/color/kcolorutils.h
0008 * SPDX-FileCopyrightText: 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
0009 * SPDX-FileCopyrightText: 2007 Thomas Zander <zander@kde.org>
0010 * SPDX-FileCopyrightText: 2007 Zack Rusin <zack@kde.org>
0011 *
0012 * SPDX-License-Identifier: LGPL-2.0-or-later
0013 */
0014 
0015 #include "config.h"
0016 
0017 #include <iostream>
0018 #include <set>
0019 #include <sstream>
0020 #include <string>
0021 
0022 namespace Oxygen
0023 {
0024 
0025     //! used to store values from kde-like rc file
0026     class Option
0027     {
0028         public:
0029 
0030         //! constructor
0031         explicit Option( const std::string& tag = std::string(), const std::string& value = std::string() ):
0032             _tag(tag),
0033             _value(value)
0034         {}
0035 
0036         //! destructor
0037         virtual ~Option( void )
0038         {}
0039 
0040         //! equal to operator
0041         bool operator == (const Option& other ) const
0042         { return tag() == other.tag(); }
0043 
0044         //! equal to operator
0045         bool operator == (const std::string& other ) const
0046         { return tag() == other; }
0047 
0048         //! less than operator
0049         bool operator < (const Option& other ) const
0050         { return tag() < other.tag(); }
0051 
0052         //! tag
0053         const std::string& tag( void ) const
0054         { return _tag; }
0055 
0056         //! value
0057         const std::string& value( void ) const
0058         { return _value; }
0059 
0060         #if OXYGEN_DEBUG
0061         //! set filename from where option was read
0062         void setFile( const std::string& file )
0063         { _file = file; }
0064         #endif
0065 
0066         //! convert to integer
0067         int toInt( int defaultValue ) const
0068         { return toVariant<int>( defaultValue ); }
0069 
0070         template< typename T>  T toVariant( T = T() ) const;
0071 
0072         class Set: public std::set<Option>
0073         {
0074             public:
0075 
0076             //! equal to operator
0077             /*!
0078             it differs from the stl version, based on Option equal to operator
0079             in that it is more strict. This is needed to actually track option
0080             changes prior to reloading */
0081             inline bool operator == (const Set&  ) const;
0082 
0083         };
0084 
0085         #if OXYGEN_DEBUG
0086         protected:
0087         const std::string& file( void ) const
0088         { return _file; }
0089         #endif
0090 
0091         private:
0092 
0093         //! tag
0094         std::string _tag;
0095 
0096         //! value
0097         std::string _value;
0098 
0099         //! file (used for debugging)
0100         std::string _file;
0101 
0102         //! streamer
0103         friend std::ostream& operator << (std::ostream& out, const Option& option )
0104         {
0105             out << option.tag() << "=" << option.value();
0106 
0107             #if OXYGEN_DEBUG
0108             if( !option.file().empty() )
0109             { out << " (" << option.file() << ")"; }
0110             #endif
0111 
0112             return out;
0113         }
0114 
0115         //! streamer
0116         friend std::ostream& operator << (std::ostream& out, const Option::Set& options )
0117         {
0118             for( Option::Set::const_iterator iter = options.begin(); iter != options.end(); ++iter )
0119             { out << *iter << std::endl; }
0120 
0121             return out;
0122         }
0123 
0124     };
0125 
0126     //_______________________________________________________________________
0127     template<typename T> T Option::toVariant( T defaultValue ) const
0128     {
0129 
0130         T out;
0131         std::istringstream stream( _value );
0132         return ( stream >> out ) ? out:defaultValue;
0133     }
0134 
0135     // specialization of template to correctly handle std::string with spaces
0136     template<> std::string Option::toVariant( std::string defaultValue ) const;
0137 
0138     //_______________________________________________________________________
0139     bool Option::Set::operator == (const Option::Set& other ) const
0140     {
0141         const_iterator firstIter = begin();
0142         const_iterator secondIter = other.begin();
0143         for(;firstIter != end() && secondIter != other.end(); ++firstIter, ++secondIter )
0144         {
0145             if( firstIter->_tag != secondIter->_tag || firstIter->_value != secondIter->_value )
0146             { return false; }
0147         }
0148 
0149         return firstIter == end() && secondIter == other.end();
0150     }
0151 
0152 }
0153 
0154 #endif