/// <summary> /// Copies all contents from another TextKeyViewModel instance to this one, merging all /// data, overwriting conflicts. Subitems are not copied to the new item. /// </summary> /// <param name="sourceKey"></param> public void MergeFrom(TextKeyViewModel sourceKey) { // Set or append comment if (!string.IsNullOrWhiteSpace(sourceKey.Comment)) { if (!string.IsNullOrWhiteSpace(Comment)) { Comment += Environment.NewLine; } Comment += sourceKey.Comment; } // Set or keep full key state IsFullKey |= sourceKey.IsFullKey; if (sourceKey.IsFullKey) { foreach (CultureTextViewModel otherctVM in sourceKey.CultureTextVMs) { var ctVM = CultureTextVMs.FirstOrDefault(c => c.CultureName == otherctVM.CultureName); if (ctVM == null) { // Culture doesn't exist here, just copy-add it CultureTextVMs.Add(otherctVM.Clone(this)); } else { // Merge culture text data ctVM.MergeFrom(otherctVM); } } UpdateCultureTextSeparators(); } }
private void OnIsFullKeyChanged() { if (!IsFullKey) { Comment = null; CultureTextVMs.Clear(); } }
public void UpdateIcon() { if (IsNamespace) { if (HasProblem) { ImageSource = "/Images/textkey_namespace_error.png"; } else { ImageSource = "/Images/textkey_namespace.png"; } } else if (IsFullKey) { if (CultureTextVMs.Any(ct => ct.QuantifiedTextVMs.Count > 0)) { if (HasProblem) { ImageSource = "/Images/key_q_error.png"; } else if (IsAccepted) { ImageSource = "/Images/key_q_accepted.png"; } else { ImageSource = "/Images/key_q.png"; } } else { if (HasProblem) { ImageSource = "/Images/key_error.png"; } else if (IsAccepted) { ImageSource = "/Images/key_accepted.png"; } else { ImageSource = "/Images/key.png"; } } } else { if (HasProblem) { ImageSource = "/Images/textkey_segment_error.png"; } else { ImageSource = "/Images/textkey_segment.png"; } } }
public bool Validate() { // NOTE: All checks are performed in their decreasing order of significance. The most- // severe errors come first, proceeding to more informational problems. The first // determined error generates the visible message and quits the method so that // no other checks are performed or could overwrite the message. // First validate all children recursively and remember whether there was a problem // somewhere down the tree bool anyChildError = false; foreach (TextKeyViewModel child in Children) { if (!child.Validate()) { anyChildError = true; } } // Partial keys can only indicate problems in the subtree if (!IsFullKey) { HasOwnProblem = false; HasProblem = anyChildError; Remarks = null; return(!anyChildError); } // The Tx namespace generally has no problems if (TextKey.StartsWith("Tx:")) { HasOwnProblem = false; HasProblem = anyChildError; Remarks = null; return(!anyChildError); } HasOwnProblem = false; HasProblem = anyChildError; Remarks = null; // ----- Check for count/modulo errors ----- // Check for invalid count values in any CultureText if (CultureTextVMs.Any(ct => ct.QuantifiedTextVMs.Any(qt => qt.Count < 0 || qt.Count >= 0xFFFF))) { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.invalid count")); } // Check for invalid modulo values in any CultureText if (CultureTextVMs.Any(ct => ct.QuantifiedTextVMs.Any(qt => qt.Modulo != 0 && (qt.Modulo < 2 || qt.Modulo > 1000)))) { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.invalid modulo")); } // Check for duplicate count/modulo values in any CultureText if (CultureTextVMs.Any(ct => ct.QuantifiedTextVMs .GroupBy(qt => qt.Count << 16 | qt.Modulo) .Any(grp => grp.Count() > 1))) { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.duplicate count modulo")); } // ----- Check referenced keys ----- if (CultureTextVMs.Any(ct => ct.TextKeyReferences != null && ct.TextKeyReferences.OfType <string>().Any(key => key == TextKey))) { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.referenced key loop")); } if (CultureTextVMs.Any(ct => ct.QuantifiedTextVMs.Any(qt => qt.TextKeyReferences != null && qt.TextKeyReferences.OfType <string>().Any(key => key == TextKey)))) { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.referenced key loop")); } if (CultureTextVMs.Any(ct => ct.TextKeyReferences != null && ct.TextKeyReferences.OfType <string>().Any(key => !MainWindowVM.TextKeys.ContainsKey(key)))) { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.missing referenced key")); } if (CultureTextVMs.Any(ct => ct.QuantifiedTextVMs.Any(qt => qt.TextKeyReferences != null && qt.TextKeyReferences.OfType <string>().Any(key => !MainWindowVM.TextKeys.ContainsKey(key))))) { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.missing referenced key")); } // ----- Check translations consistency ----- IsAccepted = false; if (CultureTextVMs.Count > 1) { string primaryText = CultureTextVMs[0].Text; for (int i = 0; i < CultureTextVMs.Count; i++) { // Skip main text of primary culture, it's what we compare everything else with if (i > 0) { string transText = CultureTextVMs[i].Text; // Ignore any empty text. If that's a problem, it'll be found as missing below. if (!String.IsNullOrEmpty(transText)) { string message; if (!CheckPlaceholdersConsistency(primaryText, transText, true, out message)) { CultureTextVMs[i].IsPlaceholdersProblem = true; if (CultureTextVMs[i].AcceptPlaceholders) { IsAccepted = true; } else { HasOwnProblem = true; HasProblem = true; AddRemarks(message); } } else { CultureTextVMs[i].IsPlaceholdersProblem = false; } if (!CheckPunctuationConsistency(primaryText, transText, out message)) { CultureTextVMs[i].IsPunctuationProblem = true; if (CultureTextVMs[i].AcceptPunctuation) { IsAccepted = true; } else { HasOwnProblem = true; HasProblem = true; AddRemarks(message); } } else { CultureTextVMs[i].IsPunctuationProblem = false; } } else { // If there's no text, and it hasn't been checked, there is no problem CultureTextVMs[i].IsPlaceholdersProblem = false; CultureTextVMs[i].IsPunctuationProblem = false; } } foreach (var qt in CultureTextVMs[i].QuantifiedTextVMs) { string transText = qt.Text; // Ignore any empty text for quantified texts. if (!String.IsNullOrEmpty(transText)) { string message; if (!CheckPlaceholdersConsistency(primaryText, transText, false, out message)) // Ignore count placeholder here { qt.IsPlaceholdersProblem = true; if (qt.AcceptPlaceholders) { IsAccepted = true; } else { HasOwnProblem = true; HasProblem = true; AddRemarks(message); } } else { qt.IsPlaceholdersProblem = false; } if (!CheckPunctuationConsistency(primaryText, transText, out message)) { qt.IsPunctuationProblem = true; if (qt.AcceptPunctuation) { IsAccepted = true; } else { HasOwnProblem = true; HasProblem = true; AddRemarks(message); } } else { qt.IsPunctuationProblem = false; } } else { // If there's no text, and it hasn't been checked, there is no problem qt.IsPlaceholdersProblem = false; qt.IsPunctuationProblem = false; } } } } // ----- Check for missing translations ----- foreach (var ctVM in CultureTextVMs) { if (ctVM.CultureName.Length == 2) { // Check that every non-region culture has a text set if (String.IsNullOrEmpty(ctVM.Text)) { ctVM.IsMissing = true; if (ctVM.AcceptMissing) { IsAccepted = true; } else { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.missing translation")); } } else { ctVM.IsMissing = false; } } else if (ctVM.CultureName.Length == 5) { // Check that every region-culture with no text has a non-region culture with a // text set (as fallback) if (String.IsNullOrEmpty(ctVM.Text) && !CultureTextVMs.Any(vm2 => vm2.CultureName == ctVM.CultureName.Substring(0, 2))) { ctVM.IsMissing = true; if (ctVM.AcceptMissing) { IsAccepted = true; } else { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.missing translation")); } } else { ctVM.IsMissing = false; } } // Also check quantified texts for missing texts foreach (var qt in ctVM.QuantifiedTextVMs) { if (String.IsNullOrEmpty(qt.Text)) { qt.IsMissing = true; if (qt.AcceptMissing) { IsAccepted = true; } else { HasOwnProblem = true; HasProblem = true; AddRemarks(Tx.T("validation.content.missing translation")); } } else { qt.IsMissing = false; } } } return(!HasProblem); }