Пример #1
0
		public void PuaCharacterToString()
		{
			string unicodeData =
				"VULGAR FRACTION ONE THIRD;No;0;ON;<fraction> 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;;";
			PUACharacter puaChar = new PUACharacter("2153",unicodeData);
			Assert.AreEqual("2153;" + unicodeData, puaChar.ToString(), "Error while writing PUACharacter");
		}
Пример #2
0
		public void SetUp()
		{
			m_comparer = new UCDComparer();
			m_bidi = new BidiCharacter("0669",
				"ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;");
			m_pua = new PUACharacter("0669",
				"ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;");
		}
Пример #3
0
		public void CreateNewPuaCharacter()
		{
			// Make some test characters
			PUACharacter newPuaChar =
				new PUACharacter("E001","ARABIC-INDIC DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;");
			PUACharacter copyOfNewPuaChar = new PUACharacter(newPuaChar);
			PUACharacter modifiedPuaChar =
				new PUACharacter("E001","CHEESE DIGIT THREE;Lu;0;L;;;;;N;;;0063;0664;0665");
			PUACharacter copyOfModifiedPuaChar = new PUACharacter(modifiedPuaChar);

			// "click" new
			m_dlgWsProps.PressBtnNewPUA(newPuaChar);
			CheckPuaCharactersMatch(copyOfNewPuaChar, "using the 'new' button", m_dlgWsProps);

			// "click" modify
			m_dlgWsProps.PressBtnModifyPUA(modifiedPuaChar);
			CheckPuaCharactersMatch(copyOfModifiedPuaChar, "using the 'modify' button", m_dlgWsProps);

			// "click" okay
			m_dlgWsProps.PressOk();
			TestUtils.Check_PUA(0xE001, "CHEESE DIGIT THREE", LgGeneralCharCategory.kccLu);
		}
Пример #4
0
		/// <summary>
		/// Makes a PUACharacter.
		/// This is useful when you are extending the class so that further constructors
		/// can make sure that we copy all the important data internally.
		/// </summary>
		/// <param name="puaChar">The PUACharacter that we are copying.</param>
		public PUACharacter(PUACharacter puaChar)
		{
			this.Copy(puaChar);
		}
Пример #5
0
		/// <summary>
		/// Constructs a UCDCharacter based off a copy of the given puaChar.
		/// </summary>
		/// <param name="puaChar"></param>
		public UCDCharacter(PUACharacter puaChar) : base (puaChar)
		{
		}
