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::wstring& GetFilename() { return m_Filename; }
 | 
				
			||||||
	std::vector<std::wstring> GetSections();
 | 
						std::vector<std::wstring> GetSections();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static std::vector<std::wstring> Tokenize(const std::wstring& str, const std::wstring delimiters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void ReadVariables();
 | 
						void ReadVariables();
 | 
				
			||||||
	void ReplaceVariables(std::wstring& result);
 | 
						void ReplaceVariables(std::wstring& result);
 | 
				
			||||||
	Gdiplus::Color ParseColor(LPCTSTR string);
 | 
						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 ReadIniFile(const std::wstring& strFileName, int depth = 0);
 | 
				
			||||||
	void SetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strValue);
 | 
						void SetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strValue);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,6 +30,7 @@
 | 
				
			|||||||
#include <commctrl.h>
 | 
					#include <commctrl.h>
 | 
				
			||||||
#include <gdiplus.h>
 | 
					#include <gdiplus.h>
 | 
				
			||||||
#include <fstream>
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
#include <shlobj.h>
 | 
					#include <shlobj.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace Gdiplus;
 | 
					using namespace Gdiplus;
 | 
				
			||||||
@@ -840,6 +841,12 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
 | 
				
			|||||||
	// Test that the Rainmeter.ini file is writable
 | 
						// Test that the Rainmeter.ini file is writable
 | 
				
			||||||
	TestSettingsFile(bDefaultIniLocation);
 | 
						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
 | 
						// Tray must exist before configs are read
 | 
				
			||||||
	m_TrayWindow = new CTrayWindow(m_Instance);
 | 
						m_TrayWindow = new CTrayWindow(m_Instance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -920,6 +927,115 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
 | 
				
			|||||||
	return Result;	// Alles OK
 | 
						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
 | 
					** CopyFiles
 | 
				
			||||||
@@ -939,7 +1055,7 @@ void CRainmeter::CopyFiles(std::wstring strFrom, std::wstring strTo)
 | 
				
			|||||||
	fo.wFunc = FO_COPY;
 | 
						fo.wFunc = FO_COPY;
 | 
				
			||||||
	fo.pFrom = strFrom.c_str();
 | 
						fo.pFrom = strFrom.c_str();
 | 
				
			||||||
	fo.pTo = strTo.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);
 | 
						int result = SHFileOperation(&fo);
 | 
				
			||||||
	if (result != 0)
 | 
						if (result != 0)
 | 
				
			||||||
@@ -1157,10 +1273,10 @@ void CRainmeter::ScanForConfigs(std::wstring& path)
 | 
				
			|||||||
	m_ConfigStrings.clear();
 | 
						m_ConfigStrings.clear();
 | 
				
			||||||
	m_ConfigMenu.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 fileData;      // Data structure describes the file found
 | 
				
			||||||
    WIN32_FIND_DATA fileDataIni;   // 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;
 | 
								menuItem.index = -1;
 | 
				
			||||||
			menu.push_back(menuItem);
 | 
								menu.push_back(menuItem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::vector<CONFIGMENU>::iterator iter = menu.end() - 1;
 | 
								if (!DontRecurse)
 | 
				
			||||||
			index = ScanForConfigsRecursive(path, base + fileData.cFileName, index, (*iter).children);
 | 
								{
 | 
				
			||||||
 | 
									std::vector<CONFIGMENU>::iterator iter = menu.end() - 1;
 | 
				
			||||||
 | 
									index = ScanForConfigsRecursive(path, base + fileData.cFileName, index, (*iter).children, false);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} while(FindNextFile(hSearch, &fileData));
 | 
						} while(FindNextFile(hSearch, &fileData));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -175,12 +175,14 @@ private:
 | 
				
			|||||||
	void Refresh(const WCHAR* arg);
 | 
						void Refresh(const WCHAR* arg);
 | 
				
			||||||
	HMENU CreateSkinMenu(CMeterWindow* meterWindow, int index);
 | 
						HMENU CreateSkinMenu(CMeterWindow* meterWindow, int index);
 | 
				
			||||||
	void ChangeSkinIndex(HMENU subMenu, 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 CreateConfigMenu(std::vector<CONFIGMENU>& configMenuData);
 | 
				
			||||||
	HMENU CreateThemeMenu();
 | 
						HMENU CreateThemeMenu();
 | 
				
			||||||
	void CreateDefaultConfigFile(std::wstring strFile);
 | 
						void CreateDefaultConfigFile(std::wstring strFile);
 | 
				
			||||||
	void TestSettingsFile(bool bDefaultIniLocation);
 | 
						void TestSettingsFile(bool bDefaultIniLocation);
 | 
				
			||||||
	void CopyFiles(std::wstring strFrom, std::wstring strTo);
 | 
						void CopyFiles(std::wstring strFrom, std::wstring strTo);
 | 
				
			||||||
 | 
						void CheckSkinVersions();
 | 
				
			||||||
 | 
						int CompareVersions(std::wstring strA, std::wstring strB);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	CTrayWindow* m_TrayWindow;
 | 
						CTrayWindow* m_TrayWindow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user