unit TableDesignWin;

interface

uses
  Windows, Messages, SysUtils, Variants, Types, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, ExtCtrls, ColorContainer, ASAttributes, ASTAble,
  TextEditor, ASColors, ScrollBoxEx;

type
  TTableDesignFrm = class(TForm)
    pnlBottom: TPanel;
    btnOk: TButton;
    btnCancel: TButton;
    pnLeft: TPanel;
    gbOuterBorder: TGroupBox;
    lblBorderColor: TLabel;
    ccBorderColor: TColorContainer;
    eBorderWidth: TEdit;
    lblBorderWidth: TLabel;
    gbGrid: TGroupBox;
    lblGridColor: TLabel;
    lblGridWidth: TLabel;
    ccGridColorX: TColorContainer;
    eGridWidthX: TEdit;
    gbCellSizes: TGroupBox;
    Label15: TLabel;
    eCellWidth: TEdit;
    Label14: TLabel;
    eCellHeight: TEdit;
    GroupBox1: TGroupBox;
    teColWidths: TTextEditor;
    btnApply: TButton;
    gbCellStyles: TGroupBox;
    sbCellStyles: TScrollBoxEx;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    btnBasicStyle: TButton;
    btnEvenCols: TButton;
    btnEvenRows: TButton;
    btnFirstCol: TButton;
    btnFirstRow: TButton;
    btnLastCol: TButton;
    btnLastRow: TButton;
    btnOddCols: TButton;
    btnOddRows: TButton;
    mBaseStyle: TMemo;
    mEvenColsStyle: TMemo;
    mEvenRowsStyle: TMemo;
    mFirstColStyle: TMemo;
    mFirstRowStyle: TMemo;
    mLastColStyle: TMemo;
    mLastRowStyle: TMemo;
    mOddColsStyle: TMemo;
    mOddRowsStyle: TMemo;
    ccGridColorY: TColorContainer;
    eGridWidthY: TEdit;
    lblInternalGridX: TLabel;
    lblInternalGridY: TLabel;
    cbUseOuterBorder: TCheckBox;
    cbUseInternalGrid: TCheckBox;
    procedure FormShow(Sender: TObject);
    procedure btnApplyClick(Sender: TObject);
    procedure btnBasicStyleClick(Sender: TObject);
    procedure btnFirstRowClick(Sender: TObject);
    procedure btnFirstColClick(Sender: TObject);
    procedure btnLastRowClick(Sender: TObject);
    procedure btnLastColClick(Sender: TObject);
    procedure btnEvenRowsClick(Sender: TObject);
    procedure btnEvenColsClick(Sender: TObject);
    procedure btnOddRowsClick(Sender: TObject);
    procedure btnOddColsClick(Sender: TObject);
    procedure btnOkClick(Sender: TObject);
    procedure cbUseOuterBorderClick(Sender: TObject);
    procedure cbUseInternalGridClick(Sender: TObject);
  private
    { Private declarations }
    FTable: TASTable;
    FTableStyle,
    FFirstRowStyle,
    FLastRowStyle,
    FFirstColStyle,
    FLastColStyle,
    FEvenRowStyle,
    FOddRowStyle,
    FEvenColStyle,
    FOddColStyle: TASAttributes;
    FOnApply: TNotifyEvent;
    procedure Apply;
  public
    { Public declarations }
    property Table: TASTable read FTable write FTable;
    property OnApply: TNotifyEvent read FOnApply write FOnApply;
  end;

implementation

uses TableStyleDialogWin;

{$R *.dfm}

procedure TTableDesignFrm.btnApplyClick(Sender: TObject);
begin
  Apply;
end;

function StyleDialog(AOwner: TComponent; ASender: TObject;
  var AAttributes: TASAttributes): boolean;
var
  StyleName: string;
begin
  if (ASender is TButton) and (TObject(TButton(ASender).Tag) is TLabel) then
  begin
    StyleName := TLabel(TButton(ASender).Tag).Caption;
    if Copy(StyleName, Length(StyleName)) = ':' then
      SetLength(StyleName, Length(StyleName) - 1);
    StyleName := StringReplace(StyleName, '&', '', [rfReplaceAll]);
  end;

  result := TableStyleDialogWIn.StyleDialog(AOwner, StyleName, AAttributes);
end;

procedure TTableDesignFrm.btnBasicStyleClick(Sender: TObject);
begin
  if StyleDialog(Self, Sender, FTableStyle) then
    mBaseStyle.Text := FTableStyle;
