public void ParagraphBreak_RemoveCharStyleFromAdjacentWhiteSpace()
        {
            CheckDisposed();
            m_draftView.RefreshDisplay();

            // *** Test setup ***
            // Insert text with a character style.
            StTxtPara    para1   = (StTxtPara)m_exodus.SectionsOS[0].ContentOA.ParagraphsOS[0];
            ITsStrBldr   tssBldr = para1.Contents.UnderlyingTsString.GetBldr();
            ITsPropsBldr ttpBldr = TsPropsBldrClass.Create();

            ttpBldr.SetStrPropValue((int)FwTextPropType.ktptNamedStyle, "Emphasis");
            tssBldr.ReplaceRgch(15, 15, "really,  really", 6, ttpBldr.GetTextProps());
            int paraCount = m_exodus.SectionsOS[0].ContentOA.ParagraphsOS.Count;

            // Set the IP in the white space within the inserted text.
            m_draftView.SetInsertionPoint(0, 0, 0, 23, true);
            IVwSelection sel0 = m_draftView.RootBox.Selection;

            Assert.IsNotNull(sel0);

            // Insert paragraph break
            m_draftView.OnKeyPress(new KeyPressEventArgs('\r'));

            Assert.AreEqual(paraCount + 1, m_exodus.SectionsOS[0].ContentOA.ParagraphsOS.Count,
                            "Should have one more paragraph in the intro section");

            // We expect that the last run of the first paragraph and first run of the new
            // paragraph will be a space character with no character style.
            ITsString tss1 = para1.Contents.UnderlyingTsString;

            Assert.AreEqual(3, tss1.RunCount, "First intro paragraph should have three runs");
            Assert.AreEqual("really,", tss1.get_RunText(1));
            ITsTextProps ttp = tss1.get_Properties(1);

            Assert.AreEqual("Emphasis", ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle));
            ttp = tss1.get_Properties(2);
            Assert.AreEqual(" ", tss1.get_RunText(2));
            Assert.AreEqual(null, ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle));

            ITsString tss2 = ((StTxtPara)m_exodus.SectionsOS[0].ContentOA.ParagraphsOS[1]).Contents.UnderlyingTsString;

            Assert.AreEqual(3, tss2.RunCount);
            Assert.AreEqual(" ", tss2.get_RunText(0));
            ttp = tss1.get_Properties(0);
            Assert.AreEqual(null, ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle));
            ttp = tss1.get_Properties(1);
            Assert.AreEqual("Emphasis", ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle));
            Assert.AreEqual("really", tss2.get_RunText(0));
        }
        public void InsertFootnote()
        {
            CheckDisposed();
            FdoCache cache = m_firstMainWnd.Cache;

            // Set the IP to the second section in the first book at the 10th character in
            // the first paragraph
            m_firstDraftView.SetInsertionPoint(0, 1, 0, 10, false);
            ScrBook book       = (ScrBook)cache.LangProject.TranslatedScriptureOA.ScriptureBooksOS[0];
            int     nFootnotes = book.FootnotesOS.Count;

            m_firstMainWnd.CallInsertFootnote();

            Assert.AreEqual(nFootnotes + 1, book.FootnotesOS.Count);

            // Test footnote
            string     expectedMarker = new String((char)((int)'a' + nFootnotes), 1);
            StFootnote footnote       = (StFootnote)book.FootnotesOS[nFootnotes];

            Assert.AreEqual(expectedMarker, footnote.FootnoteMarker.Text,
                            "Wrong footnote marker in footnote");
            ITsString    tsString  = footnote.FootnoteMarker.UnderlyingTsString;
            ITsTextProps ttp       = tsString.get_PropertiesAt(0);
            string       styleName = ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);

            Assert.AreEqual(ScrStyleNames.FootnoteMarker, styleName,
                            "Wrong style for footnote marker in footnote");

            // Test footnote marker in text
            IVwSelection sel = m_firstDraftView.RootBox.Selection;
            ITsString    tss;
            int          ich, hvoObj, tag, enc;
            bool         fAssocPrev;

            sel.TextSelInfo(true, out tss, out ich, out fAssocPrev, out hvoObj, out tag, out enc);
            string strPara = tss.Text;

            Assert.AreEqual(StringUtils.kchObject, strPara[ich]);
            ttp = tss.get_PropertiesAt(ich);
            int nDummy;
            int wsActual = ttp.GetIntPropValues((int)FwTextPropType.ktptWs, out nDummy);

            Assert.AreEqual(cache.LangProject.DefaultVernacularWritingSystem, wsActual,
                            "Wrong writing system for footnote marker in text");
            string objData = ttp.GetStrPropValue((int)FwTextPropType.ktptObjData);

            Assert.AreEqual((char)(int)FwObjDataTypes.kodtOwnNameGuidHot, objData[0]);
        }
Beispiel #3
0
        private void spyOnTextProps(ITsTextProps ttp)
        {
            int tpt;             // ??

            // look at integer props
            int cintProps = ttp.IntPropCount;

            for (int i = 0; i < cintProps; i++)
            {
                int nVar;
                int intProp = ttp.GetIntProp(i, out tpt, out nVar);
                int Value   = ttp.GetIntPropValues(tpt, out nVar);
                Value = 34;                 // need something so Value can be looked at
            }

            // look at string props
            int cstrProps = ttp.StrPropCount;

            for (int i = 0; i < cstrProps; i++)
            {
                string strProp = ttp.GetStrProp(i, out tpt);
                string Value   = ttp.GetStrPropValue(tpt);
                Value = "why?";                 // need something so Value can be looked at
            }
        }
Beispiel #4
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Answer the spelling status of the indicated character in the string, unless it is an
        /// ORC, in which case, for each ORC we answer a different value (that is not any of the
        /// valid spelling statuses).
        /// Enhance JohnT: we don't want to consider embedded-picture ORCs to count as
        /// different; we may strip them out before we start checking the word.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        int SpellCheckProps(ITsString tss, int ich, IVwStylesheet styles)
        {
            // For our purposes here, ORC (0xfffc) is considered to have a different spelling status from everything else,
            // even from every other ORC in the string. This means we always offer to insert spaces adjacent to them.
            if (ich < tss.Length && tss.GetChars(ich, ich + 1)[0] == 0xfffc)
            {
                return(-50 - ich);
            }
            ITsTextProps props = tss.get_PropertiesAt(ich);
            string       style = props.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
            int          var, val;

            if (styles != null && !string.IsNullOrEmpty(style))
            {
                ITsTextProps styleProps = styles.GetStyleRgch(style.Length, style);
                if (styleProps != null)
                {
                    val = styleProps.GetIntPropValues((int)FwTextPropType.ktptSpellCheck, out var);
                    if (var != -1)
                    {
                        return(val);                        // style overrides
                    }
                }
            }
            val = props.GetIntPropValues((int)FwTextPropType.ktptSpellCheck, out var);
            if (var == -1)
            {
                return(0);                // treat unspecified the same as default.
            }
            else
            {
                return(val);
            }
        }
Beispiel #5
0
 /// -------------------------------------------------------------------------------------
 /// <summary>
 /// For any footnote in the specified book whose first paragraph has a run marked with
 /// the Note Target Reference style, remove that run and set the property on the footnote
 /// to display the target reference in the footnote view.
 /// </summary>
 /// <param name="book">The ScrBook whose footnotes are to be searched</param>
 /// -------------------------------------------------------------------------------------
 private void RemoveDirectUsesOfFootnoteTargetRef(IScrBook book)
 {
     foreach (IStFootnote footnote in book.FootnotesOS)
     {
         // Probably only need to worry about first para
         if (footnote.ParagraphsOS.Count == 0)
         {
             continue;
         }
         IStTxtPara para = (IStTxtPara)footnote.ParagraphsOS[0];
         ITsString  tss  = para.Contents;
         ITsStrBldr bldr = null;
         for (int iRun = 0; iRun < tss.RunCount; iRun++)
         {
             ITsTextProps props = tss.get_Properties(iRun);
             string       style = props.GetStrPropValue(
                 (int)FwTextPropType.ktptNamedStyle);
             if (style == ScrStyleNames.FootnoteTargetRef)
             {
                 if (bldr == null)
                 {
                     bldr = tss.GetBldr();
                 }
                 bldr.Replace(tss.get_MinOfRun(iRun), tss.get_LimOfRun(iRun), string.Empty, null);
             }
         }
         if (bldr != null)
         {
             para.Contents = bldr.GetString();
         }
     }
 }
