GUI: Enhance ThemeEngine to find theme .zip files using SearchMan

This is based on the Android specific patch found under:
backends/platform/android/scummvm-android-themeengine.patch
After some testing we should be able to get rid of that custom patch.

svn-id: r51028
This commit is contained in:
Max Horn 2010-07-19 14:28:46 +00:00
parent 2a0cff5c6d
commit 9977e2db90
2 changed files with 67 additions and 32 deletions

View File

@ -44,10 +44,6 @@
#include "gui/ThemeEval.h"
#include "gui/ThemeParser.h"
#if defined(MACOSX) || defined(IPHONE)
#include <CoreFoundation/CoreFoundation.h>
#endif
#define GUI_ENABLE_BUILTIN_THEME
namespace GUI {
@ -396,15 +392,23 @@ bool ThemeEngine::init() {
// Try to create a Common::Archive with the files of the theme.
if (!_themeArchive && !_themeFile.empty()) {
Common::FSNode node(_themeFile);
if (node.getName().hasSuffix(".zip") && !node.isDirectory()) {
Common::Archive *zipArchive = Common::makeZipArchive(node);
if (!zipArchive) {
warning("Failed to open Zip archive '%s'.", node.getPath().c_str());
}
_themeArchive = zipArchive;
} else if (node.isDirectory()) {
if (node.isDirectory()) {
_themeArchive = new Common::FSDirectory(node);
} else if (_themeFile.hasSuffix(".zip")) {
// TODO: Also use "node" directly?
// Look for the zip file via SearchMan
Common::ArchiveMemberPtr member = SearchMan.getMember(_themeFile);
if (member) {
_themeArchive = Common::makeZipArchive(member->createReadStream());
if (!_themeArchive) {
warning("Failed to open Zip archive '%s'.", member->getDisplayName().c_str());
}
} else {
_themeArchive = Common::makeZipArchive(node);
if (!_themeArchive) {
warning("Failed to open Zip archive '%s'.", node.getPath().c_str());
}
}
}
}
@ -1553,6 +1557,28 @@ bool ThemeEngine::themeConfigParseHeader(Common::String header, Common::String &
return tok.empty();
}
bool ThemeEngine::themeConfigUsable(const Common::ArchiveMember &member, Common::String &themeName) {
Common::File stream;
bool foundHeader = false;
if (member.getName().hasSuffix(".zip")) {
Common::Archive *zipArchive = Common::makeZipArchive(member.createReadStream());
if (zipArchive && zipArchive->hasFile("THEMERC")) {
stream.open("THEMERC", *zipArchive);
}
delete zipArchive;
}
if (stream.isOpen()) {
Common::String stxHeader = stream.readLine();
foundHeader = themeConfigParseHeader(stxHeader, themeName);
}
return foundHeader;
}
bool ThemeEngine::themeConfigUsable(const Common::FSNode &node, Common::String &themeName) {
Common::File stream;
bool foundHeader = false;
@ -1608,26 +1634,7 @@ void ThemeEngine::listUsableThemes(Common::List<ThemeDescriptor> &list) {
if (ConfMan.hasKey("themepath"))
listUsableThemes(Common::FSNode(ConfMan.get("themepath")), list);
#ifdef DATA_PATH
listUsableThemes(Common::FSNode(DATA_PATH), list);
#endif
#if defined(MACOSX) || defined(IPHONE)
CFURLRef resourceUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
if (resourceUrl) {
char buf[256];
if (CFURLGetFileSystemRepresentation(resourceUrl, true, (UInt8 *)buf, 256)) {
Common::FSNode resourcePath(buf);
listUsableThemes(resourcePath, list);
}
CFRelease(resourceUrl);
}
#endif
if (ConfMan.hasKey("extrapath"))
listUsableThemes(Common::FSNode(ConfMan.get("extrapath")), list);
listUsableThemes(Common::FSNode("."), list, 1);
listUsableThemes(SearchMan, list);
// Now we need to strip all duplicates
// TODO: It might not be the best idea to strip duplicates. The user might
@ -1646,6 +1653,32 @@ void ThemeEngine::listUsableThemes(Common::List<ThemeDescriptor> &list) {
output.clear();
}
void ThemeEngine::listUsableThemes(Common::Archive &archive, Common::List<ThemeDescriptor> &list) {
ThemeDescriptor td;
Common::ArchiveMemberList fileList;
archive.listMatchingMembers(fileList, "*.zip");
for (Common::ArchiveMemberList::iterator i = fileList.begin();
i != fileList.end(); ++i) {
td.name.clear();
if (themeConfigUsable(**i, td.name)) {
td.filename = (*i)->getName();
td.id = (*i)->getDisplayName();
// If the name of the node object also contains
// the ".zip" suffix, we will strip it.
if (td.id.hasSuffix(".zip")) {
for (int j = 0; j < 4; ++j)
td.id.deleteLastChar();
}
list.push_back(td);
}
}
fileList.clear();
}
void ThemeEngine::listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth) {
if (!node.exists() || !node.isReadable() || !node.isDirectory())
return;

View File

@ -583,11 +583,13 @@ public:
static void listUsableThemes(Common::List<ThemeDescriptor> &list);
private:
static bool themeConfigUsable(const Common::FSNode &node, Common::String &themeName);
static bool themeConfigUsable(const Common::ArchiveMember &member, Common::String &themeName);
static bool themeConfigParseHeader(Common::String header, Common::String &themeName);
static Common::String getThemeFile(const Common::String &id);
static Common::String getThemeId(const Common::String &filename);
static void listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth = -1);
static void listUsableThemes(Common::Archive &archive, Common::List<ThemeDescriptor> &list);
protected:
OSystem *_system; /** Global system object. */