/// <summary> /// attach an annotation describing this failure to the object. *Does Not* remove previous annotations! /// </summary> /// <remarks> I say it does not remove previous annotations because I haven't thought about how much smarts /// it would take to only remove once associated with this particular failure. So I am stipulating for now that /// the caller should first remove all of the kinds of indications which it might create.</remarks> /// <returns></returns> protected ICmBaseAnnotation MakeAnnotation() { // callar should do something like this:CmBaseAnnotation.RemoveAnnotationsForObject(m_object.Cache, m_object.Hvo); ICmBaseAnnotation annotation = (ICmBaseAnnotation)m_cache.LangProject.AnnotationsOC.Add(new CmBaseAnnotation()); annotation.CompDetails = m_xmlDescription; annotation.TextOA = new StText(); using (StTxtParaBldr paraBldr = new StTxtParaBldr(m_cache)) { //review: I have no idea what this is as to be paraBldr.ParaProps = StyleUtils.ParaStyleTextProps("Paragraph"); //todo: this pretends that the default analysis writing system is also the user // interface 1. but I don't really know what's the right thing to do. paraBldr.AppendRun(m_explanation, StyleUtils.CharStyleTextProps(null, m_cache.DefaultAnalWs)); paraBldr.CreateParagraph(annotation.TextOAHvo); } // Dispose() frees ICU resources. annotation.BeginObjectRA = m_object; annotation.Flid = m_flid; annotation.CompDetails = m_xmlDescription; annotation.SourceRA = m_cache.LangProject.ConstraintCheckerAgent; // Although we generated a PropChanged when we actually created the annotation, we need another // one now that all its properties have been set, as there may be a filter that excludes it // until those properties. Simulate removing and re-adding the new annotation (presumed to be // at the end of the collection). int chvo = m_cache.LangProject.AnnotationsOC.Count; m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, m_cache.LangProject.Hvo, (int)LangProject.LangProjectTags.kflidAnnotations, chvo - 1, 1, 1); return(annotation); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Fires the prop changeds. /// </summary> /// ------------------------------------------------------------------------------------ public void FirePropChangeds() { foreach (PropChangedInfo propChanged in m_propChangeds) { m_cache.PropChanged(null, m_pct, propChanged.hvo, propChanged.tag, propChanged.ivMin, propChanged.cvIns, propChanged.cvDel); } }
void DoNotify(int cvIns, int cvDel) { // It's possible that in a single undo task we create a paragraph and segment it and convert the segments to real ones // (e.g., paste a paragraph in TE in segmented BT view). We Undo the creation of the segments, then Undo the creation // of the paragraph, and then come back and try to issue a PropChanged on our property of the deleted paragraph. // This can fail (e.g., TE-7904). if (!m_cache.IsValidObject(m_hvo)) { return; } // note: we must use FdoCache.PropChanged rather than sda.PropChanged, so that we can make use of PropChangedHandling m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, m_hvo, m_flid, m_index, cvIns, cvDel); }
/// <summary> /// This is invoked (using reflection) by an XmlRDEBrowseView when the user presses /// "Enter" in an RDE view that is displaying lexeme form and definition. /// (Maybe also on loss of focus, switch domain, etc?) /// It creates a new entry, lexeme form, and sense that are linked to the specified domain. /// Typically, later, a call to RDEMergeSense will be made to see whether this /// new entry should be merged into some existing sense. /// Note that this method is NOT responsible to insert the new sense into /// the fake property tagList of hvoDomain. (The caller will do that.) /// </summary> /// <param name="hvoDomain">database id of the semantic domain</param> /// <param name="tagList">id of the inverse relation for the senses that belong to the /// domain</param> /// <param name="columns"></param> /// <param name="rgtss"></param> /// <param name="cache"></param> /// <param name="stringTbl"></param> public static int RDENewSense(int hvoDomain, int tagList, List<XmlNode> columns, ITsString[] rgtss, FdoCache cache, StringTable stringTbl) { Debug.Assert(hvoDomain != 0); Debug.Assert(rgtss.Length == columns.Count); // Make a new sense in a new entry. ILexEntry le = cache.LangProject.LexDbOA.EntriesOC.Add( new LexEntry()); IMoForm morph = null; // create a LexSense that has the given definition and semantic domain // Needs to be LexSense, since later calls use non-interface methods. LexSense ls = (LexSense)le.SensesOS.Append(new LexSense()); ILgWritingSystemFactory wsf = cache.LanguageWritingSystemFactoryAccessor; // go through each column and store the appropriate information. for (int i = 0; i < columns.Count; ++i) { // Review: Currently we key off the column labels to determine which columns // correspond to CitationForm and which correspond to Definition. // Ideally we'd like to get at the flids used to build the column display strings. // Instead of passing in only ITsStrings, we could pass in a structure containing // an index of strings with any corresponding flids. Here we'd expect strings // based upon either LexemeForm.Form or LexSense.Definition. We could probably // do this as part of the solution to handling duplicate columns in LT-3763. XmlNode column = columns[i] as XmlNode; string columnLabel = XmlUtils.GetManditoryAttributeValue(column, "label"); string[] columnLabelComponents = columnLabel.Split(new char[] {' ', ':'}); // get column label without writing system or extraneous information. string columnBasicLabel = columnLabelComponents[0]; if (!String.IsNullOrEmpty(columnBasicLabel) && stringTbl != null) columnBasicLabel = stringTbl.LocalizeAttributeValue(columnBasicLabel); ITsTextProps ttp = rgtss[i].get_PropertiesAt(0); int var; int ws = ttp.GetIntPropValues((int)FwTextPropType.ktptWs, out var); Debug.Assert(ws != 0); ITsString tssStr = rgtss[i]; string sStr = tssStr.Text; if (sStr == null) sStr = ""; // otherwise Trim below blows up. sStr = sStr.Trim(); if (columnBasicLabel == Strings.ksWord) { // This is a lexeme form. if (morph == null) morph = MoForm.MakeMorph(cache, le, tssStr); Debug.Assert(le.LexemeFormOAHvo != 0); if (morph is IMoStemAllomorph) { // Make sure we have a proper allomorph and MSA for this new entry and sense. // (See LT-1318 for details and justification.) MoMorphTypeCollection typesCol = new MoMorphTypeCollection(cache); if (sStr.IndexOf(' ') > 0) morph.MorphTypeRA = typesCol.Item(MoMorphType.kmtPhrase); else morph.MorphTypeRA = typesCol.Item(MoMorphType.kmtStem); morph.Form.SetAlternative(sStr, ws); } } else if (columnBasicLabel == Strings.ksDefinition) { // This is a Definition. if (sStr != "") ls.Definition.SetAlternative(sStr, ws); } else { Debug.Fail("column (" + columnLabel + ") not supported."); } } if (morph == null) morph = le.LexemeFormOA = new MoStemAllomorph(); ls.RDEAddDomain(hvoDomain, tagList, cache); if (le.MorphoSyntaxAnalysesOC.Count == 0) { // Commonly, it's a new entry with no MSAs; make sure it has at least one. // This way of doing it allows a good bit of code to be shared with the normal // creation path, as if the user made a stem but didn't fill in any grammatical // information. DummyGenericMSA dummyMsa = new DummyGenericMSA(); if (morph != null && morph is IMoAffixForm) dummyMsa.MsaType = MsaType.kUnclassified; else dummyMsa.MsaType = MsaType.kStem; ls.DummyMSA = dummyMsa; } // We don't want a partial MSA created, so don't bother doing anything // about setting ls.MorphoSyntaxAnalysisRA // LT-1731: adding to make sure new entries are added to the lexicon // record list (full edit,...) cache.PropChanged(null, PropChangeType.kpctNotifyAll, cache.LangProject.LexDbOA.Hvo, (int)LexDb.LexDbTags.kflidEntries, 0, 1, 0); return ls.Hvo; }
internal void Undo(FdoCache cache) { if (m_doneSegments == null) return; // no change to this para int kflidSegments = StTxtPara.SegmentsFlid(cache); cache.VwCacheDaAccessor.CacheVecProp(m_hvoPara, kflidSegments, m_segments, m_segments.Length); cache.PropChanged(m_hvoPara, kflidSegments, 0, m_segments.Length, m_doneSegments.Length); }
/// <summary> /// If the segments of your paragraph now are different from when you were created, issue a suitable PropChanged. /// Enhance JohnT: we could detect more exactly where the differences lie. /// </summary> internal void HandleSegPropChanged(FdoCache cache) { int[] newSegs = GetChangedSegments(cache); if (newSegs != null) { cache.PropChanged(m_hvoPara, StTxtPara.SegmentsFlid(cache), 0, newSegs.Length, m_segments.Length); } }
public void AddToDatabase(FdoCache cache, ICmPossibilityList posList, MasterCategory parent, IPartOfSpeech subItemOwner) { CheckDisposed(); if (m_pos != null) return; // It's already in the database, so nothing more can be done. cache.BeginUndoTask(LexTextControls.ksUndoCreateCategory, LexTextControls.ksRedoCreateCategory); int newOwningFlid; int insertLocation; int newOwner = DeterminePOSLocationInfo(subItemOwner, parent, posList, out newOwningFlid, out insertLocation); ILgWritingSystemFactory wsf = cache.LanguageWritingSystemFactoryAccessor; Debug.Assert(m_pos != null); if (m_node == null) { // should not happen, but just in case... we still get something useful m_pos.Name.SetAlternative(m_term, wsf.GetWsFromStr(m_termWs)); m_pos.Abbreviation.SetAlternative(m_abbrev, wsf.GetWsFromStr(m_abbrevWs)); m_pos.Description.SetAlternative(m_def, wsf.GetWsFromStr(m_defWs)); } else { SetContentFromNode(cache, "abbrev", false, m_pos.Abbreviation); SetContentFromNode(cache, "term", true, m_pos.Name); SetContentFromNode(cache, "def", false, m_pos.Description); } m_pos.CatalogSourceId = m_id; // Need a PropChanged, since it isn't done in the 'Append' for some reason. cache.PropChanged(null, PropChangeType.kpctNotifyAll, newOwner, newOwningFlid, insertLocation, 1, 0); cache.EndUndoTask(); }
static internal int InsertObjectIntoVirtualBackref(FdoCache cache, Mediator mediator, IVwVirtualHandler vh, int hvoSlice, uint clidNewObj, uint clidOwner, uint flid) { if (vh != null) { int clidSlice = cache.GetClassOfObject(hvoSlice); if (clidNewObj == LexEntry.kclsidLexEntry && clidSlice == LexEntry.kclsidLexEntry && clidOwner == LexDb.kclsidLexDb) { if (vh.FieldName == "VariantFormEntryBackRefs") { using (InsertVariantDlg dlg = new InsertVariantDlg()) { ILexEntry entOld = LexEntry.CreateFromDBObject(cache, hvoSlice); dlg.SetHelpTopic("khtpInsertVariantDlg"); dlg.SetDlgInfo(cache, mediator, entOld as IVariantComponentLexeme); if (dlg.ShowDialog() == DialogResult.OK && dlg.NewlyCreatedVariantEntryRefResult) { int insertPos = cache.GetVectorSize(hvoSlice, (int)flid); cache.PropChanged(hvoSlice, (int)flid, insertPos, 1, 0); return insertPos; } // say we've handled this. return -2; } } } } return -1; }