Beispiel #6
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Asserts the properties of a run are set correctly to be a hyperlink for the given
        /// URL.
        /// </summary>
        /// <param name="props">The properties.</param>
        /// <param name="expectedWs">The expected writing system.</param>
        /// <param name="sUrl">The URL.</param>
        /// ------------------------------------------------------------------------------------
        public static void VerifyHyperlinkPropsAreCorrect(ITsTextProps props, int expectedWs,
                                                          string sUrl)
        {
            Assert.AreEqual(1, props.IntPropCount);
            int nDummy;

            Assert.AreEqual(expectedWs,
                            props.GetIntPropValues((int)FwTextPropType.ktptWs, out nDummy));
            Assert.AreEqual(2, props.StrPropCount);
            Assert.AreEqual(StyleServices.Hyperlink,
                            props.GetStrPropValue((int)FwTextPropType.ktptNamedStyle));
            string sObjData = props.GetStrPropValue((int)FwTextPropType.ktptObjData);

            Assert.AreEqual(Convert.ToChar((int)FwObjDataTypes.kodtExternalPathName), sObjData[0]);
            Assert.AreEqual(sUrl, sObjData.Substring(1));
        }
Beispiel #7
0
        public void TypingBeforeHyperlink_WithPrecedingItalicsText()
        {
            var selection = MakeMockSelection(false);
            var selHelper = SelectionHelper.s_mockedSelectionHelper =
                MockRepository.GenerateStub <SelectionHelper>();

            selHelper.Stub(selH => selH.Selection).Return(selection);

            ITsPropsBldr bldr = m_ttpNormal.GetBldr();

            bldr.SetStrPropValue((int)FwTextPropType.ktptNamedStyle, "Italics");
            SimulateTextFollowedByHyperlink(selHelper, bldr.GetTextProps(),
                                            IchPosition.StartOfHyperlink, IchPosition.StartOfHyperlink);

            using (FwEditingHelper editingHelper = new FwEditingHelper(Cache, m_callbacks))
            {
                editingHelper.OnKeyPress(new KeyPressEventArgs('b'), Keys.None);

                IList <object[]> argsSentToSetTypingProps =
                    selection.GetArgumentsForCallsMadeOn(sel => sel.SetTypingProps(null));
                Assert.AreEqual(1, argsSentToSetTypingProps.Count);
                ITsTextProps ttpSentToSetTypingProps = (ITsTextProps)argsSentToSetTypingProps[0][0];
                Assert.AreEqual(1, ttpSentToSetTypingProps.StrPropCount);
                Assert.AreEqual(1, ttpSentToSetTypingProps.IntPropCount);
                int nVar;
                Assert.AreEqual("Italics", ttpSentToSetTypingProps.GetStrPropValue((int)FwTextPropType.ktptNamedStyle));
                Assert.AreEqual(911, ttpSentToSetTypingProps.GetIntPropValues((int)FwTextPropType.ktptWs, out nVar));
            }
        }
            ///----------------------------------------------------------------------------------
            /// <summary>
            /// Asserts that the named style is equal to the expected style.
            /// </summary>
            ///----------------------------------------------------------------------------------
            public void StyleEqual(string expectedStyle, ITsString tss, int iRun)
            {
                ITsTextProps props = GetProperties(tss, iRun);

                Assert.AreEqual(1, props.StrPropCount);
                Assert.AreEqual(expectedStyle, props.GetStrPropValue((int)FwTextPropType.ktptNamedStyle));
            }
Beispiel #9
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Get the font for the specified TsString and writing system.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        private Font GetValuesFont(ITsString tss, int ws)
        {
            if (tss == null || tss.RunCount == 0 || m_cache == null)
            {
                return(null);
            }

            ITsTextProps ttp = tss.get_Properties(0);

            // Figure out what the font size of the string should be.
            int var;
            int fontSize = ttp.GetIntPropValues((int)FwTextPropType.ktptFontSize, out var);

            if (fontSize == -1)
            {
                fontSize = FontInfo.kDefaultFontSize;
            }

            // Font size, at this point, is in millipoints, so convert it to points.
            fontSize /= 1000;

            // Figure out what the style name is and use it to get the font face name.
            string styleName = ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
            string faceName;

            if (m_styleSheet != null)
            {
                // When there is a stylesheet, use it to get the font face name for the style
                // name specified in the text props. If there is no style name in the text props,
                // GetFaceNameFromStyle() should return the font face for the normal style.
                faceName = m_styleSheet.GetFaceNameFromStyle(styleName, ws, m_cache);
            }
            else
            {
                // When there is no stylesheet, use the default serif font for the writing
                // system.
                IWritingSystem iws =
                    m_cache.LanguageWritingSystemFactoryAccessor.get_EngineOrNull(ws);

                faceName = iws.DefaultSerif;
            }

            if (string.IsNullOrEmpty(faceName))
            {
                return(null);
            }

            // Check if the font is in our font cache. If not, add it.
            string key = string.Format("{0}{1}", faceName, fontSize);
            Font   fnt;

            if (!m_fontCache.TryGetValue(key, out fnt))
            {
                fnt = new Font(faceName, (float)fontSize, GraphicsUnit.Point);
                m_fontCache[key] = fnt;
            }

            return(fnt);
        }
            ///----------------------------------------------------------------------------------
            /// <summary>
            /// Asserts that the object data is as expected
            /// </summary>
            ///----------------------------------------------------------------------------------
            public void ObjDataEqual(string expectedObjData, ITsString tss)
            {
                ITsTextProps props = GetProperties(tss, 0);

                Assert.AreEqual(1, props.StrPropCount);
                Assert.AreEqual(expectedObjData,
                                props.GetStrPropValue((int)FwTextPropType.ktptObjData));
            }
Beispiel #11
0
 /// <inheritdoc/>
 public IStStyle FindStyle(ITsTextProps ttp)
 {
     if (ttp == null)
     {
         return(null);
     }
     return(FindStyle(ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle)));
 }
Beispiel #12
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Get the font for the specified TsString and writing system.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        private Font GetValuesFont(ITsString tss, int ws)
        {
            if (tss == null || tss.RunCount == 0 || m_cache == null)
            {
                return(null);
            }

            ITsTextProps ttp = tss.get_Properties(0);

            // Figure out what the font size of the string should be.
            int var;
            int fontSize = ttp.GetIntPropValues((int)FwTextPropType.ktptFontSize, out var);

            if (fontSize == -1)
            {
                fontSize = FontInfo.kDefaultFontSize;
            }
            else
            {
                // Font size, at this point, is in millipoints, so convert it to points.
                fontSize /= 1000;
            }
            // Figure out what the style name is and use it to get the font face name.
            string styleName = ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
            string faceName;

            if (m_styleSheet != null)
            {
                using (var font = FontHeightAdjuster.GetFontForStyle(styleName, m_styleSheet, ws, m_cache.WritingSystemFactory))
                {
                    faceName = font == null ? null : font.Name;
                }
            }
            else
            {
                // When there is no stylesheet, use the default serif font for the writing
                // system.
                faceName = m_cache.ServiceLocator.WritingSystemManager.Get(ws).DefaultFontName;
            }

            if (string.IsNullOrEmpty(faceName))
            {
                return(null);
            }

            // Check if the font is in our font cache. If not, add it.
            string key = string.Format("{0}{1}", faceName, fontSize);
            Font   fnt;

            if (!m_fontCache.TryGetValue(key, out fnt))
            {
                fnt = new Font(faceName, fontSize, GraphicsUnit.Point);
                m_fontCache[key] = fnt;
            }

            return(fnt);
        }
        public void ApplyStyle_CharStyleNotAppliedToBorderingWhiteSpace()
        {
            CheckDisposed();
            m_draftView.RefreshDisplay();

            // Select a word in the book intro with white space around it: " text. "
            m_draftView.SetInsertionPoint(0, 0, 0, 5, false);
            IVwSelection sel0 = m_draftView.RootBox.Selection;

            Assert.IsNotNull(sel0);
            m_draftView.SetInsertionPoint(0, 0, 0, 12, true);
            IVwSelection sel1 = m_draftView.RootBox.Selection;

            Assert.IsNotNull(sel1);
            IVwSelection rangeSel = m_draftView.RootBox.MakeRangeSelection(sel0, sel1, true);
            ITsString    tssSelected;

            rangeSel.GetSelectionString(out tssSelected, "*");
            Assert.AreEqual(" text. ", tssSelected.Text);

            // Apply a character style to the selected text.
            m_draftView.ApplyStyle("Emphasis");

            // The selection should be updated to omit bordering white space in the original selection.
            m_draftView.RootBox.Selection.GetSelectionString(out tssSelected, "*");
            Assert.AreEqual("text.", tssSelected.Text);

            // Confirm that the character styles are applied correctly: Emphasis style applied only to "text."
            ScrSection introSection = (ScrSection)m_exodus.SectionsOS[0];
            ITsString  paraContents = ((StTxtPara)introSection.ContentOA.ParagraphsOS[0]).Contents.UnderlyingTsString;

            Assert.AreEqual(3, paraContents.RunCount);
            Assert.AreEqual(7, paraContents.get_MinOfRun(1));
            Assert.AreEqual(11, paraContents.get_LimOfRun(1));
            ITsTextProps ttp = paraContents.get_Properties(0);

            Assert.IsNull(ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle),
                          "First run should be 'Default Paragraph Characters'");
            ttp = paraContents.get_Properties(1);
            Assert.AreEqual("Emphasis", ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle));
            ttp = paraContents.get_Properties(2);
            Assert.IsNull(ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle),
                          "Third run should be 'Default Paragraph Characters'");
        }
