[RAPPS] Bulk install!
[reactos.git] / reactos / base / applications / rapps / available.cpp
index ee75087..599defa 100644 (file)
 #include "rapps.h"
 
  // CAvailableApplicationInfo
-
 CAvailableApplicationInfo::CAvailableApplicationInfo(const ATL::CStringW& sFileNameParam)
+    : m_Parser(sFileNameParam)
 {
     LicenseType = LICENSE_TYPE::None;
     sFileName = sFileNameParam;
-    RetrieveCategory();
+
+    RetrieveGeneralInfo();
 }
 
 VOID CAvailableApplicationInfo::RefreshAppInfo()
 {
-    if (RetrieveGeneralInfo())
+    if (szUrlDownload.IsEmpty())
     {
-        RetrieveLicenseType();
-        RetrieveLanguages();
-        RetrieveInstalledStatus();
-        if (m_IsInstalled)
-        {
-            RetrieveInstalledVersion();
-        }
+        RetrieveGeneralInfo();
     }
 }
 
-BOOL CAvailableApplicationInfo::RetrieveGeneralInfo()
+VOID CAvailableApplicationInfo::RetrieveGeneralInfo()
 {
-    if (szUrlDownload.IsEmpty())
+    Category = m_Parser.GetInt(L"Category");
+
+    if (!GetString(L"Name", szName)
+        || !GetString(L"URLDownload", szUrlDownload))
     {
-        if (!GetString(L"Name", szName)
-            || !GetString(L"URLDownload", szUrlDownload))
-        {
-            return FALSE;
-        }
+        return;
+    }
 
-        GetString(L"RegName", szRegName);
-        GetString(L"Version", szVersion);
-        GetString(L"License", szLicense);
-        GetString(L"Description", szDesc);
-        GetString(L"Size", szSize);
-        GetString(L"URLSite", szUrlSite);
-        GetString(L"CDPath", szCDPath);
-        GetString(L"Language", szRegName);
-        GetString(L"SHA1", szSHA1);
-        return TRUE;
+    GetString(L"RegName", szRegName);
+    GetString(L"Version", szVersion);
+    GetString(L"License", szLicense);
+    GetString(L"Description", szDesc);
+    GetString(L"Size", szSize);
+    GetString(L"URLSite", szUrlSite);
+    GetString(L"CDPath", szCDPath);
+    GetString(L"Language", szRegName);
+    GetString(L"SHA1", szSHA1);
+
+    RetrieveLicenseType();
+    RetrieveLanguages();
+    RetrieveInstalledStatus();
+    if (m_IsInstalled)
+    {
+        RetrieveInstalledVersion();
     }
-    return FALSE;
 }
 
 VOID CAvailableApplicationInfo::RetrieveInstalledStatus()
@@ -69,42 +69,52 @@ VOID CAvailableApplicationInfo::RetrieveInstalledVersion()
         || ::GetInstalledVersion(&szInstalledVersion, szName);
 }
 
-BOOL CAvailableApplicationInfo::RetrieveLanguages()
+VOID CAvailableApplicationInfo::RetrieveLanguages()
 {
     const WCHAR cDelimiter = L'|';
     ATL::CStringW szBuffer;
 
     // TODO: Get multiline parameter
-    if (!ParserGetString(L"Languages", sFileName, szBuffer))
-        return FALSE;
+    if (!m_Parser.GetString(L"Languages", szBuffer))
+    {
+        m_HasLanguageInfo = FALSE;
+        return;
+    }
 
     // Parse parameter string
-    ATL::CStringW szLocale;
+    ATL::CStringW m_szLocale;
+    int iLCID;
     for (INT i = 0; szBuffer[i] != UNICODE_NULL; ++i)
     {
-        if (szBuffer[i] != cDelimiter)
+        if (szBuffer[i] != cDelimiter && szBuffer[i] != L'\n')
         {
-            szLocale += szBuffer[i];
+            m_szLocale += szBuffer[i];
         }
         else
         {
-            Languages.Add(szLocale);
-            szLocale.Empty();
+            if (StrToIntExW(m_szLocale.GetString(), STIF_DEFAULT, &iLCID))
+            {
+                Languages.Add(static_cast<LCID>(iLCID));
+                m_szLocale.Empty();
+            }
         }
     }
 
     // For the text after delimiter
-    if (!szLocale.IsEmpty())
+    if (!m_szLocale.IsEmpty())
     {
-        Languages.Add(szLocale);
+        if (StrToIntExW(m_szLocale.GetString(), STIF_DEFAULT, &iLCID))
+        {
+            Languages.Add(static_cast<LCID>(iLCID));
+        }
     }
 
-    return TRUE;
+    m_HasLanguageInfo = TRUE;
 }
 
 VOID CAvailableApplicationInfo::RetrieveLicenseType()
 {
-    INT IntBuffer = ParserGetInt(L"LicenseType", sFileName);
+    INT IntBuffer = m_Parser.GetInt(L"LicenseType");
 
     if (IntBuffer < 0 || IntBuffer > LICENSE_TYPE::Max)
     {
@@ -116,9 +126,24 @@ VOID CAvailableApplicationInfo::RetrieveLicenseType()
     }
 }
 
