BillsClipboard.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. unit BillsClipboard;
  2. interface
  3. uses
  4. BaseClipboard, Classes, BillsDm, ZhAPI, XmlDoc, XmlIntf, Windows, sdIDTree;
  5. type
  6. TBillsBlockNode = class
  7. private
  8. FID: Integer;
  9. FParentID: Integer;
  10. FNextSiblingID: Integer;
  11. FCode: string;
  12. FB_Code: string;
  13. FName: string;
  14. FUnits: string;
  15. FPrice: Double;
  16. FOrgQuantity: Double;
  17. FOrgTotalPrice: Double;
  18. FMisQuantity: Double;
  19. FMisTotalPrice: Double;
  20. FOthQuantity: Double;
  21. FOthTotalPrice: Double;
  22. FQuantity: Double;
  23. FTotalPrice: Double;
  24. FCalcType: Integer;
  25. FDrawingCode: string;
  26. FAlias: string;
  27. FDgnQuantity1: Double;
  28. FDgnQuantity2: Double;
  29. FMemoStr: string;
  30. FDealCode: string;
  31. FDealCompany: string;
  32. public
  33. procedure SaveToXmlNode(AXmlNode: IXMLNode);
  34. procedure LoadFromXmlNode(AXmlNode: IXMLNode);
  35. end;
  36. TBillsClipboard = class(TBaseClipboard)
  37. private
  38. FBillsData: TBillsData;
  39. FNodeList: TList;
  40. procedure SaveNodesToXml(AXmlNode: IXMLNode);
  41. procedure LoadNodesFromXml(AXmlNode: IXMLNode);
  42. procedure CopyBillsNodeData(ANode: TsdIDTreeNode);
  43. procedure CopyBillsNode(ANode: TsdIDTreeNode);
  44. procedure CopyData(ANode: TsdIDTreeNode; ACount: Integer);
  45. function AddBillsNode(ANode: TsdIDTreeNode; APos: Integer): TsdIDTreeNode;
  46. procedure PasteBillsNodeData(ANode: TsdIDTreeNode; APasteNode: TBillsBlockNode);
  47. procedure PasteChildren(AParentNode: TsdIDTreeNode; APasteParentID: Integer);
  48. procedure PasteNextSibling(APreSibling: TsdIDTreeNode; APasteNodeID: Integer);
  49. procedure PasteBillsNode(ANode: TsdIDTreeNode; APos: Integer; APasteNode: TBillsBlockNode);
  50. procedure PasteData(ANode: TsdIDTreeNode; APos: Integer);
  51. procedure Clear;
  52. protected
  53. procedure LoadXmlData(AXmlDoc: IXmlDocument); override;
  54. procedure SaveXmlData(AXmlDoc: IXmlDocument); override;
  55. public
  56. constructor Create(ABillsData: TBillsData);
  57. destructor Destroy; override;
  58. procedure Copy(ANode: TsdIDTreeNode; ACount: Integer);
  59. // APos: 0[×ÓÏî] 1[ºóÏî] 2[ǰÏî]
  60. procedure Paste(ANode: TsdIDTreeNode; APos: Integer);
  61. end;
  62. function HasBillsBlockFormat: Boolean;
  63. implementation
  64. uses sdDB, Math, SysUtils, UtilMethods;
  65. var
  66. CF_BillsBlock: Word;
  67. function HasBillsBlockFormat: Boolean;
  68. begin
  69. Result := HasClipboardFormat(CF_BillsBlock);
  70. end;
  71. { TBillsClipboard }
  72. function TBillsClipboard.AddBillsNode(ANode: TsdIDTreeNode;
  73. APos: Integer): TsdIDTreeNode;
  74. begin
  75. // ×ÓÏî²åÈë
  76. if APos = 0 then
  77. Result := ANode.Owner.Add(ANode.ID, -1)
  78. // ºóÏî²åÈë
  79. else if APos = 1 then
  80. Result := ANode.Owner.Add(ANode.ParentID, ANode.NextSiblingID)
  81. // ǰÏî²åÈë
  82. else if APos = 2 then
  83. Result := ANode.Owner.Add(ANode.ParentID, ANode.ID);
  84. end;
  85. procedure TBillsClipboard.Clear;
  86. begin
  87. ClearObjects(FNodeList);
  88. FNodeList.Clear;
  89. end;
  90. procedure TBillsClipboard.Copy(ANode: TsdIDTreeNode; ACount: Integer);
  91. begin
  92. Clear;
  93. CopyData(ANode, ACount);
  94. SaveToStream;
  95. SaveToClipboard(CF_BillsBlock);
  96. end;
  97. procedure TBillsClipboard.CopyBillsNode(ANode: TsdIDTreeNode);
  98. var
  99. iChild: Integer;
  100. begin
  101. if Assigned(ANode) then
  102. begin
  103. CopyBillsNodeData(ANode);
  104. for iChild := 0 to ANode.ChildCount - 1 do
  105. CopyBillsNode(ANode.ChildNodes[iChild]);
  106. end;
  107. end;
  108. procedure TBillsClipboard.CopyBillsNodeData(ANode: TsdIDTreeNode);
  109. var
  110. vNode: TBillsBlockNode;
  111. begin
  112. vNode := TBillsBlockNode.Create;
  113. FNodeList.Add(vNode);
  114. vNode.FID := ANode.Rec.ValueByName('ID').AsInteger;
  115. vNode.FParentID := ANode.Rec.ValueByName('ParentID').AsInteger;
  116. vNode.FNextSiblingID := ANode.Rec.ValueByName('NextSiblingID').AsInteger;
  117. vNode.FCode := ANode.Rec.ValueByName('Code').AsString;
  118. vNode.FB_Code := ANode.Rec.ValueByName('B_Code').AsString;
  119. vNode.FName := ANode.Rec.ValueByName('Name').AsString;
  120. vNode.FUnits := ANode.Rec.ValueByName('Units').AsString;
  121. vNode.FPrice := ANode.Rec.ValueByName('Price').AsFloat;
  122. vNode.FOrgQuantity := ANode.Rec.ValueByName('OrgQuantity').AsFloat;
  123. vNode.FOrgTotalPrice := ANode.Rec.ValueByName('OrgTotalPrice').AsFloat;
  124. vNode.FMisQuantity := ANode.Rec.ValueByName('MisQuantity').AsFloat;
  125. vNode.FMisTotalPrice := ANode.Rec.ValueByName('MisTotalPrice').AsFloat;
  126. vNode.FOthQuantity := ANode.Rec.ValueByName('OthQuantity').AsFloat;
  127. vNode.FOthTotalPrice := ANode.Rec.ValueByName('OthTotalPrice').AsFloat;
  128. vNode.FQuantity := ANode.Rec.ValueByName('Quantity').AsFloat;
  129. vNode.FTotalPrice := ANode.Rec.ValueByName('TotalPrice').AsFloat;
  130. vNode.FCalcType := ANode.Rec.ValueByName('CalcType').AsInteger;
  131. vNode.FDrawingCode := ANode.Rec.ValueByName('DrawingCode').AsString;
  132. vNode.FAlias := ANode.Rec.ValueByName('Alias').AsString;
  133. vNode.FDgnQuantity1 := ANode.Rec.ValueByName('DgnQuantity1').AsFloat;
  134. vNode.FDgnQuantity2 := ANode.Rec.ValueByName('DgnQuantity2').AsFloat;
  135. vNode.FMemoStr := ANode.Rec.ValueByName('MemoStr').AsString;
  136. vNode.FDealCode := ANode.Rec.ValueByName('DealCode').AsString;
  137. vNode.FDealCompany := ANode.Rec.ValueByName('DealCompany').AsString;
  138. end;
  139. procedure TBillsClipboard.CopyData(ANode: TsdIDTreeNode; ACount: Integer);
  140. begin
  141. while Assigned(ANode) and (ACount > 0) do
  142. begin
  143. CopyBillsNode(ANode);
  144. Dec(ACount, ANode.PosterityCount + 1);
  145. ANode := ANode.NextSibling;
  146. end;
  147. end;
  148. constructor TBillsClipboard.Create(ABillsData: TBillsData);
  149. begin
  150. inherited Create;
  151. FBillsData := ABillsData;
  152. FNodeList := TList.Create;
  153. end;
  154. destructor TBillsClipboard.Destroy;
  155. begin
  156. ClearObjects(FNodeList);
  157. FNodeList.Free;
  158. inherited;
  159. end;
  160. procedure TBillsClipboard.LoadNodesFromXml(AXmlNode: IXMLNode);
  161. var
  162. BillsBlockNode: TBillsBlockNode;
  163. iNum: Integer;
  164. ParentXmlNode, CurXmlNode: IXMLNode;
  165. begin
  166. ParentXmlNode := AXmlNode.ChildNodes.FindNode('BillsBlockNodes');
  167. for iNum := 0 to ParentXmlNode.ChildNodes.Count - 1 do
  168. begin
  169. CurXmlNode := ParentXmlNode.ChildNodes.Nodes[iNum];
  170. BillsBlockNode := TBillsBlockNode.Create;
  171. FNodeList.Add(BillsBlockNode);
  172. BillsBlockNode.LoadFromXmlNode(CurXmlNode);
  173. end;
  174. end;
  175. procedure TBillsClipboard.LoadXmlData(AXmlDoc: IXmlDocument);
  176. begin
  177. inherited;
  178. LoadNodesFromXml(AXmlDoc.DocumentElement);
  179. end;
  180. procedure TBillsClipboard.Paste(ANode: TsdIDTreeNode; APos: Integer);
  181. begin
  182. Clear;
  183. LoadFromClipboard(CF_BillsBlock);
  184. LoadFromStream;
  185. PasteData(ANode, APos);
  186. end;
  187. procedure TBillsClipboard.PasteBillsNode(ANode: TsdIDTreeNode;
  188. APos: Integer; APasteNode: TBillsBlockNode);
  189. var
  190. stnCurrent: TsdIDTreeNode;
  191. begin
  192. stnCurrent := AddBillsNode(ANode, APos);
  193. PasteBillsNodeData(stnCurrent, APasteNode);
  194. PasteChildren(stnCurrent, APasteNode.FID);
  195. PasteNextSibling(stnCurrent, APasteNode.FNextSiblingID);
  196. end;
  197. procedure TBillsClipboard.PasteBillsNodeData(ANode: TsdIDTreeNode;
  198. APasteNode: TBillsBlockNode);
  199. begin
  200. ANode.Rec.ValueByName('Code').AsString := APasteNode.FCode;
  201. ANode.Rec.ValueByName('B_Code').AsString := APasteNode.FB_Code;
  202. ANode.Rec.ValueByName('Name').AsString := APasteNode.FName;
  203. ANode.Rec.ValueByName('Units').AsString := APasteNode.FUnits;
  204. ANode.Rec.ValueByName('Price').AsFloat := APasteNode.FPrice;
  205. ANode.Rec.ValueByName('OrgQuantity').AsFloat := QuantityRoundTo(APasteNode.FOrgQuantity);
  206. ANode.Rec.ValueByName('OrgTotalPrice').AsFloat := TotalPriceRoundTo(APasteNode.FOrgTotalPrice);
  207. ANode.Rec.ValueByName('MisQuantity').AsFloat := QuantityRoundTo(APasteNode.FMisQuantity);
  208. ANode.Rec.ValueByName('MisTotalPrice').AsFloat := TotalPriceRoundTo(APasteNode.FMisTotalPrice);
  209. ANode.Rec.ValueByName('OthQuantity').AsFloat := QuantityRoundTo(APasteNode.FOthQuantity);
  210. ANode.Rec.ValueByName('OthTotalPrice').AsFloat := TotalPriceRoundTo(APasteNode.FOthTotalPrice);
  211. ANode.Rec.ValueByName('Quantity').AsFloat := QuantityRoundTo(APasteNode.FQuantity);
  212. ANode.Rec.ValueByName('TotalPrice').AsFloat := TotalPriceRoundTo(APasteNode.FTotalPrice);
  213. ANode.Rec.ValueByName('CalcType').AsInteger := APasteNode.FCalcType;
  214. ANode.Rec.ValueByName('DrawingCode').AsString := APasteNode.FDrawingCode;
  215. ANode.Rec.ValueByName('Alias').AsString := APasteNode.FAlias;
  216. ANode.Rec.ValueByName('DgnQuantity1').AsFloat := QuantityRoundTo(APasteNode.FDgnQuantity1);
  217. ANode.Rec.ValueByName('DgnQuantity2').AsFloat := QuantityRoundTo(APasteNode.FDgnQuantity2);
  218. ANode.Rec.ValueByName('MemoStr').AsString := APasteNode.FMemoStr;
  219. ANode.Rec.ValueByName('DealCode').AsString := APasteNode.FDealCode;
  220. ANode.Rec.ValueByName('DealCompany').AsString := APasteNode.FDealCompany;
  221. end;
  222. procedure TBillsClipboard.PasteChildren(AParentNode: TsdIDTreeNode;
  223. APasteParentID: Integer);
  224. var
  225. iNode: Integer;
  226. begin
  227. for iNode := 0 to FNodeList.Count - 1 do
  228. if TBillsBlockNode(FNodeList.Items[iNode]).FParentID = APasteParentID then
  229. begin
  230. PasteBillsNode(AParentNode, 0, TBillsBlockNode(FNodeList.Items[iNode]));
  231. Break;
  232. end;
  233. end;
  234. procedure TBillsClipboard.PasteData(ANode: TsdIDTreeNode; APos: Integer);
  235. var
  236. I: Integer;
  237. vPasteNode: TBillsBlockNode;
  238. begin
  239. PasteBillsNode(ANode, APos, TBillsBlockNode(FNodeList.First));
  240. end;
  241. procedure TBillsClipboard.PasteNextSibling(APreSibling: TsdIDTreeNode;
  242. APasteNodeID: Integer);
  243. var
  244. iNode: Integer;
  245. begin
  246. if APasteNodeID = -1 then Exit;
  247. for iNode := 0 to FNodeList.Count - 1 do
  248. if TBillsBlockNode(FNodeList.Items[iNode]).FID = APasteNodeID then
  249. begin
  250. PasteBillsNode(APreSibling, 1, TBillsBlockNode(FNodeList.Items[iNode]));
  251. Break;
  252. end;
  253. end;
  254. procedure TBillsClipboard.SaveNodesToXml(AXmlNode: IXMLNode);
  255. var
  256. ParentXmlNode, CurXmlNode: IXMLNode;
  257. iNum: Integer;
  258. BillsBlockNode: TBillsBlockNode;
  259. begin
  260. ParentXmlNode := AXmlNode.AddChild('BillsBlockNodes');
  261. for iNum := 0 to FNodeList.Count - 1 do
  262. begin
  263. BillsBlockNode := TBillsBlockNode(FNodeList.Items[iNum]);
  264. CurXmlNode := ParentXmlNode.AddChild('BillsBlockNode');
  265. BillsBlockNode.SaveToXmlNode(CurXmlNode);
  266. end;
  267. end;
  268. procedure TBillsClipboard.SaveXmlData(AXmlDoc: IXmlDocument);
  269. begin
  270. SaveNodesToXml(AXmlDoc.DocumentElement);
  271. inherited;
  272. end;
  273. { TBillsBlockNode }
  274. procedure TBillsBlockNode.LoadFromXmlNode(AXmlNode: IXMLNode);
  275. begin
  276. FID := AXmlNode.Attributes['ID'];
  277. FParentID := AXmlNode.Attributes['ParentID'];
  278. FNextSiblingID := AXmlNode.Attributes['NextSiblingID'];
  279. FCode := AXmlNode.Attributes['Code'];
  280. FB_Code := AXmlNode.Attributes['B_Code'];
  281. FName := AXmlNode.Attributes['Name'];
  282. FUnits := AXmlNode.Attributes['Units'];
  283. FPrice := AXmlNode.Attributes['Price'];
  284. FOrgQuantity := AXmlNode.Attributes['OrgQuantity'];
  285. FOrgTotalPrice := AXmlNode.Attributes['OrgTotalPrice'];
  286. FMisQuantity := AXmlNode.Attributes['MisQuantity'];
  287. FMisTotalPrice := AXmlNode.Attributes['MisTotalPrice'];
  288. FOthQuantity := AXmlNode.Attributes['OthQuantity'];
  289. FOthTotalPrice := AXmlNode.Attributes['OthTotalPrice'];
  290. FQuantity := AXmlNode.Attributes['Quantity'];
  291. FTotalPrice := AXmlNode.Attributes['TotalPrice'];
  292. FCalcType := AXmlNode.Attributes['CalcType'];
  293. FDrawingCode := AXmlNode.Attributes['DrawingCode'];
  294. FAlias := AXmlNode.Attributes['Alias'];
  295. FDgnQuantity1 := AXmlNode.Attributes['DgnQuantity1'];
  296. FDgnQuantity2 := AXmlNode.Attributes['DgnQuantity2'];
  297. FMemoStr := AXmlNode.Attributes['MemoStr'];
  298. FDealCode := AXmlNode.Attributes['DealCode'];
  299. FDealCompany := AXmlNode.Attributes['DealCompany'];
  300. end;
  301. procedure TBillsBlockNode.SaveToXmlNode(AXmlNode: IXMLNode);
  302. begin
  303. AXmlNode.Attributes['ID'] := FID;
  304. AXmlNode.Attributes['ParentID'] := FParentID;
  305. AXmlNode.Attributes['NextSiblingID'] := FNextSiblingID;
  306. AXmlNode.Attributes['Code'] := FCode;
  307. AXmlNode.Attributes['B_Code'] := FB_Code;
  308. AXmlNode.Attributes['Name'] := FName;
  309. AXmlNode.Attributes['Units'] := FUnits;
  310. AXmlNode.Attributes['Price'] := FPrice;
  311. AXmlNode.Attributes['OrgQuantity'] := FOrgQuantity;
  312. AXmlNode.Attributes['OrgTotalPrice'] := FOrgTotalPrice;
  313. AXmlNode.Attributes['MisQuantity'] := FMisQuantity;
  314. AXmlNode.Attributes['MisTotalPrice'] := FMisTotalPrice;
  315. AXmlNode.Attributes['OthQuantity'] := FOthQuantity;
  316. AXmlNode.Attributes['OthTotalPrice'] := FOthTotalPrice;
  317. AXmlNode.Attributes['Quantity'] := FQuantity;
  318. AXmlNode.Attributes['TotalPrice'] := FTotalPrice;
  319. AXmlNode.Attributes['CalcType'] := FCalcType;
  320. AXmlNode.Attributes['DrawingCode'] := FDrawingCode;
  321. AXmlNode.Attributes['Alias'] := FAlias;
  322. AXmlNode.Attributes['DgnQuantity1'] := FDgnQuantity1;
  323. AXmlNode.Attributes['DgnQuantity2'] := FDgnQuantity2;
  324. AXmlNode.Attributes['MemoStr'] := FMemoStr;
  325. AXmlNode.Attributes['DealCode'] := FDealCode;
  326. AXmlNode.Attributes['DealCompany'] := FDealCompany;
  327. end;
  328. initialization
  329. CF_BillsBlock := RegisterClipboardFormat('Zh.BillsBlock');
  330. end.