end;

procedure TTableDesignFrm.btnEvenColsClick(Sender: TObject);
begin
  if StyleDialog(Self, Sender, FEvenColStyle) then
    mEvenColsStyle.Text := FEvenColStyle;
end;

procedure TTableDesignFrm.btnEvenRowsClick(Sender: TObject);
begin
  if StyleDialog(Self, Sender, FEvenRowStyle) then
    mEvenRowsStyle.Text := FEvenRowStyle;
end;

procedure TTableDesignFrm.btnFirstColClick(Sender: TObject);
begin
  if StyleDialog(Self, Sender, FFirstColStyle) then
    mFirstColStyle.Text := FFirstColStyle;
end;

procedure TTableDesignFrm.btnFirstRowClick(Sender: TObject);
begin
  if StyleDialog(Self, Sender, FFirstRowStyle) then
    mFirstRowStyle.Text := FFirstRowStyle;
end;

procedure TTableDesignFrm.btnLastColClick(Sender: TObject);
begin
  if StyleDialog(Self, Sender, FLastColStyle) then
    mLastColStyle.Text := FLastColStyle;
end;

procedure TTableDesignFrm.btnLastRowClick(Sender: TObject);
begin
  if StyleDialog(Self, Sender, FLastRowStyle) then
    mLastRowStyle.Text := FLastRowStyle;
end;

procedure TTableDesignFrm.btnOddColsClick(Sender: TObject);
begin
  if StyleDialog(Self, Sender, FOddColStyle) then
    mOddColsStyle.Text := FOddColStyle;
end;

procedure TTableDesignFrm.btnOddRowsClick(Sender: TObject);
begin
  if StyleDialog(Self, Sender, FOddRowStyle) then
    mOddRowsStyle.Text := FOddRowStyle;
end;

procedure TTableDesignFrm.btnOkClick(Sender: TObject);
begin
  Apply;
end;

procedure TTableDesignFrm.cbUseInternalGridClick(Sender: TObject);
begin
  lblInternalGridX.Enabled := cbUseInternalGrid.Checked;
  lblInternalGridY.Enabled := cbUseInternalGrid.Checked;
  lblGridColor.Enabled := cbUseInternalGrid.Checked;
  ccGridColorX.Enabled := cbUseInternalGrid.Checked;
  ccGridColorY.Enabled := cbUseInternalGrid.Checked;
  lblGridWidth.Enabled := cbUseInternalGrid.Checked;
  eGridWidthX.Enabled := cbUseInternalGrid.Checked;
  eGridWidthY.Enabled := cbUseInternalGrid.Checked;
end;

procedure TTableDesignFrm.cbUseOuterBorderClick(Sender: TObject);
begin
  lblBorderColor.Enabled := cbUseOuterBorder.Checked;
  ccBorderColor.Enabled := cbUseOuterBorder.Checked;
  lblBorderWidth.Enabled := cbUseOuterBorder.Checked;
  eBorderWidth.Enabled := cbUseOuterBorder.Checked;
end;

procedure TTableDesignFrm.FormShow(Sender: TObject);
var
  val: string;
  clr: TColor;
  int: integer;
  i: Integer;
  style: TASAttributes;
