Exemple #1
0
        /// <summary>
        /// Make the necessary Free Translation annotation comments for the specified group
        /// of roughly matching segments. In general, we transfer corresponding material from
        /// the BT segment to the FT annotation of the main paragraph segment, with any left-over
        /// paragraph segments blank, and any left-over BT segments added to the end of the
        /// last FT segment. As a special case, if some FTs at the end of the list already have the
        /// exact text of corresponding BT ones (counting from the end of the lists), we assume that
        /// those pairs correspond, even if not in corresponding positions counting from the start,
        /// and don't change them. This helps preserve alignment when something may merge or split
        /// a segment in the base text after much of it is annotated.
        /// </summary>
        /// <param name="igroup"></param>
        private void MakeSegmentBtsForGroup(int igroup)
        {
            SegGroup group = m_segGroups[igroup];

            // Discard any items at the end of both lists which already match exactly. Leave at least one in each group.
            DiscardMatchingSegsAtEnd(group);
            // The remaining (often all) segments are transferred one-for-one. (We don't need to check for
            // exactly matching ones at the start, because in that case, copying will be a no-op.)
            for (int iParaSeg = 0; iParaSeg < group.ParaSegs.Count; iParaSeg++)
            {
                int hvoFt = m_cache.GetObjProperty(group.ParaSegs[iParaSeg], kflidFT);
                // We may assume hvoFt is non-zero, because LoadSegmentFreeTranslations ensures every segment has one.
                CmIndirectAnnotation ft = CmObject.CreateFromDBObject(m_cache, hvoFt) as CmIndirectAnnotation;
                if (iParaSeg >= group.BtSegs.Count)
                {
                    // no more Bt segments, make the annotation FT empty (in case set previously).
                    // But don't overwrite if unchanged, since PropChanged can do a good deal of work
                    // and sometimes destroy selections we want to preserve.
                    if (ft.Comment.GetAlternative(m_wsBt).Length != 0)
                    {
                        ft.Comment.SetAlternative("", m_wsBt);
                    }
                    continue;
                }
                ITsString tssFt = group.BtSegs[iParaSeg].Text;
                tssFt = InsertOrphanBtFromPreviousGroup(igroup, iParaSeg, tssFt);
                tssFt = AppendLeftoverBtToLastSeg(group, iParaSeg, tssFt);
                // But don't overwrite if unchanged, since PropChanged can do a good deal of work
                // and sometimes destroy selections we want to preserve.
                if (!ft.Comment.GetAlternativeTss(m_wsBt).Equals(tssFt))
                {
                    ft.Comment.SetAlternative(tssFt, m_wsBt);
                }
            }
        }
Exemple #2
0
 /// <summary>
 /// If this paragraph segment is the last one for its group, but there are left-over BT segments,
 /// append them to this.
 /// </summary>
 /// <param name="group"></param>
 /// <param name="iParaSeg"></param>
 /// <param name="tssFt"></param>
 /// <returns></returns>
 private ITsString AppendLeftoverBtToLastSeg(SegGroup group, int iParaSeg, ITsString tssFt)
 {
     if (iParaSeg == group.ParaSegs.Count - 1 && iParaSeg < group.BtSegs.Count - 1)
     {
         // We have left over translations. Append them.
         ITsStrBldr bldr = tssFt.GetBldr();
         for (int j = iParaSeg + 1; j < group.BtSegs.Count; j++)
         {
             ITsString tssApp = group.BtSegs[j].Text;
             AppendWithOptionalSpace(bldr, tssApp);
         }
         tssFt = bldr.GetString();
     }
     return(tssFt);
 }
