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

0001 /*
0002     this file is part of the oxygen gtk engine
0003     SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "oxygengtkrc.h"
0009 
0010 #include <gtk/gtk.h>
0011 #include <algorithm>
0012 #include <cassert>
0013 
0014 namespace Oxygen
0015 {
0016 
0017     //_________________________________________________
0018     const std::string Gtk::RC::_headerSectionName = "__head__";
0019     const std::string Gtk::RC::_rootSectionName = "__root__";
0020     const std::string Gtk::RC::_defaultSectionName = "oxygen-default-internal";
0021 
0022     //_________________________________________________
0023     void Gtk::RC::commit( void )
0024     {
0025         gtk_rc_parse_string( toString().c_str() );
0026         clear();
0027     }
0028 
0029     //_________________________________________________
0030     void Gtk::RC::merge( const Gtk::RC& other )
0031     {
0032 
0033         // loop over sections in other
0034         for( Section::List::const_iterator iter = other._sections.begin(); iter != other._sections.end(); ++iter )
0035         {
0036             Section::List::iterator sectionIter = std::find_if( _sections.begin(), _sections.end(), Section::SameNameFTor( *iter ) );
0037             if( sectionIter == _sections.end() ) _sections.push_back( *iter );
0038             else {
0039 
0040                 assert( sectionIter->_parent == iter->_parent );
0041                 sectionIter->add( iter->_content );
0042 
0043             }
0044 
0045         }
0046 
0047         return;
0048     }
0049 
0050     //_________________________________________________
0051     void Gtk::RC::addSection( const std::string& name, const std::string& parent )
0052     {
0053         if( std::find( _sections.begin(), _sections.end(), name ) != _sections.end() )
0054         {
0055 
0056             std::cerr << "Gtk::RC::addSection - section named " << name << " already exists" << std::endl;
0057 
0058         } else {
0059 
0060             _sections.push_back( Section( name, parent ) );
0061 
0062         }
0063 
0064         setCurrentSection( name );
0065 
0066     }
0067 
0068     //_________________________________________________
0069     void Gtk::RC::addToSection( const std::string& name, const std::string& content )
0070     {
0071         Section::List::iterator iter( std::find( _sections.begin(), _sections.end(), name ) );
0072         if( iter == _sections.end() )
0073         {
0074             std::cerr << "Gtk::RC::addToSection - unable to find section named " << name << std::endl;
0075             return;
0076         }
0077 
0078         iter->add( content );
0079     }
0080 
0081     //_________________________________________________
0082     void Gtk::RC::matchClassToSection( const std::string& content, const std::string& name )
0083     {
0084         if( std::find( _sections.begin(), _sections.end(), name ) == _sections.end() )
0085         { std::cerr << "Gtk::RC::matchClassToSection - unable to find section named " << name << std::endl; }
0086 
0087         std::ostringstream what;
0088         what << "class \"" << content << "\" style \"" << name << "\"";
0089         addToRootSection( what.str() );
0090     }
0091 
0092     //_________________________________________________
0093     void Gtk::RC::matchWidgetToSection( const std::string& content, const std::string& name )
0094     {
0095         if( std::find( _sections.begin(), _sections.end(), name ) == _sections.end() )
0096         { std::cerr << "Gtk::RC::matchWidgetToSection - unable to find section named " << name << std::endl; }
0097 
0098         std::ostringstream what;
0099         what << "widget \"" << content << "\" style \"" << name << "\"";
0100         addToRootSection( what.str() );
0101     }
0102 
0103     //_________________________________________________
0104     void Gtk::RC::matchWidgetClassToSection( const std::string& content, const std::string& name )
0105     {
0106         if( std::find( _sections.begin(), _sections.end(), name ) == _sections.end() )
0107         { std::cerr << "Gtk::RC::matchWidgetClassToSection - unable to find section named " << name << std::endl; }
0108 
0109         std::ostringstream what;
0110         what << "widget_class \"" << content << "\" style \"" << name << "\"";
0111         addToRootSection( what.str() );
0112     }
0113 
0114     //_________________________________________________
0115     void Gtk::RC::setCurrentSection( const std::string& name )
0116     {
0117         if( std::find( _sections.begin(), _sections.end(), name ) == _sections.end() )
0118         {
0119 
0120             std::cerr << "Gtk::RC::setCurrentSection - unable to find section named " << name << std::endl;
0121             return;
0122 
0123         } else {
0124 
0125             _currentSection = name;
0126 
0127         }
0128     }
0129 
0130     //_________________________________________________
0131     void Gtk::RC::Section::add( const Gtk::RC::Section::ContentList& content )
0132     {
0133         for( ContentList::const_iterator iter = content.begin(); iter != content.end(); ++iter )
0134         {
0135             if( std::find( _content.begin(), _content.end(), *iter ) == _content.end() )
0136             { _content.push_back( *iter ); }
0137         }
0138     }
0139 
0140     namespace Gtk
0141     {
0142         //_______________________________________________________________________
0143         std::ostream& operator << (std::ostream& out, const RC::Section& section )
0144         {
0145             if( section._name == RC::_rootSectionName || section._name == RC::_headerSectionName )
0146             {
0147 
0148                 // add contents
0149                 for( RC::Section::ContentList::const_iterator iter = section._content.begin(); iter != section._content.end(); ++iter )
0150                 { out << *iter << std::endl; }
0151 
0152             } else {
0153 
0154                 out << "style \"" << section._name << "\"";
0155                 if( !section._parent.empty() ) out << " = \"" << section._parent << "\"";
0156                 out << std::endl;
0157                 out << "{" << std::endl;
0158 
0159                 // add contents
0160                 for( RC::Section::ContentList::const_iterator iter = section._content.begin(); iter != section._content.end(); ++iter )
0161                 { out << *iter << std::endl; }
0162 
0163                 out << "}" << std::endl;
0164 
0165             }
0166 
0167             return out;
0168         }
0169 
0170         //_______________________________________________________________________
0171         std::ostream& operator << (std::ostream& out, const RC& rc )
0172         {
0173             // dump header section
0174             RC::Section::List::const_iterator iter( std::find( rc._sections.begin(), rc._sections.end(), RC::_headerSectionName ) );
0175             assert( iter != rc._sections.end() );
0176             out << *iter << std::endl;
0177 
0178             // dump all section except root
0179             for( RC::Section::List::const_iterator iter = rc._sections.begin(); iter != rc._sections.end(); ++iter )
0180             { if( !(*iter == RC::_rootSectionName || *iter == RC::_headerSectionName ) ) out << *iter << std::endl; }
0181 
0182             // dump root section
0183             iter = std::find( rc._sections.begin(), rc._sections.end(), RC::_rootSectionName );
0184             assert( iter != rc._sections.end() );
0185             out << *iter << std::endl;
0186 
0187             return out;
0188         }
0189 
0190     }
0191 }