예제 #1
0
		/// <summary>
		/// The stuff common to all the ways we mak an FSI.
		/// </summary>
		/// <param name="item"></param>
		protected void SetupFsi(FilterSortItem item)
		{
			MakeCombo(item);
			item.FilterChanged += new FilterChangeHandler(this.FilterChangedHandler);
		}
예제 #2
0
		/// <summary>
		/// Create the common options for all FSI combos (except Integer).
		/// </summary>
		/// <param name="item"></param>
		protected void MakeCombo(FilterSortItem item)
		{
			FwComboBox combo = new FwComboBox();
			combo.DropDownStyle = ComboBoxStyle.DropDownList;
			combo.BackColor = SystemColors.Window;
			combo.WritingSystemFactory = m_wsf;
			combo.StyleSheet = m_bv.StyleSheet;
			item.Combo = combo;
			combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksShowAll), null, item));

			string blankPossible = XmlUtils.GetOptionalAttributeValue(item.Spec, "blankPossible", "true");
			switch (blankPossible)
			{
				case "true":
					combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksBlanks), new BlankMatcher(), item));
					combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksNonBlanks), new NonBlankMatcher(), item));
					break;
			}

			// Enhance JohnT: figure whether the column has vernacular or analysis data...
			int ws = 0;
			if (item.Spec != null)
			{
				string wsParam = XmlViewsUtils.FindWsParam(item.Spec);
				if (wsParam.Length == 0)
					wsParam = XmlUtils.GetOptionalAttributeValue(item.Spec, "ws", "");
				ws = XmlViewsUtils.GetWsFromString(wsParam, m_cache);
			}
			if (ws == 0)
				ws = m_cache.DefaultVernWs; // some sort of fall-back in case we can't determine a WS from the spec.

			string beSpec = XmlUtils.GetOptionalAttributeValue(item.Spec, "bulkEdit", "");
			if (String.IsNullOrEmpty(beSpec))
				beSpec = XmlUtils.GetOptionalAttributeValue(item.Spec, "chooserFilter", "");

			string sortType = XmlUtils.GetOptionalAttributeValue(item.Spec, "sortType", null);
			switch (sortType)
			{
				case "integer":
					// For columns which are interger values we offer the user a couple preset filters
					// one is  "0"  and the other is "Greater than zero"
					combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksZero),
						new ExactMatcher(MatchExactPattern(XMLViewsStrings.ksZero)), item));
					combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksGreaterThanZero),
						new RangeIntMatcher(1, Int32.MaxValue), item));
					combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksGreaterThanOne),
						new RangeIntMatcher(2, Int32.MaxValue), item));
					combo.Items.Add(new RestrictComboItem(MakeLabel(XMLViewsStrings.ksRestrict_), item, m_cache.DefaultUserWs, combo));
					break;
				case "date":
					combo.Items.Add(new RestrictDateComboItem(MakeLabel(XMLViewsStrings.ksRestrict_), item, m_cache.DefaultUserWs, combo));
					break;
				case "YesNo":
					// For columns which have only the values of "yes" or "no" we offer the user these preset
					// filters to choose.
					combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksYes),
						new ExactMatcher(MatchExactPattern(XMLViewsStrings.ksYes)), item));
					combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksNo),
						new ExactMatcher(MatchExactPattern(XMLViewsStrings.ksNo)), item));
					break;
				case "stringList":
					string[] labels = m_bv.BrowseView.GetStringList(item.Spec);
					if (labels == null)
						break;
					foreach (string aLabel in labels)
					{
						combo.Items.Add(new FilterComboItem(MakeLabel(aLabel),
							new ExactMatcher(MatchExactPattern(aLabel)), item));
					}
					if (labels.Length > 2)
					{
						foreach (string aLabel in labels)
						{
							combo.Items.Add(new FilterComboItem(MakeLabel(string.Format(XMLViewsStrings.ksExcludeX, aLabel)),
								new InvertMatcher(new ExactMatcher(MatchExactPattern(aLabel))), item));
						}
					}
					break;
				default:
					// If it isn't any of those, include the bad spelling item, provided we have a dictionary
					// for the relevant language, and provided it is NOT a list (for which we will make a chooser).
					if (!String.IsNullOrEmpty(beSpec))
						break;
					Enchant.Dictionary dict = m_bv.BrowseView.EditingHelper.GetDictionary(ws);
					if (dict != null)
					{
						combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksSpellingErrors),
							new BadSpellingMatcher(ws, dict), item));
					}
					break;
			}
			combo.Items.Add(new FindComboItem(MakeLabel(XMLViewsStrings.ksFilterFor_), item, ws, combo, m_bv));

			if (!String.IsNullOrEmpty(beSpec))
			{
				MakeListChoiceFilterItem(item, combo, beSpec, m_bv.Mediator);
			}
			// Todo: lots more interesting items.
			// - search the list for existing names
			// - "any of" and "none of" launch a dialog with check boxes for all existing values.
			//		- maybe a control to check all items containing...
			// - "containing" launches dialog asking for string (may contain # at start or end).
			// - "matching pattern" launches dialog to obtain pattern.
			// - "custom" may launch dialog with "OR" options and "is, is not, is less than, is greater than, matches,..."
			// How can we get the current items? May not be available until later...
			// - May need to add 'ShowList' event to FwComboBox so we can populate the list when we show it.

			combo.SelectedIndex = 0;
			// Do this after selecting initial item, so we don't get a spurious notification.
			combo.SelectedIndexChanged += new EventHandler(Combo_SelectedIndexChanged);
			combo.AccessibleName = "FwComboBox";
			this.Controls.Add(combo);
		}
