Пример #1
0
        /// ------------------------------------------------------------------------------------
        private void SaveFileForLangId(string langId, bool forceCreation)
        {
            var tmxDoc = CreateEmptyStringFile();

            tmxDoc.Header.SourceLang = langId;
            tmxDoc.Header.SetPropValue(LocalizationManager.kAppVersionPropTag, OwningManager.AppVersion);

            foreach (var tu in TmxDocument.Body.TransUnits)
            {
                var tuv = tu.GetVariantForLang(langId);
                if (tuv == null)
                {
                    continue;
                }

                var newTu = new TMXTransUnit {
                    Id = tu.Id
                };
                tmxDoc.AddTransUnit(newTu);
                newTu.AddOrReplaceVariant(tu.GetVariantForLang(LocalizationManager.kDefaultLang));
                newTu.AddOrReplaceVariant(tuv);
                newTu.Notes = tu.CopyNotes();
                newTu.Props = tu.CopyProps();
            }

            tmxDoc.Body.TransUnits.Sort(TuComparer);

            if (forceCreation || OwningManager.DoesCustomizedTranslationExistForLanguage(langId))
            {
                tmxDoc.Save(OwningManager.GetTmxPathForLanguage(langId, true));
            }
        }
Пример #2
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Saves the cache to the file from which the cache was originally loaded, but only
        /// if the cache is dirty. If the cache is dirty and saved, then true is returned.
        /// Otherwise, false is returned.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        internal void SaveIfDirty(ICollection <string> langIdsToForceCreate)
        {
            if (!IsDirty)
            {
                return;
            }

            StringBuilder errorMsg = null;

            // ToArray() prevents exception "Collection was modified" in rare cases (e.g., Bloom BL-2400).
            foreach (var langId in TmxDocument.GetAllVariantLanguagesFound().ToArray())
            {
                try
                {
                    SaveFileForLangId(langId, langIdsToForceCreate != null && langIdsToForceCreate.Contains(langId));
                }
                catch (Exception e)
                {
                    if (e is SecurityException || e is UnauthorizedAccessException || e is IOException)
                    {
                        if (errorMsg == null)
                        {
                            errorMsg = new StringBuilder();
                            errorMsg.AppendLine("Failed to save localization changes in the following files:");
                        }
                        errorMsg.AppendLine();
                        errorMsg.Append("File: ");
                        errorMsg.AppendLine(OwningManager.GetTmxPathForLanguage(langId, true));
                        errorMsg.Append("Error Type: ");
                        errorMsg.AppendLine(e.GetType().ToString());
                        errorMsg.Append("Message: ");
                        errorMsg.AppendLine(e.Message);
                    }
                }
            }

            if (errorMsg != null)
            {
                throw new IOException(errorMsg.ToString());
            }

            IsDirty = false;
        }