Beispiel #14
0
        /// -------------------------------------------------------------------------------------
        /// <summary>
        /// Make sure that all runs of the given ts string will fit within the given height.
        /// </summary>
        /// <param name="tss">(Potentially) unadjusted TsString -- may have some pre-existing
        /// adjustments, but if it does, we (probably) ignore those and recheck every run</param>
        /// <param name="dympMaxHeight">The maximum height (in millipoints) of the Ts String.</param>
        /// <param name="styleSheet"></param>
        /// <param name="writingSystemFactory"></param>
        /// -------------------------------------------------------------------------------------
        public static ITsString GetAdjustedTsString(ITsString tss, int dympMaxHeight,
                                                    IVwStylesheet styleSheet, ILgWritingSystemFactory writingSystemFactory)
        {
            if (dympMaxHeight == 0)
            {
                return(tss);
            }

            ITsStrBldr bldr = null;

            int runCount = tss.RunCount;

            for (int irun = 0; irun < runCount; irun++)
            {
                ITsTextProps props = tss.get_Properties(irun);
                int          var;
                int          wsTmp = props.GetIntPropValues((int)FwTextPropType.ktptWs,
                                                            out var);
                string styleName =
                    props.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle);

                Font f         = GetFontForStyle(styleName, styleSheet, wsTmp, writingSystemFactory);
                int  height    = GetFontHeight(f);
                int  curHeight = height;
                // incrementally reduce the size of the font until the text can fit
                while (curHeight > dympMaxHeight)
                {
                    f         = new Font(f.Name, f.SizeInPoints - 0.25f);
                    curHeight = GetFontHeight(f);
                }

                if (curHeight != height)
                {
                    // apply formatting to the problem run
                    if (bldr == null)
                    {
                        bldr = tss.GetBldr();
                    }

                    int iStart = tss.get_MinOfRun(irun);
                    int iEnd   = tss.get_LimOfRun(irun);
                    bldr.SetIntPropValues(iStart, iEnd,
                                          (int)FwTextPropType.ktptFontSize,
                                          (int)FwTextPropVar.ktpvMilliPoint, (int)(f.SizeInPoints * 1000.0f));
                }
            }

            if (bldr != null)
            {
                return(bldr.GetString());
            }
            else
            {
                return(tss);
            }
        }
Beispiel #15
0
 /// ------------------------------------------------------------------------------------
 /// <summary>
 /// Initializes a new instance of the <see cref="XmlHyperlinkRun"/> class.
 /// </summary>
 /// ------------------------------------------------------------------------------------
 public XmlHyperlinkRun(int wsDefault, ILgWritingSystemFactory lgwsf, string text,
                        ITsTextProps props)
     : base(wsDefault, lgwsf, text, props)
 {
     Href = StringUtils.GetURL(props.GetStrPropValue((int)FwTextPropType.ktptObjData));
     if (!string.IsNullOrEmpty(Href))
     {
         Href = Href.TrimEnd(Environment.NewLine.ToCharArray());
     }
 }
        public void InsertChars_WhiteSpaceOnBorderOfStyleUsesDefaultStyle()
        {
            CheckDisposed();
            m_draftView.RefreshDisplay();

            // *** Test setup ***
            // Insert a word with a character style.
            StTxtPara    para    = (StTxtPara)m_exodus.SectionsOS[0].ContentOA.ParagraphsOS[0];
            ITsStrBldr   tssBldr = para.Contents.UnderlyingTsString.GetBldr();
            ITsPropsBldr ttpBldr = TsPropsBldrClass.Create();

            ttpBldr.SetStrPropValue((int)FwTextPropType.ktptNamedStyle, "Emphasis");
            tssBldr.ReplaceRgch(15, 15, "really", 6, ttpBldr.GetTextProps());
            para.Contents.UnderlyingTsString = tssBldr.GetString();
            Assert.AreEqual(3, para.Contents.UnderlyingTsString.RunCount);

            // Set the IP immediately before this inserted text.
            m_draftView.SetInsertionPoint(0, 0, 0, 15, true);
            IVwSelection sel0 = m_draftView.RootBox.Selection;

            Assert.IsNotNull(sel0);

            // *** Test ***
            // Type two spaces.
            m_draftView.OnKeyDown(new KeyEventArgs(Keys.Space));
            m_draftView.OnKeyDown(new KeyEventArgs(Keys.Space));

            // We expect that the spaces will be in "Default Paragraph Characters"
            // not in a character style
            ITsString tss = para.Contents.UnderlyingTsString;

            // the word "really" is in the Emphasis style but the inserted white space is not.
            Assert.AreEqual("really", tss.get_RunText(1));
            ITsTextProps ttp = tss.get_Properties(1);

            Assert.AreEqual("Emphasis",
                            ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle));
            ttp = tss.get_Properties(0);
            Assert.IsNull(ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle),
                          "Style of the first run should be 'Default Paragraph Characters'");
            Assert.AreEqual("Intro text. We   ", tss.get_RunText(0));
        }
Beispiel #17
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="XmlTextRun"/> class, based on the given
        /// run information
        /// </summary>
        /// <param name="wsDefault">The default writing system of the paragraph.</param>
        /// <param name="lgwsf">The writing system factory.</param>
        /// <param name="text">The text of the run.</param>
        /// <param name="props">The properties of the run.</param>
        /// ------------------------------------------------------------------------------------
        public XmlTextRun(int wsDefault, ILgWritingSystemFactory lgwsf, string text,
                          ITsTextProps props)
        {
            int dummy;
            int wsRun = props.GetIntPropValues((int)FwTextPropType.ktptWs, out dummy);

            if (wsRun != wsDefault)
            {
                IcuLocale = lgwsf.GetStrFromWs(wsRun);
            }
            StyleName = props.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
            m_text    = text;
        }
Beispiel #18
0
        public void MakeProps_NonNullStyle_CreatesTextProps()
        {
            var          tpf = new TsPropsFactory();
            ITsTextProps tps = tpf.MakeProps("Style", 2, 1);

            Assert.That(tps.IntPropCount, Is.EqualTo(1));
            int var;

            Assert.That(tps.GetIntPropValues((int)FwTextPropType.ktptWs, out var), Is.EqualTo(2));
            Assert.That(var, Is.EqualTo(1));
            Assert.That(tps.StrPropCount, Is.EqualTo(1));
            Assert.That(tps.GetStrPropValue((int)FwTextPropType.ktptNamedStyle), Is.EqualTo("Style"));
        }
Beispiel #19
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Determine the default font to use for the specified writing system,
        /// displayed in the default Normal style of the specified stylesheet.
        /// This is duplicated in SimpleRootSite/EditingHelper.
        /// </summary>
        /// <param name="hvoWs"></param>
        /// <param name="styleSheet"></param>
        /// <param name="wsf"></param>
        /// <returns></returns>
        /// ------------------------------------------------------------------------------------
        static public Font GetFontForNormalStyle(int hvoWs, IVwStylesheet styleSheet,
                                                 ILgWritingSystemFactory wsf)
        {
            ITsTextProps ttpNormal = styleSheet.NormalFontStyle;
            string       styleName = StStyle.NormalStyleName;

            if (ttpNormal != null)
            {
                styleName = ttpNormal.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
            }

            return(GetFontForStyle(styleName, styleSheet, hvoWs, wsf));
        }
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Checks the final space in reference label.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        private void CheckFinalSpaceInReferenceLabel(ITsString tss)
        {
            int iRun = tss.RunCount - 1;

            Assert.AreEqual(" ", tss.get_RunText(iRun));
            ITsTextProps ttp = tss.get_Properties(iRun);

            Assert.AreEqual(null, ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle));
            int var;

            Assert.AreEqual(Cache.WritingSystemFactory.UserWs,
                            ttp.GetIntPropValues((int)FwTextPropType.ktptWs, out var));
        }
Beispiel #21
0
        /// <summary>
        /// Get the name of the paragraph style.
        /// </summary>
        /// <param name="hvoPara">the id of the paragraph</param>
        /// <param name="cache">database cache</param>
        public static string GetStyleName(int hvoPara, FdoCache cache)
        {
            ISilDataAccess dataAccess  = cache.MainCacheAccessor;
            ITsTextProps   tsTextProps = dataAccess.get_UnknownProp(hvoPara,
                                                                    (int)StPara.StParaTags.kflidStyleRules) as ITsTextProps;
            string styleName = NormalParagraph;

            if (tsTextProps != null)
            {
                styleName = tsTextProps.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
            }

            return(styleName);
        }
