179 lines
4.7 KiB
C#
179 lines
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using XericUI.XTable.Mapping;
|
|
using XericUI.XTable.Rendering.Component;
|
|
|
|
namespace XericUI.XTable.Core
|
|
{
|
|
/// <summary>
|
|
/// 表格粘贴复制传输对象——将表格的尺寸、单元格文本、合并信息打包为可序列化结构,
|
|
/// 配合 MacroFile.SetClipboardObject / GetClipboardObject 实现表格内容的导入导出。
|
|
/// </summary>
|
|
[Serializable]
|
|
public class XTableClipboardData
|
|
{
|
|
[Serializable]
|
|
public struct CellEntry
|
|
{
|
|
public int Row;
|
|
public int Col;
|
|
public string Text;
|
|
public string StyleNamespace;
|
|
|
|
public CellEntry(int row, int col, string text, string styleNamespace = null)
|
|
{
|
|
Row = row;
|
|
Col = col;
|
|
Text = text;
|
|
StyleNamespace = styleNamespace;
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public struct MergeEntry
|
|
{
|
|
/// <summary>合并起始行(全局坐标)</summary>
|
|
public int StartRow;
|
|
|
|
/// <summary>合并起始列(全局坐标)</summary>
|
|
public int StartCol;
|
|
|
|
/// <summary>合并行数</summary>
|
|
public int RowSpan;
|
|
|
|
/// <summary>合并列数</summary>
|
|
public int ColSpan;
|
|
|
|
public MergeEntry(int startRow, int startCol, int rowSpan, int colSpan)
|
|
{
|
|
StartRow = startRow;
|
|
StartCol = startCol;
|
|
RowSpan = rowSpan;
|
|
ColSpan = colSpan;
|
|
}
|
|
}
|
|
|
|
/// <summary>行高数组</summary>
|
|
public float[] RowHeights;
|
|
|
|
/// <summary>列宽数组</summary>
|
|
public float[] ColWidths;
|
|
|
|
/// <summary>默认样式命名空间</summary>
|
|
public string DefaultStyleNamespace;
|
|
|
|
/// <summary>单元格数据列表(仅序列化有文本内容的单元格)</summary>
|
|
public List<CellEntry> Cells;
|
|
|
|
/// <summary>合并单元格描述列表</summary>
|
|
public List<MergeEntry> Merges;
|
|
|
|
public XTableClipboardData()
|
|
{
|
|
Cells = new List<CellEntry>();
|
|
Merges = new List<MergeEntry>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 从表格收集所有数据——尺寸、单元格文本、合并信息。
|
|
/// 调用方可将返回的 DTO 传给 MacroFile.SetClipboardObject 写入剪贴板。
|
|
/// </summary>
|
|
public static XTableClipboardData FromTable(XericUIActionTable table)
|
|
{
|
|
var data = new XTableClipboardData
|
|
{
|
|
RowHeights = table.RowHeights,
|
|
ColWidths = table.ColWidths,
|
|
DefaultStyleNamespace = table.DefaultStyleNamespace,
|
|
};
|
|
|
|
int rows = table.RowHeights?.Length ?? 0;
|
|
int cols = table.ColWidths?.Length ?? 0;
|
|
var tableData = table.TableData;
|
|
for (int r = 0; r < rows; r++)
|
|
{
|
|
for (int c = 0; c < cols; c++)
|
|
{
|
|
var cell = tableData.GetCell(r, c);
|
|
if (cell == null) continue;
|
|
|
|
bool hasContent = !string.IsNullOrEmpty(cell.Text)
|
|
|| !string.IsNullOrEmpty(cell.StyleNamespace);
|
|
if (!hasContent) continue;
|
|
|
|
data.Cells.Add(new CellEntry(r, c, cell.Text, cell.StyleNamespace));
|
|
}
|
|
}
|
|
|
|
// 收集合并信息(全局坐标)
|
|
if (tableData != null)
|
|
{
|
|
foreach (var kv in tableData.BlockMap)
|
|
{
|
|
var block = kv.Value;
|
|
if (block.MergeDescriptors == null || block.MergeDescriptors.Count == 0) continue;
|
|
|
|
XTableBlockMapping.ZIndexToBlockCoord(kv.Key, out int blockRow, out int blockCol);
|
|
|
|
foreach (var desc in block.MergeDescriptors)
|
|
{
|
|
if (desc.IsCrossBlock) continue;
|
|
|
|
int globalStartRow = blockRow * tableData.BlockSizeY + desc.LocalStartRow;
|
|
int globalStartCol = blockCol * tableData.BlockSizeX + desc.LocalStartCol;
|
|
|
|
data.Merges.Add(new MergeEntry(globalStartRow, globalStartCol,
|
|
desc.MergeRowSpan, desc.MergeColSpan));
|
|
}
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将 DTO 中的单元格文本和合并信息写回表格数据层。
|
|
/// 尺寸与命名空间的设置由表格组件在 ApplyClipboardData 中处理。
|
|
/// </summary>
|
|
public void PopulateToTable(XericUIActionTable table)
|
|
{
|
|
var td = table.TableData;
|
|
if (td == null) return;
|
|
|
|
int rows = table.RowHeights?.Length ?? 0;
|
|
int cols = table.ColWidths?.Length ?? 0;
|
|
|
|
// 单元格文本
|
|
if (Cells != null)
|
|
{
|
|
foreach (var entry in Cells)
|
|
{
|
|
if (entry.Row < 0 || entry.Row >= rows || entry.Col < 0 || entry.Col >= cols)
|
|
continue;
|
|
|
|
var cell = td.GetOrCreateCell(entry.Row, entry.Col);
|
|
cell.Text = entry.Text;
|
|
cell.StyleNamespace = entry.StyleNamespace;
|
|
}
|
|
}
|
|
|
|
// 合并信息——先清除再重建,防止残留描述干扰
|
|
if (Merges != null)
|
|
{
|
|
td.ClearAllMerges();
|
|
foreach (var merge in Merges)
|
|
{
|
|
if (merge.RowSpan > 1 || merge.ColSpan > 1)
|
|
{
|
|
int endRow = merge.StartRow + merge.RowSpan - 1;
|
|
int endCol = merge.StartCol + merge.ColSpan - 1;
|
|
if (endRow < rows && endCol < cols)
|
|
td.MergeCells(merge.StartRow, merge.StartCol, merge.RowSpan, merge.ColSpan);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|