--- a/src/hbcore/theme/hbthemeutils_p.cpp Wed Jun 23 18:33:25 2010 +0300
+++ b/src/hbcore/theme/hbthemeutils_p.cpp Tue Jul 06 14:36:53 2010 +0300
@@ -23,6 +23,19 @@
**
****************************************************************************/
+#include "hbthemeutils_p.h"
+#include "hbtheme.h"
+#include "hbiniparser_p.h"
+#include "hbthemecommon_p.h"
+#include "hbthemeclient_p.h"
+#include "hbtheme_p.h"
+
+#ifdef Q_OS_SYMBIAN
+#include "hbthemecommon_symbian_p.h"
+#include <e32std.h>
+#include <centralrepository.h>
+#endif
+
#include <QLocale>
#include <QSettings>
#include <QFile>
@@ -31,19 +44,6 @@
#include <QMap>
#include <QVariant>
-#ifdef Q_OS_SYMBIAN
-#include "hbthemecommon_symbian_p.h"
-#include <e32std.h>
-#include <centralrepository.h>
-#endif
-
-#include "hbthemeutils_p.h"
-#include "hbtheme.h"
-#include "hbiniparser_p.h"
-#include "hbthemecommon_p.h"
-#include "hbthemeclient_p.h"
-
-
// Standard folder names
const char *HbThemeUtils::themeResourceFolder = "theme";
const char *HbThemeUtils::platformHierarchy = "themes";
@@ -61,7 +61,25 @@
// These are the used setting names corresponding to HbThemeUtils::Setting enumeration.
static const QString settingNames[6] = {"", "basetheme", "defaulttheme",
- "defaultthemedir", "currenttheme", "operatorbasepath"};
+ "", "currenttheme", "operatorbasepath"};
+
+static HbHeapIndexInfo *heapIndex = 0;
+
+QString themesDir()
+{
+#ifdef Q_OS_SYMBIAN
+ static QString mainThemesDir("z:/resource/hb");
+#else
+ static QString mainThemesDir = QDir::fromNativeSeparators(qgetenv("HB_THEMES_DIR"));
+ // Do not call absolutePath if the path is empty,
+ // because it would return current path in that case.
+ if (!mainThemesDir.isEmpty()) {
+ mainThemesDir = QDir(mainThemesDir).absolutePath();
+ }
+#endif
+ return mainThemesDir;
+}
+
/*!
@proto
@@ -76,40 +94,46 @@
*/
-class HbThemeUtilsPrivate
+class HbThemeSettings
{
public:
- HbThemeUtilsPrivate() : settingsRetrieved(false), mHeapThemeOffset(0)
+ HbThemeSettings() : settingsRetrieved(false)
{
}
- ~HbThemeUtilsPrivate();
+ ~HbThemeSettings();
void readSettings();
- int heapThemeOffset(const HbThemeIndexInfo &info);
+ void initSettings();
+ QString getThemeFromFile(const QString &variable, const QString &rootDir);
public: // data
bool settingsRetrieved;
// Setting values are stored here to avoid overhead of reading from QSettings every time.
QString currentTheme;
QString defaultTheme;
- QString defaultThemeRootDir;
QString baseTheme;
QString operatorName;
-
-private:
- int mHeapThemeOffset;
};
-HbThemeUtilsPrivate::~HbThemeUtilsPrivate()
+HbThemeSettings::~HbThemeSettings()
{
- if (mHeapThemeOffset > 0) {
- GET_MEMORY_MANAGER(HbMemoryManager::HeapMemory);
- manager->free(mHeapThemeOffset);
+ if (heapIndex) {
+ // Free allocated memory
+ if (heapIndex->baseTheme.address) {
+ delete heapIndex->baseTheme.address;
+ }
+ if (heapIndex->priorityTheme.address) {
+ delete heapIndex->priorityTheme.address;
+ }
+ if (heapIndex->activeTheme.address) {
+ delete heapIndex->activeTheme.address;
+ }
+ delete heapIndex;
}
}
-void HbThemeUtilsPrivate::readSettings()
+void HbThemeSettings::readSettings()
{
// The only changing setting is currentThemeSetting and its value is updated in server side in theme change event.
@@ -129,14 +153,6 @@
defaultTheme = qvalue.trimmed();
}
value.Zero();
- if (KErrNone == repository->Get(HbThemeUtils::DefaultThemeRootDirSetting, value)) {
- QString qvalue((QChar*)value.Ptr(), value.Length());
- defaultThemeRootDir = qvalue.trimmed();
- } else {
- // Use the default value
- defaultThemeRootDir = HbThemeUtils::themesDir();
- }
- value.Zero();
if (KErrNone == repository->Get(HbThemeUtils::BaseThemeSetting, value)) {
QString qvalue((QChar*)value.Ptr(), value.Length());
baseTheme = qvalue.trimmed();
@@ -149,106 +165,106 @@
delete repository;
}
#else
- QSettings settings(QLatin1String(ORGANIZATION), QLatin1String(THEME_COMPONENT));
+ QSettings settings(QSettings::IniFormat, QSettings::UserScope, QLatin1String(ORGANIZATION), QLatin1String(THEME_COMPONENT));
currentTheme = settings.value(settingNames[HbThemeUtils::CurrentThemeSetting]).toString();
defaultTheme = settings.value(settingNames[HbThemeUtils::DefaultThemeSetting]).toString();
- defaultThemeRootDir =
- settings.value(settingNames[HbThemeUtils::DefaultThemeRootDirSetting]).toString();
baseTheme = settings.value(settingNames[HbThemeUtils::BaseThemeSetting]).toString();
operatorName = settings.value(settingNames[HbThemeUtils::OperatorNameSetting]).toString();
#endif
+ initSettings();
+
settingsRetrieved = true;
}
}
-int HbThemeUtilsPrivate::heapThemeOffset(const HbThemeIndexInfo &info)
+void HbThemeSettings::initSettings()
{
- if (mHeapThemeOffset == 0) {
- QString themeindexfile = info.path + "/" + info.name +".themeindex";
- QFile indexFile(themeindexfile);
- if (indexFile.open(QIODevice::ReadOnly)) {
- GET_MEMORY_MANAGER(HbMemoryManager::HeapMemory);
- qint64 byteSize = indexFile.size();
- mHeapThemeOffset = manager->alloc(byteSize);
- if (mHeapThemeOffset >= 0) {
- char *address = HbMemoryUtils::getAddress<char>(HbMemoryManager::HeapMemory, mHeapThemeOffset);
- indexFile.read(address, byteSize);
- indexFile.close();
- }
+ // Validate base theme
+ bool modified = false;
+ if (baseTheme.isEmpty()) {
+ modified = true;
+ baseTheme = getThemeFromFile(baseThemeVariable, themesDir());
+ if (baseTheme.isEmpty()) {
+ baseTheme = getThemeFromFile(baseThemeVariable, coreResourcesRootDir);
+ }
+ }
+ if (!HbThemeUtils::isThemeValid(baseTheme)) {
+ modified = true;
+ // check if the theme name is logical
+ baseTheme = themesDir() + '/' + HbThemeUtils::platformHierarchy + '/' +
+ HbThemeUtils::iconsResourceFolder + '/' + baseTheme;
+ if (!HbThemeUtils::isThemeValid(baseTheme)) {
+ baseTheme = getThemeFromFile(baseThemeVariable, coreResourcesRootDir);
}
}
- return mHeapThemeOffset;
+ // Save if needed
+ if (modified) {
+ HbThemeUtils::setThemeSetting(HbThemeUtils::BaseThemeSetting, baseTheme);
+ modified = false;
+ }
+
+ // Validate default theme
+ if (defaultTheme.isEmpty()) {
+ modified = true;
+ defaultTheme = getThemeFromFile(defaultThemeVariable, themesDir());
+ if (defaultTheme.isEmpty()) {
+ defaultTheme = getThemeFromFile(defaultThemeVariable, coreResourcesRootDir);
+ }
+ }
+ if (!HbThemeUtils::isThemeValid(defaultTheme)) {
+ modified = true;
+ // check if the theme name is logical
+ defaultTheme = themesDir() + '/' + HbThemeUtils::platformHierarchy + '/' +
+ HbThemeUtils::iconsResourceFolder + '/' + defaultTheme;
+ if (!HbThemeUtils::isThemeValid(defaultTheme)) {
+ defaultTheme = getThemeFromFile(defaultThemeVariable, coreResourcesRootDir);
+ }
+ }
+ if (modified) {
+ HbThemeUtils::setThemeSetting(HbThemeUtils::DefaultThemeSetting, defaultTheme);
+ modified = false;
+ }
+
+ // Validate current theme
+ if (!HbThemeUtils::isThemeValid(currentTheme)) {
+ currentTheme = defaultTheme;
+ HbThemeUtils::setThemeSetting(HbThemeUtils::CurrentThemeSetting, currentTheme);
+ }
}
-static HbThemeUtilsPrivate d;
-
-/* returns information of base theme
+/* reads the theme from theme.theme file
*/
-const HbThemeInfo &HbThemeUtils::baseTheme()
+QString HbThemeSettings::getThemeFromFile(const QString &variable, const QString &rootDir)
{
- static HbThemeInfo baseThemeInfo;
-
- if (baseThemeInfo.name.isEmpty()) {
- // basetheme is empty, means it was not yet filled with appropriate values
- // Check if its value is stored in settings.
- baseThemeInfo.name = getThemeSetting(BaseThemeSetting).trimmed();
- if ( baseThemeInfo.name.isEmpty() ) {
- // Settings not yet initialized
- // Check if Base theme is defined in theme.theme
- baseThemeInfo = getBaseThemeFromFile(HbThemeUtils::themesDir());
- if (baseThemeInfo.name.isEmpty()) {
- // Base theme does not exists in rom
- // Get the base theme info from core resources
- baseThemeInfo = getBaseThemeFromFile(coreResourcesRootDir);
- }
- } else {
- // So settings are initialized, it will have other value as well
- baseThemeInfo.rootDir = getThemeSetting(DefaultThemeRootDirSetting).trimmed();
- // On desktop platforms try the HB_THEMES_DIR environment variable instead of
- // blindly sticking to the previous stored setting, the theme directory may have been
- // moved meanwhile and that usually results in a changed HB_THEMES_DIR but nobody will
- // update the our settings stored via QSettings.
-#ifndef Q_OS_SYMBIAN
- QString themesDirFromEnv = HbThemeUtils::themesDir();
- if (!themesDirFromEnv.isEmpty()) {
- baseThemeInfo.rootDir = themesDirFromEnv;
- }
-#endif
- }
+ QFile themeSetting(rootDir + '/' + HbThemeUtils::platformHierarchy + '/' + themeSettingFile);
+ QString theme;
+ HbIniParser iniParser;
+
+ if (themeSetting.open(QIODevice::ReadOnly) && iniParser.read(&themeSetting)){
+ theme = rootDir + '/' + HbThemeUtils::platformHierarchy + '/' +
+ HbThemeUtils::iconsResourceFolder + '/' +
+ iniParser.value("Default", variable).trimmed();
}
-
- return baseThemeInfo;
+ return theme;
}
-/* returns name of default theme
- */
-HbThemeInfo HbThemeUtils::defaultTheme()
-{
- // getting base theme makes sure that default theme was added in
- // QSettings, if it was not already done
- const HbThemeInfo &themeInfo = baseTheme();
-
- // Assuming the path of default theme and base theme are same
- return HbThemeInfo(getThemeSetting(DefaultThemeSetting), themeInfo.rootDir);
-}
+Q_GLOBAL_STATIC(HbThemeSettings, themeSettings);
QString HbThemeUtils::getThemeSetting(Setting setting)
{
// Make sure settings are read from QSettings.
- d.readSettings();
+ themeSettings()->readSettings();
switch (setting) {
case CurrentThemeSetting:
- return d.currentTheme;
+ return themeSettings()->currentTheme;
case DefaultThemeSetting:
- return d.defaultTheme;
- case DefaultThemeRootDirSetting:
- return d.defaultThemeRootDir;
+ return themeSettings()->defaultTheme;
case BaseThemeSetting:
- return d.baseTheme;
+ return themeSettings()->baseTheme;
case OperatorNameSetting:
- return d.operatorName;
+ return themeSettings()->operatorName;
default:
return QString();
}
@@ -268,93 +284,47 @@
delete repository;
}
#else
- QSettings settings(QLatin1String(ORGANIZATION), QLatin1String(THEME_COMPONENT));
+ QSettings settings(QSettings::IniFormat, QSettings::UserScope, QLatin1String(ORGANIZATION), QLatin1String(THEME_COMPONENT));
settings.setValue(settingNames[setting], QVariant(value));
// Destructor of QSettings flushes the changed setting in the INI file.
#endif
+ updateThemeSetting(setting, value);
}
/**
* Updates the setting's value in stored member variables.
* Normally the settings are loaded from QSettings when method getThemeSetting() is called for the first time.
-* When there is a change in settings, this method can be used to sync the setting value stored in HbThemeUtilsPrivate.
+* When there is a change in settings, this method can be used to sync the setting value stored in HbThemeSettings.
* E.g. theme change event updates the current theme setting, currently no other settings are changing their values.
*/
void HbThemeUtils::updateThemeSetting(Setting setting, const QString &value)
{
switch (setting) {
case CurrentThemeSetting:
- d.currentTheme = value;
+ themeSettings()->currentTheme = value;
break;
case DefaultThemeSetting:
- d.defaultTheme = value;
- break;
- case DefaultThemeRootDirSetting:
- d.defaultThemeRootDir = value;
+ themeSettings()->defaultTheme = value;
break;
case BaseThemeSetting:
- d.baseTheme = value;
+ themeSettings()->baseTheme = value;
break;
case OperatorNameSetting:
- d.operatorName = value;
+ themeSettings()->operatorName = value;
break;
default:
break;
}
}
-
-/* reads the theme name from theme.theme file, stores the same in theme settings,
- returns the pair of theme name and its root directory
- */
-HbThemeInfo HbThemeUtils::getBaseThemeFromFile(const QString &rootDir)
-{
- QFile themeSetting(rootDir + '/' + platformHierarchy + '/' + themeSettingFile);
- HbThemeInfo themeInfo;
- HbIniParser iniParser;
-
- if (themeSetting.open(QIODevice::ReadOnly) && iniParser.read(&themeSetting)){
- themeInfo.name = iniParser.value("Default", baseThemeVariable).trimmed();
-
- QString defaultTheme = iniParser.value("Default", defaultThemeVariable).trimmed();
-
- // default theme name may not exist, in which case using base theme as default theme
- if (defaultTheme.isEmpty()) {
- defaultTheme = themeInfo.name;
- }
-
- // Save theme names in settings
- saveBaseThemeSettings(themeInfo, defaultTheme, rootDir);
- }
- return themeInfo;
-}
-
-void HbThemeUtils::saveBaseThemeSettings(HbThemeInfo &baseThemeInfo,
- const QString &defaultTheme,
- const QString &rootDir)
-{
- // If there is any base theme
- if ((!baseThemeInfo.name.isEmpty()) && isThemeValid(HbThemeInfo(baseThemeInfo.name, rootDir))) {
- // Save these theme names in settings
- setThemeSetting(BaseThemeSetting, baseThemeInfo.name);
- setThemeSetting(DefaultThemeRootDirSetting, rootDir);
-
- // Store default theme also in settings, only if it is valid
- if (baseThemeInfo.name == defaultTheme || isThemeValid(HbThemeInfo(defaultTheme, rootDir))) {
- setThemeSetting(DefaultThemeSetting, defaultTheme);
- }
- baseThemeInfo.rootDir = rootDir;
- d.settingsRetrieved = false;
- }
-}
/* checks whether the theme is valid
*/
-bool HbThemeUtils::isThemeValid(const HbThemeInfo &themeInfo)
+bool HbThemeUtils::isThemeValid(const QString &themePath)
{
- // If the theme contains index.theme in icons resources
+ // If the theme contains .themeindex and index.theme files
// it will be assumed valid
- return QFile::exists(themeInfo.rootDir + '/' + platformHierarchy + '/' +
- iconsResourceFolder + '/' + themeInfo.name + "/index.theme");
+ QString indexFile = QString(themePath).replace("/icons/", QString('/')) + ".themeindex";
+ return (QFile::exists(themePath + "/index.theme") && QFile::exists(indexFile));
}
HbThemeIndexInfo HbThemeUtils::getThemeIndexInfo(const HbThemeType &type)
@@ -362,23 +332,27 @@
HbThemeIndexInfo info;
#ifndef Q_OS_SYMBIAN
- // If there is no themeserver connection load theme to client's heap
- if (!HbThemeClient::global()->clientConnected()) {
- HbThemeInfo baseinfo = baseTheme();
- if (baseinfo.name.isEmpty() || baseinfo.name == "hbdefault") {
- info.name = "hbdefault";
- info.path = ":/themes";
- } else {
- info.name = baseinfo.name;
- info.path = baseinfo.rootDir + "/themes";
+ if (!heapIndex) {
+ heapIndex = new HbHeapIndexInfo();
+ HbThemeUtils::loadHeapThemeIndexes();
+ }
+
+ if (heapIndex) {
+ switch(type) {
+ case BaseTheme:
+ info = heapIndex->baseTheme;
+ break;
+ case OperatorC:
+ info = heapIndex->priorityTheme;
+ break;
+ case ActiveTheme:
+ info = heapIndex->activeTheme;
+ break;
+ default:
+ break;
}
-
- info.address = HbMemoryUtils::getAddress<char>(HbMemoryManager::HeapMemory,
- d.heapThemeOffset(info));
- return info;
}
-#endif // Q_OS_SYMBIAN
-
+#else
GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
if (manager) {
HbSharedChunkHeader *chunkHeader = (HbSharedChunkHeader*)(manager->base());
@@ -428,25 +402,112 @@
break;
}
}
+#endif // Q_OS_SYMBIAN
return info;
}
bool HbThemeUtils::isLogicalName(const QString &fileName)
{
- return !(fileName.contains(QChar('/'), Qt::CaseSensitive) || fileName.contains(QChar('\\'), Qt::CaseSensitive));
+ return !(fileName.contains(QChar(':'), Qt::CaseSensitive) ||
+ fileName.contains(QChar('/'), Qt::CaseSensitive) ||
+ fileName.contains(QChar('\\'), Qt::CaseSensitive));
+}
+
+char *HbThemeUtils::createHeapThemeIndex(const HbThemeInfo &theme)
+{
+ char *address = 0;
+
+ QString path = QDir::toNativeSeparators(theme.rootDir);
+ QString filename;
+
+ filename.append(path);
+ filename.append('/');
+ filename.append(theme.name);
+ filename.append(".themeindex");
+
+ QFile indexFile(filename);
+ if (indexFile.open(QIODevice::ReadOnly)) {
+ GET_MEMORY_MANAGER(HbMemoryManager::HeapMemory);
+ qint64 byteSize = indexFile.size();
+ int indexOffset = manager->alloc(byteSize);
+ if (indexOffset != -1) {
+ address = HbMemoryUtils::getAddress<char>(HbMemoryManager::HeapMemory, indexOffset);
+ indexFile.read(address, byteSize);
+ indexFile.close();
+ }
+ }
+
+ return address;
}
-QString HbThemeUtils::themesDir()
+void HbThemeUtils::loadHeapThemeIndex(HbThemeType type)
{
-#ifdef Q_OS_SYMBIAN
- static QString mainThemesDir("Z:/resource/hb");
-#else
- static QString mainThemesDir = QDir::fromNativeSeparators(qgetenv("HB_THEMES_DIR"));
- // Do not call absolutePath if the path is empty,
- // because it would return current path in that case.
- if (!mainThemesDir.isEmpty()) {
- mainThemesDir = QDir(mainThemesDir).absolutePath();
+ if (heapIndex) {
+ switch(type) {
+ case BaseTheme: {
+ if (heapIndex->baseTheme.address) {
+ delete heapIndex->baseTheme.address;
+ }
+ QString baseThemeName = getThemeSetting(BaseThemeSetting);
+ HbThemeInfo baseInfo;
+ QDir path(baseThemeName);
+ baseInfo.name = path.dirName();
+ QString absolutePath = path.absolutePath();
+ baseInfo.rootDir = absolutePath.left(absolutePath.indexOf("/icons/"));
+
+ heapIndex->baseTheme.address = createHeapThemeIndex(baseInfo);
+ if (heapIndex->baseTheme.address) {
+ heapIndex->baseTheme.name = baseInfo.name;
+ heapIndex->baseTheme.path = baseInfo.rootDir;
+ }
+ break;
+ }
+ case OperatorC: {
+ if (heapIndex->priorityTheme.address) {
+ delete heapIndex->priorityTheme.address;
+ }
+ HbThemeInfo operatorInfo;
+ operatorInfo.name = getThemeSetting(OperatorNameSetting);
+ if (!operatorInfo.name.isEmpty()) {
+ operatorInfo.rootDir.append(themesDir() + '/' + QLatin1String(operatorHierarchy));
+ heapIndex->priorityTheme.address = createHeapThemeIndex(operatorInfo);
+ if (heapIndex->priorityTheme.address) {
+ heapIndex->priorityTheme.name = operatorInfo.name;
+ heapIndex->priorityTheme.path = operatorInfo.rootDir;
+ }
+ }
+ break;
+ }
+ case ActiveTheme: {
+ if (heapIndex->activeTheme.address) {
+ delete heapIndex->activeTheme.address;
+ }
+ QString currentThemeName = getThemeSetting(CurrentThemeSetting);
+ QDir path(currentThemeName);
+ HbThemeInfo activeInfo;
+ activeInfo.name = path.dirName();
+ QString absolutePath = path.absolutePath();
+ activeInfo.rootDir = absolutePath.left(absolutePath.indexOf("/icons/"));
+
+ heapIndex->activeTheme.address = createHeapThemeIndex(activeInfo);
+ if (heapIndex->activeTheme.address) {
+ heapIndex->activeTheme.name = activeInfo.name;
+ heapIndex->activeTheme.path = activeInfo.rootDir;
+ }
+ break;
+ }
+ default:
+ break;
+ }
}
-#endif
- return mainThemesDir;
}
+
+void HbThemeUtils::loadHeapThemeIndexes()
+{
+ // Process base theme index, it is used as parent index also when the current theme is something else
+ loadHeapThemeIndex(BaseTheme);
+ // Process operator theme indexes
+ loadHeapThemeIndex(OperatorC);
+ // Process current theme index
+ loadHeapThemeIndex(ActiveTheme);
+}