static protected XmlNode GetStTxtParaDefnNode(FDO.IText text, XmlNode textsDefn, int iPara, out IStTxtPara para)
			{
				para = text.ContentsOA.ParagraphsOS[iPara] as IStTxtPara;
				Debug.Assert(para != null);
				if (textsDefn == null)
					return null;
				XmlNode paraNode = textsDefn.SelectSingleNode("//StTxtPara[@id='" + para.Hvo + "']");
				if (paraNode == null)
				{
					// see if we can find a new node that for which we haven't determined its hvo.
					paraNode = textsDefn.SelectSingleNode("//StTxtPara[" + (iPara + 1) + "]");
					// the paragraph shouldn't have an hvo yet.
					if (paraNode.Attributes["id"].Value == "")
					{
						// go ahead and set the hvo now.
						paraNode.Attributes["id"].Value = para.Hvo.ToString();
					}
					else
					{
						paraNode = null;
					}
				}
				return paraNode;
			}
			IStText CreateContents(FDO.IText text)
			{
				Debug.Assert(text != null);
				IStText body1 = m_cache.ServiceLocator.GetInstance<IStTextFactory>().Create();
				text.ContentsOA = body1;
				return body1;
			}
		/// <summary>
		/// Attempt to populate a new FieldWorks text with a BIRD format interlinear text. If this fails
		/// for some reason then the new text is deleted and also return false to tell the calling method to abort the import.
		/// </summary>
		/// <param name="options"></param>
		/// <param name="newText"></param>
		/// <param name="interlineartext"></param>
		/// <param name="progress"></param>
		/// <param name="version"></param>
		/// <returns>true if operation completed, false if the import operation should be aborted</returns>
		private bool PopulateTextIfPossible(ImportInterlinearOptions options, ref FDO.IText newText, Interlineartext interlineartext,
												IThreadedProgress progress, int version)
		{
			if (!PopulateTextFromBIRDDoc(ref newText,
					new TextCreationParams
					{
						Cache = m_cache,
						InterlinText = interlineartext,
						Progress = progress,
						ImportOptions = options,
						Version = version
					})) //if the user aborted this text
			{
				newText.Delete(); //remove it from the list
				return false;
			}
			return true;
		}
			internal ParagraphBuilder(XmlNode textsDefn, FDO.IText text, int iPara)
			{
				IStTxtPara para;
				m_paraDefn = GetStTxtParaDefnNode(text, textsDefn, iPara, out para);
				m_para = para;
				m_cache = para.Cache;
			}
		public bool ImportInterlinear(IThreadedProgress progress, Stream birdData, int allottedProgress, ref FDO.IText firstNewText)
		{
			return ImportInterlinear(new ImportInterlinearOptions { Progress = progress, BirdData = birdData, AllottedProgress = allottedProgress },
				ref firstNewText);
		}
		/// <summary>
		/// Import a file which looks like a FieldWorks interlinear XML export. This file can contain many interlinear texts.
		/// If a text was previously imported then attempt to merge it. If a text has not been imported before then a new text
		/// is created and it is poplulated with the input if possible.
		/// </summary>
		/// <param name="options"></param>
		/// <param name="firstNewText"></param>
		/// <returns>return false to abort merge</returns>
		public bool ImportInterlinear(ImportInterlinearOptions options, ref FDO.IText firstNewText)
		{
			IThreadedProgress progress = options.Progress;
			Stream birdData = options.BirdData;
			int allottedProgress = options.AllottedProgress;

			bool mergeSucceeded = false;
			bool continueMerge = false;
			firstNewText = null;
			BIRDDocument doc;
			int initialProgress = progress.Position;
			try
			{
				m_cache.DomainDataByFlid.BeginNonUndoableTask();
				progress.Message = ITextStrings.ksInterlinImportPhase1of2;
				var serializer = new XmlSerializer(typeof(BIRDDocument));
				doc = (BIRDDocument)serializer.Deserialize(birdData);
				Normalize(doc);
				int version = 0;
				if (!string.IsNullOrEmpty(doc.version))
					int.TryParse(doc.version, out version);
				progress.Position = initialProgress + allottedProgress / 2;
				progress.Message = ITextStrings.ksInterlinImportPhase2of2;
				if (doc.interlineartext != null)
				{
					int step = 0;
					foreach (var interlineartext in doc.interlineartext)
					{
						step++;
						ILangProject langProject = m_cache.LangProject;
						FDO.IText newText = null;
						if (!String.IsNullOrEmpty(interlineartext.guid))
						{
							ICmObject repoObj;
							m_cache.ServiceLocator.ObjectRepository.TryGetObject(new Guid(interlineartext.guid), out repoObj);
							newText = repoObj as FDO.IText;
							if (newText != null && ShowPossibleMergeDialog(progress) == DialogResult.Yes)
							{
								continueMerge = MergeTextWithBIRDDoc(ref newText,
												new TextCreationParams
												{
													Cache = m_cache,
													InterlinText = interlineartext,
													Progress = progress,
													ImportOptions = options,
													Version = version
												});
							}
							else if (newText == null)
							{
								newText = m_cache.ServiceLocator.GetInstance<ITextFactory>().Create(m_cache, new Guid(interlineartext.guid));
								continueMerge = PopulateTextIfPossible(options, ref newText, interlineartext, progress, version);
							}
							else //user said do not merge.
							{
								//ignore the Guid; we shouldn't create another text with the same guid
								newText = m_cache.ServiceLocator.GetInstance<ITextFactory>().Create();
								continueMerge = PopulateTextIfPossible(options, ref newText, interlineartext, progress, version);
							}
						}
						else
						{
							newText = m_cache.ServiceLocator.GetInstance<ITextFactory>().Create();
							continueMerge = PopulateTextIfPossible(options, ref newText, interlineartext, progress, version);
						}
						if (!continueMerge)
							break;
						progress.Position = initialProgress + allottedProgress/2 + allottedProgress*step/2/doc.interlineartext.Length;
						if (firstNewText == null)
							firstNewText = newText;

					}
					mergeSucceeded = continueMerge;

				}
			}
			catch (Exception e)
			{
				Debug.Print(e.Message);
				Debug.Print(e.StackTrace);
			}
			finally
			{
				m_cache.DomainDataByFlid.EndNonUndoableTask();
			}
			return mergeSucceeded;
		}
		/// <summary>
		/// Set text metadata, create or merge media file URI's.
		/// <note>media files (ELAN initiated) need to be processed before the paragraphs, as segments could reference these parts.</note>
		/// </summary>
		/// <param name="cache"></param>
		/// <param name="interlinText">The source text</param>
		/// <param name="wsFactory"></param>
		/// <param name="newText">The target text</param>
		/// <param name="merging">True if we are merging into an existing text; False if we are creating everything new</param>
		private static void SetTextMetaAndMergeMedia(FdoCache cache, Interlineartext interlinText, ILgWritingSystemFactory wsFactory,
			FDO.IText newText, bool merging)
		{
			if (interlinText.Items != null) // apparently it is null if there are no items.
			{
				foreach (var item in interlinText.Items)
				{
					switch (item.type)
					{
						case "title":
							newText.Name.set_String(GetWsEngine(wsFactory, item.lang).Handle, item.Value);
							break;
						case "title-abbreviation":
							newText.Abbreviation.set_String(GetWsEngine(wsFactory, item.lang).Handle, item.Value);
							break;
						case "source":
							newText.Source.set_String(GetWsEngine(wsFactory, item.lang).Handle, item.Value);
							break;
						case "comment":
							newText.Description.set_String(GetWsEngine(wsFactory, item.lang).Handle, item.Value);
							break;
					}
				}
			}

			if (interlinText.mediafiles != null)
			{
				if (newText.MediaFilesOA == null)
					newText.MediaFilesOA = cache.ServiceLocator.GetInstance<ICmMediaContainerFactory>().Create();
				newText.MediaFilesOA.OffsetType = interlinText.mediafiles.offsetType;

				foreach (var mediaFile in interlinText.mediafiles.media)
				{
					ICmObject extantObject;
					cache.ServiceLocator.ObjectRepository.TryGetObject(new Guid(mediaFile.guid), out extantObject);
					var media = extantObject as ICmMediaURI;
					if (media == null)
					{
						media = cache.ServiceLocator.GetInstance<ICmMediaURIFactory>().Create(cache, new Guid(mediaFile.guid));
						newText.MediaFilesOA.MediaURIsOC.Add(media);
					}
					else if (!merging)
					{
						// If a media URI with the same GUID exists, and we are not merging, create a new media URI with a new GUID
						media = cache.ServiceLocator.GetInstance<ICmMediaURIFactory>().Create();
						newText.MediaFilesOA.MediaURIsOC.Add(media);

						// Update references to this Media URI
						foreach (var phrase in interlinText.paragraphs.SelectMany(para => para.phrases))
						{
							if (mediaFile.guid.Equals(phrase.mediaFile))
								phrase.mediaFile = media.Guid.ToString();
						}
					}
					// else, the media URI already exists and we are merging; simply update the location
					media.MediaURI = mediaFile.location;
				}
			}
		}
