unit tpSelectTendersFrm;

interface

uses
  sdIDTree,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ZJGrid, JimPages, ActnList, sdGridDBA,
  sdGridTreeDBA;

type
  TSelectTendersForm = class(TForm)
    btnOk: TButton;
    btnCancel: TButton;
    stdTenderSelect: TsdGridTreeDBA;
    lblTenderResult: TLabel;
    Panel1: TPanel;
    pnlTenderSelectTitle: TPanel;
    lblTenderSelect: TLabel;
    pnlSelect: TPanel;
    zgTenderSelect: TZJGrid;
    pnlSelectTitle: TPanel;
    lblTenderList: TLabel;
    pnlResult: TPanel;
    zgResult: TZJGrid;
    pnlResultTitle: TPanel;
    lblResultList: TLabel;
    pnlDivision: TPanel;
    procedure zgTenderSelectDrawCellText(ACanvas: TCanvas;
      const ARect: TRect; const ACoord: TPoint; AGrid: TZJGrid;
      const Text: String; var ADefaultDraw: Boolean);
    procedure zgTenderSelectShowHint(var HintStr: String;
      var CanShow: Boolean; var HintInfo: THintInfo; const ACoord: TPoint);
    procedure zgTenderSelectCellTextChanged(Sender: TObject; Col,
      Row: Integer);
    procedure zgTenderSelectSetCellText(Sender: TObject;
      const ACoord: TPoint; var Value: String; DisplayText: Boolean);
    procedure zgTenderSelectGetCellText(Sender: TObject;
      const ACoord: TPoint; var Value: String; DisplayText: Boolean);
    procedure btnOkClick(Sender: TObject);
  private
    FSelects: TList;

    procedure AddRows(ANode: TsdIDTreeNode);
    procedure RemoveRows(ANode: TsdIDTreeNode);

    procedure InitResultGrid;
    procedure AssignResultGrid;
    procedure AssignResult;

    function GetSelectCount: Integer;
    function GetSelectTotalPrice: Double;
  public
    constructor Create(AHistorys: TList);
    destructor Destroy; override;

    procedure AssignSelectTenders(ATender: TList);

    property SelectCount: Integer read GetSelectCount;
    property SelectTotalPrice: Double read GetSelectTotalPrice;
  end;

function SelectTendersToPart(ATenders: TList): Boolean;

implementation

uses
  Globals, MainFrm, ProjectManagerDm, sdDB, UtilMethods;

function SelectTendersToPart(ATenders: TList): Boolean;
var
  vSelectFrm: TSelectTendersForm;
begin
  vSelectFrm := TSelectTendersForm.Create(ATenders);
  try
    Result := vSelectFrm.ShowModal = mrOk;
    if Result then
      vSelectFrm.AssignSelectTenders(ATenders);
  finally
    vSelectFrm.Free;
  end;
end;

{$R *.dfm}

constructor TSelectTendersForm.Create(AHistorys: TList);
begin
  inherited Create(nil);
  stdTenderSelect.DataView := ProjectManager.sdvProjectsSpare;
  FSelects := TList.Create;
  FSelects.Assign(AHistorys);
  InitResultGrid;
end;

destructor TSelectTendersForm.Destroy;
begin
  FSelects.Free;
  inherited;
end;

procedure TSelectTendersForm.zgTenderSelectDrawCellText(ACanvas: TCanvas;
  const ARect: TRect; const ACoord: TPoint; AGrid: TZJGrid;
  const Text: String; var ADefaultDraw: Boolean);

  procedure GetBitmap(AImage: TBitmap);
  begin
    with stdTenderSelect.IDTree.Items[ACoord.Y - 1] do
      if Rec.ValueByName('Type').AsInteger = 0 then
        if Expanded and HasChildren then
          MainForm.Images.GetBitmap(34, AImage)
        else
          MainForm.Images.GetBitmap(34, AImage)
      else
        MainForm.Images.GetBitmap(11, AImage);
  end;

const
  rIconWidth = 16;
  rIconHeight = 16;
var
  Img: TBitmap;
  Cell: TZjCell;
  rImg: TRect;
