/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0""
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include "cpthemechanger.h"
#include "cpthemechanger_p.h"
#include "cpthemelistmodel.h"
#include "cpthemeclient_p.h"
#include "cpthemecommon_p.h"
#include <QStringList>
#include <QSettings>
#include <QFileSystemWatcher>
#include <QPixmap>
#include <QFileInfoList>
#include <QDir>
#include <hbicon.h>
#include <hbinstance.h>
#if !defined(Q_OS_SYMBIAN)
#include <stdio.h>
static const char* KThemePathKey = "HB_THEMES_DIR";
#endif
static const QString KDefaultTheme = "sfblacktheme";
static const QString KDefaultThemeIcon = ":/image/themePreview.nvg";
static const QString KPreviewThumbnailNVG = "/scalable/qtg_graf_theme_preview_thumbnail.nvg";
static const QString KPreviewThumbnailSVG = "/scalable/qtg_graf_theme_preview_thumbnail.svg";
static const QString KPreviewPrtNVG = "/scalable/qtg_graf_theme_preview_prt.nvg";
static const QString KPreviewLscNVG = "/scalable/qtg_graf_theme_preview_lsc.nvg";
static const QString KPreviewPrtSVG = "/scalable/qtg_graf_theme_preview_prt.svg";
static const QString KPreviewLscSVG = "/scalable/qtg_graf_theme_preview_lsc.svg";
static const QString KBackgroundPrtNVG = "/scalable/qtg_graf_screen_bg_prt.nvg";
static const QString KBackgroundLscNVG = "/scalable/qtg_graf_screen_bg_lsc.nvg";
static const QString KBackgroundPrtSVG = "/scalable/qtg_graf_screen_bg_prt.svg";
static const QString KBackgroundLscSVG = "/scalable/qtg_graf_screen_bg_lsc.svg";
static const QString KBackgroundPrtPNG = "/pixmap/qtg_graf_screen_bg_prt.png";
static const QString KBackgroundLscPNG = "/pixmap/qtg_graf_screen_bg_lsc.png";
CpThemeChangerPrivate::CpThemeChangerPrivate(CpThemeChanger* qq):
q_ptr(qq),
mThemeClient(CpThemeClient::global()),
mFileWatcher(new QFileSystemWatcher(qq)),
mModel(this, qq)
{
Q_Q(CpThemeChanger);
// Figure out where our themes are. This is platform-dependent,
// but not worth breaking out into platform-private implementations
// at the moment. Ideally, this would be given to us by the theme server,
#ifdef Q_OS_WIN
static char* _path = NULL;
static size_t _size = 0;
_dupenv_s(&_path, &_size, KThemePathKey);
mThemeRootPath = QString(_path);
mThemeRootPathPostfix = QString();
free(_path);
#elif defined(Q_OS_SYMBIAN)
mThemeRootPath = "c:\\resource\\hb";
mThemeRootPathPostfix = "resource\\hb";
#elif defined(Q_OS_MACX)
mThemeRootPath = QDir::homePath() + '/' + "Library" + QString("hb");
mThemeRootPathPostfix = QString();
#elif defined(Q_OS_UNIX)
mThemeRootPath = QString(getenv(KThemePathKey));
mThemeRootPathPostfix = QString();
#else
mThemeRootPath = "c:\\resource\\hb";
mThemeRootPathPostfix = QString();
#endif
// Get our current state
if (HbInstance::instance()) {
HbTheme *hbTheme = HbInstance::instance()->theme();
if (hbTheme) {
mCurrentTheme.name = hbTheme->name();
}
}
// Watch for changes to the theme directory in flash.
// This may change once we start offering a model.
#if defined(Q_OS_SYMBIAN)
QFileInfoList driveInfoList = QDir::drives();
foreach (const QFileInfo &driveInfo, driveInfoList) {
const QString drive = driveInfo.absolutePath();
mThemesPathList << drive + mThemeRootPathPostfix;
}
#else
mThemesPathList << mThemeRootPath;
#endif
foreach (const QString &path, mThemesPathList) {
QDir themeDir;
themeDir.setPath( path ) ;
QStringList list = themeDir.entryList(QDir::AllDirs|QDir::NoDotAndDotDot,QDir::Name);
if(list.contains("themes", Qt::CaseSensitive )) {
mFileWatcher->addPath(themeDir.path() + "/themes/");
}
}
q->connect(mFileWatcher, SIGNAL(directoryChanged(const QString&)),
q, SLOT(_q_themeDirectoryChanged(const QString&)));
updateThemeList(mCurrentTheme.name);
// Connect to the theme server
connectToServer();
}
CpThemeChangerPrivate::~CpThemeChangerPrivate()
{
mThemeClient->releaseInstance();
mThemeClient = 0;
}
const CpThemeChanger::ThemeInfo& CpThemeChangerPrivate::currentTheme() const
{
return mCurrentTheme;
}
const QString& CpThemeChangerPrivate::currentThemeName() const
{
return mCurrentTheme.name.isEmpty() ? KDefaultTheme : mCurrentTheme.name;
}
int CpThemeChangerPrivate::indexOf(const CpThemeChanger::ThemeInfo& theme) const
{
return mThemeList.indexOf(theme);
}
void CpThemeChangerPrivate::updateThemeList(const QString& newThemeName)
{
if(!mThemeList.isEmpty()) {
mThemeList.clear();
}
mCurrentTheme.name = newThemeName.isEmpty() ? KDefaultTheme : newThemeName;
foreach (const QString &path, mThemesPathList) {
QDir themeDir;
themeDir.setPath( path ) ;
QStringList iconthemeslist;
QStringList list = themeDir.entryList(QDir::AllDirs|QDir::NoDotAndDotDot,QDir::Name);
CpThemeChanger::ThemeInfo nameIconPair;
if(list.contains("themes", Qt::CaseSensitive )) {
QDir root(themeDir.path());
themeDir.setPath(root.path() + "/themes/icons/") ;
iconthemeslist = themeDir.entryList(QDir::AllDirs|QDir::NoDotAndDotDot,QDir::Name);
foreach(QString themefolder, iconthemeslist) {
QDir iconThemePath(root.path() + "/themes/icons/" + themefolder);
if(iconThemePath.exists("index.theme") &&
(iconThemePath.exists("scalable") || iconThemePath.exists("pixmap") )) {
QSettings iniSetting(iconThemePath.path() + "/index.theme", QSettings::IniFormat);
iniSetting.beginGroup("Icon Theme");
QString hidden = iniSetting.value("Hidden").toString();
QString name = iniSetting.value("Name").toString();
QString iconPath = iniSetting.value("PreviewThumbnailPath").toString();
QString previewPathPrt = iniSetting.value("PreviewIconPath_prt").toString();
QString previewPathLsc = iniSetting.value("PreviewIconPath_lsc").toString();
if (name.isEmpty()) {
continue;
}
QString fullPathToIcon(iconThemePath.path());
if(iconPath.isEmpty()|| !QFileInfo(fullPathToIcon + iconPath).exists()){
//Set thumbnail
if(QFileInfo(fullPathToIcon + KPreviewThumbnailNVG).exists()){
nameIconPair.icon = HbIcon(fullPathToIcon + KPreviewThumbnailNVG);
}else if(QFileInfo(fullPathToIcon + KPreviewThumbnailSVG).exists()){
nameIconPair.icon = HbIcon(fullPathToIcon + KPreviewThumbnailSVG);
}else if(QFileInfo(fullPathToIcon + KBackgroundPrtNVG).exists()){
nameIconPair.icon = HbIcon(fullPathToIcon + KBackgroundPrtNVG);
} else if(QFileInfo(fullPathToIcon + KBackgroundPrtSVG).exists()){
nameIconPair.icon = HbIcon(fullPathToIcon + KBackgroundPrtSVG);
} else if(QFileInfo(fullPathToIcon + KBackgroundPrtPNG).exists()){
nameIconPair.icon = HbIcon(fullPathToIcon + KBackgroundPrtPNG);
}else{
nameIconPair.icon = HbIcon(KDefaultThemeIcon);
}
} else {
nameIconPair.icon = HbIcon(fullPathToIcon + iconPath);
}
//Portrait preview
if(previewPathPrt.isEmpty() || !QFileInfo(fullPathToIcon + previewPathPrt).exists()) {
if(QFileInfo(fullPathToIcon + KPreviewPrtNVG).exists()){
nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KPreviewPrtNVG);
}else if(QFileInfo(fullPathToIcon + KPreviewPrtSVG).exists()){
nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KPreviewPrtSVG);
}else if(QFileInfo(fullPathToIcon + KBackgroundPrtNVG).exists()){
nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KBackgroundPrtNVG);
} else if(QFileInfo(fullPathToIcon + KBackgroundPrtSVG).exists()){
nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KBackgroundPrtSVG);
} else if(QFileInfo(fullPathToIcon + KBackgroundPrtPNG).exists()){
nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KBackgroundPrtPNG);
} else{
nameIconPair.portraitPreviewIcon = HbIcon(KDefaultThemeIcon);
}
}
else {
nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + previewPathPrt);
}
//Landscape preview
if(previewPathLsc.isEmpty() || !QFileInfo(fullPathToIcon + previewPathLsc).exists()) {
if(QFileInfo(fullPathToIcon + KPreviewLscNVG).exists()){
nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KPreviewLscNVG);
}else if(QFileInfo(fullPathToIcon + KPreviewLscSVG).exists()){
nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KPreviewLscSVG);
}else if(QFileInfo(fullPathToIcon + KBackgroundLscNVG).exists()){
nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KBackgroundLscNVG);
} else if(QFileInfo(fullPathToIcon + KBackgroundLscSVG).exists()){
nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KBackgroundLscSVG);
} else if(QFileInfo(fullPathToIcon + KBackgroundLscPNG).exists()){
nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KBackgroundLscPNG);
} else{
nameIconPair.landscapePreviewIcon = HbIcon(KDefaultThemeIcon);
}
}
else {
nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + previewPathLsc);
}
nameIconPair.name = name;
mThemeList.append(nameIconPair);
if (name == mCurrentTheme.name) {
mCurrentTheme = nameIconPair;
}
iniSetting.endGroup();
if((hidden == "true") ||( hidden == "")||(name != themefolder) ) {
iconthemeslist.removeOne(themefolder);
if(!mThemeList.isEmpty()) {
mThemeList.removeLast();
}
}
} else {
iconthemeslist.removeOne(themefolder);
if(!mThemeList.isEmpty()) {
mThemeList.removeLast();
}
}
}
}
}
if (mCurrentTheme.name == KDefaultTheme)
{
// Include default
CpThemeChanger::ThemeInfo def;
def.name = KDefaultTheme;
def.icon = HbIcon(KDefaultThemeIcon);
mThemeList.append(def);
mCurrentTheme = def;
}
}
const QList<CpThemeChanger::ThemeInfo>& CpThemeChangerPrivate::themes() const
{
return mThemeList;
}
bool CpThemeChangerPrivate::connectToServer()
{
return mThemeClient->connectToServer();
}
/**
* Indicate if the client is connected to the server
*/
bool CpThemeChangerPrivate::isConnected() const
{
return mThemeClient->isConnected();
}
/**
* Change a theme
*/
bool CpThemeChangerPrivate::changeTheme(const QString& newTheme)
{
bool result = false;
// Skip doing this if the request is for the current theme
if (newTheme.isEmpty() || newTheme == mCurrentTheme.name) {
return result;
}
// Make sure it's a valid theme name and set the current theme.
bool exists = false;
QList<CpThemeChanger::ThemeInfo>::const_iterator i;
for (i = mThemeList.constBegin(); i != mThemeList.constEnd(); ++i) {
if ( newTheme == i->name) {
exists = true;
break;
}
}
if (exists) {
result = mThemeClient->changeTheme(newTheme);
if(result) {
mCurrentTheme = *i;
}
}
return result;
}
void CpThemeChangerPrivate::_q_themeDirectoryChanged(const QString&)
{
updateThemeList();
}
// End of file