Componentes.Terceros.SDAC/internal/4.10.0.10/1/Source/Design/CREditor.pas
2007-10-05 14:48:18 +00:00

1256 lines
32 KiB
ObjectPascal

//////////////////////////////////////////////////
// DB Access Components
// Copyright © 1998-2007 Core Lab. All right reserved.
// Base Component Editor
//////////////////////////////////////////////////
{$IFNDEF CLR}
{$I Dac.inc}
unit CREditor;
{$ENDIF}
interface
uses
{$IFDEF MSWINDOWS}
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, DBGrids, Dialogs,
StdCtrls, ExtCtrls, Buttons,
{$ENDIF}
{$IFDEF LINUX}
SysUtils, Types, Classes, QGraphics, QControls, QForms, QDBGrids, QDialogs, QStdCtrls, QExtCtrls,
QButtons, Qt,
{$ENDIF}
{$IFDEF DBTOOLS}
DBToolsClient,
{$IFDEF CLR}
System.Text,
{$ENDIF}
{$ENDIF}
DBAccess, DADesignUtils;
type
TCREditorClass = class of TCREditorForm;
TCREditorForm = class(TForm)
BtnPanel: TPanel;
btOk: TBitBtn;
btCancel: TBitBtn;
imCorner: TImage;
procedure FormShow(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure SaveClick(Sender: TObject);
procedure CloseClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormKeyPress(Sender: TObject; var Key: Char);
{$IFDEF DBTOOLS}
{$IFDEF CLR}
protected
OldMessageProcessing : TMessageEvent;
procedure MessageProcessing(var Msg: TMsg; var Handled: Boolean);
public
destructor Destroy; override;
{$ENDIF}
{$ENDIF}
private
FOldCreateOrder: boolean;
{$IFDEF MSWINDOWS}
FOldPosition: TPosition;
{$ENDIF}
FConfirmCancel: boolean;
procedure SetConfirmCancel(const Value: boolean);
{$IFDEF DBTOOLS}
procedure WMActivate(var Message: TWMActivate); message WM_ACTIVATE;
{$ENDIF}
protected
FModified: boolean;
FolderName: string;
FDADesignUtilsClass: TDADesignUtilsClass;
FInitialProperty: string;
{$IFDEF USE_SYNEDIT}
FSynSQLSyn: TPersistent;
FUseSynEdit: boolean;
{$ENDIF}
function GetModified: boolean; virtual;
procedure SetModified(Value: boolean); virtual;
procedure ReplaceMemos;
{$IFDEF USE_SYNEDIT}
procedure SynMenuItemClick(Sender: TObject);
procedure SynMenuPopup(Sender: TObject);
{$ENDIF}
procedure DoInit; virtual;
procedure DoActivate; virtual;
procedure DoSave; virtual;
procedure DoFinish; virtual;
procedure ExitActiveControl; virtual;
procedure SaveControlData; virtual;
function SaveState: boolean; virtual;
function LoadState: boolean; virtual;
function GetComponent: TComponent; virtual;
procedure SetComponent(Value: TComponent); virtual;
function GetLocalComponent: TComponent; virtual;
{$IFDEF MSWINDOWS}
function KeyPath: string;
{$ENDIF}
{$IFDEF DBTOOLS}
procedure ActiveChanged; override;
{$ENDIF}
property Modified: boolean read GetModified write SetModified;
public
constructor Create(Owner: TComponent; DADesignUtilsClass: TDADesignUtilsClass); reintroduce; virtual;
{$IFDEF USE_SYNEDIT}
procedure ReplaceMemo(var Memo: TWinControl; DrawGutter: boolean);
{$ENDIF}
procedure CheckConnection(const Component: TComponent);
/// If ConfirmCancel is True editor asks user for comfirmation to discard
/// changes. By default ConfirmCancel is set to True.
property ConfirmCancel: boolean read FConfirmCancel write SetConfirmCancel;
property DADesignUtilsClass: TDADesignUtilsClass read FDADesignUtilsClass;
property Component: TComponent read GetComponent write SetComponent;
property LocalComponent: TComponent read GetLocalComponent;
property InitialProperty: string read FInitialProperty write FInitialProperty;
published
property OldCreateOrder: boolean read FOldCreateOrder write FOldCreateOrder; // for D3
end;
{
TComponent
TControl
TWinControl
TCustomEdit
TCustomMemo
TMemo
TDAMemo
TCustomControl
TCustomSynEdit
TSynEdit
TSynMemo
}
TDAMemo = class(TMemo)
protected
BackSpacePressed: boolean;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
end;
{$IFDEF LINUX}
TWinControlClass = class of TWinControl;
{$ENDIF}
function ReplaceControl(var Control: TWinControl; const NewClass: TWinControlClass): boolean;
function ReplaceGridToCRGrid(var DBGrid: TCustomDBGrid): boolean;
function GetMemoText(Memo: TWinControl): string;
procedure SetMemoText(Memo: TWinControl; Value: string);
function GetReadOnly(Memo: TWinControl): boolean;
procedure SetReadOnly(Memo: TWinControl; Value: boolean);
function GetSelStart(Memo: TWinControl): integer;
procedure SetSelStart(Memo: TWinControl; Value: integer);
procedure SetSelLength(Memo: TWinControl; Value: integer);
procedure LoadFromFile(Memo: TWinControl; FileName: string);
procedure SaveToFile(Memo: TWinControl; FileName: string);
implementation
uses
{$IFDEF MSWINDOWS}
Registry,
{$ENDIF}
{$IFDEF USE_SYNEDIT}
Menus,
{$ENDIF}
TypInfo,
DAParamValueEditor, DB, DAConsts;
{$IFDEF IDE}
{$R *.dfm}
{$ENDIF}
{$IFDEF MSWINDOWS}
{$R CREditor.dfm}
{$ENDIF}
{$IFDEF LINUX}
{$R *.xfm}
{$ENDIF}
const
sSynMemo = 'TSynMemo';
sSynSQLSyn = 'TSynSQLSyn';
{$IFDEF USE_SYNEDIT}
SynMenuItemNames: array[0..7] of string = (
'&Undo',
'-',
'Cu&t',
'&Copy',
'&Paste',
'&Delete',
'-',
'Select &All'
);
type
TSynMenuItem = class(TMenuItem)
public
Memo: TWinControl;
end;
{$ENDIF}
function ReplaceControl(var Control: TWinControl; const NewClass: TWinControlClass): boolean;
var
NewControl: TWinControl;
i, PropCount: integer;
{$IFDEF CLR}
PropList: TPropList;
PropInfo: TPropInfo;
{$ELSE}
PropList: PPropList;
PropInfo: PPropInfo;
{$ENDIF}
OldParent: TWinControl;
OldTabOrder: integer;
OldName: string;
Obj, NewObj: TPersistent;
OldAct: boolean;
OldMemoValue: string;
begin
Result := NewClass <> nil;
if not Result then
Exit;
{$IFDEF CLR}
if NewClass.ClassName = 'TCRDBGrid' then begin
Result := False;
Exit;
end;
{$ENDIF}
NewControl := NewClass.Create(Control.Owner);
OldParent := Control.Parent;
OldTabOrder := Control.TabOrder;
OldName := Control.Name;
if (Control is TMemo) and (NewControl is TMemo) then
OldMemoValue := TMemo(Control).Lines.Text
else
OldMemoValue := '';
OldAct := (Control.Owner <> nil)
and (Control.Owner is TCustomForm)
and (TCustomForm(Control.Owner).ActiveControl = Control);
Control.Parent := OldParent;
{$IFDEF CLR}
PropList := GetPropList(NewClass.ClassInfo, tkAny, False);
PropCount := Length(PropList);
{$ELSE}
PropCount := GetPropList(NewClass.ClassInfo, tkAny, nil{$IFDEF VER6P}, False {$ENDIF});
GetMem(PropList, PropCount * sizeof(PropList[0]));
try
GetPropList(NewClass.ClassInfo, tkAny, PropList{$IFDEF VER6P}, False {$ENDIF});
{$ENDIF}
for i := 0 to PropCount - 1 do begin
PropInfo := GetPropInfo(Control, PropList[i].Name);
if (PropInfo <> nil) // published property
and (PropList[i].Name <> 'Name')
and (IsStoredProp(Control, PropInfo)) then
case PropList[i].PropType{$IFNDEF CLR}^{$ENDIF}.Kind of
tkClass:
begin
{$IFDEF CLR}
Obj := GetObjectProp(Control, PropInfo) as TPersistent;
{$ELSE}
Obj := TPersistent(integer(GetPropValue(Control, PropList[i].Name)));
{$ENDIF}
if (Obj <> nil) and (Obj.ClassName <> 'TMemoStrings'{$IFDEF CLR}{$IFDEF VER9P} + '$StdCtrls'{$ENDIF}{$ENDIF}) then begin
Assert(Obj is TPersistent);
{$IFDEF CLR}
NewObj := GetObjectProp(NewControl, PropList[i].Name) as TPersistent;
{$ELSE}
NewObj := TPersistent(integer(GetPropValue(NewControl, PropList[i].Name)));
{$ENDIF}
if NewObj = nil then begin
NewObj := Obj;
SetObjectProp(Control, PropInfo, nil);
//SetOrdProp(Control, PropList[i], integer(nil));
end
else
begin
Assert(NewObj is TPersistent);
{$IFDEF VER10}
if NewObj is TMargins then Continue;
{$ENDIF}
NewObj.Assign(Obj);
end;
{$IFDEF CLR}
PropInfo := GetPropInfo(NewControl, PropList[i].Name);
{$ENDIF}
SetObjectProp(NewControl, PropInfo, NewObj);
//SetOrdProp(NewControl, PropList[i], integer(NewObj));
end;
end;
tkMethod:
SetMethodProp(NewControl, PropList[i], GetMethodProp(Control, PropList[i]));
else
SetPropValue(NewControl, PropList[i].Name, GetPropValue(Control, PropList[i].Name));
end;
end;
{$IFNDEF CLR}
finally
FreeMem(PropList);
end;
{$ENDIF}
Control.Free;
Control := NewControl;
Control.Name := OldName;
Control.Parent := OldParent;
Control.TabOrder := OldTabOrder;
if Control is TMemo then
TMemo(Control).Lines.Text := OldMemoValue;
if OldAct then
TCustomForm(Control.Owner).ActiveControl := Control;
end;
function ReplaceGridToCRGrid(var DBGrid: TCustomDBGrid): boolean;
var
wc: TWinControl;
NewClass: TWinControlClass;
begin
wc := TWinControl(DBGrid);
NewClass := TWinControlClass(GetClass('TCRDBGrid'));
Result := ReplaceControl(wc, NewClass);
if Result then
DBGrid := wc as TCustomDBGrid;
end;
function GetMemoText(Memo: TWinControl): string;
begin
{$IFDEF DBTOOLS}
if DBTools.HasDACSqlEditorFrame(Memo) then
Result := DBTools.GetDACSqlEditorFrame(Memo).Text
else
{$ENDIF}
if Memo is TMemo then
Result := TMemo(Memo).Lines.Text
else
if Memo.ClassName = sSynMemo then
Result := TStrings(GetObjectProp(Memo, 'Lines')).Text
else
begin
Result := '';
Assert(False, Memo.ClassName);
end;
end;
procedure SetMemoText(Memo: TWinControl; Value: string);
begin
{$IFDEF DBTOOLS}
if DBTools.HasDACSqlEditorFrame(Memo) then
DBTools.GetDACSqlEditorFrame(Memo).Text := Value
else
{$ENDIF}
if Memo is TMemo then
TMemo(Memo).Lines.Text := Value
else
if Memo.ClassName = sSynMemo then
TStrings(GetObjectProp(Memo, 'Lines')).Text := Value
else
Assert(False, Memo.ClassName);
end;
function GetReadOnly(Memo: TWinControl): boolean;
begin
{$IFDEF DBTOOLS}
if DBTools.HasDACSqlEditorFrame(Memo) then
Result := DBTools.GetDACSqlEditorFrame(Memo).ReadOnly
else
{$ENDIF}
if Memo is TMemo then
Result := TMemo(Memo).ReadOnly
else
if Memo.ClassName = sSynMemo then
Result := Boolean(GetOrdProp(Memo, 'ReadOnly'))
else
begin
Result := False;
Assert(False, Memo.ClassName);
end;
end;
procedure SetReadOnly(Memo: TWinControl; Value: boolean);
begin
{$IFDEF DBTOOLS}
if DBTools.HasDACSqlEditorFrame(Memo) then
DBTools.GetDACSqlEditorFrame(Memo).ReadOnly := Value
else
{$ENDIF}
if Memo is TMemo then
TMemo(Memo).ReadOnly := Value
else
if Memo.ClassName = sSynMemo then
SetOrdProp(Memo, 'ReadOnly', Longint(Value));
end;
function GetSelStart(Memo: TWinControl): integer;
begin
{$IFDEF DBTOOLS}
if DBTools.HasDACSqlEditorFrame(Memo) then
Result := 0
else
{$ENDIF}
if Memo is TMemo then
Result := TMemo(Memo).SelStart
else
{$IFDEF USE_SYNEDIT}
if Memo.ClassName = sSynMemo then
SendMessage(Memo.Handle, EM_GETSEL, Integer(@Result), 0)
else
{$ENDIF}
begin
Result := -1;
Assert(False, Memo.ClassName);
end;
end;
procedure SetSelStart(Memo: TWinControl; Value: integer);
begin
{$IFDEF DBTOOLS}
if DBTools.HasDACSqlEditorFrame(Memo) then begin
end
else
{$ENDIF}
if Memo is TMemo then
TMemo(Memo).SelStart := Value
else
{$IFDEF USE_SYNEDIT}
if Memo.ClassName = sSynMemo then
SendMessage(Memo.Handle, EM_SETSEL, Value, Value)
else
{$ENDIF}
Assert(False, Memo.ClassName);
end;
procedure SetSelLength(Memo: TWinControl; Value: integer);
begin
{$IFDEF DBTOOLS}
if DBTools.HasDACSqlEditorFrame(Memo) then begin
end
else
{$ENDIF}
if Memo is TMemo then
TMemo(Memo).SelLength := Value
else
{$IFDEF USE_SYNEDIT}
if Memo.ClassName = sSynMemo then
SetOrdProp(Memo, 'SelLength', Value)
else
{$ENDIF}
Assert(False, Memo.ClassName);
end;
procedure LoadFromFile(Memo: TWinControl; FileName: string);
var
SL: TStrings;
{$IFDEF DBTOOLS}
UseDBTools: boolean;
{$ENDIF}
begin
SL := nil;
{$IFDEF DBTOOLS}
if not DBTools.HasDACSqlEditorFrame(Memo) then
{$ENDIF}
if Memo is TMemo then
SL := TMemo(Memo).Lines
else
{$IFDEF USE_SYNEDIT}
if Memo.ClassName = sSynMemo then
SL := TStrings(GetObjectProp(Memo, 'Lines'))
else
{$ENDIF}
Assert(False, Memo.ClassName);
{$IFDEF DBTOOLS}
UseDBTools := SL = nil;
if UseDBTools then
SL := TSTringList.Create;
try
{$ENDIF}
SL.LoadFromFile(FileName);
{$IFDEF DBTOOLS}
if UseDBTools then
DBTools.GetDACSqlEditorFrame(Memo).Text := SL.Text
finally
if UseDBTools then
SL.Free;
end;
{$ENDIF}
end;
procedure SaveToFile(Memo: TWinControl; FileName: string);
var
SL: TStrings;
{$IFDEF DBTOOLS}
UseDBTools: boolean;
{$ENDIF}
begin
SL := nil;
{$IFDEF DBTOOLS}
if not DBTools.HasDACSqlEditorFrame(Memo) then
{$ENDIF}
if Memo is TMemo then
SL := TMemo(Memo).Lines
else
{$IFDEF USE_SYNEDIT}
if Memo.ClassName = sSynMemo then
SL := TStrings(GetObjectProp(Memo, 'Lines'))
else
{$ENDIF}
Assert(False, Memo.ClassName);
{$IFDEF DBTOOLS}
UseDBTools := SL = nil;
if UseDBTools then begin
SL := TSTringList.Create;
SL.Text := DBTools.GetDACSqlEditorFrame(Memo).Text
end;
try
{$ENDIF}
SL.SaveToFile(FileName);
{$IFDEF DBTOOLS}
finally
if UseDBTools then
SL.Free;
end;
{$ENDIF}
end;
{ TDAMemo }
procedure TDAMemo.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited;
if Shift = [ssCtrl] then begin
if Key = 65 then
SelectAll
else
if (Key = {$IFNDEF LINUX}VK_BACK{$ELSE}Key_Backspace{$ENDIF}) then
BackSpacePressed := True;
end;
end;
procedure TDAMemo.KeyPress(var Key: Char);
var
StartI, EndI: integer;
Text: string;
begin
inherited;
if BackSpacePressed then begin
BackSpacePressed := False;
Text := Lines.Text;
StartI := SelStart;
EndI := SelStart;
while (StartI > 0) and (Text[StartI] <= ' ') do
Dec(StartI);
while (StartI > 0) and (Text[StartI] > ' ') do
Dec(StartI);
if EndI > StartI then begin
SelStart := StartI;
SelLength := EndI - StartI;
SelText := '';
end;
Key := #0;
end;
end;
{ TCREditorForm }
constructor TCREditorForm.Create(Owner: TComponent; DADesignUtilsClass: TDADesignUtilsClass);
begin
inherited Create(Owner);
FDADesignUtilsClass := DADesignUtilsClass;
FolderName := ClassName;
ConfirmCancel := True;
end;
{$IFDEF USE_SYNEDIT}
procedure TCREditorForm.SynMenuPopup(Sender: TObject);
var
n, m: DWORD;
Memo: TWinControl;
HasSelection: boolean;
begin
with TPopupMenu(Sender) do begin
Memo := TSynMenuItem(Items[0]).Memo;
SendMessage(Memo.Handle, EM_GETSEL, Integer(@n), Integer(@m));
HasSelection := n < m;
Items[0].Enabled := // Undo
SendMessage(Memo.Handle, EM_CANUNDO, 0, 0) <> 0;
Items[2].Enabled := // Cut
HasSelection;
Items[3].Enabled := // Copy
HasSelection;
Items[4].Enabled := // Paste
IsClipboardFormatAvailable(CF_TEXT);
Items[5].Enabled := // Delete
HasSelection;
Items[7].Enabled := // Select All
GetMemoText(Memo) <> '';
end;
end;
procedure TCREditorForm.SynMenuItemClick(Sender: TObject);
begin
with TSynMenuItem(Sender) do begin
case Tag of
0: // Undo
SendMessage(Memo.Handle, EM_UNDO, 0, 0);
2:// Cut
SendMessage(Memo.Handle, WM_CUT, 0, 0);
3:// Copy
SendMessage(Memo.Handle, WM_COPY, 0, 0);
4:// Paste
SendMessage(Memo.Handle, WM_PASTE, 0, 0);
5:// Delete
SendMessage(Memo.Handle, WM_CLEAR, 0, 0);
7:// Select All
SendMessage(Memo.Handle, EM_SETSEL, 0, Length(GetMemoText(Memo)));
end;
end;
end;
procedure TCREditorForm.ReplaceMemo(var Memo: TWinControl; DrawGutter: boolean);
type
TSetProc = procedure (Self: TObject; Ptr: pointer);
const
NilMethod: TMethod =
(Code: nil; Data: nil);
var
MemoClass: string;
NewMemo: TCustomControl;
OldName: string;
TypeInfo: PTypeInfo;
// Ptr:pointer;
// i: integer;
Gutter: TObject;
i: integer;
Menu: TPopupMenu;
MenuItem: TSynMenuItem;
begin
if FUseSynEdit and (GetClass(sSynMemo) <> nil) and (FSynSQLSyn <> nil) then begin
MemoClass := sSynMemo;
NewMemo := TCustomControl(GetClass(MemoClass).NewInstance);
NewMemo.Create(Memo.Owner);
with NewMemo do begin
Parent := Memo.Parent;
Left := Memo.Left;
Top := Memo.Top;
Width := Memo.Width;
Height := Memo.Height;
Align := Memo.Align;
TabOrder := Memo.TabOrder;
Anchors := Memo.Anchors;
//Constraints := Memo.Constraints;
TypeInfo := GetClass(MemoClass).ClassInfo;
HelpContext := Memo.HelpContext;
if Memo is TMemo then begin
SetReadOnly(NewMemo, TMemo(Memo).ReadOnly);
if MemoClass = sSynMemo then
SetOrdProp(NewMemo, 'Color', Longint(TMemo(Memo).Color));
end;
if GetPropInfo(Memo.ClassInfo, 'OnChange') <> nil then
SetMethodProp(NewMemo, GetPropInfo(TypeInfo, 'OnChange'),
GetMethodProp(Memo, GetPropInfo(Memo.ClassInfo, 'OnChange')));
SetMethodProp(NewMemo, GetPropInfo(TypeInfo, 'OnExit'),
GetMethodProp(Memo, GetPropInfo(Memo.ClassInfo, 'OnExit')));
SetMethodProp(NewMemo, GetPropInfo(TypeInfo, 'OnKeyDown'),
GetMethodProp(Memo, GetPropInfo(Memo.ClassInfo, 'OnKeyDown')));
SetMethodProp(NewMemo, GetPropInfo(TypeInfo, 'OnKeyPress'),
GetMethodProp(Memo, GetPropInfo(Memo.ClassInfo, 'OnKeyPress')));
end;
if (Memo.Owner <> nil) and (TForm(Memo.Owner).ActiveControl = Memo) then begin
SetMethodProp(Memo, GetPropInfo(TypeInfo, 'OnExit'), NilMethod);
TForm(Memo.Owner).ActiveControl := NewMemo;
end;
OldName := Memo.Name;
Memo.Free;
Memo := TMemo(NewMemo);
NewMemo.Name := OldName;
if MemoClass = sSynMemo then begin
SetObjectProp(NewMemo, 'Highlighter', FSynSQLSyn);
SetOrdProp(NewMemo, 'Options', $3680DBF); // [eoAltSetsColumnMode, eoAutoIndent, eoAutoSizeMaxScrollWidth, eoDisableScrollArrows, eoDragDropEditing, eoDropFiles, eoEnhanceEndKey, eoGroupUndo, eoHideShowScrollbars, eoKeepCaretX, eoShowScrollHint, eoSmartTabDelete, eoSmartTabs, eoTabIndent, eoTabsToSpaces]
Gutter := GetObjectProp(NewMemo, 'Gutter');
Assert(Gutter <> nil);
if DrawGutter then begin
SetOrdProp(Gutter, 'Visible', Longint(True));
SetOrdProp(Gutter, 'AutoSize', Longint(True));
SetOrdProp(Gutter, 'DigitCount', 2);
SetOrdProp(Gutter, 'LeftOffset', 0);
SetOrdProp(Gutter, 'RightOffset', 0);
SetOrdProp(Gutter, 'ShowLineNumbers', Longint(True));
SetOrdProp(Gutter, 'Width', 1);
end
else
SetOrdProp(Gutter, 'Visible', Longint(False));
Menu := TPopupMenu.Create(Self);
Menu.OnPopup := SynMenuPopup;
for i := 0 to High(SynMenuItemNames) do begin
MenuItem := TSynMenuItem.Create(Self);
MenuItem.Memo := Memo;
MenuItem.Caption := SynMenuItemNames[i];
MenuItem.Tag := i;
MenuItem.OnClick := SynMenuItemClick;
Menu.Items.Add(MenuItem);
end;
SetObjectProp(Memo, 'PopupMenu', Menu);
end;
end;
end;
{$ENDIF}
procedure TCREditorForm.ReplaceMemos;
var
i: integer;
MemoArr: array of TWinControl;
procedure ProcessComponent(Component: TComponent);
var
i: integer;
SubComponent: TComponent;
begin
for i := 0 to Component.ComponentCount - 1 do begin
SubComponent := Component.Components[i];
if SubComponent.ClassType = TMemo then begin
SetLength(MemoArr, Length(MemoArr) + 1);
MemoArr[Length(MemoArr) - 1] := TMemo(SubComponent);
end
else
if SubComponent is TFrame then
ProcessComponent(SubComponent);
end;
end;
begin
{$IFDEF USE_SYNEDIT}
if not (FUseSynEdit or FDADesignUtilsClass.DBToolsAvailable) then
{$ENDIF}
begin
ProcessComponent(Self);
for i := 0 to Length(MemoArr) - 1 do
ReplaceControl(MemoArr[i], TDAMemo)
end;
end;
procedure TCREditorForm.DoInit;
{$IFDEF LINUX}
procedure ProcessCombos(Component: TComponent);
var
i: integer;
begin
// K2 Only???
for i := 0 to Component.ComponentCount - 1 do
if (Component.Components[i] is TComboBox)
and (TComboBox(Component.Components[i]).Items.Count = 0)
and Assigned(TComboBox(Component.Components[i]).OnDropDown) then
TComboBox(Component.Components[i]).Items.Add('');
end;
var
i: integer;
{$ENDIF}
begin
Modified := False;
if (Component = nil) and (Self is TDAParamValueEditor) then
Exit;
Assert(Component <> nil, ClassName);
if Component.Owner <> nil then
Caption := Component.Owner.Name + '.' + Component.Name
else
Caption := Component.Name;
ReplaceMemos;
{$IFDEF LINUX}
ProcessCombos(Self);
for i := 0 to ComponentCount - 1 do
if Components[i] is TCustomFrame then
ProcessCombos(Components[i]);
// Events order on Windows: OnCloseQuery, OnClose
// Events order on Kylix: OnClose, OnCloseQuery
OnCloseQuery := nil;
{$ENDIF}
end;
procedure TCREditorForm.DoActivate;
begin
end;
procedure TCREditorForm.DoSave;
begin
SaveControlData;
end;
procedure TCREditorForm.DoFinish;
begin
end;
procedure TCREditorForm.ExitActiveControl;
var
C: {$IFNDEF LINUX}TWinControl{$ELSE}TWidgetControl{$ENDIF};
begin
C := ActiveControl;
if (C is TComboBox) then
(C as TComboBox).DroppedDown := False;
ActiveControl := nil;
if ActiveControl <> nil then
SysUtils.Abort; // Error on, for example, OnFrameExit
// SysUtils prefix is needed to compile in Kylix
while (C <> nil) and (not C.Visible or not C.Enabled) do // "Cannot focus disabled or invisible window" bug. See TCRGridTitleEdit.DoFinish code
C := C.Parent;
ActiveControl := C;
end;
procedure TCREditorForm.SaveControlData;
begin
ExitActiveControl;
end;
{$IFDEF MSWINDOWS}
function TCREditorForm.SaveState: boolean;
var
Registry: TRegistry;
begin
if (BorderStyle <> bsDialog) or (FOldPosition <> poScreenCenter)
then begin
Registry := TRegistry.Create;
try
with Registry do begin
OpenKey(KeyPath + '\' + FolderName, True);
if BorderStyle in [bsSizeable, bsSizeToolWin] then begin
WriteBool('Maximized', WindowState = wsMaximized);
WriteBool('Minimized', WindowState = wsMinimized);
if WindowState = wsNormal then begin
WriteInteger('Width', Width);
WriteInteger('Height', Height);
end;
end;
if (FOldPosition <> poScreenCenter) and (WindowState = wsNormal) then begin
WriteInteger('Left', Left);
WriteInteger('Top', Top);
end;
{if not Modal then
SetBool('Visible', Visible);}
Result := True;
end
finally
Registry.Free;
end
end
else
Result := False;
end;
function TCREditorForm.LoadState: boolean;
var
Registry: TRegistry;
begin
Registry := TRegistry.Create;
try
with Registry do begin
if OpenKey(KeyPath + '\' + FolderName, False) then begin
if Position <> poScreenCenter then begin
if ValueExists('Left') then
Left := ReadInteger('Left');
if ValueExists('Top') then
Top := ReadInteger('Top');
end;
if BorderStyle in [bsSizeable, bsSizeToolWin] then begin
if ValueExists('Width') then
Width := ReadInteger('Width');
if ValueExists('Height') then
Height := ReadInteger('Height');
if ValueExists('Maximized') and ReadBool('Maximized') then
WindowState := wsMaximized
else
{if ValueExists('Minimized') and ReadBool('Minimized') then
WindowState := wsMinimized
else}
WindowState := wsNormal;
end;
if ValueExists('Visible') and ReadBool('Visible') then begin
Show;
Update;
end;
Result := True;
end
else
begin
Left := (Screen.Width - Width) div 2;
Top := (Screen.Height - Height) div 2;
Result := False;
end;
{$IFDEF USE_SYNEDIT}
if OpenKey(KeyPath, False) and ValueExists('UseSynEdit') then
FUseSynEdit := ReadBool('UseSynEdit')
else
FUseSynEdit := True;
FUseSynEdit := FUseSynEdit and (GetClass(sSynSQLSyn) <> nil) and (GetClass(sSynMemo) <> nil);
{$ENDIF}
end;
finally
Registry.Free;
end;
FOldPosition := Position;
end;
function TCREditorForm.KeyPath: string;
begin
Result := '\SOFTWARE\CoreLab\' + FDADesignUtilsClass.GetProjectName + '\Editors';
end;
{$ENDIF}
{$IFDEF DBTOOLS}
procedure TCREditorForm.ActiveChanged;
begin
inherited;
if ActiveControl is TDACSqlEditorFrame then
ActiveControl.SetFocus;
end;
{$ENDIF}
{$IFDEF LINUX}
function TCREditorForm.SaveState: boolean;
begin
Result := True;
end;
function TCREditorForm.LoadState: boolean;
begin
Result := True;
end;
{$ENDIF}
function TCREditorForm.GetComponent: TComponent;
begin
Assert(False, 'Must be overriden');
Result := nil;
end;
procedure TCREditorForm.SetComponent(Value: TComponent);
begin
Assert(False, 'Must be overriden');
end;
function TCREditorForm.GetLocalComponent: TComponent;
begin
Assert(False, 'Must be overriden');
Result := nil;
end;
procedure TCREditorForm.FormShow(Sender: TObject);
{$IFDEF USE_SYNEDIT}
var
NewSHClass: TPersistentClass;
{$ENDIF}
begin
{$IFDEF DBTOOLS}
{$IFDEF CLR}
OldMessageProcessing := Application.OnMessage;
Application.OnMessage := MessageProcessing;
{$ENDIF}
{$ENDIF}
LoadState;
{$IFDEF USE_SYNEDIT}
NewSHClass := GetClass(sSynSQLSyn);
if FUseSynEdit and (NewSHClass <> nil) then begin
FSynSQLSyn := TComponentClass(NewSHClass).Create(Self);
SetOrdProp(FSynSQLSyn, 'SQLDialect', FDADesignUtilsClass.SQLDialect);
end;
{$ENDIF}
{$IFDEF LINUX}
DoInit;
{$ELSE}
try
DoInit;
except
on E: EAbort do begin
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
end;
{$ENDIF}
DoActivate;
end;
procedure TCREditorForm.FormHide(Sender: TObject);
{$IFDEF LINUX}
var
CanClose: Boolean; // Skipped by Kylix bug
{$ENDIF}
begin
{$IFDEF LINUX}
FormCloseQuery(Sender, CanClose);
{$ENDIF}
DoFinish;
SaveState;
{$IFDEF USE_SYNEDIT}
FSynSQLSyn.Free;
{$ENDIF}
end;
procedure TCREditorForm.SaveClick(Sender: TObject);
begin
DoSave;
Modified := False;
ModalResult := mrOk;
end;
procedure TCREditorForm.CloseClick(Sender: TObject);
begin
ModalResult := mrCancel
end;
procedure TCREditorForm.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
{$IFDEF MSWINDOWS}
const
ResYes = IDYES;
ResNo = IDNO;
var
Res: integer;
{$ELSE}
const
ResYes = smbYes;
ResNo = smbNo;
var
Res: TMessageButton;
{$ENDIF}
OldActiveControl: TWinControl;
begin
{$IFDEF DBTOOLS}
DBTools.CheckDBToolsChanges(Self);
{$ENDIF}
OldActiveControl := ActiveControl;
try
ExitActiveControl;
except
// Silent. User can enter wrong data
end;
if (OldActiveControl <> nil) and OldActiveControl.Visible and OldActiveControl.Enabled then
ActiveControl := OldActiveControl;
if Modified then begin
if ConfirmCancel then
{$IFDEF MSWINDOWS}
Res := Application.MessageBox('Save changes to component?', 'Confirm',
MB_YESNOCANCEL or MB_ICONQUESTION)
{$ELSE}
Res := Application.MessageBox('Save changes to component?', 'Confirm',
[smbYes, smbNo], smsWarning)
{$ENDIF}
else
Res := ResNo;
if Res = ResYes then begin
{$IFDEF MSWINDOWS}
ModalResult := mrOk;
{$ENDIF}
DoSave;
Modified := False;
CanClose := True;
end
else
if Res = ResNo then begin
CanClose := True;
{$IFDEF MSWINDOWS}
ModalResult := mrCancel;
{$ENDIF}
end
else
CanClose := False;
end
else
CanClose := True;
end;
procedure TCREditorForm.SetConfirmCancel(const Value: boolean);
begin
FConfirmCancel := Value;
end;
procedure TCREditorForm.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #27 then begin
Close;
Key := #0;
end;
end;
function TCREditorForm.GetModified: boolean;
begin
Result := FModified;
end;
procedure TCREditorForm.SetModified(Value: boolean);
begin
FModified := Value;
end;
{$IFDEF DBTOOLS}
{$IFDEF CLR}
destructor TCREditorForm.Destroy;
begin
if Assigned(OldMessageProcessing) then
Application.OnMessage := OldMessageProcessing;
inherited;
end;
procedure TCREditorForm.MessageProcessing(var Msg: TMsg; var Handled: Boolean);
var
Wnd: HWND;
ParentHwnd: HWND;
IsDbToolsCtrl: boolean;
ClassName: StringBuilder;
function IsDbToolsShortCut(Key: word): boolean;
var
Shift: word;
begin
Result := False;
if Key and $FF00 = 0 then begin
if GetKeyState(VK_CONTROL) < 0 then
Shift := scCtrl
else
Shift := 0;
if GetKeyState(VK_MENU) < 0 then
Inc(Shift, scAlt); //VK_SHIFT is of no importance
if ((Key = VK_F4) and (Shift = scAlt)) //Alt+F4
or ((Key = VK_ESCAPE) and (Shift = 0)) //ESC
or ((Key >= Ord('a')) and (Key <= Ord('z')) and (Shift = scAlt)) //Alt+a..z
or ((Key = VK_TAB) and ((Shift = scCtrl) or (Shift = 0))) then //[Ctrl+]Tab
Exit;
end;
Result := True;
end;
begin
//This procedure transports messages to managed non VCL DbToolsControls
Handled := False;
if (Msg.Message >= WM_KEYFIRST) and (Msg.Message <= WM_KEYLAST) then
with Msg do begin
IsDbToolsCtrl := False;
Wnd := HWnd;
if (FindControl(Wnd) = nil) and (Wnd <> 0) then begin
//Check that Wnd is our managed control handle
ParentHwnd := GetParent(Wnd);
ClassName := StringBuilder.Create;
ClassName.Capacity := 1024;
while (not IsDbToolsCtrl) and (ParentHwnd <> 0) do begin
GetClassName(ParentHwnd, ClassName, 1024);
IsDbToolsCtrl := Pos('TDACSqlEditorFrame', ClassName.ToString) <> 0;
ParentHwnd := GetParent(ParentHwnd);
end;
ClassName.Free;
if IsDbToolsCtrl and IsDbToolsShortCut(Msg.WParam) then begin
TranslateMessage(Msg);
Handled := DispatchMessage(Msg) = 0;
Exit;
end;
end;
end;
if (@OldMessageProcessing <> nil) then
OldMessageProcessing(Msg, Handled);
end;
{$ENDIF}
procedure TCREditorForm.WMActivate(var Message: TWMActivate);
var
Control: TWinControl;
begin
if Message.Active = WA_INACTIVE then begin
Control := DbTools.GetActiveDACSqlEditorFrame;
if Control <> nil then
ActiveControl := Control;
end;
inherited;
end;
{$ENDIF}
procedure TCREditorForm.CheckConnection(const Component: TComponent);
var
Connection: TCustomDAConnection;
begin
if Component is TCustomDAConnection then
Connection := TCustomDAConnection(Component)
else begin
Connection := FDADesignUtilsClass.UsedConnection(Component);
if Connection = nil then
DatabaseError(SConnectionNotDefined);
end;
if not Connection.Connected then begin
Connection.Connect;
{$IFDEF DBTOOLS}
DBTools.CheckConnectionChanges;
{$ENDIF}
end;
end;
end.