Exemple #3
0
 /// <summary>
 /// If this is the first segment in the group and NOT the first group, check for the possibility that
 /// there was no segment to attach the previous group's BTs to. I think this can only
 /// happen for the first group. Put the orphan BT at the start of this segment so it isn't lost.
 /// </summary>
 /// <param name="igroup"></param>
 /// <param name="iParaSeg"></param>
 /// <param name="tssFt"></param>
 /// <returns></returns>
 private ITsString InsertOrphanBtFromPreviousGroup(int igroup, int iParaSeg, ITsString tssFt)
 {
     if (iParaSeg == 0 && igroup > 0 && m_segGroups[igroup - 1].ParaSegs.Count == 0)
     {
         ITsStrBldr bldr      = TsStrBldrClass.Create();
         SegGroup   prevGroup = m_segGroups[igroup - 1];
         for (int j = 0; j < prevGroup.BtSegs.Count; j++)
         {
             AppendWithOptionalSpace(bldr, prevGroup.BtSegs[j].Text);
         }
         AppendWithOptionalSpace(bldr, tssFt);
         tssFt = bldr.GetString();
     }
     return(tssFt);
 }
Exemple #4
0
        // Discard any items at the end of both lists which already match exactly. Leave at least one in each group.
        private void DiscardMatchingSegsAtEnd(SegGroup group)
        {
            int ipara  = group.ParaSegs.Count - 1;
            int itrans = group.BtSegs.Count - 1;

            while (ipara > 0 && itrans > 0)
            {
                // See if the existing FT matches
                string desiredFT        = group.BtSegs[itrans].Text.Text;
                int    hvoFt            = m_cache.GetObjProperty(group.ParaSegs[ipara], kflidFT);
                CmIndirectAnnotation ft = CmObject.CreateFromDBObject(m_cache, hvoFt) as CmIndirectAnnotation;
                string currentFT        = ft.Comment.GetAlternative(m_wsBt).Text;
                if (desiredFT != currentFT)
                {
                    break;
                }
                // The two last items are already identical, don't need to do anything more about them.
                group.BtSegs.RemoveAt(itrans);
                group.ParaSegs.RemoveAt(ipara);
                itrans--;
                ipara--;
            }
        }
Exemple #5
0
        /// <summary>
        /// We have determined that corresponding groups start at iStartSegPara in m_paraSegs/m_segments and
        /// iStartSegBt in m_BtSegs. Make a SegGroup out of the corresponding segments and return the
        /// index of the indexes of the starts of the next group (in each case one more than the index of
        /// the matching verse segment which ended the group in the paragraph sequence). One or both indexes might
        /// be greater than the length of the corresponding array, indicating that the group extends to the end.
        /// One or both parts of the group might be empty.
        /// </summary>
        /// <returns>start index of next para segment (and next BT one in startOfNextBtSeg)</returns>
        int MakeGroup(int iStartSegPara, int iStartSegBt, out int startOfNextBtSeg)
        {
            SegGroup group = new SegGroup();

            m_segGroups.Add(group);
            int iLimSegPara = iStartSegPara;

            startOfNextBtSeg = -1;
            for (; iLimSegPara < m_paraSegs.Length; iLimSegPara++)
            {
                // The group also ends here if it is a CV-styled run and we can find a matching one in the BT.
                if (m_labelSegIndexes.Contains(iLimSegPara))
                {
                    ICmBaseAnnotation seg     = m_segments[iLimSegPara];
                    string            targetT = ConvertedBtLabel(seg);
                    startOfNextBtSeg = IndexOfMatchingVerseInBt(targetT);
                    if (startOfNextBtSeg >= 0)
                    {
                        startOfNextBtSeg++;                         // actual contents starts AFTER the common label
                        break;
                    }
                }
            }
            // Make the group's ParaSegs be the non-label segments from the range we decided.
            List <int> paraSegs = new List <int>(iLimSegPara - iStartSegPara);

            for (int i = iStartSegPara; i < iLimSegPara; i++)
            {
                if (!m_labelSegIndexes.Contains(i))
                {
                    paraSegs.Add(m_paraSegs[i]);
                }
            }
            group.ParaSegs = paraSegs;
            group.BtSegs   = GetSegGroup(iStartSegBt);
            return(iLimSegPara + 1);
        }
