mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
It's now possible to use the measures as if they were variables (use [MeasureName] instead #VariableName#). Set DynamicVariables=1 for all meters and measures which refer to other measures.
New bang !RainmeterSetVariable can be used to change the value of a variable (DynamicVariables must be 1 in places where the variable is used).
This commit is contained in:
@@ -60,6 +60,9 @@ void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter)
|
||||
m_Filename = filename;
|
||||
|
||||
m_Variables.clear();
|
||||
m_Measures.clear();
|
||||
|
||||
ReadIniFile(m_Filename);
|
||||
|
||||
// Set the default variables
|
||||
if (pRainmeter)
|
||||
@@ -99,45 +102,26 @@ void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter)
|
||||
*/
|
||||
void CConfigParser::ReadVariables()
|
||||
{
|
||||
DWORD size;
|
||||
TCHAR* buffer;
|
||||
TCHAR* variable;
|
||||
int bufferSize = 4096;
|
||||
bool loop;
|
||||
std::vector<std::wstring> listVariables = GetKeys(L"Variables");
|
||||
|
||||
do
|
||||
for (size_t i = 0; i < listVariables.size(); i++)
|
||||
{
|
||||
loop = false;
|
||||
buffer = new TCHAR[bufferSize];
|
||||
|
||||
size = GetPrivateProfileString(L"Variables", NULL, L"", buffer, bufferSize, m_Filename.c_str());
|
||||
|
||||
if (size == bufferSize - 1)
|
||||
{
|
||||
// Buffer too small, increase it and retry
|
||||
delete [] buffer;
|
||||
bufferSize *= 2;
|
||||
loop = true;
|
||||
}
|
||||
|
||||
} while(loop);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
// Read all variables
|
||||
WCHAR* pos = buffer;
|
||||
while(wcslen(pos) > 0)
|
||||
{
|
||||
std::wstring variable = ReadString(L"Variables", pos, L"");
|
||||
if (!variable.empty())
|
||||
{
|
||||
m_Variables[pos] = variable;
|
||||
}
|
||||
|
||||
pos = pos + wcslen(pos) + 1;
|
||||
}
|
||||
m_Variables[listVariables[i]] = GetValue(L"Variables", listVariables[i], L"");
|
||||
}
|
||||
delete [] buffer;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
** Sets a new value for the variable. The DynamicVariables must be set to 1 in the
|
||||
** meter/measure for the changes to be applied.
|
||||
**
|
||||
** \param strVariable
|
||||
** \param strValue
|
||||
** \return void
|
||||
*/
|
||||
void CConfigParser::SetVariable(const std::wstring& strVariable, const std::wstring& strValue)
|
||||
{
|
||||
m_Variables[strVariable] = strValue;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -148,32 +132,12 @@ void CConfigParser::ReadVariables()
|
||||
const std::wstring& CConfigParser::ReadString(LPCTSTR section, LPCTSTR key, LPCTSTR defValue)
|
||||
{
|
||||
static std::wstring result;
|
||||
DWORD size;
|
||||
TCHAR* buffer;
|
||||
int bufferSize = 4096;
|
||||
bool loop;
|
||||
|
||||
do
|
||||
result = GetValue(section, key, defValue);
|
||||
if (result == defValue)
|
||||
{
|
||||
loop = false;
|
||||
buffer = new TCHAR[bufferSize];
|
||||
buffer[0] = 0;
|
||||
|
||||
size = GetPrivateProfileString(section, key, defValue, buffer, bufferSize, m_Filename.c_str());
|
||||
|
||||
if (size == bufferSize - 1)
|
||||
{
|
||||
// Buffer too small, increase it and retry
|
||||
delete [] buffer;
|
||||
bufferSize *= 2;
|
||||
loop = true;
|
||||
}
|
||||
|
||||
} while(loop);
|
||||
|
||||
result = buffer;
|
||||
|
||||
delete [] buffer;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check Litestep vars
|
||||
if (Rainmeter && !Rainmeter->GetDummyLitestep())
|
||||
@@ -188,13 +152,13 @@ const std::wstring& CConfigParser::ReadString(LPCTSTR section, LPCTSTR key, LPCT
|
||||
}
|
||||
}
|
||||
|
||||
result = CRainmeter::ExpandEnvironmentVariables(result);
|
||||
CRainmeter::ExpandEnvironmentVariables(result);
|
||||
|
||||
// Check for variables (#VAR#)
|
||||
size_t start = 0;
|
||||
size_t end = std::wstring::npos;
|
||||
size_t pos = std::wstring::npos;
|
||||
loop = true;
|
||||
bool loop = true;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -229,9 +193,59 @@ const std::wstring& CConfigParser::ReadString(LPCTSTR section, LPCTSTR key, LPCT
|
||||
}
|
||||
} while(loop);
|
||||
|
||||
// Check for measures ([Measure])
|
||||
if (!m_Measures.empty())
|
||||
{
|
||||
start = 0;
|
||||
end = std::wstring::npos;
|
||||
pos = std::wstring::npos;
|
||||
loop = true;
|
||||
do
|
||||
{
|
||||
pos = result.find(L'[', start);
|
||||
if (pos != std::wstring::npos)
|
||||
{
|
||||
size_t end = result.find(L']', pos + 1);
|
||||
if (end != std::wstring::npos)
|
||||
{
|
||||
std::wstring var(result.begin() + pos + 1, result.begin() + end);
|
||||
|
||||
std::map<std::wstring, CMeasure*>::iterator iter = m_Measures.find(var);
|
||||
if (iter != m_Measures.end())
|
||||
{
|
||||
std::wstring value = (*iter).second->GetStringValue(true, 1, 1, false);
|
||||
|
||||
// Measure found, replace it with the value
|
||||
result.replace(result.begin() + pos, result.begin() + end + 1, value);
|
||||
start = pos + value.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
loop = false;
|
||||
}
|
||||
} while(loop);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CConfigParser::AddMeasure(CMeasure* pMeasure)
|
||||
{
|
||||
if (pMeasure)
|
||||
{
|
||||
m_Measures[pMeasure->GetName()] = pMeasure;
|
||||
}
|
||||
}
|
||||
|
||||
double CConfigParser::ReadFloat(LPCTSTR section, LPCTSTR key, double defValue)
|
||||
{
|
||||
@@ -405,3 +419,159 @@ Color CConfigParser::ParseColor(LPCTSTR string)
|
||||
|
||||
return Color(A, R, G, B);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
** Reads the given ini file and fills the m_Values and m_Keys maps.
|
||||
**
|
||||
** \param iniFile The ini file to be read.
|
||||
*/
|
||||
void CConfigParser::ReadIniFile(const std::wstring& iniFile)
|
||||
{
|
||||
m_Keys.clear();
|
||||
m_Values.clear();
|
||||
|
||||
// Get all the sections (i.e. different meters)
|
||||
WCHAR* items = new WCHAR[MAX_LINE_LENGTH];
|
||||
int size = MAX_LINE_LENGTH;
|
||||
|
||||
// Get all the sections
|
||||
while(true)
|
||||
{
|
||||
items[0] = 0;
|
||||
int res = GetPrivateProfileString( NULL, NULL, NULL, items, size, iniFile.c_str());
|
||||
if (res == 0) return; // File not found
|
||||
if (res != size - 2) break; // Fits in the buffer
|
||||
|
||||
delete [] items;
|
||||
size *= 2;
|
||||
items = new WCHAR[size];
|
||||
};
|
||||
|
||||
// Read the sections
|
||||
WCHAR* pos = items;
|
||||
while(wcslen(pos) > 0)
|
||||
{
|
||||
m_Keys[pos] = std::vector<std::wstring>();
|
||||
pos = pos + wcslen(pos) + 1;
|
||||
}
|
||||
|
||||
// Read the keys and values
|
||||
int bufferSize = MAX_LINE_LENGTH;
|
||||
TCHAR* buffer = new TCHAR[bufferSize];
|
||||
|
||||
stdext::hash_map<std::wstring, std::vector<std::wstring> >::iterator iter = m_Keys.begin();
|
||||
for ( ; iter != m_Keys.end(); iter++)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
items[0] = 0;
|
||||
int res = GetPrivateProfileString((*iter).first.c_str(), NULL, NULL, items, size, iniFile.c_str());
|
||||
if (res != size - 2) break; // Fits in the buffer
|
||||
|
||||
delete [] items;
|
||||
size *= 2;
|
||||
items = new WCHAR[size];
|
||||
};
|
||||
|
||||
WCHAR* pos = items;
|
||||
while(wcslen(pos) > 0)
|
||||
{
|
||||
std::wstring strKey = pos;
|
||||
|
||||
while(true)
|
||||
{
|
||||
buffer[0] = 0;
|
||||
int res = GetPrivateProfileString((*iter).first.c_str(), strKey.c_str(), L"", buffer, bufferSize, iniFile.c_str());
|
||||
if (res != size - 2) break; // Fits in the buffer
|
||||
|
||||
delete [] buffer;
|
||||
bufferSize *= 2;
|
||||
buffer = new WCHAR[size];
|
||||
};
|
||||
|
||||
SetValue((*iter).first, strKey, buffer);
|
||||
|
||||
pos = pos + wcslen(pos) + 1;
|
||||
}
|
||||
}
|
||||
delete [] buffer;
|
||||
delete [] items;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
** Sets the value for the key under the given section.
|
||||
**
|
||||
** \param strSection The name of the section.
|
||||
** \param strKey The name of the key.
|
||||
** \param strValue The value for the key.
|
||||
*/
|
||||
void CConfigParser::SetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strValue)
|
||||
{
|
||||
stdext::hash_map<std::wstring, std::vector<std::wstring> >::iterator iter = m_Keys.find(strSection);
|
||||
if (iter != m_Keys.end())
|
||||
{
|
||||
std::vector<std::wstring>& array = (*iter).second;
|
||||
array.push_back(strKey);
|
||||
}
|
||||
m_Values[strSection + L"::" + strKey] = strValue;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
** Returns the value for the key under the given section.
|
||||
**
|
||||
** \param strSection The name of the section.
|
||||
** \param strKey The name of the key.
|
||||
** \param strDefault The default value for the key.
|
||||
** \return The value for the key.
|
||||
*/
|
||||
const std::wstring& CConfigParser::GetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strDefault)
|
||||
{
|
||||
stdext::hash_map<std::wstring, std::wstring>::iterator iter = m_Values.find(strSection + L"::" + strKey);
|
||||
if (iter != m_Values.end())
|
||||
{
|
||||
return (*iter).second;
|
||||
}
|
||||
|
||||
return strDefault;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
** Returns the list of sections in the ini file.
|
||||
**
|
||||
** \return A list of sections in the ini file.
|
||||
*/
|
||||
std::vector<std::wstring> CConfigParser::GetSections()
|
||||
{
|
||||
std::vector<std::wstring> listSections;
|
||||
|
||||
stdext::hash_map<std::wstring, std::vector<std::wstring> >::iterator iter = m_Keys.begin();
|
||||
for ( ; iter != m_Keys.end(); iter++)
|
||||
{
|
||||
listSections.push_back((*iter).first);
|
||||
}
|
||||
|
||||
return listSections;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
** Returns a list of keys under the given section.
|
||||
**
|
||||
** \param strSection The name of the section.
|
||||
** \return A list of keys under the given section.
|
||||
*/
|
||||
std::vector<std::wstring> CConfigParser::GetKeys(const std::wstring& strSection)
|
||||
{
|
||||
stdext::hash_map<std::wstring, std::vector<std::wstring> >::iterator iter = m_Keys.find(strSection);
|
||||
if (iter != m_Keys.end())
|
||||
{
|
||||
return (*iter).second;
|
||||
}
|
||||
|
||||
return std::vector<std::wstring>();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user