Exemple #8
0
/*		private Sfm2Xml.LexImportField FieldDescriptionToLexImportField(FieldDescription fd)
		{
			string sig = "";
			if (fd.Type == 16 || fd.Type == 20)
				sig = "MultiUnicode";
			else if (fd.Type == 13 || fd.Type == 17)
				sig = "String";
			else
			{
				throw new Exception("Error converting custom field to LexImportField - unexpected signature");
			}

			Sfm2Xml.LexImportField lif = new Sfm2Xml.LexImportField(
				fd.Name,
				fd.Userlabel,
				fd.Name,
				sig,
				false,
				(sig=="MultiUnicode")?true:false,
				false,
				"MDFVALUE");

			return lif;
		}
*/
		private void GetCustomFields(FDO.FdoCache cache)
		{
			// m_CustomFields
			// FieldDescription.ClearDataAbout(m_cache);
			foreach (FieldDescription fd in FieldDescription.FieldDescriptors(cache))
			{
				if (fd.IsCustomField && fd.Class > 4999 && fd.Class < 6000)
				{
					// As per LT-7462, limit displayed fields to ones with classes
					// from module 5 (5000-5999) - GordonM

					//m_CustomFields.AddField(fd.Class.ToString(), "Entry",
					//    new Sfm2Xml.LexImportField(
					// m_customFields.Add(new FDWrapper(fd, true));
					int asdf = 88;
					asdf++;
//					m_CustomFields.AddField("className", "partOf", FieldDescriptionToLexImportField(fd));
					// <Class name="Entry" partOf="records">
					// <Class name="Sense" partOf="Entry Subentry">
					// <Class name="Subentry" partOf="Entry">
					// <Class name="Variant" partOf="Entry Subentry Sense">

				}
			}
		}
		/// <summary>
		/// Merge the contents of the given Text into the exising one. If this fails
		/// for some reason then return false to tell the calling method to abort the import.
		/// </summary>
		/// <param name="newText"></param>
		/// <param name="textParams"></param>
		/// <returns>The imported text may be in a writing system that is not part of this project. Return false if the user
		/// rejects the text  which tells the caller of this method to abort the import.</returns>
		private static bool MergeTextWithBIRDDoc(ref FDO.IText newText, TextCreationParams textParams)
		{
			s_importOptions = textParams.ImportOptions;
			Interlineartext interlinText = textParams.InterlinText;
			FdoCache cache = textParams.Cache;
			IThreadedProgress progress = textParams.Progress;
			if (s_importOptions.CheckAndAddLanguages == null)
				s_importOptions.CheckAndAddLanguages = CheckAndAddLanguagesInternal;

			ILgWritingSystemFactory wsFactory = cache.WritingSystemFactory;
			char space = ' ';
			//handle the languages(writing systems) section alerting the user if new writing systems are encountered
			if (!s_importOptions.CheckAndAddLanguages(cache, interlinText, wsFactory, progress))
				return false;

			//handle the header(info or meta) information as well as any media-files sections
			SetTextMetaAndMergeMedia(cache, interlinText, wsFactory, newText, true);

			IStText newContents = null;
			//create all the paragraphs NOTE: Currently the paragraph guids are being ignored, this might be wrong.
			foreach (var paragraph in interlinText.paragraphs)
			{
				if (newContents == null)
				{
					newContents = cache.ServiceLocator.GetInstance<IStTextFactory>().Create();
					newText.ContentsOA = newContents;
				}
				IStTxtPara newTextPara = newContents.AddNewTextPara("");
				int offset = 0;
				if (paragraph.phrases == null)
				{
					continue;
				}
				foreach (var phrase in paragraph.phrases)
				{
					ICmObject oldSegment = null;
					//Try and locate a segment with this Guid.
					if(!String.IsNullOrEmpty(phrase.guid))
					{
						if (cache.ServiceLocator.ObjectRepository.TryGetObject(new Guid(phrase.guid), out oldSegment))
						{
							if (oldSegment as ISegment != null) //The segment matches, add it into our paragraph.
								newTextPara.SegmentsOS.Add(oldSegment as ISegment);
							else if(oldSegment == null) //The segment is identified by a Guid, but apparently we don't have it in our current document, so make one
								oldSegment = cache.ServiceLocator.GetInstance<ISegmentFactory>().Create(newTextPara, offset, cache, new Guid(phrase.guid));
							else //The Guid is in use, but not by a segment. This is bad.
							{
								return false;
							}
						}
					}
					//set newSegment to the old, or create a brand new one.
					ISegment newSegment = oldSegment as ISegment ?? cache.ServiceLocator.GetInstance<ISegmentFactory>().Create(newTextPara, offset);
					var tsStrFactory = cache.ServiceLocator.GetInstance<ITsStrFactory>();
					//Fill in the ELAN time information if it is present.
					AddELANInfoToSegment(cache, phrase, newSegment);

					ITsString phraseText = null;
					bool textInFile = false;
					//Add all of the data from <item> elements into the segment.
					AddSegmentItemData(cache, wsFactory, phrase, newSegment, tsStrFactory, ref textInFile, ref phraseText);

					bool lastWasWord = false;
					if (phrase.WordsContent != null && phrase.WordsContent.Words != null)
					{
						foreach (var word in phrase.WordsContent.Words)
						{
							//If the text of the phrase was not found in a "txt" item for this segment then build it from the words.
							if (!textInFile)
							{
								UpdatePhraseTextForWordItems(wsFactory, tsStrFactory, ref phraseText, word, ref lastWasWord, space);
							}
							MergeWordToSegment(newSegment, word, tsStrFactory);
						}
					}
					UpdateParagraphTextForPhrase(newTextPara, ref offset, phraseText);
				}
			}
			return true;
		}
		/// <summary>
		/// This method will create a new Text document from the given BIRD format Interlineartext. If this fails
		/// for some reason then return false to tell the calling method to abort the import.
		/// </summary>
		/// <param name="newText">The text to populate, could be set to null.</param>
		/// <param name="textParams">This contains the interlinear text.</param>
		/// <returns>The imported text may be in a writing system that is not part of this project. Return false if the user
		/// rejects the text which tells the caller of this method to abort the import.</returns>
		private static bool PopulateTextFromBIRDDoc(ref FDO.IText newText, TextCreationParams textParams)
		{
			s_importOptions = textParams.ImportOptions;
			Interlineartext interlinText = textParams.InterlinText;
			FdoCache cache = textParams.Cache;
			IThreadedProgress progress = textParams.Progress;
			if (s_importOptions.CheckAndAddLanguages == null)
				s_importOptions.CheckAndAddLanguages = CheckAndAddLanguagesInternal;

			ILgWritingSystemFactory wsFactory = cache.WritingSystemFactory;
			const char space = ' ';
			//handle the languages(writing systems) section alerting the user if new writing systems are encountered
			if (!s_importOptions.CheckAndAddLanguages(cache, interlinText, wsFactory, progress))
				return false;

			//handle the header(info or meta) information
			SetTextMetaAndMergeMedia(cache, interlinText, wsFactory, newText, false);

			//create all the paragraphs
			foreach (var paragraph in interlinText.paragraphs)
			{
				if (newText.ContentsOA == null)
				{
					newText.ContentsOA = cache.ServiceLocator.GetInstance<IStTextFactory>().Create();
				}
				IStTxtPara newTextPara = newText.ContentsOA.AddNewTextPara("");
				int offset = 0;
				if (paragraph.phrases == null)
				{
					continue;
				}
				foreach (var phrase in paragraph.phrases)
				{
					ICmObject oldSegment = null;
					//Try and locate a segment with this Guid.
					if (!String.IsNullOrEmpty(phrase.guid))
					{
						if (cache.ServiceLocator.ObjectRepository.TryGetObject(new Guid(phrase.guid), out oldSegment))
						{
							//We aren't merging, but we have this guid in our system; ignore the file Guid
							oldSegment = cache.ServiceLocator.GetInstance<ISegmentFactory>().Create(newTextPara, offset);
						}
						else
						{
							//The segment is identified by a Guid, but apparently we don't have it in our current document, so make one with the guid
							oldSegment = cache.ServiceLocator.GetInstance<ISegmentFactory>().Create(newTextPara, offset, cache,
																									new Guid(phrase.guid));
						}
					}
					//set newSegment to the old, or create a brand new one.
					ISegment newSegment = oldSegment as ISegment ?? cache.ServiceLocator.GetInstance<ISegmentFactory>().Create(newTextPara, offset);
					var tsStrFactory = cache.ServiceLocator.GetInstance<ITsStrFactory>();
					//Fill in the ELAN time information if it is present.
					AddELANInfoToSegment(cache, phrase, newSegment);
					ITsString phraseText = null;
					bool textInFile = false;
					//Add all of the data from <item> elements into the segment.
					AddSegmentItemData(cache, wsFactory, phrase, newSegment, tsStrFactory, ref textInFile, ref phraseText);
					bool lastWasWord = false;
					if (phrase.WordsContent != null && phrase.WordsContent.Words != null)
					{
						if (textParams.Version == 0 && PhraseHasExactlyOneTxtItemNotAKnownWordform(newSegment.Cache, phrase))
						{
							// It might be a SayMore text that makes the whole segment a single txt item.
							// We want to add the text anyway (unless a higher level did so), but we will skip making
							// a wordform. Eventual parsing of the text will do so.
							if (!textInFile)
							{
								UpdatePhraseTextForWordItems(wsFactory, tsStrFactory, ref phraseText, phrase.WordsContent.Words[0], ref lastWasWord, space);
							}
						}
						else
						{
							foreach (var word in phrase.WordsContent.Words)
							{
								//If the text of the phrase was not given in the document build it from the words.
								if (!textInFile)
								{
									UpdatePhraseTextForWordItems(wsFactory, tsStrFactory, ref phraseText, word, ref lastWasWord, space);
								}
								AddWordToSegment(newSegment, word, tsStrFactory);
							}
						}
					}
					UpdateParagraphTextForPhrase(newTextPara, ref offset, phraseText);
				}
			}
			return true;
		}
