/// <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"></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) { System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); // Must not be run more than once. if (m_isDisposed) return; if (disposing) { // Dispose managed resources here. //ResetStatusBarPanel("StatusPanelRecordNumber", ""); //ResetStatusBarPanel("StatusPanelMessage", ""); m_list.ListChanged -= OnListChanged; m_list.AboutToReload -= m_list_AboutToReload; m_list.DoneReload -= m_list_DoneReload; RemoveNotification(); // before disposing list, we need it to get to the Cache. m_list.Dispose(); if (m_mediator != null) { m_mediator.RemoveColleague(this); } if (m_rch != null) m_rch.Dispose(); if (m_recordBarHandler != null) m_recordBarHandler.Dispose(); } // Dispose unmanaged resources here, whether disposing is true or false. m_mediator = null; // This has to be done after the calls to ResetStatusBarPanel in the 'true' section. m_list = null; m_id = null; m_clerkProvidingRootObject = null; m_recordBarHandler = null; m_filterProvider = null; m_activeMenuBarFilter = null; m_rch = null; m_fIsActiveInGui = false; m_isDisposed = true; }
void m_rch_Disposed(object sender, EventArgs e) { // It was disposed, so clear out the data member. if (m_rch != null) m_rch.Disposed -= new EventHandler(m_rch_Disposed); m_rch = null; }
/// <summary> /// Handle one (non-comment) child node of a template (or other node) being used to /// create slices. Update insertPosition to indicate how many were added (it also /// specifies where to add). If fTestOnly is true, do not update insertPosition, just /// return true if any slices would be created. Note that this method is recursive /// indirectly through ProcessPartChildren(). /// </summary> /// <param name="node"></param> /// <param name="path"></param> /// <param name="reuseMap"></param> /// <param name="obj"></param> /// <param name="indent"></param> /// <param name="insertPosition"></param> /// <param name="fTestOnly"></param> /// <param name="parameter"></param> /// <param name="fVisIfData">If true, show slice only if data present.</param> /// <returns></returns> private NodeTestResult ProcessSubpartNode(XmlNode node, ArrayList path, ObjSeqHashMap reuseMap, ICmObject obj, int indent, ref int insertPosition, bool fTestOnly, string parameter, bool fVisIfData, XmlNode caller) { string editor = XmlUtils.GetOptionalAttributeValue(node, "editor"); try { if (editor != null) editor = editor.ToLower(); int flid = GetFlidFromNode(node, obj); if (m_sliceFilter != null && flid != 0 && !m_sliceFilter.IncludeSlice(node, obj, flid)) { return NodeTestResult.kntrNothing; } switch (node.Name) { default: break; // Nothing to do for unrecognized element, such as deParams. case "slice": return AddSimpleNode(path, node, reuseMap, editor, flid, obj, indent, ref insertPosition, fTestOnly, fVisIfData, caller); case "seq": return AddSeqNode(path, node, reuseMap, editor, flid, obj, indent + Slice.ExtraIndent(node), ref insertPosition, fTestOnly, parameter, fVisIfData, caller); case "obj": return AddAtomicNode(path, node, reuseMap, editor, flid, obj, indent + Slice.ExtraIndent(node), ref insertPosition, fTestOnly, parameter, fVisIfData, caller); case "if": if (XmlVc.ConditionPasses(node, obj.Hvo, m_cache)) { NodeTestResult ntr = ProcessPartChildren(node, path, reuseMap, obj, indent, ref insertPosition, fTestOnly, parameter, fVisIfData, caller); if (fTestOnly && ntr != NodeTestResult.kntrNothing) return ntr; } break; case "ifnot": if (!XmlVc.ConditionPasses(node, obj.Hvo, m_cache)) { NodeTestResult ntr = ProcessPartChildren(node, path, reuseMap, obj, indent, ref insertPosition, fTestOnly, parameter, fVisIfData, caller); if (fTestOnly && ntr != NodeTestResult.kntrNothing) return ntr; } break; case "choice": foreach (XmlNode clause in node.ChildNodes) { if (clause.Name == "where") { if (XmlVc.ConditionPasses(clause, obj.Hvo, m_cache)) { NodeTestResult ntr = ProcessPartChildren(clause, path, reuseMap, obj, indent, ref insertPosition, fTestOnly, parameter, fVisIfData, caller); if (fTestOnly && ntr != NodeTestResult.kntrNothing) return ntr; break; } // Allow multiple where elements to be processed, but expand only // the first one whose condition passes. } else if (clause.Name == "otherwise") { // enhance: verify last node? NodeTestResult ntr = ProcessPartChildren(clause, path, reuseMap, obj, indent, ref insertPosition, fTestOnly, parameter, fVisIfData, caller); if (fTestOnly && ntr != NodeTestResult.kntrNothing) return ntr; break; } else { throw new Exception( "elements in choice must be <where...> or <otherwise>."); } } break; case "RecordChangeHandler": // No, since it isn't owned by the data tree, even though it created it. //if (m_rch != null && m_rch is IDisposable) // (m_rch as IDisposable).Dispose(); if (m_rch != null && !m_rch.HasRecordListUpdater && m_rch is IDisposable) { // The above version of the Dispose call was bad, // when m_rlu 'owned' the m_rch. // Now, we know there is no 'owning' m_rlu, so we have to do it. (m_rch as IDisposable).Dispose(); m_rch = null; } m_rch = (IRecordChangeHandler)DynamicLoader.CreateObject(node, null); m_rch.Disposed += new EventHandler(m_rch_Disposed); Debug.Assert(m_rch != null); m_listName = XmlUtils.GetOptionalAttributeValue(node, "listName"); m_rlu = null; ResetRecordListUpdater(); // m_rlu may still be null, but that appears to be just fine. m_rch.Setup(obj, m_rlu); return NodeTestResult.kntrNothing; } } catch (Exception error) { // This doesn't need to be localized because it's displayed in a "yellow box" // error report. string s = "FieldWorks ran into a problem trying to display this object"; s += " in DataTree::ApplyLayout: " + error.Message; s += "\r\nThe object id was " + obj.Hvo.ToString() + "."; if (editor != null) s += " The editor was '" + editor + "'.\r\n"; s += " The text of the current node was " + node.OuterXml; //now send it on throw new ApplicationException(s, error); } // other types of child nodes, for example, parameters for jtview, don't even have // the potential for expansion. return NodeTestResult.kntrNothing; }
/// ----------------------------------------------------------------------------------- /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged /// resources; <c>false</c> to release only unmanaged resources. /// </param> /// ----------------------------------------------------------------------------------- protected override void Dispose(bool disposing) { //Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************"); // Must not be run more than once. if (IsDisposed) return; // m_sda COM object block removed due to crash in Finializer thread LT-6124 if (disposing) { // Do this first, before setting m_fDisposing to true. if (m_sda != null) m_sda.RemoveNotification(this); m_fDisposing = true; // 'Disposing' isn't until we call base dispose. m_currentSlice = null; if (m_rch != null) { if (m_rch.HasRecordListUpdater) { m_rch.Fixup(false); // no need to refresh record list on shutdown. } else if (m_rch is IDisposable) { // It's fine to dispose it, after all, because m_rch has no other owner. (m_rch as IDisposable).Dispose(); } } if (m_tooltip != null) { m_tooltip.RemoveAll(); m_tooltip.Dispose(); } foreach (Slice slice in Controls) slice.ShowContextMenu -= new TreeNodeEventHandler(this.OnShowContextMenu); } m_sda = null; m_currentSlice = null; m_root = null; m_cache = null; m_mdc = null; m_autoCustomFieldNodesDocument = null; m_autoCustomFieldNodesDocRoot = null; m_rch = null; m_rootLayoutName = null; m_smallImages = null; // Client has to deal with it, since it gave it to us. // protected AutoDataTreeMenuHandler m_autoHandler; // No tusing this data member. m_layoutInventory = null; m_partInventory = null; m_sliceFilter = null; m_monitoredProps = null; m_stringTable = null; m_persistenceProvider = null; m_styleSheet = null; // We may have made it, or been given it. m_tooltip = null; m_mediator = null; m_rlu = null; base.Dispose(disposing); // This will call Dispose on each Slice. }
/// <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"></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) { // Dispose managed resources here. //ResetStatusBarPanel("StatusPanelRecordNumber", ""); //ResetStatusBarPanel("StatusPanelMessage", ""); m_list.ListChanged -= new ListChangedEventHandler(OnListChanged); m_list.AboutToReload -= new EventHandler(m_list_AboutToReload); m_list.DoneReload -= new EventHandler(m_list_DoneReload); m_list.Dispose(); if (m_mediator != null) { m_mediator.RemoveColleague(this); } if (m_filterProvider != null) m_filterProvider.Dispose(); if (m_rch != null && m_rch is IDisposable) (m_rch as IDisposable).Dispose(); if (m_recordBarHandler != null) m_recordBarHandler.Dispose(); } // Dispose unmanaged resources here, whether disposing is true or false. m_mediator = null; // This has to be done after the calls to ResetStatusBarPanel in the 'true' section. m_list = null; m_id = null; m_clerkProvidingRootObject = null; m_recordBarHandler = null; m_filterProvider = null; m_activeMenuBarFilter = null; m_rch = null; m_fIsActiveInGui = false; m_isDisposed = true; }
/// ----------------------------------------------------------------------------------- /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged /// resources; <c>false</c> to release only unmanaged resources. /// </param> /// ----------------------------------------------------------------------------------- protected override void Dispose(bool disposing) { System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); // Must not be run more than once. if (IsDisposed) return; // m_sda COM object block removed due to crash in Finializer thread LT-6124 if (disposing) { // Do this first, before setting m_fDisposing to true. if (m_sda != null) m_sda.RemoveNotification(this); // We'd prefer to do any cleanup of the current slice BEFORE its parent gets disposed. // But I can't find any event that is raised before Dispose when switching areas. // To avoid losing changes (e.g., in InterlinearSlice/ Words Analysis view), let the current // slice know it is no longer current, if we haven't already done so. if (m_currentSlice != null && !m_currentSlice.IsDisposed) m_currentSlice.SetCurrentState(false); m_currentSlice = null; m_fDisposing = true; // 'Disposing' isn't until we call base dispose. if (m_rch != null) { if (m_rch.HasRecordListUpdater) m_rch.Fixup(false); // no need to refresh record list on shutdown. else // It's fine to dispose it, after all, because m_rch has no other owner. m_rch.Dispose(); } if (m_tooltip != null) { m_tooltip.RemoveAll(); m_tooltip.Dispose(); } foreach (Slice slice in Slices) slice.ShowContextMenu -= OnShowContextMenu; } m_sda = null; m_currentSlice = null; m_root = null; m_cache = null; m_mdc = null; m_autoCustomFieldNodesDocument = null; m_autoCustomFieldNodesDocRoot = null; m_rch = null; m_rootLayoutName = null; m_smallImages = null; // Client has to deal with it, since it gave it to us. // protected AutoDataTreeMenuHandler m_autoHandler; // No tusing this data member. m_layoutInventory = null; m_partInventory = null; m_sliceFilter = null; m_monitoredProps = null; m_stringTable = null; m_persistenceProvider = null; m_styleSheet = null; // We may have made it, or been given it. m_tooltip = null; m_mediator = null; m_rlu = null; base.Dispose(disposing); // This will call Dispose on each Slice. }