예제 #3
0
		// Make a FilterSortItem with a Finder that is an OwnMlPropFinder based on saSpec,
		// which is a stringalt element.
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Makes the string alt item.
		/// </summary>
		/// <param name="viewSpec">The view spec.</param>
		/// <param name="saSpec">The sa spec.</param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		protected FilterSortItem MakeStringAltItem(XmlNode viewSpec, XmlNode saSpec)
		{
			string className = GetStringAtt(saSpec, "class");
			string attrName = GetStringAtt(saSpec, "field");
			int ws = LangProject.GetWritingSystem(saSpec, m_cache, null, 0);
			if (className == null || attrName == null || ws == 0)
				return null; // Can't interpret an incomplete stringalt.

			string sWs = m_wsf.GetStrFromWs(ws);
			if (sWs == null || sWs == "")
				return null;		// must have a valid writing system.
			int flid = (int)m_mdc.GetFieldId(className, attrName, true);

			FilterSortItem result = new FilterSortItem();
			result.Spec = viewSpec;
			result.Finder = new OwnMlPropFinder(m_sda, flid, ws);
			SetupFsi(result);
			result.Sorter = new GenRecordSorter(new StringFinderCompare(result.Finder,
				new IcuComparer(sWs)));
			return result;
		}
예제 #4
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Make a FilterSortItem with a Finder that is an OwnIntPropFinder based on intSpec,
		/// which is an &lt;int&gt; element..
		/// </summary>
		/// <param name="viewSpec">The view spec.</param>
		/// <param name="intSpec">The int spec.</param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		protected FilterSortItem MakeIntItem(XmlNode viewSpec, XmlNode intSpec)
		{
			string className = GetStringAtt(intSpec, "class");
			string attrName = GetStringAtt(intSpec, "field");
			if (className == null || attrName == null)
				return null; // Can't interpret an incomplete int.
			int flid = (int)m_mdc.GetFieldId(className, attrName, true);

			FilterSortItem result = new FilterSortItem();
			result.Spec = viewSpec;
			result.Finder = new OwnIntPropFinder(m_sda, flid);

			MakeIntCombo(result);
			result.FilterChanged += new FilterChangeHandler(this.FilterChangedHandler);
			result.Sorter = new GenRecordSorter(new StringFinderCompare(result.Finder,
				new IntStringComparer()));
			return result;
		}
예제 #5
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Make a FilterSortItem with a finder that is a LayoutFinder with the specified layout name.
		/// </summary>
		/// <param name="colSpec">The col spec.</param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		protected FilterSortItem MakeLayoutItem(XmlNode colSpec)
		{
			FilterSortItem result = new FilterSortItem();
			result.Spec = colSpec; // SetupFsi uses this to get the writing system to use for the combo.
			result.Finder = LayoutFinder.CreateFinder(m_cache, colSpec, m_bv.BrowseView.Vc);
			SetupFsi(result);
			int ws = LangProject.GetWritingSystem(colSpec, m_cache, null, 0);
			if (ws == 0)
				ws = m_cache.DefaultVernWs;
			string sWs = m_wsf.GetStrFromWs(ws);
			result.Sorter = new GenRecordSorter(new StringFinderCompare(result.Finder,
				new IcuComparer(sWs)));
			return result;
		}
