/// ------------------------------------------------------------------------------------ /// <summary> /// Create a response to an annotation /// </summary> /// <returns>The new StJournalText that will contain the response</returns> /// ------------------------------------------------------------------------------------ public IStJournalText CreateResponse() { IStJournalText response = ResponsesOS.Append(new StJournalText()); InitializeText(null, response); return(response); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Writes this response to the the specified annotation /// </summary> /// ------------------------------------------------------------------------------------ public void WriteToCache(IScrScriptureNote ann, FwStyleSheet styleSheet) { ParagraphCollection parasResponse = new ParagraphCollection(Paragraphs, styleSheet); ParagraphCollection.ParaMatchType type; int matchIndex = FindMatchingResponse(parasResponse, ann.ResponsesOS, out type); switch (type) { case ParagraphCollection.ParaMatchType.Exact: case ParagraphCollection.ParaMatchType.Contains: break; // we can ignore the new response -- it's a subset of the old. case ParagraphCollection.ParaMatchType.IsContained: IStJournalText oldText = ann.ResponsesOS[matchIndex]; oldText.ParagraphsOS.Clear(); parasResponse.WriteToCache(oldText); break; case ParagraphCollection.ParaMatchType.None: IStJournalText newText = ann.Cache.ServiceLocator.GetInstance <IStJournalTextFactory>().Create(); ann.ResponsesOS.Add(newText); parasResponse.WriteToCache(newText); break; } }
public void ExistingAnnotation_WithResponses() { IScrScriptureNote existingAnn = AddAnnotation(null, 02002008, NoteType.Translator, "This is my discussion"); existingAnn.ResolutionStatus = NoteStatus.Open; IStJournalText exisingResponse1 = Cache.ServiceLocator.GetInstance <IStJournalTextFactory>().Create(); existingAnn.ResponsesOS.Add(exisingResponse1); AddParasTo(exisingResponse1, "This is my first response"); IStJournalText exisingResponse2 = Cache.ServiceLocator.GetInstance <IStJournalTextFactory>().Create(); existingAnn.ResponsesOS.Add(exisingResponse2); AddParasTo(exisingResponse2, "This is my second response"); DateTime now = DateTime.Now; DateTime utcNow = now.ToUniversalTime(); XmlScrNote ann = CreateNote(); ann.BeginScrRef = "EXO 2:8"; ann.ResolutionStatus = NoteStatus.Open; ann.AnnotationTypeGuid = CmAnnotationDefnTags.kguidAnnTranslatorNote.ToString(); ann.DateTimeCreated = utcNow.ToString(); ann.DateTimeModified = utcNow.AddDays(1).ToString(); AddParasTo(ann.Discussion, "This is my discussion"); XmlNoteResponse firstResponse = new XmlNoteResponse(); AddParasTo(firstResponse.Paragraphs, "This is my first response"); ann.Responses.Add(firstResponse); XmlNoteResponse secondResponse = new XmlNoteResponse(); AddParasTo(secondResponse.Paragraphs, "This is my second response"); ann.Responses.Add(secondResponse); DummyXmlScrAnnotationsList list = new DummyXmlScrAnnotationsList(); list.Annotations.Add(ann); list.CallWriteToCache(Cache, m_stylesheet); IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[1]; 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.AreEqual(DateTime.MinValue, note.DateResolved); IFdoOwningSequence <IStJournalText> responses = note.ResponsesOS; Assert.AreEqual(2, responses.Count); TestAnnotationField(responses[0], "This is my first response"); TestAnnotationField(responses[1], "This is my second response"); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Saves the paragraphs contained in this paragraph collection to the specified text /// </summary> /// <param name="text">The journal text (i.e., quote, discussion, suggestion, /// resolution, etc.) to write the paragraphs to</param> /// ------------------------------------------------------------------------------------ internal void WriteToCache(IStJournalText text) { Debug.Assert(text != null); if (text == null) { return; } if (text.ParagraphsOS.Count == 0 && Count == 0) { // Create one empty paragraph even if there's no data. IStPara para = text.ParagraphsOS.Append(new StTxtPara()); para.StyleRules = StyleUtils.ParaStyleTextProps(ScrStyleNames.Remark); return; } foreach (IStTxtPara para in text.ParagraphsOS) { if (para == null) { continue; } ParaMatchType type; int iPara = FindMatchingParagraph(para, out type); switch (type) { case ParaMatchType.Exact: // new is same as old, just discard the imported paragraph. RemoveAt(iPara); break; case ParaMatchType.Contains: // no new information, just discard the imported paragraph. // REVIEW: this may indicate a deletion. RemoveAt(iPara); break; case ParaMatchType.IsContained: // we have new information added to an existing paragraph. // (or could it be a deletion?) // replace the current paragraph. para.Contents.UnderlyingTsString = this[iPara].StringBuilder.GetString(); para.StyleRules = this[iPara].ParaStylePropsProxy.Props; RemoveAt(iPara); break; case ParaMatchType.None: // Existing paragraph was not found in the list of imported paras. // REVIEW: this may indicate a deletion. break; } } // Append any new paragraphs to the list of paragraphs in the text. foreach (StTxtParaBldr paraBldr in this) { paraBldr.CreateParagraph(text.Hvo); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="XmlNoteResponse"/> class. /// </summary> /// <param name="text">The journal text to initialize from</param> /// <param name="wsDefault">The default writing system</param> /// <param name="lgwsf">The writing system factory to use</param> /// ------------------------------------------------------------------------------------ public XmlNoteResponse(IStJournalText text, int wsDefault, ILgWritingSystemFactory lgwsf) { Debug.Assert(text.ParagraphsOS.Count > 0, "Unexpected paragraph count"); foreach (IStTxtPara para in text.ParagraphsOS) { m_paras.Add(new XmlNotePara(para, wsDefault, lgwsf)); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Create a response to an annotation /// </summary> /// <returns>The new StJournalText that will contain the response</returns> /// ------------------------------------------------------------------------------------ public IStJournalText CreateResponse() { IStJournalText response = Services.GetInstance <IStJournalTextFactory>().Create(); ResponsesOS.Add(response); InitializeText(null, response); return(response); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adds the specified text paragraphs to the specified IStJournalText with a writing /// system of the default analysis language. /// </summary> /// ------------------------------------------------------------------------------------ private void AddParasTo(IStJournalText stjt, params string[] paras) { foreach (string paraText in paras) { IScrTxtPara para = Cache.ServiceLocator.GetInstance <IScrTxtParaFactory>().CreateWithStyle( stjt, ScrStyleNames.Remark); ITsStrFactory fact = TsStrFactoryClass.Create(); para.Contents = fact.MakeString(paraText, Cache.DefaultAnalWs); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adds the specified text paragraphs to the specified IStJournalText with a writing /// system of the default analysis language. /// </summary> /// ------------------------------------------------------------------------------------ private void AddParasTo(IStJournalText stjt, params string[] paras) { foreach (string paraText in paras) { StTxtPara para = (StTxtPara)stjt.ParagraphsOS.Append(new StTxtPara()); para.StyleRules = StyleUtils.ParaStyleTextProps(ScrStyleNames.Remark); ITsStrFactory fact = TsStrFactoryClass.Create(); para.Contents.UnderlyingTsString = fact.MakeString(paraText, Cache.DefaultAnalWs); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Tests the annotation field. /// </summary> /// ------------------------------------------------------------------------------------ private void TestAnnotationField(IStJournalText jtext, params string[] expected) { Assert.AreEqual(expected.Length, jtext.ParagraphsOS.Count); for (int i = 0; i < expected.Length; i++) { Assert.IsNotNull(jtext.ParagraphsOS[i].StyleRules); Assert.AreEqual(ScrStyleNames.Remark, jtext.ParagraphsOS[i].StyleRules.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); Assert.AreEqual(expected[i], ((IStTxtPara)jtext.ParagraphsOS[i]).Contents.Text); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the specified number of characters from the Quoted Text field of an annotation. /// </summary> /// <param name="quotedText">The quoted text.</param> /// <param name="textLength">The number of characters to take from the quoted text. /// Ellipses are added if the quoted text exceeds textLength.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ private string GetQuotedText(IStJournalText quotedText, int textLength) { string strQuote = ((StTxtPara)quotedText.ParagraphsOS[0]).Contents.UnderlyingTsString.Text; if (string.IsNullOrEmpty(strQuote)) { return(string.Empty); } int substrlen = Math.Min(textLength, strQuote.Length); if (substrlen < strQuote.Length) { return(strQuote.Substring(0, substrlen) + ResourceHelper.GetResourceString("ksEllipsis")); } return(strQuote); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Returns a list of XmlNotePara objects representing the paragraphs of a journal text /// of an annotation. /// </summary> /// ------------------------------------------------------------------------------------ public static List <XmlNotePara> GetParagraphList(IStJournalText stJournalText, int wsDefault, ILgWritingSystemFactory lgwsf) { if (stJournalText == null || stJournalText.ParagraphsOS.Count == 0 || string.IsNullOrEmpty(((IStTxtPara)stJournalText.ParagraphsOS[0]).Contents.Text)) { return(null); } List <XmlNotePara> list = new List <XmlNotePara>(); foreach (IStTxtPara para in stJournalText.ParagraphsOS) { list.Add(new XmlNotePara(para, wsDefault, lgwsf)); } return(list); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Returns a value indicating whether or not the specified ISJournalText contains /// the same paragraphs (and in the same order) as those in the list of paragraphs /// in the ParagraphCollection. /// </summary> /// ------------------------------------------------------------------------------------ public bool Equals(IStJournalText text) { if (text.ParagraphsOS.Count != Count) { return(false); } for (int i = 0; i < Count; i++) { ITsString textContent = ((IStTxtPara)text.ParagraphsOS[i]).Contents.UnderlyingTsString; ITsString ourContent = this[i].StringBuilder.GetString(); if (!ourContent.Equals(textContent)) { return(false); } } return(true); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Verifies that an "empty" journal text has a single empty paragraph with the correct /// writing system assigned. /// </summary> /// <param name="text">The text.</param> /// ------------------------------------------------------------------------------------ private void VerifyEmptyStJournalText(IStJournalText text) { Assert.IsNotNull(text); Assert.AreEqual(1, text.ParagraphsOS.Count); StTxtPara para = (StTxtPara)text.ParagraphsOS[0]; ITsString tss = para.Contents.UnderlyingTsString; Assert.IsNotNull(tss); AssertEx.RunIsCorrect(tss, 0, String.Empty, null, text.Cache.DefaultAnalWs); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Returns a list of XmlNotePara objects representing the paragraphs of a journal text /// of an annotation. /// </summary> /// ------------------------------------------------------------------------------------ public static List<XmlNotePara> GetParagraphList(IStJournalText stJournalText, int wsDefault, ILgWritingSystemFactory lgwsf) { if (stJournalText == null || stJournalText.ParagraphsOS.Count == 0 || string.IsNullOrEmpty(((IStTxtPara)stJournalText.ParagraphsOS[0]).Contents.Text)) { return null; } List<XmlNotePara> list = new List<XmlNotePara>(); foreach (IStTxtPara para in stJournalText.ParagraphsOS) list.Add(new XmlNotePara(para, wsDefault, lgwsf)); return list; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Export the paragraphs for the given section of an annotation. /// </summary> /// ------------------------------------------------------------------------------------ protected void ExportNotationParagraphs(IStJournalText text, string sTag) { // don't write out anything for an empty text. if (text.ParagraphsOS.Count == 0) return; if (text.ParagraphsOS.Count == 1 && (text.ParagraphsOS[0] is IStTxtPara) && (text.ParagraphsOS[0] as IStTxtPara).Contents.Length == 0) { return; } m_writer.WriteStartElement(sTag); // TODO: write out these as attributes (?) when supported by the UI. //text.CreatedByRA; //text.DateCreated; //text.ModifiedByRA; //text.DateModified; foreach (IStTxtPara para in text.ParagraphsOS) { m_writer.WriteStartElement("para"); if (para.Contents != null) { ITsTextProps ttp = para.Contents.get_Properties(0); int nVar; int wsDefault = ttp.GetIntPropValues((int)FwTextPropType.ktptWs, out nVar); if (wsDefault > 0) m_writer.WriteAttributeString("xml", "lang", null, GetRFCFromWs(wsDefault)); for (int iRun = 0; iRun < para.Contents.RunCount; iRun++) { ttp = para.Contents.get_Properties(iRun); if (TsStringUtils.IsHyperlink(ttp)) m_writer.WriteStartElement("a"); else m_writer.WriteStartElement("span"); if (iRun > 0) { int wsRun = ttp.GetIntPropValues((int)FwTextPropType.ktptWs, out nVar); if (wsRun > 0 && wsRun != wsDefault) m_writer.WriteAttributeString("xml", "lang", null, GetRFCFromWs(wsRun)); } int cprop = ttp.StrPropCount; int tpt; for (int iprop = 0; iprop < cprop; ++iprop) { string sProp = ttp.GetStrProp(iprop, out tpt); if (tpt == (int)FwTextPropType.ktptNamedStyle) { // Hyperlink style is internal, so it is applied automatically to // embedded links (i.e., it can be inferred from the href attribute). if (sProp != StyleServices.Hyperlink) m_writer.WriteAttributeString("type", sProp); } else if (!TsStringUtils.WriteHref(tpt, sProp, m_writer)) { throw new Exception("Unexpected string property in annotation field: " + sTag + ". FwTextPropType = " + tpt + "; Property = " + sProp ?? "null"); } } string runText = para.Contents.get_RunText(iRun); if (!string.IsNullOrEmpty(runText)) m_writer.WriteString(runText.Normalize()); m_writer.WriteEndElement(); } } m_writer.WriteEndElement(); } m_writer.WriteEndElement(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="XmlNoteResponse"/> class. /// </summary> /// <param name="text">The journal text to initialize from</param> /// <param name="wsDefault">The default writing system</param> /// <param name="lgwsf">The writing system factory to use</param> /// ------------------------------------------------------------------------------------ public XmlNoteResponse(IStJournalText text, int wsDefault, ILgWritingSystemFactory lgwsf) { Debug.Assert(text.ParagraphsOS.Count > 0, "Unexpected paragraph count"); foreach (IStTxtPara para in text.ParagraphsOS) m_paras.Add(new XmlNotePara(para, wsDefault, lgwsf)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Displays an expandable annotation of the specified type. /// </summary> /// ------------------------------------------------------------------------------------ private void DisplayExpandableAnnotation(IVwEnv vwenv, IScrScriptureNote ann, int tag, int hvo, IStJournalText paras, ITsString label) { DisplayExpandableAnnotation(vwenv, ann, tag, hvo, paras, label, false); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the specified number of characters from the Quoted Text field of an annotation. /// </summary> /// <param name="quotedText">The quoted text.</param> /// <param name="textLength">The number of characters to take from the quoted text. /// Ellipses are added if the quoted text exceeds textLength.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ private static string GetQuotedText(IStJournalText quotedText, int textLength) { string strQuote = ((IStTxtPara)quotedText.ParagraphsOS[0]).Contents.Text; if (string.IsNullOrEmpty(strQuote)) return string.Empty; int substrlen = Math.Min(textLength, strQuote.Length); if (substrlen < strQuote.Length) return strQuote.Substring(0, substrlen) + ResourceHelper.GetResourceString("ksEllipsis"); return strQuote; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Displays an expandable annotation of the specified type. /// </summary> /// ------------------------------------------------------------------------------------ private void DisplayExpandableAnnotation(IVwEnv vwenv, IScrScriptureNote ann, int tag, int hvo, IStJournalText paras, ITsString label, bool readOnly) { vwenv.NoteDependency(new int[] { hvo }, new int[] { m_expansionTag }, 1); SetBackgroundColorForNote(ann, vwenv); OpenTableRow(vwenv, ann); // Display empty first cell vwenv.OpenTableCell(1, 1); vwenv.CloseTableCell(); // Display +/- in the second cell, unless this is read-only vwenv.OpenTableCell(1, 1); if (!readOnly) vwenv.AddObjProp(tag, this, (int)NotesFrags.kfrExpansion); vwenv.CloseTableCell(); // Display text in the remaining cells vwenv.OpenTableCell(1, 5); vwenv.OpenConcPara(0, 0, 0, 0); vwenv.AddString(label); if (!m_expandTable.ContainsKey(hvo)) vwenv.AddString(paras[0].Contents); vwenv.CloseParagraph(); vwenv.CloseTableCell(); CloseTableRow(vwenv, ann); if (!m_expandTable.ContainsKey(hvo)) return; SetBackgroundColorForNote(ann, vwenv); OpenTableRow(vwenv, ann); // Display empty first and second cell vwenv.OpenTableCell(1, 2); vwenv.CloseTableCell(); // Display text in cells 3-7 vwenv.OpenTableCell(1, 5); if (!readOnly) SetEditBackground(vwenv); vwenv.AddObjProp(tag, this, (int)StTextFrags.kfrText); vwenv.CloseTableCell(); CloseTableRow(vwenv, ann); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Display a response to an annotation. /// </summary> /// <param name="vwenv"></param> /// <param name="text">StJournalText containing the response</param> /// <param name="expanded">whether response should be expanded</param> /// ------------------------------------------------------------------------------------ private void DisplayResponse(IVwEnv vwenv, IStJournalText text, bool expanded) { #region Response text // Display response text vwenv.OpenTableRow(); // Display empty first, second, and third cells vwenv.OpenTableCell(1, 3); vwenv.CloseTableCell(); vwenv.set_IntProperty((int)FwTextPropType.ktptBorderTop, (int)FwTextPropVar.ktpvMilliPoint, 500); vwenv.OpenTableCell(1, 2); vwenv.AddObjVecItems((int)StTextTags.kflidParagraphs, this, (int)StTextFrags.kfrPara); vwenv.CloseTableCell(); vwenv.CloseTableRow(); #endregion #region Author and creation date // Author and creation date vwenv.OpenTableRow(); // Display empty first, second, and third cells vwenv.OpenTableCell(1, 3); vwenv.CloseTableCell(); // Display author in the third cell vwenv.OpenTableCell(1, 1); SetDisabledColorForNote(vwenv); vwenv.OpenConcPara(0, 0, 0, 0); vwenv.AddString(m_authorLabel); vwenv.CloseParagraph(); vwenv.CloseTableCell(); // Display creation date in the fourth cell vwenv.OpenTableCell(1, 1); vwenv.OpenConcPara(0, 0, 0, 0); vwenv.AddString(m_createdLabel); vwenv.AddString(m_tsStrFactory.MakeString(text.DateCreated.ToShortDateString(), m_cache.DefaultUserWs)); vwenv.CloseParagraph(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); #endregion }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adds the specified text paragraphs to the specified IStJournalText with a writing /// system of the default analysis language. /// </summary> /// ------------------------------------------------------------------------------------ private void AddParasTo(IStJournalText stjt, params string[] paras) { foreach (string paraText in paras) { IScrTxtPara para = Cache.ServiceLocator.GetInstance<IScrTxtParaFactory>().CreateWithStyle( stjt, ScrStyleNames.Remark); ITsStrFactory fact = TsStrFactoryClass.Create(); para.Contents = fact.MakeString(paraText, Cache.DefaultAnalWs); } }