Exemple #11
0
		private XmlNode MakeCustomFieldNode(XmlDocument document, FDO.FieldDescription field)
		{
			XmlNode node = document.CreateElement("slice");
			AddAttribute(node, "field", field.Name);//e.g. "custom", "custom1", "custom2"
			AddAttribute(node, "classId", field.Class.ToString());
			AddAttribute(node, "label", field.Userlabel);
			AddAttribute(node, "menu", "mnuDataTree-Help");

			string strWs = "";
			string strEditor = "";
			switch(field.WsSelector)
			{
				case LangProject.kwsAnal:
					strWs = "analysis";
					strEditor = "string";
					break;
				case LangProject.kwsVern:
					strWs = "vernacular";
					strEditor = "string";
					break;
				case LangProject.kwsVerns:
					strWs = "all vernacular";
					strEditor = "multistring";
					break;
				case LangProject.kwsAnals:
					strWs = "all analysis";
					strEditor = "multistring";
					break;
				case LangProject.kwsAnalVerns:
					strWs = "analysis vernacular";
					strEditor = "multistring";
					break;
				case LangProject.kwsVernAnals:
					strWs = "vernacular analysis";
					strEditor = "multistring";
					break;
			}
			AddAttribute(node, "editor", strEditor);
			AddAttribute(node, "ws", strWs);
			return node;
		}