예제 #6
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Make a FilterSortItem with a Finder that is MultiIndirectMlPropFinder, where
		/// the first sequence flid is flidSeq1, and the rest are derived from childSpec,
		/// the contents of the "frag" n&lt;/frag&gt;
		/// </summary>
		/// <param name="viewSpec">The view spec.</param>
		/// <param name="flidSeq1">The flid seq1.</param>
		/// <param name="childSpec">The child spec.</param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		protected FilterSortItem MakeMultiIndirectItem(XmlNode viewSpec, int flidSeq1,
			XmlNode childSpec)
		{
			// currently we can only handle more levels of objseq.
			// enhance JohnT: could enhance MultiIndirectMlPropFinder so it takes information
			// about which props are sequences, then we could also handle <obj> elements.
			XmlNode subSpec = childSpec;
			List<int> flids = new List<int>();
			flids.Add(flidSeq1);
			while(subSpec != null && subSpec.Name == "objseq")
			{
				string className = GetStringAtt(subSpec, "class");
				string attrName = GetStringAtt(subSpec, "field");
				if (className == null || attrName == null)
					return null; // Can't interpret an incomplete objseq.
				int flidSeq = (int)m_mdc.GetFieldId(className, attrName, true);
				flids.Add(flidSeq);
				subSpec = ExtractFromFlow(m_bv.BrowseView.Vc.GetSubFrag(subSpec));
			}
			if (subSpec == null || subSpec.Name != "stringalt")
				return null; // leaf must be a stringalt.
			string classNameS = GetStringAtt(subSpec, "class");
			string attrNameS = GetStringAtt(subSpec, "field");
			int ws = LangProject.GetWritingSystem(subSpec, m_cache, null, 0);
			if (classNameS == null || attrNameS == null || ws == 0)
				return null; // Can't interpret an incomplete stringalt.

			int flid = (int)m_mdc.GetFieldId(classNameS, attrNameS, true);
			string sWs = m_wsf.GetStrFromWs(ws);
			if (sWs == null || sWs == "")
				return null;		// must have a valid writing system.

			FilterSortItem result = new FilterSortItem();
			result.Spec = viewSpec;
			result.Finder = new MultiIndirectMlPropFinder(m_sda, flids.ToArray(), flid, ws);
			SetupFsi(result);
			result.Sorter = new GenRecordSorter(new StringFinderCompare(result.Finder,
				new IcuComparer(sWs)));
			return result;

		}
예제 #7
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initializes a new instance of the <see cref="T:RestrictComboItem"/> class.
		/// </summary>
		/// <param name="tssName">Name of the TSS.</param>
		/// <param name="fsi">The fsi.</param>
		/// <param name="ws">The ws.</param>
		/// <param name="combo">The combo.</param>
		/// ------------------------------------------------------------------------------------
		public RestrictComboItem(ITsString tssName, FilterSortItem fsi, int ws, FwComboBox combo)
			: base(tssName, null, fsi)
		{
			m_combo = combo;
			m_ws = ws;
		}
예제 #8
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initializes a new instance of the <see cref="T:FindComboItem"/> class.
		/// </summary>
		/// <param name="tssName">Name of the TSS.</param>
		/// <param name="fsi">The fsi.</param>
		/// <param name="ws">The ws.</param>
		/// <param name="combo">The combo.</param>
		/// <param name="bv">The bv.</param>
		/// ------------------------------------------------------------------------------------
		public FindComboItem(ITsString tssName, FilterSortItem fsi, int ws, FwComboBox combo, BrowseViewer bv)
			: base(tssName, null, fsi)
		{
			m_ws = ws;
			m_combo = combo;
			m_bv = bv;
		}
