1 /*
2  *  Copyright (C) 2010 Parker Coates <coates@kde.org>
3  *
4  *  This program is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU General Public License as
6  *  published by the Free Software Foundation; either version 2 of
7  *  the License, or (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 #include "kcardtheme.h"
20 
21 // KF
22 #include <KConfig>
23 #include <KConfigGroup>
24 // Qt
25 #include <QDir>
26 #include <QFileInfo>
27 #include <QSet>
28 #include <QSharedData>
29 #include <QStandardPaths>
30 
31 
32 class KCardThemePrivate : public QSharedData
33 {
34 public:
KCardThemePrivate(bool isValid,const QString & dirName,const QString & displayName,const QString & desktopFilePath,const QString & graphicsFilePath,const QSet<QString> & supportedFeatures,const QDateTime & lastModified)35     KCardThemePrivate( bool isValid,
36                        const QString & dirName,
37                        const QString & displayName,
38                        const QString & desktopFilePath,
39                        const QString & graphicsFilePath,
40                        const QSet<QString> & supportedFeatures,
41                        const QDateTime & lastModified )
42       : isValid( isValid ),
43         dirName( dirName ),
44         displayName( displayName ),
45         desktopFilePath( desktopFilePath ),
46         graphicsFilePath( graphicsFilePath ),
47         supportedFeatures( supportedFeatures ),
48         lastModified( lastModified )
49     {
50     };
51 
52     const bool isValid;
53     const QString dirName;
54     const QString displayName;
55     const QString desktopFilePath;
56     const QString graphicsFilePath;
57     const QSet<QString> supportedFeatures;
58     const QDateTime lastModified;
59 };
60 
61 
findAll()62 QList<KCardTheme> KCardTheme::findAll()
63 {
64     QList<KCardTheme> result;
65     const QStringList indexFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("carddecks"), QStandardPaths::LocateDirectory );
66     for (const QString &index : indexFiles) {
67         const QStringList entries = QDir(index).entryList(QDir::Dirs);
68         for (const QString &d : entries) {
69             QString indexFilePath = index + QLatin1Char('/') + d + QLatin1String("/index.desktop");
70             if (QFile::exists(indexFilePath)) {
71                 QString directoryName = QFileInfo( indexFilePath ).dir().dirName();
72                 KCardTheme t( directoryName );
73                 if ( t.isValid() )
74                     result << t;
75 
76             }
77         }
78     }
79     return result;
80 }
81 
82 
findAllWithFeatures(const QSet<QString> & neededFeatures)83 QList<KCardTheme> KCardTheme::findAllWithFeatures( const QSet<QString> & neededFeatures )
84 {
85     QList<KCardTheme> result;
86     const QStringList indexFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("carddecks"), QStandardPaths::LocateDirectory );
87     for (const QString &index : indexFiles) {
88         const QStringList entries = QDir(index).entryList(QDir::Dirs);
89         for (const QString &d : entries) {
90             QString indexFilePath = index + QLatin1Char('/') + d + QLatin1String("/index.desktop");
91             if (QFile::exists(indexFilePath)) {
92                 QString directoryName = QFileInfo( indexFilePath ).dir().dirName();
93                 KCardTheme t( directoryName );
94                 if ( t.isValid() && t.supportedFeatures().contains( neededFeatures ) )
95                     result << t;
96 
97             }
98         }
99     }
100     return result;
101 }
102 
103 
KCardTheme()104 KCardTheme::KCardTheme()
105   : d( nullptr )
106 {
107 }
108 
109 
KCardTheme(const QString & dirName)110 KCardTheme::KCardTheme( const QString & dirName )
111 {
112     bool isValid = false;
113     QString displayName;
114     QString desktopFilePath;
115     QString graphicsFilePath;
116     QStringList supportedFeatures;
117     QDateTime lastModified;
118 
119     QString indexFilePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral( "carddecks/%1/index.desktop" ).arg( dirName ) );
120     if ( !indexFilePath.isEmpty() )
121     {
122         desktopFilePath = indexFilePath;
123 
124         KConfig config( indexFilePath, KConfig::SimpleConfig );
125         if ( config.hasGroup( "KDE Backdeck" ) )
126         {
127             KConfigGroup configGroup = config.group( "KDE Backdeck" );
128 
129             displayName = configGroup.readEntry( "Name" );
130 
131             supportedFeatures = configGroup.readEntry( "Features", QStringList() << QStringLiteral("AngloAmerican") << QStringLiteral("Backs1") );
132 
133             QString svgName = configGroup.readEntry( "SVG" );
134             if ( !svgName.isEmpty() )
135             {
136                 QFileInfo indexFile( indexFilePath );
137                 QFileInfo svgFile( indexFile.dir(), svgName );
138                 graphicsFilePath = svgFile.absoluteFilePath();
139 
140                 if ( svgFile.exists() )
141                 {
142                     lastModified = qMax( svgFile.lastModified(), indexFile.lastModified() );
143                     isValid = true;
144                 }
145             }
146         }
147     }
148 
149 #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
150     const QSet<QString> supportedFeaturesSet = supportedFeatures.toSet();
151 #else
152     const QSet<QString> supportedFeaturesSet(supportedFeatures.cbegin(), supportedFeatures.cend());
153 #endif
154     d = new KCardThemePrivate( isValid,
155                                dirName,
156                                displayName,
157                                desktopFilePath,
158                                graphicsFilePath,
159                                supportedFeaturesSet,
160                                lastModified );
161 }
162 
163 
KCardTheme(const KCardTheme & other)164 KCardTheme::KCardTheme( const KCardTheme & other )
165   : d( other.d )
166 {
167 }
168 
169 
~KCardTheme()170 KCardTheme::~KCardTheme()
171 {
172 }
173 
174 
operator =(const KCardTheme & other)175 KCardTheme & KCardTheme::operator=( const KCardTheme & other )
176 {
177     d = other.d;
178     return *this;
179 }
180 
181 
isValid() const182 bool KCardTheme::isValid() const
183 {
184     return d && d->isValid;
185 }
186 
187 
dirName() const188 QString KCardTheme::dirName() const
189 {
190     return d ? d->dirName : QString();
191 }
192 
193 
displayName() const194 QString KCardTheme::displayName() const
195 {
196     return d ? d->displayName : QString();
197 }
198 
199 
desktopFilePath() const200 QString KCardTheme::desktopFilePath() const
201 {
202     return d ? d->desktopFilePath : QString();
203 }
204 
205 
graphicsFilePath() const206 QString KCardTheme::graphicsFilePath() const
207 {
208     return d ? d->graphicsFilePath : QString();
209 }
210 
211 
lastModified() const212 QDateTime KCardTheme::lastModified() const
213 {
214     return d ? d->lastModified : QDateTime();
215 }
216 
217 
supportedFeatures() const218 QSet<QString> KCardTheme::supportedFeatures() const
219 {
220     return d ? d->supportedFeatures : QSet<QString>();
221 }
222 
223 
operator ==(const KCardTheme & theme) const224 bool KCardTheme::operator==( const KCardTheme &theme ) const
225 {
226     return dirName() == theme.dirName();
227 }
228 
229 
operator !=(const KCardTheme & theme) const230 bool KCardTheme::operator!=( const KCardTheme &theme ) const
231 {
232     return !operator==( theme );
233 }
234 
235