Exemple #6
0
		/// <summary>
		/// We have determined that corresponding groups start at iStartSegPara in m_paraSegs/m_segments and
		/// iStartSegBt in m_BtSegs. Make a SegGroup out of the corresponding segments and return the
		/// index of the indexes of the starts of the next group (in each case one more than the index of
		/// the matching verse segment which ended the group in the paragraph sequence). One or both indexes might
		/// be greater than the length of the corresponding array, indicating that the group extends to the end.
		/// One or both parts of the group might be empty.
		/// </summary>
		/// <returns>start index of next para segment (and next BT one in startOfNextBtSeg)</returns>
		int MakeGroup(int iStartSegPara, int iStartSegBt, out int startOfNextBtSeg)
		{
			SegGroup group = new SegGroup();
			m_segGroups.Add(group);
			int iLimSegPara = iStartSegPara;
			startOfNextBtSeg = -1;
			for (; iLimSegPara < m_paraSegs.Length; iLimSegPara++)
			{
				// The group also ends here if it is a CV-styled run and we can find a matching one in the BT.
				if (m_labelSegIndexes.Contains(iLimSegPara))
				{
					ICmBaseAnnotation seg = m_segments[iLimSegPara];
					string targetT = ConvertedBtLabel(seg);
					startOfNextBtSeg = IndexOfMatchingVerseInBt(targetT);
					if (startOfNextBtSeg >= 0)
					{
						startOfNextBtSeg++; // actual contents starts AFTER the common label
						break;
					}
				}
			}
			// Make the group's ParaSegs be the non-label segments from the range we decided.
			List<int> paraSegs = new List<int>(iLimSegPara - iStartSegPara);
			for (int i = iStartSegPara; i < iLimSegPara; i++)
			{
				if (!m_labelSegIndexes.Contains(i))
					paraSegs.Add(m_paraSegs[i]);
			}
			group.ParaSegs = paraSegs;
			group.BtSegs = GetSegGroup(iStartSegBt);
			return iLimSegPara + 1;
		}
Exemple #7
0
		/// <summary>
		/// If this paragraph segment is the last one for its group, but there are left-over BT segments,
		/// append them to this.
		/// </summary>
		/// <param name="group"></param>
		/// <param name="iParaSeg"></param>
		/// <param name="tssFt"></param>
		/// <returns></returns>
		private ITsString AppendLeftoverBtToLastSeg(SegGroup group, int iParaSeg, ITsString tssFt)
		{
			if (iParaSeg == group.ParaSegs.Count - 1 && iParaSeg < group.BtSegs.Count - 1)
			{
				// We have left over translations. Append them.
				ITsStrBldr bldr = tssFt.GetBldr();
				for (int j = iParaSeg + 1; j < group.BtSegs.Count; j++)
				{
					ITsString tssApp = group.BtSegs[j].Text;
					AppendWithOptionalSpace(bldr, tssApp);
				}
				tssFt = bldr.GetString();
			}
			return tssFt;
		}
Exemple #8
0
		// Discard any items at the end of both lists which already match exactly. Leave at least one in each group.
		private void DiscardMatchingSegsAtEnd(SegGroup group)
		{
			int ipara = group.ParaSegs.Count - 1;
			int itrans = group.BtSegs.Count - 1;
			while (ipara > 0 && itrans > 0)
			{
				// See if the existing FT matches
				string desiredFT = group.BtSegs[itrans].Text.Text;
				int hvoFt = m_cache.GetObjProperty(group.ParaSegs[ipara], kflidFT);
				CmIndirectAnnotation ft = CmObject.CreateFromDBObject(m_cache, hvoFt) as CmIndirectAnnotation;
				string currentFT = ft.Comment.GetAlternative(m_wsBt).Text;
				if (desiredFT != currentFT)
					break;
				// The two last items are already identical, don't need to do anything more about them.
				group.BtSegs.RemoveAt(itrans);
				group.ParaSegs.RemoveAt(ipara);
				itrans--;
				ipara--;
			}
		}