using System;
using System.Linq;
namespace ClosedXML.Excel
{
internal class XLCustomFilteredColumn : IXLCustomFilteredColumn
{
private readonly XLAutoFilter _autoFilter;
private readonly Int32 _column;
private readonly XLConnector _connector;
public XLCustomFilteredColumn(XLAutoFilter autoFilter, Int32 column, XLConnector connector)
{
_autoFilter = autoFilter;
_column = column;
_connector = connector;
}
#region IXLCustomFilteredColumn Members
public void EqualTo<T>(T value) where T: IComparable<T>
{
if (typeof(T) == typeof(String))
{
ApplyCustomFilter(value, XLFilterOperator.Equal,
v =>
v.ToString().Equals(value.ToString(), StringComparison.InvariantCultureIgnoreCase));
}
else
{
ApplyCustomFilter(value, XLFilterOperator.Equal,
v => v.CastTo<T>().CompareTo(value) == 0);
}
}
public void NotEqualTo<T>(T value) where T: IComparable<T>
{
if (typeof(T) == typeof(String))
{
ApplyCustomFilter(value, XLFilterOperator.NotEqual,
v =>
!v.ToString().Equals(value.ToString(), StringComparison.InvariantCultureIgnoreCase));
}
else
{
ApplyCustomFilter(value, XLFilterOperator.NotEqual,
v => v.CastTo<T>().CompareTo(value) != 0);
}
}
public void GreaterThan<T>(T value) where T: IComparable<T>
{
ApplyCustomFilter(value, XLFilterOperator.GreaterThan,
v => v.CastTo<T>().CompareTo(value) > 0);
}
public void LessThan<T>(T value) where T: IComparable<T>
{
ApplyCustomFilter(value, XLFilterOperator.LessThan, v => v.CastTo<T>().CompareTo(value) < 0);
}
public void EqualOrGreaterThan<T>(T value) where T: IComparable<T>
{
ApplyCustomFilter(value, XLFilterOperator.EqualOrGreaterThan,
v => v.CastTo<T>().CompareTo(value) >= 0);
}
public void EqualOrLessThan<T>(T value) where T: IComparable<T>
{
ApplyCustomFilter(value, XLFilterOperator.EqualOrLessThan,
v => v.CastTo<T>().CompareTo(value) <= 0);
}
public void BeginsWith(String value)
{
ApplyCustomFilter(value + "*", XLFilterOperator.Equal,
s => ((string)s).StartsWith(value, StringComparison.InvariantCultureIgnoreCase));
}
public void NotBeginsWith(String value)
{
ApplyCustomFilter(value + "*", XLFilterOperator.NotEqual,
s =>
!((string)s).StartsWith(value, StringComparison.InvariantCultureIgnoreCase));
}
public void EndsWith(String value)
{
ApplyCustomFilter("*" + value, XLFilterOperator.Equal,
s => ((string)s).EndsWith(value, StringComparison.InvariantCultureIgnoreCase));
}
public void NotEndsWith(String value)
{
ApplyCustomFilter("*" + value, XLFilterOperator.NotEqual,
s => !((string)s).EndsWith(value, StringComparison.InvariantCultureIgnoreCase));
}
public void Contains(String value)
{
ApplyCustomFilter("*" + value + "*", XLFilterOperator.Equal,
s => ((string)s).ToLower().Contains(value.ToLower()));
}
public void NotContains(String value)
{
ApplyCustomFilter("*" + value + "*", XLFilterOperator.Equal,
s => !((string)s).ToLower().Contains(value.ToLower()));
}
#endregion
private void ApplyCustomFilter<T>(T value, XLFilterOperator op, Func<Object, Boolean> condition)
where T: IComparable<T>
{
_autoFilter.Filters[_column].Add(new XLFilter
{
Value = value,
Operator = op,
Connector = _connector,
Condition = condition
});
using (var rows = _autoFilter.Range.Rows(2, _autoFilter.Range.RowCount()))
{
foreach (IXLRangeRow row in rows)
{
if (_connector == XLConnector.And)
{
if (!row.WorksheetRow().IsHidden)
{
if (condition(row.Cell(_column).GetValue<T>()))
row.WorksheetRow().Unhide().Dispose();
else
row.WorksheetRow().Hide().Dispose();
}
}
else if (condition(row.Cell(_column).GetValue<T>()))
row.WorksheetRow().Unhide().Dispose();
}
}
}
}
}