|
|
|
using UnityEngine;
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
using UnityEditor;
|
|
|
|
#endif
|
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.IO;
|
|
|
|
using Ideafixxxer.CsvParser;
|
|
|
|
|
|
|
|
namespace Fungus
|
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multi-language localization support.
|
|
|
|
*/
|
|
|
|
public class Localization : MonoBehaviour
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Language to use at startup, usually defined by a two letter language code (e.g DE = German)
|
|
|
|
*/
|
|
|
|
[Tooltip("Language to use at startup, usually defined by a two letter language code (e.g DE = German)")]
|
|
|
|
public string activeLanguage = "";
|
|
|
|
|
|
|
|
protected static Dictionary<string, string> localizedStrings = new Dictionary<string, string>();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Temp storage for a single item of standard text and its localizations
|
|
|
|
*/
|
|
|
|
protected class TextItem
|
|
|
|
{
|
|
|
|
public string description = "";
|
|
|
|
public string standardText = "";
|
|
|
|
public Dictionary<string, string> localizedStrings = new Dictionary<string, string>();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* CSV file containing localization data which can be easily edited in a spreadsheet tool.
|
|
|
|
*/
|
|
|
|
[Tooltip("CSV file containing localization data which can be easily edited in a spreadsheet tool")]
|
|
|
|
public TextAsset localizationFile;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stores any notification message from export / import methods.
|
|
|
|
*/
|
|
|
|
[NonSerialized]
|
|
|
|
public string notificationText = "";
|
|
|
|
|
|
|
|
public virtual void Start()
|
|
|
|
{
|
|
|
|
if (localizationFile != null &&
|
|
|
|
localizationFile.text.Length > 0)
|
|
|
|
{
|
|
|
|
SetActiveLanguage(activeLanguage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Looks up the specified string in the localized strings table.
|
|
|
|
* For this to work, a localization file and active language must have been set previously.
|
|
|
|
* Return null if the string is not found.
|
|
|
|
*/
|
|
|
|
public static string GetLocalizedString(string stringId)
|
|
|
|
{
|
|
|
|
if (localizedStrings == null)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (localizedStrings.ContainsKey(stringId))
|
|
|
|
{
|
|
|
|
return localizedStrings[stringId];
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert all text items and localized strings to an easy to edit CSV format.
|
|
|
|
*/
|
|
|
|
public virtual string GetCSVData()
|
|
|
|
{
|
|
|
|
// Collect all the text items present in the scene
|
|
|
|
Dictionary<string, TextItem> textItems = FindTextItems();
|
|
|
|
|
|
|
|
// Update text items with localization data from CSV file
|
|
|
|
if (localizationFile != null &&
|
|
|
|
localizationFile.text.Length > 0)
|
|
|
|
{
|
|
|
|
AddCSVDataItems(textItems, localizationFile.text);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build CSV header row and a list of the language codes currently in use
|
|
|
|
string csvHeader = "Key,Description,Standard";
|
|
|
|
List<string> languageCodes = new List<string>();
|
|
|
|
foreach (TextItem textItem in textItems.Values)
|
|
|
|
{
|
|
|
|
foreach (string languageCode in textItem.localizedStrings.Keys)
|
|
|
|
{
|
|
|
|
if (!languageCodes.Contains(languageCode))
|
|
|
|
{
|
|
|
|
languageCodes.Add(languageCode);
|
|
|
|
csvHeader += "," + languageCode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build the CSV file using collected text items
|
|
|
|
int rowCount = 0;
|
|
|
|
string csvData = csvHeader + "\n";
|
|
|
|
foreach (string stringId in textItems.Keys)
|
|
|
|
{
|
|
|
|
TextItem textItem = textItems[stringId];
|
|
|
|
|
|
|
|
string row = CSVSupport.Escape(stringId);
|
|
|
|
row += "," + CSVSupport.Escape(textItem.description);
|
|
|
|
row += "," + CSVSupport.Escape(textItem.standardText);
|
|
|
|
|
|
|
|
foreach (string languageCode in languageCodes)
|
|
|
|
{
|
|
|
|
if (textItem.localizedStrings.ContainsKey(languageCode))
|
|
|
|
{
|
|
|
|
row += "," + CSVSupport.Escape(textItem.localizedStrings[languageCode]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
row += ","; // Empty field
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
csvData += row + "\n";
|
|
|
|
rowCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
notificationText = "Exported " + rowCount + " localization text items.";
|
|
|
|
|
|
|
|
return csvData;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Builds a dictionary of localizable text items in the scene.
|
|
|
|
*/
|
|
|
|
protected Dictionary<string, TextItem> FindTextItems()
|
|
|
|
{
|
|
|
|
Dictionary<string, TextItem> textItems = new Dictionary<string, TextItem>();
|
|
|
|
|
|
|
|
// Export all character names
|
|
|
|
foreach (Character character in GameObject.FindObjectsOfType<Character>())
|
|
|
|
{
|
|
|
|
// String id for character names is CHARACTER.<Character Name>
|
|
|
|
TextItem textItem = new TextItem();
|
|
|
|
textItem.standardText = character.nameText;
|
|
|
|
textItem.description = character.description;
|
|
|
|
string stringId = "CHARACTER." + character.nameText;
|
|
|
|
textItems[stringId] = textItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Export all Say and Menu commands in the scene
|
|
|
|
// To make it easier to localize, we preserve the command order in each exported block.
|
|
|
|
Flowchart[] flowcharts = GameObject.FindObjectsOfType<Flowchart>();
|
|
|
|
foreach (Flowchart flowchart in flowcharts)
|
|
|
|
{
|
|
|
|
// If no localization id has been set then use the Flowchart name
|
|
|
|
string localizationId = flowchart.localizationId;
|
|
|
|
if (localizationId.Length == 0)
|
|
|
|
{
|
|
|
|
localizationId = flowchart.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Block[] blocks = flowchart.GetComponentsInChildren<Block>();
|
|
|
|
foreach (Block block in blocks)
|
|
|
|
{
|
|
|
|
foreach (Command command in block.commandList)
|
|
|
|
{
|
|
|
|
string stringId = "";
|
|
|
|
string standardText = "";
|
|
|
|
string description = "";
|
|
|
|
|
|
|
|
System.Type type = command.GetType();
|
|
|
|
if (type == typeof(Say))
|
|
|
|
{
|
|
|
|
// String id for Say commands is SAY.<Flowchart id>.<Command id>.<Character Name>
|
|
|
|
Say sayCommand = command as Say;
|
|
|
|
standardText = sayCommand.storyText;
|
|
|
|
description = sayCommand.description;
|
|
|
|
stringId = "SAY." + localizationId + "." + sayCommand.itemId + ".";
|
|
|
|
if (sayCommand.character != null)
|
|
|
|
{
|
|
|
|
stringId += sayCommand.character.nameText;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (type == typeof(Menu))
|
|
|
|
{
|
|
|
|
// String id for Menu commands is MENU.<Flowchart id>.<Command id>
|
|
|
|
Menu menuCommand = command as Menu;
|
|
|
|
standardText = menuCommand.text;
|
|
|
|
description = menuCommand.description;
|
|
|
|
stringId = "MENU." + localizationId + "." + menuCommand.itemId;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
TextItem textItem = null;
|
|
|
|
if (textItems.ContainsKey(stringId))
|
|
|
|
{
|
|
|
|
textItem = textItems[stringId];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
textItem = new TextItem();
|
|
|
|
textItems[stringId] = textItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update basic properties,leaving localised strings intact
|
|
|
|
textItem.standardText = standardText;
|
|
|
|
textItem.description = description;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return textItems;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds localized strings from CSV file data to a dictionary of text items in the scene.
|
|
|
|
*/
|
|
|
|
protected virtual void AddCSVDataItems(Dictionary<string, TextItem> textItems, string csvData)
|
|
|
|
{
|
|
|
|
CsvParser csvParser = new CsvParser();
|
|
|
|
string[][] csvTable = csvParser.Parse(csvData);
|
|
|
|
|
|
|
|
if (csvTable.Length <= 1)
|
|
|
|
{
|
|
|
|
// No data rows in file
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse header row
|
|
|
|
string[] columnNames = csvTable[0];
|
|
|
|
|
|
|
|
for (int i = 1; i < csvTable.Length; ++i)
|
|
|
|
{
|
|
|
|
string[] fields = csvTable[i];
|
|
|
|
if (fields.Length < 3)
|
|
|
|
{
|
|
|
|
// No standard text or localized string fields present
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
string stringId = fields[0];
|
|
|
|
|
|
|
|
if (!textItems.ContainsKey(stringId))
|
|
|
|
{
|
|
|
|
if (stringId.StartsWith("CHARACTER.") ||
|
|
|
|
stringId.StartsWith("SAY.") ||
|
|
|
|
stringId.StartsWith("MENU."))
|
|
|
|
{
|
|
|
|
// If it's a 'built-in' type this probably means that item has been deleted from its flowchart,
|
|
|
|
// so there's no need to add a text item for it.
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Key not found. Assume it's a custom string that we want to retain, so add a text item for it.
|
|
|
|
TextItem newTextItem = new TextItem();
|
|
|
|
newTextItem.description = CSVSupport.Unescape(fields[1]);
|
|
|
|
newTextItem.standardText = CSVSupport.Unescape(fields[2]);
|
|
|
|
textItems[stringId] = newTextItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
TextItem textItem = textItems[stringId];
|
|
|
|
|
|
|
|
for (int j = 3; j < fields.Length; ++j)
|
|
|
|
{
|
|
|
|
if (j >= columnNames.Length)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
string languageCode = columnNames[j];
|
|
|
|
string languageEntry = CSVSupport.Unescape(fields[j]);
|
|
|
|
|
|
|
|
if (languageEntry.Length > 0)
|
|
|
|
{
|
|
|
|
textItem.localizedStrings[languageCode] = languageEntry;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Scan a localization CSV file and copies the strings for the specified language code
|
|
|
|
* into the text properties of the appropriate scene objects.
|
|
|
|
*/
|
|
|
|
public virtual void SetActiveLanguage(string languageCode, bool forceUpdateSceneText = false)
|
|
|
|
{
|
|
|
|
if (!Application.isPlaying)
|
|
|
|
{
|
|
|
|
// This function should only ever be called when the game is playing (not in editor).
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (localizationFile == null)
|
|
|
|
{
|
|
|
|
// No localization file set
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
localizedStrings.Clear();
|
|
|
|
|
|
|
|
CsvParser csvParser = new CsvParser();
|
|
|
|
string[][] csvTable = csvParser.Parse(localizationFile.text);
|
|
|
|
|
|
|
|
if (csvTable.Length <= 1)
|
|
|
|
{
|
|
|
|
// No data rows in file
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse header row
|
|
|
|
string[] columnNames = csvTable[0];
|
|
|
|
|
|
|
|
if (columnNames.Length < 3)
|
|
|
|
{
|
|
|
|
// No languages defined in CSV file
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// First assume standard text column and then look for a matching language column
|
|
|
|
int languageIndex = 2;
|
|
|
|
for (int i = 3; i < columnNames.Length; ++i)
|
|
|
|
{
|
|
|
|
if (columnNames[i] == languageCode)
|
|
|
|
{
|
|
|
|
languageIndex = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (languageIndex == 2)
|
|
|
|
{
|
|
|
|
// Using standard text column
|
|
|
|
// Add all strings to the localized strings dict, but don't replace standard text in the scene.
|
|
|
|
// This allows string substitution to work for both standard and localized text strings.
|
|
|
|
for (int i = 1; i < csvTable.Length; ++i)
|
|
|
|
{
|
|
|
|
string[] fields = csvTable[i];
|
|
|
|
if (fields.Length < 3)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
localizedStrings[fields[0]] = fields[languageIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Early out unless we've been told to force the scene text to update.
|
|
|
|
// This happens when the Set Language command is used to reset back to the standard language.
|
|
|
|
if (!forceUpdateSceneText)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Using a localized language text column
|
|
|
|
// 1. Add all localized text to the localized strings dict
|
|
|
|
// 2. Update all scene text properties with localized versions
|
|
|
|
|
|
|
|
// Cache a lookup table of characters in the scene
|
|
|
|
Dictionary<string, Character> characterDict = new Dictionary<string, Character>();
|
|
|
|
foreach (Character character in GameObject.FindObjectsOfType<Character>())
|
|
|
|
{
|
|
|
|
characterDict[character.nameText] = character;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cache a lookup table of flowcharts in the scene
|
|
|
|
Dictionary<string, Flowchart> flowchartDict = new Dictionary<string, Flowchart>();
|
|
|
|
foreach (Flowchart flowchart in GameObject.FindObjectsOfType<Flowchart>())
|
|
|
|
{
|
|
|
|
// If no localization id has been set then use the Flowchart name
|
|
|
|
string localizationId = flowchart.localizationId;
|
|
|
|
if (localizationId.Length == 0)
|
|
|
|
{
|
|
|
|
localizationId = flowchart.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
flowchartDict[localizationId] = flowchart;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 1; i < csvTable.Length; ++i)
|
|
|
|
{
|
|
|
|
string[] fields = csvTable[i];
|
|
|
|
|
|
|
|
if (fields.Length < languageIndex + 1)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
string stringId = fields[0];
|
|
|
|
string languageEntry = CSVSupport.Unescape(fields[languageIndex]);
|
|
|
|
|
|
|
|
if (languageEntry.Length > 0)
|
|
|
|
{
|
|
|
|
localizedStrings[stringId] = languageEntry;
|
|
|
|
PopulateTextProperty(stringId, languageEntry, flowchartDict, characterDict);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Populates the text property of a single scene object with a new text value.
|
|
|
|
*/
|
|
|
|
public virtual bool PopulateTextProperty(string stringId,
|
|
|
|
string newText,
|
|
|
|
Dictionary<string, Flowchart> flowchartDict,
|
|
|
|
Dictionary<string, Character> characterDict)
|
|
|
|
{
|
|
|
|
string[] idParts = stringId.Split('.');
|
|
|
|
if (idParts.Length == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
string stringType = idParts[0];
|
|
|
|
if (stringType == "SAY")
|
|
|
|
{
|
|
|
|
if (idParts.Length != 4)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
string flowchartId = idParts[1];
|
|
|
|
if (!flowchartDict.ContainsKey(flowchartId))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Flowchart flowchart = flowchartDict[flowchartId];
|
|
|
|
|
|
|
|
int itemId = int.Parse(idParts[2]);
|
|
|
|
|
|
|
|
if (flowchart != null)
|
|
|
|
{
|
|
|
|
foreach (Say say in flowchart.GetComponentsInChildren<Say>())
|
|
|
|
{
|
|
|
|
if (say.itemId == itemId &&
|
|
|
|
say.storyText != newText)
|
|
|
|
{
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
Undo.RecordObject(say, "Set Text");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
say.storyText = newText;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (stringType == "MENU")
|
|
|
|
{
|
|
|
|
if (idParts.Length != 3)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
string flowchartId = idParts[1];
|
|
|
|
if (!flowchartDict.ContainsKey(flowchartId))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Flowchart flowchart = flowchartDict[flowchartId];
|
|
|
|
|
|
|
|
int itemId = int.Parse(idParts[2]);
|
|
|
|
|
|
|
|
if (flowchart != null)
|
|
|
|
{
|
|
|
|
foreach (Menu menu in flowchart.GetComponentsInChildren<Menu>())
|
|
|
|
{
|
|
|
|
if (menu.itemId == itemId &&
|
|
|
|
menu.text != newText)
|
|
|
|
{
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
Undo.RecordObject(menu, "Set Text");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
menu.text = newText;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (stringType == "CHARACTER")
|
|
|
|
{
|
|
|
|
if (idParts.Length != 2)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
string characterName = idParts[1];
|
|
|
|
if (!characterDict.ContainsKey(characterName))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Character character = characterDict[characterName];
|
|
|
|
if (character != null &&
|
|
|
|
character.nameText != newText)
|
|
|
|
{
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
Undo.RecordObject(character, "Set Text");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
character.nameText = newText;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns all standard text for SAY & MENU commands in the scene using an
|
|
|
|
* easy to edit custom text format.
|
|
|
|
*/
|
|
|
|
public virtual string GetStandardText()
|
|
|
|
{
|
|
|
|
// Collect all the text items present in the scene
|
|
|
|
Dictionary<string, TextItem> textItems = FindTextItems();
|
|
|
|
|
|
|
|
string textData = "";
|
|
|
|
int rowCount = 0;
|
|
|
|
foreach (string stringId in textItems.Keys)
|
|
|
|
{
|
|
|
|
if (!stringId.StartsWith("SAY.") && !(stringId.StartsWith("MENU.")))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
TextItem languageItem = textItems[stringId];
|
|
|
|
|
|
|
|
textData += "#" + stringId + "\n";
|
|
|
|
textData += languageItem.standardText.Trim() + "\n\n";
|
|
|
|
rowCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
notificationText = "Exported " + rowCount + " standard text items.";
|
|
|
|
|
|
|
|
return textData;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets standard text on scene objects by parsing a text data file.
|
|
|
|
*/
|
|
|
|
public virtual void SetStandardText(string textData)
|
|
|
|
{
|
|
|
|
// Cache a lookup table of characters in the scene
|
|
|
|
Dictionary<string, Character> characterDict = new Dictionary<string, Character>();
|
|
|
|
foreach (Character character in GameObject.FindObjectsOfType<Character>())
|
|
|
|
{
|
|
|
|
characterDict[character.nameText] = character;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cache a lookup table of flowcharts in the scene
|
|
|
|
Dictionary<string, Flowchart> flowchartDict = new Dictionary<string, Flowchart>();
|
|
|
|
foreach (Flowchart flowchart in GameObject.FindObjectsOfType<Flowchart>())
|
|
|
|
{
|
|
|
|
// If no localization id has been set then use the Flowchart name
|
|
|
|
string localizationId = flowchart.localizationId;
|
|
|
|
if (localizationId.Length == 0)
|
|
|
|
{
|
|
|
|
localizationId = flowchart.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
flowchartDict[localizationId] = flowchart;
|
|
|
|
}
|
|
|
|
|
|
|
|
string[] lines = textData.Split('\n');
|
|
|
|
|
|
|
|
int updatedCount = 0;
|
|
|
|
|
|
|
|
string stringId = "";
|
|
|
|
string buffer = "";
|
|
|
|
foreach (string line in lines)
|
|
|
|
{
|
|
|
|
// Check for string id line
|
|
|
|
if (line.StartsWith("#"))
|
|
|
|
{
|
|
|
|
if (stringId.Length > 0)
|
|
|
|
{
|
|
|
|
// Write buffered text to the appropriate text property
|
|
|
|
if (PopulateTextProperty(stringId, buffer.Trim(), flowchartDict, characterDict))
|
|
|
|
{
|
|
|
|
updatedCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the string id for the follow text lines
|
|
|
|
stringId = line.Substring(1, line.Length - 1);
|
|
|
|
buffer = "";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
buffer += line + "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle last buffered entry
|
|
|
|
if (stringId.Length > 0)
|
|
|
|
{
|
|
|
|
if (PopulateTextProperty(stringId, buffer.Trim(), flowchartDict, characterDict))
|
|
|
|
{
|
|
|
|
updatedCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
notificationText = "Updated " + updatedCount + " standard text items.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|