BGLClipboard.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. unit BGLClipboard;
  2. interface
  3. uses
  4. Classes, Clipbrd, BGLDm, ZhAPI, XmlDoc, XmlIntf, Windows, DB, SysUtils;
  5. Type
  6. TInnerClipboard = class(TClipboard);
  7. TBGBillsNode = class
  8. private
  9. FB_Code: string;
  10. FName: string;
  11. FUnits: string;
  12. FPrice: Double;
  13. FQuantity: Double;
  14. FTotalPrice: Double;
  15. public
  16. procedure SaveToXmlNode(AXmlNode: IXMLNode);
  17. procedure LoadFromXmlNode(AXmlNode: IXMLNode);
  18. property B_Code: string read FB_Code write FB_Code;
  19. property Name: string read FName write FName;
  20. property Units: string read FUnits write FUnits;
  21. property Price: Double read FPrice write FPrice;
  22. property Quantity: Double read FQuantity write FQuantity;
  23. property TotalPrice: Double read FTotalPrice write FTotalPrice;
  24. end;
  25. TBGLNode = class
  26. private
  27. FBGBills: TList;
  28. FCode: string;
  29. FName: string;
  30. FTotalPrice: Double;
  31. FPos_Reason: string;
  32. FDirection: string;
  33. FDrawingCode: string;
  34. FApprovalCode: string;
  35. public
  36. constructor Create;
  37. destructor Destroy; override;
  38. procedure SaveToXmlNode(AXmlNode: IXMLNode);
  39. procedure LoadFromXmlNode(AXmlNode: IXmlNode);
  40. end;
  41. TBGLClipboard = class
  42. private
  43. FStream: TMemoryStream;
  44. FBGLData: TBGLData;
  45. FBGLList: TList;
  46. procedure CopyBGBills(ABGL: TBGLNode; ABGLID: Integer);
  47. procedure CopyBGL;
  48. procedure CopyData(ACount: Integer);
  49. procedure SaveBGLsToXml(AXmlNode: IXMLNode);
  50. procedure SaveToStream;
  51. procedure SaveToClipboard(AFormat: Word);
  52. procedure PasteBGBills(ABGLID: Integer; ABGL: TBGLNode);
  53. function ValidBGLCode(ACode: string): string;
  54. procedure PasteBGL(ANewID: Integer; ABGL: TBGLNode);
  55. procedure PasteData;
  56. procedure LoadBGLsFromXml(AXmlNode: IXMLNode);
  57. procedure LoadFromStream;
  58. procedure LoadFromClipboard(AFormat: Word);
  59. procedure Clear;
  60. public
  61. constructor Create(ABGLData: TBGLData);
  62. destructor Destroy; override;
  63. procedure Copy(ACount: Integer);
  64. procedure Paste;
  65. end;
  66. function HasBGLBlockFormat: Boolean;
  67. implementation
  68. uses
  69. ProjectData;
  70. var
  71. CF_BGLBlock: Word;
  72. function HasBGLBlockFormat: Boolean;
  73. begin
  74. Result := Clipboard.HasFormat(CF_BGLBlock);
  75. end;
  76. { TBGBillsNode }
  77. procedure TBGBillsNode.LoadFromXmlNode(AXmlNode: IXMLNode);
  78. begin
  79. FB_Code := AXmlNode.Attributes['B_Code'];
  80. FName := AXmlNode.Attributes['Name'];
  81. FUnits := AXmlNode.Attributes['Units'];
  82. FPrice := AXmlNode.Attributes['Price'];
  83. FQuantity := AXmlNode.Attributes['Quantity'];
  84. FTotalPrice := AXmlNode.Attributes['TotalPrice'];
  85. end;
  86. procedure TBGBillsNode.SaveToXmlNode(AXmlNode: IXMLNode);
  87. begin
  88. AXmlNode.Attributes['B_Code'] := FB_Code;
  89. AXmlNode.Attributes['Name'] := FName;
  90. AXmlNode.Attributes['Units'] := FUnits;
  91. AXmlNode.Attributes['Price'] := FPrice;
  92. AXmlNode.Attributes['Quantity'] := FQuantity;
  93. AXmlNode.Attributes['TotalPrice'] := FTotalPrice;
  94. end;
  95. { TBGLNode }
  96. constructor TBGLNode.Create;
  97. begin
  98. FBGBills := TList.Create;
  99. end;
  100. destructor TBGLNode.Destroy;
  101. begin
  102. ClearObjects(FBGBills);
  103. FBGBills.Free;
  104. inherited;
  105. end;
  106. procedure TBGLNode.LoadFromXmlNode(AXmlNode: IXmlNode);
  107. var
  108. i: Integer;
  109. Child: IXMLNode;
  110. BGBill: TBGBillsNode;
  111. begin
  112. FCode := AXmlNode.Attributes['Code'];
  113. FName := AXmlNode.Attributes['Name'];
  114. FTotalPrice := AXmlNode.Attributes['TotalPrice'];
  115. FPos_Reason := AXmlNode.Attributes['Pos_Reason'];
  116. FDirection := AXmlNode.Attributes['Direction'];
  117. FDrawingCode := AXmlNode.Attributes['DrawingCode'];
  118. FApprovalCode := AXmlNode.Attributes['ApprovalCode'];
  119. for i := 0 to AXmlNode.ChildNodes.Count - 1 do
  120. begin
  121. Child := AXmlNode.ChildNodes.Nodes[i];
  122. BGBill := TBGBillsNode.Create;
  123. BGBill.LoadFromXmlNode(Child);
  124. FBGBills.Add(BGBill);
  125. end;
  126. end;
  127. procedure TBGLNode.SaveToXmlNode(AXmlNode: IXMLNode);
  128. var
  129. i: Integer;
  130. begin
  131. AXmlNode.Attributes['Code'] := FCode;
  132. AXmlNode.Attributes['Name'] := FName;
  133. AXmlNode.Attributes['TotalPrice'] := FTotalPrice;
  134. AXmlNode.Attributes['Pos_Reason'] := FPos_Reason;
  135. AXmlNode.Attributes['Direction'] := FDirection;
  136. AXmlNode.Attributes['DrawingCode'] := FDrawingCode;
  137. AXmlNode.Attributes['ApprovalCode'] := FApprovalCode;
  138. for i:= 0 to FBGBills.Count - 1 do
  139. TBGBillsNode(FBGBills.Items[i]).SaveToXmlNode(AXmlNode.AddChild('BGBill'));
  140. end;
  141. { TBGLClipboard }
  142. procedure TBGLClipboard.Clear;
  143. begin
  144. ClearObjects(FBGLList);
  145. FBGLList.Clear;
  146. end;
  147. procedure TBGLClipboard.Copy(ACount: Integer);
  148. begin
  149. Clear;
  150. CopyData(ACount);
  151. SaveToStream;
  152. SaveToClipboard(CF_BGLBlock);
  153. end;
  154. procedure TBGLClipboard.CopyBGBills(ABGL: TBGLNode; ABGLID: Integer);
  155. var
  156. BGBill: TBGBillsNode;
  157. begin
  158. with FBGLData do
  159. begin
  160. cdsBGBills.Filter := Format('BGID = %d', [ABGLID]);
  161. cdsBGBills.Filtered := True;
  162. try
  163. if cdsBGBills.RecordCount = 0 then Exit;
  164. cdsBGBills.First;
  165. while not cdsBGBills.Eof do
  166. begin
  167. BGBill := TBGBillsNode.Create;
  168. ABGL.FBGBills.Add(BGBill);
  169. BGBill.FB_Code := cdsBGBillsB_Code.AsString;
  170. BGBill.FName := cdsBGBillsName.AsString;
  171. BGBill.FUnits := cdsBGBillsUnits.AsString;
  172. BGBill.FPrice := cdsBGBillsPrice.AsFloat;
  173. BGBill.FQuantity := cdsBGBillsQuantity.AsFloat;
  174. BGBill.FTotalPrice := cdsBGBillsTotalPrice.AsFloat;
  175. cdsBGBills.Next;
  176. end;
  177. finally
  178. cdsBGBills.Filtered := False;
  179. end;
  180. end;
  181. end;
  182. procedure TBGLClipboard.CopyBGL;
  183. var
  184. vBGL: TBGLNode;
  185. begin
  186. vBGL := TBGLNode.Create;
  187. FBGLList.Add(vBGL);
  188. vBGL.FCode := FBGLData.cdsBGLViewCode.AsString;
  189. vBGL.FName := FBGLData.cdsBGLViewName.AsString;
  190. vBGL.FTotalPrice := FBGLData.cdsBGLViewTotalPrice.AsFloat;
  191. vBGL.FPos_Reason := FBGLData.cdsBGLViewPos_Reason.AsString;
  192. vBGL.FDirection := FBGLData.cdsBGLViewDirection.AsString;
  193. vBGL.FDrawingCode := FBGLData.cdsBGLViewDrawingCode.AsString;
  194. vBGL.FApprovalCode := FBGLData.cdsBGLViewApprovalCode.AsString;
  195. CopyBGBills(vBGL, FBGLData.cdsBGLViewID.AsInteger);
  196. end;
  197. procedure TBGLClipboard.CopyData(ACount: Integer);
  198. var
  199. iCount: Integer;
  200. vBM: TBookmark;
  201. begin
  202. FBGLData.cdsBGLView.DisableControls;
  203. vBM := FBGLData.cdsBGLView.GetBookmark;
  204. try
  205. iCount := 0;
  206. while iCount < ACount do
  207. begin
  208. CopyBGL;
  209. FBGLData.cdsBGLView.Next;
  210. Inc(iCount);
  211. end;
  212. finally
  213. FBGLData.cdsBGLView.GotoBookmark(vBM);
  214. FBGLData.cdsBGLView.FreeBookmark(vBM);
  215. FBGLData.cdsBGLView.EnableControls;
  216. end;
  217. end;
  218. constructor TBGLClipboard.Create(ABGLData: TBGLData);
  219. begin
  220. FStream := TMemoryStream.Create;
  221. FBGLData := ABGLData;
  222. FBGLList := TList.Create;
  223. end;
  224. destructor TBGLClipboard.Destroy;
  225. begin
  226. Clear;
  227. FBGLList.Free;
  228. FStream.Free;
  229. inherited;
  230. end;
  231. procedure TBGLClipboard.LoadBGLsFromXml(AXmlNode: IXMLNode);
  232. var
  233. vBGL: TBGLNode;
  234. iNum: Integer;
  235. ParentXmlNode, CurXmlNode: IXMLNode;
  236. begin
  237. ParentXmlNode := AXmlNode.ChildNodes.FindNode('BGLBlockNodes');
  238. for iNum := 0 to ParentXmlNode.ChildNodes.Count - 1 do
  239. begin
  240. CurXmlNode := ParentXmlNode.ChildNodes.Nodes[iNum];
  241. vBGL := TBGLNode.Create;
  242. FBGLList.Add(vBGL);
  243. vBGL.LoadFromXmlNode(CurXmlNode);
  244. end;
  245. end;
  246. procedure TBGLClipboard.LoadFromClipboard(AFormat: Word);
  247. procedure LockAndLoadData(AData: THandle);
  248. var
  249. DataPtr: Pointer;
  250. begin
  251. DataPtr := GlobalLock(AData);
  252. try
  253. FStream.WriteBuffer(DataPtr^, GlobalSize(AData));
  254. FStream.Position := 0;
  255. finally
  256. GlobalUnlock(AData);
  257. end;
  258. end;
  259. var
  260. Data: THandle;
  261. begin
  262. Clipboard.Open;
  263. try
  264. Data := GetClipboardData(AFormat);
  265. if Data <> 0 then
  266. LockAndLoadData(Data);
  267. finally
  268. Clipboard.Close;
  269. end;
  270. end;
  271. procedure TBGLClipboard.LoadFromStream;
  272. var
  273. FXmlDocument: IXMLDocument;
  274. I: Integer;
  275. begin
  276. FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
  277. try
  278. FXmlDocument.LoadFromStream(FStream);
  279. FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAutoPrefix,doNamespaceDecl];
  280. LoadBGLsFromXml(FXmlDocument.DocumentElement);
  281. finally
  282. FXmlDocument := nil;
  283. end;
  284. end;
  285. procedure TBGLClipboard.Paste;
  286. begin
  287. Clear;
  288. LoadFromClipboard(CF_BGLBlock);
  289. LoadFromStream;
  290. PasteData;
  291. end;
  292. procedure TBGLClipboard.PasteBGBills(ABGLID: Integer; ABGL: TBGLNode);
  293. var
  294. i, iNewID: Integer;
  295. vBGBills: TBGBillsNode;
  296. begin
  297. with FBGLData do
  298. begin
  299. iNewID := GetNewIDOfIndex(cdsBGBills);
  300. for i := 0 to ABGL.FBGBills.Count - 1 do
  301. begin
  302. vBGBills := TBGBillsNode(ABGL.FBGBills.Items[i]);
  303. cdsBGBills.Append;
  304. cdsBGBillsID.AsInteger := iNewID+i;
  305. cdsBGBillsBGID.AsInteger := ABGLID;
  306. cdsBGBillsB_Code.AsString := vBGBills.FB_Code;
  307. cdsBGBillsName.AsString := vBGBills.FName;
  308. cdsBGBillsUnits.AsString := vBGBills.FUnits;
  309. cdsBGBillsPrice.AsFloat := vBGBills.FPrice;
  310. cdsBGBillsQuantity.AsFloat := vBGBills.FQuantity;
  311. cdsBGBillsTotalPrice.AsFloat := vBGBills.FTotalPrice;
  312. cdsBGBills.Post;
  313. end;
  314. end;
  315. end;
  316. procedure TBGLClipboard.PasteBGL(ANewID: Integer; ABGL: TBGLNode);
  317. var
  318. sNewCode: string;
  319. begin
  320. sNewCode := ValidBGLCode(ABGL.FCode);
  321. with FBGLData do
  322. begin
  323. cdsBGL.Append;
  324. cdsBGLID.AsInteger := ANewID;
  325. cdsBGLTotalPrice.AsFloat := ABGL.FTotalPrice;
  326. cdsBGLCode.AsString := sNewCode;
  327. cdsBGLName.AsString := ABGL.FName;
  328. cdsBGLPos_Reason.AsString := ABGL.FPos_Reason;
  329. cdsBGLDirection.AsString := ABGL.FDirection;
  330. cdsBGLDrawingCode.AsString := ABGL.FDrawingCode;
  331. cdsBGLApprovalCode.AsString := ABGL.FApprovalCode;
  332. cdsBGLCreatePhaseID.AsInteger := TProjectData(ProjectData).ProjProperties.PhaseCount;
  333. cdsBGL.Post;
  334. PasteBGBills(ANewID, ABGL);
  335. end;
  336. end;
  337. procedure TBGLClipboard.PasteData;
  338. var
  339. vBGL: TBGLNode;
  340. iNewID, iIndex: Integer;
  341. begin
  342. iNewID := GetNewIDOfIndex(FBGLData.cdsBGL);
  343. FBGLData.cdsBGLView.DisableControls;
  344. try
  345. for iIndex := 0 to FBGLList.Count - 1 do
  346. PasteBGL(iNewID+iIndex, TBGLNode(FBGLList.Items[iIndex]));
  347. finally
  348. FBGLData.cdsBGLView.EnableControls;
  349. end;
  350. end;
  351. procedure TBGLClipboard.SaveBGLsToXml(AXmlNode: IXMLNode);
  352. var
  353. ParentXmlNode, CurXmlNode: IXMLNode;
  354. iNum: Integer;
  355. vBGL: TBGLNode;
  356. begin
  357. ParentXmlNode := AXmlNode.AddChild('BGLBlockNodes');
  358. for iNum := 0 to FBGLList.Count - 1 do
  359. begin
  360. vBGL := TBGLNode(FBGLList.Items[iNum]);
  361. CurXmlNode := ParentXmlNode.AddChild('BGLNode');
  362. vBGL.SaveToXmlNode(CurXmlNode);
  363. end;
  364. end;
  365. procedure TBGLClipboard.SaveToClipboard(AFormat: Word);
  366. begin
  367. Clipboard.Open;
  368. try
  369. EmptyClipboard;
  370. FStream.Position := 0;
  371. TInnerClipboard(Clipboard).SetBuffer(AFormat, FStream.Memory^, FStream.Size);
  372. finally
  373. Clipboard.Close;
  374. end;
  375. end;
  376. procedure TBGLClipboard.SaveToStream;
  377. var
  378. FXmlDocument: IXMLDocument;
  379. I: Integer;
  380. begin
  381. FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
  382. try
  383. FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAttrNull,doAutoPrefix,doNamespaceDecl];
  384. FXmlDocument.Active := True;
  385. FXmlDocument.Encoding := 'GB2312';
  386. FXmlDocument.AddChild('BGLBlock_M');
  387. SaveBGLsToXml(FXmlDocument.DocumentElement);
  388. FXmlDocument.SaveToStream(FStream);
  389. finally
  390. FXmlDocument := nil;
  391. end;
  392. end;
  393. function TBGLClipboard.ValidBGLCode(ACode: string): string;
  394. var
  395. iIncrement: Integer;
  396. begin
  397. Result := ACode;
  398. iIncrement := 1;
  399. while FBGLData.cdsBGL.Locate('Code', Result, []) do
  400. begin
  401. Result := Format('%s[%d]', [ACode, iIncrement]);
  402. Inc(iIncrement);
  403. end;
  404. end;
  405. initialization
  406. CF_BGLBlock := RegisterClipboardFormat('Zh.BGLBlock');
  407. end.