/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Apply the filter the user clicked in the side bar or in the menu.
		/// </summary>
		/// <param name="sender">The side-bar button the user clicked</param>
		/// ------------------------------------------------------------------------------------
		public virtual void OnChangeFilter(object sender)
		{
			CheckDisposed();

			CmFilter userFilter = null;
			if (sender is SBTabItemProperties) // from sidebar
				userFilter = (sender != null) ? (CmFilter)((SBTabItemProperties)sender).Tag : null;
			else if (sender is TMItemProperties) // from menu
				userFilter = (sender != null) ? (CmFilter)((TMItemProperties)sender).Tag : null;

			if (userFilter != null && !GetFilterValuesFromUser(userFilter))
				return;

			NotesViewFilter annotationFilter = new NotesViewFilter(Cache, userFilter);
			FilteredSequenceHandler handler;
			try
			{
				handler = FilteredSequenceHandler.GetFilterInstance(m_fdoCache,
					ScrBookAnnotations.kClassId, annotationFilter, Handle.ToInt32());

				if (handler != null)
					handler.Reinitialize(false);
				else
				{
					if (userFilter != null)
						userFilter.UserView = m_UserView;

					handler = new FilteredSequenceHandler(m_fdoCache, ScrBookAnnotations.kClassId,
						Handle.ToInt32(), annotationFilter, null, m_UserView);
				}
			}
			catch
			{
				// User must have cancelled the filter, or something horrible happened.
				// Just revert back to the previous state.
				NotesMainWnd notesMainWnd = TheMainWnd as NotesMainWnd;
				Debug.Assert(notesMainWnd != null);
				notesMainWnd.SelectFilterButton(m_vc.NotesSequenceHandler != null ?
					m_vc.NotesSequenceHandler.Filter as CmFilter: null);
				return;
			}

			Debug.Assert(handler != null);
			m_currentNotesTag = handler.Tag;

			// Set up the view constructor with the filtered sequence handler corresponding to the
			// notes filter chosen by the user.
			m_vc.NotesSequenceHandler = handler;
			RefreshDisplay();
			if (FilterChanged != null)
				FilterChanged(this, userFilter);
		}
		public void TestLoad_AtomicObjectFilter()
		{
			CheckDisposed();

			// Set up a filter
			CmFilter filter = new CmFilter();
			Cache.LangProject.FiltersOC.Add(filter);
			filter.ClassId = ScrScriptureNote.kClassId;
			// We will filter ScrScriptureNotes on the AnnotationType field (which is actually a
			// field of the base class CmAnnotation).
			filter.ColumnInfo = ScrScriptureNote.kclsidScrScriptureNoteString + "," +
				((int)CmAnnotation.CmAnnotationTags.kflidAnnotationType).ToString();
			filter.ShowPrompt = 0;
			CmRow row = new CmRow();
			filter.RowsOS.Append(row);
			CmCell cell = new CmCell();
			row.CellsOS.Append(cell);
			// Now specify the matching criteria for this filter cell
			ITsStrBldr bldr = TsStrBldrClass.Create();
			bldr.Replace(0, 0, "Matches ",
				SIL.FieldWorks.Common.FwUtils.StyleUtils.CharStyleTextProps(null, Cache.DefaultUserWs));
			StringUtils.InsertOrcIntoPara(m_inMemoryCache.m_translatorNoteDefn.Guid,
				FwObjDataTypes.kodtNameGuidHot,	bldr, bldr.Length,
				bldr.Length, Cache.DefaultUserWs);
			cell.Contents.UnderlyingTsString = bldr.GetString();

			// Construct a handler to apply the above filter.
			filter.UserView = m_userView;
			FilteredSequenceHandler handler = new FilteredSequenceHandler(Cache,
				ScrBookAnnotations.kClassId, -42, filter, null, m_userView);
			// CacheVecProp() should be called with an array of HVOs representing only the translator notes.
			m_mockedDataAccess.Expect("CacheVecProp",
				new object[] {m_annotationsGen.Hvo, -94, new int[] {m_note2b.Hvo, m_note3.Hvo}, 2});

			// Now test the Load method
			handler.Load(m_annotationsGen.Hvo, -94, -1, (IVwCacheDa)m_mockedDataAccess.MockInstance);
			m_mockedDataAccess.Verify();
		}
		public void TestLoad_ObjectSequenceFilterWithSubItems()
		{
			CheckDisposed();

			// Set up a filter
			CmFilter filter = new CmFilter();
			Cache.LangProject.FiltersOC.Add(filter);
			filter.ClassId = ScrScriptureNote.kClassId;
			// We will filter ScrScriptureNotes on the Categories field.
			filter.ColumnInfo = ScrScriptureNote.kclsidScrScriptureNoteString + "," +
				((int)ScrScriptureNote.ScrScriptureNoteTags.kflidCategories).ToString();
			filter.ShowPrompt = 1;
			CmRow row = new CmRow();
			filter.RowsOS.Append(row);
			CmCell cell = new CmCell();
			row.CellsOS.Append(cell);
			// Now specify the matching criteria for this filter cell
			ITsStrBldr bldr = TsStrBldrClass.Create();
			bldr.Replace(0, 0, "Matches  +subitems",
				SIL.FieldWorks.Common.FwUtils.StyleUtils.CharStyleTextProps(null, Cache.DefaultUserWs));
			StringUtils.InsertOrcIntoPara(m_inMemoryCache.m_categoryDiscourse.Guid,
				FwObjDataTypes.kodtNameGuidHot, bldr, 8, 8, Cache.DefaultUserWs);
			cell.Contents.UnderlyingTsString = bldr.GetString();

			// Set up mocked ChooserDlg to expect to be called with the default category of Discourse (from
			// filter cell criteria defined above) but return Grammar category.
			m_mockedChooserDlg.ExpectAndReturn("GetPossibility", m_inMemoryCache.m_categoryGrammar.Hvo,
				new object[] {m_scr.NoteCategoriesOA, m_inMemoryCache.m_categoryDiscourse.Hvo});

			// Construct a handler to apply the above filter.
			filter.UserView = m_userView;
			filter.PossibilitySupplier = (ICmPossibilitySupplier)m_mockedChooserDlg.MockInstance;
			FilteredSequenceHandler handler = new FilteredSequenceHandler(Cache,
				ScrBookAnnotations.kClassId, -42, filter, null, m_userView);

			// Now test the Load method
			// CacheVecProp() should be called with an array of HVOs representing all the Grammar notes,
			// including those that refer to sub-items of the main Grammar category.
			m_mockedDataAccess.Expect("CacheVecProp",
				new object[] {m_annotationsGen.Hvo, -94, new int[] {m_note2a.Hvo, m_note2b.Hvo, m_note3.Hvo}, 3});
			handler.Load(m_annotationsGen.Hvo, -94, -1, (IVwCacheDa)m_mockedDataAccess.MockInstance);
			m_mockedDataAccess.Verify();
			m_mockedChooserDlg.Verify();

			// Make sure the newly-selected object (i.e., the Grammar category) has been stored as the
			// filter criteria (for next time).
			StringUtils.InsertOrcIntoPara(m_inMemoryCache.m_categoryGrammar.Guid,
				FwObjDataTypes.kodtNameGuidHot, bldr, 8, 9, Cache.DefaultUserWs);
			AssertEx.AreTsStringsEqual(bldr.GetString(), cell.Contents.UnderlyingTsString);
		}
		public void TestLoad_IntFilter()
		{
			CheckDisposed();

			// Set up a filter
			CmFilter filter = new CmFilter();
			Cache.LangProject.FiltersOC.Add(filter);
			filter.ClassId = ScrScriptureNote.kClassId;
			// We will filter ScrScriptureNotes on the ResolutionStatus field.
			filter.ColumnInfo = ScrScriptureNote.kclsidScrScriptureNoteString + "," +
				((int)ScrScriptureNote.ScrScriptureNoteTags.kflidResolutionStatus).ToString();
			filter.ShowPrompt = 0;
			CmRow row = new CmRow();
			filter.RowsOS.Append(row);
			CmCell cell = new CmCell();
			row.CellsOS.Append(cell);
			// Now specify the matching criteria for this filter cell
			ITsStrFactory factory = TsStrFactoryClass.Create();
			cell.Contents.UnderlyingTsString = factory.MakeString("= 0", Cache.DefaultUserWs);

			// Construct a handler to apply the above filter.
			filter.UserView = m_userView;
			FilteredSequenceHandler handler = new FilteredSequenceHandler(Cache,
				ScrBookAnnotations.kClassId, -42, filter, null, m_userView);
			// CacheVecProp() should be called with an array of HVOs representing only the open notes.
			m_mockedDataAccess.Expect("CacheVecProp",
				new object[] { m_annotationsGen.Hvo, -94, new int[] { m_note1.Hvo, m_note2b.Hvo }, 2 });

			// Now test the Load method
			handler.Load(m_annotationsGen.Hvo, -94, -1, (IVwCacheDa)m_mockedDataAccess.MockInstance);
			m_mockedDataAccess.Verify();
		}
		public void TestLoad_NoFilter()
		{
			CheckDisposed();

			// Construct a handler to apply the non-existent filter.
			FilteredSequenceHandler handler = new FilteredSequenceHandler(Cache,
				ScrBookAnnotations.kClassId, -42, m_userView);
			// CacheVecProp() should be called with an array of HVOs representing all notes.
			m_mockedDataAccess.Expect("CacheVecProp",
				new object[] { m_annotationsGen.Hvo, -94,
					new int[] { m_note1.Hvo, m_note2a.Hvo, m_note2b.Hvo, m_note3.Hvo }, 4 });

			// Now test the Load method
			handler.Load(m_annotationsGen.Hvo, -94, -1, (IVwCacheDa)m_mockedDataAccess.MockInstance);
			m_mockedDataAccess.Verify();
		}
 /// ------------------------------------------------------------------------------------
 /// <summary>
 /// Initializes a new instance of the <see cref="T:VirtualPropChangeWatcher"/> class.
 /// </summary>
 /// <param name="flid">The "real" flid that the filtered sequence handler is filtering.
 /// This must be a sequence property</param>
 /// <param name="handler">The filtered sequence handler for which we are a love slave.
 /// </param>
 /// ------------------------------------------------------------------------------------
 internal VirtualPropChangeWatcher(int flid, FilteredSequenceHandler handler) :
     base(handler.Cache, flid)
 {
     m_handler = handler;
 }
		public void GetVirtualIndex()
		{
			FilteredSequenceHandler handler = new FilteredSequenceHandler(Cache,
				LangProject.kClassId, 1, new OddRowFilter(Cache,
				(int)CmFilter.CmFilterTags.kflidRows), null,
				new SimpleFlidProvider((int)CmFilter.CmFilterTags.kflidRows));

			// setup
			// Added by setup:         0, virtual index 0
			AddRow(m_filter, new DummyRow());	// 1, virtual index -1
			AddRow(m_filter, new DummyRow());	// 2, virtual index 1
			AddRow(m_filter, new DummyRow());	// 3, virtual index -1

			int hvoFilter = m_filter.Hvo;
			handler.Load(hvoFilter, handler.Tag, 0, Cache.VwCacheDaAccessor);

			// Test the GetVirtualIndex method
			Assert.AreEqual(0, handler.GetVirtualIndex(hvoFilter, 0));
			Assert.AreEqual(-1, handler.GetVirtualIndex(hvoFilter, 1));
			Assert.AreEqual(1, handler.GetVirtualIndex(hvoFilter, 2));
			Assert.AreEqual(-1, handler.GetVirtualIndex(hvoFilter, 3));
		}
			/// --------------------------------------------------------------------------------
			/// <summary>
			/// Initializes a new instance of the <see cref="DummyChangeWatcher"/> class.
			/// </summary>
			/// <param name="handler">The filtered sequence handler.</param>
			/// --------------------------------------------------------------------------------
			public DummyChangeWatcher(FilteredSequenceHandler handler)
				: base(handler.Cache, handler.Tag)
			{
			}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Constructs a TePrintLayoutConfig to configure the main print layout
		/// </summary>
		/// <param name="cache">The cache.</param>
		/// <param name="styleSheet">The style sheet.</param>
		/// <param name="publication">The publication.</param>
		/// <param name="viewType">Type of the view.</param>
		/// <param name="filterInstance">the book filter instance in effect</param>
		/// <param name="printDateTime">printing date and time</param>
		/// <param name="fIntroDivision">set to <c>true</c> for a division that displays book
		/// title and introduction material, <c>false</c> for a division that displays main
		/// scripture text.</param>
		/// <param name="hvoBook">The hvo of the book we're displaying.</param>
		/// <param name="sharedStream">A layout stream used for footnotes which is shared across
		/// multiple divisions</param>
		/// <param name="ws">The writing system to use for the view.</param>
		/// ------------------------------------------------------------------------------------
		public TePrintLayoutConfig(FdoCache cache, IVwStylesheet styleSheet,
			IPublication publication, TeViewType viewType, int filterInstance,
			DateTime printDateTime, bool fIntroDivision, int hvoBook, IVwLayoutStream sharedStream,
			int ws)
		{
			m_fdoCache = cache;
			m_scr = m_fdoCache.LangProject.TranslatedScriptureOA;
			m_styleSheet = styleSheet;
			m_pub = publication;
			m_viewType = viewType;
			m_bookFilterInstance = filterInstance;
			m_printDateTime = printDateTime;
			m_fIntroDivision = fIntroDivision;
			m_hvoBook = hvoBook;
			m_sharedStream = sharedStream;
			m_ws = ws;

			m_sectionFilterInstance = g_nextSectionFilterInstance++;
			m_sectionFilter = new FilteredSequenceHandler(cache, ScrBook.kClassId,
				m_sectionFilterInstance, this, this,
				new SimpleFlidProvider((int)ScrBook.ScrBookTags.kflidSections));

			m_paraCounter = ParagraphCounterManager.GetParaCounter(cache, (int)TeViewGroup.Scripture);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initializes a new instance of the <see cref="T:VirtualPropChangeWatcher"/> class.
		/// </summary>
		/// <param name="flid">The "real" flid that the filtered sequence handler is filtering.
		/// This must be a sequence property</param>
		/// <param name="handler">The filtered sequence handler for which we are a love slave.
		/// </param>
		/// ------------------------------------------------------------------------------------
		internal VirtualPropChangeWatcher(int flid, FilteredSequenceHandler handler):
			base(handler.Cache, flid)
		{
			m_handler = handler;
		}