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