|
@@ -0,0 +1,2489 @@
|
|
|
|
+{*******************************************************}
|
|
|
|
+{ }
|
|
|
|
+{ Delphi Visual Component Library }
|
|
|
|
+{ QBuilder dialog component }
|
|
|
|
+{ }
|
|
|
|
+{ Copyright (c) 1996-2003 Sergey Orlik }
|
|
|
|
+{ }
|
|
|
|
+{ Written by: }
|
|
|
|
+{ Sergey Orlik }
|
|
|
|
+{ product manager }
|
|
|
|
+{ Russia, C.I.S. and Baltic States (former USSR) }
|
|
|
|
+{ Borland Moscow office }
|
|
|
|
+{ Internet: [email protected], }
|
|
|
|
+{ [email protected] }
|
|
|
|
+{ http://www.fast-report.com }
|
|
|
|
+{ }
|
|
|
|
+{ Converted to Lazarus/Free Pascal by Jean Patrick }
|
|
|
|
+{ Data: 14/02/2013 }
|
|
|
|
+{ E-mail: [email protected] }
|
|
|
|
+{ }
|
|
|
|
+{ Modifications by Reinier Olislagers, 2014 }
|
|
|
|
+{*******************************************************}
|
|
|
|
+
|
|
|
|
+unit QBuilder;
|
|
|
|
+
|
|
|
|
+{$IFDEF FPC}
|
|
|
|
+ {$MODE Delphi}
|
|
|
|
+{$ENDIF}
|
|
|
|
+
|
|
|
|
+interface
|
|
|
|
+
|
|
|
|
+uses
|
|
|
|
+ SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
|
|
|
+ Buttons, ExtCtrls, StdCtrls, ComCtrls, Menus, CheckLst, Grids,
|
|
|
|
+ DB, DBGrids, LMessages, LCLIntf, LCLType, LCLProc,
|
|
|
|
+ GraphType, InterfaceBase;
|
|
|
|
+
|
|
|
|
+type
|
|
|
|
+ TOQBbutton = (bSelectDBDialog, bOpenDialog, bSaveDialog,
|
|
|
|
+ bRunQuery, bSaveResultsDialog);
|
|
|
|
+ TOQBbuttons = set of TOQBbutton;
|
|
|
|
+
|
|
|
|
+ TOQBEngine = class;
|
|
|
|
+
|
|
|
|
+ { TOQBuilderDialog }
|
|
|
|
+
|
|
|
|
+ TOQBuilderDialog = class(TComponent)
|
|
|
|
+ private
|
|
|
|
+ FDatabase: string;
|
|
|
|
+ FSystemTables: Boolean;
|
|
|
|
+ FOQBForm: TForm;
|
|
|
|
+ FSQL: TStrings;
|
|
|
|
+ FOQBEngine: TOQBEngine;
|
|
|
|
+ FShowButtons: TOQBbuttons;
|
|
|
|
+ procedure SetOQBEngine(const Value: TOQBEngine);
|
|
|
|
+ protected
|
|
|
|
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
|
|
+ public
|
|
|
|
+ constructor Create(AOwner: TComponent); override;
|
|
|
|
+ destructor Destroy; override;
|
|
|
|
+ function Execute: Boolean; virtual;
|
|
|
|
+ property SQL: TStrings read FSQL;
|
|
|
|
+ property SystemTables: Boolean read FSystemTables write FSystemTables default False;
|
|
|
|
+ property Database: string read FDatabase write FDatabase;
|
|
|
|
+ published
|
|
|
|
+ property OQBEngine: TOQBEngine read FOQBEngine write SetOQBEngine;
|
|
|
|
+ property ShowButtons: TOQBbuttons read FShowButtons write FShowButtons
|
|
|
|
+ default [bSelectDBDialog, bOpenDialog, bSaveDialog, bRunQuery, bSaveResultsDialog];
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ TOQBEngine = class(TComponent)
|
|
|
|
+ private
|
|
|
|
+ FDatabaseName: string;
|
|
|
|
+ FUserName: string;
|
|
|
|
+ FPassword: string;
|
|
|
|
+ FShowSystemTables: Boolean;
|
|
|
|
+ FTableList: TStringList;
|
|
|
|
+ FAliasList: TStringList;
|
|
|
|
+ FFieldList: TStringList;
|
|
|
|
+ FSQL: TStringList;
|
|
|
|
+ FSQLcolumns: TStringList;
|
|
|
|
+ FSQLcolumns_table: TStringList;
|
|
|
|
+ FSQLcolumns_func: TStringList;
|
|
|
|
+ FSQLfrom: TStringList;
|
|
|
|
+ FSQLwhere: TStringList;
|
|
|
|
+ FSQLgroupby: TStringList;
|
|
|
|
+ FSQLorderby: TStringList;
|
|
|
|
+ FUseTableAliases: Boolean;
|
|
|
|
+ FOQBDialog: TOQBuilderDialog;
|
|
|
|
+ procedure SetShowSystemTables(const Value: Boolean);
|
|
|
|
+ protected
|
|
|
|
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
|
|
+ procedure SetDatabaseName(const Value: string); virtual;
|
|
|
|
+ procedure SetUserName(const Value: string); virtual;
|
|
|
|
+ procedure SetPassword(const Value: string); virtual;
|
|
|
|
+ procedure SetQuerySQL(const Value: string); virtual; abstract;
|
|
|
|
+ procedure GenerateAliases; virtual;
|
|
|
|
+ // Read list of tables (system tables etc) into FTableList
|
|
|
|
+ procedure ReadTableList; virtual; abstract;
|
|
|
|
+ procedure ReadFieldList(const ATableName: string); virtual; abstract;
|
|
|
|
+ public
|
|
|
|
+ constructor Create(AOwner: TComponent); override;
|
|
|
|
+ destructor Destroy; override;
|
|
|
|
+ function SelectDatabase: Boolean; virtual; abstract;
|
|
|
|
+ function GenerateSQL: string; virtual;
|
|
|
|
+ procedure ClearQuerySQL; virtual; abstract;
|
|
|
|
+ function ResultQuery: TDataSet; virtual; abstract;
|
|
|
|
+ procedure OpenResultQuery; virtual; abstract;
|
|
|
|
+ procedure CloseResultQuery; virtual; abstract;
|
|
|
|
+ procedure SaveResultQueryData; virtual; abstract;
|
|
|
|
+ // All tables in the database
|
|
|
|
+ property TableList: TStringList read FTableList;
|
|
|
|
+ property AliasList: TStringList read FAliasList;
|
|
|
|
+ property FieldList: TStringList read FFieldList;
|
|
|
|
+ property SQL: TStringList read FSQL;
|
|
|
|
+ property SQLcolumns: TStringList read FSQLcolumns;
|
|
|
|
+ property SQLcolumns_table: TStringList read FSQLcolumns_table;
|
|
|
|
+ property SQLcolumns_func: TStringList read FSQLcolumns_func;
|
|
|
|
+ property SQLfrom: TStringList read FSQLfrom;
|
|
|
|
+ property SQLwhere: TStringList read FSQLwhere;
|
|
|
|
+ property SQLgroupby: TStringList read FSQLgroupby;
|
|
|
|
+ property SQLorderby: TStringList read FSQLorderby;
|
|
|
|
+ property UserName: string read FUserName write SetUserName;
|
|
|
|
+ property Password: string read FPassword write SetPassword;
|
|
|
|
+ published
|
|
|
|
+ property DatabaseName: string read FDatabaseName write SetDatabaseName;
|
|
|
|
+ property ShowSystemTables: Boolean read FShowSystemTables write SetShowSystemTables default False;
|
|
|
|
+ property UseTableAliases: Boolean read FUseTableAliases write FUseTableAliases default True;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+type
|
|
|
|
+ TArr = array [0..0] of Integer;
|
|
|
|
+ PArr = ^TArr;
|
|
|
|
+
|
|
|
|
+ { TOQBLbx }
|
|
|
|
+
|
|
|
|
+ TOQBLbx = class(TCheckListBox)
|
|
|
|
+ private
|
|
|
|
+ FArrBold: PArr;
|
|
|
|
+ FLoading: Boolean;
|
|
|
|
+// procedure CNDrawItem(var Message: TWMDrawItem); message CN_DrawItem;
|
|
|
|
+ procedure WMLButtonDown(var Message: TLMLButtonDblClk); message LM_LBUTTONDOWN;
|
|
|
|
+ procedure WMRButtonDown(var Message: TLMRButtonDblClk); message LM_RBUTTONDOWN;
|
|
|
|
+ function GetCheckW: Integer;
|
|
|
|
+ procedure AllocArrBold;
|
|
|
|
+ procedure SelectItemBold(Item: Integer);
|
|
|
|
+ procedure UnSelectItemBold(Item: Integer);
|
|
|
|
+ function GetItemY(Item: Integer): Integer;
|
|
|
|
+ public
|
|
|
|
+ constructor Create(AOwner: TComponent); override;
|
|
|
|
+ destructor Destroy; override;
|
|
|
|
+// procedure ClickCheck; override;
|
|
|
|
+ procedure ItemClick(const AIndex: Integer); override;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ TOQBTable = class(TPanel)
|
|
|
|
+ private
|
|
|
|
+ ScreenDC: HDC;
|
|
|
|
+ OldX: Integer;
|
|
|
|
+ OldY: Integer;
|
|
|
|
+ OldLeft: Integer;
|
|
|
|
+ OldTop: Integer;
|
|
|
|
+ ClipRgn: HRGN;
|
|
|
|
+ ClipRect: TRect;
|
|
|
|
+ MoveRect: TRect;
|
|
|
|
+ Moving: Boolean;
|
|
|
|
+ FCloseBtn: TSpeedButton;
|
|
|
|
+ FUnlinkBtn: TSpeedButton;
|
|
|
|
+ FLbx: TOQBLbx;
|
|
|
|
+ FTableName: string;
|
|
|
|
+ FTableAlias: string;
|
|
|
|
+ PopMenu: TPopupMenu;
|
|
|
|
+ procedure WMRButtonDown(var Message: TLMRButtonDblClk); message LM_RBUTTONDOWN;
|
|
|
|
+ function Activate(const ATableName: string; X, Y: Integer): Boolean;
|
|
|
|
+ function GetRowY(FldN: Integer):Integer;
|
|
|
|
+ procedure _CloseBtn(Sender: TObject);
|
|
|
|
+ procedure _UnlinkBtn(Sender: TObject);
|
|
|
|
+ procedure _SelectAll(Sender: TObject);
|
|
|
|
+ procedure _UnSelectAll(Sender: TObject);
|
|
|
|
+ procedure _DragOver(Sender, Source: TObject; X, Y: Integer;
|
|
|
|
+ State: TDragState; var Accept: Boolean);
|
|
|
|
+ procedure _DragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
|
|
+ protected
|
|
|
|
+ procedure SetParent(AParent: TWinControl); override;
|
|
|
|
+ procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
|
|
+ X, Y: Integer); override;
|
|
|
|
+ procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
|
|
+ procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
|
|
+ X, Y: Integer); override;
|
|
|
|
+ property Align;
|
|
|
|
+ public
|
|
|
|
+ constructor Create(AOwner: TComponent); override;
|
|
|
|
+ procedure Paint; override;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ { TOQBLink }
|
|
|
|
+
|
|
|
|
+ TOQBLink = class(TShape)
|
|
|
|
+ private
|
|
|
|
+ Tbl1: TOQBTable;
|
|
|
|
+ Tbl2: TOQBTable;
|
|
|
|
+ FldN1: Integer;
|
|
|
|
+ FldN2: Integer;
|
|
|
|
+ FldNam1: string;
|
|
|
|
+ FldNam2: string;
|
|
|
|
+ FLinkOpt: Integer;
|
|
|
|
+ FLinkType: Integer;
|
|
|
|
+ LnkX: Byte;
|
|
|
|
+ LnkY: Byte;
|
|
|
|
+ Rgn: HRgn;
|
|
|
|
+ PopMenu: TPopupMenu;
|
|
|
|
+ procedure _Click(X, Y: Integer);
|
|
|
|
+ procedure CMHitTest(var Message: TCMHitTest); message CM_HitTest;
|
|
|
|
+ function ControlAtPos(const Pos: TPoint): TControl;
|
|
|
|
+ function PtInRegion(RGN: HRGN; X, Y: Integer) : Boolean;
|
|
|
|
+ public
|
|
|
|
+ constructor Create(AOwner: TComponent); override;
|
|
|
|
+ destructor Destroy; override;
|
|
|
|
+ procedure WndProc(var Message: TLMessage); override;
|
|
|
|
+ procedure Paint; override;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ TOQBArea = class(TScrollBox)
|
|
|
|
+ public
|
|
|
|
+ procedure CreateParams(var Params: TCreateParams); override;
|
|
|
|
+ procedure SetOptions(Sender: TObject);
|
|
|
|
+ procedure InsertTable(X, Y: Integer);
|
|
|
|
+ function InsertLink(_tbl1, _tbl2: TOQBTable; _fldN1, _fldN2: Integer): TOQBLink;
|
|
|
|
+ function FindTable(const TableName: string): TOQBTable;
|
|
|
|
+ function FindLink(Link: TOQBLink): Boolean;
|
|
|
|
+ function FindOtherLink(Link: TOQBLink; Tbl: TOQBTable; FldN: Integer): Boolean;
|
|
|
|
+ procedure ReboundLink(Link: TOQBLink);
|
|
|
|
+ procedure ReboundLinks4Table(ATable: TOQBTable);
|
|
|
|
+ procedure Unlink(Sender: TObject);
|
|
|
|
+ procedure UnlinkTable(ATable: TOQBTable);
|
|
|
|
+ procedure _DragOver(Sender, Source: TObject; X, Y: Integer;
|
|
|
|
+ State: TDragState; var Accept: Boolean);
|
|
|
|
+ procedure _DragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ TOQBGrid = class(TStringGrid)
|
|
|
|
+ public
|
|
|
|
+ CurrCol: Integer;
|
|
|
|
+ IsEmpty: Boolean;
|
|
|
|
+ procedure CreateParams(var Params: TCreateParams); override;
|
|
|
|
+ procedure WndProc(var Message: TLMessage); override;
|
|
|
|
+ function MaxSW(const s1, s2: string): Integer;
|
|
|
|
+ procedure InsertDefault(aCol: Integer);
|
|
|
|
+ procedure Insert(aCol: Integer; const aField, aTable: string);
|
|
|
|
+ function FindColumn(const sCol: string): Integer;
|
|
|
|
+ function FindSameColumn(aCol: Integer): Boolean;
|
|
|
|
+ procedure RemoveColumn(aCol: Integer);
|
|
|
|
+ procedure RemoveColumn4Tbl(const Tbl: string);
|
|
|
|
+ procedure ClickCell(X, Y: Integer);
|
|
|
|
+ function SelectCell(ACol, ARow: Integer): Boolean; override;
|
|
|
|
+ procedure _DragOver(Sender, Source: TObject; X, Y: Integer;
|
|
|
|
+ State: TDragState; var Accept: Boolean);
|
|
|
|
+ procedure _DragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ TOQBForm = class(TForm)
|
|
|
|
+ QBPanel: TPanel;
|
|
|
|
+ Pages: TPageControl;
|
|
|
|
+ TabColumns: TTabSheet;
|
|
|
|
+ QBTables: TListBox;
|
|
|
|
+ VSplitter: TSplitter;
|
|
|
|
+ mnuTbl: TPopupMenu;
|
|
|
|
+ Remove1: TMenuItem;
|
|
|
|
+ mnuFunc: TPopupMenu;
|
|
|
|
+ Nofunction1: TMenuItem;
|
|
|
|
+ N1: TMenuItem;
|
|
|
|
+ Average1: TMenuItem;
|
|
|
|
+ Count1: TMenuItem;
|
|
|
|
+ Minimum1: TMenuItem;
|
|
|
|
+ Maximum1: TMenuItem;
|
|
|
|
+ Sum1: TMenuItem;
|
|
|
|
+ mnuGroup: TPopupMenu;
|
|
|
|
+ Group1: TMenuItem;
|
|
|
|
+ mnuSort: TPopupMenu;
|
|
|
|
+ Sort1: TMenuItem;
|
|
|
|
+ N2: TMenuItem;
|
|
|
|
+ Ascending1: TMenuItem;
|
|
|
|
+ Descending1: TMenuItem;
|
|
|
|
+ mnuShow: TPopupMenu;
|
|
|
|
+ Show1: TMenuItem;
|
|
|
|
+ HSplitter: TSplitter;
|
|
|
|
+ TabSQL: TTabSheet;
|
|
|
|
+ MemoSQL: TMemo;
|
|
|
|
+ TabResults: TTabSheet;
|
|
|
|
+ ResDBGrid: TDBGrid;
|
|
|
|
+ ResDataSource: TDataSource;
|
|
|
|
+ QBBar: TToolBar;
|
|
|
|
+ btnNew: TToolButton;
|
|
|
|
+ btnOpen: TToolButton;
|
|
|
|
+ btnSave: TToolButton;
|
|
|
|
+ ToolButton1: TToolButton;
|
|
|
|
+ btnTables: TToolButton;
|
|
|
|
+ ToolImages: TImageList;
|
|
|
|
+ btnPages: TToolButton;
|
|
|
|
+ ToolButton2: TToolButton;
|
|
|
|
+ DlgSave: TSaveDialog;
|
|
|
|
+ DlgOpen: TOpenDialog;
|
|
|
|
+ btnDB: TToolButton;
|
|
|
|
+ btnSQL: TToolButton;
|
|
|
|
+ btnResults: TToolButton;
|
|
|
|
+ ToolButton3: TToolButton;
|
|
|
|
+ btnAbout: TToolButton;
|
|
|
|
+ btnSaveResults: TToolButton;
|
|
|
|
+ btnOK: TToolButton;
|
|
|
|
+ btnCancel: TToolButton;
|
|
|
|
+ ToolButton6: TToolButton;
|
|
|
|
+ procedure mnuFunctionClick(Sender: TObject);
|
|
|
|
+ procedure mnuGroupClick(Sender: TObject);
|
|
|
|
+ procedure mnuRemoveClick(Sender: TObject);
|
|
|
|
+ procedure mnuShowClick(Sender: TObject);
|
|
|
|
+ procedure mnuSortClick(Sender: TObject);
|
|
|
|
+ procedure btnNewClick(Sender: TObject);
|
|
|
|
+ procedure btnOpenClick(Sender: TObject);
|
|
|
|
+ procedure btnSaveClick(Sender: TObject);
|
|
|
|
+ procedure btnTablesClick(Sender: TObject);
|
|
|
|
+ procedure btnPagesClick(Sender: TObject);
|
|
|
|
+ procedure btnDBClick(Sender: TObject);
|
|
|
|
+ procedure btnSQLClick(Sender: TObject);
|
|
|
|
+ procedure btnResultsClick(Sender: TObject);
|
|
|
|
+ procedure btnAboutClick(Sender: TObject);
|
|
|
|
+ procedure btnSaveResultsClick(Sender: TObject);
|
|
|
|
+ procedure btnOKClick(Sender: TObject);
|
|
|
|
+ procedure btnCancelClick(Sender: TObject);
|
|
|
|
+ protected
|
|
|
|
+ QBDialog: TOQBuilderDialog;
|
|
|
|
+ QBArea: TOQBArea;
|
|
|
|
+ QBGrid: TOQBGrid;
|
|
|
|
+ procedure CreateParams(var Params: TCreateParams); override;
|
|
|
|
+ procedure ClearAll;
|
|
|
|
+ procedure OpenDatabase;
|
|
|
|
+ procedure SelectDatabase;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+implementation
|
|
|
|
+
|
|
|
|
+{$R QBBUTTON.RES}
|
|
|
|
+
|
|
|
|
+uses
|
|
|
|
+ QBLnkFrm, QBAbout;
|
|
|
|
+
|
|
|
|
+ {$R *.lfm}
|
|
|
|
+
|
|
|
|
+resourcestring
|
|
|
|
+ sMainCaption = 'QBuilder';
|
|
|
|
+ sNotValidTableParent = 'Parent must be TScrollBox or its descendant.';
|
|
|
|
+
|
|
|
|
+const
|
|
|
|
+ cFld = 0;
|
|
|
|
+ cTbl = 1;
|
|
|
|
+ cShow = 2;
|
|
|
|
+ cSort = 3;
|
|
|
|
+ cFunc = 4;
|
|
|
|
+ cGroup = 5;
|
|
|
|
+
|
|
|
|
+ sShow = 'Show';
|
|
|
|
+ sGroup = 'Group';
|
|
|
|
+ sSort: array [1..3] of string =
|
|
|
|
+ ('',
|
|
|
|
+ 'Asc',
|
|
|
|
+ 'Desc');
|
|
|
|
+ sFunc: array [1..6] of string =
|
|
|
|
+ ('',
|
|
|
|
+ 'Avg',
|
|
|
|
+ 'Count',
|
|
|
|
+ 'Max',
|
|
|
|
+ 'Min',
|
|
|
|
+ 'Sum');
|
|
|
|
+
|
|
|
|
+ sLinkOpt: array [0..5] of string =
|
|
|
|
+ ('=',
|
|
|
|
+ '<',
|
|
|
|
+ '>',
|
|
|
|
+ '=<',
|
|
|
|
+ '=>',
|
|
|
|
+ '<>');
|
|
|
|
+
|
|
|
|
+ sOuterJoin: array [1..3] of string =
|
|
|
|
+ (' LEFT OUTER JOIN ',
|
|
|
|
+ ' RIGHT OUTER JOIN ',
|
|
|
|
+ ' FULL OUTER JOIN ');
|
|
|
|
+
|
|
|
|
+ Hand = 15;
|
|
|
|
+ Hand2 = 12;
|
|
|
|
+
|
|
|
|
+ QBSignature = '# QBuilder';
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+{ TQueryBuilderDialog}
|
|
|
|
+
|
|
|
|
+constructor TOQBuilderDialog.Create(AOwner: TComponent);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ FSystemTables := False;
|
|
|
|
+ FShowButtons := [bSelectDBDialog, bOpenDialog, bSaveDialog,
|
|
|
|
+ bRunQuery, bSaveResultsDialog];
|
|
|
|
+ FSQL := TStringList.Create;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+destructor TOQBuilderDialog.Destroy;
|
|
|
|
+begin
|
|
|
|
+ if FSQL <> nil then
|
|
|
|
+ FSQL.Free;
|
|
|
|
+ FOQBEngine := nil;
|
|
|
|
+ inherited;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBuilderDialog.Execute: Boolean;
|
|
|
|
+begin
|
|
|
|
+ Result := False;
|
|
|
|
+ if (not Assigned(FOQBForm)) and Assigned((FOQBEngine)) then
|
|
|
|
+ begin
|
|
|
|
+ TOQBForm(FOQBForm) := TOQBForm.Create(Application);
|
|
|
|
+ TOQBForm(FOQBForm).QBDialog := Self;
|
|
|
|
+ TOQBForm(FOQBForm).btnDB.Visible := bSelectDBDialog in FShowButtons;
|
|
|
|
+ TOQBForm(FOQBForm).btnOpen.Visible := bOpenDialog in FShowButtons;
|
|
|
|
+ TOQBForm(FOQBForm).btnSave.Visible := bSaveDialog in FShowButtons;
|
|
|
|
+ TOQBForm(FOQBForm).btnResults.Visible := bRunQuery in FShowButtons;
|
|
|
|
+ TOQBForm(FOQBForm).btnSaveResults.Visible := bSaveResultsDialog in FShowButtons;
|
|
|
|
+ if OQBEngine.DatabaseName <> EmptyStr then
|
|
|
|
+ TOQBForm(FOQBForm).OpenDatabase else
|
|
|
|
+ TOQBForm(FOQBForm).SelectDatabase;
|
|
|
|
+
|
|
|
|
+ if TOQBForm(FOQBForm).ShowModal = mrOk then
|
|
|
|
+ begin
|
|
|
|
+ FSQL.Assign(TOQBForm(FOQBForm).MemoSQL.Lines);
|
|
|
|
+ Result := True;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ OQBEngine.CloseResultQuery;
|
|
|
|
+ FOQBForm.Free;
|
|
|
|
+ FOQBForm := nil;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBuilderDialog.Notification(AComponent: TComponent;
|
|
|
|
+ Operation: TOperation);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ if (AComponent = FOQBEngine) and (Operation = opRemove) then
|
|
|
|
+ FOQBEngine := nil;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBuilderDialog.SetOQBEngine(const Value: TOQBEngine);
|
|
|
|
+begin
|
|
|
|
+ if FOQBEngine <> nil then
|
|
|
|
+ FOQBEngine.FOQBDialog := nil;
|
|
|
|
+ FOQBEngine := Value;
|
|
|
|
+ if FOQBEngine <> nil then
|
|
|
|
+ begin
|
|
|
|
+ FOQBEngine.FOQBDialog := Self;
|
|
|
|
+ FOQBEngine.FreeNotification(Self);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+{ TOQBEngine }
|
|
|
|
+
|
|
|
|
+constructor TOQBEngine.Create(AOwner: TComponent);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ FShowSystemTables := False;
|
|
|
|
+ FTableList := TStringList.Create;
|
|
|
|
+ FAliasList := TStringList.Create;
|
|
|
|
+ FFieldList := TStringList.Create;
|
|
|
|
+ FSQL := TStringList.Create;
|
|
|
|
+ FSQLcolumns := TStringList.Create;
|
|
|
|
+ FSQLcolumns_table := TStringList.Create;
|
|
|
|
+ FSQLcolumns_func := TStringList.Create;
|
|
|
|
+ FSQLfrom := TStringList.Create;
|
|
|
|
+ FSQLwhere := TStringList.Create;
|
|
|
|
+ FSQLgroupby := TStringList.Create;
|
|
|
|
+ FSQLorderby := TStringList.Create;
|
|
|
|
+ FUseTableAliases := True;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+destructor TOQBEngine.Destroy;
|
|
|
|
+begin
|
|
|
|
+ FSQL.Free;
|
|
|
|
+ FSQLcolumns.Free;
|
|
|
|
+ FSQLcolumns_table.Free;
|
|
|
|
+ FSQLcolumns_func.Free;
|
|
|
|
+ FSQLfrom.Free;
|
|
|
|
+ FSQLwhere.Free;
|
|
|
|
+ FSQLgroupby.Free;
|
|
|
|
+ FSQLorderby.Free;
|
|
|
|
+ FFieldList.Free;
|
|
|
|
+ FAliasList.Free;
|
|
|
|
+ FTableList.Free;
|
|
|
|
+ FreeNotification(Self);
|
|
|
|
+ inherited;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBEngine.Notification(AComponent: TComponent;
|
|
|
|
+ Operation: TOperation);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ if (AComponent = FOQBDialog) and (Operation = opRemove) then
|
|
|
|
+ FOQBDialog := nil;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBEngine.SetDatabaseName(const Value: string);
|
|
|
|
+begin
|
|
|
|
+ TableList.Clear;
|
|
|
|
+ FDatabaseName := Value;
|
|
|
|
+ if ResultQuery.Active then
|
|
|
|
+ ResultQuery.Close;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBEngine.SetUserName(const Value: string);
|
|
|
|
+begin
|
|
|
|
+ FUserName := Value;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBEngine.SetPassword(const Value: string);
|
|
|
|
+begin
|
|
|
|
+ FPassword := Value;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBEngine.SetShowSystemTables(const Value: Boolean);
|
|
|
|
+begin
|
|
|
|
+ if FShowSystemTables <> Value then
|
|
|
|
+ FShowSystemTables := Value;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBEngine.GenerateAliases;
|
|
|
|
+var
|
|
|
|
+ i, j: Integer;
|
|
|
|
+ s, s1: string;
|
|
|
|
+begin
|
|
|
|
+ FAliasList.Clear;
|
|
|
|
+ for i := 0 to FTableList.Count - 1 do
|
|
|
|
+ begin
|
|
|
|
+ s := ' ';
|
|
|
|
+ s[1] := FTableList[i][1]; // get the first character [1] of the table name [i]
|
|
|
|
+ if FAliasList.IndexOf(s) = -1 then
|
|
|
|
+ FAliasList.Add(s)
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ j := 1;
|
|
|
|
+ repeat
|
|
|
|
+ Inc(j);
|
|
|
|
+ s1 := s + IntToStr(j);
|
|
|
|
+ until FAliasList.IndexOf(s1) = -1;
|
|
|
|
+ FAliasList.Add(s1);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBEngine.GenerateSQL: string;
|
|
|
|
+var
|
|
|
|
+ s: string;
|
|
|
|
+ i: Integer;
|
|
|
|
+begin
|
|
|
|
+ SQL.Clear;
|
|
|
|
+
|
|
|
|
+ s := 'SELECT ';
|
|
|
|
+ for i := 0 to SQLcolumns.Count - 1 do
|
|
|
|
+ begin
|
|
|
|
+ if SQLcolumns_func[i] = EmptyStr then
|
|
|
|
+ s := s + SQLcolumns[i] else
|
|
|
|
+ s := s + SQLcolumns_func[i] + '(' + SQLcolumns[i] + ')';
|
|
|
|
+ if (i < SQLcolumns.Count - 1) then
|
|
|
|
+ s := s + ', ';
|
|
|
|
+ if (Length(s) > 70) or (i = SQLcolumns.Count - 1) then
|
|
|
|
+ begin
|
|
|
|
+ SQL.Add(s);
|
|
|
|
+ s := ' ';
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ s := 'FROM ';
|
|
|
|
+ for i := 0 to SQLfrom.Count - 1 do
|
|
|
|
+ begin
|
|
|
|
+ s := s + SQLfrom[i];
|
|
|
|
+ if (i < SQLfrom.Count - 1) then
|
|
|
|
+ s := s + ', ';
|
|
|
|
+ if (Length(s) > 70) or (i = SQLfrom.Count - 1) then
|
|
|
|
+ begin
|
|
|
|
+ SQL.Add(s);
|
|
|
|
+ s := ' ';
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ s := 'WHERE ';
|
|
|
|
+ for i := 0 to SQLwhere.Count - 1 do
|
|
|
|
+ begin
|
|
|
|
+ if (i < SQLwhere.Count - 1) then
|
|
|
|
+ s := s + SQLwhere[i] + ' AND ' else
|
|
|
|
+ s := s + SQLwhere[i];
|
|
|
|
+ if (Length(s) > 70) or (i = SQLwhere.Count - 1) then
|
|
|
|
+ begin
|
|
|
|
+ SQL.Add(s);
|
|
|
|
+ s := ' ';
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ s := 'GROUP BY ';
|
|
|
|
+ for i := 0 to SQLgroupby.Count - 1 do
|
|
|
|
+ begin
|
|
|
|
+ if (i < SQLgroupby.Count - 1) then
|
|
|
|
+ s := s + SQLgroupby[i] + ', ' else
|
|
|
|
+ s := s + SQLgroupby[i];
|
|
|
|
+ if (Length(s) > 70) or (i = SQLgroupby.Count - 1) then
|
|
|
|
+ begin
|
|
|
|
+ SQL.Add(s);
|
|
|
|
+ s := ' ';
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ s := 'ORDER BY ';
|
|
|
|
+ for i := 0 to SQLorderby.Count - 1 do
|
|
|
|
+ begin
|
|
|
|
+ if (i < SQLorderby.Count - 1) then
|
|
|
|
+ s := s + SQLorderby[i] + ', ' else
|
|
|
|
+ s := s + SQLorderby[i];
|
|
|
|
+ if (Length(s) > 70) or (i = SQLorderby.Count - 1) then
|
|
|
|
+ begin
|
|
|
|
+ SQL.Add(s);
|
|
|
|
+ s := ' ';
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ Result := SQL.Text;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+{ TOQBLbx }
|
|
|
|
+
|
|
|
|
+constructor TOQBLbx.Create(AOwner: TComponent);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ Style := lbStandard;
|
|
|
|
+ ParentFont := False;
|
|
|
|
+ Font.Style := [];
|
|
|
|
+ Font.Size := 8;
|
|
|
|
+ FArrBold := nil;
|
|
|
|
+ FLoading := False;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+destructor TOQBLbx.Destroy;
|
|
|
|
+begin
|
|
|
|
+ if FArrBold <> nil then
|
|
|
|
+ FreeMem(FArrBold);
|
|
|
|
+ inherited;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBLbx.GetCheckW: Integer;
|
|
|
|
+begin
|
|
|
|
+ Result := GetCheckW;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+{procedure TOQBLbx.CNDrawItem(var Message: TWMDrawItem);
|
|
|
|
+begin
|
|
|
|
+ with Message.DrawItemStruct^ do
|
|
|
|
+ begin
|
|
|
|
+ rcItem.Left := rcItem.Left + GetCheckW; //*** check
|
|
|
|
+ Canvas.Font := Font;
|
|
|
|
+ Canvas.Brush := Brush;
|
|
|
|
+ if (Integer(itemID) >= 0) and (Integer(itemID) <= Items.Count - 1) then
|
|
|
|
+ begin
|
|
|
|
+ if (FArrBold <> nil) then
|
|
|
|
+ if FArrBold^[Integer(itemID)] = 1 then
|
|
|
|
+ Canvas.Font.Style := [fsBold];
|
|
|
|
+ DrawItem(itemID, rcItem, []);
|
|
|
|
+ if (FArrBold <> nil) then
|
|
|
|
+ if FArrBold^[Integer(itemID)] = 1 then
|
|
|
|
+ Canvas.Font.Style := [];
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ Canvas.FillRect(rcItem);
|
|
|
|
+ end;
|
|
|
|
+end;}
|
|
|
|
+
|
|
|
|
+procedure TOQBLbx.WMLButtonDown(var Message: TLMLButtonDblClk);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ BeginDrag(False);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBLbx.WMRButtonDown(var Message: TLMRButtonDblClk);
|
|
|
|
+var
|
|
|
|
+ pnt: TPoint;
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ pnt.X := Message.XPos;
|
|
|
|
+ pnt.Y := Message.YPos;
|
|
|
|
+ pnt := ClientToScreen(pnt);
|
|
|
|
+ PopupMenu.Popup(pnt.X, pnt.Y);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+{procedure TOQBLbx.ClickCheck;
|
|
|
|
+var
|
|
|
|
+ iCol: Integer;
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ if FLoading then
|
|
|
|
+ Exit;
|
|
|
|
+
|
|
|
|
+ if Checked[ItemIndex] then
|
|
|
|
+ begin
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.Insert(
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.ColCount,
|
|
|
|
+ Items[ItemIndex], TOQBTable(Parent).FTableName);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ iCol := TOQBForm(GetParentForm(Self)).QBGrid.FindColumn(Items[ItemIndex]);
|
|
|
|
+ while iCol <> -1 do
|
|
|
|
+ begin
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.RemoveColumn(iCol);
|
|
|
|
+ iCol := TOQBForm(GetParentForm(Self)).QBGrid.FindColumn(Items[ItemIndex]);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.Refresh; // StringGrid bug
|
|
|
|
+end; }
|
|
|
|
+
|
|
|
|
+procedure TOQBLbx.ItemClick(const AIndex: Integer);
|
|
|
|
+var
|
|
|
|
+ iCol: Integer;
|
|
|
|
+begin
|
|
|
|
+ inherited ItemClick(AIndex);
|
|
|
|
+ if FLoading then
|
|
|
|
+ Exit;
|
|
|
|
+
|
|
|
|
+ if Checked[ItemIndex] then
|
|
|
|
+ begin
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.Insert(
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.ColCount,
|
|
|
|
+ Items[ItemIndex], TOQBTable(Parent).FTableName);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ iCol := TOQBForm(GetParentForm(Self)).QBGrid.FindColumn(Items[ItemIndex]);
|
|
|
|
+ while iCol <> -1 do
|
|
|
|
+ begin
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.RemoveColumn(iCol);
|
|
|
|
+ iCol := TOQBForm(GetParentForm(Self)).QBGrid.FindColumn(Items[ItemIndex]);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.Refresh; // StringGrid bug
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBLbx.AllocArrBold;
|
|
|
|
+begin
|
|
|
|
+ FArrBold := AllocMem(Items.Count * SizeOf(Integer));
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBLbx.SelectItemBold(Item: Integer);
|
|
|
|
+begin
|
|
|
|
+ if FArrBold <> nil then
|
|
|
|
+ if FArrBold[Item] = 0 then
|
|
|
|
+ FArrBold^[Item] := 1;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBLbx.UnSelectItemBold(Item: Integer);
|
|
|
|
+begin
|
|
|
|
+ if FArrBold <> nil then
|
|
|
|
+ if FArrBold[Item] = 1 then
|
|
|
|
+ FArrBold^[Item] := 0;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBLbx.GetItemY(Item: Integer): Integer;
|
|
|
|
+begin
|
|
|
|
+ Result := Item * ItemHeight + ItemHeight div 2 + 1;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+{ TOQBTable }
|
|
|
|
+
|
|
|
|
+constructor TOQBTable.Create(AOwner: TComponent);
|
|
|
|
+var
|
|
|
|
+ mnuArr: array [1..5] of TMenuItem;
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ Visible := False;
|
|
|
|
+ ShowHint := True;
|
|
|
|
+ BevelInner := bvRaised;
|
|
|
|
+ BevelOuter := bvRaised;
|
|
|
|
+ BorderWidth := 1;
|
|
|
|
+ FCloseBtn := TSpeedButton.Create(Self);
|
|
|
|
+ FCloseBtn.Parent := Self;
|
|
|
|
+ FCloseBtn.Hint := 'Close';
|
|
|
|
+ FUnlinkBtn := TSpeedButton.Create(Self);
|
|
|
|
+ FUnlinkBtn.Parent := Self;
|
|
|
|
+ FUnlinkBtn.Hint := 'Unlink all';
|
|
|
|
+
|
|
|
|
+ FLbx := TOQBLbx.Create(Self);
|
|
|
|
+ FLbx.Parent := Self;
|
|
|
|
+ FLbx.Style := lbStandard;
|
|
|
|
+ FLbx.Align := alBottom;
|
|
|
|
+ FLbx.TabStop := False;
|
|
|
|
+ FLbx.Visible := False;
|
|
|
|
+
|
|
|
|
+ mnuArr[1] := NewItem('Select All', 0, False, True, _SelectAll, 0, 'mnuSelectAll');
|
|
|
|
+ mnuArr[2] := NewItem('Unselect All', 0, False, True, _UnSelectAll, 0, 'mnuUnSelectAll');
|
|
|
|
+ mnuArr[3] := NewLine;
|
|
|
|
+ mnuArr[4] := NewItem('Unlink', 0, False, True, _UnlinkBtn, 0, 'mnuUnLink');
|
|
|
|
+ mnuArr[5] := NewItem('Close', 0, False, True, _CloseBtn, 0, 'mnuClose');
|
|
|
|
+ PopMenu := NewPopupMenu(Self, 'mnu', paLeft, False, mnuArr);
|
|
|
|
+ PopMenu.PopupComponent := Self;
|
|
|
|
+
|
|
|
|
+ FLbx.PopupMenu := PopMenu;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable.WMRButtonDown(var Message: TLMLButtonDblClk);
|
|
|
|
+var
|
|
|
|
+ pnt: TPoint;
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ pnt.X := Message.XPos;
|
|
|
|
+ pnt.Y := Message.YPos;
|
|
|
|
+ pnt := ClientToScreen(pnt);
|
|
|
|
+ PopMenu.Popup(pnt.X, pnt.Y);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable.Paint;
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ if TOQBForm(GetParentForm(Self)).QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ Canvas.TextOut(4, 4, FTableName + ' : ' + FTableAlias) else
|
|
|
|
+ Canvas.TextOut(4, 4, FTableName);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBTable.GetRowY(FldN: Integer): Integer;
|
|
|
|
+var
|
|
|
|
+ pnt: TPoint;
|
|
|
|
+begin
|
|
|
|
+ pnt.X := FLbx.Left;
|
|
|
|
+ pnt.Y := FLbx.Top + FLbx.GetItemY(FldN);
|
|
|
|
+ pnt := Parent.ScreenToClient(ClientToScreen(pnt));
|
|
|
|
+ Result := pnt.Y;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBTable.Activate(const ATableName: string; X, Y: Integer): Boolean;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+ W, W1: Integer;
|
|
|
|
+ OQBEngine: TOQBEngine;
|
|
|
|
+begin
|
|
|
|
+ Result := False;
|
|
|
|
+ Top := Y;
|
|
|
|
+ Left := X;
|
|
|
|
+ Font.Style := [fsBold];
|
|
|
|
+ Font.Size := 8;
|
|
|
|
+ Canvas.Font := Font;
|
|
|
|
+ Hint := ATableName;
|
|
|
|
+
|
|
|
|
+ FTableName := ATableName;
|
|
|
|
+ FTableAlias := TOQBForm(GetParentForm(Self)).QBDialog.FOQBEngine.AliasList[
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBDialog.FOQBEngine.TableList.IndexOf(ATableName)];
|
|
|
|
+ OQBEngine := TOQBForm(GetParentForm(Self)).QBDialog.FOQBEngine;
|
|
|
|
+ try
|
|
|
|
+ OQBEngine.ReadFieldList(ATableName);
|
|
|
|
+ FLbx.Items.Assign(OQBEngine.FieldList);
|
|
|
|
+ except
|
|
|
|
+ on E: EDatabaseError do
|
|
|
|
+ begin
|
|
|
|
+ ShowMessage(E.Message);
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ FLbx.AllocArrBold;
|
|
|
|
+ FLbx.ParentFont := False;
|
|
|
|
+ FLbx.TabStop := False;
|
|
|
|
+
|
|
|
|
+ case WidgetSet.LCLPlatform of
|
|
|
|
+ lpGtk: FLbx.Height := ((FLbx.ItemHeight + 6) * FLbx.Items.Count) + 4;
|
|
|
|
+ lpGtk2: FLbx.Height := ((FLbx.ItemHeight + 6) * FLbx.Items.Count) + 4;
|
|
|
|
+ lpWin32: FLbx.Height := ((FLbx.ItemHeight + 4) * FLbx.Items.Count) + 4;
|
|
|
|
+ lpCarbon:FLbx.Height := ((FLbx.ItemHeight + 8) * FLbx.Items.Count) + 4;
|
|
|
|
+ lpQT: FLbx.Height := ((FLbx.ItemHeight + 8) * FLbx.Items.Count) + 4;
|
|
|
|
+ lpfpGUI: FLbx.Height := ((FLbx.ItemHeight + 8) * FLbx.Items.Count) + 4;
|
|
|
|
+ else
|
|
|
|
+ FLbx.Height := ((FLbx.ItemHeight + 8) * FLbx.Items.Count) + 4;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ Height := FLbx.Height + 22;
|
|
|
|
+ W := 110;
|
|
|
|
+ for i := 0 to FLbx.Items.Count - 1 do
|
|
|
|
+ begin
|
|
|
|
+ W1 := Canvas.TextWidth(FLbx.Items[i]);
|
|
|
|
+ if W < W1 then
|
|
|
|
+ W := W1;
|
|
|
|
+ end;
|
|
|
|
+ Width := W + 20 + 22;//FLbx.GetCheckW; //*** check
|
|
|
|
+
|
|
|
|
+ if TOQBForm(GetParentForm(Self)).QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ begin
|
|
|
|
+ if Canvas.TextWidth(FTableName + ' : ' + FTableAlias) > Width - 34 then
|
|
|
|
+ Width := Canvas.TextWidth(FTableName + ' : ' + FTableAlias) + 34
|
|
|
|
+ end
|
|
|
|
+ else if Canvas.TextWidth(FTableName) > Width - 34 then
|
|
|
|
+ Width := Canvas.TextWidth(FTableName) + 34;
|
|
|
|
+
|
|
|
|
+ Color := clForm;
|
|
|
|
+ FLbx.Visible := True;
|
|
|
|
+ FLbx.OnDragOver := _DragOver;
|
|
|
|
+ FLbx.OnDragDrop := _DragDrop;
|
|
|
|
+ FCloseBtn.Top := 4;
|
|
|
|
+ FCloseBtn.Left := Self.ClientWidth - 16;
|
|
|
|
+ FCloseBtn.Width := 12;
|
|
|
|
+ FCloseBtn.Height := 12;
|
|
|
|
+ FCloseBtn.Glyph.LoadFromResourceName(HInstance, 'CLOSEBMP');;
|
|
|
|
+ FCloseBtn.Margin := -1;
|
|
|
|
+ FCloseBtn.Spacing := 0;
|
|
|
|
+ FCloseBtn.OnClick := _CloseBtn;
|
|
|
|
+ FCloseBtn.Visible := True;
|
|
|
|
+ FUnlinkBtn.Top := 4;
|
|
|
|
+ FUnlinkBtn.Left := Self.ClientWidth - 16 - FCloseBtn.Width;
|
|
|
|
+ FUnlinkBtn.Width := 12;
|
|
|
|
+ FUnlinkBtn.Height := 12;
|
|
|
|
+ FUnlinkBtn.Glyph.LoadFromResourceName(HInstance, 'UNLINKBMP');;
|
|
|
|
+ FUnlinkBtn.Margin := -1;
|
|
|
|
+ FUnlinkBtn.Spacing := 0;
|
|
|
|
+ FUnlinkBtn.OnClick := _UnlinkBtn;
|
|
|
|
+ FUnlinkBtn.Visible := True;
|
|
|
|
+ Visible := True;
|
|
|
|
+ Result := True;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable._CloseBtn(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ TOQBArea(Parent).UnlinkTable(Self);
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.RemoveColumn4Tbl(FTableName);
|
|
|
|
+ Parent.RemoveControl(Self);
|
|
|
|
+ Free;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable._UnlinkBtn(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ TOQBArea(Parent).UnlinkTable(Self);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable._SelectAll(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+begin
|
|
|
|
+ if FLbx.Items.Count = 1 then
|
|
|
|
+ Exit;
|
|
|
|
+ for i := 1 to (FLbx.Items.Count - 1) do
|
|
|
|
+ begin
|
|
|
|
+ FLbx.Checked[i] := True;
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.Insert(
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.ColCount,
|
|
|
|
+ FLbx.Items[i], FTableName);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable._UnSelectAll(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+begin
|
|
|
|
+ if FLbx.Items.Count = 1 then
|
|
|
|
+ Exit;
|
|
|
|
+ for i := 1 to (FLbx.Items.Count - 1) do
|
|
|
|
+ begin
|
|
|
|
+ FLbx.Checked[i] := False;
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBGrid.RemoveColumn4Tbl(FTableName);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable._DragOver(Sender, Source: TObject; X, Y: Integer;
|
|
|
|
+ State: TDragState; var Accept: Boolean);
|
|
|
|
+begin
|
|
|
|
+ if (Source is TCustomListBox) and (TWinControl(Source).Parent is TOQBTable) then
|
|
|
|
+ Accept := True;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable._DragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
|
|
+var
|
|
|
|
+ nRow: Integer;
|
|
|
|
+ hRow: Integer;
|
|
|
|
+begin
|
|
|
|
+ if (Source is TCustomListBox) then
|
|
|
|
+ begin
|
|
|
|
+ if (TWinControl(Source).Parent is TOQBTable) then
|
|
|
|
+ begin
|
|
|
|
+ hRow := FLbx.ItemHeight;
|
|
|
|
+ if hRow <> 0 then
|
|
|
|
+ nRow := Y div hRow else
|
|
|
|
+ nRow := 0;
|
|
|
|
+ if nRow > FLbx.Items.Count - 1 then
|
|
|
|
+ nRow := FLbx.Items.Count - 1;
|
|
|
|
+ // handler for target's '*' row
|
|
|
|
+ if nRow = 0 then
|
|
|
|
+ Exit;
|
|
|
|
+ // handler for source's '*' row
|
|
|
|
+ if TOQBTable(TWinControl(Source).Parent).FLbx.ItemIndex = 0 then
|
|
|
|
+ Exit;
|
|
|
|
+ if Source <> FLbx then
|
|
|
|
+ TOQBArea(Parent).InsertLink(
|
|
|
|
+ TOQBTable(TWinControl(Source).Parent), Self,
|
|
|
|
+ TOQBTable(TWinControl(Source).Parent).FLbx.ItemIndex, nRow)
|
|
|
|
+ else if nRow <> FLbx.ItemIndex then
|
|
|
|
+ TOQBArea(Parent).InsertLink(Self, Self, FLbx.ItemIndex, nRow);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ if Source = TOQBForm(GetParentForm(Self)).QBTables then
|
|
|
|
+ begin
|
|
|
|
+ X := X + Left + TWinControl(Sender).Left;
|
|
|
|
+ Y := Y + Top + TWinControl(Sender).Top;
|
|
|
|
+ TOQBArea(Parent).InsertTable(X, Y);
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable.SetParent(AParent: TWinControl);
|
|
|
|
+begin
|
|
|
|
+ if (AParent <> nil) and (not (AParent is TScrollBox)) then
|
|
|
|
+ raise Exception.Create(sNotValidTableParent);
|
|
|
|
+ inherited;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
|
|
+ X, Y: Integer);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ BringToFront;
|
|
|
|
+ if (Button = mbLeft) then
|
|
|
|
+ begin
|
|
|
|
+ SetCapture(Self.Handle);
|
|
|
|
+ ScreenDC := GetDC(0);
|
|
|
|
+
|
|
|
|
+ ClipRect := Bounds(Parent.Left, Parent.Top, Parent.Width, Parent.Height);
|
|
|
|
+ ClipRect.TopLeft := Parent.Parent.ClientToScreen(ClipRect.TopLeft);
|
|
|
|
+ ClipRect.BottomRight := Parent.Parent.ClientToScreen(ClipRect.BottomRight);
|
|
|
|
+ ClipRgn := CreateRectRgn(ClipRect.Left, ClipRect.Top, ClipRect.Right, ClipRect.Bottom);
|
|
|
|
+ SelectClipRgn(ScreenDC, ClipRgn);
|
|
|
|
+// ClipCursor(@ClipRect);
|
|
|
|
+ OldX := X;
|
|
|
|
+ OldY := Y;
|
|
|
|
+ OldLeft := X;
|
|
|
|
+ OldTop := Y;
|
|
|
|
+ MoveRect := Rect(Self.Left, Self.Top, Self.Left + Self.Width, Self.Top + Self.Height);
|
|
|
|
+ MoveRect.TopLeft := Parent.ClientToScreen(MoveRect.TopLeft);
|
|
|
|
+ MoveRect.BottomRight := Parent.ClientToScreen(MoveRect.BottomRight);
|
|
|
|
+ DrawFocusRect(ScreenDC, MoveRect);
|
|
|
|
+ Moving := True;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ if Moving then
|
|
|
|
+ begin
|
|
|
|
+ DrawFocusRect(ScreenDC, MoveRect);
|
|
|
|
+ OldX := X;
|
|
|
|
+ OldY := Y;
|
|
|
|
+ MoveRect := Rect(Self.Left + OldX - OldLeft, Self.Top + OldY - OldTop,
|
|
|
|
+ Self.Left + Self.Width + OldX - OldLeft, Self.Top + Self.Height + OldY - OldTop);
|
|
|
|
+ MoveRect.TopLeft := Parent.ClientToScreen(MoveRect.TopLeft);
|
|
|
|
+ MoveRect.BottomRight := Parent.ClientToScreen(MoveRect.BottomRight);
|
|
|
|
+ DrawFocusRect(ScreenDC, MoveRect);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBTable.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
|
|
+ X, Y: Integer);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ if Button = mbLeft then
|
|
|
|
+ begin
|
|
|
|
+ ReleaseCapture;
|
|
|
|
+ DrawFocusRect(ScreenDC, MoveRect);
|
|
|
|
+ if (Self.Left <> Self.Left + X + OldLeft) or (Self.Top <> Self.Top + Y - OldTop) then
|
|
|
|
+ begin
|
|
|
|
+ Self.Visible := False;
|
|
|
|
+ Self.Left := Self.Left + X - OldLeft;
|
|
|
|
+ Self.Top := Self.Top + Y - OldTop;
|
|
|
|
+ Self.Visible := True;
|
|
|
|
+ end;
|
|
|
|
+ ClipRect := Rect(0, 0, Screen.Width, Screen.Height);
|
|
|
|
+// ClipCursor(@ClipRect);
|
|
|
|
+ DeleteObject(ClipRgn);
|
|
|
|
+ ReleaseDC(0, ScreenDC);
|
|
|
|
+ Moving := False;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ TOQBArea(Parent).ReboundLinks4Table(Self);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+{ TOQBLink }
|
|
|
|
+
|
|
|
|
+constructor TOQBLink.Create(AOwner: TComponent);
|
|
|
|
+var
|
|
|
|
+ mnuArr: array [1..4] of TMenuItem;
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ ControlStyle := ControlStyle + [csReplicatable];
|
|
|
|
+ Width := 105;
|
|
|
|
+ Height := 105;
|
|
|
|
+ Rgn := CreateRectRgn(0, 0, Hand, Hand);
|
|
|
|
+ mnuArr[1] := NewItem('', 0, False, False, nil, 0, 'mnuLinkName');
|
|
|
|
+ mnuArr[2] := NewLine;
|
|
|
|
+ mnuArr[3] := NewItem('Link options', 0, False, True, TOQBArea(AOwner).SetOptions, 0, 'mnuOptions');
|
|
|
|
+ mnuArr[4] := NewItem('Unlink', 0, False, True, TOQBArea(AOwner).Unlink, 0, 'mnuUnlink');
|
|
|
|
+ PopMenu := NewPopupMenu(Self, 'mnu', paLeft, False, mnuArr);
|
|
|
|
+ PopMenu.PopupComponent := Self;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+destructor TOQBLink.Destroy;
|
|
|
|
+begin
|
|
|
|
+ DeleteObject(Rgn);
|
|
|
|
+ inherited;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBLink.Paint;
|
|
|
|
+var
|
|
|
|
+ ArrRgn, pntArray: array [1..4] of TPoint;
|
|
|
|
+ ArrCnt: Integer;
|
|
|
|
+begin
|
|
|
|
+ if tbl1 <> tbl2 then
|
|
|
|
+ begin
|
|
|
|
+ if ((LnkX = 1) and (LnkY = 1)) or ((LnkX = 4) and (LnkY = 2)) then
|
|
|
|
+ begin
|
|
|
|
+ pntArray[1].X := 0;
|
|
|
|
+ pntArray[1].Y := Hand div 2;
|
|
|
|
+ pntArray[2].X := Hand;
|
|
|
|
+ pntArray[2].Y := Hand div 2;
|
|
|
|
+ pntArray[3].X := Width - Hand;
|
|
|
|
+ pntArray[3].Y := Height - Hand div 2;
|
|
|
|
+ pntArray[4].X := Width;
|
|
|
|
+ pntArray[4].Y := Height - Hand div 2;
|
|
|
|
+ ArrRgn[1].X := pntArray[2].X + 5;
|
|
|
|
+ ArrRgn[1].Y := pntArray[2].Y - 5;
|
|
|
|
+ ArrRgn[2].X := pntArray[2].X - 5;
|
|
|
|
+ ArrRgn[2].Y := pntArray[2].Y + 5;
|
|
|
|
+ ArrRgn[3].X := pntArray[3].X - 5;
|
|
|
|
+ ArrRgn[3].Y := pntArray[3].Y + 5;
|
|
|
|
+ ArrRgn[4].X := pntArray[3].X + 5;
|
|
|
|
+ ArrRgn[4].Y := pntArray[3].Y - 5;
|
|
|
|
+ end;
|
|
|
|
+ if Width > Hand + Hand2 then
|
|
|
|
+ begin
|
|
|
|
+ if ((LnkX = 2) and (LnkY = 1)) or ((LnkX = 3) and (LnkY = 2)) then
|
|
|
|
+ begin
|
|
|
|
+ pntArray[1].X := 0;
|
|
|
|
+ pntArray[1].Y := Hand div 2;
|
|
|
|
+ pntArray[2].X := Hand;
|
|
|
|
+ pntArray[2].Y := Hand div 2;
|
|
|
|
+ pntArray[3].X := Width - 5;
|
|
|
|
+ pntArray[3].Y := Height - Hand div 2;
|
|
|
|
+ pntArray[4].X := Width - Hand;
|
|
|
|
+ pntArray[4].Y := Height - Hand div 2;
|
|
|
|
+ ArrRgn[1].X := pntArray[2].X + 5;
|
|
|
|
+ ArrRgn[1].Y := pntArray[2].Y - 5;
|
|
|
|
+ ArrRgn[2].X := pntArray[2].X - 5;
|
|
|
|
+ ArrRgn[2].Y := pntArray[2].Y + 5;
|
|
|
|
+ ArrRgn[3].X := pntArray[3].X - 5;
|
|
|
|
+ ArrRgn[3].Y := pntArray[3].Y + 5;
|
|
|
|
+ ArrRgn[4].X := pntArray[3].X + 5;
|
|
|
|
+ ArrRgn[4].Y := pntArray[3].Y - 5;
|
|
|
|
+ end;
|
|
|
|
+ if ((LnkX = 3) and (LnkY = 1)) or ((LnkX = 2) and (LnkY = 2)) then
|
|
|
|
+ begin
|
|
|
|
+ pntArray[1].X := Width - Hand;
|
|
|
|
+ pntArray[1].Y := Hand div 2;
|
|
|
|
+ pntArray[2].X := Width - 5;
|
|
|
|
+ pntArray[2].Y := Hand div 2;
|
|
|
|
+ pntArray[3].X := Hand;
|
|
|
|
+ pntArray[3].Y := Height - Hand div 2;
|
|
|
|
+ pntArray[4].X := 0;
|
|
|
|
+ pntArray[4].Y := Height - Hand div 2;
|
|
|
|
+ ArrRgn[1].X := pntArray[2].X - 5;
|
|
|
|
+ ArrRgn[1].Y := pntArray[2].Y - 5;
|
|
|
|
+ ArrRgn[2].X := pntArray[2].X + 5;
|
|
|
|
+ ArrRgn[2].Y := pntArray[2].Y + 5;
|
|
|
|
+ ArrRgn[3].X := pntArray[3].X + 5;
|
|
|
|
+ ArrRgn[3].Y := pntArray[3].Y + 5;
|
|
|
|
+ ArrRgn[4].X := pntArray[3].X - 5;
|
|
|
|
+ ArrRgn[4].Y := pntArray[3].Y - 5;
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ if ((LnkX = 2) and (LnkY = 1)) or ((LnkX = 3) and (LnkY = 2)) or
|
|
|
|
+ ((LnkX = 3) and (LnkY = 1)) or ((LnkX = 2) and (LnkY = 2)) then
|
|
|
|
+ begin
|
|
|
|
+ pntArray[1].X := 0;
|
|
|
|
+ pntArray[1].Y := Hand div 2;
|
|
|
|
+ pntArray[2].X := Width - Hand2;
|
|
|
|
+ pntArray[2].Y := Hand div 2;
|
|
|
|
+ pntArray[3].X := Width - Hand2;
|
|
|
|
+ pntArray[3].Y := Height - Hand div 2;
|
|
|
|
+ pntArray[4].X := 0;
|
|
|
|
+ pntArray[4].Y := Height - Hand div 2;
|
|
|
|
+ ArrRgn[1].X := pntArray[2].X - 5;
|
|
|
|
+ ArrRgn[1].Y := pntArray[2].Y - 5;
|
|
|
|
+ ArrRgn[2].X := pntArray[2].X + 5;
|
|
|
|
+ ArrRgn[2].Y := pntArray[2].Y + 5;
|
|
|
|
+ ArrRgn[3].X := pntArray[3].X + 5;
|
|
|
|
+ ArrRgn[3].Y := pntArray[3].Y + 5;
|
|
|
|
+ ArrRgn[4].X := pntArray[3].X - 5;
|
|
|
|
+ ArrRgn[4].Y := pntArray[3].Y - 5;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ if ((LnkX = 4) and (LnkY = 1)) or ((LnkX = 1) and (LnkY = 2)) then
|
|
|
|
+ begin
|
|
|
|
+ pntArray[1].X := Width;
|
|
|
|
+ pntArray[1].Y := Hand div 2;
|
|
|
|
+ pntArray[2].X := Width - Hand;
|
|
|
|
+ pntArray[2].Y := Hand div 2;
|
|
|
|
+ pntArray[3].X := Hand;
|
|
|
|
+ pntArray[3].Y := Height - Hand div 2;
|
|
|
|
+ pntArray[4].X := 0;
|
|
|
|
+ pntArray[4].Y := Height - Hand div 2;
|
|
|
|
+ ArrRgn[1].X := pntArray[2].X - 5;
|
|
|
|
+ ArrRgn[1].Y := pntArray[2].Y - 5;
|
|
|
|
+ ArrRgn[2].X := pntArray[2].X + 5;
|
|
|
|
+ ArrRgn[2].Y := pntArray[2].Y + 5;
|
|
|
|
+ ArrRgn[3].X := pntArray[3].X + 5;
|
|
|
|
+ ArrRgn[3].Y := pntArray[3].Y + 5;
|
|
|
|
+ ArrRgn[4].X := pntArray[3].X - 5;
|
|
|
|
+ ArrRgn[4].Y := pntArray[3].Y - 5;
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ pntArray[1].X := 0;
|
|
|
|
+ pntArray[1].Y := Hand div 2;
|
|
|
|
+ pntArray[2].X := Hand - 5;
|
|
|
|
+ pntArray[2].Y := Hand div 2;
|
|
|
|
+ pntArray[3].X := Hand - 5;
|
|
|
|
+ pntArray[3].Y := Height - Hand div 2;
|
|
|
|
+ pntArray[4].X := 0;
|
|
|
|
+ pntArray[4].Y := Height - Hand div 2;
|
|
|
|
+ ArrRgn[1].X := pntArray[2].X + 5;
|
|
|
|
+ ArrRgn[1].Y := pntArray[2].Y - 5;
|
|
|
|
+ ArrRgn[2].X := pntArray[2].X - 5;
|
|
|
|
+ ArrRgn[2].Y := pntArray[2].Y + 5;
|
|
|
|
+ ArrRgn[3].X := pntArray[3].X - 5;
|
|
|
|
+ ArrRgn[3].Y := pntArray[3].Y + 5;
|
|
|
|
+ ArrRgn[4].X := pntArray[3].X + 5;
|
|
|
|
+ ArrRgn[4].Y := pntArray[3].Y - 5;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ Canvas.PolyLine(pntArray);
|
|
|
|
+ Canvas.Brush := Parent.Brush;
|
|
|
|
+ DeleteObject(Rgn);
|
|
|
|
+ ArrCnt := 4;
|
|
|
|
+ Rgn := CreatePolygonRgn(@ArrRgn, ArrCnt, ALTERNATE);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBLink._Click(X, Y: Integer);
|
|
|
|
+var
|
|
|
|
+ pnt: TPoint;
|
|
|
|
+begin
|
|
|
|
+ pnt.X := X;
|
|
|
|
+ pnt.Y := Y;
|
|
|
|
+ pnt := ClientToScreen(pnt);
|
|
|
|
+ PopMenu.Popup(pnt.X, pnt.Y);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBLink.CMHitTest(var Message: TCMHitTest);
|
|
|
|
+begin
|
|
|
|
+ if PtInRegion(Rgn, Message.XPos, Message.YPos) then
|
|
|
|
+ Message.Result := 1;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBLink.ControlAtPos(const Pos: TPoint): TControl;
|
|
|
|
+var
|
|
|
|
+ I: Integer;
|
|
|
|
+ scrnP, P: TPoint;
|
|
|
|
+begin
|
|
|
|
+ scrnP := ClientToScreen(Pos);
|
|
|
|
+ for I := Parent.ControlCount - 1 downto 0 do
|
|
|
|
+ begin
|
|
|
|
+ Result := Parent.Controls[I];
|
|
|
|
+ if (Result is TOQBLink) and (Result <> Self) then
|
|
|
|
+ with Result do
|
|
|
|
+ begin
|
|
|
|
+ P := Result.ScreenToClient(scrnP);
|
|
|
|
+ if Perform(CM_HITTEST, 0, Integer(PointToSmallPoint(P))) <> 0 then
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ Result := nil;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBLink.PtInRegion(RGN: HRGN; X, Y: Integer): Boolean;
|
|
|
|
+{$IFDEF MSWINDOWS}
|
|
|
|
+begin
|
|
|
|
+ Result := LCLIntf.PtInRegion(RGN, X, Y);
|
|
|
|
+{$ELSE}
|
|
|
|
+var
|
|
|
|
+ APoint : TPoint;
|
|
|
|
+ ARect : TRect;
|
|
|
|
+begin
|
|
|
|
+ GetRgnBox(RGN, @ARect);
|
|
|
|
+ APoint.X := X;
|
|
|
|
+ APoint.Y := Y;
|
|
|
|
+ Result := LclIntf.PtInRect(ARect, APoint);
|
|
|
|
+{$ENDIF}
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBLink.WndProc(var Message: TLMessage);
|
|
|
|
+begin
|
|
|
|
+ if (Message.Msg = LM_RBUTTONDOWN) or (Message.Msg = LM_LBUTTONDOWN) then
|
|
|
|
+ if not PtInRegion(Rgn, TLMMouse(Message).XPos, TLMMouse(Message).YPos) then
|
|
|
|
+ ControlAtPos(SmallPointToPoint(TLMMouse(Message).Pos)) else
|
|
|
|
+ _Click(TLMMouse(Message).XPos, TLMMouse(Message).YPos);
|
|
|
|
+ inherited;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+{ TOQBArea }
|
|
|
|
+
|
|
|
|
+procedure TOQBArea.CreateParams(var Params: TCreateParams);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ OnDragOver := _DragOver;
|
|
|
|
+ OnDragDrop := _DragDrop;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBArea.SetOptions(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ AForm: TOQBLinkForm;
|
|
|
|
+ ALink: TOQBLink;
|
|
|
|
+begin
|
|
|
|
+ if TPopupMenu(Sender).Owner is TOQBLink then
|
|
|
|
+ begin
|
|
|
|
+ ALink := TOQBLink(TPopupMenu(Sender).Owner);
|
|
|
|
+ AForm := TOQBLinkForm.Create(Application);
|
|
|
|
+ AForm.txtTable1.Caption := ALink.tbl1.FTableName;
|
|
|
|
+ AForm.txtCol1.Caption := ALink.fldNam1;
|
|
|
|
+ AForm.txtTable2.Caption := ALink.tbl2.FTableName;
|
|
|
|
+ AForm.txtCol2.Caption := ALink.fldNam2;
|
|
|
|
+ AForm.RadioOpt.ItemIndex := ALink.FLinkOpt;
|
|
|
|
+ AForm.RadioType.ItemIndex := ALink.FLinkType;
|
|
|
|
+ if AForm.ShowModal = mrOk then
|
|
|
|
+ begin
|
|
|
|
+ ALink.FLinkOpt := AForm.RadioOpt.ItemIndex;
|
|
|
|
+ ALink.FLinkType := AForm.RadioType.ItemIndex;
|
|
|
|
+ end;
|
|
|
|
+ AForm.Free;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBArea.InsertTable(X, Y: Integer);
|
|
|
|
+var
|
|
|
|
+ NewTable: TOQBTable;
|
|
|
|
+begin
|
|
|
|
+ if FindTable(TOQBForm(GetParentForm(Self)).QBTables.Items[
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBTables.ItemIndex]) <> nil then
|
|
|
|
+ begin
|
|
|
|
+ ShowMessage('This table is already inserted.');
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ NewTable := TOQBTable.Create(Self);
|
|
|
|
+ NewTable.Parent := Self;
|
|
|
|
+ try
|
|
|
|
+ NewTable.Activate(TOQBForm(GetParentForm(Self)).QBTables.Items[
|
|
|
|
+ TOQBForm(GetParentForm(Self)).QBTables.ItemIndex], X, Y);
|
|
|
|
+ except
|
|
|
|
+ NewTable.Free;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBArea.InsertLink(_tbl1, _tbl2: TOQBTable;
|
|
|
|
+ _fldN1, _fldN2: Integer): TOQBLink;
|
|
|
|
+begin
|
|
|
|
+ Result := TOQBLink.Create(Self);
|
|
|
|
+ with Result do
|
|
|
|
+ begin
|
|
|
|
+ Parent := Self;
|
|
|
|
+ Application.ProcessMessages; // importante no gtk2
|
|
|
|
+ tbl1 := _tbl1;
|
|
|
|
+ tbl2 := _tbl2;
|
|
|
|
+ fldN1 := _fldN1;
|
|
|
|
+ fldN2 := _fldN2;
|
|
|
|
+ fldNam1 := tbl1.FLbx.Items[fldN1];
|
|
|
|
+ fldNam2 := tbl2.FLbx.Items[fldN2];
|
|
|
|
+ end;
|
|
|
|
+ if FindLink(Result) then
|
|
|
|
+ begin
|
|
|
|
+ ShowMessage('These tables are already linked.');
|
|
|
|
+ Result.Free;
|
|
|
|
+ Result := nil;
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+ with Result do
|
|
|
|
+ begin
|
|
|
|
+ tbl1.FLbx.SelectItemBold(fldN1);
|
|
|
|
+ tbl1.FLbx.Refresh;
|
|
|
|
+ tbl2.FLbx.SelectItemBold(fldN2);
|
|
|
|
+ tbl2.FLbx.Refresh;
|
|
|
|
+ OnDragOver := _DragOver;
|
|
|
|
+ OnDragDrop := _DragDrop;
|
|
|
|
+ end;
|
|
|
|
+ ReboundLink(Result);
|
|
|
|
+ Result.Visible := True;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBArea.FindTable(const TableName: string): TOQBTable;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+ TempTable: TOQBTable;
|
|
|
|
+begin
|
|
|
|
+ Result := nil;
|
|
|
|
+ for i := ControlCount - 1 downto 0 do
|
|
|
|
+ if Controls[i] is TOQBTable then
|
|
|
|
+ begin
|
|
|
|
+ TempTable := TOQBTable(Controls[i]);
|
|
|
|
+ if (TempTable.FTableName = TableName) then
|
|
|
|
+ begin
|
|
|
|
+ Result := TempTable;
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBArea.FindLink(Link: TOQBLink): Boolean;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+ TempLink: TOQBLink;
|
|
|
|
+begin
|
|
|
|
+ Result := False;
|
|
|
|
+ for i := ControlCount - 1 downto 0 do
|
|
|
|
+ if Controls[i] is TOQBLink then
|
|
|
|
+ begin
|
|
|
|
+ TempLink := TOQBLink(Controls[i]);
|
|
|
|
+ if (TempLink <> Link) then
|
|
|
|
+ if (((TempLink.tbl1 = Link.tbl1) and (TempLink.fldN1 = Link.fldN1)) and
|
|
|
|
+ ((TempLink.tbl2 = Link.tbl2) and (TempLink.fldN2 = Link.fldN2))) or
|
|
|
|
+ (((TempLink.tbl1 = Link.tbl2) and (TempLink.fldN1 = Link.fldN2)) and
|
|
|
|
+ ((TempLink.tbl2 = Link.tbl1) and (TempLink.fldN2 = Link.fldN1))) then
|
|
|
|
+ begin
|
|
|
|
+ Result := True;
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBArea.FindOtherLink(Link: TOQBLink; Tbl: TOQBTable;
|
|
|
|
+ FldN: Integer): Boolean;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+ OtherLink: TOQBLink;
|
|
|
|
+begin
|
|
|
|
+ Result := False;
|
|
|
|
+ for i := ControlCount - 1 downto 0 do
|
|
|
|
+ if Controls[i] is TOQBLink then
|
|
|
|
+ begin
|
|
|
|
+ OtherLink := TOQBLink(Controls[i]);
|
|
|
|
+ if (OtherLink <> Link) then
|
|
|
|
+ if ((OtherLink.tbl1 = Tbl) and (OtherLink.fldN1 = FldN)) or
|
|
|
|
+ ((OtherLink.tbl2 = Tbl) and (OtherLink.fldN2 = FldN)) then
|
|
|
|
+ begin
|
|
|
|
+ Result := True;
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBArea.ReboundLink(Link: TOQBLink);
|
|
|
|
+var
|
|
|
|
+ X1, X2, Y1, Y2: Integer;
|
|
|
|
+begin
|
|
|
|
+ Link.PopMenu.Items[0].Caption := Link.tbl1.FTableName + ' :: ' +
|
|
|
|
+ Link.tbl2.FTableName;
|
|
|
|
+ with Link do
|
|
|
|
+ begin
|
|
|
|
+ if Tbl1 = Tbl2 then
|
|
|
|
+ begin
|
|
|
|
+ X1 := Tbl1.Left + Tbl1.Width;
|
|
|
|
+ X2 := Tbl1.Left + Tbl1.Width + Hand;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ if Tbl1.Left < Tbl2.Left then
|
|
|
|
+ begin
|
|
|
|
+ if Tbl1.Left + Tbl1.Width + Hand < Tbl2.Left then
|
|
|
|
+ begin //A
|
|
|
|
+ X1 := Tbl1.Left + Tbl1.Width;
|
|
|
|
+ X2 := Tbl2.Left;
|
|
|
|
+ LnkX := 1;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin //B
|
|
|
|
+ if Tbl1.Left + Tbl1.Width > Tbl2.Left + Tbl2.Width then
|
|
|
|
+ begin
|
|
|
|
+ X1 := Tbl2.Left + Tbl2.Width;
|
|
|
|
+ X2 := Tbl1.Left + Tbl1.Width + Hand;
|
|
|
|
+ LnkX := 3;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ X1 := Tbl1.Left + Tbl1.Width;
|
|
|
|
+ X2 := Tbl2.Left + Tbl2.Width + Hand;
|
|
|
|
+ LnkX := 2;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ if Tbl2.Left + Tbl2.Width + Hand > Tbl1.Left then
|
|
|
|
+ begin //C
|
|
|
|
+ if Tbl2.Left + Tbl2.Width > Tbl1.Left + Tbl1.Width then
|
|
|
|
+ begin
|
|
|
|
+ X1 := Tbl1.Left + Tbl1.Width;
|
|
|
|
+ X2 := Tbl2.Left + Tbl2.Width + Hand;
|
|
|
|
+ LnkX := 2;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ X1 := Tbl2.Left + Tbl2.Width;
|
|
|
|
+ X2 := Tbl1.Left + Tbl1.Width + Hand;
|
|
|
|
+ LnkX := 3;
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin //D
|
|
|
|
+ X1 := Tbl2.Left + Tbl2.Width;
|
|
|
|
+ X2 := Tbl1.Left;
|
|
|
|
+ LnkX := 4;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ Y1 := Tbl1.GetRowY(FldN1);
|
|
|
|
+ Y2 := Tbl2.GetRowY(FldN2);
|
|
|
|
+ if Y1 < Y2 then
|
|
|
|
+ begin //M
|
|
|
|
+ Y1 := Tbl1.GetRowY(FldN1) - Hand div 2;
|
|
|
|
+ Y2 := Tbl2.GetRowY(FldN2) + Hand div 2;
|
|
|
|
+ LnkY := 1;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin //N
|
|
|
|
+ Y2 := Tbl1.GetRowY(FldN1) + Hand div 2;
|
|
|
|
+ Y1 := Tbl2.GetRowY(FldN2) - Hand div 2;
|
|
|
|
+ LnkY := 2;
|
|
|
|
+ end;
|
|
|
|
+ SetBounds(X1, Y1, X2 - X1, Y2 - Y1);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBArea.ReboundLinks4Table(ATable: TOQBTable);
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+ Link: TOQBLink;
|
|
|
|
+begin
|
|
|
|
+ for i := 0 to ControlCount - 1 do
|
|
|
|
+ begin
|
|
|
|
+ if Controls[i] is TOQBLink then
|
|
|
|
+ begin
|
|
|
|
+ Link := TOQBLink(Controls[i]);
|
|
|
|
+ if (Link.Tbl1 = ATable) or (Link.Tbl2 = ATable) then
|
|
|
|
+ ReboundLink(Link);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBArea.Unlink(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ Link: TOQBLink;
|
|
|
|
+begin
|
|
|
|
+ if TPopupMenu(Sender).Owner is TOQBLink then
|
|
|
|
+ begin
|
|
|
|
+ Link := TOQBLink(TPopupMenu(Sender).Owner);
|
|
|
|
+ RemoveControl(Link);
|
|
|
|
+
|
|
|
|
+ if not FindOtherLink(Link, Link.tbl1, Link.fldN1) then
|
|
|
|
+ begin
|
|
|
|
+ Link.tbl1.FLbx.UnSelectItemBold(Link.fldN1);
|
|
|
|
+ Link.tbl1.FLbx.Refresh;
|
|
|
|
+ end;
|
|
|
|
+ if not FindOtherLink(Link, Link.tbl2, Link.fldN2) then
|
|
|
|
+ begin
|
|
|
|
+ Link.tbl2.FLbx.UnSelectItemBold(Link.fldN2);
|
|
|
|
+ Link.tbl2.FLbx.Refresh;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ Link.Free;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBArea.UnlinkTable(ATable: TOQBTable);
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+ TempLink: TOQBLink;
|
|
|
|
+begin
|
|
|
|
+ for i := ControlCount - 1 downto 0 do
|
|
|
|
+ begin
|
|
|
|
+ if Controls[i] is TOQBLink then
|
|
|
|
+ begin
|
|
|
|
+ TempLink := TOQBLink(Controls[i]);
|
|
|
|
+
|
|
|
|
+ if (TempLink.Tbl1 = ATable) or (TempLink.Tbl2 = ATable) then
|
|
|
|
+ begin
|
|
|
|
+ RemoveControl(TempLink);
|
|
|
|
+ if not FindOtherLink(TempLink, TempLink.tbl1, TempLink.fldN1) then
|
|
|
|
+ begin
|
|
|
|
+ TempLink.tbl1.FLbx.UnSelectItemBold(TempLink.fldN1);
|
|
|
|
+ TempLink.tbl1.FLbx.Refresh;
|
|
|
|
+ end;
|
|
|
|
+ if not FindOtherLink(TempLink, TempLink.tbl2, TempLink.fldN2) then
|
|
|
|
+ begin
|
|
|
|
+ TempLink.tbl2.FLbx.UnSelectItemBold(TempLink.fldN2);
|
|
|
|
+ TempLink.tbl2.FLbx.Refresh;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ TempLink.Free;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBArea._DragOver(Sender, Source: TObject; X, Y: Integer;
|
|
|
|
+ State: TDragState; var Accept: Boolean);
|
|
|
|
+begin
|
|
|
|
+ if (Source = TOQBForm(GetParentForm(Self)).QBTables) then
|
|
|
|
+ Accept := True;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBArea._DragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
|
|
+begin
|
|
|
|
+ if not (Sender is TOQBArea) then
|
|
|
|
+ begin
|
|
|
|
+ X := X + TControl(Sender).Left;
|
|
|
|
+ Y := Y + TControl(Sender).Top;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if Source = TOQBForm(GetParentForm(Self)).QBTables then
|
|
|
|
+ InsertTable(X, Y);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+{ TOQBGrid }
|
|
|
|
+
|
|
|
|
+procedure TOQBGrid.CreateParams(var Params: TCreateParams);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ FocusRectVisible := False;
|
|
|
|
+ DefaultColWidth := 64;
|
|
|
|
+ Options := [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine,
|
|
|
|
+ goColSizing, goColMoving];
|
|
|
|
+ ColCount := 2;
|
|
|
|
+ RowCount := 6;
|
|
|
|
+ Height := Parent.ClientHeight;
|
|
|
|
+// DefaultRowHeight := Parent.Height div (6 + 1) - GridLineWidth;
|
|
|
|
+ DefaultRowHeight := 20;
|
|
|
|
+ Cells[0, cFld] := 'Field';
|
|
|
|
+ Cells[0, cTbl] := 'Table';
|
|
|
|
+ Cells[0, cShow] := 'Show';
|
|
|
|
+ Cells[0, cSort] := 'Sort';
|
|
|
|
+ Cells[0, cFunc] := 'Function';
|
|
|
|
+ Cells[0, cGroup] := 'Group';
|
|
|
|
+ OnDragOver := _DragOver;
|
|
|
|
+ OnDragDrop := _DragDrop;
|
|
|
|
+ IsEmpty := True;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBGrid.WndProc(var Message: TLMessage);
|
|
|
|
+begin
|
|
|
|
+ if (Message.Msg = LM_RBUTTONDOWN) then
|
|
|
|
+ ClickCell(TLMMouse(Message).XPos, TLMMouse(Message).YPos);
|
|
|
|
+ inherited;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBGrid.MaxSW(const s1, s2: string): Integer;
|
|
|
|
+begin
|
|
|
|
+ Result := Canvas.TextWidth(s1);
|
|
|
|
+ if Result < Canvas.TextWidth(s2) then
|
|
|
|
+ Result := Canvas.TextWidth(s2);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBGrid.InsertDefault(aCol: Integer);
|
|
|
|
+begin
|
|
|
|
+ Cells[aCol, cShow] := sShow;
|
|
|
|
+ Cells[aCol, cSort] := '';
|
|
|
|
+ Cells[aCol, cFunc] := '';
|
|
|
|
+ Cells[aCol, cGroup] := '';
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBGrid.Insert(aCol: Integer; const aField, aTable: string);
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+begin
|
|
|
|
+ if IsEmpty then
|
|
|
|
+ begin
|
|
|
|
+ IsEmpty := False;
|
|
|
|
+ aCol := 1;
|
|
|
|
+ Cells[aCol, cFld] := aField;
|
|
|
|
+ Cells[aCol, cTbl] := aTable;
|
|
|
|
+ InsertDefault(aCol);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ if aCol = -1 then
|
|
|
|
+ begin
|
|
|
|
+ ColCount := ColCount + 1;
|
|
|
|
+ aCol := ColCount - 1;
|
|
|
|
+ Cells[aCol, cFld] := aField;
|
|
|
|
+ Cells[aCol, cTbl] := aTable;
|
|
|
|
+ InsertDefault(aCol);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ ColCount := ColCount + 1;
|
|
|
|
+ for i := ColCount - 1 downto aCol + 1 do
|
|
|
|
+ MoveColRow(True,i - 1, i);
|
|
|
|
+ Cells[aCol, cFld] := aField;
|
|
|
|
+ Cells[aCol, cTbl] := aTable;
|
|
|
|
+ InsertDefault(aCol);
|
|
|
|
+ end;
|
|
|
|
+ //* Fix StringGrid Bug *
|
|
|
|
+ if aCol > 1 then
|
|
|
|
+ ColWidths[aCol - 1] := MaxSW(Cells[aCol - 1, cFld], Cells[aCol - 1, cTbl]) + 8;
|
|
|
|
+ if aCol < ColCount - 1 then
|
|
|
|
+ ColWidths[aCol + 1] := MaxSW(Cells[aCol + 1, cFld], Cells[aCol + 1, cTbl]) + 8;
|
|
|
|
+ ColWidths[ColCount - 1] := MaxSW(Cells[ColCount - 1, cFld],
|
|
|
|
+ Cells[ColCount - 1, cTbl]) + 8;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ ColWidths[aCol] := MaxSW(aTable, aField) + 8;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBGrid.FindColumn(const sCol: string): Integer;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+begin
|
|
|
|
+ Result := -1;
|
|
|
|
+ for i := 1 to ColCount - 1 do
|
|
|
|
+ if Cells[i, cFld] = sCol then
|
|
|
|
+ begin
|
|
|
|
+ Result := i;
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBGrid.FindSameColumn(aCol: Integer): Boolean;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+begin
|
|
|
|
+ Result := False;
|
|
|
|
+ for i := 1 to ColCount - 1 do
|
|
|
|
+ if i = aCol then
|
|
|
|
+ Continue
|
|
|
|
+ else if Cells[i, cFld] = Cells[aCol, cFld] then
|
|
|
|
+ begin
|
|
|
|
+ Result := True;
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBGrid.RemoveColumn(aCol: Integer);
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+begin
|
|
|
|
+ if (ColCount > 2) then
|
|
|
|
+ DeleteCol(aCol)
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ for i := 0 to RowCount - 1 do
|
|
|
|
+ Cells[1, i] := '';
|
|
|
|
+ IsEmpty := True;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBGrid.RemoveColumn4Tbl(const Tbl: string);
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+begin
|
|
|
|
+ for i := ColCount - 1 downto 1 do
|
|
|
|
+ if Cells[i, cTbl] = Tbl then
|
|
|
|
+ RemoveColumn(i);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBGrid.ClickCell(X, Y: Integer);
|
|
|
|
+var
|
|
|
|
+ P: TPoint;
|
|
|
|
+ mCol, mRow: Integer;
|
|
|
|
+begin
|
|
|
|
+ MouseToCell(X, Y, mCol, mRow);
|
|
|
|
+ CurrCol := mCol;
|
|
|
|
+ P.X := X;
|
|
|
|
+ P.Y := Y;
|
|
|
|
+ P := ClientToScreen(P);
|
|
|
|
+ if (mCol > 0) and (mCol < ColCount) and (not IsEmpty) then
|
|
|
|
+ begin
|
|
|
|
+ if (Cells[mCol, 0] = '*') and (mRow <> cFld) then
|
|
|
|
+ Exit;
|
|
|
|
+ case mRow of
|
|
|
|
+ cFld:
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuTbl.Popup(P.X, P.Y);
|
|
|
|
+ cShow:
|
|
|
|
+ begin
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuShow.Items[0].Checked := Cells[mCol, cShow] = sShow;
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuShow.Popup(P.X, P.Y);
|
|
|
|
+ end;
|
|
|
|
+ cSort:
|
|
|
|
+ begin
|
|
|
|
+ if Cells[mCol, cSort] = sSort[1] then
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuSort.Items[0].Checked := True
|
|
|
|
+ else if Cells[mCol, cSort] = sSort[2] then
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuSort.Items[2].Checked := True else
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuSort.Items[3].Checked := True;
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuSort.Popup(P.X, P.Y);
|
|
|
|
+ end;
|
|
|
|
+ cFunc:
|
|
|
|
+ begin
|
|
|
|
+ if Cells[mCol, cFunc] = sFunc[1] then
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuFunc.Items[0].Checked := True
|
|
|
|
+ else if Cells[mCol, cFunc] = sFunc[2] then
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuFunc.Items[2].Checked := True
|
|
|
|
+ else if Cells[mCol, cFunc] = sFunc[3] then
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuFunc.Items[3].Checked := True
|
|
|
|
+ else if Cells[mCol, cFunc] = sFunc[4] then
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuFunc.Items[4].Checked := True
|
|
|
|
+ else if Cells[mCol, cFunc] = sFunc[5] then
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuFunc.Items[5].Checked := True
|
|
|
|
+ else
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuFunc.Items[6].Checked := True;
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuFunc.Popup(P.X, P.Y);
|
|
|
|
+ end;
|
|
|
|
+ cGroup:
|
|
|
|
+ begin
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuGroup.Items[0].Checked := Cells[mCol, cGroup] = sGroup;
|
|
|
|
+ TOQBForm(GetParentForm(Self)).mnuGroup.Popup(P.X, P.Y);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TOQBGrid.SelectCell(ACol, ARow: Integer): Boolean;
|
|
|
|
+begin
|
|
|
|
+ inherited SelectCell(ACol, ARow);
|
|
|
|
+ Result := ARow > cGroup;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBGrid._DragOver(Sender, Source: TObject; X, Y: Integer;
|
|
|
|
+ State: TDragState; var Accept: Boolean);
|
|
|
|
+begin
|
|
|
|
+ if (Source <> TOQBForm(GetParentForm(Self)).QBTables) then
|
|
|
|
+ Accept := True;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBGrid._DragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
|
|
+var
|
|
|
|
+ dCol, dRow: Integer;
|
|
|
|
+begin
|
|
|
|
+ if ((Source is TOQBLbx) and
|
|
|
|
+ (Source <> TOQBForm(GetParentForm(Self)).QBTables)) then
|
|
|
|
+ begin
|
|
|
|
+ TOQBTable(TWinControl(Source).Parent).FLbx.Checked[
|
|
|
|
+ TOQBTable(TWinControl(Source).Parent).FLbx.ItemIndex] := True;//*** check
|
|
|
|
+ MouseToCell(X, Y, dCol, dRow);
|
|
|
|
+ if dCol = 0 then
|
|
|
|
+ Exit;
|
|
|
|
+ Insert(dCol,
|
|
|
|
+ TOQBTable(TWinControl(Source).Parent).FLbx.Items[TOQBTable(TWinControl(Source).Parent).FLbx.ItemIndex],
|
|
|
|
+ TOQBTable(TWinControl(Source).Parent).FTableName);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+{ TOQBForm }
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.CreateParams(var Params: TCreateParams);
|
|
|
|
+begin
|
|
|
|
+ inherited;
|
|
|
|
+ QBArea := TOQBArea.Create(Self);
|
|
|
|
+ QBArea.Parent := QBPanel;
|
|
|
|
+ QBArea.Align := alClient;
|
|
|
|
+ QBArea.Color := $009E9E9E;
|
|
|
|
+ QBGrid := TOQBGrid.Create(Self);
|
|
|
|
+ QBGrid.DefaultRowHeight := 22;
|
|
|
|
+ QBGrid.DefaultColWidth := 150;
|
|
|
|
+ QBGrid.Parent := TabColumns;
|
|
|
|
+ QBGrid.Align := alClient;
|
|
|
|
+ VSplitter.Tag := VSplitter.Left;
|
|
|
|
+ HSplitter.Tag := HSplitter.Top;
|
|
|
|
+ Application.ProcessMessages;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.mnuFunctionClick(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ Item: TMenuItem;
|
|
|
|
+begin
|
|
|
|
+ if Sender is TMenuItem then
|
|
|
|
+ begin
|
|
|
|
+ Item := (Sender as TMenuItem);
|
|
|
|
+ if not Item.Checked then
|
|
|
|
+ begin
|
|
|
|
+ Item.Checked := True;
|
|
|
|
+ QBGrid.Cells[QBGrid.CurrCol, cFunc] := sFunc[Item.Tag];
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.mnuGroupClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ if mnuGroup.Items[0].Checked then
|
|
|
|
+ begin
|
|
|
|
+ QBGrid.Cells[QBGrid.CurrCol, cGroup] := '';
|
|
|
|
+ mnuGroup.Items[0].Checked := False;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ QBGrid.Cells[QBGrid.CurrCol, cGroup] := sGroup;
|
|
|
|
+ mnuGroup.Items[0].Checked := True;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.mnuRemoveClick(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ TempTable: TOQBTable;
|
|
|
|
+begin
|
|
|
|
+ TempTable := QBArea.FindTable(QBGrid.Cells[QBGrid.CurrCol, cTbl]);
|
|
|
|
+ if not QBGrid.FindSameColumn(QBGrid.CurrCol) then
|
|
|
|
+ TempTable.FLbx.Checked[TempTable.FLbx.Items.IndexOf(QBGrid.Cells[QBGrid.CurrCol, cFld])] := False;
|
|
|
|
+ QBGrid.RemoveColumn(QBGrid.CurrCol);
|
|
|
|
+ QBGrid.Refresh; // fix for StringGrid bug
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.mnuShowClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ if mnuShow.Items[0].Checked then
|
|
|
|
+ begin
|
|
|
|
+ QBGrid.Cells[QBGrid.CurrCol, cShow] := '';
|
|
|
|
+ mnuShow.Items[0].Checked := False;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ QBGrid.Cells[QBGrid.CurrCol, cShow] := sShow;
|
|
|
|
+ mnuShow.Items[0].Checked := True;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.mnuSortClick(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ Item: TMenuItem;
|
|
|
|
+begin
|
|
|
|
+ if Sender is TMenuItem then
|
|
|
|
+ begin
|
|
|
|
+ Item := (Sender as TMenuItem);
|
|
|
|
+ if not Item.Checked then
|
|
|
|
+ begin
|
|
|
|
+ Item.Checked := True;
|
|
|
|
+ QBGrid.Cells[QBGrid.CurrCol, cSort] := sSort[Item.Tag];
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.ClearAll;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+ TempTable: TOQBTable;
|
|
|
|
+begin
|
|
|
|
+ for i := QBArea.ControlCount - 1 downto 0 do
|
|
|
|
+ if QBArea.Controls[i] is TOQBTable then
|
|
|
|
+ begin
|
|
|
|
+ TempTable := TOQBTable(QBArea.Controls[i]);
|
|
|
|
+ QBGrid.RemoveColumn4Tbl(TempTable.FTableName);
|
|
|
|
+ TempTable.Free;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ QBArea.Controls[i].Free; // QBLink
|
|
|
|
+
|
|
|
|
+ MemoSQL.Lines.Clear;
|
|
|
|
+ QBDialog.OQBEngine.ResultQuery.Close;
|
|
|
|
+ QBDialog.OQBEngine.ClearQuerySQL;
|
|
|
|
+ Pages.ActivePage := TabColumns;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnNewClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ ClearAll;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnOpenClick(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ i, ii, j: Integer;
|
|
|
|
+ s, ss: string;
|
|
|
|
+ TempDatabaseName: string;
|
|
|
|
+ ShowSystemTables: Boolean;
|
|
|
|
+ NewTable: TOQBTable;
|
|
|
|
+ TableName: string;
|
|
|
|
+ X, Y: Integer;
|
|
|
|
+ NewLink: TOQBLink;
|
|
|
|
+ Table1, Table2: TOQBTable;
|
|
|
|
+ FieldN1, FieldN2: Integer;
|
|
|
|
+ ColField, ColTable: string;
|
|
|
|
+ StrList: TStringList;
|
|
|
|
+
|
|
|
|
+ function GetNextVal(var s: string): string;
|
|
|
|
+ var
|
|
|
|
+ p: Integer;
|
|
|
|
+ begin
|
|
|
|
+ Result := EmptyStr;
|
|
|
|
+ p := Pos(',', s);
|
|
|
|
+ if p = 0 then
|
|
|
|
+ begin
|
|
|
|
+ p := Pos(';', s);
|
|
|
|
+ if p = 0 then
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+ Result := System.Copy(s, 1, p - 1);
|
|
|
|
+ System.Delete(s, 1, p);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ j := -1;
|
|
|
|
+ if not DlgOpen.Execute then
|
|
|
|
+ Exit;
|
|
|
|
+ StrList := TStringList.Create;
|
|
|
|
+ StrList.LoadFromFile(DlgOpen.FileName);
|
|
|
|
+ if StrList[0] <> QBSignature then
|
|
|
|
+ begin
|
|
|
|
+ ShowMessage('File ' + DlgOpen.FileName + ' is not QBuilder''s query file.');
|
|
|
|
+ StrList.Free;
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ ClearAll;
|
|
|
|
+ try
|
|
|
|
+ s := StrList[3]; // read options
|
|
|
|
+ if s = '+' then
|
|
|
|
+ WindowState := wsMaximized
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ WindowState := wsNormal;
|
|
|
|
+ Top := StrToInt(GetNextVal(s));
|
|
|
|
+ Left := StrToInt(GetNextVal(s));
|
|
|
|
+ Height := StrToInt(GetNextVal(s));
|
|
|
|
+ Width := StrToInt(GetNextVal(s));
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ s := StrList[4];
|
|
|
|
+ btnTables.Down := Boolean(StrToInt(GetNextVal(s)));
|
|
|
|
+ VSplitter.Visible := btnTables.Down;
|
|
|
|
+ QBTables.Visible := btnTables.Down;
|
|
|
|
+ QBTables.Width := StrToInt(GetNextVal(s));
|
|
|
|
+ btnPages.Down := Boolean(StrToInt(GetNextVal(s)));
|
|
|
|
+ HSplitter.Visible := btnPages.Down;
|
|
|
|
+ Pages.Visible := btnPages.Down;
|
|
|
|
+ Pages.Height := StrToInt(GetNextVal(s));
|
|
|
|
+
|
|
|
|
+ s := StrList[6]; // read database
|
|
|
|
+ TempDatabaseName := GetNextVal(s);
|
|
|
|
+ ShowSystemTables := Boolean(StrToInt(GetNextVal(s)));
|
|
|
|
+
|
|
|
|
+ QBDialog.OQBEngine.DatabaseName := TempDatabaseName;
|
|
|
|
+ QBDialog.OQBEngine.ShowSystemTables := ShowSystemTables;
|
|
|
|
+ OpenDatabase;
|
|
|
|
+
|
|
|
|
+ for i := 8 to StrList.Count - 1 do // read tables
|
|
|
|
+ begin
|
|
|
|
+ if StrList[i] = '[Links]' then
|
|
|
|
+ begin
|
|
|
|
+ j := i + 1;
|
|
|
|
+ Break;
|
|
|
|
+ end;
|
|
|
|
+ s := StrList[i];
|
|
|
|
+ TableName := GetNextVal(s);
|
|
|
|
+ Y := StrToInt(GetNextVal(s));
|
|
|
|
+ X := StrToInt(GetNextVal(s));
|
|
|
|
+ NewTable := TOQBTable.Create(Self);
|
|
|
|
+ NewTable.Parent := QBArea;
|
|
|
|
+ try
|
|
|
|
+ NewTable.Activate(TableName, X, Y);
|
|
|
|
+ NewTable.FLbx.FLoading := True;
|
|
|
|
+ for ii := 0 to NewTable.FLbx.Items.Count - 1 do
|
|
|
|
+ begin
|
|
|
|
+ ss := GetNextVal(s);
|
|
|
|
+ if ss <> EmptyStr then
|
|
|
|
+ NewTable.FLbx.Checked[ii] := Boolean(StrToInt(ss));
|
|
|
|
+ end;
|
|
|
|
+ NewTable.FLbx.FLoading := False;
|
|
|
|
+ except
|
|
|
|
+ NewTable.Free;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if j <> -1 then
|
|
|
|
+ for i := j to StrList.Count - 1 do // read links
|
|
|
|
+ begin
|
|
|
|
+ if StrList[i] = '[Columns]' then
|
|
|
|
+ begin
|
|
|
|
+ j := i + 1;
|
|
|
|
+ Break;
|
|
|
|
+ end;
|
|
|
|
+ s := StrList[i];
|
|
|
|
+ ss := GetNextVal(s);
|
|
|
|
+ Table1 := QBArea.FindTable(ss);
|
|
|
|
+ ss := GetNextVal(s);
|
|
|
|
+ FieldN1 := StrToInt(ss);
|
|
|
|
+ ss := GetNextVal(s);
|
|
|
|
+ Table2 := QBArea.FindTable(ss);
|
|
|
|
+ ss := GetNextVal(s);
|
|
|
|
+ FieldN2 := StrToInt(ss);
|
|
|
|
+ NewLink := QBArea.InsertLink(Table1, Table2, FieldN1, FieldN2);
|
|
|
|
+ ss := GetNextVal(s);
|
|
|
|
+ NewLink.FLinkOpt := StrToInt(ss);
|
|
|
|
+ ss := GetNextVal(s);
|
|
|
|
+ NewLink.FLinkType := StrToInt(ss);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if j <> -1 then
|
|
|
|
+ for i := j to StrList.Count - 1 do // read columns
|
|
|
|
+ begin
|
|
|
|
+ if StrList[i] = '[End]' then
|
|
|
|
+ Break;
|
|
|
|
+ s := StrList[i];
|
|
|
|
+ ii := StrToInt(GetNextVal(s));
|
|
|
|
+ ColField := GetNextVal(s);
|
|
|
|
+ ColTable := GetNextVal(s);
|
|
|
|
+ QBGrid.Insert(ii, ColField, ColTable);
|
|
|
|
+ QBGrid.Cells[ii, cShow] := GetNextVal(s);
|
|
|
|
+ QBGrid.Cells[ii, cSort] := GetNextVal(s);
|
|
|
|
+ QBGrid.Cells[ii, cFunc] := GetNextVal(s);
|
|
|
|
+ QBGrid.Cells[ii, cGroup] := GetNextVal(s);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ finally
|
|
|
|
+ StrList.Free;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnSaveClick(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ i, j: Integer;
|
|
|
|
+ s: string;
|
|
|
|
+ TempTable: TOQBTable;
|
|
|
|
+ TempLink: TOQBLink;
|
|
|
|
+ StrList: TStringList;
|
|
|
|
+begin
|
|
|
|
+ if not DlgSave.Execute then Exit;
|
|
|
|
+ StrList := TStringList.Create;
|
|
|
|
+ StrList.Add(QBSignature);
|
|
|
|
+ StrList.Add('# Don''t change this file !');
|
|
|
|
+ StrList.Add('[Options]');
|
|
|
|
+ if WindowState = wsMaximized then
|
|
|
|
+ s := '+' else
|
|
|
|
+ s := IntToStr(Top) + ',' + IntToStr(Left) + ',' + IntToStr(Height) + ',' +
|
|
|
|
+ IntToStr(Width) + ';';
|
|
|
|
+ StrList.Add(s);
|
|
|
|
+ s := IntToStr(Integer(btnTables.Down)) + ',' + IntToStr(QBTables.Width) +
|
|
|
|
+ ',' + IntToStr(Integer(btnPages.Down)) + ',' + IntToStr(Pages.Height) + ';';
|
|
|
|
+ StrList.Add(s);
|
|
|
|
+
|
|
|
|
+ StrList.Add('[Database]');
|
|
|
|
+ s := QBDialog.OQBEngine.DatabaseName + ',' + IntToStr(Integer(QBDialog.OQBEngine.ShowSystemTables)) + ';';
|
|
|
|
+ StrList.Add(s);
|
|
|
|
+
|
|
|
|
+ StrList.Add('[Tables]'); // save tables
|
|
|
|
+ for i := 0 to QBArea.ControlCount - 1 do
|
|
|
|
+ if QBArea.Controls[i] is TOQBTable then
|
|
|
|
+ begin
|
|
|
|
+ TempTable := TOQBTable(QBArea.Controls[i]);
|
|
|
|
+ s := TempTable.FTableName + ',' +
|
|
|
|
+ IntToStr(TempTable.Top + QBArea.VertScrollBar.ScrollPos) + ',' +
|
|
|
|
+ IntToStr(TempTable.Left + QBArea.HorzScrollBar.ScrollPos);
|
|
|
|
+ for j := 0 to TempTable.FLbx.Items.Count - 1 do
|
|
|
|
+ if TempTable.FLbx.Checked[j] then
|
|
|
|
+ s := s + ',1' else
|
|
|
|
+ s := s + ',0';
|
|
|
|
+ s := s + ';';
|
|
|
|
+ StrList.Add(s);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ StrList.Add('[Links]'); // save links
|
|
|
|
+ for i := 0 to QBArea.ControlCount - 1 do
|
|
|
|
+ if QBArea.Controls[i] is TOQBLink then
|
|
|
|
+ begin
|
|
|
|
+ TempLink := TOQBLink(QBArea.Controls[i]);
|
|
|
|
+ s := TempLink.Tbl1.FTableName + ',' + IntToStr(TempLink.FldN1) + ',' +
|
|
|
|
+ TempLink.Tbl2.FTableName + ',' + IntToStr(TempLink.FldN2) + ',' +
|
|
|
|
+ IntToStr(TempLink.FLinkOpt) + ',' + IntToStr(TempLink.FLinkType);
|
|
|
|
+ s := s + ';';
|
|
|
|
+ StrList.Add(s);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ StrList.Add('[Columns]'); // save columns
|
|
|
|
+ if not QBGrid.IsEmpty then
|
|
|
|
+ for i := 1 to QBGrid.ColCount - 1 do
|
|
|
|
+ begin
|
|
|
|
+ s := IntToStr(i) + ',' + QBGrid.Cells[i, cFld] + ',' + QBGrid.Cells[i, cTbl];
|
|
|
|
+ s := s + ',' + QBGrid.Cells[i, cShow] + ',' + QBGrid.Cells[i, cSort] +
|
|
|
|
+ ',' + QBGrid.Cells[i, cFunc] + ',' + QBGrid.Cells[i, cGroup];
|
|
|
|
+ s := s + ';';
|
|
|
|
+ StrList.Add(s);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ StrList.Add('[End]'); // end of QBuilder information
|
|
|
|
+
|
|
|
|
+ StrList.SaveToFile(DlgSave.FileName);
|
|
|
|
+ StrList.Free;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnTablesClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ VSplitter.Visible := TToolButton(Sender).Down;
|
|
|
|
+ QBTables.Visible := TToolButton(Sender).Down;
|
|
|
|
+ if not VSplitter.Visible then
|
|
|
|
+ VSplitter.Tag := VSplitter.Left
|
|
|
|
+ else
|
|
|
|
+ VSplitter.Left := VSplitter.Tag;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnPagesClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ HSplitter.Visible := TToolButton(Sender).Down;
|
|
|
|
+ Pages.Visible := TToolButton(Sender).Down;
|
|
|
|
+ if not HSplitter.Visible then
|
|
|
|
+ HSplitter.Tag := HSplitter.Top
|
|
|
|
+ else
|
|
|
|
+ HSplitter.Top := HSplitter.Tag;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.OpenDatabase;
|
|
|
|
+begin
|
|
|
|
+ try
|
|
|
|
+ QBDialog.OQBEngine.ReadTableList;
|
|
|
|
+ QBDialog.OQBEngine.GenerateAliases;
|
|
|
|
+ QBTables.Items.Assign(QBDialog.OQBEngine.TableList);
|
|
|
|
+ ResDataSource.DataSet := QBDialog.OQBEngine.ResultQuery;
|
|
|
|
+ Caption := sMainCaption + ' [' + QBDialog.OQBEngine.DatabaseName + ']';
|
|
|
|
+ except
|
|
|
|
+ // ignore errors
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.SelectDatabase;
|
|
|
|
+begin
|
|
|
|
+ if QBDialog.OQBEngine.SelectDatabase then
|
|
|
|
+ begin
|
|
|
|
+ ClearAll;
|
|
|
|
+ QBTables.Items.Clear;
|
|
|
|
+ OpenDatabase;
|
|
|
|
+ end
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnDBClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ SelectDatabase;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnSQLClick(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ Lst, Lst1, Lst2: TStringList; // temporary string lists
|
|
|
|
+ i: Integer;
|
|
|
|
+ s: string;
|
|
|
|
+ tbl1, tbl2: string;
|
|
|
|
+ Link: TOQBLink;
|
|
|
|
+
|
|
|
|
+ function ExtractName(s: string):string;
|
|
|
|
+ var
|
|
|
|
+ p: Integer;
|
|
|
|
+ begin
|
|
|
|
+ Result := s;
|
|
|
|
+ p := Pos('.', s);
|
|
|
|
+ if p = 0 then
|
|
|
|
+ Exit;
|
|
|
|
+ Result := System.Copy(s, 1, p - 1);
|
|
|
|
+ end;
|
|
|
|
+begin
|
|
|
|
+ if QBGrid.IsEmpty then
|
|
|
|
+ begin
|
|
|
|
+ ShowMessage('Columns are not selected.');
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+ Lst := TStringList.Create;
|
|
|
|
+ try
|
|
|
|
+ with QBDialog.OQBEngine do
|
|
|
|
+ begin
|
|
|
|
+ SQLcolumns.Clear;
|
|
|
|
+ SQLcolumns_func.Clear;
|
|
|
|
+ SQLcolumns_table.Clear;
|
|
|
|
+ SQLfrom.Clear;
|
|
|
|
+ SQLwhere.Clear;
|
|
|
|
+ SQLgroupby.Clear;
|
|
|
|
+ SQLorderby.Clear;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ // SELECT clause
|
|
|
|
+ with QBGrid do
|
|
|
|
+ begin
|
|
|
|
+ for i := 1 to ColCount - 1 do
|
|
|
|
+ if Cells[i, cShow] = sShow then
|
|
|
|
+ begin
|
|
|
|
+ if QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ tbl1 := QBDialog.OQBEngine.AliasList[QBDialog.OQBEngine.TableList.IndexOf(Cells[i, cTbl])]
|
|
|
|
+ else
|
|
|
|
+ tbl1 := Cells[i, cTbl];
|
|
|
|
+ s := tbl1 + '.' + Cells[i, cFld];
|
|
|
|
+ Lst.Add(LowerCase(s));
|
|
|
|
+ if Cells[i, cFunc] <> EmptyStr then
|
|
|
|
+ s := UpperCase(Cells[i, cFunc]) else
|
|
|
|
+ s := EmptyStr;
|
|
|
|
+ if QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ QBDialog.OQBEngine.SQLcolumns_table.Add(LowerCase(
|
|
|
|
+ QBDialog.OQBEngine.AliasList[QBDialog.OQBEngine.TableList.IndexOf(Cells[i, cTbl])]))
|
|
|
|
+ else
|
|
|
|
+ QBDialog.OQBEngine.SQLcolumns_table.Add(LowerCase(Cells[i, cTbl]));
|
|
|
|
+ QBDialog.OQBEngine.SQLcolumns_func.Add(s);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if Lst.Count = 0 then
|
|
|
|
+ begin
|
|
|
|
+ ShowMessage('Columns are not selected.');
|
|
|
|
+ Lst.Free;
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
|
|
+ QBDialog.OQBEngine.SQLcolumns.Assign(Lst);
|
|
|
|
+ Lst.Clear;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ // FROM clause
|
|
|
|
+ with QBArea do
|
|
|
|
+ begin
|
|
|
|
+ Lst1 := TSTringList.Create; // tables in joins
|
|
|
|
+ Lst2 := TSTringList.Create; // outer joins
|
|
|
|
+ for i := 0 to ControlCount - 1 do // search tables for joins
|
|
|
|
+ if Controls[i] is TOQBLink then
|
|
|
|
+ begin
|
|
|
|
+ Link := TOQBLink(Controls[i]);
|
|
|
|
+ if Link.FLinkType > 0 then
|
|
|
|
+ begin
|
|
|
|
+ if QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ begin
|
|
|
|
+ tbl1 := LowerCase(Link.Tbl1.FTableAlias);
|
|
|
|
+ tbl2 := LowerCase(Link.Tbl2.FTableAlias);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ tbl1 := LowerCase(Link.Tbl1.FTableName);
|
|
|
|
+ tbl2 := LowerCase(Link.Tbl2.FTableName);
|
|
|
|
+ end;
|
|
|
|
+ if Lst1.IndexOf(tbl1) = -1 then
|
|
|
|
+ Lst1.Add(tbl1);
|
|
|
|
+ if Lst1.IndexOf(tbl2) = -1 then
|
|
|
|
+ Lst1.Add(tbl2);
|
|
|
|
+ if QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ Lst2.Add(LowerCase(Link.Tbl1.FTableName) + ' ' + tbl1 +
|
|
|
|
+ sOuterJoin[Link.FLinkType] +
|
|
|
|
+ LowerCase(Link.Tbl2.FTableName) + ' ' + tbl2 + ' ON ' +
|
|
|
|
+ tbl1 + '.' + LowerCase(Link.FldNam1) + sLinkOpt[Link.FLinkOpt] +
|
|
|
|
+ tbl2 + '.' + LowerCase(Link.FldNam2))
|
|
|
|
+ else
|
|
|
|
+ Lst2.Add(tbl1 + sOuterJoin[Link.FLinkType] + tbl2 + ' ON ' +
|
|
|
|
+ tbl1 + '.' + LowerCase(Link.FldNam1) +
|
|
|
|
+ sLinkOpt[Link.FLinkOpt] + tbl2 + '.' + LowerCase(Link.FldNam2));
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ for i := 0 to ControlCount - 1 do
|
|
|
|
+ if Controls[i] is TOQBTable then
|
|
|
|
+ begin
|
|
|
|
+ if QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ tbl1 := LowerCase(TOQBTable(Controls[i]).FTableAlias) else
|
|
|
|
+ tbl1 := LowerCase(TOQBTable(Controls[i]).FTableName);
|
|
|
|
+ if (Lst.IndexOf(tbl1) = -1) and (Lst1.IndexOf(tbl1) = -1) then
|
|
|
|
+ if QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ Lst.Add(LowerCase(TOQBTable(Controls[i]).FTableName) + ' ' + tbl1) else
|
|
|
|
+ Lst.Add(tbl1);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ Lst1.Free;
|
|
|
|
+
|
|
|
|
+ QBDialog.OQBEngine.SQLfrom.Assign(Lst2);
|
|
|
|
+ QBDialog.OQBEngine.SQLfrom.AddStrings(Lst);
|
|
|
|
+ Lst2.Free;
|
|
|
|
+ Lst.Clear;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ // WHERE clause
|
|
|
|
+ with QBArea do
|
|
|
|
+ begin
|
|
|
|
+ for i := 0 to ControlCount - 1 do
|
|
|
|
+ if Controls[i] is TOQBLink then
|
|
|
|
+ begin
|
|
|
|
+ Link := TOQBLink(Controls[i]);
|
|
|
|
+ if Link.FLinkType = 0 then
|
|
|
|
+ begin
|
|
|
|
+ if QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ s := Link.tbl1.FTableAlias + '.' + Link.fldNam1 + sLinkOpt[Link.FLinkOpt] +
|
|
|
|
+ Link.tbl2.FTableAlias + '.' + Link.fldNam2
|
|
|
|
+ else
|
|
|
|
+ s := Link.tbl1.FTableName + '.' + Link.fldNam1 + sLinkOpt[Link.FLinkOpt] +
|
|
|
|
+ Link.tbl2.FTableName + '.' + Link.fldNam2;
|
|
|
|
+
|
|
|
|
+ Lst.Add(LowerCase(s));
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ QBDialog.OQBEngine.SQLwhere.Assign(Lst);
|
|
|
|
+ Lst.Clear;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ // GROUP BY clause
|
|
|
|
+ with QBGrid do
|
|
|
|
+ begin
|
|
|
|
+ for i := 1 to ColCount - 1 do
|
|
|
|
+ begin
|
|
|
|
+ if Cells[i, cGroup] <> EmptyStr then
|
|
|
|
+ begin
|
|
|
|
+ if QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ tbl1 := QBDialog.OQBEngine.AliasList[QBDialog.OQBEngine.TableList.IndexOf(Cells[i, cTbl])]
|
|
|
|
+ else
|
|
|
|
+ tbl1 := Cells[i, cTbl];
|
|
|
|
+ s := tbl1 + '.' + Cells[i, cFld];
|
|
|
|
+ Lst.Add(LowerCase(s));
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ QBDialog.OQBEngine.SQLgroupby.Assign(Lst);
|
|
|
|
+ Lst.Clear;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ // ORDER BY clause
|
|
|
|
+ with QBGrid do
|
|
|
|
+ begin
|
|
|
|
+ for i := 1 to ColCount - 1 do
|
|
|
|
+ begin
|
|
|
|
+ if Cells[i, cSort] <> EmptyStr then
|
|
|
|
+ begin
|
|
|
|
+ if QBDialog.OQBEngine.UseTableAliases then
|
|
|
|
+ tbl1 := QBDialog.OQBEngine.AliasList[QBDialog.OQBEngine.TableList.IndexOf(Cells[i, cTbl])]
|
|
|
|
+ else
|
|
|
|
+ tbl1 := Cells[i, cTbl];
|
|
|
|
+ // --- to order result set by the result of an aggregate function
|
|
|
|
+ if Cells[i, cFunc] = EmptyStr then
|
|
|
|
+ s := LowerCase(tbl1 + '.' + Cells[i, cFld]) else
|
|
|
|
+ s := IntToStr(i);
|
|
|
|
+ // ---
|
|
|
|
+
|
|
|
|
+ if Cells[i, cSort] = sSort[3] then
|
|
|
|
+ s := s + ' DESC';
|
|
|
|
+ Lst.Add(s);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ QBDialog.OQBEngine.SQLorderby.Assign(Lst);
|
|
|
|
+ Lst.Clear;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ MemoSQL.Lines.Text := QBDialog.OQBEngine.GenerateSQL;
|
|
|
|
+ Pages.ActivePage := TabSQL;
|
|
|
|
+ finally
|
|
|
|
+ Lst.Free;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnResultsClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ // We may be able to generate the SQL if the user has
|
|
|
|
+ // visually created one
|
|
|
|
+ if MemoSQL.Lines.Text='' then
|
|
|
|
+ btnSQLClick(Sender);
|
|
|
|
+ QBDialog.OQBEngine.CloseResultQuery; // OQB 4.0a
|
|
|
|
+ QBDialog.OQBEngine.SetQuerySQL(MemoSQL.Lines.Text);
|
|
|
|
+ QBDialog.OQBEngine.OpenResultQuery;
|
|
|
|
+ Pages.ActivePage := TabResults;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnAboutClick(Sender: TObject);
|
|
|
|
+var
|
|
|
|
+ QBAboutForm: TOQBAboutForm;
|
|
|
|
+begin
|
|
|
|
+ QBAboutForm := TOQBAboutForm.Create(Application);
|
|
|
|
+ QBAboutForm.ShowModal;
|
|
|
|
+ QBAboutForm.Free;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnSaveResultsClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ QBDialog.OQBEngine.SaveResultQueryData;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnOKClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ ModalResult := mrOk;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TOQBForm.btnCancelClick(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ ModalResult := mrCancel;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+end.
|