begin

  if not Assigned(FTable) then
    Exit;

  if FTable.Style.TryGetValue('table-border-color', val) and TryStrToColor(val, clr) then
  begin
    cbUseOuterBorder.Checked := True;
    ccBorderColor.Color := clr;
  end
  else
    cbUseOuterBorder.Checked := False;

  if FTable.Style.TryGetValue('table-border-width', val) and TryStrToInt(val, int) then
    eBorderWidth.Text := val
  else
    eBorderWidth.Text := '3';

  cbUseInternalGrid.Checked := False;

  if FTable.Style.TryGetValue('horizontal-grid-color', val) and TryStrToColor(val, clr) then
  begin
    cbUseInternalGrid.Checked := True;
    ccGridColorX.Color := clr;
  end;

  if FTable.Style.TryGetValue('horizontal-grid-width', val) and TryStrToInt(val, int) then
    eGridWidthX.Text := val;

  if FTable.Style.TryGetValue('vertical-grid-color', val) and TryStrToColor(val, clr) then
  begin
    cbUseInternalGrid.Checked := True;
    ccGridColorY.Color := clr;
  end;

  if FTable.Style.TryGetValue('vertical-grid-width', val) and TryStrToInt(val, int) then
    eGridWidthY.Text := val;

  if FTable.Style.TryGetValue('cell-width', val) and TryStrToInt(val, int) then
    eCellWidth.Text := val;

  if FTable.Style.TryGetValue('cell-height', val) and TryStrToInt(val, int) then
    eCellHeight.Text := val;

  if FTable.Height > 0 then
  begin
    teColWidths.BeginVisualUpdate;
    teColWidths.Clear;
    for i := 0 to FTable.Width - 1 do
      if FTable.CellStyles[Point(i, 0)].TryGetValue('column-width', val) and TryStrToInt(val, int) then
        teColWidths.AddLine(val);
    teColWidths.EndVisualUpdate(true);
  end;

  style := FTable.Style.Clone;
  style.Remove('table-border-width');
  style.Remove('table-border-color');
  style.Remove('table-grid-width');
  style.Remove('table-grid-color');
  style.Remove('cell-width');
  style.Remove('cell-height');
  mBaseStyle.Text := style;

  mFirstRowStyle.Text := FTable.FirstRow;
  mLastRowStyle.Text := FTable.LastRow;
  mFirstColStyle.Text := FTable.FirstCol;
  mLastColStyle.Text := FTable.LastCol;
  mEvenRowsStyle.Text := FTable.EvenRows;
  mOddRowsStyle.Text := FTable.OddRows;
  mEvenColsStyle.Text := FTable.EvenCols;
  mOddColsStyle.Text := FTable.OddCols;

  FTableStyle := style.Clone;

  FFirstRowStyle := FTable.FirstRow.Clone;
  FLastRowStyle := FTable.LastRow.Clone;
  FFirstColStyle := FTable.FirstCol.Clone;
  FLastColStyle := FTable.LastCol.Clone;
  FEvenRowStyle := FTable.EvenRows.Clone;
  FOddRowStyle := FTable.OddRows.Clone;
  FEvenColStyle := FTable.EvenCols.Clone;
  FOddColStyle := FTable.OddCols.Clone;

  for i := 0 to sbCellStyles.ControlCount - 1 do
    if sbCellStyles.Controls[i] is TLabel then
      if TLabel(sbCellStyles.Controls[i]).FocusControl is TButton then
        TButton(TLabel(sbCellStyles.Controls[i]).FocusControl).Tag := NativeInt(sbCellStyles.Controls[i])

end;

procedure TTableDesignFrm.Apply;
var
  style: TASAttributes;
  i: Integer;
  firstcell: TASAttributes;
begin

  style := FTableStyle.Clone;
  if cbUseOuterBorder.Checked then
  begin
    style['table-border-width'] := eBorderWidth.Text;
    style['table-border-color'] := ColorToHex(ccBorderColor.Color);
  end
  else
  begin
    style.Remove('table-border-width');
    style.Remove('table-border-color');
  end;
  if cbUseInternalGrid.Checked then
  begin
    style['horizontal-grid-width'] := egridWidthX.Text;
    style['horizontal-grid-color'] := ColorToHex(ccgridColorX.Color);
    style['vertical-grid-width'] := egridWidthY.Text;
    style['vertical-grid-color'] := ColorToHex(ccgridColorY.Color);
  end
  else
  begin
    style.Remove('horizontal-grid-width');
    style.Remove('horizontal-grid-color');
    style.Remove('vertical-grid-width');
    style.Remove('vertical-grid-color');
  end;
  style['cell-width'] := eCellWidth.Text;
  style['cell-height'] := eCellHeight.Text;

  FTable.Style := style.Clone;
  FTable.FirstRow := FFirstRowStyle.Clone;
  FTable.LastRow := FLastRowStyle.Clone;
  FTable.FirstCol := FFirstColStyle.Clone;
  FTable.LastCol := FLastColStyle.Clone;
  FTable.EvenRows := FEvenRowStyle.Clone;
  FTable.OddRows := FOddRowStyle.Clone;
  FTable.EvenCols := FEvenColstyle.Clone;
  FTable.OddCols := FOddColstyle.Clone;

  if FTable.Height > 0 then
    for i := 0 to FTable.Width - 1 do
    begin
      firstcell := FTable.CellStyles[Point(i, 0)];
      if (teColWidths.LineCount >= i + 1) and (teColWidths.Lines[i] <> '') then
        firstcell['column-width'] := teColWidths.Lines[i]
      else
        firstcell.Remove('column-width');
      FTable.CellStyles[Point(i, 0)] := firstcell;
    end;

  if Assigned(FOnApply) then
    FOnApply(Self);

end;

end.
