diff --git a/src/Chorus.Tests/UI/Misc/ServerSettingsDialogTests.cs b/src/Chorus.Tests/UI/Misc/ServerSettingsDialogTests.cs index b4bc9a48b..41ccda9f1 100644 --- a/src/Chorus.Tests/UI/Misc/ServerSettingsDialogTests.cs +++ b/src/Chorus.Tests/UI/Misc/ServerSettingsDialogTests.cs @@ -1,3 +1,5 @@ +using System.Threading; +using System.Windows.Forms; using Chorus.Model; using Chorus.UI.Misc; using NUnit.Framework; @@ -5,8 +7,15 @@ namespace Chorus.Tests.UI.Misc { [TestFixture] + [Apartment(ApartmentState.STA)] public class ServerSettingsDialogTests { + [SetUp] + public void Setup() + { + Application.EnableVisualStyles(); + } + [Test, Ignore("Run by hand only")] public void LaunchDialog_FullAddress() { diff --git a/src/Chorus.Tests/UI/Sync/SyncDialogTests.cs b/src/Chorus.Tests/UI/Sync/SyncDialogTests.cs index 07eb1da21..1da989621 100644 --- a/src/Chorus.Tests/UI/Sync/SyncDialogTests.cs +++ b/src/Chorus.Tests/UI/Sync/SyncDialogTests.cs @@ -35,7 +35,7 @@ public void ShowSyncDialog_InternetAndNetworkPaths_WindowsStyle() { setup.Repository.SetKnownRepositoryAddresses(new RepositoryAddress[] { - RepositoryAddress.Create("language forge", "https://hg-public.languageforge.org"), + RepositoryAddress.Create("Lexbox", "https://hg-public.languageforge.org"), RepositoryAddress.Create("joe's mac", "\\\\suzie-pc\\public\\chorusTest") }); @@ -58,7 +58,7 @@ public void ShowSyncDialog_InternetAndNetworkPaths() { setup.Repository.SetKnownRepositoryAddresses(new RepositoryAddress[] { - RepositoryAddress.Create("language forge", "https://hg-public.languageforge.org"), + RepositoryAddress.Create("Lexbox", "https://hg-public.languageforge.org"), RepositoryAddress.Create("joe's mac", "//suzie-pc/public/chorusTest") }); @@ -80,9 +80,9 @@ public void LaunchDialog_ExampleForBob() setup.Repository.SetKnownRepositoryAddresses(new RepositoryAddress[] { - RepositoryAddress.Create("language forge", "https://pedro:mypassword@hg-public.languageforge.org"), + RepositoryAddress.Create("Lexbox", "https://pedro:mypassword@hg-public.languageforge.org"), }); - setup.Repository.SetDefaultSyncRepositoryAliases(new[] {"language forge"}); + setup.Repository.SetDefaultSyncRepositoryAliases(new[] {"Lexbox"}); using (var dlg = new SyncDialog(setup.ProjectFolderConfig, SyncUIDialogBehaviors.StartImmediatelyAndCloseWhenFinished, @@ -102,9 +102,9 @@ public void LaunchDialog_GoodForCancelTesting() setup.Repository.SetKnownRepositoryAddresses(new RepositoryAddress[] { - RepositoryAddress.Create("language forge", "https://automatedtest:testing@hg-public.languageforge.org/tpi"), + RepositoryAddress.Create("Lexbox", "https://automatedtest:testing@hg-public.languageforge.org/tpi"), }); - setup.Repository.SetDefaultSyncRepositoryAliases(new[] { "language forge" }); + setup.Repository.SetDefaultSyncRepositoryAliases(new[] { "Lexbox" }); using (var dlg = new SyncDialog(setup.ProjectFolderConfig, SyncUIDialogBehaviors.StartImmediately, diff --git a/src/Chorus/Program.cs b/src/Chorus/Program.cs index 4ac628c9b..600eadb9e 100644 --- a/src/Chorus/Program.cs +++ b/src/Chorus/Program.cs @@ -20,6 +20,7 @@ static void Main(string[] args) Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); + SetUpLocalization(); SetUpErrorHandling(); //Xpcom.Initialize(XULRunnerLocator.GetXULRunnerLocation()); @@ -66,6 +67,23 @@ static void Main(string[] args) Application.Exit (); } + private static void SetUpLocalization() + { + // Standalone Chorus.exe has no host app to initialize L10NSharp; use English defaults unless XLF files are deployed. + LocalizationManager.StrictInitializationMode = false; + var installedTranslations = Path.Combine(AppContext.BaseDirectory, "localizations"); + if (Directory.Exists(Path.Combine(installedTranslations, "Chorus"))) + { + // Pass the app's settings root; SetUpLocalization appends "Chorus" itself, so passing + // "SIL" (not "SIL\Chorus") avoids a redundant nested Chorus\Chorus directory. + var userTranslations = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + "SIL"); + Directory.CreateDirectory(userTranslations); + ChorusSystem.SetUpLocalization("en", installedTranslations, userTranslations); + } + } + private static void SetUpErrorHandling() { try diff --git a/src/Chorus/UI/Misc/ReadinessPanel.cs b/src/Chorus/UI/Misc/ReadinessPanel.cs index 0df49eb8a..a745d5924 100644 --- a/src/Chorus/UI/Misc/ReadinessPanel.cs +++ b/src/Chorus/UI/Misc/ReadinessPanel.cs @@ -12,7 +12,7 @@ namespace Chorus.UI.Misc { /// /// Show this control somewhere in the setup UI of your application. - /// It will help people know if the project is ready to use LanguageDepot, and + /// It will help people know if the project is ready to use Lexbox, and /// gives them a button to edit the relevant settings. /// public partial class ReadinessPanel : UserControl diff --git a/src/Chorus/UI/Misc/ServerSettingsControl.Designer.cs b/src/Chorus/UI/Misc/ServerSettingsControl.Designer.cs index 4cc860500..875628c57 100644 --- a/src/Chorus/UI/Misc/ServerSettingsControl.Designer.cs +++ b/src/Chorus/UI/Misc/ServerSettingsControl.Designer.cs @@ -78,7 +78,7 @@ private void InitializeComponent() this._accountLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this._accountLabel.AutoSize = true; this.l10NSharpExtender1.SetLocalizableToolTip(this._accountLabel, null); - this.l10NSharpExtender1.SetLocalizationComment(this._accountLabel, "This is a username. On Language Depot, it is called a \"login.\""); + this.l10NSharpExtender1.SetLocalizationComment(this._accountLabel, "This is a username. On Lexbox, it is called a \"login.\""); this.l10NSharpExtender1.SetLocalizingId(this._accountLabel, "ServerSettingsControl.Login"); this._accountLabel.Location = new System.Drawing.Point(37, 44); this._accountLabel.Name = "_accountLabel"; @@ -289,15 +289,14 @@ private void InitializeComponent() this._serverLabel.Anchor = System.Windows.Forms.AnchorStyles.Left; this._serverLabel.AutoSize = true; this.l10NSharpExtender1.SetLocalizableToolTip(this._serverLabel, null); - this.l10NSharpExtender1.SetLocalizationComment(this._serverLabel, "This adds information after the \"Log in\" button. Together, these two strings form" + - " a sentence. {0} is a URL, such as public.languageforge.org"); + this.l10NSharpExtender1.SetLocalizationComment(this._serverLabel, "This adds information after the \"Log in\" button. Together, these two strings form a sentence."); this.l10NSharpExtender1.SetLocalizationPriority(this._serverLabel, L10NSharp.LocalizationPriority.Low); this.l10NSharpExtender1.SetLocalizingId(this._serverLabel, "ServerSettingsControl.ServerInfo"); this._serverLabel.Location = new System.Drawing.Point(111, 10); this._serverLabel.Name = "_serverLabel"; this._serverLabel.Size = new System.Drawing.Size(122, 13); this._serverLabel.TabIndex = 18; - this._serverLabel.Text = "to {0} (Language Depot)"; + this._serverLabel.Text = "to Lexbox"; // // _tlpPassword // diff --git a/src/Chorus/UI/Misc/ServerSettingsControl.cs b/src/Chorus/UI/Misc/ServerSettingsControl.cs index 2f2447aac..4f57da899 100644 --- a/src/Chorus/UI/Misc/ServerSettingsControl.cs +++ b/src/Chorus/UI/Misc/ServerSettingsControl.cs @@ -20,9 +20,6 @@ public ServerSettingsControl() { InitializeComponent(); - // format the string with the server URL. We build our own URL because 'resumable' is not helpful here. - _serverLabel.Text = string.Format(_serverLabel.Text, $"{(ServerSettingsModel.IsPrivateServer ? "private" : "public")}{ServerSettingsModel.LanguageForgeServer}"); - _bandwidth.Items.AddRange(ServerSettingsModel.Bandwidths); } diff --git a/src/Chorus/UI/Settings/SettingsView.resx b/src/Chorus/UI/Settings/SettingsView.resx index 3b011fad8..398e5fd6a 100644 --- a/src/Chorus/UI/Settings/SettingsView.resx +++ b/src/Chorus/UI/Settings/SettingsView.resx @@ -156,6 +156,6 @@ suzie = \\SUZIE-PC\TokPisin For an internet server, include your username and password like this: online = https://JoeSmith:mypassword@hg-public.languageforge.org/tpi -For a free internet repository, visit https://public.languageforge.org +For a free Lexbox internet repository, visit https://lexbox.org \ No newline at end of file diff --git a/src/LibChorus/Model/InternetCloneSettingsModel.cs b/src/LibChorus/Model/InternetCloneSettingsModel.cs index cd06a44c5..c51c09ac8 100644 --- a/src/LibChorus/Model/InternetCloneSettingsModel.cs +++ b/src/LibChorus/Model/InternetCloneSettingsModel.cs @@ -94,7 +94,7 @@ public virtual bool SetRepositoryAddress() } else if (name.ToLower().EndsWith(@"languageforge.org")) { - name = @"LanguageForge"; + name = @"Lexbox"; } var address = RepositoryAddress.Create(name, URL); diff --git a/src/LibChorus/Model/ServerSettingsModel.cs b/src/LibChorus/Model/ServerSettingsModel.cs index fd6bf81ff..7de2b7c14 100644 --- a/src/LibChorus/Model/ServerSettingsModel.cs +++ b/src/LibChorus/Model/ServerSettingsModel.cs @@ -365,7 +365,7 @@ public string AliasName return "custom"; } - return $"languageForge.org [{Bandwidth}]"; + return $"Lexbox [{Bandwidth}]"; } } @@ -427,12 +427,12 @@ internal static string DecryptPassword(string decryptMe) /// URL-encoded password to use for the current Send and Receive session. /// /// - /// UrlEncode encodes spaces as "+" and "+" as "%2b". LanguageDepot fails to decode plus-encoded spaces. Encode spaces as "%20" + /// UrlEncode encodes spaces as "+" and "+" as "%2b". Lexbox fails to decode plus-encoded spaces. Encode spaces as "%20" /// public static string EncodedPasswordForSession => WebUtility.UrlEncode(PasswordForSession)?.Replace("+", "%20"); /// - /// URL-encoded language forge username + /// URL-encoded Lexbox username /// public static string EncodedLanguageForgeUser => WebUtility.UrlEncode(Settings.Default.LanguageForgeUser); diff --git a/src/LibChorus/VcsDrivers/Mercurial/HgExceptions.cs b/src/LibChorus/VcsDrivers/Mercurial/HgExceptions.cs index 1b9d141a0..01a3ae878 100644 --- a/src/LibChorus/VcsDrivers/Mercurial/HgExceptions.cs +++ b/src/LibChorus/VcsDrivers/Mercurial/HgExceptions.cs @@ -77,7 +77,7 @@ public override string Message } else if(_targetUri.ToLower().Contains("languageforge")) { - return "Your computer could reach LanguageForge.org, but couldn't communicate with the Chorus server there. Possible causes:\r\n1) The Chorus server on LanguageForge might be temporarily out of order. If it is, try again later/tomorrow. \r\n2) A firewall on your machine or on your network is blocking the communication with LanguageForge.org."; + return "Your computer could reach Lexbox, but couldn't communicate with the Chorus server there. Possible causes:\r\n1) The Chorus server on Lexbox might be temporarily out of order. If it is, try again later/tomorrow. \r\n2) A firewall on your machine or on your network is blocking the communication with Lexbox."; } else { diff --git a/src/LibChorus/VcsDrivers/Mercurial/HgRepository.cs b/src/LibChorus/VcsDrivers/Mercurial/HgRepository.cs index 0f5eb695d..4e3f20e4c 100644 --- a/src/LibChorus/VcsDrivers/Mercurial/HgRepository.cs +++ b/src/LibChorus/VcsDrivers/Mercurial/HgRepository.cs @@ -1037,7 +1037,7 @@ public void LogBasicInfo(IList potentialAddresses) _progress.WriteVerbose($"Local User: {GetUserIdInUse()}"); if (potentialAddresses.Any(a => a is HttpRepositoryPath)) { - _progress.WriteVerbose($"LanguageForge User: {Settings.Default.LanguageForgeUser}"); + _progress.WriteVerbose($"Lexbox User: {Settings.Default.LanguageForgeUser}"); } _progress.WriteVerbose($"Repository URI: {string.Join(Environment.NewLine, potentialAddresses.Select(RepositoryURIForLog))}"); @@ -1498,6 +1498,19 @@ public void SetTheOnlyAddressOfThisType(RepositoryAddress address) if(match!=null) { addresses.Remove(match); + // If the alias name changed (e.g. because the default server was rebranded), migrate the + // matching entry in [ChorusDefaultRepositories] as well. Default-sync membership is matched + // by alias name, so leaving the old name behind would silently drop this repository from + // default sync operations. + if (match.Name != address.Name) + { + var defaultSyncAliases = GetDefaultSyncAliases(); + if (defaultSyncAliases.Remove(match.Name)) + { + defaultSyncAliases.Add(address.Name); + SetDefaultSyncRepositoryAliases(defaultSyncAliases); + } + } } addresses.Add(address); SetKnownRepositoryAddresses(addresses); @@ -1519,7 +1532,7 @@ public void SetDefaultSyncRepositoryAliases(IEnumerable aliases) IniSection section = GetDefaultRepositoriesSection(doc); foreach (var alias in aliases) { - section.Set(alias, string.Empty); //so we'll have "LanguageForge =", which is weird, but it's the hgrc style + section.Set(alias, string.Empty); //so we'll have "Lexbox =", which is weird, but it's the hgrc style } doc.SaveAndGiveMessageIfCannot(); @@ -2095,7 +2108,7 @@ public string GetProxyConfigParameterString(string httpUrl) public static string DoWorkOfDeterminingProxyConfigParameterString(string httpUrl, IProgress progress) { /* The hg url itself would be more robust for the theoretical possibility of different - * proxies for different destinations, but some hg servers (notably language depot) require a login. + * proxies for different destinations, but some hg servers (notably Lexbox) require a login. * So we're ignoring what we were given, and just using a known address, for now. */ httpUrl = "http://proxycheck.palaso.org"; diff --git a/src/LibChorus/VcsDrivers/RepositoryAddress.cs b/src/LibChorus/VcsDrivers/RepositoryAddress.cs index 99ef7e939..4b8888392 100644 --- a/src/LibChorus/VcsDrivers/RepositoryAddress.cs +++ b/src/LibChorus/VcsDrivers/RepositoryAddress.cs @@ -68,7 +68,7 @@ public static RepositoryAddress Create(string name,string uri) /// /// Creates a new HttpRepositoryPath or DirectoryRepositorySource. /// - /// examples: SIL Language Depot, My Machine, USB Key, Greg + /// examples: Lexbox, My Machine, USB Key, Greg /// /// examples: https://sil.org/chorus, c:\work, UsbKey, //GregSmith/public/language projects /// Note: does not work for ChorusHub diff --git a/src/LibChorusTests/VcsDrivers/Mercurial/HgRepositoryTests.cs b/src/LibChorusTests/VcsDrivers/Mercurial/HgRepositoryTests.cs index 88363ddbd..59fb8f697 100644 --- a/src/LibChorusTests/VcsDrivers/Mercurial/HgRepositoryTests.cs +++ b/src/LibChorusTests/VcsDrivers/Mercurial/HgRepositoryTests.cs @@ -152,5 +152,29 @@ public void RemoveCredentialsFromIniIfNecessary_PreservesOtherData(string savedU } } } + + [Test] + public void SetTheOnlyAddressOfThisType_AliasRenamed_MigratesDefaultSyncEntry() + { + const string oldAlias = "languageForge.org [High bandwidth]"; + const string newAlias = "Lexbox [High bandwidth]"; + const string url = "https://hg-public.languageforge.org/tpi"; + + using (var tempDir = new TemporaryFolder("HgRepoDefaultSync")) + { + var repo = new HgRepository(tempDir.Path, _progress); + Directory.CreateDirectory(Path.GetDirectoryName(repo.GetPathToHgrc())); + repo.SetTheOnlyAddressOfThisType(new HttpRepositoryPath(oldAlias, url, false)); + repo.SetDefaultSyncRepositoryAliases(new[] { oldAlias }); + + // SUT: rename the alias (same address type, e.g. server rebranding) + repo.SetTheOnlyAddressOfThisType(new HttpRepositoryPath(newAlias, url, false)); + + var defaultAliases = repo.GetDefaultSyncAliases(); + Assert.That(defaultAliases, Does.Contain(newAlias), "default sync entry should follow the renamed alias"); + Assert.That(defaultAliases, Does.Not.Contain(oldAlias), "stale default sync entry should be removed"); + Assert.That(repo.GetRepositoryPathsInHgrc().Select(p => p.Name), Does.Contain(newAlias)); + } + } } } \ No newline at end of file diff --git a/src/SampleApp/Program.cs b/src/SampleApp/Program.cs index fef85c39a..f06246543 100644 --- a/src/SampleApp/Program.cs +++ b/src/SampleApp/Program.cs @@ -2,6 +2,8 @@ using System.IO; using System.Threading; using System.Windows.Forms; +using Chorus; +using L10NSharp; namespace SampleApp { @@ -13,6 +15,17 @@ static void Main() Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); + LocalizationManager.StrictInitializationMode = false; + var installedTranslations = Path.Combine(AppContext.BaseDirectory, "localizations"); + if (Directory.Exists(Path.Combine(installedTranslations, "Chorus"))) + { + var userTranslations = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + "SIL", "ChorusSampleApp"); + Directory.CreateDirectory(userTranslations); + ChorusSystem.SetUpLocalization("en", installedTranslations, userTranslations); + } + string dataDirectory = Path.Combine(Path.GetTempPath(), "ChorusSampleApp"); if(Directory.Exists(dataDirectory )) DeleteFolderThatMayBeInUse(dataDirectory);