static internal void EliminateExtraStyleAndWsInfo(IFwMetaDataCache mdc, FwPasteFixTssEventArgs e, int flid) { var type = (CellarPropertyType)mdc.GetFieldType(flid); if (type == CellarPropertyType.MultiUnicode || type == CellarPropertyType.Unicode) { e.TsString = e.TsString.ToWsOnlyString(); } }
bool m_fGotFocus = false; // True if we have focus. public TypeAheadSupportVc(int tag, LcmCache cache) { m_tag = tag; IFwMetaDataCache mdc = cache.DomainDataByFlid.MetaDataCache; m_clid = mdc.GetOwnClsId(m_tag); m_className = mdc.GetClassName(m_clid); m_fieldName = mdc.GetFieldName(m_tag); m_type = (CellarPropertyType)(mdc.GetFieldType(m_tag) & (int)CellarPropertyTypeFilter.VirtualMask); m_sda = cache.DomainDataByFlid; Cache = cache; }
bool m_fGotFocus = false; // True if we have focus. public TypeAheadSupportVc(int tag, FdoCache cache) { m_tag = tag; IFwMetaDataCache mdc = cache.MetaDataCacheAccessor; m_clid = mdc.GetOwnClsId((uint)m_tag); m_className = mdc.GetClassName(m_clid); m_fieldName = mdc.GetFieldName((uint)m_tag); m_type = mdc.GetFieldType((uint)m_tag); m_type = m_type & 0x1f; // strip off virtual bit. m_sda = cache.MainCacheAccessor; m_cache = cache; CreateVirtualProperties(); }
/// <summary> /// Set configuration displayProperty from cmObjectCustomFieldFlid set elements' OwningList DisplayOption. /// /// If cmObjectCustomFieldFlid refers to a set of elements (in cmObject), then examine the setting on the owning list of the /// elements to determine which property of each element to use when /// displaying each element in a slice, and record that information in configurationNode. This information is used /// in DetailControls.VectorReferenceVc.Display(). /// Addresses LT-15705. /// </summary> internal static void SetConfigurationDisplayPropertyIfNeeded(XmlNode configurationNode, ICmObject cmObject, int cmObjectCustomFieldFlid, ISilDataAccess mainCacheAccessor, ILcmServiceLocator fdoServiceLocator, IFwMetaDataCache metadataCache) { var fieldType = metadataCache.GetFieldType(cmObjectCustomFieldFlid); if (!(fieldType == (int)CellarPropertyType.ReferenceCollection || fieldType == (int)CellarPropertyType.OwningCollection || fieldType == (int)CellarPropertyType.ReferenceSequence || fieldType == (int)CellarPropertyType.OwningSequence)) { return; } var element = FetchFirstElementFromSet(cmObject, cmObjectCustomFieldFlid, mainCacheAccessor, fdoServiceLocator); if (element == null) { return; } var displayOption = element.OwningList.DisplayOption; string propertyNameToGetAndShow = null; switch ((PossNameType)displayOption) { case PossNameType.kpntName: propertyNameToGetAndShow = "ShortNameTSS"; break; case PossNameType.kpntNameAndAbbrev: propertyNameToGetAndShow = "AbbrAndNameTSS"; break; case PossNameType.kpntAbbreviation: propertyNameToGetAndShow = "AbbrevHierarchyString"; break; default: break; } if (propertyNameToGetAndShow == null) { return; } SetDisplayPropertyInXMLConfiguration(configurationNode, propertyNameToGetAndShow); }
static internal bool IsMultilingual(int flid, IFwMetaDataCache mdc) { switch ((CellarPropertyType)(mdc.GetFieldType(flid) & (int)CellarPropertyTypeFilter.VirtualMask)) { case CellarPropertyType.MultiString: case CellarPropertyType.MultiUnicode: return true; default: return false; } }
private void LoadObject(XmlNode objectNode, int hvo, int clid, IDictionary <int, int> objects) { // Optimize by looping over the child nodes, // and dealing with relevant flid. // The idea is that most objects will only have a subset of fields filled in. var nodeList = objectNode.ChildNodes; for (var i = 0; i < nodeList.Count; ++i) { var fieldNode = nodeList[i]; // Item(i); var fieldName = fieldNode.Name; var idx = fieldName.IndexOfAny(new[] { '1', '2', '3', '4', '5', '6', '7', '8', '9' }); fieldName = fieldName.Substring(0, idx); var cfk = new ClidFieldnameKey(clid, fieldName); int flid; if (m_cachedFlids.ContainsKey(cfk)) { flid = m_cachedFlids[cfk]; } else { flid = m_metaDataCache.GetFieldId2(clid, fieldName, true); m_cachedFlids[cfk] = flid; } var flidType = (CellarPropertyType)m_metaDataCache.GetFieldType(flid); int ownedClid; int ownedHvo; switch (flidType) { case CellarPropertyType.Boolean: // <System18><Boolean val="true"/></System18> m_realDataCache.CacheBooleanProp(hvo, flid, bool.Parse(fieldNode.FirstChild.Attributes["val"].Value)); break; case CellarPropertyType.Integer: // <Type18><Integer val="1"/></Type18> m_realDataCache.CacheIntProp(hvo, flid, Int32.Parse(fieldNode.FirstChild.Attributes["val"].Value)); break; case CellarPropertyType.Numeric: break; case CellarPropertyType.Float: break; case CellarPropertyType.Time: // <LastModified24><Time val="2005-11-18 02:48:33.000"/></LastModified24> var valTime = DateTime.Parse(fieldNode.FirstChild.Attributes["val"].Value); m_realDataCache.CacheTimeProp(hvo, flid, valTime.Ticks); break; case CellarPropertyType.Guid: if (flid != (int)CmObjectFields.kflidCmObject_Guid) { // <App18><Guid val="5EA62D01-7A78-11D4-8078-0000C0FB81B5"/></App18> var id = fieldNode.FirstChild.Attributes["val"].Value; m_realDataCache.CacheGuidProp(hvo, flid, new Guid(id)); } break; case CellarPropertyType.Image: break; case CellarPropertyType.GenDate: // <DateOfEvent4006><GenDate val=\"193112111\" /></DateOfEvent4006> break; case CellarPropertyType.Binary: // <Details18><Binary>03000000</Binary></Details18> // <Details18><Binary>05000000\r\n</Binary></Details18> break; case CellarPropertyType.String: // "<Str><Run ws=\"eZPI\">Te mgyeey ne la Benit nuu Pwert. Za men gun men inbitar xmig men ne la Jasint nuu San José. Za Benit. Weey Benit mël. Weey Benit mëlbyuu ne ygued Benit lo xmig Benit, Jasint. Chene wdxiin Benit ruxyuu Jasint, re Benit:</Run></Str>" foreach (XmlNode strNode in fieldNode.ChildNodes) { var tssStr = m_tsf.CreateFromStr(strNode); m_realDataCache.CacheStringProp(hvo, flid, tssStr); } // CacheStringProp(hvo, tag, tss); break; case CellarPropertyType.MultiString: // <AStr> foreach (XmlNode aStrAlt in fieldNode.ChildNodes) { int wsAStr; var tssAlt = m_tsf.CreateFromAStr(aStrAlt, out wsAStr); m_realDataCache.CacheStringAlt(hvo, flid, wsAStr, tssAlt); } break; case CellarPropertyType.Unicode: string unicodeText = fieldNode.FirstChild.InnerText; m_realDataCache.CacheUnicodeProp(hvo, flid, unicodeText, unicodeText.Length); break; case CellarPropertyType.MultiUnicode: // <AUni> foreach (XmlNode uniNode in fieldNode.ChildNodes) { var ws = m_wsCache[uniNode.Attributes["ws"].Value]; var uniText = uniNode.InnerText; m_realDataCache.CacheStringAlt(hvo, flid, ws, TsStringUtils.MakeString(uniText, ws)); } break; // Cases for regular objects. case CellarPropertyType.OwningAtomic: XmlNode atomicOwnedObject = fieldNode.FirstChild; ownedHvo = LoadCmObjectProperties(atomicOwnedObject, hvo, flid, 0, out ownedClid, objects); LoadObject(atomicOwnedObject, ownedHvo, ownedClid, objects); m_realDataCache.CacheObjProp(hvo, flid, ownedHvo); break; case CellarPropertyType.ReferenceAtomic: /* Some are simple Guid links, but others contain more info. * <Category5059> * <Link target="I751B8DE1-089B-42B1-A35E-62CF838A27A3" ws="en" abbr="N" name="noun"/> * </Category5059> * <Morph5112> * <Link target="I9370DD7D-978D-484D-B304-B5D4700BAA30"/> * </Morph5112> */ // Defer caching references, until all objects are loaded. m_delayedAtomicReferences[new HvoFlidKey(hvo, flid)] = fieldNode.FirstChild; break; case CellarPropertyType.OwningCollection: // Fall through. case CellarPropertyType.OwningSequence: var hvos = new List <int>(); var newOrd = 0; foreach (XmlNode obj in fieldNode.ChildNodes) { ownedHvo = LoadCmObjectProperties(obj, hvo, flid, newOrd, out ownedClid, objects); LoadObject(obj, ownedHvo, ownedClid, objects); hvos.Add(ownedHvo); if (flidType == CellarPropertyType.OwningSequence) { newOrd++; } } m_realDataCache.CacheVecProp(hvo, flid, hvos.ToArray(), hvos.Count); break; case CellarPropertyType.ReferenceCollection: // Fall through. case CellarPropertyType.ReferenceSequence: // <Link target="ID75F7FB5-BABD-4D60-B57F-E188BEF264B7" /> // Defer caching references, until all objects are loaded. var list = new List <XmlNode>(); m_delayedVecterReferences[new HvoFlidKey(hvo, flid)] = list; foreach (XmlNode linkNode in fieldNode.ChildNodes) { list.Add(linkNode); } break; } } }
/// <summary> /// This is invoked when a generated part ref (<part ref="Custom" param="fieldName"/>) /// invokes the standard slice (<slice editor="autoCustom".../>). It comes up with the /// appropriate default slice for the custom field indicated in the param attribute of /// the caller. /// </summary> static Slice MakeAutoCustomSlice(FdoCache cache, ICmObject obj, XmlNode caller) { IFwMetaDataCache mdc = cache.DomainDataByFlid.MetaDataCache; int flid = GetCustomFieldFlid(caller, mdc, obj); if (flid == 0) { return(null); } Slice slice = null; var type = (CellarPropertyType)mdc.GetFieldType(flid); switch (type) { case CellarPropertyType.String: case CellarPropertyType.MultiUnicode: case CellarPropertyType.MultiString: int ws = mdc.GetFieldWs(flid); switch (ws) { case 0: // a desperate default. case WritingSystemServices.kwsAnal: slice = new StringSlice(obj, flid, cache.DefaultAnalWs); break; case WritingSystemServices.kwsVern: slice = new StringSlice(obj, flid, cache.DefaultVernWs); break; case WritingSystemServices.kwsAnals: case WritingSystemServices.kwsVerns: case WritingSystemServices.kwsAnalVerns: case WritingSystemServices.kwsVernAnals: slice = new MultiStringSlice(obj, flid, ws, 0, false, true, true); break; default: throw new Exception("unhandled ws code in MakeAutoCustomSlice"); } break; case CellarPropertyType.Integer: slice = new IntegerSlice(cache, obj, flid); break; case CellarPropertyType.GenDate: slice = new GenDateSlice(cache, obj, flid); break; case CellarPropertyType.OwningAtomic: int dstClsid = mdc.GetDstClsId(flid); if (dstClsid == StTextTags.kClassId) { slice = new StTextSlice(obj, flid, cache.DefaultAnalWs); } break; case CellarPropertyType.ReferenceAtomic: slice = new AtomicReferenceSlice(cache, obj, flid); break; case CellarPropertyType.ReferenceCollection: case CellarPropertyType.ReferenceSequence: slice = new ReferenceVectorSlice(cache, obj, flid); break; } if (slice == null) { throw new Exception("unhandled field type in MakeAutoCustomSlice"); } slice.Label = mdc.GetFieldLabel(flid); return(slice); }
int MakeRealObject(ITsString tssTyped) { // Figure whether owning atomic or owning collection or owning sequence. Throw if none. // Unless we're making an unowned IText for a Notebook Record. ISilDataAccess sdaReal = m_fdoCache.DomainDataByFlid; IFwMetaDataCache mdc = sdaReal.MetaDataCache; CellarPropertyType typeOwning = (CellarPropertyType)(mdc.GetFieldType(m_flidEmptyProp) & (int)CellarPropertyTypeFilter.VirtualMask); // Make a new object of the specified class in the specified property. int ord = 0; switch (typeOwning) { default: if (m_flidEmptyProp != RnGenericRecTags.kflidText) { throw new Exception("ghost string property must be owning object property"); } break; case CellarPropertyType.OwningAtomic: ord = -2; break; case CellarPropertyType.OwningCollection: ord = -1; break; case CellarPropertyType.OwningSequence: // ord = 0 set above (inserting the first and only object at position 0). break; } string sClassRaw = mdc.GetClassName(m_clidDst); string sClass = m_mediator.StringTbl.GetString(sClassRaw, "ClassNames"); string sUndo = String.Format(DetailControlsStrings.ksUndoCreate0, sClass); string sRedo = String.Format(DetailControlsStrings.ksRedoCreate0, sClass); int hvoNewObj = 0; int hvoStringObj = 0; UndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(sUndo, sRedo, m_fdoCache.ServiceLocator.GetInstance <IActionHandler>(), () => { // Special case: if we just created a Text in RnGenericRecord, and we want to show the contents // of an StTxtPara, make the intermediate objects if (m_flidEmptyProp == RnGenericRecTags.kflidText) { var servLoc = Cache.ServiceLocator; var text = servLoc.GetInstance <ITextFactory>().Create(); var stText = servLoc.GetInstance <IStTextFactory>().Create(); text.ContentsOA = stText; var para = servLoc.GetInstance <IStTxtParaFactory>().Create(); stText.ParagraphsOS.Add(para); hvoNewObj = text.Hvo; hvoStringObj = para.Hvo; // Set the RnGenericRec's Text property to reference the new text sdaReal.SetObjProp(m_hvoObj, m_flidEmptyProp, hvoNewObj); } else { hvoNewObj = hvoStringObj = sdaReal.MakeNewObject(m_clidDst, m_hvoObj, m_flidEmptyProp, ord); } // Set its property m_flidStringProp to tssTyped. If it is multilingual, choose based on ghostWs. var typeString = (CellarPropertyType)(mdc.GetFieldType(m_flidStringProp) & (int)CellarPropertyTypeFilter.VirtualMask); switch (typeString) { default: throw new Exception("ghost property must store strings!"); case CellarPropertyType.MultiString: case CellarPropertyType.MultiUnicode: sdaReal.SetMultiStringAlt(hvoStringObj, m_flidStringProp, m_wsToCreate, tssTyped); break; case CellarPropertyType.String: sdaReal.SetString(hvoStringObj, m_flidStringProp, tssTyped); break; } string ghostInitMethod = XmlUtils.GetOptionalAttributeValue(m_nodeObjProp, "ghostInitMethod"); if (ghostInitMethod != null) { var obj = m_fdoCache.ServiceLocator.GetInstance <ICmObjectRepository>().GetObject(hvoNewObj); Type objType = obj.GetType(); System.Reflection.MethodInfo mi = objType.GetMethod(ghostInitMethod); mi.Invoke(obj, null); } }); return(hvoNewObj); }
private void m_tvClasses_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e) { m_lvfields.Items.Clear(); uint clid = (uint)m_tvClasses.SelectedNode.Tag; int countFoundFlids = m_mdc.GetFields(clid, true, (int)CellarModuleDefns.kgrfcptAll, 0, null); int allFlidCount = countFoundFlids; uint[] uIds; using (ArrayPtr flids = MarshalEx.ArrayToNative(allFlidCount, typeof(uint))) { countFoundFlids = m_mdc.GetFields(clid, true, (int)CellarModuleDefns.kgrfcptAll, allFlidCount, flids); uIds = (uint[])MarshalEx.NativeToArray(flids, allFlidCount, typeof(uint)); } m_lvfields.SuspendLayout(); List <ListViewItem> list = new List <ListViewItem>(); for (int i = uIds.Length - 1; i >= 0; --i) { uint flid = uIds[i]; if (flid == 0) { continue; // Keep looking for suitable flids lower in the array. } string className = m_mdc.GetOwnClsName(flid); ListViewItem lvi = new ListViewItem(className); //m_lvfields.Items.Add(className); list.Add(lvi); // flid lvi.SubItems.Add(flid.ToString()); // field name string fieldname = m_mdc.GetFieldName(flid); lvi.SubItems.Add(fieldname); int flidType = m_mdc.GetFieldType(flid); string type = "Not recognized"; string signature = "Not recognized"; uint dstClid; switch (flidType) { // Basic data types. case (int)CellarModuleDefns.kcptBoolean: type = "Basic"; signature = "Boolean"; break; case (int)CellarModuleDefns.kcptInteger: type = "Basic"; signature = "Integer"; break; case (int)CellarModuleDefns.kcptNumeric: type = "Basic"; signature = "Numeric"; break; case (int)CellarModuleDefns.kcptFloat: type = "Basic"; signature = "Float"; break; case (int)CellarModuleDefns.kcptTime: type = "Basic"; signature = "Time"; break; case (int)CellarModuleDefns.kcptGuid: type = "Basic"; signature = "Guid"; break; case (int)CellarModuleDefns.kcptImage: type = "Basic"; signature = "Image"; break; case (int)CellarModuleDefns.kcptGenDate: type = "Basic"; signature = "GenDate"; break; case (int)CellarModuleDefns.kcptBinary: type = "Basic"; signature = "Binary"; break; case (int)CellarModuleDefns.kcptString: type = "Basic"; signature = "String"; break; case (int)CellarModuleDefns.kcptBigString: type = "Basic"; signature = "String (big)"; break; case (int)CellarModuleDefns.kcptMultiString: type = "Basic"; signature = "MultiString"; break; case (int)CellarModuleDefns.kcptMultiBigString: type = "Basic"; signature = "MultiString (big)"; break; case (int)CellarModuleDefns.kcptUnicode: type = "Basic"; signature = "Unicode"; break; case (int)CellarModuleDefns.kcptBigUnicode: type = "Basic"; signature = "Unicode (big)"; break; case (int)CellarModuleDefns.kcptMultiUnicode: type = "Basic"; signature = "MultiUnicode"; break; case (int)CellarModuleDefns.kcptMultiBigUnicode: type = "Basic"; signature = "MultiUnicode (big)"; break; // CmObjects. case (int)CellarModuleDefns.kcptOwningAtom: type = "OA"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarModuleDefns.kcptReferenceAtom: type = "RA"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarModuleDefns.kcptOwningCollection: type = "OC"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarModuleDefns.kcptReferenceCollection: type = "RC"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarModuleDefns.kcptOwningSequence: type = "OS"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarModuleDefns.kcptReferenceSequence: type = "RS"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; } // Type lvi.SubItems.Add(type); // Signature lvi.SubItems.Add(signature); } m_lvfields.Items.AddRange(list.ToArray()); m_lvfields.ResumeLayout(true); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Executes in two distinct scenarios. /// 1. If disposing is true, the method has been called directly /// or indirectly by a user's code via the Dispose method. /// Both managed and unmanaged resources can be disposed. /// 2. If disposing is false, the method has been called by the /// runtime from inside the finalizer and you should not reference (access) /// other managed objects, as they already have been garbage collected. /// Only unmanaged resources can be disposed. /// </summary> /// <param name="disposing">if set to <c>true</c> [disposing].</param> /// <remarks> /// If any exceptions are thrown, that is fine. /// If the method is being done in a finalizer, it will be ignored. /// If it is thrown by client code calling Dispose, /// it needs to be handled by fixing the bug. /// If subclasses override this method, they should call the base implementation. /// </remarks> /// ------------------------------------------------------------------------------------ protected virtual void Dispose(bool disposing) { //Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************"); // Must not be run more than once. if (m_isDisposed) { return; } if (disposing && m_fTurnOnMonitor) { try { // Dispose managed resources here. if (m_sda != null) { UpdateSemaphore semaphore = s_UpdateSemaphores[m_sda]; Debug.Assert(semaphore.fDataUpdateInProgress); // Remember selection so that we can try to reconstruct it after the PropChangeds SelectionHelper selection = SelectionHelper.Create(m_rootSite); TextSelInfo tsiAfterEdit = null; if (selection != null) { tsiAfterEdit = new TextSelInfo(selection.Selection); } bool fAdjustedChangeInfo = false; foreach (VwChangeInfo changeInfo in semaphore.changeInfoQueue) { int ivIns = changeInfo.ivIns; int cvDel = changeInfo.cvDel; int cvIns = changeInfo.cvIns; // Note: m_sda.MetaDataCache increments an internal com object // ref count that may not get cleared until you do // Marshal.FinalReleaseComObject on it. if it doesn't get cleared // it may hang tests. IFwMetaDataCache mdc = m_sda.MetaDataCache; if (!fAdjustedChangeInfo && mdc != null && tsiAfterEdit != null && m_editingHelper != null && m_editingHelper.MonitorTextEdits) { // if the selection-edit resulted in keeping the cursor in the same paragraph // we may need to do some more adjustments because views code // calculates VwChangeInfo based upon a string comparison, which does not // accurately tell us where the string was actually changed if the inserted // characters match those character positions in the original string. // For example changing "this is the old text" by inserting "this is the new text, but " // at the beginning results in the string "this is the old text, but this is the new text" // In that example the views code StringCompare would say ivIns started at "old text" // rather than the beginning of the string, since "this is the " matches the old string. // The first condition prevents our trying to make these adjustments when we have a multi-para // (end-before-anchor) selection. if (m_tsi.Hvo(true) == m_tsi.Hvo(false) && m_tsi.HvoAnchor == tsiAfterEdit.HvoAnchor && m_tsi.HvoAnchor == changeInfo.hvo && m_tsi.TagAnchor == changeInfo.tag) { // Our insertion point can be at the beginning or end of the range. int ichInsertionPointOrig = Math.Min(m_tsi.IchAnchor, m_tsi.IchEnd); // we may need to adjust ivIns, but not for MultiStrings, since // ivIns in that case is a ws, not an offset. int flidtype = mdc.GetFieldType((uint)changeInfo.tag); if (flidtype == (int)CellarModuleDefns.kcptBigString || flidtype == (int)CellarModuleDefns.kcptString) { // if the anchor has moved back after a delete, use it as a starting point if (!m_tsi.IsRange && cvDel > 0 && ivIns < m_tsi.IchAnchor) { if (ivIns + cvDel == m_tsi.IchAnchor) { // user did backspace from insertion point, so effectively // move the IP back the number of characters deleted. ivIns = Math.Max(m_tsi.IchAnchor - cvDel, 0); } // ctrl-del can also cause this, but in that case, characters // after the IP may have been deleted, too. Seems best not to try to adjust. } else { // use the original IP, since changeInfo uses CompareStrings // to calculate it, and that can be wrong when pasted string has // characters that coincidentally match the original string. ivIns = ichInsertionPointOrig; } } // if the initial selection is a range selection in the same paragraph // set the number of deleted characters to be the difference between // the begin and end offsets. if (m_tsi.HvoAnchor == m_tsi.Hvo(true) && m_tsi.IsRange) { cvDel = Math.Abs(m_tsi.IchEnd - m_tsi.IchAnchor); } // Review: do we expect this string to be Normalized already? // Review: should we do nothing if the pasted string contains newline, or set cvIns to the // length of the text after the last newline, or what?? if (InsertedTss != null && InsertedTss.Text != null && InsertedTss.Text.IndexOf(Environment.NewLine) == -1) { cvIns = InsertedTss.Length; } // indicate we've adjusted the changeInfo for the next PropChange. // this should be done only once per edit action. fAdjustedChangeInfo = true; } } m_sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, changeInfo.hvo, changeInfo.tag, ivIns, cvIns, cvDel); } semaphore.fDataUpdateInProgress = false; semaphore.sDescr = string.Empty; semaphore.changeInfoQueue.Clear(); // It is possible that the PropChanged caused a regenerate of the view. This // turned our selection invalid. Try to recover it. if (selection != null && !selection.IsValid) { selection.SetSelection(false); } // This needs to be called after setting the selection. It can cause // AnnotationAdjuster.EndKeyPressed() to be called which expects a // selection to be set. if (m_editingHelper != null) { m_editingHelper.OnFinishedEdit(); } // It is possible that OnFinishedEdit() caused a regenerate of the view. This // turned our selection invalid. Try to recover it. if (selection != null && !selection.IsValid) { selection.SetSelection(false); } } } finally { // In case anything goes wrong, if we possibly can, do this anyway, other wise the pane // may be more-or-less permanently locked. if (m_rootSite != null) { s_sitesMonitoring.Remove(m_rootSite); } // end Wait Cursor // Since it needs m_Owner, this must be done when 'disposing' is true, // as that is a disposable object, which may be gone in // Finalizer mode. if (m_Owner != null) { m_Owner.Cursor = m_oldCursor; } } } // Dispose unmanaged resources here, whether disposing is true or false. m_sda = null; m_Owner = null; m_rootSite = null; m_oldCursor = null; m_tsi = null; m_tssIns = null; m_isDisposed = true; }
static internal bool IsMultilingual(int flid, IFwMetaDataCache mdc) { int cst = mdc.GetFieldType((uint)flid); switch (cst & 0x1f) // mask strips virtual bit { case (int)CellarModuleDefns.kcptMultiString: case (int)CellarModuleDefns.kcptMultiBigString: case (int)CellarModuleDefns.kcptMultiUnicode: case (int)CellarModuleDefns.kcptMultiBigUnicode: return true; default: return false; } }
/// <summary> /// If object hvo has no cached value for the property flidVirtual, do nothing. /// Otherwise, compute a new value for the property, and issue a PropChanged. (Currently only string type supported) /// If it has owning properties of type clidVirtual, do the same for all their items. /// </summary> /// <param name="hvo"></param> /// <param name="flidVirtual"></param> /// <param name="mdc"></param> /// <param name="sda"></param> private void RecomputeVirtuals(int hvo, uint clidVirtual, int flidVirtual, int typeVirtual, IFwMetaDataCache mdc, ISilDataAccess sda, IVwVirtualHandler vh) { if (Cache.GetClassOfObject(hvo) != clidVirtual) return; // Unless it's a computeEveryTime property, we don't need to worry if it's not already cached. if (vh.ComputeEveryTime || sda.get_IsPropInCache(hvo, flidVirtual, typeVirtual, 0)) { vh.Load(hvo, flidVirtual, 0, Cache.VwCacheDaAccessor); switch (typeVirtual) { case (int)CellarModuleDefns.kcptString: sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvo, flidVirtual, 0, 0, 0); break; default: Debug.WriteLine("RecomputeVirtuals: unimplemented prop type"); break; } } uint[] flids = DbOps.GetFieldsInClassOfType(mdc, (int)clidVirtual, FieldType.kgrfcptOwning); foreach (uint flid in flids) { int type = mdc.GetFieldType(flid); if (type == (int)CellarModuleDefns.kfcptOwningAtom) { RecomputeVirtuals(sda.get_ObjectProp(hvo, (int)flid), clidVirtual, flidVirtual, typeVirtual, mdc, sda, vh); } else { // must be owning sequence or collection; do them all. int chvo = sda.get_VecSize(hvo, (int)flid); for (int i = 0; i < chvo; i++) RecomputeVirtuals(sda.get_VecItem(hvo, (int)flid, i), clidVirtual, flidVirtual, typeVirtual, mdc, sda, vh); } } }