begin
 if (ACoord.X = 2) and (ACoord.Y > zgTenderSelect.FixedRowCount - 1) then
  begin
    Cell := zgTenderSelect.Cells[ACoord.X, ACoord.Y];
    Img := TBitmap.Create;
    try
      GetBitmap(Img);
      case Cell.Align of
        gaTopLeft, gaTopCenter, gaTopRight:
          rImg := Rect(ARect.Left + 2, ARect.Top, ARect.Left + rIconWidth, ARect.Top + rIconHeight);
        gaCenterLeft, gaCenterCenter, gaCenterRight:
          rImg := Rect(ARect.Left + 2, ARect.Top + (ARect.Bottom - ARect.Top - rIconHeight) div 2, ARect.Left + rIconWidth, ARect.Bottom - (ARect.Bottom - ARect.Top - rIconHeight) div 2);
        gaBottomLeft, gaBottomCenter, gaBottomRight:
          rImg := Rect(ARect.Left + 2, ARect.Bottom - rIconHeight, ARect.Left + rIconWidth, ARect.Bottom);
      end;
      ACanvas.StretchDraw(rImg, Img);
      WriteText(ACanvas, Rect(ARect.Left + rIconWidth, ARect.Top, ARect.Right, ARect.Bottom)
        , 2, 2, Text, Cell.Align, False);
      ADefaultDraw := False;
    finally
      Img.Free;
    end;
  end;
end;

procedure TSelectTendersForm.zgTenderSelectShowHint(var HintStr: String;
  var CanShow: Boolean; var HintInfo: THintInfo; const ACoord: TPoint);
var
  vCell: TZjCell;
  vNode: TsdIDTreeNode;
  iLevelWidth: Integer;
  rText: TRect;

  procedure CalcTextRect(var R: TRect);
  var
    DC: HDC;
    iTextHeight: Integer;
  begin
    DC := CreateCompatibleDC(0);
    try
      SelectObject(DC, vCell.Font.Handle);
      iTextHeight := DrawText(DC, PChar(vCell.Text), Length(vCell.Text), R, DT_SINGLELINE or DT_VCenter
        or DT_NOCLIP or DT_CALCRECT);
    finally
      DeleteDC(DC);
    end;
  end;

begin
  if ACoord.Y < 1 then Exit;

  vCell := zgTenderSelect.Cells[ACoord.X, ACoord.Y];
  with HintInfo do
  begin
    vNode := stdTenderSelect.IDTree.Items[ACoord.Y - 1];
    if not Assigned(vNode) then Exit;
    iLevelWidth := (vNode.Level + 1) * 20 + 16;

    rText := CursorRect;
    CalcTextRect(rText);
    if (rText.Right - rText.Left + iLevelWidth > CursorRect.Right - CursorRect.Left) or
      (rText.Right > ClientWidth) then
    begin
      CanShow := True;
      HintStr := vCell.Text;
      GetCursorPos(HintPos);
    end;
  end;
end;

procedure TSelectTendersForm.InitResultGrid;
begin
  zgResult.ColCount := 2;
  zgResult.RowCount := 1;
  zgResult.Cells[1, 0].Text := '所选项目';
  zgResult.ColWidths[1] := 225;
end;

procedure TSelectTendersForm.AssignResult;
const
  sResult = '共选中标段 %d 个，金额合计 %s 元';
var
  sTotalPrice: string;
begin
  InitResultGrid;
  AssignResultGrid;
  sTotalPrice := FormatFloat('##,###,###,###.##', SelectTotalPrice);
  lblTenderResult.Caption := Format(sResult, [SelectCount, sTotalPrice]);
end;

procedure TSelectTendersForm.zgTenderSelectCellTextChanged(Sender: TObject;
  Col, Row: Integer);
begin
  if (Col = 1) then
    zgTenderSelect.InvalidateCol(1);
end;