Exemple #12
0
		/// <summary>
		/// initialization for when you don't actually know what you want to show yet
		/// (and aren't going to use XML)
		/// </summary>
		/// <param name="cache"></param>
		/// <param name="fHasSplitter"></param>
		protected void InitializeBasic(FDO.FdoCache cache, bool fHasSplitter)
		{
			//in a normal user application, this auto menu handler will not be used.
			//instead, the client of this control will call SetContextMenuHandler()
			//with a customized handler.
			// m_autoHandler = new AutoDataTreeMenuHandler(this);
			// we never use auto anymore			SetContextMenuHandler(new SliceShowMenuRequestHandler(m_autoHandler.GetSliceContextMenu));

			// This has to be created before we start adding slices, so they can be put into it.
			// (Otherwise we would normally do this in initializeComponent.)
			m_fHasSplitter = fHasSplitter;
			m_mdc = cache.MetaDataCacheAccessor;
			m_cache = cache;
		}
			IStText CreateContents(FDO.IText text)
			{
				Debug.Assert(text != null);
				IStText body1 = new StText();
				text.ContentsOA = body1;
				return body1;
			}
		private static void VerifyMediaLink(FDO.IText imported)
		{
			var mediaFilesContainer = imported.MediaFilesOA;
			var para = imported.ContentsOA[0];
			Assert.NotNull(mediaFilesContainer, "Media Files not being imported.");
			Assert.AreEqual(1, mediaFilesContainer.MediaURIsOC.Count, "Media file not imported.");
			using (var enumerator = para.SegmentsOS.GetEnumerator())
			{
				enumerator.MoveNext();
				var seg = enumerator.Current;
				Assert.AreEqual("1", seg.BeginTimeOffset, "Begin offset not imported correctly");
				Assert.AreEqual("2", seg.EndTimeOffset, "End offset not imported correctly");
				Assert.AreEqual(seg.MediaURIRA, mediaFilesContainer.MediaURIsOC.First(), "Media not correctly linked to segment.");
			}
		}
		public void Init(Sfm2Xml.ClsInFieldMarker ifm, Hashtable uiLangsHT, FDO.FdoCache cache)
		{
			CheckDisposed();

			if (ifm == null)
				ifm = new Sfm2Xml.ClsInFieldMarker();

			m_inlineMarker = ifm;
			m_uiLangs = uiLangsHT;
			m_cache = cache;

			// ====================================================================
			// Set the language descriptor combo box.  This is a DropList so that
			// the entered text can't be different from the contents of the list.
			// If the user wants a new language descriptor they have to add one.

			cbLangDesc.Items.Add(NoChange);
			cbLangDesc.SelectedItem = NoChange;

			foreach (DictionaryEntry lang in m_uiLangs)
			{
				Sfm2Xml.LanguageInfoUI langInfo = lang.Value as Sfm2Xml.LanguageInfoUI;
				// make sure there is only one entry for each writing system (especially 'ignore')
				if (cbLangDesc.FindStringExact(langInfo.ToString()) < 0)
				{
					cbLangDesc.Items.Add(langInfo);
					if (langInfo.FwName == m_inlineMarker.Language)
						cbLangDesc.SelectedItem = langInfo;
				}
			}

			InitializeStylesComboBox();

			HideOKBtn();	// see if it needs to be visible or not
		}
