From a9cf0fd3b2836061d96f6415ee5ad91f1c17398f Mon Sep 17 00:00:00 2001 From: Ansgar Becker Date: Sat, 20 Feb 2010 18:44:36 +0000 Subject: [PATCH] Organize controls on routine editor into 3 tabs (options, parameters, create code). Fixes issue #1708. --- source/main.pas | 4 +- source/routine_editor.dfm | 503 +++++++++++++++++++++----------------- source/routine_editor.pas | 94 ++++--- 3 files changed, 331 insertions(+), 270 deletions(-) diff --git a/source/main.pas b/source/main.pas index 2ed23987..89c42b35 100644 --- a/source/main.pas +++ b/source/main.pas @@ -9043,8 +9043,10 @@ begin end; if Assigned(ViewEditor) then Editors.Add(ViewEditor.SynMemoSelect); - if Assigned(RoutineEditor) then + if Assigned(RoutineEditor) then begin Editors.Add(RoutineEditor.SynMemoBody); + Editors.Add(RoutineEditor.SynMemoCREATEcode); + end; if Assigned(TriggerEditor) then Editors.Add(TriggerEditor.SynMemoStatement); if Assigned(CreateDatabaseForm) then diff --git a/source/routine_editor.dfm b/source/routine_editor.dfm index a48c0884..2f9e1321 100644 --- a/source/routine_editor.dfm +++ b/source/routine_editor.dfm @@ -1,72 +1,19 @@ object frmRoutineEditor: TfrmRoutineEditor Left = 0 Top = 0 - Width = 475 + Width = 606 Height = 484 TabOrder = 0 DesignSize = ( - 475 + 606 484) - object lblName: TLabel - Left = 3 - Top = 11 - Width = 31 - Height = 13 - Caption = '&Name:' - FocusControl = editName - end - object lblType: TLabel - Left = 3 - Top = 36 - Width = 28 - Height = 13 - Caption = '&Type:' - FocusControl = comboType - end - object lblReturns: TLabel - Left = 3 - Top = 61 - Width = 42 - Height = 13 - Caption = '&Returns:' - FocusControl = comboReturns - end - object lblParameters: TLabel - Left = 3 - Top = 187 - Width = 59 - Height = 13 - Caption = 'Parameters:' - end - object lblSQL: TLabel - Left = 3 - Top = 87 - Width = 62 - Height = 13 - Caption = '&Data access:' - FocusControl = comboDataAccess - end - object lblSecurity: TLabel - Left = 3 - Top = 112 - Width = 65 - Height = 13 - Caption = 'SQL Se&curity:' - FocusControl = comboSecurity - end - object lblComment: TLabel - Left = 3 - Top = 137 - Width = 49 - Height = 13 - Caption = '&Comment:' - FocusControl = editComment - end object lblSQLcode: TLabel + AlignWithMargins = True Left = 3 - Top = 317 - Width = 68 + Top = 175 + Width = 600 Height = 13 + Align = alTop Caption = '&Routine body:' FocusControl = SynMemoBody end @@ -78,7 +25,7 @@ object frmRoutineEditor: TfrmRoutineEditor Anchors = [akLeft, akBottom] Caption = 'Save' Default = True - TabOrder = 12 + TabOrder = 3 OnClick = btnSaveClick end object btnDiscard: TButton @@ -90,7 +37,7 @@ object frmRoutineEditor: TfrmRoutineEditor Cancel = True Caption = 'Discard' ModalResult = 2 - TabOrder = 11 + TabOrder = 2 OnClick = btnDiscardClick end object btnHelp: TButton @@ -100,184 +47,24 @@ object frmRoutineEditor: TfrmRoutineEditor Height = 25 Anchors = [akLeft, akBottom] Caption = 'Help' - TabOrder = 10 + TabOrder = 1 OnClick = btnHelpClick end - object comboReturns: TComboBox - Left = 95 - Top = 58 - Width = 377 - Height = 21 - Anchors = [akLeft, akTop, akRight] - TabOrder = 2 - Text = 'comboReturns' - OnChange = Modification - end - object comboType: TComboBox - Left = 95 - Top = 33 - Width = 377 - Height = 21 - Style = csDropDownList - Anchors = [akLeft, akTop, akRight] - TabOrder = 1 - OnSelect = comboTypeSelect - end - object editName: TEdit - Left = 95 - Top = 8 - Width = 377 - Height = 21 - Anchors = [akLeft, akTop, akRight] - TabOrder = 0 - Text = 'editName' - TextHint = 'Enter routine name' - OnChange = editNameChange - end - object tlbParameters: TToolBar - Left = 3 - Top = 206 - Width = 72 - Height = 84 - Align = alNone - ButtonWidth = 66 - Caption = 'tlbParameters' - Images = MainForm.ImageListMain - List = True - ShowCaptions = True - TabOrder = 7 - object btnAddParam: TToolButton - Left = 0 - Top = 0 - Caption = 'Add' - ImageIndex = 45 - Wrap = True - OnClick = btnAddParamClick - end - object btnRemoveParam: TToolButton - Left = 0 - Top = 22 - Caption = 'Remove' - ImageIndex = 46 - Wrap = True - OnClick = btnRemoveParamClick - end - object btnClearParams: TToolButton - Left = 0 - Top = 44 - Caption = 'Clear' - ImageIndex = 26 - OnClick = btnClearParamsClick - end - end - object listParameters: TVirtualStringTree - Left = 95 - Top = 206 - Width = 377 - Height = 100 - Anchors = [akLeft, akTop, akRight] - DragImageKind = diMainColumnOnly - DragMode = dmAutomatic - DragType = dtVCL - EditDelay = 0 - Header.AutoSizeIndex = 1 - Header.DefaultHeight = 17 - Header.MainColumn = 1 - Header.Options = [hoAutoResize, hoColumnResize, hoDblClickResize, hoDrag, hoVisible] - Header.ParentFont = True - Images = MainForm.ImageListMain - NodeDataSize = 0 - TabOrder = 8 - TreeOptions.MiscOptions = [toAcceptOLEDrop, toEditable, toFullRepaintOnResize, toGridExtensions, toInitOnSave, toToggleOnDblClick, toWheelPanning, toEditOnClick] - TreeOptions.PaintOptions = [toHideFocusRect, toHotTrack, toShowButtons, toShowDropmark, toShowHorzGridLines, toShowVertGridLines, toThemeAware, toUseBlendedImages, toFullVertGridLines, toUseExplorerTheme] - TreeOptions.SelectionOptions = [toExtendedFocus, toFullRowSelect] - OnBeforePaint = listParametersBeforePaint - OnCreateEditor = listParametersCreateEditor - OnEditing = listParametersEditing - OnFocusChanged = listParametersFocusChanged - OnGetText = listParametersGetText - OnPaintText = listParametersPaintText - OnGetImageIndex = listParametersGetImageIndex - OnNewText = listParametersNewText - Columns = < - item - Options = [coAllowClick, coDraggable, coEnabled, coParentBidiMode, coParentColor, coShowDropMark, coVisible, coAllowFocus] - Position = 0 - Width = 25 - WideText = '#' - end - item - Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus] - Position = 1 - Width = 192 - WideText = 'Name' - end - item - Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus] - Position = 2 - Width = 90 - WideText = 'Datatype' - end - item - Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus] - Position = 3 - Width = 70 - WideText = 'Context' - end> - end - object comboDataAccess: TComboBox - Left = 95 - Top = 84 - Width = 377 - Height = 21 - Style = csDropDownList - Anchors = [akLeft, akTop, akRight] - TabOrder = 3 - OnChange = Modification - end - object comboSecurity: TComboBox - Left = 95 - Top = 109 - Width = 377 - Height = 21 - Style = csDropDownList - Anchors = [akLeft, akTop, akRight] - TabOrder = 4 - OnChange = Modification - end - object editComment: TEdit - Left = 95 - Top = 134 - Width = 377 - Height = 21 - Anchors = [akLeft, akTop, akRight] - TabOrder = 5 - Text = 'editComment' - OnChange = Modification - end - object chkDeterministic: TCheckBox - Left = 95 - Top = 161 - Width = 377 - Height = 17 - Anchors = [akLeft, akTop, akRight] - Caption = '&Deterministic' - TabOrder = 6 - OnClick = Modification - end object SynMemoBody: TSynMemo + AlignWithMargins = True Left = 3 - Top = 336 - Width = 469 - Height = 113 + Top = 194 + Width = 600 + Height = 250 + Margins.Bottom = 40 SingleLineMode = False - Anchors = [akLeft, akTop, akRight, akBottom] + Align = alClient Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -13 Font.Name = 'Courier New' Font.Style = [] - TabOrder = 9 + TabOrder = 0 OnDragDrop = SynMemoBodyDragDrop OnDragOver = SynMemoBodyDragOver Gutter.AutoSize = True @@ -307,4 +94,262 @@ object frmRoutineEditor: TfrmRoutineEditor ShortCut = 16473 end> end + object PageControlMain: TPageControl + AlignWithMargins = True + Left = 3 + Top = 3 + Width = 600 + Height = 166 + ActivePage = tabOptions + Align = alTop + Images = MainForm.ImageListMain + TabOrder = 4 + object tabOptions: TTabSheet + Caption = 'Options' + ImageIndex = 39 + DesignSize = ( + 592 + 137) + object lblName: TLabel + Left = 3 + Top = 11 + Width = 31 + Height = 13 + Caption = '&Name:' + FocusControl = editName + end + object lblType: TLabel + Left = 3 + Top = 65 + Width = 28 + Height = 13 + Caption = '&Type:' + FocusControl = comboType + end + object lblReturns: TLabel + Left = 3 + Top = 90 + Width = 42 + Height = 13 + Caption = '&Returns:' + FocusControl = comboReturns + end + object lblSQL: TLabel + Left = 408 + Top = 65 + Width = 62 + Height = 13 + Caption = '&Data access:' + FocusControl = comboDataAccess + end + object lblSecurity: TLabel + Left = 408 + Top = 90 + Width = 65 + Height = 13 + Caption = 'SQL Se&curity:' + FocusControl = comboSecurity + end + object lblComment: TLabel + Left = 3 + Top = 38 + Width = 49 + Height = 13 + Caption = '&Comment:' + FocusControl = editComment + end + object chkDeterministic: TCheckBox + Left = 84 + Top = 114 + Width = 508 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = '&Deterministic' + TabOrder = 0 + OnClick = Modification + end + object editComment: TEdit + Left = 84 + Top = 35 + Width = 505 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 1 + Text = 'editComment' + OnChange = Modification + end + object comboSecurity: TComboBox + Left = 489 + Top = 87 + Width = 100 + Height = 21 + Style = csDropDownList + Anchors = [akLeft, akTop, akRight] + TabOrder = 2 + OnChange = Modification + end + object comboDataAccess: TComboBox + Left = 489 + Top = 62 + Width = 100 + Height = 21 + Style = csDropDownList + Anchors = [akLeft, akTop, akRight] + TabOrder = 3 + OnChange = Modification + end + object comboReturns: TComboBox + Left = 84 + Top = 87 + Width = 310 + Height = 21 + TabOrder = 4 + Text = 'comboReturns' + OnChange = Modification + end + object comboType: TComboBox + Left = 84 + Top = 62 + Width = 310 + Height = 21 + Style = csDropDownList + TabOrder = 5 + OnSelect = comboTypeSelect + end + object editName: TEdit + Left = 84 + Top = 8 + Width = 505 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 6 + Text = 'editName' + TextHint = 'Enter routine name' + OnChange = editNameChange + end + end + object tabParameters: TTabSheet + Caption = 'Parameters' + ImageIndex = 122 + object listParameters: TVirtualStringTree + Left = 66 + Top = 0 + Width = 526 + Height = 137 + Align = alClient + DragImageKind = diMainColumnOnly + DragMode = dmAutomatic + DragType = dtVCL + EditDelay = 0 + Header.AutoSizeIndex = 1 + Header.DefaultHeight = 17 + Header.MainColumn = 1 + Header.Options = [hoAutoResize, hoColumnResize, hoDblClickResize, hoDrag, hoVisible] + Header.ParentFont = True + Images = MainForm.ImageListMain + NodeDataSize = 0 + TabOrder = 0 + TreeOptions.MiscOptions = [toAcceptOLEDrop, toEditable, toFullRepaintOnResize, toGridExtensions, toInitOnSave, toToggleOnDblClick, toWheelPanning, toEditOnClick] + TreeOptions.PaintOptions = [toHideFocusRect, toHotTrack, toShowButtons, toShowDropmark, toShowHorzGridLines, toShowVertGridLines, toThemeAware, toUseBlendedImages, toFullVertGridLines, toUseExplorerTheme] + TreeOptions.SelectionOptions = [toExtendedFocus, toFullRowSelect] + OnBeforePaint = listParametersBeforePaint + OnCreateEditor = listParametersCreateEditor + OnEditing = listParametersEditing + OnFocusChanged = listParametersFocusChanged + OnGetText = listParametersGetText + OnPaintText = listParametersPaintText + OnGetImageIndex = listParametersGetImageIndex + OnNewText = listParametersNewText + Columns = < + item + Options = [coAllowClick, coDraggable, coEnabled, coParentBidiMode, coParentColor, coShowDropMark, coVisible, coAllowFocus] + Position = 0 + Width = 25 + WideText = '#' + end + item + Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus] + Position = 1 + Width = 337 + WideText = 'Name' + end + item + Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus] + Position = 2 + Width = 90 + WideText = 'Datatype' + end + item + Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus] + Position = 3 + Width = 70 + WideText = 'Context' + end> + end + object tlbParameters: TToolBar + Left = 0 + Top = 0 + Width = 66 + Height = 137 + Align = alLeft + AutoSize = True + ButtonWidth = 66 + Caption = 'tlbParameters' + Images = MainForm.ImageListMain + List = True + ShowCaptions = True + TabOrder = 1 + object btnAddParam: TToolButton + Left = 0 + Top = 0 + Caption = 'Add' + ImageIndex = 45 + Wrap = True + OnClick = btnAddParamClick + end + object btnRemoveParam: TToolButton + Left = 0 + Top = 22 + Caption = 'Remove' + ImageIndex = 46 + Wrap = True + OnClick = btnRemoveParamClick + end + object btnClearParams: TToolButton + Left = 0 + Top = 44 + Caption = 'Clear' + ImageIndex = 26 + OnClick = btnClearParamsClick + end + end + end + object tabCreateCode: TTabSheet + Caption = 'CREATE code' + ImageIndex = 119 + object SynMemoCREATEcode: TSynMemo + Left = 0 + Top = 0 + Width = 592 + Height = 137 + SingleLineMode = False + Align = alClient + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Courier New' + Font.Style = [] + TabOrder = 0 + Gutter.Font.Charset = DEFAULT_CHARSET + Gutter.Font.Color = clWindowText + Gutter.Font.Height = -11 + Gutter.Font.Name = 'Courier New' + Gutter.Font.Style = [] + Highlighter = MainForm.SynSQLSyn1 + Lines.Strings = ( + 'SynMemoCREATEcode') + ReadOnly = True + end + end + end end diff --git a/source/routine_editor.pas b/source/routine_editor.pas index 2c2950ee..f6bb98ba 100644 --- a/source/routine_editor.pas +++ b/source/routine_editor.pas @@ -13,27 +13,31 @@ type btnSave: TButton; btnDiscard: TButton; btnHelp: TButton; - lblName: TLabel; - lblType: TLabel; - lblReturns: TLabel; + lblSQLcode: TLabel; + SynMemoBody: TSynMemo; + PageControlMain: TPageControl; + tabOptions: TTabSheet; + tabParameters: TTabSheet; + tabCreateCode: TTabSheet; + chkDeterministic: TCheckBox; + editComment: TEdit; + comboSecurity: TComboBox; + comboDataAccess: TComboBox; comboReturns: TComboBox; comboType: TComboBox; editName: TEdit; - lblParameters: TLabel; + lblName: TLabel; + lblType: TLabel; + lblReturns: TLabel; + lblSQL: TLabel; + lblSecurity: TLabel; + lblComment: TLabel; + listParameters: TVirtualStringTree; tlbParameters: TToolBar; btnAddParam: TToolButton; btnRemoveParam: TToolButton; btnClearParams: TToolButton; - listParameters: TVirtualStringTree; - lblSQL: TLabel; - comboDataAccess: TComboBox; - lblSecurity: TLabel; - comboSecurity: TComboBox; - lblComment: TLabel; - editComment: TEdit; - chkDeterministic: TCheckBox; - lblSQLcode: TLabel; - SynMemoBody: TSynMemo; + SynMemoCREATEcode: TSynMemo; procedure comboTypeSelect(Sender: TObject); procedure btnSaveClick(Sender: TObject); procedure btnHelpClick(Sender: TObject); @@ -68,6 +72,7 @@ type private { Private declarations } FAlterRoutineType: String; + function ComposeCreateStatement(NameOfObject: String): String; public { Public declarations } Parameters: TStringList; @@ -222,6 +227,7 @@ begin Modified := True; btnSave.Enabled := Modified; btnDiscard.Enabled := Modified; + SynMemoCreateCode.Text := ComposeCreateStatement(editName.Text); end; @@ -422,35 +428,15 @@ end; function TfrmRoutineEditor.ApplyModifications: TModalResult; var - BaseSQL, TempSQL, FinalSQL, TempName: String; + TempName: String; i: Integer; - par, allRoutineNames: TStringList; + allRoutineNames: TStringList; ProcOrFunc: String; TargetExists: Boolean; begin // Save changes Result := mrOk; ProcOrFunc := UpperCase(GetFirstWord(comboType.Text)); - BaseSQL := ''; - for i := 0 to Parameters.Count - 1 do begin - par := explode(DELIM, Parameters[i]); - if ProcOrFunc = 'PROCEDURE' then - BaseSQL := BaseSQL + par[2] + ' '; - BaseSQL := BaseSQL + Mainform.Mask(par[0]) + ' ' + par[1]; - if i < Parameters.Count-1 then - BaseSQL := BaseSQL + ', '; - end; - BaseSQL := BaseSQL + ') '; - if comboReturns.Enabled then - BaseSQL := BaseSQL + 'RETURNS '+comboReturns.Text+' '; - BaseSQL := BaseSQL + 'LANGUAGE SQL '; - if not chkDeterministic.Checked then - BaseSQL := BaseSQL + 'NOT '; - BaseSQL := BaseSQL + 'DETERMINISTIC '; - BaseSQL := BaseSQL + UpperCase(comboDataAccess.Text)+' '; - BaseSQL := BaseSQL + 'SQL SECURITY ' + UpperCase(comboSecurity.Text)+' '; - BaseSQL := BaseSQL + 'COMMENT ' + esc(editComment.Text)+' '; - BaseSQL := BaseSQL + SynMemoBody.Text; // There is no way to ALTER parameters or the name of it. // Create a temp routine, check for syntax errors, then drop the old routine and create it. @@ -477,8 +463,7 @@ begin if allRoutineNames.IndexOf(TempName) = -1 then break; end; - TempSQL := 'CREATE '+ProcOrFunc+' '+Mainform.mask(tempName)+'(' + BaseSQL; - Mainform.Connection.Query(TempSQL); + Mainform.Connection.Query(ComposeCreateStatement(tempName)); // Drop temporary routine, used for syntax checking Mainform.Connection.Query('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(TempName)); // Drop edited routine @@ -488,8 +473,7 @@ begin Mainform.Connection.Query('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(editName.Text)); end; end; - FinalSQL := 'CREATE '+ProcOrFunc+' '+Mainform.mask(editName.Text)+'(' + BaseSQL; - Mainform.Connection.Query(FinalSQL); + Mainform.Connection.Query(ComposeCreateStatement(editName.Text)); // Set editing name if create/alter query was successful FEditObjectName := editName.Text; FAlterRoutineType := UpperCase(GetFirstWord(comboType.Text)); @@ -507,6 +491,36 @@ begin end; +function TfrmRoutineEditor.ComposeCreateStatement(NameOfObject: String): String; +var + ProcOrFunc: String; + par: TStringList; + i: Integer; +begin + ProcOrFunc := UpperCase(GetFirstWord(comboType.Text)); + Result := 'CREATE '+ProcOrFunc+' '+Mainform.mask(NameOfObject)+'('; + for i:=0 to Parameters.Count-1 do begin + par := explode(DELIM, Parameters[i]); + if ProcOrFunc = 'PROCEDURE' then + Result := Result + par[2] + ' '; + Result := Result + Mainform.Mask(par[0]) + ' ' + par[1]; + if i < Parameters.Count-1 then + Result := Result + ', '; + end; + Result := Result + ')'+CRLF; + if comboReturns.Enabled then + Result := Result + #9 + 'RETURNS '+comboReturns.Text+CRLF; + Result := Result + #9 + 'LANGUAGE SQL'+CRLF + #9; + if not chkDeterministic.Checked then + Result := Result + 'NOT '; + Result := Result + 'DETERMINISTIC'+CRLF + + #9 + UpperCase(comboDataAccess.Text)+CRLF + + #9 + 'SQL SECURITY ' + UpperCase(comboSecurity.Text)+CRLF + + #9 + 'COMMENT ' + esc(editComment.Text)+CRLF + + SynMemoBody.Text; +end; + + procedure TfrmRoutineEditor.btnDiscardClick(Sender: TObject); var t: TListNodeType;