/// ------------------------------------------------------------------------------------ /// <summary> /// Make a finder appropriate to the given column specification /// </summary> /// <param name="cache">FdoCache</param> /// <param name="colSpec">column specification</param> /// <param name="vc">The vc.</param> /// <param name="app">The application.</param> /// <returns>finder for colSpec</returns> /// ------------------------------------------------------------------------------------ static public IStringFinder CreateFinder(FdoCache cache, XmlNode colSpec, XmlBrowseViewBaseVc vc, IApp app) { string layoutName = XmlUtils.GetOptionalAttributeValue(colSpec, "layout"); string sSortMethod = XmlUtils.GetOptionalAttributeValue(colSpec, "sortmethod"); string sortType = XmlUtils.GetOptionalAttributeValue(colSpec, "sortType", null); LayoutFinder result; if (sSortMethod != null) { result = new SortMethodFinder(cache, sSortMethod, layoutName, colSpec, app); } else if (sortType != null) { switch (sortType) { case "integer": result = new IntCompareFinder(cache, layoutName, colSpec, app); break; case "date": case "YesNo": case "stringList": case "genDate": // no special action needed here for sorting dates or date that shows as 'yes" or "no"; // Using a SortCollectorEnv triggers special // action in case "datetime"/"gendate" of XmlVc.ProcessFrag(). result = new LayoutFinder(cache, layoutName, colSpec, vc.StringTbl, app); break; default: throw new ConfigurationException("unexpected sort type: " + sortType, colSpec); } } else { result = new LayoutFinder(cache, layoutName, colSpec, vc.StringTbl, app); } result.Vc = vc; return result; }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { //Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************"); // Must not be run more than once. if (IsDisposed) return; if (disposing) { if (m_bv != null && !m_bv.IsDisposed && m_bv.SpecialCache != null) m_bv.SpecialCache.RemoveNotification(this); } base.Dispose(disposing); if( disposing ) { if (components != null) { components.Dispose(); } if (m_bv != null && !m_bv.IsDisposed) m_bv.Dispose(); } m_xbvvc = null; m_nodeSpec = null; m_stringTable = null; m_bv = null; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Inits the specified node spec. /// </summary> /// <param name="nodeSpec">The node spec.</param> /// <param name="hvoRoot">The hvo root.</param> /// <param name="fakeFlid">The fake flid.</param> /// <param name="cache">The cache.</param> /// <param name="mediator">The mediator.</param> /// <param name="bv">The bv. Also used to set SortItemProvider</param> /// ------------------------------------------------------------------------------------ public virtual void Init(XmlNode nodeSpec, int hvoRoot, int fakeFlid, FdoCache cache, Mediator mediator, BrowseViewer bv) { CheckDisposed(); Debug.Assert((m_selectedIndex == -1), "Cannot set the index to less than zero before initializing."); Debug.Assert(m_nodeSpec == null || m_nodeSpec == nodeSpec, "XmlBrowseViewBase.Init: Mismatched configuration parameters."); m_hvoRoot = hvoRoot; m_fakeFlid = fakeFlid; if (m_nodeSpec == null) m_nodeSpec = nodeSpec; m_bv = bv; StringTbl = mediator.StringTbl; m_mediator = mediator; m_fdoCache = cache; m_sda = m_bv.SpecialCache; // This is usually done in MakeRoot, but we need it to exist right from the start // because right after we make this window we use info from the VC to help make // the column headers. if (bv != null) m_sortItemProvider = bv.SortItemProvider; m_xbvvc = Vc; string sDefaultCursor = XmlUtils.GetOptionalAttributeValue(nodeSpec, "defaultCursor", null); // Set a default cursor for a ReadOnly view, if none is given. if (sDefaultCursor == null && ReadOnlySelect) sDefaultCursor = "Arrow"; if (sDefaultCursor != null) { switch (sDefaultCursor) { case "IBeam": EditingHelper.DefaultCursor = Cursors.IBeam; break; case "Hand": EditingHelper.DefaultCursor = Cursors.Hand; break; case "Arrow": EditingHelper.DefaultCursor = Cursors.Arrow; break; case "Cross": EditingHelper.DefaultCursor = Cursors.Cross; break; } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Inits the XML. /// </summary> /// <param name="node">The node.</param> /// ------------------------------------------------------------------------------------ public override void InitXml(XmlNode node) { CheckDisposed(); base.InitXml(node); SortMethod = XmlUtils.GetManditoryAttributeValue(node, "sortmethod"); WritingSystemName = XmlUtils.GetOptionalAttributeValue(node, "ws", null); // Enhance JohnT: if we start using string tables for browse views, // we will need a better way to provide one to the Vc we make here. // Note: we don't need a top-level spec because we're only going to process one // column's worth. m_vc = new XmlBrowseViewBaseVc(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Keys the specified item. /// </summary> /// <param name="item">The item.</param> /// <param name="fForSorting">if set to <c>true</c> [f for sorting].</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ public ITsString Key(ManyOnePathSortItem item, bool fForSorting) { CheckDisposed(); if (m_cache == null) throw new ApplicationException("There's no way the browse VC (m_vc) can get a string in its current state."); int hvo = item.RootObject.Hvo; TsStringCollectorEnv collector; if (fForSorting) { collector = new SortCollectorEnv(null, m_cache.MainCacheAccessor, hvo); } else { collector = new TsStringCollectorEnv(null, m_cache.MainCacheAccessor, hvo); } // This will check to see if the VC is either null or disposed. The disposed check is neccesary because // there are several instances where we can have a reference to an instance that was disposed, which will // cause problems later on. // Enhance CurtisH/EricP: If this VC gets used in other places, rather than adding more checks like this one, // it may be better to refactor XWorksViewBase to cause it to reload the sorter and filter from persistence // every time the tool is changed if (m_vc == null || m_vc.IsDisposed) { m_vc = new XmlBrowseViewBaseVc(m_cache, m_stringTbl); } else { if (m_vc.Cache == null) m_vc.Cache = m_cache; if (m_vc.Cache == null) throw new ApplicationException("There's no way the browse VC (m_vc) can get a string in its current state."); if (m_vc.StringTbl == null) m_vc.StringTbl = m_stringTbl; } m_vc.DisplayCell(item, m_colSpec, hvo, collector); return collector.Result; }
private Set<int> GetDescendents(int hvoCommonAncestor, int relativesFlid) { string listPropertyName = Cache.MetaDataCacheAccessor.GetFieldName((uint)relativesFlid); string parentObjName = Cache.MetaDataCacheAccessor.GetClassName((uint)m_cache.GetClassOfObject(hvoCommonAncestor)); string xpathToPart = "./part[@id='" + parentObjName + "-Jt-" + listPropertyName + "']"; XmlNode pathSpec = m_parentToChildrenSpecs.SelectSingleNode(xpathToPart); if (pathSpec == null) throw new ArgumentException("Expected to find part ({0}) in ParentClassPathsToChildren", xpathToPart); // get the part spec that gives us the path from obsolete current (parent) list item object // to the new one. using (XmlBrowseViewBaseVc vc = new XmlBrowseViewBaseVc(m_cache, null)) { ManyOnePathSortItem parentItem = new ManyOnePathSortItem(hvoCommonAncestor, null, null); XmlBrowseViewBaseVc.ItemsCollectorEnv collector = new XmlBrowseViewBaseVc.ItemsCollectorEnv(null, m_cache, hvoCommonAncestor); vc.DisplayCell(parentItem, pathSpec, hvoCommonAncestor, collector); if (collector.HvosCollectedInCell != null && collector.HvosCollectedInCell.Count > 0) { return collector.HvosCollectedInCell; } } return new Set<int>(); }
private Set<int> GetDescendents(int hvoCommonAncestor, int relativesFlid) { string listPropertyName = Cache.MetaDataCacheAccessor.GetFieldName(relativesFlid); string parentObjName = Cache.ServiceLocator.GetInstance<ICmObjectRepository>().GetObject(hvoCommonAncestor).ClassName; string xpathToPart = "./part[@id='" + parentObjName + "-Jt-" + listPropertyName + "']"; XmlNode pathSpec = m_parentToChildrenSpecs.SelectSingleNode(xpathToPart); Debug.Assert(pathSpec != null, String.Format("You are experiencing a rare and difficult-to-reproduce error (LT- 11443 and linked issues). If you can add any information to the issue or fix it please do. If JohnT is available please call him over. Expected to find part ({0}) in ParentClassPathsToChildren", xpathToPart)); if (pathSpec == null) return new Set<int>(); // This just means we don't find a related object. Better than crashing, but not what we intend. // get the part spec that gives us the path from obsolete current (parent) list item object // to the new one. var vc = new XmlBrowseViewBaseVc(m_cache, null); var parentItem = new ManyOnePathSortItem(hvoCommonAncestor, null, null); var collector = new XmlBrowseViewBaseVc.ItemsCollectorEnv(null, m_cache, hvoCommonAncestor); vc.DisplayCell(parentItem, pathSpec, hvoCommonAncestor, collector); if (collector.HvosCollectedInCell != null && collector.HvosCollectedInCell.Count > 0) { return collector.HvosCollectedInCell; } return new Set<int>(); }
/// <summary> /// The stored sorter files keep messing us up here, so we need to do a bit of post-deserialization processing. /// </summary> /// <returns>true if we restored something different from what was already there.</returns> protected override bool TryRestoreSorter(Mediator mediator, XmlNode clerkConfiguration, FdoCache cache) { var fakevc = new XmlBrowseViewBaseVc { SuppressPictures = true, Cache = Cache }; // SuppressPictures to make sure that we don't leak anything as this will not be disposed. if(base.TryRestoreSorter(mediator, clerkConfiguration, cache) && Sorter is GenRecordSorter) { var sorter = (GenRecordSorter)Sorter; var stringFinderComparer = sorter.Comparer as StringFinderCompare; if (stringFinderComparer != null) { var colSpec = ReflectionHelper.GetField(stringFinderComparer.Finder, "m_colSpec") as XmlNode ?? BrowseViewFormCol; sorter.Comparer = new StringFinderCompare(LayoutFinder.CreateFinder(Cache, colSpec, fakevc, (IApp)m_mediator.PropertyTable.GetValue("App")), stringFinderComparer.SubComparer); } return true; } if(Sorter is GenRecordSorter) // If we already have a GenRecordSorter, it's probably an existing, valid one. return false; // Try to create a sorter based on the current Reversal Index's WritingSystem var newGuid = ReversalIndexEntryUi.GetObjectGuidIfValid(mediator, "ReversalIndexGuid"); if(newGuid.Equals(Guid.Empty)) return false; var ri = cache.ServiceLocator.GetObject(newGuid) as IReversalIndex; if(ri == null) return false; var writingSystem = (IWritingSystem)Cache.WritingSystemFactory.get_Engine(ri.WritingSystem); m_list.Sorter = new GenRecordSorter(new StringFinderCompare(LayoutFinder.CreateFinder(Cache, BrowseViewFormCol, fakevc, (IApp)m_mediator.PropertyTable.GetValue("App")), new WritingSystemComparer(writingSystem))); return true; }