Beispiel #22
0
        public void SavingDeserializedAnnotationsToCache_WithHyperlink()
        {
            DateTime now    = DateTime.Now;
            DateTime utcNow = now.ToUniversalTime();

            XmlScrNote ann = CreateNote();

            ann.BeginScrRef        = "GEN 2:8";
            ann.ResolutionStatus   = NoteStatus.Closed;
            ann.AnnotationTypeGuid = CmAnnotationDefnTags.kguidAnnTranslatorNote.ToString();
            ann.DateTimeCreated    = utcNow.ToString(CultureInfo.InvariantCulture);
            ann.DateTimeModified   = utcNow.AddDays(1).ToString(CultureInfo.InvariantCulture);
            ann.DateTimeResolved   = utcNow.AddDays(2).ToString(CultureInfo.InvariantCulture);
            AddParasTo(ann.Discussion, "This is my", "discussion");
            AddParasTo(ann.Resolution, "This is my", "resolution for", "the note");
            AddParasTo(ann.Quote, "This is the", "quoted text");
            AddParasTo(ann.Suggestion, "This is", "my", "suggestion");
            AddHyperTo(ann.Suggestion[1], "http://www.tim.david.com/cooldudes.html");

            DummyXmlScrAnnotationsList list = new DummyXmlScrAnnotationsList();

            list.Annotations.Add(ann);

            list.CallWriteToCache(Cache, m_stylesheet);

            IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[0];

            Assert.AreEqual(1, annotations.NotesOS.Count);

            IScrScriptureNote note = annotations.NotesOS[0];

            Assert.AreEqual(NoteType.Translator, note.AnnotationType);
            Assert.IsTrue(AreDateTimesClose(now, note.DateCreated));
            Assert.IsTrue(AreDatesClose(now.AddDays(1), note.DateModified));
            Assert.IsTrue(AreDatesClose(now.AddDays(2), note.DateResolved));

            TestAnnotationField(note.QuoteOA, "This is the", "quoted text");
            TestAnnotationField(note.DiscussionOA, "This is my", "discussion");
            TestAnnotationField(note.ResolutionOA, "This is my", "resolution for", "the note");
            TestAnnotationField(note.RecommendationOA, "This is", "mymy link", "suggestion");

            // Check the hyperlink location
            ITsTextProps props = ((IStTxtPara)note.RecommendationOA.ParagraphsOS[1]).Contents.get_Properties(1);
            string       href  = TsStringUtils.GetURL(props.GetStrPropValue((int)FwTextPropType.ktptObjData));

            Assert.AreEqual("http://www.tim.david.com/cooldudes.html", href);

            Assert.AreEqual(0, note.ResponsesOS.Count);
        }
Beispiel #23
0
        /// <summary>
        /// This is a demonstration of one way to handle special tricks as the user types.
        /// This is an oversimplified way of forcing numbers to be treated as verse numbers...
        /// for example, it will cause '5000' in the 'feeding of the 5000' to be treated as a verse number.
        /// </summary>
        /// <param name="vwselNew"></param>
        protected override void HandleSelectionChange(IVwSelection vwselNew)
        {
            base.HandleSelectionChange(vwselNew);
            if (vwselNew == null)
            {
                return;                 // Not sure whether this happens, but best to be sure.
            }
            int       ichSel, hvoObj, tag, ws;
            bool      fAssocPrev;
            ITsString tss;

            vwselNew.TextSelInfo(false, out tss, out ichSel, out fAssocPrev, out hvoObj, out tag, out ws);

            string text = tss.get_Text();

            if (text == null)
            {
                return;                 // empty string.
            }
            ITsStrBldr tsb = null;

            for (int ich = 0; ich < text.Length; ++ich)
            {
                if (Char.IsDigit(text[ich]))
                {
                    ITsTextProps ttp       = tss.get_PropertiesAt(ich);
                    string       styleName = ttp.GetStrPropValue((int)FwKernelLib.FwTextPropType.ktptNamedStyle);
                    if (styleName != "verseNumber")
                    {
                        // We'll change just this one character. We could make this more efficient for dealing with
                        // long strings of digits, but it's unlikely we'll ever have to deal with more than one.
                        if (tsb == null)
                        {
                            tsb = tss.GetBldr();
                        }
                        tsb.SetStrPropValue(ich, ich + 1, (int)FwKernelLib.FwTextPropType.ktptNamedStyle, "verseNumber");
                    }
                }
            }
            if (tsb != null)
            {
                ISilDataAccess sda = m_rootb.get_DataAccess();
                // In this sample the only string is a multistring. If in doubt, we could test for ws == 0 to
                // see whether it is a simple string.
                sda.SetMultiStringAlt(hvoObj, tag, ws, tsb.GetString());
                sda.PropChanged(null, (int)FwViews.PropChangeType.kpctNotifyAll, hvoObj, tag, 0, tss.get_Length(), tss.get_Length());
            }
        }
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Tests that the processing of a footnote has resulted in the the ORC (Object
        /// Replacement Character) being inserted in the proper place in the dummy
        /// importer's NormalParaStrBldr.
        /// </summary>
        /// <param name="iRun">Zero-base index of the run that should contain the ORC</param>
        /// <param name="iFootnoteIndex">zero-based footnote index</param>
        /// ------------------------------------------------------------------------------------
        protected void VerifyBldrFootnoteOrcRun(int iRun, int iFootnoteIndex)
        {
            ITsTextProps orcProps =
                m_importer.NormalParaStrBldr.get_Properties(iRun);
            IStFootnote footnote = GetFootnote(iFootnoteIndex);

            string objData = orcProps.GetStrPropValue((int)FwTextPropType.ktptObjData);

            Assert.AreEqual((char)(int)FwObjDataTypes.kodtOwnNameGuidHot, objData[0]);
            // Send the objData string without the first character because the first character
            // is the object replacement character and the rest of the string is the GUID.
            Assert.AreEqual(footnote.Guid, MiscUtils.GetGuidFromObjData(objData.Substring(1)));
            string sOrc = m_importer.NormalParaStrBldr.get_RunText(iRun);

            Assert.AreEqual(StringUtils.kChObject, sOrc[0]);
        }
Beispiel #25
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Use this method to move part of one StText to an adjacent one when the fromText
        /// must be left with at least one empty paragraph.
        /// </summary>
        /// <param name="fromText">StText from which the contents is moved</param>
        /// <param name="toText">StText to which the contents is moved. This StText should be
        /// empty.</param>
        /// <param name="divIndex">Index of last whole paragraph to be moved</param>
        /// <param name="toIsPreceding">Should equal true if the toText preceeds the fromText.
        /// If true, the moved paragraphs will be appended to the toText.
        /// If false, they will be placed at the beginning of the toText.</param>
        /// ------------------------------------------------------------------------------------
        public static void MoveTextParagraphsAndFixEmpty(IStText fromText, IStText toText,
                                                         int divIndex, bool toIsPreceding)
        {
            // Save the paragraph props. We might need it to create an empty paragraph.
            ITsTextProps paraPropsSave =
                ((StTxtPara)fromText.ParagraphsOS[divIndex]).StyleRules;

            MoveTextParagraphs(fromText, toText, divIndex, toIsPreceding);

            // If fromText is now empty, create a new empty paragraph.
            if (fromText.ParagraphsOS.Count == 0)
            {
                string styleName =
                    paraPropsSave.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
                StTxtParaBldr.CreateEmptyPara(fromText.Cache, fromText.Hvo,
                                              styleName, fromText.Cache.DefaultVernWs);
            }
        }
Beispiel #26
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Parse the existing Contents to determine the object match criteria and set member
        /// data needed by MatchesCriteria.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public void ParseObjectMatchCriteria()
        {
            lock (SyncRoot)
            {
                string criteria = Contents.Text;
                m_comparisonType = ComparisonTypes.kUndefined;
                m_matchValue     = 0;
                m_matchSubitems  = criteria.IndexOf("+subitems", StringComparison.Ordinal) >= 0;
                m_matchEmpty     = criteria.IndexOf("Empty", StringComparison.Ordinal) >= 0;

                if (criteria.IndexOf("Matches", StringComparison.Ordinal) >= 0)
                {
                    m_comparisonType = ComparisonTypes.kMatches;
                }
                else if (m_matchEmpty)
                {
                    m_comparisonType = ComparisonTypes.kEmpty;
                }

                Debug.Assert(m_comparisonType != ComparisonTypes.kUndefined);

                m_matchValues = null;

                // Check to see whether the criteria specifies a specific (default) object.
                if (criteria.IndexOf(StringUtils.kChObject) >= 0)
                {
                    ITsTextProps ttp     = Contents.get_Properties(1);                 //assume second run
                    string       objData = ttp.GetStrPropValue((int)FwTextPropType.ktptObjData);
                    if (objData[0] == (char)FwObjDataTypes.kodtNameGuidHot)
                    {
                        Guid                     guid = MiscUtils.GetGuidFromObjData(objData.Substring(1));
                        ICmPossibility           poss;
                        ICmPossibilityRepository repo = Cache.ServiceLocator.GetInstance <ICmPossibilityRepository>();
                        if (repo.TryGetObject(guid, out poss))
                        {
                            m_matchValue = poss.Hvo;
                        }
                    }

                    InitializeMatchValuesArray();
                }
            }
        }
        /// <summary>
        /// Any ORCs in the given string with ktptObjData of type kodtOwnNameGuidHot (meaning a GUID that
        /// 'owns' the footnote) should be changed to kodtNameGuidHot, since the BT does NOT own
        /// the footnote.
        /// </summary>
        /// <param name="tssFt"></param>
        /// <returns></returns>
        private static ITsString CorrectFootnotes(ITsString tssFt)
        {
            ITsStrBldr bldr = null;
            int        crun = tssFt.RunCount;

            for (int iRun = 0; iRun < crun; iRun++)
            {
                string sOrc = tssFt.get_RunText(iRun);
                if (String.IsNullOrEmpty(sOrc))
                {
                    continue;
                }
                if (StringUtils.kchObject != sOrc[0])
                {
                    continue;
                }
                ITsTextProps orcPropsParaFootnote = tssFt.get_Properties(iRun);
                string       objData = orcPropsParaFootnote.GetStrPropValue((int)FwTextPropType.ktptObjData);
                if (String.IsNullOrEmpty(objData))
                {
                    continue;
                }
                if ((char)(int)FwObjDataTypes.kodtOwnNameGuidHot != objData[0])
                {
                    continue;
                }
                // OK, need to fix it.
                if (bldr == null)
                {
                    bldr = tssFt.GetBldr();
                }
                objData = ((char)(int)FwObjDataTypes.kodtNameGuidHot).ToString() + objData.Substring(1);
                bldr.SetStrPropValue(tssFt.get_MinOfRun(iRun), tssFt.get_LimOfRun(iRun), (int)FwTextPropType.ktptObjData, objData);
            }
            if (bldr == null)
            {
                return(tssFt);                // no change
            }
            else
            {
                return(bldr.GetString());
            }
        }
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Scans a specified paragaph for runs with the verse number style. Then checks those
        /// runs for verse bridges.
        /// </summary>
        /// <param name="para">The paragraph to scan for runs containing verse bridges.</param>
        /// <param name="oldBridge">the old bridge sequence to replace</param>
        /// <param name="newBridge">The new verse bridge string.</param>
        /// ------------------------------------------------------------------------------------
        private void UpdateVerseBridgesInParagraph(IScrTxtPara para, string oldBridge, string newBridge)
        {
            const int  kStyleNameProp = (int)FwTextPropType.ktptNamedStyle;
            ITsString  paraContents   = para.Contents;
            ITsStrBldr bldr           = null;

            // Iterate through the runs in the paragraph.
            for (int i = 0; i < paraContents.RunCount; i++)
            {
                // Get the run info and check to see if it is a verse number
                TsRunInfo    runInfo;
                ITsTextProps props = paraContents.FetchRunInfo(i, out runInfo);

                // Check if the run is a verse number run.
                if (props.GetStrPropValue(kStyleNameProp) == ScrStyleNames.VerseNumber)
                {
                    // Look to see if this verse is a bridge. If so, then reform it
                    // with the new verse bridge string.
                    string oldVerseText = paraContents.get_RunText(i);
                    int    bridgeIndex  = oldVerseText.IndexOf(oldBridge, StringComparison.Ordinal);
                    if (bridgeIndex != -1)
                    {
                        string newVerseText = oldVerseText.Replace(oldBridge, newBridge);

                        // get a builder for the paragraph if one has not been gotten yet.
                        if (bldr == null)
                        {
                            bldr = paraContents.GetBldr();
                        }

                        // Save the verse number text in the paragraph
                        bldr.Replace(runInfo.ichMin, runInfo.ichLim, newVerseText, props);
                    }
                }
            }

            // If any run was found to contain a verse bridge, then rewrite the paragraph.
            if (bldr != null)
            {
                para.Contents = bldr.GetString();
            }
        }
Beispiel #29
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Make sure footnote exists and is referred to properly in the paragraph contents
        /// </summary>
        /// <param name="footnote"></param>
        /// <param name="para"></param>
        /// <param name="ich">Character position where ORC should be</param>
        /// ------------------------------------------------------------------------------------
        public static void VerifyFootnote(IStFootnote footnote, IStTxtPara para, int ich)
        {
            Guid         guid = footnote.Cache.GetGuidFromId(footnote.Hvo);
            ITsString    tss  = para.Contents.UnderlyingTsString;
            int          iRun = tss.get_RunAt(ich);
            ITsTextProps orcPropsParaFootnote = tss.get_Properties(iRun);
            string       objData = orcPropsParaFootnote.GetStrPropValue(
                (int)FwTextPropType.ktptObjData);

            Assert.AreEqual((char)(int)FwObjDataTypes.kodtOwnNameGuidHot, objData[0]);
            // Send the objData string without the first character because the first character
            // is the object replacement character and the rest of the string is the GUID.
            Guid newFootnoteGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));

            Assert.AreEqual(guid, newFootnoteGuid);
            Assert.AreEqual(footnote.Hvo, footnote.Cache.GetIdFromGuid(newFootnoteGuid));
            string sOrc = tss.get_RunText(iRun);

            Assert.AreEqual(StringUtils.kchObject, sOrc[0]);
        }
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Tests that a footnote marker ORC (Object Replacement Character) has been inserted
        /// as the iRunth run in the given TsString.
        /// </summary>
        /// <param name="tssPara">TsString to check</param>
        /// <param name="iRun">Zero-based index of run to check for the ORC</param>
        /// <param name="ws">Writing system that should be used for the ORC</param>
        /// <param name="fBT">Indicates whether this is checking a back translation.</param>
        /// ------------------------------------------------------------------------------------
        public static void VerifyFootnoteMarkerOrcRun(ITsString tssPara, int iRun, int ws,
                                                      bool fBT)
        {
            Debug.Assert(tssPara.RunCount > iRun, "Trying to access run #" + iRun +
                         " when there are only " + tssPara.RunCount + " run(s).");
            string sOrcRun = tssPara.get_RunText(iRun);

            Assert.AreEqual(1, sOrcRun.Length);
            Assert.AreEqual(StringUtils.kChObject, sOrcRun[0]);
            ITsTextProps ttpOrcRun = tssPara.get_Properties(iRun);
            int          nDummy;
            int          wsActual = ttpOrcRun.GetIntPropValues((int)FwTextPropType.ktptWs,
                                                               out nDummy);

            Assert.AreEqual(ws, wsActual, "Wrong writing system for footnote marker in text");
            string         objData = ttpOrcRun.GetStrPropValue((int)FwTextPropType.ktptObjData);
            FwObjDataTypes orcType = (fBT) ? FwObjDataTypes.kodtNameGuidHot :
                                     FwObjDataTypes.kodtOwnNameGuidHot;

            Assert.AreEqual((char)(int)orcType, objData[0]);
        }
