unit RecycleBinDM; interface uses SysUtils, Classes, DB, Provider, DBClient, ADODB, ZjIDTree, XMLDoc, XMLIntf, ConstVarUnit; type TRecycleBinData = class(TDataModule) atRecycleBin: TADOTable; cdsRecycleBin: TClientDataSet; dspRecycleBin: TDataSetProvider; cdsRecycleBinID: TIntegerField; cdsRecycleBinName: TWideStringField; cdsBills: TClientDataSet; cdsDrawingQuantity: TClientDataSet; cdsBillsID: TIntegerField; cdsBillsParentID: TIntegerField; cdsBillsNextSiblingID: TIntegerField; cdsBillsUnits: TWideStringField; cdsBillsQuantity: TFloatField; cdsBillsUnitPrice: TBCDField; cdsBillsTotalPrice: TBCDField; cdsBillsDesignQuantity: TFloatField; cdsBillsDesignQuantity2: TFloatField; cdsBillsDesignPrice: TFloatField; cdsBillsMemoStr: TMemoField; cdsBillsCode: TWideStringField; cdsBillsName: TWideStringField; cdsDrawingQuantityName: TWideStringField; cdsDrawingQuantityUnits: TWideStringField; cdsDrawingQuantityBillsID: TIntegerField; cdsDrawingQuantityDQuantity1: TFloatField; cdsDrawingQuantityMemoContext: TWideStringField; cdsRecycleBinCreateTime: TWideStringField; cdsRecycleBinFileName: TWideStringField; procedure DataModuleDestroy(Sender: TObject); procedure DataModuleCreate(Sender: TObject); procedure cdsRecycleBinAfterScroll(DataSet: TDataSet); procedure cdsBillsAfterScroll(DataSet: TDataSet); private FBillsTree: TZjIDTree; FConnection: TADOConnection; FXMLDoc: IXMLDocument; FLoading: Boolean; FFileList: TStrings; function GetNewID: Integer; procedure SetConnection(const Value: TADOConnection); procedure RefreshDrawingQuantity(ABillsID: Integer); procedure EmptyDateSets; function CreateXMLDoc: IXMLDocument; procedure LoadBillsAndDrawingQuantity(ANode: IXMLNode); procedure LoadBills(ANode: IXMLNode; AParentID: Integer); procedure LoadDrawingQuantity(ANode: IXMLNode); procedure ConnectBillsTree; procedure DisConnectTree; procedure DeleteFiles; public procedure InsertNode(const AProjName, AName: string); procedure DeleteCurrentNode; procedure ClearNodes; function GetCurrentFileName: string; procedure Save; procedure RefreshBills; property Connection: TADOConnection read FConnection write SetConnection; property BillsTree: TZjIDTree read FBillsTree; end; implementation uses Variants; {$R *.dfm} { TRecycleBinData } procedure TRecycleBinData.DeleteCurrentNode; begin if cdsRecycleBin.RecordCount > 0 then begin DeleteFile(GetCurrentFileName); FFileList.Delete(FFileList.IndexOf(GetCurrentFileName)); cdsRecycleBin.Delete; end; end; function TRecycleBinData.GetCurrentFileName: string; var S: string; begin S := ExtractFilePath(ParamStr(0)) + cdsRecycleBinFileName.AsString; Result := S; end; function TRecycleBinData.GetNewID: Integer; begin cdsRecycleBin.Last; Result := cdsRecycleBinID.AsInteger + 1; end; procedure TRecycleBinData.InsertNode(const AProjName, AName: string); var iID: Integer; begin FLoading := True; try iID := GetNewID; cdsRecycleBin.Append; cdsRecycleBinID.Value := iID; cdsRecycleBinName.Value := AName; cdsRecycleBinCreateTime.Value := FormatDateTime('yyyy年mm月dd日hh时nn分ss秒', Now); cdsRecycleBinFileName.Value := 'RecycleBin\' + AProjName + '\' + AName + '(' + cdsRecycleBinCreateTime.AsString + ').bak'; cdsRecycleBin.Post; FFileList.Add(GetCurrentFileName); finally FLoading := False; end; end; procedure TRecycleBinData.Save; begin FFileList.Clear; cdsRecycleBin.ApplyUpdates(0); end; procedure TRecycleBinData.SetConnection(const Value: TADOConnection); begin FConnection := Value; atRecycleBin.Connection := FConnection; cdsRecycleBin.Open; end; procedure TRecycleBinData.DataModuleDestroy(Sender: TObject); begin DeleteFiles; FBillsTree.Free; FFileList.Free; end; procedure TRecycleBinData.DataModuleCreate(Sender: TObject); begin FBillsTree := TZjIDTree.Create; FBillsTree.KeyFieldName := 'ID'; FBillsTree.ParentFieldName := 'ParentID'; FBillsTree.NextSiblingFieldName := 'NextSiblingID'; FBillsTree.AutoExpand := True; FFileList := TStringList.Create; end; procedure TRecycleBinData.cdsRecycleBinAfterScroll(DataSet: TDataSet); begin if not FLoading then RefreshBills; end; procedure TRecycleBinData.cdsBillsAfterScroll(DataSet: TDataSet); begin if not FLoading then RefreshDrawingQuantity(cdsBillsID.AsInteger); end; procedure TRecycleBinData.RefreshBills; begin if cdsRecycleBin.RecordCount = 0 then Exit; if not FileExists(GetCurrentFileName) then Exit; EmptyDateSets; FXMLDoc := CreateXMLDoc; try DisConnectTree; FXMLDoc.LoadFromFile(GetCurrentFileName); LoadBillsAndDrawingQuantity(FXMLDoc.DocumentElement); ConnectBillsTree; finally FXMLDoc := nil; end; end; procedure TRecycleBinData.RefreshDrawingQuantity(ABillsID: Integer); begin cdsDrawingQuantity.DisableControls; try cdsDrawingQuantity.Filtered := False; cdsDrawingQuantity.Filter := 'BillsID=' + IntToStr(ABillsID); cdsDrawingQuantity.Filtered := True; finally cdsDrawingQuantity.EnableControls; end; end; function TRecycleBinData.CreateXMLDoc: IXMLDocument; begin Result := TXMLDocument.Create(nil) as IXMLDocument; Result.Active := True; Result.Encoding := 'gb2312'; Result.Options := Result.Options + [doNodeAutoIndent]; Result.AddChild('SmartCost'); end; procedure TRecycleBinData.EmptyDateSets; begin cdsBills.EmptyDataSet; cdsDrawingQuantity.EmptyDataSet; end; procedure TRecycleBinData.LoadBillsAndDrawingQuantity(ANode: IXMLNode); begin ANode := ANode.ChildNodes.FindNode(c_BillsList); if Assigned(ANode) and ANode.HasChildNodes then LoadBills(ANode.ChildNodes.First, -1); end; procedure TRecycleBinData.LoadBills(ANode: IXMLNode; AParentID: Integer); var strCode: string; begin if ANode = nil then Exit; if SameText(ANode.NodeName, c_BillsItem) then begin cdsBills.Append; cdsBillsID.Value := ANode.Attributes[c_ID]; cdsBillsParentID.Value := AParentID; cdsBillsNextSiblingID.Value := ANode.Attributes[c_NextSiblingID]; strCode := VarToStr(ANode.Attributes[c_Code]); if strCode <> '' then cdsBillsCode.Value := strCode else cdsBillsCode.Value := ANode.Attributes[c_BCode]; cdsBillsName.Value := VarToStr(ANode.Attributes[c_Name]); cdsBillsUnits.Value := VarToStr(ANode.Attributes[c_Units]); cdsBillsQuantity.Value := ANode.Attributes[c_Quantity]; cdsBillsDesignQuantity.Value := ANode.Attributes[c_DesignQuantity1]; cdsBillsDesignQuantity2.Value := ANode.Attributes[c_DesignQuantity2]; cdsBillsDesignPrice.Value := ANode.Attributes[c_DesignPrice]; cdsBillsUnitPrice.Value := ANode.Attributes[c_UnitPrice]; cdsBillsTotalPrice.Value := ANode.Attributes[c_TotalPrice]; cdsBillsMemoStr.Value := ANode.Attributes[c_MemoString]; cdsBills.Post; LoadDrawingQuantity(ANode); end; if ANode.HasChildNodes then LoadBills(ANode.ChildNodes.First, cdsBillsID.AsInteger); if Assigned(ANode.NextSibling) then LoadBills(ANode.NextSibling, AParentID); end; procedure TRecycleBinData.LoadDrawingQuantity(ANode: IXMLNode); var I: Integer; vNode: IXMLNode; begin ANode := ANode.ChildNodes.FindNode(c_DrawQList); if ANode = nil then Exit; for I := 0 to ANode.ChildNodes.Count - 1 do begin vNode := ANode.ChildNodes[I]; cdsDrawingQuantity.Append; cdsDrawingQuantityBillsID.Value := vNode.Attributes[c_BillsID]; cdsDrawingQuantityName.Value := vNode.Attributes[c_Name]; cdsDrawingQuantityUnits.Value := vNode.Attributes[c_Units]; cdsDrawingQuantityDQuantity1.Value := vNode.Attributes[c_DesignQuantity1]; cdsDrawingQuantityMemoContext.Value := vNode.Attributes[c_MemoString]; cdsDrawingQuantity.Post; end; end; procedure TRecycleBinData.ConnectBillsTree; begin FBillsTree.DataSet := cdsBills; FBillsTree.Active := True; end; procedure TRecycleBinData.DisConnectTree; begin FBillsTree.DataSet := nil; FBillsTree.Active := False; end; procedure TRecycleBinData.DeleteFiles; var I: Integer; begin for I := 0 to FFileList.Count - 1 do DeleteFile(FFileList[I]); end; procedure TRecycleBinData.ClearNodes; begin cdsRecycleBin.First; while not cdsRecycleBin.Eof do DeleteCurrentNode; end; end.