BGLClipboard.pas 11 KB

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