Exemple #16
0
		IList m_items; // of IConcSliceInfo
		#endregion
		public MultiLevelConc(FDO.FdoCache cache, IList items)
		{
			m_items = items;
			InitializeBasic(cache, false);
			InitializeComponentBasic();

			// Can't add null controls to a parent control.
			//m_slices.AddRange(new Slice[items.Count]); // adds appropriate # nulls

			//			// Temporary: until I figure how to be lazy, we have to make slices
			//			// for all nodes.
			//			for (int i = 0; i < items.Count; i++)
			//				FieldAt(i);
		}
		public void Init(MarkerPresenter.ContentMapping currentMarker, Hashtable uiLangsHT, FDO.FdoCache cache)
		{
			CheckDisposed();

			m_uiLangs = uiLangsHT;
			m_cache = cache;

			// The following call is needed to 'correct' the current behavior of the FwOverrideComboBox control.
			// As the control is currently, it will not allow the space character to be passed to the base
			// control: which means it doesn't get into the edit box portion of the control. We want to allow
			// space characters in our data, so we're enabling it here. This seems like a bug in the control
			// design, but not knowing the history and it's use, we'll just make it work as we think it should
			// be for us here.
			cbFunction.AllowSpaceInEditBox = true;

			// handle processing for the custom fields (CFS)
			// - read the db and get the CFS
			// - remove CFS that are in the TV and not in the CFS list
			// - add CFS that are in the list and not in the TV
			// - handle the case where the current marker is a CF and it's no longer in the list (just throw for now)

			//ReadCustomFieldsFromDB(cache);
			bool customFieldsChanged = false;
			m_customFields = LexImportWizard.Wizard().ReadCustomFieldsFromDB(out customFieldsChanged);

			// Init will only be called the first time, so here we don't have to remove an nodes

			tvDestination.BeginUpdate();
			foreach (TreeNode classNameNode in tvDestination.Nodes)
			{
				string className = classNameNode.Text.Trim(new char[] {'(', ')'});
				if (m_customFields.FieldsForClass(className) == null)
					continue;

				foreach (Sfm2Xml.LexImportField field in m_customFields.FieldsForClass(className))
				{
					TreeNode cnode = new TreeNode(field.UIName + " (Custom Field)");
					cnode.Tag = field;
					classNameNode.Nodes.Add(cnode);
				}
				//tvDestination.Nodes.Add(tnode);
			}
			//tvDestination.ExpandAll();
			tvDestination.EndUpdate();

			// end of CFS processing

			// set the correct marker and number of times it is used
			m_lblMarker.Text = currentMarker.Marker;
			m_lblInstances.Text = String.Format(LexTextControls.ksXInstances, currentMarker.Count);

			if (currentMarker.AutoImport)
			{
				chkbxAutoField.Checked = true;
				tvDestination.Enabled = false;
			}

			// chkbxExclude.Checked = false;
			// tvDestination.Enabled = true;
			// find the node that has the tag.meaningid value the same as the currentmarker
			bool found = false;
			foreach (TreeNode classNode in tvDestination.Nodes)
			{
				if (currentMarker.ClsFieldDescription is Sfm2Xml.ClsCustomFieldDescription &&
					currentMarker.DestinationClass != classNode.Text.Trim(new char[] {'(', ')'}))
					continue;

				foreach (TreeNode fieldNode in classNode.Nodes)
				{
					if ((fieldNode.Tag as Sfm2Xml.LexImportField).ID == currentMarker.FwId)
					{
						tvDestination.SelectedNode = fieldNode;
						found = true;
						break;
					}
				}
				if (found)
					break;
			}
			if (!found && tvDestination.Nodes.Count > 0)	// make first entry topmost and visible
				tvDestination.Nodes[0].EnsureVisible();

			// set the writing system combo box
			foreach (DictionaryEntry lang in m_uiLangs)
			{
				Sfm2Xml.LanguageInfoUI langInfo = lang.Value as Sfm2Xml.LanguageInfoUI;
				// make sure there is only one entry for each writing system (especially 'ignore')
				if (cbLangDesc.FindStringExact(langInfo.ToString()) < 0)
				{
					cbLangDesc.Items.Add(langInfo);
					if (langInfo.FwName == currentMarker.WritingSystem)
						cbLangDesc.SelectedItem = langInfo;
				}
			}
			if (cbLangDesc.SelectedIndex < 0)
			{
				// default to ignore if it's in the list
				int ignorePos = cbLangDesc.FindStringExact(MarkerPresenter.ContentMapping.Ignore());
				if (ignorePos >= 0)
					cbLangDesc.SelectedIndex = ignorePos;
				else
					cbLangDesc.SelectedIndex = 0;	// first item in list as fail safe
			}

			// add the func if it's present
			m_refFuncString = string.Empty;
			if (currentMarker.IsRefField)
			{
				m_refFuncString = currentMarker.RefField;

				cbFunction.Enabled = true;

				TreeNode node = tvDestination.SelectedNode;
				if (node != null)
				{
					Sfm2Xml.LexImportField field = node.Tag as Sfm2Xml.LexImportField;
					if (field != null)
					{
						FillLexicalRefTypesCombo(field);
						// walk the name to abbr list and select the name
						string name = m_refFuncString;
						foreach (DictionaryEntry de in m_htNameToAbbr)
						{
							NameWSandAbbr nwsa = (NameWSandAbbr)de.Value;
							//if (de.Value as string == name)
							if (nwsa.abbr == name)
							{
								//name = de.Key as string;
								name = nwsa.name;	//.abbr;
								break;
							}
						}
						cbFunction.Text = name;
					}
				}
			}
			m_refFuncStringOrig = m_refFuncString;	// save the initial value

			// set the exclude chkbox and select item from FW Destination
			if (currentMarker.Exclude)// currentMarker.IsLangIgnore || // currentMarker.DestinationField == MarkerPresenter.ContentMapping.Ignore() ||
			{
				chkbxExclude.Checked = true;
				chkbxAutoField.Enabled = false;
				tvDestination.Enabled = false;
				EnableLangDesc(false);
			}

			rbAbbrName.Checked = true;
			if (currentMarker.IsAbbrvField)
			{
				// set the proper radio button
				if (currentMarker.ClsFieldDescription.IsAbbr)
					rbAbbrAbbr.Checked = true;
			}

			// LT-4722
			// btnAddCustomField.Visible = false;
		}