Beispiel #31
0
		public const string DefaultMonospace = "<default monospace>";	// CANNOT BE LOCALIZED AS PUBLIC CONST STRING.
		#endregion

		#region Public methods
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Check the given text props to see if they specify the given style
		/// </summary>
		/// <param name="ttp">Text props</param>
		/// <param name="sStyle">Style</param>
		/// <returns>true if the given text props use the given named style</returns>
		/// ------------------------------------------------------------------------------------
		public static bool IsStyle(ITsTextProps ttp, string sStyle)
		{
			return (ttp.GetStrPropValue(
				(int)FwTextPropType.ktptNamedStyle) == sStyle);
		}
Beispiel #32
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// If the embedded object is a footnote or picture, write it out.
		/// </summary>
		/// <param name="ttp">Properties contain information about the embedded object</param>
		/// ------------------------------------------------------------------------------------
		private void ExportEmbeddedObject(ITsTextProps ttp)
		{
			string objData = ttp.GetStrPropValue((int)FwTextPropType.ktptObjData);
			// if ORC doesn't have properties, continue with next run.
			if (!String.IsNullOrEmpty(objData))
			{
				switch (objData[0])
				{
					case (char)FwObjDataTypes.kodtOwnNameGuidHot:
					case (char)FwObjDataTypes.kodtNameGuidHot:
						Guid footnoteGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));
						IScrFootnote footnote;
						if (m_cache.ServiceLocator.GetInstance<IScrFootnoteRepository>().TryGetFootnote(footnoteGuid, out footnote))
						{
							ExportFootnote(footnote);
						}
						break;
					case (char)FwObjDataTypes.kodtGuidMoveableObjDisp:
						Guid pictureGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));
						ICmPicture picture;
						if (m_cache.ServiceLocator.GetInstance<ICmPictureRepository>().TryGetObject(pictureGuid, out picture))
							ExportPicture(picture);
						break;
					case (char)FwObjDataTypes.kodtPictEvenHot:
						m_writer.WriteComment("object type PictEven not handled");
						break;
					case (char)FwObjDataTypes.kodtPictOddHot:
						m_writer.WriteComment("object type PictOdd not handled");
						break;
					case (char)FwObjDataTypes.kodtExternalPathName:
						m_writer.WriteComment("object type ExternalPathName not handled");
						break;
					case (char)FwObjDataTypes.kodtEmbeddedObjectData:
						m_writer.WriteComment("object type EmbeddedObjectData not handled");
						break;
					case (char)FwObjDataTypes.kodtContextString:
						m_writer.WriteComment("object type ContextString not handled");
						break;
					default:
						m_writer.WriteComment(
							String.Format("unknown object type ({0}) not handled", (int)objData[0]));
						break;
				}
			}
		}
