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

0001 #ifndef oxygengtkrc_h
0002 #define oxygengtkrc_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 * SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #include <iostream>
0011 #include <list>
0012 #include <sstream>
0013 #include <string>
0014 #include <vector>
0015 
0016 namespace Oxygen
0017 {
0018     namespace Gtk
0019     {
0020 
0021         //! convenience class to generate GtkRC option
0022         template< typename T>
0023             class RCOption
0024         {
0025             public:
0026 
0027             //! constructor
0028             RCOption( std::string name, const T& value )
0029             {
0030                 std::ostringstream stream;
0031                 stream << name << " = " << value;
0032                 _value = stream.str();
0033             }
0034 
0035             //! cast to cairo_t
0036             operator const std::string& (void) const
0037             { return _value; }
0038 
0039             private:
0040 
0041             std::string _value;
0042 
0043         };
0044 
0045         //! handle gtkrc option generation
0046         class RC
0047         {
0048 
0049             public:
0050 
0051             //! constructor
0052             explicit RC( void )
0053             { init(); }
0054 
0055             //! destructor
0056             virtual ~RC( void )
0057             {}
0058 
0059             //! clear
0060             void clear( void )
0061             {
0062                 _sections.clear();
0063                 init();
0064             }
0065 
0066 
0067             //! merge
0068             void merge( const RC& );
0069 
0070             //! create new section and set as current
0071             void addSection( const std::string& name, const std::string& parent = std::string() );
0072 
0073             //! set current section
0074             void setCurrentSection( const std::string& name );
0075 
0076             //! add line to section
0077             void addToSection( const std::string& name, const std::string& content );
0078 
0079             //! add line to current section
0080             void addToCurrentSection( const std::string& content )
0081             { addToSection( _currentSection, content ); }
0082 
0083             //! add to header
0084             void addToHeaderSection( const std::string& content )
0085             { addToSection( _headerSectionName, content ); }
0086 
0087             //! add to root
0088             void addToRootSection( const std::string& content )
0089             { addToSection( _rootSectionName, content ); }
0090 
0091             //! match given widget selection to given section
0092             void matchClassToSection( const std::string& content, const std::string& name );
0093             void matchWidgetToSection( const std::string& content, const std::string& name );
0094             void matchWidgetClassToSection( const std::string& content, const std::string& name );
0095 
0096             //! default section name
0097             static const std::string& defaultSection( void )
0098             { return _defaultSectionName; }
0099 
0100             //! convert to string
0101             std::string toString( void ) const
0102             {
0103                 std::ostringstream out;
0104                 out << *this << std::endl;
0105                 return out.str();
0106             }
0107 
0108             //! commit to gtk and clear
0109             void commit( void );
0110 
0111             protected:
0112 
0113             //! initialize default sections
0114             void init( void )
0115             {
0116                 addSection( _headerSectionName );
0117                 addSection( _rootSectionName );
0118                 addSection( _defaultSectionName, "oxygen-default" );
0119                 addToRootSection( std::string("class \"*\" style \"")+_defaultSectionName+"\"" );
0120             }
0121 
0122             //! describes each style section in resource list
0123             class Section
0124             {
0125 
0126                 public:
0127 
0128                 //! list
0129                 typedef std::list<Section> List;
0130 
0131                 //! empty constructor
0132                 explicit Section( void )
0133                 {}
0134 
0135                 //! constructor
0136                 explicit Section( const std::string& name, const std::string& parent = std::string() ):
0137                     _name( name ),
0138                     _parent( parent )
0139                 {}
0140 
0141                 //! clear
0142                 void clear( void )
0143                 { _content.clear(); }
0144 
0145                 //! add to content
0146                 void add( const std::string& content )
0147                 {
0148                     if( !content.empty() )
0149                     _content.push_back( content );
0150                 }
0151 
0152                 //! contents list shortcut
0153                 typedef std::vector<std::string> ContentList;
0154 
0155                 //! add to content
0156                 void add( const ContentList& );
0157 
0158                 //! equal operator. Based on name only
0159                 bool operator == (const Section& other ) const
0160                 { return other._name == _name; }
0161 
0162                 //! equal operator. Based on name only
0163                 bool operator == (const std::string& other ) const
0164                 { return other == _name; }
0165 
0166                 //! name
0167                 std::string _name;
0168 
0169                 //! parent
0170                 std::string _parent;
0171 
0172                 //! content
0173                 ContentList _content;
0174 
0175                 //! used to find section with matching name
0176                 class SameNameFTor
0177                 {
0178                     public:
0179 
0180                     //! constructor
0181                     SameNameFTor( const Section& section ):
0182                         _name( section._name )
0183                         {}
0184 
0185                     //! predicate
0186                     bool operator() ( const Section& other ) const
0187                     { return _name == other._name; }
0188 
0189                     private:
0190 
0191                     //! prediction
0192                     std::string _name;
0193 
0194                 };
0195 
0196 
0197             };
0198 
0199             private:
0200 
0201             //! root section name
0202             static const std::string _headerSectionName;
0203             static const std::string _rootSectionName;
0204             static const std::string _defaultSectionName;
0205 
0206             //! list of sections
0207             Section::List _sections;
0208 
0209             //! current section
0210             std::string _currentSection;
0211 
0212             //! streamer
0213             friend std::ostream& operator << ( std::ostream&, const Section& );
0214 
0215             //! streamer
0216             friend std::ostream& operator << ( std::ostream&, const RC& );
0217 
0218         };
0219     }
0220 
0221 }
0222 #endif