1 /*
2     SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
3     SPDX-FileCopyrightText: 2015 David Edmundson <davidedmundson@kde.org>
4 
5     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
6 */
7 
8 #include "oxygensettingsprovider.h"
9 
10 #include "oxygendecohelper.h"
11 #include "oxygenshadowcache.h"
12 
13 #include "oxygenexceptionlist.h"
14 
15 #include <KWindowInfo>
16 
17 #include <QRegularExpression>
18 #include <QTextStream>
19 
20 namespace Oxygen
21 {
22 
23     SettingsProvider *SettingsProvider::s_self = nullptr;
24 
25     //__________________________________________________________________
SettingsProvider()26     SettingsProvider::SettingsProvider():
27         m_config( KSharedConfig::openConfig( QStringLiteral("oxygenrc") ) ),
28         m_decoHelper( new DecoHelper() ),
29         m_shadowCache( new ShadowCache( *m_decoHelper ) )
30     { reconfigure(); }
31 
32     //__________________________________________________________________
~SettingsProvider()33     SettingsProvider::~SettingsProvider()
34     {
35         s_self = nullptr;
36         delete m_shadowCache;
37         delete m_decoHelper;
38     }
39 
40     //__________________________________________________________________
self()41     SettingsProvider *SettingsProvider::self()
42     {
43         // TODO: this is not thread safe!
44         if (!s_self)
45         { s_self = new SettingsProvider(); }
46 
47         return s_self;
48     }
49 
50     //__________________________________________________________________
reconfigure(void)51     void SettingsProvider::reconfigure( void )
52     {
53         if( !m_defaultSettings )
54         {
55             m_defaultSettings = InternalSettingsPtr(new InternalSettings());
56             m_defaultSettings->setCurrentGroup( QStringLiteral("Windeco") );
57         }
58 
59         m_decoHelper->invalidateCaches();
60         m_decoHelper->loadConfig();
61 
62         m_shadowCache->readConfig();
63         m_defaultSettings->load();
64 
65         ExceptionList exceptions;
66         exceptions.readConfig( m_config );
67         m_exceptions = exceptions.get();
68 
69     }
70 
71     //__________________________________________________________________
internalSettings(const Decoration * decoration) const72     InternalSettingsPtr SettingsProvider::internalSettings(const Decoration *decoration ) const
73     {
74 
75         QString windowTitle;
76         QString className;
77 
78         // get the client
79         auto client = decoration->client().data();
80 
81         foreach( auto internalSettings, m_exceptions )
82         {
83 
84             // discard disabled exceptions
85             if( !internalSettings->enabled() ) continue;
86 
87             // discard exceptions with empty exception pattern
88             if( internalSettings->exceptionPattern().isEmpty() ) continue;
89 
90             /*
91             decide which value is to be compared
92             to the regular expression, based on exception type
93             */
94             QString value;
95             switch( internalSettings->exceptionType() )
96             {
97                 case InternalSettings::ExceptionWindowTitle:
98                 {
99                     value = windowTitle.isEmpty() ? (windowTitle = client->caption()):windowTitle;
100                     break;
101                 }
102 
103                 default:
104                 case InternalSettings::ExceptionWindowClassName:
105                 {
106                     if( className.isEmpty() )
107                     {
108                         // retrieve class name
109                         KWindowInfo info( client->windowId(), 0, NET::WM2WindowClass );
110                         QString window_className( QString::fromUtf8(info.windowClassName()) );
111                         QString window_class( QString::fromUtf8(info.windowClassClass()) );
112                         className = window_className + QStringLiteral(" ") + window_class;
113                     }
114 
115                     value = className;
116                     break;
117                 }
118 
119             }
120 
121             // check matching
122             if(value.contains(QRegularExpression( internalSettings->exceptionPattern() )))
123             { return internalSettings; }
124 
125         }
126 
127         return m_defaultSettings;
128 
129     }
130 
131 }
132