Пример #3
0
        /// ------------------------------------------------------------------------------------
        private void MergeTmxFilesIntoCache(IEnumerable <string> tmxFiles)
        {
            var defaultTmxDoc = TMXDocument.Read(OwningManager.DefaultStringFilePath);

            foreach (var tu in defaultTmxDoc.Body.TransUnits)
            {
                TmxDocument.Body.AddTransUnit(tu);
                // If this TMXTransUnit is marked NoLongerUsed in the English tmx, load its ID into the hashset
                // so we don't display this string in case the currentUI tmx doesn't have it marked as
                // NoLongerUsed.
                if (tu.GetPropValue(kNoLongerUsedPropTag) != null)
                {
                    _englishTuIdsNoLongerUsed.Add(tu.Id);
                }
            }
            // It's possible (I think when there is no customizable TMX, as on first install, but the version in the installed TMX
            // is out of date with the app) that we don't have all the info from the installed TMX in the customizable one.
            // We want to make sure that (a) any new dynamic strings in the installed one are considered valid by default
            // (b) any newly obsolete IDs are noted.
            if (File.Exists(OwningManager.DefaultInstalledStringFilePath))
            {
                var defaultInstalledTmxDoc = TMXDocument.Read(OwningManager.DefaultInstalledStringFilePath);
                foreach (var tu in defaultInstalledTmxDoc.Body.TransUnits)
                {
                    TmxDocument.Body.AddTransUnitOrVariantFromExisting(tu, "en");
                    // also needed in this, to prevent things we find here from being considered orphans.
                    defaultTmxDoc.Body.AddTransUnitOrVariantFromExisting(tu, "en");
                    // If this TMXTransUnit is marked NoLongerUsed in the English tmx, load its ID into the hashset
                    // so we don't display this string in case the currentUI tmx doesn't have it marked as
                    // NoLongerUsed.
                    if (tu.GetPropValue(kNoLongerUsedPropTag) != null)
                    {
                        _englishTuIdsNoLongerUsed.Add(tu.Id);
                    }
                }
            }
            // Map the default language onto itself.
            LocalizationManagerInternal <TMXDocument> .MapToExistingLanguage[LocalizationManager.kDefaultLang] = LocalizationManager.kDefaultLang;

            Exception error = null;
            var       stillNeedToLoadNoLongerUsed = _englishTuIdsNoLongerUsed.Count == 0;

            foreach (var file in tmxFiles.Where(f => Path.GetFileName(f) != OwningManager.DefaultStringFilePath))
            {
                try
                {
                    var tmxDoc = TMXDocument.Read(file);
                    var langId = tmxDoc.Header.SourceLang;
                    // Provide a mapping from a specific variant of a language to the base language.
                    // For example, "es-ES" can provide translations for "es" if we don't have "es" specifically.
                    var pieces = langId.Split('-');
                    if (pieces.Length > 1)
                    {
                        if (!LocalizationManagerInternal <TMXDocument> .MapToExistingLanguage.ContainsKey
                                (pieces[0]))
                        {
                            LocalizationManagerInternal <TMXDocument> .MapToExistingLanguage.TryAdd(pieces[0], langId);
                        }
                    }
                    // Identity mapping always wins.  Storing it simplifies code elsewhere.
                    LocalizationManagerInternal <TMXDocument> .MapToExistingLanguage[langId] = langId;

                    foreach (var tu in tmxDoc.Body.TransUnits)
                    {
                        // This block attempts to find 'orphans', that is, localizations that have been done using an obsolete ID.
                        // We assume the default language TMX has only current IDs, and therefore don't look for orphans in that case.
                        // This guards against cases such as recently occurred in Bloom, where a dynamic ID EditTab.AddPageDialog.Title
                        // was regarded as an obsolete id for PublishTab.Upload.Title
                        if (langId != LocalizationManager.kDefaultLang && defaultTmxDoc.GetTransUnitForId(tu.Id) == null &&
                            !tu.Id.EndsWith(kToolTipSuffix) && !tu.Id.EndsWith(kShortcutSuffix))
                        {
                            //if we couldn't find it, maybe the id just changed and then if so re-id it.
                            var movedUnit = defaultTmxDoc.GetTransUnitForOrphan(tu);
                            if (movedUnit == null)
                            {
                                if (tu.GetPropValue(kDiscoveredDynamically) == "true")
                                {
                                    //ok, no big deal, that what we expect with dynamic strings, by definition... that we won't find them during a static code scan
                                }
                                else
                                {
                                    tu.AddProp(kNoLongerUsedPropTag, "true");
                                }
                            }
                            else
                            {
                                tu.Id = movedUnit.Id;
                            }
                        }

                        TmxDocument.Body.AddTransUnitOrVariantFromExisting(tu, langId);
                        if (stillNeedToLoadNoLongerUsed && langId == LocalizationManager.kDefaultLang &&
                            tu.GetPropValue(kNoLongerUsedPropTag) != null)
                        {
                            _englishTuIdsNoLongerUsed.Add(tu.Id);
                        }
                    }
                }
                catch (Exception e)
                {
#if DEBUG
                    throw e;
#else
                    //REVIEW: Better explain the conditions where we get an error on a file but don't care about it?

                    // If error happened reading some localization file other than the one we care
                    // about right now, just ignore it.
                    if (file == OwningManager.GetTmxPathForLanguage(LocalizationManager.UILanguageId, false))
                    {
                        error = e;
                    }
#endif
                }
            }
            if (error != null)
            {
                throw error;
            }
        }