source: calamares/trunk/fuentes/src/libcalamaresui/Branding.cpp @ 7538

Last change on this file since 7538 was 7538, checked in by kbut, 13 months ago

sync with github

File size: 8.6 KB
Line 
1/* === This file is part of Calamares - <https://github.com/calamares> ===
2 *
3 *   Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
4 *   Copyright 2017, Adriaan de Groot <groot@kde.org>
5 *
6 *   Calamares is free software: you can redistribute it and/or modify
7 *   it under the terms of the GNU General Public License as published by
8 *   the Free Software Foundation, either version 3 of the License, or
9 *   (at your option) any later version.
10 *
11 *   Calamares is distributed in the hope that it will be useful,
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *   GNU General Public License for more details.
15 *
16 *   You should have received a copy of the GNU General Public License
17 *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "Branding.h"
21
22#include "GlobalStorage.h"
23#include "utils/CalamaresUtils.h"
24#include "utils/Logger.h"
25#include "utils/YamlUtils.h"
26#include "utils/ImageRegistry.h"
27
28#include <QDir>
29#include <QFile>
30#include <QPixmap>
31#include <QVariantMap>
32
33#include <yaml-cpp/yaml.h>
34
35
36namespace Calamares
37{
38
39Branding* Branding::s_instance = nullptr;
40
41Branding*
42Branding::instance()
43{
44    return s_instance;
45}
46
47
48const QStringList Branding::s_stringEntryStrings =
49{
50    "productName",
51    "version",
52    "shortVersion",
53    "versionedName",
54    "shortVersionedName",
55    "shortProductName",
56    "bootloaderEntryName",
57    "productUrl",
58    "supportUrl",
59    "knownIssuesUrl",
60    "releaseNotesUrl"
61};
62
63
64const QStringList Branding::s_imageEntryStrings =
65{
66    "productLogo",
67    "productIcon",
68    "productWelcome"
69};
70
71const QStringList Branding::s_styleEntryStrings =
72{
73    "sidebarBackground",
74    "sidebarText",
75    "sidebarTextSelect",
76    "sidebarTextHighlight"
77};
78
79
80Branding::Branding( const QString& brandingFilePath,
81                    QObject* parent )
82    : QObject( parent )
83    , m_descriptorPath( brandingFilePath )
84    , m_componentName()
85    , m_welcomeStyleCalamares( false )
86    , m_welcomeExpandingLogo( true )
87{
88    cDebug() << "Using Calamares branding file at" << brandingFilePath;
89    QFile file( brandingFilePath );
90    if ( file.exists() && file.open( QFile::ReadOnly | QFile::Text ) )
91    {
92        QByteArray ba = file.readAll();
93
94        QFileInfo fi ( m_descriptorPath );
95        QDir componentDir = fi.absoluteDir();
96        if ( !componentDir.exists() )
97            bail( "Bad component directory path." );
98
99        try
100        {
101            YAML::Node doc = YAML::Load( ba.constData() );
102            Q_ASSERT( doc.IsMap() );
103
104            m_componentName = QString::fromStdString( doc[ "componentName" ]
105                                                      .as< std::string >() );
106            if ( m_componentName != QFileInfo( m_descriptorPath ).absoluteDir().dirName() )
107                bail( "The branding component name should match the name of the "
108                      "component directory." );
109
110            if ( !doc[ "strings" ].IsMap() )
111                bail( "Syntax error in strings map." );
112
113            m_welcomeStyleCalamares = doc[ "welcomeStyleCalamares" ].as< bool >( false );
114            m_welcomeExpandingLogo = doc[ "welcomeExpandingLogo" ].as< bool >( true );
115
116            QVariantMap strings =
117                CalamaresUtils::yamlMapToVariant( doc[ "strings" ] ).toMap();
118            m_strings.clear();
119            for ( auto it = strings.constBegin(); it != strings.constEnd(); ++it )
120                m_strings.insert( it.key(), it.value().toString() );
121
122            if ( !doc[ "images" ].IsMap() )
123                bail( "Syntax error in images map." );
124
125            QVariantMap images =
126                CalamaresUtils::yamlMapToVariant( doc[ "images" ] ).toMap();
127            m_images.clear();
128            for ( auto it = images.constBegin(); it != images.constEnd(); ++it )
129            {
130                QString pathString = it.value().toString();
131                QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) );
132                if ( !imageFi.exists() )
133                    bail( QString( "Image file %1 does not exist." )
134                            .arg( imageFi.absoluteFilePath() ) );
135
136                m_images.insert( it.key(), imageFi.absoluteFilePath() );
137            }
138
139            if ( doc[ "slideshow" ].IsSequence() )
140            {
141                QStringList slideShowPictures;
142                doc[ "slideshow" ] >> slideShowPictures;
143                for ( int i = 0; i < slideShowPictures.count(); ++i )
144                {
145                    QString pathString = slideShowPictures[ i ];
146                    QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) );
147                    if ( !imageFi.exists() )
148                        bail( QString( "Slideshow file %1 does not exist." )
149                                .arg( imageFi.absoluteFilePath() ) );
150
151                    slideShowPictures[ i ] = imageFi.absoluteFilePath();
152                }
153
154                //FIXME: implement a GenericSlideShow.qml that uses these slideShowPictures
155            }
156            else if ( doc[ "slideshow" ].IsScalar() )
157            {
158                QString slideshowPath = QString::fromStdString( doc[ "slideshow" ]
159                                                          .as< std::string >() );
160                QFileInfo slideshowFi( componentDir.absoluteFilePath( slideshowPath ) );
161                if ( !slideshowFi.exists() ||
162                     !slideshowFi.fileName().toLower().endsWith( ".qml" ) )
163                    bail( QString( "Slideshow file %1 does not exist or is not a valid QML file." )
164                            .arg( slideshowFi.absoluteFilePath() ) );
165                m_slideshowPath = slideshowFi.absoluteFilePath();
166            }
167            else
168                bail( "Syntax error in slideshow sequence." );
169
170            if ( !doc[ "style" ].IsMap() )
171                bail( "Syntax error in style map." );
172
173            QVariantMap style =
174                CalamaresUtils::yamlMapToVariant( doc[ "style" ] ).toMap();
175            m_style.clear();
176            for ( auto it = style.constBegin(); it != style.constEnd(); ++it )
177                m_style.insert( it.key(), it.value().toString() );
178
179        }
180        catch ( YAML::Exception& e )
181        {
182            CalamaresUtils::explainYamlException( e, ba, file.fileName() );
183        }
184
185        QDir translationsDir( componentDir.filePath( "lang" ) );
186        if ( !translationsDir.exists() )
187            cWarning() << "the branding component" << componentDir.absolutePath() << "does not ship translations.";
188        m_translationsPathPrefix = translationsDir.absolutePath();
189        m_translationsPathPrefix.append( QString( "%1calamares-%2" )
190                                            .arg( QDir::separator() )
191                                            .arg( m_componentName ) );
192    }
193    else
194    {
195        cWarning() << "Cannot read branding file" << file.fileName();
196    }
197
198    s_instance = this;
199    if ( m_componentName.isEmpty() )
200    {
201        cWarning() << "Failed to load component from" << brandingFilePath;
202    }
203    else
204    {
205        cDebug() << "Loaded branding component" << m_componentName;
206    }
207}
208
209
210QString
211Branding::descriptorPath() const
212{
213    return m_descriptorPath;
214}
215
216
217QString
218Branding::componentName() const
219{
220    return m_componentName;
221}
222
223
224QString
225Branding::componentDirectory() const
226{
227    QFileInfo fi ( m_descriptorPath );
228    return fi.absoluteDir().absolutePath();
229}
230
231
232QString
233Branding::translationsPathPrefix() const
234{
235    return m_translationsPathPrefix;
236}
237
238
239QString
240Branding::string( Branding::StringEntry stringEntry ) const
241{
242    return m_strings.value( s_stringEntryStrings.value( stringEntry ) );
243}
244
245
246QString
247Branding::styleString( Branding::StyleEntry styleEntry ) const
248{
249    return m_style.value( s_styleEntryStrings.value( styleEntry ) );
250}
251
252
253QString
254Branding::imagePath( Branding::ImageEntry imageEntry ) const
255{
256    return m_images.value( s_imageEntryStrings.value( imageEntry ) );
257}
258
259
260QPixmap
261Branding::image( Branding::ImageEntry imageEntry, const QSize& size ) const
262{
263    QPixmap pixmap =
264        ImageRegistry::instance()->pixmap( imagePath( imageEntry ), size );
265
266    if ( pixmap.isNull() )
267    {
268        Q_ASSERT( false );
269        return QPixmap();
270    }
271    return pixmap;
272}
273
274
275QString
276Branding::slideshowPath() const
277{
278    return m_slideshowPath;
279}
280
281void
282Branding::setGlobals( GlobalStorage* globalStorage ) const
283{
284    QVariantMap brandingMap;
285    for ( const QString& key : s_stringEntryStrings )
286        brandingMap.insert( key, m_strings.value( key ) );
287    globalStorage->insert( "branding", brandingMap );
288}
289
290
291void
292Branding::bail( const QString& message )
293{
294    cError() << "FATAL in"
295           << m_descriptorPath
296           << "\n" + message;
297    ::exit( EXIT_FAILURE );
298}
299
300}
Note: See TracBrowser for help on using the repository browser.