-VOID CAvailableApplicationInfo::RetrieveCategory()
+BOOL CAvailableApplicationInfo::FindInLanguages(LCID what) const
 {
-    Category = ParserGetInt(L"Category", sFileName);
+    if (!m_HasLanguageInfo)
+    {
+        return FALSE;
+    }
+
+    //Find locale code in the list
+    const INT nLanguagesSize = Languages.GetSize();
+    for (INT i = 0; i < nLanguagesSize; ++i)
+    {
+        if (Languages[i] == what)
+        {
+            return TRUE;
+        }
+    }
+
+    return FALSE;
 }
 
 BOOL CAvailableApplicationInfo::HasLanguageInfo() const
@@ -128,24 +153,12 @@ BOOL CAvailableApplicationInfo::HasLanguageInfo() const
 
 BOOL CAvailableApplicationInfo::HasNativeLanguage() const
 {
-    if (!m_HasLanguageInfo)
-    {
-        return FALSE;
-    }
-
-    //TODO: make the actual check
-    return TRUE;
+    return FindInLanguages(GetUserDefaultLCID());
 }
 
 BOOL CAvailableApplicationInfo::HasEnglishLanguage() const
 {
-    if (!m_HasLanguageInfo)
-    {
-        return FALSE;
-    }
-
-    //TODO: make the actual check
-    return TRUE;
+    return FindInLanguages(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT));
 }
 
 BOOL CAvailableApplicationInfo::IsInstalled() const
@@ -170,13 +183,14 @@ VOID CAvailableApplicationInfo::SetLastWriteTime(FILETIME* ftTime)
 
 inline BOOL CAvailableApplicationInfo::GetString(LPCWSTR lpKeyName, ATL::CStringW& ReturnedString)
 {
-    if (!ParserGetString(lpKeyName, sFileName, ReturnedString))
+    if (!m_Parser.GetString(lpKeyName, ReturnedString))
     {
         ReturnedString.Empty();
         return FALSE;
     }
     return TRUE;
 }
+// CAvailableApplicationInfo 
 
 // CAvailableApps
 CAvailableApps::CAvailableApps()
@@ -237,7 +251,7 @@ BOOL CAvailableApps::UpdateAppsDB()
     if (!DeleteCurrentAppsDB())
         return FALSE;
 
-    DownloadApplicationsDB(APPLICATION_DATABASE_URL);
+    Ă‘DownloadManager::DownloadApplicationsDB(APPLICATION_DATABASE_URL);
 
     if (m_szPath.IsEmpty())
         return FALSE;
