536 lines
14 KiB
C#
536 lines
14 KiB
C#
![]() |
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Diagnostics;
|
|||
|
using CPF.Controls;
|
|||
|
using CPF.Drawing;
|
|||
|
using CPF.ReoGrid.CellTypes;
|
|||
|
using CPF.ReoGrid.Common;
|
|||
|
using CPF.ReoGrid.Events;
|
|||
|
using CPF.ReoGrid.Graphics;
|
|||
|
using CPF.ReoGrid.Interaction;
|
|||
|
using CPF.ReoGrid.Rendering;
|
|||
|
|
|||
|
namespace CPF.ReoGrid.Data
|
|||
|
{
|
|||
|
public class AutoColumnFilter
|
|||
|
{
|
|||
|
public Worksheet Worksheet { get; private set; }
|
|||
|
|
|||
|
public RangePosition ApplyRange { get; private set; }
|
|||
|
|
|||
|
internal AutoColumnFilter(Worksheet worksheet, RangePosition range)
|
|||
|
{
|
|||
|
this.Worksheet = worksheet;
|
|||
|
this.ApplyRange = range;
|
|||
|
}
|
|||
|
|
|||
|
public AutoColumnFilter.FilterColumnCollection Columns
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
bool flag = this.columnCollection == null;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
this.columnCollection = new AutoColumnFilter.FilterColumnCollection(this);
|
|||
|
}
|
|||
|
return this.columnCollection;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Apply()
|
|||
|
{
|
|||
|
bool flag = this.Worksheet == null;
|
|||
|
if (!flag)
|
|||
|
{
|
|||
|
this.Worksheet.DoFilter(this.ApplyRange, delegate(int r)
|
|||
|
{
|
|||
|
int i = this.ApplyRange.Col;
|
|||
|
while (i <= this.ApplyRange.EndCol)
|
|||
|
{
|
|||
|
ColumnHeader columnHeader = this.Worksheet.RetrieveColumnHeader(i);
|
|||
|
bool flag2 = columnHeader == null;
|
|||
|
if (flag2)
|
|||
|
{
|
|||
|
i++;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
AutoColumnFilter.AutoColumnFilterBody autoColumnFilterBody = columnHeader.Body as AutoColumnFilter.AutoColumnFilterBody;
|
|||
|
bool flag3 = autoColumnFilterBody == null || autoColumnFilterBody.IsSelectAll;
|
|||
|
if (flag3)
|
|||
|
{
|
|||
|
i++;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Cell cell = this.Worksheet.GetCell(r, i);
|
|||
|
bool flag4 = cell == null;
|
|||
|
if (flag4)
|
|||
|
{
|
|||
|
i++;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
string text = cell.DisplayText;
|
|||
|
bool flag5 = string.IsNullOrEmpty(text);
|
|||
|
if (flag5)
|
|||
|
{
|
|||
|
text = LanguageResource.Filter_Blanks;
|
|||
|
}
|
|||
|
bool flag6 = !autoColumnFilterBody.SelectedTextItems.Contains(text);
|
|||
|
if (flag6)
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
i += (int)cell.Colspan;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|||
|
public event EventHandler FilterButtonPressed;
|
|||
|
|
|||
|
internal bool RaiseFilterButtonPress(AutoColumnFilter.AutoColumnFilterBody headerBody, Point point)
|
|||
|
{
|
|||
|
bool flag = headerBody.ColumnHeader == null;
|
|||
|
bool result;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
result = false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
bool flag2 = this.FilterButtonPressed != null;
|
|||
|
if (flag2)
|
|||
|
{
|
|||
|
FilterButtonPressedEventArgs filterButtonPressedEventArgs = new FilterButtonPressedEventArgs(headerBody.ColumnHeader);
|
|||
|
this.FilterButtonPressed(this, filterButtonPressedEventArgs);
|
|||
|
bool isCancelled = filterButtonPressedEventArgs.IsCancelled;
|
|||
|
if (isCancelled)
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
bool flag3 = this.columnFilterUIFlag == AutoColumnFilterUI.DropdownButtonAndPanel;
|
|||
|
if (flag3)
|
|||
|
{
|
|||
|
ContextMenu contextMenu = new ContextMenu();
|
|||
|
contextMenu.Items.Add(new MenuItem
|
|||
|
{
|
|||
|
Header = "Item"
|
|||
|
});
|
|||
|
contextMenu.IsOpen = true;
|
|||
|
result = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
result = false;
|
|||
|
}
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private void CreateFilterHeaders(int start, int end)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
this.Worksheet.ControlAdapter.ChangeCursor(CursorStyle.Busy);
|
|||
|
for (int i = start; i <= end; i++)
|
|||
|
{
|
|||
|
ColumnHeader columnHeader = this.Worksheet.RetrieveColumnHeader(i);
|
|||
|
columnHeader.Body = new AutoColumnFilter.AutoColumnFilterBody(this, columnHeader);
|
|||
|
}
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
this.Worksheet.ControlAdapter.ChangeCursor(CursorStyle.PlatformDefault);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void RemoveFilterHeader(int start, int end)
|
|||
|
{
|
|||
|
bool flag = this.Worksheet.cols.Count <= 0;
|
|||
|
if (!flag)
|
|||
|
{
|
|||
|
for (int i = start; i <= end; i++)
|
|||
|
{
|
|||
|
ColumnHeader columnHeader = this.Worksheet.RetrieveColumnHeader(i);
|
|||
|
AutoColumnFilter.AutoColumnFilterBody autoColumnFilterBody = columnHeader.Body as AutoColumnFilter.AutoColumnFilterBody;
|
|||
|
bool flag2 = autoColumnFilterBody != null;
|
|||
|
if (flag2)
|
|||
|
{
|
|||
|
columnHeader.Body = null;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Attach(Worksheet worksheet, AutoColumnFilterUI uiFlag = AutoColumnFilterUI.DropdownButtonAndPanel)
|
|||
|
{
|
|||
|
bool flag = worksheet == null;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
throw new ArgumentNullException("cannot attach to null worksheet", "worksheet");
|
|||
|
}
|
|||
|
this.Worksheet = worksheet;
|
|||
|
this.columnFilterUIFlag = uiFlag;
|
|||
|
this.CreateFilterHeaders(this.ApplyRange.Col, this.ApplyRange.EndCol);
|
|||
|
worksheet.ColumnsInserted += this.worksheet_ColumnsInserted;
|
|||
|
}
|
|||
|
|
|||
|
public void Detach()
|
|||
|
{
|
|||
|
bool flag = this.Worksheet != null;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
this.Worksheet.ColumnsInserted -= this.worksheet_ColumnsInserted;
|
|||
|
this.Worksheet.ShowRows(this.ApplyRange.Row, this.ApplyRange.Rows);
|
|||
|
this.RemoveFilterHeader(this.ApplyRange.Col, this.ApplyRange.EndCol);
|
|||
|
this.Worksheet.RequestInvalidate();
|
|||
|
this.Worksheet = null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void worksheet_ColumnsInserted(object sender, ColumnsInsertedEventArgs e)
|
|||
|
{
|
|||
|
bool flag = e.Index < this.ApplyRange.Col;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
this.ApplyRange.Offset(0, e.Count);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
bool flag2 = e.Index > this.ApplyRange.Col && e.Index <= this.ApplyRange.EndCol;
|
|||
|
if (flag2)
|
|||
|
{
|
|||
|
this.CreateFilterHeaders(e.Index, e.Index + e.Count - 1);
|
|||
|
this.ApplyRange.SetCols(this.ApplyRange.Cols + e.Count);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private AutoColumnFilterUI columnFilterUIFlag;
|
|||
|
|
|||
|
private AutoColumnFilter.FilterColumnCollection columnCollection;
|
|||
|
|
|||
|
public class FilterColumnCollection : IEnumerable<AutoColumnFilter.AutoColumnFilterBody>, IEnumerable
|
|||
|
{
|
|||
|
internal FilterColumnCollection(AutoColumnFilter filter)
|
|||
|
{
|
|||
|
this.filter = filter;
|
|||
|
}
|
|||
|
|
|||
|
public AutoColumnFilter.AutoColumnFilterBody this[int index]
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
bool flag = index < this.filter.ApplyRange.Col || index > this.filter.ApplyRange.EndCol || index < 0 || index >= this.filter.Worksheet.ColumnCount;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
throw new ArgumentOutOfRangeException("index", "Number of column to find the filter out of the valid range");
|
|||
|
}
|
|||
|
return this.filter.Worksheet.RetrieveColumnHeader(index).Body as AutoColumnFilter.AutoColumnFilterBody;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public AutoColumnFilter.AutoColumnFilterBody this[string columnCode]
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
int numberOfChar = RGUtility.GetNumberOfChar(columnCode);
|
|||
|
return this[numberOfChar];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private IEnumerator<AutoColumnFilter.AutoColumnFilterBody> GetEnum()
|
|||
|
{
|
|||
|
int num;
|
|||
|
for (int i = this.filter.ApplyRange.Col; i <= this.filter.ApplyRange.EndCol; i = num + 1)
|
|||
|
{
|
|||
|
ColumnHeader header = this.filter.Worksheet.RetrieveColumnHeader(i);
|
|||
|
bool flag = header == null;
|
|||
|
if (!flag)
|
|||
|
{
|
|||
|
AutoColumnFilter.AutoColumnFilterBody body = header.Body as AutoColumnFilter.AutoColumnFilterBody;
|
|||
|
bool flag2 = body == null;
|
|||
|
if (!flag2)
|
|||
|
{
|
|||
|
yield return body;
|
|||
|
header = null;
|
|||
|
body = null;
|
|||
|
}
|
|||
|
}
|
|||
|
num = i;
|
|||
|
}
|
|||
|
yield break;
|
|||
|
}
|
|||
|
|
|||
|
public IEnumerator<AutoColumnFilter.AutoColumnFilterBody> GetEnumerator()
|
|||
|
{
|
|||
|
return this.GetEnum();
|
|||
|
}
|
|||
|
|
|||
|
IEnumerator IEnumerable.GetEnumerator()
|
|||
|
{
|
|||
|
return this.GetEnum();
|
|||
|
}
|
|||
|
|
|||
|
private AutoColumnFilter filter;
|
|||
|
}
|
|||
|
|
|||
|
public class AutoColumnFilterBody : IHeaderBody
|
|||
|
{
|
|||
|
public ColumnHeader ColumnHeader { get; private set; }
|
|||
|
|
|||
|
internal AutoColumnFilterBody(AutoColumnFilter autoFilter, ColumnHeader header)
|
|||
|
{
|
|||
|
this.autoFilter = autoFilter;
|
|||
|
this.ColumnHeader = header;
|
|||
|
this.DataDirty = true;
|
|||
|
this.IsSelectAll = true;
|
|||
|
}
|
|||
|
|
|||
|
internal bool IsDropdown { get; set; }
|
|||
|
|
|||
|
public void OnPaint(CellDrawingContext dc, Size headerSize)
|
|||
|
{
|
|||
|
ControlAppearanceStyle controlStyle = dc.Worksheet.controlAdapter.ControlStyle;
|
|||
|
bool flag = this.autoFilter.columnFilterUIFlag == AutoColumnFilterUI.DropdownButton || this.autoFilter.columnFilterUIFlag == AutoColumnFilterUI.DropdownButtonAndPanel;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
Rect columnFilterButtonRect = this.GetColumnFilterButtonRect(headerSize);
|
|||
|
Color colHeadStartColor = controlStyle.GetColHeadStartColor(false, this.IsDropdown, false, false);
|
|||
|
Color colHeadEndColor = controlStyle.GetColHeadEndColor(false, this.IsDropdown, false, false);
|
|||
|
IGraphics graphics = dc.Graphics;
|
|||
|
graphics.FillRectangleLinear(colHeadStartColor, colHeadEndColor, 90f, columnFilterButtonRect);
|
|||
|
graphics.DrawRectangle(columnFilterButtonRect, StaticResources.SystemColor_ControlDark);
|
|||
|
DrawingContext platformGraphics = dc.Graphics.PlatformGraphics;
|
|||
|
float size = Math.Min(7f * dc.Worksheet.renderScaleFactor, 7f);
|
|||
|
float num = columnFilterButtonRect.X + columnFilterButtonRect.Width / 2f;
|
|||
|
float num2 = columnFilterButtonRect.Y + columnFilterButtonRect.Height / 2f;
|
|||
|
GraphicsToolkit.FillTriangle(platformGraphics, size, new Point(ref num, ref num2), GraphicsToolkit.TriangleDirection.Down);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public bool OnMouseDown(Size headerSize, WorksheetMouseEventArgs e)
|
|||
|
{
|
|||
|
bool flag = this.autoFilter == null || this.autoFilter.columnFilterUIFlag == AutoColumnFilterUI.NoGUI || this.ColumnHeader == null || this.ColumnHeader.Worksheet == null;
|
|||
|
bool result;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
result = false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
bool flag2 = this.IsMouseInButton(headerSize, e.RelativePosition);
|
|||
|
result = (flag2 && this.autoFilter.RaiseFilterButtonPress(this, e.AbsolutePosition));
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public bool OnMouseMove(Size headerSize, WorksheetMouseEventArgs e)
|
|||
|
{
|
|||
|
bool flag = this.autoFilter == null || this.autoFilter.columnFilterUIFlag == AutoColumnFilterUI.NoGUI || this.ColumnHeader == null || this.ColumnHeader.Worksheet == null;
|
|||
|
bool result;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
result = false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
bool flag2 = this.IsMouseInButton(headerSize, e.RelativePosition);
|
|||
|
if (flag2)
|
|||
|
{
|
|||
|
e.CursorStyle = CursorStyle.Hand;
|
|||
|
result = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
result = false;
|
|||
|
}
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private bool IsMouseInButton(Size headerSize, Point position)
|
|||
|
{
|
|||
|
return this.GetColumnFilterButtonRect(headerSize).Contains(position);
|
|||
|
}
|
|||
|
|
|||
|
internal Rect GetColumnFilterButtonRect(Size size)
|
|||
|
{
|
|||
|
Worksheet worksheet = this.ColumnHeader.Worksheet;
|
|||
|
float renderScaleFactor = worksheet.renderScaleFactor;
|
|||
|
float num = 0f;
|
|||
|
float num2 = 0f;
|
|||
|
float num3 = Math.Min(Math.Min(size.Width - 2f, 18f * renderScaleFactor), 20f);
|
|||
|
float num4 = Math.Min(Math.Min(size.Height - 2f, 18f * renderScaleFactor), 20f);
|
|||
|
Rect result = new Rect(ref num, ref num2, ref num3, ref num4);
|
|||
|
result.X = size.Width - result.Width - 2f;
|
|||
|
result.Y = (size.Height - result.Height) / 2f - 1f;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public bool IsSelectAll { get; set; }
|
|||
|
|
|||
|
public AutoColumnFilter.AutoColumnFilterBody.TextFilterCollection SelectedTextItems
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
bool flag = this.textItemsCollection == null;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
this.textItemsCollection = new AutoColumnFilter.AutoColumnFilterBody.TextFilterCollection(this);
|
|||
|
}
|
|||
|
return this.textItemsCollection;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public List<string> GetDistinctItems()
|
|||
|
{
|
|||
|
bool flag = this.ColumnHeader == null || this.ColumnHeader.Worksheet == null;
|
|||
|
List<string> result;
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
result = null;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
List<string> items = new List<string>();
|
|||
|
int maxContentRow = this.ColumnHeader.Worksheet.MaxContentRow;
|
|||
|
this.ColumnHeader.Worksheet.IterateCells(this.autoFilter.ApplyRange.Row, this.ColumnHeader.Index, this.autoFilter.ApplyRange.Rows, 1, true, delegate(int r, int c, Cell cell)
|
|||
|
{
|
|||
|
string text = cell.DisplayText;
|
|||
|
bool flag2 = string.IsNullOrEmpty(text);
|
|||
|
if (flag2)
|
|||
|
{
|
|||
|
text = LanguageResource.Filter_Blanks;
|
|||
|
}
|
|||
|
bool flag3 = !items.Contains(text);
|
|||
|
if (flag3)
|
|||
|
{
|
|||
|
items.Add(text);
|
|||
|
}
|
|||
|
return true;
|
|||
|
});
|
|||
|
items.Sort();
|
|||
|
result = items;
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
internal bool DataDirty { get; set; }
|
|||
|
|
|||
|
public void OnDataChange(int startRow, int endRow)
|
|||
|
{
|
|||
|
this.DataDirty = true;
|
|||
|
}
|
|||
|
|
|||
|
internal AutoColumnFilter autoFilter;
|
|||
|
|
|||
|
internal List<string> selectedTextItems = new List<string>();
|
|||
|
|
|||
|
private AutoColumnFilter.AutoColumnFilterBody.TextFilterCollection textItemsCollection;
|
|||
|
|
|||
|
public class TextFilterCollection : ICollection<string>, IEnumerable<string>, IEnumerable
|
|||
|
{
|
|||
|
internal TextFilterCollection(AutoColumnFilter.AutoColumnFilterBody column)
|
|||
|
{
|
|||
|
this.columnFilter = column;
|
|||
|
}
|
|||
|
|
|||
|
public bool this[string item]
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return this.columnFilter.selectedTextItems.Contains(item);
|
|||
|
}
|
|||
|
set
|
|||
|
{
|
|||
|
if (value)
|
|||
|
{
|
|||
|
this.Add(item);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
this.Remove(item);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public IEnumerator<string> GetEnumerator()
|
|||
|
{
|
|||
|
return this.columnFilter.selectedTextItems.GetEnumerator();
|
|||
|
}
|
|||
|
|
|||
|
IEnumerator IEnumerable.GetEnumerator()
|
|||
|
{
|
|||
|
return this.columnFilter.selectedTextItems.GetEnumerator();
|
|||
|
}
|
|||
|
|
|||
|
public void Add(string item)
|
|||
|
{
|
|||
|
bool flag = !this.columnFilter.selectedTextItems.Contains(item);
|
|||
|
if (flag)
|
|||
|
{
|
|||
|
this.columnFilter.selectedTextItems.Add(item);
|
|||
|
this.columnFilter.IsSelectAll = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Clear()
|
|||
|
{
|
|||
|
this.columnFilter.selectedTextItems.Clear();
|
|||
|
this.columnFilter.IsSelectAll = false;
|
|||
|
}
|
|||
|
|
|||
|
public bool Contains(string item)
|
|||
|
{
|
|||
|
return this.columnFilter.selectedTextItems.Contains(item);
|
|||
|
}
|
|||
|
|
|||
|
public void CopyTo(string[] array, int arrayIndex)
|
|||
|
{
|
|||
|
this.columnFilter.selectedTextItems.CopyTo(array, arrayIndex);
|
|||
|
}
|
|||
|
|
|||
|
public int Count
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return this.columnFilter.selectedTextItems.Count;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public bool IsReadOnly
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public bool Remove(string item)
|
|||
|
{
|
|||
|
this.columnFilter.IsSelectAll = false;
|
|||
|
return this.columnFilter.selectedTextItems.Remove(item);
|
|||
|
}
|
|||
|
|
|||
|
public void AddRange(IEnumerable<string> items)
|
|||
|
{
|
|||
|
this.columnFilter.selectedTextItems.AddRange(items);
|
|||
|
this.columnFilter.IsSelectAll = false;
|
|||
|
}
|
|||
|
|
|||
|
private AutoColumnFilter.AutoColumnFilterBody columnFilter;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|