Пример #6
0
		public void PuaWithPua()
		{
			PUACharacter otherPua = m_pua;
			Assert.AreEqual(0, m_comparer.Compare(m_pua, otherPua));

			otherPua = new PUACharacter("0669",
				"ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;");
			Assert.AreEqual(0, m_comparer.Compare(m_pua, otherPua));

			otherPua = new PUACharacter("004F", "LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F;");
			Assert.Greater(m_comparer.Compare(m_pua, otherPua), 0);

			otherPua = new PUACharacter("0668",
				"ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;;");
			Assert.Greater(m_comparer.Compare(m_pua, otherPua), 0);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Constructs a new list item for the PUACharacterDlg wrapped around <c>puaChar</c>
		/// </summary>
		/// <param name="puaChar">The PUACharacter that this represents.</param>
		/// <param name="fIsNew">Indicates whether the PUACharacter is a newly added one (not
		/// yet saved/installed).</param>
		/// ------------------------------------------------------------------------------------
		public PuaListItem(PUACharacter puaChar, bool fIsNew)
		{
			m_puaChar = puaChar;
			m_fIsNew = fIsNew;
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Get the cached character associated with the given codepoint
		/// </summary>
		/// <param name="codepoint">The integer codepoint of the cached character.</param>
		/// <returns>The character as a PUACharacter</returns>
		/// ------------------------------------------------------------------------------------
		public PUACharacter FindCachedIcuEntry(int codepoint)
		{
			CheckDisposed();

			//? Need to have at least 4 digits in the string.
			//? string codepointAsString = string.Format("{0:x4}", codepoint).ToUpper();
			string codepointAsString = codepoint.ToString("x").ToUpper();
			foreach (int[] range in m_cachedIcuRanges)
			{
				if (IsInRange(codepoint, range))
				{
					// If the range is not loaded, load it
					if (range[2]++ == 0)
						FillRange(range);
					return (PUACharacter)m_cachedIcu.Find(codepointAsString, new UCDComparer());
				}
			}

			// If we get here, we didn't find the codepoint
			PUACharacter newIcuChar = new PUACharacter(codepointAsString);
			// Load the character if it exists and has a name
			if (newIcuChar.RefreshFromIcu(false))
			{
				// This can be called from PuaCharacterDlg where m_cachedIcu has not been initialized.
				InitializeIcuCache();
				m_cachedIcu.Insert(newIcuChar);
				return newIcuChar;
			}

			return null;
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Displays the PUACharacterDlg dialog to edit the given <c>puaChar</c>.
		/// </summary>
		/// <param name="puaChar">The PUACharacter to edit.</param>
		/// <param name="modify"><c>true</c> if we are modifying an existing character rather
		///  than making a new one.</param>
		/// ------------------------------------------------------------------------------------
		private void DisplayPUACharacterDlg(PUACharacter puaChar, bool modify)
		{
			using (PUACharacterDlg puaDlg = CreatePUACharacterDlg())
			{
				puaDlg.PUAChar = puaChar;
				puaDlg.Modify = modify;
				puaDlg.SetDialogProperties(m_helpTopicProvider);
				puaDlg.ParentDialog = this;

				if (puaDlg.CallShowDialog() == DialogResult.OK)
				{
					// For the Add dialog, create a new list item
					if (!puaDlg.Modify)
					{
						// puaChar will be modified by the dialog box if the user presses okay
						PuaListItem puaLstItem = new PuaListItem(puaChar, true);
						m_lstPUACharacters.Items.Add(puaLstItem, true);
					}
					else
					{
						PuaListItem puaListItem = FindListItem(puaChar.CodePoint);
						if (puaListItem != null)
						{
							m_lstPUACharacters.SetItemChecked(
								m_lstPUACharacters.Items.IndexOf(puaListItem), true);
						}
					}
					// Mark the character as modified if they actually clicked okay.
					MarkAsModified(puaChar);
				}
			}
			m_lstPUACharacters.Refresh();
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Determines whether a Pua Character has already been defined for a certain codepoint
		/// </summary>
		/// <param name="puaChar">The codepoint you wish to check</param>
		/// <returns><c>true</c> if it contains codepoint, otherwise <c>false</c></returns>
		/// ------------------------------------------------------------------------------------
		public bool IsDefinedPuaCharacter(PUACharacter puaChar)
		{
			CheckDisposed();

			return IsDefinedPuaCharacter(puaChar.CodePoint);
		}
Пример #11
0
		/// <summary>
		/// Compares two PUACharacters to see if they are the same.
		/// </summary>
		/// <param name="puaChar">The second PUACharacter to compare with.</param>
		/// <returns><c>true</c> if the characters are identical.</returns>
		public bool Equals(PUACharacter puaChar)
		{
			return
				this.m_codepoint == puaChar.m_codepoint &&
				this.m_name == puaChar.m_name &&
				this.m_generalCategory.Equals(puaChar.m_generalCategory) &&
				this.m_canonicalCombiningClass.Equals(puaChar.m_canonicalCombiningClass) &&
				this.m_bidiClass.Equals(puaChar.m_bidiClass) &&
				this.m_decompositionType.Equals(puaChar.m_decompositionType) &&
				this.m_decomposition == puaChar.m_decomposition &&
				this.m_numericType == puaChar.m_numericType &&
				this.m_numericValue == puaChar.m_numericValue &&
				this.m_bidiMirrored.Equals(puaChar.m_bidiMirrored) &&
				this.m_unicode1Name == puaChar.m_unicode1Name &&
				this.m_isoComment == puaChar.m_isoComment &&
				this.m_upper == puaChar.m_upper &&
				this.m_lower == puaChar.m_lower &&
				this.m_title == puaChar.m_title;
		}
Пример #12
0
		/// <summary>
		/// Constructs a new BidiCharacter, copying all the values from <c>puaChar</c>
		/// </summary>
		/// <param name="puaChar"></param>
		public BidiCharacter(PUACharacter puaChar) : base(puaChar){}
Пример #13
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Assert that PUACharacter match what we expect.
		/// </summary>
		/// <param name="puaCharacterExpected">The expected PUACharacter</param>
		/// <param name="message">The message to append, e.g. "using the 'new' button"</param>
		/// <param name="wsPropsDlg">The ws props DLG.</param>
		/// ------------------------------------------------------------------------------------
		private void CheckPuaCharactersMatch(
			PUACharacter puaCharacterExpected, string message,
			DummyWritingSystemPropertiesDialog wsPropsDlg)
		{
			Assert.IsTrue(wsPropsDlg.IsPuaCodepointAdded(puaCharacterExpected.CodePoint),
				"Didn't add the PUACharacter " + puaCharacterExpected.CodePoint + " " + message);
			Assert.AreEqual(puaCharacterExpected.ToString(),
				wsPropsDlg.GetPuaString(puaCharacterExpected),
				"Didn't modify the PUACharacter " + message);
			Assert.IsTrue(wsPropsDlg.IsPuaAdded(puaCharacterExpected),
				"Didn't modify the PUACharacter " + message);
		}
Пример #14
0
		public void CreateNewPuaCharacterWithBadData()
		{
			PUACharacter newPuaChar =
				new PUACharacter("E000", "LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;0068;0664;0665");
			PUACharacter copyOfNewPuaChar =
				new PUACharacter("E000", "LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;0068;0664;0665");

			m_dlgWsProps.PressBtnNewPUA(newPuaChar);
			CheckPuaCharactersMatch(copyOfNewPuaChar, "using the 'new' button", m_dlgWsProps);

			PUACharacter modifiedPuaChar =
				new PUACharacter("E000", "CHEESE DIGIT THREE;Lu;0;AN;;3;3;3;N;;;0063;0664;0665");
			PUACharacter copyOfModifiedPuaChar = new PUACharacter(modifiedPuaChar);

			m_dlgWsProps.PressBtnModifyPUA(modifiedPuaChar);
			CheckPuaCharactersMatch(copyOfModifiedPuaChar, "using the 'modify' button",
				m_dlgWsProps);
		}
Пример #15
0
		public void DisabledFields()
		{
			PUACharacter newPuaChar =
				new PUACharacter("EABC", "arabic-indic digit three;Nd;0;AN;;3;3;3;N;;;ABBB;ABBB;ABBB");
			PUACharacter correctedPuaChar =
				new PUACharacter("EABC", "ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;;");

			PUACharacterDlg newDlgBox = new PUACharacterDlg();

			//			m_puaChar.GeneralCategory = newDlgBoxSelectedItem;

			m_dlgWsProps.PressBtnNewPUA(newPuaChar);

			//			PUACharacterDlg
			CheckPuaCharactersMatch(correctedPuaChar, "when setting the general category...",
				m_dlgWsProps);
		}
Пример #16
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Returns a list of the user defined custom characters in ICU by scanning the Unicode data file.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public static List<PUACharacter> GetDefinedCustomPUACharsFromICU()
		{
			List<PUACharacter> definedChars = new List<PUACharacter>();

			string uniData = DirectoryFinder.GetIcuDirectory; // "c:\\work\\fw60\\distfiles\\Icu40\\icudt40l\\"
			uniData = uniData.Substring(0, uniData.LastIndexOf(@"\icudt"));
			uniData = Path.Combine(uniData, @"data\unidata\UnicodeData.txt");
			StreamReader reader = new StreamReader(uniData, System.Text.Encoding.ASCII);
			int chT = reader.Peek();	// force autodetection of encoding.
			try
			{
				string line;
				while((line = reader.ReadLine()) != null)
				{
					// skip entirely blank lines
					if(line.Length <= 0)
						continue;

					if (line.IndexOf("User Added") != -1)
					{
						PUACharacter puaChar = new PUACharacter("0000");
						string codepoint = line.Substring(0, line.IndexOf(';')).Trim();
						puaChar.CodePoint = codepoint;
						puaChar.RefreshFromIcu(false);
						definedChars.Add(puaChar);
					}
				}
			}
			finally
			{
				reader.Close();
			}

			// REVIEW (TimS/EberhardB): We don't think we should call GC.Collect().
			// If there seems to be a need for it, then we probably need to call
			// Dispose() on one of the variables we want disposed.
			GC.Collect();

			return definedChars;
		}
Пример #17
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Makes sure that if the specified codepoint is a custom PUA character, that that
		/// character is added to the language definition's PUA collection.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		private static void UpdateLangDefPUACollection(int codepoint,
			LanguageDefinition langDef, List<PUACharacter> customPuaCharacters)
		{
			// Go through all the custom defined PUA characters in ICU and make sure that if
			// our codepoint is one of them, the language definition contains our codepoint
			// in its collection of PUA characters.
			foreach (PUACharacter customChar in customPuaCharacters)
			{
				string sCodePoint = codepoint.ToString("x4").ToUpperInvariant();

				// Is our codepoint one of the custom PUA characters? If so,
				// add it to the language definition's PUA collection.
				if (sCodePoint == customChar.CodePoint)
				{
					PUACharacter puaChar = new PUACharacter(sCodePoint);
					puaChar.RefreshFromIcu(false);
					langDef.AddPuaDefinition(codepoint, puaChar.ToString());
				}
			}
		}
Пример #18
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Determines whether or not the specified codepoint is defined in ICU. If it is and
		/// its a custom PUA character, then make sure the language definition's PUA character
		/// collection is updated. Return false if the codepoint is not defined in ICU.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		private static bool IsCodePointDefined(int codepoint)
		{
			PUACharacter puaChar = new PUACharacter(codepoint);
			try
			{
				// If the definition doesn't exist in ICU or the character has no name then
				// it's undefined and shouldn't be allowed in the valid characters list.
				if (!puaChar.RefreshFromIcu(false) || puaChar.Name.Length == 0)
					return false;

				// If the ICU category is one of the "Other" categories, then it's
				// undefined and shouldn't be allowed in the valid characters list.
				string ucdrep = puaChar.GeneralCategory.UcdRepresentation;
				ucdrep = ucdrep.ToUpperInvariant();

				// TODO: When tabs are supported, then allow them (they are in category Cc).
				// See TE-3004.
				if (ucdrep[0] == 'C' && ucdrep[1] != 'F')
					return false;
			}
			catch
			{
				return false;
			}

			return true;
		}
Пример #19
0
		/// <summary>
		/// Constructs a new Normalization character with the given normalization property.
		/// </summary>
		/// <param name="puaChar"></param>
		/// <param name="property"></param>
		public NormalizationCharacter(PUACharacter puaChar, string property) : base(puaChar)
		{
			this.property = property;
		}
Пример #20
0
		public void PuaCharacterTextConstructor()
		{
			PUACharacter puaCharacter = new PUACharacter("0669", "ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;");
		}
Пример #21
0
		/// <summary>
		/// Copy data from the given PUACharacter
		/// </summary>
		/// <param name="sourcePuaChar">The character to copy.</param>
		public void Copy(PUACharacter sourcePuaChar)
		{
			this.CodePoint = sourcePuaChar.m_codepoint;
			this.Name = sourcePuaChar.m_name;
			this.m_generalCategory = sourcePuaChar.m_generalCategory;
			this.m_canonicalCombiningClass = sourcePuaChar.m_canonicalCombiningClass;
			this.m_bidiClass = sourcePuaChar.m_bidiClass;
			this.m_decompositionType = sourcePuaChar.m_decompositionType;
			this.m_decomposition = sourcePuaChar.m_decomposition;
			this.m_numericType = sourcePuaChar.m_numericType;
			this.m_numericValue = sourcePuaChar.m_numericValue;
			this.m_bidiMirrored = sourcePuaChar.m_bidiMirrored;
			this.m_unicode1Name = sourcePuaChar.m_unicode1Name;
			this.m_isoComment = sourcePuaChar.m_isoComment;
			this.m_upper = sourcePuaChar.m_upper;
			this.m_lower = sourcePuaChar.m_lower;
			this.m_title = sourcePuaChar.m_title;
		}
		/// --------------------------------------------------------------------------------
		/// <summary>
		/// Tests the "Modify" button.
		/// </summary>
		/// <param name="puaChar">The pua char.</param>
		/// --------------------------------------------------------------------------------
		public void PressBtnModifyPUA(PUACharacter puaChar)
		{
			CheckDisposed();

			// Set the test pua character used to hold all the information to enter.
			// NOTE: This is never used directly,
			//       it is only used to hold values to be copied one at time
			DummyPUACharacterDlg.TestPuaCharacter = puaChar;
			// Select puaChar in the list
			foreach (PuaListItem pualistItem in m_lstPUACharacters.Items)
			{
				if (pualistItem.PUAChar.CodePoint == puaChar.CodePoint)
				{
					m_lstPUACharacters.SelectedItem = pualistItem;
					break;
				}
			}
			// "click" modify
			m_btnModifyPUA_Click(null, null);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Finds the given PUACharacter via its codepoint and sets it as modified.
		/// </summary>
		/// <param name="puaChar">The PUACharacter to mark as modified</param>
		/// ------------------------------------------------------------------------------------
		public void MarkAsModified(PUACharacter puaChar)
		{
			CheckDisposed();

			PuaListItem puaListItem = FindListItem(puaChar.CodePoint);
			if (puaListItem != null)
			{
				puaListItem.Modified = true;
				// Update the underlying LD data
				m_langDefCurrent.RemovePuaDefinition(puaListItem.PUAChar.CharDef);
				m_langDefCurrent.AddPuaDefinition(puaListItem.PUAChar.CharDef);
			}
		}
		/// --------------------------------------------------------------------------------
		/// <summary>
		/// Gets the PUA character as string
		/// </summary>
		/// <param name="addedPuaChar">The PUACharacter that was added.</param>
		/// <returns>
		/// </returns>
		/// --------------------------------------------------------------------------------
		public string GetPuaString(PUACharacter addedPuaChar)
		{
			CheckDisposed();

			foreach (PuaListItem pualistItem in m_lstPUACharacters.Items)
			{
				// Find the PUACharacter in the list.
				if (pualistItem.PUAChar.CodePoint == addedPuaChar.CodePoint)
				{
					// Return the value of the actual PUACharacter that is in the list
					return pualistItem.PUAChar.ToString();
				}
			}
			return "No PUACharacter found";
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		///
		/// </summary>
		/// ------------------------------------------------------------------------------------
		private void FillRange(int[] range)
		{
			// Makes a new empty Icu Cache, if it doesn't already exist
			InitializeIcuCache();

			PUACharacter newIcuChar;

			for (int codepoint = range[0]; codepoint <= range[1]; codepoint++)
			{
				// TODO: Make sure that leaving off leading zeros is okay.
				newIcuChar = new PUACharacter(codepoint.ToString("x").ToUpper());
				// Fill in the character from the ICU database.
				newIcuChar.RefreshFromIcu(true);
				// Add the character to the cache
				m_cachedIcu.Insert(newIcuChar);

				// REVIEW (TimS/EberhardB): We don't think we should call GC.Collect().
				// If there seems to be a need for it, then we probably need to call
				// Dispose() on one of the variables we want disposed.
				if (codepoint % 0x100 == 0)
					GC.Collect();
			}
		}
		/// --------------------------------------------------------------------------------
		/// <summary>
		/// Selectes the given PUACharacter via its codepoint from the list
		/// </summary>
		/// <param name="puaChar">The pua char.</param>
		/// --------------------------------------------------------------------------------
		public void SelectPuaCharacter(PUACharacter puaChar)
		{
			CheckDisposed();

			foreach (PuaListItem puaListItem in m_lstPUACharacters.Items)
			{
				// Find the PUACharacter in the list.
				if (puaListItem.PUAChar.CodePoint == puaChar.CodePoint)
				{
					// Return the value of the actual PUACharacter that is in the list
					m_lstPUACharacters.SelectedItem = puaListItem;
					break;
				}
			}
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Constructs a new list item for the PUACharacterDlg wrapped around <c>puaChar</c>
		/// </summary>
		/// <param name="puaChar">The PUACharacter that this represents.</param>
		/// ------------------------------------------------------------------------------------
		public PuaListItem(PUACharacter puaChar) : this(puaChar, false)
		{
		}
		/// --------------------------------------------------------------------------------
		/// <summary>
		/// Tests to see if a PUACharacter with the given codepoint was added to m_lstPUACharacters
		/// and that it has the same properties.
		/// </summary>
		/// <param name="addedPuaChar">The PUACharacter that was added.</param>
		/// <returns>
		/// 	<c>true</c> if the character is found and it matches.
		/// </returns>
		/// --------------------------------------------------------------------------------
		public bool IsPuaAdded(PUACharacter addedPuaChar)
		{
			CheckDisposed();

			foreach (PuaListItem pualistItem in m_lstPUACharacters.Items)
			{
				// Find the PUACharacter in the list.
				if (pualistItem.PUAChar.CodePoint == addedPuaChar.CodePoint)
					return pualistItem.PUAChar.Equals(addedPuaChar);
			}
			return false;
		}
Пример #29
0
		public void PopulateFromLanguageClass()
		{
			//Extracts the locale filename from a given path
			int icuName = m_inputFilename.LastIndexOf("\\");
			string icuPortion = m_inputFilename.Substring(icuName+1);

			//Appears this maps the XML file to a LanguageDefinition class
			/////////////////
			ILgWritingSystemFactory wsf = LgWritingSystemFactoryClass.Create();

			LanguageDefinitionFactory langDefFactory = new LanguageDefinitionFactory(wsf, icuPortion);

			LanguageDefinition langDef = langDefFactory.InitializeFromXml(wsf, icuPortion) as LanguageDefinition;
			if (langDef == null)
			{
				throw new Exception("Unable to read and parse the input XML file " + m_inputFilename);
			}
			/////////////////

			int i=0;
			int cpua = langDef.PuaDefinitionCount;
			// if we have PUA characters in the LD file make an array of PUACharacters.  But be careful
			// to handle invalid definitions gracefully.
			if (langDef.PuaDefinitions != null && cpua != 0)
			{
				puaChars = new PUACharacter[cpua];
				foreach (CharDef charDef in langDef.PuaDefinitions)
				{
					try
					{
						puaChars[i] = new PUACharacter(charDef);
						++i;
					}
					catch
					{
					}
				}
			}
			if (i < cpua)
			{
				if (i == 0)
				{
					puaChars = null;
				}
				else
				{
					PUACharacter[] puaGoodChars = new PUACharacter[i];
					for (int ic = 0; ic < i; ++ic)
						puaGoodChars[ic] = puaChars[ic];
					puaChars = puaGoodChars;
				}
				if (LogFile.IsLogging())
					LogFile.AddErrorLine("Warning, " + (cpua - i) + " out of " + cpua +
						" PUA character definitions are invalid.");
			}
			baseLocale = langDef.BaseLocale;
			newLocale = langDef.XmlWritingSystem.WritingSystem.IcuLocale;
			localeResources = langDef.LocaleResources;
			// Get the collation elements, whether from the CollationElements element directly,
			// or from the WritingSystem element.
			collationElements = langDef.CollationElements;
			if (collationElements == null)
			{
				IWritingSystem lws = langDef.WritingSystem;
				int ccoll = lws.CollationCount;
				if (ccoll > 0)
					collationElements = lws.get_Collation(0).IcuRules;
			}
			localeWinLCID = langDef.XmlWritingSystem.WritingSystem.Locale.ToString();

			// make sure the newlocale has the proper case for each property:
			// lang, country and variant
			InstallLanguage.LocaleParser lp = new LocaleParser(newLocale);
			newLocale = lp.Locale;

			// Make sure the display names [Name, Country & Variant] have Unicode characters
			// greater than 7F converted to the \uxxxx format where xxxx is the unicode
			// hex value of the character.
			localeName    = ConvertToUnicodeNotation(langDef.LocaleName);
			localeScript  = ConvertToUnicodeNotation(langDef.LocaleScript);
			localeCountry = ConvertToUnicodeNotation(langDef.LocaleCountry);
			localeVariant = ConvertToUnicodeNotation(langDef.LocaleVariant);

			// Save the multilingual names of the writing system, together with the
			// ICU locale for each name.
			NameMultiUnicode rgName = langDef.XmlWritingSystem.Name;
			int cws = rgName.Count;
			// If we don't have a name, use the IcuLocale rather than going without a name.
			// Otherwise it won't register as a language in en.txt/res.
			if (cws == 0)
			{
				StringWithWs sw = new StringWithWs(langDef.XmlWritingSystem.WritingSystem.IcuLocale, "en");
				rgName.Add(sw);
				cws = 1;
			}
			m_rgNames = new System.Collections.ArrayList(cws);
			for (int iws = 0; iws < cws; ++iws)
			{
				StringWithWs x = rgName[iws];
				m_rgNames.Add(x);
			}

			// TODO - dlh
			// Once collationElements are handled, something will have to be checked there
			// as the current implementation assumes that it's in the valid format.

			wsf.Shutdown();		// This is (always) needed to balance creating the factory.
		}
		/// --------------------------------------------------------------------------------
		/// <summary>
		/// Simulates pressing the "Add" button.
		/// </summary>
		/// <param name="puaChar">The pua char.</param>
		/// --------------------------------------------------------------------------------
		public void PressBtnNewPUA(PUACharacter puaChar)
		{
			CheckDisposed();

			// Set the test pua character used to hold all the information to enter.
			// NOTE: This is never used directly,
			//       it is only used to hold values to be copied one at time
			DummyPUACharacterDlg.TestPuaCharacter = puaChar;
			// "Click" new
			m_btnNewPUA_Click(null, null);
		}