procedure TSelectTendersForm.zgTenderSelectSetCellText(Sender: TObject;
  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
var
  stnNode: TsdIDTreeNode;
begin
  if ACoord.X = 1 then
  begin
    stnNode := stdTenderSelect.IDTree.Items[ACoord.Y - 1];
    if Value = 'True' then
      AddRows(stnNode)
    else
      RemoveRows(stnNode);
    AssignResult;
  end;
end;

procedure TSelectTendersForm.AddRows(ANode: TsdIDTreeNode);
var
  iChild: Integer;
begin
  if not Assigned(ANode) then Exit;

  if FSelects.IndexOf(Pointer(ANode.ID)) = -1 then
    FSelects.Add(Pointer(ANode.ID));

  if ANode.HasChildren then
    for iChild := 0 to ANode.ChildCount - 1 do
      AddRows(ANode.ChildNodes[iChild]);
end;

procedure TSelectTendersForm.RemoveRows(ANode: TsdIDTreeNode);
var
  iChild: Integer;
begin
  if not Assigned(ANode) then Exit;

  if FSelects.IndexOf(Pointer(ANode.ID)) > -1 then
    FSelects.Remove(Pointer(ANode.ID));

  if ANode.HasChildren then
    for iChild := 0 to ANode.ChildCount - 1 do
      RemoveRows(ANode.ChildNodes[iChild]);
end;

procedure TSelectTendersForm.zgTenderSelectGetCellText(Sender: TObject;
  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
var
  stnNode: TsdIDTreeNode;
begin
  if ACoord.X = 1 then
  begin
    stnNode := stdTenderSelect.IDTree.Items[ACoord.Y - 1];
    if Assigned(stnNode) and (FSelects.IndexOf(Pointer(stnNode.ID)) > -1) then
      Value := 'True';
  end;
end;

procedure TSelectTendersForm.AssignResultGrid;
var
  i, iID: Integer;
  vNode: TsdIDTreeNode;
begin
  for i := 0 to FSelects.Count - 1 do
  begin
    iID := Integer(FSelects.Items[i]);
    vNode := stdTenderSelect.IDTree.FindNode(iID);
    if vNode.Rec.ValueByName('Type').AsInteger = 1 then
    begin
      zgResult.RowCount := zgResult.RowCount + 1;
      zgResult.Cells[1, zgResult.RowCount - 1].Text := vNode.Rec.ValueByName('Name').AsString;
      zgResult.Cells[1, zgResult.RowCount - 1].Align := gaCenterLeft;
      zgResult.Rows[zgResult.RowCount - 1].Data := vNode;
    end;
  end;
end;

function TSelectTendersForm.GetSelectCount: Integer;
begin
  Result := zgResult.RowCount - 1;
end;

function TSelectTendersForm.GetSelectTotalPrice: Double;
var
  iRow: Integer;
  vNode: TsdIDTreeNode;
begin
  Result := 0;
  for iRow := 1 to zgResult.RowCount - 1 do
  begin
    vNode := TsdIDTreeNode(zgResult.Rows[iRow].Data);
    if Assigned(vNode) then
      Result := Result + vNode.Rec.ValueByName('DealTotalPrice').AsFloat;
  end;
end;

procedure TSelectTendersForm.btnOkClick(Sender: TObject);

  function CheckValid(var AMessage: string): Boolean;
  begin
    Result := False;
    if SelectCount = 0 then
      AMessage := '请勾选需统一划分的标段。'
    else if SelectTotalPrice <= 0 then
      AMessage := '当前勾选的标段，合计金额为0，请检查标段数据是否正确。'
    else
      Result := True;
  end;

var
  iCount: Integer;
  sMessage: string;
begin
  if not CheckValid(sMessage) then
  begin
    WarningMessage(sMessage);
    Exit;
  end
  else
    ModalResult := mrOk;
end;

procedure TSelectTendersForm.AssignSelectTenders(ATender: TList);
//var
  //iRow: Integer;
begin
  ATender.Assign(FSelects);
  //for iRow := 1 to zgResult.RowCount - 1 do
  //begin
  //  if Assigned(zgResult.Rows[iRow].Data) then
  //    ATender.Add(Pointer(TsdIDTreeNode(zgResult.Rows[iRow].Data).ID));
  //end;
end;

end.
