From 4820160ed10736ba6578541a85ee336f4ccfd37e Mon Sep 17 00:00:00 2001 From: reiniero Date: Mon, 17 Dec 2012 13:15:20 +0000 Subject: [PATCH] + fcl-db tests: GUI test framework: add db connector selector/editor. Addresses issue #23483 git-svn-id: trunk@23162 - --- .gitattributes | 2 + packages/fcl-db/tests/dbtestframework_gui.lpi | 11 +- packages/fcl-db/tests/dbtestframework_gui.lpr | 16 +- packages/fcl-db/tests/inieditor.lfm | 579 ++++++++++++++++++ packages/fcl-db/tests/inieditor.pas | 251 ++++++++ 5 files changed, 854 insertions(+), 5 deletions(-) create mode 100644 packages/fcl-db/tests/inieditor.lfm create mode 100644 packages/fcl-db/tests/inieditor.pas diff --git a/.gitattributes b/.gitattributes index 67eebf1dbc..217e407f01 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2135,6 +2135,8 @@ packages/fcl-db/tests/dbftoolsunit.pas svneol=native#text/plain packages/fcl-db/tests/dbtestframework.pas svneol=native#text/plain packages/fcl-db/tests/dbtestframework_gui.lpi svneol=native#text/plain packages/fcl-db/tests/dbtestframework_gui.lpr svneol=native#text/plain +packages/fcl-db/tests/inieditor.lfm svneol=native#text/plain +packages/fcl-db/tests/inieditor.pas svneol=native#text/plain packages/fcl-db/tests/memdstoolsunit.pas svneol=native#text/plain packages/fcl-db/tests/sdfdstoolsunit.pas svneol=native#text/plain packages/fcl-db/tests/sqldbtoolsunit.pas svneol=native#text/plain diff --git a/packages/fcl-db/tests/dbtestframework_gui.lpi b/packages/fcl-db/tests/dbtestframework_gui.lpi index 929c999075..9630ddd84c 100644 --- a/packages/fcl-db/tests/dbtestframework_gui.lpi +++ b/packages/fcl-db/tests/dbtestframework_gui.lpi @@ -42,16 +42,19 @@ - + - + - + - + + + + diff --git a/packages/fcl-db/tests/dbtestframework_gui.lpr b/packages/fcl-db/tests/dbtestframework_gui.lpr index d9efced73a..db94deb274 100644 --- a/packages/fcl-db/tests/dbtestframework_gui.lpr +++ b/packages/fcl-db/tests/dbtestframework_gui.lpr @@ -10,7 +10,9 @@ program dbtestframework_gui; // the .ppu files before you can build fcl-db in the regular way. (Using fpmake) uses - Interfaces, Forms, GuiTestRunner, + Interfaces, Forms, + // GUI: + GuiTestRunner, inieditor, // Generic DB test framework units ToolsUnit, // Connectors for different database-types @@ -30,8 +32,20 @@ uses {$R *.res} +var + DBSelectForm: TFormIniEditor; begin Application.Initialize; + DBSelectForm:=TFormIniEditor.Create(nil); + try + DBSelectForm.INIFile:='database.ini'; + DBSelectForm.ProfileSelectSection:='Database'; + DBSelectForm.ProfileSelectKey:='type'; + // We can ignore resulting db selection as the file is saved already: + DBSelectForm.ShowModal; + finally + DBSelectForm.Free; + end; Application.CreateForm(TGuiTestRunner, TestRunner); Application.Run; end. diff --git a/packages/fcl-db/tests/inieditor.lfm b/packages/fcl-db/tests/inieditor.lfm new file mode 100644 index 0000000000..8437c995f0 --- /dev/null +++ b/packages/fcl-db/tests/inieditor.lfm @@ -0,0 +1,579 @@ +object FormIniEditor: TFormIniEditor + Left = 238 + Height = 501 + Top = 145 + Width = 754 + Caption = 'Select/edit profile' + ClientHeight = 501 + ClientWidth = 754 + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnDestroy = FormDestroy + OnDropFiles = FormDropFiles + OnShow = FormShow + LCLVersion = '1.1' + inline SynMemo: TSynMemo + Cursor = crIBeam + Left = 8 + Height = 360 + Top = 88 + Width = 736 + Font.Height = -13 + Font.Name = 'Courier New' + Font.Pitch = fpFixed + Font.Quality = fqNonAntialiased + ParentColor = False + ParentFont = False + TabOrder = 2 + Gutter.Width = 57 + Gutter.MouseActions = <> + Highlighter = SynIniHighlighter + Keystrokes = < + item + Command = ecUp + ShortCut = 38 + end + item + Command = ecSelUp + ShortCut = 8230 + end + item + Command = ecScrollUp + ShortCut = 16422 + end + item + Command = ecDown + ShortCut = 40 + end + item + Command = ecSelDown + ShortCut = 8232 + end + item + Command = ecScrollDown + ShortCut = 16424 + end + item + Command = ecLeft + ShortCut = 37 + end + item + Command = ecSelLeft + ShortCut = 8229 + end + item + Command = ecWordLeft + ShortCut = 16421 + end + item + Command = ecSelWordLeft + ShortCut = 24613 + end + item + Command = ecRight + ShortCut = 39 + end + item + Command = ecSelRight + ShortCut = 8231 + end + item + Command = ecWordRight + ShortCut = 16423 + end + item + Command = ecSelWordRight + ShortCut = 24615 + end + item + Command = ecPageDown + ShortCut = 34 + end + item + Command = ecSelPageDown + ShortCut = 8226 + end + item + Command = ecPageBottom + ShortCut = 16418 + end + item + Command = ecSelPageBottom + ShortCut = 24610 + end + item + Command = ecPageUp + ShortCut = 33 + end + item + Command = ecSelPageUp + ShortCut = 8225 + end + item + Command = ecPageTop + ShortCut = 16417 + end + item + Command = ecSelPageTop + ShortCut = 24609 + end + item + Command = ecLineStart + ShortCut = 36 + end + item + Command = ecSelLineStart + ShortCut = 8228 + end + item + Command = ecEditorTop + ShortCut = 16420 + end + item + Command = ecSelEditorTop + ShortCut = 24612 + end + item + Command = ecLineEnd + ShortCut = 35 + end + item + Command = ecSelLineEnd + ShortCut = 8227 + end + item + Command = ecEditorBottom + ShortCut = 16419 + end + item + Command = ecSelEditorBottom + ShortCut = 24611 + end + item + Command = ecToggleMode + ShortCut = 45 + end + item + Command = ecCopy + ShortCut = 16429 + end + item + Command = ecPaste + ShortCut = 8237 + end + item + Command = ecDeleteChar + ShortCut = 46 + end + item + Command = ecCut + ShortCut = 8238 + end + item + Command = ecDeleteLastChar + ShortCut = 8 + end + item + Command = ecDeleteLastChar + ShortCut = 8200 + end + item + Command = ecDeleteLastWord + ShortCut = 16392 + end + item + Command = ecUndo + ShortCut = 32776 + end + item + Command = ecRedo + ShortCut = 40968 + end + item + Command = ecLineBreak + ShortCut = 13 + end + item + Command = ecSelectAll + ShortCut = 16449 + end + item + Command = ecCopy + ShortCut = 16451 + end + item + Command = ecBlockIndent + ShortCut = 24649 + end + item + Command = ecLineBreak + ShortCut = 16461 + end + item + Command = ecInsertLine + ShortCut = 16462 + end + item + Command = ecDeleteWord + ShortCut = 16468 + end + item + Command = ecBlockUnindent + ShortCut = 24661 + end + item + Command = ecPaste + ShortCut = 16470 + end + item + Command = ecCut + ShortCut = 16472 + end + item + Command = ecDeleteLine + ShortCut = 16473 + end + item + Command = ecDeleteEOL + ShortCut = 24665 + end + item + Command = ecUndo + ShortCut = 16474 + end + item + Command = ecRedo + ShortCut = 24666 + end + item + Command = ecGotoMarker0 + ShortCut = 16432 + end + item + Command = ecGotoMarker1 + ShortCut = 16433 + end + item + Command = ecGotoMarker2 + ShortCut = 16434 + end + item + Command = ecGotoMarker3 + ShortCut = 16435 + end + item + Command = ecGotoMarker4 + ShortCut = 16436 + end + item + Command = ecGotoMarker5 + ShortCut = 16437 + end + item + Command = ecGotoMarker6 + ShortCut = 16438 + end + item + Command = ecGotoMarker7 + ShortCut = 16439 + end + item + Command = ecGotoMarker8 + ShortCut = 16440 + end + item + Command = ecGotoMarker9 + ShortCut = 16441 + end + item + Command = ecSetMarker0 + ShortCut = 24624 + end + item + Command = ecSetMarker1 + ShortCut = 24625 + end + item + Command = ecSetMarker2 + ShortCut = 24626 + end + item + Command = ecSetMarker3 + ShortCut = 24627 + end + item + Command = ecSetMarker4 + ShortCut = 24628 + end + item + Command = ecSetMarker5 + ShortCut = 24629 + end + item + Command = ecSetMarker6 + ShortCut = 24630 + end + item + Command = ecSetMarker7 + ShortCut = 24631 + end + item + Command = ecSetMarker8 + ShortCut = 24632 + end + item + Command = ecSetMarker9 + ShortCut = 24633 + end + item + Command = EcFoldLevel1 + ShortCut = 41009 + end + item + Command = EcFoldLevel2 + ShortCut = 41010 + end + item + Command = EcFoldLevel1 + ShortCut = 41011 + end + item + Command = EcFoldLevel1 + ShortCut = 41012 + end + item + Command = EcFoldLevel1 + ShortCut = 41013 + end + item + Command = EcFoldLevel6 + ShortCut = 41014 + end + item + Command = EcFoldLevel7 + ShortCut = 41015 + end + item + Command = EcFoldLevel8 + ShortCut = 41016 + end + item + Command = EcFoldLevel9 + ShortCut = 41017 + end + item + Command = EcFoldLevel0 + ShortCut = 41008 + end + item + Command = EcFoldCurrent + ShortCut = 41005 + end + item + Command = EcUnFoldCurrent + ShortCut = 41003 + end + item + Command = EcToggleMarkupWord + ShortCut = 32845 + end + item + Command = ecNormalSelect + ShortCut = 24654 + end + item + Command = ecColumnSelect + ShortCut = 24643 + end + item + Command = ecLineSelect + ShortCut = 24652 + end + item + Command = ecTab + ShortCut = 9 + end + item + Command = ecShiftTab + ShortCut = 8201 + end + item + Command = ecMatchBracket + ShortCut = 24642 + end + item + Command = ecColSelUp + ShortCut = 40998 + end + item + Command = ecColSelDown + ShortCut = 41000 + end + item + Command = ecColSelLeft + ShortCut = 40997 + end + item + Command = ecColSelRight + ShortCut = 40999 + end + item + Command = ecColSelPageDown + ShortCut = 40994 + end + item + Command = ecColSelPageBottom + ShortCut = 57378 + end + item + Command = ecColSelPageUp + ShortCut = 40993 + end + item + Command = ecColSelPageTop + ShortCut = 57377 + end + item + Command = ecColSelLineStart + ShortCut = 40996 + end + item + Command = ecColSelLineEnd + ShortCut = 40995 + end + item + Command = ecColSelEditorTop + ShortCut = 57380 + end + item + Command = ecColSelEditorBottom + ShortCut = 57379 + end> + MouseActions = <> + MouseSelActions = <> + Lines.Strings = ( + '' + ) + SelectedColor.BackPriority = 50 + SelectedColor.ForePriority = 50 + SelectedColor.FramePriority = 50 + SelectedColor.BoldPriority = 50 + SelectedColor.ItalicPriority = 50 + SelectedColor.UnderlinePriority = 50 + OnStatusChange = SynMemoStatusChange + inline SynLeftGutterPartList1: TSynGutterPartList + object SynGutterMarks1: TSynGutterMarks + Width = 24 + MouseActions = <> + end + object SynGutterLineNumber1: TSynGutterLineNumber + Width = 17 + MouseActions = <> + MarkupInfo.Background = clBtnFace + MarkupInfo.Foreground = clNone + DigitCount = 2 + ShowOnlyLineNumbersMultiplesOf = 1 + ZeroStart = False + LeadingZeros = False + end + object SynGutterChanges1: TSynGutterChanges + Width = 4 + MouseActions = <> + ModifiedColor = 59900 + SavedColor = clGreen + end + object SynGutterSeparator1: TSynGutterSeparator + Width = 2 + MouseActions = <> + end + object SynGutterCodeFolding1: TSynGutterCodeFolding + MouseActions = <> + MarkupInfo.Background = clNone + MarkupInfo.Foreground = clGray + MouseActionsExpanded = <> + MouseActionsCollapsed = <> + end + end + end + object FileNameEdit: TFileNameEdit + Left = 56 + Height = 23 + Top = 24 + Width = 368 + OnAcceptFileName = FileNameEditAcceptFileName + FilterIndex = 0 + HideDirectories = False + ButtonWidth = 23 + NumGlyphs = 1 + MaxLength = 0 + TabOrder = 0 + end + object INIFileLabel: TLabel + Left = 8 + Height = 15 + Top = 24 + Width = 34 + Caption = 'INI file' + ParentColor = False + end + object ProfileSelect: TComboBox + Left = 56 + Height = 23 + Hint = 'Choose the profile you want to enable' + Top = 61 + Width = 164 + ItemHeight = 15 + OnSelect = ProfileSelectSelect + Sorted = True + TabOrder = 1 + end + object ProfileLabel: TLabel + Left = 8 + Height = 15 + Top = 64 + Width = 34 + Caption = 'Profile' + ParentColor = False + end + object OKButton: TButton + Left = 664 + Height = 25 + Top = 456 + Width = 75 + Caption = '&OK' + Default = True + ModalResult = 1 + TabOrder = 4 + end + object CancelButton: TButton + Left = 568 + Height = 25 + Top = 456 + Width = 75 + Cancel = True + Caption = '&Cancel' + ModalResult = 2 + OnClick = CancelButtonClick + TabOrder = 3 + end + object SynIniHighlighter: TSynIniSyn + DefaultFilter = 'INI Files (*.ini)|*.ini' + Enabled = False + CommentAttri.FrameEdges = sfeAround + TextAttri.FrameEdges = sfeAround + SectionAttri.FrameEdges = sfeAround + KeyAttri.FrameEdges = sfeAround + NumberAttri.FrameEdges = sfeAround + SpaceAttri.FrameEdges = sfeAround + StringAttri.FrameEdges = sfeAround + SymbolAttri.FrameEdges = sfeAround + left = 32 + top = 456 + end + object GUITimer: TIdleTimer + AutoEnabled = True + OnTimer = GUITimerTimer + left = 560 + top = 16 + end +end diff --git a/packages/fcl-db/tests/inieditor.pas b/packages/fcl-db/tests/inieditor.pas new file mode 100644 index 0000000000..60a365c975 --- /dev/null +++ b/packages/fcl-db/tests/inieditor.pas @@ -0,0 +1,251 @@ +unit inieditor; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, + Graphics, Dialogs, StdCtrls, EditBtn, ExtCtrls, + IniFiles, lazutf8, SynEdit,SynMemo,{SynEditTypes,}SynHighlighterIni, SynEditTypes; + +type + + { TFormIniEditor } + + TFormIniEditor = class(TForm) + GUITimer: TIdleTimer; + OKButton: TButton; + CancelButton: TButton; + ProfileSelect: TComboBox; + FileNameEdit: TFileNameEdit; + INIFileLabel: TLabel; + ProfileLabel: TLabel; + SynIniHighlighter: TSynIniSyn; + SynMemo: TSynMemo; + procedure CancelButtonClick(Sender: TObject); + + procedure FileNameEditAcceptFileName(Sender: TObject; var Value: String); + procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormDropFiles(Sender: TObject; const FileNames: array of String); + procedure FormShow(Sender: TObject); + procedure GUITimerTimer(Sender: TObject); + procedure ProfileSelectSelect(Sender: TObject); + procedure SynMemoStatusChange(Sender: TObject; Changes: TSynStatusChanges); + private + FIniFilename: string; + FIniStream: TMemoryStream; + FMustReloadProfileSelect: boolean; + FSaveChanges: boolean; //If off, don't save any changes (e.g. when canceling form) + FProfileSelectKey: string; + FProfileSelectSection: string; + FProfileSelectValue: string; + procedure LoadGUI(KeepCursorPosition: boolean; LoadSynmemo: boolean; LoadProfileselect: boolean); //Loads GUI elements from backing stream + procedure SetIniFilename(AValue: string); //Loads file into stream + procedure SetProfileSelectKey(AValue: string); + procedure SetProfileSelectSection(AValue: string); + // Saves synmemo contents to memory stream and optionally to file, too + procedure SynMemoSave(AlsoToFile: boolean); + { private declarations } + public + // File to be edited/viewed: + property INIFile: string read FIniFilename write SetIniFilename; + // Section name where profile selection is to be stored. If nothing, the root/top level will be used + property ProfileSelectSection: string read FProfileSelectSection write SetProfileSelectSection; + // Key to be used for storing selected profile + // If empty, don't use the select profile combobox + property ProfileSelectKey: string read FProfileSelectKey write SetProfileSelectKey; + // The value the user selected + property ProfileSelectValue: string read FProfileSelectValue; + end; + +var + Form1: TFormIniEditor; + +implementation + +{$R *.lfm} + +{ TFormIniEditor } + + +procedure TFormIniEditor.FormDropFiles(Sender: TObject; + const FileNames: array of String); +begin + // Go through property for reload file+reload GUI code + IniFile:=FileNames[0]; +end; + +procedure TFormIniEditor.FormShow(Sender: TObject); +begin + if FileNameEdit.FileName='' then + FileNameEdit.FileName:=ExpandFileNameUTF8(FIniFilename); +end; + +procedure TFormIniEditor.GUITimerTimer(Sender: TObject); +begin + if FMustReloadProfileSelect then + LoadGUI(true,false,true); +end; + +procedure TFormIniEditor.ProfileSelectSelect(Sender: TObject); +// Save selected profile +var + MyIniFile: TIniFile; +begin + FProfileSelectValue:=ProfileSelect.Text; + if FProfileSelectValue<>'' then + begin + // Save any changes in synmemo + SynMemoSave(false); + FIniStream.Position:=0; //Load from beginning + MyIniFile := TIniFile.Create(FIniStream, True); + FIniStream.Position:=0; //Needed to save again + try + MyIniFile.WriteString(FProfileSelectSection,FProfileSelectKey,FProfileSelectValue); + finally + MyIniFile.Free; + end; + LoadGUI(true,true,true); + end; +end; + +procedure TFormIniEditor.SynMemoStatusChange(Sender: TObject; + Changes: TSynStatusChanges); +begin + // If user edits the profile name directly or edits/deletes/adds + // one of the section names, the combobox will need to be refreshed. + // Pass this on to a timer so it gets done without disturbing the updates + if (FMustReloadProfileSelect=false) and (scModified in Changes) then + begin + //todo: test for section line or key=value + FMustReloadProfileSelect:=true; + end; +end; + +procedure TFormIniEditor.LoadGUI(KeepCursorPosition: boolean; LoadSynmemo: boolean; LoadProfileselect: boolean); +var + MyIniFile : TIniFile; + OldPos: TPoint; + ProfIndex: integer; + Sections: TStringList; +begin + SynMemo.BeginUpdate(false); + if LoadSynMemo then + begin + OldPos:=SynMemo.CaretXY; + FIniStream.Position:=0; //Load from beginning + SynMemo.Lines.LoadFromStream(FIniStream); + end; + FIniStream.Position:=0; //Load from beginning + MyIniFile := TIniFile.Create(FIniStream, True); + FIniStream.Position:=0; //In case we want to save + Sections:=TStringList.Create; + try + if LoadProfileselect then + begin + Sections.Sorted:=true; + MyIniFile.ReadSections(Sections); + // Now take out the one where the profile is stored as it will confuse users + if Sections.Find(FProfileSelectSection, ProfIndex) then + Sections.Delete(ProfIndex); + ProfileSelect.Clear; + ProfileSelect.Items.AddStrings(Sections); + FProfileSelectValue:=MyIniFile.ReadString(FProfileSelectSection,FProfileSelectKey,''); + ProfileSelect.Text:=FProfileSelectValue; + FMustReloadProfileSelect:=false; + end; + + // restore cursor/caret position + if LoadSynMemo and KeepCursorPosition then + SynMemo.CaretXY:=OldPos; + finally + MyIniFile.Free; + Sections.Free; + SynMemo.EndUpdate; + end; +end; + +procedure TFormIniEditor.SetIniFilename(AValue: string); +begin + if FIniFilename=AValue then Exit; + FIniFilename:=AValue; + if FIniFileName<>'' then + begin + try + FIniStream.Clear; + FIniStream.LoadFromFile(FIniFilename); + except + on E: Exception do + ShowMessage('Error loading file '+FIniFilename+': '+E.Message); + end; + LoadGUI(false,true,true); + end; +end; + +procedure TFormIniEditor.SetProfileSelectKey(AValue: string); +begin + if FProfileSelectKey=AValue then Exit; + FProfileSelectKey:=AValue; + if (FProfileSelectKey<>'') and (FProfileSelectSection<>'') then + LoadGUI(false,true,true); +end; + +procedure TFormIniEditor.SetProfileSelectSection(AValue: string); +begin + if FProfileSelectSection=AValue then Exit; + FProfileSelectSection:=AValue; + if (FProfileSelectKey<>'') and (FProfileSelectSection<>'') then + LoadGUI(false,true,true); +end; + +procedure TFormIniEditor.SynMemoSave(AlsoToFile: boolean); +begin + if FSaveChanges then + begin + FIniStream.Clear; + FIniStream.Position:=0; //Save from beginning + SynMemo.Lines.SaveToStream(FiniStream); + FIniStream.Position:=0; //Save from beginning + if AlsoToFile and (FIniFileName<>'') then + FIniStream.SaveToFile(FIniFilename); + end; +end; + + +procedure TFormIniEditor.CancelButtonClick(Sender: TObject); +begin + FSaveChanges:=false; +end; + + + +procedure TFormIniEditor.FileNameEditAcceptFileName(Sender: TObject; + var Value: String); +begin + // go through the property to load new file + INIFile:=Value; +end; + +procedure TFormIniEditor.FormCloseQuery(Sender: TObject; var CanClose: boolean); +begin + // Save any uncommitted changes + //todo: only if dirty synmemo changestamp?; also check if this is best event + SynMemoSave(true); +end; + +procedure TFormIniEditor.FormCreate(Sender: TObject); +begin + FIniStream:=TMemoryStream.Create; + FSaveChanges:=true; //allow editing +end; + +procedure TFormIniEditor.FormDestroy(Sender: TObject); +begin + FIniStream.Free; +end; + +end. +