QBuilder.pas 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489
  1. {*******************************************************}
  2. { }
  3. { Delphi Visual Component Library }
  4. { QBuilder dialog component }
  5. { }
  6. { Copyright (c) 1996-2003 Sergey Orlik }
  7. { }
  8. { Written by: }
  9. { Sergey Orlik }
  10. { product manager }
  11. { Russia, C.I.S. and Baltic States (former USSR) }
  12. { Borland Moscow office }
  13. { Internet: [email protected], }
  14. { [email protected] }
  15. { http://www.fast-report.com }
  16. { }
  17. { Converted to Lazarus/Free Pascal by Jean Patrick }
  18. { Data: 14/02/2013 }
  19. { E-mail: [email protected] }
  20. { }
  21. { Modifications by Reinier Olislagers, 2014 }
  22. {*******************************************************}
  23. unit QBuilder;
  24. {$IFDEF FPC}
  25. {$MODE Delphi}
  26. {$ENDIF}
  27. interface
  28. uses
  29. SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  30. Buttons, ExtCtrls, StdCtrls, ComCtrls, Menus, CheckLst, Grids,
  31. DB, DBGrids, LMessages, LCLIntf, LCLType, LCLProc,
  32. GraphType, InterfaceBase;
  33. type
  34. TOQBbutton = (bSelectDBDialog, bOpenDialog, bSaveDialog,
  35. bRunQuery, bSaveResultsDialog);
  36. TOQBbuttons = set of TOQBbutton;
  37. TOQBEngine = class;
  38. { TOQBuilderDialog }
  39. TOQBuilderDialog = class(TComponent)
  40. private
  41. FDatabase: string;
  42. FSystemTables: Boolean;
  43. FOQBForm: TForm;
  44. FSQL: TStrings;
  45. FOQBEngine: TOQBEngine;
  46. FShowButtons: TOQBbuttons;
  47. procedure SetOQBEngine(const Value: TOQBEngine);
  48. protected
  49. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  50. public
  51. constructor Create(AOwner: TComponent); override;
  52. destructor Destroy; override;
  53. function Execute: Boolean; virtual;
  54. property SQL: TStrings read FSQL;
  55. property SystemTables: Boolean read FSystemTables write FSystemTables default False;
  56. property Database: string read FDatabase write FDatabase;
  57. published
  58. property OQBEngine: TOQBEngine read FOQBEngine write SetOQBEngine;
  59. property ShowButtons: TOQBbuttons read FShowButtons write FShowButtons
  60. default [bSelectDBDialog, bOpenDialog, bSaveDialog, bRunQuery, bSaveResultsDialog];
  61. end;
  62. TOQBEngine = class(TComponent)
  63. private
  64. FDatabaseName: string;
  65. FUserName: string;
  66. FPassword: string;
  67. FShowSystemTables: Boolean;
  68. FTableList: TStringList;
  69. FAliasList: TStringList;
  70. FFieldList: TStringList;
  71. FSQL: TStringList;
  72. FSQLcolumns: TStringList;
  73. FSQLcolumns_table: TStringList;
  74. FSQLcolumns_func: TStringList;
  75. FSQLfrom: TStringList;
  76. FSQLwhere: TStringList;
  77. FSQLgroupby: TStringList;
  78. FSQLorderby: TStringList;
  79. FUseTableAliases: Boolean;
  80. FOQBDialog: TOQBuilderDialog;
  81. procedure SetShowSystemTables(const Value: Boolean);
  82. protected
  83. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  84. procedure SetDatabaseName(const Value: string); virtual;
  85. procedure SetUserName(const Value: string); virtual;
  86. procedure SetPassword(const Value: string); virtual;
  87. procedure SetQuerySQL(const Value: string); virtual; abstract;
  88. procedure GenerateAliases; virtual;
  89. // Read list of tables (system tables etc) into FTableList
  90. procedure ReadTableList; virtual; abstract;
  91. procedure ReadFieldList(const ATableName: string); virtual; abstract;
  92. public
  93. constructor Create(AOwner: TComponent); override;
  94. destructor Destroy; override;
  95. function SelectDatabase: Boolean; virtual; abstract;
  96. function GenerateSQL: string; virtual;
  97. procedure ClearQuerySQL; virtual; abstract;
  98. function ResultQuery: TDataSet; virtual; abstract;
  99. procedure OpenResultQuery; virtual; abstract;
  100. procedure CloseResultQuery; virtual; abstract;
  101. procedure SaveResultQueryData; virtual; abstract;
  102. // All tables in the database
  103. property TableList: TStringList read FTableList;
  104. property AliasList: TStringList read FAliasList;
  105. property FieldList: TStringList read FFieldList;
  106. property SQL: TStringList read FSQL;
  107. property SQLcolumns: TStringList read FSQLcolumns;
  108. property SQLcolumns_table: TStringList read FSQLcolumns_table;
  109. property SQLcolumns_func: TStringList read FSQLcolumns_func;
  110. property SQLfrom: TStringList read FSQLfrom;
  111. property SQLwhere: TStringList read FSQLwhere;
  112. property SQLgroupby: TStringList read FSQLgroupby;
  113. property SQLorderby: TStringList read FSQLorderby;
  114. property UserName: string read FUserName write SetUserName;
  115. property Password: string read FPassword write SetPassword;
  116. published
  117. property DatabaseName: string read FDatabaseName write SetDatabaseName;
  118. property ShowSystemTables: Boolean read FShowSystemTables write SetShowSystemTables default False;
  119. property UseTableAliases: Boolean read FUseTableAliases write FUseTableAliases default True;
  120. end;
  121. type
  122. TArr = array [0..0] of Integer;
  123. PArr = ^TArr;
  124. { TOQBLbx }
  125. TOQBLbx = class(TCheckListBox)
  126. private
  127. FArrBold: PArr;
  128. FLoading: Boolean;
  129. // procedure CNDrawItem(var Message: TWMDrawItem); message CN_DrawItem;
  130. procedure WMLButtonDown(var Message: TLMLButtonDblClk); message LM_LBUTTONDOWN;
  131. procedure WMRButtonDown(var Message: TLMRButtonDblClk); message LM_RBUTTONDOWN;
  132. function GetCheckW: Integer;
  133. procedure AllocArrBold;
  134. procedure SelectItemBold(Item: Integer);
  135. procedure UnSelectItemBold(Item: Integer);
  136. function GetItemY(Item: Integer): Integer;
  137. public
  138. constructor Create(AOwner: TComponent); override;
  139. destructor Destroy; override;
  140. // procedure ClickCheck; override;
  141. procedure ItemClick(const AIndex: Integer); override;
  142. end;
  143. TOQBTable = class(TPanel)
  144. private
  145. ScreenDC: HDC;
  146. OldX: Integer;
  147. OldY: Integer;
  148. OldLeft: Integer;
  149. OldTop: Integer;
  150. ClipRgn: HRGN;
  151. ClipRect: TRect;
  152. MoveRect: TRect;
  153. Moving: Boolean;
  154. FCloseBtn: TSpeedButton;
  155. FUnlinkBtn: TSpeedButton;
  156. FLbx: TOQBLbx;
  157. FTableName: string;
  158. FTableAlias: string;
  159. PopMenu: TPopupMenu;
  160. procedure WMRButtonDown(var Message: TLMRButtonDblClk); message LM_RBUTTONDOWN;
  161. function Activate(const ATableName: string; X, Y: Integer): Boolean;
  162. function GetRowY(FldN: Integer):Integer;
  163. procedure _CloseBtn(Sender: TObject);
  164. procedure _UnlinkBtn(Sender: TObject);
  165. procedure _SelectAll(Sender: TObject);
  166. procedure _UnSelectAll(Sender: TObject);
  167. procedure _DragOver(Sender, Source: TObject; X, Y: Integer;
  168. State: TDragState; var Accept: Boolean);
  169. procedure _DragDrop(Sender, Source: TObject; X, Y: Integer);
  170. protected
  171. procedure SetParent(AParent: TWinControl); override;
  172. procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  173. X, Y: Integer); override;
  174. procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  175. procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  176. X, Y: Integer); override;
  177. property Align;
  178. public
  179. constructor Create(AOwner: TComponent); override;
  180. procedure Paint; override;
  181. end;
  182. { TOQBLink }
  183. TOQBLink = class(TShape)
  184. private
  185. Tbl1: TOQBTable;
  186. Tbl2: TOQBTable;
  187. FldN1: Integer;
  188. FldN2: Integer;
  189. FldNam1: string;
  190. FldNam2: string;
  191. FLinkOpt: Integer;
  192. FLinkType: Integer;
  193. LnkX: Byte;
  194. LnkY: Byte;
  195. Rgn: HRgn;
  196. PopMenu: TPopupMenu;
  197. procedure _Click(X, Y: Integer);
  198. procedure CMHitTest(var Message: TCMHitTest); message CM_HitTest;
  199. function ControlAtPos(const Pos: TPoint): TControl;
  200. function PtInRegion(RGN: HRGN; X, Y: Integer) : Boolean;
  201. public
  202. constructor Create(AOwner: TComponent); override;
  203. destructor Destroy; override;
  204. procedure WndProc(var Message: TLMessage); override;
  205. procedure Paint; override;
  206. end;
  207. TOQBArea = class(TScrollBox)
  208. public
  209. procedure CreateParams(var Params: TCreateParams); override;
  210. procedure SetOptions(Sender: TObject);
  211. procedure InsertTable(X, Y: Integer);
  212. function InsertLink(_tbl1, _tbl2: TOQBTable; _fldN1, _fldN2: Integer): TOQBLink;
  213. function FindTable(const TableName: string): TOQBTable;
  214. function FindLink(Link: TOQBLink): Boolean;
  215. function FindOtherLink(Link: TOQBLink; Tbl: TOQBTable; FldN: Integer): Boolean;
  216. procedure ReboundLink(Link: TOQBLink);
  217. procedure ReboundLinks4Table(ATable: TOQBTable);
  218. procedure Unlink(Sender: TObject);
  219. procedure UnlinkTable(ATable: TOQBTable);
  220. procedure _DragOver(Sender, Source: TObject; X, Y: Integer;
  221. State: TDragState; var Accept: Boolean);
  222. procedure _DragDrop(Sender, Source: TObject; X, Y: Integer);
  223. end;
  224. TOQBGrid = class(TStringGrid)
  225. public
  226. CurrCol: Integer;
  227. IsEmpty: Boolean;
  228. procedure CreateParams(var Params: TCreateParams); override;
  229. procedure WndProc(var Message: TLMessage); override;
  230. function MaxSW(const s1, s2: string): Integer;
  231. procedure InsertDefault(aCol: Integer);
  232. procedure Insert(aCol: Integer; const aField, aTable: string);
  233. function FindColumn(const sCol: string): Integer;
  234. function FindSameColumn(aCol: Integer): Boolean;
  235. procedure RemoveColumn(aCol: Integer);
  236. procedure RemoveColumn4Tbl(const Tbl: string);
  237. procedure ClickCell(X, Y: Integer);
  238. function SelectCell(ACol, ARow: Integer): Boolean; override;
  239. procedure _DragOver(Sender, Source: TObject; X, Y: Integer;
  240. State: TDragState; var Accept: Boolean);
  241. procedure _DragDrop(Sender, Source: TObject; X, Y: Integer);
  242. end;
  243. TOQBForm = class(TForm)
  244. QBPanel: TPanel;
  245. Pages: TPageControl;
  246. TabColumns: TTabSheet;
  247. QBTables: TListBox;
  248. VSplitter: TSplitter;
  249. mnuTbl: TPopupMenu;
  250. Remove1: TMenuItem;
  251. mnuFunc: TPopupMenu;
  252. Nofunction1: TMenuItem;
  253. N1: TMenuItem;
  254. Average1: TMenuItem;
  255. Count1: TMenuItem;
  256. Minimum1: TMenuItem;
  257. Maximum1: TMenuItem;
  258. Sum1: TMenuItem;
  259. mnuGroup: TPopupMenu;
  260. Group1: TMenuItem;
  261. mnuSort: TPopupMenu;
  262. Sort1: TMenuItem;
  263. N2: TMenuItem;
  264. Ascending1: TMenuItem;
  265. Descending1: TMenuItem;
  266. mnuShow: TPopupMenu;
  267. Show1: TMenuItem;
  268. HSplitter: TSplitter;
  269. TabSQL: TTabSheet;
  270. MemoSQL: TMemo;
  271. TabResults: TTabSheet;
  272. ResDBGrid: TDBGrid;
  273. ResDataSource: TDataSource;
  274. QBBar: TToolBar;
  275. btnNew: TToolButton;
  276. btnOpen: TToolButton;
  277. btnSave: TToolButton;
  278. ToolButton1: TToolButton;
  279. btnTables: TToolButton;
  280. ToolImages: TImageList;
  281. btnPages: TToolButton;
  282. ToolButton2: TToolButton;
  283. DlgSave: TSaveDialog;
  284. DlgOpen: TOpenDialog;
  285. btnDB: TToolButton;
  286. btnSQL: TToolButton;
  287. btnResults: TToolButton;
  288. ToolButton3: TToolButton;
  289. btnAbout: TToolButton;
  290. btnSaveResults: TToolButton;
  291. btnOK: TToolButton;
  292. btnCancel: TToolButton;
  293. ToolButton6: TToolButton;
  294. procedure mnuFunctionClick(Sender: TObject);
  295. procedure mnuGroupClick(Sender: TObject);
  296. procedure mnuRemoveClick(Sender: TObject);
  297. procedure mnuShowClick(Sender: TObject);
  298. procedure mnuSortClick(Sender: TObject);
  299. procedure btnNewClick(Sender: TObject);
  300. procedure btnOpenClick(Sender: TObject);
  301. procedure btnSaveClick(Sender: TObject);
  302. procedure btnTablesClick(Sender: TObject);
  303. procedure btnPagesClick(Sender: TObject);
  304. procedure btnDBClick(Sender: TObject);
  305. procedure btnSQLClick(Sender: TObject);
  306. procedure btnResultsClick(Sender: TObject);
  307. procedure btnAboutClick(Sender: TObject);
  308. procedure btnSaveResultsClick(Sender: TObject);
  309. procedure btnOKClick(Sender: TObject);
  310. procedure btnCancelClick(Sender: TObject);
  311. protected
  312. QBDialog: TOQBuilderDialog;
  313. QBArea: TOQBArea;
  314. QBGrid: TOQBGrid;
  315. procedure CreateParams(var Params: TCreateParams); override;
  316. procedure ClearAll;
  317. procedure OpenDatabase;
  318. procedure SelectDatabase;
  319. end;
  320. implementation
  321. {$R QBBUTTON.RES}
  322. uses
  323. QBLnkFrm, QBAbout;
  324. {$R *.lfm}
  325. resourcestring
  326. sMainCaption = 'QBuilder';
  327. sNotValidTableParent = 'Parent must be TScrollBox or its descendant.';
  328. const
  329. cFld = 0;
  330. cTbl = 1;
  331. cShow = 2;
  332. cSort = 3;
  333. cFunc = 4;
  334. cGroup = 5;
  335. sShow = 'Show';
  336. sGroup = 'Group';
  337. sSort: array [1..3] of string =
  338. ('',
  339. 'Asc',
  340. 'Desc');
  341. sFunc: array [1..6] of string =
  342. ('',
  343. 'Avg',
  344. 'Count',
  345. 'Max',
  346. 'Min',
  347. 'Sum');
  348. sLinkOpt: array [0..5] of string =
  349. ('=',
  350. '<',
  351. '>',
  352. '=<',
  353. '=>',
  354. '<>');
  355. sOuterJoin: array [1..3] of string =
  356. (' LEFT OUTER JOIN ',
  357. ' RIGHT OUTER JOIN ',
  358. ' FULL OUTER JOIN ');
  359. Hand = 15;
  360. Hand2 = 12;
  361. QBSignature = '# QBuilder';
  362. { TQueryBuilderDialog}
  363. constructor TOQBuilderDialog.Create(AOwner: TComponent);
  364. begin
  365. inherited;
  366. FSystemTables := False;
  367. FShowButtons := [bSelectDBDialog, bOpenDialog, bSaveDialog,
  368. bRunQuery, bSaveResultsDialog];
  369. FSQL := TStringList.Create;
  370. end;
  371. destructor TOQBuilderDialog.Destroy;
  372. begin
  373. if FSQL <> nil then
  374. FSQL.Free;
  375. FOQBEngine := nil;
  376. inherited;
  377. end;
  378. function TOQBuilderDialog.Execute: Boolean;
  379. begin
  380. Result := False;
  381. if (not Assigned(FOQBForm)) and Assigned((FOQBEngine)) then
  382. begin
  383. TOQBForm(FOQBForm) := TOQBForm.Create(Application);
  384. TOQBForm(FOQBForm).QBDialog := Self;
  385. TOQBForm(FOQBForm).btnDB.Visible := bSelectDBDialog in FShowButtons;
  386. TOQBForm(FOQBForm).btnOpen.Visible := bOpenDialog in FShowButtons;
  387. TOQBForm(FOQBForm).btnSave.Visible := bSaveDialog in FShowButtons;
  388. TOQBForm(FOQBForm).btnResults.Visible := bRunQuery in FShowButtons;
  389. TOQBForm(FOQBForm).btnSaveResults.Visible := bSaveResultsDialog in FShowButtons;
  390. if OQBEngine.DatabaseName <> EmptyStr then
  391. TOQBForm(FOQBForm).OpenDatabase else
  392. TOQBForm(FOQBForm).SelectDatabase;
  393. if TOQBForm(FOQBForm).ShowModal = mrOk then
  394. begin
  395. FSQL.Assign(TOQBForm(FOQBForm).MemoSQL.Lines);
  396. Result := True;
  397. end;
  398. OQBEngine.CloseResultQuery;
  399. FOQBForm.Free;
  400. FOQBForm := nil;
  401. end;
  402. end;
  403. procedure TOQBuilderDialog.Notification(AComponent: TComponent;
  404. Operation: TOperation);
  405. begin
  406. inherited;
  407. if (AComponent = FOQBEngine) and (Operation = opRemove) then
  408. FOQBEngine := nil;
  409. end;
  410. procedure TOQBuilderDialog.SetOQBEngine(const Value: TOQBEngine);
  411. begin
  412. if FOQBEngine <> nil then
  413. FOQBEngine.FOQBDialog := nil;
  414. FOQBEngine := Value;
  415. if FOQBEngine <> nil then
  416. begin
  417. FOQBEngine.FOQBDialog := Self;
  418. FOQBEngine.FreeNotification(Self);
  419. end;
  420. end;
  421. { TOQBEngine }
  422. constructor TOQBEngine.Create(AOwner: TComponent);
  423. begin
  424. inherited;
  425. FShowSystemTables := False;
  426. FTableList := TStringList.Create;
  427. FAliasList := TStringList.Create;
  428. FFieldList := TStringList.Create;
  429. FSQL := TStringList.Create;
  430. FSQLcolumns := TStringList.Create;
  431. FSQLcolumns_table := TStringList.Create;
  432. FSQLcolumns_func := TStringList.Create;
  433. FSQLfrom := TStringList.Create;
  434. FSQLwhere := TStringList.Create;
  435. FSQLgroupby := TStringList.Create;
  436. FSQLorderby := TStringList.Create;
  437. FUseTableAliases := True;
  438. end;
  439. destructor TOQBEngine.Destroy;
  440. begin
  441. FSQL.Free;
  442. FSQLcolumns.Free;
  443. FSQLcolumns_table.Free;
  444. FSQLcolumns_func.Free;
  445. FSQLfrom.Free;
  446. FSQLwhere.Free;
  447. FSQLgroupby.Free;
  448. FSQLorderby.Free;
  449. FFieldList.Free;
  450. FAliasList.Free;
  451. FTableList.Free;
  452. FreeNotification(Self);
  453. inherited;
  454. end;
  455. procedure TOQBEngine.Notification(AComponent: TComponent;
  456. Operation: TOperation);
  457. begin
  458. inherited;
  459. if (AComponent = FOQBDialog) and (Operation = opRemove) then
  460. FOQBDialog := nil;
  461. end;
  462. procedure TOQBEngine.SetDatabaseName(const Value: string);
  463. begin
  464. TableList.Clear;
  465. FDatabaseName := Value;
  466. if ResultQuery.Active then
  467. ResultQuery.Close;
  468. end;
  469. procedure TOQBEngine.SetUserName(const Value: string);
  470. begin
  471. FUserName := Value;
  472. end;
  473. procedure TOQBEngine.SetPassword(const Value: string);
  474. begin
  475. FPassword := Value;
  476. end;
  477. procedure TOQBEngine.SetShowSystemTables(const Value: Boolean);
  478. begin
  479. if FShowSystemTables <> Value then
  480. FShowSystemTables := Value;
  481. end;
  482. procedure TOQBEngine.GenerateAliases;
  483. var
  484. i, j: Integer;
  485. s, s1: string;
  486. begin
  487. FAliasList.Clear;
  488. for i := 0 to FTableList.Count - 1 do
  489. begin
  490. s := ' ';
  491. s[1] := FTableList[i][1]; // get the first character [1] of the table name [i]
  492. if FAliasList.IndexOf(s) = -1 then
  493. FAliasList.Add(s)
  494. else
  495. begin
  496. j := 1;
  497. repeat
  498. Inc(j);
  499. s1 := s + IntToStr(j);
  500. until FAliasList.IndexOf(s1) = -1;
  501. FAliasList.Add(s1);
  502. end;
  503. end;
  504. end;
  505. function TOQBEngine.GenerateSQL: string;
  506. var
  507. s: string;
  508. i: Integer;
  509. begin
  510. SQL.Clear;
  511. s := 'SELECT ';
  512. for i := 0 to SQLcolumns.Count - 1 do
  513. begin
  514. if SQLcolumns_func[i] = EmptyStr then
  515. s := s + SQLcolumns[i] else
  516. s := s + SQLcolumns_func[i] + '(' + SQLcolumns[i] + ')';
  517. if (i < SQLcolumns.Count - 1) then
  518. s := s + ', ';
  519. if (Length(s) > 70) or (i = SQLcolumns.Count - 1) then
  520. begin
  521. SQL.Add(s);
  522. s := ' ';
  523. end;
  524. end;
  525. s := 'FROM ';
  526. for i := 0 to SQLfrom.Count - 1 do
  527. begin
  528. s := s + SQLfrom[i];
  529. if (i < SQLfrom.Count - 1) then
  530. s := s + ', ';
  531. if (Length(s) > 70) or (i = SQLfrom.Count - 1) then
  532. begin
  533. SQL.Add(s);
  534. s := ' ';
  535. end;
  536. end;
  537. s := 'WHERE ';
  538. for i := 0 to SQLwhere.Count - 1 do
  539. begin
  540. if (i < SQLwhere.Count - 1) then
  541. s := s + SQLwhere[i] + ' AND ' else
  542. s := s + SQLwhere[i];
  543. if (Length(s) > 70) or (i = SQLwhere.Count - 1) then
  544. begin
  545. SQL.Add(s);
  546. s := ' ';
  547. end;
  548. end;
  549. s := 'GROUP BY ';
  550. for i := 0 to SQLgroupby.Count - 1 do
  551. begin
  552. if (i < SQLgroupby.Count - 1) then
  553. s := s + SQLgroupby[i] + ', ' else
  554. s := s + SQLgroupby[i];
  555. if (Length(s) > 70) or (i = SQLgroupby.Count - 1) then
  556. begin
  557. SQL.Add(s);
  558. s := ' ';
  559. end;
  560. end;
  561. s := 'ORDER BY ';
  562. for i := 0 to SQLorderby.Count - 1 do
  563. begin
  564. if (i < SQLorderby.Count - 1) then
  565. s := s + SQLorderby[i] + ', ' else
  566. s := s + SQLorderby[i];
  567. if (Length(s) > 70) or (i = SQLorderby.Count - 1) then
  568. begin
  569. SQL.Add(s);
  570. s := ' ';
  571. end;
  572. end;
  573. Result := SQL.Text;
  574. end;
  575. { TOQBLbx }
  576. constructor TOQBLbx.Create(AOwner: TComponent);
  577. begin
  578. inherited;
  579. Style := lbStandard;
  580. ParentFont := False;
  581. Font.Style := [];
  582. Font.Size := 8;
  583. FArrBold := nil;
  584. FLoading := False;
  585. end;
  586. destructor TOQBLbx.Destroy;
  587. begin
  588. if FArrBold <> nil then
  589. FreeMem(FArrBold);
  590. inherited;
  591. end;
  592. function TOQBLbx.GetCheckW: Integer;
  593. begin
  594. Result := GetCheckW;
  595. end;
  596. {procedure TOQBLbx.CNDrawItem(var Message: TWMDrawItem);
  597. begin
  598. with Message.DrawItemStruct^ do
  599. begin
  600. rcItem.Left := rcItem.Left + GetCheckW; //*** check
  601. Canvas.Font := Font;
  602. Canvas.Brush := Brush;
  603. if (Integer(itemID) >= 0) and (Integer(itemID) <= Items.Count - 1) then
  604. begin
  605. if (FArrBold <> nil) then
  606. if FArrBold^[Integer(itemID)] = 1 then
  607. Canvas.Font.Style := [fsBold];
  608. DrawItem(itemID, rcItem, []);
  609. if (FArrBold <> nil) then
  610. if FArrBold^[Integer(itemID)] = 1 then
  611. Canvas.Font.Style := [];
  612. end
  613. else
  614. Canvas.FillRect(rcItem);
  615. end;
  616. end;}
  617. procedure TOQBLbx.WMLButtonDown(var Message: TLMLButtonDblClk);
  618. begin
  619. inherited;
  620. BeginDrag(False);
  621. end;
  622. procedure TOQBLbx.WMRButtonDown(var Message: TLMRButtonDblClk);
  623. var
  624. pnt: TPoint;
  625. begin
  626. inherited;
  627. pnt.X := Message.XPos;
  628. pnt.Y := Message.YPos;
  629. pnt := ClientToScreen(pnt);
  630. PopupMenu.Popup(pnt.X, pnt.Y);
  631. end;
  632. {procedure TOQBLbx.ClickCheck;
  633. var
  634. iCol: Integer;
  635. begin
  636. inherited;
  637. if FLoading then
  638. Exit;
  639. if Checked[ItemIndex] then
  640. begin
  641. TOQBForm(GetParentForm(Self)).QBGrid.Insert(
  642. TOQBForm(GetParentForm(Self)).QBGrid.ColCount,
  643. Items[ItemIndex], TOQBTable(Parent).FTableName);
  644. end
  645. else
  646. begin
  647. iCol := TOQBForm(GetParentForm(Self)).QBGrid.FindColumn(Items[ItemIndex]);
  648. while iCol <> -1 do
  649. begin
  650. TOQBForm(GetParentForm(Self)).QBGrid.RemoveColumn(iCol);
  651. iCol := TOQBForm(GetParentForm(Self)).QBGrid.FindColumn(Items[ItemIndex]);
  652. end;
  653. end;
  654. TOQBForm(GetParentForm(Self)).QBGrid.Refresh; // StringGrid bug
  655. end; }
  656. procedure TOQBLbx.ItemClick(const AIndex: Integer);
  657. var
  658. iCol: Integer;
  659. begin
  660. inherited ItemClick(AIndex);
  661. if FLoading then
  662. Exit;
  663. if Checked[ItemIndex] then
  664. begin
  665. TOQBForm(GetParentForm(Self)).QBGrid.Insert(
  666. TOQBForm(GetParentForm(Self)).QBGrid.ColCount,
  667. Items[ItemIndex], TOQBTable(Parent).FTableName);
  668. end
  669. else
  670. begin
  671. iCol := TOQBForm(GetParentForm(Self)).QBGrid.FindColumn(Items[ItemIndex]);
  672. while iCol <> -1 do
  673. begin
  674. TOQBForm(GetParentForm(Self)).QBGrid.RemoveColumn(iCol);
  675. iCol := TOQBForm(GetParentForm(Self)).QBGrid.FindColumn(Items[ItemIndex]);
  676. end;
  677. end;
  678. TOQBForm(GetParentForm(Self)).QBGrid.Refresh; // StringGrid bug
  679. end;
  680. procedure TOQBLbx.AllocArrBold;
  681. begin
  682. FArrBold := AllocMem(Items.Count * SizeOf(Integer));
  683. end;
  684. procedure TOQBLbx.SelectItemBold(Item: Integer);
  685. begin
  686. if FArrBold <> nil then
  687. if FArrBold[Item] = 0 then
  688. FArrBold^[Item] := 1;
  689. end;
  690. procedure TOQBLbx.UnSelectItemBold(Item: Integer);
  691. begin
  692. if FArrBold <> nil then
  693. if FArrBold[Item] = 1 then
  694. FArrBold^[Item] := 0;
  695. end;
  696. function TOQBLbx.GetItemY(Item: Integer): Integer;
  697. begin
  698. Result := Item * ItemHeight + ItemHeight div 2 + 1;
  699. end;
  700. { TOQBTable }
  701. constructor TOQBTable.Create(AOwner: TComponent);
  702. var
  703. mnuArr: array [1..5] of TMenuItem;
  704. begin
  705. inherited;
  706. Visible := False;
  707. ShowHint := True;
  708. BevelInner := bvRaised;
  709. BevelOuter := bvRaised;
  710. BorderWidth := 1;
  711. FCloseBtn := TSpeedButton.Create(Self);
  712. FCloseBtn.Parent := Self;
  713. FCloseBtn.Hint := 'Close';
  714. FUnlinkBtn := TSpeedButton.Create(Self);
  715. FUnlinkBtn.Parent := Self;
  716. FUnlinkBtn.Hint := 'Unlink all';
  717. FLbx := TOQBLbx.Create(Self);
  718. FLbx.Parent := Self;
  719. FLbx.Style := lbStandard;
  720. FLbx.Align := alBottom;
  721. FLbx.TabStop := False;
  722. FLbx.Visible := False;
  723. mnuArr[1] := NewItem('Select All', 0, False, True, _SelectAll, 0, 'mnuSelectAll');
  724. mnuArr[2] := NewItem('Unselect All', 0, False, True, _UnSelectAll, 0, 'mnuUnSelectAll');
  725. mnuArr[3] := NewLine;
  726. mnuArr[4] := NewItem('Unlink', 0, False, True, _UnlinkBtn, 0, 'mnuUnLink');
  727. mnuArr[5] := NewItem('Close', 0, False, True, _CloseBtn, 0, 'mnuClose');
  728. PopMenu := NewPopupMenu(Self, 'mnu', paLeft, False, mnuArr);
  729. PopMenu.PopupComponent := Self;
  730. FLbx.PopupMenu := PopMenu;
  731. end;
  732. procedure TOQBTable.WMRButtonDown(var Message: TLMLButtonDblClk);
  733. var
  734. pnt: TPoint;
  735. begin
  736. inherited;
  737. pnt.X := Message.XPos;
  738. pnt.Y := Message.YPos;
  739. pnt := ClientToScreen(pnt);
  740. PopMenu.Popup(pnt.X, pnt.Y);
  741. end;
  742. procedure TOQBTable.Paint;
  743. begin
  744. inherited;
  745. if TOQBForm(GetParentForm(Self)).QBDialog.OQBEngine.UseTableAliases then
  746. Canvas.TextOut(4, 4, FTableName + ' : ' + FTableAlias) else
  747. Canvas.TextOut(4, 4, FTableName);
  748. end;
  749. function TOQBTable.GetRowY(FldN: Integer): Integer;
  750. var
  751. pnt: TPoint;
  752. begin
  753. pnt.X := FLbx.Left;
  754. pnt.Y := FLbx.Top + FLbx.GetItemY(FldN);
  755. pnt := Parent.ScreenToClient(ClientToScreen(pnt));
  756. Result := pnt.Y;
  757. end;
  758. function TOQBTable.Activate(const ATableName: string; X, Y: Integer): Boolean;
  759. var
  760. i: Integer;
  761. W, W1: Integer;
  762. OQBEngine: TOQBEngine;
  763. begin
  764. Result := False;
  765. Top := Y;
  766. Left := X;
  767. Font.Style := [fsBold];
  768. Font.Size := 8;
  769. Canvas.Font := Font;
  770. Hint := ATableName;
  771. FTableName := ATableName;
  772. FTableAlias := TOQBForm(GetParentForm(Self)).QBDialog.FOQBEngine.AliasList[
  773. TOQBForm(GetParentForm(Self)).QBDialog.FOQBEngine.TableList.IndexOf(ATableName)];
  774. OQBEngine := TOQBForm(GetParentForm(Self)).QBDialog.FOQBEngine;
  775. try
  776. OQBEngine.ReadFieldList(ATableName);
  777. FLbx.Items.Assign(OQBEngine.FieldList);
  778. except
  779. on E: EDatabaseError do
  780. begin
  781. ShowMessage(E.Message);
  782. Exit;
  783. end;
  784. end;
  785. FLbx.AllocArrBold;
  786. FLbx.ParentFont := False;
  787. FLbx.TabStop := False;
  788. case WidgetSet.LCLPlatform of
  789. lpGtk: FLbx.Height := ((FLbx.ItemHeight + 6) * FLbx.Items.Count) + 4;
  790. lpGtk2: FLbx.Height := ((FLbx.ItemHeight + 6) * FLbx.Items.Count) + 4;
  791. lpWin32: FLbx.Height := ((FLbx.ItemHeight + 4) * FLbx.Items.Count) + 4;
  792. lpCarbon:FLbx.Height := ((FLbx.ItemHeight + 8) * FLbx.Items.Count) + 4;
  793. lpQT: FLbx.Height := ((FLbx.ItemHeight + 8) * FLbx.Items.Count) + 4;
  794. lpfpGUI: FLbx.Height := ((FLbx.ItemHeight + 8) * FLbx.Items.Count) + 4;
  795. else
  796. FLbx.Height := ((FLbx.ItemHeight + 8) * FLbx.Items.Count) + 4;
  797. end;
  798. Height := FLbx.Height + 22;
  799. W := 110;
  800. for i := 0 to FLbx.Items.Count - 1 do
  801. begin
  802. W1 := Canvas.TextWidth(FLbx.Items[i]);
  803. if W < W1 then
  804. W := W1;
  805. end;
  806. Width := W + 20 + 22;//FLbx.GetCheckW; //*** check
  807. if TOQBForm(GetParentForm(Self)).QBDialog.OQBEngine.UseTableAliases then
  808. begin
  809. if Canvas.TextWidth(FTableName + ' : ' + FTableAlias) > Width - 34 then
  810. Width := Canvas.TextWidth(FTableName + ' : ' + FTableAlias) + 34
  811. end
  812. else if Canvas.TextWidth(FTableName) > Width - 34 then
  813. Width := Canvas.TextWidth(FTableName) + 34;
  814. Color := clForm;
  815. FLbx.Visible := True;
  816. FLbx.OnDragOver := _DragOver;
  817. FLbx.OnDragDrop := _DragDrop;
  818. FCloseBtn.Top := 4;
  819. FCloseBtn.Left := Self.ClientWidth - 16;
  820. FCloseBtn.Width := 12;
  821. FCloseBtn.Height := 12;
  822. FCloseBtn.Glyph.LoadFromResourceName(HInstance, 'CLOSEBMP');;
  823. FCloseBtn.Margin := -1;
  824. FCloseBtn.Spacing := 0;
  825. FCloseBtn.OnClick := _CloseBtn;
  826. FCloseBtn.Visible := True;
  827. FUnlinkBtn.Top := 4;
  828. FUnlinkBtn.Left := Self.ClientWidth - 16 - FCloseBtn.Width;
  829. FUnlinkBtn.Width := 12;
  830. FUnlinkBtn.Height := 12;
  831. FUnlinkBtn.Glyph.LoadFromResourceName(HInstance, 'UNLINKBMP');;
  832. FUnlinkBtn.Margin := -1;
  833. FUnlinkBtn.Spacing := 0;
  834. FUnlinkBtn.OnClick := _UnlinkBtn;
  835. FUnlinkBtn.Visible := True;
  836. Visible := True;
  837. Result := True;
  838. end;
  839. procedure TOQBTable._CloseBtn(Sender: TObject);
  840. begin
  841. TOQBArea(Parent).UnlinkTable(Self);
  842. TOQBForm(GetParentForm(Self)).QBGrid.RemoveColumn4Tbl(FTableName);
  843. Parent.RemoveControl(Self);
  844. Free;
  845. end;
  846. procedure TOQBTable._UnlinkBtn(Sender: TObject);
  847. begin
  848. TOQBArea(Parent).UnlinkTable(Self);
  849. end;
  850. procedure TOQBTable._SelectAll(Sender: TObject);
  851. var
  852. i: Integer;
  853. begin
  854. if FLbx.Items.Count = 1 then
  855. Exit;
  856. for i := 1 to (FLbx.Items.Count - 1) do
  857. begin
  858. FLbx.Checked[i] := True;
  859. TOQBForm(GetParentForm(Self)).QBGrid.Insert(
  860. TOQBForm(GetParentForm(Self)).QBGrid.ColCount,
  861. FLbx.Items[i], FTableName);
  862. end;
  863. end;
  864. procedure TOQBTable._UnSelectAll(Sender: TObject);
  865. var
  866. i: Integer;
  867. begin
  868. if FLbx.Items.Count = 1 then
  869. Exit;
  870. for i := 1 to (FLbx.Items.Count - 1) do
  871. begin
  872. FLbx.Checked[i] := False;
  873. TOQBForm(GetParentForm(Self)).QBGrid.RemoveColumn4Tbl(FTableName);
  874. end;
  875. end;
  876. procedure TOQBTable._DragOver(Sender, Source: TObject; X, Y: Integer;
  877. State: TDragState; var Accept: Boolean);
  878. begin
  879. if (Source is TCustomListBox) and (TWinControl(Source).Parent is TOQBTable) then
  880. Accept := True;
  881. end;
  882. procedure TOQBTable._DragDrop(Sender, Source: TObject; X, Y: Integer);
  883. var
  884. nRow: Integer;
  885. hRow: Integer;
  886. begin
  887. if (Source is TCustomListBox) then
  888. begin
  889. if (TWinControl(Source).Parent is TOQBTable) then
  890. begin
  891. hRow := FLbx.ItemHeight;
  892. if hRow <> 0 then
  893. nRow := Y div hRow else
  894. nRow := 0;
  895. if nRow > FLbx.Items.Count - 1 then
  896. nRow := FLbx.Items.Count - 1;
  897. // handler for target's '*' row
  898. if nRow = 0 then
  899. Exit;
  900. // handler for source's '*' row
  901. if TOQBTable(TWinControl(Source).Parent).FLbx.ItemIndex = 0 then
  902. Exit;
  903. if Source <> FLbx then
  904. TOQBArea(Parent).InsertLink(
  905. TOQBTable(TWinControl(Source).Parent), Self,
  906. TOQBTable(TWinControl(Source).Parent).FLbx.ItemIndex, nRow)
  907. else if nRow <> FLbx.ItemIndex then
  908. TOQBArea(Parent).InsertLink(Self, Self, FLbx.ItemIndex, nRow);
  909. end
  910. else
  911. if Source = TOQBForm(GetParentForm(Self)).QBTables then
  912. begin
  913. X := X + Left + TWinControl(Sender).Left;
  914. Y := Y + Top + TWinControl(Sender).Top;
  915. TOQBArea(Parent).InsertTable(X, Y);
  916. end;
  917. end
  918. end;
  919. procedure TOQBTable.SetParent(AParent: TWinControl);
  920. begin
  921. if (AParent <> nil) and (not (AParent is TScrollBox)) then
  922. raise Exception.Create(sNotValidTableParent);
  923. inherited;
  924. end;
  925. procedure TOQBTable.MouseDown(Button: TMouseButton; Shift: TShiftState;
  926. X, Y: Integer);
  927. begin
  928. inherited;
  929. BringToFront;
  930. if (Button = mbLeft) then
  931. begin
  932. SetCapture(Self.Handle);
  933. ScreenDC := GetDC(0);
  934. ClipRect := Bounds(Parent.Left, Parent.Top, Parent.Width, Parent.Height);
  935. ClipRect.TopLeft := Parent.Parent.ClientToScreen(ClipRect.TopLeft);
  936. ClipRect.BottomRight := Parent.Parent.ClientToScreen(ClipRect.BottomRight);
  937. ClipRgn := CreateRectRgn(ClipRect.Left, ClipRect.Top, ClipRect.Right, ClipRect.Bottom);
  938. SelectClipRgn(ScreenDC, ClipRgn);
  939. // ClipCursor(@ClipRect);
  940. OldX := X;
  941. OldY := Y;
  942. OldLeft := X;
  943. OldTop := Y;
  944. MoveRect := Rect(Self.Left, Self.Top, Self.Left + Self.Width, Self.Top + Self.Height);
  945. MoveRect.TopLeft := Parent.ClientToScreen(MoveRect.TopLeft);
  946. MoveRect.BottomRight := Parent.ClientToScreen(MoveRect.BottomRight);
  947. DrawFocusRect(ScreenDC, MoveRect);
  948. Moving := True;
  949. end;
  950. end;
  951. procedure TOQBTable.MouseMove(Shift: TShiftState; X, Y: Integer);
  952. begin
  953. inherited;
  954. if Moving then
  955. begin
  956. DrawFocusRect(ScreenDC, MoveRect);
  957. OldX := X;
  958. OldY := Y;
  959. MoveRect := Rect(Self.Left + OldX - OldLeft, Self.Top + OldY - OldTop,
  960. Self.Left + Self.Width + OldX - OldLeft, Self.Top + Self.Height + OldY - OldTop);
  961. MoveRect.TopLeft := Parent.ClientToScreen(MoveRect.TopLeft);
  962. MoveRect.BottomRight := Parent.ClientToScreen(MoveRect.BottomRight);
  963. DrawFocusRect(ScreenDC, MoveRect);
  964. end;
  965. end;
  966. procedure TOQBTable.MouseUp(Button: TMouseButton; Shift: TShiftState;
  967. X, Y: Integer);
  968. begin
  969. inherited;
  970. if Button = mbLeft then
  971. begin
  972. ReleaseCapture;
  973. DrawFocusRect(ScreenDC, MoveRect);
  974. if (Self.Left <> Self.Left + X + OldLeft) or (Self.Top <> Self.Top + Y - OldTop) then
  975. begin
  976. Self.Visible := False;
  977. Self.Left := Self.Left + X - OldLeft;
  978. Self.Top := Self.Top + Y - OldTop;
  979. Self.Visible := True;
  980. end;
  981. ClipRect := Rect(0, 0, Screen.Width, Screen.Height);
  982. // ClipCursor(@ClipRect);
  983. DeleteObject(ClipRgn);
  984. ReleaseDC(0, ScreenDC);
  985. Moving := False;
  986. end;
  987. TOQBArea(Parent).ReboundLinks4Table(Self);
  988. end;
  989. { TOQBLink }
  990. constructor TOQBLink.Create(AOwner: TComponent);
  991. var
  992. mnuArr: array [1..4] of TMenuItem;
  993. begin
  994. inherited;
  995. ControlStyle := ControlStyle + [csReplicatable];
  996. Width := 105;
  997. Height := 105;
  998. Rgn := CreateRectRgn(0, 0, Hand, Hand);
  999. mnuArr[1] := NewItem('', 0, False, False, nil, 0, 'mnuLinkName');
  1000. mnuArr[2] := NewLine;
  1001. mnuArr[3] := NewItem('Link options', 0, False, True, TOQBArea(AOwner).SetOptions, 0, 'mnuOptions');
  1002. mnuArr[4] := NewItem('Unlink', 0, False, True, TOQBArea(AOwner).Unlink, 0, 'mnuUnlink');
  1003. PopMenu := NewPopupMenu(Self, 'mnu', paLeft, False, mnuArr);
  1004. PopMenu.PopupComponent := Self;
  1005. end;
  1006. destructor TOQBLink.Destroy;
  1007. begin
  1008. DeleteObject(Rgn);
  1009. inherited;
  1010. end;
  1011. procedure TOQBLink.Paint;
  1012. var
  1013. ArrRgn, pntArray: array [1..4] of TPoint;
  1014. ArrCnt: Integer;
  1015. begin
  1016. if tbl1 <> tbl2 then
  1017. begin
  1018. if ((LnkX = 1) and (LnkY = 1)) or ((LnkX = 4) and (LnkY = 2)) then
  1019. begin
  1020. pntArray[1].X := 0;
  1021. pntArray[1].Y := Hand div 2;
  1022. pntArray[2].X := Hand;
  1023. pntArray[2].Y := Hand div 2;
  1024. pntArray[3].X := Width - Hand;
  1025. pntArray[3].Y := Height - Hand div 2;
  1026. pntArray[4].X := Width;
  1027. pntArray[4].Y := Height - Hand div 2;
  1028. ArrRgn[1].X := pntArray[2].X + 5;
  1029. ArrRgn[1].Y := pntArray[2].Y - 5;
  1030. ArrRgn[2].X := pntArray[2].X - 5;
  1031. ArrRgn[2].Y := pntArray[2].Y + 5;
  1032. ArrRgn[3].X := pntArray[3].X - 5;
  1033. ArrRgn[3].Y := pntArray[3].Y + 5;
  1034. ArrRgn[4].X := pntArray[3].X + 5;
  1035. ArrRgn[4].Y := pntArray[3].Y - 5;
  1036. end;
  1037. if Width > Hand + Hand2 then
  1038. begin
  1039. if ((LnkX = 2) and (LnkY = 1)) or ((LnkX = 3) and (LnkY = 2)) then
  1040. begin
  1041. pntArray[1].X := 0;
  1042. pntArray[1].Y := Hand div 2;
  1043. pntArray[2].X := Hand;
  1044. pntArray[2].Y := Hand div 2;
  1045. pntArray[3].X := Width - 5;
  1046. pntArray[3].Y := Height - Hand div 2;
  1047. pntArray[4].X := Width - Hand;
  1048. pntArray[4].Y := Height - Hand div 2;
  1049. ArrRgn[1].X := pntArray[2].X + 5;
  1050. ArrRgn[1].Y := pntArray[2].Y - 5;
  1051. ArrRgn[2].X := pntArray[2].X - 5;
  1052. ArrRgn[2].Y := pntArray[2].Y + 5;
  1053. ArrRgn[3].X := pntArray[3].X - 5;
  1054. ArrRgn[3].Y := pntArray[3].Y + 5;
  1055. ArrRgn[4].X := pntArray[3].X + 5;
  1056. ArrRgn[4].Y := pntArray[3].Y - 5;
  1057. end;
  1058. if ((LnkX = 3) and (LnkY = 1)) or ((LnkX = 2) and (LnkY = 2)) then
  1059. begin
  1060. pntArray[1].X := Width - Hand;
  1061. pntArray[1].Y := Hand div 2;
  1062. pntArray[2].X := Width - 5;
  1063. pntArray[2].Y := Hand div 2;
  1064. pntArray[3].X := Hand;
  1065. pntArray[3].Y := Height - Hand div 2;
  1066. pntArray[4].X := 0;
  1067. pntArray[4].Y := Height - Hand div 2;
  1068. ArrRgn[1].X := pntArray[2].X - 5;
  1069. ArrRgn[1].Y := pntArray[2].Y - 5;
  1070. ArrRgn[2].X := pntArray[2].X + 5;
  1071. ArrRgn[2].Y := pntArray[2].Y + 5;
  1072. ArrRgn[3].X := pntArray[3].X + 5;
  1073. ArrRgn[3].Y := pntArray[3].Y + 5;
  1074. ArrRgn[4].X := pntArray[3].X - 5;
  1075. ArrRgn[4].Y := pntArray[3].Y - 5;
  1076. end;
  1077. end
  1078. else
  1079. begin
  1080. if ((LnkX = 2) and (LnkY = 1)) or ((LnkX = 3) and (LnkY = 2)) or
  1081. ((LnkX = 3) and (LnkY = 1)) or ((LnkX = 2) and (LnkY = 2)) then
  1082. begin
  1083. pntArray[1].X := 0;
  1084. pntArray[1].Y := Hand div 2;
  1085. pntArray[2].X := Width - Hand2;
  1086. pntArray[2].Y := Hand div 2;
  1087. pntArray[3].X := Width - Hand2;
  1088. pntArray[3].Y := Height - Hand div 2;
  1089. pntArray[4].X := 0;
  1090. pntArray[4].Y := Height - Hand div 2;
  1091. ArrRgn[1].X := pntArray[2].X - 5;
  1092. ArrRgn[1].Y := pntArray[2].Y - 5;
  1093. ArrRgn[2].X := pntArray[2].X + 5;
  1094. ArrRgn[2].Y := pntArray[2].Y + 5;
  1095. ArrRgn[3].X := pntArray[3].X + 5;
  1096. ArrRgn[3].Y := pntArray[3].Y + 5;
  1097. ArrRgn[4].X := pntArray[3].X - 5;
  1098. ArrRgn[4].Y := pntArray[3].Y - 5;
  1099. end;
  1100. end;
  1101. if ((LnkX = 4) and (LnkY = 1)) or ((LnkX = 1) and (LnkY = 2)) then
  1102. begin
  1103. pntArray[1].X := Width;
  1104. pntArray[1].Y := Hand div 2;
  1105. pntArray[2].X := Width - Hand;
  1106. pntArray[2].Y := Hand div 2;
  1107. pntArray[3].X := Hand;
  1108. pntArray[3].Y := Height - Hand div 2;
  1109. pntArray[4].X := 0;
  1110. pntArray[4].Y := Height - Hand div 2;
  1111. ArrRgn[1].X := pntArray[2].X - 5;
  1112. ArrRgn[1].Y := pntArray[2].Y - 5;
  1113. ArrRgn[2].X := pntArray[2].X + 5;
  1114. ArrRgn[2].Y := pntArray[2].Y + 5;
  1115. ArrRgn[3].X := pntArray[3].X + 5;
  1116. ArrRgn[3].Y := pntArray[3].Y + 5;
  1117. ArrRgn[4].X := pntArray[3].X - 5;
  1118. ArrRgn[4].Y := pntArray[3].Y - 5;
  1119. end;
  1120. end
  1121. else
  1122. begin
  1123. pntArray[1].X := 0;
  1124. pntArray[1].Y := Hand div 2;
  1125. pntArray[2].X := Hand - 5;
  1126. pntArray[2].Y := Hand div 2;
  1127. pntArray[3].X := Hand - 5;
  1128. pntArray[3].Y := Height - Hand div 2;
  1129. pntArray[4].X := 0;
  1130. pntArray[4].Y := Height - Hand div 2;
  1131. ArrRgn[1].X := pntArray[2].X + 5;
  1132. ArrRgn[1].Y := pntArray[2].Y - 5;
  1133. ArrRgn[2].X := pntArray[2].X - 5;
  1134. ArrRgn[2].Y := pntArray[2].Y + 5;
  1135. ArrRgn[3].X := pntArray[3].X - 5;
  1136. ArrRgn[3].Y := pntArray[3].Y + 5;
  1137. ArrRgn[4].X := pntArray[3].X + 5;
  1138. ArrRgn[4].Y := pntArray[3].Y - 5;
  1139. end;
  1140. Canvas.PolyLine(pntArray);
  1141. Canvas.Brush := Parent.Brush;
  1142. DeleteObject(Rgn);
  1143. ArrCnt := 4;
  1144. Rgn := CreatePolygonRgn(@ArrRgn, ArrCnt, ALTERNATE);
  1145. end;
  1146. procedure TOQBLink._Click(X, Y: Integer);
  1147. var
  1148. pnt: TPoint;
  1149. begin
  1150. pnt.X := X;
  1151. pnt.Y := Y;
  1152. pnt := ClientToScreen(pnt);
  1153. PopMenu.Popup(pnt.X, pnt.Y);
  1154. end;
  1155. procedure TOQBLink.CMHitTest(var Message: TCMHitTest);
  1156. begin
  1157. if PtInRegion(Rgn, Message.XPos, Message.YPos) then
  1158. Message.Result := 1;
  1159. end;
  1160. function TOQBLink.ControlAtPos(const Pos: TPoint): TControl;
  1161. var
  1162. I: Integer;
  1163. scrnP, P: TPoint;
  1164. begin
  1165. scrnP := ClientToScreen(Pos);
  1166. for I := Parent.ControlCount - 1 downto 0 do
  1167. begin
  1168. Result := Parent.Controls[I];
  1169. if (Result is TOQBLink) and (Result <> Self) then
  1170. with Result do
  1171. begin
  1172. P := Result.ScreenToClient(scrnP);
  1173. if Perform(CM_HITTEST, 0, Integer(PointToSmallPoint(P))) <> 0 then
  1174. Exit;
  1175. end;
  1176. end;
  1177. Result := nil;
  1178. end;
  1179. function TOQBLink.PtInRegion(RGN: HRGN; X, Y: Integer): Boolean;
  1180. {$IFDEF MSWINDOWS}
  1181. begin
  1182. Result := LCLIntf.PtInRegion(RGN, X, Y);
  1183. {$ELSE}
  1184. var
  1185. APoint : TPoint;
  1186. ARect : TRect;
  1187. begin
  1188. GetRgnBox(RGN, @ARect);
  1189. APoint.X := X;
  1190. APoint.Y := Y;
  1191. Result := LclIntf.PtInRect(ARect, APoint);
  1192. {$ENDIF}
  1193. end;
  1194. procedure TOQBLink.WndProc(var Message: TLMessage);
  1195. begin
  1196. if (Message.Msg = LM_RBUTTONDOWN) or (Message.Msg = LM_LBUTTONDOWN) then
  1197. if not PtInRegion(Rgn, TLMMouse(Message).XPos, TLMMouse(Message).YPos) then
  1198. ControlAtPos(SmallPointToPoint(TLMMouse(Message).Pos)) else
  1199. _Click(TLMMouse(Message).XPos, TLMMouse(Message).YPos);
  1200. inherited;
  1201. end;
  1202. { TOQBArea }
  1203. procedure TOQBArea.CreateParams(var Params: TCreateParams);
  1204. begin
  1205. inherited;
  1206. OnDragOver := _DragOver;
  1207. OnDragDrop := _DragDrop;
  1208. end;
  1209. procedure TOQBArea.SetOptions(Sender: TObject);
  1210. var
  1211. AForm: TOQBLinkForm;
  1212. ALink: TOQBLink;
  1213. begin
  1214. if TPopupMenu(Sender).Owner is TOQBLink then
  1215. begin
  1216. ALink := TOQBLink(TPopupMenu(Sender).Owner);
  1217. AForm := TOQBLinkForm.Create(Application);
  1218. AForm.txtTable1.Caption := ALink.tbl1.FTableName;
  1219. AForm.txtCol1.Caption := ALink.fldNam1;
  1220. AForm.txtTable2.Caption := ALink.tbl2.FTableName;
  1221. AForm.txtCol2.Caption := ALink.fldNam2;
  1222. AForm.RadioOpt.ItemIndex := ALink.FLinkOpt;
  1223. AForm.RadioType.ItemIndex := ALink.FLinkType;
  1224. if AForm.ShowModal = mrOk then
  1225. begin
  1226. ALink.FLinkOpt := AForm.RadioOpt.ItemIndex;
  1227. ALink.FLinkType := AForm.RadioType.ItemIndex;
  1228. end;
  1229. AForm.Free;
  1230. end;
  1231. end;
  1232. procedure TOQBArea.InsertTable(X, Y: Integer);
  1233. var
  1234. NewTable: TOQBTable;
  1235. begin
  1236. if FindTable(TOQBForm(GetParentForm(Self)).QBTables.Items[
  1237. TOQBForm(GetParentForm(Self)).QBTables.ItemIndex]) <> nil then
  1238. begin
  1239. ShowMessage('This table is already inserted.');
  1240. Exit;
  1241. end;
  1242. NewTable := TOQBTable.Create(Self);
  1243. NewTable.Parent := Self;
  1244. try
  1245. NewTable.Activate(TOQBForm(GetParentForm(Self)).QBTables.Items[
  1246. TOQBForm(GetParentForm(Self)).QBTables.ItemIndex], X, Y);
  1247. except
  1248. NewTable.Free;
  1249. end;
  1250. end;
  1251. function TOQBArea.InsertLink(_tbl1, _tbl2: TOQBTable;
  1252. _fldN1, _fldN2: Integer): TOQBLink;
  1253. begin
  1254. Result := TOQBLink.Create(Self);
  1255. with Result do
  1256. begin
  1257. Parent := Self;
  1258. Application.ProcessMessages; // importante no gtk2
  1259. tbl1 := _tbl1;
  1260. tbl2 := _tbl2;
  1261. fldN1 := _fldN1;
  1262. fldN2 := _fldN2;
  1263. fldNam1 := tbl1.FLbx.Items[fldN1];
  1264. fldNam2 := tbl2.FLbx.Items[fldN2];
  1265. end;
  1266. if FindLink(Result) then
  1267. begin
  1268. ShowMessage('These tables are already linked.');
  1269. Result.Free;
  1270. Result := nil;
  1271. Exit;
  1272. end;
  1273. with Result do
  1274. begin
  1275. tbl1.FLbx.SelectItemBold(fldN1);
  1276. tbl1.FLbx.Refresh;
  1277. tbl2.FLbx.SelectItemBold(fldN2);
  1278. tbl2.FLbx.Refresh;
  1279. OnDragOver := _DragOver;
  1280. OnDragDrop := _DragDrop;
  1281. end;
  1282. ReboundLink(Result);
  1283. Result.Visible := True;
  1284. end;
  1285. function TOQBArea.FindTable(const TableName: string): TOQBTable;
  1286. var
  1287. i: Integer;
  1288. TempTable: TOQBTable;
  1289. begin
  1290. Result := nil;
  1291. for i := ControlCount - 1 downto 0 do
  1292. if Controls[i] is TOQBTable then
  1293. begin
  1294. TempTable := TOQBTable(Controls[i]);
  1295. if (TempTable.FTableName = TableName) then
  1296. begin
  1297. Result := TempTable;
  1298. Exit;
  1299. end;
  1300. end;
  1301. end;
  1302. function TOQBArea.FindLink(Link: TOQBLink): Boolean;
  1303. var
  1304. i: Integer;
  1305. TempLink: TOQBLink;
  1306. begin
  1307. Result := False;
  1308. for i := ControlCount - 1 downto 0 do
  1309. if Controls[i] is TOQBLink then
  1310. begin
  1311. TempLink := TOQBLink(Controls[i]);
  1312. if (TempLink <> Link) then
  1313. if (((TempLink.tbl1 = Link.tbl1) and (TempLink.fldN1 = Link.fldN1)) and
  1314. ((TempLink.tbl2 = Link.tbl2) and (TempLink.fldN2 = Link.fldN2))) or
  1315. (((TempLink.tbl1 = Link.tbl2) and (TempLink.fldN1 = Link.fldN2)) and
  1316. ((TempLink.tbl2 = Link.tbl1) and (TempLink.fldN2 = Link.fldN1))) then
  1317. begin
  1318. Result := True;
  1319. Exit;
  1320. end;
  1321. end;
  1322. end;
  1323. function TOQBArea.FindOtherLink(Link: TOQBLink; Tbl: TOQBTable;
  1324. FldN: Integer): Boolean;
  1325. var
  1326. i: Integer;
  1327. OtherLink: TOQBLink;
  1328. begin
  1329. Result := False;
  1330. for i := ControlCount - 1 downto 0 do
  1331. if Controls[i] is TOQBLink then
  1332. begin
  1333. OtherLink := TOQBLink(Controls[i]);
  1334. if (OtherLink <> Link) then
  1335. if ((OtherLink.tbl1 = Tbl) and (OtherLink.fldN1 = FldN)) or
  1336. ((OtherLink.tbl2 = Tbl) and (OtherLink.fldN2 = FldN)) then
  1337. begin
  1338. Result := True;
  1339. Exit;
  1340. end;
  1341. end;
  1342. end;
  1343. procedure TOQBArea.ReboundLink(Link: TOQBLink);
  1344. var
  1345. X1, X2, Y1, Y2: Integer;
  1346. begin
  1347. Link.PopMenu.Items[0].Caption := Link.tbl1.FTableName + ' :: ' +
  1348. Link.tbl2.FTableName;
  1349. with Link do
  1350. begin
  1351. if Tbl1 = Tbl2 then
  1352. begin
  1353. X1 := Tbl1.Left + Tbl1.Width;
  1354. X2 := Tbl1.Left + Tbl1.Width + Hand;
  1355. end
  1356. else
  1357. begin
  1358. if Tbl1.Left < Tbl2.Left then
  1359. begin
  1360. if Tbl1.Left + Tbl1.Width + Hand < Tbl2.Left then
  1361. begin //A
  1362. X1 := Tbl1.Left + Tbl1.Width;
  1363. X2 := Tbl2.Left;
  1364. LnkX := 1;
  1365. end
  1366. else
  1367. begin //B
  1368. if Tbl1.Left + Tbl1.Width > Tbl2.Left + Tbl2.Width then
  1369. begin
  1370. X1 := Tbl2.Left + Tbl2.Width;
  1371. X2 := Tbl1.Left + Tbl1.Width + Hand;
  1372. LnkX := 3;
  1373. end
  1374. else
  1375. begin
  1376. X1 := Tbl1.Left + Tbl1.Width;
  1377. X2 := Tbl2.Left + Tbl2.Width + Hand;
  1378. LnkX := 2;
  1379. end;
  1380. end;
  1381. end
  1382. else
  1383. begin
  1384. if Tbl2.Left + Tbl2.Width + Hand > Tbl1.Left then
  1385. begin //C
  1386. if Tbl2.Left + Tbl2.Width > Tbl1.Left + Tbl1.Width then
  1387. begin
  1388. X1 := Tbl1.Left + Tbl1.Width;
  1389. X2 := Tbl2.Left + Tbl2.Width + Hand;
  1390. LnkX := 2;
  1391. end
  1392. else
  1393. begin
  1394. X1 := Tbl2.Left + Tbl2.Width;
  1395. X2 := Tbl1.Left + Tbl1.Width + Hand;
  1396. LnkX := 3;
  1397. end;
  1398. end
  1399. else
  1400. begin //D
  1401. X1 := Tbl2.Left + Tbl2.Width;
  1402. X2 := Tbl1.Left;
  1403. LnkX := 4;
  1404. end;
  1405. end;
  1406. end;
  1407. Y1 := Tbl1.GetRowY(FldN1);
  1408. Y2 := Tbl2.GetRowY(FldN2);
  1409. if Y1 < Y2 then
  1410. begin //M
  1411. Y1 := Tbl1.GetRowY(FldN1) - Hand div 2;
  1412. Y2 := Tbl2.GetRowY(FldN2) + Hand div 2;
  1413. LnkY := 1;
  1414. end
  1415. else
  1416. begin //N
  1417. Y2 := Tbl1.GetRowY(FldN1) + Hand div 2;
  1418. Y1 := Tbl2.GetRowY(FldN2) - Hand div 2;
  1419. LnkY := 2;
  1420. end;
  1421. SetBounds(X1, Y1, X2 - X1, Y2 - Y1);
  1422. end;
  1423. end;
  1424. procedure TOQBArea.ReboundLinks4Table(ATable: TOQBTable);
  1425. var
  1426. i: Integer;
  1427. Link: TOQBLink;
  1428. begin
  1429. for i := 0 to ControlCount - 1 do
  1430. begin
  1431. if Controls[i] is TOQBLink then
  1432. begin
  1433. Link := TOQBLink(Controls[i]);
  1434. if (Link.Tbl1 = ATable) or (Link.Tbl2 = ATable) then
  1435. ReboundLink(Link);
  1436. end;
  1437. end;
  1438. end;
  1439. procedure TOQBArea.Unlink(Sender: TObject);
  1440. var
  1441. Link: TOQBLink;
  1442. begin
  1443. if TPopupMenu(Sender).Owner is TOQBLink then
  1444. begin
  1445. Link := TOQBLink(TPopupMenu(Sender).Owner);
  1446. RemoveControl(Link);
  1447. if not FindOtherLink(Link, Link.tbl1, Link.fldN1) then
  1448. begin
  1449. Link.tbl1.FLbx.UnSelectItemBold(Link.fldN1);
  1450. Link.tbl1.FLbx.Refresh;
  1451. end;
  1452. if not FindOtherLink(Link, Link.tbl2, Link.fldN2) then
  1453. begin
  1454. Link.tbl2.FLbx.UnSelectItemBold(Link.fldN2);
  1455. Link.tbl2.FLbx.Refresh;
  1456. end;
  1457. Link.Free;
  1458. end;
  1459. end;
  1460. procedure TOQBArea.UnlinkTable(ATable: TOQBTable);
  1461. var
  1462. i: Integer;
  1463. TempLink: TOQBLink;
  1464. begin
  1465. for i := ControlCount - 1 downto 0 do
  1466. begin
  1467. if Controls[i] is TOQBLink then
  1468. begin
  1469. TempLink := TOQBLink(Controls[i]);
  1470. if (TempLink.Tbl1 = ATable) or (TempLink.Tbl2 = ATable) then
  1471. begin
  1472. RemoveControl(TempLink);
  1473. if not FindOtherLink(TempLink, TempLink.tbl1, TempLink.fldN1) then
  1474. begin
  1475. TempLink.tbl1.FLbx.UnSelectItemBold(TempLink.fldN1);
  1476. TempLink.tbl1.FLbx.Refresh;
  1477. end;
  1478. if not FindOtherLink(TempLink, TempLink.tbl2, TempLink.fldN2) then
  1479. begin
  1480. TempLink.tbl2.FLbx.UnSelectItemBold(TempLink.fldN2);
  1481. TempLink.tbl2.FLbx.Refresh;
  1482. end;
  1483. TempLink.Free;
  1484. end;
  1485. end;
  1486. end;
  1487. end;
  1488. procedure TOQBArea._DragOver(Sender, Source: TObject; X, Y: Integer;
  1489. State: TDragState; var Accept: Boolean);
  1490. begin
  1491. if (Source = TOQBForm(GetParentForm(Self)).QBTables) then
  1492. Accept := True;
  1493. end;
  1494. procedure TOQBArea._DragDrop(Sender, Source: TObject; X, Y: Integer);
  1495. begin
  1496. if not (Sender is TOQBArea) then
  1497. begin
  1498. X := X + TControl(Sender).Left;
  1499. Y := Y + TControl(Sender).Top;
  1500. end;
  1501. if Source = TOQBForm(GetParentForm(Self)).QBTables then
  1502. InsertTable(X, Y);
  1503. end;
  1504. { TOQBGrid }
  1505. procedure TOQBGrid.CreateParams(var Params: TCreateParams);
  1506. begin
  1507. inherited;
  1508. FocusRectVisible := False;
  1509. DefaultColWidth := 64;
  1510. Options := [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine,
  1511. goColSizing, goColMoving];
  1512. ColCount := 2;
  1513. RowCount := 6;
  1514. Height := Parent.ClientHeight;
  1515. // DefaultRowHeight := Parent.Height div (6 + 1) - GridLineWidth;
  1516. DefaultRowHeight := 20;
  1517. Cells[0, cFld] := 'Field';
  1518. Cells[0, cTbl] := 'Table';
  1519. Cells[0, cShow] := 'Show';
  1520. Cells[0, cSort] := 'Sort';
  1521. Cells[0, cFunc] := 'Function';
  1522. Cells[0, cGroup] := 'Group';
  1523. OnDragOver := _DragOver;
  1524. OnDragDrop := _DragDrop;
  1525. IsEmpty := True;
  1526. end;
  1527. procedure TOQBGrid.WndProc(var Message: TLMessage);
  1528. begin
  1529. if (Message.Msg = LM_RBUTTONDOWN) then
  1530. ClickCell(TLMMouse(Message).XPos, TLMMouse(Message).YPos);
  1531. inherited;
  1532. end;
  1533. function TOQBGrid.MaxSW(const s1, s2: string): Integer;
  1534. begin
  1535. Result := Canvas.TextWidth(s1);
  1536. if Result < Canvas.TextWidth(s2) then
  1537. Result := Canvas.TextWidth(s2);
  1538. end;
  1539. procedure TOQBGrid.InsertDefault(aCol: Integer);
  1540. begin
  1541. Cells[aCol, cShow] := sShow;
  1542. Cells[aCol, cSort] := '';
  1543. Cells[aCol, cFunc] := '';
  1544. Cells[aCol, cGroup] := '';
  1545. end;
  1546. procedure TOQBGrid.Insert(aCol: Integer; const aField, aTable: string);
  1547. var
  1548. i: Integer;
  1549. begin
  1550. if IsEmpty then
  1551. begin
  1552. IsEmpty := False;
  1553. aCol := 1;
  1554. Cells[aCol, cFld] := aField;
  1555. Cells[aCol, cTbl] := aTable;
  1556. InsertDefault(aCol);
  1557. end
  1558. else
  1559. begin
  1560. if aCol = -1 then
  1561. begin
  1562. ColCount := ColCount + 1;
  1563. aCol := ColCount - 1;
  1564. Cells[aCol, cFld] := aField;
  1565. Cells[aCol, cTbl] := aTable;
  1566. InsertDefault(aCol);
  1567. end
  1568. else
  1569. begin
  1570. ColCount := ColCount + 1;
  1571. for i := ColCount - 1 downto aCol + 1 do
  1572. MoveColRow(True,i - 1, i);
  1573. Cells[aCol, cFld] := aField;
  1574. Cells[aCol, cTbl] := aTable;
  1575. InsertDefault(aCol);
  1576. end;
  1577. //* Fix StringGrid Bug *
  1578. if aCol > 1 then
  1579. ColWidths[aCol - 1] := MaxSW(Cells[aCol - 1, cFld], Cells[aCol - 1, cTbl]) + 8;
  1580. if aCol < ColCount - 1 then
  1581. ColWidths[aCol + 1] := MaxSW(Cells[aCol + 1, cFld], Cells[aCol + 1, cTbl]) + 8;
  1582. ColWidths[ColCount - 1] := MaxSW(Cells[ColCount - 1, cFld],
  1583. Cells[ColCount - 1, cTbl]) + 8;
  1584. end;
  1585. ColWidths[aCol] := MaxSW(aTable, aField) + 8;
  1586. end;
  1587. function TOQBGrid.FindColumn(const sCol: string): Integer;
  1588. var
  1589. i: Integer;
  1590. begin
  1591. Result := -1;
  1592. for i := 1 to ColCount - 1 do
  1593. if Cells[i, cFld] = sCol then
  1594. begin
  1595. Result := i;
  1596. Exit;
  1597. end;
  1598. end;
  1599. function TOQBGrid.FindSameColumn(aCol: Integer): Boolean;
  1600. var
  1601. i: Integer;
  1602. begin
  1603. Result := False;
  1604. for i := 1 to ColCount - 1 do
  1605. if i = aCol then
  1606. Continue
  1607. else if Cells[i, cFld] = Cells[aCol, cFld] then
  1608. begin
  1609. Result := True;
  1610. Exit;
  1611. end;
  1612. end;
  1613. procedure TOQBGrid.RemoveColumn(aCol: Integer);
  1614. var
  1615. i: Integer;
  1616. begin
  1617. if (ColCount > 2) then
  1618. DeleteCol(aCol)
  1619. else
  1620. begin
  1621. for i := 0 to RowCount - 1 do
  1622. Cells[1, i] := '';
  1623. IsEmpty := True;
  1624. end;
  1625. end;
  1626. procedure TOQBGrid.RemoveColumn4Tbl(const Tbl: string);
  1627. var
  1628. i: Integer;
  1629. begin
  1630. for i := ColCount - 1 downto 1 do
  1631. if Cells[i, cTbl] = Tbl then
  1632. RemoveColumn(i);
  1633. end;
  1634. procedure TOQBGrid.ClickCell(X, Y: Integer);
  1635. var
  1636. P: TPoint;
  1637. mCol, mRow: Integer;
  1638. begin
  1639. MouseToCell(X, Y, mCol, mRow);
  1640. CurrCol := mCol;
  1641. P.X := X;
  1642. P.Y := Y;
  1643. P := ClientToScreen(P);
  1644. if (mCol > 0) and (mCol < ColCount) and (not IsEmpty) then
  1645. begin
  1646. if (Cells[mCol, 0] = '*') and (mRow <> cFld) then
  1647. Exit;
  1648. case mRow of
  1649. cFld:
  1650. TOQBForm(GetParentForm(Self)).mnuTbl.Popup(P.X, P.Y);
  1651. cShow:
  1652. begin
  1653. TOQBForm(GetParentForm(Self)).mnuShow.Items[0].Checked := Cells[mCol, cShow] = sShow;
  1654. TOQBForm(GetParentForm(Self)).mnuShow.Popup(P.X, P.Y);
  1655. end;
  1656. cSort:
  1657. begin
  1658. if Cells[mCol, cSort] = sSort[1] then
  1659. TOQBForm(GetParentForm(Self)).mnuSort.Items[0].Checked := True
  1660. else if Cells[mCol, cSort] = sSort[2] then
  1661. TOQBForm(GetParentForm(Self)).mnuSort.Items[2].Checked := True else
  1662. TOQBForm(GetParentForm(Self)).mnuSort.Items[3].Checked := True;
  1663. TOQBForm(GetParentForm(Self)).mnuSort.Popup(P.X, P.Y);
  1664. end;
  1665. cFunc:
  1666. begin
  1667. if Cells[mCol, cFunc] = sFunc[1] then
  1668. TOQBForm(GetParentForm(Self)).mnuFunc.Items[0].Checked := True
  1669. else if Cells[mCol, cFunc] = sFunc[2] then
  1670. TOQBForm(GetParentForm(Self)).mnuFunc.Items[2].Checked := True
  1671. else if Cells[mCol, cFunc] = sFunc[3] then
  1672. TOQBForm(GetParentForm(Self)).mnuFunc.Items[3].Checked := True
  1673. else if Cells[mCol, cFunc] = sFunc[4] then
  1674. TOQBForm(GetParentForm(Self)).mnuFunc.Items[4].Checked := True
  1675. else if Cells[mCol, cFunc] = sFunc[5] then
  1676. TOQBForm(GetParentForm(Self)).mnuFunc.Items[5].Checked := True
  1677. else
  1678. TOQBForm(GetParentForm(Self)).mnuFunc.Items[6].Checked := True;
  1679. TOQBForm(GetParentForm(Self)).mnuFunc.Popup(P.X, P.Y);
  1680. end;
  1681. cGroup:
  1682. begin
  1683. TOQBForm(GetParentForm(Self)).mnuGroup.Items[0].Checked := Cells[mCol, cGroup] = sGroup;
  1684. TOQBForm(GetParentForm(Self)).mnuGroup.Popup(P.X, P.Y);
  1685. end;
  1686. end;
  1687. end;
  1688. end;
  1689. function TOQBGrid.SelectCell(ACol, ARow: Integer): Boolean;
  1690. begin
  1691. inherited SelectCell(ACol, ARow);
  1692. Result := ARow > cGroup;
  1693. end;
  1694. procedure TOQBGrid._DragOver(Sender, Source: TObject; X, Y: Integer;
  1695. State: TDragState; var Accept: Boolean);
  1696. begin
  1697. if (Source <> TOQBForm(GetParentForm(Self)).QBTables) then
  1698. Accept := True;
  1699. end;
  1700. procedure TOQBGrid._DragDrop(Sender, Source: TObject; X, Y: Integer);
  1701. var
  1702. dCol, dRow: Integer;
  1703. begin
  1704. if ((Source is TOQBLbx) and
  1705. (Source <> TOQBForm(GetParentForm(Self)).QBTables)) then
  1706. begin
  1707. TOQBTable(TWinControl(Source).Parent).FLbx.Checked[
  1708. TOQBTable(TWinControl(Source).Parent).FLbx.ItemIndex] := True;//*** check
  1709. MouseToCell(X, Y, dCol, dRow);
  1710. if dCol = 0 then
  1711. Exit;
  1712. Insert(dCol,
  1713. TOQBTable(TWinControl(Source).Parent).FLbx.Items[TOQBTable(TWinControl(Source).Parent).FLbx.ItemIndex],
  1714. TOQBTable(TWinControl(Source).Parent).FTableName);
  1715. end;
  1716. end;
  1717. { TOQBForm }
  1718. procedure TOQBForm.CreateParams(var Params: TCreateParams);
  1719. begin
  1720. inherited;
  1721. QBArea := TOQBArea.Create(Self);
  1722. QBArea.Parent := QBPanel;
  1723. QBArea.Align := alClient;
  1724. QBArea.Color := $009E9E9E;
  1725. QBGrid := TOQBGrid.Create(Self);
  1726. QBGrid.DefaultRowHeight := 22;
  1727. QBGrid.DefaultColWidth := 150;
  1728. QBGrid.Parent := TabColumns;
  1729. QBGrid.Align := alClient;
  1730. VSplitter.Tag := VSplitter.Left;
  1731. HSplitter.Tag := HSplitter.Top;
  1732. Application.ProcessMessages;
  1733. end;
  1734. procedure TOQBForm.mnuFunctionClick(Sender: TObject);
  1735. var
  1736. Item: TMenuItem;
  1737. begin
  1738. if Sender is TMenuItem then
  1739. begin
  1740. Item := (Sender as TMenuItem);
  1741. if not Item.Checked then
  1742. begin
  1743. Item.Checked := True;
  1744. QBGrid.Cells[QBGrid.CurrCol, cFunc] := sFunc[Item.Tag];
  1745. end;
  1746. end;
  1747. end;
  1748. procedure TOQBForm.mnuGroupClick(Sender: TObject);
  1749. begin
  1750. if mnuGroup.Items[0].Checked then
  1751. begin
  1752. QBGrid.Cells[QBGrid.CurrCol, cGroup] := '';
  1753. mnuGroup.Items[0].Checked := False;
  1754. end
  1755. else
  1756. begin
  1757. QBGrid.Cells[QBGrid.CurrCol, cGroup] := sGroup;
  1758. mnuGroup.Items[0].Checked := True;
  1759. end;
  1760. end;
  1761. procedure TOQBForm.mnuRemoveClick(Sender: TObject);
  1762. var
  1763. TempTable: TOQBTable;
  1764. begin
  1765. TempTable := QBArea.FindTable(QBGrid.Cells[QBGrid.CurrCol, cTbl]);
  1766. if not QBGrid.FindSameColumn(QBGrid.CurrCol) then
  1767. TempTable.FLbx.Checked[TempTable.FLbx.Items.IndexOf(QBGrid.Cells[QBGrid.CurrCol, cFld])] := False;
  1768. QBGrid.RemoveColumn(QBGrid.CurrCol);
  1769. QBGrid.Refresh; // fix for StringGrid bug
  1770. end;
  1771. procedure TOQBForm.mnuShowClick(Sender: TObject);
  1772. begin
  1773. if mnuShow.Items[0].Checked then
  1774. begin
  1775. QBGrid.Cells[QBGrid.CurrCol, cShow] := '';
  1776. mnuShow.Items[0].Checked := False;
  1777. end
  1778. else
  1779. begin
  1780. QBGrid.Cells[QBGrid.CurrCol, cShow] := sShow;
  1781. mnuShow.Items[0].Checked := True;
  1782. end;
  1783. end;
  1784. procedure TOQBForm.mnuSortClick(Sender: TObject);
  1785. var
  1786. Item: TMenuItem;
  1787. begin
  1788. if Sender is TMenuItem then
  1789. begin
  1790. Item := (Sender as TMenuItem);
  1791. if not Item.Checked then
  1792. begin
  1793. Item.Checked := True;
  1794. QBGrid.Cells[QBGrid.CurrCol, cSort] := sSort[Item.Tag];
  1795. end;
  1796. end;
  1797. end;
  1798. procedure TOQBForm.ClearAll;
  1799. var
  1800. i: Integer;
  1801. TempTable: TOQBTable;
  1802. begin
  1803. for i := QBArea.ControlCount - 1 downto 0 do
  1804. if QBArea.Controls[i] is TOQBTable then
  1805. begin
  1806. TempTable := TOQBTable(QBArea.Controls[i]);
  1807. QBGrid.RemoveColumn4Tbl(TempTable.FTableName);
  1808. TempTable.Free;
  1809. end
  1810. else
  1811. QBArea.Controls[i].Free; // QBLink
  1812. MemoSQL.Lines.Clear;
  1813. QBDialog.OQBEngine.ResultQuery.Close;
  1814. QBDialog.OQBEngine.ClearQuerySQL;
  1815. Pages.ActivePage := TabColumns;
  1816. end;
  1817. procedure TOQBForm.btnNewClick(Sender: TObject);
  1818. begin
  1819. ClearAll;
  1820. end;
  1821. procedure TOQBForm.btnOpenClick(Sender: TObject);
  1822. var
  1823. i, ii, j: Integer;
  1824. s, ss: string;
  1825. TempDatabaseName: string;
  1826. ShowSystemTables: Boolean;
  1827. NewTable: TOQBTable;
  1828. TableName: string;
  1829. X, Y: Integer;
  1830. NewLink: TOQBLink;
  1831. Table1, Table2: TOQBTable;
  1832. FieldN1, FieldN2: Integer;
  1833. ColField, ColTable: string;
  1834. StrList: TStringList;
  1835. function GetNextVal(var s: string): string;
  1836. var
  1837. p: Integer;
  1838. begin
  1839. Result := EmptyStr;
  1840. p := Pos(',', s);
  1841. if p = 0 then
  1842. begin
  1843. p := Pos(';', s);
  1844. if p = 0 then
  1845. Exit;
  1846. end;
  1847. Result := System.Copy(s, 1, p - 1);
  1848. System.Delete(s, 1, p);
  1849. end;
  1850. begin
  1851. j := -1;
  1852. if not DlgOpen.Execute then
  1853. Exit;
  1854. StrList := TStringList.Create;
  1855. StrList.LoadFromFile(DlgOpen.FileName);
  1856. if StrList[0] <> QBSignature then
  1857. begin
  1858. ShowMessage('File ' + DlgOpen.FileName + ' is not QBuilder''s query file.');
  1859. StrList.Free;
  1860. Exit;
  1861. end;
  1862. ClearAll;
  1863. try
  1864. s := StrList[3]; // read options
  1865. if s = '+' then
  1866. WindowState := wsMaximized
  1867. else
  1868. begin
  1869. WindowState := wsNormal;
  1870. Top := StrToInt(GetNextVal(s));
  1871. Left := StrToInt(GetNextVal(s));
  1872. Height := StrToInt(GetNextVal(s));
  1873. Width := StrToInt(GetNextVal(s));
  1874. end;
  1875. s := StrList[4];
  1876. btnTables.Down := Boolean(StrToInt(GetNextVal(s)));
  1877. VSplitter.Visible := btnTables.Down;
  1878. QBTables.Visible := btnTables.Down;
  1879. QBTables.Width := StrToInt(GetNextVal(s));
  1880. btnPages.Down := Boolean(StrToInt(GetNextVal(s)));
  1881. HSplitter.Visible := btnPages.Down;
  1882. Pages.Visible := btnPages.Down;
  1883. Pages.Height := StrToInt(GetNextVal(s));
  1884. s := StrList[6]; // read database
  1885. TempDatabaseName := GetNextVal(s);
  1886. ShowSystemTables := Boolean(StrToInt(GetNextVal(s)));
  1887. QBDialog.OQBEngine.DatabaseName := TempDatabaseName;
  1888. QBDialog.OQBEngine.ShowSystemTables := ShowSystemTables;
  1889. OpenDatabase;
  1890. for i := 8 to StrList.Count - 1 do // read tables
  1891. begin
  1892. if StrList[i] = '[Links]' then
  1893. begin
  1894. j := i + 1;
  1895. Break;
  1896. end;
  1897. s := StrList[i];
  1898. TableName := GetNextVal(s);
  1899. Y := StrToInt(GetNextVal(s));
  1900. X := StrToInt(GetNextVal(s));
  1901. NewTable := TOQBTable.Create(Self);
  1902. NewTable.Parent := QBArea;
  1903. try
  1904. NewTable.Activate(TableName, X, Y);
  1905. NewTable.FLbx.FLoading := True;
  1906. for ii := 0 to NewTable.FLbx.Items.Count - 1 do
  1907. begin
  1908. ss := GetNextVal(s);
  1909. if ss <> EmptyStr then
  1910. NewTable.FLbx.Checked[ii] := Boolean(StrToInt(ss));
  1911. end;
  1912. NewTable.FLbx.FLoading := False;
  1913. except
  1914. NewTable.Free;
  1915. end;
  1916. end;
  1917. if j <> -1 then
  1918. for i := j to StrList.Count - 1 do // read links
  1919. begin
  1920. if StrList[i] = '[Columns]' then
  1921. begin
  1922. j := i + 1;
  1923. Break;
  1924. end;
  1925. s := StrList[i];
  1926. ss := GetNextVal(s);
  1927. Table1 := QBArea.FindTable(ss);
  1928. ss := GetNextVal(s);
  1929. FieldN1 := StrToInt(ss);
  1930. ss := GetNextVal(s);
  1931. Table2 := QBArea.FindTable(ss);
  1932. ss := GetNextVal(s);
  1933. FieldN2 := StrToInt(ss);
  1934. NewLink := QBArea.InsertLink(Table1, Table2, FieldN1, FieldN2);
  1935. ss := GetNextVal(s);
  1936. NewLink.FLinkOpt := StrToInt(ss);
  1937. ss := GetNextVal(s);
  1938. NewLink.FLinkType := StrToInt(ss);
  1939. end;
  1940. if j <> -1 then
  1941. for i := j to StrList.Count - 1 do // read columns
  1942. begin
  1943. if StrList[i] = '[End]' then
  1944. Break;
  1945. s := StrList[i];
  1946. ii := StrToInt(GetNextVal(s));
  1947. ColField := GetNextVal(s);
  1948. ColTable := GetNextVal(s);
  1949. QBGrid.Insert(ii, ColField, ColTable);
  1950. QBGrid.Cells[ii, cShow] := GetNextVal(s);
  1951. QBGrid.Cells[ii, cSort] := GetNextVal(s);
  1952. QBGrid.Cells[ii, cFunc] := GetNextVal(s);
  1953. QBGrid.Cells[ii, cGroup] := GetNextVal(s);
  1954. end;
  1955. finally
  1956. StrList.Free;
  1957. end;
  1958. end;
  1959. procedure TOQBForm.btnSaveClick(Sender: TObject);
  1960. var
  1961. i, j: Integer;
  1962. s: string;
  1963. TempTable: TOQBTable;
  1964. TempLink: TOQBLink;
  1965. StrList: TStringList;
  1966. begin
  1967. if not DlgSave.Execute then Exit;
  1968. StrList := TStringList.Create;
  1969. StrList.Add(QBSignature);
  1970. StrList.Add('# Don''t change this file !');
  1971. StrList.Add('[Options]');
  1972. if WindowState = wsMaximized then
  1973. s := '+' else
  1974. s := IntToStr(Top) + ',' + IntToStr(Left) + ',' + IntToStr(Height) + ',' +
  1975. IntToStr(Width) + ';';
  1976. StrList.Add(s);
  1977. s := IntToStr(Integer(btnTables.Down)) + ',' + IntToStr(QBTables.Width) +
  1978. ',' + IntToStr(Integer(btnPages.Down)) + ',' + IntToStr(Pages.Height) + ';';
  1979. StrList.Add(s);
  1980. StrList.Add('[Database]');
  1981. s := QBDialog.OQBEngine.DatabaseName + ',' + IntToStr(Integer(QBDialog.OQBEngine.ShowSystemTables)) + ';';
  1982. StrList.Add(s);
  1983. StrList.Add('[Tables]'); // save tables
  1984. for i := 0 to QBArea.ControlCount - 1 do
  1985. if QBArea.Controls[i] is TOQBTable then
  1986. begin
  1987. TempTable := TOQBTable(QBArea.Controls[i]);
  1988. s := TempTable.FTableName + ',' +
  1989. IntToStr(TempTable.Top + QBArea.VertScrollBar.ScrollPos) + ',' +
  1990. IntToStr(TempTable.Left + QBArea.HorzScrollBar.ScrollPos);
  1991. for j := 0 to TempTable.FLbx.Items.Count - 1 do
  1992. if TempTable.FLbx.Checked[j] then
  1993. s := s + ',1' else
  1994. s := s + ',0';
  1995. s := s + ';';
  1996. StrList.Add(s);
  1997. end;
  1998. StrList.Add('[Links]'); // save links
  1999. for i := 0 to QBArea.ControlCount - 1 do
  2000. if QBArea.Controls[i] is TOQBLink then
  2001. begin
  2002. TempLink := TOQBLink(QBArea.Controls[i]);
  2003. s := TempLink.Tbl1.FTableName + ',' + IntToStr(TempLink.FldN1) + ',' +
  2004. TempLink.Tbl2.FTableName + ',' + IntToStr(TempLink.FldN2) + ',' +
  2005. IntToStr(TempLink.FLinkOpt) + ',' + IntToStr(TempLink.FLinkType);
  2006. s := s + ';';
  2007. StrList.Add(s);
  2008. end;
  2009. StrList.Add('[Columns]'); // save columns
  2010. if not QBGrid.IsEmpty then
  2011. for i := 1 to QBGrid.ColCount - 1 do
  2012. begin
  2013. s := IntToStr(i) + ',' + QBGrid.Cells[i, cFld] + ',' + QBGrid.Cells[i, cTbl];
  2014. s := s + ',' + QBGrid.Cells[i, cShow] + ',' + QBGrid.Cells[i, cSort] +
  2015. ',' + QBGrid.Cells[i, cFunc] + ',' + QBGrid.Cells[i, cGroup];
  2016. s := s + ';';
  2017. StrList.Add(s);
  2018. end;
  2019. StrList.Add('[End]'); // end of QBuilder information
  2020. StrList.SaveToFile(DlgSave.FileName);
  2021. StrList.Free;
  2022. end;
  2023. procedure TOQBForm.btnTablesClick(Sender: TObject);
  2024. begin
  2025. VSplitter.Visible := TToolButton(Sender).Down;
  2026. QBTables.Visible := TToolButton(Sender).Down;
  2027. if not VSplitter.Visible then
  2028. VSplitter.Tag := VSplitter.Left
  2029. else
  2030. VSplitter.Left := VSplitter.Tag;
  2031. end;
  2032. procedure TOQBForm.btnPagesClick(Sender: TObject);
  2033. begin
  2034. HSplitter.Visible := TToolButton(Sender).Down;
  2035. Pages.Visible := TToolButton(Sender).Down;
  2036. if not HSplitter.Visible then
  2037. HSplitter.Tag := HSplitter.Top
  2038. else
  2039. HSplitter.Top := HSplitter.Tag;
  2040. end;
  2041. procedure TOQBForm.OpenDatabase;
  2042. begin
  2043. try
  2044. QBDialog.OQBEngine.ReadTableList;
  2045. QBDialog.OQBEngine.GenerateAliases;
  2046. QBTables.Items.Assign(QBDialog.OQBEngine.TableList);
  2047. ResDataSource.DataSet := QBDialog.OQBEngine.ResultQuery;
  2048. Caption := sMainCaption + ' [' + QBDialog.OQBEngine.DatabaseName + ']';
  2049. except
  2050. // ignore errors
  2051. end;
  2052. end;
  2053. procedure TOQBForm.SelectDatabase;
  2054. begin
  2055. if QBDialog.OQBEngine.SelectDatabase then
  2056. begin
  2057. ClearAll;
  2058. QBTables.Items.Clear;
  2059. OpenDatabase;
  2060. end
  2061. end;
  2062. procedure TOQBForm.btnDBClick(Sender: TObject);
  2063. begin
  2064. SelectDatabase;
  2065. end;
  2066. procedure TOQBForm.btnSQLClick(Sender: TObject);
  2067. var
  2068. Lst, Lst1, Lst2: TStringList; // temporary string lists
  2069. i: Integer;
  2070. s: string;
  2071. tbl1, tbl2: string;
  2072. Link: TOQBLink;
  2073. function ExtractName(s: string):string;
  2074. var
  2075. p: Integer;
  2076. begin
  2077. Result := s;
  2078. p := Pos('.', s);
  2079. if p = 0 then
  2080. Exit;
  2081. Result := System.Copy(s, 1, p - 1);
  2082. end;
  2083. begin
  2084. if QBGrid.IsEmpty then
  2085. begin
  2086. ShowMessage('Columns are not selected.');
  2087. Exit;
  2088. end;
  2089. Lst := TStringList.Create;
  2090. try
  2091. with QBDialog.OQBEngine do
  2092. begin
  2093. SQLcolumns.Clear;
  2094. SQLcolumns_func.Clear;
  2095. SQLcolumns_table.Clear;
  2096. SQLfrom.Clear;
  2097. SQLwhere.Clear;
  2098. SQLgroupby.Clear;
  2099. SQLorderby.Clear;
  2100. end;
  2101. // SELECT clause
  2102. with QBGrid do
  2103. begin
  2104. for i := 1 to ColCount - 1 do
  2105. if Cells[i, cShow] = sShow then
  2106. begin
  2107. if QBDialog.OQBEngine.UseTableAliases then
  2108. tbl1 := QBDialog.OQBEngine.AliasList[QBDialog.OQBEngine.TableList.IndexOf(Cells[i, cTbl])]
  2109. else
  2110. tbl1 := Cells[i, cTbl];
  2111. s := tbl1 + '.' + Cells[i, cFld];
  2112. Lst.Add(LowerCase(s));
  2113. if Cells[i, cFunc] <> EmptyStr then
  2114. s := UpperCase(Cells[i, cFunc]) else
  2115. s := EmptyStr;
  2116. if QBDialog.OQBEngine.UseTableAliases then
  2117. QBDialog.OQBEngine.SQLcolumns_table.Add(LowerCase(
  2118. QBDialog.OQBEngine.AliasList[QBDialog.OQBEngine.TableList.IndexOf(Cells[i, cTbl])]))
  2119. else
  2120. QBDialog.OQBEngine.SQLcolumns_table.Add(LowerCase(Cells[i, cTbl]));
  2121. QBDialog.OQBEngine.SQLcolumns_func.Add(s);
  2122. end;
  2123. if Lst.Count = 0 then
  2124. begin
  2125. ShowMessage('Columns are not selected.');
  2126. Lst.Free;
  2127. Exit;
  2128. end;
  2129. QBDialog.OQBEngine.SQLcolumns.Assign(Lst);
  2130. Lst.Clear;
  2131. end;
  2132. // FROM clause
  2133. with QBArea do
  2134. begin
  2135. Lst1 := TSTringList.Create; // tables in joins
  2136. Lst2 := TSTringList.Create; // outer joins
  2137. for i := 0 to ControlCount - 1 do // search tables for joins
  2138. if Controls[i] is TOQBLink then
  2139. begin
  2140. Link := TOQBLink(Controls[i]);
  2141. if Link.FLinkType > 0 then
  2142. begin
  2143. if QBDialog.OQBEngine.UseTableAliases then
  2144. begin
  2145. tbl1 := LowerCase(Link.Tbl1.FTableAlias);
  2146. tbl2 := LowerCase(Link.Tbl2.FTableAlias);
  2147. end
  2148. else
  2149. begin
  2150. tbl1 := LowerCase(Link.Tbl1.FTableName);
  2151. tbl2 := LowerCase(Link.Tbl2.FTableName);
  2152. end;
  2153. if Lst1.IndexOf(tbl1) = -1 then
  2154. Lst1.Add(tbl1);
  2155. if Lst1.IndexOf(tbl2) = -1 then
  2156. Lst1.Add(tbl2);
  2157. if QBDialog.OQBEngine.UseTableAliases then
  2158. Lst2.Add(LowerCase(Link.Tbl1.FTableName) + ' ' + tbl1 +
  2159. sOuterJoin[Link.FLinkType] +
  2160. LowerCase(Link.Tbl2.FTableName) + ' ' + tbl2 + ' ON ' +
  2161. tbl1 + '.' + LowerCase(Link.FldNam1) + sLinkOpt[Link.FLinkOpt] +
  2162. tbl2 + '.' + LowerCase(Link.FldNam2))
  2163. else
  2164. Lst2.Add(tbl1 + sOuterJoin[Link.FLinkType] + tbl2 + ' ON ' +
  2165. tbl1 + '.' + LowerCase(Link.FldNam1) +
  2166. sLinkOpt[Link.FLinkOpt] + tbl2 + '.' + LowerCase(Link.FldNam2));
  2167. end;
  2168. end;
  2169. for i := 0 to ControlCount - 1 do
  2170. if Controls[i] is TOQBTable then
  2171. begin
  2172. if QBDialog.OQBEngine.UseTableAliases then
  2173. tbl1 := LowerCase(TOQBTable(Controls[i]).FTableAlias) else
  2174. tbl1 := LowerCase(TOQBTable(Controls[i]).FTableName);
  2175. if (Lst.IndexOf(tbl1) = -1) and (Lst1.IndexOf(tbl1) = -1) then
  2176. if QBDialog.OQBEngine.UseTableAliases then
  2177. Lst.Add(LowerCase(TOQBTable(Controls[i]).FTableName) + ' ' + tbl1) else
  2178. Lst.Add(tbl1);
  2179. end;
  2180. Lst1.Free;
  2181. QBDialog.OQBEngine.SQLfrom.Assign(Lst2);
  2182. QBDialog.OQBEngine.SQLfrom.AddStrings(Lst);
  2183. Lst2.Free;
  2184. Lst.Clear;
  2185. end;
  2186. // WHERE clause
  2187. with QBArea do
  2188. begin
  2189. for i := 0 to ControlCount - 1 do
  2190. if Controls[i] is TOQBLink then
  2191. begin
  2192. Link := TOQBLink(Controls[i]);
  2193. if Link.FLinkType = 0 then
  2194. begin
  2195. if QBDialog.OQBEngine.UseTableAliases then
  2196. s := Link.tbl1.FTableAlias + '.' + Link.fldNam1 + sLinkOpt[Link.FLinkOpt] +
  2197. Link.tbl2.FTableAlias + '.' + Link.fldNam2
  2198. else
  2199. s := Link.tbl1.FTableName + '.' + Link.fldNam1 + sLinkOpt[Link.FLinkOpt] +
  2200. Link.tbl2.FTableName + '.' + Link.fldNam2;
  2201. Lst.Add(LowerCase(s));
  2202. end;
  2203. end;
  2204. QBDialog.OQBEngine.SQLwhere.Assign(Lst);
  2205. Lst.Clear;
  2206. end;
  2207. // GROUP BY clause
  2208. with QBGrid do
  2209. begin
  2210. for i := 1 to ColCount - 1 do
  2211. begin
  2212. if Cells[i, cGroup] <> EmptyStr then
  2213. begin
  2214. if QBDialog.OQBEngine.UseTableAliases then
  2215. tbl1 := QBDialog.OQBEngine.AliasList[QBDialog.OQBEngine.TableList.IndexOf(Cells[i, cTbl])]
  2216. else
  2217. tbl1 := Cells[i, cTbl];
  2218. s := tbl1 + '.' + Cells[i, cFld];
  2219. Lst.Add(LowerCase(s));
  2220. end;
  2221. end;
  2222. QBDialog.OQBEngine.SQLgroupby.Assign(Lst);
  2223. Lst.Clear;
  2224. end;
  2225. // ORDER BY clause
  2226. with QBGrid do
  2227. begin
  2228. for i := 1 to ColCount - 1 do
  2229. begin
  2230. if Cells[i, cSort] <> EmptyStr then
  2231. begin
  2232. if QBDialog.OQBEngine.UseTableAliases then
  2233. tbl1 := QBDialog.OQBEngine.AliasList[QBDialog.OQBEngine.TableList.IndexOf(Cells[i, cTbl])]
  2234. else
  2235. tbl1 := Cells[i, cTbl];
  2236. // --- to order result set by the result of an aggregate function
  2237. if Cells[i, cFunc] = EmptyStr then
  2238. s := LowerCase(tbl1 + '.' + Cells[i, cFld]) else
  2239. s := IntToStr(i);
  2240. // ---
  2241. if Cells[i, cSort] = sSort[3] then
  2242. s := s + ' DESC';
  2243. Lst.Add(s);
  2244. end;
  2245. end;
  2246. QBDialog.OQBEngine.SQLorderby.Assign(Lst);
  2247. Lst.Clear;
  2248. end;
  2249. MemoSQL.Lines.Text := QBDialog.OQBEngine.GenerateSQL;
  2250. Pages.ActivePage := TabSQL;
  2251. finally
  2252. Lst.Free;
  2253. end;
  2254. end;
  2255. procedure TOQBForm.btnResultsClick(Sender: TObject);
  2256. begin
  2257. // We may be able to generate the SQL if the user has
  2258. // visually created one
  2259. if MemoSQL.Lines.Text='' then
  2260. btnSQLClick(Sender);
  2261. QBDialog.OQBEngine.CloseResultQuery; // OQB 4.0a
  2262. QBDialog.OQBEngine.SetQuerySQL(MemoSQL.Lines.Text);
  2263. QBDialog.OQBEngine.OpenResultQuery;
  2264. Pages.ActivePage := TabResults;
  2265. end;
  2266. procedure TOQBForm.btnAboutClick(Sender: TObject);
  2267. var
  2268. QBAboutForm: TOQBAboutForm;
  2269. begin
  2270. QBAboutForm := TOQBAboutForm.Create(Application);
  2271. QBAboutForm.ShowModal;
  2272. QBAboutForm.Free;
  2273. end;
  2274. procedure TOQBForm.btnSaveResultsClick(Sender: TObject);
  2275. begin
  2276. QBDialog.OQBEngine.SaveResultQueryData;
  2277. end;
  2278. procedure TOQBForm.btnOKClick(Sender: TObject);
  2279. begin
  2280. ModalResult := mrOk;
  2281. end;
  2282. procedure TOQBForm.btnCancelClick(Sender: TObject);
  2283. begin
  2284. ModalResult := mrCancel;
  2285. end;
  2286. end.