@@ -266,7 +280,7 @@ BOOL CAvailableApps::EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnu
     if (hFind == INVALID_HANDLE_VALUE)
     {
         if (GetFileAttributesW(m_szCabPath) == INVALID_FILE_ATTRIBUTES)
-            DownloadApplicationsDB(APPLICATION_DATABASE_URL);
+            Ă‘DownloadManager::DownloadApplicationsDB(APPLICATION_DATABASE_URL);
 
         ExtractFilesFromCab(m_szCabPath, m_szAppsPath);
         hFind = FindFirstFileW(m_szSearchPath.GetString(), &FindFileData);
@@ -277,7 +291,7 @@ BOOL CAvailableApps::EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnu
 
     do
     {
-        /* loop for all the cached entries */
+        // loop for all the cached entries
         POSITION CurrentListPosition = m_InfoList.GetHeadPosition();
         CAvailableApplicationInfo* Info = NULL;
 
@@ -286,31 +300,31 @@ BOOL CAvailableApps::EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnu
             POSITION LastListPosition = CurrentListPosition;
             Info = m_InfoList.GetNext(CurrentListPosition);
 
-            /* do we already have this entry in cache? */
+            // do we already have this entry in cache?
             if (Info->sFileName == FindFileData.cFileName)
             {
-                /* is it current enough, or the file has been modified since our last time here? */
+                // is it current enough, or the file has been modified since our last time here?
                 if (CompareFileTime(&FindFileData.ftLastWriteTime, &Info->ftCacheStamp) == 1)
                 {
-                    /* recreate our cache, this is the slow path */
+                    // recreate our cache, this is the slow path
                     m_InfoList.RemoveAt(LastListPosition);
 
                     delete Info;
-                    Info = nullptr;
+                    Info = NULL;
                     break;
                 }
                 else
                 {
-                    /* speedy path, compare directly, we already have the data */
+                    // speedy path, compare directly, we already have the data
                     goto skip_if_cached;
                 }
             }
         }
 
-        /* create a new entry */
+        // create a new entry
         Info = new CAvailableApplicationInfo(FindFileData.cFileName);
 
-        /* set a timestamp for the next time */
+        // set a timestamp for the next time
         Info->SetLastWriteTime(&FindFileData.ftLastWriteTime);
         m_InfoList.AddTail(Info);
 
@@ -361,3 +375,110 @@ const LPCWSTR CAvailableApps::GetCabPathString()
 {
     return m_szPath.GetString();
 }
+// CAvailableApps
+
+// CConfigParser
+ATL::CStringW CConfigParser::m_szLocaleID;
+ATL::CStringW CConfigParser::m_szCachedINISectionLocale;
+ATL::CStringW CConfigParser::m_szCachedINISectionLocaleNeutral;
+
+CConfigParser::CConfigParser(const ATL::CStringW& FileName) : szConfigPath(GetINIFullPath(FileName))
+{
+    // we don't have cached section strings for the current system language, create them, lazy
+    CacheINILocaleLazy();
+}
+
+ATL::CStringW CConfigParser::GetINIFullPath(const ATL::CStringW& FileName)
+{
+    ATL::CStringW szDir;
+    ATL::CStringW szBuffer;
+
+    GetStorageDirectory(szDir);
+    szBuffer.Format(L"%ls\\rapps\\%ls", szDir, FileName);
+
+    return szBuffer;
+}
+
+VOID CConfigParser::CacheINILocaleLazy()
+{
+    if (m_szLocaleID.IsEmpty())
+    {
+        // TODO: Set default locale if call fails
+        // find out what is the current system lang code (e.g. "0a") and append it to SectionLocale
+        GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_ILANGUAGE,
+                       m_szLocaleID.GetBuffer(m_cchLocaleSize), m_cchLocaleSize);
+
+        m_szLocaleID.ReleaseBuffer();
+        m_szCachedINISectionLocale = L"Section." + m_szLocaleID;
+
+        // turn "Section.0c0a" into "Section.0a", keeping just the neutral lang part
+        m_szCachedINISectionLocaleNeutral = m_szCachedINISectionLocale + m_szLocaleID.Right(2);
+    }
+}
+
+const ATL::CStringW& CConfigParser::GetLocale()
+{
+    CacheINILocaleLazy();
+    return m_szLocaleID;
+}
+
+INT CConfigParser::GetLocaleSize()
+{
+    return m_cchLocaleSize;
+}
+
+UINT CConfigParser::GetString(const ATL::CStringW& KeyName, ATL::CStringW& ResultString)
+{
+    DWORD dwResult;
+
+    LPWSTR ResultStringBuffer = ResultString.GetBuffer(MAX_PATH);
+    // 1st - find localized strings (e.g. "Section.0c0a")
+    dwResult = GetPrivateProfileStringW(m_szCachedINISectionLocale.GetString(),
+                                        KeyName.GetString(),
+                                        NULL,
+                                        ResultStringBuffer,
+                                        MAX_PATH,
+                                        szConfigPath.GetString());
+
+    if (!dwResult)
+    {
+        // 2nd - if they weren't present check for neutral sub-langs/ generic translations (e.g. "Section.0a")
+        dwResult = GetPrivateProfileStringW(m_szCachedINISectionLocaleNeutral.GetString(),
+                                            KeyName.GetString(),
+                                            NULL,
+                                            ResultStringBuffer,
+                                            MAX_PATH,
+                                            szConfigPath.GetString());
+        if (!dwResult)
+        {
+            // 3rd - if they weren't present fallback to standard english strings (just "Section")
+            dwResult = GetPrivateProfileStringW(L"Section",
+                                                KeyName.GetString(),
+                                                NULL,
+                                                ResultStringBuffer,
+                                                MAX_PATH,
+                                                szConfigPath.GetString());
+        }
+    }
+
+    ResultString.ReleaseBuffer();
+    return (dwResult != 0 ? TRUE : FALSE);
+}
+
+UINT CConfigParser::GetInt(const ATL::CStringW& KeyName)
+{
+    ATL::CStringW Buffer;
+
+    // grab the text version of our entry
+    if (!GetString(KeyName, Buffer))
+        return FALSE;
+
+    if (Buffer.IsEmpty())
+        return FALSE;
+
+    // convert it to an actual integer
+    int result = StrToIntW(Buffer.GetString());
+
+    return (UINT) (result <= 0) ? 0 : result;
+}
+// CConfigParser
\ No newline at end of file