diff --git a/.gitignore b/.gitignore index 48b8bb03..d18636e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +superpowers/** obj/ **/output/** **/bin/** diff --git a/DistFiles/aboutBox.htm b/DistFiles/aboutBox.htm index 7cbb893e..61cae812 100644 --- a/DistFiles/aboutBox.htm +++ b/DistFiles/aboutBox.htm @@ -37,7 +37,7 @@

Thanks

Sarah Moeller, Tim Gaved, Cambell Prince, Michael Cochran, Gary Simons, John Wickberg, Will Reiman (SIL Global)

Microsoft for Github, the repository where our open-source code is hosted for free, and also for free use of Visual Studio Community, our preferred IDE.

Atlassian, for a free open-source license for Jira, where we keep bug reports.

- +

Crowdin, for great on-line localization tools.

GitHub, for free hosting of our source code repository.

Open Source Components/Libraries

diff --git a/DistFiles/license.rtf b/DistFiles/license.rtf index 66edba3e..060221cc 100644 Binary files a/DistFiles/license.rtf and b/DistFiles/license.rtf differ diff --git a/DistFiles/releaseNotes.md b/DistFiles/releaseNotes.md index f396df43..083bc1d3 100644 --- a/DistFiles/releaseNotes.md +++ b/DistFiles/releaseNotes.md @@ -1,6 +1,7 @@ ## _VERSION_ (_DATE_) * SayMore is now a 64-bit application, so it will make better use of available memory and avoid out-of-memory errors. * SayMore now targets .Net Framework 4.8, which is the latest version supported on Windows 7 through Windows 11. It will not run on Windows versions earlier than 7. +* Added ability (both in the installer and in a dialog inside SayMore) to opt out of sending analytics data to SIL. ## 3.7.4 (30 July 2025) * Small improvement in the logic to guess at the correct initial writing system for translations when exporting FLEx Interlinear files (flextext). diff --git a/SayMore.sln.DotSettings b/SayMore.sln.DotSettings index 95865b2c..52111874 100644 --- a/SayMore.sln.DotSettings +++ b/SayMore.sln.DotSettings @@ -1,6 +1,8 @@  + HTML IE IMDI + ISO MRU OK RAMP @@ -12,6 +14,7 @@ True True True + True True True True @@ -25,6 +28,7 @@ True True True + True True True True @@ -37,6 +41,7 @@ True True True + True True True True diff --git a/build/SayMore.proj b/build/SayMore.proj index 41f09ed1..67dd4937 100644 --- a/build/SayMore.proj +++ b/build/SayMore.proj @@ -14,7 +14,7 @@ $(RootDir)/packages/ 16.2.0 $(NuGetPackageRoot)SIL.libpalaso.l10ns/$(PalasoL10nsVersion)/ - $(NuGetPackageRoot)SIL.ReleaseTasks/3.1.1/build/SIL.ReleaseTasks.props + $(NuGetPackageRoot)SIL.ReleaseTasks/3.2.0/build/SIL.ReleaseTasks.props $(LocalPackagesRoot)SIL.BuildTasks/ $(BuildTasksVersionFolder)tools/SIL.BuildTasks.dll $(BuildTasksVersionFolder)build/SIL.BuildTasks.props diff --git a/build/TestInstallerBuild.bat b/build/TestInstallerBuild.bat index de77879b..9085d179 100644 --- a/build/TestInstallerBuild.bat +++ b/build/TestInstallerBuild.bat @@ -1,10 +1,28 @@ pushd .\ FOR /F "tokens=*" %%i IN ('"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe') DO SET msbuildexe="%%i" + +REM Remember which build-modified files are currently clean so we can restore them afterwards. +REM Files with pre-existing unstaged changes are left alone. +SET REVERT_FILES= +git diff --quiet -- ..\DistFiles\releaseNotes.md +IF NOT ERRORLEVEL 1 SET REVERT_FILES=%REVERT_FILES% ../DistFiles/releaseNotes.md +git diff --quiet -- ..\src\Installer\Installer.wxs +IF NOT ERRORLEVEL 1 SET REVERT_FILES=%REVERT_FILES% ../src/Installer/Installer.wxs +git diff --quiet -- ..\src\AutoSegmenter\Properties\AssemblyInfo.cs +IF NOT ERRORLEVEL 1 SET REVERT_FILES=%REVERT_FILES% ../src/AutoSegmenter/Properties/AssemblyInfo.cs +git diff --quiet -- ..\src\SayMore\Properties\AssemblyInfo.cs +IF NOT ERRORLEVEL 1 SET REVERT_FILES=%REVERT_FILES% ../src/SayMore/Properties/AssemblyInfo.cs +git diff --quiet -- ..\src\SayMoreTests\Properties\AssemblyInfo.cs +IF NOT ERRORLEVEL 1 SET REVERT_FILES=%REVERT_FILES% ../src/SayMoreTests/Properties/AssemblyInfo.cs + dotnet restore ..\SayMore.sln %msbuildexe% /target:Build /verbosity:detailed %msbuildexe% /target:ConvertReleaseNotesToHtml;installer /property:Version=3.8.2000 /verbosity:detailed + +IF DEFINED REVERT_FILES git checkout -- %REVERT_FILES% + popd GOTO pauseforusertoseeoutput :pauseforusertoseeoutput -ECHO %CMDCMDLINE% | findstr /i "/c" >nul +ECHO %CMDCMDLINE% | findstr /i /c:"/c" >nul IF NOT errorlevel 1 PAUSE diff --git a/src/Installer/Installer.wxs b/src/Installer/Installer.wxs index 7fc72a12..8819bfcd 100644 --- a/src/Installer/Installer.wxs +++ b/src/Installer/Installer.wxs @@ -7,6 +7,9 @@ + + + @@ -14,26 +17,103 @@ http://blogs.msdn.com/robmen/archive/2003/10/04/56479.aspx --> - - + + + + + + + + + + + + + - - - + + + + + + + + + + 1 + + + + NOT PRODUCT_ANALYTICS_ENABLED AND NOT SIL_ANALYTICS_APPLY_GLOBALLY + + PRODUCT_ANALYTICS_ENABLED = "1" AND SIL_ANALYTICS_APPLY_GLOBALLY = "1" + NOT PRODUCT_ANALYTICS_ENABLED AND SIL_ANALYTICS_APPLY_GLOBALLY = "1" + 1 + + + 1 + + + + + + + LicenseAccepted = "1" + AND NOT PRODUCT_ANALYTICS_SETTING + AND NOT GLOBAL_ANALYTICS_SETTING + + + + LicenseAccepted = "1" + AND (PRODUCT_ANALYTICS_SETTING OR GLOBAL_ANALYTICS_SETTING) + + + + - + + - + - + + + + + + + + + + "1"]]> + + + + + + + + + + @@ -341,22 +449,22 @@ are trying to support, you're better off using non-advertised shortcuts. "--> - + - + - + - + - + - + @@ -367,6 +475,8 @@ are trying to support, you're better off using non-advertised shortcuts. "--> + + @@ -382,6 +492,7 @@ are trying to support, you're better off using non-advertised shortcuts. "--> + @@ -429,9 +540,22 @@ are trying to support, you're better off using non-advertised shortcuts. "--> + - + + + + + + NOT Installed + GetValues(); - } - /// ---------------------------------------------------------------------------------------- /// /// Gives lists of data, indexed by a key into a dictionary @@ -27,7 +19,6 @@ public interface ISingleListDataGatherer public interface IMultiListDataProvider { event EventHandler NewDataAvailable; - event EventHandler FinishedProcessingAllFiles; Dictionary> GetValueLists(bool includeUnattestedFactoryChoices); } @@ -35,7 +26,7 @@ public interface IMultiListDataProvider /// /// This is the base class for processes which live in the background, /// gathering data about the files in the collection so that this data - /// is quickly accesible when needed. + /// is quickly accessible when needed. /// /// ---------------------------------------------------------------------------------------- public abstract class BackgroundFileProcessor : IDisposable where T : class @@ -49,17 +40,17 @@ public abstract class BackgroundFileProcessor : IDisposable where T : class protected readonly IEnumerable _typesOfFilesToProcess; protected readonly Func _fileDataFactory; protected bool _restartRequested = true; - protected Dictionary _fileToDataDictionary = new Dictionary(); + protected Dictionary _fileToDataDictionary = new(); private readonly Queue _pendingFileEvents; private volatile int _suspendEventProcessingCount; - private readonly object _lockObj = new object(); - private readonly object _lockSuspendObj = new object(); + private readonly object _lockObj = new(); + private readonly object _lockSuspendObj = new(); public event EventHandler NewDataAvailable; public event EventHandler FinishedProcessingAllFiles; /// ------------------------------------------------------------------------------------ - public BackgroundFileProcessor(string rootDirectoryPath, + protected BackgroundFileProcessor(string rootDirectoryPath, IEnumerable typesOfFilesToProcess, Func fileDataFactory) { RootDirectoryPath = rootDirectoryPath; @@ -72,8 +63,7 @@ public BackgroundFileProcessor(string rootDirectoryPath, /// ------------------------------------------------------------------------------------ public void Dispose() { - if (_workerThread != null) - _workerThread.Abort(); //will eventually lead to it stopping + _workerThread?.Abort(); //will eventually lead to it stopping _workerThread = null; } @@ -122,22 +112,21 @@ public virtual void ResumeProcessing(bool processAllPendingEventsNow) protected virtual bool GetDoIncludeFile(string path) { var fileName = Path.GetFileName(path); - return (fileName != null && !fileName.StartsWith(".") && - (_typesOfFilesToProcess.Any(t => t.IsMatch(path)))); + return fileName != null && !fileName.StartsWith(".") && + _typesOfFilesToProcess.Any(t => t.IsMatch(path)); } /// ------------------------------------------------------------------------------------ - protected virtual ThreadPriority ThreadPriority - { - get { return ThreadPriority.Lowest; } - } + protected virtual ThreadPriority ThreadPriority => ThreadPriority.Lowest; /// ------------------------------------------------------------------------------------ public virtual void Start() { - _workerThread = new Thread(StartWorking); - _workerThread.Name = GetType().Name; - _workerThread.Priority = ThreadPriority; + _workerThread = new Thread(StartWorking) + { + Name = GetType().Name, + Priority = ThreadPriority + }; _workerThread.TrySetApartmentState(ApartmentState.STA);//needed in case we eventually show an error & need to talk to email. _workerThread.Start(); } @@ -145,8 +134,7 @@ public virtual void Start() /// ------------------------------------------------------------------------------------ protected virtual void OnNewDataAvailable(T fileData) { - if (NewDataAvailable != null) - NewDataAvailable(this, EventArgs.Empty); + NewDataAvailable?.Invoke(this, EventArgs.Empty); } /// ------------------------------------------------------------------------------------ @@ -154,7 +142,7 @@ private void StartWorking() { try { - Status = kWorkingStatus; //NB: this helps simplify unit tests, if go to the busy state before returning + Status = kWorkingStatus; //NB: this helps simplify unit tests, if we go to the busy state before returning using (var watcher = new FileSystemWatcher(RootDirectoryPath)) { @@ -189,11 +177,11 @@ private void StartWorking() } catch (ThreadAbortException) { - //this is fine, it happens when we quit + // This is fine, it happens when we quit } catch (Exception error) { - SIL.Reporting.ErrorReport.NotifyUserOfProblem(error, "Background file watching failed."); + ErrorReport.NotifyUserOfProblem(error, "Background file watching failed."); } } @@ -216,13 +204,11 @@ private void ProcessFileEvent(FileSystemEventArgs fileEvent) { try { - if (fileEvent is RenamedEventArgs) + if (fileEvent is RenamedEventArgs e) { - var e = fileEvent as RenamedEventArgs; lock (((ICollection)_fileToDataDictionary).SyncRoot) { - T fileData; - if (_fileToDataDictionary.TryGetValue(e.OldFullPath, out fileData)) + if (_fileToDataDictionary.TryGetValue(e.OldFullPath, out var fileData)) { _fileToDataDictionary.Remove(e.OldFullPath); _fileToDataDictionary[e.FullPath] = fileData; @@ -244,7 +230,7 @@ private void ProcessFileEvent(FileSystemEventArgs fileEvent) Debug.WriteLine(e.Message); Logger.WriteEvent("Handled Exception in {0}.ProcessingFileEvent:\r\n{1}", GetType().Name, e.ToString()); #if DEBUG - SIL.Reporting.ErrorReport.NotifyUserOfProblem(e, "Error gathering data"); + ErrorReport.NotifyUserOfProblem(e, "Error gathering data"); #endif //nothing here is worth crashing over } @@ -255,14 +241,13 @@ public T GetFileData(string filePath) { lock (((ICollection)_fileToDataDictionary).SyncRoot) { - T stats; - if (_fileToDataDictionary.TryGetValue(filePath, out stats)) + if (_fileToDataDictionary.TryGetValue(filePath, out var stats)) return stats; if (GetDoIncludeFile(filePath)) { CollectDataForFile(filePath); - return (_fileToDataDictionary.TryGetValue(filePath, out stats) ? stats : null); + return _fileToDataDictionary.TryGetValue(filePath, out stats) ? stats : null; } return null; } @@ -310,7 +295,7 @@ protected virtual void CollectDataForFile(string path) { ErrorReport.NotifyUserOfProblem(new ShowOncePerSessionBasedOnExactMessagePolicy(), e, string.Format(LocalizationManager.GetString("MainWindow.AutoCompleteValueGathererError", - "An error of type {0} ocurred trying to gather information from file: {1}", + "An error of type {0} occurred trying to gather information from file: {1}", "Parameter 0 is an exception type; parameter 1 is a file name"), e.GetType(), path)); } else @@ -356,7 +341,7 @@ public virtual void ProcessAllFilesInFolder(string folder) /// ------------------------------------------------------------------------------------ public virtual void ProcessAllFiles() { - //now that the watcher is up and running, gather up all existing files + // Now that the watcher is up and running, gather all existing files lock (((ICollection)_fileToDataDictionary).SyncRoot) { _fileToDataDictionary.Clear(); @@ -405,8 +390,7 @@ protected virtual void ProcessAllFiles(string topLevelFolder, bool searchSubFold Status = kUpToDataStatus; - if (FinishedProcessingAllFiles != null) - FinishedProcessingAllFiles(this, EventArgs.Empty); + FinishedProcessingAllFiles?.Invoke(this, EventArgs.Empty); } private static List WalkDirectoryTree(string topLevelFolder, SearchOption searchOption) @@ -416,7 +400,7 @@ private static List WalkDirectoryTree(string topLevelFolder, SearchOptio // First, process all the files directly under this folder try { - // SP-879: Crash reading .DS_Store file on MacOS + // SP-879: Crash reading .DS_Store file on macOS files = Directory.GetFiles(topLevelFolder, "*.*").Where(name => { var fileName = Path.GetFileName(name); @@ -435,13 +419,13 @@ private static List WalkDirectoryTree(string topLevelFolder, SearchOptio Debug.Print("Directory not found: " + topLevelFolder); } - if ((files != null) && (searchOption == SearchOption.AllDirectories)) + if (files != null && searchOption == SearchOption.AllDirectories) { // Now find all the subdirectories under this directory. var dirs = Directory.GetDirectories(topLevelFolder); foreach (var dir in dirs) { - // Resursive call for each subdirectory. + // Recursive call for each subdirectory. returnVal.AddRange(WalkDirectoryTree(dir, searchOption)); } } @@ -468,16 +452,10 @@ protected bool ShouldStop } /// ------------------------------------------------------------------------------------ - public bool Busy - { - get { return Status.StartsWith(kWorkingStatus); } - } + public bool Busy => Status.StartsWith(kWorkingStatus); /// ------------------------------------------------------------------------------------ - public bool DataUpToDate - { - get { return Status == kUpToDataStatus; } - } + public bool DataUpToDate => Status == kUpToDataStatus; /// ------------------------------------------------------------------------------------ public string Status diff --git a/src/SayMore/Model/Files/FieldUpdater.cs b/src/SayMore/Model/Files/FieldUpdater.cs index 2aa949b5..976b610c 100644 --- a/src/SayMore/Model/Files/FieldUpdater.cs +++ b/src/SayMore/Model/Files/FieldUpdater.cs @@ -77,8 +77,7 @@ private void FindAndUpdateFiles(ComponentFile file, string idOfFieldToFind, var matchingFiles = GetMatchingFiles(file.FileType); - if (_fieldGatherer != null) - _fieldGatherer.SuspendProcessing(); + _fieldGatherer?.SuspendProcessing(); foreach (var path in matchingFiles) { diff --git a/src/SayMore/Model/Project.cs b/src/SayMore/Model/Project.cs index dace0be1..5aa6ec0c 100644 --- a/src/SayMore/Model/Project.cs +++ b/src/SayMore/Model/Project.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using System.Drawing; +using System.IO; using System.IO.Compression; using System.Linq; using System.Text; @@ -13,21 +13,23 @@ using System.Xml.Serialization; using DesktopAnalytics; using L10NSharp; -using SIL.Extensions; -using SIL.Reporting; -using SIL.Windows.Forms; +using SayMore.Model.Files; +using SayMore.Properties; +using SayMore.Transcription.Model; using SayMore.UI.ComponentEditors; using SayMore.UI.Overview; +using SayMore.UI.Overview.Statistics; +using SayMore.Utilities; using SIL.Archiving; using SIL.Archiving.Generic; using SIL.Archiving.IMDI; -using SayMore.Properties; -using SayMore.Transcription.Model; -using SayMore.Model.Files; -using SayMore.Utilities; using SIL.Core.ClearShare; +using SIL.Extensions; using SIL.IO; +using SIL.Reporting; +using SIL.Windows.Forms; using static System.IO.Path; +using static SayMore.Model.Files.ComponentRole.MeasurementTypes; using static SIL.Archiving.ArchivingDlgViewModel.MessageType; namespace SayMore.Model @@ -63,6 +65,120 @@ public class Project : IAutoSegmenterSettings, IRAMPArchivable, IDisposable private bool _needToDisposeFreeTranslationFont; private Font _workingLanguageFont; private bool _needToDisposeWorkingLanguageFont; + private bool _disposed = false; + + private sealed class ProgressStats + { + private readonly StatisticsViewModel _model; + + private readonly int _initialNumberOfSessions; + private readonly int _initialNumberOfPersons; + + private sealed class MediaDurationStats(TimeSpan initial) + { + private TimeSpan Initial { get; } = initial; + public TimeSpan Current { get; set; } = initial; + + public TimeSpan Delta => Current - Initial; + } + + private sealed class RoleCountStats(int initial) + { + private int Initial { get; } = initial; + public int Current { get; set; } = initial; + + public int Delta => Current - Initial; + } + + private readonly Dictionary _mediaDurationStats; + private readonly Dictionary _sessionRoleStats; + + internal ProgressStats(StatisticsViewModel model) + { + _model = model; + + _initialNumberOfSessions = _model.SessionInformant.NumberOfSessions; + _initialNumberOfPersons = _model.PersonInformant.NumberOfPeople; + _mediaDurationStats = _model.GetComponentRoleStatisticsPairs() + .ToDictionary(s => s.Name, s => new MediaDurationStats(s.Length)); + + _sessionRoleStats = _model.SessionInformant.GetSessionsCategorizedByStage() + .Where(s => s.Key.MeasurementType != Time) + .ToDictionary(s => s.Key.Id, s => new RoleCountStats(s.Value.Count())); + } + + internal void ReportUpdatedStatistics() + { + if (_model.IsBusy) + Thread.Sleep(200); // Give it a fighting chance to finish. + + var sessionDelta = _model.SessionInformant.NumberOfSessions - _initialNumberOfSessions; + var personDelta = _model.PersonInformant.NumberOfPeople - _initialNumberOfPersons; + + foreach (var stat in _model.GetComponentRoleStatisticsPairs()) + { + if (_mediaDurationStats.TryGetValue(stat.Name, out var entry)) + entry.Current = stat.Length; + else + { + _mediaDurationStats[stat.Name] = + new MediaDurationStats(TimeSpan.Zero) + { + Current = stat.Length + }; + } + } + + foreach (var stat in _model.SessionInformant.GetSessionsCategorizedByStage() + .Where(s => s.Key.MeasurementType != Time)) + { + if (_sessionRoleStats.TryGetValue(stat.Key.Id, out var entry)) + entry.Current = stat.Value.Count(); + else + { + _sessionRoleStats[stat.Key.Id] = new RoleCountStats(0) + { + Current = stat.Value.Count() + }; + } + } + + var properties = new Dictionary(); + + if (sessionDelta > 0) + properties["SessionsAdded"] = sessionDelta.ToString(); + + if (personDelta > 0) + properties["PersonsAdded"] = personDelta.ToString(); + + foreach (var kvp in _mediaDurationStats) + { + var delta = kvp.Value.Delta; + if (delta > TimeSpan.Zero) + { + properties[$"MediaDurationAdded.{kvp.Key}"] = + delta.TotalSeconds.ToString("F0"); + } + } + + foreach (var kvp in _sessionRoleStats) + { + var delta = kvp.Value.Delta; + if (delta > 0) + { + properties[$"CompletedStages.{kvp.Key}"] = + delta.ToString(); + } + } + + if (properties.Any()) + Analytics.Track("ProjectProgress", properties); + } + } + + private readonly object _statisticsLock = new(); + private StatisticsViewModel _statisticsViewModel; + private ProgressStats _progressStats; public delegate Project Factory(string desiredOrExistingFilePath); @@ -105,30 +221,40 @@ public Project(string desiredOrExistingSettingsFilePath, throw new ArgumentException("Invalid project path specified", nameof(desiredOrExistingSettingsFilePath)); var saveNeeded = false; + var projectInfo = new Dictionary {{"projectName", Name}}; + if (File.Exists(desiredOrExistingSettingsFilePath)) { RenameEventsToSessions(projectDirectory); Load(); + projectInfo["vernacularISO3CodeAndName"] = VernacularISO3CodeAndName; + projectInfo["analysisISO3CodeAndName"] = AnalysisISO3CodeAndName; + projectInfo["projectLocation"] = Location; + projectInfo["projectRegion"] = Region; + projectInfo["projectCountry"] = Country; + projectInfo["projectContinent"] = Continent; } else { + Analytics.Track("Project Created", projectInfo); Directory.CreateDirectory(projectDirectory); Title = Name; saveNeeded = true; } - if (TranscriptionFont == null) - TranscriptionFont = Program.DialogFont; + TranscriptionFont ??= Program.DialogFont; + projectInfo["transcriptionFont"] = TranscriptionFont.Name; + FreeTranslationFont ??= Program.DialogFont; + projectInfo["freeTranslationFont"] = FreeTranslationFont.Name; - if (FreeTranslationFont == null) - FreeTranslationFont = Program.DialogFont; + Analytics.Track("Project Opened", projectInfo); if (AutoSegmenterMinimumSegmentLengthInMilliseconds < Settings.Default.MinimumSegmentLengthInMilliseconds || - AutoSegmenterMaximumSegmentLengthInMilliseconds <= 0 || - AutoSegmenterMinimumSegmentLengthInMilliseconds >= AutoSegmenterMaximumSegmentLengthInMilliseconds || - AutoSegmenterPreferredPauseLengthInMilliseconds <= 0 || - AutoSegmenterPreferredPauseLengthInMilliseconds > AutoSegmenterMaximumSegmentLengthInMilliseconds || - AutoSegmenterOptimumLengthClampingFactor <= 0) + AutoSegmenterMaximumSegmentLengthInMilliseconds <= 0 || + AutoSegmenterMinimumSegmentLengthInMilliseconds >= AutoSegmenterMaximumSegmentLengthInMilliseconds || + AutoSegmenterPreferredPauseLengthInMilliseconds <= 0 || + AutoSegmenterPreferredPauseLengthInMilliseconds > AutoSegmenterMaximumSegmentLengthInMilliseconds || + AutoSegmenterOptimumLengthClampingFactor <= 0) { saveNeeded = AutoSegmenterMinimumSegmentLengthInMilliseconds != 0 || AutoSegmenterMaximumSegmentLengthInMilliseconds != 0 || AutoSegmenterPreferredPauseLengthInMilliseconds != 0 || !AutoSegmenterOptimumLengthClampingFactor.Equals(0) || saveNeeded; @@ -143,9 +269,57 @@ public Project(string desiredOrExistingSettingsFilePath, Save(); } + /// ------------------------------------------------------------------------------------ + public void ReportProgressIfAny() + { + if (Monitor.TryEnter(_statisticsLock, TimeSpan.FromMilliseconds(200))) + { + try + { + if (_statisticsViewModel == null) + return; + + _statisticsViewModel.FinishedGatheringStatisticsForAllFiles -= FinishedGatheringStatistics; + + // Really unlikely, but if we get here before the initial gathering is done, we can't do anything. + if (_progressStats == null) + return; + + try + { + _progressStats.ReportUpdatedStatistics(); + } + catch (ObjectDisposedException e) + { + // This probably should be impossible, but just in case, we don't want reporting stats to + // crash the program. + Logger.WriteError(e); + } + _progressStats = null; // This ensures we only report once per project open. + } + finally + { + Monitor.Exit(_statisticsLock); + } + } + } + /// ------------------------------------------------------------------------------------ public void Dispose() { + lock (_statisticsLock) + { + if (_disposed) + return; + + _disposed = true; + + _progressStats = null; + _progressStats = null; // Probably already done, but it also had a copy of _statisticsViewModel. + _statisticsViewModel?.Dispose(); + _statisticsViewModel = null; + } + _sessionsRepoFactory = null; if (_needToDisposeTranscriptionFont) TranscriptionFont.Dispose(); @@ -328,54 +502,6 @@ public void Save() _accessProtocolChanged = false; } - /// ------------------------------------------------------------------------------------ - public string GetFileDescription(string key, string file) - { - var description = (key == string.Empty ? "SayMore Session File" : "SayMore Contributor File"); - - if (file.ToLower().EndsWith(Settings.Default.SessionFileExtension)) - description = "SayMore Session Metadata (XML)"; - else if (file.ToLower().EndsWith(Settings.Default.PersonFileExtension)) - description = "SayMore Contributor Metadata (XML)"; - else if (file.ToLower().EndsWith(Settings.Default.MetadataFileExtension)) - description = "SayMore File Metadata (XML)"; - - return description; - } - - /// ------------------------------------------------------------------------------------ - public void SetAdditionalMetsData(RampArchivingDlgViewModel model) - { - foreach (var session in GetAllSessions(CancellationToken.None)) - { - model.SetScholarlyWorkType(ScholarlyWorkType.PrimaryData); - model.SetDomains(SilDomain.Ling_LanguageDocumentation); - - var value = session.MetaDataFile.GetStringValue(SessionFileType.kDateFieldName, null); - if (!string.IsNullOrEmpty(value)) - model.SetCreationDate(value); - - // Return the session's note as the abstract portion of the package's description. - value = session.MetaDataFile.GetStringValue(SessionFileType.kSynopsisFieldName, null); - if (!string.IsNullOrEmpty(value)) - model.SetAbstract(value, string.Empty); - - // Set contributors - var contribsVal = session.MetaDataFile.GetValue(SessionFileType.kContributionsFieldName, null); - if (contribsVal is ContributionCollection contributions && contributions.Count > 0) - model.SetContributors(contributions); - - // Return total duration of source audio/video recordings. - TimeSpan totalDuration = session.GetTotalDurationOfSourceMedia(); - if (totalDuration.Ticks > 0) - model.SetAudioVideoExtent($"Total Length of Source Recordings: {totalDuration}"); - - //First session details are enough for "Archive RAMP (SIL)..." from Project menu - break; - } - } - - /// ------------------------------------------------------------------------------------ public void Load() { @@ -483,26 +609,26 @@ private static string GetFontErrorMessage(string description, string settingValu } /// ------------------------------------------------------------------------------------ - private string GetStringSettingValue(XElement project, string elementName, string defaultValue) + private static string GetStringSettingValue(XElement project, string elementName, string defaultValue) { var element = project.Element(elementName); return element == null ? defaultValue : element.Value; } /// ------------------------------------------------------------------------------------ - private int GetIntAttributeValue(XElement project, string attribName, string fallbackAttribName = null) + private static int GetIntAttributeValue(XElement project, string attribName, string fallbackAttribName = null) { var attrib = project.Attribute(attribName); if (attrib == null && fallbackAttribName != null) attrib = project.Attribute(fallbackAttribName); - return (attrib != null && Int32.TryParse(attrib.Value, out var val)) ? val : default; + return attrib != null && Int32.TryParse(attrib.Value, out var val) ? val : 0; } /// ------------------------------------------------------------------------------------ - private double GetDoubleAttributeValue(XElement project, string attribName) + private static double GetDoubleAttributeValue(XElement project, string attribName) { var attrib = project.Attribute(attribName); - return (attrib != null && Double.TryParse(attrib.Value, out var val)) ? val : default; + return attrib != null && Double.TryParse(attrib.Value, out var val) ? val : 0; } /// ------------------------------------------------------------------------------------ @@ -558,6 +684,53 @@ internal IEnumerable GetAllSessions(CancellationToken cancellationToken } #region Archiving + /// ------------------------------------------------------------------------------------ + public string GetFileDescription(string key, string file) + { + var description = key == string.Empty ? "SayMore Session File" : "SayMore Contributor File"; + + if (file.ToLower().EndsWith(Settings.Default.SessionFileExtension)) + description = "SayMore Session Metadata (XML)"; + else if (file.ToLower().EndsWith(Settings.Default.PersonFileExtension)) + description = "SayMore Contributor Metadata (XML)"; + else if (file.ToLower().EndsWith(Settings.Default.MetadataFileExtension)) + description = "SayMore File Metadata (XML)"; + + return description; + } + + /// ------------------------------------------------------------------------------------ + public void SetAdditionalMetsData(RampArchivingDlgViewModel model) + { + foreach (var session in GetAllSessions(CancellationToken.None)) + { + model.SetScholarlyWorkType(ScholarlyWorkType.PrimaryData); + model.SetDomains(SilDomain.Ling_LanguageDocumentation); + + var value = session.MetaDataFile.GetStringValue(SessionFileType.kDateFieldName, null); + if (!string.IsNullOrEmpty(value)) + model.SetCreationDate(value); + + // Return the session's note as the abstract portion of the package's description. + value = session.MetaDataFile.GetStringValue(SessionFileType.kSynopsisFieldName, null); + if (!string.IsNullOrEmpty(value)) + model.SetAbstract(value, string.Empty); + + // Set contributors + var contribsVal = session.MetaDataFile.GetValue(SessionFileType.kContributionsFieldName, null); + if (contribsVal is ContributionCollection contributions && contributions.Count > 0) + model.SetContributors(contributions); + + // Return total duration of source audio/video recordings. + TimeSpan totalDuration = session.GetTotalDurationOfSourceMedia(); + if (totalDuration.Ticks > 0) + model.SetAudioVideoExtent($"Total Length of Source Recordings: {totalDuration}"); + + //First session details are enough for "Archive RAMP (SIL)..." from Project menu + break; + } + } + /// ------------------------------------------------------------------------------------ public string ArchiveInfoDetails => LocalizationManager.GetString("DialogBoxes.ArchivingDlg.ProjectArchivingInfoDetails", @@ -821,5 +994,33 @@ public IEnumerable GetSessionFilesToArchive(Type typeOfArchive, Settings.Default.SessionFileExtension, CancellationToken.None)); } #endregion + + public void TrackStatistics(StatisticsViewModel statisticsViewModel) + { + lock (_statisticsLock) + { + if (_statisticsViewModel != null) + _statisticsViewModel.FinishedGatheringStatisticsForAllFiles -= FinishedGatheringStatistics; + + _statisticsViewModel = statisticsViewModel; + _statisticsViewModel.FinishedGatheringStatisticsForAllFiles += FinishedGatheringStatistics; + if (_statisticsViewModel.IsDataUpToDate) + { + // It finished before we could hook the event. + FinishedGatheringStatistics(_statisticsViewModel, null); + } + } + } + + private void FinishedGatheringStatistics(object sender, EventArgs e) + { + lock (_statisticsLock) + { + _statisticsViewModel.FinishedGatheringStatisticsForAllFiles -= FinishedGatheringStatistics; + Debug.Assert(_progressStats == null); + + _progressStats = new ProgressStats(_statisticsViewModel); + } + } } } diff --git a/src/SayMore/Model/SessionWorkflowInformant.cs b/src/SayMore/Model/SessionWorkflowInformant.cs index 7a1d9ca2..1973df83 100644 --- a/src/SayMore/Model/SessionWorkflowInformant.cs +++ b/src/SayMore/Model/SessionWorkflowInformant.cs @@ -14,7 +14,7 @@ namespace SayMore.Model public class SessionWorkflowInformant { private readonly ElementRepository _sessionRepository; - private IEnumerable _componentRoles; + private readonly IEnumerable _componentRoles; [Obsolete("For mocking only")] public SessionWorkflowInformant(){} @@ -28,10 +28,7 @@ public SessionWorkflowInformant(ElementRepository sessionRepository, } /// ------------------------------------------------------------------------------------ - public int NumberOfSessions - { - get { return _sessionRepository.AllItems.Count(); } - } + public int NumberOfSessions => _sessionRepository.AllItems.Count(); /// ------------------------------------------------------------------------------------ /// diff --git a/src/SayMore/Program.cs b/src/SayMore/Program.cs index 1971d7b6..1e556892 100644 --- a/src/SayMore/Program.cs +++ b/src/SayMore/Program.cs @@ -3,10 +3,10 @@ using System.Collections.Specialized; using System.ComponentModel; using System.Configuration; -using System.Drawing; -using System.Linq; using System.Diagnostics; +using System.Drawing; using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.ExceptionServices; using System.Text; @@ -15,20 +15,23 @@ using System.Xml; using DesktopAnalytics; using L10NSharp; -using SIL.Code; -using SIL.Extensions; -using SIL.IO; -using SIL.Reporting; -using SIL.Windows.Forms.Miscellaneous; -using SIL.Windows.Forms.PortableSettingsProvider; +using L10NSharp.Windows.Forms; using SayMore.Media; +using SayMore.Model; using SayMore.Properties; using SayMore.UI; using SayMore.UI.Overview; using SayMore.UI.ProjectWindow; -using SayMore.Model; using SayMore.Utilities; +using SIL.Code; +using SIL.Core.Desktop.Privacy; +using SIL.Extensions; +using SIL.IO; +using SIL.Reporting; using SIL.Windows.Forms.Extensions; +using SIL.Windows.Forms.Miscellaneous; +using SIL.Windows.Forms.PortableSettingsProvider; +using SIL.Windows.Forms.Privacy; using SIL.Windows.Forms.Reporting; using SIL.WritingSystems; using static System.Environment; @@ -60,6 +63,7 @@ static class Program private static readonly List _pendingExceptionsToReportToAnalytics = new List(); private static UserInfo s_userInfo; + internal static IAnalyticsConsent AnalyticsImpl; private static bool s_handlingFirstChanceExceptionThreadsafe = false; private static bool s_handlingFirstChanceExceptionUnsafe = false; @@ -205,11 +209,8 @@ static void Main() // Always track if this is a debug build, but track to a different segment.io project using (new Analytics("twa75xkko9", s_userInfo)) #else - // If this is a release build, then allow an environment variable to be set to false - // so that testers aren't generating false analytics - string feedbackSetting = System.Environment.GetEnvironmentVariable("FEEDBACK"); - - var allowTracking = IsNullOrEmpty(feedbackSetting) || feedbackSetting.ToLower() == "yes" || feedbackSetting.ToLower() == "true"; + // If this is a release build, then allow opt-out. + var allowTracking = IsAnalyticsEnabled; using (new Analytics("jtfe7dyef3", s_userInfo, allowTracking)) #endif @@ -235,6 +236,8 @@ static void Main() { Application.Run(); Settings.Default.Save(); + _projectContext?.Project.ReportProgressIfAny(); + Analytics.FlushClient(); Logger.WriteEvent("SayMore shutting down"); if (s_countOfContiguousFirstChanceOutOfMemoryExceptions > 1) Logger.WriteEvent("Total number of contiguous OutOfMemoryExceptions: {0}", s_countOfContiguousFirstChanceOutOfMemoryExceptions); @@ -251,6 +254,25 @@ static void Main() } } + private static bool IsAnalyticsEnabled + { + get + { + AnalyticsImpl = new AnalyticsConsent(Application.ProductName); + AnalyticsImpl.AllowTrackingChanged += (_, allowTrackingChangedEventArgs) => + { + Analytics.AllowTracking = allowTrackingChangedEventArgs.IsTrackingAllowed; + }; + + // For testers (so they aren't generating false analytics) + var feedbackSetting = GetEnvironmentVariable("FEEDBACK")?.ToLowerInvariant(); + if (!IsNullOrEmpty(feedbackSetting)) + return feedbackSetting == "yes" || feedbackSetting == "true"; + + return AnalyticsImpl.AllowTracking; + } + } + public static string GetAnalyticsConfigFilePath() { try @@ -581,23 +603,23 @@ static void ChooseAnotherProject(object sender, EventArgs e) while (true) { - using (var dlg = _applicationContainer.CreateWelcomeDialog()) + using var dlg = _applicationContainer.CreateWelcomeDialog(); + if (dlg.ShowDialog() != DialogResult.OK) { - if (dlg.ShowDialog() != DialogResult.OK) - { - Application.Exit(); - return; - } - - if (OpenProjectWindow(dlg.Model.ProjectSettingsFilePath)) - return; + Application.Exit(); + return; } + + if (OpenProjectWindow(dlg.Model.ProjectSettingsFilePath)) + return; } } /// ------------------------------------------------------------------------------------ - static void HandleProjectWindowClosed(object sender, EventArgs e) + private static void HandleProjectWindowClosed(object sender, EventArgs e) { + _projectContext?.Project.ReportProgressIfAny(); + SafelyDisposeProjectContext(); ReleaseMutexForThisProject(); @@ -833,7 +855,7 @@ public static void UpdateUiLanguageForUser(string languageId) Analytics.IdentifyUpdate(s_userInfo); Settings.Default.UserInterfaceLanguage = languageId; Logger.WriteEvent("Changed UI Locale to: " + languageId); - LocalizationManager.SetUILanguage(languageId, true); + LocalizationManagerWinforms.SetUILanguage(languageId, true); } } } diff --git a/src/SayMore/ProjectContext.cs b/src/SayMore/ProjectContext.cs index 31973d0a..a1946e3c 100644 --- a/src/SayMore/ProjectContext.cs +++ b/src/SayMore/ProjectContext.cs @@ -179,17 +179,15 @@ public static void SetContributorsListToSession(string sessionsFolder) private static XmlDocument LoadXmlDocument(string xmlFile) { var doc = new XmlDocument(); - using (var reader = XmlReader.Create(xmlFile)) + using var reader = XmlReader.Create(xmlFile); + try { - try - { - doc.Load(reader); - } - catch (XmlException e) - { - Logger.WriteError($"Error loading {xmlFile}", e); - throw; - } + doc.Load(reader); + } + catch (XmlException e) + { + Logger.WriteError($"Error loading {xmlFile}", e); + throw; } return doc; @@ -369,47 +367,37 @@ public void Dispose() /// ------------------------------------------------------------------------------------ public void SuspendAudioVideoBackgroundProcesses() { - if (_audioVideoDataGatherer != null) - _audioVideoDataGatherer.SuspendProcessing(); + _audioVideoDataGatherer?.SuspendProcessing(); } /// ------------------------------------------------------------------------------------ public void ResumeAudioVideoBackgroundProcesses(bool processAllPendingEventsNow) { - if (_audioVideoDataGatherer != null) - _audioVideoDataGatherer.ResumeProcessing(processAllPendingEventsNow); + _audioVideoDataGatherer?.ResumeProcessing(processAllPendingEventsNow); } /// ------------------------------------------------------------------------------------ public void SuspendBackgroundProcesses() { - if (_audioVideoDataGatherer != null) - _audioVideoDataGatherer.SuspendProcessing(); + _audioVideoDataGatherer?.SuspendProcessing(); - if (_autoCompleteValueGatherer != null) - _autoCompleteValueGatherer.SuspendProcessing(); + _autoCompleteValueGatherer?.SuspendProcessing(); - if (_fieldGatherer != null) - _fieldGatherer.SuspendProcessing(); + _fieldGatherer?.SuspendProcessing(); - if (_presetGatherer != null) - _presetGatherer.SuspendProcessing(); + _presetGatherer?.SuspendProcessing(); } /// ------------------------------------------------------------------------------------ public void ResumeBackgroundProcesses(bool processAllPendingEventsNow) { - if (_audioVideoDataGatherer != null) - _audioVideoDataGatherer.ResumeProcessing(processAllPendingEventsNow); + _audioVideoDataGatherer?.ResumeProcessing(processAllPendingEventsNow); - if (_autoCompleteValueGatherer != null) - _autoCompleteValueGatherer.ResumeProcessing(processAllPendingEventsNow); + _autoCompleteValueGatherer?.ResumeProcessing(processAllPendingEventsNow); - if (_fieldGatherer != null) - _fieldGatherer.ResumeProcessing(processAllPendingEventsNow); + _fieldGatherer?.ResumeProcessing(processAllPendingEventsNow); - if (_presetGatherer != null) - _presetGatherer.ResumeProcessing(processAllPendingEventsNow); + _presetGatherer?.ResumeProcessing(processAllPendingEventsNow); } /// ------------------------------------------------------------------------------------ diff --git a/src/SayMore/Properties/AssemblyInfo.cs b/src/SayMore/Properties/AssemblyInfo.cs index dd2e5029..59b87d0a 100644 --- a/src/SayMore/Properties/AssemblyInfo.cs +++ b/src/SayMore/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("SIL Global")] [assembly: AssemblyProduct("SayMore")] -[assembly: AssemblyCopyright("Copyright © 2011-2025 SIL Global")] +[assembly: AssemblyCopyright("Copyright © 2011-2026 SIL Global")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/src/SayMore/SayMore.csproj b/src/SayMore/SayMore.csproj index 10bcf972..fe3da98c 100644 --- a/src/SayMore/SayMore.csproj +++ b/src/SayMore/SayMore.csproj @@ -37,10 +37,10 @@ - + - - + + @@ -49,24 +49,27 @@ - - - - - - + + + + + + All - - - - + + + + + + - + + diff --git a/src/SayMore/Transcription/UI/ComponentEditors/ConvertToStandardAudioEditor.Designer.cs b/src/SayMore/Transcription/UI/ComponentEditors/ConvertToStandardAudioEditor.Designer.cs index 6b84a968..b1da8296 100644 --- a/src/SayMore/Transcription/UI/ComponentEditors/ConvertToStandardAudioEditor.Designer.cs +++ b/src/SayMore/Transcription/UI/ComponentEditors/ConvertToStandardAudioEditor.Designer.cs @@ -30,7 +30,7 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._pictureInfo = new System.Windows.Forms.PictureBox(); this._labelSourceFileName = new System.Windows.Forms.Label(); this._labelConvertIntroduction = new System.Windows.Forms.Label(); @@ -236,7 +236,7 @@ private void InitializeComponent() #endregion - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private TableLayoutPanel _tableLayoutConvert; private PictureBox _pictureInfo; private Label _labelSourceFileName; diff --git a/src/SayMore/Transcription/UI/ComponentEditors/ConvertToStandardAudioEditor.cs b/src/SayMore/Transcription/UI/ComponentEditors/ConvertToStandardAudioEditor.cs index efadc4da..acf97eda 100644 --- a/src/SayMore/Transcription/UI/ComponentEditors/ConvertToStandardAudioEditor.cs +++ b/src/SayMore/Transcription/UI/ComponentEditors/ConvertToStandardAudioEditor.cs @@ -18,7 +18,8 @@ public partial class ConvertToStandardAudioEditor : EditorBase { private static Bitmap s_informationIconAsBitmap; /// ------------------------------------------------------------------------------------ - public ConvertToStandardAudioEditor(ComponentFile file) : base(file, null, null) + public ConvertToStandardAudioEditor(ComponentFile file) : + base(file, null) { Logger.WriteEvent("ConvertToStandardAudioEditor constructor. file = {0}", file); InitializeComponent(); @@ -38,8 +39,7 @@ public ConvertToStandardAudioEditor(ComponentFile file) : base(file, null, null) // Finally, I "solved" the problem by caching and reusing the bitmap each time it is // needed rather than create a new one. So now that bitmap stays in memory the whole // time, but at least it's just one. - if (s_informationIconAsBitmap == null) - s_informationIconAsBitmap = SystemIcons.Information.ToBitmap(); + s_informationIconAsBitmap ??= SystemIcons.Information.ToBitmap(); _pictureInfo.Image = s_informationIconAsBitmap; } @@ -102,25 +102,17 @@ private string GetIntroMessage() } /// ------------------------------------------------------------------------------------ - public override bool IsOKToShow - { - get - { - return (_file != null && !_file.GetDoesHaveAnnotationFile() && - _file.GetNeedsConvertingToStandardAudio() && - !File.Exists(_file.GetSuggestedPathToStandardAudioFile())); - } - } + public override bool IsOKToShow => + _file != null && !_file.GetDoesHaveAnnotationFile() && + _file.GetNeedsConvertingToStandardAudio() && + !File.Exists(_file.GetSuggestedPathToStandardAudioFile()); /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = CommonUIStrings.StartAnnotatingTabText; - } + TabText = CommonUIStrings.StartAnnotatingTabText; - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } /// ------------------------------------------------------------------------------------ diff --git a/src/SayMore/Transcription/UI/ComponentEditors/OralAnnotationEditor.Designer.cs b/src/SayMore/Transcription/UI/ComponentEditors/OralAnnotationEditor.Designer.cs index 63b14824..603272ca 100644 --- a/src/SayMore/Transcription/UI/ComponentEditors/OralAnnotationEditor.Designer.cs +++ b/src/SayMore/Transcription/UI/ComponentEditors/OralAnnotationEditor.Designer.cs @@ -38,7 +38,7 @@ private void InitializeComponent() this._panelOralAnnotationWaveViewer = new SIL.Windows.Forms.Widgets.EnhancedPanel(); this._oralAnnotationWaveViewer = new SayMore.Transcription.UI.OralAnnotationWaveViewer(); this._labelCursorTime = new System.Windows.Forms.Label(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayout.SuspendLayout(); this._toolStrip.SuspendLayout(); this._panelOralAnnotationWaveViewer.SuspendLayout(); @@ -227,7 +227,7 @@ private void InitializeComponent() private OralAnnotationWaveViewer _oralAnnotationWaveViewer; private System.Windows.Forms.ToolStripButton _buttonPlay; private System.Windows.Forms.ToolStripButton _buttonStop; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.ToolStripButton _buttonRegenerate; private System.Windows.Forms.Label _labelCursorTime; diff --git a/src/SayMore/Transcription/UI/ComponentEditors/OralAnnotationEditor.cs b/src/SayMore/Transcription/UI/ComponentEditors/OralAnnotationEditor.cs index 6c81eebf..12c096e7 100644 --- a/src/SayMore/Transcription/UI/ComponentEditors/OralAnnotationEditor.cs +++ b/src/SayMore/Transcription/UI/ComponentEditors/OralAnnotationEditor.cs @@ -20,7 +20,8 @@ public partial class OralAnnotationEditor : EditorBase private string _fileTooLongMsgDisplayedForFile; /// ------------------------------------------------------------------------------------ - public OralAnnotationEditor(ComponentFile file) : base(file, null, "Audio") + public OralAnnotationEditor(ComponentFile file) : + base(file, "Audio") { Logger.WriteEvent("OralAnnotationEditor constructor. file = {0}", file); InitializeComponent(); @@ -268,16 +269,13 @@ private void HandleRegenerateFileButtonClick(object sender, EventArgs e) /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = LocalizationManager.GetString( - "SessionsView.Transcription.GeneratedOralAnnotationView.TabText", - "Generated Audio"); - } + TabText = LocalizationManager.GetString( + "SessionsView.Transcription.GeneratedOralAnnotationView.TabText", + "Generated Audio"); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } } } diff --git a/src/SayMore/Transcription/UI/ComponentEditors/StartAnnotatingEditor.Designer.cs b/src/SayMore/Transcription/UI/ComponentEditors/StartAnnotatingEditor.Designer.cs index 5714599d..5bfea893 100644 --- a/src/SayMore/Transcription/UI/ComponentEditors/StartAnnotatingEditor.Designer.cs +++ b/src/SayMore/Transcription/UI/ComponentEditors/StartAnnotatingEditor.Designer.cs @@ -48,7 +48,7 @@ private void InitializeComponent() this._buttonAutoSegmenterHelp = new System.Windows.Forms.Button(); this._cboAudacityLabelTier = new System.Windows.Forms.ComboBox(); this._labelAudacityLabelTier = new System.Windows.Forms.Label(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayoutGetStarted.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); this.SuspendLayout(); @@ -411,7 +411,7 @@ private void InitializeComponent() #endregion private System.Windows.Forms.TableLayoutPanel _tableLayoutGetStarted; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Label _labelSegmentationMethodQuestion; private System.Windows.Forms.Label _labelSegmentationMethod; private System.Windows.Forms.Label _labelIntroduction; diff --git a/src/SayMore/Transcription/UI/ComponentEditors/StartAnnotatingEditor.cs b/src/SayMore/Transcription/UI/ComponentEditors/StartAnnotatingEditor.cs index 35e07ddd..8bfb5a5c 100644 --- a/src/SayMore/Transcription/UI/ComponentEditors/StartAnnotatingEditor.cs +++ b/src/SayMore/Transcription/UI/ComponentEditors/StartAnnotatingEditor.cs @@ -21,7 +21,7 @@ public partial class StartAnnotatingEditor : EditorBase /// ------------------------------------------------------------------------------------ public StartAnnotatingEditor(ComponentFile file, Project project) : - base(file, null, null) + base(file, null) { _project = project; Logger.WriteEvent("OralAnnotationEditor constructor. file = {0}", file); @@ -78,22 +78,19 @@ public override bool IsOKToShow } /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) + TabText = CommonUIStrings.StartAnnotatingTabText; + + if (_cboAudacityLabelTier != null) { - TabText = CommonUIStrings.StartAnnotatingTabText; - - if (_cboAudacityLabelTier != null) - { - var selectedIndex = _cboAudacityLabelTier.SelectedIndex; - _cboAudacityLabelTier.Items.Clear(); - PopulateAudacityLabelTierItems(); - _cboAudacityLabelTier.SelectedIndex = selectedIndex >= 0 ? selectedIndex : 0; - } - } + var selectedIndex = _cboAudacityLabelTier.SelectedIndex; + _cboAudacityLabelTier.Items.Clear(); + PopulateAudacityLabelTierItems(); + _cboAudacityLabelTier.SelectedIndex = selectedIndex >= 0 ? selectedIndex : 0; + } - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } private void PopulateAudacityLabelTierItems() diff --git a/src/SayMore/Transcription/UI/ComponentEditors/TextAnnotationEditor.Designer.cs b/src/SayMore/Transcription/UI/ComponentEditors/TextAnnotationEditor.Designer.cs index 76bd6f71..54dce190 100644 --- a/src/SayMore/Transcription/UI/ComponentEditors/TextAnnotationEditor.Designer.cs +++ b/src/SayMore/Transcription/UI/ComponentEditors/TextAnnotationEditor.Designer.cs @@ -36,7 +36,7 @@ private void InitializeComponent() this._buttonCarefulSpeech = new System.Windows.Forms.ToolStripMenuItem(); this._buttonOralTranslation = new System.Windows.Forms.ToolStripMenuItem(); this._comboPlaybackSpeed = new System.Windows.Forms.ToolStripComboBox(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._splitter = new System.Windows.Forms.SplitContainer(); this._toolStrip.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); @@ -340,7 +340,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem _buttonOralTranslation; private System.Windows.Forms.ToolStripButton _buttonHelp; private System.Windows.Forms.ToolStripButton _buttonResegment; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.ToolStripDropDownButton _exportMenu; private System.Windows.Forms.ToolStripMenuItem _plainTextExportMenuItem; private System.Windows.Forms.ToolStripMenuItem _flexInterlinearExportMenuItem; diff --git a/src/SayMore/Transcription/UI/ComponentEditors/TextAnnotationEditor.cs b/src/SayMore/Transcription/UI/ComponentEditors/TextAnnotationEditor.cs index be222a49..a4677e3f 100644 --- a/src/SayMore/Transcription/UI/ComponentEditors/TextAnnotationEditor.cs +++ b/src/SayMore/Transcription/UI/ComponentEditors/TextAnnotationEditor.cs @@ -7,7 +7,7 @@ using System.Linq; using DesktopAnalytics; using L10NSharp; -using L10NSharp.UI; +using L10NSharp.Windows.Forms; using SIL.Reporting; using SIL.Windows.Forms.Extensions; using SayMore.Media.Audio; @@ -19,6 +19,7 @@ using SayMore.Media.MPlayer; using SayMore.Model; using SayMore.Utilities; +using SIL.Windows.Forms; // ReSharper disable once CheckNamespace namespace SayMore.Transcription.UI @@ -37,7 +38,7 @@ public partial class TextAnnotationEditor : EditorBase /// ------------------------------------------------------------------------------------ public TextAnnotationEditor(ComponentFile file, string imageKey, Project project) - : base(file, null, imageKey) + : base(file, imageKey) { Logger.WriteEvent("TextAnnotationEditor constructor. file = {0}; imagekey = {1}", file, imageKey); InitializeComponent(); @@ -454,15 +455,12 @@ private void HandleResegmentButtonClick(object sender, EventArgs e) /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = LocalizationManager.GetString( - "SessionsView.Transcription.TextAnnotationEditor.TabText", "Annotations"); - } + TabText = LocalizationManager.GetString( + "SessionsView.Transcription.TextAnnotationEditor.TabText", "Annotations"); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } private void OnExportElanMenuItem_Click(object sender, EventArgs e) diff --git a/src/SayMore/Transcription/UI/ExportToFieldWorksInterlinearDlg.Designer.cs b/src/SayMore/Transcription/UI/ExportToFieldWorksInterlinearDlg.Designer.cs index 47725293..007a79db 100644 --- a/src/SayMore/Transcription/UI/ExportToFieldWorksInterlinearDlg.Designer.cs +++ b/src/SayMore/Transcription/UI/ExportToFieldWorksInterlinearDlg.Designer.cs @@ -1,4 +1,4 @@ -using L10NSharp.UI; +using L10NSharp.Windows.Forms.UIComponents; using L10NSharp.XLiffUtils; namespace SayMore.Transcription.UI @@ -17,11 +17,7 @@ partial class ExportToFieldWorksInterlinearDlg protected override void Dispose(bool disposing) { if (disposing && (components != null)) - { components.Dispose(); - - LocalizeItemDlg.StringsLocalized -= HandleStringsLocalized; - } base.Dispose(disposing); } @@ -43,7 +39,7 @@ private void InitializeComponent() this._comboTranslationWs = new System.Windows.Forms.ComboBox(); this._labelOverview = new System.Windows.Forms.Label(); this._labelImportInstructions = new System.Windows.Forms.Label(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayout.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); this.SuspendLayout(); @@ -249,7 +245,7 @@ private void InitializeComponent() private System.Windows.Forms.Label _labelFreeTranslationColumnHeadingText; private System.Windows.Forms.ComboBox _comboTranslationWs; private System.Windows.Forms.Label _labelOverview; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Label _labelImportInstructions; } } \ No newline at end of file diff --git a/src/SayMore/Transcription/UI/ExportToFieldWorksInterlinearDlg.cs b/src/SayMore/Transcription/UI/ExportToFieldWorksInterlinearDlg.cs index 11c68347..dc8ec4e7 100644 --- a/src/SayMore/Transcription/UI/ExportToFieldWorksInterlinearDlg.cs +++ b/src/SayMore/Transcription/UI/ExportToFieldWorksInterlinearDlg.cs @@ -1,6 +1,4 @@ using L10NSharp; -using L10NSharp.UI; -using L10NSharp.XLiffUtils; using SayMore.Properties; using SIL.Reporting; using SIL.WritingSystems; @@ -31,7 +29,7 @@ public class DisplayFriendlyWritingSystem #endregion - private string _intructionsFmt; + private string _instructionsFmt; public string FileName { get; private set; } public DisplayFriendlyWritingSystem TranscriptionWs { get; private set; } @@ -62,17 +60,13 @@ public ExportToFieldWorksInterlinearDlg() _comboTranslationWs.Font = Program.DialogFont; HandleStringsLocalized(); - LocalizeItemDlg.StringsLocalized += HandleStringsLocalized; } /// ------------------------------------------------------------------------------------ - protected void HandleStringsLocalized(ILocalizationManager lm = null) + protected void HandleStringsLocalized() { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - _intructionsFmt = _labelImportInstructions.Text; - FormatImportInstructions(); - } + _instructionsFmt = _labelImportInstructions.Text; + FormatImportInstructions(); } /// ------------------------------------------------------------------------------------ @@ -80,7 +74,7 @@ private void FormatImportInstructions() { if (_comboTranslationWs.SelectedIndex >= 0) { - _labelImportInstructions.Text = Format(_intructionsFmt, kFlexProgramName, + _labelImportInstructions.Text = Format(_instructionsFmt, kFlexProgramName, (DisplayFriendlyWritingSystem)_comboTranslationWs.SelectedItem); } } @@ -139,7 +133,7 @@ protected override void OnShown(EventArgs e) /// ------------------------------------------------------------------------------------ /// Select the desired writing system in the given combo. /// The writing system combo box (whose items are expected to be of - /// type . + /// type ). /// An array of BCP-47 writing system locale identifiers. If more /// than one is provided, they should be given in order of descending preference; the first /// one that corresponds to an existing writing system in the combo box will be selected. @@ -161,44 +155,41 @@ private static void InitializeWritingSystemCombo(ComboBox combo, params string[] } } - if (combo.SelectedItem == null) - combo.SelectedItem = combo.Items[0]; + combo.SelectedItem ??= combo.Items[0]; } /// ------------------------------------------------------------------------------------ private void HandleExportButtonClick(object sender, EventArgs e) { var folder = TextAnnotationEditor.GetDefaultExportFolder("LastFlexInterlinearExportDestinationFolder"); - using (var dlg = new SaveFileDialog()) + using var dlg = new SaveFileDialog(); + dlg.Title = LocalizationManager.GetString( + "DialogBoxes.Transcription.ExportToFieldWorksInterlinearDlg.ExportSaveFileDlg.Caption", + "Export to File"); + + var flexInterlinearFilesDesc = LocalizationManager.GetString( + "DialogBoxes.Transcription.ExportToFieldWorksInterlinearDlg.ExportSaveFileDlg.InterlinearFilesDesc", + "FLEx Interlinear ({0})", "Parameter is a file-matching pattern: \"*.flextext\""); + + dlg.Filter = Format("{0}|{1}|{2}|{3}", + Format(flexInterlinearFilesDesc, "*" + kFlexTextExt), + "*" + kFlexTextExt, + Format(LocalizedVersionOfAllFilesDescriptor, kAllFilesFilter), + kAllFilesFilter); + + dlg.FileName = FileName; + dlg.OverwritePrompt = true; + dlg.CheckPathExists = true; + dlg.AutoUpgradeEnabled = true; + dlg.RestoreDirectory = true; + dlg.InitialDirectory = folder ?? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + + if (dlg.ShowDialog() == DialogResult.OK) { - dlg.Title = LocalizationManager.GetString( - "DialogBoxes.Transcription.ExportToFieldWorksInterlinearDlg.ExportSaveFileDlg.Caption", - "Export to File"); - - var flexInterlinearFilesDesc = LocalizationManager.GetString( - "DialogBoxes.Transcription.ExportToFieldWorksInterlinearDlg.ExportSaveFileDlg.InterlinearFilesDesc", - "FLEx Interlinear ({0})", "Parameter is a file-matching pattern: \"*.flextext\""); - - dlg.Filter = Format("{0}|{1}|{2}|{3}", - Format(flexInterlinearFilesDesc, "*" + kFlexTextExt), - "*" + kFlexTextExt, - Format(LocalizedVersionOfAllFilesDescriptor, kAllFilesFilter), - kAllFilesFilter); - - dlg.FileName = FileName; - dlg.OverwritePrompt = true; - dlg.CheckPathExists = true; - dlg.AutoUpgradeEnabled = true; - dlg.RestoreDirectory = true; - dlg.InitialDirectory = folder ?? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - - if (dlg.ShowDialog() == DialogResult.OK) - { - FileName = dlg.FileName; - Settings.Default.LastFlexInterlinearExportDestinationFolder = Path.GetDirectoryName(FileName); - DialogResult = DialogResult.OK; - Close(); - } + FileName = dlg.FileName; + Settings.Default.LastFlexInterlinearExportDestinationFolder = Path.GetDirectoryName(FileName); + DialogResult = DialogResult.OK; + Close(); } } diff --git a/src/SayMore/Transcription/UI/OralAnnotationWaveViewer.Designer.cs b/src/SayMore/Transcription/UI/OralAnnotationWaveViewer.Designer.cs index 592dba67..6c18122e 100644 --- a/src/SayMore/Transcription/UI/OralAnnotationWaveViewer.Designer.cs +++ b/src/SayMore/Transcription/UI/OralAnnotationWaveViewer.Designer.cs @@ -22,7 +22,7 @@ private void InitializeComponent() this._labelCareful = new System.Windows.Forms.Label(); this._labelSource = new System.Windows.Forms.Label(); this._waveControl = new SayMore.Media.Audio.WaveControlBasic(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayout.SuspendLayout(); this._panelLabels.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); @@ -153,7 +153,7 @@ private void InitializeComponent() private System.Windows.Forms.Label _labelSource; private System.Windows.Forms.Label _labelTranslation; private System.Windows.Forms.Label _labelCareful; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Panel _panelLabels; } } diff --git a/src/SayMore/Transcription/UI/SegmentingAndRecording/CarefulSpeechRecorderDlg.designer.cs b/src/SayMore/Transcription/UI/SegmentingAndRecording/CarefulSpeechRecorderDlg.designer.cs index 5ab78c54..cc7d677c 100644 --- a/src/SayMore/Transcription/UI/SegmentingAndRecording/CarefulSpeechRecorderDlg.designer.cs +++ b/src/SayMore/Transcription/UI/SegmentingAndRecording/CarefulSpeechRecorderDlg.designer.cs @@ -26,7 +26,7 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._labelCarefulSpeech = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); this.SuspendLayout(); @@ -70,7 +70,7 @@ private void InitializeComponent() #endregion - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Label _labelCarefulSpeech; } } diff --git a/src/SayMore/Transcription/UI/SegmentingAndRecording/ManualSegmenterDlg.cs b/src/SayMore/Transcription/UI/SegmentingAndRecording/ManualSegmenterDlg.cs index 97932335..c73f8496 100644 --- a/src/SayMore/Transcription/UI/SegmentingAndRecording/ManualSegmenterDlg.cs +++ b/src/SayMore/Transcription/UI/SegmentingAndRecording/ManualSegmenterDlg.cs @@ -396,11 +396,10 @@ private void ResetAddSegmentButton(object sender, EventArgs e) } /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized() { - base.HandleStringsLocalized(lm); - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - UpdateDisplay(); + base.HandleStringsLocalized(); + UpdateDisplay(); } /// ------------------------------------------------------------------------------------ diff --git a/src/SayMore/Transcription/UI/SegmentingAndRecording/ManualSegmenterDlg.designer.cs b/src/SayMore/Transcription/UI/SegmentingAndRecording/ManualSegmenterDlg.designer.cs index f12af9f5..ecf561c3 100644 --- a/src/SayMore/Transcription/UI/SegmentingAndRecording/ManualSegmenterDlg.designer.cs +++ b/src/SayMore/Transcription/UI/SegmentingAndRecording/ManualSegmenterDlg.designer.cs @@ -27,7 +27,7 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this._buttonAddSegmentBoundary = new System.Windows.Forms.ToolStripButton(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this.toolStripButtons = new System.Windows.Forms.ToolStrip(); this._buttonListenToOriginal = new System.Windows.Forms.ToolStripButton(); this._buttonStopOriginal = new System.Windows.Forms.ToolStripButton(); @@ -200,7 +200,7 @@ private void InitializeComponent() #endregion private System.Windows.Forms.ToolStripButton _buttonAddSegmentBoundary; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.ToolStrip toolStripButtons; private System.Windows.Forms.ToolStripButton _buttonListenToOriginal; private System.Windows.Forms.ToolStripButton _buttonStopOriginal; diff --git a/src/SayMore/Transcription/UI/SegmentingAndRecording/OralAnnotationRecorderDlgBase.cs b/src/SayMore/Transcription/UI/SegmentingAndRecording/OralAnnotationRecorderDlgBase.cs index 7f3395ff..5f4a36fb 100644 --- a/src/SayMore/Transcription/UI/SegmentingAndRecording/OralAnnotationRecorderDlgBase.cs +++ b/src/SayMore/Transcription/UI/SegmentingAndRecording/OralAnnotationRecorderDlgBase.cs @@ -6,8 +6,6 @@ using System.Linq; using DesktopAnalytics; using L10NSharp; -using L10NSharp.XLiffUtils; -using L10NSharp.UI; using SIL.Media.Naudio.UI; using SIL.Reporting; using SIL.Windows.Forms; @@ -72,9 +70,9 @@ private enum AdvanceOptionsAfterRecording public static OralAnnotationRecorderBaseDlg Create( OralAnnotationRecorderDlgViewModel viewModel, AudioRecordingType annotationType) { - return (annotationType == AudioRecordingType.Careful ? - new CarefulSpeechRecorderDlg(viewModel) as OralAnnotationRecorderBaseDlg : - new OralTranslationRecorderDlg(viewModel)); + return annotationType == AudioRecordingType.Careful ? + new CarefulSpeechRecorderDlg(viewModel) : + new OralTranslationRecorderDlg(viewModel); } /// ------------------------------------------------------------------------------------ @@ -177,8 +175,6 @@ protected override void Dispose(bool disposing) _hotPlaySourceButton.Dispose(); _hotRecordAnnotationButton.Dispose(); _waveControl?.Dispose(); - - LocalizeItemDlg.StringsLocalized -= HandleStringsLocalized; } base.Dispose(disposing); @@ -363,8 +359,6 @@ private void InitializeHintLabelsAndButtonFonts() _videoHelpMenu.Font = _labelSourceRecording.Font; _annotationSegmentFont = FontHelper.MakeFont(Program.DialogFont, 8, FontStyle.Bold); - - LocalizeItemDlg.StringsLocalized += HandleStringsLocalized; } private const int kNumberOfRows = 4; @@ -522,11 +516,10 @@ protected override void OnFormClosed(FormClosedEventArgs e) } /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized() { - base.HandleStringsLocalized(lm); - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - UpdateDisplay(); + base.HandleStringsLocalized(); + UpdateDisplay(); } /// ------------------------------------------------------------------------------------ @@ -1285,11 +1278,9 @@ private void DrawOralAnnotationWave(PaintEventArgs e, Rectangle rc, AnnotationSe try { // Draw the oral annotation's wave in the bottom, reserved area of the wave control. - using (var painter = new WavePainterBasic { ForeColor = Color.Black, BackColor = Color.Black }) - { - painter.SetSamplesToDraw(ViewModel.GetSegmentSamples(segment, (uint)rc.Width)); - painter.Draw(e, rc); - } + using var painter = new WavePainterBasic { ForeColor = Color.Black, BackColor = Color.Black }; + painter.SetSamplesToDraw(ViewModel.GetSegmentSamples(segment, (uint)rc.Width)); + painter.Draw(e, rc); } catch (IOException) { @@ -1304,10 +1295,8 @@ private void DrawCursorInOralAnnotationWave(PaintEventArgs e, Rectangle rc) if (x > 0 && x >= rc.X && x <= rc.Right) { rc.Inflate(0, 3); - using (var pen = new Pen(_waveControl.Painter.CursorColor)) - { - e.Graphics.DrawLine(pen, x, rc.Y, x, rc.Bottom); - } + using var pen = new Pen(_waveControl.Painter.CursorColor); + e.Graphics.DrawLine(pen, x, rc.Y, x, rc.Bottom); } } @@ -1360,8 +1349,8 @@ protected override void HandleWaveControlPostPaint(PaintEventArgs e) var rc = GetReadyToRecordCursorRectangle(); if (rc != Rectangle.Empty) { - using (var brush = new SolidBrush(_labelRecordButton.ForeColor)) - e.Graphics.FillRectangle(brush, rc); + using var brush = new SolidBrush(_labelRecordButton.ForeColor); + e.Graphics.FillRectangle(brush, rc); } } @@ -1396,16 +1385,14 @@ private void DrawHighlightedBorderForRecording(Graphics g, Rectangle rc) if (_labelRecordButton.ClientRectangle.Contains(_labelRecordButton.PointToClient(MousePosition)) || ViewModel.GetIsRecording()) { - using (var pen = new Pen(_labelRecordButton.ForeColor)) - { - var rcHighlight = rc; - rcHighlight.Y--; - rcHighlight.Width--; - rcHighlight.Inflate(-1, -1); - g.DrawRectangle(pen, rcHighlight); - rcHighlight.Inflate(-1, -1); - g.DrawRectangle(pen, rcHighlight); - } + using var pen = new Pen(_labelRecordButton.ForeColor); + var rcHighlight = rc; + rcHighlight.Y--; + rcHighlight.Width--; + rcHighlight.Inflate(-1, -1); + g.DrawRectangle(pen, rcHighlight); + rcHighlight.Inflate(-1, -1); + g.DrawRectangle(pen, rcHighlight); } } @@ -1517,11 +1504,9 @@ private void HandleMediaButtonTableLayoutPaint(object sender, PaintEventArgs e) { var rc = _tableLayoutMediaButtons.ClientRectangle; - using (var pen = new Pen(Settings.Default.BarColorBorder)) - { - e.Graphics.DrawLine(pen, rc.X, rc.Y, rc.X, rc.Bottom); - e.Graphics.DrawLine(pen, rc.Right - 1, rc.Y, rc.Right - 1, rc.Bottom); - } + using var pen = new Pen(Settings.Default.BarColorBorder); + e.Graphics.DrawLine(pen, rc.X, rc.Y, rc.X, rc.Bottom); + e.Graphics.DrawLine(pen, rc.Right - 1, rc.Y, rc.Right - 1, rc.Bottom); } #endregion diff --git a/src/SayMore/Transcription/UI/SegmentingAndRecording/OralAnnotationRecorderDlgBase.designer.cs b/src/SayMore/Transcription/UI/SegmentingAndRecording/OralAnnotationRecorderDlgBase.designer.cs index 3c8d3933..78f99fde 100644 --- a/src/SayMore/Transcription/UI/SegmentingAndRecording/OralAnnotationRecorderDlgBase.designer.cs +++ b/src/SayMore/Transcription/UI/SegmentingAndRecording/OralAnnotationRecorderDlgBase.designer.cs @@ -18,7 +18,7 @@ private void InitializeComponent() this.components = new System.ComponentModel.Container(); this._panelListen = new System.Windows.Forms.Panel(); this._labelListenButton = new System.Windows.Forms.Label(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._labelRecordButton = new System.Windows.Forms.Label(); this._pictureRecording = new System.Windows.Forms.PictureBox(); this._labelErrorInfo = new System.Windows.Forms.Label(); @@ -355,7 +355,7 @@ private void InitializeComponent() #endregion - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Timer _scrollTimer; private System.Windows.Forms.Timer _cursorBlinkTimer; protected System.Windows.Forms.TableLayoutPanel _tableLayoutRecordAnnotations; diff --git a/src/SayMore/Transcription/UI/SegmentingAndRecording/OralTranslationRecorderDlg.designer.cs b/src/SayMore/Transcription/UI/SegmentingAndRecording/OralTranslationRecorderDlg.designer.cs index c6a4a36d..8a2caa5d 100644 --- a/src/SayMore/Transcription/UI/SegmentingAndRecording/OralTranslationRecorderDlg.designer.cs +++ b/src/SayMore/Transcription/UI/SegmentingAndRecording/OralTranslationRecorderDlg.designer.cs @@ -26,7 +26,7 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._labelOralTranslation = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); this.SuspendLayout(); @@ -70,7 +70,7 @@ private void InitializeComponent() #endregion - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Label _labelOralTranslation; } } diff --git a/src/SayMore/Transcription/UI/SegmentingAndRecording/SegmenterDlgBase.cs b/src/SayMore/Transcription/UI/SegmentingAndRecording/SegmenterDlgBase.cs index 6b7f8a7e..72d7192c 100644 --- a/src/SayMore/Transcription/UI/SegmentingAndRecording/SegmenterDlgBase.cs +++ b/src/SayMore/Transcription/UI/SegmentingAndRecording/SegmenterDlgBase.cs @@ -7,19 +7,18 @@ using System.Linq; using System.Windows.Forms; using L10NSharp; -using L10NSharp.XLiffUtils; -using L10NSharp.UI; +using L10NSharp.Windows.Forms; using NAudio.Wave; -using SIL.Windows.Forms; -using SIL.Windows.Forms.Miscellaneous; -using SIL.Windows.Forms.PortableSettingsProvider; using SayMore.Media.Audio; +using SayMore.Media.MPlayer; using SayMore.Properties; using SayMore.Transcription.Model; using SayMore.UI.LowLevelControls; -using SayMore.Media.MPlayer; using SayMore.Utilities; +using SIL.Windows.Forms; using SIL.Windows.Forms.Extensions; +using SIL.Windows.Forms.Miscellaneous; +using SIL.Windows.Forms.PortableSettingsProvider; using Timer = System.Windows.Forms.Timer; namespace SayMore.Transcription.UI @@ -81,8 +80,6 @@ public SegmenterDlgBase() _segmentXofYFormat = _labelSegmentXofY.Text; _segmentNumberFormat = _labelSegmentNumber.Text; - - LocalizeItemDlg.StringsLocalized += HandleStringsLocalized; } /// ------------------------------------------------------------------------------------ @@ -157,7 +154,7 @@ protected override void OnLoad(EventArgs e) _undoToolStripMenuItem.Height *= 2; _ignoreToolStripMenuItem.Height = _undoToolStripMenuItem.Height; - HandleStringsLocalized(null); + HandleStringsLocalized(); } /// ------------------------------------------------------------------------------------ @@ -186,10 +183,7 @@ protected override void Dispose(bool disposing) { if (disposing) { - LocalizeItemDlg.StringsLocalized -= HandleStringsLocalized; - - if (components != null) - components.Dispose(); + components?.Dispose(); if (_waveControl != null) { @@ -213,14 +207,11 @@ protected virtual WaveControlWithMovableBoundaries CreateWaveControl() } /// ------------------------------------------------------------------------------------ - protected virtual void HandleStringsLocalized(ILocalizationManager lm) + protected virtual void HandleStringsLocalized() { - if (lm != null && lm.Id != ApplicationContainer.kSayMoreLocalizationId) - return; - _segmentXofYFormat = _labelSegmentXofY.Text; _segmentNumberFormat = _labelSegmentNumber.Text; - var zoomToolTip = LocalizationManager.GetLocalizedToolTipForControl(_comboBoxZoom); + var zoomToolTip = LocalizationManagerWinforms.GetLocalizedToolTipForControl(_comboBoxZoom); if (!string.IsNullOrEmpty(zoomToolTip)) _tooltip.SetToolTip(_labelZoom, zoomToolTip); } diff --git a/src/SayMore/Transcription/UI/SegmentingAndRecording/SegmenterDlgBase.designer.cs b/src/SayMore/Transcription/UI/SegmentingAndRecording/SegmenterDlgBase.designer.cs index cfa4c793..a1f4949e 100644 --- a/src/SayMore/Transcription/UI/SegmentingAndRecording/SegmenterDlgBase.designer.cs +++ b/src/SayMore/Transcription/UI/SegmentingAndRecording/SegmenterDlgBase.designer.cs @@ -36,7 +36,7 @@ private void InitializeComponent() this._labelSourceRecording = new System.Windows.Forms.Label(); this._buttonOK = new System.Windows.Forms.Button(); this._buttonCancel = new System.Windows.Forms.Button(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayoutButtons = new System.Windows.Forms.TableLayoutPanel(); this._tooltip = new System.Windows.Forms.ToolTip(this.components); this._panelWaveControl.SuspendLayout(); @@ -417,7 +417,7 @@ private void InitializeComponent() #endregion protected System.Windows.Forms.Button _buttonOK; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; protected System.Windows.Forms.TableLayoutPanel _tableLayoutOuter; protected Panel _panelWaveControl; protected System.Windows.Forms.Label _labelSourceRecording; diff --git a/src/SayMore/UI/Charts/ChartBarInfo.cs b/src/SayMore/UI/Charts/ChartBarInfo.cs index 196820c6..7cc957df 100644 --- a/src/SayMore/UI/Charts/ChartBarInfo.cs +++ b/src/SayMore/UI/Charts/ChartBarInfo.cs @@ -130,7 +130,7 @@ public ChartBarSegmentInfo(string fieldName, string fieldValue, } catch (InvalidOperationException) { - // SP-854: This can happen if the the list is still loading, "Collection was modified; enumeration operation may not execute." + // SP-854: This can happen if the list is still loading, "Collection was modified; enumeration operation may not execute." // Let the other thread continue and try again. Application.DoEvents(); Thread.Sleep(0); diff --git a/src/SayMore/UI/Charts/HTMLChartBuilder.cs b/src/SayMore/UI/Charts/HTMLChartBuilder.cs index 273a0f44..f24ce6c4 100644 --- a/src/SayMore/UI/Charts/HTMLChartBuilder.cs +++ b/src/SayMore/UI/Charts/HTMLChartBuilder.cs @@ -18,7 +18,7 @@ public class HTMLChartBuilder public const string kNonBreakingSpace = " "; private readonly StatisticsViewModel _statsViewModel; - protected readonly StringBuilder _htmlText = new StringBuilder(6000); + protected readonly StringBuilder _htmlText = new(6000); /// ------------------------------------------------------------------------------------ public HTMLChartBuilder(StatisticsViewModel statsViewModel) @@ -61,7 +61,7 @@ public string GetStatisticsCharts() WriteStageChart(); var backColors = GetStatusSegmentColors(); - var textColors = backColors.ToDictionary(kvp => kvp.Key, kvp => Color.Empty); + var textColors = backColors.ToDictionary(kvp => kvp.Key, _ => Color.Empty); text = LocalizationManager.GetString("ProgressView.ByGenreHeadingText", "By Genre"); WriteChartByFieldPair(text, SessionFileType.kGenreFieldName, SessionFileType.kStatusFieldName, backColors, textColors); @@ -91,8 +91,8 @@ private void WriteStageChart() var sessionsByStage = _statsViewModel.SessionInformant.GetSessionsCategorizedByStage() .Where(r => r.Key.Id != ComponentRole.kConsentComponentRoleId); - var barInfoList = (sessionsByStage.Select( - x => new ChartBarInfo(x.Key.Name, x.Value, x.Key.Color, x.Key.TextColor))).ToList(); + var barInfoList = sessionsByStage.Select( + x => new ChartBarInfo(x.Key.Name, x.Value, x.Key.Color, x.Key.TextColor)).ToList(); ChartBarInfo.CalculateBarSizes(barInfoList); var text = LocalizationManager.GetString("ProgressView.ByStagesHeadingText", "Completed Stages"); @@ -104,7 +104,7 @@ private IDictionary GetStatusSegmentColors() { var statusColors = new Dictionary(); - foreach (var statusName in Enum.GetNames(typeof(Session.Status)).Where(x => x != Session.Status.Skipped.ToString())) + foreach (var statusName in Enum.GetNames(typeof(Session.Status)).Where(x => x != nameof(Session.Status.Skipped))) { statusColors[Session.GetLocalizedStatus(statusName)] = (Color)Properties.Settings.Default[statusName + "StatusColor"]; @@ -135,9 +135,10 @@ private void WriteOverviewSection() foreach (var stats in _statsViewModel.GetComponentRoleStatisticsPairs()) { OpenTableRow(); - WriteTableRowHead(string.Format("{0}:", stats.Name)); - WriteTableCell(stats.Length); - WriteTableCell(stats.Size); + WriteTableRowHead($"{stats.Name}:"); + WriteTableCell(stats.Length.ToString()); + var size = stats.Size == 0 ? "---" : ComponentFile.GetDisplayableFileSize(stats.Size, false); + WriteTableCell(size); CloseTableRow(); } diff --git a/src/SayMore/UI/ComponentEditors/AudioComponentEditor.cs b/src/SayMore/UI/ComponentEditors/AudioComponentEditor.cs index ad7d0f13..475598b1 100644 --- a/src/SayMore/UI/ComponentEditors/AudioComponentEditor.cs +++ b/src/SayMore/UI/ComponentEditors/AudioComponentEditor.cs @@ -1,3 +1,4 @@ +using System; using L10NSharp; using SayMore.Model.Files; using SayMore.Model.Files.DataGathering; @@ -12,7 +13,7 @@ public partial class AudioComponentEditor : MediaComponentEditor /// ------------------------------------------------------------------------------------ public AudioComponentEditor(ComponentFile file, string imageKey, AutoCompleteValueGatherer autoCompleteProvider, FieldGatherer fieldGatherer) - : base(file, null, imageKey, autoCompleteProvider, fieldGatherer) + : base(file, imageKey, autoCompleteProvider, fieldGatherer) { Name = "Audio File Information"; } @@ -22,11 +23,12 @@ public AudioComponentEditor(ComponentFile file, string imageKey, /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { + var lm = (ILocalizationManager)sender; if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) TabText = GetPropertiesTabText(); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } } } diff --git a/src/SayMore/UI/ComponentEditors/AudioVideoPlayer.cs b/src/SayMore/UI/ComponentEditors/AudioVideoPlayer.cs index 6a239060..f997fcfb 100644 --- a/src/SayMore/UI/ComponentEditors/AudioVideoPlayer.cs +++ b/src/SayMore/UI/ComponentEditors/AudioVideoPlayer.cs @@ -18,7 +18,8 @@ public partial class AudioVideoPlayer : EditorBase private readonly MediaPlayer _mediaPlayer; /// ------------------------------------------------------------------------------------ - public AudioVideoPlayer(ComponentFile file, string imageKey) : base(file, null, imageKey) + public AudioVideoPlayer(ComponentFile file, string imageKey) : + base(file, imageKey) { Logger.WriteEvent("AudioVideoPlayer constructor. file = {0}; imageKey = {1}", file, imageKey); InitializeComponent(); @@ -38,7 +39,7 @@ private void FinishInitializing(ComponentFile file) SetComponentFile(file); // SP-831: tab is being localized before the file has been set in the base class - HandleStringsLocalized(null); + HandleStringsLocalized(null, EventArgs.Empty); } /// ------------------------------------------------------------------------------------ @@ -64,22 +65,19 @@ protected override void Dispose(bool disposing) /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { // SP-831: tab is being localized before the file has been set in the base class if (_file == null) return; - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = _file.FileType.IsVideo ? - LocalizationManager.GetString( - "CommonToMultipleViews.MediaPlayer.TabText-Video", "Video") : - LocalizationManager.GetString( - "CommonToMultipleViews.MediaPlayer.TabText-Audio", "Audio"); - } + TabText = _file.FileType.IsVideo ? + LocalizationManager.GetString( + "CommonToMultipleViews.MediaPlayer.TabText-Video", "Video") : + LocalizationManager.GetString( + "CommonToMultipleViews.MediaPlayer.TabText-Audio", "Audio"); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } /// ------------------------------------------------------------------------------------ @@ -120,7 +118,7 @@ private void LoadAnnotationFile(ComponentFile file) Invoke((Action)(() => ErrorReport.NotifyUserOfProblem(e.Message))); else ErrorReport.NotifyUserOfProblem(e.Message); - }; + } } } @@ -137,12 +135,6 @@ public override void Deactivated() _mediaPlayerViewModel.ShutdownMPlayerProcess(); } - ///// ------------------------------------------------------------------------------------ - //private static void HandleMediaError(object sender, _WMPOCXEvents_MediaErrorEvent e) - //{ - // SIL.Reporting.ErrorReport.NotifyUserOfProblem("Media error: " + e.pMediaObject); - //} - /// ------------------------------------------------------------------------------------ protected override void OnParentChanged(EventArgs e) { diff --git a/src/SayMore/UI/ComponentEditors/BasicFieldGridEditor.cs b/src/SayMore/UI/ComponentEditors/BasicFieldGridEditor.cs index 0ef2b3ed..34e365c8 100644 --- a/src/SayMore/UI/ComponentEditors/BasicFieldGridEditor.cs +++ b/src/SayMore/UI/ComponentEditors/BasicFieldGridEditor.cs @@ -1,3 +1,4 @@ +using System; using System.Windows.Forms; using L10NSharp; using SayMore.Model.Files; @@ -16,7 +17,7 @@ public partial class BasicFieldGridEditor : EditorBase /// ------------------------------------------------------------------------------------ public BasicFieldGridEditor(ComponentFile file, string imageKey, AutoCompleteValueGatherer autoCompleteProvider, FieldGatherer fieldGatherer) - : base(file, null, imageKey) + : base(file, imageKey) { InitializeComponent(); Name = "BasicFieldGridEditor"; @@ -49,12 +50,11 @@ public override void SetComponentFile(ComponentFile file) /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - TabText = GetPropertiesTabText(); + TabText = GetPropertiesTabText(); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } } } diff --git a/src/SayMore/UI/ComponentEditors/BrowserEditor.cs b/src/SayMore/UI/ComponentEditors/BrowserEditor.cs index 13b7374a..41f56d16 100644 --- a/src/SayMore/UI/ComponentEditors/BrowserEditor.cs +++ b/src/SayMore/UI/ComponentEditors/BrowserEditor.cs @@ -17,7 +17,7 @@ public partial class BrowserEditor : EditorBase private HtmlElement _fileLink; /// ------------------------------------------------------------------------------------ - public BrowserEditor(ComponentFile file, string imageKey) : base(file, null, imageKey) + public BrowserEditor(ComponentFile file, string imageKey) : base(file, imageKey) { InitializeComponent(); Name = "Browser"; @@ -193,17 +193,14 @@ void HandleFileLinkClick(object sender, HtmlElementEventArgs e) /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = LocalizationManager.GetString( - "CommonToMultipleViews.GenericFileTypeViewer.TabText", "View"); - if (_browser?.Tag is string filePath) - DisplayFile(filePath); - } + TabText = LocalizationManager.GetString( + "CommonToMultipleViews.GenericFileTypeViewer.TabText", "View"); + if (_browser?.Tag is string filePath) + DisplayFile(filePath); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } } } diff --git a/src/SayMore/UI/ComponentEditors/ContributorsEditor.cs b/src/SayMore/UI/ComponentEditors/ContributorsEditor.cs index e0b71241..30870e56 100644 --- a/src/SayMore/UI/ComponentEditors/ContributorsEditor.cs +++ b/src/SayMore/UI/ComponentEditors/ContributorsEditor.cs @@ -6,7 +6,7 @@ using System.Text; using System.Windows.Forms; using L10NSharp; -using L10NSharp.UI; +using L10NSharp.Windows.Forms; using SIL.Windows.Forms.ClearShare; using SIL.Windows.Forms.ClearShare.WinFormsUI; using SayMore.Model; @@ -33,7 +33,7 @@ public partial class ContributorsEditor : EditorBase /// ------------------------------------------------------------------------------------ public ContributorsEditor(ComponentFile file, string imageKey, AutoCompleteValueGatherer autoCompleteProvider, PersonInformant personInformant) : - base(file, null, imageKey) + base(file, imageKey) { InitializeComponent(); Name = "Contributors"; @@ -154,12 +154,12 @@ private void InitializeGrid(Func> getPeopleNames) // set the localizable column header text string[] headerText = - { + [ @"_L10N_:SessionsView.ContributorsEditor.NameColumnTitle!Name", @"_L10N_:SessionsView.ContributorsEditor.RoleColumnTitle!Role", @"_L10N_:SessionsView.ContributorsEditor.DateColumnTitle!Date", @"_L10N_:SessionsView.ContributorsEditor.CommentColumnTitle!Comments" - }; + ]; for (var i = 0; i < headerText.Length; i++) { @@ -416,15 +416,12 @@ private string GetParticipants(bool withRoles) /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = LocalizationManager.GetString( - "CommonToMultipleViews.ContributorsEditor.TabText", "Contributors"); - } + TabText = LocalizationManager.GetString( + "CommonToMultipleViews.ContributorsEditor.TabText", "Contributors"); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } } } diff --git a/src/SayMore/UI/ComponentEditors/EditorBase.cs b/src/SayMore/UI/ComponentEditors/EditorBase.cs index 9ca1f310..53a95699 100644 --- a/src/SayMore/UI/ComponentEditors/EditorBase.cs +++ b/src/SayMore/UI/ComponentEditors/EditorBase.cs @@ -6,8 +6,6 @@ using System.Threading; using System.Windows.Forms; using L10NSharp; -using L10NSharp.XLiffUtils; -using L10NSharp.UI; using SIL.Windows.Forms; using SayMore.Model.Files; using SayMore.Utilities; @@ -20,7 +18,6 @@ public interface IEditorProvider Control Control { get; } string TabText { get; } string ImageKey { get; } - void Initialize(string tabText, string imageKey); void SetComponentFile(ComponentFile file); bool ComponentFileDeletionInitiated(ComponentFile file); Action ComponentFileListRefreshAction { set; } @@ -37,6 +34,7 @@ public interface IEditorProvider // Should be abstract, but that messes up the Designer public class EditorBase : UserControl, IEditorProvider { + private readonly ILocalizationManager _localizationManager; private bool _setWorkingFontWhenHandleIsCreated = false; private BindingHelper _binder; protected ComponentFile _file; @@ -48,8 +46,9 @@ public class EditorBase : UserControl, IEditorProvider public Action ComponentFileListRefreshAction { protected get; set; } /// ------------------------------------------------------------------------------------ - public EditorBase() + protected EditorBase() { + _localizationManager = ApplicationContainer.SayMoreLocalizationManager; DoubleBuffered = true; BackColor = AppColors.DataEntryPanelBegin; Padding = new Padding(7); @@ -60,23 +59,21 @@ public EditorBase() ControlRemoved += HandleControlRemoved; Layout += HandleLayout; - LocalizeItemDlg.StringsLocalized += HandleStringsLocalized; - HandleStringsLocalized(null); + _localizationManager?.UiLanguageChanged += HandleStringsLocalized; } /// ------------------------------------------------------------------------------------ - public EditorBase(ComponentFile file, string tabText, string imageKey) : this() + public EditorBase(ComponentFile file, string imageKey) : this() { _file = file; - Initialize(tabText, imageKey); + ImageKey = imageKey; } /// ------------------------------------------------------------------------------------ protected override void Dispose(bool disposing) { - if (disposing) - LocalizeItemDlg.StringsLocalized -= HandleStringsLocalized; - + if (disposing && _localizationManager != null) + _localizationManager.UiLanguageChanged -= HandleStringsLocalized; try { base.Dispose(disposing); @@ -91,13 +88,6 @@ protected override void Dispose(bool disposing) } } - /// ------------------------------------------------------------------------------------ - public void Initialize(string tabText, string imageKey) - { - TabText = tabText ?? TabText; - ImageKey = imageKey; - } - /// ------------------------------------------------------------------------------------ public void RefreshComponentFiles(string fileToSelectAfterRefresh, Type componentEditorTypeToSelect) @@ -181,6 +171,7 @@ protected set protected override void OnLoad(EventArgs e) { SetLabelFonts(this, FontHelper.MakeFont(Program.DialogFont, FontStyle.Bold)); + HandleStringsLocalized(null, EventArgs.Empty); base.OnLoad(e); } @@ -190,8 +181,7 @@ protected override void OnHandleCreated(EventArgs e) base.OnHandleCreated(e); var owningTabControl = FindParent(this); - if (owningTabControl != null) - owningTabControl.VisibleChanged += (sender, args) => OnParentTabControlVisibleChanged(); + owningTabControl?.VisibleChanged += (sender, args) => OnParentTabControlVisibleChanged(); if (_setWorkingFontWhenHandleIsCreated) SetWorkingLanguageFont(); @@ -208,7 +198,7 @@ public static T FindParent(Control control) where T : Control } /// ------------------------------------------------------------------------------------ - protected virtual void HandleStringsLocalized(ILocalizationManager lm) + protected virtual void HandleStringsLocalized(object sender, EventArgs e) { } diff --git a/src/SayMore/UI/ComponentEditors/FieldsValuesGrid.cs b/src/SayMore/UI/ComponentEditors/FieldsValuesGrid.cs index 1ee4a928..c4d87966 100644 --- a/src/SayMore/UI/ComponentEditors/FieldsValuesGrid.cs +++ b/src/SayMore/UI/ComponentEditors/FieldsValuesGrid.cs @@ -3,7 +3,7 @@ using System.Media; using System.Windows.Forms; using L10NSharp; -using L10NSharp.UI; +using L10NSharp.Windows.Forms; using SIL.Windows.Forms.Widgets.BetterGrid; using SayMore.Properties; using SayMore.UI.LowLevelControls; @@ -390,8 +390,8 @@ private static bool AskUserToVerifyRemovingFieldEverywhere(string id) var msg = LocalizationManager.GetString("CommonToMultipleViews.FieldsAndValuesGrid.VerifyDeleteFieldQuestion", "Do you want to delete the field '{0}' and its contents from the entire project?"); - using (var dlg = new DeleteMessageBox(string.Format(msg, id))) - return (dlg.ShowDialog() == DialogResult.OK); + using var dlg = new DeleteMessageBox(string.Format(msg, id)); + return dlg.ShowDialog() == DialogResult.OK; } } } diff --git a/src/SayMore/UI/ComponentEditors/ImageViewer.Designer.cs b/src/SayMore/UI/ComponentEditors/ImageViewer.Designer.cs index 2590d28f..824e750d 100644 --- a/src/SayMore/UI/ComponentEditors/ImageViewer.Designer.cs +++ b/src/SayMore/UI/ComponentEditors/ImageViewer.Designer.cs @@ -30,7 +30,7 @@ private void InitializeComponent() this._zoomTrackBar = new System.Windows.Forms.TrackBar(); this._tableLayoutZoom = new System.Windows.Forms.TableLayoutPanel(); this._labelZoom = new System.Windows.Forms.Label(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); ((System.ComponentModel.ISupportInitialize)(this._zoomTrackBar)).BeginInit(); this._tableLayoutZoom.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); @@ -117,6 +117,6 @@ private void InitializeComponent() private System.Windows.Forms.TrackBar _zoomTrackBar; private System.Windows.Forms.TableLayoutPanel _tableLayoutZoom; private System.Windows.Forms.Label _labelZoom; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; } } diff --git a/src/SayMore/UI/ComponentEditors/ImageViewer.cs b/src/SayMore/UI/ComponentEditors/ImageViewer.cs index 1d9d14aa..c8ee18d8 100644 --- a/src/SayMore/UI/ComponentEditors/ImageViewer.cs +++ b/src/SayMore/UI/ComponentEditors/ImageViewer.cs @@ -17,7 +17,8 @@ public partial class ImageViewer : EditorBase private ImageViewerViewModel _model; /// ------------------------------------------------------------------------------------ - public ImageViewer(ComponentFile file) : base(file, null, "Image") + public ImageViewer(ComponentFile file) : + base(file, "Image") { Logger.WriteEvent("ImageViewer constructor. file = {0}", file); InitializeComponent(); @@ -140,15 +141,12 @@ private void HandleZoomTrackBarValueChanged(object sender, EventArgs e) /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = LocalizationManager.GetString( - "CommonToMultipleViews.ImageViewer.TabText", "Image"); - } + TabText = LocalizationManager.GetString( + "CommonToMultipleViews.ImageViewer.TabText", "Image"); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } } } diff --git a/src/SayMore/UI/ComponentEditors/MediaComponentEditor.Designer.cs b/src/SayMore/UI/ComponentEditors/MediaComponentEditor.Designer.cs index 154cfce1..9425d2cc 100644 --- a/src/SayMore/UI/ComponentEditors/MediaComponentEditor.Designer.cs +++ b/src/SayMore/UI/ComponentEditors/MediaComponentEditor.Designer.cs @@ -34,7 +34,7 @@ private void InitializeComponent() this._buttonPresets = new System.Windows.Forms.ToolStripDropDownButton(); this._buttonMoreInfo = new System.Windows.Forms.ToolStripButton(); this._presetMenu = new System.Windows.Forms.ContextMenuStrip(this.components); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayout.SuspendLayout(); this._toolStrip.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); @@ -135,7 +135,7 @@ private void InitializeComponent() #endregion private System.Windows.Forms.TableLayoutPanel _tableLayout; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; protected System.Windows.Forms.ContextMenuStrip _presetMenu; private System.Windows.Forms.ToolStrip _toolStrip; private System.Windows.Forms.ToolStripButton _buttonMoreInfo; diff --git a/src/SayMore/UI/ComponentEditors/MediaComponentEditor.cs b/src/SayMore/UI/ComponentEditors/MediaComponentEditor.cs index 412d497e..03aa4702 100644 --- a/src/SayMore/UI/ComponentEditors/MediaComponentEditor.cs +++ b/src/SayMore/UI/ComponentEditors/MediaComponentEditor.cs @@ -26,9 +26,9 @@ public MediaComponentEditor() } /// ------------------------------------------------------------------------------------ - public MediaComponentEditor(ComponentFile file, string tabText, string imageKey, + public MediaComponentEditor(ComponentFile file, string imageKey, AutoCompleteValueGatherer autoCompleteProvider, FieldGatherer fieldGatherer) - : base(file, tabText, imageKey) + : base(file, imageKey) { InitializeComponent(); InitializeGrid(autoCompleteProvider, fieldGatherer); diff --git a/src/SayMore/UI/ComponentEditors/MediaFileMoreInfoDlg.Designer.cs b/src/SayMore/UI/ComponentEditors/MediaFileMoreInfoDlg.Designer.cs index 74f7fb6b..8b98e5ce 100644 --- a/src/SayMore/UI/ComponentEditors/MediaFileMoreInfoDlg.Designer.cs +++ b/src/SayMore/UI/ComponentEditors/MediaFileMoreInfoDlg.Designer.cs @@ -14,9 +14,7 @@ partial class MediaFileMoreInfoDlg protected override void Dispose(bool disposing) { if (disposing && (components != null)) - { components.Dispose(); - } base.Dispose(disposing); } @@ -36,7 +34,7 @@ private void InitializeComponent() this._flowLayoutButtons = new System.Windows.Forms.FlowLayoutPanel(); this._buttonEvenMoreInfo = new System.Windows.Forms.Button(); this._buttonLessInfo = new System.Windows.Forms.Button(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._lblSource = new System.Windows.Forms.Label(); this.tableLayoutPanel1.SuspendLayout(); this._panelBrowser.SuspendLayout(); @@ -225,7 +223,7 @@ private void InitializeComponent() private System.Windows.Forms.WebBrowser _webBrowserInfo; private SIL.Windows.Forms.Widgets.EnhancedPanel _panelBrowser; private System.Windows.Forms.Button _buttonLessInfo; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Label _lblSource; } } \ No newline at end of file diff --git a/src/SayMore/UI/ComponentEditors/MediaFileMoreInfoDlg.cs b/src/SayMore/UI/ComponentEditors/MediaFileMoreInfoDlg.cs index 731d4f15..0b43f5d3 100644 --- a/src/SayMore/UI/ComponentEditors/MediaFileMoreInfoDlg.cs +++ b/src/SayMore/UI/ComponentEditors/MediaFileMoreInfoDlg.cs @@ -6,8 +6,6 @@ using System.Xml; using System.Xml.Xsl; using L10NSharp; -using L10NSharp.UI; -using L10NSharp.XLiffUtils; using SIL.Reporting; using SIL.Windows.Forms.PortableSettingsProvider; using SayMore.Media; @@ -21,7 +19,7 @@ public partial class MediaFileMoreInfoDlg : Form { private readonly string _mediaFilePath; private string _source; - private static bool alreadyDisplayedEvenMoreInfoDisclaimer = false; + private static bool s_alreadyDisplayedEvenMoreInfoDisclaimer = false; /// ------------------------------------------------------------------------------------ public MediaFileMoreInfoDlg() @@ -29,7 +27,6 @@ public MediaFileMoreInfoDlg() InitializeComponent(); _buttonClose.Click += delegate { Close(); }; - LocalizeItemDlg.StringsLocalized += HandleStringsLocalized; HandleStringsLocalized(); } @@ -49,13 +46,10 @@ public MediaFileMoreInfoDlg(string mediaFileInfo) : this() /// ------------------------------------------------------------------------------------ - protected void HandleStringsLocalized(ILocalizationManager lm = null) + protected void HandleStringsLocalized() { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - _lblSource.Tag = _lblSource.Text; - UpdateSourceLabelDisplay(); - } + _lblSource.Tag = _lblSource.Text; + UpdateSourceLabelDisplay(); } /// ------------------------------------------------------------------------------------ @@ -105,8 +99,9 @@ private bool LoadBrowserControl() return false; _webBrowserInfo.DocumentStream = TransformInfoOutput(html); - _webBrowserInfo.Document.Encoding = "utf-8"; - return true; + if (_webBrowserInfo.Document != null) + _webBrowserInfo.Document.Encoding = "utf-8"; + return true; } /// ------------------------------------------------------------------------------------ @@ -158,13 +153,11 @@ public MemoryStream TransformInfoOutput(string htmlInput) var inputReader = XmlReader.Create(inputStream); var outputWriter = XmlWriter.Create(outputStream); - using (var xsltReader = new XmlTextReader(xsltStream)) - { - var xslt = new XslCompiledTransform(true); - xslt.Load(xsltReader); - xslt.Transform(inputReader, outputWriter); - xsltReader.Close(); - } + using var xsltReader = new XmlTextReader(xsltStream); + var xslt = new XslCompiledTransform(true); + xslt.Load(xsltReader); + xslt.Transform(inputReader, outputWriter); + xsltReader.Close(); } catch { @@ -183,8 +176,7 @@ public MemoryStream TransformInfoOutput(string htmlInput) var transformedHtml = reader.ReadToEnd(); outputStream.Close(); - var styleInfo = Format("\r\n", - Resources.MoreMediaInfoStyles); + var styleInfo = $"\r"; transformedHtml = transformedHtml.Replace("", HTMLChartBuilder.XMLDocTypeInfo); transformedHtml = transformedHtml.Replace("", styleInfo + ""); @@ -199,7 +191,7 @@ private void HandleEvenMoreInfoButtonClick(object sender, EventArgs e) _buttonLessInfo.Visible = true; var origSource = _source; if (LoadBrowserControl() && origSource != _source && - !alreadyDisplayedEvenMoreInfoDisclaimer) + !s_alreadyDisplayedEvenMoreInfoDisclaimer) { // Note: I'm hard-coding the utility program names in the localizer comment // because as things currently stand, that's definitely what they will be. @@ -212,7 +204,7 @@ private void HandleEvenMoreInfoButtonClick(object sender, EventArgs e) "Parameters are utility program names. Param 0: \"MediaInfo.DLL\";" + " Param 1: \"FFprobe\""), _source, origSource); MessageBox.Show(this, msg, ProductName, MessageBoxButtons.OK); - alreadyDisplayedEvenMoreInfoDisclaimer = true; + s_alreadyDisplayedEvenMoreInfoDisclaimer = true; } } diff --git a/src/SayMore/UI/ComponentEditors/MissingMediaFileEditor.cs b/src/SayMore/UI/ComponentEditors/MissingMediaFileEditor.cs index 7c717724..86897cf3 100644 --- a/src/SayMore/UI/ComponentEditors/MissingMediaFileEditor.cs +++ b/src/SayMore/UI/ComponentEditors/MissingMediaFileEditor.cs @@ -1,3 +1,4 @@ +using System; using System.Windows.Forms; using L10NSharp; using SIL.Reporting; @@ -11,12 +12,12 @@ public partial class MissingMediaFileEditor : EditorBase { /// ------------------------------------------------------------------------------------ public MissingMediaFileEditor(ComponentFile file, string imageKey) - : base(file, null, imageKey) + : base(file, imageKey) { Logger.WriteEvent("MissingMediaFileEditor constructor. file = {0}", file); InitializeComponent(); SetComponentFile(file); - HandleStringsLocalized(null); + HandleStringsLocalized(null, EventArgs.Empty); } /// ------------------------------------------------------------------------------------ @@ -28,14 +29,14 @@ public override void SetComponentFile(ComponentFile file) } /// ------------------------------------------------------------------------------------ - protected override void OnVisibleChanged(System.EventArgs e) + protected override void OnVisibleChanged(EventArgs e) { base.OnVisibleChanged(e); ReselectFilePathAndScrollIntoViewAsMuchAsPossible(); } /// ------------------------------------------------------------------------------------ - protected override void OnSizeChanged(System.EventArgs e) + protected override void OnSizeChanged(EventArgs e) { base.OnSizeChanged(e); ReselectFilePathAndScrollIntoViewAsMuchAsPossible(); @@ -55,25 +56,22 @@ private void HandleHelpTopicLinkClicked(object sender, LinkLabelLinkClickedEvent } /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = LocalizationManager.GetString( - "SessionsView.MissingMediaFileEditor.TabText", "Missing Media File"); - - if (lblExplanation == null) - return; + TabText = LocalizationManager.GetString( + "SessionsView.MissingMediaFileEditor.TabText", "Missing Media File"); - lblExplanation.Text = LocalizationManager.GetString( - "SessionsView.MissingMediaFileEditor.lblExplanation", - "This can happen if the media file is inadvertently deleted or renamed outside of SayMore. " + - "It could also happen if a properly named ELAN file is added to a SayMore session but internally " + - "refers to a media file that is not where SayMore expects to find it. If you have access to the media " + - "file and would like to be able to annotate it in SayMore, please copy it to the above location."); - } + if (lblExplanation == null) + return; + + lblExplanation.Text = LocalizationManager.GetString( + "SessionsView.MissingMediaFileEditor.lblExplanation", + "This can happen if the media file is inadvertently deleted or renamed outside of SayMore. " + + "It could also happen if a properly named ELAN file is added to a SayMore session but internally " + + "refers to a media file that is not where SayMore expects to find it. If you have access to the media " + + "file and would like to be able to annotate it in SayMore, please copy it to the above location."); } } } diff --git a/src/SayMore/UI/ComponentEditors/MissingMediaFileEditor.designer.cs b/src/SayMore/UI/ComponentEditors/MissingMediaFileEditor.designer.cs index 2f57ed83..79e562ea 100644 --- a/src/SayMore/UI/ComponentEditors/MissingMediaFileEditor.designer.cs +++ b/src/SayMore/UI/ComponentEditors/MissingMediaFileEditor.designer.cs @@ -36,7 +36,7 @@ private void InitializeComponent() this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.linkHelpTopic = new System.Windows.Forms.LinkLabel(); this.txtMissingMediaFilePath = new System.Windows.Forms.TextBox(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._panelBrowser.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); @@ -182,7 +182,7 @@ private void InitializeComponent() private System.Windows.Forms.LinkLabel linkHelpTopic; private System.Windows.Forms.TextBox txtMissingMediaFilePath; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Label lblMediaFileMissing; private System.Windows.Forms.Label lblExplanation; } diff --git a/src/SayMore/UI/ComponentEditors/NotesEditor.cs b/src/SayMore/UI/ComponentEditors/NotesEditor.cs index 5097c919..9f092c9f 100644 --- a/src/SayMore/UI/ComponentEditors/NotesEditor.cs +++ b/src/SayMore/UI/ComponentEditors/NotesEditor.cs @@ -14,7 +14,7 @@ public partial class NotesEditor : EditorBase private string _origTabText; /// ------------------------------------------------------------------------------------ - public NotesEditor(ComponentFile file) : base(file, null, "Notes") + public NotesEditor(ComponentFile file) : base(file, "Notes") { InitializeComponent(); Name = "Notes"; @@ -67,15 +67,12 @@ private static void HandleNotesTextBoxKeyDown(object sender, KeyEventArgs e) /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - _origTabText = TabText = LocalizationManager.GetString( - "CommonToMultipleViews.NotesEditor.TabText", "Notes"); - } + _origTabText = TabText = LocalizationManager.GetString( + "CommonToMultipleViews.NotesEditor.TabText", "Notes"); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } private void NotesEditor_Load(object sender, EventArgs e) diff --git a/src/SayMore/UI/ComponentEditors/PersonBasicEditor.Designer.cs b/src/SayMore/UI/ComponentEditors/PersonBasicEditor.Designer.cs index 3726b313..3030d8e1 100644 --- a/src/SayMore/UI/ComponentEditors/PersonBasicEditor.Designer.cs +++ b/src/SayMore/UI/ComponentEditors/PersonBasicEditor.Designer.cs @@ -81,7 +81,7 @@ private void InitializeComponent() this._binder = new SayMore.UI.ComponentEditors.BindingHelper(this.components); this._autoCompleteHelper = new SayMore.UI.ComponentEditors.AutoCompleteHelper(this.components); this._tooltip = new System.Windows.Forms.ToolTip(this.components); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayout.SuspendLayout(); this._panelPicture.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this._personsPicture)).BeginInit(); @@ -1049,7 +1049,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolTip _tooltip; private System.Windows.Forms.PictureBox _personsPicture; private System.Windows.Forms.Panel _panelPicture; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.FlowLayoutPanel _panelPrivacy; private System.Windows.Forms.Label _labelPrivacy; private System.Windows.Forms.CheckBox _privacyProtection; diff --git a/src/SayMore/UI/ComponentEditors/PersonBasicEditor.cs b/src/SayMore/UI/ComponentEditors/PersonBasicEditor.cs index 246b1890..f2cd0d07 100644 --- a/src/SayMore/UI/ComponentEditors/PersonBasicEditor.cs +++ b/src/SayMore/UI/ComponentEditors/PersonBasicEditor.cs @@ -22,12 +22,16 @@ using static System.StringComparison; using static SayMore.UI.LowLevelControls.ParentType; using static SIL.Windows.Forms.Extensions.ControlExtensions.ErrorHandlingAction; +using static System.Text.NormalizationForm; namespace SayMore.UI.ComponentEditors { /// ---------------------------------------------------------------------------------------- public sealed partial class PersonBasicEditor : EditorBase { + private const int kMaleIndex = 0; + private const int kFemaleIndex = 1; + public delegate PersonBasicEditor Factory(ComponentFile file, string imageKey); private readonly List _fatherButtons = new List(); @@ -38,6 +42,7 @@ public sealed partial class PersonBasicEditor : EditorBase private readonly ImageFileType _imgFileType; private bool _loaded; + private int? _pendingSelectedGenderIndex; // SP-846: Do not save parent languages while setting them private bool _loadingLanguages; @@ -51,7 +56,7 @@ public sealed partial class PersonBasicEditor : EditorBase public PersonBasicEditor(ComponentFile file, string imageKey, AutoCompleteValueGatherer autoCompleteProvider, FieldGatherer fieldGatherer, ImageFileType imgFileType) - : base(file, null, imageKey) + : base(file, imageKey) { Logger.WriteEvent("PersonBasicEditor constructor. file = {0}", file); @@ -86,7 +91,6 @@ public PersonBasicEditor(ComponentFile file, string imageKey, { _otherLanguage3, _otherLanguage3.ForeColor} }; - HandleStringsLocalized(null); _binder.TranslateBoundValueBeingSaved += HandleBinderTranslateBoundValueBeingSaved; _binder.TranslateBoundValueBeingRetrieved += HandleBinderTranslateBoundValueBeingRetrieved; _binder.SetComponentFile(file); @@ -810,39 +814,64 @@ private string GetPictureFileFromDragData(IDataObject data) #endregion #region Methods for handling localized gender names + /// ------------------------------------------------------------------------------------ /// /// Update the tab text and gender names in case they were localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = LocalizationManager.GetString("PeopleView.MetadataEditor.TabText", - "Person"); + TabText = LocalizationManager.GetString("PeopleView.MetadataEditor.TabText", "Person"); - if (_gender != null) + if (_gender != null) + { + // If a pending selected index was recorded earlier (before we had populated + // the items), prefer that; otherwise use the current SelectedIndex. We'll + // populate the localized items and then clamp the selected index to a valid + // range to avoid exceptions during startup/initialization. + int selectedIndex = _pendingSelectedGenderIndex ?? _gender.SelectedIndex; + _pendingSelectedGenderIndex = null; + _gender.Items.Clear(); + _gender.Items.Add(LocalizationManager.GetString( + "PeopleView.MetadataEditor.GenderSelector.Male", "Male")); + _gender.Items.Add(LocalizationManager.GetString( + "PeopleView.MetadataEditor.GenderSelector.Female", "Female")); + // Ensure the index is within bounds in case of unusual state during startup. + if (_gender.Items.Count > 0) { - int i = _gender.SelectedIndex; - _gender.Items.Clear(); - _gender.Items.Add(LocalizationManager.GetString( - "PeopleView.MetadataEditor.GenderSelector.Male", "Male")); - _gender.Items.Add(LocalizationManager.GetString( - "PeopleView.MetadataEditor.GenderSelector.Female", "Female")); - _gender.SelectedIndex = i; + if (selectedIndex < 0) + selectedIndex = 0; + if (selectedIndex >= _gender.Items.Count) + selectedIndex = _gender.Items.Count - 1; + _gender.SelectedIndex = selectedIndex; } } - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } /// ------------------------------------------------------------------------------------ /// - /// Instead of letting the binding helper set the gender combo box value from the - /// value in the file (which will be the English text for male or female), we'll - /// intercept the process since the text in the gender combo box may have been - /// localized to non-English text. + /// Localized forms of "Male" known to have been written by versions of SayMore affected + /// by SP-847. + /// + /// ------------------------------------------------------------------------------------ + private static readonly HashSet s_maleGenderValues = + [ + "Male", + "Macho", + "Mâle".Normalize(FormD), + "Мужской".Normalize(FormD), + "男性".Normalize(FormD), + ]; + + /// ------------------------------------------------------------------------------------ + /// + /// A former bug (SP-847) caused gender metadata to be saved as a localized form rather + /// than the standard (English) values. So, instead of letting the binding helper set the + /// index of the gender combo box from the value in the file, recognize the localized + /// versions as well. /// /// ------------------------------------------------------------------------------------ private void HandleBinderTranslateBoundValueBeingRetrieved(object sender, @@ -850,15 +879,14 @@ private void HandleBinderTranslateBoundValueBeingRetrieved(object sender, { if (args.BoundControl == _gender) { - // Because of a former bug (SP-847), gender metadata was saved as localized - // string instead of English, so when retrieving, recognize those versions of the - // values for "Male" as well. - string valueFromFile = args.ValueFromFile.Normalize(NormalizationForm.FormD); - _gender.SelectedIndex = (valueFromFile == "Male" || - valueFromFile == "Macho" || - valueFromFile == "Mâle".Normalize(NormalizationForm.FormD) || - valueFromFile == "Мужской".Normalize(NormalizationForm.FormD) || - valueFromFile == "男性".Normalize(NormalizationForm.FormD) ? 0 : 1); + // Normalize and map any localized "male" values to our canonical indices. + string valueFromFile = args.ValueFromFile.Normalize(FormD); + int index = s_maleGenderValues.Contains(valueFromFile) ? kMaleIndex : kFemaleIndex; + // Record the desired index and defer actually setting SelectedIndex until the + // localized items have been populated (see HandleStringsLocalized). This avoids + // attempting to set SelectedIndex on a ComboBox that hasn't been filled yet, + // which can throw in certain initialization sequences. + _pendingSelectedGenderIndex = index; args.Handled = true; } } diff --git a/src/SayMore/UI/ComponentEditors/PersonContributionEditor.Designer.cs b/src/SayMore/UI/ComponentEditors/PersonContributionEditor.Designer.cs index 943ef6ff..447e9deb 100644 --- a/src/SayMore/UI/ComponentEditors/PersonContributionEditor.Designer.cs +++ b/src/SayMore/UI/ComponentEditors/PersonContributionEditor.Designer.cs @@ -38,7 +38,7 @@ private void InitializeComponent() this.colRole = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.colDate = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.colComments = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); this.SuspendLayout(); // @@ -118,6 +118,6 @@ private void InitializeComponent() private System.Windows.Forms.DataGridViewTextBoxColumn colRole; private System.Windows.Forms.DataGridViewTextBoxColumn colDate; private System.Windows.Forms.DataGridViewTextBoxColumn colComments; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; } } diff --git a/src/SayMore/UI/ComponentEditors/PersonContributionEditor.cs b/src/SayMore/UI/ComponentEditors/PersonContributionEditor.cs index 248f7d3c..df69295a 100644 --- a/src/SayMore/UI/ComponentEditors/PersonContributionEditor.cs +++ b/src/SayMore/UI/ComponentEditors/PersonContributionEditor.cs @@ -20,7 +20,7 @@ public partial class PersonContributionEditor : EditorBase private string _personCode; public PersonContributionEditor(ComponentFile file, string imageKey) - : base(file, null, imageKey) + : base(file, imageKey) { InitializeComponent(); RememberPersonId(file); @@ -131,15 +131,12 @@ private object[] GetContribRowData(SessionContribution contrib) return new object[] { description, localizedRole, formattedDate, contrib.Contribution.Comments }; } - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) - { - TabText = LocalizationManager.GetString( - "PeopleView.ContributionEditor.TabText", "Contributions"); - } + TabText = LocalizationManager.GetString( + "PeopleView.ContributionEditor.TabText", "Contributions"); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } public override void SetComponentFile(ComponentFile file) diff --git a/src/SayMore/UI/ComponentEditors/SessionBasicEditor.Designer.cs b/src/SayMore/UI/ComponentEditors/SessionBasicEditor.Designer.cs index 724cc156..aaa5667c 100644 --- a/src/SayMore/UI/ComponentEditors/SessionBasicEditor.Designer.cs +++ b/src/SayMore/UI/ComponentEditors/SessionBasicEditor.Designer.cs @@ -62,7 +62,7 @@ private void InitializeComponent() this._labelCustomFields = new System.Windows.Forms.Label(); this._binder = new SayMore.UI.ComponentEditors.BindingHelper(this.components); this._autoCompleteHelper = new SayMore.UI.ComponentEditors.AutoCompleteHelper(this.components); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._moreFieldsToolTip = new System.Windows.Forms.ToolTip(this.components); this._tableLayout.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); @@ -631,7 +631,7 @@ private void InitializeComponent() private AutoCompleteHelper _autoCompleteHelper; private System.Windows.Forms.Panel _panelGrid; private System.Windows.Forms.Label _labelDate; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.ComboBox _access; private System.Windows.Forms.Label _labelMoreFields; private System.Windows.Forms.Panel _panelAdditionalGrid; diff --git a/src/SayMore/UI/ComponentEditors/SessionBasicEditor.cs b/src/SayMore/UI/ComponentEditors/SessionBasicEditor.cs index a809c105..3fe4bda9 100644 --- a/src/SayMore/UI/ComponentEditors/SessionBasicEditor.cs +++ b/src/SayMore/UI/ComponentEditors/SessionBasicEditor.cs @@ -42,7 +42,7 @@ public partial class SessionBasicEditor : EditorBase public SessionBasicEditor(ComponentFile file, string imageKey, AutoCompleteValueGatherer autoCompleteProvider, FieldGatherer fieldGatherer, PersonInformant personInformant) - : base(file, null, imageKey) + : base(file, imageKey) { Logger.WriteEvent("SessionBasicEditor constructor. file = {0}", file); @@ -431,31 +431,28 @@ protected override void OnCurrentProjectSet() /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) + TabText = LocalizationManager.GetString("SessionsView.MetadataEditor.TabText", + "Session"); + if (_genre != null && !String.IsNullOrEmpty(_genre.Text)) { - TabText = LocalizationManager.GetString("SessionsView.MetadataEditor.TabText", - "Session"); - if (_genre != null && !String.IsNullOrEmpty(_genre.Text)) - { - var genreId = GenreDefinition.TranslateNameToId(_genre.Text); - if (genreId != _genre.Text) - _genre.Text = GenreDefinition.TranslateIdToName(genreId); - } + var genreId = GenreDefinition.TranslateNameToId(_genre.Text); + if (genreId != _genre.Text) + _genre.Text = GenreDefinition.TranslateIdToName(genreId); + } - if (_gridAdditionalFields != null) + if (_gridAdditionalFields != null) + { + for (int iRow = 0; iRow < _gridAdditionalFields.RowCount; iRow++) { - for (int iRow = 0; iRow < _gridAdditionalFields.RowCount; iRow++) - { - var comboBoxCell = _gridAdditionalFields[1, iRow] as DataGridViewComboBoxCell; - if (comboBoxCell?.DataSource is IMDIItemList list) - list.Localize(Localize); - } + var comboBoxCell = _gridAdditionalFields[1, iRow] as DataGridViewComboBoxCell; + if (comboBoxCell?.DataSource is IMDIItemList list) + list.Localize(Localize); } } - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } /// ------------------------------------------------------------------------------------ diff --git a/src/SayMore/UI/ComponentEditors/StatusAndStagesEditor.Designer.cs b/src/SayMore/UI/ComponentEditors/StatusAndStagesEditor.Designer.cs index 0451e2c7..262a34da 100644 --- a/src/SayMore/UI/ComponentEditors/StatusAndStagesEditor.Designer.cs +++ b/src/SayMore/UI/ComponentEditors/StatusAndStagesEditor.Designer.cs @@ -38,7 +38,7 @@ private void InitializeComponent() this._labelReadAboutStages = new System.Windows.Forms.Label(); this._labelStagesHint = new System.Windows.Forms.Label(); this._buttonReadAboutStages = new System.Windows.Forms.Button(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._toolTip = new System.Windows.Forms.ToolTip(this.components); this._tableLayoutOuter.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); @@ -253,7 +253,7 @@ private void InitializeComponent() private System.Windows.Forms.Label _labelReadAboutStages; private System.Windows.Forms.Label _labelStagesHint; private System.Windows.Forms.Button _buttonReadAboutStages; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.ToolTip _toolTip; } } diff --git a/src/SayMore/UI/ComponentEditors/StatusAndStagesEditor.cs b/src/SayMore/UI/ComponentEditors/StatusAndStagesEditor.cs index 789b80b4..85019b14 100644 --- a/src/SayMore/UI/ComponentEditors/StatusAndStagesEditor.cs +++ b/src/SayMore/UI/ComponentEditors/StatusAndStagesEditor.cs @@ -23,7 +23,7 @@ public partial class StatusAndStagesEditor : EditorBase /// ---------------------------------------------------------------------------------------- public StatusAndStagesEditor(ComponentFile file, string imageKey, - IEnumerable componentRoles) : base(file, null, imageKey) + IEnumerable componentRoles) : base(file, imageKey) { InitializeComponent(); Name = "StatusAndStages"; @@ -331,22 +331,19 @@ private void HandleStagesColorBlockPaint(object sender, PaintEventArgs e) } /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { - if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) + TabText = LocalizationManager.GetString( + "SessionsView.StatusAndStagesEditor.TabText", "Status && Stages"); + if (_statusRadioButtons != null) { - TabText = LocalizationManager.GetString( - "SessionsView.StatusAndStagesEditor.TabText", "Status && Stages"); - if (_statusRadioButtons != null) + foreach (var radioButton in _statusRadioButtons.Where(b => b.Tag is Session.Status)) { - foreach (var radioButton in _statusRadioButtons.Where(b => b.Tag is Session.Status)) - { - var status = (Session.Status)radioButton.Tag; - radioButton.Text = Session.GetLocalizedStatus(status.ToString()); - var toolTip = GetStatusToolTip(status); - if (toolTip != null) - _toolTip.SetToolTip(radioButton, toolTip); - } + var status = (Session.Status)radioButton.Tag; + radioButton.Text = Session.GetLocalizedStatus(status.ToString()); + var toolTip = GetStatusToolTip(status); + if (toolTip != null) + _toolTip.SetToolTip(radioButton, toolTip); } if (_stageCheckBoxes != null) { @@ -355,7 +352,7 @@ protected override void HandleStringsLocalized(ILocalizationManager lm) } } - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } /// ------------------------------------------------------------------------------------ diff --git a/src/SayMore/UI/ComponentEditors/VideoComponentEditor.cs b/src/SayMore/UI/ComponentEditors/VideoComponentEditor.cs index 3557da9c..12377946 100644 --- a/src/SayMore/UI/ComponentEditors/VideoComponentEditor.cs +++ b/src/SayMore/UI/ComponentEditors/VideoComponentEditor.cs @@ -1,3 +1,4 @@ +using System; using L10NSharp; using SayMore.Model.Files; using SayMore.Model.Files.DataGathering; @@ -12,7 +13,7 @@ public partial class VideoComponentEditor : MediaComponentEditor /// ------------------------------------------------------------------------------------ public VideoComponentEditor(ComponentFile file, string imageKey, AutoCompleteValueGatherer autoCompleteProvider, FieldGatherer fieldGatherer) - : base(file, null, imageKey, autoCompleteProvider, fieldGatherer) + : base(file, imageKey, autoCompleteProvider, fieldGatherer) { Name = "Video File Information"; } @@ -22,11 +23,12 @@ public VideoComponentEditor(ComponentFile file, string imageKey, /// Update the tab text in case it was localized. /// /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { + var lm = (ILocalizationManager)sender; if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) TabText = GetPropertiesTabText(); - base.HandleStringsLocalized(lm); + base.HandleStringsLocalized(sender, e); } } } diff --git a/src/SayMore/UI/ConvertMediaDlg.Designer.cs b/src/SayMore/UI/ConvertMediaDlg.Designer.cs index 174a3a24..8ccbe8e3 100644 --- a/src/SayMore/UI/ConvertMediaDlg.Designer.cs +++ b/src/SayMore/UI/ConvertMediaDlg.Designer.cs @@ -49,7 +49,7 @@ private void InitializeComponent() this._textBoxOutput = new System.Windows.Forms.TextBox(); this._labelOutputFile = new System.Windows.Forms.Label(); this._labelOutputFileValue = new System.Windows.Forms.Label(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayoutOuter.SuspendLayout(); this._flowLayoutBottomButtons.SuspendLayout(); this._flowLayoutShowHideButtons.SuspendLayout(); @@ -413,7 +413,7 @@ private void InitializeComponent() private System.Windows.Forms.Button _buttonShowOutput; private System.Windows.Forms.Button _buttonHideOutput; private System.Windows.Forms.TextBox _textBoxOutput; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Label _labelOutputFile; private System.Windows.Forms.Label _labelOutputFileValue; } diff --git a/src/SayMore/UI/ElementListScreen/ComponentFileGrid.Designer.cs b/src/SayMore/UI/ElementListScreen/ComponentFileGrid.Designer.cs index 013d5cc5..651d10b4 100644 --- a/src/SayMore/UI/ElementListScreen/ComponentFileGrid.Designer.cs +++ b/src/SayMore/UI/ElementListScreen/ComponentFileGrid.Designer.cs @@ -1,5 +1,5 @@ using L10NSharp.XLiffUtils; -using L10NSharp.UI; +using L10NSharp.Windows.Forms.UIComponents; namespace SayMore.UI.ElementListScreen { @@ -18,10 +18,10 @@ protected override void Dispose(bool disposing) { if (disposing) { - if (components != null) - components.Dispose(); + components?.Dispose(); - LocalizeItemDlg.StringsLocalized -= HandleStringsLocalized; + if (_localizationManager != null) + _localizationManager.UiLanguageChanged -= HandleStringsLocalized; } base.Dispose(disposing); } @@ -55,7 +55,7 @@ private void InitializeComponent() this._buttonRename = new System.Windows.Forms.ToolStripButton(); this._buttonConvert = new System.Windows.Forms.ToolStripButton(); this._buttonAddFiles = new System.Windows.Forms.ToolStripButton(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._contextMenuStrip.SuspendLayout(); this._panelOuter.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this._grid)).BeginInit(); @@ -339,7 +339,7 @@ private void InitializeComponent() private System.Windows.Forms.DataGridViewTextBoxColumn colDataModified; private System.Windows.Forms.DataGridViewTextBoxColumn colSize; private System.Windows.Forms.DataGridViewTextBoxColumn colDuration; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.ToolStripButton _buttonConvert; } diff --git a/src/SayMore/UI/ElementListScreen/ComponentFileGrid.cs b/src/SayMore/UI/ElementListScreen/ComponentFileGrid.cs index 4186f13f..6aa36b85 100644 --- a/src/SayMore/UI/ElementListScreen/ComponentFileGrid.cs +++ b/src/SayMore/UI/ElementListScreen/ComponentFileGrid.cs @@ -10,7 +10,6 @@ using System.Windows.Forms; using L10NSharp; using L10NSharp.XLiffUtils; -using L10NSharp.UI; using SIL.Reporting; using SIL.Windows.Forms.Widgets.BetterGrid; using SayMore.Model.Files; @@ -26,6 +25,7 @@ namespace SayMore.UI.ElementListScreen /// ---------------------------------------------------------------------------------------- public partial class ComponentFileGrid : UserControl { + private readonly ILocalizationManager _localizationManager; private IReadOnlyCollection _files; private string _gridColSettingPrefix; @@ -65,13 +65,14 @@ public partial class ComponentFileGrid : UserControl /// ------------------------------------------------------------------------------------ public ComponentFileGrid() { + _localizationManager = ApplicationContainer.SayMoreLocalizationManager; ShowContextMenu = true; Logger.WriteEvent("ComponentFileGrid constructor"); InitializeComponent(); Font = Program.DialogFont; - _toolStripActions.Renderer = new SIL.Windows.Forms.NoToolStripBorderRenderer(); + _toolStripActions.Renderer = new NoToolStripBorderRenderer(); try { @@ -110,12 +111,14 @@ public ComponentFileGrid() _menuDeleteFile.Click += (s, e) => DeleteFile(); - LocalizeItemDlg.StringsLocalized += HandleStringsLocalized; + if (_localizationManager != null) + _localizationManager.UiLanguageChanged += HandleStringsLocalized; } /// ------------------------------------------------------------------------------------ - private void HandleStringsLocalized(ILocalizationManager lm) + private void HandleStringsLocalized(object sender, EventArgs e) { + var lm = (ILocalizationManager)sender; Debug.Assert(lm != null); // In this class, we never call this method directly. if (_grid != null && !_grid.IsDisposed && lm.Id == ApplicationContainer.kSayMoreLocalizationId) diff --git a/src/SayMore/UI/ElementListScreen/ComponentFileRenamingDialog.Designer.cs b/src/SayMore/UI/ElementListScreen/ComponentFileRenamingDialog.Designer.cs index 68d5a930..14554abf 100644 --- a/src/SayMore/UI/ElementListScreen/ComponentFileRenamingDialog.Designer.cs +++ b/src/SayMore/UI/ElementListScreen/ComponentFileRenamingDialog.Designer.cs @@ -53,7 +53,7 @@ private void InitializeComponent() this._messagePanel = new System.Windows.Forms.Panel(); this._warningIcon = new System.Windows.Forms.PictureBox(); this._labelMessage = new System.Windows.Forms.Label(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayout.SuspendLayout(); this._tableLayoutButtons.SuspendLayout(); this._tableLayoutTextBox.SuspendLayout(); @@ -511,7 +511,7 @@ private void InitializeComponent() private System.Windows.Forms.Label _labelPrefix; private System.Windows.Forms.Label _labelMessage; private System.Windows.Forms.Label _labelExtension; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Label _labelChangeNameTo; private System.Windows.Forms.FlowLayoutPanel _flowLayoutShortcuts; private System.Windows.Forms.Label _labelShortcuts; diff --git a/src/SayMore/UI/ElementListScreen/ElementGrid.cs b/src/SayMore/UI/ElementListScreen/ElementGrid.cs index d55007fc..50117cd0 100644 --- a/src/SayMore/UI/ElementListScreen/ElementGrid.cs +++ b/src/SayMore/UI/ElementListScreen/ElementGrid.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Windows.Forms; using L10NSharp; -using L10NSharp.UI; +using L10NSharp.Windows.Forms; using SIL.Extensions; using SIL.Windows.Forms.Widgets.BetterGrid; using SayMore.Model; @@ -27,8 +27,8 @@ public class ElementGrid : BetterGrid public Action DeleteAction; protected FileType _fileType; - private IEnumerable _items = new ProjectElement[] { }; - protected ContextMenuStrip _contextMenuStrip = new ContextMenuStrip(); + private IEnumerable _items = []; + protected ContextMenuStrip _contextMenuStrip = new(); protected readonly L10NSharpExtender _locExtender; /// ------------------------------------------------------------------------------------ diff --git a/src/SayMore/UI/ElementListScreen/ElementListScreen.cs b/src/SayMore/UI/ElementListScreen/ElementListScreen.cs index 363580ab..06969e20 100644 --- a/src/SayMore/UI/ElementListScreen/ElementListScreen.cs +++ b/src/SayMore/UI/ElementListScreen/ElementListScreen.cs @@ -5,8 +5,6 @@ using System.Linq; using System.Windows.Forms; using L10NSharp; -using L10NSharp.XLiffUtils; -using L10NSharp.UI; using SIL.Windows.Forms.FileSystem; using SayMore.Model.Files; using SayMore.Model; @@ -35,6 +33,7 @@ namespace SayMore.UI.ElementListScreen public partial class ElementListScreen : UserControl where T : ProjectElement { protected readonly ElementListViewModel _model; + private readonly ILocalizationManager _localizationManagerm; protected ElementGrid _elementsGrid; protected TabControl _selectedEditorsTabControl; protected ListPanel _elementsListPanel; @@ -49,9 +48,10 @@ public partial class ElementListScreen : UserControl where T : ProjectElement public ToolStripMenuItem MainMenuItem { get; } /// ------------------------------------------------------------------------------------ - public ElementListScreen(ElementListViewModel presentationModel) + public ElementListScreen(ElementListViewModel presentationModel, ILocalizationManager lm) { _model = presentationModel; + _localizationManagerm = lm; MainMenuItem = new ToolStripMenuItem(); } @@ -79,7 +79,6 @@ protected void Initialize(Control tabControlHostControl, _elementsListPanel = elementsListPanel; _elementsListPanel.NewButtonClicked += HandleAddingNewElement; - _elementsListPanel.DeleteButtonClicked += HandleDeletingSelectedElements; _elementsListPanel.ListControl = _elementsGrid; _componentFilesControl = componentGrid; @@ -100,19 +99,19 @@ protected void Initialize(Control tabControlHostControl, protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); - HandleStringsLocalized(null); - LocalizeItemDlg.StringsLocalized += HandleStringsLocalized; + HandleStringsLocalized(null, EventArgs.Empty); + _localizationManagerm.UiLanguageChanged += HandleStringsLocalized; } /// ------------------------------------------------------------------------------------ protected override void OnHandleDestroyed(EventArgs e) { - LocalizeItemDlg.StringsLocalized -= HandleStringsLocalized; + _localizationManagerm.UiLanguageChanged -= HandleStringsLocalized; base.OnHandleDestroyed(e); } /// ------------------------------------------------------------------------------------ - protected virtual void HandleStringsLocalized(ILocalizationManager lm) + protected virtual void HandleStringsLocalized(object sender, EventArgs e) { // Overridden in derived classes } @@ -139,8 +138,8 @@ private void HandleParentFormActivated(object sender, EventArgs e) if (_model.FileLoadErrors.Any()) { - using (var dlg = new FileLoadErrorsReportDlg(_model.FileLoadErrors)) - dlg.ShowDialog(this); + using var dlg = new FileLoadErrorsReportDlg(_model.FileLoadErrors); + dlg.ShowDialog(this); } // Do this in case some of the metadata changed (e.g. audio file was edited) @@ -440,12 +439,6 @@ protected virtual bool DoesUserConfirmDeletingSelectedElements() return ConfirmRecycleDialog.JustConfirm(msg, itemCount > 1, kSayMoreLocalizationId); } - /// ------------------------------------------------------------------------------------ - protected virtual void HandleDeletingSelectedElements(object sender, EventArgs e) - { - DeleteSelectedElements(); - } - /// ------------------------------------------------------------------------------------ private void DeleteSelectedElements() { @@ -559,7 +552,6 @@ protected override void Dispose(bool disposing) _elementsGrid.SelectedElementChanged -= HandleSelectedElementChanged; _elementsListPanel.NewButtonClicked -= HandleAddingNewElement; - _elementsListPanel.DeleteButtonClicked -= HandleDeletingSelectedElements; var frm = FindForm(); if (frm != null) diff --git a/src/SayMore/UI/ElementListScreen/PersonListScreen.Designer.cs b/src/SayMore/UI/ElementListScreen/PersonListScreen.Designer.cs index 418937d3..b82048ae 100644 --- a/src/SayMore/UI/ElementListScreen/PersonListScreen.Designer.cs +++ b/src/SayMore/UI/ElementListScreen/PersonListScreen.Designer.cs @@ -36,7 +36,7 @@ private void InitializeComponent() this._componentsSplitter = new System.Windows.Forms.SplitContainer(); this._personComponentFileGrid = new SayMore.UI.ElementListScreen.ComponentFileGrid(); this._labelClickNewHelpPrompt = new System.Windows.Forms.Label(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._elementListSplitter.Panel1.SuspendLayout(); this._elementListSplitter.Panel2.SuspendLayout(); this._elementListSplitter.SuspendLayout(); @@ -170,6 +170,6 @@ private void InitializeComponent() private System.Windows.Forms.SplitContainer _componentsSplitter; private ComponentFileGrid _personComponentFileGrid; private System.Windows.Forms.Label _labelClickNewHelpPrompt; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; } } diff --git a/src/SayMore/UI/ElementListScreen/PersonListScreen.cs b/src/SayMore/UI/ElementListScreen/PersonListScreen.cs index 7fd6b8fa..a6e8f11d 100644 --- a/src/SayMore/UI/ElementListScreen/PersonListScreen.cs +++ b/src/SayMore/UI/ElementListScreen/PersonListScreen.cs @@ -14,7 +14,8 @@ public partial class PersonListScreen : ConcretePersonListScreen, ISayMoreView { /// ------------------------------------------------------------------------------------ public PersonListScreen(ElementListViewModel presentationModel, - PersonGrid.Factory personGridFactory) : base(presentationModel) + PersonGrid.Factory personGridFactory, ILocalizationManager localizationManager) : + base(presentationModel, localizationManager) { Logger.WriteEvent("PersonListScreen constructor"); @@ -47,8 +48,9 @@ public PersonListScreen(ElementListViewModel presentationModel, } /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { + var lm = (ILocalizationManager)sender; if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) { _personComponentFileGrid.AddFileButtonTooltipText = @@ -93,28 +95,16 @@ void HandleLastSetOfComponentEditorsRemoved(object sender, ControlEventArgs e) } /// ------------------------------------------------------------------------------------ - public Image Image - { - get { return ResourceImageCache.People; } - } + public Image Image => ResourceImageCache.People; /// ------------------------------------------------------------------------------------ - public string NameForUsageReporting - { - get { return "People"; } - } + public string NameForUsageReporting => "People"; /// ------------------------------------------------------------------------------------ - protected override Color ComponentEditorBackgroundColor - { - get { return Settings.Default.PersonEditorsBackgroundColor; } - } + protected override Color ComponentEditorBackgroundColor => Settings.Default.PersonEditorsBackgroundColor; /// ------------------------------------------------------------------------------------ - protected override Color ComponentEditorBorderColor - { - get { return Settings.Default.PersonEditorsBorderColor; } - } + protected override Color ComponentEditorBorderColor => Settings.Default.PersonEditorsBorderColor; /// ------------------------------------------------------------------------------------ public void AddTabToTabGroup(ViewTabGroup viewTabGroup) @@ -161,18 +151,18 @@ protected override void OnHandleDestroyed(EventArgs e) /// /// This class is used to overcome a limitation in the VS 2008 designer: /// not only can it not design a generic class, but it cannot even design a class which - /// directly inhertis from a generic class! So we have this intermediate class. + /// directly inherits from a generic class! So we have this intermediate class. /// /// ---------------------------------------------------------------------------------------- public class ConcretePersonListScreen : ElementListScreen { //design time only - private ConcretePersonListScreen() - : base(null) + private ConcretePersonListScreen() : base(null, null) {} - public ConcretePersonListScreen(ElementListViewModel presentationModel) - : base(presentationModel) + public ConcretePersonListScreen(ElementListViewModel presentationModel, + ILocalizationManager localizationManager) + : base(presentationModel, localizationManager) {} } } diff --git a/src/SayMore/UI/ElementListScreen/SessionsListScreen.Designer.cs b/src/SayMore/UI/ElementListScreen/SessionsListScreen.Designer.cs index b45438ea..e63d74f0 100644 --- a/src/SayMore/UI/ElementListScreen/SessionsListScreen.Designer.cs +++ b/src/SayMore/UI/ElementListScreen/SessionsListScreen.Designer.cs @@ -26,7 +26,7 @@ private void InitializeComponent() this._componentsSplitter = new System.Windows.Forms.SplitContainer(); this._sessionComponentFileGrid = new SayMore.UI.ElementListScreen.ComponentFileGrid(); this._labelClickNewHelpPrompt = new System.Windows.Forms.Label(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); ((System.ComponentModel.ISupportInitialize)(this._elementListSplitter)).BeginInit(); this._elementListSplitter.Panel1.SuspendLayout(); this._elementListSplitter.Panel2.SuspendLayout(); @@ -204,7 +204,7 @@ private void InitializeComponent() private ComponentFileGrid _sessionComponentFileGrid; private System.Windows.Forms.Button _buttonNewFromFiles; private System.Windows.Forms.Label _labelClickNewHelpPrompt; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.Button _buttonNewFromRecording; public string NameForUsageReporting diff --git a/src/SayMore/UI/ElementListScreen/SessionsListScreen.cs b/src/SayMore/UI/ElementListScreen/SessionsListScreen.cs index d59a897f..34fcd7f9 100644 --- a/src/SayMore/UI/ElementListScreen/SessionsListScreen.cs +++ b/src/SayMore/UI/ElementListScreen/SessionsListScreen.cs @@ -21,8 +21,8 @@ public partial class SessionsListScreen : ConcreteSessionScreen, ISayMoreView /// ------------------------------------------------------------------------------------ public SessionsListScreen(ElementListViewModel presentationModel, NewSessionsFromFileDlgViewModel.Factory newSessionsFromFileDlgViewModel, - SessionsGrid.Factory sessionGridFactory) - : base(presentationModel) + SessionsGrid.Factory sessionGridFactory, ILocalizationManager localizationManager) + : base(presentationModel, localizationManager) { Logger.WriteEvent("PersonListScreen constructor"); @@ -59,8 +59,9 @@ public SessionsListScreen(ElementListViewModel presentationModel, } /// ------------------------------------------------------------------------------------ - protected override void HandleStringsLocalized(ILocalizationManager lm) + protected override void HandleStringsLocalized(object sender, EventArgs e) { + var lm = (ILocalizationManager)sender; if (lm == null || lm.Id == ApplicationContainer.kSayMoreLocalizationId) { _sessionComponentFileGrid.AddFileButtonTooltipText = LocalizationManager.GetString( @@ -156,22 +157,13 @@ public override void ViewDeactivated() } /// ------------------------------------------------------------------------------------ - public Image Image - { - get { return ResourceImageCache.Sessions; } - } + public Image Image => ResourceImageCache.Sessions; /// ------------------------------------------------------------------------------------ - protected override Color ComponentEditorBackgroundColor - { - get { return Settings.Default.SessionEditorsBackgroundColor; } - } + protected override Color ComponentEditorBackgroundColor => Settings.Default.SessionEditorsBackgroundColor; /// ------------------------------------------------------------------------------------ - protected override Color ComponentEditorBorderColor - { - get { return Settings.Default.SessionEditorsBorderColor; } - } + protected override Color ComponentEditorBorderColor => Settings.Default.SessionEditorsBorderColor; /// ------------------------------------------------------------------------------------ protected override void OnHandleDestroyed(EventArgs e) @@ -187,14 +179,12 @@ private void HandleButtonNewFromFilesClick(object sender, EventArgs e) if (!_elementsGrid.IsOKToSelectDifferentElement()) return; - using (var viewModel = _newSessionsFromFileDlgViewModel(_model)) - using (var dlg = new NewSessionsFromFilesDlg(viewModel)) - { - if (dlg.ShowDialog(FindForm()) == DialogResult.OK) - LoadElementList(viewModel.FirstNewSessionAdded); + using var viewModel = _newSessionsFromFileDlgViewModel(_model); + using var dlg = new NewSessionsFromFilesDlg(viewModel); + if (dlg.ShowDialog(FindForm()) == DialogResult.OK) + LoadElementList(viewModel.FirstNewSessionAdded); - SetFocusOnId(); - } + SetFocusOnId(); } /// ------------------------------------------------------------------------------------ @@ -203,18 +193,16 @@ private void HandleButtonNewFromRecordingsClick(object sender, EventArgs e) if (!_elementsGrid.IsOKToSelectDifferentElement() || !AudioUtils.GetCanRecordAudio()) return; - using (var viewModel = new SessionRecorderDlgViewModel()) - using (var dlg = new SessionRecorderDlg(viewModel)) - { - if (dlg.ShowDialog(FindForm()) != DialogResult.OK) - return; + using var viewModel = new SessionRecorderDlgViewModel(); + using var dlg = new SessionRecorderDlg(viewModel); + if (dlg.ShowDialog(FindForm()) != DialogResult.OK) + return; - var newSession = _model.CreateNewElement(); - viewModel.MoveRecordingToSessionFolder(newSession); - LoadElementList(newSession); + var newSession = _model.CreateNewElement(); + viewModel.MoveRecordingToSessionFolder(newSession); + LoadElementList(newSession); - SetFocusOnId(); - } + SetFocusOnId(); } /// SP-55: Set focus to id field after creating a new session, and select the text @@ -261,11 +249,12 @@ public class ConcreteSessionScreen : ElementListScreen { //design time only private ConcreteSessionScreen() - : base(null) + : base(null, null) {} - public ConcreteSessionScreen(ElementListViewModel presentationModel) - : base(presentationModel) + public ConcreteSessionScreen(ElementListViewModel presentationModel, + ILocalizationManager localizationManager) + : base(presentationModel, localizationManager) {} } } diff --git a/src/SayMore/UI/LoadingDlg.Designer.cs b/src/SayMore/UI/LoadingDlg.Designer.cs index 86be78d9..216368b0 100644 --- a/src/SayMore/UI/LoadingDlg.Designer.cs +++ b/src/SayMore/UI/LoadingDlg.Designer.cs @@ -32,7 +32,7 @@ private void InitializeComponent() this._labelLoading = new System.Windows.Forms.Label(); this._linkCancel = new System.Windows.Forms.LinkLabel(); this._pictureLoading = new System.Windows.Forms.PictureBox(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); ((System.ComponentModel.ISupportInitialize)(this._pictureLoading)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.locExtender)).BeginInit(); @@ -153,7 +153,7 @@ private void InitializeComponent() private System.Windows.Forms.Label _labelLoading; private System.Windows.Forms.PictureBox _pictureLoading; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; private System.Windows.Forms.LinkLabel _linkCancel; private System.Windows.Forms.TableLayoutPanel _tableLayoutPanel; } diff --git a/src/SayMore/UI/LowLevelControls/DeleteMessageBox.Designer.cs b/src/SayMore/UI/LowLevelControls/DeleteMessageBox.Designer.cs index 2f5abbbe..394b2314 100644 --- a/src/SayMore/UI/LowLevelControls/DeleteMessageBox.Designer.cs +++ b/src/SayMore/UI/LowLevelControls/DeleteMessageBox.Designer.cs @@ -35,7 +35,7 @@ private void InitializeComponent() this._buttonDelete = new System.Windows.Forms.Button(); this._buttonCancel = new System.Windows.Forms.Button(); this._tableLayoutButtons = new System.Windows.Forms.TableLayoutPanel(); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._tableLayoutMessage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this._pictureDeleteX)).BeginInit(); this._tableLayoutButtons.SuspendLayout(); @@ -194,6 +194,6 @@ private void InitializeComponent() private System.Windows.Forms.Button _buttonCancel; private SIL.Windows.Forms.Widgets.AutoHeightLabel _labelMessage; private System.Windows.Forms.TableLayoutPanel _tableLayoutButtons; - private L10NSharp.UI.L10NSharpExtender locExtender; + private L10NSharp.Windows.Forms.L10NSharpExtender locExtender; } } \ No newline at end of file diff --git a/src/SayMore/UI/LowLevelControls/ListPanel.Designer.cs b/src/SayMore/UI/LowLevelControls/ListPanel.Designer.cs index f052ab11..591cddbe 100644 --- a/src/SayMore/UI/LowLevelControls/ListPanel.Designer.cs +++ b/src/SayMore/UI/LowLevelControls/ListPanel.Designer.cs @@ -1,5 +1,6 @@ using L10NSharp; -using L10NSharp.UI; +using L10NSharp.Windows.Forms; +using L10NSharp.Windows.Forms.UIComponents; namespace SayMore.UI.LowLevelControls { @@ -20,7 +21,7 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ListPanel)); - this.locExtender = new L10NSharp.UI.L10NSharpExtender(this.components); + this.locExtender = new L10NSharp.Windows.Forms.L10NSharpExtender(this.components); this._outerPanel = new SIL.Windows.Forms.Widgets.EnhancedPanel(); this._buttonsFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel(); this._buttonNew = new System.Windows.Forms.Button(); diff --git a/src/SayMore/UI/LowLevelControls/ListPanel.cs b/src/SayMore/UI/LowLevelControls/ListPanel.cs index 0883e475..d45b2ed3 100644 --- a/src/SayMore/UI/LowLevelControls/ListPanel.cs +++ b/src/SayMore/UI/LowLevelControls/ListPanel.cs @@ -11,15 +11,14 @@ namespace SayMore.UI.LowLevelControls { /// ---------------------------------------------------------------------------------------- /// - /// Control encapsulating a heading, list view and 'New'/'Delete' buttons. + /// Control encapsulating a heading, list view and 'New' button. /// /// ---------------------------------------------------------------------------------------- public partial class ListPanel : UserControl { public event EventHandler NewButtonClicked; - public event EventHandler DeleteButtonClicked; - private readonly List