Beispiel #33
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// If the embedded object is a footnote or picture, write it out.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		private void ExportEmbeddedObject(ITsTextProps ttp)
		{
			string objData = ttp.GetStrPropValue((int)FwTextPropType.ktptObjData);
			// if ORC doesn't have properties, continue with next run.
			if (!String.IsNullOrEmpty(objData))
			{
				switch (objData[0])
				{
					case (char)FwObjDataTypes.kodtOwnNameGuidHot:
					case (char)FwObjDataTypes.kodtNameGuidHot:
						Guid footnoteGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));
						int hvoFootnote = m_cache.GetIdFromGuid(footnoteGuid);
						if (hvoFootnote != 0)
							ExportFootnote(new ScrFootnote(m_cache, hvoFootnote));
						break;
					case (char)FwObjDataTypes.kodtGuidMoveableObjDisp:
						Guid pictureGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));
						int hvoPicture = m_cache.GetIdFromGuid(pictureGuid);
						if (hvoPicture != 0)
							ExportPicture(new CmPicture(m_cache, hvoPicture));
						break;
					case (char)FwObjDataTypes.kodtPictEven:
						m_writer.WriteComment("object type PictEven not handled");
						break;
					case (char)FwObjDataTypes.kodtPictOdd:
						m_writer.WriteComment("object type PictOdd not handled");
						break;
					case (char)FwObjDataTypes.kodtExternalPathName:
						m_writer.WriteComment("object type ExternalPathName not handled");
						break;
					case (char)FwObjDataTypes.kodtEmbeddedObjectData:
						m_writer.WriteComment("object type EmbeddedObjectData not handled");
						break;
					case (char)FwObjDataTypes.kodtContextString:
						m_writer.WriteComment("object type ContextString not handled");
						break;
					default:
						m_writer.WriteComment(
							String.Format("unknown object type ({0}) not handled", (int)objData[0]));
						break;
				}
			}
		}
Beispiel #34
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Get a Guid from the given run in a structured text string.
		/// </summary>
		/// <param name="tss">given structured text string</param>
		/// <param name="iRun">given run</param>
		/// <param name="odt">object data type, 0 if no ORC guid located</param>
		/// <param name="tri">run information</param>
		/// <param name="ttp">text properties of the run (if incoming value is  null and the
		/// run is an object, this will be set to the run props)</param>
		/// <param name="desiredOrcTypes">The desired ORC types, or null to return any type of
		/// ORC</param>
		/// <returns>
		/// The GUID associated with the specified run of the tss, if any; otherwise Guid.Empty
		/// </returns>
		/// ------------------------------------------------------------------------------------
		private static Guid GetGuidFromRun(ITsString tss, int iRun,
			Set<FwObjDataTypes> desiredOrcTypes, out FwObjDataTypes odt, out TsRunInfo tri,
			ref ITsTextProps ttp)
		{
			odt = 0;
			tss.FetchRunInfo(iRun, out tri);
			if (tri.ichLim - tri.ichMin == 1 &&
				tss.get_RunText(iRun)[0] == kchObject)
			{
				// determine if single-character run contains an ORC
				ttp = ttp ?? tss.get_Properties(iRun);
				string sObjData = ttp.GetStrPropValue(
					(int)FwTextPropType.ktptObjData);

				if (sObjData != null)
				{
					odt = (FwObjDataTypes)Convert.ToByte(sObjData[0]);
					// See if it's one of the types of objects we want.
					if (desiredOrcTypes == null || desiredOrcTypes.Contains(odt))
					{
						// Get GUID for ORC
						return MiscUtils.GetGuidFromObjData(sObjData.Substring(1));
					}
				}
			}
			return Guid.Empty;
		}
Beispiel #35
0
		/// <summary>
		/// Compute the assembled styles that results from applying the properties specified in the text props to this.
		/// We might start with a root assembled styles that says to use a 10-point font,
		/// then apply a paragraph style which says to use a 12-point font, except for French use 14-point.
		/// Then in another text props we may tell it the writing system is French, and must get 14-point as the
		/// result. Or, in a single TsTextProps, we may tell it the WS is French and to apply a character
		/// style which says to use 16-point, except for French 18-point; the result needs to be 18-point.
		/// It's also theoretically possible that the same text props again says directly to use 20-point; that
		/// should win over all the others.
		/// We achieve most of this by simply looking for the ws, then the named style, then everything else
		/// (and when we process a style, if we already know a ws we include the overrides for that ws).
		/// However, when we process the paragraph style, we don't know what ws a run in that paragraph will have.
		/// </summary>
		/// <param name="props"></param>
		/// <returns></returns>
		public AssembledStyles ApplyTextProps(ITsTextProps props)
		{
			AssembledStyles result = this;
			// Apply writing system, if present, first, so that it can be used to select
			// a named style effect.
			int ttv;
			int ws = props.GetIntPropValues((int) FwTextPropType.ktptWs, out ttv);
			if (ttv != -1)
				result = result.WithWs(ws);
			// Apply named style next, if present, so that style effects can be overridden by explicit ones.
			var namedStyle = props.GetStrPropValue((int) FwTextPropType.ktptNamedStyle);
			if (namedStyle != null)
				result = result.WithNamedStyle(namedStyle);
			int count = props.IntPropCount;
			for (int i = 0; i < count; i++)
			{
				int tpt;
				int val = props.GetIntProp(i, out tpt, out ttv);
				switch (tpt)
				{
					case (int) FwTextPropType.ktptWs: // handled first
						break;
					case (int) FwTextPropType.ktptBold:
						int weight;

						Debug.Assert(ttv == (int) FwTextPropVar.ktpvEnum);
						switch (val)
						{
							case (int) FwTextToggleVal.kttvForceOn:
								weight = (int) VwFontWeight.kvfwBold;
								break;
								// todo JohnT: several others.
							default:
								weight = (int)VwFontWeight.kvfwNormal;
								break;
						}
						result = result.WithFontWeight(weight);
						break;
				}
			}
			return result;
		}
Beispiel #36
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Export whatever goes with an ORC (e.g. footnote, picture, etc.)
		/// </summary>
		/// <param name="ttp">Text properties of the run containing the ORC (from which we get
		/// the footnote GUID).</param>
		/// <param name="exportMode">The export mode.</param>
		/// <param name="iWs">index into the available analysis writing systems (should be -1 if
		/// exportMode is ExportMode.VernacularOnly; should  be 0 if exportMode is
		/// ExportMode.BackTransOnly)</param>
		/// <param name="vernFootnotes">If this is a non-interleaved back translation, this is
		/// the list of footnotes in the (vernacular) paragraph being exported.</param>
		/// ------------------------------------------------------------------------------------
		private void ExportOrcRun(ITsTextProps ttp, ExportMode exportMode, int iWs,
			List<IScrFootnote> vernFootnotes)
		{
			Debug.Assert(exportMode != ExportMode.VernacularOnly || iWs == -1);
			Debug.Assert(exportMode != ExportMode.BackTransOnly || iWs == 0);
			string objData = ttp.GetStrPropValue((int)FwTextPropType.ktptObjData);

			if (objData == null)
			{
				// We encountered a bogus ORC. Ignore it.
				return;
			}

			switch (objData[0])
			{
				case (char)FwObjDataTypes.kodtNameGuidHot:
				case (char)FwObjDataTypes.kodtOwnNameGuidHot:
					{
						Guid footnoteGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));
						IScrFootnote footnote;
						if (m_cache.ServiceLocator.GetInstance<IScrFootnoteRepository>().TryGetFootnote(footnoteGuid, out footnote))
						{
							ExportFootnote(footnote, exportMode, iWs);
							if (vernFootnotes != null)
								vernFootnotes.Remove(footnote);
						}
						break;
					}
				case (char)FwObjDataTypes.kodtGuidMoveableObjDisp:
					{
						Guid pictureGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));
						ICmPicture picture;
						if (m_cache.ServiceLocator.GetInstance<ICmPictureRepository>().TryGetObject(pictureGuid, out picture))
						{
							// TODO (TE-3619): Need to pass export mode once we can handle putting picture ORCs in back translations.
							ExportPicture(picture);
						}
						break;
					}
			}
		}
Beispiel #37
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initializes a new instance of the <see cref="XmlTextRun"/> class, based on the given
		/// run information
		/// </summary>
		/// <param name="wsDefault">The default writing system of the paragraph.</param>
		/// <param name="lgwsf">The writing system factory.</param>
		/// <param name="text">The text of the run.</param>
		/// <param name="props">The properties of the run.</param>
		/// ------------------------------------------------------------------------------------
		public XmlTextRun(int wsDefault, ILgWritingSystemFactory lgwsf, string text,
			ITsTextProps props)
		{
			int dummy;
			int wsRun = props.GetIntPropValues((int)FwTextPropType.ktptWs, out dummy);
			if (wsRun != wsDefault)
				IcuLocale = lgwsf.GetStrFromWs(wsRun);
			StyleName = props.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
			m_text = text;
		}
