public ReversalIndexEntryFormSlice(FdoCache cache, string editor, int flid, XmlNode node, CmObject obj, StringTable stringTbl, IPersistenceProvider persistenceProvider, int ws) : base(obj.Hvo, flid, LangProject.kwsAllReversalIndex, false, true, true) { m_configNode = node; m_stringTbl = stringTbl; m_persistProvider = persistenceProvider; }
/// <summary> /// We want the persistence provider, and the easiest way to get it is to get all /// this other stuff we don't need or use. /// </summary> /// <param name="cache"></param> /// <param name="editor"></param> /// <param name="flid"></param> /// <param name="node"></param> /// <param name="obj"></param> /// <param name="stringTbl"></param> /// <param name="persistenceProvider"></param> /// <param name="ws"></param> public PhEnvStrRepresentationSlice(FdoCache cache, string editor, int flid, System.Xml.XmlNode node, CmObject obj, StringTable stringTbl, IPersistenceProvider persistenceProvider, int ws) : base(new StringRepSliceView(obj.Hvo), obj.Hvo, StringRepSliceVc.Flid) { m_persistenceProvider = persistenceProvider; m_ws = ws; }
/// <summary> /// This is the core method that actually updates the CmTranslation from the segmented one. /// </summary> private void DoMonitorAction() { m_fInUpdate = true; try { MonitorAction(); } finally { m_fInUpdate = false; m_objectToMonitor = null; } }
/// <summary> /// determine whether the object should be included in the output /// </summary> /// <param name="obj">the object in question</param> /// <param name="filterReason">any explanation of why the object should not be included</param> /// <returns>true if the object should be included in the output</returns> public bool DoInclude (CmObject obj, out string filterReason) { ConstraintFailure failure; //discussion: should we were first check can to see if there are already errors? // pro: it would be faster on the relatively few objects that already have error annotations // con: it would allow a error which is no longer true to live on, causing problems // decision: just go ahead in check them every time. if (!obj.CheckConstraints(0, out failure)) { filterReason = failure.GetMessage(); return false; } filterReason=null; return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets info about the current selection needed to insert an annotation. /// </summary> /// <param name="beginObj">The begin object referenced by the annotation.</param> /// <param name="endObj">The end object referenced by the annotation.</param> /// <param name="wsSelector">The writing system selector.</param> /// <param name="tssQuote">The quote in the annotation (referenced text).</param> /// <param name="startRef">The starting reference in the selection.</param> /// <param name="endRef">The end reference in the selection.</param> /// <param name="startOffset">The starting character offset in the beginObj.</param> /// <param name="endOffset">The ending character offset in the endObj.</param> /// <exception cref="InvalidOperationException">When the current selection is not in /// a paragraph at all</exception> /// ------------------------------------------------------------------------------------ public void GetAnnotationLocationInfo(out CmObject beginObj, out CmObject endObj, out int wsSelector, out int startOffset, out int endOffset, out ITsString tssQuote, out BCVRef startRef, out BCVRef endRef) { CheckDisposed(); int beginObjHvo = 0; int endObjHvo = 0; beginObj = null; endObj = null; if (CurrentSelection != null) { // Get the Scripture reference information that the note will apply to SelLevInfo[] startSel = CurrentSelection.GetLevelInfo(SelectionHelper.SelLimitType.Top); SelLevInfo[] endSel = CurrentSelection.GetLevelInfo(SelectionHelper.SelLimitType.Bottom); if (startSel.Length > 0 && endSel.Length > 0) { beginObjHvo = startSel[0].hvo; endObjHvo = endSel[0].hvo; // Get the objects at the beginning and end of the selection. beginObj = GetNoteTargetObject(beginObjHvo); endObj = GetNoteTargetObject(endObjHvo); } } if (beginObj == null || endObj == null) { // No selection, or selection is in unexpected object. throw new InvalidOperationException("No translation or paragraph in current selection levels"); } int wsStart = GetCurrentBtWs(SelectionHelper.SelLimitType.Top); int wsEnd = GetCurrentBtWs(SelectionHelper.SelLimitType.Bottom); ScrReference[] startScrRef = GetCurrentRefRange(CurrentSelection, SelectionHelper.SelLimitType.Top); ScrReference[] endScrRef = GetCurrentRefRange(CurrentSelection, SelectionHelper.SelLimitType.Bottom); if (wsStart == wsEnd && beginObjHvo == endObjHvo) { // The selection range does not include more than one para or type of translation. wsSelector = wsStart; tssQuote = GetCleanSelectedText(out startOffset, out endOffset); } else { wsSelector = -1; startOffset = 0; endOffset = 0; tssQuote = null; } startRef = startScrRef[0]; endRef = endScrRef[1]; }
private int GetFlidAndHvo(CmObject currentObject, XmlNode node, ref int hvo) { Debug.Assert(currentObject != null); hvo = currentObject.Hvo; int flid = 0; if (currentObject.Cache == null) return flid; IFwMetaDataCache mdc = currentObject.Cache.MetaDataCacheAccessor; if (mdc == null) return flid; XmlAttribute xa = node.Attributes["flid"]; if (xa == null) { string sClass = XmlUtils.GetOptionalAttributeValue(node, "class"); string sFieldPath = XmlUtils.GetOptionalAttributeValue(node, "field"); string[] rgsFields = sFieldPath.Split(new char[] { '/' }); for (int i = 0; i < rgsFields.Length; i++) { if (i > 0) { hvo = currentObject.Cache.GetObjProperty(hvo, flid); if (hvo == 0) return -1; } if (sClass == null || sClass.Length == 0) { uint clsid = (uint)currentObject.Cache.GetClassOfObject(hvo); flid = (int)mdc.GetFieldId2(clsid, rgsFields[i], true); } else { flid = (int)mdc.GetFieldId(sClass, rgsFields[i], true); if (flid != 0) { // And cache it for next time if possible... // Can only do this if it doesn't depend on the current object. // (Hence we only do this here where there was an explicit "class" attribute, // not in the branch where we looked up the class on the object.) XmlNode xmldocT = node; while (xmldocT != null && !(xmldocT is XmlDocument)) xmldocT = xmldocT.ParentNode; if (xmldocT != null) { XmlDocument xmldoc = (XmlDocument)xmldocT; XmlAttribute xaT = xmldoc.CreateAttribute("flid"); xaT.Value = flid.ToString(); node.Attributes.Prepend(xaT); } } } sClass = null; } } else { flid = Convert.ToInt32(xa.Value, 10); } return flid; }
private bool StringEqualsTestPasses(CmObject currentObject, XmlNode node) { string sValue = XmlUtils.GetOptionalAttributeValue(node, "stringequals"); if (sValue != null) { string value = GetStringValueForTest(currentObject, node); if (value == null) value = String.Empty; return sValue == value; } return true; }
private bool LengthEqualsTestPasses(CmObject currentObject, XmlNode node) { int intValue = XmlUtils.GetOptionalIntegerValue(node, "lengthequals", -2); // -2 might be valid int intValue2 = XmlUtils.GetOptionalIntegerValue(node, "lengthequals", -3); // -3 might be valid if (intValue == intValue2) { int value = GetLengthFromCache(currentObject, node); if (value != intValue) return false; } return true; }
private bool ValueEqualityTestsPass(CmObject currentObject, XmlNode node) { if (!IntEqualsTestPasses(currentObject, node)) return false; else if (!LengthEqualsTestPasses(currentObject, node)) return false; else if (!StringEqualsTestPasses(currentObject, node)) return false; return true; }
/// <summary> /// Conditionally process the children. /// </summary> /// <param name="contentsStream"></param> /// <param name="currentObject"></param> /// <param name="node"></param> protected void DoIfElement(TextWriter contentsStream, CmObject currentObject, XmlNode node, bool fExpected) { if (TestPasses(currentObject, node) == fExpected) DoChildren(/*null,*/ contentsStream, currentObject, node, null); }
protected void DoChildren(TextWriter contentsStream, CmObject currentObject, XmlNode parentNode, string flags) { foreach (XmlNode node in parentNode) { if (m_cancelNow) return; string s; switch (node.Name) { case "attribute": case "attributeIndirect": case "dateAttribute": break; // handled in CollectAttributes(). case "element": DoElementElement(contentsStream, currentObject, node, flags); break; case "call": DoCallElement(contentsStream, currentObject, node); break; case "numberElement": DoNumberElement(contentsStream, currentObject, node); break; case "booleanElement": DoBooleanElement(contentsStream, currentObject, node); break; case "multilingualStringElement": DoMultilingualStringElement(contentsStream, currentObject, node, flags); break; case "stringElement": DoStringElement(contentsStream, currentObject, node); break; case "group": DoGroupElement(contentsStream, currentObject, node); break; case "refVector": DoReferenceVectorElement(contentsStream, currentObject, node); break; case "refObjVector": DoReferenceObjVectorElement(contentsStream, currentObject, node); break; case "objVector": DoObjectVectorElement(contentsStream, currentObject, node); break; case "refAtomic": DoAtomicRefElement(contentsStream, currentObject, node, flags); break; case "objAtomic": DoObjectAtomicElement(contentsStream, currentObject, node); break; case "string": DoStringOutput(contentsStream, currentObject, node); break; case "xmlstring": DoXmlStringOutput(contentsStream, currentObject, node); break; /* I don't think these can be used for anything as # is illegal in xml element name. */ case "#comment": break; case "#text": s = Icu.Normalize(node.InnerText, m_eIcuNormalizationMode); contentsStream.Write(s); break; case "comment": DoCommentOutput(contentsStream, node); break; case "text": s = Icu.Normalize(node.InnerText, m_eIcuNormalizationMode); contentsStream.Write(s); break; case "template": DoTemplateElement(contentsStream, node); break; case "newLine": contentsStream.WriteLine(""); break; case "tab": contentsStream.Write("\x009"); break; case "progress": CheckForProgressAttribute(node); break; case "space": contentsStream.Write(" "); break; case "customMultilingualStringElement": doCustomMultilingualStringElementSFM(contentsStream, currentObject, node, flags); break; case "customStringElement": DoCustomStringElement(contentsStream, currentObject, node, flags); break; case "if": DoIfElement(contentsStream, currentObject, node, true); break; case "ifnot": DoIfElement(contentsStream, currentObject, node, false); break; case "generateCustom": DoCustomElements(contentsStream, currentObject, node); break; default: DoLiteralElement(contentsStream, currentObject, node); break; } } }
public void Go(CmObject rootObject, string templateFilePath, TextWriter writer, IFilterStrategy[] filters) { CheckDisposed(); m_sTemplateFilePath = templateFilePath; XmlDocument document = new XmlDocument(); document.Load(templateFilePath); FxtDocument = document; Go(rootObject,writer, filters); }
/// <summary> /// Handle attributes separately so that they can be sorted deterministically and fully /// written to the parent stream. /// </summary> /// <param name="rgsAttrs"></param> /// <param name="currentObject"></param> /// <param name="parentNode"></param> /// <param name="flags"></param> protected void CollectAttributes(List<string> rgsAttrs, CmObject currentObject, XmlNode parentNode, string flags) { foreach (XmlNode node in parentNode) { if (m_cancelNow) return; switch (node.Name) { case "attribute": DoAttributeElement(rgsAttrs, currentObject, node); break; case "attributeIndirect": DoAttributeIndirectElement(rgsAttrs, currentObject, node); break; case "dateAttribute": DoDateAttributeOutput(rgsAttrs, currentObject, node); break; case "element": CollectElementElementAttributes(rgsAttrs, currentObject, node, flags); break; case "call": CollectCallElementAttributes(rgsAttrs, currentObject, node); break; case "if": if (TestPasses(currentObject, node)) CollectAttributes(rgsAttrs, currentObject, node, flags); break; case "ifnot": if (!TestPasses(currentObject, node)) CollectAttributes(rgsAttrs, currentObject, node, flags); break; default: break; } } }
protected void DoGroupElement (TextWriter contentsStream,CmObject currentObject, XmlNode node) { string property =XmlUtils.GetManditoryAttributeValue(node, "objProperty"); //Debug.WriteLine ("<group "+" "+property+">"); CmObject ownedObject = GetObjectFromProperty(currentObject, property); if (ownedObject == null) //nb: this code a late addition return; bool previousAssumeCacheSetting = false;//disabled because parserDump test fails 'cause morphtypes aren't preloaded m_cache.TestingOnly_AssumeCacheFullyLoaded; string sPreload = XmlUtils.GetOptionalAttributeValue(node, "preload"); if (sPreload != null && sPreload.Length > 0) { m_cache.TestingOnly_AssumeCacheFullyLoaded = false; ownedObject.GetType().InvokeMember(sPreload, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, ownedObject, null); m_cache.TestingOnly_AssumeCacheFullyLoaded = true; } DoChildren(/*null,*/ contentsStream, ownedObject, node, null); m_cache.TestingOnly_AssumeCacheFullyLoaded = previousAssumeCacheSetting; }
/// <summary> /// The <objVector> element is used when you want to embed the object of an atomic element, usually owned but works if only referenced. /// </summary> /// <param name="contentsStream"></param> /// <param name="currentObject"></param> /// <param name="node"></param> protected void DoObjectAtomicElement (TextWriter contentsStream,CmObject currentObject, XmlNode node) { //string mode = XmlUtils.GetOptionalAttributeValue(node, "mode"); string property =XmlUtils.GetManditoryAttributeValue(node, "objProperty"); string sClassTag = XmlUtils.GetOptionalAttributeValue(node, "classtag"); //Debug.WriteLine ("<objAtomic property ="+property+">"); currentObject = GetObjectFromProperty(currentObject, property); if (currentObject != null) { DumpObject(contentsStream, currentObject, sClassTag); } Debug.Assert(node.ChildNodes.Count ==0, "child nodes are not supported in objAtomic elements"); }
protected void CollectCallElementAttributes(List<string> rgsAttrs, CmObject currentObject, XmlNode node) { string name = XmlUtils.GetManditoryAttributeValue(node, "name").Trim(); XmlNode classNode = GetClassTemplateNode(name); if (classNode == null) return;// throw new RuntimeConfigurationException("Did not find a <class> element matching the root object type of "+className+"."); string flagsList = XmlUtils.GetOptionalAttributeValue(node, "flags"); CollectAttributes(rgsAttrs, currentObject, classNode, flagsList); }
/// <summary> /// invoking another template (for now, just in other <class> template) /// </summary> /// <param name="contentsStream"></param> /// <param name="currentObject"></param> /// <param name="node"></param> protected void DoCallElement(TextWriter contentsStream, CmObject currentObject, XmlNode node) { string name = XmlUtils.GetManditoryAttributeValue(node, "name").Trim(); XmlNode classNode = GetClassTemplateNode(name); if ( classNode ==null) return;// throw new RuntimeConfigurationException("Did not find a <class> element matching the root object type of "+className+"."); string flagsList = XmlUtils.GetOptionalAttributeValue(node, "flags"); DoChildren(contentsStream, currentObject, classNode, flagsList); }
public void Go(CmObject rootObject, TextWriter writer, IFilterStrategy[] filters) { CheckDisposed(); try { m_rootObject = rootObject; m_filters = filters; // Get the output filename from the writer. if (writer is StreamWriter) { StreamWriter sw = writer as StreamWriter; if (sw.BaseStream is System.IO.FileStream) m_sOutputFilePath = (sw.BaseStream as System.IO.FileStream).Name; } ////This allows the template to be somewhere other than the root of the xml ////document, which is useful if the document is, for example, an xhtml doc. //m_templateRootNode =document.SelectSingleNode("//template"); //if (m_templateRootNode == null) // throw new ConfigurationException ("Could not find the <template> element."); //DumpObject(writer, rootObject); // Ensure that ICU has been initialzed before we dump anything. This should // help fix LT-3970. Icu.InitIcuDataDir(); Go(writer); } finally { writer.Close(); } if (!m_fSkipAuxFileOutput && !String.IsNullOrEmpty(m_sAuxiliaryFxtFile) && !String.IsNullOrEmpty(m_sAuxiliaryFilename)) { using (TextWriter w = new StreamWriter(m_sAuxiliaryFilename)) { XmlDocument document = new XmlDocument(); string sTemplatePath = Path.Combine(Path.GetDirectoryName(m_sTemplateFilePath), m_sAuxiliaryFxtFile); document.Load(sTemplatePath); FxtDocument = document; Go(w); } } }
private bool TestPasses(CmObject currentObject, XmlNode node) { if (!VariableTestsPass(node)) return false; if (!ValueEqualityTestsPass(currentObject, node)) return false; return true; // All conditions present passed. }
protected object GetProperty(CmObject target, string property) { if (target == null) { return null; } if (property == "Hvo") { return GetIdString(target.Hvo); } else if (property == "Guid") { return (target.Guid.ToString()); } else if (property == "Owner") { return (CmObject.CreateFromDBObject(m_cache, m_cache.GetOwnerOfObject(target.Hvo))); } else if (property == "IndexInOwner") { return target.IndexInOwner.ToString(); } Type type = target.GetType(); PropertyInfo info = type.GetProperty(property,BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy ); if (property.StartsWith("custom")) { return GetCustomFieldValue(target, property); } if (info == null) { throw new ConfigurationException ("There is no public property named '" + property + "' in "+type.ToString()+". Remember, properties often end in a two-character suffix such as OA,OS,RA, or RS."); } object result = null; try { result = info.GetValue(target,null); if (property.EndsWith("Hvo")) { int hvo = (int)result; if (hvo > 0) return GetIdString(hvo); } } catch (Exception error) { throw new ApplicationException (string.Format("There was an error while trying to get the property {0}. One thing that has caused this in the past has been a database which was not migrated properly.", property), error); } return result; }
private int GetIntValueForTest(CmObject currentObject, XmlNode node) { int hvo = 0; int flid = GetFlidAndHvo(currentObject, node, ref hvo); if (flid == 0 || hvo == 0) { string sField = XmlUtils.GetOptionalAttributeValue(node, "field"); if (String.IsNullOrEmpty(sField)) return 0; // This is rather arbitrary...objects missing, what should each test do? try { Type type = currentObject.GetType(); PropertyInfo info = type.GetProperty(sField, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (info != null) { object result = info.GetValue(currentObject, null); if (typeof(bool) == result.GetType()) return ((bool)result) ? 1 : 0; else return (int)result; } } catch (Exception error) { throw new ApplicationException(string.Format("There was an error while trying to get the property {0}. One thing that has caused this in the past has been a database which was not migrated properly.", sField), error); } return 0; // This is rather arbitrary...objects missing, what should each test do? } switch (currentObject.Cache.GetFieldType(flid)) { case FieldType.kcptBoolean: if (currentObject.Cache.GetBoolProperty(hvo, flid)) return 1; else return 0; case FieldType.kcptInteger: return currentObject.Cache.GetIntProperty(hvo, flid); case FieldType.kcptOwningAtom: case FieldType.kcptReferenceAtom: return currentObject.Cache.GetObjProperty(hvo, flid); default: return 0; } }
private object GetCustomFieldValue(CmObject target, string property) { try { string sClass = m_cache.MetaDataCacheAccessor.GetClassName((uint)target.ClassID); uint flid = m_cache.MetaDataCacheAccessor.GetFieldId(sClass, property, true); if (flid == 0) return null; int type = m_cache.MetaDataCacheAccessor.GetFieldType(flid); string sView; switch (type) { case (int)CellarModuleDefns.kcptString: case (int)CellarModuleDefns.kcptBigString: TsStringAccessor tsa = new TsStringAccessor(m_cache, target.Hvo, (int)flid); return tsa; case (int)CellarModuleDefns.kcptMultiUnicode: case (int)CellarModuleDefns.kcptMultiBigUnicode: sView = sClass + '_' + property; MultiUnicodeAccessor mua = new MultiUnicodeAccessor(m_cache, target.Hvo, (int)flid, sView); return mua; case (int)CellarModuleDefns.kcptMultiString: case (int)CellarModuleDefns.kcptMultiBigString: sView = sClass + '_' + property; MultiStringAccessor msa = new MultiStringAccessor(m_cache, target.Hvo, (int)flid, sView); return msa; } } catch { } return null; }
private int GetLengthFromCache(CmObject currentObject, XmlNode node) { int hvo = 0; int flid = GetFlidAndHvo(currentObject, node, ref hvo); if (flid == 0 || hvo == 0) return 0; // This is rather arbitrary...objects missing, what should each test do? if (m_mapFlids.ContainsKey(flid)) flid = m_mapFlids[flid]; return currentObject.Cache.GetVectorSize(hvo, flid); }
protected object GetMethodResult(CmObject target, string methodName, object[] args) { Type type = target.GetType(); MethodInfo mi = type.GetMethod(methodName); if (mi == null) throw new ConfigurationException ("There is no public method named '" + methodName + "."); object result = null; try { result = mi.Invoke(target, args); } catch (Exception error) { throw new ApplicationException (string.Format("There was an error while executing the method {0}.", methodName), error); } return result; }
private string GetStringValueForTest(CmObject currentObject, XmlNode node) { int hvo = 0; int flid = GetFlidAndHvo(currentObject, node, ref hvo); if (flid == 0 || hvo == 0) { // Try for a property on the object. string sField = XmlUtils.GetOptionalAttributeValue(node, "field"); if (String.IsNullOrEmpty(sField)) return null; try { Type type = currentObject.GetType(); PropertyInfo info = type.GetProperty(sField, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (info != null) { object result = info.GetValue(currentObject, null); return result.ToString(); } } catch (Exception error) { throw new ApplicationException(string.Format("There was an error while trying to get the property {0}. One thing that has caused this in the past has been a database which was not migrated properly.", sField), error); } return null; // This is rather arbitrary...objects missing, what should each test do? } switch (currentObject.Cache.GetFieldType(flid)) { case FieldType.kcptUnicode: case FieldType.kcptBigUnicode: return currentObject.Cache.GetUnicodeProperty(hvo, flid); case FieldType.kcptString: case FieldType.kcptBigString: return currentObject.Cache.GetTsStringProperty(hvo, flid).Text; case FieldType.kcptMultiUnicode: case FieldType.kcptMultiBigUnicode: return currentObject.Cache.GetMultiUnicodeAlt(hvo, flid, GetSingleWritingSystemDescriptor(node), ViewNameForFlid(flid, currentObject.Cache.MetaDataCacheAccessor)); case FieldType.kcptMultiString: case FieldType.kcptMultiBigString: return currentObject.Cache.GetMultiStringAlt(hvo, flid, GetSingleWritingSystemDescriptor(node)).Text; default: return null; } }
protected CmObject GetObjectFromProperty(CmObject target,string property) { return (CmObject)GetProperty(target, property); }
protected void DoCustomElements(TextWriter contentsStream, CmObject currentObject, XmlNode node) { string sClass = XmlUtils.GetManditoryAttributeValue(node, "class"); string sType = XmlUtils.GetOptionalAttributeValue(node, "fieldType", ""); int[] flids; if (!m_customFlids.TryGetValue(sClass + sType, out flids)) { int clid = 0; try { clid = (int)m_cache.MetaDataCacheAccessor.GetClassId(sClass); } catch { clid = 0; } if (clid == 0) { m_customFlids[sClass + sType] = new int[0]; return; // we don't know what to do! } StringBuilder sbTypes = new StringBuilder(); switch (sType) { case "mlstring": sbTypes.AppendFormat(" AND Type IN ({0}, {1}, {2}, {3})", (int)CellarModuleDefns.kcptMultiUnicode, (int)CellarModuleDefns.kcptMultiBigUnicode, (int)CellarModuleDefns.kcptMultiString, (int)CellarModuleDefns.kcptMultiBigString); break; case "simplestring": sbTypes.AppendFormat(" AND Type IN ({0}, {1})", (int)CellarModuleDefns.kcptString, (int)CellarModuleDefns.kcptBigString); break; } StringBuilder sb = new StringBuilder("SELECT Id From Field$ WHERE Custom=1 AND Class="); sb.Append(clid.ToString()); if (sbTypes.Length > 0) sb.Append(sbTypes.ToString()); string sql = sb.ToString(); flids = DbOps.ReadIntArrayFromCommand(m_cache, sql, null); m_customFlids[sClass + sType] = flids; } if (flids.Length == 0) return; // nothing to do. for (int i = 0; i < flids.Length; ++i) { XmlNode parentNode = node.Clone(); uint flid = (uint)flids[i]; string labelName = m_cache.MetaDataCacheAccessor.GetFieldLabel(flid); string fieldName = m_cache.MetaDataCacheAccessor.GetFieldName(flid); string className = m_cache.MetaDataCacheAccessor.GetOwnClsName(flid); if (String.IsNullOrEmpty(labelName)) labelName = fieldName; string sfMarker = "zz"; if (fieldName.StartsWith("custom")) { sfMarker = String.Format("z{0}", fieldName.Substring(6)); if (sfMarker == "z") sfMarker = "z0"; } ReplaceSubstringInAttr visitorFn = new ReplaceSubstringInAttr("${fieldName}", fieldName); ReplaceSubstringInAttr visitorLab = new ReplaceSubstringInAttr("${label}", labelName); ReplaceSubstringInAttr visitorSfm = new ReplaceSubstringInAttr("${sfm}", sfMarker); foreach (XmlNode xn in parentNode.ChildNodes) { XmlUtils.VisitAttributes(xn, visitorFn); XmlUtils.VisitAttributes(xn, visitorLab); XmlUtils.VisitAttributes(xn, visitorSfm); } if (parentNode.InnerText.Contains("${definition}")) FillInCustomFieldDefinition(parentNode, flid); if (parentNode.InnerText.Contains("${description}")) FillInCustomFieldDescription(parentNode, flid); DoChildren(contentsStream, currentObject, parentNode, null); } }
protected IEnumerable GetEnumerableFromProperty(CmObject target,string property) { return (IEnumerable)GetProperty(target, property); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Inserts a note referencing the currently selected paragraph. /// </summary> /// <param name="noteType">Type of note</param> /// <param name="startRef">reference at beginning of selection</param> /// <param name="endRef">reference at end of selection</param> /// <param name="topObj">The object where quoted text begins.</param> /// <param name="bottomObj">The object where quoted text ends.</param> /// <param name="wsSelector">The writing system selector.</param> /// <param name="startOffset">The starting character offset.</param> /// <param name="endOffset">The ending character offset.</param> /// <param name="tssQuote">The text of the quote.</param> /// <returns>The inserted note</returns> /// ------------------------------------------------------------------------------------ public virtual IScrScriptureNote InsertNote(ICmAnnotationDefn noteType, BCVRef startRef, BCVRef endRef, CmObject topObj, CmObject bottomObj, int wsSelector, int startOffset, int endOffset, ITsString tssQuote) { CheckDisposed(); TeNotesVc notesVc = CurrentNotesVc; IScrScriptureNote annotation; string sUndo, sRedo; int iPos; ScrBookAnnotations annotations = (ScrBookAnnotations)m_scr.BookAnnotationsOS[startRef.Book - 1]; TeResourceHelper.MakeUndoRedoLabels("kstidInsertAnnotation", out sUndo, out sRedo); string sType = noteType.Name.UserDefaultWritingSystem; sUndo = string.Format(sUndo, sType); sRedo = string.Format(sRedo, sType); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(m_cache.MainCacheAccessor, Control as IVwRootSite, sUndo, sRedo, false)) { try { StTxtParaBldr quoteParaBldr = new StTxtParaBldr(m_cache); quoteParaBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.Remark); quoteParaBldr.StringBuilder.ReplaceTsString(0, 0, tssQuote); annotation = annotations.InsertNote(startRef, endRef, topObj, bottomObj, noteType.Guid, wsSelector, startOffset, endOffset, quoteParaBldr, null, null, null, out iPos); if (notesVc != null) { // tell the VC that the newly inserted item should be expanded. That will cause // the view to be updated to show the new note. notesVc.ExpandItem(annotation.Hvo); notesVc.ExpandItem(annotation.DiscussionOAHvo); } } catch { undoTaskHelper.EndUndoTask = false; FwApp.App.RefreshAllViews(m_cache); throw; } } if (Control != null) Control.Focus(); // Make a selection in the discussion so the user can start to type if (notesVc != null && notesVc.NotesSequenceHandler != null) { // Get the corresponding index in the virtual property. iPos = notesVc.NotesSequenceHandler.GetVirtualIndex(annotations.Hvo, iPos); } IVwRootSite rootSite = Control as IVwRootSite; MakeSelectionInNote(notesVc, startRef.Book - 1, iPos, rootSite, true); // REVIEW: Do we need to create a synch record? return annotation; }
protected void DumpObject(TextWriter contentsStream, CmObject currentObject, string sClassTag) { string className = m_cache.GetClassName((uint)currentObject.ClassID); XmlNode classNode = null; if (sClassTag != null && sClassTag.Length > 0) { className = className + "-" + sClassTag; classNode = GetClassTemplateNode(className); } if (classNode == null) { classNode = FindClassTemplateNode(currentObject.GetType(), sClassTag); } if (classNode == null) { return; // would have thrown an exception if that's what the template wanted } string sPreload = XmlUtils.GetOptionalAttributeValue(classNode, "preload"); bool previousAssumeCacheSetting = m_cache.TestingOnly_AssumeCacheFullyLoaded; if (sPreload != null && sPreload.Length > 0) { m_cache.TestingOnly_AssumeCacheFullyLoaded = false; currentObject.GetType().InvokeMember(sPreload, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, currentObject, null); m_cache.TestingOnly_AssumeCacheFullyLoaded = true; } if (m_filters != null) { foreach(IFilterStrategy filter in m_filters) { string explanation; if (!filter.DoInclude (currentObject, out explanation)) { if (explanation==null) explanation = "none"; XmlTextWriter writer = new XmlTextWriter(contentsStream); writer.WriteComment(String.Format(" Object filtered out by filter {0}, reason: {1} ", filter.Label, explanation)); // would choke the parser later if there were reserved chars in there //contentsStream.Write("<!-- Object filtered out by filter " + filter.Label + ", reason: "+ explanation + " "); // contentsStream.Write(" -->"); return; } } } DoChildren(/*null,*/ contentsStream, currentObject, classNode, null); m_cache.TestingOnly_AssumeCacheFullyLoaded = previousAssumeCacheSetting; }