Added support for @Resources

This commit is contained in:
Birunthan Mohanathas 2012-05-20 16:12:13 +03:00
parent 965a400657
commit cb0fd823e7
10 changed files with 152 additions and 66 deletions

View File

@ -51,10 +51,8 @@ CConfigParser::~CConfigParser()
{ {
} }
void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter, CMeterWindow* meterWindow, LPCTSTR config) void CConfigParser::Initialize(const std::wstring& filename, CMeterWindow* meterWindow, LPCTSTR config)
{ {
m_Filename = filename;
m_Measures.clear(); m_Measures.clear();
m_Sections.clear(); m_Sections.clear();
m_Values.clear(); m_Values.clear();
@ -70,12 +68,19 @@ void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter, CMeterW
m_CurrentSection = NULL; m_CurrentSection = NULL;
// Set the built-in variables. Do this before the ini file is read so that the paths can be used with @include // Set the built-in variables. Do this before the ini file is read so that the paths can be used with @include
SetBuiltInVariables(pRainmeter, meterWindow); SetBuiltInVariables(filename, meterWindow);
ResetMonitorVariables(meterWindow); ResetMonitorVariables(meterWindow);
CSystem::UpdateIniFileMappingList(); CSystem::UpdateIniFileMappingList();
ReadIniFile(m_Filename, config); std::wstring resourcePath;
if (meterWindow)
{
resourcePath = meterWindow->GetSkinRootPath();
resourcePath += L"@Resources\\";
}
ReadIniFile(filename, resourcePath, config);
ReadVariables(); ReadVariables();
// Clear and minimize // Clear and minimize
@ -83,18 +88,16 @@ void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter, CMeterW
m_ListVariables.clear(); m_ListVariables.clear();
} }
void CConfigParser::SetBuiltInVariables(CRainmeter* pRainmeter, CMeterWindow* meterWindow) void CConfigParser::SetBuiltInVariables(const std::wstring& filename, CMeterWindow* meterWindow)
{ {
if (pRainmeter) SetBuiltInVariable(L"PROGRAMPATH", Rainmeter->GetPath());
{ SetBuiltInVariable(L"PROGRAMDRIVE", Rainmeter->GetDrive());
SetBuiltInVariable(L"PROGRAMPATH", pRainmeter->GetPath()); SetBuiltInVariable(L"SETTINGSPATH", Rainmeter->GetSettingsPath());
SetBuiltInVariable(L"PROGRAMDRIVE", pRainmeter->GetDrive()); SetBuiltInVariable(L"SKINSPATH", Rainmeter->GetSkinPath());
SetBuiltInVariable(L"SETTINGSPATH", pRainmeter->GetSettingsPath()); SetBuiltInVariable(L"PLUGINSPATH", Rainmeter->GetPluginPath());
SetBuiltInVariable(L"SKINSPATH", pRainmeter->GetSkinPath()); SetBuiltInVariable(L"CURRENTPATH", CRainmeter::ExtractPath(filename));
SetBuiltInVariable(L"PLUGINSPATH", pRainmeter->GetPluginPath()); SetBuiltInVariable(L"ADDONSPATH", Rainmeter->GetAddonPath());
SetBuiltInVariable(L"CURRENTPATH", CRainmeter::ExtractPath(m_Filename));
SetBuiltInVariable(L"ADDONSPATH", pRainmeter->GetAddonPath());
}
if (meterWindow) if (meterWindow)
{ {
SetBuiltInVariable(L"CURRENTFILE", meterWindow->GetSkinIniFile()); SetBuiltInVariable(L"CURRENTFILE", meterWindow->GetSkinIniFile());
@ -1152,7 +1155,7 @@ RECT CConfigParser::ParseRECT(LPCTSTR string)
** Reads the given ini file and fills the m_Values and m_Keys maps. ** Reads the given ini file and fills the m_Values and m_Keys maps.
** **
*/ */
void CConfigParser::ReadIniFile(const std::wstring& iniFile, LPCTSTR config, int depth) void CConfigParser::ReadIniFile(const std::wstring& iniFile, const std::wstring& resourcePath, LPCTSTR config, int depth)
{ {
if (depth > 100) // Is 100 enough to assume the include loop never ends? if (depth > 100) // Is 100 enough to assume the include loop never ends?
{ {
@ -1316,10 +1319,18 @@ void CConfigParser::ReadIniFile(const std::wstring& iniFile, LPCTSTR config, int
ReplaceVariables(value); ReplaceVariables(value);
if (!CSystem::IsAbsolutePath(value)) if (!CSystem::IsAbsolutePath(value))
{ {
// It's a relative path so add the current path as a prefix if (!resourcePath.empty() &&
value[0] == L'@' && value[1] == L'\\') // value[1] == L'\0' if value.size() == 1
{
value.replace(0, 2, resourcePath);
}
else
{
// Relative to the ini folder
value.insert(0, CRainmeter::ExtractPath(iniFile)); value.insert(0, CRainmeter::ExtractPath(iniFile));
} }
ReadIniFile(value, config, depth + 1); }
ReadIniFile(value, resourcePath, config, depth + 1);
} }
} }
else else

View File

@ -40,7 +40,7 @@ public:
CConfigParser(); CConfigParser();
~CConfigParser(); ~CConfigParser();
void Initialize(LPCTSTR filename, CRainmeter* pRainmeter, CMeterWindow* meterWindow = NULL, LPCTSTR config = NULL); void Initialize(const std::wstring& filename, CMeterWindow* meterWindow = NULL, LPCTSTR config = NULL);
void AddMeasure(CMeasure* pMeasure); void AddMeasure(CMeasure* pMeasure);
bool GetVariable(const std::wstring& strVariable, std::wstring& strValue); bool GetVariable(const std::wstring& strVariable, std::wstring& strValue);
@ -81,7 +81,6 @@ public:
bool ParseFormula(const std::wstring& formula, double* resultValue); bool ParseFormula(const std::wstring& formula, double* resultValue);
const std::wstring& GetFilename() { return m_Filename; }
const std::list<std::wstring>& GetSections() { return m_Sections; } const std::list<std::wstring>& GetSections() { return m_Sections; }
bool ReplaceVariables(std::wstring& result); bool ReplaceVariables(std::wstring& result);
@ -101,13 +100,13 @@ public:
static void UpdateWorkareaVariables() { SetMultiMonitorVariables(false); } static void UpdateWorkareaVariables() { SetMultiMonitorVariables(false); }
private: private:
void SetBuiltInVariables(CRainmeter* pRainmeter, CMeterWindow* meterWindow); void SetBuiltInVariables(const std::wstring& filename, CMeterWindow* meterWindow);
void ReadVariables(); void ReadVariables();
CMeasure* GetMeasure(const std::wstring& name); CMeasure* GetMeasure(const std::wstring& name);
void ReadIniFile(const std::wstring& strFileName, LPCTSTR config = NULL, int depth = 0); void ReadIniFile(const std::wstring& iniFile, const std::wstring& resourcePath, LPCTSTR config = NULL, int depth = 0);
void SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow); void SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow);
@ -122,8 +121,6 @@ private:
static std::wstring StrToUpper(const WCHAR* str) { std::wstring strTmp(str); StrToUpperC(strTmp); return strTmp; } static std::wstring StrToUpper(const WCHAR* str) { std::wstring strTmp(str); StrToUpperC(strTmp); return strTmp; }
static std::wstring& StrToUpperC(std::wstring& str) { _wcsupr(&str[0]); return str; } static std::wstring& StrToUpperC(std::wstring& str) { _wcsupr(&str[0]); return str; }
std::wstring m_Filename;
std::unordered_map<std::wstring, CMeasure*> m_Measures; std::unordered_map<std::wstring, CMeasure*> m_Measures;
std::vector<std::wstring> m_StyleTemplate; std::vector<std::wstring> m_StyleTemplate;

View File

@ -1429,7 +1429,7 @@ INT_PTR CDialogManage::CTabThemes::OnCommand(WPARAM wParam, LPARAM lParam)
if (Button_GetCheck(item) == BST_CHECKED) if (Button_GetCheck(item) == BST_CHECKED)
{ {
CConfigParser parser; CConfigParser parser;
parser.Initialize(path.c_str(), Rainmeter); parser.Initialize(path);
// Remove sections with Active=0 // Remove sections with Active=0
std::list<std::wstring>::const_iterator iter = parser.GetSections().begin(); std::list<std::wstring>::const_iterator iter = parser.GetSections().begin();

View File

@ -569,12 +569,12 @@ void CMeasureNet::ResetStats()
** Reads statistics. ** Reads statistics.
** **
*/ */
void CMeasureNet::ReadStats(const WCHAR* iniFile, std::wstring& statsDate) void CMeasureNet::ReadStats(const std::wstring& iniFile, std::wstring& statsDate)
{ {
WCHAR buffer[48]; WCHAR buffer[48];
CConfigParser parser; CConfigParser parser;
parser.Initialize(iniFile, NULL, NULL, L"Statistics"); parser.Initialize(iniFile, NULL, L"Statistics");
const std::wstring& date = parser.ReadString(L"Statistics", L"Since", L"", false); const std::wstring& date = parser.ReadString(L"Statistics", L"Since", L"", false);
if (!date.empty()) if (!date.empty())

View File

@ -48,7 +48,7 @@ public:
static void UpdateStats(); static void UpdateStats();
static void ResetStats(); static void ResetStats();
static void ReadStats(const WCHAR* iniFile, std::wstring& statsDate); static void ReadStats(const std::wstring& iniFile, std::wstring& statsDate);
static void WriteStats(const WCHAR* iniFile, const std::wstring& statsDate); static void WriteStats(const WCHAR* iniFile, const std::wstring& statsDate);
static void InitializeNewApi(); static void InitializeNewApi();

View File

@ -208,7 +208,7 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section)
if (initializeFunc) if (initializeFunc)
{ {
maxValue = ((INITIALIZE)initializeFunc)(m_Plugin, parser.GetFilename().c_str(), section, m_ID); maxValue = ((INITIALIZE)initializeFunc)(m_Plugin, m_MeterWindow->GetSkinFilePath().c_str(), section, m_ID);
} }
} }

View File

@ -137,6 +137,7 @@ CMeterWindow::CMeterWindow(const std::wstring& config, const std::wstring& iniFi
m_Refreshing(false), m_Refreshing(false),
m_Hidden(false), m_Hidden(false),
m_ResizeWindow(RESIZEMODE_NONE), m_ResizeWindow(RESIZEMODE_NONE),
m_ResourcesFolder(false),
m_UpdateCounter(), m_UpdateCounter(),
m_MouseMoveCounter(), m_MouseMoveCounter(),
m_FontCollection(), m_FontCollection(),
@ -1801,7 +1802,7 @@ void CMeterWindow::ReadConfig()
m_ConfigGroup.clear(); m_ConfigGroup.clear();
CConfigParser parser; CConfigParser parser;
parser.Initialize(iniFile.c_str(), Rainmeter, NULL, m_SkinName.c_str()); parser.Initialize(iniFile, NULL, m_SkinName.c_str());
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
{ {
@ -1958,7 +1959,18 @@ bool CMeterWindow::ReadSkin()
return false; return false;
} }
m_Parser.Initialize(iniFile.c_str(), Rainmeter, this); std::wstring::size_type suiteLen;
if ((suiteLen = m_SkinName.find_first_of(L'\\')) == std::wstring::npos)
{
suiteLen = m_SkinName.size();
}
std::wstring resourcePath = Rainmeter->GetSkinPath();
resourcePath.append(m_SkinName, 0, suiteLen);
resourcePath += L"\\@Resources\\";
m_ResourcesFolder = (_waccess(resourcePath.c_str(), 0) == 0);
m_Parser.Initialize(iniFile, this);
// Check the version // Check the version
UINT appVersion = m_Parser.ReadUInt(L"Rainmeter", L"AppVersion", 0); UINT appVersion = m_Parser.ReadUInt(L"Rainmeter", L"AppVersion", 0);
@ -2052,8 +2064,7 @@ bool CMeterWindow::ReadSkin()
{ {
ResizeBlur(blurRegion, RGN_OR); ResizeBlur(blurRegion, RGN_OR);
// Here we are checking to see if there are more than one blur region // Check for BlurRegion2, BlurRegion3, etc.
// to be loaded. They will be named BlurRegion2, BlurRegion3, etc.
_snwprintf_s(buffer, _TRUNCATE, L"BlurRegion%i", ++i); _snwprintf_s(buffer, _TRUNCATE, L"BlurRegion%i", ++i);
blurRegion = m_Parser.ReadString(L"Rainmeter", buffer, L"").c_str(); blurRegion = m_Parser.ReadString(L"Rainmeter", buffer, L"").c_str();
} }
@ -2070,36 +2081,73 @@ bool CMeterWindow::ReadSkin()
} }
} }
// Load fonts in Resources folder
if (m_ResourcesFolder)
{
WIN32_FIND_DATA fd;
resourcePath += L"Fonts\\*";
HANDLE find = FindFirstFileEx(
resourcePath.c_str(),
(CSystem::GetOSPlatform() >= OSPLATFORM_7) ? FindExInfoBasic : FindExInfoStandard,
&fd,
FindExSearchNameMatch,
NULL,
0);
if (find != INVALID_HANDLE_VALUE)
{
m_FontCollection = new PrivateFontCollection();
do
{
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
std::wstring file(resourcePath, 0, resourcePath.length() - 1);
file += fd.cFileName;
Status status = m_FontCollection->AddFontFile(file.c_str());
if (status != Ok)
{
std::wstring error = L"Unable to load font: ";
error += file.c_str();
Log(LOG_ERROR, error.c_str());
}
}
}
while (FindNextFile(find, &fd));
}
}
// Load local fonts // Load local fonts
const WCHAR* localFont = m_Parser.ReadString(L"Rainmeter", L"LocalFont", L"").c_str(); const WCHAR* localFont = m_Parser.ReadString(L"Rainmeter", L"LocalFont", L"").c_str();
if (*localFont) if (*localFont)
{
if (!m_FontCollection)
{ {
m_FontCollection = new PrivateFontCollection(); m_FontCollection = new PrivateFontCollection();
int i = 1; }
int i = 1;
do do
{ {
// Try program folder first // Try program folder first
std::wstring szFontFile = Rainmeter->GetPath() + L"Fonts\\"; std::wstring szFontFile = Rainmeter->GetPath() + L"Fonts\\";
szFontFile += localFont; szFontFile += localFont;
Status nResults = m_FontCollection->AddFontFile(szFontFile.c_str()); Status status = m_FontCollection->AddFontFile(szFontFile.c_str());
if (status != Ok)
if (nResults != Ok)
{ {
szFontFile = localFont; szFontFile = localFont;
MakePathAbsolute(szFontFile); MakePathAbsolute(szFontFile);
nResults = m_FontCollection->AddFontFile(szFontFile.c_str()); status = m_FontCollection->AddFontFile(szFontFile.c_str());
if (status != Ok)
if (nResults != Ok)
{ {
std::wstring error = L"Unable to load font file: "; std::wstring error = L"Unable to load font: ";
error += localFont; error += localFont;
Log(LOG_ERROR, error.c_str()); Log(LOG_ERROR, error.c_str());
} }
} }
// Here we are checking to see if there are more than one local font // Check for LocalFont2, LocalFont3, etc.
// to be loaded. They will be named LocalFont2, LocalFont3, etc.
_snwprintf_s(buffer, _TRUNCATE, L"LocalFont%i", ++i); _snwprintf_s(buffer, _TRUNCATE, L"LocalFont%i", ++i);
localFont = m_Parser.ReadString(L"Rainmeter", buffer, L"").c_str(); localFont = m_Parser.ReadString(L"Rainmeter", buffer, L"").c_str();
} }
@ -4640,15 +4688,44 @@ void CMeterWindow::MakePathAbsolute(std::wstring& path)
else else
{ {
std::wstring absolute; std::wstring absolute;
if (m_ResourcesFolder && (path[0] == L'@' && path[1] == L'\\')) // path[1] == L'\0' if path.size() == 1
{
const std::wstring::size_type resourcesLen = 13; // Count of "\\@Resources\\"
std::wstring::size_type suiteLen;
if ((suiteLen = m_SkinName.find_first_of(L'\\')) == std::wstring::npos)
{
suiteLen = m_SkinName.size();
}
absolute.reserve(Rainmeter->GetSkinPath().size() + suiteLen + resourcesLen + (path.size() - 2));
absolute = Rainmeter->GetSkinPath();
absolute.append(m_SkinName, 0, suiteLen);
absolute += L"\\@Resources\\";
absolute.append(path, 2, path.length() - 1);
}
else
{
absolute.reserve(Rainmeter->GetSkinPath().size() + m_SkinName.size() + 1 + path.size()); absolute.reserve(Rainmeter->GetSkinPath().size() + m_SkinName.size() + 1 + path.size());
absolute = Rainmeter->GetSkinPath(); absolute = Rainmeter->GetSkinPath();
absolute += m_SkinName; absolute += m_SkinName;
absolute += L'\\'; absolute += L'\\';
absolute += path; absolute += path;
}
absolute.swap(path); absolute.swap(path);
} }
} }
std::wstring CMeterWindow::GetSkinFilePath()
{
std::wstring file = Rainmeter->GetSkinPath() + m_SkinName;
file += L'\\';
file += m_SkinIniFile;
return file;
}
std::wstring CMeterWindow::GetSkinRootPath() std::wstring CMeterWindow::GetSkinRootPath()
{ {
std::wstring path = Rainmeter->GetSkinPath(); std::wstring path = Rainmeter->GetSkinPath();

View File

@ -203,6 +203,7 @@ public:
const std::wstring& GetSkinName() { return m_SkinName; } const std::wstring& GetSkinName() { return m_SkinName; }
const std::wstring& GetSkinIniFile() { return m_SkinIniFile; } const std::wstring& GetSkinIniFile() { return m_SkinIniFile; }
std::wstring GetSkinFilePath();
std::wstring GetSkinRootPath(); std::wstring GetSkinRootPath();
std::list<CMeasure*>& GetMeasures() { return m_Measures; } std::list<CMeasure*>& GetMeasures() { return m_Measures; }
@ -450,6 +451,8 @@ private:
const std::wstring m_SkinName; // Name of the current skin folder const std::wstring m_SkinName; // Name of the current skin folder
const std::wstring m_SkinIniFile; // Name of the current skin iniFile const std::wstring m_SkinIniFile; // Name of the current skin iniFile
bool m_ResourcesFolder;
int m_UpdateCounter; int m_UpdateCounter;
UINT m_MouseMoveCounter; UINT m_MouseMoveCounter;

View File

@ -1552,10 +1552,10 @@ void CRainmeter::ScanForConfigs(const std::wstring& path)
m_ConfigMenu.clear(); m_ConfigMenu.clear();
m_ConfigOrders.clear(); m_ConfigOrders.clear();
ScanForConfigsRecursive(path, L"", 0, m_ConfigMenu, false); ScanForConfigsRecursive(path, L"", 0, m_ConfigMenu);
} }
int CRainmeter::ScanForConfigsRecursive(const std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool DontRecurse) int CRainmeter::ScanForConfigsRecursive(const std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool rootSkinFolder)
{ {
WIN32_FIND_DATA fileData; // Data structure describes the file found WIN32_FIND_DATA fileData; // Data structure describes the file found
HANDLE hSearch; // Search handle returned by FindFirstFile HANDLE hSearch; // Search handle returned by FindFirstFile
@ -1589,7 +1589,8 @@ int CRainmeter::ScanForConfigsRecursive(const std::wstring& path, std::wstring b
{ {
if (wcscmp(L".", fileData.cFileName) != 0 && if (wcscmp(L".", fileData.cFileName) != 0 &&
wcscmp(L"..", fileData.cFileName) != 0 && wcscmp(L"..", fileData.cFileName) != 0 &&
!(first && wcscmp(L"Backup", fileData.cFileName) == 0)) // Skip the backup folder !(first && wcscmp(L"Backup", fileData.cFileName) == 0) &&
!(rootSkinFolder && wcscmp(L"@Resources", fileData.cFileName) == 0))
{ {
folders.push_back(filename); folders.push_back(filename);
} }
@ -1635,10 +1636,8 @@ int CRainmeter::ScanForConfigsRecursive(const std::wstring& path, std::wstring b
menuItem.index = -1; menuItem.index = -1;
menu.push_back(std::move(menuItem)); menu.push_back(std::move(menuItem));
if (!DontRecurse)
{
std::vector<CONFIGMENU>::iterator iter2 = menu.end() - 1; std::vector<CONFIGMENU>::iterator iter2 = menu.end() - 1;
index = ScanForConfigsRecursive(path, base + (*iter), index, (*iter2).children, false); index = ScanForConfigsRecursive(path, base + (*iter), index, (*iter2).children, base.empty());
// Remove menu item if it has no child // Remove menu item if it has no child
if ((*iter2).children.empty()) if ((*iter2).children.empty())
@ -1646,7 +1645,6 @@ int CRainmeter::ScanForConfigsRecursive(const std::wstring& path, std::wstring b
menu.erase(iter2); menu.erase(iter2);
} }
} }
}
return index; return index;
} }
@ -2169,7 +2167,7 @@ void CRainmeter::ReadGeneralSettings(const std::wstring& iniFile)
m_DesktopWorkAreas.clear(); m_DesktopWorkAreas.clear();
CConfigParser parser; CConfigParser parser;
parser.Initialize(iniFile.c_str(), this); parser.Initialize(iniFile, NULL, NULL);
// Read Logging settings // Read Logging settings
m_Logging = 0!=parser.ReadInt(L"Rainmeter", L"Logging", 0); m_Logging = 0!=parser.ReadInt(L"Rainmeter", L"Logging", 0);
@ -2567,7 +2565,7 @@ void CRainmeter::ReadStats()
} }
// Only Net measure has stats at the moment // Only Net measure has stats at the moment
CMeasureNet::ReadStats(statsFile, m_StatsDate); CMeasureNet::ReadStats(m_StatsFile, m_StatsDate);
} }
/* /*

View File

@ -258,7 +258,7 @@ private:
void UpdateDesktopWorkArea(bool reset); void UpdateDesktopWorkArea(bool reset);
HMENU CreateSkinMenu(CMeterWindow* meterWindow, int index, HMENU configMenu); HMENU CreateSkinMenu(CMeterWindow* meterWindow, int index, HMENU configMenu);
void ChangeSkinIndex(HMENU subMenu, int index); void ChangeSkinIndex(HMENU subMenu, int index);
int ScanForConfigsRecursive(const std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool DontRecurse); int ScanForConfigsRecursive(const std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool rootSkinFolder = false);
HMENU CreateConfigMenu(HMENU configMenu, const std::vector<CONFIGMENU>& configMenuData); HMENU CreateConfigMenu(HMENU configMenu, const std::vector<CONFIGMENU>& configMenuData);
void CreateThemeMenu(HMENU themeMenu); void CreateThemeMenu(HMENU themeMenu);
void CreateMonitorMenu(HMENU monitorMenu, CMeterWindow* meterWindow); void CreateMonitorMenu(HMENU monitorMenu, CMeterWindow* meterWindow);