mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	Added a version check for the skins which come with Rainmeter so they can be upgraded.
This commit is contained in:
		@@ -51,11 +51,12 @@ public:
 | 
			
		||||
	std::wstring& GetFilename() { return m_Filename; }
 | 
			
		||||
	std::vector<std::wstring> GetSections();
 | 
			
		||||
 | 
			
		||||
	static std::vector<std::wstring> Tokenize(const std::wstring& str, const std::wstring delimiters);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void ReadVariables();
 | 
			
		||||
	void ReplaceVariables(std::wstring& result);
 | 
			
		||||
	Gdiplus::Color ParseColor(LPCTSTR string);
 | 
			
		||||
	std::vector<std::wstring> Tokenize(const std::wstring& str, const std::wstring delimiters);
 | 
			
		||||
 | 
			
		||||
	void ReadIniFile(const std::wstring& strFileName, int depth = 0);
 | 
			
		||||
	void SetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strValue);
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@
 | 
			
		||||
#include <commctrl.h>
 | 
			
		||||
#include <gdiplus.h>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <shlobj.h>
 | 
			
		||||
 | 
			
		||||
using namespace Gdiplus;
 | 
			
		||||
@@ -840,6 +841,12 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
 | 
			
		||||
	// Test that the Rainmeter.ini file is writable
 | 
			
		||||
	TestSettingsFile(bDefaultIniLocation);
 | 
			
		||||
 | 
			
		||||
	// If the skin folder is somewhere else than in the program path
 | 
			
		||||
	if (wcsnicmp(m_Path.c_str(), m_SkinPath.c_str(), m_Path.size()) != 0)
 | 
			
		||||
	{
 | 
			
		||||
		CheckSkinVersions();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Tray must exist before configs are read
 | 
			
		||||
	m_TrayWindow = new CTrayWindow(m_Instance);
 | 
			
		||||
 | 
			
		||||
@@ -920,6 +927,115 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
 | 
			
		||||
	return Result;	// Alles OK
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
** CheckSkinVersions
 | 
			
		||||
**
 | 
			
		||||
** Checks if any of the skins in the program folder are newer than in the skin folder.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
void CRainmeter::CheckSkinVersions()
 | 
			
		||||
{
 | 
			
		||||
	// List all skins in the program folder
 | 
			
		||||
	std::wstring strMainSkinsPath = m_Path + L"Skins\\";
 | 
			
		||||
	std::vector<CONFIGMENU> menu;
 | 
			
		||||
	ScanForConfigsRecursive(strMainSkinsPath, L"", 0, menu, true);
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < menu.size(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		// DebugLog(L"%s", menu[i].name.c_str());
 | 
			
		||||
 | 
			
		||||
		// Read the version files
 | 
			
		||||
		std::wstring strNewVersionFile = strMainSkinsPath + menu[i].name + L"\\version";
 | 
			
		||||
		std::wstring strCurrentVersionFile = m_SkinPath + menu[i].name + L"\\version";
 | 
			
		||||
 | 
			
		||||
		std::string strVersion;
 | 
			
		||||
		std::wstring strVersionNew;
 | 
			
		||||
		std::wstring strVersionCurrent;
 | 
			
		||||
		std::wstring strVersionInIni;
 | 
			
		||||
 | 
			
		||||
		std::ifstream newFile(strNewVersionFile.c_str(), std::ios_base::in);
 | 
			
		||||
		if (getline(newFile, strVersion))
 | 
			
		||||
		{
 | 
			
		||||
			strVersionNew = ConvertToWide(strVersion.c_str());
 | 
			
		||||
			// DebugLog(L"New: %s", strVersionNew.c_str());
 | 
			
		||||
 | 
			
		||||
			// Compare with the version entry in the Rainmeter.ini
 | 
			
		||||
			WCHAR tmpSz[MAX_LINE_LENGTH] = {0};
 | 
			
		||||
			GetPrivateProfileString(menu[i].name.c_str(), L"Version", L"", tmpSz, MAX_LINE_LENGTH, m_IniFile.c_str());
 | 
			
		||||
			strVersionInIni = tmpSz;
 | 
			
		||||
 | 
			
		||||
			// DebugLog(L"In Ini: %s", strVersionInIni.c_str());
 | 
			
		||||
 | 
			
		||||
			// Compare with the version file in the skin folder
 | 
			
		||||
			std::ifstream currentFile(strCurrentVersionFile.c_str(), std::ios_base::in);
 | 
			
		||||
			if (getline(currentFile, strVersion))
 | 
			
		||||
			{
 | 
			
		||||
				strVersionCurrent = ConvertToWide(strVersion.c_str());
 | 
			
		||||
				// DebugLog(L"Current: %s", strVersionCurrent.c_str());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the skin doesn't define a version file no need to do anything
 | 
			
		||||
		if (!strVersionNew.empty())
 | 
			
		||||
		{
 | 
			
		||||
			// Compare the version files
 | 
			
		||||
			if (CompareVersions(strVersionNew, strVersionInIni) == 1 &&
 | 
			
		||||
				CompareVersions(strVersionNew, strVersionCurrent) == 1)
 | 
			
		||||
			{
 | 
			
		||||
				std::wstring strMessage = L"The config called \"" + menu[i].name + L"\" is newer\nthan the one you are currently using.\n\n";
 | 
			
		||||
				strMessage += L"New config: " + (strVersionNew.empty() ? L"Unknown" : strVersionNew) + L"\n";
 | 
			
		||||
				strMessage += L"Current config: " + (strVersionCurrent.empty() ? L"Unknown" : strVersionCurrent) + L"\n";
 | 
			
		||||
				strMessage += L"\n";
 | 
			
		||||
				strMessage += L"Do you want to upgrade it?";
 | 
			
		||||
 | 
			
		||||
				if (IDYES == MessageBox(NULL, strMessage.c_str(), APPNAME, MB_YESNO | MB_ICONQUESTION))
 | 
			
		||||
				{
 | 
			
		||||
					// Upgrade the skin by overwriting the existing skin.
 | 
			
		||||
					CopyFiles(strMainSkinsPath + menu[i].name, m_SkinPath);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Even if the user doesn't want to upgrade mark it to the Rainmeter.ini so we don't ask the upgrade question again
 | 
			
		||||
				WritePrivateProfileString(menu[i].name.c_str(), L"Version", strVersionNew.c_str(), m_IniFile.c_str());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*	
 | 
			
		||||
** CompareVersions
 | 
			
		||||
**
 | 
			
		||||
** Compares two version strings. Returns 0 if they are equal, 1 if A > B and -1 if A < B.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
int CRainmeter::CompareVersions(std::wstring strA, std::wstring strB)
 | 
			
		||||
{
 | 
			
		||||
	if (strA.empty() && strB.empty()) return 0;
 | 
			
		||||
	if (strA.empty()) return -1;
 | 
			
		||||
	if (strB.empty()) return 1;
 | 
			
		||||
 | 
			
		||||
	std::vector<std::wstring> arrayA = CConfigParser::Tokenize(strA, L".");
 | 
			
		||||
	std::vector<std::wstring> arrayB = CConfigParser::Tokenize(strB, L".");
 | 
			
		||||
	
 | 
			
		||||
	size_t len = max(arrayA.size(), arrayB.size());
 | 
			
		||||
	for (size_t i = 0; i < len; i++)
 | 
			
		||||
	{
 | 
			
		||||
		int a = 0;
 | 
			
		||||
		int b = 0;
 | 
			
		||||
 | 
			
		||||
		if (i < arrayA.size())
 | 
			
		||||
		{
 | 
			
		||||
			a = _wtoi(arrayA[i].c_str());
 | 
			
		||||
		}
 | 
			
		||||
		if (i < arrayB.size())
 | 
			
		||||
		{
 | 
			
		||||
			b = _wtoi(arrayB[i].c_str());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (a > b) return 1;
 | 
			
		||||
		if (a < b) return -1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
** CopyFiles
 | 
			
		||||
@@ -939,7 +1055,7 @@ void CRainmeter::CopyFiles(std::wstring strFrom, std::wstring strTo)
 | 
			
		||||
	fo.wFunc = FO_COPY;
 | 
			
		||||
	fo.pFrom = strFrom.c_str();
 | 
			
		||||
	fo.pTo = strTo.c_str();
 | 
			
		||||
	fo.fFlags = FOF_NO_UI;
 | 
			
		||||
	fo.fFlags = FOF_NO_UI | FOF_NOCONFIRMATION | FOF_ALLOWUNDO;
 | 
			
		||||
 | 
			
		||||
	int result = SHFileOperation(&fo);
 | 
			
		||||
	if (result != 0)
 | 
			
		||||
@@ -1157,10 +1273,10 @@ void CRainmeter::ScanForConfigs(std::wstring& path)
 | 
			
		||||
	m_ConfigStrings.clear();
 | 
			
		||||
	m_ConfigMenu.clear();
 | 
			
		||||
 | 
			
		||||
	ScanForConfigsRecursive(path, L"", 0, m_ConfigMenu);
 | 
			
		||||
	ScanForConfigsRecursive(path, L"", 0, m_ConfigMenu, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CRainmeter::ScanForConfigsRecursive(std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu)
 | 
			
		||||
int CRainmeter::ScanForConfigsRecursive(std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool DontRecurse)
 | 
			
		||||
{
 | 
			
		||||
    WIN32_FIND_DATA fileData;      // Data structure describes the file found
 | 
			
		||||
    WIN32_FIND_DATA fileDataIni;   // Data structure describes the file found
 | 
			
		||||
@@ -1220,8 +1336,11 @@ int CRainmeter::ScanForConfigsRecursive(std::wstring& path, std::wstring base, i
 | 
			
		||||
			menuItem.index = -1;
 | 
			
		||||
			menu.push_back(menuItem);
 | 
			
		||||
 | 
			
		||||
			if (!DontRecurse)
 | 
			
		||||
			{
 | 
			
		||||
				std::vector<CONFIGMENU>::iterator iter = menu.end() - 1;
 | 
			
		||||
			index = ScanForConfigsRecursive(path, base + fileData.cFileName, index, (*iter).children);
 | 
			
		||||
				index = ScanForConfigsRecursive(path, base + fileData.cFileName, index, (*iter).children, false);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} while(FindNextFile(hSearch, &fileData));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,12 +175,14 @@ private:
 | 
			
		||||
	void Refresh(const WCHAR* arg);
 | 
			
		||||
	HMENU CreateSkinMenu(CMeterWindow* meterWindow, int index);
 | 
			
		||||
	void ChangeSkinIndex(HMENU subMenu, int index);
 | 
			
		||||
	int ScanForConfigsRecursive(std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu);
 | 
			
		||||
	int ScanForConfigsRecursive(std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool DontRecurse);
 | 
			
		||||
	HMENU CreateConfigMenu(std::vector<CONFIGMENU>& configMenuData);
 | 
			
		||||
	HMENU CreateThemeMenu();
 | 
			
		||||
	void CreateDefaultConfigFile(std::wstring strFile);
 | 
			
		||||
	void TestSettingsFile(bool bDefaultIniLocation);
 | 
			
		||||
	void CopyFiles(std::wstring strFrom, std::wstring strTo);
 | 
			
		||||
	void CheckSkinVersions();
 | 
			
		||||
	int CompareVersions(std::wstring strA, std::wstring strB);
 | 
			
		||||
 | 
			
		||||
	CTrayWindow* m_TrayWindow;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user