예제 #9
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initializes a new instance of the <see cref="T:ListChoiceComboItem"/> class.
		/// </summary>
		/// <param name="tssName">Name of the TSS.</param>
		/// <param name="fsi">The fsi.</param>
		/// <param name="cache">The cache.</param>
		/// <param name="mediator">The mediator.</param>
		/// <param name="combo">The combo.</param>
		/// <param name="fAtomic">if set to <c>true</c> [f atomic].</param>
		/// <param name="filterType">Type of the filter.</param>
		/// ------------------------------------------------------------------------------------
		public ListChoiceComboItem(ITsString tssName, FilterSortItem fsi, FdoCache cache,
			XCore.Mediator mediator, FwComboBox combo, bool fAtomic, Type filterType)
			: base(tssName, null, fsi)
		{
			m_colSpec = fsi.Spec;

			if (filterType == null)
			{
				m_hvoList = BulkEditBar.GetNamedList(cache, fsi.Spec, "list");
				// This basically duplicates the loading of treeBarHandler properties. Currently, we don't have access
				// to that information in XMLViews, and even if we did, the information may not be loaded until
				// the user actually switches to that RecordList.
				XmlNode windowConfiguration = (XmlNode)mediator.PropertyTable.GetValue("WindowConfiguration");
				string owningClass;
				string property;
				BulkEditBar.GetListInfo(fsi.Spec, out owningClass, out property);
				XmlNode recordListNode = windowConfiguration.SelectSingleNode(
					String.Format("//recordList[@owner='{0}' and @property='{1}']", owningClass, property));
				XmlNode treeBarHandlerNode = recordListNode.ParentNode.SelectSingleNode("treeBarHandler");
				m_includeAbbr = XmlUtils.GetBooleanAttributeValue(treeBarHandlerNode, "includeAbbr");
				m_bestWS = XmlUtils.GetOptionalAttributeValue(treeBarHandlerNode, "ws", null);
			}
			else
			{
				MethodInfo mi = filterType.GetMethod("List", BindingFlags.Public | BindingFlags.Static);
				m_hvoList = (int)mi.Invoke(null, new object[] { cache });
			}
			m_cache = cache;
			m_mediator = mediator;
			m_combo = combo;
			m_fAtomic = fAtomic;
			m_filterType = filterType;
		}
예제 #10
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Determine whether this combo item could have produced the specified filter.
		/// If so, return the string that should be displayed as the value of the combo box
		/// when this filter is active. Otherwise return null.
		/// By default, if the filter is exactly the same, just return your label.
		/// </summary>
		/// <param name="recordFilter">The record filter.</param>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		public override ITsString SetFromFilter(RecordFilter recordFilter, FilterSortItem item)
		{
			CheckDisposed();

			ListChoiceFilter filter = recordFilter as ListChoiceFilter;
			if (filter == null)
				return null;
			if (!filter.CompatibleFilter(m_colSpec))
				return null;
			return MakeLabel(filter);
		}
예제 #11
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Determine whether this combo item could have produced the specified filter.
		/// If so, return the string that should be displayed as the value of the combo box
		/// when this filter is active. Otherwise return null.
		/// By default, if the filter is exactly the same, just return your label.
		/// </summary>
		/// <param name="recordFilter">The record filter.</param>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		public virtual ITsString SetFromFilter(RecordFilter recordFilter, FilterSortItem item)
		{
			CheckDisposed();

			FilterBarCellFilter filter = recordFilter as FilterBarCellFilter;
			if (filter == null)
				return null; // combo items that don't produce FilterBarCellFilters should override.
			if (!filter.Finder.SameFinder(item.Finder))
				return null;
			IMatcher matcher = filter.Matcher;
			ITsString result = SetFromMatcher(matcher);
			if (result != null)
				m_matcher = matcher;
			return result;
		}
예제 #12
0
		/// <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.
				//if (m_matcher != null)
				//{
				//	if (m_matcher is IDisposable)
				//		(m_matcher as IDisposable).Dispose();
				//}
			}

			// Dispose unmanaged resources here, whether disposing is true or false.
			m_matcher = null;
			m_fsi = null; // Disposed elesewhere.
			if (m_tssName != null)
			{
				Marshal.ReleaseComObject(m_tssName);
				m_tssName = null;
			}

			m_isDisposed = true;
		}