Beispiel #38
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initializes a new instance of the <see cref="XmlHyperlinkRun"/> class.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public XmlHyperlinkRun(int wsDefault, ILgWritingSystemFactory lgwsf, string text,
			ITsTextProps props)
			: base(wsDefault, lgwsf, text, props)
		{
			Href = TsStringUtils.GetURL(props.GetStrPropValue((int)FwTextPropType.ktptObjData));
			if (!string.IsNullOrEmpty(Href))
				Href = Href.TrimEnd(Environment.NewLine.ToCharArray());
		}
Beispiel #39
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Obtain a style object from character properties.
		/// </summary>
		/// <param name="ttp">Properties containing a named style</param>
		/// ------------------------------------------------------------------------------------
		public IStStyle FindStyle(ITsTextProps ttp)
		{
			if (ttp == null)
				return null;
			return FindStyle(ttp.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle));
		}
Beispiel #40
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Compares two TsTextProps
		/// </summary>
		/// <param name="ttp1">expected</param>
		/// <param name="ttp2">actual</param>
		/// <param name="sHowDifferent">Human(geek)-readable string telling how the props are
		/// different, or indicating no difference</param>
		/// <returns>True if they contain the same props, false otherwise</returns>
		/// ------------------------------------------------------------------------------------
		public static bool PropsAreEqual(ITsTextProps ttp1, ITsTextProps ttp2,
			out string sHowDifferent)
		{
			// check how intProps compare
			int cProps1 = ttp1.IntPropCount;
			int cProps2 = ttp2.IntPropCount;
			int tpv1, tpv2; // prop values
			int nVar1, nVar2; // variation info
			int tpt; // prop type
			for (int iprop = 0; iprop < cProps1; iprop++)
			{
				tpv1 = ttp1.GetIntProp(iprop, out tpt, out nVar1);
				tpv2 = ttp2.GetIntPropValues(tpt, out nVar2);

				if (tpv1 != tpv2 || nVar1 != nVar2)
				{
					if (tpt == (int)FwTextPropType.ktptWs)
						sHowDifferent = string.Format("Props differ in ktptWs property. "
							+ "Expected <{0}>, but was <{1}>.", tpv1, tpv2);
					else
						sHowDifferent = string.Format("Props differ in intProp type {0}. "
							+ "Expected <{1},{2}>, but was <{3},{4}>.", tpt, tpv1, nVar1, tpv2, nVar2);
					return false;
				}
			}
			// if count of intProps differs, it will be difficult to report exact difference
			//  so just issue a simple response for now
			if (cProps1 != cProps2)
			{
				sHowDifferent = string.Format("Props differ in count of intProps. "
					+ "Expected <{0}>, but was <{1}>.", cProps1, cProps2);
				return false;
			}

			// check for string properties differences
			int s1count = ttp1.StrPropCount;
			int s2count = ttp2.StrPropCount;
			int strtype;
			string strval1, strval2; // prop values
			for (int iprop = 0; iprop < s1count; iprop++)
			{
				strval1 = ttp1.GetStrProp(iprop, out strtype);
				strval2 = ttp2.GetStrPropValue(strtype);

				if (strval1 != strval2)
				{
					if (strtype == (int)FwTextPropType.ktptNamedStyle)
						sHowDifferent = string.Format("Props differ in ktptNamedStyle property. "
							+ "Expected <{0}>, but was <{1}>.", strval1, strval2);
					else if (strtype == (int)FwTextPropType.ktptObjData)
						sHowDifferent = string.Format("Props differ in ktptObjData property. "
							+ "Expected <{0}>, but was <{1}>.", strval1, strval2);
							// we could detail the objectDataType and Guid if needed
					else
						sHowDifferent = string.Format("Props differ in strProp type {0}. "
							+ "Expected <{1}>, but was <{2}>.", strtype, strval1, strval2);
					return false;
				}
			}
			// if count of strProps differs, it will be difficult to report exact difference
			//  so just issue a simple response for now
			if (s1count != s2count)
			{
				sHowDifferent = string.Format("Props differ in count of strProps. "
					+ "Expected <{0}>, but was <{1}>.", s1count, s2count);
				return false;
			}

			// if we reach this point, no differences were found
			sHowDifferent = "TextProps objects appear to contain the same properties.";
			return true;
		}
Beispiel #41
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Handle insertion of paragraphs (i.e., from clipboard) with properties that don't
		/// match the properties of the paragraph where they are being inserted. This gives us
		/// the opportunity to create/modify the DB structure to recieve the paragraphs being
		/// inserted and to reject certain types of paste operations (such as attempting to
		/// paste a book).
		/// </summary>
		/// <param name="rootBox">the sender</param>
		/// <param name="ttpDest">properties of destination paragraph</param>
		/// <param name="cPara">number of paragraphs to be inserted</param>
		/// <param name="ttpSrcArray">Array of props of each para to be inserted</param>
		/// <param name="tssParas">Array of TsStrings for each para to be inserted</param>
		/// <param name="tssTrailing">Text of an incomplete paragraph to insert at end (with
		/// the properties of the destination paragraph.</param>
		/// <returns>One of the following:
		/// kidprDefault - causes the base implementation to insert the material as part of the
		/// current StText in the usual way;
		/// kidprFail - indicates that we have decided that this text should not be pasted at
		/// this location at all, causing entire operation to roll back;
		/// kidprDone - indicates that we have handled the paste ourselves, inserting the data
		/// whereever it ought to go and creating any necessary new structure.</returns>
		/// ------------------------------------------------------------------------------------
		public VwInsertDiffParaResponse InsertDiffParas(IVwRootBox rootBox,
			ITsTextProps ttpDest, int cPara, ITsTextProps[] ttpSrcArray, ITsString[] tssParas,
			ITsString tssTrailing)
		{
			CheckDisposed();

			Debug.Assert(!IsBackTranslation);

			if (cPara != ttpSrcArray.Length || cPara != tssParas.Length || ttpDest == null ||
				IsBackTranslation)
				return VwInsertDiffParaResponse.kidprFail;

			// Get the context of the style we are inserting into
			string destStyleName =
				ttpDest.GetStrPropValue((int)FwTextStringProp.kstpNamedStyle);
			IStStyle destStyle = null;
			if (destStyleName != null)
				destStyle = m_scr.FindStyle(destStyleName);
			if (destStyle == null)
				return VwInsertDiffParaResponse.kidprFail;
			ContextValues destContext = destStyle.Context;
			StructureValues destStructure = destStyle.Structure;

			// If pasted data came from a non-FW app, all elements in the source props array
			// will be null. In this case, the default behavior will work fine.
			if (ttpSrcArray[0] == null)
			{
				int i;
				for (i = 1; i < ttpSrcArray.Length; i++)
				{
					if (ttpSrcArray[i] != null)
						break;
				}
				if (i >= ttpSrcArray.Length)
					return VwInsertDiffParaResponse.kidprDefault;
			}

			// Look through the source data (being inserted) to see if there is a conflict.
			ContextValues srcContext;
			StructureValues srcStructure;
			if (!GetSourceContextAndStructure(ttpSrcArray, out srcContext, out srcStructure))
			{
				MiscUtils.ErrorBeep();
				return VwInsertDiffParaResponse.kidprFail;
			}

			// If context of the style is Title then throw out the entire insert.
			// REVIEW: Should this allow insertion of a title para within an existing title?
			if (srcContext == ContextValues.Title)
			{
				MiscUtils.ErrorBeep();
				return VwInsertDiffParaResponse.kidprFail;
			}

			// Set a flag if the src context/structure is different from the dest context/structure
			bool foundMismatch = (srcContext != destContext) || (srcStructure != destStructure);

			if (!foundMismatch)
				// let the views handle it!
				return VwInsertDiffParaResponse.kidprDefault;

			bool noTrailingText =
				(tssTrailing == null || tssTrailing.Length == 0);

			// If insertion point is at beginning of paragraph and there is no trailing text
			if (CurrentSelection.IchAnchor == 0 && noTrailingText)
			{
				if (InBookTitle)
				{
					if (InsertParagraphsBeforeBook(ttpSrcArray, tssParas, srcContext))
						return VwInsertDiffParaResponse.kidprDone;
				}
				else if (InSectionHead)
				{
					if (SectionIndex > 0 && ParagraphIndex == 0 &&
						InsertParagraphsBeforeSection(ttpSrcArray, tssParas, srcContext))
						return VwInsertDiffParaResponse.kidprDone;
				}
				else if (srcContext == destContext && InsertParagraphsInSection(ttpSrcArray, tssParas))
					return VwInsertDiffParaResponse.kidprDone;
			}

			// The contexts don't match and we don't handle it so fail.
			// Case not handled - beep and return failure
			MiscUtils.ErrorBeep();
			return VwInsertDiffParaResponse.kidprFail;
		}
