CPF/CPF.ReoGrid/Data/AutoColumnFilter.cs
2024-06-24 10:15:59 +08:00

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;
}
}
}
}