예제 #13
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initializes a new instance of the <see cref="T:FilterComboItem"/> class.
		/// </summary>
		/// <param name="tssName">Name of the TSS.</param>
		/// <param name="matcher">The matcher.</param>
		/// <param name="fsi">The fsi.</param>
		/// ------------------------------------------------------------------------------------
		public FilterComboItem(ITsString tssName, IMatcher matcher, FilterSortItem fsi)
		{
			m_tssName = tssName;
			m_matcher = matcher;
			m_fsi = fsi;
		}
예제 #14
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Makes the int combo.
		/// </summary>
		/// <param name="item">The item.</param>
		/// ------------------------------------------------------------------------------------
		protected void MakeIntCombo(FilterSortItem item)
		{
			// This is just similar enough to MakeCombo to be annoying.
			FwComboBox combo = new FwComboBox();
			combo.DropDownStyle = ComboBoxStyle.DropDownList;
			combo.WritingSystemFactory = m_wsf;
			item.Combo = combo;
			combo.Items.Add(new FilterComboItem(MakeLabel(XMLViewsStrings.ksShowAll), null, item));
			combo.Items.Add(new RestrictComboItem(MakeLabel(XMLViewsStrings.ksRestrict_),  item, m_cache.DefaultUserWs, combo));
			combo.SelectedIndex = 0;
			// Do this after selecting initial item, so we don't get a spurious notification.
			combo.SelectedIndexChanged +=new EventHandler(Combo_SelectedIndexChanged);
			combo.AccessibleName = "FwComboBox";
			this.Controls.Add(combo);
		}
예제 #15
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Make a combo menu item (and install it) for choosing from a list, based on the column
		/// spec at item.Spec.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <param name="combo">The combo.</param>
		/// <param name="beSpec">The be spec.</param>
		/// <param name="mediator">The mediator.</param>
		/// ------------------------------------------------------------------------------------
		private void MakeListChoiceFilterItem(FilterSortItem item, FwComboBox combo, string beSpec, XCore.Mediator mediator)
		{
			switch (beSpec)
			{
				case "complexListMultiple":
					combo.Items.Add(new ListChoiceComboItem(MakeLabel(XMLViewsStrings.ksChoose_), item, m_cache, mediator, combo, false, null));
					break;
				case "external":
					Type beType = DynamicLoader.TypeForLoaderNode(item.Spec);
					Type filterType = null;
					if (typeof(ListChoiceFilter).IsAssignableFrom(beType))
					{
						// typically it is a chooserFilter attribute, and gives the actual filter.
						filterType = beType;
					}
					else
					{
						// typically got a bulkEdit spec, and the editor class may know a compatible filter class.
						MethodInfo mi = beType.GetMethod("FilterType", BindingFlags.Static | BindingFlags.Public);
						if (mi != null)
							filterType = mi.Invoke(null, null) as Type;
					}

					if (filterType != null)
					{
						PropertyInfo pi = filterType.GetProperty("Atomic", BindingFlags.Public | BindingFlags.Static);
						bool fAtomic = false;
						if (pi != null)
							fAtomic = (bool)pi.GetValue(null, null);
						ListChoiceComboItem comboItem = new ListChoiceComboItem(MakeLabel(XMLViewsStrings.ksChoose_), item, m_cache, mediator, combo,
							fAtomic, filterType);
						combo.Items.Add(comboItem);

						PropertyInfo piLeaf = filterType.GetProperty("LeafFlid", BindingFlags.Public | BindingFlags.Static);
						if (piLeaf != null)
							comboItem.LeafFlid = (int)piLeaf.GetValue(null, null);
					}
					break;
				case "atomicFlatListItem": // Fall through
				case "morphTypeListItem":  // Fall through
				case "variantConditionListItem":
					combo.Items.Add(new ListChoiceComboItem(MakeLabel(XMLViewsStrings.ksChoose_), item, m_cache, mediator, combo, true, null));
					break;
				default:
					// if we didn't find it, try "chooserFilter", if we haven't already.
					string chooserFilter = XmlUtils.GetOptionalAttributeValue(item.Spec, "chooserFilter", "");
					if (!String.IsNullOrEmpty(chooserFilter) && chooserFilter != beSpec)
						MakeListChoiceFilterItem(item, combo, chooserFilter, mediator);
					return;
			}
		}