Beispiel #42
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Write out a reference to a footnote. A reference should only be exported from a back
		/// translation.
		/// </summary>
		/// <param name="ttp">Properties contain information about the embedded object</param>
		/// ------------------------------------------------------------------------------------
		private void ExportRefToEmbeddedObject(ITsTextProps ttp)
		{
			string objData = ttp.GetStrPropValue((int) FwTextPropType.ktptObjData);
			// if ORC doesn't have properties, continue with next run.
			if (!String.IsNullOrEmpty(objData))
			{
				switch (objData[0])
				{
					case (char) FwObjDataTypes.kodtNameGuidHot:
						IScrFootnote footnote;
						if (!GetReferencedFootnote(ttp, out footnote))
							return; // unable to find referenced footnote

						m_writer.WriteStartElement("note");
						m_writer.WriteAttributeString("noteRef", "f" + m_sCurrentBookId +
							(footnote.IndexInOwner + 1));
						m_writer.WriteEndElement(); // end <note> element
						break;
					default:
						// give warning about dropped pictures in BT, but only give it once.
						if (!m_droppedBtPictureWarningGiven)
						{
							MessageBoxUtils.Show(
								"OXES file format does not support pictures in back translation. Location of pictures in BT will be lost.",
								m_app.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
							m_droppedBtPictureWarningGiven = true;
						}
						break;
				}
			}
		}
Beispiel #43
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Asserts the properties of a run are set correctly to be a hyperlink for the given
		/// URL.
		/// </summary>
		/// <param name="props">The properties.</param>
		/// <param name="expectedWs">The expected writing system.</param>
		/// <param name="sUrl">The URL.</param>
		/// ------------------------------------------------------------------------------------
		public static void VerifyHyperlinkPropsAreCorrect(ITsTextProps props, int expectedWs,
			string sUrl)
		{
			Assert.AreEqual(1, props.IntPropCount);
			int nDummy;
			Assert.AreEqual(expectedWs,
				props.GetIntPropValues((int)FwTextPropType.ktptWs, out nDummy));
			Assert.AreEqual(2, props.StrPropCount);
			Assert.AreEqual(StyleServices.Hyperlink,
				props.GetStrPropValue((int)FwTextPropType.ktptNamedStyle));
			string sObjData = props.GetStrPropValue((int)FwTextPropType.ktptObjData);
			Assert.AreEqual(Convert.ToChar((int)FwObjDataTypes.kodtExternalPathName), sObjData[0]);
			Assert.AreEqual(sUrl, sObjData.Substring(1));
		}
Beispiel #44
0
		private void spyOnTextProps(ITsTextProps ttp)
		{
			int tpt; // ??

			// look at integer props
			int cintProps = ttp.IntPropCount;
			for (int i = 0; i < cintProps; i++)
			{
				int nVar;
				int intProp = ttp.GetIntProp(i, out tpt, out nVar);
				int Value = ttp.GetIntPropValues(tpt, out nVar);
				Value = 34; // need something so Value can be looked at
			}

			// look at string props
			int cstrProps = ttp.StrPropCount;
			for (int i = 0; i < cstrProps; i++)
			{
				string strProp = ttp.GetStrProp(i, out tpt);
				string Value = ttp.GetStrPropValue(tpt);
				Value = "why?"; // need something so Value can be looked at
			}
		}
Beispiel #45
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Checks to see if the text properties are for a hyperlink.
		/// </summary>
		/// <param name="ttp">The text properties.</param>
		/// <returns><c>true</c> if the properties are for a hyperlink; <c>false</c> otherwise.
		/// </returns>
		/// ------------------------------------------------------------------------------------
		public static bool IsHyperlink(ITsTextProps ttp)
		{
			string objData = ttp.GetStrPropValue((int)FwTextPropType.ktptObjData);
			if (!String.IsNullOrEmpty(objData) && objData.Length > 1 &&
				objData[0] == Convert.ToChar((int)FwObjDataTypes.kodtExternalPathName))
			{
				return true;
			}
			return false;
		}
Beispiel #46
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Gets footnote hvo from reference in text properties
		/// </summary>
		/// <param name="cache"></param>
		/// <param name="tprops"></param>
		/// <returns>Hvo of the footnote that was found or 0 if none was found</returns>
		/// ------------------------------------------------------------------------------------
		protected static int GetFootnoteFromProps(FdoCache cache, ITsTextProps tprops)
		{
			string footnoteRef =
				tprops.GetStrPropValue((int)FwTextPropType.ktptObjData);

			if (footnoteRef != null)
			{
				// first char. of strData is type code - GUID will follow it.
				Guid objGuid = MiscUtils.GetGuidFromObjData(footnoteRef.Substring(1));

				int hvo = cache.GetIdFromGuid(objGuid);
				if (hvo > 0 && cache.GetClassOfObject(hvo) == StFootnote.kClassId)
					return hvo;
			}
			return 0;
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Change the paragraph style.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		protected override void ChangeParagraphStyle(ISilDataAccess sda, ITsTextProps ttp, int hvoPara)
		{
			if (ttp != null)
			{
				string style = ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle);
				string undo, redo;
				ResourceHelper.MakeUndoRedoLabels("kstidUndoStyleChanges", out undo, out redo);
				undo = string.Format(undo, style);
				redo = string.Format(redo, style);
				UndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(undo, redo,
					Cache.ServiceLocator.GetInstance<IActionHandler>(),
					() => CallBaseChangeParagraphStyle(sda, ttp, hvoPara));
			}

		}
Beispiel #48
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Export whatever goes with an ORC (e.g. footnote, picture, etc.)
		/// </summary>
		/// <param name="ttp">Text properties of the run containing the ORC (from which we get
		/// the footnote GUID).</param>
		/// <param name="exportMode">The export mode.</param>
		/// <param name="iWs">index into the available analysis writing systems (should be -1 if
		/// exportMode is ExportMode.VernacularOnly; should  be 0 if exportMode is
		/// ExportMode.BackTransOnly)</param>
		/// ------------------------------------------------------------------------------------
		private void ExportOrcRun(ITsTextProps ttp, ExportMode exportMode, int iWs)
		{
			Debug.Assert(exportMode != ExportMode.VernacularOnly || iWs == -1);
			Debug.Assert(exportMode != ExportMode.BackTransOnly || iWs == 0);
			string objData = ttp.GetStrPropValue((int)FwTextPropType.ktptObjData);

			if (objData == null)
			{
				// We encountered a bogus ORC. Ignore it.
				return;
			}

			switch (objData[0])
			{
				case (char)FwObjDataTypes.kodtNameGuidHot:
				case (char)FwObjDataTypes.kodtOwnNameGuidHot:
					{
						Guid footnoteGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));
						int hvoFootnote = m_cache.GetIdFromGuid(footnoteGuid);
						if (hvoFootnote > 0)
							ExportFootnote(new ScrFootnote(m_cache, hvoFootnote), exportMode, iWs);
						break;
					}
				case (char)FwObjDataTypes.kodtGuidMoveableObjDisp:
					{
						Guid pictureGuid = MiscUtils.GetGuidFromObjData(objData.Substring(1));
						int hvoPicture = m_cache.GetIdFromGuid(pictureGuid);
						// TODO (TE-3619): Need to pass export mode once we can handle putting picture ORCs in back translations.
						if (hvoPicture > 0)
							ExportPicture(new CmPicture(m_cache, hvoPicture));
						break;
					}
			}
		}
Beispiel #49
0
//#if DEBUG
//        private void WriteSegmentedBackTransDebugInfo(BTSegment bts, int iseg)
//        {
//            foreach (int ws1 in bts.AvailableTranslations)
//            {
//                ITsString tssBT = bts.GetTransForWs(ws1);
//                string sBTDebug = String.Format("Seg[{0}] begin={1,4}, end={2,4}; [{3}]='{4}'",
//                    iseg, bts.BeginOffset, bts.EndOffset,
//                    m_cache.LanguageWritingSystemFactoryAccessor.GetStrFromWs(ws1),
//                    tssBT == null ? "<NULL>" : tssBT.Text);
//                Debug.WriteLine(sBTDebug);
//            }
//        }
//#endif

		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// If the text props contains a footnote pointer, return the Guid which refers to the
		/// footnote.  Otherwise, return Guid.Empty.
		/// </summary>
		/// <param name="props"></param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		private static Guid GetFootnoteGuidIfAny(ITsTextProps props)
		{
			string objData = props.GetStrPropValue((int)FwTextPropType.ktptObjData);
			if (!String.IsNullOrEmpty(objData) &&
				(objData[0] == (char)FwObjDataTypes.kodtOwnNameGuidHot ||
				objData[0] == (char)FwObjDataTypes.kodtNameGuidHot))
			{
				return MiscUtils.GetGuidFromObjData(objData.Substring(1));
			}
			return Guid.Empty;
		}