i18n: Checking ECERE_LANGUAGE first; Setting environment variable from IDE and installer
[sdk] / ide / src / IDESettings.ec
index 3a1ae2e..05325dd 100644 (file)
@@ -1,7 +1,14 @@
+#if defined(__WIN32__)
+#define MessageBox _MessageBox
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef MessageBox
+#endif
+
 #ifdef ECERE_STATIC
-import static "ecere"
+public import static "ecere"
 #else
-import "ecere"
+public import "ecere"
 #endif
 
 import "StringsBox"
@@ -23,6 +30,31 @@ char * settingsDirectoryNames[DirTypes] =
    "Executable Files"
 };
 
+// This function cannot accept same pointer for source and output
+// todo: rename ReplaceSpaces to EscapeSpaceAndSpecialChars or something
+void ReplaceSpaces(char * output, char * source)
+{
+   int c, dc;
+   char ch, pch = 0;
+
+   for(c = 0, dc = 0; (ch = source[c]); c++, dc++)
+   {
+      if(ch == ' ') output[dc++] = '\\';
+      if(ch == '\"') output[dc++] = '\\';
+      if(ch == '&') output[dc++] = '\\';
+      if(pch != '$')
+      {
+         if(ch == '(' || ch == ')') output[dc++] = '\\';
+         pch = ch;
+      }
+      else if(ch == ')')
+         pch = 0;
+      output[dc] = ch;
+   }
+   output[dc] = '\0';
+}
+
+
 enum GlobalSettingsChange { none, editorSettings, projectOptions, compilerSettings };
 
 enum PathRelationship { unrelated, identical, siblings, subPath, parentPath, insuficientInput, pathEmpty, toEmpty, pathNull, toNull, bothEmpty, bothNull };
@@ -76,7 +108,7 @@ char * CopyValidateMakefilePath(char * path)
    if(path)
    {
       int len;
-      len = strlen(path);
+      len = (int)strlen(path);
       copy = CopyString(path);
       if(len)
       {
@@ -156,7 +188,7 @@ void ValidPathBufCopy(char *output, char *input)
 void RemoveTrailingPathSeparator(char *path)
 {
    int len;
-   len = strlen(path);
+   len = (int)strlen(path);
    if(len>1 && path[len-1] == DIR_SEP)
       path[--len] = '\0';
 }
@@ -443,6 +475,17 @@ public:
       isset { return defaultCompiler && defaultCompiler[0]; }
    }
 
+   property String language
+   {
+      set
+      {
+         delete language;
+         language = CopyString(value);
+      }
+      get { return language; }
+      isset { return language != null; }
+   }
+
 private:
    char * docDir;
    char * ideFileDialogLocation;
@@ -451,6 +494,7 @@ private:
    char * projectDefaultIntermediateObjDir;
    char * compilerConfigsDir;
    char * defaultCompiler;
+   String language;
 
    CompilerConfig GetCompilerConfig(String compilerName)
    {
@@ -941,6 +985,20 @@ public:
       get { return excludeLibs; }
       isset { return excludeLibs.count != 0; }
    }
+   property Array<String> eCcompilerFlags
+   {
+      set
+      {
+         eCcompilerFlags.Free();
+         if(value)
+         {
+            delete eCcompilerFlags;
+            eCcompilerFlags = value;
+         }
+      }
+      get { return eCcompilerFlags; }
+      isset { return eCcompilerFlags.count != 0; }
+   }
    property Array<String> compilerFlags
    {
       set
@@ -978,6 +1036,7 @@ private:
    Array<NamedString> environmentVars { };
    Array<String> prepDirectives { };
    Array<String> excludeLibs { };
+   Array<String> eCcompilerFlags { };
    Array<String> compilerFlags { };
    Array<String> linkerFlags { };
    char * name;
@@ -1021,6 +1080,7 @@ private:
       if(prepDirectives) { prepDirectives.Free(); }
       if(excludeLibs) { excludeLibs.Free(); }
       if(compilerFlags) { compilerFlags.Free(); }
+      if(eCcompilerFlags) { eCcompilerFlags.Free(); }
       if(linkerFlags) { linkerFlags.Free(); }
    }
    CompilerConfig Copy()
@@ -1055,9 +1115,231 @@ private:
       for(s : prepDirectives) copy.prepDirectives.Add(CopyString(s));
       for(s : excludeLibs) copy.excludeLibs.Add(CopyString(s));
       for(s : compilerFlags) copy.compilerFlags.Add(CopyString(s));
+      for(s : eCcompilerFlags) copy.eCcompilerFlags.Add(CopyString(s));
       for(s : linkerFlags) copy.linkerFlags.Add(CopyString(s));
 
       incref copy;
       return copy;
    }
 }
+
+struct LanguageOption
+{
+   String name;
+   String bitmap;
+   String code;
+   BitmapResource res;
+
+   char * OnGetString(char * tempString, void * fieldData, bool * needClass)
+   {
+      return name;
+   }
+
+   void OnDisplay(Surface surface, int x, int y, int width, void * data, Alignment alignment, DataDisplayFlags flags)
+   {
+      Bitmap icon = res ? res.bitmap : null;
+      int w = 8 + 16;
+      if(icon)
+         surface.Blit(icon, x + (16 - icon.width) / 2,y+2,0,0, icon.width, icon.height);
+      class::OnDisplay(surface, x + w, y, width - w, null, alignment, flags);
+   }
+};
+
+Array<LanguageOption> languages
+{ [
+   { "English",            ":countryCode/gb.png", "" },
+   { "汉语",                ":countryCode/cn.png", "zh_CN" },
+   { "Español",            ":countryCode/es.png", "es" },
+   { "Português (Brazil)", ":countryCode/br.png", "pt_BR" },
+   { "Русский (43%)",      ":countryCode/ru.png", "ru" },
+   { "Nederlandse (13%)",  ":countryCode/nl.png", "nl" },
+   { "Tiếng Việt (12%)",   ":countryCode/vn.png", "vi" },
+   { "मराठी (10%)",          ":countryCode/in.png", "mr" },
+   { "Hebrew (8%)",        ":countryCode/il.png", "he" },
+   { "Magyar (8%)",        ":countryCode/hu.png", "hu" }
+] };
+
+String GetLanguageString()
+{
+   String language = getenv("ECERE_LANGUAGE");
+   if(!language) language = getenv("LANGUAGE");
+   if(!language) language = getenv("LC_ALL");
+   if(!language) language = getenv("LC_MESSAGES");
+   if(!language) language = getenv("LANG");
+   if(!language) language = "";
+   return language;
+}
+
+bool LanguageRestart(char * code, Application app, IDESettings settings, IDESettingsContainer settingsContainer, Window ide, Window projectView, bool wait)
+{
+   bool restart = true;
+   String command = null;
+   int arg0Len = (int)strlen(app.argv[0]);
+   int len = arg0Len;
+   int j;
+   char ch;
+
+   if(ide)
+   {
+      Window w;
+
+      if(projectView)
+      {
+         Window w;
+         for(w = ide.firstChild; w; w = w.next)
+         {
+            if(w.isActiveClient && w.isDocument)
+            {
+               if(!w.CloseConfirmation(true))
+               {
+                  restart = false;
+                  break;
+               }
+            }
+         }
+         if(restart)
+         {
+            if(!projectView.CloseConfirmation(true))
+               restart = false;
+            if(projectView.fileName)
+            {
+               char * name = projectView.fileName;
+               if(name)
+               {
+                  for(j = 0; (ch = name[j]); j++)
+                     len += (ch == ' ' || ch == '\"' || ch == '&' || ch == '$' || ch == '(' || ch == ')') ? 2 : 1;
+               }
+            }
+
+            command = new char[len + 1];
+
+            strcpy(command, app.argv[0]);
+            len = arg0Len;
+            if(projectView.fileName)
+            {
+               strcat(command, " ");
+               len++;
+               ReplaceSpaces(command + len, projectView.fileName);
+            }
+         }
+         if(restart)
+         {
+            for(w = ide.firstChild; w; w = w.next)
+               if(w.isActiveClient && w.isDocument)
+                  w.modifiedDocument = false;
+            projectView.modifiedDocument = false;
+         }
+      }
+      else
+      {
+         for(w = ide.firstChild; w; w = w.next)
+         {
+            if(w.isActiveClient && w.isDocument)
+            {
+               if(!w.CloseConfirmation(true))
+               {
+                  restart = false;
+                  break;
+               }
+               if(w.fileName)
+               {
+                  char * name = w.fileName;
+                  len++;
+                  for(j = 0; (ch = name[j]); j++)
+                     len += (ch == ' ' || ch == '\"' || ch == '&' || ch == '$' || ch == '(' || ch == ')') ? 2 : 1;
+               }
+            }
+         }
+
+         if(restart)
+         {
+            command = new char[len + 1];
+            strcpy(command, app.argv[0]);
+            len = arg0Len;
+
+            for(w = ide.firstChild; w; w = w.next)
+            {
+               if(w.isActiveClient && w.isDocument)
+               {
+                  char * name = w.fileName;
+                  if(name)
+                  {
+                     strcat(command, " ");
+                     len++;
+                     ReplaceSpaces(command + len, name);
+                     len = (int)strlen(command);
+                  }
+               }
+            }
+         }
+         if(restart)
+         {
+            for(w = ide.firstChild; w; w = w.next)
+               if(w.isActiveClient && w.isDocument)
+                  w.modifiedDocument = false;
+         }
+      }
+      if(restart)
+      {
+         settings.language = code;
+         settingsContainer.Save();
+
+#if defined(__WIN32__)
+         // Set LANGUAGE environment variable
+         {
+            HKEY key = null;
+            uint16 wLanguage[256];
+            HRESULT status;
+            wLanguage[0] = 0;
+
+            RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
+            if(key)
+            {
+               UTF8toUTF16Buffer(code, wLanguage, sizeof(wLanguage) / sizeof(uint16));
+               RegSetValueExW(key, L"ECERE_LANGUAGE", 0, REG_EXPAND_SZ, (byte *)wLanguage, (uint)(wcslen(wLanguage)+1) * 2);
+               RegCloseKey(key);
+            }
+         }
+#endif
+
+         if(eClass_IsDerived(app._class, class(GuiApplication)))
+         {
+            GuiApplication guiApp = (GuiApplication)app;
+            guiApp.desktop.Destroy(0);
+         }
+      }
+   }
+   else
+   {
+      int i;
+      for(i = 1; i < app.argc; i++)
+      {
+         char * arg = app.argv[i];
+         len++;
+         for(j = 0; (ch = arg[j]); j++)
+            len += (ch == ' ' || ch == '\"' || ch == '&' || ch == '$' || ch == '(' || ch == ')') ? 2 : 1;
+      }
+
+      command = new char[len + 1];
+      strcpy(command, app.argv[0]);
+      len = arg0Len;
+      for(i = 1; i < app.argc; i++)
+      {
+         strcat(command, " ");
+         len++;
+         ReplaceSpaces(command + len, app.argv[i]);
+         len = (int)strlen(command);
+      }
+   }
+
+   if(restart)
+   {
+      SetEnvironment("ECERE_LANGUAGE", code);
+      if(wait)
+         ExecuteWait(command);
+      else
+         Execute(command);
+   }
+   delete command;
+   return restart;
+}