From 8c985ac62b00fba04cd5539084ee8e78c20c3105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 30 Jul 2024 22:06:27 -0300 Subject: [PATCH 001/109] Update DelphiAIDev.Utils.OTA.pas --- Src/Utils/DelphiAIDev.Utils.OTA.pas | 1 - 1 file changed, 1 deletion(-) diff --git a/Src/Utils/DelphiAIDev.Utils.OTA.pas b/Src/Utils/DelphiAIDev.Utils.OTA.pas index 11f4cce..a281483 100644 --- a/Src/Utils/DelphiAIDev.Utils.OTA.pas +++ b/Src/Utils/DelphiAIDev.Utils.OTA.pas @@ -595,7 +595,6 @@ class function TUtilsOTA.GetIOTASourceEditor(AIOTAModule: IOTAModule; const AFil Result := nil; end; end; - begin if(not Assigned(AIOTAModule))then begin From 344dfa742e46df90afd6fbeca5f227335602799e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 8 Aug 2024 00:25:07 -0300 Subject: [PATCH 002/109] bk/2024-08-08-0025 --- Package/DelphiAIDeveloper.dpk | 4 +- Package/DelphiAIDeveloper.dproj | 6 + Package/Img/c4d_database.bmp | Bin 0 -> 732 bytes Src/Consts/DelphiAIDev.Consts.pas | 11 ++ Src/DelphiAIDev.Register.pas | 4 +- .../DelphiAIDev.IDE.ImageListMain.pas | 3 + Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas | 14 +- Src/MainMenu/DelphiAIDev.MainMenu.pas | 14 +- .../DelphiAIDev.PopupMenuProjects.Item.pas | 173 ++++++++++++++++++ .../DelphiAIDev.PopupMenuProjects.pas | 120 ++++++++++++ Src/Types/DelphiAIDev.Types.pas | 2 + 11 files changed, 345 insertions(+), 6 deletions(-) create mode 100644 Package/Img/c4d_database.bmp create mode 100644 Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.Item.pas create mode 100644 Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 8213a74..a9301e0 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -74,6 +74,8 @@ contains DelphiAIDev.Utils.ABMenuAction in '..\Src\Utils\DelphiAIDev.Utils.ABMenuAction.pas', DelphiAIDev.IDE.Splash in '..\Src\IDE\Splash\DelphiAIDev.IDE.Splash.pas', DelphiAIDev.Chat.ProcessResponse in '..\Src\Chat\DelphiAIDev.Chat.ProcessResponse.pas', - DelphiAIDev.AI.Groq in '..\Src\AI\DelphiAIDev.AI.Groq.pas'; + DelphiAIDev.AI.Groq in '..\Src\AI\DelphiAIDev.AI.Groq.pas', + DelphiAIDev.PopupMenuProjects in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.pas', + DelphiAIDev.PopupMenuProjects.Item in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.Item.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index ae30900..f4f3874 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -181,6 +181,8 @@ + + BITMAP c4d_gear @@ -205,6 +207,10 @@ BITMAP c4d_question + + BITMAP + c4d_database + Cfg_2 Base diff --git a/Package/Img/c4d_database.bmp b/Package/Img/c4d_database.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ba3f71dd609e8e92012531e683608a762454362d GIT binary patch literal 732 zcmX|;Yex`~5JlO8|> ztNd2&0m;e*+XK8;T+V9Iq9~;h*Au~kXHYfF!6Tp9SfFD{0KWK++m_nu(Ak#V7>4dyNhs4*Pkl8tkti~RcPb@&y z`W33CKHQnKx?#+P4K@bx2j zVVH&2^ImvXwZZ3UHv-@2;rpl&(su?(-y0B8KMGlGKf>#@kXO_q>Ej@{`_16)HGwO8 z3rST6B$e&(s_uYi#Rqgv{swoq0bEgy>uB7R>~9%Gig5S~W7L-+7!vlz4FiJi$r8gnT#C0k^FMZ*45M45l1xZt|T-l1Vz z4-#4I;cXW$i!6;vKbJxL6!DQsxgsm`H6?1|8+S~8;EKqy*dyCd5=o$s*Om~G{S*li qr^(F?o7S%j64^KI_>SnSh3@&qr03?~qP59g$$&yPb8AUg2lx-!nEP=6 literal 0 HcmV?d00001 diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index ea69fe7..4140765 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -19,6 +19,7 @@ TConsts = class MARK_BEGIN_PASCAL = '```objectpascal'; MARK_BEGIN_PASCAL2 = '``pascal'; MARK_END = '```'; + PREFIX_NAME_SEPARATOR = 'DelphiAIDevSeparator'; //SETTINGS KEY_SETTINGS_IN_WINDOWS_REGISTRY = '\SOFTWARE\DelphiAIDeveloper'; @@ -50,6 +51,13 @@ TConsts = class ITEM_MENU_C4DDelphiAIDev_NAME = 'C4DDelphiAIDevItemMenu'; ITEM_MENU_C4DDelphiAIDev_CAPTION = 'AI Developer'; + //CODE4D-WIZARD INFORMATION + //ITEM_MENU_Code4D_CAPTION = 'Code4D'; + + //CAPTIONS ITENS POPUPMENU PROJ + ITEM_POPUP_MENU_PROJ_CAPTION = 'AI Developer'; + ITEM_POPUP_MENU_PROJ_ConfigureDB_CAPTION = 'Configure Database'; + //MAIN MENU IDE NAME AND CAPTIONS MENU_IDE_CHAT_NAME = 'DelphiAIDevChat1'; MENU_IDE_CHAT_CAPTION = 'Chat'; @@ -57,6 +65,9 @@ TConsts = class MENU_IDE_DEFAULTS_QUESTIONS_NAME = 'DelphiAIDevDefaultsQuestions1'; MENU_IDE_DEFAULTS_QUESTIONS_CAPTION = 'Defaults questions'; + MENU_IDE_DEFAULTS_DATABASES_NAME = 'DelphiAIDevDatabases1'; + MENU_IDE_DEFAULTS_DATABASES_CAPTION = 'Databases'; + MENU_IDE_CHAT_SETTINGS_NAME = 'DelphiAIDevSettings1'; MENU_IDE_CHAT_SETTINGS_CAPTION = 'Settings'; MENU_IDE_SETTINGS_NAME = 'C4DWizarSettings1'; diff --git a/Src/DelphiAIDev.Register.pas b/Src/DelphiAIDev.Register.pas index 709d890..141a1e3 100644 --- a/Src/DelphiAIDev.Register.pas +++ b/Src/DelphiAIDev.Register.pas @@ -5,7 +5,8 @@ interface uses DelphiAIDev.Chat.View, DelphiAIDev.MainMenu.Register, - DelphiAIDev.IDE.Shortcuts; + DelphiAIDev.IDE.Shortcuts, + DelphiAIDev.PopupMenuProjects; procedure Register; @@ -16,6 +17,7 @@ procedure Register; DelphiAIDev.Chat.View.RegisterSelf; DelphiAIDev.MainMenu.Register.RegisterSelf; DelphiAIDev.IDE.Shortcuts.RefreshRegister; + DelphiAIDev.PopupMenuProjects.RegisterSelf; end; end. diff --git a/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas b/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas index ca39d1f..ef47d16 100644 --- a/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas +++ b/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas @@ -13,6 +13,7 @@ TDelphiAIDevIDEImageListMain = class FImgIndexGear: Integer; FImgIndexMessage: Integer; FImgQuestion: Integer; + FImgDatabase: Integer; constructor Create; public class function GetInstance: TDelphiAIDevIDEImageListMain; @@ -20,6 +21,7 @@ TDelphiAIDevIDEImageListMain = class property ImgIndexGear: Integer read FImgIndexGear; property ImgIndexMessage: Integer read FImgIndexMessage; property ImgQuestion: Integer read FImgQuestion; + property ImgDatabase: Integer read FImgDatabase; end; implementation @@ -43,6 +45,7 @@ constructor TDelphiAIDevIDEImageListMain.Create; FImgIndexGear := TUtilsOTA.AddImgIDEResourceName('c4d_gear'); FImgIndexMessage := TUtilsOTA.AddImgIDEResourceName('c4d_message'); FImgQuestion := TUtilsOTA.AddImgIDEResourceName('c4d_question'); + FImgDatabase := TUtilsOTA.AddImgIDEResourceName('c4d_database'); end; initialization diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas index f07deb0..ac4f031 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas @@ -10,10 +10,10 @@ interface type TDelphiAIDevIDEMainMenuClicks = class - private public class procedure ChatClick(Sender: TObject); class procedure DefaultsQuestionsClick(Sender: TObject); + class procedure DatabasesClick(Sender: TObject); class procedure SettingsClick(Sender: TObject); class procedure AboutClick(Sender: TObject); end; @@ -46,6 +46,18 @@ class procedure TDelphiAIDevIDEMainMenuClicks.DefaultsQuestionsClick(Sender: TOb end; end; +class procedure TDelphiAIDevIDEMainMenuClicks.DatabasesClick(Sender: TObject); +var + LView: TDelphiAIDevDefaultsQuestionsView; +begin + LView := TDelphiAIDevDefaultsQuestionsView.Create(nil); + try + LView.ShowModal; + finally + FreeAndNil(LView); + end; +end; + class procedure TDelphiAIDevIDEMainMenuClicks.SettingsClick(Sender: TObject); begin DelphiAIDevSettingsView := TDelphiAIDevSettingsView.Create(nil); diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.pas b/Src/MainMenu/DelphiAIDev.MainMenu.pas index 65d8dac..e5e1a7d 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.pas @@ -67,7 +67,7 @@ procedure TDelphiAIDevIDEMainMenu.CreateMenus; Self.GetShortCutStrChat ); - Self.CreateSubMenu('C4DSeparator40', '-', nil); + Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '10', '-', nil); Self.CreateSubMenu(TConsts.MENU_IDE_DEFAULTS_QUESTIONS_NAME, TConsts.MENU_IDE_DEFAULTS_QUESTIONS_CAPTION, @@ -75,7 +75,15 @@ procedure TDelphiAIDevIDEMainMenu.CreateMenus; TDelphiAIDevIDEImageListMain.GetInstance.ImgQuestion ); - Self.CreateSubMenu('C4DSeparator50', '-', nil); + Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '20', '-', nil); + + Self.CreateSubMenu(TConsts.MENU_IDE_DEFAULTS_DATABASES_NAME, + TConsts.MENU_IDE_DEFAULTS_DATABASES_Caption, + TDelphiAIDevIDEMainMenuClicks.DatabasesClick, + TDelphiAIDevIDEImageListMain.GetInstance.ImgDatabase + ); + + Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '30', '-', nil); Self.CreateSubMenu(TConsts.MENU_IDE_SETTINGS_NAME, TConsts.MENU_IDE_SETTINGS_CAPTION, @@ -84,7 +92,7 @@ procedure TDelphiAIDevIDEMainMenu.CreateMenus; ); - Self.CreateSubMenu('C4DSeparator90', '-', nil); + Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '40', '-', nil); Self.CreateSubMenu(TConsts.MENU_IDE_ABOUT_NAME, TConsts.MENU_IDE_ABOUT_CAPTION, TDelphiAIDevIDEMainMenuClicks.AboutClick, diff --git a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.Item.pas b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.Item.pas new file mode 100644 index 0000000..3e25030 --- /dev/null +++ b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.Item.pas @@ -0,0 +1,173 @@ +unit DelphiAIDev.PopupMenuProjects.Item; + +interface + +uses + System.SysUtils, + System.Classes, + ToolsAPI, + DelphiAIDev.Types; + +type + TDelphiAIDevPopupMenuProjectsItem = class(TNotifierObject, IOTALocalMenu, IOTAProjectManagerMenu) + private + FCaption: string; + FIsMultiSelectable: Boolean; + FChecked: Boolean; + FEnabled: Boolean; + FHelpContext: Integer; + FName: string; + FParent: string; + FPosition: Integer; + FVerb: string; + protected + FProject: IOTAProject; + FOnExecute: TC4DWizardMenuContextList; + function GetCaption: string; + function GetChecked: Boolean; + function GetEnabled: Boolean; + function GetHelpContext: Integer; + function GetName: string; + function GetParent: string; + function GetPosition: Integer; + function GetVerb: string; + procedure SetCaption(const Value: string); + procedure SetChecked(Value: Boolean); + procedure SetEnabled(Value: Boolean); + procedure SetHelpContext(Value: Integer); + procedure SetName(const Value: string); + procedure SetParent(const Value: string); + procedure SetPosition(Value: Integer); + procedure SetVerb(const Value: string); + function GetIsMultiSelectable: Boolean; + procedure SetIsMultiSelectable(Value: Boolean); + procedure Execute(const MenuContextList: IInterfaceList); virtual; + function PreExecute(const MenuContextList: IInterfaceList): Boolean; + function PostExecute(const MenuContextList: IInterfaceList): Boolean; + public + class function New(OnExecute: TC4DWizardMenuContextList): IOTAProjectManagerMenu; overload; + constructor Create(OnExecute: TC4DWizardMenuContextList); overload; + end; + +implementation + +class function TDelphiAIDevPopupMenuProjectsItem.New(OnExecute: TC4DWizardMenuContextList): IOTAProjectManagerMenu; +begin + Result := Self.Create(OnExecute); +end; + +constructor TDelphiAIDevPopupMenuProjectsItem.Create(OnExecute: TC4DWizardMenuContextList); +begin + FOnExecute := OnExecute; + FEnabled := True; + FChecked := False; + FIsMultiSelectable := False; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.Execute(const MenuContextList: IInterfaceList); +begin + if(Assigned(FOnExecute))then + FOnExecute(MenuContextList); +end; + +function TDelphiAIDevPopupMenuProjectsItem.GetCaption: string; +begin + Result := FCaption; +end; + +function TDelphiAIDevPopupMenuProjectsItem.GetChecked: Boolean; +begin + Result := FChecked; +end; + +function TDelphiAIDevPopupMenuProjectsItem.GetEnabled: Boolean; +begin + Result := FEnabled; +end; + +function TDelphiAIDevPopupMenuProjectsItem.GetHelpContext: Integer; +begin + Result := FHelpContext; +end; + +function TDelphiAIDevPopupMenuProjectsItem.GetIsMultiSelectable: Boolean; +begin + Result := FIsMultiSelectable; +end; + +function TDelphiAIDevPopupMenuProjectsItem.GetName: string; +begin + Result := FName; +end; + +function TDelphiAIDevPopupMenuProjectsItem.GetParent: string; +begin + Result := FParent; +end; + +function TDelphiAIDevPopupMenuProjectsItem.GetPosition: Integer; +begin + Result := FPosition; +end; + +function TDelphiAIDevPopupMenuProjectsItem.GetVerb: string; +begin + Result := FVerb; +end; + +function TDelphiAIDevPopupMenuProjectsItem.PostExecute(const MenuContextList: IInterfaceList): Boolean; +begin + Result := True; +end; + +function TDelphiAIDevPopupMenuProjectsItem.PreExecute(const MenuContextList: IInterfaceList): Boolean; +begin + Result := True; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.SetCaption(const Value: string); +begin + FCaption := Value; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.SetChecked(Value: Boolean); +begin + FChecked := Value; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.SetEnabled(Value: Boolean); +begin + FEnabled := Value; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.SetHelpContext(Value: Integer); +begin + FHelpContext := Value; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.SetIsMultiSelectable(Value: Boolean); +begin + FIsMultiSelectable := Value; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.SetName(const Value: string); +begin + FName := Value; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.SetParent(const Value: string); +begin + FParent := Value; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.SetPosition(Value: Integer); +begin + FPosition := Value; +end; + +procedure TDelphiAIDevPopupMenuProjectsItem.SetVerb(const Value: string); +begin + FVerb := Value; +end; + +end. diff --git a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas new file mode 100644 index 0000000..a5d0799 --- /dev/null +++ b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas @@ -0,0 +1,120 @@ +unit DelphiAIDev.PopupMenuProjects; + +interface + +uses + System.SysUtils, + System.Classes, + ToolsAPI, + DelphiAIDev.Types, + DelphiAIDev.PopupMenuProjects.Item; + +type + TC4DWizardIDEPopupMenuNotifier = class(TNotifierObject, IOTAProjectMenuItemCreatorNotifier) + private + FProject: IOTAProject; + FPosition: Integer; + function AddItemInMenu(const ACaption: string): IOTAProjectManagerMenu; + function AddSubItemInMenu(const ACaption: string; + const AOnExecute: TC4DWizardMenuContextList = nil; + const AChecked: Boolean = False): IOTAProjectManagerMenu; + procedure CheckFileNameProject; + //function GetReopenDataOfFileName: TC4DWizardReopenData; + procedure OnExecuteEditInformations(const MenuContextList: IInterfaceList); + protected + procedure AddMenu(const Project: IOTAProject; const IdentList: TStrings; const ProjectManagerMenuList: IInterfaceList; IsMultiSelect: Boolean); + public + class function New: IOTAProjectMenuItemCreatorNotifier; + end; + +procedure RegisterSelf; + +implementation + +uses + DelphiAIDev.Consts, + DelphiAIDev.Utils, + DelphiAIDev.Utils.OTA; + +var + Index: Integer = -1; + +procedure RegisterSelf; +begin + Index := TUtilsOTA + .GetIOTAProjectManager + .AddMenuItemCreatorNotifier(TC4DWizardIDEPopupMenuNotifier.New); +end; + +class function TC4DWizardIDEPopupMenuNotifier.New: IOTAProjectMenuItemCreatorNotifier; +begin + Result := Self.Create; +end; + +procedure TC4DWizardIDEPopupMenuNotifier.AddMenu(const Project: IOTAProject; const IdentList: TStrings; const ProjectManagerMenuList: IInterfaceList; IsMultiSelect: Boolean); +begin + if(not Assigned(ProjectManagerMenuList))then + Exit; + + if(IdentList.IndexOf(sProjectContainer) >= 0)then + FPosition := pmmpUninstall + else if(IdentList.IndexOf(sProjectGroupContainer) >= 0)then + FPosition := pmmpRename + else + Exit; + + FProject := Project; + FPosition := FPosition + 201; + ProjectManagerMenuList.Add(Self.AddItemInMenu('-')); + ProjectManagerMenuList.Add(Self.AddItemInMenu(TConsts.ITEM_POPUP_MENU_PROJ_CAPTION)); + + ProjectManagerMenuList.Add(Self.AddSubItemInMenu(TConsts.ITEM_POPUP_MENU_PROJ_ConfigureDB_CAPTION, + OnExecuteEditInformations)); +end; + +procedure TC4DWizardIDEPopupMenuNotifier.OnExecuteEditInformations(const MenuContextList: IInterfaceList); +begin + Self.CheckFileNameProject; + //TC4DWizardReopenController.New(FProject.FileName).EditInformations; +end; + +function TC4DWizardIDEPopupMenuNotifier.AddItemInMenu(const ACaption: string): IOTAProjectManagerMenu; +begin + Result := TDelphiAIDevPopupMenuProjectsItem.New({$IF CompilerVersion = 30.0} TC4DWizardMenuContextList(nil) {$ELSE} nil {$ENDIF}); + Result.Caption := ACaption; + Result.Verb := ACaption; + Result.Parent := ''; + Result.Position := TUtils.IncInt(FPosition); + Result.Checked := False; + Result.IsMultiSelectable := False; +end; + +function TC4DWizardIDEPopupMenuNotifier.AddSubItemInMenu(const ACaption: string; + const AOnExecute: TC4DWizardMenuContextList = nil; + const AChecked: Boolean = False): IOTAProjectManagerMenu; +begin + Result := TDelphiAIDevPopupMenuProjectsItem.New(AOnExecute); + Result.Caption := ACaption; + Result.Verb := ACaption; + Result.Parent := TConsts.ITEM_POPUP_MENU_PROJ_CAPTION; + Result.Position := TUtils.IncInt(FPosition); + Result.Checked := AChecked; + Result.IsMultiSelectable := False; +end; + +procedure TC4DWizardIDEPopupMenuNotifier.CheckFileNameProject; +begin + if(FProject.FileName.Trim.IsEmpty)then + TUtils.ShowMsgAndAbort('File name is empty'); + + if(not System.SysUtils.FileExists(FProject.FileName))then + TUtils.ShowMsgAndAbort('File not found'); +end; + +initialization + +finalization + if Index >= 0 then + TUtilsOTA.GetIOTAProjectManager.RemoveMenuItemCreatorNotifier(Index); + +end. diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index 7ea08fb..e119842 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -8,6 +8,8 @@ interface System.TypInfo; type + TC4DWizardMenuContextList = procedure(const MenuContextList: IInterfaceList) of object; + {$SCOPEDENUMS ON} TC4DAIsAvailable = (Gemini, OpenAI, Groq); TC4DLanguage = (en, ptBR, es); From 8c04c311c06ce5a669c7ee8ec8740e31c742df36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 8 Aug 2024 01:32:44 -0300 Subject: [PATCH 003/109] bk/2024-08-08-0132 --- Package/DelphiAIDeveloper.dpk | 8 +- Package/DelphiAIDeveloper.dproj | 11 +- Src/Consts/DelphiAIDev.Consts.pas | 3 +- .../DelphiAIDev.Databases.Fields.pas | 55 +++ .../DelphiAIDev.Databases.Interfaces.pas | 19 + Src/Databases/DelphiAIDev.Databases.Model.pas | 271 +++++++++++++ Src/Databases/DelphiAIDev.Databases.View.dfm | 218 +++++++++++ Src/Databases/DelphiAIDev.Databases.View.pas | 359 ++++++++++++++++++ .../DelphiAIDev.DefaultsQuestions.View.pas | 8 +- Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas | 5 +- Src/Types/DelphiAIDev.Types.pas | 1 + Src/Utils/DelphiAIDev.Utils.pas | 6 + 12 files changed, 953 insertions(+), 11 deletions(-) create mode 100644 Src/Databases/DelphiAIDev.Databases.Fields.pas create mode 100644 Src/Databases/DelphiAIDev.Databases.Interfaces.pas create mode 100644 Src/Databases/DelphiAIDev.Databases.Model.pas create mode 100644 Src/Databases/DelphiAIDev.Databases.View.dfm create mode 100644 Src/Databases/DelphiAIDev.Databases.View.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index a9301e0..65f2289 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -63,7 +63,7 @@ contains DelphiAIDev.IDE.ImageListMain in '..\Src\IDE\ImageListMain\DelphiAIDev.IDE.ImageListMain.pas', DelphiAIDev.IDE.Shortcuts in '..\Src\IDE\Shortcuts\DelphiAIDev.IDE.Shortcuts.pas', DelphiAIDev.Utils.CnWizard in '..\Src\Utils\DelphiAIDev.Utils.CnWizard.pas', - DelphiAIDev.DefaultsQuestions.View in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.View.pas' {DelphiAIDevDefaultsQuestionsView}, + DelphiAIDev.Databases.View in '..\Src\Databases\DelphiAIDev.Databases.View.pas' {DelphiAIDevDatabasesView}, DelphiAIDev.Utils.ListView in '..\Src\Utils\DelphiAIDev.Utils.ListView.pas', DelphiAIDev.Utils.GetIniPositionStr in '..\Src\Utils\DelphiAIDev.Utils.GetIniPositionStr.pas', DelphiAIDev.DefaultsQuestions.Fields in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.Fields.pas', @@ -76,6 +76,10 @@ contains DelphiAIDev.Chat.ProcessResponse in '..\Src\Chat\DelphiAIDev.Chat.ProcessResponse.pas', DelphiAIDev.AI.Groq in '..\Src\AI\DelphiAIDev.AI.Groq.pas', DelphiAIDev.PopupMenuProjects in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.pas', - DelphiAIDev.PopupMenuProjects.Item in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.Item.pas'; + DelphiAIDev.PopupMenuProjects.Item in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.Item.pas', + DelphiAIDev.DefaultsQuestions.View in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.View.pas' {DelphiAIDevDefaultsQuestionsView}, + DelphiAIDev.Databases.Model in '..\Src\Databases\DelphiAIDev.Databases.Model.pas', + DelphiAIDev.Databases.Interfaces in '..\Src\Databases\DelphiAIDev.Databases.Interfaces.pas', + DelphiAIDev.Databases.Fields in '..\Src\Databases\DelphiAIDev.Databases.Fields.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index f4f3874..0c75582 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -163,8 +163,8 @@ - -
DelphiAIDevDefaultsQuestionsView
+ +
DelphiAIDevDatabasesView
dfm
@@ -183,6 +183,13 @@ + +
DelphiAIDevDefaultsQuestionsView
+ dfm +
+ + + BITMAP c4d_gear diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index 4140765..1cb7b94 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -34,8 +34,9 @@ TConsts = class //NAMES FILES .rtf FILE_RTF_CHAT = 'chat.rtf'; - //NAMES FILE Database + //NAMES FILE JSON FILE_JSON_DEFAULTS_QUESTIONS = 'delphi_ai_developer_questions.json'; + FILE_JSON_DATABASES = 'delphi_ai_developer_databases.json'; //ABOUT AND SPLASH ABOUT_TITLE = 'Delphi AI Developer'; diff --git a/Src/Databases/DelphiAIDev.Databases.Fields.pas b/Src/Databases/DelphiAIDev.Databases.Fields.pas new file mode 100644 index 0000000..df1054e --- /dev/null +++ b/Src/Databases/DelphiAIDev.Databases.Fields.pas @@ -0,0 +1,55 @@ +unit DelphiAIDev.Databases.Fields; + +interface + +uses + DelphiAIDev.Types; + +type + TDelphiAIDevDatabasesFields = class + private + FGuid: string; + FDriverID: TC4DDriverID; + FDescription: string; + FHost: string; + FUser: string; + FPassword: string; + FPort: Integer; + FDatabaseName: string; + FVisible: Boolean; + public + constructor Create; + procedure Clear; + + property Guid: string read FGuid write FGuid; + property DriverID: TC4DDriverID read FDriverID write FDriverID; + property Description: string read FDescription write FDescription; + property Host: string read FHost write FHost; + property User: string read FUser write FUser; + property Password: string read FPassword write FPassword; + property Port: Integer read FPort write FPort; + property DatabaseName: string read FDatabaseName write FDatabaseName; + property Visible: Boolean read FVisible write FVisible; + end; + +implementation + +constructor TDelphiAIDevDatabasesFields.Create; +begin + Self.Clear; +end; + +procedure TDelphiAIDevDatabasesFields.Clear; +begin + FGuid := ''; + FDriverID := TC4DDriverID.MySQL; + FDescription := ''; + FHost := ''; + FUser := ''; + FPassword := ''; + FPort := 0; + FDatabaseName := ''; + FVisible := True; +end; + +end. diff --git a/Src/Databases/DelphiAIDev.Databases.Interfaces.pas b/Src/Databases/DelphiAIDev.Databases.Interfaces.pas new file mode 100644 index 0000000..19ddb10 --- /dev/null +++ b/Src/Databases/DelphiAIDev.Databases.Interfaces.pas @@ -0,0 +1,19 @@ +unit DelphiAIDev.Databases.Interfaces; + +interface + +uses + System.SysUtils, + DelphiAIDev.Databases.Fields; + +type + IDelphiAIDevDatabasesModel = interface + ['{3399A776-4B23-4CFC-8992-568AE07FE065}'] + procedure ReadData(AProc: TProc); + procedure SaveOrEditData(const AFields: TDelphiAIDevDatabasesFields); + procedure RemoveData(const AGuid: string); + end; + +implementation + +end. diff --git a/Src/Databases/DelphiAIDev.Databases.Model.pas b/Src/Databases/DelphiAIDev.Databases.Model.pas new file mode 100644 index 0000000..cb69c6b --- /dev/null +++ b/Src/Databases/DelphiAIDev.Databases.Model.pas @@ -0,0 +1,271 @@ +unit DelphiAIDev.Databases.Model; + +interface + +uses + System.SysUtils, + System.Classes, + System.JSON, + Rest.JSON, + DelphiAIDev.Utils, + DelphiAIDev.Types, + DelphiAIDev.Databases.Interfaces, + DelphiAIDev.Databases.Fields; + +type + TDelphiAIDevDatabasesModel = class(TInterfacedObject, IDelphiAIDevDatabasesModel) + private + procedure SaveData(const AFields: TDelphiAIDevDatabasesFields); + procedure EditData(const AFields: TDelphiAIDevDatabasesFields); + protected + procedure ReadData(AProc: TProc); + procedure SaveOrEditData(const AFields: TDelphiAIDevDatabasesFields); + procedure RemoveData(const AGuid: string); + public + class function New: IDelphiAIDevDatabasesModel; + constructor Create; + end; + +implementation + +const + GUID = 'guid'; + DRIVER_ID = 'driver_id'; + DESCRIPTION = 'description'; + HOST = 'host'; + USER = 'user'; + PASSWORD = 'password'; + PORT = 'port'; + DATABASE_NAME = 'database_name'; + VISIBLE = 'visible'; + +class function TDelphiAIDevDatabasesModel.New: IDelphiAIDevDatabasesModel; +begin + Result := Self.Create; +end; + +constructor TDelphiAIDevDatabasesModel.Create; +begin + // +end; + +procedure TDelphiAIDevDatabasesModel.ReadData(AProc: TProc); +var + LStringList: TStringList; + LJSONObjItem: TJSONObject; + LJSONArray: TJsonArray; + i: Integer; + LFields: TDelphiAIDevDatabasesFields; +begin + LFields := TDelphiAIDevDatabasesFields.Create; + try + if not FileExists(TUtils.GetPathFileJSONDatabases) then + begin + AProc(LFields); + Exit; + end; + + LStringList := TStringList.Create; + try + LStringList.LoadFromFile(TUtils.GetPathFileJSONDatabases); + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + finally + LStringList.Free; + end; + + try + for i := 0 to Pred(LJSONArray.Count) do + begin + if not(LJSONArray.Items[i] is TJSONObject) then + Continue; + + LJSONObjItem := LJSONArray.Items[i] as TJSONObject; + LFields.Guid := LJSONObjItem.GetValue(GUID); + LFields.DriverID := TC4DDriverID(LJSONObjItem.GetValue(DRIVER_ID)); + LFields.Description := LJSONObjItem.GetValue(DESCRIPTION); + LFields.Host := LJSONObjItem.GetValue(HOST); + LFields.User := LJSONObjItem.GetValue(USER); + LFields.Password := LJSONObjItem.GetValue(PASSWORD); + LFields.Port := LJSONObjItem.GetValue(PORT); + LFields.DatabaseName := LJSONObjItem.GetValue(DATABASE_NAME); + LFields.Visible := LJSONObjItem.GetValue(VISIBLE); + AProc(LFields); + end; + finally + LJSONArray.Free; + end; + finally + LFields.Free; + end; +end; + +procedure TDelphiAIDevDatabasesModel.SaveOrEditData(const AFields: TDelphiAIDevDatabasesFields); +begin + if AFields.Guid.Trim.IsEmpty then + Self.SaveData(AFields) + else + Self.EditData(AFields); +end; + +procedure TDelphiAIDevDatabasesModel.SaveData(const AFields: TDelphiAIDevDatabasesFields); +var + LStringList: TStringList; + LJSONArray: TJSONArray; + LJSONObject: TJSONObject; +begin + LStringList := TStringList.Create; + try + if FileExists(TUtils.GetPathFileJSONDatabases) then + LStringList.LoadFromFile(TUtils.GetPathFileJSONDatabases); + + LJSONArray := TJSONArray.Create; + try + if string(LStringList.Text).Trim.StartsWith('[') then + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + + LJSONObject := TJSONObject.Create; + LJSONObject.AddPair(GUID, TUtils.GetGuidStr); + LJSONObject.AddPair(DRIVER_ID, TJSONNumber.Create(Integer(AFields.DriverID))); + LJSONObject.AddPair(DESCRIPTION, AFields.Description); + LJSONObject.AddPair(HOST, AFields.Host); + LJSONObject.AddPair(USER, AFields.User); + LJSONObject.AddPair(PASSWORD, AFields.Password); + LJSONObject.AddPair(PORT, TJSONNumber.Create(AFields.Port)); + LJSONObject.AddPair(DATABASE_NAME, AFields.DatabaseName); + LJSONObject.AddPair(VISIBLE, TJSONBool.Create(AFields.Visible)); + LJSONArray.AddElement(LJSONObject); + + {$IF CompilerVersion <= 32.0} //Tokyo + LStringList.Text := LJSONArray.ToJSON; + {$ELSE} + LStringList.Text := LJSONArray.Format(2); + {$ENDIF} + finally + LJSONArray.Free; + end; + + LStringList.SaveToFile(TUtils.GetPathFileJSONDatabases); + finally + LStringList.Free; + end; +end; + +procedure TDelphiAIDevDatabasesModel.EditData(const AFields: TDelphiAIDevDatabasesFields); +var + LStringList: TStringList; + LJSONArray: TJSONArray; + LJSONObjItem: TJSONObject; + i: Integer; +begin + LStringList := TStringList.Create; + try + if FileExists(TUtils.GetPathFileJSONDatabases) then + LStringList.LoadFromFile(TUtils.GetPathFileJSONDatabases); + + LJSONArray := TJSONArray.Create; + try + if string(LStringList.Text).Trim.StartsWith('[') then + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + + for i := 0 to Pred(LJSONArray.Count) do + begin + if not(LJSONArray.Items[i] is TJSONObject) then + Continue; + + LJSONObjItem := LJSONArray.Items[i] as TJSONObject; + + if LJSONObjItem.GetValue(GUID) = AFields.Guid then + begin + LJSONObjItem.RemovePair(DRIVER_ID).Free; + LJSONObjItem.AddPair(DRIVER_ID, TJSONNumber.Create(Integer(AFields.DriverID))); + + LJSONObjItem.RemovePair(DESCRIPTION).Free; + LJSONObjItem.AddPair(DESCRIPTION, AFields.Description); + + LJSONObjItem.RemovePair(HOST).Free; + LJSONObjItem.AddPair(HOST, AFields.Host); + + LJSONObjItem.RemovePair(USER).Free; + LJSONObjItem.AddPair(USER, AFields.User); + + LJSONObjItem.RemovePair(PASSWORD).Free; + LJSONObjItem.AddPair(PASSWORD, AFields.Password); + + LJSONObjItem.RemovePair(PORT).Free; + LJSONObjItem.AddPair(PORT, TJSONNumber.Create(AFields.Port)); + + LJSONObjItem.RemovePair(DATABASE_NAME).Free; + LJSONObjItem.AddPair(DATABASE_NAME, AFields.DatabaseName); + + LJSONObjItem.RemovePair(VISIBLE).Free; + LJSONObjItem.AddPair(VISIBLE, TJSONBool.Create(AFields.Visible)); + + Break; + end; + end; + + {$IF CompilerVersion <= 32.0} //Tokyo + LStringList.Text := LJSONArray.ToJSON; + {$ELSE} + LStringList.Text := LJSONArray.Format(2); + {$ENDIF} + finally + LJSONArray.Free; + end; + + LStringList.SaveToFile(TUtils.GetPathFileJSONDatabases); + finally + LStringList.Free; + end; +end; + +procedure TDelphiAIDevDatabasesModel.RemoveData(const AGuid: string); +var + LStringList: TStringList; + LJSONArray: TJSONArray; + LJSONObjItem: TJSONObject; + i: Integer; +begin + if AGuid.Trim.IsEmpty then + Exit; + + if not FileExists(TUtils.GetPathFileJSONDatabases) then + Exit; + + LStringList := TStringList.Create; + try + LStringList.LoadFromFile(TUtils.GetPathFileJSONDatabases); + if not string(LStringList.Text).Trim.StartsWith('[') then + Exit; + + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + try + for i := 0 to Pred(LJSONArray.Count) do + begin + if not(LJSONArray.Items[i] is TJSONObject) then + Continue; + + LJSONObjItem := LJSONArray.Items[i] as TJSONObject; + if LJSONObjItem.GetValue(GUID) = AGuid then + begin + LJSONArray.Remove(i); + Break; + end; + end; + + {$IF CompilerVersion <= 32.0} //Tokyo + LStringList.Text := LJSONArray.ToJSON; + {$ELSE} + LStringList.Text := LJSONArray.Format(2); + {$ENDIF} + finally + LJSONArray.Free; + end; + + LStringList.SaveToFile(TUtils.GetPathFileJSONDatabases); + finally + LStringList.Free; + end; +end; + +end. diff --git a/Src/Databases/DelphiAIDev.Databases.View.dfm b/Src/Databases/DelphiAIDev.Databases.View.dfm new file mode 100644 index 0000000..ca0c060 --- /dev/null +++ b/Src/Databases/DelphiAIDev.Databases.View.dfm @@ -0,0 +1,218 @@ +object DelphiAIDevDatabasesView: TDelphiAIDevDatabasesView + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu] + Caption = 'IA Developer - Database registration' + ClientHeight = 561 + ClientWidth = 884 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + KeyPreview = True + OldCreateOrder = False + Position = poScreenCenter + OnCreate = FormCreate + OnKeyDown = FormKeyDown + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object Panel1: TPanel + Left = 0 + Top = 507 + Width = 884 + Height = 35 + Align = alBottom + BevelEdges = [beLeft, beRight, beBottom] + BevelOuter = bvNone + Padding.Left = 2 + Padding.Top = 2 + Padding.Right = 2 + Padding.Bottom = 2 + ParentBackground = False + TabOrder = 0 + object btnEdit: TButton + AlignWithMargins = True + Left = 124 + Top = 2 + Width = 120 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 2 + Margins.Bottom = 0 + Align = alLeft + Caption = 'Edit' + TabOrder = 0 + OnClick = btnEditClick + end + object btnClose: TButton + AlignWithMargins = True + Left = 770 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 2 + Margins.Bottom = 0 + Align = alRight + Caption = 'Close' + TabOrder = 1 + OnClick = btnCloseClick + end + object btnAdd: TButton + AlignWithMargins = True + Left = 2 + Top = 2 + Width = 120 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 2 + Margins.Bottom = 0 + Align = alLeft + Caption = 'Add new' + TabOrder = 2 + OnClick = btnAddClick + end + object btnRemove: TButton + AlignWithMargins = True + Left = 246 + Top = 2 + Width = 120 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 2 + Margins.Bottom = 0 + Align = alLeft + Caption = 'Remove' + TabOrder = 3 + OnClick = btnRemoveClick + end + end + object ListView: TListView + Left = 0 + Top = 50 + Width = 884 + Height = 457 + Align = alClient + Columns = < + item + Caption = 'Description' + Width = 200 + end + item + Caption = 'Driver ID' + Width = 70 + end + item + Caption = 'Host' + Width = 100 + end + item + Alignment = taCenter + Caption = 'User' + Width = 90 + end + item + Alignment = taCenter + Caption = 'Port' + Width = 60 + end + item + Caption = 'Database name' + Width = 200 + end + item + Caption = 'Password' + MaxWidth = 1 + Width = 1 + end + item + Caption = 'Guid' + MaxWidth = 1 + Width = 1 + end> + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Tahoma' + Font.Style = [] + ReadOnly = True + RowSelect = True + ParentFont = False + SortType = stText + TabOrder = 1 + ViewStyle = vsReport + OnColumnClick = ListViewColumnClick + OnDblClick = ListViewDblClick + OnKeyDown = ListViewKeyDown + OnSelectItem = ListViewSelectItem + ExplicitTop = 49 + end + object pnTop: TPanel + Left = 0 + Top = 0 + Width = 884 + Height = 50 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + BevelOuter = bvNone + TabOrder = 2 + object btnSearch: TButton + AlignWithMargins = True + Left = 799 + Top = 14 + Width = 75 + Height = 27 + Cursor = crHandPoint + Margins.Left = 2 + Margins.Top = 14 + Margins.Right = 10 + Margins.Bottom = 9 + Align = alRight + Caption = 'Search' + TabOrder = 0 + OnClick = btnSearchClick + end + object edtSearch: TEdit + AlignWithMargins = True + Left = 10 + Top = 15 + Width = 787 + Height = 25 + Margins.Left = 10 + Margins.Top = 15 + Margins.Right = 0 + Margins.Bottom = 10 + Align = alClient + AutoSize = False + TabOrder = 1 + OnKeyDown = edtSearchKeyDown + end + end + object StatusBar1: TStatusBar + Left = 0 + Top = 542 + Width = 884 + Height = 19 + Panels = < + item + Width = 50 + end + item + Width = 50 + end> + end +end diff --git a/Src/Databases/DelphiAIDev.Databases.View.pas b/Src/Databases/DelphiAIDev.Databases.View.pas new file mode 100644 index 0000000..a9219ee --- /dev/null +++ b/Src/Databases/DelphiAIDev.Databases.View.pas @@ -0,0 +1,359 @@ +unit DelphiAIDev.Databases.View; + +interface + +uses + Winapi.Windows, + System.SysUtils, + System.StrUtils, + System.Classes, + Vcl.Controls, + Vcl.Forms, + Vcl.StdCtrls, + Vcl.ExtCtrls, + Vcl.ComCtrls, + DelphiAIDev.Utils.ListView, + DelphiAIDev.Databases.Model, + DelphiAIDev.Databases.Fields; + //DelphiAIDev.Databases.AddEdit.View; + +type + TDelphiAIDevDatabasesView = class(TForm) + Panel1: TPanel; + btnEdit: TButton; + btnClose: TButton; + ListView: TListView; + pnTop: TPanel; + btnSearch: TButton; + edtSearch: TEdit; + StatusBar1: TStatusBar; + btnAdd: TButton; + btnRemove: TButton; + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure btnCloseClick(Sender: TObject); + procedure btnSearchClick(Sender: TObject); + procedure ListViewSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); + procedure ListViewDblClick(Sender: TObject); + procedure ListViewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure btnEditClick(Sender: TObject); + procedure btnAddClick(Sender: TObject); + procedure btnRemoveClick(Sender: TObject); + procedure edtSearchKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure ListViewColumnClick(Sender: TObject; Column: TListColumn); + private + FUtilsListView: IDelphiAIDevUtilsListView; + FMadeChanges: Boolean; + procedure ReloadData; + procedure ReloadDataInternal; + procedure FillStatusBar(AItem: TListItem); + procedure FillFieldsWithSelectedItem(var AFields: TDelphiAIDevDefaultsQuestionsFields); + public + property MadeChanges: Boolean read FMadeChanges; + end; + +implementation + +uses + DelphiAIDev.Utils, + DelphiAIDev.Utils.OTA, + DelphiAIDev.Types; + +{$R *.dfm} + +const + C_INDEX_SUBITEM_DriverId = 0; + C_INDEX_SUBITEM_Host = 1; + C_INDEX_SUBITEM_User = 2; + C_INDEX_SUBITEM_Port = 3; + C_INDEX_SUBITEM_DatabaseName = 4; + C_INDEX_SUBITEM_Password = 5; + C_INDEX_SUBITEM_Guid = 6; + +procedure TDelphiAIDevDatabasesView.FormCreate(Sender: TObject); +begin + TUtilsOTA.IDEThemingAll(TDelphiAIDevDatabasesView, Self); + FUtilsListView := TDelphiAIDevUtilsListView.New(ListView); +end; + +procedure TDelphiAIDevDatabasesView.FormShow(Sender: TObject); +begin + Self.ReloadData; + + if ListView.Items.Count > 0 then + ListView.Items.Item[0].Selected := True; + FMadeChanges := False; + edtSearch.SetFocus; + + FUtilsListView + .InvertOrder(False) + .SortStyle(TDelphiAIDevUtilsListViewSortStyle.Numeric) + .ColumnIndex(C_INDEX_SUBITEM_DatabaseName + 1) + .CustomSort; +end; + +procedure TDelphiAIDevDatabasesView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +begin + case Key of + VK_F4: + if ssAlt in Shift then + Key := 0; + VK_ESCAPE: + if Shift = [] then + btnClose.Click; + VK_DOWN, VK_UP: + begin + if ListView <> ActiveControl then + begin + case Key of + VK_DOWN: + if ListView.ItemIndex < Pred(ListView.Items.Count) then + ListView.ItemIndex := ListView.ItemIndex + 1; + VK_UP: + if ListView.ItemIndex > 0 then + ListView.ItemIndex := ListView.ItemIndex - 1; + end; + Key := 0; + end; + end; + end; +end; + +procedure TDelphiAIDevDatabasesView.btnCloseClick(Sender: TObject); +begin + Self.Close; +end; + +procedure TDelphiAIDevDatabasesView.edtSearchKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +begin + if Key = VK_RETURN then + Self.ReloadData; +end; + +procedure TDelphiAIDevDatabasesView.btnSearchClick(Sender: TObject); +begin + Screen.Cursor := crHourGlass; + try + Self.ReloadData; + finally + Screen.Cursor := crDefault; + end; +end; + +procedure TDelphiAIDevDatabasesView.ReloadData; +begin + Screen.Cursor := crHourGlass; + try + Self.ReloadDataInternal; + finally + Screen.Cursor := crDefault; + end; +end; + +procedure TDelphiAIDevDatabasesView.ReloadDataInternal; +var + LStrSearch: string; + LListItem: TListItem; + LGuid: string; +begin + LStrSearch := LowerCase(edtSearch.Text); + + if ListView.Selected <> nil then + LGuid := ListView.Items[ListView.Selected.Index].SubItems[C_INDEX_SUBITEM_Guid]; + + ListView.Clear; + + TDelphiAIDevDefaultsQuestionsModel.New.ReadData( + procedure(AFields: TDelphiAIDevDefaultsQuestionsFields) + begin + if AFields.Caption.Trim.IsEmpty then + Exit; + + if (AFields.Kind = TC4DQuestionKind.ItemMenuNormal) and (AFields.Question.Trim.IsEmpty) then + Exit; + + if(LStrSearch.Trim.IsEmpty) + or(AFields.Caption.ToLower.Contains(LStrSearch)) + or(AFields.Question.ToLower.Contains(LStrSearch)) + then + begin + LListItem := ListView.Items.Add; + LListItem.Caption := AFields.Caption; + LListItem.ImageIndex := -1; + LListItem.SubItems.Add(AFields.Kind.Tostring); + LListItem.SubItems.Add(AFields.Order.Tostring); + LListItem.SubItems.Add(TUtils.BoolToStrC4D(AFields.Visible)); + LListItem.SubItems.Add(TUtils.BoolToStrC4D(AFields.CodeOnly)); + LListItem.SubItems.Add(AFields.Guid); + LListItem.SubItems.Add(AFields.GuidMenuMaster); + LListItem.SubItems.Add(AFields.Question); + end; + end + ); + + FUtilsListView + .InvertOrder(False) + .CustomSort; + + if(not LGuid.Trim.IsEmpty)then + TUtils.FindListVewItem(ListView, C_INDEX_SUBITEM_Guid, LGuid); + + Self.FillStatusBar(ListView.Selected); +end; + +procedure TDelphiAIDevDatabasesView.ListViewSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); +begin + Self.FillStatusBar(Item); +end; + +procedure TDelphiAIDevDatabasesView.FillFieldsWithSelectedItem(var AFields: TDelphiAIDevDefaultsQuestionsFields); +var + LListItem: TListItem; +begin + AFields.Clear; + if(ListView.Selected = nil)then + Exit; + + LListItem := ListView.Items[ListView.Selected.Index]; + AFields.Guid := LListItem.SubItems[C_INDEX_SUBITEM_Guid]; + AFields.GuidMenuMaster := LListItem.SubItems[C_INDEX_SUBITEM_GuidMenuMaster]; + AFields.Caption := LListItem.Caption; + AFields.Kind := TUtils.StrToDefaultsQuestionsKind(LListItem.SubItems[C_INDEX_SUBITEM_Kind]); + AFields.Order := StrToIntDef(LListItem.SubItems[C_INDEX_SUBITEM_Order], 0); + AFields.Visible := TUtils.StrToBoolC4D(LListItem.SubItems[C_INDEX_SUBITEM_Visible]); + AFields.CodeOnly := TUtils.StrToBoolC4D(LListItem.SubItems[C_INDEX_SUBITEM_CodeOnly]); + AFields.Question := LListItem.SubItems[C_INDEX_SUBITEM_Question]; +end; + +procedure TDelphiAIDevDatabasesView.FillStatusBar(AItem: TListItem); +var + LIndex: Integer; + LQuestion: string; +begin + LIndex := -1; + LQuestion := ''; + if(AItem <> nil)then + begin + LIndex := AItem.Index; + LQuestion := ListView.Items[LIndex].SubItems[C_INDEX_SUBITEM_Question]; + end; + + StatusBar1.Panels[0].Text := Format('%d of %d', [LIndex + 1, ListView.Items.Count]); + StatusBar1.Panels[1].Text := LQuestion; +end; + +procedure TDelphiAIDevDatabasesView.ListViewColumnClick(Sender: TObject; Column: TListColumn); +var + LSortStyle: TDelphiAIDevUtilsListViewSortStyle; +begin + LSortStyle := TDelphiAIDevUtilsListViewSortStyle.AlphaNum; + case(Column.Index)of + C_INDEX_SUBITEM_Order + 1: + LSortStyle := TDelphiAIDevUtilsListViewSortStyle.Numeric; + end; + + FUtilsListView + .InvertOrder(True) + .SortStyle(LSortStyle) + .ColumnIndex(Column.Index) + .CustomSort; +end; + +procedure TDelphiAIDevDatabasesView.ListViewDblClick(Sender: TObject); +begin + btnEdit.Click +end; + +procedure TDelphiAIDevDatabasesView.ListViewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +begin + if Key = VK_RETURN then + btnEdit.Click +end; + +procedure TDelphiAIDevDatabasesView.btnAddClick(Sender: TObject); +var + LFields: TDelphiAIDevDefaultsQuestionsFields; + LView: TDelphiAIDevDefaultsQuestionsAddEditView; +begin + LFields := TDelphiAIDevDefaultsQuestionsFields.Create; + try + //LFields.Guid := ''; + LView := TDelphiAIDevDefaultsQuestionsAddEditView.Create(nil); + try + LView.Caption := string(LView.Caption).Replace('[action]', 'Adding', [rfReplaceAll, rfIgnoreCase]); + LView.Fields := LFields; + + if(LView.ShowModal <> mrOk)then + Exit; + + FMadeChanges := True; + finally + LView.Free; + end; + Self.ReloadData; + finally + LFields.Free; + end; +end; + +procedure TDelphiAIDevDatabasesView.btnEditClick(Sender: TObject); +var + LFields: TDelphiAIDevDefaultsQuestionsFields; + LView: TDelphiAIDevDefaultsQuestionsAddEditView; +begin + if(ListView.Selected = nil)then + Exit; + + LFields := TDelphiAIDevDefaultsQuestionsFields.Create; + try + Self.FillFieldsWithSelectedItem(LFields); + + if(LFields.Caption.Trim.IsEmpty)then + TUtils.ShowMsgErrorAndAbort('Caption not found'); + + LView := TDelphiAIDevDefaultsQuestionsAddEditView.Create(nil); + try + LView.Caption := string(LView.Caption).Replace('[action]', 'Editing', [rfReplaceAll, rfIgnoreCase]); + LView.Fields := LFields; + if(LView.ShowModal <> mrOk)then + Exit; + + FMadeChanges := True; + finally + LView.Free; + end; + Self.ReloadData; + finally + LFields.Free; + end; +end; + +procedure TDelphiAIDevDatabasesView.btnRemoveClick(Sender: TObject); +var + LGuid: string; +begin + if(ListView.Selected = nil)then + Exit; + + LGuid := ListView.Items[ListView.Selected.Index].SubItems[C_INDEX_SUBITEM_Guid]; + if(LGuid.Trim.IsEmpty)then + TUtils.ShowMsgErrorAndAbort('Guid not found'); + +// if(TC4DWizardOpenExternalModel.New.ExistGuidInIniFile(LId))then +// TUtils.ShowMsgAndAbort('This registration cannot be deleted, as it is linked to other registration(s)'); + + if(not TUtils.ShowQuestion2('Confirm remove?'))then + Exit; + + Screen.Cursor := crHourGlass; + try + TDelphiAIDevDefaultsQuestionsModel.New.RemoveData(LGuid); + Self.ReloadData; + finally + FMadeChanges := True; + Screen.Cursor := crDefault; + end; +end; + +end. diff --git a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas index b69f5c9..e842db1 100644 --- a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas +++ b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas @@ -108,7 +108,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.FormKeyDown(Sender: TObject; var Key begin case Key of VK_DOWN: - if(ListView.ItemIndex < Pred(ListView.Items.Count))then + if ListView.ItemIndex < Pred(ListView.Items.Count) then ListView.ItemIndex := ListView.ItemIndex + 1; VK_UP: if(ListView.ItemIndex > 0)then @@ -127,7 +127,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.btnCloseClick(Sender: TObject); procedure TDelphiAIDevDefaultsQuestionsView.edtSearchKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin - if(Key = VK_RETURN)then + if Key = VK_RETURN then Self.ReloadData; end; @@ -159,7 +159,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.ReloadDataInternal; begin LStrSearch := LowerCase(edtSearch.Text); - if(ListView.Selected <> nil)then + if ListView.Selected <> nil then LGuid := ListView.Items[ListView.Selected.Index].SubItems[C_INDEX_SUBITEM_Guid]; ListView.Clear; @@ -267,7 +267,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.ListViewDblClick(Sender: TObject); procedure TDelphiAIDevDefaultsQuestionsView.ListViewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin - if(Key = VK_RETURN)then + if Key = VK_RETURN then btnEdit.Click end; diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas index ac4f031..4d835a4 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas @@ -25,6 +25,7 @@ implementation DelphiAIDev.Utils.OTA, DelphiAIDev.Chat.View, DelphiAIDev.DefaultsQuestions.View, + DelphiAIDev.Databases.View, DelphiAIDev.Settings.View, DelphiAIDev.View.About; @@ -48,9 +49,9 @@ class procedure TDelphiAIDevIDEMainMenuClicks.DefaultsQuestionsClick(Sender: TOb class procedure TDelphiAIDevIDEMainMenuClicks.DatabasesClick(Sender: TObject); var - LView: TDelphiAIDevDefaultsQuestionsView; + LView: TDelphiAIDevDatabasesView; begin - LView := TDelphiAIDevDefaultsQuestionsView.Create(nil); + LView := TDelphiAIDevDatabasesView.Create(nil); try LView.ShowModal; finally diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index e119842..2cf42b1 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -20,6 +20,7 @@ interface TC4DButtons = (OK, OK_Cancel); TC4DBtnFocu = (OK, Cancel); TC4DQuestionKind = (None, ItemMenuNormal, MenuMasterOnly, Separators); + TC4DDriverID = (MySQL, Firebird); {$SCOPEDENUMS OFF} TC4DAIsAvailableHelper = record helper for TC4DAIsAvailable diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index cb19999..f53927d 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -79,6 +79,7 @@ TUtils = class //class function GetPathFileIniGeneralSettings: string; class function GetPathFileChat: string; class function GetPathFileJSONDefaultsQuestions: string; + class function GetPathFileJSONDatabases: string; class function CreateIfNecessaryAndGetPathFolderTemp: string; class function GetGuidStr: string; class function GuidToFileName(const AGuid: string; const AExtension: string): string; @@ -750,6 +751,11 @@ class function TUtils.GetPathFileJSONDefaultsQuestions: string; Result := Self.GetPathFolderRoot + TConsts.FILE_JSON_DEFAULTS_QUESTIONS; end; +class function TUtils.GetPathFileJSONDatabases: string; +begin + Result := Self.GetPathFolderRoot + TConsts.FILE_JSON_DATABASES; +end; + class function TUtils.CreateIfNecessaryAndGetPathFolderTemp: string; begin Result := Self.GetPathFolderRoot + TConsts.NAME_FOLDER_TEMP; From 08431a2d1dd8f85def69f096cf4738cd2c951ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 8 Aug 2024 02:40:28 -0300 Subject: [PATCH 004/109] Update DelphiAIDev.Databases.View.pas --- Src/Databases/DelphiAIDev.Databases.View.pas | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Src/Databases/DelphiAIDev.Databases.View.pas b/Src/Databases/DelphiAIDev.Databases.View.pas index a9219ee..9691140 100644 --- a/Src/Databases/DelphiAIDev.Databases.View.pas +++ b/Src/Databases/DelphiAIDev.Databases.View.pas @@ -48,7 +48,7 @@ TDelphiAIDevDatabasesView = class(TForm) procedure ReloadData; procedure ReloadDataInternal; procedure FillStatusBar(AItem: TListItem); - procedure FillFieldsWithSelectedItem(var AFields: TDelphiAIDevDefaultsQuestionsFields); + procedure FillFieldsWithSelectedItem(var AFields: TDelphiAIDevDatabasesFields); public property MadeChanges: Boolean read FMadeChanges; end; @@ -164,8 +164,8 @@ procedure TDelphiAIDevDatabasesView.ReloadDataInternal; ListView.Clear; - TDelphiAIDevDefaultsQuestionsModel.New.ReadData( - procedure(AFields: TDelphiAIDevDefaultsQuestionsFields) + TDelphiAIDevDatabasesModel.New.ReadData( + procedure(AFields: TDelphiAIDevDatabasesFields) begin if AFields.Caption.Trim.IsEmpty then Exit; @@ -207,7 +207,7 @@ procedure TDelphiAIDevDatabasesView.ListViewSelectItem(Sender: TObject; Item: TL Self.FillStatusBar(Item); end; -procedure TDelphiAIDevDatabasesView.FillFieldsWithSelectedItem(var AFields: TDelphiAIDevDefaultsQuestionsFields); +procedure TDelphiAIDevDatabasesView.FillFieldsWithSelectedItem(var AFields: TDelphiAIDevDatabasesFields); var LListItem: TListItem; begin @@ -219,7 +219,7 @@ procedure TDelphiAIDevDatabasesView.FillFieldsWithSelectedItem(var AFields: TDel AFields.Guid := LListItem.SubItems[C_INDEX_SUBITEM_Guid]; AFields.GuidMenuMaster := LListItem.SubItems[C_INDEX_SUBITEM_GuidMenuMaster]; AFields.Caption := LListItem.Caption; - AFields.Kind := TUtils.StrToDefaultsQuestionsKind(LListItem.SubItems[C_INDEX_SUBITEM_Kind]); + AFields.Kind := TUtils.StrToDatabasesKind(LListItem.SubItems[C_INDEX_SUBITEM_Kind]); AFields.Order := StrToIntDef(LListItem.SubItems[C_INDEX_SUBITEM_Order], 0); AFields.Visible := TUtils.StrToBoolC4D(LListItem.SubItems[C_INDEX_SUBITEM_Visible]); AFields.CodeOnly := TUtils.StrToBoolC4D(LListItem.SubItems[C_INDEX_SUBITEM_CodeOnly]); @@ -273,13 +273,13 @@ procedure TDelphiAIDevDatabasesView.ListViewKeyDown(Sender: TObject; var Key: Wo procedure TDelphiAIDevDatabasesView.btnAddClick(Sender: TObject); var - LFields: TDelphiAIDevDefaultsQuestionsFields; - LView: TDelphiAIDevDefaultsQuestionsAddEditView; + LFields: TDelphiAIDevDatabasesFields; + LView: TDelphiAIDevDatabasesAddEditView; begin - LFields := TDelphiAIDevDefaultsQuestionsFields.Create; + LFields := TDelphiAIDevDatabasesFields.Create; try //LFields.Guid := ''; - LView := TDelphiAIDevDefaultsQuestionsAddEditView.Create(nil); + LView := TDelphiAIDevDatabasesAddEditView.Create(nil); try LView.Caption := string(LView.Caption).Replace('[action]', 'Adding', [rfReplaceAll, rfIgnoreCase]); LView.Fields := LFields; @@ -299,20 +299,20 @@ procedure TDelphiAIDevDatabasesView.btnAddClick(Sender: TObject); procedure TDelphiAIDevDatabasesView.btnEditClick(Sender: TObject); var - LFields: TDelphiAIDevDefaultsQuestionsFields; - LView: TDelphiAIDevDefaultsQuestionsAddEditView; + LFields: TDelphiAIDevDatabasesFields; + LView: TDelphiAIDevDatabasesAddEditView; begin if(ListView.Selected = nil)then Exit; - LFields := TDelphiAIDevDefaultsQuestionsFields.Create; + LFields := TDelphiAIDevDatabasesFields.Create; try Self.FillFieldsWithSelectedItem(LFields); if(LFields.Caption.Trim.IsEmpty)then TUtils.ShowMsgErrorAndAbort('Caption not found'); - LView := TDelphiAIDevDefaultsQuestionsAddEditView.Create(nil); + LView := TDelphiAIDevDatabasesAddEditView.Create(nil); try LView.Caption := string(LView.Caption).Replace('[action]', 'Editing', [rfReplaceAll, rfIgnoreCase]); LView.Fields := LFields; @@ -348,7 +348,7 @@ procedure TDelphiAIDevDatabasesView.btnRemoveClick(Sender: TObject); Screen.Cursor := crHourGlass; try - TDelphiAIDevDefaultsQuestionsModel.New.RemoveData(LGuid); + TDelphiAIDevDatabasesModel.New.RemoveData(LGuid); Self.ReloadData; finally FMadeChanges := True; From 66702238d8a6b39f764d2ec8eda403bbc6917b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 9 Aug 2024 01:03:13 -0300 Subject: [PATCH 005/109] bk/2024-08-09-0103 --- Src/Databases/DelphiAIDev.Databases.View.dfm | 6 +- Src/Databases/DelphiAIDev.Databases.View.pas | 152 +++++++++--------- ...hiAIDev.DefaultsQuestions.AddEdit.View.pas | 2 +- .../DelphiAIDev.DefaultsQuestions.View.pas | 22 +-- Src/Types/DelphiAIDev.Types.pas | 17 +- Src/Utils/DelphiAIDev.Utils.pas | 9 ++ 6 files changed, 118 insertions(+), 90 deletions(-) diff --git a/Src/Databases/DelphiAIDev.Databases.View.dfm b/Src/Databases/DelphiAIDev.Databases.View.dfm index ca0c060..08a71ac 100644 --- a/Src/Databases/DelphiAIDev.Databases.View.dfm +++ b/Src/Databases/DelphiAIDev.Databases.View.dfm @@ -131,6 +131,11 @@ object DelphiAIDevDatabasesView: TDelphiAIDevDatabasesView Caption = 'Database name' Width = 200 end + item + Alignment = taCenter + Caption = 'Visible' + Width = 45 + end item Caption = 'Password' MaxWidth = 1 @@ -156,7 +161,6 @@ object DelphiAIDevDatabasesView: TDelphiAIDevDatabasesView OnDblClick = ListViewDblClick OnKeyDown = ListViewKeyDown OnSelectItem = ListViewSelectItem - ExplicitTop = 49 end object pnTop: TPanel Left = 0 diff --git a/Src/Databases/DelphiAIDev.Databases.View.pas b/Src/Databases/DelphiAIDev.Databases.View.pas index 9691140..d03f810 100644 --- a/Src/Databases/DelphiAIDev.Databases.View.pas +++ b/Src/Databases/DelphiAIDev.Databases.View.pas @@ -68,8 +68,9 @@ implementation C_INDEX_SUBITEM_User = 2; C_INDEX_SUBITEM_Port = 3; C_INDEX_SUBITEM_DatabaseName = 4; - C_INDEX_SUBITEM_Password = 5; - C_INDEX_SUBITEM_Guid = 6; + C_INDEX_SUBITEM_Visible = 5; + C_INDEX_SUBITEM_Password = 6; + C_INDEX_SUBITEM_Guid = 7; procedure TDelphiAIDevDatabasesView.FormCreate(Sender: TObject); begin @@ -88,7 +89,7 @@ procedure TDelphiAIDevDatabasesView.FormShow(Sender: TObject); FUtilsListView .InvertOrder(False) - .SortStyle(TDelphiAIDevUtilsListViewSortStyle.Numeric) + .SortStyle(TDelphiAIDevUtilsListViewSortStyle.AlphaNum) .ColumnIndex(C_INDEX_SUBITEM_DatabaseName + 1) .CustomSort; end; @@ -167,27 +168,29 @@ procedure TDelphiAIDevDatabasesView.ReloadDataInternal; TDelphiAIDevDatabasesModel.New.ReadData( procedure(AFields: TDelphiAIDevDatabasesFields) begin - if AFields.Caption.Trim.IsEmpty then + if AFields.Description.Trim.IsEmpty then Exit; - if (AFields.Kind = TC4DQuestionKind.ItemMenuNormal) and (AFields.Question.Trim.IsEmpty) then - Exit; + //if (AFields.Kind = TC4DQuestionKind.ItemMenuNormal) and (AFields.Question.Trim.IsEmpty) then + // Exit; if(LStrSearch.Trim.IsEmpty) - or(AFields.Caption.ToLower.Contains(LStrSearch)) - or(AFields.Question.ToLower.Contains(LStrSearch)) + or(AFields.Description.ToLower.Contains(LStrSearch)) + or(AFields.Host.ToLower.Contains(LStrSearch)) + or(AFields.DatabaseName.ToLower.Contains(LStrSearch)) then begin LListItem := ListView.Items.Add; - LListItem.Caption := AFields.Caption; + LListItem.Caption := AFields.Description; LListItem.ImageIndex := -1; - LListItem.SubItems.Add(AFields.Kind.Tostring); - LListItem.SubItems.Add(AFields.Order.Tostring); + LListItem.SubItems.Add(AFields.DriverID.ToString); + LListItem.SubItems.Add(AFields.Host); + LListItem.SubItems.Add(AFields.User); + LListItem.SubItems.Add(AFields.Port.ToString); + LListItem.SubItems.Add(AFields.DatabaseName); LListItem.SubItems.Add(TUtils.BoolToStrC4D(AFields.Visible)); - LListItem.SubItems.Add(TUtils.BoolToStrC4D(AFields.CodeOnly)); + LListItem.SubItems.Add(AFields.Password); LListItem.SubItems.Add(AFields.Guid); - LListItem.SubItems.Add(AFields.GuidMenuMaster); - LListItem.SubItems.Add(AFields.Question); end; end ); @@ -212,18 +215,19 @@ procedure TDelphiAIDevDatabasesView.FillFieldsWithSelectedItem(var AFields: TDel LListItem: TListItem; begin AFields.Clear; - if(ListView.Selected = nil)then + if ListView.Selected = nil then Exit; LListItem := ListView.Items[ListView.Selected.Index]; - AFields.Guid := LListItem.SubItems[C_INDEX_SUBITEM_Guid]; - AFields.GuidMenuMaster := LListItem.SubItems[C_INDEX_SUBITEM_GuidMenuMaster]; - AFields.Caption := LListItem.Caption; - AFields.Kind := TUtils.StrToDatabasesKind(LListItem.SubItems[C_INDEX_SUBITEM_Kind]); - AFields.Order := StrToIntDef(LListItem.SubItems[C_INDEX_SUBITEM_Order], 0); + AFields.Description := LListItem.Caption; + AFields.DriverID := TUtils.StrToDriverID(LListItem.SubItems[C_INDEX_SUBITEM_DriverId]); + AFields.Host := LListItem.SubItems[C_INDEX_SUBITEM_Host]; + AFields.User := LListItem.SubItems[C_INDEX_SUBITEM_User]; + AFields.Port := StrToIntDef(LListItem.SubItems[C_INDEX_SUBITEM_Port], 0); + AFields.DatabaseName := LListItem.SubItems[C_INDEX_SUBITEM_DatabaseName]; AFields.Visible := TUtils.StrToBoolC4D(LListItem.SubItems[C_INDEX_SUBITEM_Visible]); - AFields.CodeOnly := TUtils.StrToBoolC4D(LListItem.SubItems[C_INDEX_SUBITEM_CodeOnly]); - AFields.Question := LListItem.SubItems[C_INDEX_SUBITEM_Question]; + AFields.Password := LListItem.SubItems[C_INDEX_SUBITEM_Password]; + AFields.Guid := LListItem.SubItems[C_INDEX_SUBITEM_Guid]; end; procedure TDelphiAIDevDatabasesView.FillStatusBar(AItem: TListItem); @@ -233,10 +237,10 @@ procedure TDelphiAIDevDatabasesView.FillStatusBar(AItem: TListItem); begin LIndex := -1; LQuestion := ''; - if(AItem <> nil)then + if AItem <> nil then begin LIndex := AItem.Index; - LQuestion := ListView.Items[LIndex].SubItems[C_INDEX_SUBITEM_Question]; + LQuestion := ListView.Items[LIndex].SubItems[C_INDEX_SUBITEM_DatabaseName]; end; StatusBar1.Panels[0].Text := Format('%d of %d', [LIndex + 1, ListView.Items.Count]); @@ -248,9 +252,9 @@ procedure TDelphiAIDevDatabasesView.ListViewColumnClick(Sender: TObject; Column: LSortStyle: TDelphiAIDevUtilsListViewSortStyle; begin LSortStyle := TDelphiAIDevUtilsListViewSortStyle.AlphaNum; - case(Column.Index)of - C_INDEX_SUBITEM_Order + 1: - LSortStyle := TDelphiAIDevUtilsListViewSortStyle.Numeric; + case Column.Index of + C_INDEX_SUBITEM_Port + 1: + LSortStyle := TDelphiAIDevUtilsListViewSortStyle.Numeric; end; FUtilsListView @@ -274,76 +278,76 @@ procedure TDelphiAIDevDatabasesView.ListViewKeyDown(Sender: TObject; var Key: Wo procedure TDelphiAIDevDatabasesView.btnAddClick(Sender: TObject); var LFields: TDelphiAIDevDatabasesFields; - LView: TDelphiAIDevDatabasesAddEditView; + //LView: TDelphiAIDevDatabasesAddEditView; begin - LFields := TDelphiAIDevDatabasesFields.Create; - try - //LFields.Guid := ''; - LView := TDelphiAIDevDatabasesAddEditView.Create(nil); - try - LView.Caption := string(LView.Caption).Replace('[action]', 'Adding', [rfReplaceAll, rfIgnoreCase]); - LView.Fields := LFields; - - if(LView.ShowModal <> mrOk)then - Exit; - - FMadeChanges := True; - finally - LView.Free; - end; - Self.ReloadData; - finally - LFields.Free; - end; +// LFields := TDelphiAIDevDatabasesFields.Create; +// try +// //LFields.Guid := ''; +// LView := TDelphiAIDevDatabasesAddEditView.Create(nil); +// try +// LView.Caption := string(LView.Caption).Replace('[action]', 'Adding', [rfReplaceAll, rfIgnoreCase]); +// LView.Fields := LFields; +// +// if LView.ShowModal <> mrOk then +// Exit; +// +// FMadeChanges := True; +// finally +// LView.Free; +// end; +// Self.ReloadData; +// finally +// LFields.Free; +// end; end; procedure TDelphiAIDevDatabasesView.btnEditClick(Sender: TObject); var LFields: TDelphiAIDevDatabasesFields; - LView: TDelphiAIDevDatabasesAddEditView; + //LView: TDelphiAIDevDatabasesAddEditView; begin - if(ListView.Selected = nil)then + if ListView.Selected = nil then Exit; - LFields := TDelphiAIDevDatabasesFields.Create; - try - Self.FillFieldsWithSelectedItem(LFields); - - if(LFields.Caption.Trim.IsEmpty)then - TUtils.ShowMsgErrorAndAbort('Caption not found'); - - LView := TDelphiAIDevDatabasesAddEditView.Create(nil); - try - LView.Caption := string(LView.Caption).Replace('[action]', 'Editing', [rfReplaceAll, rfIgnoreCase]); - LView.Fields := LFields; - if(LView.ShowModal <> mrOk)then - Exit; - - FMadeChanges := True; - finally - LView.Free; - end; - Self.ReloadData; - finally - LFields.Free; - end; +// LFields := TDelphiAIDevDatabasesFields.Create; +// try +// Self.FillFieldsWithSelectedItem(LFields); +// +// if LFields.Caption.Trim.IsEmpty then +// TUtils.ShowMsgErrorAndAbort('Caption not found'); +// +// LView := TDelphiAIDevDatabasesAddEditView.Create(nil); +// try +// LView.Caption := string(LView.Caption).Replace('[action]', 'Editing', [rfReplaceAll, rfIgnoreCase]); +// LView.Fields := LFields; +// if LView.ShowModal <> mrOk then +// Exit; +// +// FMadeChanges := True; +// finally +// LView.Free; +// end; +// Self.ReloadData; +// finally +// LFields.Free; +// end; end; procedure TDelphiAIDevDatabasesView.btnRemoveClick(Sender: TObject); var LGuid: string; begin - if(ListView.Selected = nil)then + if ListView.Selected = nil then Exit; LGuid := ListView.Items[ListView.Selected.Index].SubItems[C_INDEX_SUBITEM_Guid]; - if(LGuid.Trim.IsEmpty)then + if LGuid.Trim.IsEmpty then TUtils.ShowMsgErrorAndAbort('Guid not found'); // if(TC4DWizardOpenExternalModel.New.ExistGuidInIniFile(LId))then // TUtils.ShowMsgAndAbort('This registration cannot be deleted, as it is linked to other registration(s)'); - if(not TUtils.ShowQuestion2('Confirm remove?'))then + if not TUtils.ShowQuestion2('Confirm remove?') then Exit; Screen.Cursor := crHourGlass; diff --git a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas index 8b41b12..49bd0cc 100644 --- a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas +++ b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas @@ -94,7 +94,7 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.FormShow(Sender: TObject); cBoxKind.ItemIndex := cBoxKind.Items.IndexOf(FFields.Kind.ToString); edtCaption.Text := FFields.Caption; mmQuestion.Lines.Text := FFields.Question; - edtOrder.Text := FFields.Order.Tostring; + edtOrder.Text := FFields.Order.ToString; ckVisible.Checked := FFields.Visible; ckCodeOnly.Checked := FFields.CodeOnly; diff --git a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas index e842db1..170cd82 100644 --- a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas +++ b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas @@ -81,7 +81,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.FormShow(Sender: TObject); begin Self.ReloadData; - if(ListView.Items.Count > 0)then + if ListView.Items.Count > 0 then ListView.Items.Item[0].Selected := True; FMadeChanges := False; edtSearch.SetFocus; @@ -111,7 +111,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.FormKeyDown(Sender: TObject; var Key if ListView.ItemIndex < Pred(ListView.Items.Count) then ListView.ItemIndex := ListView.ItemIndex + 1; VK_UP: - if(ListView.ItemIndex > 0)then + if ListView.ItemIndex > 0 then ListView.ItemIndex := ListView.ItemIndex - 1; end; Key := 0; @@ -212,7 +212,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.FillFieldsWithSelectedItem(var AFiel LListItem: TListItem; begin AFields.Clear; - if(ListView.Selected = nil)then + if ListView.Selected = nil then Exit; LListItem := ListView.Items[ListView.Selected.Index]; @@ -233,7 +233,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.FillStatusBar(AItem: TListItem); begin LIndex := -1; LQuestion := ''; - if(AItem <> nil)then + if AItem <> nil then begin LIndex := AItem.Index; LQuestion := ListView.Items[LIndex].SubItems[C_INDEX_SUBITEM_Question]; @@ -248,7 +248,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.ListViewColumnClick(Sender: TObject; LSortStyle: TDelphiAIDevUtilsListViewSortStyle; begin LSortStyle := TDelphiAIDevUtilsListViewSortStyle.AlphaNum; - case(Column.Index)of + case Column.Index of C_INDEX_SUBITEM_Order + 1: LSortStyle := TDelphiAIDevUtilsListViewSortStyle.Numeric; end; @@ -284,7 +284,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.btnAddClick(Sender: TObject); LView.Caption := string(LView.Caption).Replace('[action]', 'Adding', [rfReplaceAll, rfIgnoreCase]); LView.Fields := LFields; - if(LView.ShowModal <> mrOk)then + if LView.ShowModal <> mrOk then Exit; FMadeChanges := True; @@ -302,21 +302,21 @@ procedure TDelphiAIDevDefaultsQuestionsView.btnEditClick(Sender: TObject); LFields: TDelphiAIDevDefaultsQuestionsFields; LView: TDelphiAIDevDefaultsQuestionsAddEditView; begin - if(ListView.Selected = nil)then + if ListView.Selected = nil then Exit; LFields := TDelphiAIDevDefaultsQuestionsFields.Create; try Self.FillFieldsWithSelectedItem(LFields); - if(LFields.Caption.Trim.IsEmpty)then + if LFields.Caption.Trim.IsEmpty then TUtils.ShowMsgErrorAndAbort('Caption not found'); LView := TDelphiAIDevDefaultsQuestionsAddEditView.Create(nil); try LView.Caption := string(LView.Caption).Replace('[action]', 'Editing', [rfReplaceAll, rfIgnoreCase]); LView.Fields := LFields; - if(LView.ShowModal <> mrOk)then + if LView.ShowModal <> mrOk then Exit; FMadeChanges := True; @@ -333,7 +333,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.btnRemoveClick(Sender: TObject); var LGuid: string; begin - if(ListView.Selected = nil)then + if ListView.Selected = nil then Exit; LGuid := ListView.Items[ListView.Selected.Index].SubItems[C_INDEX_SUBITEM_Guid]; @@ -343,7 +343,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.btnRemoveClick(Sender: TObject); // if(TC4DWizardOpenExternalModel.New.ExistGuidInIniFile(LId))then // TUtils.ShowMsgAndAbort('This registration cannot be deleted, as it is linked to other registration(s)'); - if(not TUtils.ShowQuestion2('Confirm remove?'))then + if not TUtils.ShowQuestion2('Confirm remove?') then Exit; Screen.Cursor := crHourGlass; diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index 2cf42b1..722c7fc 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -52,6 +52,10 @@ TC4DQuestionKindHelper = record helper for TC4DQuestionKind function ToString: string; end; + TC4DDriverIDHelper = record helper for TC4DDriverID + function ToString: string; + end; + implementation uses @@ -171,14 +175,21 @@ function TC4DExtensionsCommonHelper.ToStringWithPoint: string; { TC4DQuestionKindHelper } function TC4DQuestionKindHelper.ToString: string; begin - if(Self = TC4DQuestionKind.ItemMenuNormal)then + if Self = TC4DQuestionKind.ItemMenuNormal then Exit('Item menu normal') - else if(Self = TC4DQuestionKind.MenuMasterOnly)then + else if Self = TC4DQuestionKind.MenuMasterOnly then Exit('Menu master only') - else if(Self = TC4DQuestionKind.Separators)then + else if Self = TC4DQuestionKind.Separators then Exit('Separator') else Result := GetEnumName(TypeInfo(TC4DQuestionKind), Integer(Self)); end; +{ TC4DDriverIDHelper } + +function TC4DDriverIDHelper.ToString: string; +begin + Result := GetEnumName(TypeInfo(TC4DDriverID), Integer(Self)); +end; + end. diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index f53927d..6b7f84a 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -29,6 +29,7 @@ TUtils = class public class function GetExceptionMessage(const E: Exception): string; class function StrToDefaultsQuestionsKind(Value: string): TC4DQuestionKind; + class function StrToDriverID(Value: string): TC4DDriverID; class procedure DefaultsQuestionsKindFillItemsTStrings(AStrings: TStrings); class function AdjustQuestionToJson(const AValue: string): string; class procedure AddLog(const AMessage: string); @@ -166,6 +167,14 @@ class function TUtils.StrToDefaultsQuestionsKind(Value: string): TC4DQuestionKin Result := TC4DQuestionKind.Separators; end; +class function TUtils.StrToDriverID(Value: string): TC4DDriverID; +begin + Result := TC4DDriverID.MySQL; + if Value = 'Firebird' then + Result := TC4DDriverID.Firebird +end; + + class procedure TUtils.DefaultsQuestionsKindFillItemsTStrings(AStrings: TStrings); var LItem: TC4DQuestionKind; From 07db5732b3ba11f51835c5d8e128c67db17845d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Sat, 10 Aug 2024 00:03:49 -0300 Subject: [PATCH 006/109] bk/2024-08-10-0003 --- Package/DelphiAIDeveloper.dpk | 6 +- Package/DelphiAIDeveloper.dproj | 11 +- .../DelphiAIDev.Databases.AddEdit.View.dfm | 268 ++++++++++++++++++ .../DelphiAIDev.Databases.AddEdit.View.pas | 176 ++++++++++++ .../DelphiAIDev.Databases.Fields.pas | 5 +- Src/Databases/DelphiAIDev.Databases.Model.pas | 9 +- Src/Databases/DelphiAIDev.Databases.View.dfm | 5 + Src/Databases/DelphiAIDev.Databases.View.pas | 97 ++++--- ...hiAIDev.DefaultsQuestions.AddEdit.View.dfm | 1 - ...hiAIDev.DefaultsQuestions.AddEdit.View.pas | 48 ++-- Src/Types/DelphiAIDev.Types.pas | 2 +- Src/Utils/DelphiAIDev.Utils.Crypt.pas | 43 +++ Src/Utils/DelphiAIDev.Utils.pas | 35 +-- 13 files changed, 607 insertions(+), 99 deletions(-) create mode 100644 Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm create mode 100644 Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas create mode 100644 Src/Utils/DelphiAIDev.Utils.Crypt.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 65f2289..828bdff 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -69,7 +69,7 @@ contains DelphiAIDev.DefaultsQuestions.Fields in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.Fields.pas', DelphiAIDev.DefaultsQuestions.Interfaces in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.Interfaces.pas', DelphiAIDev.DefaultsQuestions.Model in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.Model.pas', - DelphiAIDev.DefaultsQuestions.AddEdit.View in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.AddEdit.View.pas' {DelphiAIDevDefaultsQuestionsAddEditView}, + DelphiAIDev.Databases.AddEdit.View in '..\Src\Databases\DelphiAIDev.Databases.AddEdit.View.pas' {DelphiAIDevDatabasesAddEditView}, DelphiAIDev.DefaultsQuestions.PopupMenu in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.PopupMenu.pas', DelphiAIDev.Utils.ABMenuAction in '..\Src\Utils\DelphiAIDev.Utils.ABMenuAction.pas', DelphiAIDev.IDE.Splash in '..\Src\IDE\Splash\DelphiAIDev.IDE.Splash.pas', @@ -80,6 +80,8 @@ contains DelphiAIDev.DefaultsQuestions.View in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.View.pas' {DelphiAIDevDefaultsQuestionsView}, DelphiAIDev.Databases.Model in '..\Src\Databases\DelphiAIDev.Databases.Model.pas', DelphiAIDev.Databases.Interfaces in '..\Src\Databases\DelphiAIDev.Databases.Interfaces.pas', - DelphiAIDev.Databases.Fields in '..\Src\Databases\DelphiAIDev.Databases.Fields.pas'; + DelphiAIDev.Databases.Fields in '..\Src\Databases\DelphiAIDev.Databases.Fields.pas', + DelphiAIDev.DefaultsQuestions.AddEdit.View in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.AddEdit.View.pas' {DelphiAIDevDefaultsQuestionsAddEditView}, + DelphiAIDev.Utils.Crypt in '..\Src\Utils\DelphiAIDev.Utils.Crypt.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 0c75582..56cf2ba 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -67,7 +67,7 @@ System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) All DelphiAIDeveloper - modules\.dcp;modules\.dcu;modules;modules\restrequest4delphi\src;$(DCC_UnitSearchPath) + modules\.dcp;modules\.dcu;modules;modules\bcrypt\src;modules\restrequest4delphi\src;$(DCC_UnitSearchPath) 1046 CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= @@ -172,8 +172,8 @@ - -
DelphiAIDevDefaultsQuestionsAddEditView
+ +
DelphiAIDevDatabasesAddEditView
dfm
@@ -190,6 +190,11 @@ + +
DelphiAIDevDefaultsQuestionsAddEditView
+ dfm +
+ BITMAP c4d_gear diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm new file mode 100644 index 0000000..0d495b2 --- /dev/null +++ b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm @@ -0,0 +1,268 @@ +object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu] + Caption = 'IA Developer - Databases - [action]' + ClientHeight = 307 + ClientWidth = 657 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + KeyPreview = True + OldCreateOrder = False + Position = poScreenCenter + OnCreate = FormCreate + OnKeyDown = FormKeyDown + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object Bevel2: TBevel + AlignWithMargins = True + Left = 0 + Top = 268 + Width = 657 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alBottom + Shape = bsTopLine + ExplicitLeft = -5 + ExplicitTop = 476 + ExplicitWidth = 676 + end + object Panel1: TPanel + Left = 0 + Top = 272 + Width = 657 + Height = 35 + Align = alBottom + BevelEdges = [beLeft, beRight, beBottom] + BevelOuter = bvNone + Padding.Left = 2 + Padding.Top = 2 + Padding.Right = 2 + Padding.Bottom = 2 + ParentBackground = False + TabOrder = 1 + ExplicitTop = 282 + object btnConfirm: TButton + AlignWithMargins = True + Left = 429 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alRight + Caption = 'Confirm' + TabOrder = 0 + OnClick = btnConfirmClick + end + object btnClose: TButton + AlignWithMargins = True + Left = 542 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alRight + Caption = 'Close' + TabOrder = 1 + OnClick = btnCloseClick + end + object btnTestConnection: TButton + AlignWithMargins = True + Left = 2 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alLeft + Caption = 'Test Connection' + TabOrder = 2 + OnClick = btnTestConnectionClick + ExplicitLeft = 429 + end + end + object Panel9: TPanel + Left = 0 + Top = 0 + Width = 657 + Height = 268 + Align = alClient + BevelOuter = bvNone + ParentBackground = False + TabOrder = 0 + ExplicitHeight = 279 + object Bevel1: TBevel + AlignWithMargins = True + Left = 0 + Top = 264 + Width = 657 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alBottom + Shape = bsTopLine + ExplicitTop = 444 + ExplicitWidth = 676 + end + object Label2: TLabel + Left = 31 + Top = 25 + Width = 43 + Height = 13 + Caption = 'Driver ID' + end + object Label3: TLabel + Left = 31 + Top = 71 + Width = 53 + Height = 13 + Caption = 'Description' + end + object Label1: TLabel + Left = 234 + Top = 71 + Width = 22 + Height = 13 + Caption = 'Host' + end + object Label5: TLabel + Left = 437 + Top = 71 + Width = 22 + Height = 13 + Caption = 'User' + end + object Label6: TLabel + Left = 31 + Top = 120 + Width = 46 + Height = 13 + Caption = 'Password' + end + object Label7: TLabel + Left = 234 + Top = 120 + Width = 20 + Height = 13 + Caption = 'Port' + end + object Label4: TLabel + Left = 437 + Top = 120 + Width = 46 + Height = 13 + Caption = 'Database' + end + object Label8: TLabel + Left = 31 + Top = 168 + Width = 47 + Height = 13 + Caption = 'VendorLib' + end + object lbAddLocalDatabase: TLabel + Left = 262 + Top = 71 + Width = 99 + Height = 13 + Cursor = crHandPoint + Caption = '[Add local database]' + OnClick = lbAddLocalDatabaseClick + end + object cBoxDriverID: TComboBox + Left = 31 + Top = 41 + Width = 200 + Height = 21 + Style = csDropDownList + TabOrder = 0 + end + object edtDescription: TEdit + Left = 31 + Top = 87 + Width = 200 + Height = 21 + TabOrder = 1 + end + object edtHost: TEdit + Left = 234 + Top = 87 + Width = 200 + Height = 21 + TabOrder = 2 + end + object edtUser: TEdit + Left = 437 + Top = 87 + Width = 200 + Height = 21 + TabOrder = 3 + end + object edtPassword: TEdit + Left = 31 + Top = 136 + Width = 164 + Height = 21 + PasswordChar = '*' + TabOrder = 4 + end + object edtPort: TEdit + Left = 234 + Top = 136 + Width = 200 + Height = 21 + NumbersOnly = True + TabOrder = 5 + end + object edtDatabase: TEdit + Left = 437 + Top = 136 + Width = 200 + Height = 21 + TabOrder = 6 + end + object edtVendorLib: TEdit + Left = 31 + Top = 184 + Width = 606 + Height = 21 + PasswordChar = '*' + TabOrder = 7 + end + object ckVisible: TCheckBox + Left = 31 + Top = 216 + Width = 53 + Height = 17 + Cursor = crHandPoint + Caption = 'Visible' + TabOrder = 8 + end + object Button1: TButton + Left = 197 + Top = 135 + Width = 34 + Height = 23 + Cursor = crHandPoint + Caption = 'View' + TabOrder = 9 + OnClick = Button1Click + end + end +end diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas new file mode 100644 index 0000000..3cf4a46 --- /dev/null +++ b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas @@ -0,0 +1,176 @@ +unit DelphiAIDev.Databases.AddEdit.View; + +interface + +uses + Winapi.Windows, + System.SysUtils, + System.Classes, + Vcl.Controls, + Vcl.Forms, + Vcl.StdCtrls, + Vcl.ExtCtrls, + Vcl.Menus, + Vcl.ComCtrls, + DelphiAIDev.Types, + DelphiAIDev.Databases.Fields; + +type + TDelphiAIDevDatabasesAddEditView = class(TForm) + Panel1: TPanel; + btnConfirm: TButton; + btnClose: TButton; + Panel9: TPanel; + Bevel1: TBevel; + Bevel2: TBevel; + Label2: TLabel; + cBoxDriverID: TComboBox; + Label3: TLabel; + edtDescription: TEdit; + Label1: TLabel; + edtHost: TEdit; + Label5: TLabel; + edtUser: TEdit; + Label6: TLabel; + edtPassword: TEdit; + Label7: TLabel; + edtPort: TEdit; + Label4: TLabel; + edtDatabase: TEdit; + Label8: TLabel; + edtVendorLib: TEdit; + ckVisible: TCheckBox; + lbAddLocalDatabase: TLabel; + Button1: TButton; + btnTestConnection: TButton; + procedure btnCloseClick(Sender: TObject); + procedure btnConfirmClick(Sender: TObject); + procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure FormShow(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure lbAddLocalDatabaseClick(Sender: TObject); + procedure Button1Click(Sender: TObject); + procedure btnTestConnectionClick(Sender: TObject); + private + FFields: TDelphiAIDevDatabasesFields; + procedure FillcBoxDriverID; + procedure FillScreenFields; + public + property Fields: TDelphiAIDevDatabasesFields read FFields write FFields; + end; + +implementation + +uses + DelphiAIDev.Consts, + DelphiAIDev.Utils, + DelphiAIDev.Utils.OTA, + DelphiAIDev.DataBases.Model; + +{$R *.dfm} + +procedure TDelphiAIDevDatabasesAddEditView.FillcBoxDriverID; +begin + cBoxDriverID.Items.Clear; + TUtils.DriverIDFillItemsTStrings(cBoxDriverID.Items); +end; + +procedure TDelphiAIDevDatabasesAddEditView.FormCreate(Sender: TObject); +begin + Self.ModalResult := mrCancel; + TUtilsOTA.IDEThemingAll(TDelphiAIDevDatabasesAddEditView, Self); + Self.FillcBoxDriverID; +end; + +procedure TDelphiAIDevDatabasesAddEditView.FormShow(Sender: TObject); +begin + Self.FillScreenFields; + edtDescription.SetFocus +end; + +procedure TDelphiAIDevDatabasesAddEditView.lbAddLocalDatabaseClick(Sender: TObject); +begin + edtHost.Text := 'localhost'; +end; + +procedure TDelphiAIDevDatabasesAddEditView.FillScreenFields; +begin + cBoxDriverID.ItemIndex := cBoxDriverID.Items.IndexOf(FFields.DriverID.ToString); + edtDescription.Text := FFields.Description; + edtHost.Text := FFields.Host; + edtUser.Text := FFields.User; + edtPassword.Text := FFields.Password; + edtPort.Text := FFields.Port.ToString; + edtDatabase.Text := FFields.DatabaseName; + edtVendorLib.Text := FFields.VendorLib; + ckVisible.Checked := FFields.Visible; +end; + +procedure TDelphiAIDevDatabasesAddEditView.btnCloseClick(Sender: TObject); +begin + Self.Close; + Self.ModalResult := mrCancel; +end; + +procedure TDelphiAIDevDatabasesAddEditView.btnConfirmClick(Sender: TObject); +begin + if cBoxDriverID.ItemIndex < 0 then + TUtils.ShowMsgAndAbort('No informed Driver ID', cBoxDriverID); + + if TUtils.StrToDriverID(cBoxDriverID.Text) = TC4DDriverID.None then + TUtils.ShowMsgAndAbort('Select a DriverID', cBoxDriverID); + + if Trim(edtDescription.Text).IsEmpty then + TUtils.ShowMsgAndAbort('No informed Description', edtDescription); + + if Trim(edtHost.Text).IsEmpty then + TUtils.ShowMsgAndAbort('No informed Host', edtHost); + + if Trim(edtUser.Text).IsEmpty then + TUtils.ShowMsgAndAbort('No informed User', edtUser); + + if Trim(edtDatabase.Text).IsEmpty then + TUtils.ShowMsgAndAbort('No informed Database', edtDatabase); + + FFields.DriverID := TUtils.StrToDriverID(cBoxDriverID.Text); + FFields.Description := edtDescription.Text; + FFields.Host := edtHost.Text; + FFields.User := edtUser.Text; + FFields.Password := edtPassword.Text; + FFields.Port := StrToIntDef(edtPort.Text, 0); + FFields.DatabaseName := edtDatabase.Text; + FFields.VendorLib := edtVendorLib.Text; + FFields.Visible := ckVisible.Checked; + + TDelphiAIDevDatabasesModel.New.SaveOrEditData(FFields); + + Self.Close; + Self.ModalResult := mrOK; +end; + +procedure TDelphiAIDevDatabasesAddEditView.Button1Click(Sender: TObject); +begin + if edtPassword.PasswordChar = '*' then + edtPassword.PasswordChar := #0 + else + edtPassword.PasswordChar := '*'; +end; + +procedure TDelphiAIDevDatabasesAddEditView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +begin + case Key of + VK_F4: + if ssAlt in Shift then + Key := 0; + VK_ESCAPE: + if Shift = [] then + btnClose.Click; + end; +end; + +procedure TDelphiAIDevDatabasesAddEditView.btnTestConnectionClick(Sender: TObject); +begin + // +end; + +end. diff --git a/Src/Databases/DelphiAIDev.Databases.Fields.pas b/Src/Databases/DelphiAIDev.Databases.Fields.pas index df1054e..a36b196 100644 --- a/Src/Databases/DelphiAIDev.Databases.Fields.pas +++ b/Src/Databases/DelphiAIDev.Databases.Fields.pas @@ -17,6 +17,7 @@ TDelphiAIDevDatabasesFields = class FPort: Integer; FDatabaseName: string; FVisible: Boolean; + FVendorLib: string; public constructor Create; procedure Clear; @@ -30,6 +31,7 @@ TDelphiAIDevDatabasesFields = class property Port: Integer read FPort write FPort; property DatabaseName: string read FDatabaseName write FDatabaseName; property Visible: Boolean read FVisible write FVisible; + property VendorLib: string read FVendorLib write FVendorLib; end; implementation @@ -42,7 +44,7 @@ constructor TDelphiAIDevDatabasesFields.Create; procedure TDelphiAIDevDatabasesFields.Clear; begin FGuid := ''; - FDriverID := TC4DDriverID.MySQL; + FDriverID := TC4DDriverID.None; FDescription := ''; FHost := ''; FUser := ''; @@ -50,6 +52,7 @@ procedure TDelphiAIDevDatabasesFields.Clear; FPort := 0; FDatabaseName := ''; FVisible := True; + FVendorLib := ''; end; end. diff --git a/Src/Databases/DelphiAIDev.Databases.Model.pas b/Src/Databases/DelphiAIDev.Databases.Model.pas index cb69c6b..915e5ec 100644 --- a/Src/Databases/DelphiAIDev.Databases.Model.pas +++ b/Src/Databases/DelphiAIDev.Databases.Model.pas @@ -10,7 +10,8 @@ interface DelphiAIDev.Utils, DelphiAIDev.Types, DelphiAIDev.Databases.Interfaces, - DelphiAIDev.Databases.Fields; + DelphiAIDev.Databases.Fields, + DelphiAIDev.Utils.Crypt; type TDelphiAIDevDatabasesModel = class(TInterfacedObject, IDelphiAIDevDatabasesModel) @@ -85,7 +86,7 @@ procedure TDelphiAIDevDatabasesModel.ReadData(AProc: TProc(DESCRIPTION); LFields.Host := LJSONObjItem.GetValue(HOST); LFields.User := LJSONObjItem.GetValue(USER); - LFields.Password := LJSONObjItem.GetValue(PASSWORD); + LFields.Password := TUtilsCrypt.Decrypt(LJSONObjItem.GetValue(PASSWORD)); LFields.Port := LJSONObjItem.GetValue(PORT); LFields.DatabaseName := LJSONObjItem.GetValue(DATABASE_NAME); LFields.Visible := LJSONObjItem.GetValue(VISIBLE); @@ -129,7 +130,7 @@ procedure TDelphiAIDevDatabasesModel.SaveData(const AFields: TDelphiAIDevDatabas LJSONObject.AddPair(DESCRIPTION, AFields.Description); LJSONObject.AddPair(HOST, AFields.Host); LJSONObject.AddPair(USER, AFields.User); - LJSONObject.AddPair(PASSWORD, AFields.Password); + LJSONObject.AddPair(PASSWORD, TUtilsCrypt.Encrypt(AFields.Password)); LJSONObject.AddPair(PORT, TJSONNumber.Create(AFields.Port)); LJSONObject.AddPair(DATABASE_NAME, AFields.DatabaseName); LJSONObject.AddPair(VISIBLE, TJSONBool.Create(AFields.Visible)); @@ -189,7 +190,7 @@ procedure TDelphiAIDevDatabasesModel.EditData(const AFields: TDelphiAIDevDatabas LJSONObjItem.AddPair(USER, AFields.User); LJSONObjItem.RemovePair(PASSWORD).Free; - LJSONObjItem.AddPair(PASSWORD, AFields.Password); + LJSONObjItem.AddPair(PASSWORD, TUtilsCrypt.Encrypt(AFields.Password)); LJSONObjItem.RemovePair(PORT).Free; LJSONObjItem.AddPair(PORT, TJSONNumber.Create(AFields.Port)); diff --git a/Src/Databases/DelphiAIDev.Databases.View.dfm b/Src/Databases/DelphiAIDev.Databases.View.dfm index 08a71ac..9b5e435 100644 --- a/Src/Databases/DelphiAIDev.Databases.View.dfm +++ b/Src/Databases/DelphiAIDev.Databases.View.dfm @@ -145,6 +145,11 @@ object DelphiAIDevDatabasesView: TDelphiAIDevDatabasesView Caption = 'Guid' MaxWidth = 1 Width = 1 + end + item + Caption = 'VendorLib' + MaxWidth = 1 + Width = 1 end> Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText diff --git a/Src/Databases/DelphiAIDev.Databases.View.pas b/Src/Databases/DelphiAIDev.Databases.View.pas index d03f810..0418ee5 100644 --- a/Src/Databases/DelphiAIDev.Databases.View.pas +++ b/Src/Databases/DelphiAIDev.Databases.View.pas @@ -14,8 +14,8 @@ interface Vcl.ComCtrls, DelphiAIDev.Utils.ListView, DelphiAIDev.Databases.Model, - DelphiAIDev.Databases.Fields; - //DelphiAIDev.Databases.AddEdit.View; + DelphiAIDev.Databases.Fields, + DelphiAIDev.Databases.AddEdit.View; type TDelphiAIDevDatabasesView = class(TForm) @@ -233,18 +233,18 @@ procedure TDelphiAIDevDatabasesView.FillFieldsWithSelectedItem(var AFields: TDel procedure TDelphiAIDevDatabasesView.FillStatusBar(AItem: TListItem); var LIndex: Integer; - LQuestion: string; + LDatabaseName: string; begin LIndex := -1; - LQuestion := ''; + LDatabaseName := ''; if AItem <> nil then begin LIndex := AItem.Index; - LQuestion := ListView.Items[LIndex].SubItems[C_INDEX_SUBITEM_DatabaseName]; + LDatabaseName := ListView.Items[LIndex].SubItems[C_INDEX_SUBITEM_DatabaseName]; end; StatusBar1.Panels[0].Text := Format('%d of %d', [LIndex + 1, ListView.Items.Count]); - StatusBar1.Panels[1].Text := LQuestion; + StatusBar1.Panels[1].Text := LDatabaseName; end; procedure TDelphiAIDevDatabasesView.ListViewColumnClick(Sender: TObject; Column: TListColumn); @@ -278,59 +278,58 @@ procedure TDelphiAIDevDatabasesView.ListViewKeyDown(Sender: TObject; var Key: Wo procedure TDelphiAIDevDatabasesView.btnAddClick(Sender: TObject); var LFields: TDelphiAIDevDatabasesFields; - //LView: TDelphiAIDevDatabasesAddEditView; + LView: TDelphiAIDevDatabasesAddEditView; begin -// LFields := TDelphiAIDevDatabasesFields.Create; -// try -// //LFields.Guid := ''; -// LView := TDelphiAIDevDatabasesAddEditView.Create(nil); -// try -// LView.Caption := string(LView.Caption).Replace('[action]', 'Adding', [rfReplaceAll, rfIgnoreCase]); -// LView.Fields := LFields; -// -// if LView.ShowModal <> mrOk then -// Exit; -// -// FMadeChanges := True; -// finally -// LView.Free; -// end; -// Self.ReloadData; -// finally -// LFields.Free; -// end; + LFields := TDelphiAIDevDatabasesFields.Create; + try + LView := TDelphiAIDevDatabasesAddEditView.Create(nil); + try + LView.Caption := string(LView.Caption).Replace('[action]', 'Adding', [rfReplaceAll, rfIgnoreCase]); + LView.Fields := LFields; + + if LView.ShowModal <> mrOk then + Exit; + + FMadeChanges := True; + finally + LView.Free; + end; + Self.ReloadData; + finally + LFields.Free; + end; end; procedure TDelphiAIDevDatabasesView.btnEditClick(Sender: TObject); var LFields: TDelphiAIDevDatabasesFields; - //LView: TDelphiAIDevDatabasesAddEditView; + LView: TDelphiAIDevDatabasesAddEditView; begin if ListView.Selected = nil then Exit; -// LFields := TDelphiAIDevDatabasesFields.Create; -// try -// Self.FillFieldsWithSelectedItem(LFields); -// -// if LFields.Caption.Trim.IsEmpty then -// TUtils.ShowMsgErrorAndAbort('Caption not found'); -// -// LView := TDelphiAIDevDatabasesAddEditView.Create(nil); -// try -// LView.Caption := string(LView.Caption).Replace('[action]', 'Editing', [rfReplaceAll, rfIgnoreCase]); -// LView.Fields := LFields; -// if LView.ShowModal <> mrOk then -// Exit; -// -// FMadeChanges := True; -// finally -// LView.Free; -// end; -// Self.ReloadData; -// finally -// LFields.Free; -// end; + LFields := TDelphiAIDevDatabasesFields.Create; + try + Self.FillFieldsWithSelectedItem(LFields); + + if LFields.Description.Trim.IsEmpty then + TUtils.ShowMsgErrorAndAbort('Caption not found'); + + LView := TDelphiAIDevDatabasesAddEditView.Create(nil); + try + LView.Caption := string(LView.Caption).Replace('[action]', 'Editing', [rfReplaceAll, rfIgnoreCase]); + LView.Fields := LFields; + if LView.ShowModal <> mrOk then + Exit; + + FMadeChanges := True; + finally + LView.Free; + end; + Self.ReloadData; + finally + LFields.Free; + end; end; procedure TDelphiAIDevDatabasesView.btnRemoveClick(Sender: TObject); diff --git a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.dfm b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.dfm index fd3cdd7..b659efd 100644 --- a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.dfm +++ b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.dfm @@ -89,7 +89,6 @@ object DelphiAIDevDefaultsQuestionsAddEditView: TDelphiAIDevDefaultsQuestionsAdd BevelOuter = bvNone ParentBackground = False TabOrder = 0 - ExplicitTop = -2 DesignSize = ( 674 350) diff --git a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas index 49bd0cc..8ab81dd 100644 --- a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas +++ b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas @@ -52,6 +52,7 @@ TDelphiAIDevDefaultsQuestionsAddEditView = class(TForm) procedure MenuMasterLoad; procedure MenuMasterClear; procedure ConfFieldsKind; + procedure FillScreenFields; public property Fields: TDelphiAIDevDefaultsQuestionsFields read FFields write FFields; end; @@ -91,12 +92,7 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.FormDestroy(Sender: TObject); procedure TDelphiAIDevDefaultsQuestionsAddEditView.FormShow(Sender: TObject); begin - cBoxKind.ItemIndex := cBoxKind.Items.IndexOf(FFields.Kind.ToString); - edtCaption.Text := FFields.Caption; - mmQuestion.Lines.Text := FFields.Question; - edtOrder.Text := FFields.Order.ToString; - ckVisible.Checked := FFields.Visible; - ckCodeOnly.Checked := FFields.CodeOnly; + Self.FillScreenFields; Self.ConfFieldsKind; Self.MenuMasterLoad; @@ -106,6 +102,16 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.FormShow(Sender: TObject); cBoxKind.SetFocus; end; +procedure TDelphiAIDevDefaultsQuestionsAddEditView.FillScreenFields; +begin + cBoxKind.ItemIndex := cBoxKind.Items.IndexOf(FFields.Kind.ToString); + edtCaption.Text := FFields.Caption; + mmQuestion.Lines.Text := FFields.Question; + edtOrder.Text := FFields.Order.ToString; + ckVisible.Checked := FFields.Visible; + ckCodeOnly.Checked := FFields.CodeOnly; +end; + procedure TDelphiAIDevDefaultsQuestionsAddEditView.MenuMasterClear; var I: Integer; @@ -134,7 +140,7 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.MenuMasterLoad; LFields: TDelphiAIDevDefaultsQuestionsFields; LItemIndex: Integer; begin - if(AFields.Kind <> TC4DQuestionKind.MenuMasterOnly)then + if AFields.Kind <> TC4DQuestionKind.MenuMasterOnly then Exit; LFields := TDelphiAIDevDefaultsQuestionsFields.Create; @@ -145,7 +151,7 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.MenuMasterLoad; //if (FFields.IdParent > 0)and(FFields.IdParent = LFields.IdParent) then // LItemIndexDefault := LItemIndex; - if(FFields.GuidMenuMaster = LFields.Guid)then + if FFields.GuidMenuMaster = LFields.Guid then LItemIndexDefault := LItemIndex; end ); @@ -161,13 +167,13 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.btnCloseClick(Sender: TObject procedure TDelphiAIDevDefaultsQuestionsAddEditView.btnConfirmClick(Sender: TObject); begin - if(cBoxKind.ItemIndex <= 0)then + if cBoxKind.ItemIndex <= 0 then TUtils.ShowMsgAndAbort('No informed Kind', cBoxKind); if Trim(edtCaption.Text).IsEmpty then TUtils.ShowMsgAndAbort('No informed Caption', edtCaption); - if (mmQuestion.Enabled) and (Trim(mmQuestion.Lines.Text).IsEmpty )then + if (mmQuestion.Enabled) and (Trim(mmQuestion.Lines.Text).IsEmpty)then TUtils.ShowMsgAndAbort('No informed Question', mmQuestion); FFields.Kind := TUtils.StrToDefaultsQuestionsKind(cBoxKind.Text); @@ -178,8 +184,8 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.btnConfirmClick(Sender: TObje FFields.CodeOnly := ckCodeOnly.Checked; FFields.GuidMenuMaster := ''; - if(cBoxMenuMaster.ItemIndex >= 0)then - if(TDelphiAIDevDefaultsQuestionsFields(cBoxMenuMaster.Items.Objects[cBoxMenuMaster.ItemIndex]) <> nil)then + if cBoxMenuMaster.ItemIndex >= 0 then + if TDelphiAIDevDefaultsQuestionsFields(cBoxMenuMaster.Items.Objects[cBoxMenuMaster.ItemIndex]) <> nil then FFields.GuidMenuMaster := TDelphiAIDevDefaultsQuestionsFields(cBoxMenuMaster.Items.Objects[cBoxMenuMaster.ItemIndex]).Guid; TDelphiAIDevDefaultsQuestionsModel.New.SaveOrEditData(FFields); @@ -199,7 +205,7 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.ConfFieldsKind; mmQuestion.Enabled := True; cBoxMenuMaster.Enabled := True; - if(cBoxKind.Text = TC4DQuestionKind.Separators.ToString)then + if cBoxKind.Text = TC4DQuestionKind.Separators.ToString then begin FLastCaption := edtCaption.Text; edtCaption.Text := '-'; @@ -209,7 +215,7 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.ConfFieldsKind; mmQuestion.Lines.Clear; mmQuestion.Enabled := False; end - else if(cBoxKind.Text = TC4DQuestionKind.MenuMasterOnly.ToString)then + else if cBoxKind.Text = TC4DQuestionKind.MenuMasterOnly.ToString then begin if(edtCaption.Text = '-')and(not FLastCaption.Trim.IsEmpty)then edtCaption.Text := FLastCaption; @@ -231,22 +237,20 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.ConfFieldsKind; mmQuestion.Text := FLastQuestion; end; - if(cBoxKind.Text <> TC4DQuestionKind.MenuMasterOnly.ToString)then - begin - if(cBoxMenuMaster.ItemIndex <= 0)then + if cBoxKind.Text <> TC4DQuestionKind.MenuMasterOnly.ToString then + if cBoxMenuMaster.ItemIndex <= 0 then cBoxMenuMaster.ItemIndex := FLastItemIndexMenuMaster; - end; end; procedure TDelphiAIDevDefaultsQuestionsAddEditView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of VK_F4: - if ssAlt in Shift then - Key := 0; + if ssAlt in Shift then + Key := 0; VK_ESCAPE: - if Shift = [] then - btnClose.Click; + if Shift = [] then + btnClose.Click; end; end; diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index 722c7fc..020bc8b 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -20,7 +20,7 @@ interface TC4DButtons = (OK, OK_Cancel); TC4DBtnFocu = (OK, Cancel); TC4DQuestionKind = (None, ItemMenuNormal, MenuMasterOnly, Separators); - TC4DDriverID = (MySQL, Firebird); + TC4DDriverID = (None, MySQL, Firebird); {$SCOPEDENUMS OFF} TC4DAIsAvailableHelper = record helper for TC4DAIsAvailable diff --git a/Src/Utils/DelphiAIDev.Utils.Crypt.pas b/Src/Utils/DelphiAIDev.Utils.Crypt.pas new file mode 100644 index 0000000..d57b65e --- /dev/null +++ b/Src/Utils/DelphiAIDev.Utils.Crypt.pas @@ -0,0 +1,43 @@ +unit DelphiAIDev.Utils.Crypt; + +interface + +uses + System.SysUtils; + +type + TUtilsCrypt = class + public + class function Decrypt(Value: string): string; + class function Encrypt(Value: string): string; + end; + +implementation + +const + SEQUENCE01 = '1234567890ABCDEFGHIJLMNOPQRSTUVXZWYKabcdefghijlmnopqrstuvxzwyk'; + SEQUENCE02 = '2wqVR03ILHNYMvu6qip9EmsJKb4yl7tvQ1FdPZgOc8nXTzjokxBDSU5fhAGW'; + +class function TUtilsCrypt.Encrypt(Value: string): string; +var + i: Integer; +begin + for i := 1 to Length(Value)do + if Pos(Value[i], SEQUENCE01) <> 0 then + Value[i] := SEQUENCE02[Pos(Value[i], SEQUENCE01)]; + + Result := Value; +end; + +class function TUtilsCrypt.Decrypt(Value: string): string; +var + i: Integer; +begin + for i := 1 to Length(Value) do + if Pos(Value[i], SEQUENCE02) <> 0 then + Value[i] := SEQUENCE01[Pos(Value[i], SEQUENCE02)]; + + Result := Value; +end; + +end. diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 6b7f84a..a4c5a82 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -30,6 +30,7 @@ TUtils = class class function GetExceptionMessage(const E: Exception): string; class function StrToDefaultsQuestionsKind(Value: string): TC4DQuestionKind; class function StrToDriverID(Value: string): TC4DDriverID; + class procedure DriverIDFillItemsTStrings(AStrings: TStrings); class procedure DefaultsQuestionsKindFillItemsTStrings(AStrings: TStrings); class function AdjustQuestionToJson(const AValue: string): string; class procedure AddLog(const AMessage: string); @@ -139,16 +140,6 @@ implementation DelphiAIDev.View.Dialog, DelphiAIDev.WaitingScreen; -//Winapi.WinInet -//class function TUtils.TestInternetConnection: Boolean; -//var -// LFlags: DWord; -//begin -// Result := InternetGetConnectedState(@LFlags, 0); -// if Result then -// Result := InternetCheckConnection('http://google.com', 1, 0); -//end; - class function TUtils.GetExceptionMessage(const E: Exception): string; begin Result := E.Message; @@ -167,22 +158,34 @@ class function TUtils.StrToDefaultsQuestionsKind(Value: string): TC4DQuestionKin Result := TC4DQuestionKind.Separators; end; +class procedure TUtils.DefaultsQuestionsKindFillItemsTStrings(AStrings: TStrings); +var + LItem: TC4DQuestionKind; +begin + if AStrings = nil then + Exit; + + for LItem := Low(TC4DQuestionKind) to High(TC4DQuestionKind) do + AStrings.Add(LItem.ToString); +end; + class function TUtils.StrToDriverID(Value: string): TC4DDriverID; begin - Result := TC4DDriverID.MySQL; - if Value = 'Firebird' then + Result := TC4DDriverID.None; + if Value = TC4DDriverID.MySQL.ToString then + Result := TC4DDriverID.MySQL + else if Value = TC4DDriverID.Firebird.ToString then Result := TC4DDriverID.Firebird end; - -class procedure TUtils.DefaultsQuestionsKindFillItemsTStrings(AStrings: TStrings); +class procedure TUtils.DriverIDFillItemsTStrings(AStrings: TStrings); var - LItem: TC4DQuestionKind; + LItem: TC4DDriverID; begin if AStrings = nil then Exit; - for LItem := Low(TC4DQuestionKind) to High(TC4DQuestionKind) do + for LItem := Low(TC4DDriverID) to High(TC4DDriverID) do AStrings.Add(LItem.ToString); end; From 8bb8e7ea079753af90548f3458eadc9b72a1514c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Sat, 10 Aug 2024 02:55:35 -0300 Subject: [PATCH 007/109] bk/2024-08-10-0255 --- Package/DelphiAIDeveloper.dpk | 16 +- Package/DelphiAIDeveloper.dproj | 12 + Src/Conn/C4D.Conn.Configs.pas | 193 ++++++++ Src/Conn/C4D.Conn.Firedac.Query.pas | 420 +++++++++++++++++ Src/Conn/C4D.Conn.Firedac.pas | 188 ++++++++ Src/Conn/C4D.Conn.Interfaces.pas | 81 ++++ Src/Conn/C4D.Conn.Types.pas | 12 + Src/Conn/C4D.Conn.Utils.pas | 57 +++ Src/Conn/C4D.Conn.Zeos.Query.pas | 427 ++++++++++++++++++ Src/Conn/C4D.Conn.Zeos.pas | 160 +++++++ Src/Conn/C4D.Conn.pas | 130 ++++++ .../DelphiAIDev.Databases.AddEdit.View.dfm | 95 ++-- .../DelphiAIDev.Databases.AddEdit.View.pas | 85 +++- .../DelphiAIDev.Databases.Fields.pas | 1 - .../DelphiAIDev.Databases.Interfaces.pas | 2 +- Src/Databases/DelphiAIDev.Databases.Model.pas | 13 +- Src/Types/DelphiAIDev.Types.pas | 9 + Src/Utils/DelphiAIDev.Utils.Crypt.pas | 2 +- 18 files changed, 1824 insertions(+), 79 deletions(-) create mode 100644 Src/Conn/C4D.Conn.Configs.pas create mode 100644 Src/Conn/C4D.Conn.Firedac.Query.pas create mode 100644 Src/Conn/C4D.Conn.Firedac.pas create mode 100644 Src/Conn/C4D.Conn.Interfaces.pas create mode 100644 Src/Conn/C4D.Conn.Types.pas create mode 100644 Src/Conn/C4D.Conn.Utils.pas create mode 100644 Src/Conn/C4D.Conn.Zeos.Query.pas create mode 100644 Src/Conn/C4D.Conn.Zeos.pas create mode 100644 Src/Conn/C4D.Conn.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 828bdff..a9a1fb6 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -32,7 +32,12 @@ package DelphiAIDeveloper; requires rtl, designide, - RESTComponents; + RESTComponents, + vclFireDAC, + FireDAC, + FireDACCommonDriver, + FireDACCommon, + FireDACMySQLDriver; contains DelphiAIDev.Register in '..\Src\DelphiAIDev.Register.pas', @@ -82,6 +87,13 @@ contains DelphiAIDev.Databases.Interfaces in '..\Src\Databases\DelphiAIDev.Databases.Interfaces.pas', DelphiAIDev.Databases.Fields in '..\Src\Databases\DelphiAIDev.Databases.Fields.pas', DelphiAIDev.DefaultsQuestions.AddEdit.View in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.AddEdit.View.pas' {DelphiAIDevDefaultsQuestionsAddEditView}, - DelphiAIDev.Utils.Crypt in '..\Src\Utils\DelphiAIDev.Utils.Crypt.pas'; + DelphiAIDev.Utils.Crypt in '..\Src\Utils\DelphiAIDev.Utils.Crypt.pas', + C4D.Conn.Types in '..\Src\Conn\C4D.Conn.Types.pas', + C4D.Conn.Configs in '..\Src\Conn\C4D.Conn.Configs.pas', + C4D.Conn.Firedac in '..\Src\Conn\C4D.Conn.Firedac.pas', + C4D.Conn.Firedac.Query in '..\Src\Conn\C4D.Conn.Firedac.Query.pas', + C4D.Conn.Interfaces in '..\Src\Conn\C4D.Conn.Interfaces.pas', + C4D.Conn in '..\Src\Conn\C4D.Conn.pas', + C4D.Conn.Utils in '..\Src\Conn\C4D.Conn.Utils.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 56cf2ba..b9ed77d 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -122,6 +122,11 @@ + + + + +
DelphiAIDevChatView
@@ -195,6 +200,13 @@ dfm
+ + + + + + + BITMAP c4d_gear diff --git a/Src/Conn/C4D.Conn.Configs.pas b/Src/Conn/C4D.Conn.Configs.pas new file mode 100644 index 0000000..c25ddee --- /dev/null +++ b/Src/Conn/C4D.Conn.Configs.pas @@ -0,0 +1,193 @@ +unit C4D.Conn.Configs; + +interface + +uses + System.SysUtils, + System.Classes, + C4D.Conn.Types, + DelphiAIDev.Types; + +type + TC4DConnConfigs = class + private + FComponentConnection: TComponentConnection; + FConnectionSingleton: Boolean; + FDriverID: TC4DDriverID; + FHost: string; + FUserName: string; + FPassword: string; + FDatabase: string; + FPort: Integer; + FVendorLib: string; + public + constructor Create; + destructor Destroy; override; + function ComponentConnection: TComponentConnection; + function ConnectionSingleton: Boolean; + function ConnectionSingletonON: TC4DConnConfigs; + function ConnectionSingletonOFF: TC4DConnConfigs; + function DriverID: TC4DDriverID; overload; + function DriverID(Value: TC4DDriverID): TC4DConnConfigs; overload; + function Host: string; overload; + function Host(Value: string): TC4DConnConfigs; overload; + function UserName: string; overload; + function UserName(Value: string): TC4DConnConfigs; overload; + function Password: string; overload; + function Password(Value: string): TC4DConnConfigs; overload; + function Database: string; overload; + function Database(Value: string): TC4DConnConfigs; overload; + function Port: Integer; overload; + function Port(Value: Integer): TC4DConnConfigs; overload; + function VendorLib: string; overload; + function VendorLib(Value: string): TC4DConnConfigs; overload; + function TestFieldFilling: TC4DConnConfigs; + end; + +implementation + +constructor TC4DConnConfigs.Create; +begin + FConnectionSingleton := True; + + {$IFDEF C4D_ZEOS} + FComponentConnection := TComponentConnection.Zeos; + {$ELSE} + FComponentConnection := TComponentConnection.FireDac; + {$ENDIF} +end; + +destructor TC4DConnConfigs.Destroy; +begin + inherited; +end; + +function TC4DConnConfigs.ComponentConnection: TComponentConnection; +begin + if FComponentConnection = TComponentConnection.Empty then + raise Exception.Create('Component for connection to the bank not informed'); + + Result := FComponentConnection; +end; + +function TC4DConnConfigs.ConnectionSingleton: Boolean; +begin + Result := FConnectionSingleton; +end; + +function TC4DConnConfigs.ConnectionSingletonON: TC4DConnConfigs; +begin + Result := Self; + FConnectionSingleton := True; +end; + +function TC4DConnConfigs.ConnectionSingletonOFF: TC4DConnConfigs; +begin + Result := Self; + FConnectionSingleton := False; +end; + +function TC4DConnConfigs.DriverID: TC4DDriverID; +begin + Result := FDriverID; +end; + +function TC4DConnConfigs.DriverID(Value: TC4DDriverID): TC4DConnConfigs; +begin + Result := Self; + FDriverID := Value; +end; + +function TC4DConnConfigs.Host: string; +begin + Result := FHost; +end; + +function TC4DConnConfigs.Host(Value: string): TC4DConnConfigs; +begin + Result := Self; + FHost := Value; +end; + +function TC4DConnConfigs.UserName: string; +begin + Result := FUserName; +end; + +function TC4DConnConfigs.UserName(Value: string): TC4DConnConfigs; +begin + Result := Self; + FUserName := Value; +end; + +function TC4DConnConfigs.Password: string; +begin + Result := FPassword; +end; + +function TC4DConnConfigs.Password(Value: string): TC4DConnConfigs; +begin + Result := Self; + FPassword := Value; +end; + +function TC4DConnConfigs.Database: string; +begin + Result := FDatabase; +end; + +function TC4DConnConfigs.Database(Value: string): TC4DConnConfigs; +begin + Result := Self; + FDatabase := Value; +end; + +function TC4DConnConfigs.Port: Integer; +begin + Result := FPort; +end; + +function TC4DConnConfigs.Port(Value: Integer): TC4DConnConfigs; +begin + Result := Self; + FPort := Value; +end; + +function TC4DConnConfigs.VendorLib: string; +begin + Result := FVendorLib; +end; + +function TC4DConnConfigs.VendorLib(Value: string): TC4DConnConfigs; +begin + Result := Self; + FVendorLib := Value; +end; + +function TC4DConnConfigs.TestFieldFilling: TC4DConnConfigs; +var + LTemp: string; +begin + Result := Self; + LTemp := ''; + + if FDriverID = TC4DDriverID.None then + LTemp := LTemp + 'Driver ID. '; + + if FHost.Trim.IsEmpty then + LTemp := LTemp + 'Host. '; + + if FUserName.Trim.IsEmpty then + LTemp := LTemp + 'User. '; + + if FPassword.Trim.IsEmpty then + LTemp := LTemp + 'Password. '; + + if FDatabase.Trim.IsEmpty then + LTemp := LTemp + 'Database name.'; + + if not LTemp.Trim.IsEmpty then + raise Exception.Create('To connect to the database, the following data must be filled in: ' + LTemp); +end; + +end. diff --git a/Src/Conn/C4D.Conn.Firedac.Query.pas b/Src/Conn/C4D.Conn.Firedac.Query.pas new file mode 100644 index 0000000..a5c0c93 --- /dev/null +++ b/Src/Conn/C4D.Conn.Firedac.Query.pas @@ -0,0 +1,420 @@ +unit C4D.Conn.Firedac.Query; + +interface + +uses + System.SysUtils, + System.StrUtils, + System.Classes, + System.Generics.Collections, + Data.DB, + Firedac.Stan.Intf, + Firedac.Stan.Option, + Firedac.Stan.Param, + Firedac.Stan.Error, + Firedac.DatS, + Firedac.Phys.Intf, + Firedac.DApt.Intf, + Firedac.Stan.Async, + Firedac.DApt, + Firedac.Comp.DataSet, + Firedac.Comp.Client, + Firedac.Stan.Def, + C4D.Conn.Interfaces, + C4D.Conn.Firedac, + C4D.Conn.Utils; + +type + TC4DConnFiredacQuery = class(TInterfacedObject, IC4DConnQuery) + private + FC4DConnection: IC4DConnection; + FQuery: TFDQuery; + FListCond: TStringList; + FListCondParam: TDictionary; + FListGroup: TStringList; + FListOrder: TStringList; + FListLimit: TStringList; + procedure ProcessaListCond; + procedure ProcessaListGroup; + procedure ProcessaListOrder; + procedure ProcessListLimit; + protected + function Close: IC4DConnQuery; + function Clear: IC4DConnQuery; + function CloseClear: IC4DConnQuery; + function Add(Value: string): IC4DConnQuery; + function AddParam(Param: string; Value: Variant): IC4DConnQuery; + function AddCond(ACond: string): IC4DConnQuery; + function AddCondParam(Param: string; Value: Variant): IC4DConnQuery; + function AddGroup(ACond: string): IC4DConnQuery; + function AddOrder(ACond: string): IC4DConnQuery; + function AddLimit(ACond: string): IC4DConnQuery; + function Text(Value: string): IC4DConnQuery; + function SQL: TStrings; + function ExecSQL: IC4DConnQuery; overload; + function ExecSQL(const ASQL: string): IC4DConnQuery; overload; + function Open: IC4DConnQuery; overload; + function Open(const ASQL: string): IC4DConnQuery; overload; + + function DataSet: TDataSet; + function DataSource(Value: TDataSource): IC4DConnQuery; + function DataSourceMasterDetail(Value: TDataSource): IC4DConnQuery; + + function Append: IC4DConnQuery; + function Edit: IC4DConnQuery; + function Post: IC4DConnQuery; + function Delete: IC4DConnQuery; + + function Eof: Boolean; + function Bof: Boolean; + function Prior: IC4DConnQuery; + function Next: IC4DConnQuery; + function First: IC4DConnQuery; + function Last: IC4DConnQuery; + function IsEmpty: Boolean; + function RowsAffected: Integer; + function FieldByName(Value: string): TField; + function RecNo: Integer; + function RecordCount: Integer; + function RecordCountStr(pNumZerosLeft: Integer = 6): string; + function GetLastAutoGenValue(const AName: string): Variant; + public + class function New(AC4DConnection: IC4DConnection; ANameQuery: string): IC4DConnQuery; + constructor Create(AC4DConnection: IC4DConnection; ANameQuery: string); + destructor Destroy; override; + end; + +implementation + +class function TC4DConnFiredacQuery.New(AC4DConnection: IC4DConnection; ANameQuery: string): IC4DConnQuery; +begin + Result := Self.Create(AC4DConnection, ANameQuery); +end; + +constructor TC4DConnFiredacQuery.Create(AC4DConnection: IC4DConnection; ANameQuery: string); +begin + FC4DConnection := AC4DConnection; + + FQuery := TFDQuery.Create(nil); + FQuery.Name := ANameQuery; + FQuery.FetchOptions.Mode := fmAll; + FQuery.Connection := TFDConnection(FC4DConnection.Component); + FQuery.Close; + FQuery.SQL.Clear; + + FListCond := TStringList.Create; + FListCondParam := TDictionary.Create; + FListGroup := TStringList.Create; + FListOrder := TStringList.Create; + FListLimit := TStringList.Create; +end; + +destructor TC4DConnFiredacQuery.Destroy; +begin + FListLimit.Free; + FListOrder.Free; + FListGroup.Free; + FListCondParam.Free; + FListCond.Free; + FreeAndNil(FQuery); + inherited; +end; + +function TC4DConnFiredacQuery.Close: IC4DConnQuery; +begin + Result := Self; + FQuery.Close; +end; + +function TC4DConnFiredacQuery.Clear: IC4DConnQuery; +begin + Result := Self; + FQuery.SQL.Clear; + FListCond.Clear; + FListCondParam.Clear; + FListLimit.Clear; + FListGroup.Clear; + FListOrder.Clear; +end; + +function TC4DConnFiredacQuery.CloseClear: IC4DConnQuery; +begin + Result := Self; + Self.Close; + Self.Clear; +end; + +function TC4DConnFiredacQuery.Add(Value: string): IC4DConnQuery; +begin + Result := Self; + FQuery.SQL.Add(Value); +end; + +function TC4DConnFiredacQuery.AddParam(Param: string; Value: Variant): IC4DConnQuery; +begin + Result := Self; + FQuery.ParamByName(Param).Value := Value; +end; + +function TC4DConnFiredacQuery.AddCond(ACond: string): IC4DConnQuery; +begin + Result := Self; + FListCond.Add(ACond); +end; + +function TC4DConnFiredacQuery.AddCondParam(Param: string; Value: Variant): IC4DConnQuery; +begin + Result := Self; + FListCondParam.Add(Param, Value); +end; + +function TC4DConnFiredacQuery.AddGroup(ACond: string): IC4DConnQuery; +begin + Result := Self; + FListGroup.Add(ACond); +end; + +function TC4DConnFiredacQuery.AddOrder(ACond: string): IC4DConnQuery; +begin + Result := Self; + FListOrder.Add(ACond); +end; + +function TC4DConnFiredacQuery.AddLimit(ACond: string): IC4DConnQuery; +begin + Result := Self; + FListLimit.Add(ACond); +end; + +function TC4DConnFiredacQuery.Text(Value: string): IC4DConnQuery; +begin + Result := Self; + FQuery.SQL.Text := Value; +end; + +function TC4DConnFiredacQuery.ExecSQL: IC4DConnQuery; +begin + Result := Self; + FQuery.ExecSQL; +end; + +function TC4DConnFiredacQuery.ExecSQL(const ASQL: string): IC4DConnQuery; +begin + Result := Self; + FQuery.ExecSQL(ASQL); +end; + +function TC4DConnFiredacQuery.Open: IC4DConnQuery; +begin + Result := Self; + Self.ProcessaListCond; + Self.ProcessaListGroup; + Self.ProcessaListOrder; + Self.ProcessListLimit; + FQuery.Open; +end; + +function TC4DConnFiredacQuery.Open(const ASQL: string): IC4DConnQuery; +begin + Result := Self; + FQuery.Close; + FQuery.SQL.Clear; + FQuery.SQL.Add(ASQL); + FQuery.Open; + //FQuery.Open(ASQL); +end; + +procedure TC4DConnFiredacQuery.ProcessaListCond; +var + i: Integer; + LKey: string; + LValue: Variant; + LCond: string; +begin + if FListCond.Count <= 0 then + Exit; + + LCond := ''; + for i := 0 to Pred(FListCond.Count)do + LCond := LCond + FListCond.Strings[i] + sLineBreak; + + LCond := TC4DConnUtils.SQLConfBusca(LCond); + FQuery.SQL.Add(LCond); + + for LKey in FListCondParam.Keys do + begin + if FListCondParam.TryGetValue(LKey, LValue) then + Self.AddParam(LKey, LValue); + end; +end; + +procedure TC4DConnFiredacQuery.ProcessaListGroup; +var + i: Integer; + LGroup: string; +begin + if FListGroup.Count <= 0 then + Exit; + + LGroup := ''; + for i := 0 to Pred(FListGroup.Count)do + LGroup := LGroup + FListGroup.Strings[i].Trim + ', '; + + if pos(LGroup, 'group by') <= 0 then + LGroup := 'group by ' + LGroup; + + LGroup := LGroup.Trim; + System.Delete(LGroup, LGroup.Length, 1); + FQuery.SQL.Add(LGroup); +end; + +procedure TC4DConnFiredacQuery.ProcessaListOrder; +var + i: Integer; + LOrdem: string; +begin + if FListOrder.Count <= 0 then + Exit; + + LOrdem := ''; + for i := 0 to Pred(FListOrder.Count)do + LOrdem := LOrdem + FListOrder.Strings[i].Trim + ', '; + + if pos(LOrdem, 'order by') <= 0 then + LOrdem := 'order by ' + LOrdem; + + LOrdem := LOrdem.Trim; + System.Delete(LOrdem, LOrdem.Length, 1); + FQuery.SQL.Add(LOrdem); +end; + +procedure TC4DConnFiredacQuery.ProcessListLimit; +var + i: Integer; +begin + for i := 0 to Pred(FListLimit.Count)do + FQuery.SQL.Add(FListLimit.Strings[i]); +end; + +function TC4DConnFiredacQuery.DataSet: TDataSet; +begin + Result := FQuery; +end; + +function TC4DConnFiredacQuery.DataSource(Value: TDataSource): IC4DConnQuery; +begin + Result := Self; + Value.DataSet := FQuery; +end; + +function TC4DConnFiredacQuery.DataSourceMasterDetail(Value: TDataSource): IC4DConnQuery; +begin + Result := Self; + FQuery.MasterSource := Value; +end; + +function TC4DConnFiredacQuery.Append: IC4DConnQuery; +begin + Result := Self; + FQuery.Append; +end; + +function TC4DConnFiredacQuery.Edit: IC4DConnQuery; +begin + Result := Self; + FQuery.Edit; +end; + +function TC4DConnFiredacQuery.Post: IC4DConnQuery; +begin + Result := Self; + FQuery.Post; +end; + +function TC4DConnFiredacQuery.Delete: IC4DConnQuery; +begin + Result := Self; + FQuery.Delete; +end; + +function TC4DConnFiredacQuery.Eof: Boolean; +begin + Result := FQuery.Eof; +end; + +function TC4DConnFiredacQuery.Bof: Boolean; +begin + Result := FQuery.Bof; +end; + +function TC4DConnFiredacQuery.Prior: IC4DConnQuery; +begin + Result := Self; + FQuery.Prior; +end; + +function TC4DConnFiredacQuery.Next: IC4DConnQuery; +begin + Result := Self; + FQuery.Next; +end; + +function TC4DConnFiredacQuery.First: IC4DConnQuery; +begin + Result := Self; + FQuery.First; +end; + +function TC4DConnFiredacQuery.Last: IC4DConnQuery; +begin + Result := Self; + FQuery.Last; +end; + +function TC4DConnFiredacQuery.IsEmpty: Boolean; +begin + Result := FQuery.IsEmpty; +end; + +function TC4DConnFiredacQuery.RowsAffected: Integer; +begin + Result := FQuery.RowsAffected; +end; + +function TC4DConnFiredacQuery.SQL: TStrings; +begin + Result := FQuery.SQL; +end; + +function TC4DConnFiredacQuery.FieldByName(Value: string): TField; +begin + Result := FQuery.FieldByName(Value); +end; + +function TC4DConnFiredacQuery.RecNo: Integer; +begin + Result := FQuery.RecNo; +end; + +function TC4DConnFiredacQuery.RecordCount: Integer; +begin + Result := FQuery.RecordCount; +end; + +function TC4DConnFiredacQuery.RecordCountStr(pNumZerosLeft: Integer = 6): string; +begin + Result := FQuery.RecordCount.ToString; +end; + +//AName = PARA MYSQL E FIREDAC NOME DO CAMPO +function TC4DConnFiredacQuery.GetLastAutoGenValue(const AName: string): Variant; +begin + try + Result := FQuery.Connection.GetLastAutoGenValue(AName); + except + on E: Exception do + raise Exception.Create('Unable to retrieve the last code/id inserted into the database: ' + E.Message); + end; +end; + +end. diff --git a/Src/Conn/C4D.Conn.Firedac.pas b/Src/Conn/C4D.Conn.Firedac.pas new file mode 100644 index 0000000..70f42ab --- /dev/null +++ b/Src/Conn/C4D.Conn.Firedac.pas @@ -0,0 +1,188 @@ +unit C4D.Conn.Firedac; + +interface + +uses + {$IFNDEF CONSOLE} + Firedac.VCLUI.Wait, + {$ENDIF} + System.Classes, + System.SysUtils, + System.Generics.Collections, + Data.DB, + Firedac.Stan.Intf, + Firedac.Stan.Option, + Firedac.Stan.Error, + Firedac.UI.Intf, + Firedac.Phys.Intf, + Firedac.Stan.Def, + Firedac.Stan.Pool, + Firedac.Stan.Async, + Firedac.Phys, + Firedac.Comp.Client, + Firedac.DApt, + Firedac.Comp.UI, + Firedac.Phys.MySQLDef, + Firedac.Phys.MySQL, + C4D.Conn.Interfaces, + C4D.Conn.Configs, + DelphiAIDev.Types; + +type + TC4DConnFiredac = class(TInterfacedObject, IC4DConnection) + private + [weak] + FC4DConnConfigs: TC4DConnConfigs; + FConnection: TFDConnection; + function TestFieldsComponentConnection: IC4DConnection; + protected + function Component: TComponent; + function Open: IC4DConnection; + function Close: IC4DConnection; + function StartTransaction: IC4DConnection; + function Commit: IC4DConnection; + function Rollback: IC4DConnection; + function TestConnection: Boolean; + function TestConnectionOnly: Boolean; + function LoadConnectionConfig: IC4DConnection; + public + class function New(AC4DConnConfigs: TC4DConnConfigs): IC4DConnection; + constructor Create(AC4DConnConfigs: TC4DConnConfigs); + destructor Destroy; override; + end; + +implementation + +class function TC4DConnFiredac.New(AC4DConnConfigs: TC4DConnConfigs): IC4DConnection; +begin + Result := Self.Create(AC4DConnConfigs); +end; + +constructor TC4DConnFiredac.Create(AC4DConnConfigs: TC4DConnConfigs); +begin + FC4DConnConfigs := AC4DConnConfigs; + FConnection := TFDConnection.Create(nil); + FConnection.LoginPrompt := False; + Self.LoadConnectionConfig; +end; + +destructor TC4DConnFiredac.Destroy; +begin + FConnection.Close; + FreeAndNil(FConnection); + + inherited; +end; + +function TC4DConnFiredac.LoadConnectionConfig: IC4DConnection; +begin + Result := Self; + FConnection.Close; + FConnection.Params.Clear; + FConnection.Params.DriverID := FC4DConnConfigs.DriverID.ToStringID; //'MySQL'; + FConnection.Params.Database := FC4DConnConfigs.Database; + FConnection.Params.UserName := FC4DConnConfigs.UserName; + FConnection.Params.Password := FC4DConnConfigs.Password; + FConnection.Params.Add('Server=' + FC4DConnConfigs.Host); + if FC4DConnConfigs.Port > 0 then + FConnection.Params.Add('Port=' + FC4DConnConfigs.Port.ToString); +end; + +{FConnection.TXOptions.AutoStart := True; + FConnection.TXOptions.AutoStop := True; + FConnection.TXOptions.AutoCommit := True; + FConnection.TxOptions.StopOptions := [xoIfAutoStarted, xoFinishRetaining]; + FConnection.UpdateOptions.AutoCommitUpdates := True; + FConnection.UpdateOptions.RefreshMode := rmAll; } + +function TC4DConnFiredac.Component: TComponent; +begin + Result := FConnection; +end; + +function TC4DConnFiredac.Open: IC4DConnection; +begin + Result := Self; + Self.TestFieldsComponentConnection; + FConnection.Open; +end; + +function TC4DConnFiredac.Close: IC4DConnection; +begin + Result := Self; + FConnection.Close; +end; + +function TC4DConnFiredac.StartTransaction: IC4DConnection; +begin + FConnection.StartTransaction; +end; + +function TC4DConnFiredac.Commit: IC4DConnection; +begin + FConnection.Commit; +end; + +function TC4DConnFiredac.Rollback: IC4DConnection; +begin + FConnection.Rollback; +end; + +function TC4DConnFiredac.TestConnection: Boolean; +var + LConnectedOld: Boolean; +begin + Self.TestFieldsComponentConnection; + try + LConnectedOld := FConnection.Connected; + FConnection.Open; + Result := FConnection.Connected; + + if FConnection.Connected <> LConnectedOld then + FConnection.Connected := LConnectedOld; + except + on E: exception do + raise exception.Create('Unsuccessful Connection! ' + sLineBreak + E.Message); + end; +end; + +function TC4DConnFiredac.TestConnectionOnly: Boolean; +var + LConnectedOld: Boolean; +begin + Result := False; + try + LConnectedOld := FConnection.Connected; + FConnection.Open; + Result := FConnection.Connected; + + if FConnection.Connected <> LConnectedOld then + FConnection.Connected := LConnectedOld; + except + end; +end; + +function TC4DConnFiredac.TestFieldsComponentConnection: IC4DConnection; +var + LEmptyFields: string; +begin + Result := Self; + + LEmptyFields := ''; + if FC4DConnConfigs.Database.Trim.IsEmpty then + LEmptyFields := LEmptyFields + 'Host. '; + + if FConnection.Params.UserName.Trim.IsEmpty then + LEmptyFields := LEmptyFields + 'UserName. '; + + if FConnection.Params.Password.Trim.IsEmpty then + LEmptyFields := LEmptyFields + 'Password. '; + + if Trim(FConnection.Params.Database).IsEmpty then + LEmptyFields := LEmptyFields + 'Database.'; + + if not LEmptyFields.Trim.IsEmpty then + raise exception.Create('To connect to the database, the following data must be filled in: ' + LEmptyFields); +end; + +end. diff --git a/Src/Conn/C4D.Conn.Interfaces.pas b/Src/Conn/C4D.Conn.Interfaces.pas new file mode 100644 index 0000000..6a7bd08 --- /dev/null +++ b/Src/Conn/C4D.Conn.Interfaces.pas @@ -0,0 +1,81 @@ +unit C4D.Conn.Interfaces; + +interface + +uses + Data.DB, + System.Classes, + C4D.Conn.Configs; + +type + IC4DConnection = interface + ['{5B72EBFB-CE76-42F6-B716-226E5149F572}'] + function Component: TComponent; + function Open: IC4DConnection; + function Close: IC4DConnection; + function StartTransaction: IC4DConnection; + function Commit: IC4DConnection; + function Rollback: IC4DConnection; + + function TestConnection: Boolean; + function TestConnectionOnly: Boolean; + function LoadConnectionConfig: IC4DConnection; + end; + + IC4DConnQuery = interface + ['{8C098AA7-288F-4458-AFDB-E44CC95E5441}'] + function Close: IC4DConnQuery; + function Clear: IC4DConnQuery; + function CloseClear: IC4DConnQuery; + function Add(Value: string): IC4DConnQuery; + function AddParam(Param: string; Value: Variant): IC4DConnQuery; + function AddCond(ACond: string): IC4DConnQuery; + function AddCondParam(Param: string; Value: Variant): IC4DConnQuery; + function AddGroup(ACond: string): IC4DConnQuery; + function AddOrder(ACond: string): IC4DConnQuery; + function AddLimit(ACond: string): IC4DConnQuery; + function Text(Value: string): IC4DConnQuery; + function SQL: TStrings; + function ExecSQL: IC4DConnQuery; overload; + function ExecSQL(const ASQL: string): IC4DConnQuery; overload; + function Open: IC4DConnQuery; overload; + function Open(const ASQL: string): IC4DConnQuery; overload; + + function DataSet: TDataSet; + function DataSource(Valeu: TDataSource): IC4DConnQuery; + function DataSourceMasterDetail(Value: TDataSource): IC4DConnQuery; + + function Append: IC4DConnQuery; + function Edit: IC4DConnQuery; + function Post: IC4DConnQuery; + function Delete: IC4DConnQuery; + + function Eof: Boolean; + function Bof: Boolean; + function Prior: IC4DConnQuery; + function Next: IC4DConnQuery; + function First: IC4DConnQuery; + function Last: IC4DConnQuery; + function IsEmpty: Boolean; + function RowsAffected: Integer; + function FieldByName(Value: string): TField; + function RecNo: Integer; + function RecordCount: Integer; + function RecordCountStr(ANumZerosLeft: Integer = 6): string; + + //AName = PARA MYSQL E ZEOS NOME DA TABELA + //AName = PARA MYSQL E FIREDAC NOME DO CAMPO + function GetLastAutoGenValue(const AName: string): Variant; + end; + + IC4DConn = interface + ['{71342615-E414-4D66-9280-67218D5FB27A}'] + function Configs: TC4DConnConfigs; + function Connection: IC4DConnection; + function Query: IC4DConnQuery; overload; + function Query(const ANameQuery: string): IC4DConnQuery; overload; + end; + +implementation + +end. diff --git a/Src/Conn/C4D.Conn.Types.pas b/Src/Conn/C4D.Conn.Types.pas new file mode 100644 index 0000000..13f1d9d --- /dev/null +++ b/Src/Conn/C4D.Conn.Types.pas @@ -0,0 +1,12 @@ +unit C4D.Conn.Types; + +interface + +type + {$SCOPEDENUMS ON} + TComponentConnection = (Empty, FireDac {$IFDEF C4D_ZEOS}, Zeos {$ENDIF}); + {$SCOPEDENUMS OFF} + +implementation + +end. diff --git a/Src/Conn/C4D.Conn.Utils.pas b/Src/Conn/C4D.Conn.Utils.pas new file mode 100644 index 0000000..8ca7b3f --- /dev/null +++ b/Src/Conn/C4D.Conn.Utils.pas @@ -0,0 +1,57 @@ +unit C4D.Conn.Utils; + +interface + +uses + System.SysUtils, + System.StrUtils; + +type + TC4DConnUtils = class + public + class function SQLConfBusca(const ASql: string): string; + class function SQLTratar(const ASql: string): string; + end; + +implementation + +class function TC4DConnUtils.SQLConfBusca(const ASql: string): string; +begin + Result := ASql.Trim; + + if Result.IsEmpty then + Exit; + + if copy(Result, 1, 3) = 'and' then + begin + Delete(Result, 1, 3); + Result := 'where '+ Result; + end + else if copy(Result, 1, 2) = 'or' then + begin + Delete(Result, 1, 2); + Result := 'where '+ Result; + end + else if(copy(Result, 1, 5) <> 'where') + and(copy(Result, 1, 5) <> 'limit') + and(copy(Result, 1, 8) <> 'order by') + and(copy(Result, 1, 8) <> 'group by') + then + Result := 'where '+ Result; + + Result := Self.SQLTratar(Result) + ' '; +end; + +class function TC4DConnUtils.SQLTratar(const ASql: string): string; +begin + Result := ASql; + Result := StringReplace(Result, ' ALTER ', ' ALTERA ', [rfReplaceAll, rfIgnoreCase]); + Result := StringReplace(Result, 'ALTER TABLE', 'ALTERA TABLE', [rfReplaceAll, rfIgnoreCase]); + + Result := StringReplace(Result, ' DROP ', ' DROPE ', [rfReplaceAll, rfIgnoreCase]); + Result := StringReplace(Result, 'DROP TABLE', 'DROPE TABLE', [rfReplaceAll, rfIgnoreCase]); + Result := StringReplace(Result, 'DROP PROCEDURE', 'DROPE PROCEDURE', [rfReplaceAll, rfIgnoreCase]); + Result := StringReplace(Result, 'DROP FUNCTION', 'DROPE FUNCTION', [rfReplaceAll, rfIgnoreCase]); +end; + +end. diff --git a/Src/Conn/C4D.Conn.Zeos.Query.pas b/Src/Conn/C4D.Conn.Zeos.Query.pas new file mode 100644 index 0000000..434a5fb --- /dev/null +++ b/Src/Conn/C4D.Conn.Zeos.Query.pas @@ -0,0 +1,427 @@ +unit C4D.Conn.Zeos.Query; + +interface + +uses + System.SysUtils, + System.StrUtils, + System.Classes, + System.Generics.Collections, + ZAbstractConnection, + ZConnection, + Data.DB, + ZAbstractRODataset, + ZAbstractDataset, + ZDataset, + C4D.Conn.Interfaces, + C4D.Conn.Zeos, + C4D.Conn.Utils; + +type + TC4DConnZeosQuery = class(TInterfacedObject, IC4DConnQuery) + private + FC4DConnection: IC4DConnection; + FQuery: TZQuery; + FListCond: TStringList; + FListCondParam: TDictionary; + FListGroup: TStringList; + FListOrder: TStringList; + FListLimit: TStringList; + procedure ProcessaListCond; + procedure ProcessaListGroup; + procedure ProcessaListOrder; + procedure ProcessaListLimit; + protected + function Close: IC4DConnQuery; + function Clear: IC4DConnQuery; + function CloseClear: IC4DConnQuery; + function Add(Value: string): IC4DConnQuery; + function AddParam(Param: string; Value: Variant): IC4DConnQuery; + function AddCond(ACond: string): IC4DConnQuery; + function AddCondParam(Param: string; Value: Variant): IC4DConnQuery; + function AddGroup(ACond: string): IC4DConnQuery; + function AddOrder(ACond: string): IC4DConnQuery; + function AddLimit(ACond: string): IC4DConnQuery; + function Text(Value: string): IC4DConnQuery; + function SQL: TStrings; + function ExecSQL: IC4DConnQuery; overload; + function ExecSQL(const ASQL: string): IC4DConnQuery; overload; + function Open: IC4DConnQuery; overload; + function Open(const ASQL: string): IC4DConnQuery; overload; + + function DataSet: TDataSet; + function DataSource(Value: TDataSource): IC4DConnQuery; + function DataSourceMasterDetail(Value: TDataSource): IC4DConnQuery; + + function Append: IC4DConnQuery; + function Edit: IC4DConnQuery; + function Post: IC4DConnQuery; + function Delete: IC4DConnQuery; + + function Eof: Boolean; + function Bof: Boolean; + function Prior: IC4DConnQuery; + function Next: IC4DConnQuery; + function First: IC4DConnQuery; + function Last: IC4DConnQuery; + function IsEmpty: Boolean; + function RowsAffected: Integer; + function FieldByName(Value: string): TField; + function RecNo: Integer; + function RecordCount: Integer; + function RecordCountStr(ANumZerosLeft: Integer = 6): string; + function GetLastAutoGenValue(const AName: string): Variant; + public + class function New(AC4DConnection: IC4DConnection; ANameQuery: string): IC4DConnQuery; + constructor Create(AC4DConnection: IC4DConnection; ANameQuery: string); + destructor Destroy; override; + end; + +implementation + +class function TC4DConnZeosQuery.New(AC4DConnection: IC4DConnection; ANameQuery: string): IC4DConnQuery; +begin + Result := Self.Create(AC4DConnection, ANameQuery); +end; + +constructor TC4DConnZeosQuery.Create(AC4DConnection: IC4DConnection; ANameQuery: string); +begin + FC4DConnection := AC4DConnection; + + FQuery := TZQuery.Create(nil); + FQuery.Name := ANameQuery; + FQuery.Connection := TZConnection(FC4DConnection.Component); + + FQuery.Close; + FQuery.SQL.Clear; + + FListCond := TStringList.Create; + FListCondParam := TDictionary.Create; + FListGroup := TStringList.Create; + FListOrder := TStringList.Create; + FListLimit := TStringList.Create; +end; + +destructor TC4DConnZeosQuery.Destroy; +begin + FListLimit.Free; + FListOrder.Free; + FListGroup.Free; + FListCondParam.Free; + FListCond.Free; + FreeAndNil(FQuery); + inherited; +end; + +function TC4DConnZeosQuery.Close: IC4DConnQuery; +begin + Result := Self; + FQuery.Close; +end; + +function TC4DConnZeosQuery.Clear: IC4DConnQuery; +begin + Result := Self; + FQuery.SQL.Clear; + FListCond.Clear; + FListCondParam.Clear; + FListLimit.Clear; + FListGroup.Clear; + FListOrder.Clear; +end; + +function TC4DConnZeosQuery.CloseClear: IC4DConnQuery; +begin + Result := Self; + Self.Close; + Self.Clear; +end; + +function TC4DConnZeosQuery.Add(Value: string): IC4DConnQuery; +begin + Result := Self; + FQuery.SQL.Add(Value); +end; + +function TC4DConnZeosQuery.AddParam(Param: string; Value: Variant): IC4DConnQuery; +begin + Result := Self; + FQuery.ParamByName(Param).Value := Value; +end; + +function TC4DConnZeosQuery.AddCond(ACond: string): IC4DConnQuery; +begin + Result := Self; + FListCond.Add(ACond); +end; + +function TC4DConnZeosQuery.AddCondParam(Param: string; Value: Variant): IC4DConnQuery; +begin + Result := Self; + FListCondParam.Add(Param, Value); +end; + +function TC4DConnZeosQuery.AddGroup(ACond: string): IC4DConnQuery; +begin + Result := Self; + FListGroup.Add(ACond); +end; + +function TC4DConnZeosQuery.AddOrder(ACond: string): IC4DConnQuery; +begin + Result := Self; + FListOrder.Add(ACond); +end; + +function TC4DConnZeosQuery.AddLimit(ACond: string): IC4DConnQuery; +begin + Result := Self; + FListLimit.Add(ACond); +end; + +function TC4DConnZeosQuery.Text(Value: string): IC4DConnQuery; +begin + Result := Self; + FQuery.SQL.Text := Value; +end; + +function TC4DConnZeosQuery.ExecSQL: IC4DConnQuery; +begin + Result := Self; + FQuery.ExecSQL; +end; + +function TC4DConnZeosQuery.ExecSQL(const ASQL: string): IC4DConnQuery; +begin + Result := Self; + FQuery.Close; + FQuery.SQL.Clear; + FQuery.SQL.Add(ASQL); + FQuery.ExecSQL; +end; + +function TC4DConnZeosQuery.Open: IC4DConnQuery; +begin + Result := Self; + Self.ProcessaListCond; + Self.ProcessaListGroup; + Self.ProcessaListOrder; + Self.ProcessaListLimit; + FQuery.Open; +end; + +function TC4DConnZeosQuery.Open(const ASQL: string): IC4DConnQuery; +begin + Result := Self; + FQuery.Close; + FQuery.SQL.Clear; + FQuery.SQL.Add(ASQL); + FQuery.Open; +end; + +procedure TC4DConnZeosQuery.ProcessaListCond; +var + i: Integer; + LKey: string; + LValue: Variant; + LCond: string; +begin + if(FListCond.Count <= 0)then + Exit; + + LCond := ''; + for i := 0 to Pred(FListCond.Count)do + LCond := LCond + FListCond.Strings[i] + sLineBreak; + + LCond := TC4DConnUtils.SQLConfBusca(LCond); + FQuery.SQL.Add(LCond); + + for LKey in FListCondParam.Keys do + if FListCondParam.TryGetValue(LKey, LValue) then + Self.AddParam(LKey, LValue); +end; + +procedure TC4DConnZeosQuery.ProcessaListGroup; +var + i: Integer; + LGroup: string; +begin + if FListGroup.Count <= 0 then + Exit; + + LGroup := ''; + for i := 0 to Pred(FListGroup.Count)do + LGroup := LGroup + FListGroup.Strings[i].Trim + ', '; + + if pos('group by', LGroup) <= 0 then + LGroup := 'group by ' + LGroup; + + LGroup := LGroup.Trim; + System.Delete(LGroup, LGroup.Length, 1); + FQuery.SQL.Add(LGroup); +end; + +procedure TC4DConnZeosQuery.ProcessaListOrder; +var + i: Integer; + LOrdem: string; +begin + if FListOrder.Count <= 0 then + Exit; + + LOrdem := ''; + for i := 0 to Pred(FListOrder.Count)do + LOrdem := LOrdem + FListOrder.Strings[i].Trim + ', '; + + if pos('order by', LOrdem) <= 0 then + LOrdem := 'order by ' + LOrdem; + + LOrdem := LOrdem.Trim; + System.Delete(LOrdem, LOrdem.Length, 1); + FQuery.SQL.Add(LOrdem); +end; + +procedure TC4DConnZeosQuery.ProcessaListLimit; +var + i: Integer; +begin + for i := 0 to Pred(FListLimit.Count)do + FQuery.SQL.Add(FListLimit.Strings[i]); +end; + +function TC4DConnZeosQuery.DataSet: TDataSet; +begin + Result := FQuery; +end; + +function TC4DConnZeosQuery.DataSource(Value: TDataSource): IC4DConnQuery; +begin + Result := Self; + Value.DataSet := FQuery; +end; + +function TC4DConnZeosQuery.DataSourceMasterDetail(Value: TDataSource): IC4DConnQuery; +begin + Result := Self; + FQuery.DataSource := Value; +end; + +function TC4DConnZeosQuery.Append: IC4DConnQuery; +begin + Result := Self; + FQuery.Append; +end; + +function TC4DConnZeosQuery.Edit: IC4DConnQuery; +begin + Result := Self; + FQuery.Edit; +end; + +function TC4DConnZeosQuery.Post: IC4DConnQuery; +begin + Result := Self; + FQuery.Post; +end; + +function TC4DConnZeosQuery.Delete: IC4DConnQuery; +begin + Result := Self; + FQuery.Delete; +end; + +function TC4DConnZeosQuery.Eof: Boolean; +begin + Result := FQuery.Eof; +end; + +function TC4DConnZeosQuery.Bof: Boolean; +begin + Result := FQuery.Bof; +end; + +function TC4DConnZeosQuery.Prior: IC4DConnQuery; +begin + Result := Self; + FQuery.Prior; +end; + +function TC4DConnZeosQuery.Next: IC4DConnQuery; +begin + Result := Self; + FQuery.Next; +end; + +function TC4DConnZeosQuery.First: IC4DConnQuery; +begin + Result := Self; + FQuery.First; +end; + +function TC4DConnZeosQuery.Last: IC4DConnQuery; +begin + Result := Self; + FQuery.Last; +end; + +function TC4DConnZeosQuery.IsEmpty: Boolean; +begin + Result := FQuery.IsEmpty; +end; + +function TC4DConnZeosQuery.RowsAffected: Integer; +begin + Result := FQuery.RowsAffected +end; + +function TC4DConnZeosQuery.SQL: TStrings; +begin + Result := FQuery.SQL; +end; + +function TC4DConnZeosQuery.FieldByName(Value: string): TField; +begin + Result := FQuery.FieldByName(Value); +end; + +function TC4DConnZeosQuery.RecNo: Integer; +begin + Result := FQuery.RecNo; +end; + +function TC4DConnZeosQuery.RecordCount: Integer; +begin + Result := FQuery.RecordCount; +end; + +function TC4DConnZeosQuery.RecordCountStr(ANumZerosLeft: Integer = 6): string; +begin + Result := FQuery.RecordCount.ToString; +end; + +//AName = PARA MYSQL E ZEOS NOME DA TABELA +function TC4DConnZeosQuery.GetLastAutoGenValue(const AName: string): Variant; +var + LQuery: TZQuery; +begin + LQuery := TZQuery.Create(nil); + try + try + LQuery.Connection := FQuery.Connection; + LQuery.Close; + LQuery.SQL.Clear; + LQuery.SQL.Add('Select Last_Insert_ID() as Last_Insert_ID from ' + AName); + LQuery.Open; + + Result := LQuery.FieldByName('Last_Insert_ID').AsInteger; + LQuery.Close; + except + on E: Exception do + raise Exception.Create('Unable to retrieve the last code/id inserted into the database: ' + E.Message); + end; + finally + FreeAndNil(LQuery); + end; +end; + +end. diff --git a/Src/Conn/C4D.Conn.Zeos.pas b/Src/Conn/C4D.Conn.Zeos.pas new file mode 100644 index 0000000..eb411fd --- /dev/null +++ b/Src/Conn/C4D.Conn.Zeos.pas @@ -0,0 +1,160 @@ +unit C4D.Conn.Zeos; + +interface + +uses + System.Classes, + System.SysUtils, + System.Generics.Collections, + ZAbstractConnection, + ZConnection, + C4D.Conn.Interfaces, + C4D.Conn.Configs; + +type + TC4DConnZeos = class(TInterfacedObject, IC4DConnection) + private + [weak] + FC4DConnConfigs: TC4DConnConfigs; + FConnection: TZConnection; + function TestFieldsComponentConnection: IC4DConnection; + protected + function Component: TComponent; + function Open: IC4DConnection; + function Close: IC4DConnection; + function StartTransaction: IC4DConnection; + function Commit: IC4DConnection; + function Rollback: IC4DConnection; + function TestConnection: Boolean; + function TestConnectionOnly: Boolean; + function LoadConnectionConfig: IC4DConnection; + public + class function New(AC4DConnConfigs: TC4DConnConfigs): IC4DConnection; + constructor Create(AC4DConnConfigs: TC4DConnConfigs); + destructor Destroy; override; + end; + +implementation + +class function TC4DConnZeos.New(AC4DConnConfigs: TC4DConnConfigs): IC4DConnection; +begin + Result := Self.Create(AC4DConnConfigs); +end; + +constructor TC4DConnZeos.Create(AC4DConnConfigs: TC4DConnConfigs); +begin + FC4DConnConfigs := AC4DConnConfigs; + FConnection := TZConnection.Create(nil); + Self.LoadConnectionConfig; +end; + +destructor TC4DConnZeos.Destroy; +begin + FConnection.Connected := False; + FreeAndNil(FConnection); + + inherited; +end; + +function TC4DConnZeos.LoadConnectionConfig: IC4DConnection; +begin + Result := Self; + FConnection.Connected := False; + FConnection.Protocol := 'mysql'; + FConnection.Database := FC4DConnConfigs.Database; + FConnection.User := FC4DConnConfigs.UserName; + FConnection.Password := FC4DConnConfigs.Password; + FConnection.HostName := FC4DConnConfigs.Host; + FConnection.Port := FC4DConnConfigs.Port; + //FConnection.TransactIsolationLevel := tiReadCommitted; +end; + +function TC4DConnZeos.Component: TComponent; +begin + Result := FConnection; +end; + +function TC4DConnZeos.Open: IC4DConnection; +begin + Result := Self; + Self.TestFieldsComponentConnection; + FConnection.Connected := True; +end; + +function TC4DConnZeos.Close: IC4DConnection; +begin + Result := Self; + FConnection.Connected := False; +end; + +function TC4DConnZeos.StartTransaction: IC4DConnection; +begin + FConnection.StartTransaction; +end; + +function TC4DConnZeos.Commit: IC4DConnection; +begin + FConnection.Commit; +end; + +function TC4DConnZeos.Rollback: IC4DConnection; +begin + FConnection.Rollback; +end; + +function TC4DConnZeos.TestConnection: Boolean; +var + LConnectedOld: Boolean; +begin + Self.TestFieldsComponentConnection; + try + LConnectedOld := FConnection.Connected; + FConnection.Connected := True; + Result := FConnection.Connected; + if(FConnection.Connected <> LConnectedOld)then + FConnection.Connected := LConnectedOld; + except + on E: exception do + raise exception.Create('Conexão não pode ser realizada: ' + E.Message); + end; +end; + +function TC4DConnZeos.TestConnectionOnly: Boolean; +var + LConnectedOld: Boolean; +begin + Result := False; + try + LConnectedOld := FConnection.Connected; + FConnection.Connected := True; + Result := FConnection.Connected; + if(FConnection.Connected <> LConnectedOld)then + FConnection.Connected := LConnectedOld; + except + end; +end; + +function TC4DConnZeos.TestFieldsComponentConnection: IC4DConnection; +var + LEmptyFields: string; +begin + Result := Self; + LEmptyFields := ''; + + if FConnection.HostName.Trim.IsEmpty then + LEmptyFields := LEmptyFields + 'HostName. '; + + if FConnection.User.Trim.IsEmpty then + LEmptyFields := LEmptyFields + 'User. '; + + if FConnection.Password.Trim.IsEmpty then + LEmptyFields := LEmptyFields + 'Password. '; + + if FConnection.Database.Trim.IsEmpty then + LEmptyFields := LEmptyFields + 'Database.'; + + if not LEmptyFields.IsEmpty then + raise exception.Create('To connect to the database, the following data must be filled in: ' + LEmptyFields); +end; + +end. diff --git a/Src/Conn/C4D.Conn.pas b/Src/Conn/C4D.Conn.pas new file mode 100644 index 0000000..204d725 --- /dev/null +++ b/Src/Conn/C4D.Conn.pas @@ -0,0 +1,130 @@ +unit C4D.Conn; + +interface + +uses + System.SysUtils, + System.Classes, + C4D.Conn.Interfaces, + C4D.Conn.Types, + C4D.Conn.Configs, + {$IFDEF C4D_ZEOS} + C4D.Conn.Zeos, + C4D.Conn.Zeos.Query, + {$ENDIF} + C4D.Conn.Firedac, + C4D.Conn.Firedac.Query; + +type + IC4DConn = C4D.Conn.Interfaces.IC4DConn; + IC4DConnQuery = C4D.Conn.Interfaces.IC4DConnQuery; + + TC4DConn = class(TInterfacedObject, IC4DConn) + private + FC4DConnConfigs: TC4DConnConfigs; + FC4DConnInstance: IC4DConnection; + FCountNameQuery: Integer; + function CountNameQuery: Integer; + function QueryInternal(const ANameQuery: string): IC4DConnQuery; + protected + function Configs: TC4DConnConfigs; + function Connection: IC4DConnection; + function Query: IC4DConnQuery; overload; + function Query(const ANameQuery: string): IC4DConnQuery; overload; + public + class function New: IC4DConn; + constructor Create; + destructor Destroy; override; + end; + +//function C4DConn: IC4DConn; + +var + Instance: IC4DConn; + +implementation + +uses + DelphiAIDev.Utils; + +class function TC4DConn.New: IC4DConn; +begin + Result := Self.Create; +end; + +constructor TC4DConn.Create; +begin + FCountNameQuery := 0; + FC4DConnConfigs := TC4DConnConfigs.Create; +end; + +destructor TC4DConn.Destroy; +begin + FC4DConnConfigs.Free; + inherited; +end; + +function C4DConn: IC4DConn; +begin + if not Assigned(Instance) then + Instance := TC4DConn.New; + + Result := Instance; +end; + +function TC4DConn.Configs: TC4DConnConfigs; +begin + Result := FC4DConnConfigs; +end; + +function TC4DConn.CountNameQuery: Integer; +begin + Inc(FCountNameQuery); + Result := FCountNameQuery; +end; + +function TC4DConn.Connection: IC4DConnection; +begin + {$IFDEF C4D_ZEOS} + if FC4DConnConfigs.ConnectionSingleton then + begin + if not Assigned(FC4DConnInstance) then + FC4DConnInstance := TC4DConnZeos.New(FC4DConnConfigs); + + Result := FC4DConnInstance; + end + else + Result := TC4DConnZeos.New(FC4DConnConfigs); + {$ELSE} + if FC4DConnConfigs.ConnectionSingleton then + begin + if not Assigned(FC4DConnInstance) then + FC4DConnInstance := TC4DConnFiredac.New(FC4DConnConfigs); + + Result := FC4DConnInstance; + end + else + Result := TC4DConnFiredac.New(FC4DConnConfigs); + {$ENDIF} +end; + +function TC4DConn.Query: IC4DConnQuery; +begin + Result := Self.QueryInternal('Query' + Self.CountNameQuery.ToString); +end; + +function TC4DConn.Query(const ANameQuery: string): IC4DConnQuery; +begin + Result := Self.QueryInternal(ANameQuery); +end; + +function TC4DConn.QueryInternal(const ANameQuery: string): IC4DConnQuery; +begin + {$IFDEF C4D_ZEOS} + Result := TC4DConnZeosQuery.New(Self.Connection, ANameQuery); + {$ELSE} + Result := TC4DConnFiredacQuery.New(Self.Connection, ANameQuery); + {$ENDIF} +end; + +end. diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm index 0d495b2..dd471ae 100644 --- a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm +++ b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm @@ -3,8 +3,8 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView Top = 0 BorderIcons = [biSystemMenu] Caption = 'IA Developer - Databases - [action]' - ClientHeight = 307 - ClientWidth = 657 + ClientHeight = 303 + ClientWidth = 665 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -22,8 +22,8 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView object Bevel2: TBevel AlignWithMargins = True Left = 0 - Top = 268 - Width = 657 + Top = 264 + Width = 665 Height = 1 Margins.Left = 0 Margins.Top = 0 @@ -36,8 +36,8 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView end object Panel1: TPanel Left = 0 - Top = 272 - Width = 657 + Top = 268 + Width = 665 Height = 35 Align = alBottom BevelEdges = [beLeft, beRight, beBottom] @@ -48,10 +48,9 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView Padding.Bottom = 2 ParentBackground = False TabOrder = 1 - ExplicitTop = 282 object btnConfirm: TButton AlignWithMargins = True - Left = 429 + Left = 437 Top = 2 Width = 110 Height = 31 @@ -66,7 +65,7 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView end object btnClose: TButton AlignWithMargins = True - Left = 542 + Left = 550 Top = 2 Width = 110 Height = 31 @@ -93,24 +92,22 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView Caption = 'Test Connection' TabOrder = 2 OnClick = btnTestConnectionClick - ExplicitLeft = 429 end end object Panel9: TPanel Left = 0 Top = 0 - Width = 657 - Height = 268 + Width = 665 + Height = 264 Align = alClient BevelOuter = bvNone ParentBackground = False TabOrder = 0 - ExplicitHeight = 279 object Bevel1: TBevel AlignWithMargins = True Left = 0 - Top = 264 - Width = 657 + Top = 260 + Width = 665 Height = 1 Margins.Left = 0 Margins.Top = 0 @@ -121,7 +118,7 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView ExplicitWidth = 676 end object Label2: TLabel - Left = 31 + Left = 234 Top = 25 Width = 43 Height = 13 @@ -129,56 +126,56 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView end object Label3: TLabel Left = 31 - Top = 71 + Top = 25 Width = 53 Height = 13 Caption = 'Description' end object Label1: TLabel - Left = 234 - Top = 71 + Left = 437 + Top = 25 Width = 22 Height = 13 Caption = 'Host' end object Label5: TLabel - Left = 437 - Top = 71 + Left = 31 + Top = 69 Width = 22 Height = 13 Caption = 'User' end object Label6: TLabel - Left = 31 - Top = 120 + Left = 234 + Top = 69 Width = 46 Height = 13 Caption = 'Password' end object Label7: TLabel - Left = 234 - Top = 120 + Left = 437 + Top = 69 Width = 20 Height = 13 Caption = 'Port' end object Label4: TLabel - Left = 437 - Top = 120 + Left = 31 + Top = 119 Width = 46 Height = 13 Caption = 'Database' end object Label8: TLabel Left = 31 - Top = 168 + Top = 164 Width = 47 Height = 13 Caption = 'VendorLib' end object lbAddLocalDatabase: TLabel - Left = 262 - Top = 71 + Left = 465 + Top = 25 Width = 99 Height = 13 Cursor = crHandPoint @@ -186,60 +183,60 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView OnClick = lbAddLocalDatabaseClick end object cBoxDriverID: TComboBox - Left = 31 + Left = 234 Top = 41 Width = 200 Height = 21 Style = csDropDownList - TabOrder = 0 + TabOrder = 1 end object edtDescription: TEdit Left = 31 - Top = 87 + Top = 41 Width = 200 Height = 21 - TabOrder = 1 + TabOrder = 0 end object edtHost: TEdit - Left = 234 - Top = 87 + Left = 437 + Top = 41 Width = 200 Height = 21 TabOrder = 2 end object edtUser: TEdit - Left = 437 - Top = 87 + Left = 31 + Top = 85 Width = 200 Height = 21 TabOrder = 3 end object edtPassword: TEdit - Left = 31 - Top = 136 + Left = 234 + Top = 85 Width = 164 Height = 21 PasswordChar = '*' TabOrder = 4 end object edtPort: TEdit - Left = 234 - Top = 136 + Left = 437 + Top = 85 Width = 200 Height = 21 NumbersOnly = True TabOrder = 5 end object edtDatabase: TEdit - Left = 437 - Top = 136 - Width = 200 + Left = 31 + Top = 135 + Width = 606 Height = 21 TabOrder = 6 end object edtVendorLib: TEdit Left = 31 - Top = 184 + Top = 180 Width = 606 Height = 21 PasswordChar = '*' @@ -247,7 +244,7 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView end object ckVisible: TCheckBox Left = 31 - Top = 216 + Top = 212 Width = 53 Height = 17 Cursor = crHandPoint @@ -255,8 +252,8 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView TabOrder = 8 end object Button1: TButton - Left = 197 - Top = 135 + Left = 400 + Top = 84 Width = 34 Height = 23 Cursor = crHandPoint diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas index 3cf4a46..18aeae9 100644 --- a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas +++ b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas @@ -13,7 +13,8 @@ interface Vcl.Menus, Vcl.ComCtrls, DelphiAIDev.Types, - DelphiAIDev.Databases.Fields; + DelphiAIDev.Databases.Fields, + C4D.Conn; type TDelphiAIDevDatabasesAddEditView = class(TForm) @@ -55,6 +56,7 @@ TDelphiAIDevDatabasesAddEditView = class(TForm) FFields: TDelphiAIDevDatabasesFields; procedure FillcBoxDriverID; procedure FillScreenFields; + procedure ValidateFillingFields; public property Fields: TDelphiAIDevDatabasesFields read FFields write FFields; end; @@ -114,23 +116,7 @@ procedure TDelphiAIDevDatabasesAddEditView.btnCloseClick(Sender: TObject); procedure TDelphiAIDevDatabasesAddEditView.btnConfirmClick(Sender: TObject); begin - if cBoxDriverID.ItemIndex < 0 then - TUtils.ShowMsgAndAbort('No informed Driver ID', cBoxDriverID); - - if TUtils.StrToDriverID(cBoxDriverID.Text) = TC4DDriverID.None then - TUtils.ShowMsgAndAbort('Select a DriverID', cBoxDriverID); - - if Trim(edtDescription.Text).IsEmpty then - TUtils.ShowMsgAndAbort('No informed Description', edtDescription); - - if Trim(edtHost.Text).IsEmpty then - TUtils.ShowMsgAndAbort('No informed Host', edtHost); - - if Trim(edtUser.Text).IsEmpty then - TUtils.ShowMsgAndAbort('No informed User', edtUser); - - if Trim(edtDatabase.Text).IsEmpty then - TUtils.ShowMsgAndAbort('No informed Database', edtDatabase); + Self.ValidateFillingFields; FFields.DriverID := TUtils.StrToDriverID(cBoxDriverID.Text); FFields.Description := edtDescription.Text; @@ -148,6 +134,27 @@ procedure TDelphiAIDevDatabasesAddEditView.btnConfirmClick(Sender: TObject); Self.ModalResult := mrOK; end; +procedure TDelphiAIDevDatabasesAddEditView.ValidateFillingFields; +begin + if Trim(edtDescription.Text).IsEmpty then + TUtils.ShowMsgAndAbort('No informed Description', edtDescription); + + if cBoxDriverID.ItemIndex < 0 then + TUtils.ShowMsgAndAbort('No informed Driver ID', cBoxDriverID); + + if TUtils.StrToDriverID(cBoxDriverID.Text) = TC4DDriverID.None then + TUtils.ShowMsgAndAbort('Select a DriverID', cBoxDriverID); + + if Trim(edtHost.Text).IsEmpty then + TUtils.ShowMsgAndAbort('No informed Host', edtHost); + + if Trim(edtUser.Text).IsEmpty then + TUtils.ShowMsgAndAbort('No informed User', edtUser); + + if Trim(edtDatabase.Text).IsEmpty then + TUtils.ShowMsgAndAbort('No informed Database', edtDatabase); +end; + procedure TDelphiAIDevDatabasesAddEditView.Button1Click(Sender: TObject); begin if edtPassword.PasswordChar = '*' then @@ -169,8 +176,48 @@ procedure TDelphiAIDevDatabasesAddEditView.FormKeyDown(Sender: TObject; var Key: end; procedure TDelphiAIDevDatabasesAddEditView.btnTestConnectionClick(Sender: TObject); +var + LConn: IC4DConn; begin - // + Screen.Cursor := crHourGlass; + try + LConn := TC4DConn.New; + LConn.Configs + .DriverID(TUtils.StrToDriverID(cBoxDriverID.Text)) + .Host(edtHost.Text) + .UserName(edtUser.Text) + .Password(edtPassword.Text) + .Port(StrToIntDef(edtPort.Text, 0)) + .Database(edtDatabase.Text) + .VendorLib(edtVendorLib.Text); + + try + if LConn.Connection.TestConnection then + TUtils.ShowV('Connection Successful'); + except + on E: exception do + TUtils.ShowError(E.Message); + end; + finally + Screen.Cursor := crDefault; + end; + + //Self.ValidateFillingFields; + +// Screen.Cursor := crHourGlass; +// try +// C4DConn.Configs +// .Host(edtHost.Text) +// .UserName(edtUser.Text) +// .Password(edtPassword.Text) +// .Port(StrToIntDef(edtPort.Text, 0)) +// .Database(edtDatabase.Text) +// .VendorLib(edtVendorLib.Text); +// +// C4DConn.Connection.TestConnection; +// finally +// Screen.Cursor := crDefault; +// end; end; end. diff --git a/Src/Databases/DelphiAIDev.Databases.Fields.pas b/Src/Databases/DelphiAIDev.Databases.Fields.pas index a36b196..fc9e3e1 100644 --- a/Src/Databases/DelphiAIDev.Databases.Fields.pas +++ b/Src/Databases/DelphiAIDev.Databases.Fields.pas @@ -21,7 +21,6 @@ TDelphiAIDevDatabasesFields = class public constructor Create; procedure Clear; - property Guid: string read FGuid write FGuid; property DriverID: TC4DDriverID read FDriverID write FDriverID; property Description: string read FDescription write FDescription; diff --git a/Src/Databases/DelphiAIDev.Databases.Interfaces.pas b/Src/Databases/DelphiAIDev.Databases.Interfaces.pas index 19ddb10..4fa2001 100644 --- a/Src/Databases/DelphiAIDev.Databases.Interfaces.pas +++ b/Src/Databases/DelphiAIDev.Databases.Interfaces.pas @@ -10,7 +10,7 @@ interface IDelphiAIDevDatabasesModel = interface ['{3399A776-4B23-4CFC-8992-568AE07FE065}'] procedure ReadData(AProc: TProc); - procedure SaveOrEditData(const AFields: TDelphiAIDevDatabasesFields); + procedure SaveOrEditData(AFields: TDelphiAIDevDatabasesFields); procedure RemoveData(const AGuid: string); end; diff --git a/Src/Databases/DelphiAIDev.Databases.Model.pas b/Src/Databases/DelphiAIDev.Databases.Model.pas index 915e5ec..a9586e2 100644 --- a/Src/Databases/DelphiAIDev.Databases.Model.pas +++ b/Src/Databases/DelphiAIDev.Databases.Model.pas @@ -16,11 +16,11 @@ interface type TDelphiAIDevDatabasesModel = class(TInterfacedObject, IDelphiAIDevDatabasesModel) private - procedure SaveData(const AFields: TDelphiAIDevDatabasesFields); - procedure EditData(const AFields: TDelphiAIDevDatabasesFields); + procedure SaveData(AFields: TDelphiAIDevDatabasesFields); + procedure EditData(AFields: TDelphiAIDevDatabasesFields); protected procedure ReadData(AProc: TProc); - procedure SaveOrEditData(const AFields: TDelphiAIDevDatabasesFields); + procedure SaveOrEditData(AFields: TDelphiAIDevDatabasesFields); procedure RemoveData(const AGuid: string); public class function New: IDelphiAIDevDatabasesModel; @@ -100,7 +100,7 @@ procedure TDelphiAIDevDatabasesModel.ReadData(AProc: TProc Date: Tue, 13 Aug 2024 09:52:32 -0300 Subject: [PATCH 008/109] bk/2024-08-13-0952 --- Package/DelphiAIDeveloper.dpk | 3 +- Package/DelphiAIDeveloper.dproj | 1 + Src/Conn/C4D.Conn.Firedac.pas | 38 ++++++++++++++++--- .../DelphiAIDev.Databases.AddEdit.View.dfm | 13 ++++++- .../DelphiAIDev.Databases.AddEdit.View.pas | 1 + Src/Databases/DelphiAIDev.Databases.Model.pas | 12 +++++- 6 files changed, 58 insertions(+), 10 deletions(-) diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index a9a1fb6..eca73b9 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -37,7 +37,8 @@ requires FireDAC, FireDACCommonDriver, FireDACCommon, - FireDACMySQLDriver; + FireDACMySQLDriver, + FireDACIBDriver; contains DelphiAIDev.Register in '..\Src\DelphiAIDev.Register.pas', diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index b9ed77d..de5b230 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -127,6 +127,7 @@ +
DelphiAIDevChatView
diff --git a/Src/Conn/C4D.Conn.Firedac.pas b/Src/Conn/C4D.Conn.Firedac.pas index 70f42ab..cd6f6e5 100644 --- a/Src/Conn/C4D.Conn.Firedac.pas +++ b/Src/Conn/C4D.Conn.Firedac.pas @@ -22,6 +22,10 @@ interface Firedac.Comp.Client, Firedac.DApt, Firedac.Comp.UI, + //FIREBIRD + FireDAC.Phys.IBBase, + FireDAC.Phys.FB, + //MySQL Firedac.Phys.MySQLDef, Firedac.Phys.MySQL, C4D.Conn.Interfaces, @@ -34,7 +38,10 @@ TC4DConnFiredac = class(TInterfacedObject, IC4DConnection) [weak] FC4DConnConfigs: TC4DConnConfigs; FConnection: TFDConnection; + FMySQLDriverLink: TFDPhysMySQLDriverLink; + FFBDriverLink: TFDPhysFBDriverLink; function TestFieldsComponentConnection: IC4DConnection; + procedure ConfigDrivers; protected function Component: TComponent; function Open: IC4DConnection; @@ -63,11 +70,18 @@ constructor TC4DConnFiredac.Create(AC4DConnConfigs: TC4DConnConfigs); FC4DConnConfigs := AC4DConnConfigs; FConnection := TFDConnection.Create(nil); FConnection.LoginPrompt := False; + + FMySQLDriverLink := TFDPhysMySQLDriverLink.Create(nil); + FFBDriverLink := TFDPhysFBDriverLink.Create(nil); + Self.LoadConnectionConfig; end; destructor TC4DConnFiredac.Destroy; begin + FFBDriverLink.Free; + FMySQLDriverLink.Free; + FConnection.Close; FreeAndNil(FConnection); @@ -86,14 +100,26 @@ function TC4DConnFiredac.LoadConnectionConfig: IC4DConnection; FConnection.Params.Add('Server=' + FC4DConnConfigs.Host); if FC4DConnConfigs.Port > 0 then FConnection.Params.Add('Port=' + FC4DConnConfigs.Port.ToString); + +// FConnection.TXOptions.AutoStart := True; +// FConnection.TXOptions.AutoStop := True; +// FConnection.TXOptions.AutoCommit := True; +// FConnection.TxOptions.StopOptions := [xoIfAutoStarted, xoFinishRetaining]; +// FConnection.UpdateOptions.AutoCommitUpdates := True; +// FConnection.UpdateOptions.RefreshMode := rmAll; + + Self.ConfigDrivers; end; -{FConnection.TXOptions.AutoStart := True; - FConnection.TXOptions.AutoStop := True; - FConnection.TXOptions.AutoCommit := True; - FConnection.TxOptions.StopOptions := [xoIfAutoStarted, xoFinishRetaining]; - FConnection.UpdateOptions.AutoCommitUpdates := True; - FConnection.UpdateOptions.RefreshMode := rmAll; } +procedure TC4DConnFiredac.ConfigDrivers; +begin + case FC4DConnConfigs.DriverID of + TC4DDriverID.MySQL: + FMySQLDriverLink.VendorLib := FC4DConnConfigs.VendorLib; + TC4DDriverID.Firebird: + FFBDriverLink.VendorLib := FC4DConnConfigs.VendorLib; + end; +end; function TC4DConnFiredac.Component: TComponent; begin diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm index dd471ae..847f7ce 100644 --- a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm +++ b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm @@ -237,9 +237,8 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView object edtVendorLib: TEdit Left = 31 Top = 180 - Width = 606 + Width = 581 Height = 21 - PasswordChar = '*' TabOrder = 7 end object ckVisible: TCheckBox @@ -261,5 +260,15 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView TabOrder = 9 OnClick = Button1Click end + object Button2: TButton + Left = 613 + Top = 179 + Width = 24 + Height = 23 + Cursor = crHandPoint + Caption = '...' + TabOrder = 10 + OnClick = Button1Click + end end end diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas index 18aeae9..0f75445 100644 --- a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas +++ b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas @@ -44,6 +44,7 @@ TDelphiAIDevDatabasesAddEditView = class(TForm) lbAddLocalDatabase: TLabel; Button1: TButton; btnTestConnection: TButton; + Button2: TButton; procedure btnCloseClick(Sender: TObject); procedure btnConfirmClick(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); diff --git a/Src/Databases/DelphiAIDev.Databases.Model.pas b/Src/Databases/DelphiAIDev.Databases.Model.pas index a9586e2..d96c23e 100644 --- a/Src/Databases/DelphiAIDev.Databases.Model.pas +++ b/Src/Databases/DelphiAIDev.Databases.Model.pas @@ -38,6 +38,7 @@ implementation PASSWORD = 'password'; PORT = 'port'; DATABASE_NAME = 'database_name'; + VENDOR_LIB = 'vendor_lib'; VISIBLE = 'visible'; class function TDelphiAIDevDatabasesModel.New: IDelphiAIDevDatabasesModel; @@ -89,7 +90,12 @@ procedure TDelphiAIDevDatabasesModel.ReadData(AProc: TProc(PASSWORD)); LFields.Port := LJSONObjItem.GetValue(PORT); LFields.DatabaseName := LJSONObjItem.GetValue(DATABASE_NAME); - LFields.Visible := LJSONObjItem.GetValue(VISIBLE); + + if LJSONObjItem.GetValue(VENDOR_LIB) <> nil then + LFields.VendorLib := LJSONObjItem.GetValue(VENDOR_LIB); + + if LJSONObjItem.GetValue(VISIBLE) <> nil then + LFields.Visible := LJSONObjItem.GetValue(VISIBLE); AProc(LFields); end; finally @@ -134,6 +140,7 @@ procedure TDelphiAIDevDatabasesModel.SaveData(AFields: TDelphiAIDevDatabasesFiel LJSONObject.AddPair(PASSWORD, TUtilsCrypt.Encrypt(AFields.Password)); LJSONObject.AddPair(PORT, TJSONNumber.Create(AFields.Port)); LJSONObject.AddPair(DATABASE_NAME, AFields.DatabaseName); + LJSONObject.AddPair(VENDOR_LIB, AFields.VendorLib); LJSONObject.AddPair(VISIBLE, TJSONBool.Create(AFields.Visible)); LJSONArray.AddElement(LJSONObject); @@ -199,6 +206,9 @@ procedure TDelphiAIDevDatabasesModel.EditData(AFields: TDelphiAIDevDatabasesFiel LJSONObjItem.RemovePair(DATABASE_NAME).Free; LJSONObjItem.AddPair(DATABASE_NAME, AFields.DatabaseName); + LJSONObjItem.RemovePair(VENDOR_LIB).Free; + LJSONObjItem.AddPair(VENDOR_LIB, AFields.VendorLib); + LJSONObjItem.RemovePair(VISIBLE).Free; LJSONObjItem.AddPair(VISIBLE, TJSONBool.Create(AFields.Visible)); From e0688de3ce7a507cf7cbdce5910e75a724be6713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 13 Aug 2024 10:27:15 -0300 Subject: [PATCH 009/109] bk/2024-08-13-1027 --- Src/Conn/C4D.Conn.Firedac.pas | 22 +++--------- Src/Conn/C4D.Conn.Interfaces.pas | 1 - Src/Databases/DelphiAIDev.Databases.Model.pas | 34 +++++++++++++++---- Src/Databases/DelphiAIDev.Databases.View.dfm | 1 - Src/Utils/DelphiAIDev.Utils.pas | 11 ++++++ 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/Src/Conn/C4D.Conn.Firedac.pas b/Src/Conn/C4D.Conn.Firedac.pas index cd6f6e5..3c9e4ef 100644 --- a/Src/Conn/C4D.Conn.Firedac.pas +++ b/Src/Conn/C4D.Conn.Firedac.pas @@ -30,7 +30,8 @@ interface Firedac.Phys.MySQL, C4D.Conn.Interfaces, C4D.Conn.Configs, - DelphiAIDev.Types; + DelphiAIDev.Types, + DelphiAIDev.Utils; type TC4DConnFiredac = class(TInterfacedObject, IC4DConnection) @@ -50,7 +51,6 @@ TC4DConnFiredac = class(TInterfacedObject, IC4DConnection) function Commit: IC4DConnection; function Rollback: IC4DConnection; function TestConnection: Boolean; - function TestConnectionOnly: Boolean; function LoadConnectionConfig: IC4DConnection; public class function New(AC4DConnConfigs: TC4DConnConfigs): IC4DConnection; @@ -79,6 +79,7 @@ constructor TC4DConnFiredac.Create(AC4DConnConfigs: TC4DConnConfigs); destructor TC4DConnFiredac.Destroy; begin + TUtils.ShowMsg('TC4DConnFiredac.Destroy'); FFBDriverLink.Free; FMySQLDriverLink.Free; @@ -161,6 +162,7 @@ function TC4DConnFiredac.TestConnection: Boolean; Self.TestFieldsComponentConnection; try LConnectedOld := FConnection.Connected; + FConnection.Close; // FConnection.Open; Result := FConnection.Connected; @@ -172,22 +174,6 @@ function TC4DConnFiredac.TestConnection: Boolean; end; end; -function TC4DConnFiredac.TestConnectionOnly: Boolean; -var - LConnectedOld: Boolean; -begin - Result := False; - try - LConnectedOld := FConnection.Connected; - FConnection.Open; - Result := FConnection.Connected; - - if FConnection.Connected <> LConnectedOld then - FConnection.Connected := LConnectedOld; - except - end; -end; - function TC4DConnFiredac.TestFieldsComponentConnection: IC4DConnection; var LEmptyFields: string; diff --git a/Src/Conn/C4D.Conn.Interfaces.pas b/Src/Conn/C4D.Conn.Interfaces.pas index 6a7bd08..b5286e4 100644 --- a/Src/Conn/C4D.Conn.Interfaces.pas +++ b/Src/Conn/C4D.Conn.Interfaces.pas @@ -18,7 +18,6 @@ interface function Rollback: IC4DConnection; function TestConnection: Boolean; - function TestConnectionOnly: Boolean; function LoadConnectionConfig: IC4DConnection; end; diff --git a/Src/Databases/DelphiAIDev.Databases.Model.pas b/Src/Databases/DelphiAIDev.Databases.Model.pas index d96c23e..7d11c32 100644 --- a/Src/Databases/DelphiAIDev.Databases.Model.pas +++ b/Src/Databases/DelphiAIDev.Databases.Model.pas @@ -82,20 +82,40 @@ procedure TDelphiAIDevDatabasesModel.ReadData(AProc: TProc(GUID); - LFields.DriverID := TC4DDriverID(LJSONObjItem.GetValue(DRIVER_ID)); - LFields.Description := LJSONObjItem.GetValue(DESCRIPTION); - LFields.Host := LJSONObjItem.GetValue(HOST); - LFields.User := LJSONObjItem.GetValue(USER); - LFields.Password := TUtilsCrypt.Decrypt(LJSONObjItem.GetValue(PASSWORD)); - LFields.Port := LJSONObjItem.GetValue(PORT); - LFields.DatabaseName := LJSONObjItem.GetValue(DATABASE_NAME); + + if LJSONObjItem.GetValue(DRIVER_ID) <> nil then + LFields.DriverID := TC4DDriverID(LJSONObjItem.GetValue(DRIVER_ID)); + + if LJSONObjItem.GetValue(DESCRIPTION) <> nil then + LFields.Description := LJSONObjItem.GetValue(DESCRIPTION); + + if LJSONObjItem.GetValue(HOST) <> nil then + LFields.Host := LJSONObjItem.GetValue(HOST); + + if LJSONObjItem.GetValue(USER) <> nil then + LFields.User := LJSONObjItem.GetValue(USER); + + if LJSONObjItem.GetValue(PASSWORD) <> nil then + LFields.Password := TUtilsCrypt.Decrypt(LJSONObjItem.GetValue(PASSWORD)); + + if LJSONObjItem.GetValue(PORT) <> nil then + LFields.Port := LJSONObjItem.GetValue(PORT); + + if LJSONObjItem.GetValue(DATABASE_NAME) <> nil then + LFields.DatabaseName := LJSONObjItem.GetValue(DATABASE_NAME); if LJSONObjItem.GetValue(VENDOR_LIB) <> nil then LFields.VendorLib := LJSONObjItem.GetValue(VENDOR_LIB); if LJSONObjItem.GetValue(VISIBLE) <> nil then LFields.Visible := LJSONObjItem.GetValue(VISIBLE); + AProc(LFields); end; finally diff --git a/Src/Databases/DelphiAIDev.Databases.View.dfm b/Src/Databases/DelphiAIDev.Databases.View.dfm index 9b5e435..c4b68be 100644 --- a/Src/Databases/DelphiAIDev.Databases.View.dfm +++ b/Src/Databases/DelphiAIDev.Databases.View.dfm @@ -118,7 +118,6 @@ object DelphiAIDevDatabasesView: TDelphiAIDevDatabasesView Width = 100 end item - Alignment = taCenter Caption = 'User' Width = 90 end diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index a4c5a82..3a9fe5c 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -11,6 +11,10 @@ interface System.StrUtils, System.Classes, System.TypInfo, + + System.JSON, + System.Generics.Collections, + Vcl.Controls, Vcl.Forms, Vcl.Graphics, @@ -27,6 +31,7 @@ TUtils = class class function ShowMsgInternal(const AMsg, ADetails: string; const AIcon: TC4DIcon; const AButtons: TC4DButtons; const ABtnFocu: TC4DBtnFocu; const AWinControlFocu: TWinControl): Boolean; public + class procedure TryGetValueJson(const AJSONObject: TJSONObject; const AKey: string; AResult: T); class function GetExceptionMessage(const E: Exception): string; class function StrToDefaultsQuestionsKind(Value: string): TC4DQuestionKind; class function StrToDriverID(Value: string): TC4DDriverID; @@ -140,6 +145,12 @@ implementation DelphiAIDev.View.Dialog, DelphiAIDev.WaitingScreen; +class procedure TUtils.TryGetValueJson(const AJSONObject: TJSONObject; const AKey: string; AResult: T); +begin + if AJSONObject.GetValue(AKey) <> nil then + AResult := AJSONObject.GetValue(AKey); +end; + class function TUtils.GetExceptionMessage(const E: Exception): string; begin Result := E.Message; From 7dd35ed5a5cffe4874c85457478cb5a35919acef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 13 Aug 2024 10:38:47 -0300 Subject: [PATCH 010/109] Update C4D.Conn.Firedac.pas --- Src/Conn/C4D.Conn.Firedac.pas | 1 + 1 file changed, 1 insertion(+) diff --git a/Src/Conn/C4D.Conn.Firedac.pas b/Src/Conn/C4D.Conn.Firedac.pas index 3c9e4ef..ce13d55 100644 --- a/Src/Conn/C4D.Conn.Firedac.pas +++ b/Src/Conn/C4D.Conn.Firedac.pas @@ -161,6 +161,7 @@ function TC4DConnFiredac.TestConnection: Boolean; begin Self.TestFieldsComponentConnection; try + Self.LoadConnectionConfig; LConnectedOld := FConnection.Connected; FConnection.Close; // FConnection.Open; From cb98190b4ef97ef556a2bd179172c299471d7149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 13 Aug 2024 13:22:08 -0300 Subject: [PATCH 011/109] bk/2024-08-13-1322 --- Src/Conn/C4D.Conn.Configs.pas | 35 +++++-------- Src/Conn/C4D.Conn.Firedac.pas | 3 ++ Src/Conn/C4D.Conn.pas | 42 ++++++--------- .../DelphiAIDev.Databases.AddEdit.View.dfm | 42 ++++++++++----- .../DelphiAIDev.Databases.AddEdit.View.pas | 51 +++++++++---------- Src/Databases/DelphiAIDev.Databases.Model.pas | 1 - Src/Databases/DelphiAIDev.Databases.View.dfm | 4 +- Src/Databases/DelphiAIDev.Databases.View.pas | 5 +- 8 files changed, 89 insertions(+), 94 deletions(-) diff --git a/Src/Conn/C4D.Conn.Configs.pas b/Src/Conn/C4D.Conn.Configs.pas index c25ddee..48192cf 100644 --- a/Src/Conn/C4D.Conn.Configs.pas +++ b/Src/Conn/C4D.Conn.Configs.pas @@ -12,7 +12,6 @@ interface TC4DConnConfigs = class private FComponentConnection: TComponentConnection; - FConnectionSingleton: Boolean; FDriverID: TC4DDriverID; FHost: string; FUserName: string; @@ -20,13 +19,11 @@ TC4DConnConfigs = class FDatabase: string; FPort: Integer; FVendorLib: string; + procedure Clear; public constructor Create; destructor Destroy; override; function ComponentConnection: TComponentConnection; - function ConnectionSingleton: Boolean; - function ConnectionSingletonON: TC4DConnConfigs; - function ConnectionSingletonOFF: TC4DConnConfigs; function DriverID: TC4DDriverID; overload; function DriverID(Value: TC4DDriverID): TC4DConnConfigs; overload; function Host: string; overload; @@ -48,7 +45,7 @@ implementation constructor TC4DConnConfigs.Create; begin - FConnectionSingleton := True; + Self.Clear; {$IFDEF C4D_ZEOS} FComponentConnection := TComponentConnection.Zeos; @@ -62,6 +59,17 @@ destructor TC4DConnConfigs.Destroy; inherited; end; +procedure TC4DConnConfigs.Clear; +begin + FDriverID := TC4DDriverID.None;; + FHost := ''; + FUserName := ''; + FPassword := ''; + FDatabase := ''; + FPort := 0; + FVendorLib := ''; +end; + function TC4DConnConfigs.ComponentConnection: TComponentConnection; begin if FComponentConnection = TComponentConnection.Empty then @@ -70,23 +78,6 @@ function TC4DConnConfigs.ComponentConnection: TComponentConnection; Result := FComponentConnection; end; -function TC4DConnConfigs.ConnectionSingleton: Boolean; -begin - Result := FConnectionSingleton; -end; - -function TC4DConnConfigs.ConnectionSingletonON: TC4DConnConfigs; -begin - Result := Self; - FConnectionSingleton := True; -end; - -function TC4DConnConfigs.ConnectionSingletonOFF: TC4DConnConfigs; -begin - Result := Self; - FConnectionSingleton := False; -end; - function TC4DConnConfigs.DriverID: TC4DDriverID; begin Result := FDriverID; diff --git a/Src/Conn/C4D.Conn.Firedac.pas b/Src/Conn/C4D.Conn.Firedac.pas index ce13d55..50f0b16 100644 --- a/Src/Conn/C4D.Conn.Firedac.pas +++ b/Src/Conn/C4D.Conn.Firedac.pas @@ -114,6 +114,9 @@ function TC4DConnFiredac.LoadConnectionConfig: IC4DConnection; procedure TC4DConnFiredac.ConfigDrivers; begin + FMySQLDriverLink.VendorLib := ''; + FFBDriverLink.VendorLib := ''; + case FC4DConnConfigs.DriverID of TC4DDriverID.MySQL: FMySQLDriverLink.VendorLib := FC4DConnConfigs.VendorLib; diff --git a/Src/Conn/C4D.Conn.pas b/Src/Conn/C4D.Conn.pas index 204d725..af36471 100644 --- a/Src/Conn/C4D.Conn.pas +++ b/Src/Conn/C4D.Conn.pas @@ -39,8 +39,8 @@ TC4DConn = class(TInterfacedObject, IC4DConn) //function C4DConn: IC4DConn; -var - Instance: IC4DConn; +//var +// Instance: IC4DConn; implementation @@ -64,13 +64,13 @@ destructor TC4DConn.Destroy; inherited; end; -function C4DConn: IC4DConn; -begin - if not Assigned(Instance) then - Instance := TC4DConn.New; - - Result := Instance; -end; +//function C4DConn: IC4DConn; +//begin +// if not Assigned(Instance) then +// Instance := TC4DConn.New; +// +// Result := Instance; +//end; function TC4DConn.Configs: TC4DConnConfigs; begin @@ -86,26 +86,14 @@ function TC4DConn.CountNameQuery: Integer; function TC4DConn.Connection: IC4DConnection; begin {$IFDEF C4D_ZEOS} - if FC4DConnConfigs.ConnectionSingleton then - begin - if not Assigned(FC4DConnInstance) then - FC4DConnInstance := TC4DConnZeos.New(FC4DConnConfigs); - - Result := FC4DConnInstance; - end - else - Result := TC4DConnZeos.New(FC4DConnConfigs); + if not Assigned(FC4DConnInstance) then + FC4DConnInstance := TC4DConnZeos.New(FC4DConnConfigs); {$ELSE} - if FC4DConnConfigs.ConnectionSingleton then - begin - if not Assigned(FC4DConnInstance) then - FC4DConnInstance := TC4DConnFiredac.New(FC4DConnConfigs); - - Result := FC4DConnInstance; - end - else - Result := TC4DConnFiredac.New(FC4DConnConfigs); + if not Assigned(FC4DConnInstance) then + FC4DConnInstance := TC4DConnFiredac.New(FC4DConnConfigs); {$ENDIF} + + Result := FC4DConnInstance; end; function TC4DConn.Query: IC4DConnQuery; diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm index 847f7ce..e096ffa 100644 --- a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm +++ b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm @@ -103,6 +103,7 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView BevelOuter = bvNone ParentBackground = False TabOrder = 0 + ExplicitTop = -2 object Bevel1: TBevel AlignWithMargins = True Left = 0 @@ -169,9 +170,9 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView object Label8: TLabel Left = 31 Top = 164 - Width = 47 + Width = 68 Height = 13 - Caption = 'VendorLib' + Caption = 'VendorLib (dll)' end object lbAddLocalDatabase: TLabel Left = 465 @@ -230,16 +231,9 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView object edtDatabase: TEdit Left = 31 Top = 135 - Width = 606 - Height = 21 - TabOrder = 6 - end - object edtVendorLib: TEdit - Left = 31 - Top = 180 Width = 581 Height = 21 - TabOrder = 7 + TabOrder = 6 end object ckVisible: TCheckBox Left = 31 @@ -250,7 +244,7 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView Caption = 'Visible' TabOrder = 8 end - object Button1: TButton + object edtPasswordView: TButton Left = 400 Top = 84 Width = 34 @@ -258,9 +252,10 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView Cursor = crHandPoint Caption = 'View' TabOrder = 9 - OnClick = Button1Click + TabStop = False + OnClick = edtPasswordViewClick end - object Button2: TButton + object btnVendorLibSearch: TButton Left = 613 Top = 179 Width = 24 @@ -268,7 +263,26 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView Cursor = crHandPoint Caption = '...' TabOrder = 10 - OnClick = Button1Click + TabStop = False + OnClick = btnVendorLibSearchClick + end + object edtVendorLib: TEdit + Left = 31 + Top = 180 + Width = 581 + Height = 21 + TabOrder = 7 + end + object btnDatabaseSearch: TButton + Left = 613 + Top = 134 + Width = 24 + Height = 23 + Cursor = crHandPoint + Caption = '...' + TabOrder = 11 + TabStop = False + OnClick = btnDatabaseSearchClick end end end diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas index 0f75445..e3b9871 100644 --- a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas +++ b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas @@ -39,20 +39,23 @@ TDelphiAIDevDatabasesAddEditView = class(TForm) Label4: TLabel; edtDatabase: TEdit; Label8: TLabel; - edtVendorLib: TEdit; ckVisible: TCheckBox; lbAddLocalDatabase: TLabel; - Button1: TButton; + edtPasswordView: TButton; btnTestConnection: TButton; - Button2: TButton; + btnVendorLibSearch: TButton; + edtVendorLib: TEdit; + btnDatabaseSearch: TButton; procedure btnCloseClick(Sender: TObject); procedure btnConfirmClick(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormShow(Sender: TObject); procedure FormCreate(Sender: TObject); procedure lbAddLocalDatabaseClick(Sender: TObject); - procedure Button1Click(Sender: TObject); + procedure edtPasswordViewClick(Sender: TObject); procedure btnTestConnectionClick(Sender: TObject); + procedure btnVendorLibSearchClick(Sender: TObject); + procedure btnDatabaseSearchClick(Sender: TObject); private FFields: TDelphiAIDevDatabasesFields; procedure FillcBoxDriverID; @@ -72,12 +75,6 @@ implementation {$R *.dfm} -procedure TDelphiAIDevDatabasesAddEditView.FillcBoxDriverID; -begin - cBoxDriverID.Items.Clear; - TUtils.DriverIDFillItemsTStrings(cBoxDriverID.Items); -end; - procedure TDelphiAIDevDatabasesAddEditView.FormCreate(Sender: TObject); begin Self.ModalResult := mrCancel; @@ -91,6 +88,13 @@ procedure TDelphiAIDevDatabasesAddEditView.FormShow(Sender: TObject); edtDescription.SetFocus end; +procedure TDelphiAIDevDatabasesAddEditView.FillcBoxDriverID; +begin + cBoxDriverID.Items.Clear; + TUtils.DriverIDFillItemsTStrings(cBoxDriverID.Items); +end; + + procedure TDelphiAIDevDatabasesAddEditView.lbAddLocalDatabaseClick(Sender: TObject); begin edtHost.Text := 'localhost'; @@ -156,7 +160,7 @@ procedure TDelphiAIDevDatabasesAddEditView.ValidateFillingFields; TUtils.ShowMsgAndAbort('No informed Database', edtDatabase); end; -procedure TDelphiAIDevDatabasesAddEditView.Button1Click(Sender: TObject); +procedure TDelphiAIDevDatabasesAddEditView.edtPasswordViewClick(Sender: TObject); begin if edtPassword.PasswordChar = '*' then edtPassword.PasswordChar := #0 @@ -202,23 +206,16 @@ procedure TDelphiAIDevDatabasesAddEditView.btnTestConnectionClick(Sender: TObjec finally Screen.Cursor := crDefault; end; +end; - //Self.ValidateFillingFields; - -// Screen.Cursor := crHourGlass; -// try -// C4DConn.Configs -// .Host(edtHost.Text) -// .UserName(edtUser.Text) -// .Password(edtPassword.Text) -// .Port(StrToIntDef(edtPort.Text, 0)) -// .Database(edtDatabase.Text) -// .VendorLib(edtVendorLib.Text); -// -// C4DConn.Connection.TestConnection; -// finally -// Screen.Cursor := crDefault; -// end; +procedure TDelphiAIDevDatabasesAddEditView.btnDatabaseSearchClick(Sender: TObject); +begin + edtDatabase.Text := TUtils.SelectFile(edtDatabase.Text); +end; + +procedure TDelphiAIDevDatabasesAddEditView.btnVendorLibSearchClick(Sender: TObject); +begin + edtVendorLib.Text := TUtils.SelectFile(edtVendorLib.Text); end; end. diff --git a/Src/Databases/DelphiAIDev.Databases.Model.pas b/Src/Databases/DelphiAIDev.Databases.Model.pas index 7d11c32..5e52e75 100644 --- a/Src/Databases/DelphiAIDev.Databases.Model.pas +++ b/Src/Databases/DelphiAIDev.Databases.Model.pas @@ -156,7 +156,6 @@ procedure TDelphiAIDevDatabasesModel.SaveData(AFields: TDelphiAIDevDatabasesFiel LJSONObject.AddPair(DESCRIPTION, AFields.Description); LJSONObject.AddPair(HOST, AFields.Host); LJSONObject.AddPair(USER, AFields.User); - //TUtils.ShowMsg(TUtilsCrypt.Encrypt(AFields.Password)); LJSONObject.AddPair(PASSWORD, TUtilsCrypt.Encrypt(AFields.Password)); LJSONObject.AddPair(PORT, TJSONNumber.Create(AFields.Port)); LJSONObject.AddPair(DATABASE_NAME, AFields.DatabaseName); diff --git a/Src/Databases/DelphiAIDev.Databases.View.dfm b/Src/Databases/DelphiAIDev.Databases.View.dfm index c4b68be..621f32f 100644 --- a/Src/Databases/DelphiAIDev.Databases.View.dfm +++ b/Src/Databases/DelphiAIDev.Databases.View.dfm @@ -141,12 +141,12 @@ object DelphiAIDevDatabasesView: TDelphiAIDevDatabasesView Width = 1 end item - Caption = 'Guid' + Caption = 'VendorLib' MaxWidth = 1 Width = 1 end item - Caption = 'VendorLib' + Caption = 'Guid' MaxWidth = 1 Width = 1 end> diff --git a/Src/Databases/DelphiAIDev.Databases.View.pas b/Src/Databases/DelphiAIDev.Databases.View.pas index 0418ee5..6c007fe 100644 --- a/Src/Databases/DelphiAIDev.Databases.View.pas +++ b/Src/Databases/DelphiAIDev.Databases.View.pas @@ -70,7 +70,8 @@ implementation C_INDEX_SUBITEM_DatabaseName = 4; C_INDEX_SUBITEM_Visible = 5; C_INDEX_SUBITEM_Password = 6; - C_INDEX_SUBITEM_Guid = 7; + C_INDEX_SUBITEM_VendorLib = 7; + C_INDEX_SUBITEM_Guid = 8; procedure TDelphiAIDevDatabasesView.FormCreate(Sender: TObject); begin @@ -190,6 +191,7 @@ procedure TDelphiAIDevDatabasesView.ReloadDataInternal; LListItem.SubItems.Add(AFields.DatabaseName); LListItem.SubItems.Add(TUtils.BoolToStrC4D(AFields.Visible)); LListItem.SubItems.Add(AFields.Password); + LListItem.SubItems.Add(AFields.VendorLib); LListItem.SubItems.Add(AFields.Guid); end; end @@ -227,6 +229,7 @@ procedure TDelphiAIDevDatabasesView.FillFieldsWithSelectedItem(var AFields: TDel AFields.DatabaseName := LListItem.SubItems[C_INDEX_SUBITEM_DatabaseName]; AFields.Visible := TUtils.StrToBoolC4D(LListItem.SubItems[C_INDEX_SUBITEM_Visible]); AFields.Password := LListItem.SubItems[C_INDEX_SUBITEM_Password]; + AFields.VendorLib := LListItem.SubItems[C_INDEX_SUBITEM_VendorLib]; AFields.Guid := LListItem.SubItems[C_INDEX_SUBITEM_Guid]; end; From 57c1827104e0a14e77964c2eeea141b48339307c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 13 Aug 2024 13:24:58 -0300 Subject: [PATCH 012/109] Update DelphiAIDev.Databases.AddEdit.View.pas --- Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas | 1 - 1 file changed, 1 deletion(-) diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas index e3b9871..40a8636 100644 --- a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas +++ b/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas @@ -94,7 +94,6 @@ procedure TDelphiAIDevDatabasesAddEditView.FillcBoxDriverID; TUtils.DriverIDFillItemsTStrings(cBoxDriverID.Items); end; - procedure TDelphiAIDevDatabasesAddEditView.lbAddLocalDatabaseClick(Sender: TObject); begin edtHost.Text := 'localhost'; From 0c4202b214b7fb15648f658360e2b987af1bc787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 13 Aug 2024 14:09:39 -0300 Subject: [PATCH 013/109] refactor/parenteses --- Src/Chat/DelphiAIDev.Chat.View.pas | 8 ++++---- Src/Utils/DelphiAIDev.Utils.OTA.pas | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index fe424a3..8510f44 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -159,10 +159,10 @@ implementation procedure RegisterSelf; begin - if(not Assigned(DelphiAIDevChatView))then + if not Assigned(DelphiAIDevChatView) then DelphiAIDevChatView := TDelphiAIDevChatView.Create(nil); - if(@RegisterFieldAddress <> nil)then + if @RegisterFieldAddress <> nil then RegisterFieldAddress(DelphiAIDevChatView.Name, @DelphiAIDevChatView); RegisterDesktopFormClass(TDelphiAIDevChatView, DelphiAIDevChatView.Name, DelphiAIDevChatView.Name); @@ -170,7 +170,7 @@ procedure RegisterSelf; procedure Unregister; begin - if(@UnRegisterFieldAddress <> nil)then + if @UnRegisterFieldAddress <> nil then UnRegisterFieldAddress(@DelphiAIDevChatView); FreeAndNil(DelphiAIDevChatView); end; @@ -344,7 +344,7 @@ procedure TDelphiAIDevChatView.FormResize(Sender: TObject); procedure TDelphiAIDevChatView.FillMemoReturnWithFile; begin - if(FileExists(TUtils.GetPathFileChat))then + if FileExists(TUtils.GetPathFileChat) then mmReturn.Lines.LoadFromFile(TUtils.GetPathFileChat) end; diff --git a/Src/Utils/DelphiAIDev.Utils.OTA.pas b/Src/Utils/DelphiAIDev.Utils.OTA.pas index a281483..b1d3f04 100644 --- a/Src/Utils/DelphiAIDev.Utils.OTA.pas +++ b/Src/Utils/DelphiAIDev.Utils.OTA.pas @@ -412,7 +412,7 @@ class function TUtilsOTA.CheckIfExistFileInCurrentsProjectGroups(const ANameFile for LContFile := 0 to Pred(LIOTAProjectCurrent.GetModuleCount) do begin LFilePath := LIOTAProjectCurrent.GetModule(LContFile).FileName; - if(LFilePath.Trim.IsEmpty)then + if LFilePath.Trim.IsEmpty then Continue; if(ExtractFileName(LFilePath) = ANameFileWithExtension)then @@ -700,7 +700,7 @@ class function TUtilsOTA.GetCurrentModule: IOTAModule; begin Result := nil; LIOTAModuleServices := Self.GetIOTAModuleServices; - if(LIOTAModuleServices <> nil)then + if LIOTAModuleServices <> nil then Result := LIOTAModuleServices.CurrentModule; end; @@ -710,7 +710,7 @@ class function TUtilsOTA.GetCurrentModuleFileName: string; begin Result := ''; LIOTAModule := Self.GetCurrentModule; - if(Assigned(LIOTAModule))then + if Assigned(LIOTAModule) then Result := LIOTAModule.FileName.Trim; end; @@ -720,7 +720,7 @@ class function TUtilsOTA.GetModule(const AFileName: string): IOTAModule; begin Result := nil; LIOTAModuleServices := Self.GetIOTAModuleServices; - if(LIOTAModuleServices <> nil)then + if LIOTAModuleServices <> nil then Result := LIOTAModuleServices.FindModule(AFileName); end; @@ -897,7 +897,7 @@ class procedure TUtilsOTA.GetAllFilesFromProjectGroup(AListFiles: TStrings; for LContFile := 0 to Pred(LIOTAProjectCurrent.GetModuleCount) do begin LFilePath := LIOTAProjectCurrent.GetModule(LContFile).FileName; - if(LFilePath.Trim.IsEmpty)then + if LFilePath.Trim.IsEmpty then Continue; if(not AC4DExtensions.ContainsStr(ExtractFileExt(LFilePath)))then From e2ed31b5993ff4b08cd82ca856d05bad2d63b49a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 13 Aug 2024 14:25:08 -0300 Subject: [PATCH 014/109] refactor/databases-for-DBRegisters --- Package/DelphiAIDeveloper.dpk | 10 +-- Package/DelphiAIDeveloper.dproj | 14 ++-- ...DelphiAIDev.DB.Registers.AddEdit.View.dfm} | 3 +- ...DelphiAIDev.DB.Registers.AddEdit.View.pas} | 42 +++++------ .../DelphiAIDev.DB.Registers.Fields.pas} | 8 +-- .../DelphiAIDev.DB.Registers.Interfaces.pas | 19 +++++ .../DelphiAIDev.DB.Registers.Model.pas} | 34 ++++----- .../DelphiAIDev.DB.Registers.View.dfm} | 2 +- .../DelphiAIDev.DB.Registers.View.pas} | 70 +++++++++---------- .../DelphiAIDev.Databases.Interfaces.pas | 19 ----- Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas | 6 +- 11 files changed, 113 insertions(+), 114 deletions(-) rename Src/{Databases/DelphiAIDev.Databases.AddEdit.View.dfm => DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm} (98%) rename Src/{Databases/DelphiAIDev.Databases.AddEdit.View.pas => DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas} (76%) rename Src/{Databases/DelphiAIDev.Databases.Fields.pas => DB/Registers/DelphiAIDev.DB.Registers.Fields.pas} (87%) create mode 100644 Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas rename Src/{Databases/DelphiAIDev.Databases.Model.pas => DB/Registers/DelphiAIDev.DB.Registers.Model.pas} (87%) rename Src/{Databases/DelphiAIDev.Databases.View.dfm => DB/Registers/DelphiAIDev.DB.Registers.View.dfm} (98%) rename Src/{Databases/DelphiAIDev.Databases.View.pas => DB/Registers/DelphiAIDev.DB.Registers.View.pas} (78%) delete mode 100644 Src/Databases/DelphiAIDev.Databases.Interfaces.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index eca73b9..d828d69 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -69,13 +69,13 @@ contains DelphiAIDev.IDE.ImageListMain in '..\Src\IDE\ImageListMain\DelphiAIDev.IDE.ImageListMain.pas', DelphiAIDev.IDE.Shortcuts in '..\Src\IDE\Shortcuts\DelphiAIDev.IDE.Shortcuts.pas', DelphiAIDev.Utils.CnWizard in '..\Src\Utils\DelphiAIDev.Utils.CnWizard.pas', - DelphiAIDev.Databases.View in '..\Src\Databases\DelphiAIDev.Databases.View.pas' {DelphiAIDevDatabasesView}, + DelphiAIDev.DB.Registers.View in '..\Src\DB\Registers\DelphiAIDev.DB.Registers.View.pas' {DelphiAIDevDBRegistersView}, DelphiAIDev.Utils.ListView in '..\Src\Utils\DelphiAIDev.Utils.ListView.pas', DelphiAIDev.Utils.GetIniPositionStr in '..\Src\Utils\DelphiAIDev.Utils.GetIniPositionStr.pas', DelphiAIDev.DefaultsQuestions.Fields in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.Fields.pas', DelphiAIDev.DefaultsQuestions.Interfaces in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.Interfaces.pas', DelphiAIDev.DefaultsQuestions.Model in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.Model.pas', - DelphiAIDev.Databases.AddEdit.View in '..\Src\Databases\DelphiAIDev.Databases.AddEdit.View.pas' {DelphiAIDevDatabasesAddEditView}, + DelphiAIDev.DB.Registers.AddEdit.View in '..\Src\DB\Registers\DelphiAIDev.DB.Registers.AddEdit.View.pas' {DelphiAIDevDBRegistersAddEditView}, DelphiAIDev.DefaultsQuestions.PopupMenu in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.PopupMenu.pas', DelphiAIDev.Utils.ABMenuAction in '..\Src\Utils\DelphiAIDev.Utils.ABMenuAction.pas', DelphiAIDev.IDE.Splash in '..\Src\IDE\Splash\DelphiAIDev.IDE.Splash.pas', @@ -84,9 +84,9 @@ contains DelphiAIDev.PopupMenuProjects in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.pas', DelphiAIDev.PopupMenuProjects.Item in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.Item.pas', DelphiAIDev.DefaultsQuestions.View in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.View.pas' {DelphiAIDevDefaultsQuestionsView}, - DelphiAIDev.Databases.Model in '..\Src\Databases\DelphiAIDev.Databases.Model.pas', - DelphiAIDev.Databases.Interfaces in '..\Src\Databases\DelphiAIDev.Databases.Interfaces.pas', - DelphiAIDev.Databases.Fields in '..\Src\Databases\DelphiAIDev.Databases.Fields.pas', + DelphiAIDev.DB.Registers.Model in '..\Src\DB\Registers\DelphiAIDev.DB.Registers.Model.pas', + DelphiAIDev.DB.Registers.Interfaces in '..\Src\DB\Registers\DelphiAIDev.DB.Registers.Interfaces.pas', + DelphiAIDev.DB.Registers.Fields in '..\Src\DB\Registers\DelphiAIDev.DB.Registers.Fields.pas', DelphiAIDev.DefaultsQuestions.AddEdit.View in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.AddEdit.View.pas' {DelphiAIDevDefaultsQuestionsAddEditView}, DelphiAIDev.Utils.Crypt in '..\Src\Utils\DelphiAIDev.Utils.Crypt.pas', C4D.Conn.Types in '..\Src\Conn\C4D.Conn.Types.pas', diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index de5b230..af98721 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -169,8 +169,8 @@ - -
DelphiAIDevDatabasesView
+ +
DelphiAIDevDBRegistersView
dfm
@@ -178,8 +178,8 @@ - -
DelphiAIDevDatabasesAddEditView
+ +
DelphiAIDevDBRegistersAddEditView
dfm
@@ -193,9 +193,9 @@
DelphiAIDevDefaultsQuestionsView
dfm
- - - + + +
DelphiAIDevDefaultsQuestionsAddEditView
dfm diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm similarity index 98% rename from Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm rename to Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm index e096ffa..db50f99 100644 --- a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm @@ -1,4 +1,4 @@ -object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView +object DelphiAIDevDBRegistersAddEditView: TDelphiAIDevDBRegistersAddEditView Left = 0 Top = 0 BorderIcons = [biSystemMenu] @@ -103,7 +103,6 @@ object DelphiAIDevDatabasesAddEditView: TDelphiAIDevDatabasesAddEditView BevelOuter = bvNone ParentBackground = False TabOrder = 0 - ExplicitTop = -2 object Bevel1: TBevel AlignWithMargins = True Left = 0 diff --git a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas similarity index 76% rename from Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas rename to Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas index 40a8636..168c4fc 100644 --- a/Src/Databases/DelphiAIDev.Databases.AddEdit.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas @@ -1,4 +1,4 @@ -unit DelphiAIDev.Databases.AddEdit.View; +unit DelphiAIDev.DB.Registers.AddEdit.View; interface @@ -13,11 +13,11 @@ interface Vcl.Menus, Vcl.ComCtrls, DelphiAIDev.Types, - DelphiAIDev.Databases.Fields, + DelphiAIDev.DB.Registers.Fields, C4D.Conn; type - TDelphiAIDevDatabasesAddEditView = class(TForm) + TDelphiAIDevDBRegistersAddEditView = class(TForm) Panel1: TPanel; btnConfirm: TButton; btnClose: TButton; @@ -57,12 +57,12 @@ TDelphiAIDevDatabasesAddEditView = class(TForm) procedure btnVendorLibSearchClick(Sender: TObject); procedure btnDatabaseSearchClick(Sender: TObject); private - FFields: TDelphiAIDevDatabasesFields; + FFields: TDelphiAIDevDBRegistersFields; procedure FillcBoxDriverID; procedure FillScreenFields; procedure ValidateFillingFields; public - property Fields: TDelphiAIDevDatabasesFields read FFields write FFields; + property Fields: TDelphiAIDevDBRegistersFields read FFields write FFields; end; implementation @@ -71,35 +71,35 @@ implementation DelphiAIDev.Consts, DelphiAIDev.Utils, DelphiAIDev.Utils.OTA, - DelphiAIDev.DataBases.Model; + DelphiAIDev.DB.Registers.Model; {$R *.dfm} -procedure TDelphiAIDevDatabasesAddEditView.FormCreate(Sender: TObject); +procedure TDelphiAIDevDBRegistersAddEditView.FormCreate(Sender: TObject); begin Self.ModalResult := mrCancel; - TUtilsOTA.IDEThemingAll(TDelphiAIDevDatabasesAddEditView, Self); + TUtilsOTA.IDEThemingAll(TDelphiAIDevDBRegistersAddEditView, Self); Self.FillcBoxDriverID; end; -procedure TDelphiAIDevDatabasesAddEditView.FormShow(Sender: TObject); +procedure TDelphiAIDevDBRegistersAddEditView.FormShow(Sender: TObject); begin Self.FillScreenFields; edtDescription.SetFocus end; -procedure TDelphiAIDevDatabasesAddEditView.FillcBoxDriverID; +procedure TDelphiAIDevDBRegistersAddEditView.FillcBoxDriverID; begin cBoxDriverID.Items.Clear; TUtils.DriverIDFillItemsTStrings(cBoxDriverID.Items); end; -procedure TDelphiAIDevDatabasesAddEditView.lbAddLocalDatabaseClick(Sender: TObject); +procedure TDelphiAIDevDBRegistersAddEditView.lbAddLocalDatabaseClick(Sender: TObject); begin edtHost.Text := 'localhost'; end; -procedure TDelphiAIDevDatabasesAddEditView.FillScreenFields; +procedure TDelphiAIDevDBRegistersAddEditView.FillScreenFields; begin cBoxDriverID.ItemIndex := cBoxDriverID.Items.IndexOf(FFields.DriverID.ToString); edtDescription.Text := FFields.Description; @@ -112,13 +112,13 @@ procedure TDelphiAIDevDatabasesAddEditView.FillScreenFields; ckVisible.Checked := FFields.Visible; end; -procedure TDelphiAIDevDatabasesAddEditView.btnCloseClick(Sender: TObject); +procedure TDelphiAIDevDBRegistersAddEditView.btnCloseClick(Sender: TObject); begin Self.Close; Self.ModalResult := mrCancel; end; -procedure TDelphiAIDevDatabasesAddEditView.btnConfirmClick(Sender: TObject); +procedure TDelphiAIDevDBRegistersAddEditView.btnConfirmClick(Sender: TObject); begin Self.ValidateFillingFields; @@ -132,13 +132,13 @@ procedure TDelphiAIDevDatabasesAddEditView.btnConfirmClick(Sender: TObject); FFields.VendorLib := edtVendorLib.Text; FFields.Visible := ckVisible.Checked; - TDelphiAIDevDatabasesModel.New.SaveOrEditData(FFields); + TDelphiAIDevDBRegistersModel.New.SaveOrEditData(FFields); Self.Close; Self.ModalResult := mrOK; end; -procedure TDelphiAIDevDatabasesAddEditView.ValidateFillingFields; +procedure TDelphiAIDevDBRegistersAddEditView.ValidateFillingFields; begin if Trim(edtDescription.Text).IsEmpty then TUtils.ShowMsgAndAbort('No informed Description', edtDescription); @@ -159,7 +159,7 @@ procedure TDelphiAIDevDatabasesAddEditView.ValidateFillingFields; TUtils.ShowMsgAndAbort('No informed Database', edtDatabase); end; -procedure TDelphiAIDevDatabasesAddEditView.edtPasswordViewClick(Sender: TObject); +procedure TDelphiAIDevDBRegistersAddEditView.edtPasswordViewClick(Sender: TObject); begin if edtPassword.PasswordChar = '*' then edtPassword.PasswordChar := #0 @@ -167,7 +167,7 @@ procedure TDelphiAIDevDatabasesAddEditView.edtPasswordViewClick(Sender: TObject) edtPassword.PasswordChar := '*'; end; -procedure TDelphiAIDevDatabasesAddEditView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +procedure TDelphiAIDevDBRegistersAddEditView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of VK_F4: @@ -179,7 +179,7 @@ procedure TDelphiAIDevDatabasesAddEditView.FormKeyDown(Sender: TObject; var Key: end; end; -procedure TDelphiAIDevDatabasesAddEditView.btnTestConnectionClick(Sender: TObject); +procedure TDelphiAIDevDBRegistersAddEditView.btnTestConnectionClick(Sender: TObject); var LConn: IC4DConn; begin @@ -207,12 +207,12 @@ procedure TDelphiAIDevDatabasesAddEditView.btnTestConnectionClick(Sender: TObjec end; end; -procedure TDelphiAIDevDatabasesAddEditView.btnDatabaseSearchClick(Sender: TObject); +procedure TDelphiAIDevDBRegistersAddEditView.btnDatabaseSearchClick(Sender: TObject); begin edtDatabase.Text := TUtils.SelectFile(edtDatabase.Text); end; -procedure TDelphiAIDevDatabasesAddEditView.btnVendorLibSearchClick(Sender: TObject); +procedure TDelphiAIDevDBRegistersAddEditView.btnVendorLibSearchClick(Sender: TObject); begin edtVendorLib.Text := TUtils.SelectFile(edtVendorLib.Text); end; diff --git a/Src/Databases/DelphiAIDev.Databases.Fields.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas similarity index 87% rename from Src/Databases/DelphiAIDev.Databases.Fields.pas rename to Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas index fc9e3e1..f238f94 100644 --- a/Src/Databases/DelphiAIDev.Databases.Fields.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas @@ -1,4 +1,4 @@ -unit DelphiAIDev.Databases.Fields; +unit DelphiAIDev.DB.Registers.Fields; interface @@ -6,7 +6,7 @@ interface DelphiAIDev.Types; type - TDelphiAIDevDatabasesFields = class + TDelphiAIDevDBRegistersFields = class private FGuid: string; FDriverID: TC4DDriverID; @@ -35,12 +35,12 @@ TDelphiAIDevDatabasesFields = class implementation -constructor TDelphiAIDevDatabasesFields.Create; +constructor TDelphiAIDevDBRegistersFields.Create; begin Self.Clear; end; -procedure TDelphiAIDevDatabasesFields.Clear; +procedure TDelphiAIDevDBRegistersFields.Clear; begin FGuid := ''; FDriverID := TC4DDriverID.None; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas new file mode 100644 index 0000000..8eda7a4 --- /dev/null +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas @@ -0,0 +1,19 @@ +unit DelphiAIDev.DB.Registers.Interfaces; + +interface + +uses + System.SysUtils, + DelphiAIDev.DB.Registers.Fields; + +type + IDelphiAIDevDatabasesModel = interface + ['{3399A776-4B23-4CFC-8992-568AE07FE065}'] + procedure ReadData(AProc: TProc); + procedure SaveOrEditData(AFields: TDelphiAIDevDBRegistersFields); + procedure RemoveData(const AGuid: string); + end; + +implementation + +end. diff --git a/Src/Databases/DelphiAIDev.Databases.Model.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas similarity index 87% rename from Src/Databases/DelphiAIDev.Databases.Model.pas rename to Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas index 5e52e75..d3a6e6c 100644 --- a/Src/Databases/DelphiAIDev.Databases.Model.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas @@ -1,4 +1,4 @@ -unit DelphiAIDev.Databases.Model; +unit DelphiAIDev.DB.Registers.Model; interface @@ -9,18 +9,18 @@ interface Rest.JSON, DelphiAIDev.Utils, DelphiAIDev.Types, - DelphiAIDev.Databases.Interfaces, - DelphiAIDev.Databases.Fields, + DelphiAIDev.DB.Registers.Interfaces, + DelphiAIDev.DB.Registers.Fields, DelphiAIDev.Utils.Crypt; type - TDelphiAIDevDatabasesModel = class(TInterfacedObject, IDelphiAIDevDatabasesModel) + TDelphiAIDevDBRegistersModel = class(TInterfacedObject, IDelphiAIDevDatabasesModel) private - procedure SaveData(AFields: TDelphiAIDevDatabasesFields); - procedure EditData(AFields: TDelphiAIDevDatabasesFields); + procedure SaveData(AFields: TDelphiAIDevDBRegistersFields); + procedure EditData(AFields: TDelphiAIDevDBRegistersFields); protected - procedure ReadData(AProc: TProc); - procedure SaveOrEditData(AFields: TDelphiAIDevDatabasesFields); + procedure ReadData(AProc: TProc); + procedure SaveOrEditData(AFields: TDelphiAIDevDBRegistersFields); procedure RemoveData(const AGuid: string); public class function New: IDelphiAIDevDatabasesModel; @@ -41,25 +41,25 @@ implementation VENDOR_LIB = 'vendor_lib'; VISIBLE = 'visible'; -class function TDelphiAIDevDatabasesModel.New: IDelphiAIDevDatabasesModel; +class function TDelphiAIDevDBRegistersModel.New: IDelphiAIDevDatabasesModel; begin Result := Self.Create; end; -constructor TDelphiAIDevDatabasesModel.Create; +constructor TDelphiAIDevDBRegistersModel.Create; begin // end; -procedure TDelphiAIDevDatabasesModel.ReadData(AProc: TProc); +procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc); var LStringList: TStringList; LJSONObjItem: TJSONObject; LJSONArray: TJsonArray; i: Integer; - LFields: TDelphiAIDevDatabasesFields; + LFields: TDelphiAIDevDBRegistersFields; begin - LFields := TDelphiAIDevDatabasesFields.Create; + LFields := TDelphiAIDevDBRegistersFields.Create; try if not FileExists(TUtils.GetPathFileJSONDatabases) then begin @@ -126,7 +126,7 @@ procedure TDelphiAIDevDatabasesModel.ReadData(AProc: TProc); - procedure SaveOrEditData(AFields: TDelphiAIDevDatabasesFields); - procedure RemoveData(const AGuid: string); - end; - -implementation - -end. diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas index 4d835a4..ac145a6 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas @@ -25,7 +25,7 @@ implementation DelphiAIDev.Utils.OTA, DelphiAIDev.Chat.View, DelphiAIDev.DefaultsQuestions.View, - DelphiAIDev.Databases.View, + DelphiAIDev.DB.Registers.View, DelphiAIDev.Settings.View, DelphiAIDev.View.About; @@ -49,9 +49,9 @@ class procedure TDelphiAIDevIDEMainMenuClicks.DefaultsQuestionsClick(Sender: TOb class procedure TDelphiAIDevIDEMainMenuClicks.DatabasesClick(Sender: TObject); var - LView: TDelphiAIDevDatabasesView; + LView: TDelphiAIDevDBRegistersView; begin - LView := TDelphiAIDevDatabasesView.Create(nil); + LView := TDelphiAIDevDBRegistersView.Create(nil); try LView.ShowModal; finally From e6a0aa6fdc8a5e5ffbe3e4bcbd478914d01af654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 13 Aug 2024 15:02:00 -0300 Subject: [PATCH 015/109] add-view-DB-chat --- Package/DelphiAIDeveloper.dpk | 7 +- Package/DelphiAIDeveloper.dproj | 40 +- Package/Img/c4d_database_add.bmp | Bin 0 -> 1334 bytes Package/Img/c4d_database_execute.bmp | Bin 0 -> 1334 bytes Src/Chat/DelphiAIDev.Chat.View.dfm | 3 +- Src/Consts/DelphiAIDev.Consts.pas | 6 +- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 888 ++++++++++++++++++ Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 808 ++++++++++++++++ Src/DelphiAIDev.Register.pas | 4 +- .../DelphiAIDev.IDE.ImageListMain.pas | 6 + Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas | 11 +- Src/MainMenu/DelphiAIDev.MainMenu.pas | 27 +- 12 files changed, 1757 insertions(+), 43 deletions(-) create mode 100644 Package/Img/c4d_database_add.bmp create mode 100644 Package/Img/c4d_database_execute.bmp create mode 100644 Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm create mode 100644 Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index d828d69..1993fca 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -42,7 +42,6 @@ requires contains DelphiAIDev.Register in '..\Src\DelphiAIDev.Register.pas', - DelphiAIDev.Chat.View in '..\Src\Chat\DelphiAIDev.Chat.View.pas' {DelphiAIDevChatView}, DelphiAIDev.Utils.OTA in '..\Src\Utils\DelphiAIDev.Utils.OTA.pas', DelphiAIDev.Utils in '..\Src\Utils\DelphiAIDev.Utils.pas', DelphiAIDev.Types in '..\Src\Types\DelphiAIDev.Types.pas', @@ -59,6 +58,8 @@ contains DelphiAIDev.Settings.View in '..\Src\Settings\DelphiAIDev.Settings.View.pas' {DelphiAIDevSettingsView}, DelphiAIDev.Settings in '..\Src\Settings\DelphiAIDev.Settings.pas', DelphiAIDev.Chat in '..\Src\Chat\DelphiAIDev.Chat.pas', + DelphiAIDev.Chat.View in '..\Src\Chat\DelphiAIDev.Chat.View.pas' {DelphiAIDevChatView}, + DelphiAIDev.Chat.ProcessResponse in '..\Src\Chat\DelphiAIDev.Chat.ProcessResponse.pas', DelphiAIDev.AI.Gemini in '..\Src\AI\DelphiAIDev.AI.Gemini.pas', DelphiAIDev.AI.ChatGPT in '..\Src\AI\DelphiAIDev.AI.ChatGPT.pas', DelphiAIDev.AI.Interfaces in '..\Src\AI\DelphiAIDev.AI.Interfaces.pas', @@ -79,7 +80,6 @@ contains DelphiAIDev.DefaultsQuestions.PopupMenu in '..\Src\DefaultsQuestions\DelphiAIDev.DefaultsQuestions.PopupMenu.pas', DelphiAIDev.Utils.ABMenuAction in '..\Src\Utils\DelphiAIDev.Utils.ABMenuAction.pas', DelphiAIDev.IDE.Splash in '..\Src\IDE\Splash\DelphiAIDev.IDE.Splash.pas', - DelphiAIDev.Chat.ProcessResponse in '..\Src\Chat\DelphiAIDev.Chat.ProcessResponse.pas', DelphiAIDev.AI.Groq in '..\Src\AI\DelphiAIDev.AI.Groq.pas', DelphiAIDev.PopupMenuProjects in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.pas', DelphiAIDev.PopupMenuProjects.Item in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.Item.pas', @@ -95,6 +95,7 @@ contains C4D.Conn.Firedac.Query in '..\Src\Conn\C4D.Conn.Firedac.Query.pas', C4D.Conn.Interfaces in '..\Src\Conn\C4D.Conn.Interfaces.pas', C4D.Conn in '..\Src\Conn\C4D.Conn.pas', - C4D.Conn.Utils in '..\Src\Conn\C4D.Conn.Utils.pas'; + C4D.Conn.Utils in '..\Src\Conn\C4D.Conn.Utils.pas', + DelphiAIDev.DB.Chat.View in '..\Src\DB\Chat\DelphiAIDev.DB.Chat.View.pas' {DelphiAIDevDBChatView}; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index af98721..f690788 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -129,9 +129,6 @@ - -
DelphiAIDevChatView
-
@@ -155,10 +152,13 @@
DelphiAIDevSettingsView
- dfm
+ +
DelphiAIDevChatView
+
+ @@ -171,7 +171,6 @@
DelphiAIDevDBRegistersView
- dfm
@@ -180,25 +179,21 @@
DelphiAIDevDBRegistersAddEditView
- dfm
-
DelphiAIDevDefaultsQuestionsView
- dfm
DelphiAIDevDefaultsQuestionsAddEditView
- dfm
@@ -208,21 +203,24 @@ - - BITMAP - c4d_gear - + +
DelphiAIDevDBChatView
+
BITMAP c4d_Logo - + BITMAP - c4d_logo_24x24 + c4d_database - + BITMAP - c4d_logo_48x48 + c4d_database_add + + + BITMAP + c4d_gear BITMAP @@ -232,9 +230,13 @@ BITMAP c4d_question - + BITMAP - c4d_database + c4d_logo_24x24 + + + BITMAP + c4d_database_execute Cfg_2 diff --git a/Package/Img/c4d_database_add.bmp b/Package/Img/c4d_database_add.bmp new file mode 100644 index 0000000000000000000000000000000000000000..59e69bfc6dd4c9bf781648f0a551abcd7a2f237f GIT binary patch literal 1334 zcmZ?rHDhG}12Yx|1`Qxf0E!tII3N;?5DH9!*g*Ur2$`c;8Q3Q9F>p*3WZ;@9%D^*M zl7V-D41>T@MFzoTDh$G_)fq(AXflXz&|{F;WWXT3-IPIQmj#3Teme$*gANQzN1Pdy zkGe9b9(QL@Kkdz+amJTH^L!A4&gD=B-766c1~=mvOzx#Ju%=FCU`?CKz>z(Rfhl7# z15?RL2A0b83?h|l8Q44aFbH(*W{{t_pMkmc00V3HaR&B@M;T;RU1rc(ewo2=>tzOm z4YwGCPXA*tIQf!6;p|@q`^WznDi7RY@Hqd8A@KS)hQJ%&8A9&;X9)fFk0Jiwe}<9= zKNvE;{bwlt^^c+A_dkYupjh*--wd5V_N4#+8Ri4&89;jZ%g+ppKmTV~0Az3b^q*ln zkUj>)w|@L*xC5jgegDJo_SYYV4?y;BARYyyAu#MhfDs75o{|9r21aHkFkfC*N6*Au zQ-+b11;m%P)Ys870x9NT1Cda^urMz#CkGn~gm26!E+Wjw%gxEbC~xoN;_eAjDIyG3 z@2H`!q^zQ7z$h*THcty^o{71(9HW#Z+4YaF|5=EVqIp2EynB&lN}`(COXP9tZ`st*x<;(uqi~Gq21q* zVMm$)!=6lIhGVfj3^&SU8TJ=DFr+tCG2H2QXE@gr$?$n=7Q^!`l??B;S23`sOkiM5 zo65kEJ&S>>F&LbD$)IrVAA|kle+(YyKQV;f_{I=&?>|H6w|@-r|Nb+SJov$o@$ElD z@vnaj6~F&6)C0x-T%N{o^w2Jbe-D;3H2?a|&}moNH2f+nPKtg{|pO& z>}{X^Gi(Ra$AI|OkN*sJfb`Q}{~6x?`or)6$o>t)qhK@yhD8YQp!!0dm4{hg9xkS+ zr^Cp@t_c%Rv@p=o;NWLdfeL{5`Vzc6EXaH#Az@A?hzW|0E^eOQHoP*NP`*i1lBOq3gB0z}?STR=bntU=Mz+{Dz< j-cS{0zn`y%tD~cX3CzJtKA!H5_I3&o>p>=f0fY+xSe2v4 literal 0 HcmV?d00001 diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index 9c5c1b6..d352cfb 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -138,7 +138,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Left = 0 Top = 3 Width = 56 - Height = 22 + Height = 13 Cursor = crHandPoint Hint = 'AI being used' Margins.Left = 0 @@ -149,7 +149,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'lbCurrentAI' PopupMenu = pMenuCurrentAI OnClick = lbCurrentAIClick - ExplicitHeight = 13 end object btnSend: TButton AlignWithMargins = True diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index 1cb7b94..84359d1 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -66,8 +66,10 @@ TConsts = class MENU_IDE_DEFAULTS_QUESTIONS_NAME = 'DelphiAIDevDefaultsQuestions1'; MENU_IDE_DEFAULTS_QUESTIONS_CAPTION = 'Defaults questions'; - MENU_IDE_DEFAULTS_DATABASES_NAME = 'DelphiAIDevDatabases1'; - MENU_IDE_DEFAULTS_DATABASES_CAPTION = 'Databases'; + MENU_IDE_DEFAULTS_DATABASES_ADD_NAME = 'DelphiAIDevDatabasesAdd1'; + MENU_IDE_DEFAULTS_DATABASES_ADD_CAPTION = 'Databases Registers'; + MENU_IDE_DEFAULTS_DATABASES_CHAT_NAME = 'DelphiAIDevDatabasesChat1'; + MENU_IDE_DEFAULTS_DATABASES_CHAT_CAPTION = 'Databases Chat'; MENU_IDE_CHAT_SETTINGS_NAME = 'DelphiAIDevSettings1'; MENU_IDE_CHAT_SETTINGS_CAPTION = 'Settings'; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm new file mode 100644 index 0000000..27eb2b6 --- /dev/null +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -0,0 +1,888 @@ +object DelphiAIDevDBChatView: TDelphiAIDevDBChatView + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu, biMaximize] + Caption = 'AI DB Chat' + ClientHeight = 661 + ClientWidth = 975 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + KeyPreview = True + OldCreateOrder = False + Position = poScreenCenter + ShowHint = True + OnActivate = FormActivate + OnClose = FormClose + OnResize = FormResize + OnShow = FormShow + DesignSize = ( + 975 + 661) + PixelsPerInch = 96 + TextHeight = 13 + object pnBack: TPanel + Left = 0 + Top = 0 + Width = 956 + Height = 661 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alClient + BevelEdges = [] + BevelOuter = bvNone + Padding.Left = 18 + Padding.Top = 15 + ParentBackground = False + TabOrder = 0 + object Splitter1: TSplitter + Left = 18 + Top = 190 + Width = 938 + Height = 3 + Cursor = crVSplit + Align = alBottom + ExplicitLeft = 0 + ExplicitTop = 2 + ExplicitWidth = 528 + end + object Splitter2: TSplitter + Left = 18 + Top = 333 + Width = 938 + Height = 3 + Cursor = crVSplit + Align = alBottom + ExplicitLeft = 12 + ExplicitTop = 340 + end + object mmReturn: TRichEdit + AlignWithMargins = True + Left = 18 + Top = 15 + Width = 938 + Height = 172 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + ParentCustomHint = False + Align = alClient + BevelInner = bvNone + BevelOuter = bvNone + Ctl3D = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindow + Font.Height = -12 + Font.Name = 'Courier New' + Font.Style = [] + Lines.Strings = ( + 'iii' + 'www') + ParentCtl3D = False + ParentFont = False + ParentShowHint = False + PopupMenu = pMenuMemoReturn + ScrollBars = ssVertical + ShowHint = True + TabOrder = 1 + Zoom = 100 + end + object pnBackQuestion: TPanel + Left = 18 + Top = 193 + Width = 938 + Height = 113 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alBottom + BevelOuter = bvNone + Padding.Top = 5 + ParentBackground = False + TabOrder = 0 + object mmQuestion: TMemo + AlignWithMargins = True + Left = 0 + Top = 5 + Width = 938 + Height = 108 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alClient + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + TabOrder = 0 + OnChange = mmQuestionChange + OnKeyDown = mmQuestionKeyDown + OnKeyUp = mmQuestionKeyUp + end + end + object pnBackStatusBar: TPanel + Left = 18 + Top = 306 + Width = 938 + Height = 27 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alBottom + BevelOuter = bvNone + Padding.Top = 3 + Padding.Bottom = 2 + ParentBackground = False + TabOrder = 2 + object lbCurrentAI: TLabel + Left = 0 + Top = 3 + Width = 56 + Height = 22 + Cursor = crHandPoint + Hint = 'AI being used' + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alLeft + Caption = 'lbCurrentAI' + PopupMenu = pMenuCurrentAI + OnClick = lbCurrentAIClick + ExplicitHeight = 13 + end + object btnSend: TButton + AlignWithMargins = True + Left = 864 + Top = 3 + Width = 74 + Height = 22 + Cursor = crHandPoint + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alRight + Caption = 'Send' + TabOrder = 0 + OnClick = btnSendClick + ExplicitTop = 2 + end + object pnBackConfigurableButtons: TPanel + Left = 395 + Top = 3 + Width = 466 + Height = 22 + Align = alRight + BevelOuter = bvNone + TabOrder = 1 + object btnUseCurrentUnitCode: TButton + AlignWithMargins = True + Left = 261 + Top = 0 + Width = 205 + Height = 22 + Cursor = crHandPoint + Hint = 'Use data from current unit in query' + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alRight + Caption = '* Use current unit code in query * ' + ImageIndex = 0 + Images = ImageList1 + TabOrder = 0 + OnClick = btnUseCurrentUnitCodeClick + end + object btnCodeOnly: TButton + AlignWithMargins = True + Left = 149 + Top = 0 + Width = 109 + Height = 22 + Cursor = crHandPoint + Hint = 'Return only code without comments or explanations' + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alRight + Caption = '* Code only *' + ImageIndex = 2 + Images = ImageList1 + TabOrder = 1 + OnClick = btnCodeOnlyClick + end + object btnDefaultsQuestions: TButton + AlignWithMargins = True + Left = 56 + Top = 0 + Width = 90 + Height = 22 + Cursor = crHandPoint + Hint = 'Defaults Questions' + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alRight + Caption = '*Questions*' + ImageIndex = 4 + Images = ImageList1 + PopupMenu = pMenuQuestions + TabOrder = 2 + OnClick = btnDefaultsQuestionsClick + end + end + end + object pnGridBack: TPanel + Left = 18 + Top = 336 + Width = 938 + Height = 325 + Align = alBottom + BevelOuter = bvNone + ParentBackground = False + TabOrder = 3 + object DBGrid1: TDBGrid + Left = 0 + Top = 0 + Width = 938 + Height = 304 + Align = alClient + DataSource = DataSource1 + TabOrder = 0 + TitleFont.Charset = DEFAULT_CHARSET + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + TitleFont.Style = [] + end + object Panel9: TPanel + Left = 0 + Top = 304 + Width = 938 + Height = 21 + Align = alBottom + BevelOuter = bvNone + Padding.Left = 3 + Padding.Top = 3 + Padding.Right = 3 + Padding.Bottom = 3 + ParentBackground = False + TabOrder = 1 + end + end + end + object pnWait: TPanel + Left = 413 + Top = 256 + Width = 125 + Height = 35 + BevelOuter = bvNone + BiDiMode = bdLeftToRight + Caption = 'Wait for loading...' + ParentBiDiMode = False + ParentBackground = False + TabOrder = 1 + Visible = False + object ShapeWait: TShape + Left = 0 + Top = 0 + Width = 125 + Height = 35 + Align = alClient + Brush.Color = 16770222 + Pen.Color = 12615680 + Pen.Style = psInsideFrame + Pen.Width = 2 + ExplicitLeft = 32 + ExplicitTop = 19 + ExplicitWidth = 228 + ExplicitHeight = 49 + end + object pnWaitCaption: TPanel + Left = 0 + Top = 0 + Width = 125 + Height = 35 + Align = alClient + BevelOuter = bvNone + Caption = 'Wait for loading...' + TabOrder = 0 + end + end + object StatusBar1: TStatusBar + Left = 956 + Top = 0 + Width = 19 + Height = 661 + Align = alRight + Panels = < + item + Width = 50 + end> + end + object pnCommands: TPanel + Left = 936 + Top = 8 + Width = 26 + Height = 115 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Anchors = [akTop, akRight] + BevelOuter = bvNone + ParentBackground = False + TabOrder = 3 + DesignSize = ( + 26 + 115) + object ShapeCommands: TShape + Left = 0 + Top = 0 + Width = 26 + Height = 115 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Anchors = [akLeft, akTop, akRight, akBottom] + Brush.Style = bsClear + Pen.Color = clGray + Pen.Style = psInsideFrame + ExplicitHeight = 73 + end + object btnCopy: TSpeedButton + AlignWithMargins = True + Left = 0 + Top = 46 + Width = 26 + Height = 23 + Cursor = crHandPoint + Hint = 'Copy' + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 1800000000000003000000000000000000000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFB58C8C8C5A5A8C5A5A8C5A5A8C5A5A8C5A5A8C5A5A8C5A + 5A8C5A5A8C5A5AFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58C8CFFF7E7F7 + EFDEF7EFDEF7EFDEF7EFDEF7EFDEF7EFDEF7E7CE8C5A5AFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFB58C8CF7EFDEF7DECEF7DEC6F7DEC6F7DEC6F7DEC6EFDE + CEEFDECE8C5A5AFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58C8CFFF7E7FF + D6A5FFD6A5FFD6A5FFD6A5FFD6A5FFD6A5EFDECE8C5A5AFF00FFFF00FFB58C8C + 8C5A5A8C5A5A8C5A5AB58C8CFFF7EFF7DEC6F7DEC6F7DEC6F7DEC6F7DEBDF7E7 + CEEFDECE9C6B63FF00FFFF00FFB58C8CFFF7E7F7EFDEF7EFDEB58C8CFFF7EFF7 + E7CEF7DEC6F7DEC6F7DEC6F7DEC6F7E7D6EFDECE9C6B6BFF00FFFF00FFB58C8C + F7EFDEF7DECEF7DEC6B58C8CFFFFF7FFD6A5FFD6A5FFD6A5FFD6A5FFD6A5FFD6 + A5EFE7D6A57B73FF00FFFF00FFB58C8CFFF7E7FFD6A5FFD6A5B58C8CFFFFF7FF + E7D6FFE7D6F7E7D6F7E7CEFFE7D6FFF7E7EFDEDEA57B73FF00FFFF00FFB58C8C + FFF7EFF7DEC6F7DEC6B58C8CFFFFFFFFFFFFFFFFFFFFFFF7FFFFF7EFDEDED6C6 + C6BDADADB58473FF00FFFF00FFB58C8CFFF7EFF7E7CEF7DEC6B58C8CFFFFFFFF + FFFFFFFFFFFFFFF7FFFFF7B58C8CB58C8CB58C8CB58C8CFF00FFFF00FFB58C8C + FFFFF7FFD6A5FFD6A5B58C8CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB58C8CEFB5 + 6BC68C7BFF00FFFF00FFFF00FFB58C8CFFFFF7FFE7D6FFE7D6B58C8CB58C8CB5 + 8C8CB58C8CB58C8CB58C8CB58C8CBD8484FF00FFFF00FFFF00FFFF00FFB58C8C + FFFFFFFFFFFFFFFFFFFFFFF7FFFFF7EFDEDED6C6C6BDADADB58473FF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFB58C8CFFFFFFFFFFFFFFFFFFFFFFF7FFFFF7B5 + 8C8CB58C8CB58C8CB58C8CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58C8C + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB58C8CEFB56BC68C7BFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFB58C8CB58C8CB58C8CB58C8CB58C8CB58C8CB5 + 8C8CBD8484FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + OnClick = btnCopyClick + ExplicitLeft = -8 + ExplicitTop = 55 + end + object btnInsertAtCursor: TSpeedButton + AlignWithMargins = True + Left = 0 + Top = 0 + Width = 26 + Height = 23 + Cursor = crHandPoint + Hint = 'Insert Selected Text at Cursor' + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + Flat = True + Glyph.Data = { + 8E010000424D8E010000000000008E0000002800000010000000100000000100 + 08000000000000010000120B0000120B0000160000001600000000000000FFFF + FF00FF00FF00811E0000BD4C0000FFFBF800FFE9D300FFF6ED00FEE0C000FEE3 + C500FEE6CB00FFF0E000FFF3E600FEDEB800FEEAD100FEEED900FFF7ED00FEFB + F700FFFAF200FFFEFB00004B000031C758000202020202020202020202020202 + 02020404040404040402020202020202020211100B0E090D0402020202020202 + 020213120C0F0A08040202020202020202020105070B06090402020202020202 + 0202030303030303040202020202020202020202020202020202140204030303 + 03030202020202020214140204100B0E090D0202020202021415140204120C0F + 0A08020202020202021414020405070B06090202020202020202140204030303 + 03030303030303030402020202020202020211100B0E090D0402020202020202 + 020213120C0F0A08040202020202020202020105070B06090402020202020202 + 020204040404040404020202020202020202} + OnClick = btnInsertAtCursorClick + end + object btnMoreActions: TSpeedButton + AlignWithMargins = True + Left = 0 + Top = 92 + Width = 26 + Height = 23 + Cursor = crHandPoint + Hint = 'More actions...' + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + Caption = '...' + Flat = True + PopupMenu = pMenuMoreActions + OnClick = btnMoreActionsClick + ExplicitTop = 46 + end + object btnCreateNewUnit: TSpeedButton + AlignWithMargins = True + Left = 0 + Top = 23 + Width = 26 + Height = 23 + Cursor = crHandPoint + Hint = 'Create new unit with selected code' + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 1800000000000003000000000000000000000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFAD7384B58484B58484B58484B5 + 8484B58484B58484B58484B58484B58484B58484B58484FF00FFFF00FFFF00FF + FF00FFAD7384FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFB58484FF00FFFF00FFFF00FFFF00FFAD7384FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB58484FF00FFFF00FFFF00FF + FF00FFAD7384FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFB58484FF00FFFF00FFFF00FFFF00FFAD7384FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB58484FF00FFFF00FFFF00FF + FF00FFAD7384FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFB58484FF00FFFF00FFFF00FFFF00FFAD7384FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB58484FF00FFFF00FFFF00FF + FF00FFAD7384FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFB58484FF00FFFF00FFFF00FF3184FF3184FF3184FFF7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7B58484FF00FFFF00FFFF00FF + 3184FF42B5F73184FFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFB58484FF00FF3184FF3184FF3184FF42B5F73184FF3184FF3184FFE7 + E7E7E7E7E7E7E7E7E7E7E7B58473B5948CB58C84B58484FF00FF3184FF8CD6F7 + B5DEF7B5DEF7B5DEF78CD6F73184FFDEDEDEDEDEDEDEDEDEC6C6C6B58473FFFF + FFFFFFFFB58484FF00FF3184FF3184FF3184FFB5DEF73184FF3184FF3184FFD6 + D6D6D6D6D6D6D6D6C6C6C6B58473FFFFFFB58484FF00FFFF00FFFF00FFFF00FF + 3184FFB5DEF73184FFCECECECECECECECECECECECECECECEC6C6C6B58473B584 + 84FF00FFFF00FFFF00FFFF00FFFF00FF3184FF3184FF3184FFEFD6C6EFD6C6EF + D6C6EFD6C6EFD6C6D6BDB5B58473FF00FFFF00FFFF00FFFF00FF} + OnClick = btnCreateNewUnitClick + end + object btnCleanAll: TSpeedButton + AlignWithMargins = True + Left = 0 + Top = 69 + Width = 26 + Height = 23 + Cursor = crHandPoint + Hint = 'Clean all and start a new chat' + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + Flat = True + Glyph.Data = { + 1A020000424D1A020000000000001A0100002800000010000000100000000100 + 08000000000000010000210B0000210B00003900000039000000EA8F3100B66A + 5000AB735800C07B5800EAA15800FFB65800AB6A6000B67B6000C0846000A16A + 6A00A1736A00C0846A00A17B7300B68F7B00EAC07B00F4C07B00B68F8400EAC0 + 8400F4C08400F4CA8400B6988F00C0988F00F4CA8F00C0A19800CAA19800B6AB + 9800F4CA9800F4D49800CAABA100D4ABA100D4B6A100E0B6A100EAB6A100EAC0 + A100F4CAA100F4D4A100FFD4A100EAC0AB00F4D4AB00E0D4B600F4D4B600F4E0 + B600E0C0C000E0CAC000F4E0C000E0CACA00F4E0CA00FFE0CA00FFEACA00FFEA + D400FFEAE000FFF4E000FFF4EA00FFF4F400FFFFF400FF00FF00FFFFFF003737 + 0909090909090909090909090937373710302926231A16110E0E0E1309373737 + 10302C2826221611110E0E110937373714322E2C2826221A11110E1109373737 + 14332E2C292823221A11110E093737371736322E2E2C2826221A111109373737 + 183834322E2C2928261A1616093737371C383534312E2C292826221A09373737 + 1C38383534322E2C28262323093737371D3838383532312E2C28282209373737 + 1E3838383835323131302719093737371F383838383834342E0D0C0A09373737 + 1F383838383838362A0204000137373725383838383838382B07050337373737 + 1F353434343434342A070B37373737371F212121211F1F211C0637373737} + OnClick = btnCleanAllClick + ExplicitTop = 92 + end + end + object ImageList1: TImageList + Left = 96 + Top = 240 + Bitmap = { + 494C010105003000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000002000000001002000000000000020 + 000000000000000000000000000000000000000000FF000000FF000000FF0000 + 00FF000000FFF0CAA600F0CAA600C0C0C000C0C0C000CCCC9900F0CAA6000000 + 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000FF000000FF000000FFF0CA + A600D7D7D700E3E3E300E3E3E300CBCBCB00C0C0C000C0C0C000B2B2B200A4A0 + A000F0CAA600000000FF000000FF000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000FF000000FFF0CAA600EAEA + EA00F0FBFF00F0CAA600CC666600CC663300CC663300CC666600CC999900B2B2 + B200A4A0A000CC999900000000FF000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000FFF0CAA600F1F1F100FFFF + FF00CC996600CC330000CC333300FFCCCC00F0CAA600CC330000CC330000CC66 + 6600B2B2B200B2B2B200F0CAA600000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000FFE3E3E300FFFFFF00CC99 + 6600CC330000CC333300CC663300CC999900CC999900CC333300CC333300CC33 + 0000CC996600C0C0C000C0C0C000000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000F0CAA600FFFFFF00FFECCC00CC66 + 3300CC333300CC333300CC663300CC999900CC996600CC333300CC663300CC33 + 3300CC663300B2B2B200CBCBCB00F0CAA6000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FFCCCC00FFFFFF00CC999900CC66 + 3300CC663300CC663300CC663300F8F8F800EAEAEA00CC663300CC330000CC66 + 3300CC330000CC996600D7D7D700F0CAA6000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FFCCCC00FFFFFF00CC996600CC66 + 3300CC663300CC663300CC663300F0CAA600FFFFFF00F0CAA600CC663300CC33 + 0000CC330000CC666600EAEAEA00F0CAA6000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FFCCCC00FFFFFF00CC996600CC66 + 3300CC663300CC663300CC663300CC663300F0CAA600FFFFFF00FFECCC00CC66 + 3300CC330000CC666600F1F1F100F0CAA6000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FFCCCC00FFFFFF00F0CAA600CC66 + 3300CC993300CC996600CC663300CC663300CC663300F0CAA600FFFFFF00CC99 + 6600CC330000CC996600F0FBFF00F0CAA6000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FFCCCC00F8F8F800EAEAEA00CC99 + 6600F0CAA600FFFFFF00CC996600CC663300CC663300CC996600FFFFFF00CC99 + 9900CC663300FFCCCC00F1F1F100F0CAA6000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000FFE3E3E300FFFFFF00F0CA + A600FF999900FFFFFF00F8F8F800F0CAA600F0CAA600F8F8F800F8F8F800CC66 + 3300CC996600FFFFFF00FFCCCC00000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000FFF0CAA600F1F1F100FFFF + FF00F0CAA600F0CAA600FFECCC00F8F8F800F8F8F800FFECCC00CC996600CC99 + 9900FFFFFF00EAEAEA00FFCCCC00000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000FF000000FFF0CAA600F1F1 + F100FFFFFF00FFECCC00F0CAA600F0CAA600F0CAA600F0CAA600FFCCCC00FFFF + FF00EAEAEA00F0CAA600000000FF000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000FF000000FF000000FFF0CA + A600EAEAEA00F1F1F100FFFFFF00FFFFFF00FFFFFF00F8F8F800F8F8F800E3E3 + E300E3E3E300000000FF000000FF000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000FF000000FF000000FF0000 + 00FF000000FFF0CAA600F0CAA600FFCCCC00FFCCCC00F0CAA600F0CAA6000000 + 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000999999009999 + 9900999999009999990000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000555555005555 + 5500555555005555550000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000009696 + 9600969696009696960000000000000000000000000099999900E3E3E300CCCC + CC00C0C0C000C0C0C00096969600000000000000000000000000000000004D4D + 4D004D4D4D004D4D4D0000000000000000000000000055555500CBCBCB00A4A0 + A00096969600969696004D4D4D00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000666666006666 + 6600000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000006600000066 + 0000000000000000000000000000000000000000000000000000969696009999 + 9900A4A0A000B2B2B2009696960096969600000000009999990096969600CBCB + CB00B2B2B200A4A0A000868686000000000000000000000000004D4D4D005555 + 550066666600777777004D4D4D004D4D4D0000000000555555004D4D4D009999 + 9900808080006666660042424200000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000066666600777777007777 + 7700000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000660000008000000066 + 0000000000000000000000000000000000000000000096969600C0C0C0009999 + 9900B2B2B200A4A0A000B2B2B200B2B2B20096969600CCCCCC00CBCBCB009696 + 960096969600868686000000000000000000000000004D4D4D00868686005555 + 5500777777005F5F5F0066996600777777004D4D4D00A4A0A000999999004D4D + 4D004D4D4D003939390000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000006666660086868600868686007777 + 7700666666000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000066000000800000009900000080 + 00000033000000000000000000000000000096969600C0C0C000E3E3E3009999 + 9900B2B2B200A4A0A000A4A0A000B2B2B20096969600B2B2B200CBCBCB00D7D7 + D700D7D7D700D7D7D700B2B2B200868686004D4D4D0096969600C0C0C0005555 + 5500777777005F5F5F0033993300666699004D4D4D00FF990000FFCC3300FFCC + 6600FFCC6600CC99990077777700393939000000000000000000000000000000 + 0000000000000000000000000000666666009696960096969600808080008686 + 8600666666000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000006600000099330000990000008000000080 + 00000066000000000000000000000000000096969600EAEAEA00D7D7D7009696 + 9600B2B2B200B2B2B200A4A0A000969696009696960099999900A4A0A000C0C0 + C000C0C0C000C0C0C000C0C0C000868686004D4D4D00CCCCCC00B2B2B2005555 + 550077777700777777006666990033669900006699003366660099993300FF99 + 3300FF993300FF993300FF993300424242000000000000000000000000000000 + 0000000000000000000077777700A4A0A000A4A0A00077777700666666008686 + 8600808080000000000000000000000000000000000000000000000000000000 + 0000000000000000000000660000009933000099330000660000003300000080 + 00000080000000000000000000000000000096969600EAEAEA00D7D7D7008686 + 8600999999009999990096969600A4A0A000B2B2B200A4A0A00096969600B2B2 + B200CCCCCC00CBCBCB00B2B2B200868686004D4D4D00CCCCCC00B2B2B2000033 + 99003366660033666600006699000066CC003399FF000066CC00006699009999 + 6600FFCC6600FFCC3300FF993300393939000000000000000000000000000000 + 0000000000000000000000000000868686007777770000000000000000007777 + 7700969696006666660000000000000000000000000000000000000000000000 + 0000000000000000000000000000009933000066000000000000000000000066 + 00000099000000660000000000000000000096969600EAEAEA00D7D7D7008686 + 86009696960099999900C0C0C000B2B2B20096969600A4A0A000A4A0A0008686 + 8600C0C0C000D7D7D700C0C0C000808080004D4D4D00CCCCCC00B2B2B2000033 + 99000066CC000066CC003399FF003399CC000066990066666600336699000033 + 990086868600FFCC6600FF993300333333000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000868686008080800000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000080000000660000000000000000000096969600EAEAEA00D7D7D7008686 + 8600A4A0A000B2B2B200B2B2B2009696960096969600CCCCCC00DDDDDD00C0C0 + C00099999900D7D7D700CBCBCB00777777004D4D4D00D7D7D700B2B2B2000033 + 99000066FF000099FF003366CC00336666004D4D4D00FFCC6600FFCC99006699 + 990033669900FFCC6600FFCC3300292929000000000000000000333333003333 + 3300000000000000000000000000333333003333330000000000000000000000 + 00003333330033333300333333000000000000000000000000000000FF000000 + FF000000000000000000000000000000FF000000FF0000000000000000000000 + 00000000FF000000FF000000FF000000000096969600F1F1F100DDDDDD008686 + 8600A4A0A000B2B2B200A4A0A0009696960096969600B2B2B200C0C0C000CBCB + CB00C0C0C000CCCCCC00CBCBCB00777777004D4D4D00DDDDDD00C0C0C0000033 + 99000066FF000099FF000066CC00336699004D4D4D008080800099996600A4A0 + A00099996600CCCC6600CC996600222222000000000033333300000000000000 + 0000333333000000000033333300000000000000000033333300000000003333 + 330000000000808080003333330000000000000000000000FF00000000000000 + 00000000FF00000000000000FF0000000000000000000000FF00000000000000 + FF0000000000006600000000FF000000000096969600FFFFFF00E3E3E3008686 + 860086868600868686008686860086868600B2B2B20096969600969696009696 + 9600969696009696960080808000000000004D4D4D00F1F1F100CBCBCB000033 + 990000339900003399000033990000339900666699004D4D4D004D4D4D004D4D + 4D004D4D4D004D4D4D0039393900000000000000000033333300000000000000 + 0000000000000000000033333300000000000000000033333300000000003333 + 330000000000000000003333330000000000000000000000FF00000000000000 + 000000000000000000000000FF0000000000000000000000FF00000000000000 + FF0000000000000000000000FF000000000096969600F1F1F100C0C0C0009999 + 9900CCCCCC0099999900A4A0A000B2B2B200C0C0C00096969600000000000000 + 0000000000000000000000000000000000004D4D4D00DDDDDD00969696005555 + 5500A4A0A000555555005F5F5F0077777700969696004D4D4D00000000000000 + 0000000000000000000000000000000000000000000033333300000000000000 + 0000333333000000000033333300000000000000000033333300000000003333 + 330000000000000000003333330066666600000000000000FF00000000000000 + 00000000FF00000000000000FF0000000000000000000000FF00000000000000 + FF0000000000000000000000FF000033000096969600CCCCCC00F1F1F100C0C0 + C000B2B2B200B2B2B200C0C0C000A4A0A000A4A0A00096969600000000000000 + 0000000000000000000000000000000000004D4D4D00A4A0A000DDDDDD009696 + 9600777777008080800096969600666666005F5F5F004D4D4D00000000000000 + 0000000000000000000000000000000000000000000000000000333333003333 + 3300000000000000000000000000333333003333330000000000000000000000 + 00003333330033333300333333006666660000000000000000000000FF000000 + FF000000000000000000000000000000FF000000FF0000000000000000000000 + 00000000FF000000FF000000FF000033000096969600FFFFFF00FFFFFF00F8F8 + F800DDDDDD00CCCCCC00C0C0C000C0C0C000C0C0C00096969600000000000000 + 0000000000000000000000000000000000004D4D4D00FFFFFF00F1F1F100E3E3 + E300C0C0C000A4A0A0008686860080808000808080004D4D4D00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000033333300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000FF0000000000A4A0A00096969600FFFFFF00FFFF + FF00FFFFFF00EAEAEA00CCCCCC00969696009696960000000000000000000000 + 000000000000000000000000000000000000666666004D4D4D00FFFFFF00FFFF + FF00F8F8F800D7D7D700A4A0A0004D4D4D004D4D4D0000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000033333300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000FF00000000000000000000000000969696009696 + 9600969696009696960096969600000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000004D4D4D004D4D + 4D004D4D4D004D4D4D004D4D4D00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000200000000100010000000000000100000000000000000000 + 000000000000000000000000FFFFFF00F81F000000000000E007000000000000 + C003000000000000800100000000000080010000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000080010000000000008001000000000000C003000000000000 + E007000000000000F81F000000000000FFC3FFC3FFFFFFFFE381E381FFCFFFCF + C081C081FF8FFF8F80038003FF07FF0700000000FE07FE0700000000FC07FC07 + 00000000FE63FE6300000000FFF3FFF300000000CE71CE7100000000B5A9B5A9 + 00010001BDADBDAD003F003FB5ACB5AC003F003FCE70CE70003F003FFFFDFFFD + 007F007FFFFDFFFDC1FFC1FFFFFFFFFF00000000000000000000000000000000 + 000000000000} + end + object pMenuMemoReturn: TPopupMenu + Left = 96 + Top = 296 + object Cut1: TMenuItem + Caption = 'Cut' + ShortCut = 16472 + OnClick = Cut1Click + end + object Copy1: TMenuItem + Caption = 'Copy' + ShortCut = 16451 + OnClick = Copy1Click + end + object Paste1: TMenuItem + Caption = 'Paste' + ShortCut = 16470 + OnClick = Paste1Click + end + object N2: TMenuItem + Caption = '-' + end + object WordWrap1: TMenuItem + AutoCheck = True + Caption = 'WordWrap' + OnClick = WordWrap1Click + end + object N1: TMenuItem + Caption = '-' + end + object SelectAll1: TMenuItem + Caption = 'Select all' + ShortCut = 16449 + OnClick = SelectAll1Click + end + object Clear1: TMenuItem + Caption = 'Clear' + ShortCut = 16430 + OnClick = Clear1Click + end + end + object pMenuCurrentAI: TPopupMenu + OnPopup = pMenuCurrentAIPopup + Left = 50 + Top = 583 + object Gemini1: TMenuItem + Caption = 'Gemini' + OnClick = Gemini1Click + end + object ChatGPT1: TMenuItem + Tag = 1 + Caption = 'ChatGPT' + OnClick = Gemini1Click + end + object Groq1: TMenuItem + Tag = 2 + Caption = 'Groq' + OnClick = Gemini1Click + end + end + object pMenuMoreActions: TPopupMenu + Images = ImageList1 + Left = 824 + Top = 40 + object SaveContentToFile1: TMenuItem + Caption = 'Save content to file' + OnClick = SaveContentToFile1Click + end + end + object pMenuQuestions: TPopupMenu + Left = 522 + Top = 563 + end + object DataSource1: TDataSource + Left = 170 + Top = 464 + end +end diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas new file mode 100644 index 0000000..817e893 --- /dev/null +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -0,0 +1,808 @@ +unit DelphiAIDev.DB.Chat.View; + +interface + +uses + Winapi.Windows, + Winapi.Messages, + System.SysUtils, + System.StrUtils, + System.Variants, + System.Classes, + System.JSON, + System.Threading, + Vcl.Graphics, + Vcl.Controls, + Vcl.Forms, + Vcl.Dialogs, + System.ImageList, + Vcl.ImgList, + DockForm, + Vcl.StdCtrls, + Vcl.ExtCtrls, + Vcl.ComCtrls, + Vcl.Menus, + Vcl.Buttons, + Clipbrd, + DelphiAIDev.Types, + DelphiAIDev.Consts, + DelphiAIDev.Chat, + DelphiAIDev.Settings, + DelphiAIDev.ModuleCreator, + DelphiAIDev.DefaultsQuestions.PopupMenu, + DelphiAIDev.Chat.ProcessResponse, Data.DB, Vcl.Grids, Vcl.DBGrids; + +type + TDelphiAIDevDBChatView = class(TDockableForm) + ImageList1: TImageList; + pMenuMemoReturn: TPopupMenu; + Cut1: TMenuItem; + Copy1: TMenuItem; + Paste1: TMenuItem; + SelectAll1: TMenuItem; + pnBack: TPanel; + pnBackQuestion: TPanel; + mmQuestion: TMemo; + N1: TMenuItem; + mmReturn: TRichEdit; + Splitter1: TSplitter; + pnWait: TPanel; + ShapeWait: TShape; + pnWaitCaption: TPanel; + pMenuCurrentAI: TPopupMenu; + Gemini1: TMenuItem; + ChatGPT1: TMenuItem; + pnBackStatusBar: TPanel; + lbCurrentAI: TLabel; + StatusBar1: TStatusBar; + pnCommands: TPanel; + btnCopy: TSpeedButton; + btnInsertAtCursor: TSpeedButton; + btnMoreActions: TSpeedButton; + ShapeCommands: TShape; + btnSend: TButton; + pMenuMoreActions: TPopupMenu; + SaveContentToFile1: TMenuItem; + btnCreateNewUnit: TSpeedButton; + Clear1: TMenuItem; + N2: TMenuItem; + WordWrap1: TMenuItem; + pnBackConfigurableButtons: TPanel; + btnUseCurrentUnitCode: TButton; + btnCodeOnly: TButton; + btnDefaultsQuestions: TButton; + pMenuQuestions: TPopupMenu; + btnCleanAll: TSpeedButton; + Groq1: TMenuItem; + pnGridBack: TPanel; + DBGrid1: TDBGrid; + Panel9: TPanel; + Splitter2: TSplitter; + DataSource1: TDataSource; + procedure FormShow(Sender: TObject); + procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); + procedure Cut1Click(Sender: TObject); + procedure Copy1Click(Sender: TObject); + procedure Paste1Click(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure btnSendClick(Sender: TObject); + procedure mmQuestionKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure btnCopyClick(Sender: TObject); + procedure btnInsertAtCursorClick(Sender: TObject); + procedure SelectAll1Click(Sender: TObject); + procedure mmQuestionChange(Sender: TObject); + procedure mmQuestionKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure FormActivate(Sender: TObject); + procedure lbCurrentAIClick(Sender: TObject); + procedure Gemini1Click(Sender: TObject); + procedure pMenuCurrentAIPopup(Sender: TObject); + procedure btnMoreActionsClick(Sender: TObject); + procedure SaveContentToFile1Click(Sender: TObject); + procedure btnCreateNewUnitClick(Sender: TObject); + procedure btnUseCurrentUnitCodeClick(Sender: TObject); + procedure FormResize(Sender: TObject); + procedure WordWrap1Click(Sender: TObject); + procedure btnCodeOnlyClick(Sender: TObject); + procedure btnDefaultsQuestionsClick(Sender: TObject); + procedure Clear1Click(Sender: TObject); + procedure btnCleanAllClick(Sender: TObject); + private + FChat: TDelphiAIDevChat; + FSettings: TDelphiAIDevSettings; + FProcessResponse: TDelphiAIDevChatProcessResponse; + FPopupMenuQuestions: TDelphiAIDevDefaultsQuestionsPopupMenu; + FbtnUseCurrentUnitCodeWidth: Integer; + FbtnCodeOnlyWidth: Integer; + FbtnDefaultsQuestionsWidth: Integer; + FQuestionOnShow: string; + procedure FillMemoReturnWithFile; + procedure SaveMemoReturnInFile; + procedure InitializeRichEditReturn; + procedure ProcessSend; + procedure AddResponseSimple(const AString: string); + procedure Last; + function GetSelectedTextOrAllFromReturn: string; + function GetSelectedTextOrAllOrAbort: string; + procedure WaitingFormOFF; + procedure WaitingFormON; + procedure ConfLabelCurrentAI; + procedure ConfScreenOnShow; + procedure ChangeUseCurrentUnitCode; + procedure ChangeCodeOnly; + procedure AddItemsPopupMenuQuestion; + procedure DoProcessClickInItemDefaultQuestions(ACodeOnly: Boolean; AQuestion: string); + procedure ProcessWordWrap; + procedure ConfScreenOnCreate; + procedure ValidateRegistrationOfSelectedAI; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + property QuestionOnShow: string write FQuestionOnShow; + end; + +var + DelphiAIDevDBChatView: TDelphiAIDevDBChatView; + +procedure RegisterSelf; +procedure Unregister; +procedure DelphiAIDevDBChatViewShowDockableForm; + +implementation + +uses + DeskUtil, + DelphiAIDev.Utils, + DelphiAIDev.Utils.OTA; + +{$R *.dfm} + +const + UseCurrentUnitCode_ImageIndex_OFF = 0; + UseCurrentUnitCode_ImageIndex_ON = 1; + CodeOnly_ImageIndex_OFF = 2; + CodeOnly_ImageIndex_ON = 3; + +procedure RegisterSelf; +begin + if not Assigned(DelphiAIDevDBChatView) then + DelphiAIDevDBChatView := TDelphiAIDevDBChatView.Create(nil); + + if @RegisterFieldAddress <> nil then + RegisterFieldAddress(DelphiAIDevDBChatView.Name, @DelphiAIDevDBChatView); + + RegisterDesktopFormClass(TDelphiAIDevDBChatView, DelphiAIDevDBChatView.Name, DelphiAIDevDBChatView.Name); +end; + +procedure Unregister; +begin + if @UnRegisterFieldAddress <> nil then + UnRegisterFieldAddress(@DelphiAIDevDBChatView); + FreeAndNil(DelphiAIDevDBChatView); +end; + +procedure DelphiAIDevDBChatViewShowDockableForm; +begin + ShowDockableForm(DelphiAIDevDBChatView); + FocusWindow(DelphiAIDevDBChatView); +end; + +constructor TDelphiAIDevDBChatView.Create(AOwner: TComponent); +begin + inherited; + DeskSection := Self.Name; + AutoSave := True; + SaveStateNecessary := True; + + FChat := TDelphiAIDevChat.Create; + FSettings := TDelphiAIDevSettings.GetInstance; + FProcessResponse := TDelphiAIDevChatProcessResponse.Create(mmReturn); + FPopupMenuQuestions := TDelphiAIDevDefaultsQuestionsPopupMenu.Create; + FQuestionOnShow := ''; + + Self.ConfScreenOnCreate; + Self.FillMemoReturnWithFile; +end; + +destructor TDelphiAIDevDBChatView.Destroy; +begin + Self.SaveMemoReturnInFile; + FPopupMenuQuestions.Free; + FProcessResponse.Free; + FChat.Free; + inherited; +end; + +procedure TDelphiAIDevDBChatView.FormShow(Sender: TObject); +begin + Self.ConfScreenOnShow; + Self.InitializeRichEditReturn; + Self.ProcessWordWrap; + Self.AddItemsPopupMenuQuestion; + TUtils.MemoFocusOnTheEnd(mmQuestion); +end; + +procedure TDelphiAIDevDBChatView.FormActivate(Sender: TObject); +begin + Self.ConfLabelCurrentAI; + + if not FQuestionOnShow.Trim.IsEmpty then + begin + mmQuestion.Lines.Clear; + mmQuestion.Lines.Add(FQuestionOnShow); + FQuestionOnShow := ''; + end; +end; + +procedure TDelphiAIDevDBChatView.ConfScreenOnCreate; +begin + mmReturn.Lines.Clear; + + pnWait.Visible := False; + FbtnUseCurrentUnitCodeWidth := btnUseCurrentUnitCode.Width; + FbtnCodeOnlyWidth := btnCodeOnly.Width; + FbtnDefaultsQuestionsWidth := btnDefaultsQuestions.Width; + + ShapeCommands.Left := 0; + ShapeCommands.Top := 0; + ShapeCommands.Width := ShapeCommands.Parent.Width; + ShapeCommands.Height := ShapeCommands.Parent.Height; +end; + +procedure TDelphiAIDevDBChatView.ConfScreenOnShow; +begin + TUtilsOTA.IDEThemingAll(TDelphiAIDevDBChatView, Self); + btnMoreActions.Font.Color := TUtilsOTA.ActiveThemeColorDefault; + + Self.Constraints.MinWidth := 200; + Self.Constraints.MinHeight := 300; +end; + +procedure TDelphiAIDevDBChatView.AddItemsPopupMenuQuestion; +begin + FPopupMenuQuestions + .ProcessClickInItem(DoProcessClickInItemDefaultQuestions) + .CreateMenus(pMenuQuestions); +end; + +procedure TDelphiAIDevDBChatView.DoProcessClickInItemDefaultQuestions(ACodeOnly: Boolean; AQuestion: string); +begin + if ACodeOnly then + btnCodeOnly.ImageIndex := CodeOnly_ImageIndex_ON + else + btnCodeOnly.ImageIndex := CodeOnly_ImageIndex_OFF; + + mmQuestion.Lines.Add(AQuestion); +end; + +procedure TDelphiAIDevDBChatView.mmQuestionChange(Sender: TObject); +begin + if mmQuestion.Lines.Count >= 7 then + mmQuestion.ScrollBars := ssVertical + else + mmQuestion.ScrollBars := ssNone; +end; + +procedure TDelphiAIDevDBChatView.mmQuestionKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +begin + if (ssCtrl in Shift)and(Key = VK_RETURN) then + begin + btnSend.Click; + Key := 0; + end +end; + +procedure TDelphiAIDevDBChatView.mmQuestionKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); +begin + if (ssCtrl in Shift)and(Key = 65) then + begin + mmQuestion.SelectAll; + Key := 0; + end; +end; + +procedure TDelphiAIDevDBChatView.FormClose(Sender: TObject; var Action: TCloseAction); +begin + Self.WaitingFormOFF; +end; + +procedure TDelphiAIDevDBChatView.FormResize(Sender: TObject); +var + LWidth: Integer; +const + CAPTION_UseCurrentUnitCode = 'Use current unit code in query'; + CAPTION_CodeOnly = 'Code only'; + CAPTION_DefaultsQuestions = 'Questions'; +begin + if Self.Width > 620 then + begin + btnUseCurrentUnitCode.Caption := CAPTION_UseCurrentUnitCode; + btnUseCurrentUnitCode.Width := FbtnUseCurrentUnitCodeWidth; + btnUseCurrentUnitCode.ImageAlignment := TImageAlignment.iaLeft; + + btnCodeOnly.Caption := CAPTION_CodeOnly; + btnCodeOnly.Width := FbtnCodeOnlyWidth; + btnCodeOnly.ImageAlignment := TImageAlignment.iaLeft; + + btnDefaultsQuestions.Caption := CAPTION_DefaultsQuestions; + btnDefaultsQuestions.Width := FbtnDefaultsQuestionsWidth; + btnDefaultsQuestions.ImageAlignment := TImageAlignment.iaLeft; + end + else + begin + LWidth := btnSend.Width; + if Self.Width < 405 then + LWidth := 24; + + btnUseCurrentUnitCode.Caption := ''; + btnUseCurrentUnitCode.Width := LWidth; + btnUseCurrentUnitCode.ImageAlignment := TImageAlignment.iaCenter; + + btnCodeOnly.Caption := ''; + btnCodeOnly.Width := LWidth; + btnCodeOnly.ImageAlignment := TImageAlignment.iaCenter; + + btnDefaultsQuestions.Caption := ''; + btnDefaultsQuestions.Width := LWidth; + btnDefaultsQuestions.ImageAlignment := TImageAlignment.iaCenter; + end; +end; + +procedure TDelphiAIDevDBChatView.FillMemoReturnWithFile; +begin + if FileExists(TUtils.GetPathFileChat) then + mmReturn.Lines.LoadFromFile(TUtils.GetPathFileChat) +end; + +procedure TDelphiAIDevDBChatView.SaveMemoReturnInFile; +begin + mmReturn.Lines.SaveToFile(TUtils.GetPathFileChat); +end; + +procedure TDelphiAIDevDBChatView.SelectAll1Click(Sender: TObject); +begin + mmReturn.SelectAll; +end; + +procedure TDelphiAIDevDBChatView.cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); +begin + if not(CharInSet(Key, ['0'..'9', #8]))then + Key := #0; +end; + +procedure TDelphiAIDevDBChatView.Cut1Click(Sender: TObject); +begin + mmReturn.CutToClipboard; +end; + +procedure TDelphiAIDevDBChatView.Copy1Click(Sender: TObject); +begin + mmReturn.CopyToClipboard; +end; + +procedure TDelphiAIDevDBChatView.Paste1Click(Sender: TObject); +begin + mmReturn.PasteFromClipboard; +end; + +procedure TDelphiAIDevDBChatView.btnUseCurrentUnitCodeClick(Sender: TObject); +begin + Self.ChangeUseCurrentUnitCode; +end; + +procedure TDelphiAIDevDBChatView.btnDefaultsQuestionsClick(Sender: TObject); +begin + pMenuQuestions.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); +end; + +procedure TDelphiAIDevDBChatView.ChangeUseCurrentUnitCode; +begin + if btnUseCurrentUnitCode.ImageIndex = UseCurrentUnitCode_ImageIndex_OFF then + btnUseCurrentUnitCode.ImageIndex := UseCurrentUnitCode_ImageIndex_ON + else + btnUseCurrentUnitCode.ImageIndex := UseCurrentUnitCode_ImageIndex_OFF; +end; + +procedure TDelphiAIDevDBChatView.btnCodeOnlyClick(Sender: TObject); +begin + Self.ChangeCodeOnly; +end; + +procedure TDelphiAIDevDBChatView.ChangeCodeOnly; +begin + if btnCodeOnly.ImageIndex = CodeOnly_ImageIndex_OFF then + btnCodeOnly.ImageIndex := CodeOnly_ImageIndex_ON + else + btnCodeOnly.ImageIndex := CodeOnly_ImageIndex_OFF; +end; + +procedure TDelphiAIDevDBChatView.btnSendClick(Sender: TObject); +begin + //Self.ProcessSend; + + +end; + +procedure TDelphiAIDevDBChatView.ProcessSend; +var + LTask: ITask; + LQuestion: string; +begin + if mmQuestion.Lines.Text.Trim.IsEmpty then + TUtils.ShowMsgAndAbort('No questions have been added', mmQuestion); + + Self.ValidateRegistrationOfSelectedAI; + + mmReturn.Lines.Clear; + Self.WaitingFormON; + + LQuestion := FSettings.LanguageQuestions.GetLanguageDefinition; + + if btnUseCurrentUnitCode.ImageIndex = UseCurrentUnitCode_ImageIndex_ON then + LQuestion := TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim + sLineBreak; + + if btnCodeOnly.ImageIndex = CodeOnly_ImageIndex_ON then + LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgCodeOnly; + + LQuestion := LQuestion + mmQuestion.Lines.Text; + + LTask := TTask.Create( + procedure + begin + try + try + FChat.ProcessSend(LQuestion); + except + on E: Exception do + TThread.Synchronize(nil, + procedure + begin + Self.AddResponseSimple('Unable to perform processing.' + sLineBreak + TUtils.GetExceptionMessage(E)); + Abort; + end); + end; + + TThread.Synchronize(nil, + procedure + begin + mmReturn.Lines.BeginUpdate; + try + //Optional use of one of the following lines + FProcessResponse.AddResponseComplete(FChat.Response); + Self.Last; + //Self.AddResponseSimple(FChat.Response.Text); + finally + mmReturn.Lines.EndUpdate; + end; + end); + finally + TThread.Synchronize(nil, + procedure + begin + Self.WaitingFormOFF; + end); + end; + end); + LTask.Start; +end; + +procedure TDelphiAIDevDBChatView.ValidateRegistrationOfSelectedAI; +const + MSG = '"%s" for IA %s not specified in settings.' + sLineBreak + sLineBreak + + 'Access menu > AI Developer > Settings'; +begin + case FSettings.AIDefault of + TC4DAIsAvailable.Gemini: + begin + if FSettings.BaseUrlGemini.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'Gemini'])); + + if FSettings.ModelGemini.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Gemini'])); + + if FSettings.ApiKeyGemini.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'Gemini'])); + end; + TC4DAIsAvailable.OpenAI: + begin + if FSettings.BaseUrlOpenAI.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'ChatGPT'])); + + if FSettings.ModelOpenAI.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'ChatGPT'])); + + if FSettings.ApiKeyOpenAI.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'ChatGPT'])); + end; + end; +end; + +procedure TDelphiAIDevDBChatView.AddResponseSimple(const AString: string); +begin + Self.Last; + mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; + mmReturn.SelAttributes.Style := []; + mmReturn.Lines.Add(AString); + Self.Last; +end; + +////Add line-by-line response to color where Delphi code is +//procedure TDelphiAIDevDBChatView.AddResponseComplete(const AStrings: TStrings); +//var +// LLineNum: Integer; +// LLineStr: string; +// LCodeStarted: Boolean; +//begin +// mmReturn.Lines.Clear; +// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; +// mmReturn.SelAttributes.Style := []; +// +// LCodeStarted := False; +// for LLineNum := 0 to Pred(AStrings.Count) do +// begin +// LLineStr := AStrings[LLineNum].TrimRight; +// +// if not LCodeStarted then +// begin +// if TUtils.CodeIdMarkBeginCode(LLineStr) then +// begin +// LCodeStarted := True; +// Continue; +// end; +// end; +// +// if LLineStr.Trim = TConsts.MARK_END then +// begin +// LCodeStarted := False; +// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; +// Continue; +// end; +// +// if LCodeStarted then +// begin +// if (FSettings.ColorHighlightCodeDelphiUse) and (FSettings.ColorHighlightCodeDelphi <> clNone) then +// mmReturn.SelAttributes.Color := FSettings.ColorHighlightCodeDelphi +// else +// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeForCode; +// end +// else +// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; +// +// //Optional use of one of the following lines +// //mmReturn.Lines.Add(LLineStr); +// Self.AddResponseLine(LLineStr); //.Replace(TConsts.MARK_BEGIN_PASCAL2, '', [rfReplaceAll, rfIgnoreCase]) +// end; +// Self.Last; +//end; +// +////Bold in words between Backtick +//procedure TDelphiAIDevDBChatView.AddResponseLine(const ALineStr: string); +//const +// BACKTICK = '`'; +//var +// i: Integer; +// LCurrentLetter: Char; +// LNextLetter: Char; +// LLineStarted: Boolean; +// LCodeStarted: Boolean; +//begin +// if not ALineStr.Contains(BACKTICK) then +// begin +// mmReturn.Lines.Add(IFThen(ALineStr.IsEmpty, ' ', ALineStr)); +// Exit; +// end; +// +// LLineStarted := False; +// LCodeStarted := False; +// for i := 0 to ALineStr.Length do +// begin +// LCurrentLetter := ALineStr[i]; +// LNextLetter := ALineStr[Succ(i)]; +// +// if not LCodeStarted then +// begin +// if(LCurrentLetter = BACKTICK)and(LNextLetter <> BACKTICK)then +// begin +// LCodeStarted := True; +// Continue; +// end; +// end; +// +// if(LCurrentLetter = BACKTICK)and(LNextLetter <> BACKTICK)then +// begin +// LCodeStarted := False; +// mmReturn.SelAttributes.Style := []; +// Continue; +// end; +// +// SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); +// if LCodeStarted then +// mmReturn.SelAttributes.Style := [fsBold] +// else +// mmReturn.SelAttributes.Style := []; +// +// if LLineStarted then +// mmReturn.SelText := LCurrentLetter +// else +// begin +// mmReturn.Lines.Add(''); +// mmReturn.SelText := LCurrentLetter; +// +// LLineStarted := True; +// end; +// SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); +// end; +// mmReturn.SelText := ' '; +// SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); +//end; + +procedure TDelphiAIDevDBChatView.WaitingFormON; +begin + pnWait.Visible := False; + TUtils.CenterPanel(pnWait, mmReturn); + pnWait.Visible := True; +end; + +procedure TDelphiAIDevDBChatView.WordWrap1Click(Sender: TObject); +begin + Self.ProcessWordWrap; +end; + +procedure TDelphiAIDevDBChatView.ProcessWordWrap; +begin + if WordWrap1.Checked then + mmReturn.ScrollBars := ssVertical + else + mmReturn.ScrollBars := ssBoth; +end; + +procedure TDelphiAIDevDBChatView.WaitingFormOFF; +begin + pnWait.Visible := False; +end; + +procedure TDelphiAIDevDBChatView.Last; +begin + SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); +end; + +procedure TDelphiAIDevDBChatView.lbCurrentAIClick(Sender: TObject); +begin + pMenuCurrentAI.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); +end; + +function TDelphiAIDevDBChatView.GetSelectedTextOrAllFromReturn: string; +begin + if not mmReturn.SelText.Trim.IsEmpty then + Result := mmReturn.SelText + else + Result := mmReturn.Lines.Text; +end; + +function TDelphiAIDevDBChatView.GetSelectedTextOrAllOrAbort: string; +begin + Result := Self.GetSelectedTextOrAllFromReturn; + if Result.Trim.IsEmpty then + TUtils.ShowMsgAndAbort('There is no data to be used in this action'); +end; + +procedure TDelphiAIDevDBChatView.btnInsertAtCursorClick(Sender: TObject); +var + LText: string; +begin + LText := Self.GetSelectedTextOrAllOrAbort; + TUtilsOTA.DeleteBlockTextSelectedInEditor; + TUtilsOTA.InsertBlockTextIntoEditor(LText); +end; + +procedure TDelphiAIDevDBChatView.btnCopyClick(Sender: TObject); +var + LText: string; +begin + LText := Self.GetSelectedTextOrAllOrAbort; + Clipboard.AsText := LText; +end; + +procedure TDelphiAIDevDBChatView.btnCreateNewUnitClick(Sender: TObject); +var + LText: string; +begin + LText := Self.GetSelectedTextOrAllOrAbort; + TDelphiAIDevModuleCreator.New.CreateNewUnit(LText); +end; + +procedure TDelphiAIDevDBChatView.SaveContentToFile1Click(Sender: TObject); +var + LFileName: string; +begin + Self.GetSelectedTextOrAllOrAbort; + + LFileName := TUtils.GetFileName('rtf'); + mmReturn.Lines.SaveToFile(LFileName); + TUtils.ShowV('File saved successfully'); +end; + +procedure TDelphiAIDevDBChatView.Clear1Click(Sender: TObject); +begin + mmReturn.Lines.Clear; +end; + +procedure TDelphiAIDevDBChatView.btnMoreActionsClick(Sender: TObject); +begin + pMenuMoreActions.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); +end; + +procedure TDelphiAIDevDBChatView.InitializeRichEditReturn; +begin + mmReturn.SelAttributes.Name := 'Courier New'; + mmReturn.SelAttributes.Size := 10; + + if TUtilsOTA.ActiveThemeIsDark then + begin + mmReturn.Color := $004A4136; + mmReturn.SelAttributes.Color := clWhite; + end + else + begin + mmReturn.Color := clWindow; + mmReturn.SelAttributes.Color := clWindowText; + end; +end; + +procedure TDelphiAIDevDBChatView.pMenuCurrentAIPopup(Sender: TObject); +begin + Gemini1.Checked := False; + ChatGPT1.Checked := False; + Groq1.Checked := False; + case FSettings.AIDefault of + TC4DAIsAvailable.Gemini: + Gemini1.Checked := True; + TC4DAIsAvailable.OpenAI: + ChatGPT1.Checked := True; + TC4DAIsAvailable.Groq: + Groq1.Checked := True; + end; +end; + +procedure TDelphiAIDevDBChatView.ConfLabelCurrentAI; +begin + lbCurrentAI.Caption := FSettings.AIDefault.ToString; + + case FSettings.AIDefault of + TC4DAIsAvailable.Gemini: + lbCurrentAI.Hint := FSettings.ModelGemini; + TC4DAIsAvailable.OpenAI: + lbCurrentAI.Hint := FSettings.ModelOpenAI; + TC4DAIsAvailable.Groq: + lbCurrentAI.Hint := FSettings.ModelGroq; + end; + + lbCurrentAI.Repaint; + Self.Repaint; +end; + +procedure TDelphiAIDevDBChatView.Gemini1Click(Sender: TObject); +var + LTag: Integer; +begin + //*SEVERAL + LTag := TMenuItem(Sender).Tag; + if not(LTag in [0, 1, 2])then + Exit; + + FSettings.AIDefault := TC4DAIsAvailable(LTag); + FSettings.SaveData; + Self.ConfLabelCurrentAI; +end; + +procedure TDelphiAIDevDBChatView.btnCleanAllClick(Sender: TObject); +begin + mmQuestion.Lines.Clear; + mmReturn.Lines.Clear; +end; + +initialization + +finalization + Unregister; + +end. diff --git a/Src/DelphiAIDev.Register.pas b/Src/DelphiAIDev.Register.pas index 141a1e3..06dd643 100644 --- a/Src/DelphiAIDev.Register.pas +++ b/Src/DelphiAIDev.Register.pas @@ -6,7 +6,8 @@ interface DelphiAIDev.Chat.View, DelphiAIDev.MainMenu.Register, DelphiAIDev.IDE.Shortcuts, - DelphiAIDev.PopupMenuProjects; + DelphiAIDev.PopupMenuProjects, + DelphiAIDev.DB.Chat.View; procedure Register; @@ -18,6 +19,7 @@ procedure Register; DelphiAIDev.MainMenu.Register.RegisterSelf; DelphiAIDev.IDE.Shortcuts.RefreshRegister; DelphiAIDev.PopupMenuProjects.RegisterSelf; + DelphiAIDev.DB.Chat.View.RegisterSelf; end; end. diff --git a/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas b/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas index ef47d16..449f95d 100644 --- a/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas +++ b/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas @@ -14,6 +14,8 @@ TDelphiAIDevIDEImageListMain = class FImgIndexMessage: Integer; FImgQuestion: Integer; FImgDatabase: Integer; + FImgDatabaseAdd: Integer; + FImgDatabaseExecute: Integer; constructor Create; public class function GetInstance: TDelphiAIDevIDEImageListMain; @@ -22,6 +24,8 @@ TDelphiAIDevIDEImageListMain = class property ImgIndexMessage: Integer read FImgIndexMessage; property ImgQuestion: Integer read FImgQuestion; property ImgDatabase: Integer read FImgDatabase; + property ImgDatabaseAdd: Integer read FImgDatabaseAdd; + property ImgDatabaseExecute: Integer read FImgDatabaseExecute; end; implementation @@ -46,6 +50,8 @@ constructor TDelphiAIDevIDEImageListMain.Create; FImgIndexMessage := TUtilsOTA.AddImgIDEResourceName('c4d_message'); FImgQuestion := TUtilsOTA.AddImgIDEResourceName('c4d_question'); FImgDatabase := TUtilsOTA.AddImgIDEResourceName('c4d_database'); + FImgDatabaseAdd := TUtilsOTA.AddImgIDEResourceName('c4d_database_add'); + FImgDatabaseExecute := TUtilsOTA.AddImgIDEResourceName('c4d_database_execute'); end; initialization diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas index ac145a6..b5647c7 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas @@ -13,7 +13,8 @@ TDelphiAIDevIDEMainMenuClicks = class public class procedure ChatClick(Sender: TObject); class procedure DefaultsQuestionsClick(Sender: TObject); - class procedure DatabasesClick(Sender: TObject); + class procedure DatabasesAddClick(Sender: TObject); + class procedure DatabasesChatClick(Sender: TObject); class procedure SettingsClick(Sender: TObject); class procedure AboutClick(Sender: TObject); end; @@ -26,6 +27,7 @@ implementation DelphiAIDev.Chat.View, DelphiAIDev.DefaultsQuestions.View, DelphiAIDev.DB.Registers.View, + DelphiAIDev.DB.Chat.View, DelphiAIDev.Settings.View, DelphiAIDev.View.About; @@ -47,7 +49,7 @@ class procedure TDelphiAIDevIDEMainMenuClicks.DefaultsQuestionsClick(Sender: TOb end; end; -class procedure TDelphiAIDevIDEMainMenuClicks.DatabasesClick(Sender: TObject); +class procedure TDelphiAIDevIDEMainMenuClicks.DatabasesAddClick(Sender: TObject); var LView: TDelphiAIDevDBRegistersView; begin @@ -59,6 +61,11 @@ class procedure TDelphiAIDevIDEMainMenuClicks.DatabasesClick(Sender: TObject); end; end; +class procedure TDelphiAIDevIDEMainMenuClicks.DatabasesChatClick(Sender: TObject); +begin + DelphiAIDev.DB.Chat.View.DelphiAIDevDBChatViewShowDockableForm; +end; + class procedure TDelphiAIDevIDEMainMenuClicks.SettingsClick(Sender: TObject); begin DelphiAIDevSettingsView := TDelphiAIDevSettingsView.Create(nil); diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.pas b/Src/MainMenu/DelphiAIDev.MainMenu.pas index e5e1a7d..b8f0d67 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.pas @@ -64,40 +64,39 @@ procedure TDelphiAIDevIDEMainMenu.CreateMenus; TConsts.MENU_IDE_CHAT_CAPTION, TDelphiAIDevIDEMainMenuClicks.ChatClick, TDelphiAIDevIDEImageListMain.GetInstance.ImgIndexMessage, - Self.GetShortCutStrChat - ); + Self.GetShortCutStrChat); Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '10', '-', nil); Self.CreateSubMenu(TConsts.MENU_IDE_DEFAULTS_QUESTIONS_NAME, TConsts.MENU_IDE_DEFAULTS_QUESTIONS_CAPTION, TDelphiAIDevIDEMainMenuClicks.DefaultsQuestionsClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgQuestion - ); + TDelphiAIDevIDEImageListMain.GetInstance.ImgQuestion); Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '20', '-', nil); - Self.CreateSubMenu(TConsts.MENU_IDE_DEFAULTS_DATABASES_NAME, - TConsts.MENU_IDE_DEFAULTS_DATABASES_Caption, - TDelphiAIDevIDEMainMenuClicks.DatabasesClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgDatabase - ); + Self.CreateSubMenu(TConsts.MENU_IDE_DEFAULTS_DATABASES_ADD_NAME, + TConsts.MENU_IDE_DEFAULTS_DATABASES_ADD_Caption, + TDelphiAIDevIDEMainMenuClicks.DatabasesAddClick, + TDelphiAIDevIDEImageListMain.GetInstance.ImgDatabaseAdd); + + Self.CreateSubMenu(TConsts.MENU_IDE_DEFAULTS_DATABASES_CHAT_NAME, + TConsts.MENU_IDE_DEFAULTS_DATABASES_CHAT_CAPTION, + TDelphiAIDevIDEMainMenuClicks.DatabasesChatClick, + TDelphiAIDevIDEImageListMain.GetInstance.ImgDatabaseExecute); Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '30', '-', nil); Self.CreateSubMenu(TConsts.MENU_IDE_SETTINGS_NAME, TConsts.MENU_IDE_SETTINGS_CAPTION, TDelphiAIDevIDEMainMenuClicks.SettingsClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgIndexGear - ); - + TDelphiAIDevIDEImageListMain.GetInstance.ImgIndexGear); Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '40', '-', nil); Self.CreateSubMenu(TConsts.MENU_IDE_ABOUT_NAME, TConsts.MENU_IDE_ABOUT_CAPTION, TDelphiAIDevIDEMainMenuClicks.AboutClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgIndexC4D_Logo - ); + TDelphiAIDevIDEImageListMain.GetInstance.ImgIndexC4D_Logo); end; procedure TDelphiAIDevIDEMainMenu.CreateMenuDelphiAIDeveloperInIDEMenu; From 22130217ec7122f7d26c5a819249c75661f2edd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 13 Aug 2024 15:35:33 -0300 Subject: [PATCH 016/109] bk/2024-08-13-1535 --- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 35 +++++++++++++++++------ Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 36 +++++++++++++++++++++++- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 27eb2b6..537f64c 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -175,7 +175,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Caption = 'Send' TabOrder = 0 OnClick = btnSendClick - ExplicitTop = 2 end object pnBackConfigurableButtons: TPanel Left = 395 @@ -255,7 +254,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Left = 0 Top = 0 Width = 938 - Height = 304 + Height = 291 Align = alClient DataSource = DataSource1 TabOrder = 0 @@ -267,9 +266,9 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object Panel9: TPanel Left = 0 - Top = 304 + Top = 291 Width = 938 - Height = 21 + Height = 34 Align = alBottom BevelOuter = bvNone Padding.Left = 3 @@ -278,6 +277,26 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Bottom = 3 ParentBackground = False TabOrder = 1 + object Button1: TButton + Left = 196 + Top = 3 + Width = 75 + Height = 28 + Align = alLeft + Caption = 'Button1' + TabOrder = 0 + OnClick = Button1Click + end + object cBoxDatabases: TComboBox + AlignWithMargins = True + Left = 6 + Top = 6 + Width = 187 + Height = 21 + Align = alLeft + TabOrder = 1 + Text = 'cBoxDatabases' + end end end end @@ -851,8 +870,8 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object pMenuCurrentAI: TPopupMenu OnPopup = pMenuCurrentAIPopup - Left = 50 - Top = 583 + Left = 26 + Top = 263 object Gemini1: TMenuItem Caption = 'Gemini' OnClick = Gemini1Click @@ -878,8 +897,8 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end end object pMenuQuestions: TPopupMenu - Left = 522 - Top = 563 + Left = 530 + Top = 531 end object DataSource1: TDataSource Left = 170 diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 817e893..f8e1dfc 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -30,7 +30,13 @@ interface DelphiAIDev.Settings, DelphiAIDev.ModuleCreator, DelphiAIDev.DefaultsQuestions.PopupMenu, - DelphiAIDev.Chat.ProcessResponse, Data.DB, Vcl.Grids, Vcl.DBGrids; + DelphiAIDev.Chat.ProcessResponse, + Data.DB, + Vcl.Grids, + Vcl.DBGrids, + DelphiAIDev.DB.Registers.Model, + DelphiAIDev.DB.Registers.Fields, + C4D.Conn; type TDelphiAIDevDBChatView = class(TDockableForm) @@ -79,6 +85,8 @@ TDelphiAIDevDBChatView = class(TDockableForm) Panel9: TPanel; Splitter2: TSplitter; DataSource1: TDataSource; + Button1: TButton; + cBoxDatabases: TComboBox; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); procedure Cut1Click(Sender: TObject); @@ -106,6 +114,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure btnDefaultsQuestionsClick(Sender: TObject); procedure Clear1Click(Sender: TObject); procedure btnCleanAllClick(Sender: TObject); + procedure Button1Click(Sender: TObject); private FChat: TDelphiAIDevChat; FSettings: TDelphiAIDevSettings; @@ -134,6 +143,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure ProcessWordWrap; procedure ConfScreenOnCreate; procedure ValidateRegistrationOfSelectedAI; + procedure ReloadDatabases; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -219,6 +229,7 @@ procedure TDelphiAIDevDBChatView.FormShow(Sender: TObject); Self.ProcessWordWrap; Self.AddItemsPopupMenuQuestion; TUtils.MemoFocusOnTheEnd(mmQuestion); + Self.ReloadDatabases; end; procedure TDelphiAIDevDBChatView.FormActivate(Sender: TObject); @@ -422,6 +433,29 @@ procedure TDelphiAIDevDBChatView.btnSendClick(Sender: TObject); end; +procedure TDelphiAIDevDBChatView.ReloadDatabases; +begin TUtils.ShowMsg('ReloadDatabases'); + cBoxDatabases.Items.Clear; + + TDelphiAIDevDBRegistersModel.New.ReadData( + procedure(AFields: TDelphiAIDevDBRegistersFields) + begin + if AFields.Description.Trim.IsEmpty then + Exit; + + if AFields.Visible then + begin + cBoxDatabases.Items.AddObject(AFields.Description, AFields); + end; + end + ); +end; + +procedure TDelphiAIDevDBChatView.Button1Click(Sender: TObject); +begin + TUtils.ShowMsg(TDelphiAIDevDBRegistersFields(cBoxDatabases.Items.Objects[cBoxDatabases.ItemIndex]).Description); +end; + procedure TDelphiAIDevDBChatView.ProcessSend; var LTask: ITask; From dfde85ecf45e265526a8d7d92c8f6c8695d27c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 13 Aug 2024 16:12:11 -0300 Subject: [PATCH 017/109] bk/2024-08-13-1612 --- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 2 +- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 35 ++++++++++++++++--- .../DelphiAIDev.DB.Registers.Interfaces.pas | 3 +- .../DelphiAIDev.DB.Registers.Model.pas | 7 ++-- Src/Types/DelphiAIDev.Types.pas | 1 + 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 537f64c..74e3ad6 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -294,8 +294,8 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Width = 187 Height = 21 Align = alLeft + Style = csDropDownList TabOrder = 1 - Text = 'cBoxDatabases' end end end diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index f8e1dfc..9710d56 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -144,6 +144,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure ConfScreenOnCreate; procedure ValidateRegistrationOfSelectedAI; procedure ReloadDatabases; + procedure ClearcBoxDatabases; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -430,12 +431,13 @@ procedure TDelphiAIDevDBChatView.btnSendClick(Sender: TObject); begin //Self.ProcessSend; - end; procedure TDelphiAIDevDBChatView.ReloadDatabases; -begin TUtils.ShowMsg('ReloadDatabases'); - cBoxDatabases.Items.Clear; +begin + TUtils.ShowMsg('ReloadDatabases'); + + Self.ClearcBoxDatabases; TDelphiAIDevDBRegistersModel.New.ReadData( procedure(AFields: TDelphiAIDevDBRegistersFields) @@ -447,8 +449,33 @@ procedure TDelphiAIDevDBChatView.ReloadDatabases; begin cBoxDatabases.Items.AddObject(AFields.Description, AFields); end; - end + end, + TAutoFreeField.No ); + + cBoxDatabases.ItemIndex := 0; +end; + +procedure TDelphiAIDevDBChatView.ClearcBoxDatabases; +var + i: Integer; + LObj: TObject; +begin + TUtils.ShowMsg('ClearcBoxDatabases INI'); + + for i := 0 to Pred(cBoxDatabases.Items.Count) do + begin + if not Assigned(cBoxDatabases.Items.Objects[i]) then + Continue; + + LObj := cBoxDatabases.Items.Objects[i]; + + if LObj is TDelphiAIDevDBRegistersFields then + TDelphiAIDevDBRegistersFields(LObj).Free; + end; + + TUtils.ShowMsg('ClearcBoxDatabases fim'); + cBoxDatabases.Items.Clear; end; procedure TDelphiAIDevDBChatView.Button1Click(Sender: TObject); diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas index 8eda7a4..ce8b3b6 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas @@ -4,12 +4,13 @@ interface uses System.SysUtils, + DelphiAIDev.Types, DelphiAIDev.DB.Registers.Fields; type IDelphiAIDevDatabasesModel = interface ['{3399A776-4B23-4CFC-8992-568AE07FE065}'] - procedure ReadData(AProc: TProc); + procedure ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); procedure SaveOrEditData(AFields: TDelphiAIDevDBRegistersFields); procedure RemoveData(const AGuid: string); end; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas index d3a6e6c..2fa03d2 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas @@ -19,7 +19,7 @@ TDelphiAIDevDBRegistersModel = class(TInterfacedObject, IDelphiAIDevDatabasesM procedure SaveData(AFields: TDelphiAIDevDBRegistersFields); procedure EditData(AFields: TDelphiAIDevDBRegistersFields); protected - procedure ReadData(AProc: TProc); + procedure ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); procedure SaveOrEditData(AFields: TDelphiAIDevDBRegistersFields); procedure RemoveData(const AGuid: string); public @@ -51,7 +51,7 @@ constructor TDelphiAIDevDBRegistersModel.Create; // end; -procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc); +procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); var LStringList: TStringList; LJSONObjItem: TJSONObject; @@ -122,7 +122,8 @@ procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc Date: Wed, 14 Aug 2024 02:02:41 -0300 Subject: [PATCH 018/109] bk/2024-08-14-0202 --- .../DelphiAIDev.DB.Registers.AddEdit.View.dfm | 18 ++++++++++++++ .../DelphiAIDev.DB.Registers.AddEdit.View.pas | 24 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm index db50f99..e05c36f 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm @@ -48,6 +48,7 @@ object DelphiAIDevDBRegistersAddEditView: TDelphiAIDevDBRegistersAddEditView Padding.Bottom = 2 ParentBackground = False TabOrder = 1 + ExplicitTop = 267 object btnConfirm: TButton AlignWithMargins = True Left = 437 @@ -92,6 +93,23 @@ object DelphiAIDevDBRegistersAddEditView: TDelphiAIDevDBRegistersAddEditView Caption = 'Test Connection' TabOrder = 2 OnClick = btnTestConnectionClick + ExplicitLeft = 0 + ExplicitTop = 0 + end + object btnGenerateDatabaseReference: TButton + AlignWithMargins = True + Left = 115 + Top = 2 + Width = 165 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alLeft + Caption = 'Generate database reference' + TabOrder = 3 + OnClick = btnGenerateDatabaseReferenceClick end end object Panel9: TPanel diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas index 168c4fc..8f0708b 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas @@ -46,6 +46,7 @@ TDelphiAIDevDBRegistersAddEditView = class(TForm) btnVendorLibSearch: TButton; edtVendorLib: TEdit; btnDatabaseSearch: TButton; + btnGenerateDatabaseReference: TButton; procedure btnCloseClick(Sender: TObject); procedure btnConfirmClick(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); @@ -56,6 +57,7 @@ TDelphiAIDevDBRegistersAddEditView = class(TForm) procedure btnTestConnectionClick(Sender: TObject); procedure btnVendorLibSearchClick(Sender: TObject); procedure btnDatabaseSearchClick(Sender: TObject); + procedure btnGenerateDatabaseReferenceClick(Sender: TObject); private FFields: TDelphiAIDevDBRegistersFields; procedure FillcBoxDriverID; @@ -217,4 +219,26 @@ procedure TDelphiAIDevDBRegistersAddEditView.btnVendorLibSearchClick(Sender: TOb edtVendorLib.Text := TUtils.SelectFile(edtVendorLib.Text); end; +procedure TDelphiAIDevDBRegistersAddEditView.btnGenerateDatabaseReferenceClick(Sender: TObject); +var + LConn: IC4DConn; +begin + Screen.Cursor := crHourGlass; + try + LConn := TC4DConn.New; + LConn.Configs + .DriverID(TUtils.StrToDriverID(cBoxDriverID.Text)) + .Host(edtHost.Text) + .UserName(edtUser.Text) + .Password(edtPassword.Text) + .Port(StrToIntDef(edtPort.Text, 0)) + .Database(edtDatabase.Text) + .VendorLib(edtVendorLib.Text); + + + finally + Screen.Cursor := crDefault; + end; +end; + end. From 2d91df8ba897607d653ab269d86c3ffd3be46769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Wed, 14 Aug 2024 02:40:09 -0300 Subject: [PATCH 019/109] add/metainfo --- Package/DelphiAIDeveloper.dpk | 3 +- Package/DelphiAIDeveloper.dproj | 1 + .../DelphiAIDev.DB.Registers.AddEdit.View.dfm | 4 +- .../DelphiAIDev.DB.Registers.AddEdit.View.pas | 11 +- Src/MetaInfo/DelphiAIDev.MetaInfo.pas | 102 ++++++++++++++++++ 5 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 Src/MetaInfo/DelphiAIDev.MetaInfo.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 1993fca..c42f9a5 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -96,6 +96,7 @@ contains C4D.Conn.Interfaces in '..\Src\Conn\C4D.Conn.Interfaces.pas', C4D.Conn in '..\Src\Conn\C4D.Conn.pas', C4D.Conn.Utils in '..\Src\Conn\C4D.Conn.Utils.pas', - DelphiAIDev.DB.Chat.View in '..\Src\DB\Chat\DelphiAIDev.DB.Chat.View.pas' {DelphiAIDevDBChatView}; + DelphiAIDev.DB.Chat.View in '..\Src\DB\Chat\DelphiAIDev.DB.Chat.View.pas' {DelphiAIDevDBChatView}, + DelphiAIDev.MetaInfo in '..\Src\MetaInfo\DelphiAIDev.MetaInfo.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index f690788..eeb6e5d 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -206,6 +206,7 @@
DelphiAIDevDBChatView
+ BITMAP c4d_Logo diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm index e05c36f..b676b50 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm @@ -48,7 +48,6 @@ object DelphiAIDevDBRegistersAddEditView: TDelphiAIDevDBRegistersAddEditView Padding.Bottom = 2 ParentBackground = False TabOrder = 1 - ExplicitTop = 267 object btnConfirm: TButton AlignWithMargins = True Left = 437 @@ -93,8 +92,6 @@ object DelphiAIDevDBRegistersAddEditView: TDelphiAIDevDBRegistersAddEditView Caption = 'Test Connection' TabOrder = 2 OnClick = btnTestConnectionClick - ExplicitLeft = 0 - ExplicitTop = 0 end object btnGenerateDatabaseReference: TButton AlignWithMargins = True @@ -110,6 +107,7 @@ object DelphiAIDevDBRegistersAddEditView: TDelphiAIDevDBRegistersAddEditView Caption = 'Generate database reference' TabOrder = 3 OnClick = btnGenerateDatabaseReferenceClick + ExplicitTop = 0 end end object Panel9: TPanel diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas index 8f0708b..5d52677 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas @@ -14,7 +14,8 @@ interface Vcl.ComCtrls, DelphiAIDev.Types, DelphiAIDev.DB.Registers.Fields, - C4D.Conn; + C4D.Conn, + DelphiAIDev.MetaInfo; type TDelphiAIDevDBRegistersAddEditView = class(TForm) @@ -222,6 +223,7 @@ procedure TDelphiAIDevDBRegistersAddEditView.btnVendorLibSearchClick(Sender: TOb procedure TDelphiAIDevDBRegistersAddEditView.btnGenerateDatabaseReferenceClick(Sender: TObject); var LConn: IC4DConn; + LMetaInfo: TDelphiAIDevMetaInfo; begin Screen.Cursor := crHourGlass; try @@ -235,7 +237,14 @@ procedure TDelphiAIDevDBRegistersAddEditView.btnGenerateDatabaseReferenceClick(S .Database(edtDatabase.Text) .VendorLib(edtVendorLib.Text); + LConn.Connection.Open; + LMetaInfo := TDelphiAIDevMetaInfo.Create(LConn); + try + LMetaInfo.Process + finally + LMetaInfo.Free; + end; finally Screen.Cursor := crDefault; end; diff --git a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas new file mode 100644 index 0000000..34874fa --- /dev/null +++ b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas @@ -0,0 +1,102 @@ +unit DelphiAIDev.MetaInfo; + +interface + +uses + System.SysUtils, + System.Json, + FireDAC.Stan.Intf, + FireDAC.Stan.Option, + FireDAC.Stan.Param, + FireDAC.Stan.Error, + FireDAC.DatS, + FireDAC.Phys.Intf, + FireDAC.DApt.Intf, + FireDAC.Stan.Async, + FireDAC.DApt, + Data.DB, + FireDAC.Comp.DataSet, + FireDAC.Comp.Client, + C4D.Conn, + DelphiAIDev.Utils; + +type + TDelphiAIDevMetaInfo = class + private + FC4DConn: IC4DConn; + FMetaInfoTables: TFDMetaInfoQuery; + FMetaInfoFields: TFDMetaInfoQuery; + public + constructor Create(const AC4DConn: IC4DConn); + destructor Destroy; override; + procedure Process; + end; + +implementation + + +constructor TDelphiAIDevMetaInfo.Create(const AC4DConn: IC4DConn); +begin + FC4DConn := AC4DConn; + + FMetaInfoTables := TFDMetaInfoQuery.Create(nil); + FMetaInfoTables.Connection := TFDConnection(FC4DConn.Connection.Component); + FMetaInfoTables.MetaInfoKind := mkTables; + + FMetaInfoFields := TFDMetaInfoQuery.Create(nil); + FMetaInfoFields.Connection := TFDConnection(FC4DConn.Connection.Component); + FMetaInfoFields.MetaInfoKind := mkTableFields; +end; + +destructor TDelphiAIDevMetaInfo.Destroy; +begin + FMetaInfoFields.Free; + FMetaInfoTables.Free; + inherited; +end; + +procedure TDelphiAIDevMetaInfo.Process; +var + LJSONArrayTables: TJSONArray; + LJSONObjectTable: TJSONObject; + LJSONArrayColumns: TJSONArray; + LJSONObjectColumn: TJSONObject; +begin + FMetaInfoTables.Open; + if FMetaInfoTables.IsEmpty then + TUtils.ShowMsgAndAbort('No tables could be found in the current connection'); + + LJSONArrayTables := TJSONArray.Create; + + FMetaInfoTables.First; + while not FMetaInfoTables.Eof do + begin + FMetaInfoFields.Close; + FMetaInfoFields.ObjectName := FMetaInfoTables.FieldByName('TABLE_NAME').AsString; + FMetaInfoFields.Open; + + LJSONArrayColumns := TJSONArray.Create; + FMetaInfoFields.First; + while not FMetaInfoFields.Eof do + begin + LJSONObjectColumn := TJSONObject.Create; + LJSONObjectColumn.AddPair('name', TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); + LJSONObjectColumn.AddPair('type', TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); + LJSONObjectColumn.AddPair('length', TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); + + LJSONArrayColumns.AddElement(LJSONObjectColumn); + FMetaInfoFields.Next; + end; + + LJSONObjectTable := TJSONObject.Create; + LJSONObjectTable.AddPair('table_name', TJSONString.Create(FMetaInfoTables.FieldByName('TABLE_NAME').AsString)); + LJSONObjectTable.AddPair('columns', LJSONArrayColumns); + LJSONArrayTables.AddElement(LJSONObjectTable); + + FMetaInfoTables.Next; + end; + + TUtils.ShowMsg('Terminou', LJSONArrayTables.Format); +end; + +end. From 66cbd369aac10136183a4a9b4bcdc0b45ba31ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Wed, 14 Aug 2024 03:10:45 -0300 Subject: [PATCH 020/109] bk/2024-08-14-0310 --- .../DelphiAIDev.DB.Registers.AddEdit.View.dfm | 16 -- .../DelphiAIDev.DB.Registers.AddEdit.View.pas | 35 +---- .../DelphiAIDev.DB.Registers.Interfaces.pas | 1 + .../DelphiAIDev.DB.Registers.Model.pas | 137 ++++++++++++++---- .../DelphiAIDev.DB.Registers.View.dfm | 15 ++ .../DelphiAIDev.DB.Registers.View.pas | 36 ++++- 6 files changed, 160 insertions(+), 80 deletions(-) diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm index b676b50..db50f99 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm @@ -93,22 +93,6 @@ object DelphiAIDevDBRegistersAddEditView: TDelphiAIDevDBRegistersAddEditView TabOrder = 2 OnClick = btnTestConnectionClick end - object btnGenerateDatabaseReference: TButton - AlignWithMargins = True - Left = 115 - Top = 2 - Width = 165 - Height = 31 - Cursor = crHandPoint - Margins.Left = 0 - Margins.Top = 0 - Margins.Bottom = 0 - Align = alLeft - Caption = 'Generate database reference' - TabOrder = 3 - OnClick = btnGenerateDatabaseReferenceClick - ExplicitTop = 0 - end end object Panel9: TPanel Left = 0 diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas index 5d52677..168c4fc 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas @@ -14,8 +14,7 @@ interface Vcl.ComCtrls, DelphiAIDev.Types, DelphiAIDev.DB.Registers.Fields, - C4D.Conn, - DelphiAIDev.MetaInfo; + C4D.Conn; type TDelphiAIDevDBRegistersAddEditView = class(TForm) @@ -47,7 +46,6 @@ TDelphiAIDevDBRegistersAddEditView = class(TForm) btnVendorLibSearch: TButton; edtVendorLib: TEdit; btnDatabaseSearch: TButton; - btnGenerateDatabaseReference: TButton; procedure btnCloseClick(Sender: TObject); procedure btnConfirmClick(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); @@ -58,7 +56,6 @@ TDelphiAIDevDBRegistersAddEditView = class(TForm) procedure btnTestConnectionClick(Sender: TObject); procedure btnVendorLibSearchClick(Sender: TObject); procedure btnDatabaseSearchClick(Sender: TObject); - procedure btnGenerateDatabaseReferenceClick(Sender: TObject); private FFields: TDelphiAIDevDBRegistersFields; procedure FillcBoxDriverID; @@ -220,34 +217,4 @@ procedure TDelphiAIDevDBRegistersAddEditView.btnVendorLibSearchClick(Sender: TOb edtVendorLib.Text := TUtils.SelectFile(edtVendorLib.Text); end; -procedure TDelphiAIDevDBRegistersAddEditView.btnGenerateDatabaseReferenceClick(Sender: TObject); -var - LConn: IC4DConn; - LMetaInfo: TDelphiAIDevMetaInfo; -begin - Screen.Cursor := crHourGlass; - try - LConn := TC4DConn.New; - LConn.Configs - .DriverID(TUtils.StrToDriverID(cBoxDriverID.Text)) - .Host(edtHost.Text) - .UserName(edtUser.Text) - .Password(edtPassword.Text) - .Port(StrToIntDef(edtPort.Text, 0)) - .Database(edtDatabase.Text) - .VendorLib(edtVendorLib.Text); - - LConn.Connection.Open; - - LMetaInfo := TDelphiAIDevMetaInfo.Create(LConn); - try - LMetaInfo.Process - finally - LMetaInfo.Free; - end; - finally - Screen.Cursor := crDefault; - end; -end; - end. diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas index ce8b3b6..64ac8f0 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Interfaces.pas @@ -10,6 +10,7 @@ interface type IDelphiAIDevDatabasesModel = interface ['{3399A776-4B23-4CFC-8992-568AE07FE065}'] + function ReadGuid(const AGuid: string): TDelphiAIDevDBRegistersFields; procedure ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); procedure SaveOrEditData(AFields: TDelphiAIDevDBRegistersFields); procedure RemoveData(const AGuid: string); diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas index 2fa03d2..5e87049 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas @@ -18,7 +18,9 @@ TDelphiAIDevDBRegistersModel = class(TInterfacedObject, IDelphiAIDevDatabasesM private procedure SaveData(AFields: TDelphiAIDevDBRegistersFields); procedure EditData(AFields: TDelphiAIDevDBRegistersFields); + procedure FillField(const AJSONObjItem: TJSONObject; var AField: TDelphiAIDevDBRegistersFields); protected + function ReadGuid(const AGuid: string): TDelphiAIDevDBRegistersFields; procedure ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); procedure SaveOrEditData(AFields: TDelphiAIDevDBRegistersFields); procedure RemoveData(const AGuid: string); @@ -51,6 +53,81 @@ constructor TDelphiAIDevDBRegistersModel.Create; // end; +function TDelphiAIDevDBRegistersModel.ReadGuid(const AGuid: string): TDelphiAIDevDBRegistersFields; +var + LStringList: TStringList; + LJSONObjItem: TJSONObject; + LJSONArray: TJsonArray; + i: Integer; +begin + Result := TDelphiAIDevDBRegistersFields.Create; + + if not FileExists(TUtils.GetPathFileJSONDatabases) then + Exit; + + LStringList := TStringList.Create; + try + LStringList.LoadFromFile(TUtils.GetPathFileJSONDatabases); + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + finally + LStringList.Free; + end; + + try + for i := 0 to Pred(LJSONArray.Count) do + begin + if not(LJSONArray.Items[i] is TJSONObject) then + Continue; + + LJSONObjItem := LJSONArray.Items[i] as TJSONObject; + + if LJSONObjItem.GetValue(GUID) = nil then + Continue; + + if LJSONObjItem.GetValue(GUID) <> AGuid then + Continue; + + Self.FillField(LJSONObjItem, Result); + Break; + end; + finally + LJSONArray.Free; + end; +end; + +procedure TDelphiAIDevDBRegistersModel.FillField(const AJSONObjItem: TJSONObject; var AField: TDelphiAIDevDBRegistersFields); +begin + AField.Clear; + AField.Guid := AJSONObjItem.GetValue(GUID); + + if AJSONObjItem.GetValue(DRIVER_ID) <> nil then + AField.DriverID := TC4DDriverID(AJSONObjItem.GetValue(DRIVER_ID)); + + if AJSONObjItem.GetValue(DESCRIPTION) <> nil then + AField.Description := AJSONObjItem.GetValue(DESCRIPTION); + + if AJSONObjItem.GetValue(HOST) <> nil then + AField.Host := AJSONObjItem.GetValue(HOST); + + if AJSONObjItem.GetValue(USER) <> nil then + AField.User := AJSONObjItem.GetValue(USER); + + if AJSONObjItem.GetValue(PASSWORD) <> nil then + AField.Password := TUtilsCrypt.Decrypt(AJSONObjItem.GetValue(PASSWORD)); + + if AJSONObjItem.GetValue(PORT) <> nil then + AField.Port := AJSONObjItem.GetValue(PORT); + + if AJSONObjItem.GetValue(DATABASE_NAME) <> nil then + AField.DatabaseName := AJSONObjItem.GetValue(DATABASE_NAME); + + if AJSONObjItem.GetValue(VENDOR_LIB) <> nil then + AField.VendorLib := AJSONObjItem.GetValue(VENDOR_LIB); + + if AJSONObjItem.GetValue(VISIBLE) <> nil then + AField.Visible := AJSONObjItem.GetValue(VISIBLE); +end; + procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); var LStringList: TStringList; @@ -86,35 +163,37 @@ procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc(GUID); - - if LJSONObjItem.GetValue(DRIVER_ID) <> nil then - LFields.DriverID := TC4DDriverID(LJSONObjItem.GetValue(DRIVER_ID)); - - if LJSONObjItem.GetValue(DESCRIPTION) <> nil then - LFields.Description := LJSONObjItem.GetValue(DESCRIPTION); - - if LJSONObjItem.GetValue(HOST) <> nil then - LFields.Host := LJSONObjItem.GetValue(HOST); - - if LJSONObjItem.GetValue(USER) <> nil then - LFields.User := LJSONObjItem.GetValue(USER); - - if LJSONObjItem.GetValue(PASSWORD) <> nil then - LFields.Password := TUtilsCrypt.Decrypt(LJSONObjItem.GetValue(PASSWORD)); - - if LJSONObjItem.GetValue(PORT) <> nil then - LFields.Port := LJSONObjItem.GetValue(PORT); - - if LJSONObjItem.GetValue(DATABASE_NAME) <> nil then - LFields.DatabaseName := LJSONObjItem.GetValue(DATABASE_NAME); - - if LJSONObjItem.GetValue(VENDOR_LIB) <> nil then - LFields.VendorLib := LJSONObjItem.GetValue(VENDOR_LIB); - - if LJSONObjItem.GetValue(VISIBLE) <> nil then - LFields.Visible := LJSONObjItem.GetValue(VISIBLE); + Self.FillField(LJSONObjItem, LFields); + +// LFields.Clear; +// LFields.Guid := LJSONObjItem.GetValue(GUID); +// +// if LJSONObjItem.GetValue(DRIVER_ID) <> nil then +// LFields.DriverID := TC4DDriverID(LJSONObjItem.GetValue(DRIVER_ID)); +// +// if LJSONObjItem.GetValue(DESCRIPTION) <> nil then +// LFields.Description := LJSONObjItem.GetValue(DESCRIPTION); +// +// if LJSONObjItem.GetValue(HOST) <> nil then +// LFields.Host := LJSONObjItem.GetValue(HOST); +// +// if LJSONObjItem.GetValue(USER) <> nil then +// LFields.User := LJSONObjItem.GetValue(USER); +// +// if LJSONObjItem.GetValue(PASSWORD) <> nil then +// LFields.Password := TUtilsCrypt.Decrypt(LJSONObjItem.GetValue(PASSWORD)); +// +// if LJSONObjItem.GetValue(PORT) <> nil then +// LFields.Port := LJSONObjItem.GetValue(PORT); +// +// if LJSONObjItem.GetValue(DATABASE_NAME) <> nil then +// LFields.DatabaseName := LJSONObjItem.GetValue(DATABASE_NAME); +// +// if LJSONObjItem.GetValue(VENDOR_LIB) <> nil then +// LFields.VendorLib := LJSONObjItem.GetValue(VENDOR_LIB); +// +// if LJSONObjItem.GetValue(VISIBLE) <> nil then +// LFields.Visible := LJSONObjItem.GetValue(VISIBLE); AProc(LFields); end; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm index 1cec1a5..1c27a4c 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm @@ -97,6 +97,21 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView TabOrder = 3 OnClick = btnRemoveClick end + object btnGenerateDatabaseReference: TButton + AlignWithMargins = True + Left = 368 + Top = 2 + Width = 165 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alLeft + Caption = 'Generate database reference' + TabOrder = 4 + OnClick = btnGenerateDatabaseReferenceClick + end end object ListView: TListView Left = 0 diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas index 6608dbf..604d852 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas @@ -12,10 +12,12 @@ interface Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.ComCtrls, + C4D.Conn, DelphiAIDev.Utils.ListView, DelphiAIDev.DB.Registers.Model, DelphiAIDev.DB.Registers.Fields, - DelphiAIDev.DB.Registers.AddEdit.View; + DelphiAIDev.DB.Registers.AddEdit.View, + DelphiAIDev.MetaInfo; type TDelphiAIDevDBRegistersView = class(TForm) @@ -29,6 +31,7 @@ TDelphiAIDevDBRegistersView = class(TForm) StatusBar1: TStatusBar; btnAdd: TButton; btnRemove: TButton; + btnGenerateDatabaseReference: TButton; procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); @@ -42,6 +45,7 @@ TDelphiAIDevDBRegistersView = class(TForm) procedure btnRemoveClick(Sender: TObject); procedure edtSearchKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure ListViewColumnClick(Sender: TObject; Column: TListColumn); + procedure btnGenerateDatabaseReferenceClick(Sender: TObject); private FUtilsListView: IDelphiAIDevUtilsListView; FMadeChanges: Boolean; @@ -362,4 +366,34 @@ procedure TDelphiAIDevDBRegistersView.btnRemoveClick(Sender: TObject); end; end; +procedure TDelphiAIDevDBRegistersView.btnGenerateDatabaseReferenceClick(Sender: TObject); +var + LConn: IC4DConn; + LMetaInfo: TDelphiAIDevMetaInfo; +begin + Screen.Cursor := crHourGlass; + try + LConn := TC4DConn.New; + LConn.Configs + .DriverID(TUtils.StrToDriverID(cBoxDriverID.Text)) + .Host(edtHost.Text) + .UserName(edtUser.Text) + .Password(edtPassword.Text) + .Port(StrToIntDef(edtPort.Text, 0)) + .Database(edtDatabase.Text) + .VendorLib(edtVendorLib.Text); + + LConn.Connection.Open; + + LMetaInfo := TDelphiAIDevMetaInfo.Create(LConn); + try + LMetaInfo.Process + finally + LMetaInfo.Free; + end; + finally + Screen.Cursor := crDefault; + end; +end; + end. From 80206910d2b765fb46c422294a47195bb5870b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Wed, 14 Aug 2024 03:56:31 -0300 Subject: [PATCH 021/109] bk/2024-08-14-0356 --- Src/Consts/DelphiAIDev.Consts.pas | 1 + .../DelphiAIDev.DB.Registers.View.pas | 30 +++-- Src/MetaInfo/DelphiAIDev.MetaInfo.pas | 104 +++++++++++++----- Src/Utils/DelphiAIDev.Utils.pas | 10 +- 4 files changed, 98 insertions(+), 47 deletions(-) diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index 84359d1..f4ba79e 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -12,6 +12,7 @@ TConsts = class DELPHI_AI_DEVELOPER_BPL = 'DelphiAIDeveloper.bpl'; C4D_PROJECT_GROUP1 = 'ProjectGroup1.groupproj'; NAME_FOLDER_TEMP = 'Temp'; + NAME_FOLDER_MetaInfo = 'MetaInfo'; GITHUB_Code4Delphi = 'https://github.com/Code4Delphi'; GITHUB_PROJECT = 'https://github.com/Code4Delphi/Delphi-AI-Developer'; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas index 604d852..65926a0 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas @@ -320,7 +320,7 @@ procedure TDelphiAIDevDBRegistersView.btnEditClick(Sender: TObject); Self.FillFieldsWithSelectedItem(LFields); if LFields.Description.Trim.IsEmpty then - TUtils.ShowMsgErrorAndAbort('Caption not found'); + TUtils.ShowMsgErrorAndAbort('Description not found'); LView := TDelphiAIDevDBRegistersAddEditView.Create(nil); try @@ -368,30 +368,28 @@ procedure TDelphiAIDevDBRegistersView.btnRemoveClick(Sender: TObject); procedure TDelphiAIDevDBRegistersView.btnGenerateDatabaseReferenceClick(Sender: TObject); var - LConn: IC4DConn; + LFields: TDelphiAIDevDBRegistersFields; LMetaInfo: TDelphiAIDevMetaInfo; begin + if ListView.Selected = nil then + Exit; + Screen.Cursor := crHourGlass; + LFields := TDelphiAIDevDBRegistersFields.Create; try - LConn := TC4DConn.New; - LConn.Configs - .DriverID(TUtils.StrToDriverID(cBoxDriverID.Text)) - .Host(edtHost.Text) - .UserName(edtUser.Text) - .Password(edtPassword.Text) - .Port(StrToIntDef(edtPort.Text, 0)) - .Database(edtDatabase.Text) - .VendorLib(edtVendorLib.Text); - - LConn.Connection.Open; - - LMetaInfo := TDelphiAIDevMetaInfo.Create(LConn); + Self.FillFieldsWithSelectedItem(LFields); + + if LFields.Description.Trim.IsEmpty then + TUtils.ShowMsgErrorAndAbort('Description not found'); + + LMetaInfo := TDelphiAIDevMetaInfo.Create(LFields); try - LMetaInfo.Process + LMetaInfo.Process; finally LMetaInfo.Free; end; finally + LFields.Free; Screen.Cursor := crDefault; end; end; diff --git a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas index 34874fa..057372f 100644 --- a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas +++ b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas @@ -4,6 +4,7 @@ interface uses System.SysUtils, + System.Classes, System.Json, FireDAC.Stan.Intf, FireDAC.Stan.Option, @@ -18,26 +19,31 @@ interface FireDAC.Comp.DataSet, FireDAC.Comp.Client, C4D.Conn, - DelphiAIDev.Utils; + DelphiAIDev.Utils, + DelphiAIDev.DB.Registers.Fields; type TDelphiAIDevMetaInfo = class private + FField: TDelphiAIDevDBRegistersFields; FC4DConn: IC4DConn; FMetaInfoTables: TFDMetaInfoQuery; FMetaInfoFields: TFDMetaInfoQuery; + procedure ConfigConn; + procedure SaveJsonInFolder(const AJSONArrayTables: TJSONArray); public - constructor Create(const AC4DConn: IC4DConn); + constructor Create(const AField: TDelphiAIDevDBRegistersFields); destructor Destroy; override; procedure Process; end; implementation - -constructor TDelphiAIDevMetaInfo.Create(const AC4DConn: IC4DConn); +constructor TDelphiAIDevMetaInfo.Create(const AField: TDelphiAIDevDBRegistersFields); begin - FC4DConn := AC4DConn; + FField := AField; + FC4DConn := TC4DConn.New; + Self.ConfigConn; FMetaInfoTables := TFDMetaInfoQuery.Create(nil); FMetaInfoTables.Connection := TFDConnection(FC4DConn.Connection.Component); @@ -55,6 +61,18 @@ destructor TDelphiAIDevMetaInfo.Destroy; inherited; end; +procedure TDelphiAIDevMetaInfo.ConfigConn; +begin + FC4DConn.Configs + .DriverID(FField.DriverID) + .Host(FField.Host) + .UserName(FField.User) + .Password(FField.Password) + .Port(FField.Port) + .Database(FField.DatabaseName) + .VendorLib(FField.VendorLib); +end; + procedure TDelphiAIDevMetaInfo.Process; var LJSONArrayTables: TJSONArray; @@ -62,41 +80,67 @@ procedure TDelphiAIDevMetaInfo.Process; LJSONArrayColumns: TJSONArray; LJSONObjectColumn: TJSONObject; begin + FC4DConn.Connection.Open; + FMetaInfoTables.Open; if FMetaInfoTables.IsEmpty then TUtils.ShowMsgAndAbort('No tables could be found in the current connection'); LJSONArrayTables := TJSONArray.Create; - - FMetaInfoTables.First; - while not FMetaInfoTables.Eof do - begin - FMetaInfoFields.Close; - FMetaInfoFields.ObjectName := FMetaInfoTables.FieldByName('TABLE_NAME').AsString; - FMetaInfoFields.Open; - - LJSONArrayColumns := TJSONArray.Create; - FMetaInfoFields.First; - while not FMetaInfoFields.Eof do + try + FMetaInfoTables.First; + while not FMetaInfoTables.Eof do begin - LJSONObjectColumn := TJSONObject.Create; - LJSONObjectColumn.AddPair('name', TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); - LJSONObjectColumn.AddPair('type', TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); - LJSONObjectColumn.AddPair('length', TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); - - LJSONArrayColumns.AddElement(LJSONObjectColumn); - FMetaInfoFields.Next; + FMetaInfoFields.Close; + FMetaInfoFields.ObjectName := FMetaInfoTables.FieldByName('TABLE_NAME').AsString; + FMetaInfoFields.Open; + + LJSONArrayColumns := TJSONArray.Create; + FMetaInfoFields.First; + while not FMetaInfoFields.Eof do + begin + LJSONObjectColumn := TJSONObject.Create; + LJSONObjectColumn.AddPair('name', TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); + LJSONObjectColumn.AddPair('type', TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); + LJSONObjectColumn.AddPair('length', TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); + + LJSONArrayColumns.AddElement(LJSONObjectColumn); + FMetaInfoFields.Next; + end; + + LJSONObjectTable := TJSONObject.Create; + LJSONObjectTable.AddPair('name', TJSONString.Create(FMetaInfoTables.FieldByName('TABLE_NAME').AsString)); + LJSONObjectTable.AddPair('columns', LJSONArrayColumns); + LJSONArrayTables.AddElement(LJSONObjectTable); + + FMetaInfoTables.Next; end; - LJSONObjectTable := TJSONObject.Create; - LJSONObjectTable.AddPair('table_name', TJSONString.Create(FMetaInfoTables.FieldByName('TABLE_NAME').AsString)); - LJSONObjectTable.AddPair('columns', LJSONArrayColumns); - LJSONArrayTables.AddElement(LJSONObjectTable); - - FMetaInfoTables.Next; + TUtils.ShowMsg('Terminou', LJSONArrayTables.Format); + Self.SaveJsonInFolder(LJSONArrayTables); + finally + LJSONArrayTables.Free; end; +end; - TUtils.ShowMsg('Terminou', LJSONArrayTables.Format); +procedure TDelphiAIDevMetaInfo.SaveJsonInFolder(const AJSONArrayTables: TJSONArray); +var + LStringList: TStringList; +begin + LStringList := TStringList.Create; + try +// {$IF CompilerVersion <= 32.0} //Tokyo +// LStringList.Text := AJSONArrayTables.ToJSON; +// {$ELSE} +// LStringList.Text := AJSONArrayTables.Format(2); +// {$ENDIF} + + LStringList.Text := AJSONArrayTables.ToString; + + LStringList.SaveToFile(TUtils.GetPathFolderMetaInfo + FField.Guid + '.json'); + finally + LStringList.Free; + end; end; end. diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 3a9fe5c..480564b 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -88,6 +88,7 @@ TUtils = class class function GetPathFileJSONDefaultsQuestions: string; class function GetPathFileJSONDatabases: string; class function CreateIfNecessaryAndGetPathFolderTemp: string; + class function GetPathFolderMetaInfo: string; class function GetGuidStr: string; class function GuidToFileName(const AGuid: string; const AExtension: string): string; class function GetNamespace(AText: string): string; @@ -782,7 +783,14 @@ class function TUtils.GetPathFileJSONDatabases: string; class function TUtils.CreateIfNecessaryAndGetPathFolderTemp: string; begin Result := Self.GetPathFolderRoot + TConsts.NAME_FOLDER_TEMP; - if(not DirectoryExists(Result))then + if not DirectoryExists(Result) then + ForceDirectories(Result); +end; + +class function TUtils.GetPathFolderMetaInfo: string; +begin + Result := IncludeTrailingPathDelimiter(Self.GetPathFolderRoot + TConsts.NAME_FOLDER_MetaInfo); + if not DirectoryExists(Result) then ForceDirectories(Result); end; From 58b3c8f2e2e194a1e2d115689dad4a355ce5c3e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 16 Aug 2024 16:40:46 -0300 Subject: [PATCH 022/109] Update DelphiAIDev.MetaInfo.pas --- Src/MetaInfo/DelphiAIDev.MetaInfo.pas | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas index 057372f..d2ef13b 100644 --- a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas +++ b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas @@ -74,6 +74,19 @@ procedure TDelphiAIDevMetaInfo.ConfigConn; end; procedure TDelphiAIDevMetaInfo.Process; +const +{.$DEFINE C4D_SHORT_KEY} +{$IFDEF C4D_SHORT_KEY} + KEY_NAME = 'N'; + KEY_TYPE = 'T'; + KEY_LENGTH = 'L'; + KEY_COLUMNS = 'c'; +{$ELSE} + KEY_NAME = 'name'; + KEY_TYPE = 'type'; + KEY_LENGTH = 'length'; + KEY_COLUMNS = 'columns'; +{$ENDIF} var LJSONArrayTables: TJSONArray; LJSONObjectTable: TJSONObject; @@ -100,17 +113,18 @@ procedure TDelphiAIDevMetaInfo.Process; while not FMetaInfoFields.Eof do begin LJSONObjectColumn := TJSONObject.Create; - LJSONObjectColumn.AddPair('name', TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); - LJSONObjectColumn.AddPair('type', TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); - LJSONObjectColumn.AddPair('length', TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); + LJSONObjectColumn.AddPair(KEY_NAME, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); + LJSONObjectColumn.AddPair(KEY_TYPE, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); + if KEY_LENGTH <> 'L' then + LJSONObjectColumn.AddPair(KEY_LENGTH, TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); LJSONArrayColumns.AddElement(LJSONObjectColumn); FMetaInfoFields.Next; end; LJSONObjectTable := TJSONObject.Create; - LJSONObjectTable.AddPair('name', TJSONString.Create(FMetaInfoTables.FieldByName('TABLE_NAME').AsString)); - LJSONObjectTable.AddPair('columns', LJSONArrayColumns); + LJSONObjectTable.AddPair(KEY_NAME, TJSONString.Create(FMetaInfoTables.FieldByName('TABLE_NAME').AsString)); + LJSONObjectTable.AddPair(KEY_COLUMNS, LJSONArrayColumns); LJSONArrayTables.AddElement(LJSONObjectTable); FMetaInfoTables.Next; From 8c3cda08a951f06cac947bc5d0655dd6686e6751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 16 Aug 2024 17:49:38 -0300 Subject: [PATCH 023/109] add-form-para-gerar-referencia-do-bd --- Package/DelphiAIDeveloper.dpk | 3 +- Package/DelphiAIDeveloper.dproj | 4 + Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 1 + .../DelphiAIDev.DB.References.View.dfm | 127 ++++++++++++++++++ .../DelphiAIDev.DB.References.View.pas | 98 ++++++++++++++ .../DelphiAIDev.DB.Registers.AddEdit.View.dfm | 1 + .../DelphiAIDev.DB.Registers.AddEdit.View.pas | 2 +- .../DelphiAIDev.DB.Registers.Fields.pas | 3 + .../DelphiAIDev.DB.Registers.Model.pas | 38 ++---- .../DelphiAIDev.DB.Registers.View.dfm | 20 +-- .../DelphiAIDev.DB.Registers.View.pas | 22 +-- Src/MetaInfo/DelphiAIDev.MetaInfo.pas | 18 ++- Src/Utils/DelphiAIDev.Utils.pas | 2 +- 13 files changed, 285 insertions(+), 54 deletions(-) create mode 100644 Src/DB/References/DelphiAIDev.DB.References.View.dfm create mode 100644 Src/DB/References/DelphiAIDev.DB.References.View.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index c42f9a5..b2bf14e 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -97,6 +97,7 @@ contains C4D.Conn in '..\Src\Conn\C4D.Conn.pas', C4D.Conn.Utils in '..\Src\Conn\C4D.Conn.Utils.pas', DelphiAIDev.DB.Chat.View in '..\Src\DB\Chat\DelphiAIDev.DB.Chat.View.pas' {DelphiAIDevDBChatView}, - DelphiAIDev.MetaInfo in '..\Src\MetaInfo\DelphiAIDev.MetaInfo.pas'; + DelphiAIDev.MetaInfo in '..\Src\MetaInfo\DelphiAIDev.MetaInfo.pas', + DelphiAIDev.DB.References.View in '..\Src\DB\References\DelphiAIDev.DB.References.View.pas' {DelphiAIDevDBReferencesView}; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index eeb6e5d..774640f 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -207,6 +207,10 @@
DelphiAIDevDBChatView
+ +
DelphiAIDevDBReferencesView
+ dfm +
BITMAP c4d_Logo diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 74e3ad6..84c260b 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -348,6 +348,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView item Width = 50 end> + ExplicitLeft = 959 end object pnCommands: TPanel Left = 936 diff --git a/Src/DB/References/DelphiAIDev.DB.References.View.dfm b/Src/DB/References/DelphiAIDev.DB.References.View.dfm new file mode 100644 index 0000000..de4de4c --- /dev/null +++ b/Src/DB/References/DelphiAIDev.DB.References.View.dfm @@ -0,0 +1,127 @@ +object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu] + Caption = 'IA Developer - Databases References' + ClientHeight = 161 + ClientWidth = 396 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + KeyPreview = True + OldCreateOrder = False + Position = poScreenCenter + OnCreate = FormCreate + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object Bevel2: TBevel + AlignWithMargins = True + Left = 0 + Top = 122 + Width = 396 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alBottom + Shape = bsTopLine + ExplicitLeft = -87 + ExplicitTop = 264 + ExplicitWidth = 665 + end + object Panel1: TPanel + Left = 0 + Top = 126 + Width = 396 + Height = 35 + Align = alBottom + BevelEdges = [beLeft, beRight, beBottom] + BevelOuter = bvNone + Padding.Left = 2 + Padding.Top = 2 + Padding.Right = 2 + Padding.Bottom = 2 + ParentBackground = False + TabOrder = 0 + object btnGenerate: TButton + AlignWithMargins = True + Left = 168 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alRight + Caption = 'Generate' + TabOrder = 0 + OnClick = btnGenerateClick + end + object btnClose: TButton + AlignWithMargins = True + Left = 281 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alRight + Caption = 'Close' + TabOrder = 1 + OnClick = btnCloseClick + end + end + object Panel9: TPanel + Left = 0 + Top = 0 + Width = 396 + Height = 122 + Align = alClient + BevelOuter = bvNone + ParentBackground = False + TabOrder = 1 + object Bevel1: TBevel + AlignWithMargins = True + Left = 0 + Top = 118 + Width = 396 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alBottom + Shape = bsTopLine + ExplicitTop = 444 + ExplicitWidth = 676 + end + object Label1: TLabel + Left = 24 + Top = 22 + Width = 79 + Height = 13 + Caption = 'Last generation:' + end + object lbLastGeneration: TLabel + Left = 109 + Top = 22 + Width = 81 + Height = 13 + Caption = 'lbLastGeneration' + end + object ckAddFieldSize: TCheckBox + Left = 24 + Top = 53 + Width = 85 + Height = 17 + Caption = 'Add field size' + TabOrder = 0 + end + end +end diff --git a/Src/DB/References/DelphiAIDev.DB.References.View.pas b/Src/DB/References/DelphiAIDev.DB.References.View.pas new file mode 100644 index 0000000..d331a1e --- /dev/null +++ b/Src/DB/References/DelphiAIDev.DB.References.View.pas @@ -0,0 +1,98 @@ +unit DelphiAIDev.DB.References.View; + +interface + +uses + Winapi.Windows, + Winapi.Messages, + System.SysUtils, + System.Variants, + System.Classes, + Vcl.Graphics, + Vcl.Controls, + Vcl.Forms, + Vcl.Dialogs, + Vcl.StdCtrls, + Vcl.ExtCtrls, + DelphiAIDev.Types, + DelphiAIDev.DB.Registers.Fields, + DelphiAIDev.MetaInfo; + +type + TDelphiAIDevDBReferencesView = class(TForm) + Bevel2: TBevel; + Panel1: TPanel; + btnGenerate: TButton; + btnClose: TButton; + Panel9: TPanel; + Bevel1: TBevel; + Label1: TLabel; + lbLastGeneration: TLabel; + ckAddFieldSize: TCheckBox; + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure btnCloseClick(Sender: TObject); + procedure btnGenerateClick(Sender: TObject); + private + FFields: TDelphiAIDevDBRegistersFields; + procedure FillScreenFields; + public + property Fields: TDelphiAIDevDBRegistersFields read FFields write FFields; + end; + +implementation + +uses + DelphiAIDev.Consts, + DelphiAIDev.Utils, + DelphiAIDev.Utils.OTA; + +{$R *.dfm} + +procedure TDelphiAIDevDBReferencesView.FormCreate(Sender: TObject); +begin + Self.ModalResult := mrCancel; + TUtilsOTA.IDEThemingAll(TDelphiAIDevDBReferencesView, Self); +end; + +procedure TDelphiAIDevDBReferencesView.FormShow(Sender: TObject); +begin + Self.FillScreenFields; +end; + +procedure TDelphiAIDevDBReferencesView.FillScreenFields; +begin + lbLastGeneration.Caption := 'Never'; + if FFields.LastReferences > 0 then + lbLastGeneration.Caption := DateTimeToStr(FFields.LastReferences); +end; + +procedure TDelphiAIDevDBReferencesView.btnGenerateClick(Sender: TObject); +var + LMetaInfo: TDelphiAIDevMetaInfo; +begin + Screen.Cursor := crHourGlass; + try + LMetaInfo := TDelphiAIDevMetaInfo.Create(FFields); + try + LMetaInfo.AddFieldSize := ckAddFieldSize.Checked; + LMetaInfo.Process; + finally + LMetaInfo.Free; + end; + finally + Screen.Cursor := crDefault; + end; + + Self.Close; + Self.ModalResult := mrOk; +end; + +procedure TDelphiAIDevDBReferencesView.btnCloseClick(Sender: TObject); +begin + Self.Close; + Self.ModalResult := mrCancel; +end; + +end. + diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm index db50f99..2d994a0 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm @@ -62,6 +62,7 @@ object DelphiAIDevDBRegistersAddEditView: TDelphiAIDevDBRegistersAddEditView Caption = 'Confirm' TabOrder = 0 OnClick = btnConfirmClick + ExplicitTop = 0 end object btnClose: TButton AlignWithMargins = True diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas index 168c4fc..d3436a1 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.pas @@ -85,7 +85,7 @@ procedure TDelphiAIDevDBRegistersAddEditView.FormCreate(Sender: TObject); procedure TDelphiAIDevDBRegistersAddEditView.FormShow(Sender: TObject); begin Self.FillScreenFields; - edtDescription.SetFocus + edtDescription.SetFocus; end; procedure TDelphiAIDevDBRegistersAddEditView.FillcBoxDriverID; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas index f238f94..319ea1f 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas @@ -18,6 +18,7 @@ TDelphiAIDevDBRegistersFields = class FDatabaseName: string; FVisible: Boolean; FVendorLib: string; + FLastReferences: TDateTime; public constructor Create; procedure Clear; @@ -31,6 +32,7 @@ TDelphiAIDevDBRegistersFields = class property DatabaseName: string read FDatabaseName write FDatabaseName; property Visible: Boolean read FVisible write FVisible; property VendorLib: string read FVendorLib write FVendorLib; + property LastReferences: TDateTime read FLastReferences write FLastReferences; end; implementation @@ -52,6 +54,7 @@ procedure TDelphiAIDevDBRegistersFields.Clear; FDatabaseName := ''; FVisible := True; FVendorLib := ''; + FLastReferences := 0; end; end. diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas index 5e87049..eca4e26 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas @@ -42,6 +42,7 @@ implementation DATABASE_NAME = 'database_name'; VENDOR_LIB = 'vendor_lib'; VISIBLE = 'visible'; + LAST_REFERENCE = 'last_reference'; class function TDelphiAIDevDBRegistersModel.New: IDelphiAIDevDatabasesModel; begin @@ -126,6 +127,9 @@ procedure TDelphiAIDevDBRegistersModel.FillField(const AJSONObjItem: TJSONObject if AJSONObjItem.GetValue(VISIBLE) <> nil then AField.Visible := AJSONObjItem.GetValue(VISIBLE); + + if AJSONObjItem.GetValue(LAST_REFERENCE) <> nil then + AField.LastReferences := StrToDateTimeDef(AJSONObjItem.GetValue(LAST_REFERENCE), 0); end; procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); @@ -165,36 +169,6 @@ procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc(GUID); -// -// if LJSONObjItem.GetValue(DRIVER_ID) <> nil then -// LFields.DriverID := TC4DDriverID(LJSONObjItem.GetValue(DRIVER_ID)); -// -// if LJSONObjItem.GetValue(DESCRIPTION) <> nil then -// LFields.Description := LJSONObjItem.GetValue(DESCRIPTION); -// -// if LJSONObjItem.GetValue(HOST) <> nil then -// LFields.Host := LJSONObjItem.GetValue(HOST); -// -// if LJSONObjItem.GetValue(USER) <> nil then -// LFields.User := LJSONObjItem.GetValue(USER); -// -// if LJSONObjItem.GetValue(PASSWORD) <> nil then -// LFields.Password := TUtilsCrypt.Decrypt(LJSONObjItem.GetValue(PASSWORD)); -// -// if LJSONObjItem.GetValue(PORT) <> nil then -// LFields.Port := LJSONObjItem.GetValue(PORT); -// -// if LJSONObjItem.GetValue(DATABASE_NAME) <> nil then -// LFields.DatabaseName := LJSONObjItem.GetValue(DATABASE_NAME); -// -// if LJSONObjItem.GetValue(VENDOR_LIB) <> nil then -// LFields.VendorLib := LJSONObjItem.GetValue(VENDOR_LIB); -// -// if LJSONObjItem.GetValue(VISIBLE) <> nil then -// LFields.Visible := LJSONObjItem.GetValue(VISIBLE); - AProc(LFields); end; finally @@ -241,6 +215,7 @@ procedure TDelphiAIDevDBRegistersModel.SaveData(AFields: TDelphiAIDevDBRegisters LJSONObject.AddPair(DATABASE_NAME, AFields.DatabaseName); LJSONObject.AddPair(VENDOR_LIB, AFields.VendorLib); LJSONObject.AddPair(VISIBLE, TJSONBool.Create(AFields.Visible)); + LJSONObject.AddPair(LAST_REFERENCE, TJSONString.Create(TUtils.DateTimeToStrEmpty(AFields.LastReferences))); LJSONArray.AddElement(LJSONObject); {$IF CompilerVersion <= 32.0} //Tokyo @@ -311,6 +286,9 @@ procedure TDelphiAIDevDBRegistersModel.EditData(AFields: TDelphiAIDevDBRegisters LJSONObjItem.RemovePair(VISIBLE).Free; LJSONObjItem.AddPair(VISIBLE, TJSONBool.Create(AFields.Visible)); + LJSONObjItem.RemovePair(LAST_REFERENCE).Free; + LJSONObjItem.AddPair(LAST_REFERENCE, TJSONString.Create(TUtils.DateTimeToStrEmpty(AFields.LastReferences))); + Break; end; end; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm index 1c27a4c..0f5b3e9 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm @@ -4,7 +4,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView BorderIcons = [biSystemMenu] Caption = 'IA Developer - Database registration' ClientHeight = 561 - ClientWidth = 884 + ClientWidth = 1032 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -22,7 +22,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView object Panel1: TPanel Left = 0 Top = 507 - Width = 884 + Width = 1032 Height = 35 Align = alBottom BevelEdges = [beLeft, beRight, beBottom] @@ -51,7 +51,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView end object btnClose: TButton AlignWithMargins = True - Left = 770 + Left = 918 Top = 2 Width = 110 Height = 31 @@ -116,7 +116,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView object ListView: TListView Left = 0 Top = 50 - Width = 884 + Width = 1032 Height = 457 Align = alClient Columns = < @@ -150,6 +150,10 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView Caption = 'Visible' Width = 45 end + item + Caption = 'Last generation of reference' + Width = 180 + end item Caption = 'Password' MaxWidth = 1 @@ -184,7 +188,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView object pnTop: TPanel Left = 0 Top = 0 - Width = 884 + Width = 1032 Height = 50 Margins.Left = 0 Margins.Top = 0 @@ -195,7 +199,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView TabOrder = 2 object btnSearch: TButton AlignWithMargins = True - Left = 799 + Left = 947 Top = 14 Width = 75 Height = 27 @@ -213,7 +217,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView AlignWithMargins = True Left = 10 Top = 15 - Width = 787 + Width = 935 Height = 25 Margins.Left = 10 Margins.Top = 15 @@ -228,7 +232,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView object StatusBar1: TStatusBar Left = 0 Top = 542 - Width = 884 + Width = 1032 Height = 19 Panels = < item diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas index 65926a0..51b4128 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas @@ -17,7 +17,7 @@ interface DelphiAIDev.DB.Registers.Model, DelphiAIDev.DB.Registers.Fields, DelphiAIDev.DB.Registers.AddEdit.View, - DelphiAIDev.MetaInfo; + DelphiAIDev.DB.References.View; type TDelphiAIDevDBRegistersView = class(TForm) @@ -73,9 +73,10 @@ implementation C_INDEX_SUBITEM_Port = 3; C_INDEX_SUBITEM_DatabaseName = 4; C_INDEX_SUBITEM_Visible = 5; - C_INDEX_SUBITEM_Password = 6; - C_INDEX_SUBITEM_VendorLib = 7; - C_INDEX_SUBITEM_Guid = 8; + C_INDEX_SUBITEM_LastReferences = 6; + C_INDEX_SUBITEM_Password = 7; + C_INDEX_SUBITEM_VendorLib = 8; + C_INDEX_SUBITEM_Guid = 9; procedure TDelphiAIDevDBRegistersView.FormCreate(Sender: TObject); begin @@ -194,6 +195,7 @@ procedure TDelphiAIDevDBRegistersView.ReloadDataInternal; LListItem.SubItems.Add(AFields.Port.ToString); LListItem.SubItems.Add(AFields.DatabaseName); LListItem.SubItems.Add(TUtils.BoolToStrC4D(AFields.Visible)); + LListItem.SubItems.Add(TUtils.DateTimeToStrEmpty(AFields.LastReferences)); LListItem.SubItems.Add(AFields.Password); LListItem.SubItems.Add(AFields.VendorLib); LListItem.SubItems.Add(AFields.Guid); @@ -232,6 +234,7 @@ procedure TDelphiAIDevDBRegistersView.FillFieldsWithSelectedItem(var AFields: TD AFields.Port := StrToIntDef(LListItem.SubItems[C_INDEX_SUBITEM_Port], 0); AFields.DatabaseName := LListItem.SubItems[C_INDEX_SUBITEM_DatabaseName]; AFields.Visible := TUtils.StrToBoolC4D(LListItem.SubItems[C_INDEX_SUBITEM_Visible]); + AFields.LastReferences := StrToDateTimeDef(LListItem.SubItems[C_INDEX_SUBITEM_LastReferences], 0); AFields.Password := LListItem.SubItems[C_INDEX_SUBITEM_Password]; AFields.VendorLib := LListItem.SubItems[C_INDEX_SUBITEM_VendorLib]; AFields.Guid := LListItem.SubItems[C_INDEX_SUBITEM_Guid]; @@ -368,13 +371,12 @@ procedure TDelphiAIDevDBRegistersView.btnRemoveClick(Sender: TObject); procedure TDelphiAIDevDBRegistersView.btnGenerateDatabaseReferenceClick(Sender: TObject); var + LView: TDelphiAIDevDBReferencesView; LFields: TDelphiAIDevDBRegistersFields; - LMetaInfo: TDelphiAIDevMetaInfo; begin if ListView.Selected = nil then Exit; - Screen.Cursor := crHourGlass; LFields := TDelphiAIDevDBRegistersFields.Create; try Self.FillFieldsWithSelectedItem(LFields); @@ -382,15 +384,15 @@ procedure TDelphiAIDevDBRegistersView.btnGenerateDatabaseReferenceClick(Sender: if LFields.Description.Trim.IsEmpty then TUtils.ShowMsgErrorAndAbort('Description not found'); - LMetaInfo := TDelphiAIDevMetaInfo.Create(LFields); + LView := TDelphiAIDevDBReferencesView.Create(nil); try - LMetaInfo.Process; + LView.Fields := LFields; + LView.ShowModal; finally - LMetaInfo.Free; + LView.Free; end; finally LFields.Free; - Screen.Cursor := crDefault; end; end; diff --git a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas index d2ef13b..fd72f98 100644 --- a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas +++ b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas @@ -20,7 +20,8 @@ interface FireDAC.Comp.Client, C4D.Conn, DelphiAIDev.Utils, - DelphiAIDev.DB.Registers.Fields; + DelphiAIDev.DB.Registers.Fields, + DelphiAIDev.DB.Registers.Model; type TDelphiAIDevMetaInfo = class @@ -29,12 +30,16 @@ TDelphiAIDevMetaInfo = class FC4DConn: IC4DConn; FMetaInfoTables: TFDMetaInfoQuery; FMetaInfoFields: TFDMetaInfoQuery; + FAddFieldSize: Boolean; procedure ConfigConn; procedure SaveJsonInFolder(const AJSONArrayTables: TJSONArray); + procedure SaveGenerationDataToField; public constructor Create(const AField: TDelphiAIDevDBRegistersFields); destructor Destroy; override; procedure Process; + + property AddFieldSize: Boolean read FAddFieldSize write FAddFieldSize; end; implementation @@ -115,7 +120,7 @@ procedure TDelphiAIDevMetaInfo.Process; LJSONObjectColumn := TJSONObject.Create; LJSONObjectColumn.AddPair(KEY_NAME, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); LJSONObjectColumn.AddPair(KEY_TYPE, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); - if KEY_LENGTH <> 'L' then + if FAddFieldSize then LJSONObjectColumn.AddPair(KEY_LENGTH, TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); LJSONArrayColumns.AddElement(LJSONObjectColumn); @@ -132,11 +137,19 @@ procedure TDelphiAIDevMetaInfo.Process; TUtils.ShowMsg('Terminou', LJSONArrayTables.Format); Self.SaveJsonInFolder(LJSONArrayTables); + + Self.SaveGenerationDataToField; finally LJSONArrayTables.Free; end; end; +procedure TDelphiAIDevMetaInfo.SaveGenerationDataToField; +begin + FField.LastReferences := Now; + TDelphiAIDevDBRegistersModel.New.SaveOrEditData(FField); +end; + procedure TDelphiAIDevMetaInfo.SaveJsonInFolder(const AJSONArrayTables: TJSONArray); var LStringList: TStringList; @@ -150,7 +163,6 @@ procedure TDelphiAIDevMetaInfo.SaveJsonInFolder(const AJSONArrayTables: TJSONArr // {$ENDIF} LStringList.Text := AJSONArrayTables.ToString; - LStringList.SaveToFile(TUtils.GetPathFolderMetaInfo + FField.Guid + '.json'); finally LStringList.Free; diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 480564b..fad7ba5 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -665,7 +665,7 @@ class function TUtils.StringToColorDef(AValue: string; AColorDefault: TColor = c class function TUtils.DateTimeToStrEmpty(AValue: TDateTime): string; begin Result := ''; - if(AValue > 0)then + if AValue > 0 then Result := DateTimeToStr(AValue); end; From 55f229fe288f6f3acb569266c83ec9888eb59bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 16 Aug 2024 18:00:42 -0300 Subject: [PATCH 024/109] Update DelphiAIDev.MetaInfo.pas --- Src/MetaInfo/DelphiAIDev.MetaInfo.pas | 48 +++++++++++++++------------ 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas index fd72f98..9d6bb21 100644 --- a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas +++ b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas @@ -32,7 +32,7 @@ TDelphiAIDevMetaInfo = class FMetaInfoFields: TFDMetaInfoQuery; FAddFieldSize: Boolean; procedure ConfigConn; - procedure SaveJsonInFolder(const AJSONArrayTables: TJSONArray); + procedure SaveJsonInFolder(const AJSONObject: TJSONObject); procedure SaveGenerationDataToField; public constructor Create(const AField: TDelphiAIDevDBRegistersFields); @@ -93,10 +93,11 @@ procedure TDelphiAIDevMetaInfo.Process; KEY_COLUMNS = 'columns'; {$ENDIF} var + LJSONObjAll: TJSONObject; LJSONArrayTables: TJSONArray; - LJSONObjectTable: TJSONObject; + LJSONObjTable: TJSONObject; LJSONArrayColumns: TJSONArray; - LJSONObjectColumn: TJSONObject; + LJSONObjColumn: TJSONObject; begin FC4DConn.Connection.Open; @@ -104,8 +105,12 @@ procedure TDelphiAIDevMetaInfo.Process; if FMetaInfoTables.IsEmpty then TUtils.ShowMsgAndAbort('No tables could be found in the current connection'); - LJSONArrayTables := TJSONArray.Create; + LJSONObjAll := TJSONObject.Create; try + LJSONObjAll.AddPair('Instructions', 'Teste'); + + LJSONArrayTables := TJSONArray.Create; + FMetaInfoTables.First; while not FMetaInfoTables.Eof do begin @@ -117,30 +122,31 @@ procedure TDelphiAIDevMetaInfo.Process; FMetaInfoFields.First; while not FMetaInfoFields.Eof do begin - LJSONObjectColumn := TJSONObject.Create; - LJSONObjectColumn.AddPair(KEY_NAME, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); - LJSONObjectColumn.AddPair(KEY_TYPE, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); + LJSONObjColumn := TJSONObject.Create; + LJSONObjColumn.AddPair(KEY_NAME, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); + LJSONObjColumn.AddPair(KEY_TYPE, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); if FAddFieldSize then - LJSONObjectColumn.AddPair(KEY_LENGTH, TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); + LJSONObjColumn.AddPair(KEY_LENGTH, TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); - LJSONArrayColumns.AddElement(LJSONObjectColumn); + LJSONArrayColumns.AddElement(LJSONObjColumn); FMetaInfoFields.Next; end; - LJSONObjectTable := TJSONObject.Create; - LJSONObjectTable.AddPair(KEY_NAME, TJSONString.Create(FMetaInfoTables.FieldByName('TABLE_NAME').AsString)); - LJSONObjectTable.AddPair(KEY_COLUMNS, LJSONArrayColumns); - LJSONArrayTables.AddElement(LJSONObjectTable); + LJSONObjTable := TJSONObject.Create; + LJSONObjTable.AddPair(KEY_NAME, TJSONString.Create(FMetaInfoTables.FieldByName('TABLE_NAME').AsString)); + LJSONObjTable.AddPair(KEY_COLUMNS, LJSONArrayColumns); + LJSONArrayTables.AddElement(LJSONObjTable); FMetaInfoTables.Next; end; - TUtils.ShowMsg('Terminou', LJSONArrayTables.Format); - Self.SaveJsonInFolder(LJSONArrayTables); - + LJSONObjAll.AddPair('tables', LJSONArrayTables); + Self.SaveJsonInFolder(LJSONObjAll); Self.SaveGenerationDataToField; + + TUtils.ShowMsg('Terminou', LJSONObjAll.Format); finally - LJSONArrayTables.Free; + LJSONObjAll.Free; end; end; @@ -150,19 +156,19 @@ procedure TDelphiAIDevMetaInfo.SaveGenerationDataToField; TDelphiAIDevDBRegistersModel.New.SaveOrEditData(FField); end; -procedure TDelphiAIDevMetaInfo.SaveJsonInFolder(const AJSONArrayTables: TJSONArray); +procedure TDelphiAIDevMetaInfo.SaveJsonInFolder(const AJSONObject: TJSONObject); var LStringList: TStringList; begin LStringList := TStringList.Create; try // {$IF CompilerVersion <= 32.0} //Tokyo -// LStringList.Text := AJSONArrayTables.ToJSON; +// LStringList.Text := AJSONObject.ToJSON; // {$ELSE} -// LStringList.Text := AJSONArrayTables.Format(2); +// LStringList.Text := AJSONObject.Format(2); // {$ENDIF} - LStringList.Text := AJSONArrayTables.ToString; + LStringList.Text := AJSONObject.ToString; LStringList.SaveToFile(TUtils.GetPathFolderMetaInfo + FField.Guid + '.json'); finally LStringList.Free; From bc70cc39e6edc51a90ceaf09a8a70f816111bafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Sat, 17 Aug 2024 00:08:03 -0300 Subject: [PATCH 025/109] Update DelphiAIDev.MetaInfo.pas --- Src/MetaInfo/DelphiAIDev.MetaInfo.pas | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas index 9d6bb21..efcd594 100644 --- a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas +++ b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas @@ -107,7 +107,8 @@ procedure TDelphiAIDevMetaInfo.Process; LJSONObjAll := TJSONObject.Create; try - LJSONObjAll.AddPair('Instructions', 'Teste'); + //LJSONObjAll.AddPair('Instructions', 'Teste'); + LJSONObjAll.AddPair('database_name', FField.DatabaseName); LJSONArrayTables := TJSONArray.Create; @@ -144,7 +145,7 @@ procedure TDelphiAIDevMetaInfo.Process; Self.SaveJsonInFolder(LJSONObjAll); Self.SaveGenerationDataToField; - TUtils.ShowMsg('Terminou', LJSONObjAll.Format); + TUtils.ShowV('Terminou', LJSONObjAll.Format); finally LJSONObjAll.Free; end; From 7dcd06540186bddd02469acf55b86fac87fa8fbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Sat, 17 Aug 2024 00:56:33 -0300 Subject: [PATCH 026/109] bk/2024-08-17-0056 --- Src/Conn/C4D.Conn.Firedac.pas | 1 - .../DelphiAIDev.DB.References.View.dfm | 32 ++++--- .../DelphiAIDev.DB.References.View.pas | 4 +- .../DelphiAIDev.DB.Registers.View.dfm | 1 + .../DelphiAIDev.DB.Registers.View.pas | 14 ++- Src/MetaInfo/DelphiAIDev.MetaInfo.pas | 90 +++++++++++++------ 6 files changed, 94 insertions(+), 48 deletions(-) diff --git a/Src/Conn/C4D.Conn.Firedac.pas b/Src/Conn/C4D.Conn.Firedac.pas index 50f0b16..92bdc46 100644 --- a/Src/Conn/C4D.Conn.Firedac.pas +++ b/Src/Conn/C4D.Conn.Firedac.pas @@ -79,7 +79,6 @@ constructor TC4DConnFiredac.Create(AC4DConnConfigs: TC4DConnConfigs); destructor TC4DConnFiredac.Destroy; begin - TUtils.ShowMsg('TC4DConnFiredac.Destroy'); FFBDriverLink.Free; FMySQLDriverLink.Free; diff --git a/Src/DB/References/DelphiAIDev.DB.References.View.dfm b/Src/DB/References/DelphiAIDev.DB.References.View.dfm index de4de4c..455a3c8 100644 --- a/Src/DB/References/DelphiAIDev.DB.References.View.dfm +++ b/Src/DB/References/DelphiAIDev.DB.References.View.dfm @@ -4,7 +4,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView BorderIcons = [biSystemMenu] Caption = 'IA Developer - Databases References' ClientHeight = 161 - ClientWidth = 396 + ClientWidth = 295 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -22,7 +22,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView AlignWithMargins = True Left = 0 Top = 122 - Width = 396 + Width = 295 Height = 1 Margins.Left = 0 Margins.Top = 0 @@ -36,7 +36,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView object Panel1: TPanel Left = 0 Top = 126 - Width = 396 + Width = 295 Height = 35 Align = alBottom BevelEdges = [beLeft, beRight, beBottom] @@ -49,7 +49,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView TabOrder = 0 object btnGenerate: TButton AlignWithMargins = True - Left = 168 + Left = 67 Top = 2 Width = 110 Height = 31 @@ -64,7 +64,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView end object btnClose: TButton AlignWithMargins = True - Left = 281 + Left = 180 Top = 2 Width = 110 Height = 31 @@ -81,7 +81,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView object Panel9: TPanel Left = 0 Top = 0 - Width = 396 + Width = 295 Height = 122 Align = alClient BevelOuter = bvNone @@ -91,7 +91,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView AlignWithMargins = True Left = 0 Top = 118 - Width = 396 + Width = 295 Height = 1 Margins.Left = 0 Margins.Top = 0 @@ -102,26 +102,34 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView ExplicitWidth = 676 end object Label1: TLabel - Left = 24 + Left = 37 Top = 22 Width = 79 Height = 13 Caption = 'Last generation:' end object lbLastGeneration: TLabel - Left = 109 + Left = 122 Top = 22 Width = 81 Height = 13 Caption = 'lbLastGeneration' end object ckAddFieldSize: TCheckBox - Left = 24 + Left = 37 Top = 53 - Width = 85 + Width = 99 Height = 17 - Caption = 'Add field size' + Caption = 'Add Field Length' TabOrder = 0 end + object ckCompressData: TCheckBox + Left = 37 + Top = 78 + Width = 93 + Height = 17 + Caption = 'Compress Data' + TabOrder = 1 + end end end diff --git a/Src/DB/References/DelphiAIDev.DB.References.View.pas b/Src/DB/References/DelphiAIDev.DB.References.View.pas index d331a1e..1d5d2ca 100644 --- a/Src/DB/References/DelphiAIDev.DB.References.View.pas +++ b/Src/DB/References/DelphiAIDev.DB.References.View.pas @@ -29,6 +29,7 @@ TDelphiAIDevDBReferencesView = class(TForm) Label1: TLabel; lbLastGeneration: TLabel; ckAddFieldSize: TCheckBox; + ckCompressData: TCheckBox; procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure btnCloseClick(Sender: TObject); @@ -75,7 +76,8 @@ procedure TDelphiAIDevDBReferencesView.btnGenerateClick(Sender: TObject); try LMetaInfo := TDelphiAIDevMetaInfo.Create(FFields); try - LMetaInfo.AddFieldSize := ckAddFieldSize.Checked; + LMetaInfo.AddFieldLength := ckAddFieldSize.Checked; + LMetaInfo.CompressData := ckCompressData.Checked; LMetaInfo.Process; finally LMetaInfo.Free; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm index 0f5b3e9..6400afd 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm @@ -212,6 +212,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView Caption = 'Search' TabOrder = 0 OnClick = btnSearchClick + ExplicitTop = 11 end object edtSearch: TEdit AlignWithMargins = True diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas index 51b4128..3cae233 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas @@ -94,7 +94,7 @@ procedure TDelphiAIDevDBRegistersView.FormShow(Sender: TObject); edtSearch.SetFocus; FUtilsListView - .InvertOrder(False) + .InvertOrder(True) .SortStyle(TDelphiAIDevUtilsListViewSortStyle.AlphaNum) .ColumnIndex(C_INDEX_SUBITEM_DatabaseName + 1) .CustomSort; @@ -140,12 +140,7 @@ procedure TDelphiAIDevDBRegistersView.edtSearchKeyDown(Sender: TObject; var Key: procedure TDelphiAIDevDBRegistersView.btnSearchClick(Sender: TObject); begin - Screen.Cursor := crHourGlass; - try - Self.ReloadData; - finally - Screen.Cursor := crDefault; - end; + Self.ReloadData; end; procedure TDelphiAIDevDBRegistersView.ReloadData; @@ -207,7 +202,7 @@ procedure TDelphiAIDevDBRegistersView.ReloadDataInternal; .InvertOrder(False) .CustomSort; - if(not LGuid.Trim.IsEmpty)then + if not LGuid.Trim.IsEmpty then TUtils.FindListVewItem(ListView, C_INDEX_SUBITEM_Guid, LGuid); Self.FillStatusBar(ListView.Selected); @@ -387,7 +382,8 @@ procedure TDelphiAIDevDBRegistersView.btnGenerateDatabaseReferenceClick(Sender: LView := TDelphiAIDevDBReferencesView.Create(nil); try LView.Fields := LFields; - LView.ShowModal; + if LView.ShowModal = mrOk then + Self.ReloadData; finally LView.Free; end; diff --git a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas index efcd594..e12b6dc 100644 --- a/Src/MetaInfo/DelphiAIDev.MetaInfo.pas +++ b/Src/MetaInfo/DelphiAIDev.MetaInfo.pas @@ -20,6 +20,7 @@ interface FireDAC.Comp.Client, C4D.Conn, DelphiAIDev.Utils, + DelphiAIDev.Types, DelphiAIDev.DB.Registers.Fields, DelphiAIDev.DB.Registers.Model; @@ -30,22 +31,46 @@ TDelphiAIDevMetaInfo = class FC4DConn: IC4DConn; FMetaInfoTables: TFDMetaInfoQuery; FMetaInfoFields: TFDMetaInfoQuery; - FAddFieldSize: Boolean; + FAddFieldLength: Boolean; + FCompressData: Boolean; + + FKeyName: string; + FKeyTYPE: string; + FKeyLength: string; + FKeyColumns: string; + procedure ConfigConn; procedure SaveJsonInFolder(const AJSONObject: TJSONObject); procedure SaveGenerationDataToField; + function GetInstructionsNamesKeysCompress: string; + procedure ProcessNamesKeys; public constructor Create(const AField: TDelphiAIDevDBRegistersFields); destructor Destroy; override; procedure Process; - property AddFieldSize: Boolean read FAddFieldSize write FAddFieldSize; + property AddFieldLength: Boolean read FAddFieldLength write FAddFieldLength; + property CompressData: Boolean read FCompressData write FCompressData; end; implementation +const + KEY_NAME = 'name'; + KEY_TYPE = 'type'; + KEY_LENGTH = 'length'; + KEY_COLUMNS = 'columns'; + + KEY_NAME_SHORT = 'n'; + KEY_TYPE_SHORT = 't'; + KEY_LENGTH_SHORT = 'l'; + KEY_COLUMNS_SHORT = 'c'; + constructor TDelphiAIDevMetaInfo.Create(const AField: TDelphiAIDevDBRegistersFields); begin + FAddFieldLength := False; + FCompressData := False; + FField := AField; FC4DConn := TC4DConn.New; Self.ConfigConn; @@ -78,20 +103,32 @@ procedure TDelphiAIDevMetaInfo.ConfigConn; .VendorLib(FField.VendorLib); end; +procedure TDelphiAIDevMetaInfo.ProcessNamesKeys; +begin + FKeyName := KEY_NAME; + FKeyTYPE := KEY_TYPE; + FKeyLength := KEY_LENGTH; + FKeyColumns := KEY_COLUMNS; + + if FCompressData then + begin + FKeyName := KEY_NAME_SHORT; + FKeyTYPE := KEY_TYPE_SHORT; + FKeyLength := KEY_LENGTH_SHORT; + FKeyColumns := KEY_COLUMNS_SHORT; + end; +end; + +function TDelphiAIDevMetaInfo.GetInstructionsNamesKeysCompress: string; +begin + Result := 'Some JSON keys have been abbreviated, here is the legend for the abbreviations: ' + + Format('%s = %s; ', [KEY_NAME_SHORT, KEY_NAME]) + + Format('%s = %s; ', [KEY_TYPE_SHORT, KEY_TYPE]) + + Format('%s = %s; ', [KEY_LENGTH_SHORT, KEY_LENGTH]) + + Format('%s = %s. ', [KEY_COLUMNS_SHORT, KEY_COLUMNS]); +end; + procedure TDelphiAIDevMetaInfo.Process; -const -{.$DEFINE C4D_SHORT_KEY} -{$IFDEF C4D_SHORT_KEY} - KEY_NAME = 'N'; - KEY_TYPE = 'T'; - KEY_LENGTH = 'L'; - KEY_COLUMNS = 'c'; -{$ELSE} - KEY_NAME = 'name'; - KEY_TYPE = 'type'; - KEY_LENGTH = 'length'; - KEY_COLUMNS = 'columns'; -{$ENDIF} var LJSONObjAll: TJSONObject; LJSONArrayTables: TJSONArray; @@ -99,6 +136,7 @@ procedure TDelphiAIDevMetaInfo.Process; LJSONArrayColumns: TJSONArray; LJSONObjColumn: TJSONObject; begin + Self.ProcessNamesKeys; FC4DConn.Connection.Open; FMetaInfoTables.Open; @@ -107,8 +145,11 @@ procedure TDelphiAIDevMetaInfo.Process; LJSONObjAll := TJSONObject.Create; try - //LJSONObjAll.AddPair('Instructions', 'Teste'); - LJSONObjAll.AddPair('database_name', FField.DatabaseName); + if FCompressData then + LJSONObjAll.AddPair('instructions', Self.GetInstructionsNamesKeysCompress); + + LJSONObjAll.AddPair('SGBD (database)', FField.DriverID.ToString); + LJSONObjAll.AddPair('database name', FField.DatabaseName); LJSONArrayTables := TJSONArray.Create; @@ -124,18 +165,18 @@ procedure TDelphiAIDevMetaInfo.Process; while not FMetaInfoFields.Eof do begin LJSONObjColumn := TJSONObject.Create; - LJSONObjColumn.AddPair(KEY_NAME, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); - LJSONObjColumn.AddPair(KEY_TYPE, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); - if FAddFieldSize then - LJSONObjColumn.AddPair(KEY_LENGTH, TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); + LJSONObjColumn.AddPair(FKeyName, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_NAME').AsString)); + LJSONObjColumn.AddPair(FKeyType, TJSONString.Create(FMetaInfoFields.FieldByName('COLUMN_TYPENAME').AsString)); + if FAddFieldLength then + LJSONObjColumn.AddPair(FKeyLength, TJSONNumber.Create(FMetaInfoFields.FieldByName('COLUMN_LENGTH').AsInteger)); LJSONArrayColumns.AddElement(LJSONObjColumn); FMetaInfoFields.Next; end; LJSONObjTable := TJSONObject.Create; - LJSONObjTable.AddPair(KEY_NAME, TJSONString.Create(FMetaInfoTables.FieldByName('TABLE_NAME').AsString)); - LJSONObjTable.AddPair(KEY_COLUMNS, LJSONArrayColumns); + LJSONObjTable.AddPair(FKeyName, TJSONString.Create(FMetaInfoTables.FieldByName('TABLE_NAME').AsString)); + LJSONObjTable.AddPair(FKeyColumns, LJSONArrayColumns); LJSONArrayTables.AddElement(LJSONObjTable); FMetaInfoTables.Next; @@ -145,7 +186,7 @@ procedure TDelphiAIDevMetaInfo.Process; Self.SaveJsonInFolder(LJSONObjAll); Self.SaveGenerationDataToField; - TUtils.ShowV('Terminou', LJSONObjAll.Format); + TUtils.ShowV('Process completed'); finally LJSONObjAll.Free; end; @@ -168,7 +209,6 @@ procedure TDelphiAIDevMetaInfo.SaveJsonInFolder(const AJSONObject: TJSONObject); // {$ELSE} // LStringList.Text := AJSONObject.Format(2); // {$ENDIF} - LStringList.Text := AJSONObject.ToString; LStringList.SaveToFile(TUtils.GetPathFolderMetaInfo + FField.Guid + '.json'); finally From 41033f01a5d19831072756bec9844ccce1e54d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Sat, 17 Aug 2024 03:14:41 -0300 Subject: [PATCH 027/109] bk/2024-08-17-0314 --- Src/Conn/C4D.Conn.Firedac.pas | 8 +- Src/Consts/DelphiAIDev.Consts.pas | 1 + Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 36 +- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 370 ++++++++---------- .../DelphiAIDev.DB.Registers.Fields.pas | 16 + .../DelphiAIDev.DB.Registers.Model.pas | 6 +- .../DelphiAIDev.DB.Registers.View.dfm | 1 - Src/Utils/DelphiAIDev.Utils.pas | 6 + 8 files changed, 228 insertions(+), 216 deletions(-) diff --git a/Src/Conn/C4D.Conn.Firedac.pas b/Src/Conn/C4D.Conn.Firedac.pas index 92bdc46..2782cac 100644 --- a/Src/Conn/C4D.Conn.Firedac.pas +++ b/Src/Conn/C4D.Conn.Firedac.pas @@ -184,16 +184,16 @@ function TC4DConnFiredac.TestFieldsComponentConnection: IC4DConnection; Result := Self; LEmptyFields := ''; - if FC4DConnConfigs.Database.Trim.IsEmpty then + if FC4DConnConfigs.Host.Trim.IsEmpty then LEmptyFields := LEmptyFields + 'Host. '; - if FConnection.Params.UserName.Trim.IsEmpty then + if FC4DConnConfigs.UserName.Trim.IsEmpty then LEmptyFields := LEmptyFields + 'UserName. '; - if FConnection.Params.Password.Trim.IsEmpty then + if FC4DConnConfigs.Password.Trim.IsEmpty then LEmptyFields := LEmptyFields + 'Password. '; - if Trim(FConnection.Params.Database).IsEmpty then + if FC4DConnConfigs.Database.Trim.IsEmpty then LEmptyFields := LEmptyFields + 'Database.'; if not LEmptyFields.Trim.IsEmpty then diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index f4ba79e..340c211 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -34,6 +34,7 @@ TConsts = class //NAMES FILES .rtf FILE_RTF_CHAT = 'chat.rtf'; + FILE_RTF_CHAT_DB = 'chat_db.rtf'; //NAMES FILE JSON FILE_JSON_DEFAULTS_QUESTIONS = 'delphi_ai_developer_questions.json'; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 84c260b..c523068 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -277,15 +277,35 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Bottom = 3 ParentBackground = False TabOrder = 1 - object Button1: TButton + object Label1: TLabel Left = 196 Top = 3 + Width = 85 + Height = 28 + Align = alLeft + Caption = ' Last generation: ' + Layout = tlCenter + ExplicitHeight = 13 + end + object lbLastGeneration: TLabel + Left = 281 + Top = 3 + Width = 120 + Height = 28 + Align = alLeft + AutoSize = False + Caption = 'lbLastGeneration' + Layout = tlCenter + end + object btnTestSQL: TButton + Left = 401 + Top = 3 Width = 75 Height = 28 Align = alLeft - Caption = 'Button1' + Caption = 'Test SQL' TabOrder = 0 - OnClick = Button1Click + OnClick = btnTestSQLClick end object cBoxDatabases: TComboBox AlignWithMargins = True @@ -296,6 +316,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Align = alLeft Style = csDropDownList TabOrder = 1 + OnClick = cBoxDatabasesClick end end end @@ -348,7 +369,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView item Width = 50 end> - ExplicitLeft = 959 end object pnCommands: TPanel Left = 936 @@ -556,7 +576,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object ImageList1: TImageList Left = 96 - Top = 240 + Top = 208 Bitmap = { 494C010105003000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000002000000001002000000000000020 @@ -830,8 +850,8 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView 000000000000} end object pMenuMemoReturn: TPopupMenu - Left = 96 - Top = 296 + Left = 120 + Top = 248 object Cut1: TMenuItem Caption = 'Cut' ShortCut = 16472 @@ -872,7 +892,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView object pMenuCurrentAI: TPopupMenu OnPopup = pMenuCurrentAIPopup Left = 26 - Top = 263 + Top = 231 object Gemini1: TMenuItem Caption = 'Gemini' OnClick = Gemini1Click diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 9710d56..750853a 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -3,8 +3,6 @@ interface uses - Winapi.Windows, - Winapi.Messages, System.SysUtils, System.StrUtils, System.Variants, @@ -23,6 +21,8 @@ interface Vcl.ComCtrls, Vcl.Menus, Vcl.Buttons, + Winapi.Windows, + Winapi.Messages, Clipbrd, DelphiAIDev.Types, DelphiAIDev.Consts, @@ -85,8 +85,10 @@ TDelphiAIDevDBChatView = class(TDockableForm) Panel9: TPanel; Splitter2: TSplitter; DataSource1: TDataSource; - Button1: TButton; + btnTestSQL: TButton; cBoxDatabases: TComboBox; + Label1: TLabel; + lbLastGeneration: TLabel; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); procedure Cut1Click(Sender: TObject); @@ -114,7 +116,8 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure btnDefaultsQuestionsClick(Sender: TObject); procedure Clear1Click(Sender: TObject); procedure btnCleanAllClick(Sender: TObject); - procedure Button1Click(Sender: TObject); + procedure btnTestSQLClick(Sender: TObject); + procedure cBoxDatabasesClick(Sender: TObject); private FChat: TDelphiAIDevChat; FSettings: TDelphiAIDevSettings; @@ -124,6 +127,8 @@ TDelphiAIDevDBChatView = class(TDockableForm) FbtnCodeOnlyWidth: Integer; FbtnDefaultsQuestionsWidth: Integer; FQuestionOnShow: string; + FConn: IC4DConn; + FQuery: IC4DConnQuery; procedure FillMemoReturnWithFile; procedure SaveMemoReturnInFile; procedure InitializeRichEditReturn; @@ -145,6 +150,9 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure ValidateRegistrationOfSelectedAI; procedure ReloadDatabases; procedure ClearcBoxDatabases; + procedure FillDateLastReferences; + function GetFieldDBSelected: TDelphiAIDevDBRegistersFields; + function GetJsonDatabase: string; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -210,6 +218,9 @@ constructor TDelphiAIDevDBChatView.Create(AOwner: TComponent); FPopupMenuQuestions := TDelphiAIDevDefaultsQuestionsPopupMenu.Create; FQuestionOnShow := ''; + FConn := TC4DConn.New; + FQuery := FConn.Query.DataSource(DataSource1); + Self.ConfScreenOnCreate; Self.FillMemoReturnWithFile; end; @@ -305,7 +316,7 @@ procedure TDelphiAIDevDBChatView.mmQuestionKeyDown(Sender: TObject; var Key: Wor procedure TDelphiAIDevDBChatView.mmQuestionKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin - if (ssCtrl in Shift)and(Key = 65) then + if (ssCtrl in Shift) and (Key = 65) then begin mmQuestion.SelectAll; Key := 0; @@ -361,13 +372,13 @@ procedure TDelphiAIDevDBChatView.FormResize(Sender: TObject); procedure TDelphiAIDevDBChatView.FillMemoReturnWithFile; begin - if FileExists(TUtils.GetPathFileChat) then - mmReturn.Lines.LoadFromFile(TUtils.GetPathFileChat) + if FileExists(TUtils.GetPathFileChatDB) then + mmReturn.Lines.LoadFromFile(TUtils.GetPathFileChatDB) end; procedure TDelphiAIDevDBChatView.SaveMemoReturnInFile; begin - mmReturn.Lines.SaveToFile(TUtils.GetPathFileChat); + mmReturn.Lines.SaveToFile(TUtils.GetPathFileChatDB); end; procedure TDelphiAIDevDBChatView.SelectAll1Click(Sender: TObject); @@ -377,7 +388,7 @@ procedure TDelphiAIDevDBChatView.SelectAll1Click(Sender: TObject); procedure TDelphiAIDevDBChatView.cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); begin - if not(CharInSet(Key, ['0'..'9', #8]))then + if not CharInSet(Key, ['0'..'9', #8]) then Key := #0; end; @@ -427,33 +438,30 @@ procedure TDelphiAIDevDBChatView.ChangeCodeOnly; btnCodeOnly.ImageIndex := CodeOnly_ImageIndex_OFF; end; -procedure TDelphiAIDevDBChatView.btnSendClick(Sender: TObject); -begin - //Self.ProcessSend; - -end; - procedure TDelphiAIDevDBChatView.ReloadDatabases; +var + LField: TDelphiAIDevDBRegistersFields; begin - TUtils.ShowMsg('ReloadDatabases'); - Self.ClearcBoxDatabases; TDelphiAIDevDBRegistersModel.New.ReadData( procedure(AFields: TDelphiAIDevDBRegistersFields) begin - if AFields.Description.Trim.IsEmpty then + if (not AFields.Visible) or (AFields.Description.Trim.IsEmpty) then Exit; if AFields.Visible then begin - cBoxDatabases.Items.AddObject(AFields.Description, AFields); + LField := TDelphiAIDevDBRegistersFields.Create; + LField.GetDataFromOtherObject(AFields); + cBoxDatabases.Items.AddObject(LField.Description, LField); end; end, - TAutoFreeField.No + TAutoFreeField.Yes ); cBoxDatabases.ItemIndex := 0; + Self.FillDateLastReferences; end; procedure TDelphiAIDevDBChatView.ClearcBoxDatabases; @@ -461,8 +469,6 @@ procedure TDelphiAIDevDBChatView.ClearcBoxDatabases; i: Integer; LObj: TObject; begin - TUtils.ShowMsg('ClearcBoxDatabases INI'); - for i := 0 to Pred(cBoxDatabases.Items.Count) do begin if not Assigned(cBoxDatabases.Items.Objects[i]) then @@ -474,78 +480,9 @@ procedure TDelphiAIDevDBChatView.ClearcBoxDatabases; TDelphiAIDevDBRegistersFields(LObj).Free; end; - TUtils.ShowMsg('ClearcBoxDatabases fim'); cBoxDatabases.Items.Clear; end; -procedure TDelphiAIDevDBChatView.Button1Click(Sender: TObject); -begin - TUtils.ShowMsg(TDelphiAIDevDBRegistersFields(cBoxDatabases.Items.Objects[cBoxDatabases.ItemIndex]).Description); -end; - -procedure TDelphiAIDevDBChatView.ProcessSend; -var - LTask: ITask; - LQuestion: string; -begin - if mmQuestion.Lines.Text.Trim.IsEmpty then - TUtils.ShowMsgAndAbort('No questions have been added', mmQuestion); - - Self.ValidateRegistrationOfSelectedAI; - - mmReturn.Lines.Clear; - Self.WaitingFormON; - - LQuestion := FSettings.LanguageQuestions.GetLanguageDefinition; - - if btnUseCurrentUnitCode.ImageIndex = UseCurrentUnitCode_ImageIndex_ON then - LQuestion := TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim + sLineBreak; - - if btnCodeOnly.ImageIndex = CodeOnly_ImageIndex_ON then - LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgCodeOnly; - - LQuestion := LQuestion + mmQuestion.Lines.Text; - - LTask := TTask.Create( - procedure - begin - try - try - FChat.ProcessSend(LQuestion); - except - on E: Exception do - TThread.Synchronize(nil, - procedure - begin - Self.AddResponseSimple('Unable to perform processing.' + sLineBreak + TUtils.GetExceptionMessage(E)); - Abort; - end); - end; - - TThread.Synchronize(nil, - procedure - begin - mmReturn.Lines.BeginUpdate; - try - //Optional use of one of the following lines - FProcessResponse.AddResponseComplete(FChat.Response); - Self.Last; - //Self.AddResponseSimple(FChat.Response.Text); - finally - mmReturn.Lines.EndUpdate; - end; - end); - finally - TThread.Synchronize(nil, - procedure - begin - Self.WaitingFormOFF; - end); - end; - end); - LTask.Start; -end; - procedure TDelphiAIDevDBChatView.ValidateRegistrationOfSelectedAI; const MSG = '"%s" for IA %s not specified in settings.' + sLineBreak + sLineBreak + @@ -586,116 +523,6 @@ procedure TDelphiAIDevDBChatView.AddResponseSimple(const AString: string); Self.Last; end; -////Add line-by-line response to color where Delphi code is -//procedure TDelphiAIDevDBChatView.AddResponseComplete(const AStrings: TStrings); -//var -// LLineNum: Integer; -// LLineStr: string; -// LCodeStarted: Boolean; -//begin -// mmReturn.Lines.Clear; -// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; -// mmReturn.SelAttributes.Style := []; -// -// LCodeStarted := False; -// for LLineNum := 0 to Pred(AStrings.Count) do -// begin -// LLineStr := AStrings[LLineNum].TrimRight; -// -// if not LCodeStarted then -// begin -// if TUtils.CodeIdMarkBeginCode(LLineStr) then -// begin -// LCodeStarted := True; -// Continue; -// end; -// end; -// -// if LLineStr.Trim = TConsts.MARK_END then -// begin -// LCodeStarted := False; -// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; -// Continue; -// end; -// -// if LCodeStarted then -// begin -// if (FSettings.ColorHighlightCodeDelphiUse) and (FSettings.ColorHighlightCodeDelphi <> clNone) then -// mmReturn.SelAttributes.Color := FSettings.ColorHighlightCodeDelphi -// else -// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeForCode; -// end -// else -// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; -// -// //Optional use of one of the following lines -// //mmReturn.Lines.Add(LLineStr); -// Self.AddResponseLine(LLineStr); //.Replace(TConsts.MARK_BEGIN_PASCAL2, '', [rfReplaceAll, rfIgnoreCase]) -// end; -// Self.Last; -//end; -// -////Bold in words between Backtick -//procedure TDelphiAIDevDBChatView.AddResponseLine(const ALineStr: string); -//const -// BACKTICK = '`'; -//var -// i: Integer; -// LCurrentLetter: Char; -// LNextLetter: Char; -// LLineStarted: Boolean; -// LCodeStarted: Boolean; -//begin -// if not ALineStr.Contains(BACKTICK) then -// begin -// mmReturn.Lines.Add(IFThen(ALineStr.IsEmpty, ' ', ALineStr)); -// Exit; -// end; -// -// LLineStarted := False; -// LCodeStarted := False; -// for i := 0 to ALineStr.Length do -// begin -// LCurrentLetter := ALineStr[i]; -// LNextLetter := ALineStr[Succ(i)]; -// -// if not LCodeStarted then -// begin -// if(LCurrentLetter = BACKTICK)and(LNextLetter <> BACKTICK)then -// begin -// LCodeStarted := True; -// Continue; -// end; -// end; -// -// if(LCurrentLetter = BACKTICK)and(LNextLetter <> BACKTICK)then -// begin -// LCodeStarted := False; -// mmReturn.SelAttributes.Style := []; -// Continue; -// end; -// -// SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); -// if LCodeStarted then -// mmReturn.SelAttributes.Style := [fsBold] -// else -// mmReturn.SelAttributes.Style := []; -// -// if LLineStarted then -// mmReturn.SelText := LCurrentLetter -// else -// begin -// mmReturn.Lines.Add(''); -// mmReturn.SelText := LCurrentLetter; -// -// LLineStarted := True; -// end; -// SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); -// end; -// mmReturn.SelText := ' '; -// SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); -//end; - procedure TDelphiAIDevDBChatView.WaitingFormON; begin pnWait.Visible := False; @@ -861,6 +688,147 @@ procedure TDelphiAIDevDBChatView.btnCleanAllClick(Sender: TObject); mmReturn.Lines.Clear; end; +procedure TDelphiAIDevDBChatView.cBoxDatabasesClick(Sender: TObject); +begin + Self.FillDateLastReferences; +end; + +procedure TDelphiAIDevDBChatView.FillDateLastReferences; +begin + lbLastGeneration.Caption := ''; + + if cBoxDatabases.Items.Count < 0 then + Exit; + + lbLastGeneration.Caption := TUtils.DateTimeToStrEmpty(Self.GetFieldDBSelected.LastReferences); +end; + +function TDelphiAIDevDBChatView.GetFieldDBSelected: TDelphiAIDevDBRegistersFields; +begin + Result := TDelphiAIDevDBRegistersFields(cBoxDatabases.Items.Objects[cBoxDatabases.ItemIndex]); +end; + +procedure TDelphiAIDevDBChatView.btnSendClick(Sender: TObject); +begin + Self.ProcessSend; +end; + +procedure TDelphiAIDevDBChatView.ProcessSend; +var + LTask: ITask; + LQuestion: string; +begin + if mmQuestion.Lines.Text.Trim.IsEmpty then + TUtils.ShowMsgAndAbort('No questions have been added', mmQuestion); + + Self.ValidateRegistrationOfSelectedAI; + + mmReturn.Lines.Clear; + Self.WaitingFormON; + + LQuestion := FSettings.LanguageQuestions.GetLanguageDefinition; + + if btnUseCurrentUnitCode.ImageIndex = UseCurrentUnitCode_ImageIndex_ON then + LQuestion := TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim + sLineBreak; + + if btnCodeOnly.ImageIndex = CodeOnly_ImageIndex_ON then + LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgCodeOnly + sLineBreak; + + LQuestion := LQuestion + 'O seguinte JSON se refere a estrutura de um banco de dados: '; + LQuestion := LQuestion + Self.GetJsonDatabase + sLineBreak; + LQuestion := LQuestion + 'Com base no JSON que foi informado, responda a seguinte pergunta: '; + LQuestion := LQuestion + mmQuestion.Lines.Text; + + LTask := TTask.Create( + procedure + begin + try + try + FChat.ProcessSend(LQuestion); + except + on E: Exception do + TThread.Synchronize(nil, + procedure + begin + Self.AddResponseSimple('Unable to perform processing.' + sLineBreak + TUtils.GetExceptionMessage(E)); + Abort; + end); + end; + + TThread.Synchronize(nil, + procedure + begin + mmReturn.Lines.BeginUpdate; + try + //Optional use of one of the following lines + FProcessResponse.AddResponseComplete(FChat.Response); + Self.Last; + //Self.AddResponseSimple(FChat.Response.Text); + finally + mmReturn.Lines.EndUpdate; + end; + end); + finally + TThread.Synchronize(nil, + procedure + begin + Self.WaitingFormOFF; + end); + end; + end); + LTask.Start; +end; + +function TDelphiAIDevDBChatView.GetJsonDatabase: string; +var + LFileName: string; + LStringList: TStringList; +begin + LFileName := TUtils.GetPathFolderMetaInfo + Self.GetFieldDBSelected.Guid + '.json'; + + if not FileExists(LFileName) then + TUtils.ShowMsgAndAbort('File with database structure not found', LFileName); + + LStringList := TStringList.Create; + try + LStringList.LoadFromFile(LFileName); + Result := LStringList.Text; + finally + LStringList.Free; + end; +end; + +procedure TDelphiAIDevDBChatView.btnTestSQLClick(Sender: TObject); +var + LField: TDelphiAIDevDBRegistersFields; +begin + Screen.Cursor := crHourGlass; + try + LField := Self.GetFieldDBSelected; + TUtils.ShowMsg(LField.User); + FConn.Configs + .DriverID(LField.DriverID) + .Host(LField.Host) + .UserName(LField.User) + .Password(LField.Password) + .Port(LField.Port) + .Database(LField.DatabaseName) + .VendorLib(LField.VendorLib); + + try + if not FConn.Connection.TestConnection then + TUtils.ShowMsgAndAbort('Connection refused'); + except + on E: exception do + TUtils.ShowMsgErrorAndAbort(E.Message); + end; + + FQuery.CloseClear.Add(mmReturn.Lines.Text).Open; + finally + Screen.Cursor := crDefault; + end; +end; + initialization finalization diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas index 319ea1f..ebce1f8 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas @@ -22,6 +22,7 @@ TDelphiAIDevDBRegistersFields = class public constructor Create; procedure Clear; + procedure GetDataFromOtherObject(const AOtherObj: TDelphiAIDevDBRegistersFields); property Guid: string read FGuid write FGuid; property DriverID: TC4DDriverID read FDriverID write FDriverID; property Description: string read FDescription write FDescription; @@ -57,4 +58,19 @@ procedure TDelphiAIDevDBRegistersFields.Clear; FLastReferences := 0; end; +procedure TDelphiAIDevDBRegistersFields.GetDataFromOtherObject(const AOtherObj: TDelphiAIDevDBRegistersFields); +begin + FGuid := AOtherObj.Guid; + FDriverID := AOtherObj.DriverID; + FDescription := AOtherObj.Description; + FHost := AOtherObj.Host; + FUser := AOtherObj.User; + FPassword := AOtherObj.Password; + FPort := AOtherObj.Port; + FDatabaseName := AOtherObj.DatabaseName; + FVisible := AOtherObj.Visible; + FVendorLib := AOtherObj.VendorLib; + FLastReferences := AOtherObj.LastReferences; +end; + end. diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas index eca4e26..8f61607 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Model.pas @@ -96,7 +96,8 @@ function TDelphiAIDevDBRegistersModel.ReadGuid(const AGuid: string): TDelphiAIDe end; end; -procedure TDelphiAIDevDBRegistersModel.FillField(const AJSONObjItem: TJSONObject; var AField: TDelphiAIDevDBRegistersFields); +procedure TDelphiAIDevDBRegistersModel.FillField(const AJSONObjItem: TJSONObject; + var AField: TDelphiAIDevDBRegistersFields); begin AField.Clear; AField.Guid := AJSONObjItem.GetValue(GUID); @@ -132,7 +133,8 @@ procedure TDelphiAIDevDBRegistersModel.FillField(const AJSONObjItem: TJSONObject AField.LastReferences := StrToDateTimeDef(AJSONObjItem.GetValue(LAST_REFERENCE), 0); end; -procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); +procedure TDelphiAIDevDBRegistersModel.ReadData(AProc: TProc; + const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); var LStringList: TStringList; LJSONObjItem: TJSONObject; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm index 6400afd..0f5b3e9 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm @@ -212,7 +212,6 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView Caption = 'Search' TabOrder = 0 OnClick = btnSearchClick - ExplicitTop = 11 end object edtSearch: TEdit AlignWithMargins = True diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index fad7ba5..3d0ec91 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -85,6 +85,7 @@ TUtils = class class function GetPathFolderRoot: string; //class function GetPathFileIniGeneralSettings: string; class function GetPathFileChat: string; + class function GetPathFileChatDB: string; class function GetPathFileJSONDefaultsQuestions: string; class function GetPathFileJSONDatabases: string; class function CreateIfNecessaryAndGetPathFolderTemp: string; @@ -770,6 +771,11 @@ class function TUtils.GetPathFileChat: string; Result := Self.GetPathFolderRoot + TConsts.FILE_RTF_CHAT; end; +class function TUtils.GetPathFileChatDB: string; +begin + Result := Self.GetPathFolderRoot + TConsts.FILE_RTF_CHAT_DB; +end; + class function TUtils.GetPathFileJSONDefaultsQuestions: string; begin Result := Self.GetPathFolderRoot + TConsts.FILE_JSON_DEFAULTS_QUESTIONS; From b4ba27237d8f67868a37f8352d3267589e2d745c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Sat, 17 Aug 2024 04:04:17 -0300 Subject: [PATCH 028/109] bk/2024-08-17-0404 --- Package/DelphiAIDeveloper.dpk | 3 +- Package/DelphiAIDeveloper.dproj | 1 + Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 13 ++++ Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 29 ++++++-- Src/Utils/DelphiAIDev.Utils.DBGrids.pas | 89 ++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 Src/Utils/DelphiAIDev.Utils.DBGrids.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index b2bf14e..38c9f25 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -98,6 +98,7 @@ contains C4D.Conn.Utils in '..\Src\Conn\C4D.Conn.Utils.pas', DelphiAIDev.DB.Chat.View in '..\Src\DB\Chat\DelphiAIDev.DB.Chat.View.pas' {DelphiAIDevDBChatView}, DelphiAIDev.MetaInfo in '..\Src\MetaInfo\DelphiAIDev.MetaInfo.pas', - DelphiAIDev.DB.References.View in '..\Src\DB\References\DelphiAIDev.DB.References.View.pas' {DelphiAIDevDBReferencesView}; + DelphiAIDev.DB.References.View in '..\Src\DB\References\DelphiAIDev.DB.References.View.pas' {DelphiAIDevDBReferencesView}, + DelphiAIDev.Utils.DBGrids in '..\Src\Utils\DelphiAIDev.Utils.DBGrids.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 774640f..b32a2a2 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -211,6 +211,7 @@
DelphiAIDevDBReferencesView
dfm
+ BITMAP c4d_Logo diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index c523068..db1b77b 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -17,6 +17,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView ShowHint = True OnActivate = FormActivate OnClose = FormClose + OnCreate = FormCreate OnResize = FormResize OnShow = FormShow DesignSize = ( @@ -257,12 +258,14 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Height = 291 Align = alClient DataSource = DataSource1 + Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit, dgTitleClick, dgTitleHotTrack] TabOrder = 0 TitleFont.Charset = DEFAULT_CHARSET TitleFont.Color = clWindowText TitleFont.Height = -11 TitleFont.Name = 'Tahoma' TitleFont.Style = [] + OnDrawColumnCell = DBGrid1DrawColumnCell end object Panel9: TPanel Left = 0 @@ -318,6 +321,16 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView TabOrder = 1 OnClick = cBoxDatabasesClick end + object Panel1: TPanel + Left = 656 + Top = 0 + Width = 81 + Height = 33 + Caption = 'Panel1' + Color = 5460819 + ParentBackground = False + TabOrder = 2 + end end end end diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 750853a..3bd9ce1 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -36,7 +36,8 @@ interface Vcl.DBGrids, DelphiAIDev.DB.Registers.Model, DelphiAIDev.DB.Registers.Fields, - C4D.Conn; + C4D.Conn, + DelphiAIDev.Utils.DBGrids; type TDelphiAIDevDBChatView = class(TDockableForm) @@ -89,6 +90,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) cBoxDatabases: TComboBox; Label1: TLabel; lbLastGeneration: TLabel; + Panel1: TPanel; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); procedure Cut1Click(Sender: TObject); @@ -118,6 +120,8 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure btnCleanAllClick(Sender: TObject); procedure btnTestSQLClick(Sender: TObject); procedure cBoxDatabasesClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); private FChat: TDelphiAIDevChat; FSettings: TDelphiAIDevSettings; @@ -225,6 +229,12 @@ constructor TDelphiAIDevDBChatView.Create(AOwner: TComponent); Self.FillMemoReturnWithFile; end; +procedure TDelphiAIDevDBChatView.DBGrid1DrawColumnCell(Sender: TObject; + const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); +begin + TUtilsDBGrids.DrawColumnCell(TDBGrid(Sender), Rect, DataCol, Column, Vcl.Grids.TGridDrawState(State)); +end; + destructor TDelphiAIDevDBChatView.Destroy; begin Self.SaveMemoReturnInFile; @@ -256,6 +266,16 @@ procedure TDelphiAIDevDBChatView.FormActivate(Sender: TObject); end; end; +procedure TDelphiAIDevDBChatView.FormCreate(Sender: TObject); +begin + TUtilsDBGrids.ConfDBGrid(DBGrid1); +end; + +procedure TDelphiAIDevDBChatView.FormClose(Sender: TObject; var Action: TCloseAction); +begin + Self.WaitingFormOFF; +end; + procedure TDelphiAIDevDBChatView.ConfScreenOnCreate; begin mmReturn.Lines.Clear; @@ -323,11 +343,6 @@ procedure TDelphiAIDevDBChatView.mmQuestionKeyUp(Sender: TObject; var Key: Word; end; end; -procedure TDelphiAIDevDBChatView.FormClose(Sender: TObject; var Action: TCloseAction); -begin - Self.WaitingFormOFF; -end; - procedure TDelphiAIDevDBChatView.FormResize(Sender: TObject); var LWidth: Integer; @@ -805,7 +820,7 @@ procedure TDelphiAIDevDBChatView.btnTestSQLClick(Sender: TObject); Screen.Cursor := crHourGlass; try LField := Self.GetFieldDBSelected; - TUtils.ShowMsg(LField.User); + FConn.Configs .DriverID(LField.DriverID) .Host(LField.Host) diff --git a/Src/Utils/DelphiAIDev.Utils.DBGrids.pas b/Src/Utils/DelphiAIDev.Utils.DBGrids.pas new file mode 100644 index 0000000..1944224 --- /dev/null +++ b/Src/Utils/DelphiAIDev.Utils.DBGrids.pas @@ -0,0 +1,89 @@ +unit DelphiAIDev.Utils.DBGrids; + +interface + +uses + System.Types, + Vcl.DBGrids, + Vcl.Grids, + Vcl.Graphics, + DelphiAIDev.Utils.Ota; + +type + TUtilsDBGrids = class + private + class procedure DrawColumnCellLight(const ADBGrid: TDBGrid; const ARect: TRect; const ADataCol: Integer; const AColumn: TColumn; + const AState: TGridDrawState); + class procedure DrawColumnCellDark(const ADBGrid: TDBGrid; const ARect: TRect; const ADataCol: Integer; const AColumn: TColumn; + const AState: TGridDrawState); + public + class procedure ConfDBGrid(const ADBGrid: TDBGrid); + + class procedure DrawColumnCell(const ADBGrid: TDBGrid; const ARect: TRect; const ADataCol: Integer; const AColumn: TColumn; + const AState: TGridDrawState); + end; + +implementation + +class procedure TUtilsDBGrids.DrawColumnCell(const ADBGrid: TDBGrid; const ARect: TRect; + const ADataCol: Integer; const AColumn: TColumn; const AState: TGridDrawState); +begin + if TUtilsOTA.ActiveThemeIsDark then + Self.DrawColumnCellDark(ADBGrid, ARect, ADataCol, AColumn, AState) + else + Self.DrawColumnCellLight(ADBGrid, ARect, ADataCol, AColumn, AState); +end; + +class procedure TUtilsDBGrids.DrawColumnCellLight(const ADBGrid: TDBGrid; const ARect: TRect; + const ADataCol: Integer; const AColumn: TColumn; const AState: TGridDrawState); +begin + ADBGrid.Canvas.Brush.Color := $00E6ECEC; //$00E6ECEC; + //EMULA dgRowSelect + if ARect.Top = TStringGrid(ADBGrid).CellRect(0, TStringGrid(ADBGrid).Row).Top then + begin + ADBGrid.Canvas.FillRect(ARect); + ADBGrid.Canvas.Brush.Color := $0056BBF9; + ADBGrid.Canvas.Font.Color := clWindowText; + ADBGrid.DefaultDrawDataCell(ARect, AColumn.Field, AState) + end + else if Odd(ADBGrid.DataSource.DataSet.RecNo) then + ADBGrid.Canvas.Brush.Color := clwhite; + + ADBGrid.DefaultDrawColumnCell(ARect, ADataCol, AColumn, AState); +end; + +class procedure TUtilsDBGrids.DrawColumnCellDark(const ADBGrid: TDBGrid; const ARect: TRect; const ADataCol: Integer; const AColumn: TColumn; const AState: TGridDrawState); +begin + ADBGrid.Canvas.Brush.Color := $004A4136; //$00E6ECEC + ADBGrid.Canvas.Font.Color := clWindow; + //EMULA dgRowSelect + if ARect.Top = TStringGrid(ADBGrid).CellRect(0, TStringGrid(ADBGrid).Row).Top then + begin + ADBGrid.Canvas.FillRect(ARect); + ADBGrid.Canvas.Brush.Color := clSilver; + ADBGrid.Canvas.Font.Color := clWindowText; + ADBGrid.DefaultDrawDataCell(ARect, AColumn.Field, AState) + end + else if Odd(ADBGrid.DataSource.DataSet.RecNo) then + ADBGrid.Canvas.Brush.Color := $00535353; + + ADBGrid.DefaultDrawColumnCell(ARect, ADataCol, AColumn, AState); +end; + +class procedure TUtilsDBGrids.ConfDBGrid(const ADBGrid: TDBGrid); +begin + ADBGrid.Options := ADBGrid.Options + [dgColumnResize]; + ADBGrid.Options := ADBGrid.Options + [dgTitleClick]; + ADBGrid.Options := ADBGrid.Options - [dgRowSelect]; + ADBGrid.TitleFont.Style := ADBGrid.TitleFont.Style + [fsBold]; + ADBGrid.TitleFont.Name := 'Arial'; + ADBGrid.DrawingStyle := TGridDrawingStyle.gdsThemed; + if TUtilsOTA.ActiveThemeIsDark then + begin + ADBGrid.DrawingStyle := TGridDrawingStyle.gdsGradient; + ADBGrid.GradientEndColor := $00FFF1D5; + ADBGrid.GradientStartColor := clWhite; + end; +end; + +end. From 3a7ac529497314484db7fd2072faa5f331a10bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 19 Aug 2024 23:10:49 -0300 Subject: [PATCH 029/109] bk/2024-08-19-2310 --- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 1 + Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 2 +- Src/Utils/DelphiAIDev.Utils.DBGrids.pas | 18 +++++++++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index db1b77b..2ebc4b9 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -257,6 +257,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Width = 938 Height = 291 Align = alClient + BorderStyle = bsNone DataSource = DataSource1 Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit, dgTitleClick, dgTitleHotTrack] TabOrder = 0 diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 3bd9ce1..d044235 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -230,7 +230,7 @@ constructor TDelphiAIDevDBChatView.Create(AOwner: TComponent); end; procedure TDelphiAIDevDBChatView.DBGrid1DrawColumnCell(Sender: TObject; - const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); + const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); begin TUtilsDBGrids.DrawColumnCell(TDBGrid(Sender), Rect, DataCol, Column, Vcl.Grids.TGridDrawState(State)); end; diff --git a/Src/Utils/DelphiAIDev.Utils.DBGrids.pas b/Src/Utils/DelphiAIDev.Utils.DBGrids.pas index 1944224..80ee9b8 100644 --- a/Src/Utils/DelphiAIDev.Utils.DBGrids.pas +++ b/Src/Utils/DelphiAIDev.Utils.DBGrids.pas @@ -49,23 +49,26 @@ class procedure TUtilsDBGrids.DrawColumnCellLight(const ADBGrid: TDBGrid; const else if Odd(ADBGrid.DataSource.DataSet.RecNo) then ADBGrid.Canvas.Brush.Color := clwhite; + ADBGrid.DefaultDrawColumnCell(ARect, ADataCol, AColumn, AState); end; class procedure TUtilsDBGrids.DrawColumnCellDark(const ADBGrid: TDBGrid; const ARect: TRect; const ADataCol: Integer; const AColumn: TColumn; const AState: TGridDrawState); begin - ADBGrid.Canvas.Brush.Color := $004A4136; //$00E6ECEC + ADBGrid.Canvas.Brush.Color := $00322F2D; //$004A4136; //$00E6ECEC ADBGrid.Canvas.Font.Color := clWindow; //EMULA dgRowSelect if ARect.Top = TStringGrid(ADBGrid).CellRect(0, TStringGrid(ADBGrid).Row).Top then begin ADBGrid.Canvas.FillRect(ARect); - ADBGrid.Canvas.Brush.Color := clSilver; + ADBGrid.Canvas.Brush.Color := $00C08000; //$005B4224; ADBGrid.Canvas.Font.Color := clWindowText; ADBGrid.DefaultDrawDataCell(ARect, AColumn.Field, AState) end else if Odd(ADBGrid.DataSource.DataSet.RecNo) then - ADBGrid.Canvas.Brush.Color := $00535353; + ADBGrid.Canvas.Brush.Color := $004A4132; //$00535353; + + //ADBGrid.Canvas.FillRect(ARect); ADBGrid.DefaultDrawColumnCell(ARect, ADataCol, AColumn, AState); end; @@ -77,12 +80,17 @@ class procedure TUtilsDBGrids.ConfDBGrid(const ADBGrid: TDBGrid); ADBGrid.Options := ADBGrid.Options - [dgRowSelect]; ADBGrid.TitleFont.Style := ADBGrid.TitleFont.Style + [fsBold]; ADBGrid.TitleFont.Name := 'Arial'; + ADBGrid.TitleFont.Color := clWindowText; ADBGrid.DrawingStyle := TGridDrawingStyle.gdsThemed; + if TUtilsOTA.ActiveThemeIsDark then begin + ADBGrid.TitleFont.Color := clWindow; ADBGrid.DrawingStyle := TGridDrawingStyle.gdsGradient; - ADBGrid.GradientEndColor := $00FFF1D5; - ADBGrid.GradientStartColor := clWhite; + ADBGrid.GradientStartColor := $005C5143; + ADBGrid.GradientEndColor := $00342D25; //$00FFF1D5; + + ADBGrid.Color := $00322F2D; end; end; From c2b8327454e8a0b8032c4e0e6bcd32938a21422e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 20 Aug 2024 00:19:14 -0300 Subject: [PATCH 030/109] bk/2024-08-20-0019 --- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 29 +++++ Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 39 +++++++ Src/Types/DelphiAIDev.Types.pas | 4 +- Src/Utils/DelphiAIDev.Utils.DBGrids.pas | 133 ++++++++++++++++++++++- Src/Utils/DelphiAIDev.Utils.pas | 3 - 5 files changed, 201 insertions(+), 7 deletions(-) diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 2ebc4b9..7aaf555 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -260,6 +260,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView BorderStyle = bsNone DataSource = DataSource1 Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit, dgTitleClick, dgTitleHotTrack] + PopupMenu = pMenuGrid TabOrder = 0 TitleFont.Charset = DEFAULT_CHARSET TitleFont.Color = clWindowText @@ -939,4 +940,32 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Left = 170 Top = 464 end + object pMenuGrid: TPopupMenu + Left = 794 + Top = 472 + object CopyCurrentColumn1: TMenuItem + Caption = 'Copy current column' + ShortCut = 16451 + OnClick = CopyCurrentColumn1Click + end + object CopyCurrentLine1: TMenuItem + Caption = 'Copy current line' + OnClick = CopyCurrentLine1Click + end + object CopyAllGridData: TMenuItem + Caption = 'Copy all grid data' + OnClick = CopyAllGridDataClick + end + object N3: TMenuItem + Caption = '-' + end + object SaveAllGridDataAsCSV: TMenuItem + Caption = 'Save all grid data as CSV' + OnClick = SaveAllGridDataAsCSVClick + end + object SaveAllGridDataAsTXT: TMenuItem + Caption = 'Save all grid data as TXT' + OnClick = SaveAllGridDataAsTXTClick + end + end end diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index d044235..d91cda9 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -91,6 +91,13 @@ TDelphiAIDevDBChatView = class(TDockableForm) Label1: TLabel; lbLastGeneration: TLabel; Panel1: TPanel; + pMenuGrid: TPopupMenu; + CopyCurrentColumn1: TMenuItem; + CopyCurrentLine1: TMenuItem; + CopyAllGridData: TMenuItem; + N3: TMenuItem; + SaveAllGridDataAsCSV: TMenuItem; + SaveAllGridDataAsTXT: TMenuItem; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); procedure Cut1Click(Sender: TObject); @@ -122,6 +129,11 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure cBoxDatabasesClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); + procedure CopyCurrentColumn1Click(Sender: TObject); + procedure CopyCurrentLine1Click(Sender: TObject); + procedure CopyAllGridDataClick(Sender: TObject); + procedure SaveAllGridDataAsCSVClick(Sender: TObject); + procedure SaveAllGridDataAsTXTClick(Sender: TObject); private FChat: TDelphiAIDevChat; FSettings: TDelphiAIDevSettings; @@ -844,6 +856,33 @@ procedure TDelphiAIDevDBChatView.btnTestSQLClick(Sender: TObject); end; end; +procedure TDelphiAIDevDBChatView.CopyCurrentColumn1Click(Sender: TObject); +begin + TUtilsDBGrids.DBGridToClipboardCurrentColumn(DBGrid1); +end; + +procedure TDelphiAIDevDBChatView.CopyCurrentLine1Click(Sender: TObject); +begin + TUtilsDBGrids.DBGridToClipboardCurrentLine(DBGrid1); +end; + +procedure TDelphiAIDevDBChatView.CopyAllGridDataClick(Sender: TObject); +begin + TUtilsDBGrids.DBGridToClipboardAll(DBGrid1); +end; + +procedure TDelphiAIDevDBChatView.SaveAllGridDataAsCSVClick(Sender: TObject); +begin + TUtilsDBGrids.DBGridToCSV(DBGrid1); + TUtils.ShowV('File saved successfully'); +end; + +procedure TDelphiAIDevDBChatView.SaveAllGridDataAsTXTClick(Sender: TObject); +begin + TUtilsDBGrids.DBGridToTxt(DBGrid1); + TUtils.ShowV('File saved successfully'); +end; + initialization finalization diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index 54920f0..fba14f0 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -15,7 +15,7 @@ interface TC4DLanguage = (en, ptBR, es); TC4DExtensionsFiles = (None, PAS, DFM, FMX, DPR, DPK, DPROJ, ZIP, BMP, INI, ALL); TC4DExtensionsOfFiles = set of TC4DExtensionsFiles; - TC4DExtensionsCommon = (rtf); + TC4DExtensionsCommon = (rtf, csv, txt); TC4DIcon = (Information, Question, Warning, Error, Success); TC4DButtons = (OK, OK_Cancel); TC4DBtnFocu = (OK, Cancel); @@ -166,7 +166,7 @@ function TC4DExtensionsOfFilesHelper.ContainsStr(const AExtension: string): Bool { TC4DExtensionsCommonHelper } function TC4DExtensionsCommonHelper.ToString: string; begin - Result := GetEnumName(TypeInfo(TC4DExtensionsFiles), Integer(Self)).ToLower; + Result := GetEnumName(TypeInfo(TC4DExtensionsCommon), Integer(Self)).ToLower; end; function TC4DExtensionsCommonHelper.ToStringWithPoint: string; diff --git a/Src/Utils/DelphiAIDev.Utils.DBGrids.pas b/Src/Utils/DelphiAIDev.Utils.DBGrids.pas index 80ee9b8..d310562 100644 --- a/Src/Utils/DelphiAIDev.Utils.DBGrids.pas +++ b/Src/Utils/DelphiAIDev.Utils.DBGrids.pas @@ -3,11 +3,17 @@ interface uses + System.SysUtils, System.Types, + System.Classes, + Data.DB, Vcl.DBGrids, Vcl.Grids, Vcl.Graphics, - DelphiAIDev.Utils.Ota; + Vcl.Clipbrd, + DelphiAIDev.Utils, + DelphiAIDev.Utils.Ota, + DelphiAIDev.Types; type TUtilsDBGrids = class @@ -17,14 +23,137 @@ TUtilsDBGrids = class class procedure DrawColumnCellDark(const ADBGrid: TDBGrid; const ARect: TRect; const ADataCol: Integer; const AColumn: TColumn; const AState: TGridDrawState); public - class procedure ConfDBGrid(const ADBGrid: TDBGrid); + class procedure DBGridToClipboardCurrentColumn(const ADBGrid: TDBGrid); + class procedure DBGridToClipboardCurrentLine(ADBGrid: TDBGrid; ACopyTitle: Boolean = True); + class procedure DBGridToClipboardAll(ADBGrid: TDBGrid; ACopyTitle: Boolean = True); + class procedure DBGridToCSV(ADBGrid: TDBGrid; ACopyTitle: Boolean = True); + class procedure DBGridToTxt(ADBGrid: TDBGrid; ACopyTitle: Boolean = True); + class procedure DBGridToFile(ADBGrid: TDBGrid; const AExtension: string; + const ASeparator: string; ACopyTitle: Boolean = True); + class function DBGridToString(ADBGrid: TDBGrid; const AExtension: string; + ACopyTitle: Boolean = True): string; + class procedure ConfDBGrid(const ADBGrid: TDBGrid); class procedure DrawColumnCell(const ADBGrid: TDBGrid; const ARect: TRect; const ADataCol: Integer; const AColumn: TColumn; const AState: TGridDrawState); end; implementation +class procedure TUtilsDBGrids.DBGridToClipboardCurrentColumn(const ADBGrid: TDBGrid); +var + LText: string; +begin + if ADBGrid.DataSource.DataSet.IsEmpty then + Exit; + + if ADBGrid.SelectedIndex < 0 then + Exit; + + LText := ADBGrid.Columns[ADBGrid.SelectedIndex].Field.AsString; + ClipBoard.Clear; + ClipBoard.SetTextBuf(PWideChar(LText)); +end; + +class procedure TUtilsDBGrids.DBGridToClipboardCurrentLine(ADBGrid: TDBGrid; ACopyTitle: Boolean = True); +var + LText: string; + LContCol: Integer; +begin + if ADBGrid.DataSource.DataSet.IsEmpty then + Exit; + + LText := ''; + if ACopyTitle then + begin + LText := ADBGrid.Columns[0].Title.Caption; + for LContCol := 1 to Pred(ADBGrid.Columns.Count) do + LText := format('%s|%s', [LText, ADBGrid.Columns[LContCol].Title.Caption]); + + LText := LText + sLineBreak; + end; + + LText := LText + ADBGrid.Columns[0].Field.AsString; + for LContCol := 1 to Pred(ADBGrid.Columns.Count) do + LText := format('%s|%s', [LText, ADBGrid.Columns[LContCol].Field.AsString]); + + LText := LText + sLineBreak; + ClipBoard.Clear; + ClipBoard.SetTextBuf(PWideChar(LText)); +end; + +class procedure TUtilsDBGrids.DBGridToClipboardAll(ADBGrid: TDBGrid; ACopyTitle: Boolean = True); +var + LText: string; +begin + LText := Self.DBGridToString(ADBGrid, ';', ACopyTitle); + ClipBoard.Clear; + ClipBoard.SetTextBuf(PWideChar(LText)); +end; + +class procedure TUtilsDBGrids.DBGridToCSV(ADBGrid: TDBGrid; ACopyTitle: Boolean = True); +begin + Self.DBGridToFile(ADBGrid, TC4DExtensionsCommon.csv.ToString, ';', ACopyTitle); +end; + +class procedure TUtilsDBGrids.DBGridToTxt(ADBGrid: TDBGrid; ACopyTitle: Boolean = True); +begin + Self.DBGridToFile(ADBGrid, TC4DExtensionsCommon.txt.ToString, '|', ACopyTitle); +end; + +class procedure TUtilsDBGrids.DBGridToFile(ADBGrid: TDBGrid; const AExtension: string; + const ASeparator: string; ACopyTitle: Boolean = True); +var + LStrings: TStringList; + LFileName: string; +begin + LFileName := TUtils.GetFileName(AExtension); + + LStrings := TStringList.Create; + try + LStrings.Text := Self.DBGridToString(ADBGrid, ASeparator, ACopyTitle); + LStrings.SaveToFile(LFileName); + finally + LStrings.Free; + end; +end; + +class function TUtilsDBGrids.DBGridToString(ADBGrid: TDBGrid; const AExtension: string; + ACopyTitle: Boolean = True): string; +var + LContCol: Integer; + LBookMarkCurrent: TBookMark; +begin + Result := ''; + if ACopyTitle then + begin + Result := ADBGrid.Columns[0].Title.Caption; + for LContCol := 1 to Pred(ADBGrid.Columns.Count) do + Result := format('%s%s%s', [Result, AExtension, ADBGrid.Columns[LContCol].Title.Caption]); + + Result := Result + sLineBreak; + end; + + LBookMarkCurrent := ADBGrid.DataSource.DataSet.GetBookmark; + ADBGrid.DataSource.DataSet.DisableControls; + try + ADBGrid.DataSource.DataSet.First; + while not ADBGrid.DataSource.DataSet.Eof do + begin + Result := Result + ADBGrid.Columns[0].Field.AsString; + for LContCol := 1 to Pred(ADBGrid.Columns.Count) do + Result := format('%s%s%s', [Result, AExtension, ADBGrid.Columns[LContCol].Field.AsString]); + Result := Result + sLineBreak; + ADBGrid.DataSource.DataSet.Next; + end; + + ADBGrid.DataSource.DataSet.GotoBookMark(LBookMarkCurrent); + ADBGrid.DataSource.DataSet.FreeBookMark(LBookMarkCurrent); + finally + ADBGrid.DataSource.DataSet.EnableControls; + end; +end; + class procedure TUtilsDBGrids.DrawColumnCell(const ADBGrid: TDBGrid; const ARect: TRect; const ADataCol: Integer; const AColumn: TColumn; const AState: TGridDrawState); begin diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 3d0ec91..27f006d 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -11,10 +11,8 @@ interface System.StrUtils, System.Classes, System.TypInfo, - System.JSON, System.Generics.Collections, - Vcl.Controls, Vcl.Forms, Vcl.Graphics, @@ -236,7 +234,6 @@ class procedure TUtils.AddLog(const AMessage: string); end; class function TUtils.GetFileName(const AExtension: string): string; - var LFileName: string; LSaveDialog: TSaveDialog; From 8ba723990a74644b56c5e62ae569655feb65a952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 20 Aug 2024 00:33:40 -0300 Subject: [PATCH 031/109] bk/2024-08-20-0033 --- Src/Conn/C4D.Conn.Firedac.Query.pas | 13 +++++++++++++ Src/Conn/C4D.Conn.Interfaces.pas | 2 ++ Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 1 + Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 20 ++++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/Src/Conn/C4D.Conn.Firedac.Query.pas b/Src/Conn/C4D.Conn.Firedac.Query.pas index a5c0c93..01f059c 100644 --- a/Src/Conn/C4D.Conn.Firedac.Query.pas +++ b/Src/Conn/C4D.Conn.Firedac.Query.pas @@ -77,6 +77,8 @@ TC4DConnFiredacQuery = class(TInterfacedObject, IC4DConnQuery) function RecNo: Integer; function RecordCount: Integer; function RecordCountStr(pNumZerosLeft: Integer = 6): string; + function IndexFieldNames: string; overload; + function IndexFieldNames(Value: string): IC4DConnQuery; overload; function GetLastAutoGenValue(const AName: string): Variant; public class function New(AC4DConnection: IC4DConnection; ANameQuery: string): IC4DConnQuery; @@ -406,6 +408,17 @@ function TC4DConnFiredacQuery.RecordCountStr(pNumZerosLeft: Integer = 6): string Result := FQuery.RecordCount.ToString; end; +function TC4DConnFiredacQuery.IndexFieldNames: string; +begin + Result := FQuery.IndexFieldNames; +end; + +function TC4DConnFiredacQuery.IndexFieldNames(Value: string): IC4DConnQuery; +begin + Result := Self; + FQuery.IndexFieldNames := Value; +end; + //AName = PARA MYSQL E FIREDAC NOME DO CAMPO function TC4DConnFiredacQuery.GetLastAutoGenValue(const AName: string): Variant; begin diff --git a/Src/Conn/C4D.Conn.Interfaces.pas b/Src/Conn/C4D.Conn.Interfaces.pas index b5286e4..bc5d018 100644 --- a/Src/Conn/C4D.Conn.Interfaces.pas +++ b/Src/Conn/C4D.Conn.Interfaces.pas @@ -61,6 +61,8 @@ interface function RecNo: Integer; function RecordCount: Integer; function RecordCountStr(ANumZerosLeft: Integer = 6): string; + function IndexFieldNames: string; overload; + function IndexFieldNames(Value: string): IC4DConnQuery; overload; //AName = PARA MYSQL E ZEOS NOME DA TABELA //AName = PARA MYSQL E FIREDAC NOME DO CAMPO diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 7aaf555..b1bfcfa 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -268,6 +268,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView TitleFont.Name = 'Tahoma' TitleFont.Style = [] OnDrawColumnCell = DBGrid1DrawColumnCell + OnTitleClick = DBGrid1TitleClick end object Panel9: TPanel Left = 0 diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index d91cda9..b6713db 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -134,6 +134,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure CopyAllGridDataClick(Sender: TObject); procedure SaveAllGridDataAsCSVClick(Sender: TObject); procedure SaveAllGridDataAsTXTClick(Sender: TObject); + procedure DBGrid1TitleClick(Column: TColumn); private FChat: TDelphiAIDevChat; FSettings: TDelphiAIDevSettings; @@ -883,6 +884,25 @@ procedure TDelphiAIDevDBChatView.SaveAllGridDataAsTXTClick(Sender: TObject); TUtils.ShowV('File saved successfully'); end; +procedure TDelphiAIDevDBChatView.DBGrid1TitleClick(Column: TColumn); +var + LCampo: string; + LOrdem: string; +begin + if DataSource1.DataSet.IsEmpty then + Exit; + + LCampo := Column.FieldName.Trim; + if (LCampo.IsEmpty) or (Column.Field.FieldKind = fkCalculated) then + Exit; + + LOrdem := LCampo + ':D'; + if FQuery.IndexFieldNames.Contains(':D') then + LOrdem := LCampo; + + FQuery.IndexFieldNames(LOrdem); +end; + initialization finalization From e465e0b3d7822790563a83bd41a8ba440ab0058e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 20 Aug 2024 03:20:45 -0300 Subject: [PATCH 032/109] bk/2024-08-20-0320 --- Src/AI/DelphiAIDev.AI.ChatGPT.pas | 4 +- Src/AI/DelphiAIDev.AI.Gemini.pas | 7 +- Src/AI/DelphiAIDev.AI.Groq.pas | 4 +- Src/Chat/DelphiAIDev.Chat.View.dfm | 5 +- Src/Chat/DelphiAIDev.Chat.View.pas | 2 +- Src/Chat/DelphiAIDev.Chat.pas | 13 +- Src/Conn/C4D.Conn.Firedac.Query.pas | 6 +- Src/Consts/DelphiAIDev.Consts.pas | 4 + Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 285 ++++++++++++--------- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 29 ++- Src/Settings/DelphiAIDev.Settings.View.dfm | 20 +- Src/Settings/DelphiAIDev.Settings.pas | 4 +- Src/Types/DelphiAIDev.Types.pas | 36 ++- Src/Utils/DelphiAIDev.Utils.pas | 5 +- 14 files changed, 253 insertions(+), 171 deletions(-) diff --git a/Src/AI/DelphiAIDev.AI.ChatGPT.pas b/Src/AI/DelphiAIDev.AI.ChatGPT.pas index 7d7e4a8..caabefb 100644 --- a/Src/AI/DelphiAIDev.AI.ChatGPT.pas +++ b/Src/AI/DelphiAIDev.AI.ChatGPT.pas @@ -39,7 +39,6 @@ constructor TDelphiAIDevAIChatGPT.Create(const ASettings: TDelphiAIDevSettings); function TDelphiAIDevAIChatGPT.GetResponse(const AQuestion: string): string; var - LQuestion: string; LResponse: IResponse; LJsonValueAll: TJSONValue; LJsonValueChoices: TJSONValue; @@ -50,14 +49,13 @@ function TDelphiAIDevAIChatGPT.GetResponse(const AQuestion: string): string; LItemChoices: Integer; begin Result := ''; - LQuestion := TUtils.AdjustQuestionToJson(AQuestion); //AQuestion.Replace(sLineBreak, '\n', [rfReplaceAll, rfIgnoreCase]); LResponse := TRequest.New .BaseURL(FSettings.BaseUrlOpenAI) .ContentType('application/json') .Accept('application/json') .Token('Bearer ' + FSettings.ApiKeyOpenAI) - .AddBody(Format(API_JSON_BODY_BASE, [FSettings.ModelOpenAI, LQuestion])) + .AddBody(Format(API_JSON_BODY_BASE, [FSettings.ModelOpenAI, AQuestion])) .Post; if LResponse.StatusCode <> 200 then diff --git a/Src/AI/DelphiAIDev.AI.Gemini.pas b/Src/AI/DelphiAIDev.AI.Gemini.pas index ea58252..c70470b 100644 --- a/Src/AI/DelphiAIDev.AI.Gemini.pas +++ b/Src/AI/DelphiAIDev.AI.Gemini.pas @@ -40,23 +40,22 @@ constructor TDelphiAIDevAIGemini.Create(const ASettings: TDelphiAIDevSettings); function TDelphiAIDevAIGemini.GetResponse(const AQuestion: string): string; var LApiUrl: string; - LQuestion: string; LResponse: IResponse; LJsonValueAll: TJSONVALUE; LJsonArrayCandidates: TJsonArray; LJsonArrayParts: TJsonArray; LJsonObjContent: TJsonObject; LJsonObjParts: TJsonObject; - LItemCandidates, LItemParts: Integer; + LItemCandidates: Integer; + LItemParts: Integer; begin Result := ''; LApiUrl := FSettings.BaseUrlGemini + FSettings.ModelGemini + '?key=' + FSettings.ApiKeyGemini; - LQuestion := TUtils.AdjustQuestionToJson(AQuestion); LResponse := TRequest.New .BaseURL(LApiUrl) .Accept('application/json') - .AddBody(Format(API_JSON_BODY_BASE, [LQuestion])) + .AddBody(Format(API_JSON_BODY_BASE, [AQuestion])) .Post; if LResponse.StatusCode <> 200 then diff --git a/Src/AI/DelphiAIDev.AI.Groq.pas b/Src/AI/DelphiAIDev.AI.Groq.pas index 599efde..d534328 100644 --- a/Src/AI/DelphiAIDev.AI.Groq.pas +++ b/Src/AI/DelphiAIDev.AI.Groq.pas @@ -39,7 +39,6 @@ constructor TDelphiAIDevAIGroq.Create(const ASettings: TDelphiAIDevSettings); function TDelphiAIDevAIGroq.GetResponse(const AQuestion: string): string; var - LQuestion: string; LResponse: IResponse; LJsonValueAll: TJSONVALUE; LJsonArrayChoices: TJsonArray; @@ -48,14 +47,13 @@ function TDelphiAIDevAIGroq.GetResponse(const AQuestion: string): string; LItemChoices: Integer; begin Result := ''; - LQuestion := TUtils.AdjustQuestionToJson(AQuestion); LResponse := TRequest.New .BaseURL(FSettings.BaseUrlGroq) .ContentType('application/json') .Accept('application/json') .Token('Bearer ' + FSettings.ApiKeyGroq) - .AddBody(Format(API_JSON_BODY_BASE, [LQuestion, FSettings.ModelGroq])) + .AddBody(Format(API_JSON_BODY_BASE, [AQuestion, FSettings.ModelGroq])) .Post; if LResponse.StatusCode <> 200 then diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index d352cfb..c4617a5 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -119,7 +119,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView OnKeyUp = mmQuestionKeyUp end end - object pnBackStatusBar: TPanel + object pnBackButtons: TPanel Left = 18 Top = 634 Width = 938 @@ -138,7 +138,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Left = 0 Top = 3 Width = 56 - Height = 13 + Height = 22 Cursor = crHandPoint Hint = 'AI being used' Margins.Left = 0 @@ -149,6 +149,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'lbCurrentAI' PopupMenu = pMenuCurrentAI OnClick = lbCurrentAIClick + ExplicitHeight = 13 end object btnSend: TButton AlignWithMargins = True diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index 8510f44..d32cf98 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -52,7 +52,7 @@ TDelphiAIDevChatView = class(TDockableForm) pMenuCurrentAI: TPopupMenu; Gemini1: TMenuItem; ChatGPT1: TMenuItem; - pnBackStatusBar: TPanel; + pnBackButtons: TPanel; lbCurrentAI: TLabel; StatusBar1: TStatusBar; pnCommands: TPanel; diff --git a/Src/Chat/DelphiAIDev.Chat.pas b/Src/Chat/DelphiAIDev.Chat.pas index 614e282..3bf535e 100644 --- a/Src/Chat/DelphiAIDev.Chat.pas +++ b/Src/Chat/DelphiAIDev.Chat.pas @@ -5,6 +5,7 @@ interface uses System.SysUtils, System.Classes, + DelphiAIDev.Utils, DelphiAIDev.Types, DelphiAIDev.Settings, DelphiAIDev.AI.Gemini, @@ -39,18 +40,22 @@ destructor TDelphiAIDevChat.Destroy; end; procedure TDelphiAIDevChat.ProcessSend(const AQuestion: string); +var + LQuestion: string; begin + LQuestion := TUtils.AdjustQuestionToJson(AQuestion); + TUtils.ShowMsgSynchronize('LQuestion', LQuestion); FResponse.Clear; case FSettings.AIDefault of TC4DAIsAvailable.Gemini: - FResponse.Text := TDelphiAIDevAIGemini.New(FSettings).GetResponse(AQuestion); + FResponse.Text := TDelphiAIDevAIGemini.New(FSettings).GetResponse(LQuestion); TC4DAIsAvailable.OpenAI: - FResponse.Text := TDelphiAIDevAIChatGPT.New(FSettings).GetResponse(AQuestion); + FResponse.Text := TDelphiAIDevAIChatGPT.New(FSettings).GetResponse(LQuestion); TC4DAIsAvailable.Groq: - FResponse.Text := TDelphiAIDevAIGroq.New(FSettings).GetResponse(AQuestion); + FResponse.Text := TDelphiAIDevAIGroq.New(FSettings).GetResponse(LQuestion); else - FResponse.Add('Default AI not reported in Delphi AI Developer settings'); + FResponse.Text := 'Default AI not reported in Delphi AI Developer settings'; end; end; diff --git a/Src/Conn/C4D.Conn.Firedac.Query.pas b/Src/Conn/C4D.Conn.Firedac.Query.pas index 01f059c..e998cc1 100644 --- a/Src/Conn/C4D.Conn.Firedac.Query.pas +++ b/Src/Conn/C4D.Conn.Firedac.Query.pas @@ -76,7 +76,7 @@ TC4DConnFiredacQuery = class(TInterfacedObject, IC4DConnQuery) function FieldByName(Value: string): TField; function RecNo: Integer; function RecordCount: Integer; - function RecordCountStr(pNumZerosLeft: Integer = 6): string; + function RecordCountStr(ANumZerosLeft: Integer = 6): string; function IndexFieldNames: string; overload; function IndexFieldNames(Value: string): IC4DConnQuery; overload; function GetLastAutoGenValue(const AName: string): Variant; @@ -403,9 +403,9 @@ function TC4DConnFiredacQuery.RecordCount: Integer; Result := FQuery.RecordCount; end; -function TC4DConnFiredacQuery.RecordCountStr(pNumZerosLeft: Integer = 6): string; +function TC4DConnFiredacQuery.RecordCountStr(ANumZerosLeft: Integer = 6): string; begin - Result := FQuery.RecordCount.ToString; + Result := Format('%'+ ANumZerosLeft.ToString +'.'+ ANumZerosLeft.ToString +'d',[FQuery.RecordCount]); end; function TC4DConnFiredacQuery.IndexFieldNames: string; diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index 340c211..8f6f816 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -19,6 +19,8 @@ TConsts = class MARK_BEGIN_DELPHI = '```delphi'; MARK_BEGIN_PASCAL = '```objectpascal'; MARK_BEGIN_PASCAL2 = '``pascal'; + MARK_BEGIN_SQL = '```sql'; + MARK_BEGIN_SQL2 = '``sql'; MARK_END = '```'; PREFIX_NAME_SEPARATOR = 'DelphiAIDevSeparator'; @@ -27,7 +29,9 @@ TConsts = class BASE_URL_GEMINI_DEFAULT = 'https://generativelanguage.googleapis.com/'; MODEL_GEMINI_DEFAULT = 'v1/models/gemini-1.5-flash:generateContent'; BASE_URL_OPEN_AI = 'https://api.openai.com/v1/chat/completions/'; + MODEL_OPEN_AI_DEFAULT = 'gpt-4o-2024-08-06'; BASE_URL_GROQ = 'https://api.groq.com/openai/v1/chat/completions'; + MODEL_GROQ_DEFAULT = 'llama3-70b-8192'; //'llama3-8b-8192';; //NAMES FILES .INI FILE_INI_GENERAL_SETTINGS = 'delphi-ai-developer.ini'; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index b1bfcfa..4afd496 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -43,11 +43,11 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView TabOrder = 0 object Splitter1: TSplitter Left = 18 - Top = 190 + Top = 128 Width = 938 Height = 3 Cursor = crVSplit - Align = alBottom + Align = alTop ExplicitLeft = 0 ExplicitTop = 2 ExplicitWidth = 528 @@ -65,9 +65,10 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView object mmReturn: TRichEdit AlignWithMargins = True Left = 18 - Top = 15 + Top = 158 Width = 938 - Height = 172 + Height = 145 + Hint = 'Response returned' Margins.Left = 0 Margins.Top = 0 Margins.Right = 0 @@ -95,14 +96,14 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object pnBackQuestion: TPanel Left = 18 - Top = 193 + Top = 15 Width = 938 Height = 113 Margins.Left = 0 Margins.Top = 0 Margins.Right = 0 Margins.Bottom = 0 - Align = alBottom + Align = alTop BevelOuter = bvNone Padding.Top = 5 ParentBackground = False @@ -113,6 +114,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Top = 5 Width = 938 Height = 108 + Hint = 'Insert question' Margins.Left = 0 Margins.Top = 0 Margins.Right = 0 @@ -124,22 +126,24 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Font.Name = 'Tahoma' Font.Style = [] ParentFont = False + ParentShowHint = False + ShowHint = True TabOrder = 0 OnChange = mmQuestionChange OnKeyDown = mmQuestionKeyDown OnKeyUp = mmQuestionKeyUp end end - object pnBackStatusBar: TPanel + object pnBackButtonsSearch: TPanel Left = 18 - Top = 306 + Top = 131 Width = 938 Height = 27 Margins.Left = 0 Margins.Top = 0 Margins.Right = 0 Margins.Bottom = 0 - Align = alBottom + Align = alTop BevelOuter = bvNone Padding.Top = 3 Padding.Bottom = 2 @@ -216,7 +220,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Margins.Bottom = 0 Align = alRight Caption = '* Code only *' - ImageIndex = 2 + ImageIndex = 3 Images = ImageList1 TabOrder = 1 OnClick = btnCodeOnlyClick @@ -255,7 +259,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Left = 0 Top = 0 Width = 938 - Height = 291 + Height = 298 Align = alClient BorderStyle = bsNone DataSource = DataSource1 @@ -272,9 +276,9 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object Panel9: TPanel Left = 0 - Top = 291 + Top = 298 Width = 938 - Height = 34 + Height = 27 Align = alBottom BevelOuter = bvNone Padding.Left = 3 @@ -283,63 +287,98 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Bottom = 3 ParentBackground = False TabOrder = 1 - object Label1: TLabel - Left = 196 + object lbCount: TLabel + Left = 899 Top = 3 - Width = 85 - Height = 28 - Align = alLeft - Caption = ' Last generation: ' + Width = 36 + Height = 21 + Align = alRight + Caption = '000000' Layout = tlCenter ExplicitHeight = 13 end - object lbLastGeneration: TLabel - Left = 281 - Top = 3 - Width = 120 - Height = 28 - Align = alLeft - AutoSize = False - Caption = 'lbLastGeneration' - Layout = tlCenter - end - object btnTestSQL: TButton - Left = 401 + object Label3: TLabel + Left = 863 Top = 3 - Width = 75 - Height = 28 - Align = alLeft - Caption = 'Test SQL' - TabOrder = 0 - OnClick = btnTestSQLClick - end - object cBoxDatabases: TComboBox - AlignWithMargins = True - Left = 6 - Top = 6 - Width = 187 + Width = 36 Height = 21 - Align = alLeft - Style = csDropDownList - TabOrder = 1 - OnClick = cBoxDatabasesClick - end - object Panel1: TPanel - Left = 656 - Top = 0 - Width = 81 - Height = 33 - Caption = 'Panel1' - Color = 5460819 - ParentBackground = False - TabOrder = 2 + Align = alRight + Caption = 'Count: ' + Layout = tlCenter + ExplicitHeight = 13 end end end + object Panel1: TPanel + Left = 18 + Top = 306 + Width = 938 + Height = 27 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alBottom + BevelOuter = bvNone + Padding.Bottom = 2 + ParentBackground = False + TabOrder = 4 + object Label1: TLabel + Left = 337 + Top = 0 + Width = 85 + Height = 25 + Align = alLeft + Caption = ' Last generation: ' + Layout = tlCenter + ExplicitHeight = 13 + end + object lbLastGeneration: TLabel + Left = 422 + Top = 0 + Width = 120 + Height = 25 + Align = alLeft + AutoSize = False + Caption = 'lbLastGeneration' + Layout = tlCenter + ExplicitLeft = 585 + ExplicitTop = 3 + end + object btnExecuteSQL: TButton + AlignWithMargins = True + Left = 825 + Top = 0 + Width = 113 + Height = 25 + Cursor = crHandPoint + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alRight + Caption = 'Execute SQL' + ImageIndex = 5 + ImageMargins.Left = 5 + Images = ImageList1 + TabOrder = 0 + OnClick = btnExecuteSQLClick + end + object cBoxDatabases: TComboBox + AlignWithMargins = True + Left = 3 + Top = 3 + Width = 331 + Height = 21 + Align = alLeft + Style = csDropDownList + TabOrder = 1 + OnClick = cBoxDatabasesClick + end + end end object pnWait: TPanel Left = 413 - Top = 256 + Top = 208 Width = 125 Height = 35 BevelOuter = bvNone @@ -388,7 +427,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object pnCommands: TPanel Left = 936 - Top = 8 + Top = 184 Width = 26 Height = 115 Margins.Left = 0 @@ -592,139 +631,139 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object ImageList1: TImageList Left = 96 - Top = 208 + Top = 200 Bitmap = { - 494C010105003000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 494C010106003000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000002000000001002000000000000020 - 000000000000000000000000000000000000000000FF000000FF000000FF0000 - 00FF000000FFF0CAA600F0CAA600C0C0C000C0C0C000CCCC9900F0CAA6000000 - 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000F0CAA600F0CAA600C0C0C000C0C0C000CCCC9900F0CAA6000000 + 000000000000000000000000000000000000000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF00660000003300000033 + 00000033000000660000000000FF000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000FF000000FF000000FFF0CA + 000000000000000000000000000000000000000000000000000000000000F0CA A600D7D7D700E3E3E300E3E3E300CBCBCB00C0C0C000C0C0C000B2B2B200A4A0 - A000F0CAA600000000FF000000FF000000FF0000000000000000000000000000 + A000F0CAA600000000000000000000000000000000FF000000FF000000FF0066 + 9900006699000066990000669900006699000066000000800000009900000099 + 0000008000000066000000330000000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000FF000000FFF0CAA600EAEA + 0000000000000000000000000000000000000000000000000000F0CAA600EAEA EA00F0FBFF00F0CAA600CC666600CC663300CC663300CC666600CC999900B2B2 - B200A4A0A000CC999900000000FF000000FF0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + B200A4A0A000CC9999000000000000000000000000FF000000FF0066990033CC + FF0000CCFF0033CCFF0066CCFF0000663300009933000099330099CC99003399 + 3300009900000099000000660000006600000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000FFF0CAA600F1F1F100FFFF + 00000000000000000000000000000000000000000000F0CAA600F1F1F100FFFF FF00CC996600CC330000CC333300FFCCCC00F0CAA600CC330000CC330000CC66 - 6600B2B2B200B2B2B200F0CAA600000000FF0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 6600B2B2B200B2B2B200F0CAA60000000000000000FF0066990066FFFF0033CC + FF0000CCFF0033CCFF0066CCFF000099000000CC330000993300FFFFFF00FFFF + FF0033CC66000099000000990000006600000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000FFE3E3E300FFFFFF00CC99 + 00000000000000000000000000000000000000000000E3E3E300FFFFFF00CC99 6600CC330000CC333300CC663300CC999900CC999900CC333300CC333300CC33 - 0000CC996600C0C0C000C0C0C000000000FF0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 0000CC996600C0C0C000C0C0C00000000000000000FF0066990066FFFF0033CC + FF0000CCFF0033CCFF0066CCFF000099000033CC660000993300FFFFFF00FFFF + FF00FFFFFF0033CC330000990000006600000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000F0CAA600FFFFFF00FFECCC00CC66 3300CC333300CC333300CC663300CC999900CC996600CC333300CC663300CC33 - 3300CC663300B2B2B200CBCBCB00F0CAA6000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 3300CC663300B2B2B200CBCBCB00F0CAA600000000FF0066990066FFFF0033CC + FF0000CCFF0033CCFF0066CCFF000099000066CC990000993300FFFFFF00FFFF + FF0033CC66000099000000990000006600000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000FFCCCC00FFFFFF00CC999900CC66 3300CC663300CC663300CC663300F8F8F800EAEAEA00CC663300CC330000CC66 - 3300CC330000CC996600D7D7D700F0CAA6000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 3300CC330000CC996600D7D7D700F0CAA600000000FF0066990099FFFF0099FF + FF00CCFFFF00CCFFFF00F0FBFF003399330066CC990066CC660099CC990033CC + 6600009933000099330000993300006600000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000FFCCCC00FFFFFF00CC996600CC66 3300CC663300CC663300CC663300F0CAA600FFFFFF00F0CAA600CC663300CC33 - 0000CC330000CC666600EAEAEA00F0CAA6000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 0000CC330000CC666600EAEAEA00F0CAA600000000FF0066990099FFFF003399 + CC000099CC000099CC000099CC00008080000099000099CC990066CC990066CC + 660033CC66000099330000993300000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000FFCCCC00FFFFFF00CC996600CC66 3300CC663300CC663300CC663300CC663300F0CAA600FFFFFF00FFECCC00CC66 - 3300CC330000CC666600F1F1F100F0CAA6000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 3300CC330000CC666600F1F1F100F0CAA600000000FF0066990033CCCC0033CC + FF0000CCFF0033CCFF0066CCFF0066CCFF003399990000993300009900000099 + 00000099000000993300000000FF000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000FFCCCC00FFFFFF00F0CAA600CC66 3300CC993300CC996600CC663300CC663300CC663300F0CAA600FFFFFF00CC99 - 6600CC330000CC996600F0FBFF00F0CAA6000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 6600CC330000CC996600F0FBFF00F0CAA600000000FF0066990066FFFF0033CC + FF0000CCFF0033CCFF0066CCFF0066CCFF003399CC000099CC00006699000000 + 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000FFCCCC00F8F8F800EAEAEA00CC99 6600F0CAA600FFFFFF00CC996600CC663300CC663300CC996600FFFFFF00CC99 - 9900CC663300FFCCCC00F1F1F100F0CAA6000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 9900CC663300FFCCCC00F1F1F100F0CAA600000000FF0066990066FFFF0033CC + FF0000CCFF0033CCFF0066CCFF0066CCFF003399CC000099CC00006699000000 + 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000FFE3E3E300FFFFFF00F0CA + 00000000000000000000000000000000000000000000E3E3E300FFFFFF00F0CA A600FF999900FFFFFF00F8F8F800F0CAA600F0CAA600F8F8F800F8F8F800CC66 - 3300CC996600FFFFFF00FFCCCC00000000FF0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 3300CC996600FFFFFF00FFCCCC0000000000000000FF0066990066FFFF0033CC + FF0000CCFF0033CCFF0066CCFF0066CCFF003399CC000099CC00006699000000 + 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000FFF0CAA600F1F1F100FFFF + 00000000000000000000000000000000000000000000F0CAA600F1F1F100FFFF FF00F0CAA600F0CAA600FFECCC00F8F8F800F8F8F800FFECCC00CC996600CC99 - 9900FFFFFF00EAEAEA00FFCCCC00000000FF0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + 9900FFFFFF00EAEAEA00FFCCCC0000000000000000FF0066990066FFFF0066FF + FF0066FFFF0066FFFF0066FFFF0099FFFF0033CCFF000099CC00006699000000 + 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000FF000000FFF0CAA600F1F1 + 0000000000000000000000000000000000000000000000000000F0CAA600F1F1 F100FFFFFF00FFECCC00F0CAA600F0CAA600F0CAA600F0CAA600FFCCCC00FFFF - FF00EAEAEA00F0CAA600000000FF000000FF0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + FF00EAEAEA00F0CAA6000000000000000000000000FF00669900FFFFFF00F0FB + FF00CCFFFF0099FFFF0099FFFF0099FFFF0099FFFF0066FFFF00006699000000 + 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000FF000000FF000000FFF0CA + 000000000000000000000000000000000000000000000000000000000000F0CA A600EAEAEA00F1F1F100FFFFFF00FFFFFF00FFFFFF00F8F8F800F8F8F800E3E3 - E300E3E3E300000000FF000000FF000000FF0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + E300E3E3E300000000000000000000000000000000FF000000FF00669900F0FB + FF00CCFFFF00CCFFFF0099FFFF0099FFFF0099FFFF0000669900000000FF0000 + 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000FF000000FF000000FF0000 - 00FF000000FFF0CAA600F0CAA600FFCCCC00FFCCCC00F0CAA600F0CAA6000000 + 000000000000F0CAA600F0CAA600FFCCCC00FFCCCC00F0CAA600F0CAA6000000 + 000000000000000000000000000000000000000000FF000000FF000000FF0066 + 99000066990000669900006699000066990000669900000000FF000000FF0000 00FF000000FF000000FF000000FF000000FF0000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000999999009999 9900999999009999990000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000555555005555 @@ -854,11 +893,11 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView 0000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000424D3E000000000000003E000000 2800000040000000200000000100010000000000000100000000000000000000 - 000000000000000000000000FFFFFF00F81F000000000000E007000000000000 - C003000000000000800100000000000080010000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000080010000000000008001000000000000C003000000000000 - E007000000000000F81F000000000000FFC3FFC3FFFFFFFFE381E381FFCFFFCF + 000000000000000000000000FFFFFF00F81FFF8300000000E007E00100000000 + C003C00000000000800180000000000080018000000000000000800000000000 + 0000800000000000000080010000000000008003000000000000801F00000000 + 0000801F000000008001801F000000008001801F00000000C003801F00000000 + E007C03F00000000F81FE07F00000000FFC3FFC3FFFFFFFFE381E381FFCFFFCF C081C081FF8FFF8F80038003FF07FF0700000000FE07FE0700000000FC07FC07 00000000FE63FE6300000000FFF3FFF300000000CE71CE7100000000B5A9B5A9 00010001BDADBDAD003F003FB5ACB5AC003F003FCE70CE70003F003FFFFDFFFD diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index b6713db..8aeb31e 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -59,7 +59,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) pMenuCurrentAI: TPopupMenu; Gemini1: TMenuItem; ChatGPT1: TMenuItem; - pnBackStatusBar: TPanel; + pnBackButtonsSearch: TPanel; lbCurrentAI: TLabel; StatusBar1: TStatusBar; pnCommands: TPanel; @@ -83,14 +83,8 @@ TDelphiAIDevDBChatView = class(TDockableForm) Groq1: TMenuItem; pnGridBack: TPanel; DBGrid1: TDBGrid; - Panel9: TPanel; Splitter2: TSplitter; DataSource1: TDataSource; - btnTestSQL: TButton; - cBoxDatabases: TComboBox; - Label1: TLabel; - lbLastGeneration: TLabel; - Panel1: TPanel; pMenuGrid: TPopupMenu; CopyCurrentColumn1: TMenuItem; CopyCurrentLine1: TMenuItem; @@ -98,6 +92,14 @@ TDelphiAIDevDBChatView = class(TDockableForm) N3: TMenuItem; SaveAllGridDataAsCSV: TMenuItem; SaveAllGridDataAsTXT: TMenuItem; + Panel1: TPanel; + btnExecuteSQL: TButton; + cBoxDatabases: TComboBox; + Label1: TLabel; + lbLastGeneration: TLabel; + Panel9: TPanel; + lbCount: TLabel; + Label3: TLabel; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); procedure Cut1Click(Sender: TObject); @@ -125,7 +127,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure btnDefaultsQuestionsClick(Sender: TObject); procedure Clear1Click(Sender: TObject); procedure btnCleanAllClick(Sender: TObject); - procedure btnTestSQLClick(Sender: TObject); + procedure btnExecuteSQLClick(Sender: TObject); procedure cBoxDatabasesClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); @@ -762,9 +764,9 @@ procedure TDelphiAIDevDBChatView.ProcessSend; if btnCodeOnly.ImageIndex = CodeOnly_ImageIndex_ON then LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgCodeOnly + sLineBreak; - LQuestion := LQuestion + 'O seguinte JSON se refere a estrutura de um banco de dados: '; + LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgJSONIsDatabaseStructure(Self.GetFieldDBSelected.DriverID.ToString); LQuestion := LQuestion + Self.GetJsonDatabase + sLineBreak; - LQuestion := LQuestion + 'Com base no JSON que foi informado, responda a seguinte pergunta: '; + LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgJSONInformedAnswerQuestion; LQuestion := LQuestion + mmQuestion.Lines.Text; LTask := TTask.Create( @@ -826,12 +828,13 @@ function TDelphiAIDevDBChatView.GetJsonDatabase: string; end; end; -procedure TDelphiAIDevDBChatView.btnTestSQLClick(Sender: TObject); +procedure TDelphiAIDevDBChatView.btnExecuteSQLClick(Sender: TObject); var LField: TDelphiAIDevDBRegistersFields; begin Screen.Cursor := crHourGlass; try + lbCount.Caption := '000000'; LField := Self.GetFieldDBSelected; FConn.Configs @@ -851,7 +854,9 @@ procedure TDelphiAIDevDBChatView.btnTestSQLClick(Sender: TObject); TUtils.ShowMsgErrorAndAbort(E.Message); end; - FQuery.CloseClear.Add(mmReturn.Lines.Text).Open; + TUtils.ShowMsg(mmReturn.Lines.Text); + FQuery.CloseClear.Add(Trim(mmReturn.Lines.Text)).Open; + lbCount.Caption := FQuery.RecordCountStr; finally Screen.Cursor := crDefault; end; diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 3be8253..4fb8194 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -291,7 +291,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Caption = 'API key' end object Label2: TLabel - Left = 478 + Left = 374 Top = 5 Width = 28 Height = 13 @@ -375,7 +375,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object edtBaseUrlOpenAI: TEdit Left = 16 Top = 21 - Width = 460 + Width = 356 Height = 21 TabOrder = 0 end @@ -388,17 +388,17 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView TabOrder = 2 end object cBoxModelOpenAI: TComboBox - Left = 478 + Left = 374 Top = 21 - Width = 122 + Width = 226 Height = 21 - Style = csDropDownList TabOrder = 1 Items.Strings = ( 'gpt-3.5-turbo' 'gpt-3.5-turbo-16k' 'gpt-4' - 'gpt-4-32k') + 'gpt-4o-2024-05-13' + 'gpt-4o-2024-08-06') end end end @@ -459,7 +459,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Caption = 'API key' end object Label10: TLabel - Left = 478 + Left = 374 Top = 5 Width = 28 Height = 13 @@ -561,7 +561,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object edtBaseUrlGroq: TEdit Left = 16 Top = 21 - Width = 460 + Width = 356 Height = 21 TabOrder = 0 end @@ -574,9 +574,9 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView TabOrder = 2 end object cBoxModelGroq: TComboBox - Left = 478 + Left = 374 Top = 21 - Width = 122 + Width = 226 Height = 21 Style = csDropDownList TabOrder = 1 diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index f5bc2c9..aedd2ba 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -100,11 +100,11 @@ procedure TDelphiAIDevSettings.LoadDefaults; FApiKeyGemini := ''; FBaseUrlOpenAI := TConsts.BASE_URL_OPEN_AI; - FModelOpenAI := 'gpt-3.5-turbo'; + FModelOpenAI := TConsts.MODEL_OPEN_AI_DEFAULT; FApiKeyOpenAI := ''; FBaseUrlGroq := TConsts.BASE_URL_GROQ; - FModelGroq := 'llama3-8b-8192'; + FModelGroq := TConsts.MODEL_GROQ_DEFAULT; FApiKeyGroq := ''; end; diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index fba14f0..01c314a 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -33,6 +33,8 @@ TC4DLanguageHelper = record helper for TC4DLanguage function ToString: string; function GetLanguageDefinition: string; function GetMsgCodeOnly: string; + function GetMsgJSONIsDatabaseStructure(ASGBDName: string): string; + function GetMsgJSONInformedAnswerQuestion: string; end; TC4DExtensionsFilesHelper = record helper for TC4DExtensionsFiles @@ -116,13 +118,41 @@ function TC4DLanguageHelper.GetLanguageDefinition: string; function TC4DLanguageHelper.GetMsgCodeOnly: string; begin - Result := 'Faça a seguinte ação sem adicionar comentários:' + sLineBreak; + Result := 'Faça a seguinte ação sem adicionar comentários:'; case Self of TC4DLanguage.en: - Result := 'Perform the following action without adding comments:' + sLineBreak; + Result := 'Perform the following action without adding comments:'; TC4DLanguage.es: - Result := 'Realice la siguiente acción sin agregar comentarios:' + sLineBreak; + Result := 'Realice la siguiente acción sin agregar comentarios:'; end; + + Result := Result + sLineBreak; +end; + +function TC4DLanguageHelper.GetMsgJSONIsDatabaseStructure(ASGBDName: string): string; +begin + Result := 'O seguinte JSON se refere a estrutura SQL de um banco de dados '; + case Self of + TC4DLanguage.en: + Result := 'The following JSON refers to the SQL structure of a database '; + TC4DLanguage.es: + Result := 'El siguiente JSON hace referencia a la estructura SQL de una base de datos '; + end; + + Result := Result + ASGBDName + ': ' + sLineBreak; +end; + +function TC4DLanguageHelper.GetMsgJSONInformedAnswerQuestion: string; +begin + Result := 'Com base na estrutura que foi informada, responda a seguinte pergunta e retorne o comando SQL correspondente:'; + case Self of + TC4DLanguage.en: + Result := 'Based on the structure that was provided, answer the following question and return the corresponding SQL command:'; + TC4DLanguage.es: + Result := 'Según la estructura proporcionada, responda la siguiente pregunta y devuelva el comando SQL correspondiente:'; + end; + + Result := Result + sLineBreak; end; { TC4DExtensionsFilesHelper } diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 27f006d..1c0a3b5 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -351,7 +351,8 @@ class procedure TUtils.TogglePasswordChar(const AEdit: TEdit); class function TUtils.CodeIdMarkBeginCode(const AValue: string): Boolean; begin Result := (AValue.Trim = TConsts.MARK_BEGIN_DELPHI) - or(AValue.Trim = TConsts.MARK_BEGIN_PASCAL); + or(AValue.Trim = TConsts.MARK_BEGIN_PASCAL) + or(AValue.Trim = TConsts.MARK_BEGIN_SQL); //or(AValue.Trim = TConsts.MARK_BEGIN_PASCAL2); end; @@ -361,6 +362,8 @@ class function TUtils.ConfReturnAI(const AValue: string): string; .Replace(TConsts.MARK_BEGIN_DELPHI, '', [rfReplaceAll, rfIgnoreCase]) .Replace(TConsts.MARK_BEGIN_PASCAL, '', [rfReplaceAll, rfIgnoreCase]) //.Replace(TConsts.MARK_BEGIN_PASCAL2, '', [rfReplaceAll, rfIgnoreCase]) + .Replace(TConsts.MARK_BEGIN_SQL, '', [rfReplaceAll, rfIgnoreCase]) + .Replace(TConsts.MARK_BEGIN_SQL2, '', [rfReplaceAll, rfIgnoreCase]) .Replace(TConsts.MARK_END, '', [rfReplaceAll, rfIgnoreCase]); end; From 9decbee343ddc101bb568d9748b36f854d24673b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 20 Aug 2024 03:52:22 -0300 Subject: [PATCH 033/109] Update DelphiAIDev.Types.pas --- Src/Types/DelphiAIDev.Types.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index 01c314a..f6d873f 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -139,12 +139,12 @@ function TC4DLanguageHelper.GetMsgJSONIsDatabaseStructure(ASGBDName: string): st Result := 'El siguiente JSON hace referencia a la estructura SQL de una base de datos '; end; - Result := Result + ASGBDName + ': ' + sLineBreak; + Result := Result + ASGBDName + ' ' + sLineBreak; end; function TC4DLanguageHelper.GetMsgJSONInformedAnswerQuestion: string; begin - Result := 'Com base na estrutura que foi informada, responda a seguinte pergunta e retorne o comando SQL correspondente:'; + Result := 'Com base nesta estrutura responda a seguinte pergunta e retorne o comando SQL correspondente:'; case Self of TC4DLanguage.en: Result := 'Based on the structure that was provided, answer the following question and return the corresponding SQL command:'; From 121361881256ff249923ad9c6dc5c0e9c8f1948d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Wed, 21 Aug 2024 16:46:37 -0300 Subject: [PATCH 034/109] bk/2024-08-21-1646 --- Package/DelphiAIDeveloper.dpk | 3 +- Package/DelphiAIDeveloper.dproj | 1 + Src/AI/DelphiAIDev.AI.ChatGPT.pas | 5 +- Src/AI/DelphiAIDev.AI.Gemini.pas | 3 +- Src/AI/DelphiAIDev.AI.Groq.pas | 5 +- Src/AI/DelphiAIDev.AI.Ollama.pas | 88 +++++++++++++++++++++++++++ Src/Chat/DelphiAIDev.Chat.View.dfm | 5 ++ Src/Chat/DelphiAIDev.Chat.View.pas | 8 ++- Src/Chat/DelphiAIDev.Chat.pas | 6 +- Src/Consts/DelphiAIDev.Consts.pas | 4 ++ Src/Settings/DelphiAIDev.Settings.pas | 30 +++++++++ Src/Types/DelphiAIDev.Types.pas | 2 +- 12 files changed, 150 insertions(+), 10 deletions(-) create mode 100644 Src/AI/DelphiAIDev.AI.Ollama.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 38c9f25..e79d4be 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -99,6 +99,7 @@ contains DelphiAIDev.DB.Chat.View in '..\Src\DB\Chat\DelphiAIDev.DB.Chat.View.pas' {DelphiAIDevDBChatView}, DelphiAIDev.MetaInfo in '..\Src\MetaInfo\DelphiAIDev.MetaInfo.pas', DelphiAIDev.DB.References.View in '..\Src\DB\References\DelphiAIDev.DB.References.View.pas' {DelphiAIDevDBReferencesView}, - DelphiAIDev.Utils.DBGrids in '..\Src\Utils\DelphiAIDev.Utils.DBGrids.pas'; + DelphiAIDev.Utils.DBGrids in '..\Src\Utils\DelphiAIDev.Utils.DBGrids.pas', + DelphiAIDev.AI.Ollama in '..\Src\AI\DelphiAIDev.AI.Ollama.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index b32a2a2..89e7c85 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -212,6 +212,7 @@ dfm + BITMAP c4d_Logo diff --git a/Src/AI/DelphiAIDev.AI.ChatGPT.pas b/Src/AI/DelphiAIDev.AI.ChatGPT.pas index caabefb..76b965d 100644 --- a/Src/AI/DelphiAIDev.AI.ChatGPT.pas +++ b/Src/AI/DelphiAIDev.AI.ChatGPT.pas @@ -7,6 +7,7 @@ interface System.JSON, System.Classes, RESTRequest4D, + DelphiAIDev.Consts, DelphiAIDev.Utils, DelphiAIDev.Settings, DelphiAIDev.AI.Interfaces; @@ -52,8 +53,8 @@ function TDelphiAIDevAIChatGPT.GetResponse(const AQuestion: string): string; LResponse := TRequest.New .BaseURL(FSettings.BaseUrlOpenAI) - .ContentType('application/json') - .Accept('application/json') + .ContentType(TConsts.APPLICATION_JSON) + .Accept(TConsts.APPLICATION_JSON) .Token('Bearer ' + FSettings.ApiKeyOpenAI) .AddBody(Format(API_JSON_BODY_BASE, [FSettings.ModelOpenAI, AQuestion])) .Post; diff --git a/Src/AI/DelphiAIDev.AI.Gemini.pas b/Src/AI/DelphiAIDev.AI.Gemini.pas index c70470b..38e9e62 100644 --- a/Src/AI/DelphiAIDev.AI.Gemini.pas +++ b/Src/AI/DelphiAIDev.AI.Gemini.pas @@ -7,6 +7,7 @@ interface System.JSON, System.Classes, RESTRequest4D, + DelphiAIDev.Consts, DelphiAIDev.Utils, DelphiAIDev.Settings, DelphiAIDev.AI.Interfaces; @@ -54,7 +55,7 @@ function TDelphiAIDevAIGemini.GetResponse(const AQuestion: string): string; LResponse := TRequest.New .BaseURL(LApiUrl) - .Accept('application/json') + .Accept(TConsts.APPLICATION_JSON) .AddBody(Format(API_JSON_BODY_BASE, [AQuestion])) .Post; diff --git a/Src/AI/DelphiAIDev.AI.Groq.pas b/Src/AI/DelphiAIDev.AI.Groq.pas index d534328..12404a1 100644 --- a/Src/AI/DelphiAIDev.AI.Groq.pas +++ b/Src/AI/DelphiAIDev.AI.Groq.pas @@ -7,6 +7,7 @@ interface System.JSON, System.Classes, RESTRequest4D, + DelphiAIDev.Consts, DelphiAIDev.Utils, DelphiAIDev.Settings, DelphiAIDev.AI.Interfaces; @@ -50,8 +51,8 @@ function TDelphiAIDevAIGroq.GetResponse(const AQuestion: string): string; LResponse := TRequest.New .BaseURL(FSettings.BaseUrlGroq) - .ContentType('application/json') - .Accept('application/json') + .ContentType(TConsts.APPLICATION_JSON) + .Accept(TConsts.APPLICATION_JSON) .Token('Bearer ' + FSettings.ApiKeyGroq) .AddBody(Format(API_JSON_BODY_BASE, [AQuestion, FSettings.ModelGroq])) .Post; diff --git a/Src/AI/DelphiAIDev.AI.Ollama.pas b/Src/AI/DelphiAIDev.AI.Ollama.pas new file mode 100644 index 0000000..81be377 --- /dev/null +++ b/Src/AI/DelphiAIDev.AI.Ollama.pas @@ -0,0 +1,88 @@ +unit DelphiAIDev.AI.Ollama; + +interface + +uses + System.SysUtils, + System.JSON, + System.Classes, + RESTRequest4D, + DelphiAIDev.Consts, + DelphiAIDev.Utils, + DelphiAIDev.Settings, + DelphiAIDev.AI.Interfaces; + +type + TDelphiAIDevAIOllama = class(TInterfacedObject, IDelphiAIDevAI) + private + FSettings: TDelphiAIDevSettings; + protected + function GetResponse(const AQuestion: string): string; + public + class function New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; + constructor Create(const ASettings: TDelphiAIDevSettings); + end; + +implementation + +const + API_JSON_BODY_BASE = //'{"messages": [{"role": "user", "content": "%s"}], "model": "%s"}'; + '{"model": "%s", '+ + '"messages": [{"role": "user", "content": "%s"}], '+ + '"stream": false}'; + +class function TDelphiAIDevAIOllama.New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; +begin + Result := Self.Create(ASettings); +end; + +constructor TDelphiAIDevAIOllama.Create(const ASettings: TDelphiAIDevSettings); +begin + FSettings := ASettings; +end; + +function TDelphiAIDevAIOllama.GetResponse(const AQuestion: string): string; +var + LResponse: IResponse; + LJsonValueAll: TJSONVALUE; + LJsonArrayChoices: TJsonArray; + LJsonObjMessage: TJsonObject; + LContent: string; + LItemChoices: Integer; +begin + Result := ''; + + TUtils.ShowMsgSynchronize(Format(API_JSON_BODY_BASE, [FSettings.ModelOllama, AQuestion])); + + LResponse := TRequest.New + .BaseURL(FSettings.BaseUrlOllama) + .ContentType(TConsts.APPLICATION_JSON) + .Accept(TConsts.APPLICATION_JSON) + //.Token('Bearer ' + FSettings.ApiKeyOllama) + .AddBody(Format(API_JSON_BODY_BASE, [FSettings.ModelOllama, AQuestion])) + .Post; + + if LResponse.StatusCode <> 200 then + Exit('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + + Exit(LResponse.Content); + + + Exit; + LJsonValueAll := TJsonObject.ParseJSONValue(LResponse.Content); + if not(LJsonValueAll is TJSONObject) then + Exit('The question cannot be answered, return object not found.' + sLineBreak + + 'Return: ' + LResponse.Content); + + LJsonArrayChoices := (LJsonValueAll as TJsonObject).GetValue('choices'); + for LItemChoices := 0 to Pred(LJsonArrayChoices.Count) do + begin + LJsonObjMessage := LJsonArrayChoices.Items[LItemChoices].GetValue('message'); + LContent := LJsonObjMessage.GetValue('content'); + Result := Result + LContent.Trim + sLineBreak; + end; + + Result := Result.Trim; +end; + +end. diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index c4617a5..2610221 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -818,6 +818,11 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'Groq' OnClick = Gemini1Click end + object Ollama1: TMenuItem + Tag = 3 + Caption = 'Ollama (offline)' + OnClick = Gemini1Click + end end object pMenuMoreActions: TPopupMenu Images = ImageList1 diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index d32cf98..b08fdd0 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -74,6 +74,7 @@ TDelphiAIDevChatView = class(TDockableForm) pMenuQuestions: TPopupMenu; btnCleanAll: TSpeedButton; Groq1: TMenuItem; + Ollama1: TMenuItem; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); procedure Cut1Click(Sender: TObject); @@ -746,6 +747,7 @@ procedure TDelphiAIDevChatView.pMenuCurrentAIPopup(Sender: TObject); Gemini1.Checked := False; ChatGPT1.Checked := False; Groq1.Checked := False; + Ollama1.Checked := False; case FSettings.AIDefault of TC4DAIsAvailable.Gemini: Gemini1.Checked := True; @@ -753,6 +755,8 @@ procedure TDelphiAIDevChatView.pMenuCurrentAIPopup(Sender: TObject); ChatGPT1.Checked := True; TC4DAIsAvailable.Groq: Groq1.Checked := True; + TC4DAIsAvailable.Ollama: + Ollama1.Checked := True; end; end; @@ -767,6 +771,8 @@ procedure TDelphiAIDevChatView.ConfLabelCurrentAI; lbCurrentAI.Hint := FSettings.ModelOpenAI; TC4DAIsAvailable.Groq: lbCurrentAI.Hint := FSettings.ModelGroq; + TC4DAIsAvailable.Ollama: + lbCurrentAI.Hint := FSettings.ModelOllama; end; lbCurrentAI.Repaint; @@ -779,7 +785,7 @@ procedure TDelphiAIDevChatView.Gemini1Click(Sender: TObject); begin //*SEVERAL LTag := TMenuItem(Sender).Tag; - if not(LTag in [0, 1, 2])then + if not(LTag in [0, 1, 2, 3])then Exit; FSettings.AIDefault := TC4DAIsAvailable(LTag); diff --git a/Src/Chat/DelphiAIDev.Chat.pas b/Src/Chat/DelphiAIDev.Chat.pas index 3bf535e..ec0a21e 100644 --- a/Src/Chat/DelphiAIDev.Chat.pas +++ b/Src/Chat/DelphiAIDev.Chat.pas @@ -10,7 +10,8 @@ interface DelphiAIDev.Settings, DelphiAIDev.AI.Gemini, DelphiAIDev.AI.ChatGPT, - DelphiAIDev.AI.Groq; + DelphiAIDev.AI.Groq, + DelphiAIDev.AI.Ollama; type TDelphiAIDevChat = class @@ -44,7 +45,6 @@ procedure TDelphiAIDevChat.ProcessSend(const AQuestion: string); LQuestion: string; begin LQuestion := TUtils.AdjustQuestionToJson(AQuestion); - TUtils.ShowMsgSynchronize('LQuestion', LQuestion); FResponse.Clear; case FSettings.AIDefault of @@ -54,6 +54,8 @@ procedure TDelphiAIDevChat.ProcessSend(const AQuestion: string); FResponse.Text := TDelphiAIDevAIChatGPT.New(FSettings).GetResponse(LQuestion); TC4DAIsAvailable.Groq: FResponse.Text := TDelphiAIDevAIGroq.New(FSettings).GetResponse(LQuestion); + TC4DAIsAvailable.Ollama: + FResponse.Text := TDelphiAIDevAIOllama.New(FSettings).GetResponse(LQuestion); else FResponse.Text := 'Default AI not reported in Delphi AI Developer settings'; end; diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index 8f6f816..aa40be5 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -15,6 +15,7 @@ TConsts = class NAME_FOLDER_MetaInfo = 'MetaInfo'; GITHUB_Code4Delphi = 'https://github.com/Code4Delphi'; GITHUB_PROJECT = 'https://github.com/Code4Delphi/Delphi-AI-Developer'; + APPLICATION_JSON = 'application/json'; MARK_BEGIN_DELPHI = '```delphi'; MARK_BEGIN_PASCAL = '```objectpascal'; @@ -33,6 +34,9 @@ TConsts = class BASE_URL_GROQ = 'https://api.groq.com/openai/v1/chat/completions'; MODEL_GROQ_DEFAULT = 'llama3-70b-8192'; //'llama3-8b-8192';; + BASE_URL_OLLAMA = ' http://localhost:11434/api/chat'; + MODEL_OLLAMA_DEFAULT = 'tinyllama'; //'mistral'; + //NAMES FILES .INI FILE_INI_GENERAL_SETTINGS = 'delphi-ai-developer.ini'; diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index aedd2ba..2775492 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -28,6 +28,9 @@ TDelphiAIDevSettings = class FIELD_BaseUrlGroq = 'BaseUrlGroq'; FIELD_ModelGroq = 'ModelGroq'; FIELD_ApiKeyGroq = 'ApiKeyGroq'; + FIELD_BaseUrlOllama = 'BaseUrlOllama'; + FIELD_ModelOllama = 'ModelOllama'; + FIELD_ApiKeyOllama = 'ApiKeyOllama'; private FLanguageQuestions: TC4DLanguage; FAIDefault: TC4DAIsAvailable; @@ -45,6 +48,11 @@ TDelphiAIDevSettings = class FBaseUrlGroq: string; FModelGroq: string; FApiKeyGroq: string; + + FBaseUrlOllama: string; + FModelOllama: string; + FApiKeyOllama: string; + constructor Create; public class function GetInstance: TDelphiAIDevSettings; @@ -68,6 +76,10 @@ TDelphiAIDevSettings = class property BaseUrlGroq: string read FBaseUrlGroq write FBaseUrlGroq; property ModelGroq: string read FModelGroq write FModelGroq; property ApiKeyGroq: string read FApiKeyGroq write FApiKeyGroq; + + property BaseUrlOllama: string read FBaseUrlOllama write FBaseUrlOllama; + property ModelOllama: string read FModelOllama write FModelOllama; + property ApiKeyOllama: string read FApiKeyOllama write FApiKeyOllama; end; implementation @@ -106,6 +118,10 @@ procedure TDelphiAIDevSettings.LoadDefaults; FBaseUrlGroq := TConsts.BASE_URL_GROQ; FModelGroq := TConsts.MODEL_GROQ_DEFAULT; FApiKeyGroq := ''; + + FBaseUrlOllama := TConsts.BASE_URL_OLLAMA; + FModelOllama := TConsts.MODEL_OLLAMA_DEFAULT; + FApiKeyOllama := ''; end; procedure TDelphiAIDevSettings.SaveData; @@ -136,6 +152,10 @@ procedure TDelphiAIDevSettings.SaveData; LReg.WriteString(FIELD_BaseUrlGroq, FBaseUrlGroq); LReg.WriteString(FIELD_ModelGroq, FModelGroq); LReg.WriteString(FIELD_ApiKeyGroq, FApiKeyGroq); + + LReg.WriteString(FIELD_BaseUrlOllama, FBaseUrlOllama); + LReg.WriteString(FIELD_ModelOllama, FModelOllama); + LReg.WriteString(FIELD_ApiKeyOllama, FApiKeyOllama); finally LReg.Free; end; @@ -198,6 +218,16 @@ procedure TDelphiAIDevSettings.LoadData; if LReg.ValueExists(FIELD_ApiKeyGroq) then fApiKeyGroq := LReg.ReadString(FIELD_ApiKeyGroq); + + //OLLAMA + if LReg.ValueExists(FIELD_BaseUrlOllama) then + fBaseUrlOllama := LReg.ReadString(FIELD_BaseUrlOllama); + + if LReg.ValueExists(FIELD_ModelOllama) then + fModelOllama := LReg.ReadString(FIELD_ModelOllama); + + if LReg.ValueExists(FIELD_ApiKeyOllama) then + fApiKeyOllama := LReg.ReadString(FIELD_ApiKeyOllama); except Self.LoadDefaults; end; diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index f6d873f..f6fb30a 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -11,7 +11,7 @@ interface TC4DWizardMenuContextList = procedure(const MenuContextList: IInterfaceList) of object; {$SCOPEDENUMS ON} - TC4DAIsAvailable = (Gemini, OpenAI, Groq); + TC4DAIsAvailable = (Gemini, OpenAI, Groq, Ollama); TC4DLanguage = (en, ptBR, es); TC4DExtensionsFiles = (None, PAS, DFM, FMX, DPR, DPK, DPROJ, ZIP, BMP, INI, ALL); TC4DExtensionsOfFiles = set of TC4DExtensionsFiles; From 3ad688226e9e2c4a2b05d2158b65c59905429d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 23 Aug 2024 13:09:22 -0300 Subject: [PATCH 035/109] add-ValidateRegistrationOfSelectedAI --- Src/Chat/DelphiAIDev.Chat.View.pas | 34 +-------------- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 7 ++- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 46 +++++--------------- Src/Settings/DelphiAIDev.Settings.pas | 54 ++++++++++++++++++++++++ Src/Types/DelphiAIDev.Types.pas | 14 ++++++ 5 files changed, 85 insertions(+), 70 deletions(-) diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index b08fdd0..6a9ca36 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -129,7 +129,6 @@ TDelphiAIDevChatView = class(TDockableForm) procedure DoProcessClickInItemDefaultQuestions(ACodeOnly: Boolean; AQuestion: string); procedure ProcessWordWrap; procedure ConfScreenOnCreate; - procedure ValidateRegistrationOfSelectedAI; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -424,7 +423,7 @@ procedure TDelphiAIDevChatView.ProcessSend; if mmQuestion.Lines.Text.Trim.IsEmpty then TUtils.ShowMsgAndAbort('No questions have been added', mmQuestion); - Self.ValidateRegistrationOfSelectedAI; + FSettings.ValidateFillingSelectedAI; mmReturn.Lines.Clear; Self.WaitingFormON; @@ -479,37 +478,6 @@ procedure TDelphiAIDevChatView.ProcessSend; LTask.Start; end; -procedure TDelphiAIDevChatView.ValidateRegistrationOfSelectedAI; -const - MSG = '"%s" for IA %s not specified in settings.' + sLineBreak + sLineBreak + - 'Access menu > AI Developer > Settings'; -begin - case FSettings.AIDefault of - TC4DAIsAvailable.Gemini: - begin - if FSettings.BaseUrlGemini.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'Gemini'])); - - if FSettings.ModelGemini.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Gemini'])); - - if FSettings.ApiKeyGemini.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'Gemini'])); - end; - TC4DAIsAvailable.OpenAI: - begin - if FSettings.BaseUrlOpenAI.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'ChatGPT'])); - - if FSettings.ModelOpenAI.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'ChatGPT'])); - - if FSettings.ApiKeyOpenAI.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'ChatGPT'])); - end; - end; -end; - procedure TDelphiAIDevChatView.AddResponseSimple(const AString: string); begin Self.Last; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 4afd496..2283560 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -219,7 +219,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Margins.Right = 0 Margins.Bottom = 0 Align = alRight - Caption = '* Code only *' + Caption = '* SQL only *' ImageIndex = 3 Images = ImageList1 TabOrder = 1 @@ -962,6 +962,11 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Caption = 'Groq' OnClick = Gemini1Click end + object Ollama1: TMenuItem + Tag = 3 + Caption = 'Ollama (offline)' + OnClick = Gemini1Click + end end object pMenuMoreActions: TPopupMenu Images = ImageList1 diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 8aeb31e..5c78bee 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -100,6 +100,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) Panel9: TPanel; lbCount: TLabel; Label3: TLabel; + Ollama1: TMenuItem; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); procedure Cut1Click(Sender: TObject); @@ -166,7 +167,6 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure DoProcessClickInItemDefaultQuestions(ACodeOnly: Boolean; AQuestion: string); procedure ProcessWordWrap; procedure ConfScreenOnCreate; - procedure ValidateRegistrationOfSelectedAI; procedure ReloadDatabases; procedure ClearcBoxDatabases; procedure FillDateLastReferences; @@ -363,7 +363,7 @@ procedure TDelphiAIDevDBChatView.FormResize(Sender: TObject); LWidth: Integer; const CAPTION_UseCurrentUnitCode = 'Use current unit code in query'; - CAPTION_CodeOnly = 'Code only'; + CAPTION_CodeOnly = 'SQL only'; CAPTION_DefaultsQuestions = 'Questions'; begin if Self.Width > 620 then @@ -513,37 +513,6 @@ procedure TDelphiAIDevDBChatView.ClearcBoxDatabases; cBoxDatabases.Items.Clear; end; -procedure TDelphiAIDevDBChatView.ValidateRegistrationOfSelectedAI; -const - MSG = '"%s" for IA %s not specified in settings.' + sLineBreak + sLineBreak + - 'Access menu > AI Developer > Settings'; -begin - case FSettings.AIDefault of - TC4DAIsAvailable.Gemini: - begin - if FSettings.BaseUrlGemini.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'Gemini'])); - - if FSettings.ModelGemini.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Gemini'])); - - if FSettings.ApiKeyGemini.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'Gemini'])); - end; - TC4DAIsAvailable.OpenAI: - begin - if FSettings.BaseUrlOpenAI.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'ChatGPT'])); - - if FSettings.ModelOpenAI.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'ChatGPT'])); - - if FSettings.ApiKeyOpenAI.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'ChatGPT'])); - end; - end; -end; - procedure TDelphiAIDevDBChatView.AddResponseSimple(const AString: string); begin Self.Last; @@ -671,6 +640,7 @@ procedure TDelphiAIDevDBChatView.pMenuCurrentAIPopup(Sender: TObject); Gemini1.Checked := False; ChatGPT1.Checked := False; Groq1.Checked := False; + Ollama1.Checked := False; case FSettings.AIDefault of TC4DAIsAvailable.Gemini: Gemini1.Checked := True; @@ -678,6 +648,8 @@ procedure TDelphiAIDevDBChatView.pMenuCurrentAIPopup(Sender: TObject); ChatGPT1.Checked := True; TC4DAIsAvailable.Groq: Groq1.Checked := True; + TC4DAIsAvailable.Ollama: + Ollama1.Checked := True; end; end; @@ -692,6 +664,8 @@ procedure TDelphiAIDevDBChatView.ConfLabelCurrentAI; lbCurrentAI.Hint := FSettings.ModelOpenAI; TC4DAIsAvailable.Groq: lbCurrentAI.Hint := FSettings.ModelGroq; + TC4DAIsAvailable.Ollama: + lbCurrentAI.Hint := FSettings.ModelOllama; end; lbCurrentAI.Repaint; @@ -704,7 +678,7 @@ procedure TDelphiAIDevDBChatView.Gemini1Click(Sender: TObject); begin //*SEVERAL LTag := TMenuItem(Sender).Tag; - if not(LTag in [0, 1, 2])then + if not(LTag in [0, 1, 2, 3])then Exit; FSettings.AIDefault := TC4DAIsAvailable(LTag); @@ -751,7 +725,7 @@ procedure TDelphiAIDevDBChatView.ProcessSend; if mmQuestion.Lines.Text.Trim.IsEmpty then TUtils.ShowMsgAndAbort('No questions have been added', mmQuestion); - Self.ValidateRegistrationOfSelectedAI; + FSettings.ValidateFillingSelectedAI; mmReturn.Lines.Clear; Self.WaitingFormON; @@ -762,7 +736,7 @@ procedure TDelphiAIDevDBChatView.ProcessSend; LQuestion := TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim + sLineBreak; if btnCodeOnly.ImageIndex = CodeOnly_ImageIndex_ON then - LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgCodeOnly + sLineBreak; + LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgSQLOnly + sLineBreak; LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgJSONIsDatabaseStructure(Self.GetFieldDBSelected.DriverID.ToString); LQuestion := LQuestion + Self.GetJsonDatabase + sLineBreak; diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index 2775492..d45d045 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -59,6 +59,7 @@ TDelphiAIDevSettings = class procedure LoadDefaults; procedure SaveData; procedure LoadData; + procedure ValidateFillingSelectedAI; property LanguageQuestions: TC4DLanguage read FLanguageQuestions write FLanguageQuestions; property AIDefault: TC4DAIsAvailable read FAIDefault write FAIDefault; @@ -236,6 +237,59 @@ procedure TDelphiAIDevSettings.LoadData; end; end; +procedure TDelphiAIDevSettings.ValidateFillingSelectedAI; +const + MSG = '"%s" for IA %s not specified in settings.' + sLineBreak + sLineBreak + + 'Access menu > AI Developer > Settings'; +begin + case FAIDefault of + TC4DAIsAvailable.Gemini: + begin + if FBaseUrlGemini.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'Gemini'])); + + if FModelGemini.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Gemini'])); + + if FApiKeyGemini.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'Gemini'])); + end; + TC4DAIsAvailable.OpenAI: + begin + if FBaseUrlOpenAI.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'ChatGPT'])); + + if FModelOpenAI.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'ChatGPT'])); + + if FApiKeyOpenAI.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'ChatGPT'])); + end; + TC4DAIsAvailable.Groq: + begin + if FBaseUrlGroq.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'Groq'])); + + if FModelGroq.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Groq'])); + + if FApiKeyGroq.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'Groq'])); + end; + TC4DAIsAvailable.Ollama: + begin + if FBaseUrlOllama.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'Ollama'])); + + if FModelOllama.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Ollama'])); + + if FApiKeyOllama.Trim.IsEmpty then + TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'Ollama'])); + end; + end; +end; + initialization finalization diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index f6fb30a..65a9546 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -33,6 +33,7 @@ TC4DLanguageHelper = record helper for TC4DLanguage function ToString: string; function GetLanguageDefinition: string; function GetMsgCodeOnly: string; + function GetMsgSQLOnly: string; function GetMsgJSONIsDatabaseStructure(ASGBDName: string): string; function GetMsgJSONInformedAnswerQuestion: string; end; @@ -129,6 +130,19 @@ function TC4DLanguageHelper.GetMsgCodeOnly: string; Result := Result + sLineBreak; end; +function TC4DLanguageHelper.GetMsgSQLOnly: string; +begin + Result := 'Faça a seguinte ação sem adicionar comentários e retorne apenas os Comandos SQLs:'; + case Self of + TC4DLanguage.en: + Result := 'Perform the following action without adding comments, returning only the SQL commands:'; + TC4DLanguage.es: + Result := 'Realice la siguiente acción sin agregar comentarios, devolviendo solo comandos SQL:'; + end; + + Result := Result + sLineBreak; +end; + function TC4DLanguageHelper.GetMsgJSONIsDatabaseStructure(ASGBDName: string): string; begin Result := 'O seguinte JSON se refere a estrutura SQL de um banco de dados '; From 6c385fe15c9aeee26f276847c39a0610bb1b1c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 23 Aug 2024 16:14:40 -0300 Subject: [PATCH 036/109] feature/add-ollama --- Src/AI/DelphiAIDev.AI.Ollama.pas | 26 +- Src/Consts/DelphiAIDev.Consts.pas | 4 +- Src/Settings/DelphiAIDev.Settings.View.dfm | 351 +++++++++++++++++---- Src/Settings/DelphiAIDev.Settings.View.pas | 55 +++- Src/Settings/DelphiAIDev.Settings.pas | 3 - Src/View/DelphiAIDev.View.About.dfm | 1 + 6 files changed, 350 insertions(+), 90 deletions(-) diff --git a/Src/AI/DelphiAIDev.AI.Ollama.pas b/Src/AI/DelphiAIDev.AI.Ollama.pas index 81be377..2bdeced 100644 --- a/Src/AI/DelphiAIDev.AI.Ollama.pas +++ b/Src/AI/DelphiAIDev.AI.Ollama.pas @@ -45,15 +45,11 @@ function TDelphiAIDevAIOllama.GetResponse(const AQuestion: string): string; var LResponse: IResponse; LJsonValueAll: TJSONVALUE; - LJsonArrayChoices: TJsonArray; + LJsonValueMessage: TJSONValue; LJsonObjMessage: TJsonObject; - LContent: string; - LItemChoices: Integer; begin Result := ''; - TUtils.ShowMsgSynchronize(Format(API_JSON_BODY_BASE, [FSettings.ModelOllama, AQuestion])); - LResponse := TRequest.New .BaseURL(FSettings.BaseUrlOllama) .ContentType(TConsts.APPLICATION_JSON) @@ -65,24 +61,18 @@ function TDelphiAIDevAIOllama.GetResponse(const AQuestion: string): string; if LResponse.StatusCode <> 200 then Exit('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); - Exit(LResponse.Content); - - - Exit; - LJsonValueAll := TJsonObject.ParseJSONValue(LResponse.Content); + LJsonValueAll := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LResponse.Content), 0); if not(LJsonValueAll is TJSONObject) then Exit('The question cannot be answered, return object not found.' + sLineBreak + 'Return: ' + LResponse.Content); - LJsonArrayChoices := (LJsonValueAll as TJsonObject).GetValue('choices'); - for LItemChoices := 0 to Pred(LJsonArrayChoices.Count) do - begin - LJsonObjMessage := LJsonArrayChoices.Items[LItemChoices].GetValue('message'); - LContent := LJsonObjMessage.GetValue('content'); - Result := Result + LContent.Trim + sLineBreak; - end; + LJsonValueMessage := (LJsonValueAll as TJSONObject).GetValue('message'); + if not(LJsonValueMessage is TJSONObject) then + Exit('The question cannot be answered, return object not found.' + sLineBreak + + 'Return: ' + LResponse.Content); - Result := Result.Trim; + LJsonObjMessage := LJsonValueMessage as TJSONObject; + Result := TJSONString(LJsonObjMessage.GetValue('content')).Value.Trim; end; end. diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index aa40be5..712b9d8 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -34,8 +34,8 @@ TConsts = class BASE_URL_GROQ = 'https://api.groq.com/openai/v1/chat/completions'; MODEL_GROQ_DEFAULT = 'llama3-70b-8192'; //'llama3-8b-8192';; - BASE_URL_OLLAMA = ' http://localhost:11434/api/chat'; - MODEL_OLLAMA_DEFAULT = 'tinyllama'; //'mistral'; + BASE_URL_OLLAMA = 'http://localhost:11434/api/chat'; + MODEL_OLLAMA_DEFAULT = ''; //'tinyllama' 'mistral'; //NAMES FILES .INI FILE_INI_GENERAL_SETTINGS = 'delphi-ai-developer.ini'; diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 4fb8194..a7fec97 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -2,7 +2,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Caption = 'Delphi AI Developer - Settings' - ClientHeight = 578 + ClientHeight = 647 ClientWidth = 632 Color = clBtnFace Font.Charset = DEFAULT_CHARSET @@ -22,7 +22,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 632 - Height = 578 + Height = 647 Align = alClient BevelOuter = bvNone TabOrder = 0 @@ -30,16 +30,78 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 632 - Height = 543 + Height = 612 Align = alClient BevelOuter = bvNone ParentBackground = False TabOrder = 0 + object Bevel1: TBevel + AlignWithMargins = True + Left = 0 + Top = 608 + Width = 632 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alBottom + Shape = bsTopLine + ExplicitTop = 158 + ExplicitWidth = 441 + end + object Bevel2: TBevel + AlignWithMargins = True + Left = 0 + Top = 475 + Width = 632 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alTop + Shape = bsTopLine + end + object Bevel3: TBevel + AlignWithMargins = True + Left = 0 + Top = 347 + Width = 632 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alTop + Shape = bsTopLine + end + object Bevel4: TBevel + AlignWithMargins = True + Left = 0 + Top = 218 + Width = 632 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alTop + Shape = bsTopLine + end + object Bevel5: TBevel + AlignWithMargins = True + Left = 0 + Top = 90 + Width = 632 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alTop + Shape = bsTopLine + end object gBoxGemini: TGroupBox Left = 0 - Top = 97 + Top = 94 Width = 632 - Height = 133 + Height = 124 Align = alTop Caption = ' Gemini (Google) ' ParentBackground = False @@ -49,7 +111,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 5 Top = 18 Width = 622 - Height = 110 + Height = 101 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -63,7 +125,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object Label6: TLabel Left = 16 - Top = 48 + Top = 44 Width = 37 Height = 13 Caption = 'API key' @@ -77,7 +139,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object lbLinkGemini01: TLabel Left = 16 - Top = 89 + Top = 83 Width = 86 Height = 13 Cursor = crHandPoint @@ -95,7 +157,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object lbLinkGemini02: TLabel Left = 128 - Top = 89 + Top = 83 Width = 72 Height = 13 Cursor = crHandPoint @@ -113,7 +175,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object btnApiKeyGeminiView: TSpeedButton Left = 582 - Top = 63 + Top = 59 Width = 23 Height = 22 Cursor = crHandPoint @@ -152,7 +214,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object lbLinkGemini03: TLabel Left = 232 - Top = 89 + Top = 83 Width = 67 Height = 13 Cursor = crHandPoint @@ -177,7 +239,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object edtApiKeyGemini: TEdit Left = 16 - Top = 64 + Top = 60 Width = 563 Height = 21 PasswordChar = '*' @@ -200,7 +262,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 632 - Height = 97 + Height = 90 Align = alTop Caption = ' Preferences ' ParentBackground = False @@ -231,14 +293,14 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object ColorBoxColorHighlightCodeDelphi: TColorBox Left = 218 - Top = 66 + Top = 63 Width = 133 Height = 22 TabOrder = 3 end object ckColorHighlightCodeDelphiUse: TCheckBox Left = 21 - Top = 68 + Top = 65 Width = 194 Height = 17 Caption = 'Color to highlight Delphi/Pascal code' @@ -259,9 +321,9 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object gBoxOpenAI: TGroupBox Left = 0 - Top = 230 + Top = 222 Width = 632 - Height = 133 + Height = 125 Align = alTop Caption = ' ChatGPT (OpenAI)' ParentBackground = False @@ -271,7 +333,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 5 Top = 18 Width = 622 - Height = 110 + Height = 102 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -285,7 +347,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object Label3: TLabel Left = 16 - Top = 48 + Top = 44 Width = 37 Height = 13 Caption = 'API key' @@ -299,7 +361,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object lbLinkGpt01: TLabel Left = 16 - Top = 90 + Top = 84 Width = 86 Height = 13 Cursor = crHandPoint @@ -317,7 +379,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object btnApiKeyOpenAIView: TSpeedButton Left = 582 - Top = 63 + Top = 59 Width = 23 Height = 22 Cursor = crHandPoint @@ -356,7 +418,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object lbLinkGpt02: TLabel Left = 128 - Top = 90 + Top = 84 Width = 72 Height = 13 Cursor = crHandPoint @@ -381,7 +443,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object edtApiKeyOpenAI: TEdit Left = 16 - Top = 64 + Top = 60 Width = 563 Height = 21 PasswordChar = '*' @@ -402,44 +464,21 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end end end - object gboxData: TGroupBox - Left = 0 - Top = 498 - Width = 632 - Height = 45 - Align = alBottom - Caption = ' Data ' - Padding.Left = 2 - Padding.Top = 5 - Padding.Bottom = 3 - TabOrder = 3 - object btnOpenDataFolder: TButton - Left = 4 - Top = 20 - Width = 122 - Height = 20 - Cursor = crHandPoint - Align = alLeft - Caption = 'Open Data Folder' - TabOrder = 0 - OnClick = btnOpenDataFolderClick - end - end object gBoxGroq: TGroupBox Left = 0 - Top = 363 + Top = 351 Width = 632 - Height = 135 - Align = alClient + Height = 124 + Align = alTop Caption = ' Groq ' ParentBackground = False - TabOrder = 4 + TabOrder = 3 object pnGroqBack: TPanel AlignWithMargins = True Left = 5 Top = 18 Width = 622 - Height = 112 + Height = 101 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -453,7 +492,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object Label9: TLabel Left = 16 - Top = 48 + Top = 44 Width = 37 Height = 13 Caption = 'API key' @@ -467,7 +506,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object lbLinkGroq01: TLabel Left = 16 - Top = 90 + Top = 84 Width = 86 Height = 13 Cursor = crHandPoint @@ -485,7 +524,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object btnApiKeyGroqView: TSpeedButton Left = 582 - Top = 63 + Top = 59 Width = 23 Height = 22 Cursor = crHandPoint @@ -524,7 +563,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object lbLinkGroq02: TLabel Left = 128 - Top = 90 + Top = 84 Width = 72 Height = 13 Cursor = crHandPoint @@ -542,7 +581,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object lbLinkGroq03: TLabel Left = 232 - Top = 89 + Top = 84 Width = 59 Height = 13 Cursor = crHandPoint @@ -567,7 +606,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object edtApiKeyGroq: TEdit Left = 16 - Top = 64 + Top = 60 Width = 563 Height = 21 PasswordChar = '*' @@ -578,7 +617,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Top = 21 Width = 226 Height = 21 - Style = csDropDownList TabOrder = 1 Items.Strings = ( 'llama3-8b-8192' @@ -592,10 +630,174 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end end end + object GroupBox1: TGroupBox + Left = 0 + Top = 479 + Width = 632 + Height = 129 + Align = alClient + Caption = ' Ollama (offline) ' + ParentBackground = False + TabOrder = 4 + object Panel1: TPanel + AlignWithMargins = True + Left = 5 + Top = 18 + Width = 622 + Height = 106 + Align = alClient + BevelOuter = bvNone + ParentBackground = False + TabOrder = 0 + object Label12: TLabel + Left = 16 + Top = 5 + Width = 45 + Height = 13 + Caption = 'Base URL' + end + object Label13: TLabel + Left = 16 + Top = 44 + Width = 29 + Height = 13 + Caption = 'Token' + end + object Label14: TLabel + Left = 374 + Top = 5 + Width = 28 + Height = 13 + Caption = 'Model' + end + object btnApiKeyOllamaView: TSpeedButton + Left = 582 + Top = 59 + Width = 23 + Height = 22 + Cursor = crHandPoint + Hint = 'Show/Hide API Key' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C + BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF + 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF + 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 + B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD + EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF + FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 + C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF + FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF + E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 + C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 + C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 + DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 + 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + OnClick = btnApiKeyOllamaViewClick + end + object lbLinkOllama02: TLabel + Left = 128 + Top = 84 + Width = 72 + Height = 13 + Cursor = crHandPoint + Hint = 'https://github.com/ollama/ollama/blob/main/docs/api.md' + Caption = 'Documentation' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object lbLinkOllama03: TLabel + Left = 232 + Top = 84 + Width = 68 + Height = 13 + Cursor = crHandPoint + Hint = 'https://ollama.com/library' + Caption = 'Ollama Models' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object lbLinkOllama01: TLabel + Left = 16 + Top = 84 + Width = 82 + Height = 13 + Cursor = crHandPoint + Hint = 'https://ollama.com/' + Caption = 'Ollama Download' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object edtBaseUrlOllama: TEdit + Left = 16 + Top = 21 + Width = 356 + Height = 21 + TabOrder = 0 + end + object edtApiKeyOllama: TEdit + Left = 16 + Top = 60 + Width = 563 + Height = 21 + PasswordChar = '*' + TabOrder = 2 + end + object cBoxModelOllama: TComboBox + Left = 374 + Top = 21 + Width = 226 + Height = 21 + TabOrder = 1 + Items.Strings = ( + 'llama2' + 'llama3' + 'llama3.1' + 'codellama' + 'tinyllama' + 'mistral') + end + end + end end object pnBottom: TPanel Left = 0 - Top = 543 + Top = 612 Width = 632 Height = 35 Margins.Left = 0 @@ -613,12 +815,13 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object lbRestoreDefaults: TLabel AlignWithMargins = True Left = 16 - Top = 12 + Top = 7 Width = 80 - Height = 18 + Height = 21 Cursor = crHandPoint Margins.Left = 16 - Margins.Top = 10 + Margins.Top = 5 + Margins.Bottom = 5 Align = alLeft Caption = 'Restore defaults' Font.Charset = DEFAULT_CHARSET @@ -633,6 +836,30 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView OnClick = lbRestoreDefaultsClick ExplicitHeight = 13 end + object lbOpenDataFolder: TLabel + AlignWithMargins = True + Left = 115 + Top = 7 + Width = 85 + Height = 21 + Cursor = crHandPoint + Margins.Left = 16 + Margins.Top = 5 + Margins.Bottom = 5 + Align = alLeft + Caption = 'Open Data Folder' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + Layout = tlCenter + OnClick = lbOpenDataFolderClick + ExplicitHeight = 13 + end object btnConfirm: TButton AlignWithMargins = True Left = 404 diff --git a/Src/Settings/DelphiAIDev.Settings.View.pas b/Src/Settings/DelphiAIDev.Settings.View.pas index 764b65e..750d25a 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.pas +++ b/Src/Settings/DelphiAIDev.Settings.View.pas @@ -16,7 +16,7 @@ interface Vcl.ExtCtrls, DelphiAIDev.Settings, DelphiAIDev.Types, - Vcl.Buttons; + Vcl.Buttons, Vcl.ComCtrls; type TDelphiAIDevSettingsView = class(TForm) @@ -56,8 +56,6 @@ TDelphiAIDevSettingsView = class(TForm) lbLinkGemini03: TLabel; Label4: TLabel; cBoxLanguageQuestions: TComboBox; - gboxData: TGroupBox; - btnOpenDataFolder: TButton; gBoxGroq: TGroupBox; pnGroqBack: TPanel; Label8: TLabel; @@ -70,6 +68,24 @@ TDelphiAIDevSettingsView = class(TForm) edtApiKeyGroq: TEdit; cBoxModelGroq: TComboBox; lbLinkGroq03: TLabel; + lbOpenDataFolder: TLabel; + GroupBox1: TGroupBox; + Panel1: TPanel; + Label12: TLabel; + Label13: TLabel; + Label14: TLabel; + btnApiKeyOllamaView: TSpeedButton; + lbLinkOllama01: TLabel; + lbLinkOllama02: TLabel; + lbLinkOllama03: TLabel; + edtBaseUrlOllama: TEdit; + edtApiKeyOllama: TEdit; + cBoxModelOllama: TComboBox; + Bevel1: TBevel; + Bevel2: TBevel; + Bevel3: TBevel; + Bevel4: TBevel; + Bevel5: TBevel; procedure FormCreate(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure btnCloseClick(Sender: TObject); @@ -81,8 +97,9 @@ TDelphiAIDevSettingsView = class(TForm) procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure lbRestoreDefaultsClick(Sender: TObject); procedure ckColorHighlightCodeDelphiUseClick(Sender: TObject); - procedure btnOpenDataFolderClick(Sender: TObject); procedure btnApiKeyGroqViewClick(Sender: TObject); + procedure lbOpenDataFolderClick(Sender: TObject); + procedure btnApiKeyOllamaViewClick(Sender: TObject); private FSettings: TDelphiAIDevSettings; procedure SaveSettings; @@ -160,6 +177,10 @@ procedure TDelphiAIDevSettingsView.ConfigScreen; lbLinkGroq02.Font.Color := LColor; lbLinkGroq03.Font.Color := LColor; lbRestoreDefaults.Font.Color := LColor; + lbOpenDataFolder.Font.Color := LColor; + lbLinkOllama01.Font.Color := LColor; + lbLinkOllama02.Font.Color := LColor; + lbLinkOllama03.Font.Color := LColor; end; procedure TDelphiAIDevSettingsView.btnApiKeyGeminiViewClick(Sender: TObject); @@ -206,16 +227,19 @@ procedure TDelphiAIDevSettingsView.lbRestoreDefaultsClick(Sender: TObject); LApiKeyGemini: string; LApiKeyOpenAI: string; LApiKeyGroq: string; + LApiKeyOllama: string; begin LApiKeyGemini := FSettings.ApiKeyGemini; LApiKeyOpenAI := FSettings.ApiKeyOpenAI; LApiKeyGroq := FSettings.ApiKeyGroq; + LApiKeyOllama := FSettings.ApiKeyOllama; FSettings.LoadDefaults; FSettings.ApiKeyGemini := LApiKeyGemini; FSettings.ApiKeyOpenAI := LApiKeyOpenAI; FSettings.ApiKeyGroq := LApiKeyGroq; + FSettings.ApiKeyOllama := LApiKeyOllama; Self.LoadSettings; end; @@ -248,15 +272,27 @@ procedure TDelphiAIDevSettingsView.LoadSettings; edtBaseUrlGemini.Text := FSettings.BaseUrlGemini; cBoxModelGemini.ItemIndex := cBoxModelGemini.Items.IndexOf(FSettings.ModelGemini); + if cBoxModelGemini.ItemIndex < 0 then + cBoxModelGemini.Text := FSettings.ModelGemini; edtApiKeyGemini.Text := FSettings.ApiKeyGemini; edtBaseUrlOpenAI.Text := FSettings.BaseUrlOpenAI; cBoxModelOpenAI.ItemIndex := cBoxModelOpenAI.Items.IndexOf(FSettings.ModelOpenAI); + if cBoxModelOpenAI.ItemIndex < 0 then + cBoxModelOpenAI.Text := FSettings.ModelOpenAI; edtApiKeyOpenAI.Text := FSettings.ApiKeyOpenAI; edtBaseUrlGroq.Text := FSettings.BaseUrlGroq; cBoxModelGroq.ItemIndex := cBoxModelGroq.Items.IndexOf(FSettings.ModelGroq); + if cBoxModelGroq.ItemIndex < 0 then + cBoxModelGroq.Text := FSettings.ModelGroq; edtApiKeyGroq.Text := FSettings.ApiKeyGroq; + + edtBaseUrlOllama.Text := FSettings.BaseUrlOllama; + cBoxModelOllama.ItemIndex := cBoxModelOllama.Items.IndexOf(FSettings.ModelOllama); + if cBoxModelOllama.ItemIndex < 0 then + cBoxModelOllama.Text := FSettings.ModelOllama; + edtApiKeyOllama.Text := FSettings.ApiKeyOllama; end; procedure TDelphiAIDevSettingsView.SaveSettings; @@ -279,10 +315,14 @@ procedure TDelphiAIDevSettingsView.SaveSettings; FSettings.ModelGroq := cBoxModelGroq.Text; FSettings.ApiKeyGroq := edtApiKeyGroq.Text; + FSettings.BaseUrlOllama := edtBaseUrlOllama.Text; + FSettings.ModelOllama := cBoxModelOllama.Text; + FSettings.ApiKeyOllama := edtApiKeyOllama.Text; + FSettings.SaveData; end; -procedure TDelphiAIDevSettingsView.btnOpenDataFolderClick(Sender: TObject); +procedure TDelphiAIDevSettingsView.lbOpenDataFolderClick(Sender: TObject); var LPathFolder: string; begin @@ -293,4 +333,9 @@ procedure TDelphiAIDevSettingsView.btnOpenDataFolderClick(Sender: TObject); TUtils.OpenFolder(LPathFolder); end; +procedure TDelphiAIDevSettingsView.btnApiKeyOllamaViewClick(Sender: TObject); +begin + TUtils.TogglePasswordChar(edtApiKeyOllama); +end; + end. diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index d45d045..33f9f75 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -283,9 +283,6 @@ procedure TDelphiAIDevSettings.ValidateFillingSelectedAI; if FModelOllama.Trim.IsEmpty then TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Ollama'])); - - if FApiKeyOllama.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'Ollama'])); end; end; end; diff --git a/Src/View/DelphiAIDev.View.About.dfm b/Src/View/DelphiAIDev.View.About.dfm index 056b279..46d9422 100644 --- a/Src/View/DelphiAIDev.View.About.dfm +++ b/Src/View/DelphiAIDev.View.About.dfm @@ -29,6 +29,7 @@ object DelphiAIDevViewAbout: TDelphiAIDevViewAbout Color = clWindow ParentBackground = False TabOrder = 0 + ExplicitTop = -4 object Bevel1: TBevel AlignWithMargins = True Left = 0 From 0e0d80b89df8146b4811977e14257a1426ad1e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 23 Aug 2024 16:52:59 -0300 Subject: [PATCH 037/109] Update DelphiAIDev.Utils.pas --- Src/Utils/DelphiAIDev.Utils.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 1c0a3b5..7ff04e1 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -333,8 +333,8 @@ class procedure TUtils.CenterPanel(const APanel: TPanel; const AWinControl: TWin if AWinControl = nil then Exit; - LCenterX := AWinControl.Width div 2; - LCenterY := AWinControl.Height div 2; + LCenterX := AWinControl.Left + (AWinControl.Width div 2); + LCenterY := AWinControl.Top + (AWinControl.Height div 2); APanel.Left := LCenterX - (APanel.Width div 2); APanel.Top := LCenterY - (APanel.Height div 2); From f14a60c8b6a2d126511695757aa6f25bd72e12dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Sat, 24 Aug 2024 00:00:30 -0300 Subject: [PATCH 038/109] bk/2024-08-24-0000 --- Src/AI/DelphiAIDev.AI.Ollama.pas | 3 ++- Src/Settings/DelphiAIDev.Settings.View.dfm | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Src/AI/DelphiAIDev.AI.Ollama.pas b/Src/AI/DelphiAIDev.AI.Ollama.pas index 2bdeced..10239a5 100644 --- a/Src/AI/DelphiAIDev.AI.Ollama.pas +++ b/Src/AI/DelphiAIDev.AI.Ollama.pas @@ -26,9 +26,10 @@ TDelphiAIDevAIOllama = class(TInterfacedObject, IDelphiAIDevAI) implementation const - API_JSON_BODY_BASE = //'{"messages": [{"role": "user", "content": "%s"}], "model": "%s"}'; + API_JSON_BODY_BASE = '{"model": "%s", '+ '"messages": [{"role": "user", "content": "%s"}], '+ + '"options": {"seed": 101, "temperature": 0}, '+ '"stream": false}'; class function TDelphiAIDevAIOllama.New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index a7fec97..7b13457 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -817,7 +817,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 16 Top = 7 Width = 80 - Height = 21 + Height = 13 Cursor = crHandPoint Margins.Left = 16 Margins.Top = 5 @@ -834,14 +834,13 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView ShowHint = True Layout = tlCenter OnClick = lbRestoreDefaultsClick - ExplicitHeight = 13 end object lbOpenDataFolder: TLabel AlignWithMargins = True Left = 115 Top = 7 Width = 85 - Height = 21 + Height = 13 Cursor = crHandPoint Margins.Left = 16 Margins.Top = 5 @@ -858,7 +857,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView ShowHint = True Layout = tlCenter OnClick = lbOpenDataFolderClick - ExplicitHeight = 13 end object btnConfirm: TButton AlignWithMargins = True From dbdf28cdce96236fa5241d28715f9b2f50fb85cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 26 Aug 2024 10:18:30 -0300 Subject: [PATCH 039/109] refactor/parenteses-em-ifs --- Src/Chat/DelphiAIDev.Chat.ProcessResponse.pas | 8 +- Src/Chat/DelphiAIDev.Chat.View.dfm | 3 +- Src/Chat/DelphiAIDev.Chat.View.pas | 8 +- Src/Conn/C4D.Conn.Utils.pas | 2 +- .../DelphiAIDev.DB.Registers.View.pas | 4 +- ...hiAIDev.DefaultsQuestions.AddEdit.View.pas | 6 +- ...elphiAIDev.DefaultsQuestions.PopupMenu.pas | 16 +-- .../DelphiAIDev.DefaultsQuestions.View.pas | 10 +- .../DelphiAIDev.IDE.ImageListMain.pas | 4 +- .../DelphiAIDev.MainMenu.Register.pas | 2 +- Src/MainMenu/DelphiAIDev.MainMenu.pas | 12 +- .../DelphiAIDev.PopupMenuProjects.Item.pas | 2 +- .../DelphiAIDev.PopupMenuProjects.pas | 25 ++-- Src/Settings/DelphiAIDev.Settings.View.pas | 2 +- Src/Types/DelphiAIDev.Types.pas | 18 +-- Src/Utils/DelphiAIDev.Utils.ABMenuAction.pas | 10 +- .../DelphiAIDev.Utils.GetIniPositionStr.pas | 28 ++-- Src/Utils/DelphiAIDev.Utils.ListView.pas | 58 ++++---- Src/Utils/DelphiAIDev.Utils.OTA.pas | 126 +++++++++--------- Src/Utils/DelphiAIDev.Utils.pas | 70 +++++----- Src/View/DelphiAIDev.View.Dialog.dfm | 12 +- Src/View/DelphiAIDev.View.Dialog.pas | 8 +- Src/View/DelphiAIDev.View.Memo.pas | 2 +- .../DelphiAIDev.WaitingScreen.View.pas | 4 +- .../DelphiAIDev.WaitingScreen.pas | 6 +- 25 files changed, 219 insertions(+), 227 deletions(-) diff --git a/Src/Chat/DelphiAIDev.Chat.ProcessResponse.pas b/Src/Chat/DelphiAIDev.Chat.ProcessResponse.pas index 73c75f9..060ef51 100644 --- a/Src/Chat/DelphiAIDev.Chat.ProcessResponse.pas +++ b/Src/Chat/DelphiAIDev.Chat.ProcessResponse.pas @@ -121,14 +121,14 @@ procedure TDelphiAIDevChatProcessResponse.BoldInWordsBetweenBacktick(const ALine if not LCodeStarted then begin - if(LCurrentLetter = BACKTICK)and(LNextLetter <> BACKTICK)then + if (LCurrentLetter = BACKTICK) and (LNextLetter <> BACKTICK) then begin LCodeStarted := True; Continue; end; end; - if(LCurrentLetter = BACKTICK)and(LNextLetter <> BACKTICK)then + if (LCurrentLetter = BACKTICK) and (LNextLetter <> BACKTICK) then begin LCodeStarted := False; FRichEdit.SelAttributes.Style := []; @@ -177,7 +177,7 @@ procedure TDelphiAIDevChatProcessResponse.BoldInWordsBetweenTwoAsterisk(const AL if not LCodeStarted then begin - if(LCurrentLetter = ASTERISK)and(LNextLetter = ASTERISK)then + if (LCurrentLetter = ASTERISK) and (LNextLetter = ASTERISK) then begin LCodeStarted := True; Inc(LPosLetter, 2); @@ -185,7 +185,7 @@ procedure TDelphiAIDevChatProcessResponse.BoldInWordsBetweenTwoAsterisk(const AL end; end; - if(LCurrentLetter = ASTERISK)and(LNextLetter = ASTERISK)then + if (LCurrentLetter = ASTERISK) and (LNextLetter = ASTERISK) then begin LCodeStarted := False; FRichEdit.SelAttributes.Style := []; diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index 2610221..11c2036 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -138,7 +138,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Left = 0 Top = 3 Width = 56 - Height = 22 + Height = 13 Cursor = crHandPoint Hint = 'AI being used' Margins.Left = 0 @@ -149,7 +149,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'lbCurrentAI' PopupMenu = pMenuCurrentAI OnClick = lbCurrentAIClick - ExplicitHeight = 13 end object btnSend: TButton AlignWithMargins = True diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index 6a9ca36..07f9407 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -279,7 +279,7 @@ procedure TDelphiAIDevChatView.mmQuestionChange(Sender: TObject); procedure TDelphiAIDevChatView.mmQuestionKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin - if (ssCtrl in Shift)and(Key = VK_RETURN) then + if (ssCtrl in Shift) and (Key = VK_RETURN) then begin btnSend.Click; Key := 0; @@ -288,7 +288,7 @@ procedure TDelphiAIDevChatView.mmQuestionKeyDown(Sender: TObject; var Key: Word; procedure TDelphiAIDevChatView.mmQuestionKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin - if (ssCtrl in Shift)and(Key = 65) then + if (ssCtrl in Shift) and (Key = 65) then begin mmQuestion.SelectAll; Key := 0; @@ -562,14 +562,14 @@ procedure TDelphiAIDevChatView.AddResponseSimple(const AString: string); // // if not LCodeStarted then // begin -// if(LCurrentLetter = BACKTICK)and(LNextLetter <> BACKTICK)then +// if (LCurrentLetter = BACKTICK) and (LNextLetter <> BACKTICK) then // begin // LCodeStarted := True; // Continue; // end; // end; // -// if(LCurrentLetter = BACKTICK)and(LNextLetter <> BACKTICK)then +// if (LCurrentLetter = BACKTICK) and (LNextLetter <> BACKTICK) then // begin // LCodeStarted := False; // mmReturn.SelAttributes.Style := []; diff --git a/Src/Conn/C4D.Conn.Utils.pas b/Src/Conn/C4D.Conn.Utils.pas index 8ca7b3f..32dab91 100644 --- a/Src/Conn/C4D.Conn.Utils.pas +++ b/Src/Conn/C4D.Conn.Utils.pas @@ -32,7 +32,7 @@ class function TC4DConnUtils.SQLConfBusca(const ASql: string): string; Delete(Result, 1, 2); Result := 'where '+ Result; end - else if(copy(Result, 1, 5) <> 'where') + else if (copy(Result, 1, 5) <> 'where') and(copy(Result, 1, 5) <> 'limit') and(copy(Result, 1, 8) <> 'order by') and(copy(Result, 1, 8) <> 'group by') diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas index 3cae233..109708a 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas @@ -175,7 +175,7 @@ procedure TDelphiAIDevDBRegistersView.ReloadDataInternal; //if (AFields.Kind = TC4DQuestionKind.ItemMenuNormal) and (AFields.Question.Trim.IsEmpty) then // Exit; - if(LStrSearch.Trim.IsEmpty) + if (LStrSearch.Trim.IsEmpty) or(AFields.Description.ToLower.Contains(LStrSearch)) or(AFields.Host.ToLower.Contains(LStrSearch)) or(AFields.DatabaseName.ToLower.Contains(LStrSearch)) @@ -348,7 +348,7 @@ procedure TDelphiAIDevDBRegistersView.btnRemoveClick(Sender: TObject); if LGuid.Trim.IsEmpty then TUtils.ShowMsgErrorAndAbort('Guid not found'); -// if(TC4DWizardOpenExternalModel.New.ExistGuidInIniFile(LId))then +// if TC4DWizardOpenExternalModel.New.ExistGuidInIniFile(LId) then // TUtils.ShowMsgAndAbort('This registration cannot be deleted, as it is linked to other registration(s)'); if not TUtils.ShowQuestion2('Confirm remove?') then diff --git a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas index 8ab81dd..b114e88 100644 --- a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas +++ b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.AddEdit.View.pas @@ -217,7 +217,7 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.ConfFieldsKind; end else if cBoxKind.Text = TC4DQuestionKind.MenuMasterOnly.ToString then begin - if(edtCaption.Text = '-')and(not FLastCaption.Trim.IsEmpty)then + if (edtCaption.Text = '-') and (not FLastCaption.Trim.IsEmpty) then edtCaption.Text := FLastCaption; FLastQuestion := mmQuestion.Lines.Text; @@ -230,10 +230,10 @@ procedure TDelphiAIDevDefaultsQuestionsAddEditView.ConfFieldsKind; end else begin - if(edtCaption.Text = '-')and(not FLastCaption.Trim.IsEmpty)then + if (edtCaption.Text = '-') and (not FLastCaption.Trim.IsEmpty) then edtCaption.Text := FLastCaption; - if(mmQuestion.Text = '')and(not FLastQuestion.Trim.IsEmpty)then + if (mmQuestion.Text = '') and (not FLastQuestion.Trim.IsEmpty) then mmQuestion.Text := FLastQuestion; end; diff --git a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.PopupMenu.pas b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.PopupMenu.pas index 8d1c903..6614170 100644 --- a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.PopupMenu.pas +++ b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.PopupMenu.pas @@ -107,8 +107,8 @@ procedure TDelphiAIDevDefaultsQuestionsPopupMenu.CreateMenuItemsList; for LOrder2 in LListOrder do for LItem2 in FList do begin - if(LItem2.Order = LOrder2)then - if(not LItem2.Created)and(LItem2.GuidMenuMaster.Trim = AFields.Guid.Trim)then + if LItem2.Order = LOrder2 then + if (not LItem2.Created) and (LItem2.GuidMenuMaster.Trim = AFields.Guid.Trim) then begin LMenuItem2 := Self.CreateSubMenu(AMenuItem, LItem2); LItem2.Created := True; @@ -129,10 +129,10 @@ procedure TDelphiAIDevDefaultsQuestionsPopupMenu.CreateMenuItemsList; try for LItem in FList do begin - if(LItem.Order <= 0)then + if LItem.Order <= 0 then LItem.Order := 9999; - if(not LListOrder.Contains(LItem.Order))then //(LItem.Order > 0)and + if not LListOrder.Contains(LItem.Order) then //(LItem.Order > 0)and LListOrder.Add(LItem.Order); end; @@ -142,8 +142,8 @@ procedure TDelphiAIDevDefaultsQuestionsPopupMenu.CreateMenuItemsList; for LOrder in LListOrder do for LItem in FList do begin - if(LItem.Order = LOrder)then - if(not LItem.Created)and(LITem.GuidMenuMaster.Trim.IsEmpty)then + if LItem.Order = LOrder then + if (not LItem.Created) and (LITem.GuidMenuMaster.Trim.IsEmpty) then begin LMenuItem := Self.CreateSubMenu(nil, LItem); LItem.Created := True; @@ -156,8 +156,8 @@ procedure TDelphiAIDevDefaultsQuestionsPopupMenu.CreateMenuItemsList; for LOrder in LListOrder do for LItem in FList do begin - if(LItem.Order = LOrder)then - if(not LItem.Created)then + if LItem.Order = LOrder then + if not LItem.Created then begin LMenuItem := Self.CreateSubMenu(nil, LItem); LItem.Created := True; diff --git a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas index 170cd82..296fcec 100644 --- a/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas +++ b/Src/DefaultsQuestions/DelphiAIDev.DefaultsQuestions.View.pas @@ -104,7 +104,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.FormKeyDown(Sender: TObject; var Key btnClose.Click; VK_DOWN, VK_UP: begin - if(ListView <> ActiveControl)then + if ListView <> ActiveControl then begin case Key of VK_DOWN: @@ -173,7 +173,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.ReloadDataInternal; if (AFields.Kind = TC4DQuestionKind.ItemMenuNormal) and (AFields.Question.Trim.IsEmpty) then Exit; - if(LStrSearch.Trim.IsEmpty) + if (LStrSearch.Trim.IsEmpty) or(AFields.Caption.ToLower.Contains(LStrSearch)) or(AFields.Question.ToLower.Contains(LStrSearch)) then @@ -196,7 +196,7 @@ procedure TDelphiAIDevDefaultsQuestionsView.ReloadDataInternal; .InvertOrder(False) .CustomSort; - if(not LGuid.Trim.IsEmpty)then + if not LGuid.Trim.IsEmpty then TUtils.FindListVewItem(ListView, C_INDEX_SUBITEM_Guid, LGuid); Self.FillStatusBar(ListView.Selected); @@ -337,10 +337,10 @@ procedure TDelphiAIDevDefaultsQuestionsView.btnRemoveClick(Sender: TObject); Exit; LGuid := ListView.Items[ListView.Selected.Index].SubItems[C_INDEX_SUBITEM_Guid]; - if(LGuid.Trim.IsEmpty)then + if LGuid.Trim.IsEmpty then TUtils.ShowMsgErrorAndAbort('Guid not found'); -// if(TC4DWizardOpenExternalModel.New.ExistGuidInIniFile(LId))then +// if TC4DWizardOpenExternalModel.New.ExistGuidInIniFile(LId) then // TUtils.ShowMsgAndAbort('This registration cannot be deleted, as it is linked to other registration(s)'); if not TUtils.ShowQuestion2('Confirm remove?') then diff --git a/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas b/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas index 449f95d..efe47d8 100644 --- a/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas +++ b/Src/IDE/ImageListMain/DelphiAIDev.IDE.ImageListMain.pas @@ -38,7 +38,7 @@ implementation class function TDelphiAIDevIDEImageListMain.GetInstance: TDelphiAIDevIDEImageListMain; begin - if(not Assigned(Instance))then + if not Assigned(Instance) then Instance := Self.Create; Result := Instance; end; @@ -58,7 +58,7 @@ initialization Instance := TDelphiAIDevIDEImageListMain.GetInstance; finalization - if(Assigned(Instance))then + if Assigned(Instance) then Instance.Free; end. diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.Register.pas b/Src/MainMenu/DelphiAIDev.MainMenu.Register.pas index aa7c6f0..d5e88c7 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.Register.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.Register.pas @@ -39,7 +39,7 @@ procedure RegisterSelf; begin DelphiAIDevIDEMainMenuRegister := TDelphiAIDevIDEMainMenuRegister.Create; - if(Supports(TObject(DelphiAIDevIDEMainMenuRegister), IOTAWizard, LIOTAWizard))then + if Supports(TObject(DelphiAIDevIDEMainMenuRegister), IOTAWizard, LIOTAWizard) then IndexPlugin := TUtilsOTA.GetIOTAWizardServices.AddWizard(LIOTAWizard); end; diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.pas b/Src/MainMenu/DelphiAIDev.MainMenu.pas index b8f0d67..8c914a3 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.pas @@ -39,7 +39,7 @@ implementation class function TDelphiAIDevIDEMainMenu.GetInstance: IDelphiAIDevIDEMainMenu; begin - if(not Assigned(Instance))then + if not Assigned(Instance) then Instance := Self.Create; Result := Instance; end; @@ -51,7 +51,7 @@ constructor TDelphiAIDevIDEMainMenu.Create; destructor TDelphiAIDevIDEMainMenu.Destroy; begin - if(Assigned(FMenuItemC4D))then + if Assigned(FMenuItemC4D) then FreeAndNil(FMenuItemC4D); inherited; end; @@ -105,7 +105,7 @@ procedure TDelphiAIDevIDEMainMenu.CreateMenuDelphiAIDeveloperInIDEMenu; LMenuItemTools: TMenuItem; begin FMenuItemC4D := TMenuItem(FMainMenuIDE.FindComponent(TConsts.ITEM_MENU_C4DDelphiAIDev_NAME)); - if(Assigned(FMenuItemC4D))then + if Assigned(FMenuItemC4D) then FreeAndNil(FMenuItemC4D); FMenuItemC4D := TMenuItem.Create(FMainMenuIDE); @@ -113,14 +113,14 @@ procedure TDelphiAIDevIDEMainMenu.CreateMenuDelphiAIDeveloperInIDEMenu; FMenuItemC4D.Caption := TConsts.ITEM_MENU_C4DDelphiAIDev_CAPTION; LMenuItemTabs := FMainMenuIDE.Items.Find('Tabs'); - if(Assigned(LMenuItemTabs))then + if Assigned(LMenuItemTabs) then begin FMainMenuIDE.Items.Insert(FMainMenuIDE.Items.IndexOf(LMenuItemTabs), FMenuItemC4D); Exit; end; LMenuItemTools := FMainMenuIDE.Items.Find('Tools'); - if(Assigned(LMenuItemTools))then + if Assigned(LMenuItemTools) then begin FMainMenuIDE.Items.Insert(FMainMenuIDE.Items.IndexOf(LMenuItemTools) + 1, FMenuItemC4D); Exit; @@ -151,7 +151,7 @@ function TDelphiAIDevIDEMainMenu.GetShortCutStrChat: string; initialization finalization - if(Assigned(Instance))then + if Assigned(Instance) then Instance := nil; end. diff --git a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.Item.pas b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.Item.pas index 3e25030..2e3857b 100644 --- a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.Item.pas +++ b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.Item.pas @@ -66,7 +66,7 @@ constructor TDelphiAIDevPopupMenuProjectsItem.Create(OnExecute: TC4DWizardMenuCo procedure TDelphiAIDevPopupMenuProjectsItem.Execute(const MenuContextList: IInterfaceList); begin - if(Assigned(FOnExecute))then + if Assigned(FOnExecute) then FOnExecute(MenuContextList); end; diff --git a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas index a5d0799..4c3bc17 100644 --- a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas +++ b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas @@ -7,7 +7,7 @@ interface System.Classes, ToolsAPI, DelphiAIDev.Types, - DelphiAIDev.PopupMenuProjects.Item; + DelphiAIDev.PopupMenuProjects.Item; type TC4DWizardIDEPopupMenuNotifier = class(TNotifierObject, IOTAProjectMenuItemCreatorNotifier) @@ -15,14 +15,13 @@ TC4DWizardIDEPopupMenuNotifier = class(TNotifierObject, IOTAProjectMenuItemCre FProject: IOTAProject; FPosition: Integer; function AddItemInMenu(const ACaption: string): IOTAProjectManagerMenu; - function AddSubItemInMenu(const ACaption: string; - const AOnExecute: TC4DWizardMenuContextList = nil; + function AddSubItemInMenu(const ACaption: string; const AOnExecute: TC4DWizardMenuContextList = nil; const AChecked: Boolean = False): IOTAProjectManagerMenu; procedure CheckFileNameProject; - //function GetReopenDataOfFileName: TC4DWizardReopenData; procedure OnExecuteEditInformations(const MenuContextList: IInterfaceList); protected - procedure AddMenu(const Project: IOTAProject; const IdentList: TStrings; const ProjectManagerMenuList: IInterfaceList; IsMultiSelect: Boolean); + procedure AddMenu(const Project: IOTAProject; const IdentList: TStrings; + const ProjectManagerMenuList: IInterfaceList; IsMultiSelect: Boolean); public class function New: IOTAProjectMenuItemCreatorNotifier; end; @@ -51,14 +50,15 @@ class function TC4DWizardIDEPopupMenuNotifier.New: IOTAProjectMenuItemCreatorNot Result := Self.Create; end; -procedure TC4DWizardIDEPopupMenuNotifier.AddMenu(const Project: IOTAProject; const IdentList: TStrings; const ProjectManagerMenuList: IInterfaceList; IsMultiSelect: Boolean); +procedure TC4DWizardIDEPopupMenuNotifier.AddMenu(const Project: IOTAProject; const IdentList: TStrings; + const ProjectManagerMenuList: IInterfaceList; IsMultiSelect: Boolean); begin - if(not Assigned(ProjectManagerMenuList))then + if not Assigned(ProjectManagerMenuList) then Exit; - if(IdentList.IndexOf(sProjectContainer) >= 0)then + if IdentList.IndexOf(sProjectContainer) >= 0 then FPosition := pmmpUninstall - else if(IdentList.IndexOf(sProjectGroupContainer) >= 0)then + else if IdentList.IndexOf(sProjectGroupContainer) >= 0 then FPosition := pmmpRename else Exit; @@ -90,8 +90,7 @@ function TC4DWizardIDEPopupMenuNotifier.AddItemInMenu(const ACaption: string): I end; function TC4DWizardIDEPopupMenuNotifier.AddSubItemInMenu(const ACaption: string; - const AOnExecute: TC4DWizardMenuContextList = nil; - const AChecked: Boolean = False): IOTAProjectManagerMenu; + const AOnExecute: TC4DWizardMenuContextList = nil; const AChecked: Boolean = False): IOTAProjectManagerMenu; begin Result := TDelphiAIDevPopupMenuProjectsItem.New(AOnExecute); Result.Caption := ACaption; @@ -104,10 +103,10 @@ function TC4DWizardIDEPopupMenuNotifier.AddSubItemInMenu(const ACaption: string; procedure TC4DWizardIDEPopupMenuNotifier.CheckFileNameProject; begin - if(FProject.FileName.Trim.IsEmpty)then + if FProject.FileName.Trim.IsEmpty then TUtils.ShowMsgAndAbort('File name is empty'); - if(not System.SysUtils.FileExists(FProject.FileName))then + if not System.SysUtils.FileExists(FProject.FileName) then TUtils.ShowMsgAndAbort('File not found'); end; diff --git a/Src/Settings/DelphiAIDev.Settings.View.pas b/Src/Settings/DelphiAIDev.Settings.View.pas index 750d25a..55dcac7 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.pas +++ b/Src/Settings/DelphiAIDev.Settings.View.pas @@ -327,7 +327,7 @@ procedure TDelphiAIDevSettingsView.lbOpenDataFolderClick(Sender: TObject); LPathFolder: string; begin LPathFolder := TUtils.GetPathFolderRoot; - if(not DirectoryExists(LPathFolder))then + if not DirectoryExists(LPathFolder) then TUtils.ShowMsg('Forder not found: ' + LPathFolder); TUtils.OpenFolder(LPathFolder); diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index 65a9546..9f770e6 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -187,23 +187,23 @@ function TC4DExtensionsOfFilesHelper.ContainsStr(const AExtension: string): Bool begin Result := False; LExtension := AExtension.Trim.ToLower; - if(LExtension = '.pas')then + if LExtension = '.pas' then Result := TC4DExtensionsFiles.PAS in Self - else if(LExtension = '.dfm')then + else if LExtension = '.dfm' then Result := TC4DExtensionsFiles.DFM in Self - else if(LExtension = '.fmx')then + else if LExtension = '.fmx' then Result := TC4DExtensionsFiles.FMX in Self - else if(LExtension = '.dpr')then + else if LExtension = '.dpr' then Result := TC4DExtensionsFiles.DPR in Self - else if(LExtension = '.dpk')then + else if LExtension = '.dpk' then Result := TC4DExtensionsFiles.DPK in Self - else if(LExtension = '.dproj')then + else if LExtension = '.dproj' then Result := TC4DExtensionsFiles.DPROJ in Self - else if(LExtension = '.zip')then + else if LExtension = '.zip' then Result := TC4DExtensionsFiles.ZIP in Self - else if(LExtension = '.bmp')then + else if LExtension = '.bmp' then Result := TC4DExtensionsFiles.BMP in Self - else if(LExtension = '.ini')then + else if LExtension = '.ini' then Result := TC4DExtensionsFiles.INI in Self; end; diff --git a/Src/Utils/DelphiAIDev.Utils.ABMenuAction.pas b/Src/Utils/DelphiAIDev.Utils.ABMenuAction.pas index 4e4a820..46f533a 100644 --- a/Src/Utils/DelphiAIDev.Utils.ABMenuAction.pas +++ b/Src/Utils/DelphiAIDev.Utils.ABMenuAction.pas @@ -28,23 +28,23 @@ implementation function GetMenuItemOfSender(Sender: TObject): TMenuItem; begin Result := nil; - if(Sender.ClassType.ClassName = TMenuItem.ClassName)then + if Sender.ClassType.ClassName = TMenuItem.ClassName then Result := TMenuItem(Sender) - else if(Sender.ClassType.ClassName = TABMenuAction.ClassName)then + else if Sender.ClassType.ClassName = TABMenuAction.ClassName then Result := TABMenuAction(Sender).MenuItem end; {TABMenuAction} destructor TABMenuAction.Destroy; begin - if(Assigned(FMenuItem))then + if Assigned(FMenuItem) then FMenuItem.RemoveFreeNotification(Self); inherited; end; procedure TABMenuAction.ExecuteTarget(Target: TObject); begin - if(Assigned(FMenuItem))then + if Assigned(FMenuItem) then FMenuItem.Click; end; @@ -55,7 +55,7 @@ function TABMenuAction.HandlesTarget(Target: TObject): Boolean; procedure TABMenuAction.Notification(AComponent: TComponent; Operation: TOperation); begin - if(Operation = opRemove) and (AComponent = FMenuItem)then + if (Operation = opRemove) and (AComponent = FMenuItem) then FMenuItem := nil; end; diff --git a/Src/Utils/DelphiAIDev.Utils.GetIniPositionStr.pas b/Src/Utils/DelphiAIDev.Utils.GetIniPositionStr.pas index 8b3bdc4..cc155cc 100644 --- a/Src/Utils/DelphiAIDev.Utils.GetIniPositionStr.pas +++ b/Src/Utils/DelphiAIDev.Utils.GetIniPositionStr.pas @@ -75,8 +75,8 @@ function TDelphiAIDevUtilsGetIniPositionStr.TextIgnore(Value: string): IDelphiAI //ESTA ROTINA CONFERE DE A LETRA ANTERIOR/POSTERIOR A PALAVRA FECHA COM VAZIO OU NÃO LETRA NEM NUMERO procedure TDelphiAIDevUtilsGetIniPositionStr.CheckWholeWord; begin - if((IfThen(FColCurrent = 0, '', Copy(FStrOriginal, FColCurrent - 1, 1)) <> '')and(Copy(FStrOriginal, FColCurrent - 1, 1)[1] in ['0'..'9', 'A'..'Z', 'a'..'z'])) - or((IfThen(FColCurrent = 0, '', Copy(FStrOriginal, FColCurrent + Length(FStrToLocate), 1)) <> '')and(Copy(FStrOriginal, FColCurrent + Length(FStrToLocate), 1)[1] in ['0'..'9', 'A'..'Z', 'a'..'z'])) + if ((IfThen(FColCurrent = 0, '', Copy(FStrOriginal, FColCurrent - 1, 1)) <> '') and (Copy(FStrOriginal, FColCurrent - 1, 1)[1] in ['0'..'9', 'A'..'Z', 'a'..'z'])) + or ((IfThen(FColCurrent = 0, '', Copy(FStrOriginal, FColCurrent + Length(FStrToLocate), 1)) <> '') and (Copy(FStrOriginal, FColCurrent + Length(FStrToLocate), 1)[1] in ['0'..'9', 'A'..'Z', 'a'..'z'])) then FFound := False; end; @@ -89,13 +89,13 @@ function TDelphiAIDevUtilsGetIniPositionStr.GetWholeWord: string; LChar: Char; begin Result := ''; - if(FStrToLocate = ' ')then + if FStrToLocate = ' ' then Exit; Result := FStrOriginal[FColCurrent]; LColIni := FColCurrent; - if(LColIni > 0)then + if LColIni > 0 then begin Dec(LColIni); LChar := FStrOriginal[LColIni]; @@ -109,7 +109,7 @@ function TDelphiAIDevUtilsGetIniPositionStr.GetWholeWord: string; LColEnd := FColCurrent; LLastColLine := FStrOriginal.Length; - if(LColEnd < LLastColLine)then + if LColEnd < LLastColLine then begin Inc(LColEnd); LChar := FStrOriginal[LColEnd]; @@ -127,21 +127,21 @@ procedure TDelphiAIDevUtilsGetIniPositionStr.CheckWordIgnore; LStrValidate: string; LStrIgnore: string; begin - if(FTextIgnore.Trim.IsEmpty)then + if FTextIgnore.Trim.IsEmpty then Exit; LStrValidate := Self.GetWholeWord; - if(LStrValidate.Trim.IsEmpty)then + if LStrValidate.Trim.IsEmpty then Exit; LStrIgnore := FTextIgnore; - if(not FCaseSensitive)then + if not FCaseSensitive then begin LStrValidate := LStrValidate.ToLower; LStrIgnore := LStrIgnore.ToLower; end; - if(LStrValidate.Contains(LStrIgnore))then + if LStrValidate.Contains(LStrIgnore) then FFound := False; end; @@ -157,21 +157,21 @@ function TDelphiAIDevUtilsGetIniPositionStr.GetInitialPosition(const AStrOrigina begin FColCurrent := LColCurrent; - if(FCaseSensitive)then + if FCaseSensitive then FFound := FStrToLocate = Copy(FStrOriginal, FColCurrent, Length(FStrToLocate)) else FFound := AnsiUpperCase(FStrToLocate) = AnsiUpperCase(Copy(FStrOriginal, FColCurrent, Length(FStrToLocate))); - if(FFound)and(FWholeWordOnly)then + if (FFound) and (FWholeWordOnly) then Self.CheckWholeWord; - if(FFound)then + if FFound then Self.CheckWordIgnore; - if(FFound)then + if FFound then begin Result := FColCurrent - 1; - if(Result < 0)then + if Result < 0 then Result := 0; Break; end; diff --git a/Src/Utils/DelphiAIDev.Utils.ListView.pas b/Src/Utils/DelphiAIDev.Utils.ListView.pas index 375e1b0..5ec432b 100644 --- a/Src/Utils/DelphiAIDev.Utils.ListView.pas +++ b/Src/Utils/DelphiAIDev.Utils.ListView.pas @@ -73,18 +73,18 @@ function IsValidDate(Astring: string; var ADateTime: TDateTime): Boolean; function CompareDates(dt1, dt2: TDateTime): Integer; begin Result := -1; - if(dt1 > dt2)then + if dt1 > dt2 then Result := 1 - else if(dt1 = dt2)then + else if dt1 = dt2 then Result := 0; end; function CompareNumeric(AInt1, AInt2: Integer): Integer; begin Result := -1; - if(AInt1 > AInt2)then + if AInt1 > AInt2 then Result := 1 - else if(AInt1 = AInt2)then + else if AInt1 = AInt2 then Result := 0; end; {$ENDREGION} @@ -101,11 +101,11 @@ procedure TDelphiAIDevUtilsListView.FindAndSelectItems(const AStrFind: string; LStrSource: string; LStrFind: string; begin - if(FListView.Items.Count <= 0)then + if FListView.Items.Count <= 0 then Exit; LStrFind := AStrFind.ToLower; - if(LStrFind.Trim.IsEmpty)then + if LStrFind.Trim.IsEmpty then Exit; LUtilsGetIniPositionStr := TDelphiAIDevUtilsGetIniPositionStr.New @@ -113,20 +113,20 @@ procedure TDelphiAIDevUtilsListView.FindAndSelectItems(const AStrFind: string; .CaseSensitive(False); LIndexCurrent := 0; - if(FListView.Selected <> nil)then + if FListView.Selected <> nil then LIndexCurrent := FListView.Selected.Index + 1; for i := LIndexCurrent to Pred(FListView.Items.Count) do begin LListItem := FListView.Items[i]; - if(ANumColumn = 0)then + if ANumColumn = 0 then LStrSource := LowerCase(LListItem.Caption) - else if(ANumColumn > 0)then + else if ANumColumn > 0 then LStrSource := LowerCase(LListItem.SubItems[Pred(ANumColumn)]); LColIni := 0; LColIni := LUtilsGetIniPositionStr.GetInitialPosition(LStrSource, LStrFind, LColIni); - if(LColIni > -1)then + if LColIni > -1 then begin FListView.Selected := LListItem; LListItem.MakeVisible(False); @@ -134,9 +134,9 @@ procedure TDelphiAIDevUtilsListView.FindAndSelectItems(const AStrFind: string; end; end; - if(AAutoRestart)then + if AAutoRestart then begin - if(FListView.Items.Count > 0)then + if FListView.Items.Count > 0 then FListView.Items.Item[0].Selected := True; Self.FindAndSelectItems(AStrFind, ANumColumn, False); end; @@ -147,19 +147,19 @@ procedure TDelphiAIDevUtilsListView.CopyIndexListView(const AIndexSubItem: Integ LListItemSel: TListItem; LStrCopy: string; begin - if(AIndexSubItem < -1)then + if AIndexSubItem < -1 then Exit; - if(FListView.Selected = nil)then + if FListView.Selected = nil then Exit; LListItemSel := FListView.Items[FListView.Selected.Index]; - if(AIndexSubItem = -1)then + if AIndexSubItem = -1 then LStrCopy := LListItemSel.Caption else LStrCopy := LListItemSel.SubItems[AIndexSubItem]; - if(not LStrCopy.Trim.IsEmpty)then + if not LStrCopy.Trim.IsEmpty then Clipboard.AsText := LStrCopy; end; @@ -171,41 +171,39 @@ function ListViewCustomSortProc(Item1, Item2: TListItem; SortColumn: Integer): I LDhItem1, LDhItem2: TDateTime; begin Result := 0; - if(Item1 = nil)or(Item2 = nil)then + if (Item1 = nil) or (Item2 = nil) then Exit; - case(SortColumn)of + case SortColumn of -1: //COMPARE CAPTIONS begin LStrItem1 := Item1.Caption; LStrItem2 := Item2.Caption; end; - else //COMPARE SUBITEMS + else //COMPARE SUBITEMS LStrItem1 := ''; LStrItem2 := ''; //CHECK RANGE - if(SortColumn < Item1.SubItems.Count)then + if SortColumn < Item1.SubItems.Count then LStrItem1 := Item1.SubItems[SortColumn]; - if(SortColumn < Item2.SubItems.Count)then + if SortColumn < Item2.SubItems.Count then LStrItem2 := Item2.SubItems[SortColumn] end; //SORT STYLES - case(TDelphiAIDevUtilsListView.FSortStyle)of + case TDelphiAIDevUtilsListView.FSortStyle of TDelphiAIDevUtilsListViewSortStyle.AlphaNum: - begin Result := lstrcmp(PChar(LStrItem1), PChar(LStrItem2)); - end; TDelphiAIDevUtilsListViewSortStyle.Numeric: begin LValidItem1 := IsValidNumber(LStrItem1, LIntItem1); LValidItem2 := IsValidNumber(LStrItem2, LIntItem2); Result := ord(LValidItem1 or LValidItem2); - if(Result <> 0)then + if Result <> 0 then begin - if(LIntItem1 = 0)then + if LIntItem1 = 0 then LIntItem1 := 99999999; - if(LIntItem2 = 0)then + if LIntItem2 = 0 then LIntItem2 := 99999999; Result := CompareNumeric(LIntItem2, LIntItem1); end; @@ -215,13 +213,13 @@ function ListViewCustomSortProc(Item1, Item2: TListItem; SortColumn: Integer): I LValidItem1 := IsValidDate(LStrItem1, LDhItem1); LValidItem2 := IsValidDate(LStrItem2, LDhItem2); Result := ord(LValidItem1 or LValidItem2); - if(Result <> 0)then + if Result <> 0 then Result := CompareDates(LDhItem1, LDhItem2); end; end; //SORT DIRECTION - if(not TDelphiAIDevUtilsListView.FSortOrder[SortColumn + 1])then + if not TDelphiAIDevUtilsListView.FSortOrder[SortColumn + 1] then Result := - Result; end; @@ -262,7 +260,7 @@ function TDelphiAIDevUtilsListView.ColumnIndex(const AColumnIndex: Integer): IDe procedure TDelphiAIDevUtilsListView.CustomSort; begin - if(FInvertOrder)then + if FInvertOrder then FSortOrder[FColumnIndex] := not FSortOrder[FColumnIndex]; FListView.CustomSort(@ListViewCustomSortProc, FColumnIndex -1); end; diff --git a/Src/Utils/DelphiAIDev.Utils.OTA.pas b/Src/Utils/DelphiAIDev.Utils.OTA.pas index b1d3f04..9b3096a 100644 --- a/Src/Utils/DelphiAIDev.Utils.OTA.pas +++ b/Src/Utils/DelphiAIDev.Utils.OTA.pas @@ -95,7 +95,7 @@ class function TUtilsOTA.CurrentProjectIsDelphiAIDeveloperDPROJ: Boolean; Result := False; LIOTAProject := Self.GetCurrentProject; - if(LIOTAProject = nil)then + if LIOTAProject = nil then Exit; Result := TUtils.FileNameIsDelphiAIDeveloperDPROJ(LIOTAProject.FileName); @@ -108,7 +108,7 @@ class function TUtilsOTA.CurrentModuleIsReadOnly: Boolean; Result := False; LIOTAEditBuffer := Self.GetIOTAEditBufferCurrentModule; - if(LIOTAEditBuffer = nil)then + if LIOTAEditBuffer = nil then Exit; Result := LIOTAEditBuffer.IsReadOnly; @@ -140,7 +140,7 @@ class function TUtilsOTA.AddImgIDEResourceName(AResourceName: string): Integer; LMaskColor: TColor; begin Result := -1; - if(FindResource(hInstance, PChar(AResourceName), RT_BITMAP) <= 0)then + if FindResource(hInstance, PChar(AResourceName), RT_BITMAP) <= 0 then Exit; LBitmap := TBitmap.Create; @@ -248,7 +248,7 @@ class procedure TUtilsOTA.DeleteBlockTextSelectedInEditor; begin LIOTAEditorServices := Self.GetIOTAEditorServices; LIOTAEditView := LIOTAEditorServices.TopView; - if(LIOTAEditView = nil)then + if LIOTAEditView = nil then TUtils.ShowMsgAndAbort('No projects or files selected'); LIOTAEditBlock := LIOTAEditView.Block; @@ -295,7 +295,7 @@ class function TUtilsOTA.GetBlockTextSelect: string; begin Result := ''; LIOTAEditorServices := Self.GetIOTAEditorServices; - if(LIOTAEditorServices.TopView <> nil)then + if LIOTAEditorServices.TopView <> nil then Result := LIOTAEditorServices.TopView.GetBlock.Text; end; @@ -308,10 +308,10 @@ class function TUtilsOTA.GetSelectedBlockOrAllCodeUnit: string; class procedure TUtilsOTA.OpenFilePathInIDE(AFilePath: string); begin - if(not FileExists(AFilePath))then + if not FileExists(AFilePath) then Exit; - if(TUtils.IsProject(AFilePath))then + if TUtils.IsProject(AFilePath) then Self.GetIOTAActionServices.OpenProject(AFilePath, True) else Self.GetIOTAActionServices.OpenFile(AFilePath); @@ -328,7 +328,7 @@ class function TUtilsOTA.RefreshProject: Boolean; begin Result := True; LIOTAProject := GetCurrentProject; - if(LIOTAProject = nil)then + if LIOTAProject = nil then Exit(False); LIOTAProject.Refresh(False); end; @@ -339,14 +339,14 @@ class function TUtilsOTA.RefreshModule: Boolean; begin Result := True; LIOTAModule := GetCurrentModule; - if(LIOTAModule = nil)then + if LIOTAModule = nil then Exit(False); LIOTAModule.Refresh(False); end; class procedure TUtilsOTA.RefreshProjectOrModule; begin - if(not Self.RefreshProject)then + if not Self.RefreshProject then Self.RefreshModule; end; @@ -358,7 +358,7 @@ class function TUtilsOTA.FileIsOpenInIDE(const APathFile: string): Boolean; i: Integer; begin Result := False; - if(APathFile.Trim.IsEmpty)then + if APathFile.Trim.IsEmpty then Exit; LIOTAModuleServices := Self.GetIOTAModuleServices; @@ -374,7 +374,7 @@ class function TUtilsOTA.FileIsOpenInIDE(const APathFile: string): Boolean; Continue; Result := SameFileName(APathFile, LIOTAModule.FileName); - if(Result)then + if Result then Exit; end; end; @@ -384,27 +384,27 @@ class function TUtilsOTA.CheckIfExistFileInCurrentsProjectGroups(const ANameFile LIOTAModuleServices: IOTAModuleServices; LIOTAModuleCurrent: IOTAModule; LOTAProjectGroup: IOTAProjectGroup; - LIOTAProjectCurrent: IOTAProject; LContModule: Integer; + LIOTAProjectCurrent: IOTAProject; LContProject: Integer; LContFile: Integer; LFilePath: string; begin Result := False; LIOTAModuleServices := Self.GetIOTAModuleServices; - if(LIOTAModuleServices = nil)then + if LIOTAModuleServices = nil then Exit; - if(LIOTAModuleServices.ModuleCount = 0)then + if LIOTAModuleServices.ModuleCount = 0 then Exit; for LContModule := 0 to Pred(LIOTAModuleServices.ModuleCount) do begin LIOTAModuleCurrent := LIOTAModuleServices.Modules[LContModule]; - if(ExtractFileName(LIOTAModuleCurrent.FileName) = ANameFileWithExtension)then + if ExtractFileName(LIOTAModuleCurrent.FileName) = ANameFileWithExtension then Exit(True); - if(Supports(LIOTAModuleCurrent, IOTAProjectGroup, LOTAProjectGroup))then + if Supports(LIOTAModuleCurrent, IOTAProjectGroup, LOTAProjectGroup) then begin for LContProject := 0 to Pred(LOTAProjectGroup.ProjectCount) do begin @@ -415,7 +415,7 @@ class function TUtilsOTA.CheckIfExistFileInCurrentsProjectGroups(const ANameFile if LFilePath.Trim.IsEmpty then Continue; - if(ExtractFileName(LFilePath) = ANameFileWithExtension)then + if ExtractFileName(LFilePath) = ANameFileWithExtension then Exit(True); end; end; @@ -440,7 +440,7 @@ class procedure TUtilsOTA.IDEThemingAll(AFormClass: TCustomFormClass; AForm: TFo for i := 0 to Pred(AForm.ComponentCount) do begin - if(AForm.Components[i] is TPanel)then + if AForm.Components[i] is TPanel then TPanel(AForm.Components[i]).ParentBackground := True; LIOTAIDEThemingServices250.ApplyTheme(AForm.Components[i]); @@ -481,14 +481,14 @@ class function TUtilsOTA.GetIOTAFormEditor(const AIOTAModule: IOTAModule): IOTAF LIOTAFormEditor: IOTAFormEditor; begin Result := nil; - if(not Assigned(AIOTAModule))then + if not Assigned(AIOTAModule) then Exit; for i := 0 to Pred(AIOTAModule.GetModuleFileCount) do begin LIOTAEditor := AIOTAModule.GetModuleFileEditor(i); - if(Supports(LIOTAEditor, IOTAFormEditor, LIOTAFormEditor))then + if Supports(LIOTAEditor, IOTAFormEditor, LIOTAFormEditor) then begin Result := LIOTAFormEditor; Break; @@ -499,26 +499,26 @@ class function TUtilsOTA.GetIOTAFormEditor(const AIOTAModule: IOTAModule): IOTAF {$IF CompilerVersion >= 32.0} //Tokyo class function TUtilsOTA.GetIOTAIDEThemingServices: IOTAIDEThemingServices; begin - if(not Supports(BorlandIDEServices, IOTAIDEThemingServices, Result))then + if not Supports(BorlandIDEServices, IOTAIDEThemingServices, Result) then raise Exception.Create('Interface not supported: IOTAIDEThemingServices'); end; class function TUtilsOTA.GetIOTAIDEThemingServices250: IOTAIDEThemingServices250; begin - if(not Supports(BorlandIDEServices, IOTAIDEThemingServices250, Result))then + if not Supports(BorlandIDEServices, IOTAIDEThemingServices250, Result) then raise Exception.Create('Interface not supported: IOTAIDEThemingServices250'); end; {$ENDIF} class function TUtilsOTA.GetIOTACompileServices: IOTACompileServices; begin - if(not Supports(BorlandIDEServices, IOTACompileServices, Result))then + if not Supports(BorlandIDEServices, IOTACompileServices, Result) then raise Exception.Create('Interface not supported: IOTACompileServices'); end; class function TUtilsOTA.GetIOTAWizardServices: IOTAWizardServices; begin - if(not Supports(BorlandIDEServices, IOTAWizardServices, Result))then + if not Supports(BorlandIDEServices, IOTAWizardServices, Result) then raise Exception.Create('Interface not supported: IOTAWizardServices'); end; @@ -528,11 +528,11 @@ class function TUtilsOTA.GetIOTAEditView(AIOTAModule: IOTAModule): IOTAEditView; LIOTAEditView: IOTAEditView; begin LIOTASourceEditor := Self.GetIOTASourceEditor(AIOTAModule); - if(LIOTASourceEditor = nil)then + if LIOTASourceEditor = nil then Exit; LIOTAEditView := Self.GetIOTAEditView(LIOTASourceEditor); - if(LIOTAEditView = nil)then + if LIOTAEditView = nil then Exit; //LIOTASourceEditor.Show; Result := LIOTAEditView; @@ -544,10 +544,10 @@ class function TUtilsOTA.GetIOTAEditView(AIOTASourceEditor: IOTASourceEditor): I begin Result := nil; - if(not Supports(AIOTASourceEditor, IOTAEditBuffer, LIOTAEditBuffer))then + if not Supports(AIOTASourceEditor, IOTAEditBuffer, LIOTAEditBuffer) then raise Exception.Create('Interface not supported: IOTAEditBuffer'); - if(LIOTAEditBuffer <> nil)then + if LIOTAEditBuffer <> nil then Result := LIOTAEditBuffer.TopView else if AIOTASourceEditor.EditViewCount > 0 then Result := AIOTASourceEditor.EditViews[0]; @@ -562,7 +562,7 @@ class function TUtilsOTA.GetIOTASourceEditor(AIOTAModule: IOTAModule): IOTASourc LIOTAModule := AIOTAModule; for i := 0 to Pred(LIOTAModule.ModuleFileCount) do begin - if(LIOTAModule.ModuleFileEditors[i].QueryInterface(IOTASourceEditor, Result) = S_OK)then + if LIOTAModule.ModuleFileEditors[i].QueryInterface(IOTASourceEditor, Result) = S_OK then Break; end; end; @@ -570,7 +570,7 @@ class function TUtilsOTA.GetIOTASourceEditor(AIOTAModule: IOTAModule): IOTASourc class function TUtilsOTA.GetIOTASourceEditor(AIOTAEditor: IOTAEditor): IOTASourceEditor; begin Result := nil; - if(not Supports(AIOTAEditor, IOTASourceEditor, Result))then + if not Supports(AIOTAEditor, IOTASourceEditor, Result) then raise Exception.Create('Interface not supported: IOTASourceEditor'); end; @@ -596,7 +596,7 @@ class function TUtilsOTA.GetIOTASourceEditor(AIOTAModule: IOTAModule; const AFil end; end; begin - if(not Assigned(AIOTAModule))then + if not Assigned(AIOTAModule) then begin Result := nil; Exit; @@ -605,11 +605,11 @@ class function TUtilsOTA.GetIOTASourceEditor(AIOTAModule: IOTAModule; const AFil for i := 0 to Pred(AIOTAModule.GetModuleFileCount) do begin LIOTAEditor := GetFileEditorForModule(AIOTAModule, i); - if(Supports(LIOTAEditor, IOTASourceEditor, LIOTASourceEditor))then + if Supports(LIOTAEditor, IOTASourceEditor, LIOTASourceEditor) then begin - if(Assigned(LIOTASourceEditor))then + if Assigned(LIOTASourceEditor) then begin - if(AFileName = '')or(SameFileName(LIOTASourceEditor.FileName, AFileName))then + if (AFileName = '') or (SameFileName(LIOTASourceEditor.FileName, AFileName)) then begin Result := LIOTASourceEditor; Exit; @@ -627,7 +627,7 @@ class function TUtilsOTA.GetIOTAEditBufferCurrentModule: IOTAEditBuffer; Result := nil; LIOTAModule := Self.GetCurrentModule; - if(LIOTAModule = nil)then + if LIOTAModule = nil then Exit; Result := TUtilsOTA.GetIOTAEditBuffer(LIOTAModule); @@ -639,58 +639,58 @@ class function TUtilsOTA.GetIOTAEditBuffer(AIOTAModule: IOTAModule): IOTAEditBuf begin Result := nil; LIOTASourceEditor := Self.GetIOTASourceEditor(AIOTAModule); - if(LIOTASourceEditor = nil)then + if LIOTASourceEditor = nil then Exit; - if(not Supports(LIOTASourceEditor, IOTAEditBuffer, Result))then + if not Supports(LIOTASourceEditor, IOTAEditBuffer, Result) then raise Exception.Create('Interface not supported: IOTAEditBuffer'); end; class function TUtilsOTA.GetIOTAMessageServices: IOTAMessageServices; begin - if(not Supports(BorlandIDEServices, IOTAMessageServices, Result))then + if not Supports(BorlandIDEServices, IOTAMessageServices, Result) then raise Exception.Create('Interface not supported: IOTAMessageServices'); end; class function TUtilsOTA.GetIOTAProjectManager: IOTAProjectManager; begin - if(not Supports(BorlandIDEServices, IOTAProjectManager, Result))then + if not Supports(BorlandIDEServices, IOTAProjectManager, Result) then raise Exception.Create('Interface not supported: IOTAProjectManager'); end; class function TUtilsOTA.GetIOTAKeyboardServices: IOTAKeyboardServices; begin - if(not Supports(BorlandIDEServices, IOTAKeyboardServices, Result))then + if not Supports(BorlandIDEServices, IOTAKeyboardServices, Result) then raise Exception.Create('Interface not supported: IOTAKeyboardServices'); end; class function TUtilsOTA.GetIOTAServices: IOTAServices; begin - if(not Supports(BorlandIDEServices, IOTAServices, Result))then + if not Supports(BorlandIDEServices, IOTAServices, Result) then raise Exception.Create('Interface not supported: IOTAServices'); end; class function TUtilsOTA.GetIOTAActionServices: IOTAActionServices; begin - if(not Supports(BorlandIDEServices, IOTAActionServices, Result))then + if not Supports(BorlandIDEServices, IOTAActionServices, Result) then raise Exception.Create('Interface not supported: IOTAActionServices'); end; class function TUtilsOTA.GetINTAServices: INTAServices; begin - if(not Supports(BorlandIDEServices, INTAServices, Result))then + if not Supports(BorlandIDEServices, INTAServices, Result) then raise Exception.Create('Interface not supported: INTAServices'); end; class function TUtilsOTA.GetIOTAModuleServices: IOTAModuleServices; begin - if(not Supports(BorlandIDEServices, IOTAModuleServices, Result))then + if not Supports(BorlandIDEServices, IOTAModuleServices, Result) then raise Exception.Create('Interface not supported: IOTAModuleServices'); end; class function TUtilsOTA.GetIOTAEditorServices: IOTAEditorServices; begin - if(not Supports(BorlandIDEServices, IOTAEditorServices, Result))then + if not Supports(BorlandIDEServices, IOTAEditorServices, Result) then raise Exception.Create('Interface not supported: IOTAEditorServices'); end; @@ -735,7 +735,7 @@ class function TUtilsOTA.GetCurrentProject: IOTAProject; begin Result := nil; LIOTAProjectGroup := Self.GetCurrentProjectGroup; - if(not Assigned(LIOTAProjectGroup))then + if not Assigned(LIOTAProjectGroup) then Exit; try @@ -751,7 +751,7 @@ class function TUtilsOTA.GetCurrentProjectFileName: string; begin Result := ''; LIOTAProject := Self.GetCurrentProject; - if(Assigned(LIOTAProject))then + if Assigned(LIOTAProject) then Result := LIOTAProject.FileName.Trim; end; @@ -764,7 +764,7 @@ class function TUtilsOTA.GetProjectName(const AIOTAProject: IOTAProject): string for i := 0 to Pred(AIOTAProject.ModuleFileCount) do begin LExt := LowerCase(ExtractFileExt(AIOTAProject.ModuleFileEditors[i].FileName)); - if(LExt = TC4DExtensionsFiles.DPR.ToString)or(LExt = TC4DExtensionsFiles.DPK.ToString) Then + if (LExt = TC4DExtensionsFiles.DPR.ToString) or (LExt = TC4DExtensionsFiles.DPK.ToString) Then begin Result := ChangeFileExt(Result, LExt); Break; @@ -787,7 +787,7 @@ class function TUtilsOTA.GetFileNameDprOrDpkIfDproj(const AIOTAModule: IOTAModul LFileName := AIOTAModule.ModuleFileEditors[i].FileName; LExt := ExtractFileExt(LFileName); - if(LExt = TC4DExtensionsFiles.DPR.ToStringWithPoint)or(LExt = TC4DExtensionsFiles.DPK.ToStringWithPoint)then + if (LExt = TC4DExtensionsFiles.DPR.ToStringWithPoint) or (LExt = TC4DExtensionsFiles.DPK.ToStringWithPoint) then Result := LFileName; end; end; @@ -799,7 +799,7 @@ class function TUtilsOTA.GetCurrentProjectOptions: IOTAProjectOptions; begin Result := nil; LIOTAProject := Self.GetCurrentProject; - if(LIOTAProject = nil)then + if LIOTAProject = nil then Exit; Result := LIOTAProject.ProjectOptions; @@ -810,7 +810,7 @@ class function TUtilsOTA.GetCurrentOutputDir: string; LIOTAProjectOptions: IOTAProjectOptions; begin LIOTAProjectOptions := Self.GetCurrentProjectOptions; - if(LIOTAProjectOptions = nil)then + if LIOTAProjectOptions = nil then Exit; Result := VarToStr(LIOTAProjectOptions.Values['OutputDir']); @@ -821,8 +821,8 @@ class function TUtilsOTA.GetCurrentProjectOptionsConfigurations: IOTAProjectOpti LIOTAProjectOptions: IOTAProjectOptions; begin LIOTAProjectOptions := Self.GetCurrentProjectOptions; - if(LIOTAProjectOptions <> nil)then - if(Supports(LIOTAProjectOptions, IOTAProjectOptionsConfigurations, Result))then + if LIOTAProjectOptions <> nil then + if Supports(LIOTAProjectOptions, IOTAProjectOptionsConfigurations, Result) then Exit; Result := nil; @@ -860,19 +860,19 @@ class procedure TUtilsOTA.GetAllFilesFromProjectGroup(AListFiles: TStrings; LFilterIsProject: Boolean; begin LIOTAModuleServices := Self.GetIOTAModuleServices; - if(LIOTAModuleServices = nil)then + if LIOTAModuleServices = nil then Exit; - if(LIOTAModuleServices.ModuleCount = 0)then + if LIOTAModuleServices.ModuleCount = 0 then Exit; LFilterIsProjectGroup := False; LFilterIsProject := False; - if(not AFilePathProjectOrGroupForFilter.Trim.IsEmpty)then + if not AFilePathProjectOrGroupForFilter.Trim.IsEmpty then begin - if(TUtils.IsProjectGroup(AFilePathProjectOrGroupForFilter))then + if TUtils.IsProjectGroup(AFilePathProjectOrGroupForFilter) then LFilterIsProjectGroup := True - else if(TUtils.IsProject(AFilePathProjectOrGroupForFilter)) + else if TUtils.IsProject(AFilePathProjectOrGroupForFilter) or(TUtils.IsDPROJ(AFilePathProjectOrGroupForFilter)) then LFilterIsProject := True; @@ -882,16 +882,16 @@ class procedure TUtilsOTA.GetAllFilesFromProjectGroup(AListFiles: TStrings; begin LIOTAModuleCurrent := LIOTAModuleServices.Modules[LContModule]; LFilePath := LIOTAModuleCurrent.FileName; - if(Supports(LIOTAModuleCurrent, IOTAProjectGroup, LOTAProjectGroup))then + if Supports(LIOTAModuleCurrent, IOTAProjectGroup, LOTAProjectGroup) then begin - if(LFilterIsProjectGroup)and(LFilePath <> AFilePathProjectOrGroupForFilter)then + if (LFilterIsProjectGroup) and (LFilePath <> AFilePathProjectOrGroupForFilter) then Continue; for LContProject := 0 to Pred(LOTAProjectGroup.ProjectCount) do begin LIOTAProjectCurrent := LOTAProjectGroup.Projects[LContProject]; - if(LFilterIsProject)and(LIOTAProjectCurrent.FileName <> AFilePathProjectOrGroupForFilter)then + if (LFilterIsProject) and (LIOTAProjectCurrent.FileName <> AFilePathProjectOrGroupForFilter) then Continue; for LContFile := 0 to Pred(LIOTAProjectCurrent.GetModuleCount) do @@ -900,7 +900,7 @@ class procedure TUtilsOTA.GetAllFilesFromProjectGroup(AListFiles: TStrings; if LFilePath.Trim.IsEmpty then Continue; - if(not AC4DExtensions.ContainsStr(ExtractFileExt(LFilePath)))then + if not AC4DExtensions.ContainsStr(ExtractFileExt(LFilePath)) then Continue; AListFiles.Add(LFilePath); diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 7ff04e1..9e70d19 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -425,7 +425,7 @@ class function TUtils.FileNameIsDelphiAIDeveloperDPROJ(const AFileName: string): class procedure TUtils.RemoveBlankSpaceInBegin(var AValue: string; const ACount: Integer); begin - if(ACount <= 0)then + if ACount <= 0 then Exit; if Trim(copy(AValue, 1, ACount)).IsEmpty then @@ -467,9 +467,9 @@ class procedure TUtils.ExplodeList(const AText, ASeparator: string; AStrings: TS I := 1; while(I <= LLengthText)do begin - if(Copy(LText, I, LLengthSeparator) = ASeparator)or(I = LLengthText)then + if (Copy(LText, I, LLengthSeparator) = ASeparator) or (I = LLengthText) then begin - if(I = LLengthText)then + if I = LLengthText then LItem := LItem + StringReplace(LText[I], ASeparator, '', [rfReplaceAll, rfIgnoreCase]); AStrings.Add(Trim(LItem)); @@ -492,7 +492,7 @@ class procedure TUtils.MemoVerticalCenter(AMemo: TMemo; ANumLines: Integer; ATex AMemo.Lines.Text := AText.Trim; LLinesCount := AMemo.Lines.Count; AMemo.ScrollBars := System.UITypes.TScrollStyle.ssVertical; - if(LLinesCount < ANumLines)then + if LLinesCount < ANumLines then begin AMemo.ScrollBars := System.UITypes.TScrollStyle.ssNone; AMemo.Lines.Clear; @@ -509,14 +509,14 @@ class function TUtils.StatusBarNumPanelDblClick(AStatusBar: TStatusBar): Integer LNumPanel: Integer; begin LNumPanel := 0; - if(not AStatusBar.SimplePanel)and(AStatusBar.Panels.Count > 0)then + if (not AStatusBar.SimplePanel) and (AStatusBar.Panels.Count > 0) then begin LPointMouse := AStatusBar.ScreenToClient(Mouse.CursorPos); LWidth := 0; for LNumPanel := 0 to AStatusBar.Panels.Count - 2 do begin LWidth := LWidth + AStatusBar.Panels[LNumPanel].Width; - if(LPointMouse.X <= LWidth)then + if LPointMouse.X <= LWidth then Break; end; end; @@ -536,7 +536,7 @@ class function TUtils.StrToBoolC4D(Value: string): Boolean; class function TUtils.RemoveCommentAfterTwoBars(Value: string): string; begin Result := Value; - if(Result.Contains('//'))then + if Result.Contains('//') then Result := Copy(Result, 1, (Pos('//', Result) - 1)); end; @@ -544,12 +544,12 @@ class procedure TUtils.FindListVewItem(AListView: TListView; AIndexSubItem: Inte var I: Integer; begin - if(AStrFind.Trim.IsEmpty)then + if AStrFind.Trim.IsEmpty then Exit; for I := 0 to Pred(AListView.Items.Count)do begin - if(AListView.Items[I].SubItems[AIndexSubItem] = AStrFind)then + if AListView.Items[I].SubItems[AIndexSubItem] = AStrFind then begin AListView.ItemIndex := I; AListView.SetFocus; @@ -601,23 +601,23 @@ class function TUtils.SelectFile(const ADefaultFile: string; const ADefaultExt: LOpenDialog := TOpenDialog.Create(nil); try LOpenDialog.Title := 'C4D - Select a file'; - if(not ADefaultFile.Trim.IsEmpty)then + if not ADefaultFile.Trim.IsEmpty then begin LFolder := ExtractFilePath(ADefaultFile); - if(System.SysUtils.DirectoryExists(LFolder))then + if System.SysUtils.DirectoryExists(LFolder) then LOpenDialog.InitialDir := LFolder; - if(System.SysUtils.FileExists(ADefaultFile))then + if System.SysUtils.FileExists(ADefaultFile) then LOpenDialog.FileName := ExtractFileName(ADefaultFile); end; - if(ADefaultExt <> TC4DExtensionsFiles.All)then + if ADefaultExt <> TC4DExtensionsFiles.All then begin LOpenDialog.DefaultExt := ADefaultExt.ToString; LOpenDialog.Filter := Format('Arquivo %s|*.%s', [ADefaultExt.ToString.ToUpper, ADefaultExt.ToString]); end; - if(not LOpenDialog.Execute)then + if not LOpenDialog.Execute then Exit(ADefaultFile); Result := LOpenDialog.FileName; finally @@ -637,12 +637,12 @@ class function TUtils.SelectFolder(const ADefaultFolder: string; const ADefaultF LFileOpenDialog.Title := 'Delphi AI Developer - Select a folder'; LFileOpenDialog.Options := [fdoPickFolders]; - if(not ADefaultFolder.Trim.IsEmpty)and(System.SysUtils.DirectoryExists(ADefaultFolder))then + if (not ADefaultFolder.Trim.IsEmpty) and (System.SysUtils.DirectoryExists(ADefaultFolder)) then LFileOpenDialog.DefaultFolder := ADefaultFolder; - if(not LFileOpenDialog.Execute)then + if not LFileOpenDialog.Execute then begin - if(ADefaultFolderIfCancel)then + if ADefaultFolderIfCancel then Result := ADefaultFolder; Exit; end; @@ -675,19 +675,19 @@ class function TUtils.DirectoryDelete(AFullPath: string): Boolean; LSr: TSearchRec; LFullName: string; begin - if(not System.SysUtils.DirectoryExists(AFullPath))then + if not System.SysUtils.DirectoryExists(AFullPath) then Exit(False); try Result := True; - if(FindFirst(AFullPath + '\*.*', faAnyFile, LSr) = 0)then + if FindFirst(AFullPath + '\*.*', faAnyFile, LSr) = 0 then begin try repeat LFullName := IncludeTrailingPathDelimiter(AFullPath) + LSr.Name; - if(LSr.Name <> '.')and(LSr.Name <> '..')then + if (LSr.Name <> '.') and (LSr.Name <> '..') then begin - if((LSr.Attr and faDirectory) = 0)then + if ((LSr.Attr and faDirectory) = 0) then Result := System.SysUtils.DeleteFile(LFullName) else Result := DirectoryDelete(LFullName); @@ -707,7 +707,7 @@ class function TUtils.DirectoryOrFileMove(AFrom, ATo: string): Boolean; begin Result := False; try - if(MoveFile(PWideChar(AFrom), PWideChar(ATo)))then + if MoveFile(PWideChar(AFrom), PWideChar(ATo)) then Result := True; except on E: Exception do @@ -733,7 +733,7 @@ class procedure TUtils.OpenFile(AFilePath: string); class procedure TUtils.OpenFileOrFolder(APath: string); begin - if(FileExists(APath))then + if FileExists(APath) then Self.OpenFile(APath) else Self.OpenFolder(APath); @@ -817,7 +817,7 @@ class function TUtils.GuidToFileName(const AGuid: string; const AExtension: stri class function TUtils.GetNamespace(AText: string): string; begin Result := ''; - if(ContainsStr(AText, '.'))then + if ContainsStr(AText, '.') then Result := Copy(AText, 1, Pos('.', AText)); end; @@ -829,23 +829,23 @@ class function TUtils.GetTextBetween(AText, ADelimitador1, ADelimitador2: string begin Result := ''; LText := AText; - if(ACaseSensitive)then + if ACaseSensitive then LPosIni := Pos(ADelimitador1, LText) else LPosIni := Pos(AnsiUpperCase(ADelimitador1), AnsiUpperCase(LText)); - if(LPosIni > 0)then + if LPosIni > 0 then LText := Copy(LText, LPosIni, Length(LText)); - if(ACaseSensitive)then + if ACaseSensitive then LPosFim := Pos(ADelimitador2, LText) else LPosFim := Pos(AnsiUpperCase(ADelimitador2), AnsiUpperCase(LText)); - if(LPosFim > 0)then + if LPosFim > 0 then LText := Copy(LText, 1, LPosFim + Length(ADelimitador2) - 1); - if(LPosIni > 0)or(LPosFim > 0)then + if (LPosIni > 0) or (LPosFim > 0) then Result := LText; end; @@ -895,9 +895,9 @@ class function TUtils.ChangeLastComma(AValue: string; ANewLastChar: Char): strin begin Result := AValue; AValue := AValue.TrimRight; - if(not AValue.IsEmpty)then + if not AValue.IsEmpty then begin - if(RightStr(AValue, 1) = ',')then + if RightStr(AValue, 1) = ',' then begin Delete(AValue, AValue.Length, 1); Result := AValue + ANewLastChar; @@ -909,9 +909,9 @@ class function TUtils.RemoveLastChar(AValue: string; AChar: Char): string; begin Result := AValue; AValue := AValue.Trim; - if(not AValue.IsEmpty)then + if not AValue.IsEmpty then begin - if(RightStr(AValue, 1) = AChar)then + if RightStr(AValue, 1) = AChar then begin Delete(AValue, AValue.Length, 1); Result := AValue; @@ -932,7 +932,7 @@ class function TUtils.RemoveAccents(AValue: string): string; I: Integer; begin for I := 1 to Length(AValue) do - if(Pos(AValue[I], WITH_ACCENTS) <> 0)then + if Pos(AValue[I], WITH_ACCENTS) <> 0 then AValue[I] := OUT_ACCENTS[Pos(AValue[I], WITH_ACCENTS)]; Result := AValue; @@ -946,7 +946,7 @@ class function TUtils.SwapSymbols(AValue: string): string; I: Integer; begin for I := 1 to Length(AValue)do - if(Pos(AValue[I], SYMBOLS_OLD) <> 0)then + if Pos(AValue[I], SYMBOLS_OLD) <> 0 then AValue[I] := SYMBOLS_NEW[Pos(AValue[I], SYMBOLS_OLD)]; Result := AValue; diff --git a/Src/View/DelphiAIDev.View.Dialog.dfm b/Src/View/DelphiAIDev.View.Dialog.dfm index 63d2404..441b4d7 100644 --- a/Src/View/DelphiAIDev.View.Dialog.dfm +++ b/Src/View/DelphiAIDev.View.Dialog.dfm @@ -100,8 +100,8 @@ object DelphiAIDevViewDialog: TDelphiAIDevViewDialog object lbMsg: TLabel Left = 32 Top = 0 - Width = 432 - Height = 133 + Width = 30 + Height = 14 Align = alClient Alignment = taCenter Caption = 'lbMsg' @@ -114,8 +114,6 @@ object DelphiAIDevViewDialog: TDelphiAIDevViewDialog PopupMenu = PopupMenu1 Layout = tlCenter WordWrap = True - ExplicitWidth = 30 - ExplicitHeight = 14 end object pnDetailsLabel: TPanel Left = 0 @@ -132,7 +130,7 @@ object DelphiAIDevViewDialog: TDelphiAIDevViewDialog Left = 389 Top = 0 Width = 68 - Height = 17 + Height = 14 Cursor = crHandPoint Margins.Left = 0 Margins.Top = 0 @@ -149,14 +147,13 @@ object DelphiAIDevViewDialog: TDelphiAIDevViewDialog ParentFont = False Layout = tlCenter OnClick = lbViewDetailsClick - ExplicitHeight = 14 end object lbViewDetails02: TLabel AlignWithMargins = True Left = 462 Top = 0 Width = 12 - Height = 17 + Height = 14 Cursor = crHandPoint Margins.Left = 0 Margins.Top = 0 @@ -173,7 +170,6 @@ object DelphiAIDevViewDialog: TDelphiAIDevViewDialog ParentFont = False Layout = tlCenter OnClick = lbViewDetailsClick - ExplicitHeight = 14 end end object pnImg: TPanel diff --git a/Src/View/DelphiAIDev.View.Dialog.pas b/Src/View/DelphiAIDev.View.Dialog.pas index 556a0a7..4ffb25a 100644 --- a/Src/View/DelphiAIDev.View.Dialog.pas +++ b/Src/View/DelphiAIDev.View.Dialog.pas @@ -112,7 +112,7 @@ procedure TDelphiAIDevViewDialog.FormKeyDown(Sender: TObject; var Key: Word; Shi VK_ESCAPE: if Shift = [] then begin - if(btnCancel.Visible)then + if btnCancel.Visible then btnCancel.Click else Self.Close; @@ -132,7 +132,7 @@ procedure TDelphiAIDevViewDialog.ConfHeightForm; begin pnDetailsLabel.Visible := True; pnDetails.Visible := True; - if(FDetails.Trim.IsEmpty)then + if FDetails.Trim.IsEmpty then begin pnDetailsLabel.Visible := False; pnDetails.Visible := False; @@ -149,14 +149,14 @@ procedure TDelphiAIDevViewDialog.ConfButtons; begin btnCancel.Visible := FButtons = TC4DButtons.OK_Cancel; btnOK.SetFocus; - if(btnCancel.Visible)and(FBtnFocu = TC4DBtnFocu.Cancel)then + if (btnCancel.Visible) and (FBtnFocu = TC4DBtnFocu.Cancel) then btnCancel.SetFocus; end; procedure TDelphiAIDevViewDialog.lbViewDetailsClick(Sender: TObject); begin try - if(mmDetails.Visible)then + if mmDetails.Visible then begin mmDetails.Visible := False; lbViewDetails02.Caption := '>>'; diff --git a/Src/View/DelphiAIDev.View.Memo.pas b/Src/View/DelphiAIDev.View.Memo.pas index cb7a9f8..becf793 100644 --- a/Src/View/DelphiAIDev.View.Memo.pas +++ b/Src/View/DelphiAIDev.View.Memo.pas @@ -56,7 +56,7 @@ procedure TDelphiAIDevViewMemo.mmMensagemKeyDown(Sender: TObject; var Key: Word; const KEY_A = $41; begin - if(Key = KEY_A)and(Shift = [ssCtrl])then + if (Key = KEY_A) and (Shift = [ssCtrl]) then mmMensagem.SelectAll; end; diff --git a/Src/WaitingScreen/DelphiAIDev.WaitingScreen.View.pas b/Src/WaitingScreen/DelphiAIDev.WaitingScreen.View.pas index 4657d7c..6faad8d 100644 --- a/Src/WaitingScreen/DelphiAIDev.WaitingScreen.View.pas +++ b/Src/WaitingScreen/DelphiAIDev.WaitingScreen.View.pas @@ -47,7 +47,7 @@ procedure TDelphiAIDevWaitingScreenView.FormCreate(Sender: TObject); procedure TDelphiAIDevWaitingScreenView.FormShow(Sender: TObject); begin lbMsg.Caption := C_MSG_DEFAULT; - if(not FMsg.Trim.IsEmpty)then + if not FMsg.Trim.IsEmpty then lbMsg.Caption := FMsg; Self.BringToFront; @@ -55,7 +55,7 @@ procedure TDelphiAIDevWaitingScreenView.FormShow(Sender: TObject); procedure TDelphiAIDevWaitingScreenView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin - if(Key = VK_F4)and(ssAlt in Shift)then + if (Key = VK_F4) and (ssAlt in Shift) then Key := 0; end; diff --git a/Src/WaitingScreen/DelphiAIDev.WaitingScreen.pas b/Src/WaitingScreen/DelphiAIDev.WaitingScreen.pas index 0c5906f..82123a3 100644 --- a/Src/WaitingScreen/DelphiAIDev.WaitingScreen.pas +++ b/Src/WaitingScreen/DelphiAIDev.WaitingScreen.pas @@ -25,7 +25,7 @@ implementation class function TDelphiAIDevWaitingScreen.GetInstance: TDelphiAIDevWaitingScreen; begin - if(not Assigned(Instance))then + if not Assigned(Instance) then Instance := Self.Create; Result := Instance; end; @@ -42,7 +42,7 @@ destructor TDelphiAIDevWaitingScreen.Destroy; procedure TDelphiAIDevWaitingScreen.Show(const AMsg: string = ''); begin - if(not Assigned(FDelphiAIDevWaitingScreenView))then + if not Assigned(FDelphiAIDevWaitingScreenView) then FDelphiAIDevWaitingScreenView := TDelphiAIDevWaitingScreenView.Create(nil); FDelphiAIDevWaitingScreenView.Msg := AMsg; FDelphiAIDevWaitingScreenView.Show; @@ -57,7 +57,7 @@ procedure TDelphiAIDevWaitingScreen.Close; initialization finalization - if(Assigned(Instance))then + if Assigned(Instance) then FreeAndNil(Instance); end. From 5b2e16ccf29a94bf49555faf341abd4d38d5065e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 26 Aug 2024 15:54:56 -0300 Subject: [PATCH 040/109] add-link-databse-projects --- Package/DelphiAIDeveloper.dpk | 8 +- Package/DelphiAIDeveloper.dproj | 9 + Src/Consts/DelphiAIDev.Consts.pas | 3 +- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 45 +-- .../DelphiAIDev.DB.LinkedProject.View.dfm | 134 +++++++ .../DelphiAIDev.DB.LinkedProject.View.pas | 174 +++++++++ .../DelphiAIDev.DB.References.View.dfm | 5 +- .../DelphiAIDev.DB.References.View.pas | 17 +- .../DelphiAIDev.DB.Registers.AddEdit.View.dfm | 1 - .../DelphiAIDev.DB.Registers.View.dfm | 1 + .../DelphiAIDev.DB.Registers.View.pas | 8 +- Src/DB/Utils/DelphiAIDev.DB.Utils.pas | 73 ++++ ...elphiAIDev.PopupMenuProjects.OnExecute.pas | 50 +++ .../DelphiAIDev.PopupMenuProjects.pas | 44 +-- Src/Projects/DelphiAIDev.Projects.Fields.pas | 48 +++ .../DelphiAIDev.Projects.Interfaces.pas | 22 ++ Src/Projects/DelphiAIDev.Projects.Model.pas | 351 ++++++++++++++++++ Src/Utils/DelphiAIDev.Utils.pas | 6 + 18 files changed, 924 insertions(+), 75 deletions(-) create mode 100644 Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.dfm create mode 100644 Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.pas create mode 100644 Src/DB/Utils/DelphiAIDev.DB.Utils.pas create mode 100644 Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas create mode 100644 Src/Projects/DelphiAIDev.Projects.Fields.pas create mode 100644 Src/Projects/DelphiAIDev.Projects.Interfaces.pas create mode 100644 Src/Projects/DelphiAIDev.Projects.Model.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index e79d4be..33c7a50 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -100,6 +100,12 @@ contains DelphiAIDev.MetaInfo in '..\Src\MetaInfo\DelphiAIDev.MetaInfo.pas', DelphiAIDev.DB.References.View in '..\Src\DB\References\DelphiAIDev.DB.References.View.pas' {DelphiAIDevDBReferencesView}, DelphiAIDev.Utils.DBGrids in '..\Src\Utils\DelphiAIDev.Utils.DBGrids.pas', - DelphiAIDev.AI.Ollama in '..\Src\AI\DelphiAIDev.AI.Ollama.pas'; + DelphiAIDev.AI.Ollama in '..\Src\AI\DelphiAIDev.AI.Ollama.pas', + DelphiAIDev.DB.LinkedProject.View in '..\Src\DB\LinkedProject\DelphiAIDev.DB.LinkedProject.View.pas' {DelphiAIDevDBLinkedProjectView}, + DelphiAIDev.DB.Utils in '..\Src\DB\Utils\DelphiAIDev.DB.Utils.pas', + DelphiAIDev.PopupMenuProjects.OnExecute in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.OnExecute.pas', + DelphiAIDev.Projects.Fields in '..\Src\Projects\DelphiAIDev.Projects.Fields.pas', + DelphiAIDev.Projects.Model in '..\Src\Projects\DelphiAIDev.Projects.Model.pas', + DelphiAIDev.Projects.Interfaces in '..\Src\Projects\DelphiAIDev.Projects.Interfaces.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 89e7c85..0f42cb8 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -213,6 +213,15 @@ + +
DelphiAIDevDBLinkedProjectView
+ dfm +
+ + + + + BITMAP c4d_Logo diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index 712b9d8..bc9c8bf 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -47,6 +47,7 @@ TConsts = class //NAMES FILE JSON FILE_JSON_DEFAULTS_QUESTIONS = 'delphi_ai_developer_questions.json'; FILE_JSON_DATABASES = 'delphi_ai_developer_databases.json'; + FILE_JSON_PROJECTS = 'delphi_ai_developer_projects.json'; //ABOUT AND SPLASH ABOUT_TITLE = 'Delphi AI Developer'; @@ -67,7 +68,7 @@ TConsts = class //CAPTIONS ITENS POPUPMENU PROJ ITEM_POPUP_MENU_PROJ_CAPTION = 'AI Developer'; - ITEM_POPUP_MENU_PROJ_ConfigureDB_CAPTION = 'Configure Database'; + ITEM_POPUP_MENU_PROJ_LinkDatabase_CAPTION = 'Link database'; //MAIN MENU IDE NAME AND CAPTIONS MENU_IDE_CHAT_NAME = 'DelphiAIDevChat1'; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 5c78bee..e76c438 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -168,7 +168,6 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure ProcessWordWrap; procedure ConfScreenOnCreate; procedure ReloadDatabases; - procedure ClearcBoxDatabases; procedure FillDateLastReferences; function GetFieldDBSelected: TDelphiAIDevDBRegistersFields; function GetJsonDatabase: string; @@ -190,7 +189,8 @@ implementation uses DeskUtil, DelphiAIDev.Utils, - DelphiAIDev.Utils.OTA; + DelphiAIDev.Utils.OTA, + DelphiAIDev.DB.Utils; {$R *.dfm} @@ -469,50 +469,11 @@ procedure TDelphiAIDevDBChatView.ChangeCodeOnly; end; procedure TDelphiAIDevDBChatView.ReloadDatabases; -var - LField: TDelphiAIDevDBRegistersFields; begin - Self.ClearcBoxDatabases; - - TDelphiAIDevDBRegistersModel.New.ReadData( - procedure(AFields: TDelphiAIDevDBRegistersFields) - begin - if (not AFields.Visible) or (AFields.Description.Trim.IsEmpty) then - Exit; - - if AFields.Visible then - begin - LField := TDelphiAIDevDBRegistersFields.Create; - LField.GetDataFromOtherObject(AFields); - cBoxDatabases.Items.AddObject(LField.Description, LField); - end; - end, - TAutoFreeField.Yes - ); - - cBoxDatabases.ItemIndex := 0; + TDelphiAIDevDBUtils.FillComboBoxDataBases(cBoxDatabases); Self.FillDateLastReferences; end; -procedure TDelphiAIDevDBChatView.ClearcBoxDatabases; -var - i: Integer; - LObj: TObject; -begin - for i := 0 to Pred(cBoxDatabases.Items.Count) do - begin - if not Assigned(cBoxDatabases.Items.Objects[i]) then - Continue; - - LObj := cBoxDatabases.Items.Objects[i]; - - if LObj is TDelphiAIDevDBRegistersFields then - TDelphiAIDevDBRegistersFields(LObj).Free; - end; - - cBoxDatabases.Items.Clear; -end; - procedure TDelphiAIDevDBChatView.AddResponseSimple(const AString: string); begin Self.Last; diff --git a/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.dfm b/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.dfm new file mode 100644 index 0000000..90ec90f --- /dev/null +++ b/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.dfm @@ -0,0 +1,134 @@ +object DelphiAIDevDBLinkedProjectView: TDelphiAIDevDBLinkedProjectView + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu] + Caption = 'IA Developer - Linked Databese With Project' + ClientHeight = 213 + ClientWidth = 629 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + Position = poScreenCenter + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnKeyDown = FormKeyDown + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object Bevel2: TBevel + AlignWithMargins = True + Left = 0 + Top = 174 + Width = 629 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alBottom + Shape = bsTopLine + ExplicitLeft = -87 + ExplicitTop = 264 + ExplicitWidth = 665 + end + object pnBody: TPanel + Left = 0 + Top = 0 + Width = 629 + Height = 174 + Align = alClient + BevelOuter = bvNone + ParentBackground = False + TabOrder = 0 + ExplicitWidth = 624 + object Bevel1: TBevel + AlignWithMargins = True + Left = 0 + Top = 170 + Width = 629 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alBottom + Shape = bsTopLine + ExplicitTop = 444 + ExplicitWidth = 676 + end + object Label1: TLabel + Left = 24 + Top = 101 + Width = 79 + Height = 13 + Caption = 'Last generation:' + end + object lbLastGeneration: TLabel + Left = 109 + Top = 101 + Width = 81 + Height = 13 + Caption = 'lbLastGeneration' + end + object cBoxDatabases: TComboBox + Left = 24 + Top = 77 + Width = 577 + Height = 21 + Style = csDropDownList + TabOrder = 0 + OnClick = cBoxDatabasesClick + end + end + object pnButtons: TPanel + Left = 0 + Top = 178 + Width = 629 + Height = 35 + Align = alBottom + BevelEdges = [beLeft, beRight, beBottom] + BevelOuter = bvNone + Padding.Left = 2 + Padding.Top = 2 + Padding.Right = 2 + Padding.Bottom = 2 + ParentBackground = False + TabOrder = 1 + ExplicitWidth = 624 + object btnSaveLink: TButton + AlignWithMargins = True + Left = 401 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alRight + Caption = 'Save link' + TabOrder = 0 + OnClick = btnSaveLinkClick + ExplicitLeft = 396 + end + object btnClose: TButton + AlignWithMargins = True + Left = 514 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alRight + Caption = 'Close' + TabOrder = 1 + OnClick = btnCloseClick + ExplicitLeft = 509 + end + end +end diff --git a/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.pas b/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.pas new file mode 100644 index 0000000..5813c8c --- /dev/null +++ b/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.pas @@ -0,0 +1,174 @@ +unit DelphiAIDev.DB.LinkedProject.View; + +interface + +uses + Winapi.Windows, + Winapi.Messages, + System.SysUtils, + System.Variants, + System.Classes, + Vcl.Graphics, + Vcl.Controls, + Vcl.Forms, + Vcl.Dialogs, + Vcl.StdCtrls, + Vcl.ExtCtrls, + ToolsAPI, + DelphiAIDev.DB.Registers.Model, + DelphiAIDev.DB.Registers.Fields, + DelphiAIDev.Projects.Model, + DelphiAIDev.Projects.Fields; + +type + TDelphiAIDevDBLinkedProjectView = class(TForm) + Bevel2: TBevel; + pnBody: TPanel; + Bevel1: TBevel; + Label1: TLabel; + lbLastGeneration: TLabel; + pnButtons: TPanel; + btnSaveLink: TButton; + btnClose: TButton; + cBoxDatabases: TComboBox; + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure btnCloseClick(Sender: TObject); + procedure btnSaveLinkClick(Sender: TObject); + procedure cBoxDatabasesClick(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + private + FOTAProject: IOTAProject; + FProjectsFields: TDelphiAIDevProjectsFields; + procedure FillScreenFields; + procedure FillcBoxDatabases; + procedure FillDateLastReferences; + function GetFieldDBSelected: TDelphiAIDevDBRegistersFields; + procedure ValidateFillingFields; + public + property OTAProject: IOTAProject write FOTAProject; + end; + +implementation + +uses + DelphiAIDev.Consts, + DelphiAIDev.Utils, + DelphiAIDev.Utils.OTA, + DelphiAIDev.DB.Utils; + +{$R *.dfm} + +procedure TDelphiAIDevDBLinkedProjectView.FormCreate(Sender: TObject); +begin + Self.ModalResult := mrCancel; + TUtilsOTA.IDEThemingAll(TDelphiAIDevDBLinkedProjectView, Self); +end; + +procedure TDelphiAIDevDBLinkedProjectView.FormDestroy(Sender: TObject); +begin + //FProjectsFields.Free; +end; + +procedure TDelphiAIDevDBLinkedProjectView.FormShow(Sender: TObject); +begin + FProjectsFields := TDelphiAIDevProjectsModel.New.ReadFilePath(FOTAProject.FileName); + + Self.FillScreenFields; +end; + +procedure TDelphiAIDevDBLinkedProjectView.FormClose(Sender: TObject; var Action: TCloseAction); +begin + if Assigned(FProjectsFields)then + FProjectsFields.Free; +end; + +procedure TDelphiAIDevDBLinkedProjectView.FillScreenFields; +begin + Screen.Cursor := crHourGlass; + try + Self.FillcBoxDatabases; + finally + Screen.Cursor := crDefault; + end; +end; + +procedure TDelphiAIDevDBLinkedProjectView.FillcBoxDatabases; +var + LDBRegistersFields: TDelphiAIDevDBRegistersFields; +begin + TDelphiAIDevDBUtils.FillComboBoxDataBases(cBoxDatabases); + + LDBRegistersFields := TDelphiAIDevDBRegistersModel.New.Re + +// if not FProjectsFields.GuidDatabaseDefault.Trim.IsEmpty then +// cBoxDatabases.ItemIndex := cBoxDatabases.Items.IndexOf(FProjectsFields); + + Self.FillDateLastReferences; +end; + +procedure TDelphiAIDevDBLinkedProjectView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +begin + case Key of + VK_F4: + if ssAlt in Shift then + Key := 0; + VK_ESCAPE: + if Shift = [] then + btnClose.Click; + end; +end; + +procedure TDelphiAIDevDBLinkedProjectView.cBoxDatabasesClick(Sender: TObject); +begin + Self.FillDateLastReferences; +end; + +procedure TDelphiAIDevDBLinkedProjectView.FillDateLastReferences; +begin + lbLastGeneration.Caption := ''; + + if cBoxDatabases.Items.Count < 0 then + Exit; + + lbLastGeneration.Caption := TUtils.DateTimeToStrEmpty(Self.GetFieldDBSelected.LastReferences); +end; + +function TDelphiAIDevDBLinkedProjectView.GetFieldDBSelected: TDelphiAIDevDBRegistersFields; +begin + Result := TDelphiAIDevDBRegistersFields(cBoxDatabases.Items.Objects[cBoxDatabases.ItemIndex]); +end; + +procedure TDelphiAIDevDBLinkedProjectView.btnCloseClick(Sender: TObject); +begin + Self.Close; + Self.ModalResult := mrCancel; +end; + +procedure TDelphiAIDevDBLinkedProjectView.btnSaveLinkClick(Sender: TObject); +begin + Self.ValidateFillingFields; + + Screen.Cursor := crHourGlass; + try + FProjectsFields.FilePath := FOTAProject.FileName; + FProjectsFields.GuidDatabaseDefault := Self.GetFieldDBSelected.Guid; + + TDelphiAIDevProjectsModel.New.SaveOrEditData(FProjectsFields); + finally + Screen.Cursor := crDefault; + end; + + Self.Close; + Self.ModalResult := mrOk; +end; + +procedure TDelphiAIDevDBLinkedProjectView.ValidateFillingFields; +begin + if cBoxDatabases.ItemIndex < 0 then + TUtils.ShowMsgAndAbort('No informed Database', cBoxDatabases); +end; + +end. diff --git a/Src/DB/References/DelphiAIDev.DB.References.View.dfm b/Src/DB/References/DelphiAIDev.DB.References.View.dfm index 455a3c8..fd6623d 100644 --- a/Src/DB/References/DelphiAIDev.DB.References.View.dfm +++ b/Src/DB/References/DelphiAIDev.DB.References.View.dfm @@ -15,6 +15,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView OldCreateOrder = False Position = poScreenCenter OnCreate = FormCreate + OnKeyDown = FormKeyDown OnShow = FormShow PixelsPerInch = 96 TextHeight = 13 @@ -33,7 +34,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView ExplicitTop = 264 ExplicitWidth = 665 end - object Panel1: TPanel + object pnButtons: TPanel Left = 0 Top = 126 Width = 295 @@ -78,7 +79,7 @@ object DelphiAIDevDBReferencesView: TDelphiAIDevDBReferencesView OnClick = btnCloseClick end end - object Panel9: TPanel + object pnBody: TPanel Left = 0 Top = 0 Width = 295 diff --git a/Src/DB/References/DelphiAIDev.DB.References.View.pas b/Src/DB/References/DelphiAIDev.DB.References.View.pas index 1d5d2ca..03eb343 100644 --- a/Src/DB/References/DelphiAIDev.DB.References.View.pas +++ b/Src/DB/References/DelphiAIDev.DB.References.View.pas @@ -21,10 +21,10 @@ interface type TDelphiAIDevDBReferencesView = class(TForm) Bevel2: TBevel; - Panel1: TPanel; + pnButtons: TPanel; btnGenerate: TButton; btnClose: TButton; - Panel9: TPanel; + pnBody: TPanel; Bevel1: TBevel; Label1: TLabel; lbLastGeneration: TLabel; @@ -34,6 +34,7 @@ TDelphiAIDevDBReferencesView = class(TForm) procedure FormShow(Sender: TObject); procedure btnCloseClick(Sender: TObject); procedure btnGenerateClick(Sender: TObject); + procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private FFields: TDelphiAIDevDBRegistersFields; procedure FillScreenFields; @@ -56,6 +57,18 @@ procedure TDelphiAIDevDBReferencesView.FormCreate(Sender: TObject); TUtilsOTA.IDEThemingAll(TDelphiAIDevDBReferencesView, Self); end; +procedure TDelphiAIDevDBReferencesView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +begin + case Key of + VK_F4: + if ssAlt in Shift then + Key := 0; + VK_ESCAPE: + if Shift = [] then + btnClose.Click; + end; +end; + procedure TDelphiAIDevDBReferencesView.FormShow(Sender: TObject); begin Self.FillScreenFields; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm index 2d994a0..db50f99 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.AddEdit.View.dfm @@ -62,7 +62,6 @@ object DelphiAIDevDBRegistersAddEditView: TDelphiAIDevDBRegistersAddEditView Caption = 'Confirm' TabOrder = 0 OnClick = btnConfirmClick - ExplicitTop = 0 end object btnClose: TButton AlignWithMargins = True diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm index 0f5b3e9..a734729 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm @@ -48,6 +48,7 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView Caption = 'Edit' TabOrder = 0 OnClick = btnEditClick + ExplicitTop = 1 end object btnClose: TButton AlignWithMargins = True diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas index 109708a..56f68c9 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.pas @@ -157,12 +157,12 @@ procedure TDelphiAIDevDBRegistersView.ReloadDataInternal; var LStrSearch: string; LListItem: TListItem; - LGuid: string; + LGuidSelected: string; begin LStrSearch := LowerCase(edtSearch.Text); if ListView.Selected <> nil then - LGuid := ListView.Items[ListView.Selected.Index].SubItems[C_INDEX_SUBITEM_Guid]; + LGuidSelected := ListView.Items[ListView.Selected.Index].SubItems[C_INDEX_SUBITEM_Guid]; ListView.Clear; @@ -202,8 +202,8 @@ procedure TDelphiAIDevDBRegistersView.ReloadDataInternal; .InvertOrder(False) .CustomSort; - if not LGuid.Trim.IsEmpty then - TUtils.FindListVewItem(ListView, C_INDEX_SUBITEM_Guid, LGuid); + if not LGuidSelected.Trim.IsEmpty then + TUtils.FindListVewItem(ListView, C_INDEX_SUBITEM_Guid, LGuidSelected); Self.FillStatusBar(ListView.Selected); end; diff --git a/Src/DB/Utils/DelphiAIDev.DB.Utils.pas b/Src/DB/Utils/DelphiAIDev.DB.Utils.pas new file mode 100644 index 0000000..e2ae29b --- /dev/null +++ b/Src/DB/Utils/DelphiAIDev.DB.Utils.pas @@ -0,0 +1,73 @@ +unit DelphiAIDev.DB.Utils; + +interface + +uses + System.SysUtils, + Vcl.StdCtrls; + +type + TDelphiAIDevDBUtils = class + private + + public + class procedure ClearComboBox(const AComboBox: TComboBox); + class procedure FillComboBoxDatabases(const AComboBox: TComboBox); + class procedure SelectByGuidDatabase(const AComboBox: TComboBox; const AGuidDatabase); + end; + +implementation + +uses + DelphiAIDev.DB.Registers.Fields, + DelphiAIDev.DB.Registers.Model; + +class procedure TDelphiAIDevDBUtils.ClearComboBox(const AComboBox: TComboBox); +var + i: Integer; + LObj: TObject; +begin + for i := 0 to Pred(AComboBox.Items.Count) do + begin + if not Assigned(AComboBox.Items.Objects[i]) then + Continue; + + LObj := AComboBox.Items.Objects[i]; + + if LObj is TDelphiAIDevDBRegistersFields then + TDelphiAIDevDBRegistersFields(LObj).Free; + end; + + AComboBox.Items.Clear; +end; + +class procedure TDelphiAIDevDBUtils.FillComboBoxDatabases(const AComboBox: TComboBox); +var + LField: TDelphiAIDevDBRegistersFields; +begin + Self.ClearComboBox(AComboBox); + + TDelphiAIDevDBRegistersModel.New.ReadData( + procedure(AFields: TDelphiAIDevDBRegistersFields) + begin + if (not AFields.Visible) or (AFields.Description.Trim.IsEmpty) then + Exit; + + if AFields.Visible then + begin + LField := TDelphiAIDevDBRegistersFields.Create; + LField.GetDataFromOtherObject(AFields); + AComboBox.Items.AddObject(LField.Description, LField); + end; + end + ); + + AComboBox.ItemIndex := 0; +end; + +class procedure TDelphiAIDevDBUtils.SelectByGuidDatabase(const AComboBox: TComboBox; const AGuidDatabase); +begin + AComboBox +end; + +end. diff --git a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas new file mode 100644 index 0000000..6d14181 --- /dev/null +++ b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas @@ -0,0 +1,50 @@ +unit DelphiAIDev.PopupMenuProjects.OnExecute; + +interface + +uses + System.SysUtils, + System.Classes, + ToolsAPI; + +type + TDelphiAIDevPopupMenuProjectsOnExecute = class + private + FIOTAProject: IOTAProject; + procedure CheckFileNameProject; + public + procedure LinkDatabase(const MenuContextList: IInterfaceList); + property OTAProject: IOTAProject write FIOTAProject; + end; + +implementation + +uses + DelphiAIDev.Utils, + DelphiAIDev.DB.LinkedProject.View; + +procedure TDelphiAIDevPopupMenuProjectsOnExecute.CheckFileNameProject; +begin + if FIOTAProject.FileName.Trim.IsEmpty then + TUtils.ShowMsgAndAbort('Project file name is empty'); + +// if not System.SysUtils.FileExists(FIOTAProject.FileName) then +// TUtils.ShowMsgAndAbort('Project file not found'); +end; + +procedure TDelphiAIDevPopupMenuProjectsOnExecute.LinkDatabase(const MenuContextList: IInterfaceList); +var + LView: TDelphiAIDevDBLinkedProjectView; +begin + Self.CheckFileNameProject; + + LView := TDelphiAIDevDBLinkedProjectView.Create(nil); + try + LView.OTAProject := FIOTAProject; + LView.ShowModal; + finally + LView.Free; + end; +end; + +end. diff --git a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas index 4c3bc17..cf253e6 100644 --- a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas +++ b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas @@ -7,23 +7,25 @@ interface System.Classes, ToolsAPI, DelphiAIDev.Types, - DelphiAIDev.PopupMenuProjects.Item; + DelphiAIDev.PopupMenuProjects.Item, + DelphiAIDev.PopupMenuProjects.OnExecute; type TC4DWizardIDEPopupMenuNotifier = class(TNotifierObject, IOTAProjectMenuItemCreatorNotifier) private - FProject: IOTAProject; + FOnExecute: TDelphiAIDevPopupMenuProjectsOnExecute; + FIOTAProject: IOTAProject; FPosition: Integer; function AddItemInMenu(const ACaption: string): IOTAProjectManagerMenu; function AddSubItemInMenu(const ACaption: string; const AOnExecute: TC4DWizardMenuContextList = nil; const AChecked: Boolean = False): IOTAProjectManagerMenu; - procedure CheckFileNameProject; - procedure OnExecuteEditInformations(const MenuContextList: IInterfaceList); protected procedure AddMenu(const Project: IOTAProject; const IdentList: TStrings; const ProjectManagerMenuList: IInterfaceList; IsMultiSelect: Boolean); public class function New: IOTAProjectMenuItemCreatorNotifier; + constructor Create; + destructor Destroy; override; end; procedure RegisterSelf; @@ -50,6 +52,17 @@ class function TC4DWizardIDEPopupMenuNotifier.New: IOTAProjectMenuItemCreatorNot Result := Self.Create; end; +constructor TC4DWizardIDEPopupMenuNotifier.Create; +begin + FOnExecute := TDelphiAIDevPopupMenuProjectsOnExecute.Create; +end; + +destructor TC4DWizardIDEPopupMenuNotifier.Destroy; +begin + FOnExecute.Free; + inherited; +end; + procedure TC4DWizardIDEPopupMenuNotifier.AddMenu(const Project: IOTAProject; const IdentList: TStrings; const ProjectManagerMenuList: IInterfaceList; IsMultiSelect: Boolean); begin @@ -63,19 +76,15 @@ procedure TC4DWizardIDEPopupMenuNotifier.AddMenu(const Project: IOTAProject; con else Exit; - FProject := Project; + FIOTAProject := Project; + FOnExecute.OTAProject := FIOTAProject; + FPosition := FPosition + 201; ProjectManagerMenuList.Add(Self.AddItemInMenu('-')); ProjectManagerMenuList.Add(Self.AddItemInMenu(TConsts.ITEM_POPUP_MENU_PROJ_CAPTION)); - ProjectManagerMenuList.Add(Self.AddSubItemInMenu(TConsts.ITEM_POPUP_MENU_PROJ_ConfigureDB_CAPTION, - OnExecuteEditInformations)); -end; - -procedure TC4DWizardIDEPopupMenuNotifier.OnExecuteEditInformations(const MenuContextList: IInterfaceList); -begin - Self.CheckFileNameProject; - //TC4DWizardReopenController.New(FProject.FileName).EditInformations; + ProjectManagerMenuList.Add(Self.AddSubItemInMenu(TConsts.ITEM_POPUP_MENU_PROJ_LinkDatabase_CAPTION, + FOnExecute.LinkDatabase)); end; function TC4DWizardIDEPopupMenuNotifier.AddItemInMenu(const ACaption: string): IOTAProjectManagerMenu; @@ -101,15 +110,6 @@ function TC4DWizardIDEPopupMenuNotifier.AddSubItemInMenu(const ACaption: string; Result.IsMultiSelectable := False; end; -procedure TC4DWizardIDEPopupMenuNotifier.CheckFileNameProject; -begin - if FProject.FileName.Trim.IsEmpty then - TUtils.ShowMsgAndAbort('File name is empty'); - - if not System.SysUtils.FileExists(FProject.FileName) then - TUtils.ShowMsgAndAbort('File not found'); -end; - initialization finalization diff --git a/Src/Projects/DelphiAIDev.Projects.Fields.pas b/Src/Projects/DelphiAIDev.Projects.Fields.pas new file mode 100644 index 0000000..5906092 --- /dev/null +++ b/Src/Projects/DelphiAIDev.Projects.Fields.pas @@ -0,0 +1,48 @@ +unit DelphiAIDev.Projects.Fields; + +interface + +uses + DelphiAIDev.Types; + +type + TDelphiAIDevProjectsFields = class + private + FGuid: string; + FFilePath: string; + FDescription: string; + FGuidDatabaseDefault: string; + public + constructor Create; + procedure Clear; + procedure GetDataFromOtherObject(const AOtherObj: TDelphiAIDevProjectsFields); + property Guid: string read FGuid write FGuid; + property FilePath: string read FFilePath write FFilePath; + property Description: string read FDescription write FDescription; + property GuidDatabaseDefault: string read FGuidDatabaseDefault write FGuidDatabaseDefault; + end; + +implementation + +constructor TDelphiAIDevProjectsFields.Create; +begin + Self.Clear; +end; + +procedure TDelphiAIDevProjectsFields.Clear; +begin + FGuid := ''; + FFilePath := ''; + FDescription := ''; + FGuidDatabaseDefault := ''; +end; + +procedure TDelphiAIDevProjectsFields.GetDataFromOtherObject(const AOtherObj: TDelphiAIDevProjectsFields); +begin + FGuid := AOtherObj.Guid; + FDescription := AOtherObj.Description; + FFilePath := AOtherObj.FilePath; + FGuidDatabaseDefault := AOtherObj.GuidDatabaseDefault; +end; + +end. diff --git a/Src/Projects/DelphiAIDev.Projects.Interfaces.pas b/Src/Projects/DelphiAIDev.Projects.Interfaces.pas new file mode 100644 index 0000000..e528d41 --- /dev/null +++ b/Src/Projects/DelphiAIDev.Projects.Interfaces.pas @@ -0,0 +1,22 @@ +unit DelphiAIDev.Projects.Interfaces; + +interface + +uses + System.SysUtils, + DelphiAIDev.Types, + DelphiAIDev.Projects.Fields; + +type + IDelphiAIDevProjectsModel = interface + ['{D919A407-4301-447F-A267-6965153DC01A}'] + function ReadGuid(const AGuid: string): TDelphiAIDevProjectsFields; + function ReadFilePath(const AFilePath: string): TDelphiAIDevProjectsFields; + procedure ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); + procedure SaveOrEditData(AFields: TDelphiAIDevProjectsFields); + procedure RemoveData(const AGuid: string); + end; + +implementation + +end. diff --git a/Src/Projects/DelphiAIDev.Projects.Model.pas b/Src/Projects/DelphiAIDev.Projects.Model.pas new file mode 100644 index 0000000..0011ac1 --- /dev/null +++ b/Src/Projects/DelphiAIDev.Projects.Model.pas @@ -0,0 +1,351 @@ +unit DelphiAIDev.Projects.Model; + +interface + +uses + System.SysUtils, + System.Classes, + System.JSON, + Rest.JSON, + DelphiAIDev.Utils, + DelphiAIDev.Types, + DelphiAIDev.Projects.Interfaces, + DelphiAIDev.Projects.Fields; + +type + TDelphiAIDevProjectsModel = class(TInterfacedObject, IDelphiAIDevProjectsModel) + private + procedure SaveData(AFields: TDelphiAIDevProjectsFields); + procedure EditData(AFields: TDelphiAIDevProjectsFields); + procedure FillField(const AJSONObjItem: TJSONObject; var AField: TDelphiAIDevProjectsFields); + protected + function ReadGuid(const AGuid: string): TDelphiAIDevProjectsFields; + function ReadFilePath(const AFilePath: string): TDelphiAIDevProjectsFields; + procedure ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); + procedure SaveOrEditData(AFields: TDelphiAIDevProjectsFields); + procedure RemoveData(const AGuid: string); + public + class function New: IDelphiAIDevProjectsModel; + constructor Create; + end; + +implementation + +const + GUID = 'guid'; + FILE_PATH = 'file_path'; + DESCRIPTION = 'description'; + GUID_DATABASE_DEFAULT = 'guid_database_default'; + +class function TDelphiAIDevProjectsModel.New: IDelphiAIDevProjectsModel; +begin + Result := Self.Create; +end; + +constructor TDelphiAIDevProjectsModel.Create; +begin + // +end; + +function TDelphiAIDevProjectsModel.ReadGuid(const AGuid: string): TDelphiAIDevProjectsFields; +var + LStringList: TStringList; + LJSONObjItem: TJSONObject; + LJSONArray: TJsonArray; + i: Integer; +begin + Result := TDelphiAIDevProjectsFields.Create; + + if not FileExists(TUtils.GetPathFileJSONProjects) then + Exit; + + LStringList := TStringList.Create; + try + LStringList.LoadFromFile(TUtils.GetPathFileJSONProjects); + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + finally + LStringList.Free; + end; + + try + for i := 0 to Pred(LJSONArray.Count) do + begin + if not(LJSONArray.Items[i] is TJSONObject) then + Continue; + + LJSONObjItem := LJSONArray.Items[i] as TJSONObject; + + if LJSONObjItem.GetValue(GUID) = nil then + Continue; + + if LJSONObjItem.GetValue(GUID) <> AGuid then + Continue; + + Self.FillField(LJSONObjItem, Result); + Break; + end; + finally + LJSONArray.Free; + end; +end; + +function TDelphiAIDevProjectsModel.ReadFilePath(const AFilePath: string): TDelphiAIDevProjectsFields; +var + LStringList: TStringList; + LJSONObjItem: TJSONObject; + LJSONArray: TJsonArray; + i: Integer; +begin + Result := TDelphiAIDevProjectsFields.Create; + + if AFilePath.Trim.IsEmpty then + Exit; + + if not FileExists(TUtils.GetPathFileJSONProjects) then + Exit; + + LStringList := TStringList.Create; + try + LStringList.LoadFromFile(TUtils.GetPathFileJSONProjects); + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + finally + LStringList.Free; + end; + + try + for i := 0 to Pred(LJSONArray.Count) do + begin + if not(LJSONArray.Items[i] is TJSONObject) then + Continue; + + LJSONObjItem := LJSONArray.Items[i] as TJSONObject; + + if LJSONObjItem.GetValue(FILE_PATH) = nil then + Continue; + + if LJSONObjItem.GetValue(FILE_PATH) <> AFilePath then + Continue; + + Self.FillField(LJSONObjItem, Result); + Break; + end; + finally + LJSONArray.Free; + end; +end; + +procedure TDelphiAIDevProjectsModel.FillField(const AJSONObjItem: TJSONObject; + var AField: TDelphiAIDevProjectsFields); +begin + AField.Clear; + AField.Guid := AJSONObjItem.GetValue(GUID); + + if AJSONObjItem.GetValue(FILE_PATH) <> nil then + AField.FilePath := AJSONObjItem.GetValue(FILE_PATH); + + if AJSONObjItem.GetValue(DESCRIPTION) <> nil then + AField.Description := AJSONObjItem.GetValue(DESCRIPTION); + + if AJSONObjItem.GetValue(GUID_DATABASE_DEFAULT) <> nil then + AField.GuidDatabaseDefault := AJSONObjItem.GetValue(GUID_DATABASE_DEFAULT); +end; + +procedure TDelphiAIDevProjectsModel.ReadData(AProc: TProc; + const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); +var + LStringList: TStringList; + LJSONObjItem: TJSONObject; + LJSONArray: TJsonArray; + i: Integer; + LFields: TDelphiAIDevProjectsFields; +begin + LFields := TDelphiAIDevProjectsFields.Create; + try + if not FileExists(TUtils.GetPathFileJSONProjects) then + begin + AProc(LFields); + Exit; + end; + + LStringList := TStringList.Create; + try + LStringList.LoadFromFile(TUtils.GetPathFileJSONProjects); + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + finally + LStringList.Free; + end; + + try + for i := 0 to Pred(LJSONArray.Count) do + begin + if not(LJSONArray.Items[i] is TJSONObject) then + Continue; + + LJSONObjItem := LJSONArray.Items[i] as TJSONObject; + + if LJSONObjItem.GetValue(GUID) = nil then + Continue; + + Self.FillField(LJSONObjItem, LFields); + + AProc(LFields); + end; + finally + LJSONArray.Free; + end; + finally + if AAutoFreeField = TAutoFreeField.Yes then + LFields.Free; + end; +end; + +procedure TDelphiAIDevProjectsModel.SaveOrEditData(AFields: TDelphiAIDevProjectsFields); +begin + if AFields.Guid.Trim.IsEmpty then + Self.SaveData(AFields) + else + Self.EditData(AFields); +end; + +procedure TDelphiAIDevProjectsModel.SaveData(AFields: TDelphiAIDevProjectsFields); +var + LStringList: TStringList; + LJSONArray: TJSONArray; + LJSONObject: TJSONObject; +begin + LStringList := TStringList.Create; + try + if FileExists(TUtils.GetPathFileJSONProjects) then + LStringList.LoadFromFile(TUtils.GetPathFileJSONProjects); + + LJSONArray := TJSONArray.Create; + try + if string(LStringList.Text).Trim.StartsWith('[') then + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + + LJSONObject := TJSONObject.Create; + LJSONObject.AddPair(GUID, TUtils.GetGuidStr); + LJSONObject.AddPair(FILE_PATH, AFields.FilePath); + LJSONObject.AddPair(DESCRIPTION, AFields.Description); + LJSONObject.AddPair(GUID_DATABASE_DEFAULT, AFields.GuidDatabaseDefault); + LJSONArray.AddElement(LJSONObject); + + {$IF CompilerVersion <= 32.0} //Tokyo + LStringList.Text := LJSONArray.ToJSON; + {$ELSE} + LStringList.Text := LJSONArray.Format(2); + {$ENDIF} + finally + LJSONArray.Free; + end; + + LStringList.SaveToFile(TUtils.GetPathFileJSONProjects); + finally + LStringList.Free; + end; +end; + +procedure TDelphiAIDevProjectsModel.EditData(AFields: TDelphiAIDevProjectsFields); +var + LStringList: TStringList; + LJSONArray: TJSONArray; + LJSONObjItem: TJSONObject; + i: Integer; +begin + LStringList := TStringList.Create; + try + if FileExists(TUtils.GetPathFileJSONProjects) then + LStringList.LoadFromFile(TUtils.GetPathFileJSONProjects); + + LJSONArray := TJSONArray.Create; + try + if string(LStringList.Text).Trim.StartsWith('[') then + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + + for i := 0 to Pred(LJSONArray.Count) do + begin + if not(LJSONArray.Items[i] is TJSONObject) then + Continue; + + LJSONObjItem := LJSONArray.Items[i] as TJSONObject; + + if LJSONObjItem.GetValue(GUID) = AFields.Guid then + begin + LJSONObjItem.RemovePair(FILE_PATH).Free; + LJSONObjItem.AddPair(FILE_PATH, AFields.FilePath); + + LJSONObjItem.RemovePair(DESCRIPTION).Free; + LJSONObjItem.AddPair(DESCRIPTION, AFields.Description); + + LJSONObjItem.RemovePair(GUID_DATABASE_DEFAULT).Free; + LJSONObjItem.AddPair(GUID_DATABASE_DEFAULT, AFields.GuidDatabaseDefault); + + Break; + end; + end; + + {$IF CompilerVersion <= 32.0} //Tokyo + LStringList.Text := LJSONArray.ToJSON; + {$ELSE} + LStringList.Text := LJSONArray.Format(2); + {$ENDIF} + finally + LJSONArray.Free; + end; + + LStringList.SaveToFile(TUtils.GetPathFileJSONProjects); + finally + LStringList.Free; + end; +end; + +procedure TDelphiAIDevProjectsModel.RemoveData(const AGuid: string); +var + LStringList: TStringList; + LJSONArray: TJSONArray; + LJSONObjItem: TJSONObject; + i: Integer; +begin + if AGuid.Trim.IsEmpty then + Exit; + + if not FileExists(TUtils.GetPathFileJSONProjects) then + Exit; + + LStringList := TStringList.Create; + try + LStringList.LoadFromFile(TUtils.GetPathFileJSONProjects); + if not string(LStringList.Text).Trim.StartsWith('[') then + Exit; + + LJSONArray := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LStringList.Text), 0) as TJSONArray; + try + for i := 0 to Pred(LJSONArray.Count) do + begin + if not(LJSONArray.Items[i] is TJSONObject) then + Continue; + + LJSONObjItem := LJSONArray.Items[i] as TJSONObject; + if LJSONObjItem.GetValue(GUID) = AGuid then + begin + LJSONArray.Remove(i); + Break; + end; + end; + + {$IF CompilerVersion <= 32.0} //Tokyo + LStringList.Text := LJSONArray.ToJSON; + {$ELSE} + LStringList.Text := LJSONArray.Format(2); + {$ENDIF} + finally + LJSONArray.Free; + end; + + LStringList.SaveToFile(TUtils.GetPathFileJSONProjects); + finally + LStringList.Free; + end; +end; + +end. diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 9e70d19..dfca055 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -86,6 +86,7 @@ TUtils = class class function GetPathFileChatDB: string; class function GetPathFileJSONDefaultsQuestions: string; class function GetPathFileJSONDatabases: string; + class function GetPathFileJSONProjects: string; class function CreateIfNecessaryAndGetPathFolderTemp: string; class function GetPathFolderMetaInfo: string; class function GetGuidStr: string; @@ -786,6 +787,11 @@ class function TUtils.GetPathFileJSONDatabases: string; Result := Self.GetPathFolderRoot + TConsts.FILE_JSON_DATABASES; end; +class function TUtils.GetPathFileJSONProjects: string; +begin + Result := Self.GetPathFolderRoot + TConsts.FILE_JSON_PROJECTS; +end; + class function TUtils.CreateIfNecessaryAndGetPathFolderTemp: string; begin Result := Self.GetPathFolderRoot + TConsts.NAME_FOLDER_TEMP; From 47c80d1f9dfec1036b7df74553c6c914b4fb91de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 26 Aug 2024 16:45:33 -0300 Subject: [PATCH 041/109] add-projcts-addedit --- Package/DelphiAIDeveloper.dpk | 2 +- Package/DelphiAIDeveloper.dproj | 4 +- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 9 +++- Src/DB/Utils/DelphiAIDev.DB.Utils.pas | 19 +++---- ...elphiAIDev.PopupMenuProjects.OnExecute.pas | 6 +-- .../DelphiAIDev.Projects.AddEdit.View.dfm} | 15 +++--- .../DelphiAIDev.Projects.AddEdit.View.pas} | 49 ++++++++----------- .../DelphiAIDev.Projects.Interfaces.pas | 1 + Src/Projects/DelphiAIDev.Projects.Model.pas | 7 +++ 9 files changed, 57 insertions(+), 55 deletions(-) rename Src/{DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.dfm => Projects/DelphiAIDev.Projects.AddEdit.View.dfm} (88%) rename Src/{DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.pas => Projects/DelphiAIDev.Projects.AddEdit.View.pas} (68%) diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 33c7a50..e079891 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -101,7 +101,7 @@ contains DelphiAIDev.DB.References.View in '..\Src\DB\References\DelphiAIDev.DB.References.View.pas' {DelphiAIDevDBReferencesView}, DelphiAIDev.Utils.DBGrids in '..\Src\Utils\DelphiAIDev.Utils.DBGrids.pas', DelphiAIDev.AI.Ollama in '..\Src\AI\DelphiAIDev.AI.Ollama.pas', - DelphiAIDev.DB.LinkedProject.View in '..\Src\DB\LinkedProject\DelphiAIDev.DB.LinkedProject.View.pas' {DelphiAIDevDBLinkedProjectView}, + DelphiAIDev.Projects.AddEdit.View in '..\Src\Projects\DelphiAIDev.Projects.AddEdit.View.pas' {DelphiAIDevProjectsAddEditView}, DelphiAIDev.DB.Utils in '..\Src\DB\Utils\DelphiAIDev.DB.Utils.pas', DelphiAIDev.PopupMenuProjects.OnExecute in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.OnExecute.pas', DelphiAIDev.Projects.Fields in '..\Src\Projects\DelphiAIDev.Projects.Fields.pas', diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 0f42cb8..4c078d8 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -213,8 +213,8 @@ - -
DelphiAIDevDBLinkedProjectView
+ +
DelphiAIDevProjectsAddEditView
dfm
diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index e76c438..608b29d 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -37,7 +37,8 @@ interface DelphiAIDev.DB.Registers.Model, DelphiAIDev.DB.Registers.Fields, C4D.Conn, - DelphiAIDev.Utils.DBGrids; + DelphiAIDev.Utils.DBGrids, + DelphiAIDev.Projects.Model; type TDelphiAIDevDBChatView = class(TDockableForm) @@ -469,8 +470,12 @@ procedure TDelphiAIDevDBChatView.ChangeCodeOnly; end; procedure TDelphiAIDevDBChatView.ReloadDatabases; +var + LGuidDatabaseDefault: string; begin - TDelphiAIDevDBUtils.FillComboBoxDataBases(cBoxDatabases); + LGuidDatabaseDefault := TDelphiAIDevProjectsModel.New.ReadFilePathCurrentProject.GuidDatabaseDefault; + + TDelphiAIDevDBUtils.FillComboBoxDataBases(cBoxDatabases, LGuidDatabaseDefault); Self.FillDateLastReferences; end; diff --git a/Src/DB/Utils/DelphiAIDev.DB.Utils.pas b/Src/DB/Utils/DelphiAIDev.DB.Utils.pas index e2ae29b..29787a8 100644 --- a/Src/DB/Utils/DelphiAIDev.DB.Utils.pas +++ b/Src/DB/Utils/DelphiAIDev.DB.Utils.pas @@ -9,11 +9,9 @@ interface type TDelphiAIDevDBUtils = class private - public class procedure ClearComboBox(const AComboBox: TComboBox); - class procedure FillComboBoxDatabases(const AComboBox: TComboBox); - class procedure SelectByGuidDatabase(const AComboBox: TComboBox; const AGuidDatabase); + class procedure FillComboBoxDatabases(const AComboBox: TComboBox; const AGuidDatabaseDefault: string); end; implementation @@ -41,11 +39,14 @@ class procedure TDelphiAIDevDBUtils.ClearComboBox(const AComboBox: TComboBox); AComboBox.Items.Clear; end; -class procedure TDelphiAIDevDBUtils.FillComboBoxDatabases(const AComboBox: TComboBox); +class procedure TDelphiAIDevDBUtils.FillComboBoxDatabases(const AComboBox: TComboBox; const AGuidDatabaseDefault: string); var LField: TDelphiAIDevDBRegistersFields; + LFieldDefault: TDelphiAIDevDBRegistersFields; + FIndex: Integer; begin Self.ClearComboBox(AComboBox); + LFieldDefault := nil; TDelphiAIDevDBRegistersModel.New.ReadData( procedure(AFields: TDelphiAIDevDBRegistersFields) @@ -58,16 +59,16 @@ class procedure TDelphiAIDevDBUtils.FillComboBoxDatabases(const AComboBox: TComb LField := TDelphiAIDevDBRegistersFields.Create; LField.GetDataFromOtherObject(AFields); AComboBox.Items.AddObject(LField.Description, LField); + + if LField.Guid = AGuidDatabaseDefault then + LFieldDefault := LField; end; end ); AComboBox.ItemIndex := 0; -end; - -class procedure TDelphiAIDevDBUtils.SelectByGuidDatabase(const AComboBox: TComboBox; const AGuidDatabase); -begin - AComboBox + if LFieldDefault <> nil then + AComboBox.ItemIndex := AComboBox.Items.IndexOfObject(LFieldDefault); end; end. diff --git a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas index 6d14181..cd7f22e 100644 --- a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas +++ b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas @@ -21,7 +21,7 @@ implementation uses DelphiAIDev.Utils, - DelphiAIDev.DB.LinkedProject.View; + DelphiAIDev.Projects.AddEdit.View; procedure TDelphiAIDevPopupMenuProjectsOnExecute.CheckFileNameProject; begin @@ -34,11 +34,11 @@ procedure TDelphiAIDevPopupMenuProjectsOnExecute.CheckFileNameProject; procedure TDelphiAIDevPopupMenuProjectsOnExecute.LinkDatabase(const MenuContextList: IInterfaceList); var - LView: TDelphiAIDevDBLinkedProjectView; + LView: TDelphiAIDevProjectsAddEditView; begin Self.CheckFileNameProject; - LView := TDelphiAIDevDBLinkedProjectView.Create(nil); + LView := TDelphiAIDevProjectsAddEditView.Create(nil); try LView.OTAProject := FIOTAProject; LView.ShowModal; diff --git a/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.dfm b/Src/Projects/DelphiAIDev.Projects.AddEdit.View.dfm similarity index 88% rename from Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.dfm rename to Src/Projects/DelphiAIDev.Projects.AddEdit.View.dfm index 90ec90f..e0524e5 100644 --- a/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.dfm +++ b/Src/Projects/DelphiAIDev.Projects.AddEdit.View.dfm @@ -1,8 +1,8 @@ -object DelphiAIDevDBLinkedProjectView: TDelphiAIDevDBLinkedProjectView +object DelphiAIDevProjectsAddEditView: TDelphiAIDevProjectsAddEditView Left = 0 Top = 0 BorderIcons = [biSystemMenu] - Caption = 'IA Developer - Linked Databese With Project' + Caption = 'IA Developer - Project Config' ClientHeight = 213 ClientWidth = 629 Color = clBtnFace @@ -11,6 +11,7 @@ object DelphiAIDevDBLinkedProjectView: TDelphiAIDevDBLinkedProjectView Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] + KeyPreview = True OldCreateOrder = False Position = poScreenCenter OnClose = FormClose @@ -44,7 +45,6 @@ object DelphiAIDevDBLinkedProjectView: TDelphiAIDevDBLinkedProjectView BevelOuter = bvNone ParentBackground = False TabOrder = 0 - ExplicitWidth = 624 object Bevel1: TBevel AlignWithMargins = True Left = 0 @@ -97,8 +97,7 @@ object DelphiAIDevDBLinkedProjectView: TDelphiAIDevDBLinkedProjectView Padding.Bottom = 2 ParentBackground = False TabOrder = 1 - ExplicitWidth = 624 - object btnSaveLink: TButton + object btnConfirm: TButton AlignWithMargins = True Left = 401 Top = 2 @@ -109,10 +108,9 @@ object DelphiAIDevDBLinkedProjectView: TDelphiAIDevDBLinkedProjectView Margins.Top = 0 Margins.Bottom = 0 Align = alRight - Caption = 'Save link' + Caption = 'Confirm' TabOrder = 0 - OnClick = btnSaveLinkClick - ExplicitLeft = 396 + OnClick = btnConfirmClick end object btnClose: TButton AlignWithMargins = True @@ -128,7 +126,6 @@ object DelphiAIDevDBLinkedProjectView: TDelphiAIDevDBLinkedProjectView Caption = 'Close' TabOrder = 1 OnClick = btnCloseClick - ExplicitLeft = 509 end end end diff --git a/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.pas b/Src/Projects/DelphiAIDev.Projects.AddEdit.View.pas similarity index 68% rename from Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.pas rename to Src/Projects/DelphiAIDev.Projects.AddEdit.View.pas index 5813c8c..17ebf30 100644 --- a/Src/DB/LinkedProject/DelphiAIDev.DB.LinkedProject.View.pas +++ b/Src/Projects/DelphiAIDev.Projects.AddEdit.View.pas @@ -1,4 +1,4 @@ -unit DelphiAIDev.DB.LinkedProject.View; +unit DelphiAIDev.Projects.AddEdit.View; interface @@ -21,21 +21,21 @@ interface DelphiAIDev.Projects.Fields; type - TDelphiAIDevDBLinkedProjectView = class(TForm) + TDelphiAIDevProjectsAddEditView = class(TForm) Bevel2: TBevel; pnBody: TPanel; Bevel1: TBevel; Label1: TLabel; lbLastGeneration: TLabel; pnButtons: TPanel; - btnSaveLink: TButton; + btnConfirm: TButton; btnClose: TButton; cBoxDatabases: TComboBox; procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure btnCloseClick(Sender: TObject); - procedure btnSaveLinkClick(Sender: TObject); + procedure btnConfirmClick(Sender: TObject); procedure cBoxDatabasesClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); @@ -61,31 +61,30 @@ implementation {$R *.dfm} -procedure TDelphiAIDevDBLinkedProjectView.FormCreate(Sender: TObject); +procedure TDelphiAIDevProjectsAddEditView.FormCreate(Sender: TObject); begin Self.ModalResult := mrCancel; - TUtilsOTA.IDEThemingAll(TDelphiAIDevDBLinkedProjectView, Self); + TUtilsOTA.IDEThemingAll(TDelphiAIDevProjectsAddEditView, Self); end; -procedure TDelphiAIDevDBLinkedProjectView.FormDestroy(Sender: TObject); +procedure TDelphiAIDevProjectsAddEditView.FormDestroy(Sender: TObject); begin - //FProjectsFields.Free; + // end; -procedure TDelphiAIDevDBLinkedProjectView.FormShow(Sender: TObject); +procedure TDelphiAIDevProjectsAddEditView.FormShow(Sender: TObject); begin FProjectsFields := TDelphiAIDevProjectsModel.New.ReadFilePath(FOTAProject.FileName); - Self.FillScreenFields; end; -procedure TDelphiAIDevDBLinkedProjectView.FormClose(Sender: TObject; var Action: TCloseAction); +procedure TDelphiAIDevProjectsAddEditView.FormClose(Sender: TObject; var Action: TCloseAction); begin if Assigned(FProjectsFields)then FProjectsFields.Free; end; -procedure TDelphiAIDevDBLinkedProjectView.FillScreenFields; +procedure TDelphiAIDevProjectsAddEditView.FillScreenFields; begin Screen.Cursor := crHourGlass; try @@ -95,21 +94,13 @@ procedure TDelphiAIDevDBLinkedProjectView.FillScreenFields; end; end; -procedure TDelphiAIDevDBLinkedProjectView.FillcBoxDatabases; -var - LDBRegistersFields: TDelphiAIDevDBRegistersFields; +procedure TDelphiAIDevProjectsAddEditView.FillcBoxDatabases; begin - TDelphiAIDevDBUtils.FillComboBoxDataBases(cBoxDatabases); - - LDBRegistersFields := TDelphiAIDevDBRegistersModel.New.Re - -// if not FProjectsFields.GuidDatabaseDefault.Trim.IsEmpty then -// cBoxDatabases.ItemIndex := cBoxDatabases.Items.IndexOf(FProjectsFields); - + TDelphiAIDevDBUtils.FillComboBoxDataBases(cBoxDatabases, FProjectsFields.GuidDatabaseDefault); Self.FillDateLastReferences; end; -procedure TDelphiAIDevDBLinkedProjectView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +procedure TDelphiAIDevProjectsAddEditView.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of VK_F4: @@ -121,12 +112,12 @@ procedure TDelphiAIDevDBLinkedProjectView.FormKeyDown(Sender: TObject; var Key: end; end; -procedure TDelphiAIDevDBLinkedProjectView.cBoxDatabasesClick(Sender: TObject); +procedure TDelphiAIDevProjectsAddEditView.cBoxDatabasesClick(Sender: TObject); begin Self.FillDateLastReferences; end; -procedure TDelphiAIDevDBLinkedProjectView.FillDateLastReferences; +procedure TDelphiAIDevProjectsAddEditView.FillDateLastReferences; begin lbLastGeneration.Caption := ''; @@ -136,18 +127,18 @@ procedure TDelphiAIDevDBLinkedProjectView.FillDateLastReferences; lbLastGeneration.Caption := TUtils.DateTimeToStrEmpty(Self.GetFieldDBSelected.LastReferences); end; -function TDelphiAIDevDBLinkedProjectView.GetFieldDBSelected: TDelphiAIDevDBRegistersFields; +function TDelphiAIDevProjectsAddEditView.GetFieldDBSelected: TDelphiAIDevDBRegistersFields; begin Result := TDelphiAIDevDBRegistersFields(cBoxDatabases.Items.Objects[cBoxDatabases.ItemIndex]); end; -procedure TDelphiAIDevDBLinkedProjectView.btnCloseClick(Sender: TObject); +procedure TDelphiAIDevProjectsAddEditView.btnCloseClick(Sender: TObject); begin Self.Close; Self.ModalResult := mrCancel; end; -procedure TDelphiAIDevDBLinkedProjectView.btnSaveLinkClick(Sender: TObject); +procedure TDelphiAIDevProjectsAddEditView.btnConfirmClick(Sender: TObject); begin Self.ValidateFillingFields; @@ -165,7 +156,7 @@ procedure TDelphiAIDevDBLinkedProjectView.btnSaveLinkClick(Sender: TObject); Self.ModalResult := mrOk; end; -procedure TDelphiAIDevDBLinkedProjectView.ValidateFillingFields; +procedure TDelphiAIDevProjectsAddEditView.ValidateFillingFields; begin if cBoxDatabases.ItemIndex < 0 then TUtils.ShowMsgAndAbort('No informed Database', cBoxDatabases); diff --git a/Src/Projects/DelphiAIDev.Projects.Interfaces.pas b/Src/Projects/DelphiAIDev.Projects.Interfaces.pas index e528d41..36caa95 100644 --- a/Src/Projects/DelphiAIDev.Projects.Interfaces.pas +++ b/Src/Projects/DelphiAIDev.Projects.Interfaces.pas @@ -11,6 +11,7 @@ interface IDelphiAIDevProjectsModel = interface ['{D919A407-4301-447F-A267-6965153DC01A}'] function ReadGuid(const AGuid: string): TDelphiAIDevProjectsFields; + function ReadFilePathCurrentProject: TDelphiAIDevProjectsFields; function ReadFilePath(const AFilePath: string): TDelphiAIDevProjectsFields; procedure ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); procedure SaveOrEditData(AFields: TDelphiAIDevProjectsFields); diff --git a/Src/Projects/DelphiAIDev.Projects.Model.pas b/Src/Projects/DelphiAIDev.Projects.Model.pas index 0011ac1..c4dec2f 100644 --- a/Src/Projects/DelphiAIDev.Projects.Model.pas +++ b/Src/Projects/DelphiAIDev.Projects.Model.pas @@ -8,6 +8,7 @@ interface System.JSON, Rest.JSON, DelphiAIDev.Utils, + DelphiAIDev.Utils.OTA, DelphiAIDev.Types, DelphiAIDev.Projects.Interfaces, DelphiAIDev.Projects.Fields; @@ -20,6 +21,7 @@ TDelphiAIDevProjectsModel = class(TInterfacedObject, IDelphiAIDevProjectsModel procedure FillField(const AJSONObjItem: TJSONObject; var AField: TDelphiAIDevProjectsFields); protected function ReadGuid(const AGuid: string): TDelphiAIDevProjectsFields; + function ReadFilePathCurrentProject: TDelphiAIDevProjectsFields; function ReadFilePath(const AFilePath: string): TDelphiAIDevProjectsFields; procedure ReadData(AProc: TProc; const AAutoFreeField: TAutoFreeField = TAutoFreeField.Yes); procedure SaveOrEditData(AFields: TDelphiAIDevProjectsFields); @@ -89,6 +91,11 @@ function TDelphiAIDevProjectsModel.ReadGuid(const AGuid: string): TDelphiAIDevPr end; end; +function TDelphiAIDevProjectsModel.ReadFilePathCurrentProject: TDelphiAIDevProjectsFields; +begin + Result := Self.ReadFilePath(TUtilsOTA.GetCurrentProjectFileName); +end; + function TDelphiAIDevProjectsModel.ReadFilePath(const AFilePath: string): TDelphiAIDevProjectsFields; var LStringList: TStringList; From 391c2cc861fa711a06fa41eec60571cc0727c50a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 26 Aug 2024 17:01:02 -0300 Subject: [PATCH 042/109] bk/2024-08-26-1701 --- Src/Consts/DelphiAIDev.Consts.pas | 2 +- Src/DB/Utils/DelphiAIDev.DB.Utils.pas | 1 - ...elphiAIDev.PopupMenuProjects.OnExecute.pas | 4 +- .../DelphiAIDev.PopupMenuProjects.pas | 4 +- .../DelphiAIDev.Projects.AddEdit.View.dfm | 47 +++++++++++++++---- .../DelphiAIDev.Projects.AddEdit.View.pas | 24 ++++++---- Src/Projects/DelphiAIDev.Projects.Fields.pas | 8 ++-- Src/Projects/DelphiAIDev.Projects.Model.pas | 12 ++--- 8 files changed, 68 insertions(+), 34 deletions(-) diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index bc9c8bf..ba55055 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -68,7 +68,7 @@ TConsts = class //CAPTIONS ITENS POPUPMENU PROJ ITEM_POPUP_MENU_PROJ_CAPTION = 'AI Developer'; - ITEM_POPUP_MENU_PROJ_LinkDatabase_CAPTION = 'Link database'; + ITEM_POPUP_MENU_PROJ_EditInformation_CAPTION = 'Edit Information'; //MAIN MENU IDE NAME AND CAPTIONS MENU_IDE_CHAT_NAME = 'DelphiAIDevChat1'; diff --git a/Src/DB/Utils/DelphiAIDev.DB.Utils.pas b/Src/DB/Utils/DelphiAIDev.DB.Utils.pas index 29787a8..649afbd 100644 --- a/Src/DB/Utils/DelphiAIDev.DB.Utils.pas +++ b/Src/DB/Utils/DelphiAIDev.DB.Utils.pas @@ -43,7 +43,6 @@ class procedure TDelphiAIDevDBUtils.FillComboBoxDatabases(const AComboBox: TComb var LField: TDelphiAIDevDBRegistersFields; LFieldDefault: TDelphiAIDevDBRegistersFields; - FIndex: Integer; begin Self.ClearComboBox(AComboBox); LFieldDefault := nil; diff --git a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas index cd7f22e..74cba54 100644 --- a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas +++ b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.OnExecute.pas @@ -13,7 +13,7 @@ TDelphiAIDevPopupMenuProjectsOnExecute = class FIOTAProject: IOTAProject; procedure CheckFileNameProject; public - procedure LinkDatabase(const MenuContextList: IInterfaceList); + procedure EditInformation(const MenuContextList: IInterfaceList); property OTAProject: IOTAProject write FIOTAProject; end; @@ -32,7 +32,7 @@ procedure TDelphiAIDevPopupMenuProjectsOnExecute.CheckFileNameProject; // TUtils.ShowMsgAndAbort('Project file not found'); end; -procedure TDelphiAIDevPopupMenuProjectsOnExecute.LinkDatabase(const MenuContextList: IInterfaceList); +procedure TDelphiAIDevPopupMenuProjectsOnExecute.EditInformation(const MenuContextList: IInterfaceList); var LView: TDelphiAIDevProjectsAddEditView; begin diff --git a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas index cf253e6..8fb874a 100644 --- a/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas +++ b/Src/PopupMenuProjects/DelphiAIDev.PopupMenuProjects.pas @@ -83,8 +83,8 @@ procedure TC4DWizardIDEPopupMenuNotifier.AddMenu(const Project: IOTAProject; con ProjectManagerMenuList.Add(Self.AddItemInMenu('-')); ProjectManagerMenuList.Add(Self.AddItemInMenu(TConsts.ITEM_POPUP_MENU_PROJ_CAPTION)); - ProjectManagerMenuList.Add(Self.AddSubItemInMenu(TConsts.ITEM_POPUP_MENU_PROJ_LinkDatabase_CAPTION, - FOnExecute.LinkDatabase)); + ProjectManagerMenuList.Add(Self.AddSubItemInMenu(TConsts.ITEM_POPUP_MENU_PROJ_EditInformation_CAPTION, + FOnExecute.EditInformation)); end; function TC4DWizardIDEPopupMenuNotifier.AddItemInMenu(const ACaption: string): IOTAProjectManagerMenu; diff --git a/Src/Projects/DelphiAIDev.Projects.AddEdit.View.dfm b/Src/Projects/DelphiAIDev.Projects.AddEdit.View.dfm index e0524e5..bc09ff6 100644 --- a/Src/Projects/DelphiAIDev.Projects.AddEdit.View.dfm +++ b/Src/Projects/DelphiAIDev.Projects.AddEdit.View.dfm @@ -3,7 +3,7 @@ object DelphiAIDevProjectsAddEditView: TDelphiAIDevProjectsAddEditView Top = 0 BorderIcons = [biSystemMenu] Caption = 'IA Developer - Project Config' - ClientHeight = 213 + ClientHeight = 230 ClientWidth = 629 Color = clBtnFace Font.Charset = DEFAULT_CHARSET @@ -24,7 +24,7 @@ object DelphiAIDevProjectsAddEditView: TDelphiAIDevProjectsAddEditView object Bevel2: TBevel AlignWithMargins = True Left = 0 - Top = 174 + Top = 191 Width = 629 Height = 1 Margins.Left = 0 @@ -40,7 +40,7 @@ object DelphiAIDevProjectsAddEditView: TDelphiAIDevProjectsAddEditView Left = 0 Top = 0 Width = 629 - Height = 174 + Height = 191 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -48,7 +48,7 @@ object DelphiAIDevProjectsAddEditView: TDelphiAIDevProjectsAddEditView object Bevel1: TBevel AlignWithMargins = True Left = 0 - Top = 170 + Top = 187 Width = 629 Height = 1 Margins.Left = 0 @@ -61,31 +61,58 @@ object DelphiAIDevProjectsAddEditView: TDelphiAIDevProjectsAddEditView end object Label1: TLabel Left = 24 - Top = 101 + Top = 135 Width = 79 Height = 13 Caption = 'Last generation:' end object lbLastGeneration: TLabel Left = 109 - Top = 101 + Top = 135 Width = 81 Height = 13 Caption = 'lbLastGeneration' end - object cBoxDatabases: TComboBox + object Label2: TLabel Left = 24 - Top = 77 + Top = 43 + Width = 55 + Height = 13 + Caption = 'Nickname' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False + end + object Label3: TLabel + Left = 24 + Top = 95 + Width = 84 + Height = 13 + Caption = 'Database Default' + end + object cBoxDatabaseDefault: TComboBox + Left = 24 + Top = 111 Width = 577 Height = 21 Style = csDropDownList + TabOrder = 1 + OnClick = cBoxDatabaseDefaultClick + end + object edtNickname: TEdit + Left = 24 + Top = 59 + Width = 577 + Height = 21 TabOrder = 0 - OnClick = cBoxDatabasesClick end end object pnButtons: TPanel Left = 0 - Top = 178 + Top = 195 Width = 629 Height = 35 Align = alBottom diff --git a/Src/Projects/DelphiAIDev.Projects.AddEdit.View.pas b/Src/Projects/DelphiAIDev.Projects.AddEdit.View.pas index 17ebf30..a619608 100644 --- a/Src/Projects/DelphiAIDev.Projects.AddEdit.View.pas +++ b/Src/Projects/DelphiAIDev.Projects.AddEdit.View.pas @@ -30,13 +30,16 @@ TDelphiAIDevProjectsAddEditView = class(TForm) pnButtons: TPanel; btnConfirm: TButton; btnClose: TButton; - cBoxDatabases: TComboBox; + cBoxDatabaseDefault: TComboBox; + Label2: TLabel; + edtNickname: TEdit; + Label3: TLabel; procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure btnCloseClick(Sender: TObject); procedure btnConfirmClick(Sender: TObject); - procedure cBoxDatabasesClick(Sender: TObject); + procedure cBoxDatabaseDefaultClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private @@ -88,6 +91,7 @@ procedure TDelphiAIDevProjectsAddEditView.FillScreenFields; begin Screen.Cursor := crHourGlass; try + edtNickname.Text := FProjectsFields.Nickname; Self.FillcBoxDatabases; finally Screen.Cursor := crDefault; @@ -96,7 +100,7 @@ procedure TDelphiAIDevProjectsAddEditView.FillScreenFields; procedure TDelphiAIDevProjectsAddEditView.FillcBoxDatabases; begin - TDelphiAIDevDBUtils.FillComboBoxDataBases(cBoxDatabases, FProjectsFields.GuidDatabaseDefault); + TDelphiAIDevDBUtils.FillComboBoxDataBases(cBoxDatabaseDefault, FProjectsFields.GuidDatabaseDefault); Self.FillDateLastReferences; end; @@ -112,7 +116,7 @@ procedure TDelphiAIDevProjectsAddEditView.FormKeyDown(Sender: TObject; var Key: end; end; -procedure TDelphiAIDevProjectsAddEditView.cBoxDatabasesClick(Sender: TObject); +procedure TDelphiAIDevProjectsAddEditView.cBoxDatabaseDefaultClick(Sender: TObject); begin Self.FillDateLastReferences; end; @@ -121,7 +125,7 @@ procedure TDelphiAIDevProjectsAddEditView.FillDateLastReferences; begin lbLastGeneration.Caption := ''; - if cBoxDatabases.Items.Count < 0 then + if cBoxDatabaseDefault.Items.Count < 0 then Exit; lbLastGeneration.Caption := TUtils.DateTimeToStrEmpty(Self.GetFieldDBSelected.LastReferences); @@ -129,7 +133,7 @@ procedure TDelphiAIDevProjectsAddEditView.FillDateLastReferences; function TDelphiAIDevProjectsAddEditView.GetFieldDBSelected: TDelphiAIDevDBRegistersFields; begin - Result := TDelphiAIDevDBRegistersFields(cBoxDatabases.Items.Objects[cBoxDatabases.ItemIndex]); + Result := TDelphiAIDevDBRegistersFields(cBoxDatabaseDefault.Items.Objects[cBoxDatabaseDefault.ItemIndex]); end; procedure TDelphiAIDevProjectsAddEditView.btnCloseClick(Sender: TObject); @@ -145,6 +149,7 @@ procedure TDelphiAIDevProjectsAddEditView.btnConfirmClick(Sender: TObject); Screen.Cursor := crHourGlass; try FProjectsFields.FilePath := FOTAProject.FileName; + FProjectsFields.Nickname := edtNickname.Text; FProjectsFields.GuidDatabaseDefault := Self.GetFieldDBSelected.Guid; TDelphiAIDevProjectsModel.New.SaveOrEditData(FProjectsFields); @@ -158,8 +163,11 @@ procedure TDelphiAIDevProjectsAddEditView.btnConfirmClick(Sender: TObject); procedure TDelphiAIDevProjectsAddEditView.ValidateFillingFields; begin - if cBoxDatabases.ItemIndex < 0 then - TUtils.ShowMsgAndAbort('No informed Database', cBoxDatabases); + if Trim(edtNickname.Text).IsEmpty then + TUtils.ShowMsgAndAbort('No informed Nickname', edtNickname); + +// if cBoxDatabaseDefault.ItemIndex < 0 then +// TUtils.ShowMsgAndAbort('No informed Database', cBoxDatabaseDefault); end; end. diff --git a/Src/Projects/DelphiAIDev.Projects.Fields.pas b/Src/Projects/DelphiAIDev.Projects.Fields.pas index 5906092..2b6ac26 100644 --- a/Src/Projects/DelphiAIDev.Projects.Fields.pas +++ b/Src/Projects/DelphiAIDev.Projects.Fields.pas @@ -10,7 +10,7 @@ TDelphiAIDevProjectsFields = class private FGuid: string; FFilePath: string; - FDescription: string; + FNickname: string; FGuidDatabaseDefault: string; public constructor Create; @@ -18,7 +18,7 @@ TDelphiAIDevProjectsFields = class procedure GetDataFromOtherObject(const AOtherObj: TDelphiAIDevProjectsFields); property Guid: string read FGuid write FGuid; property FilePath: string read FFilePath write FFilePath; - property Description: string read FDescription write FDescription; + property Nickname: string read FNickname write FNickname; property GuidDatabaseDefault: string read FGuidDatabaseDefault write FGuidDatabaseDefault; end; @@ -33,14 +33,14 @@ procedure TDelphiAIDevProjectsFields.Clear; begin FGuid := ''; FFilePath := ''; - FDescription := ''; + FNickname := ''; FGuidDatabaseDefault := ''; end; procedure TDelphiAIDevProjectsFields.GetDataFromOtherObject(const AOtherObj: TDelphiAIDevProjectsFields); begin FGuid := AOtherObj.Guid; - FDescription := AOtherObj.Description; + FNickname := AOtherObj.Nickname; FFilePath := AOtherObj.FilePath; FGuidDatabaseDefault := AOtherObj.GuidDatabaseDefault; end; diff --git a/Src/Projects/DelphiAIDev.Projects.Model.pas b/Src/Projects/DelphiAIDev.Projects.Model.pas index c4dec2f..1a9469e 100644 --- a/Src/Projects/DelphiAIDev.Projects.Model.pas +++ b/Src/Projects/DelphiAIDev.Projects.Model.pas @@ -36,7 +36,7 @@ implementation const GUID = 'guid'; FILE_PATH = 'file_path'; - DESCRIPTION = 'description'; + NICKNAME = 'Nickname'; GUID_DATABASE_DEFAULT = 'guid_database_default'; class function TDelphiAIDevProjectsModel.New: IDelphiAIDevProjectsModel; @@ -150,8 +150,8 @@ procedure TDelphiAIDevProjectsModel.FillField(const AJSONObjItem: TJSONObject; if AJSONObjItem.GetValue(FILE_PATH) <> nil then AField.FilePath := AJSONObjItem.GetValue(FILE_PATH); - if AJSONObjItem.GetValue(DESCRIPTION) <> nil then - AField.Description := AJSONObjItem.GetValue(DESCRIPTION); + if AJSONObjItem.GetValue(NICKNAME) <> nil then + AField.Nickname := AJSONObjItem.GetValue(NICKNAME); if AJSONObjItem.GetValue(GUID_DATABASE_DEFAULT) <> nil then AField.GuidDatabaseDefault := AJSONObjItem.GetValue(GUID_DATABASE_DEFAULT); @@ -233,7 +233,7 @@ procedure TDelphiAIDevProjectsModel.SaveData(AFields: TDelphiAIDevProjectsFields LJSONObject := TJSONObject.Create; LJSONObject.AddPair(GUID, TUtils.GetGuidStr); LJSONObject.AddPair(FILE_PATH, AFields.FilePath); - LJSONObject.AddPair(DESCRIPTION, AFields.Description); + LJSONObject.AddPair(NICKNAME, AFields.Nickname); LJSONObject.AddPair(GUID_DATABASE_DEFAULT, AFields.GuidDatabaseDefault); LJSONArray.AddElement(LJSONObject); @@ -281,8 +281,8 @@ procedure TDelphiAIDevProjectsModel.EditData(AFields: TDelphiAIDevProjectsFields LJSONObjItem.RemovePair(FILE_PATH).Free; LJSONObjItem.AddPair(FILE_PATH, AFields.FilePath); - LJSONObjItem.RemovePair(DESCRIPTION).Free; - LJSONObjItem.AddPair(DESCRIPTION, AFields.Description); + LJSONObjItem.RemovePair(NICKNAME).Free; + LJSONObjItem.AddPair(NICKNAME, AFields.Nickname); LJSONObjItem.RemovePair(GUID_DATABASE_DEFAULT).Free; LJSONObjItem.AddPair(GUID_DATABASE_DEFAULT, AFields.GuidDatabaseDefault); From 7067a5aaf7a54fa639cc60074131cd4ca53a4a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 26 Aug 2024 17:59:11 -0300 Subject: [PATCH 043/109] Update DelphiAIDev.DB.Chat.View.pas --- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 55 +++++++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 608b29d..bb11e10 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -149,7 +149,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) FbtnDefaultsQuestionsWidth: Integer; FQuestionOnShow: string; FConn: IC4DConn; - FQuery: IC4DConnQuery; + FQueryExecuteSQL: IC4DConnQuery; procedure FillMemoReturnWithFile; procedure SaveMemoReturnInFile; procedure InitializeRichEditReturn; @@ -172,6 +172,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure FillDateLastReferences; function GetFieldDBSelected: TDelphiAIDevDBRegistersFields; function GetJsonDatabase: string; + procedure HandleErrorExecutingSQLCommand(const E: Exception); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -239,7 +240,8 @@ constructor TDelphiAIDevDBChatView.Create(AOwner: TComponent); FQuestionOnShow := ''; FConn := TC4DConn.New; - FQuery := FConn.Query.DataSource(DataSource1); + FQueryExecuteSQL := FConn.Query.DataSource(DataSource1); + Self.ConfScreenOnCreate; Self.FillMemoReturnWithFile; @@ -770,8 +772,13 @@ function TDelphiAIDevDBChatView.GetJsonDatabase: string; procedure TDelphiAIDevDBChatView.btnExecuteSQLClick(Sender: TObject); var + LCommand: string; LField: TDelphiAIDevDBRegistersFields; begin + LCommand := Trim(mmReturn.Lines.Text); + if LCommand.IsEmpty then + TUtils.ShowMsgAndAbort('No SQL command informed'); + Screen.Cursor := crHourGlass; try lbCount.Caption := '000000'; @@ -794,14 +801,48 @@ procedure TDelphiAIDevDBChatView.btnExecuteSQLClick(Sender: TObject); TUtils.ShowMsgErrorAndAbort(E.Message); end; - TUtils.ShowMsg(mmReturn.Lines.Text); - FQuery.CloseClear.Add(Trim(mmReturn.Lines.Text)).Open; - lbCount.Caption := FQuery.RecordCountStr; + try + FQueryExecuteSQL.CloseClear.Add(LCommand).Open; + except + on E: Exception do + Self.HandleErrorExecutingSQLCommand(E); + end; + + lbCount.Caption := FQueryExecuteSQL.RecordCountStr; finally Screen.Cursor := crDefault; end; end; +procedure TDelphiAIDevDBChatView.HandleErrorExecutingSQLCommand(const E: Exception); +var + LCommand: string; + LMsg: string; +begin + LCommand := Trim(mmReturn.Lines.Text).ToLower; + LMsg := 'Unable to execute command.'; + + if LCommand.Contains('insert') then + LMsg := LMsg + sLineBreak + 'Insert commands are blocked'; + + if LCommand.Contains('update') then + LMsg := LMsg + sLineBreak + 'Update commands are blocked'; + + if LCommand.Contains('delete') then + LMsg := LMsg + sLineBreak + 'Delete commands are blocked'; + + if LCommand.Contains('drop') then + LMsg := LMsg + sLineBreak + 'Drop commands are blocked'; + + if LCommand.Contains('create') then + LMsg := LMsg + sLineBreak + 'Create commands are blocked'; + + if LMsg.Trim.IsEmpty then + LMsg := LMsg + sLineBreak + E.Message; + + TUtils.ShowMsgErrorAndAbort(LMsg.Trim, E.Message); +end; + procedure TDelphiAIDevDBChatView.CopyCurrentColumn1Click(Sender: TObject); begin TUtilsDBGrids.DBGridToClipboardCurrentColumn(DBGrid1); @@ -842,10 +883,10 @@ procedure TDelphiAIDevDBChatView.DBGrid1TitleClick(Column: TColumn); Exit; LOrdem := LCampo + ':D'; - if FQuery.IndexFieldNames.Contains(':D') then + if FQueryExecuteSQL.IndexFieldNames.Contains(':D') then LOrdem := LCampo; - FQuery.IndexFieldNames(LOrdem); + FQueryExecuteSQL.IndexFieldNames(LOrdem); end; initialization From a9e659514d307e1a78cffce8f2669645b81c72de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 26 Aug 2024 22:54:27 -0300 Subject: [PATCH 044/109] bk/2024-08-26-2254 --- Src/Conn/C4D.Conn.Firedac.pas | 2 +- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 27 +++++++++++++++--- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 28 ++++++++++++++++++- .../DelphiAIDev.DB.Registers.View.dfm | 1 - 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/Src/Conn/C4D.Conn.Firedac.pas b/Src/Conn/C4D.Conn.Firedac.pas index 2782cac..c6ccf1a 100644 --- a/Src/Conn/C4D.Conn.Firedac.pas +++ b/Src/Conn/C4D.Conn.Firedac.pas @@ -165,7 +165,7 @@ function TC4DConnFiredac.TestConnection: Boolean; try Self.LoadConnectionConfig; LConnectedOld := FConnection.Connected; - FConnection.Close; // + FConnection.Close; FConnection.Open; Result := FConnection.Connected; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 2283560..cc3c49d 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -334,16 +334,19 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView ExplicitHeight = 13 end object lbLastGeneration: TLabel + AlignWithMargins = True Left = 422 Top = 0 - Width = 120 + Width = 81 Height = 25 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 5 + Margins.Bottom = 0 Align = alLeft - AutoSize = False Caption = 'lbLastGeneration' Layout = tlCenter - ExplicitLeft = 585 - ExplicitTop = 3 + ExplicitHeight = 13 end object btnExecuteSQL: TButton AlignWithMargins = True @@ -374,6 +377,22 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView TabOrder = 1 OnClick = cBoxDatabasesClick end + object btnGenerateDatabaseReference: TButton + AlignWithMargins = True + Left = 508 + Top = 0 + Width = 58 + Height = 25 + Cursor = crHandPoint + Margins.Left = 0 + Margins.Top = 0 + Margins.Bottom = 0 + Align = alLeft + Caption = 'Generate' + TabOrder = 2 + OnClick = btnGenerateDatabaseReferenceClick + ExplicitLeft = 503 + end end end object pnWait: TPanel diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index bb11e10..3b4dc01 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -38,7 +38,8 @@ interface DelphiAIDev.DB.Registers.Fields, C4D.Conn, DelphiAIDev.Utils.DBGrids, - DelphiAIDev.Projects.Model; + DelphiAIDev.Projects.Model, + DelphiAIDev.DB.References.View; type TDelphiAIDevDBChatView = class(TDockableForm) @@ -102,6 +103,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) lbCount: TLabel; Label3: TLabel; Ollama1: TMenuItem; + btnGenerateDatabaseReference: TButton; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); procedure Cut1Click(Sender: TObject); @@ -139,6 +141,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure SaveAllGridDataAsCSVClick(Sender: TObject); procedure SaveAllGridDataAsTXTClick(Sender: TObject); procedure DBGrid1TitleClick(Column: TColumn); + procedure btnGenerateDatabaseReferenceClick(Sender: TObject); private FChat: TDelphiAIDevChat; FSettings: TDelphiAIDevSettings; @@ -675,6 +678,29 @@ procedure TDelphiAIDevDBChatView.FillDateLastReferences; lbLastGeneration.Caption := TUtils.DateTimeToStrEmpty(Self.GetFieldDBSelected.LastReferences); end; +procedure TDelphiAIDevDBChatView.btnGenerateDatabaseReferenceClick(Sender: TObject); +var + LView: TDelphiAIDevDBReferencesView; + LFields: TDelphiAIDevDBRegistersFields; +begin + if cBoxDatabases.Items.Count < 0 then + Exit; + + LFields := Self.GetFieldDBSelected; + if LFields = nil then + Exit; + + LView := TDelphiAIDevDBReferencesView.Create(nil); + try + LView.Fields := LFields; + if LView.ShowModal = mrOk then + Self.FillDateLastReferences; + finally + LView.Free; + end; +end; + + function TDelphiAIDevDBChatView.GetFieldDBSelected: TDelphiAIDevDBRegistersFields; begin Result := TDelphiAIDevDBRegistersFields(cBoxDatabases.Items.Objects[cBoxDatabases.ItemIndex]); diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm index a734729..0f5b3e9 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.View.dfm @@ -48,7 +48,6 @@ object DelphiAIDevDBRegistersView: TDelphiAIDevDBRegistersView Caption = 'Edit' TabOrder = 0 OnClick = btnEditClick - ExplicitTop = 1 end object btnClose: TButton AlignWithMargins = True From be5cd836fb437643166c6d4ebfdd12ee94e996fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 27 Aug 2024 09:39:22 -0300 Subject: [PATCH 045/109] refactor/rename-Shortcuts-to-KeyboardBinding --- Package/DelphiAIDeveloper.dpk | 2 +- Package/DelphiAIDeveloper.dproj | 2 +- Src/DelphiAIDev.Register.pas | 4 ++-- .../DelphiAIDev.KeyboardBinding.pas} | 20 +++++++++---------- 4 files changed, 14 insertions(+), 14 deletions(-) rename Src/{IDE/Shortcuts/DelphiAIDev.IDE.Shortcuts.pas => KeyboardBinding/DelphiAIDev.KeyboardBinding.pas} (76%) diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index e079891..61a439c 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -68,7 +68,7 @@ contains DelphiAIDev.ModuleCreator in '..\Src\ModuleCreator\DelphiAIDev.ModuleCreator.pas', DelphiAIDev.ModuleCreator.Interfaces in '..\Src\ModuleCreator\DelphiAIDev.ModuleCreator.Interfaces.pas', DelphiAIDev.IDE.ImageListMain in '..\Src\IDE\ImageListMain\DelphiAIDev.IDE.ImageListMain.pas', - DelphiAIDev.IDE.Shortcuts in '..\Src\IDE\Shortcuts\DelphiAIDev.IDE.Shortcuts.pas', + DelphiAIDev.KeyboardBinding in '..\Src\KeyboardBinding\DelphiAIDev.KeyboardBinding.pas', DelphiAIDev.Utils.CnWizard in '..\Src\Utils\DelphiAIDev.Utils.CnWizard.pas', DelphiAIDev.DB.Registers.View in '..\Src\DB\Registers\DelphiAIDev.DB.Registers.View.pas' {DelphiAIDevDBRegistersView}, DelphiAIDev.Utils.ListView in '..\Src\Utils\DelphiAIDev.Utils.ListView.pas', diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 4c078d8..f98b79d 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -167,7 +167,7 @@ - +
DelphiAIDevDBRegistersView
diff --git a/Src/DelphiAIDev.Register.pas b/Src/DelphiAIDev.Register.pas index 06dd643..3851259 100644 --- a/Src/DelphiAIDev.Register.pas +++ b/Src/DelphiAIDev.Register.pas @@ -5,7 +5,7 @@ interface uses DelphiAIDev.Chat.View, DelphiAIDev.MainMenu.Register, - DelphiAIDev.IDE.Shortcuts, + DelphiAIDev.KeyboardBinding, DelphiAIDev.PopupMenuProjects, DelphiAIDev.DB.Chat.View; @@ -17,7 +17,7 @@ procedure Register; begin DelphiAIDev.Chat.View.RegisterSelf; DelphiAIDev.MainMenu.Register.RegisterSelf; - DelphiAIDev.IDE.Shortcuts.RefreshRegister; + DelphiAIDev.KeyboardBinding.RefreshRegister; DelphiAIDev.PopupMenuProjects.RegisterSelf; DelphiAIDev.DB.Chat.View.RegisterSelf; end; diff --git a/Src/IDE/Shortcuts/DelphiAIDev.IDE.Shortcuts.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas similarity index 76% rename from Src/IDE/Shortcuts/DelphiAIDev.IDE.Shortcuts.pas rename to Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 6ca9253..2ae02b2 100644 --- a/Src/IDE/Shortcuts/DelphiAIDev.IDE.Shortcuts.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -1,4 +1,4 @@ -unit DelphiAIDev.IDE.Shortcuts; +unit DelphiAIDev.KeyboardBinding; interface @@ -12,7 +12,7 @@ interface DelphiAIDev.Chat.View; type - TDelphiAIDevIDEShortcuts = class(TNotifierObject, IOTAKeyboardBinding) + TDelphiAIDevKeyboardBinding = class(TNotifierObject, IOTAKeyboardBinding) private //procedure KeyProcBlockReturn(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); procedure KeyProcBlockReturnAndAlt(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); @@ -39,7 +39,7 @@ implementation procedure RegisterSelf; begin if Index < 0 then - Index := TUtilsOTA.GetIOTAKeyboardServices.AddKeyboardBinding(TDelphiAIDevIDEShortcuts.New); + Index := TUtilsOTA.GetIOTAKeyboardServices.AddKeyboardBinding(TDelphiAIDevKeyboardBinding.New); end; procedure UnRegisterSelf; @@ -57,27 +57,27 @@ procedure RefreshRegister; RegisterSelf; end; -class function TDelphiAIDevIDEShortcuts.New: IOTAKeyboardBinding; +class function TDelphiAIDevKeyboardBinding.New: IOTAKeyboardBinding; begin Result := Self.Create; end; -function TDelphiAIDevIDEShortcuts.GetBindingType: TBindingType; +function TDelphiAIDevKeyboardBinding.GetBindingType: TBindingType; begin Result := btPartial; end; -function TDelphiAIDevIDEShortcuts.GetDisplayName: string; +function TDelphiAIDevKeyboardBinding.GetDisplayName: string; begin Result := Self.ClassName; end; -function TDelphiAIDevIDEShortcuts.GetName: string; +function TDelphiAIDevKeyboardBinding.GetName: string; begin Result := Self.ClassName; end; -procedure TDelphiAIDevIDEShortcuts.BindKeyboard(const BindingServices: IOTAKeyBindingServices); +procedure TDelphiAIDevKeyboardBinding.BindKeyboard(const BindingServices: IOTAKeyBindingServices); begin // if TUtilsOTA.CurrentProjectIsDelphiAIDeveloperDPROJ then // Exit; @@ -86,7 +86,7 @@ procedure TDelphiAIDevIDEShortcuts.BindKeyboard(const BindingServices: IOTAKeyBi BindingServices.AddKeyBinding([Shortcut(VK_RETURN, [ssAlt])], Self.KeyProcBlockReturnAndAlt, nil); end; -//procedure TDelphiAIDevIDEShortcuts.KeyProcBlockReturn(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); +//procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturn(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); //begin // if KeyCode <> Shortcut(VK_RETURN, []) then // Exit; @@ -95,7 +95,7 @@ procedure TDelphiAIDevIDEShortcuts.BindKeyboard(const BindingServices: IOTAKeyBi // BindingResult := TKeyBindingResult.krNextProc; //krUnhandled; //end; -procedure TDelphiAIDevIDEShortcuts.KeyProcBlockReturnAndAlt(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); +procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturnAndAlt(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); var LTextCurrentLineOrBlock: string; begin From 14612c201e90576827b07d2938d609948ffcc27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 27 Aug 2024 10:44:20 -0300 Subject: [PATCH 046/109] bk/2024-08-27-1044 --- Package/DelphiAIDeveloper.dpk | 3 +- Package/DelphiAIDeveloper.dproj | 1 + .../DelphiAIDev.CodeCompletion.Vars.pas | 69 ++++++++++++++++ .../DelphiAIDev.KeyboardBinding.pas | 81 ++++++++++++++++++- 4 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 Src/CodeCompletion/DelphiAIDev.CodeCompletion.Vars.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 61a439c..6650683 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -106,6 +106,7 @@ contains DelphiAIDev.PopupMenuProjects.OnExecute in '..\Src\PopupMenuProjects\DelphiAIDev.PopupMenuProjects.OnExecute.pas', DelphiAIDev.Projects.Fields in '..\Src\Projects\DelphiAIDev.Projects.Fields.pas', DelphiAIDev.Projects.Model in '..\Src\Projects\DelphiAIDev.Projects.Model.pas', - DelphiAIDev.Projects.Interfaces in '..\Src\Projects\DelphiAIDev.Projects.Interfaces.pas'; + DelphiAIDev.Projects.Interfaces in '..\Src\Projects\DelphiAIDev.Projects.Interfaces.pas', + DelphiAIDev.CodeCompletion.Vars in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Vars.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index f98b79d..b063d5b 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -222,6 +222,7 @@ + BITMAP c4d_Logo diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Vars.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Vars.pas new file mode 100644 index 0000000..790c280 --- /dev/null +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Vars.pas @@ -0,0 +1,69 @@ +unit DelphiAIDev.CodeCompletion.Vars; + +interface + +uses + System.SysUtils, + System.Classes; + +type + TDelphiAIDevCodeCompletionVars = class + private + FLineIni: Integer; + FLineEnd: Integer; + FRow: Integer; + FColumn: Integer; + FContents: TStrings; + constructor Create; + public + class function GetInstance: TDelphiAIDevCodeCompletionVars; + destructor Destroy; override; + procedure Clear; + property LineIni: Integer read FLineIni write FLineIni; + property LineEnd: Integer read FLineEnd write FLineEnd; + property Row: Integer read FRow write FRow; + property Column: Integer read FColumn write FColumn; + property Contents: TStrings read FContents write FContents; + end; + +implementation + +var + Instance: TDelphiAIDevCodeCompletionVars; + +class function TDelphiAIDevCodeCompletionVars.GetInstance: TDelphiAIDevCodeCompletionVars; +begin + if not Assigned(Instance) then + Instance := Self.Create; + + Result := Instance; +end; + +constructor TDelphiAIDevCodeCompletionVars.Create; +begin + FContents := TStringList.Create; + Self.Clear; +end; + +destructor TDelphiAIDevCodeCompletionVars.Destroy; +begin + FContents.Free; + inherited; +end; + +procedure TDelphiAIDevCodeCompletionVars.Clear; +begin + FLineIni := 0; + FLineEnd := 0; + FRow := 0; + FColumn := 0; + FContents.Clear; +end; + +initialization + +finalization + if Assigned(Instance) then + FreeAndNil(Instance); + +end. diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 2ae02b2..4e3ba1d 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -14,8 +14,11 @@ interface type TDelphiAIDevKeyboardBinding = class(TNotifierObject, IOTAKeyboardBinding) private + procedure KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); + procedure KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); //procedure KeyProcBlockReturn(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); procedure KeyProcBlockReturnAndAlt(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); + procedure AddBlockText; protected function GetBindingType: TBindingType; function GetDisplayName: string; @@ -31,7 +34,8 @@ implementation uses DelphiAIDev.Utils, - DelphiAIDev.Utils.OTA; + DelphiAIDev.Utils.OTA, + DelphiAIDev.CodeCompletion.Vars; var Index: Integer = -1; @@ -82,6 +86,9 @@ procedure TDelphiAIDevKeyboardBinding.BindKeyboard(const BindingServices: IOTAKe // if TUtilsOTA.CurrentProjectIsDelphiAIDeveloperDPROJ then // Exit; + BindingServices.AddKeyBinding([Shortcut(VK_HOME, [ssAlt])], Self.KeyAltHome, nil); + BindingServices.AddKeyBinding([Shortcut(VK_TAB, [])], Self.KeyTab, nil); + //BindingServices.AddKeyBinding([Shortcut(VK_RETURN, [])], Self.KeyProcBlockReturn, nil); BindingServices.AddKeyBinding([Shortcut(VK_RETURN, [ssAlt])], Self.KeyProcBlockReturnAndAlt, nil); end; @@ -116,6 +123,78 @@ procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturnAndAlt(const Context: IO BindingResult := TKeyBindingResult.krUnhandled; //krNextProc; end; +procedure TDelphiAIDevKeyboardBinding.AddBlockText; +begin + TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Clear; + TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(' TUtils.AddLog(EmptyStr);'); + TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(' TUtils.ShowMsg(EmptyStr);'); +end; + +procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); +var + LRow: Integer; + LColumn: Integer; + i: Integer; + LText: string; +begin + if KeyCode <> Shortcut(VK_HOME, [ssAlt]) then + Exit; + + Self.AddBlockText; + + LRow := Context.EditBuffer.EditPosition.Row; + LColumn := Context.EditBuffer.EditPosition.Column; + + TDelphiAIDevCodeCompletionVars.GetInstance.LineIni := LRow; // + 1; + TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + (TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count); // + 1 //TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + 1; + + //Context.EditBuffer.EditPosition.InsertText(sLineBreak + sLineBreak); + LText := ''; + for i := 0 to Pred(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count) do + LText := LText + sLineBreak; + + Context.EditBuffer.EditPosition.InsertText(LText.TrimRight + sLineBreak); + Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineIni, LColumn); + + TDelphiAIDevCodeCompletionVars.GetInstance.Row := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni; + TDelphiAIDevCodeCompletionVars.GetInstance.Column := LColumn; + + //Context.EditBuffer.EditPosition.MoveBOL; + // //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; + // LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView); + // if LTextCurrentLineOrBlock.Trim.IsEmpty then + // Exit; + + BindingResult := TKeyBindingResult.krUnhandled; //krNextProc; +end; + +procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); +var + LText: string; + i: Integer; +begin + TUtils.AddLog('KeyTab ' + TDelphiAIDevCodeCompletionVars.GetInstance.LineIni.ToString); + + if KeyCode <> Shortcut(VK_TAB, []) then + Exit; + + if TDelphiAIDevCodeCompletionVars.GetInstance.LineIni > 0 then + begin + //Context.EditBuffer.EditPosition.InsertText('Minha linha 01' + sLineBreak + 'Linha 2'); + LText := ''; + for i := 0 to Pred(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count) do + LText := LText + TDelphiAIDevCodeCompletionVars.GetInstance.Contents[i].Trim + sLineBreak; + + Context.EditBuffer.EditPosition.InsertText(LText.Trim); + //Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd, 20); + + TDelphiAIDevCodeCompletionVars.GetInstance.Clear; + end; + + BindingResult := TKeyBindingResult.krUnhandled; //krNextProc; + TUtils.AddLog('KeyTab krUnhandled'); +end; + initialization finalization From c611d88d84d7490786ef45feb1c7112505bb6fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Wed, 28 Aug 2024 01:07:39 -0300 Subject: [PATCH 047/109] code-completion-add-02 --- Package/DelphiAIDeveloper.dpk | 5 +- Package/DelphiAIDeveloper.dproj | 3 + Src/DelphiAIDev.Register.pas | 4 +- .../DelphiAIDev.IDE.NTAEditViewNotifier.pas | 169 ++++++++++++++++++ .../DelphiAIDev.IDE.OTAEditorNotifier.pas | 93 ++++++++++ .../DelphiAIDev.IDE.OTAIDENotifier.pas | 137 ++++++++++++++ .../DelphiAIDev.KeyboardBinding.pas | 1 + Src/Test/DelphiAIDev.Test.pas | 23 +++ Src/Utils/DelphiAIDev.Utils.OTA.pas | 93 +++++++++- Src/Utils/DelphiAIDev.Utils.pas | 2 + 10 files changed, 527 insertions(+), 3 deletions(-) create mode 100644 Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas create mode 100644 Src/IDE/OTAEditorNotifier/DelphiAIDev.IDE.OTAEditorNotifier.pas create mode 100644 Src/IDE/OTAIDENotifier/DelphiAIDev.IDE.OTAIDENotifier.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 6650683..4cead8e 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -107,6 +107,9 @@ contains DelphiAIDev.Projects.Fields in '..\Src\Projects\DelphiAIDev.Projects.Fields.pas', DelphiAIDev.Projects.Model in '..\Src\Projects\DelphiAIDev.Projects.Model.pas', DelphiAIDev.Projects.Interfaces in '..\Src\Projects\DelphiAIDev.Projects.Interfaces.pas', - DelphiAIDev.CodeCompletion.Vars in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Vars.pas'; + DelphiAIDev.CodeCompletion.Vars in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Vars.pas', + DelphiAIDev.IDE.OTAIDENotifier in '..\Src\IDE\OTAIDENotifier\DelphiAIDev.IDE.OTAIDENotifier.pas', + DelphiAIDev.IDE.OTAEditorNotifier in '..\Src\IDE\OTAEditorNotifier\DelphiAIDev.IDE.OTAEditorNotifier.pas', + DelphiAIDev.IDE.NTAEditViewNotifier in '..\Src\IDE\NTAEditViewNotifier\DelphiAIDev.IDE.NTAEditViewNotifier.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index b063d5b..92bed87 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -223,6 +223,9 @@ + + + BITMAP c4d_Logo diff --git a/Src/DelphiAIDev.Register.pas b/Src/DelphiAIDev.Register.pas index 3851259..671f1e6 100644 --- a/Src/DelphiAIDev.Register.pas +++ b/Src/DelphiAIDev.Register.pas @@ -7,7 +7,8 @@ interface DelphiAIDev.MainMenu.Register, DelphiAIDev.KeyboardBinding, DelphiAIDev.PopupMenuProjects, - DelphiAIDev.DB.Chat.View; + DelphiAIDev.DB.Chat.View, + DelphiAIDev.IDE.OTAIDENotifier; procedure Register; @@ -20,6 +21,7 @@ procedure Register; DelphiAIDev.KeyboardBinding.RefreshRegister; DelphiAIDev.PopupMenuProjects.RegisterSelf; DelphiAIDev.DB.Chat.View.RegisterSelf; + DelphiAIDev.IDE.OTAIDENotifier.RegisterSelf; end; end. diff --git a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas new file mode 100644 index 0000000..cabcd68 --- /dev/null +++ b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas @@ -0,0 +1,169 @@ +unit DelphiAIDev.IDE.NTAEditViewNotifier; + +interface + +uses + System.SysUtils, + System.Classes, + System.Generics.Collections, + System.Types, + System.SyncObjs, + System.RegularExpressions, + Vcl.Dialogs, + Vcl.Graphics, + Vcl.Imaging.pngimage, + DelphiAIDev.Utils, + DelphiAIDev.Utils.OTA, + DelphiAIDev.Consts, + DelphiAIDev.CodeCompletion.Vars, + ToolsAPI; + +type + TDelphiAIDevIDENTAEditViewNotifier = class(TInterfacedObject, IOTANotifier, INTAEditViewNotifier) + protected + FIOTAEditView: IOTAEditView; + FIndex: Integer; + procedure RemoveNotifier; + public + constructor Create(FileName: string; AEditView: IOTAEditView); + destructor Destroy; override; + + { INTAEditViewNotifier } + ///EditorIdle é chamado após alguma ação ter ocorrido na visualização + ///(edição, movimento do cursor, etc.) e um período de tempo ter passado sem que outra + ///ação acontecesse. Isso é aproximadamente equivalente ao momento em que o Code + ///Insight é acionado (e está vinculado à configuração de atraso do Code Insight) + procedure EditorIdle(const View: IOTAEditView); + procedure BeginPaint(const View: IOTAEditView; var FullRepaint: Boolean); + procedure PaintLine(const View: IOTAEditView; LineNumber: Integer; + const LineText: PAnsiChar; const TextWidth: Word; const LineAttributes: TOTAAttributeArray; + const Canvas: TCanvas; const TextRect: TRect; const LineRect: TRect; const CellSize: TSize); + ///EndPaint é chamado depois que todas as linhas foram repintadas. + ///Use isso para limpar quaisquer estruturas de dados que foram mantidas + ///ao longo da pintura das linhas + procedure EndPaint(const View: IOTAEditView); + + //IOTANotifier + procedure AfterSave; + procedure BeforeSave; + procedure Modified; + procedure Destroyed; + end; + +implementation + +constructor TDelphiAIDevIDENTAEditViewNotifier.Create(FileName: string; AEditView: IOTAEditView); +begin + inherited Create; + FIOTAEditView := AEditView; + FIndex := FIOTAEditView.AddNotifier(Self); +end; + +destructor TDelphiAIDevIDENTAEditViewNotifier.Destroy; +begin + RemoveNotifier; + inherited; +end; + +procedure TDelphiAIDevIDENTAEditViewNotifier.Destroyed; +begin + RemoveNotifier; +end; + +procedure TDelphiAIDevIDENTAEditViewNotifier.AfterSave; +begin + +end; + +procedure TDelphiAIDevIDENTAEditViewNotifier.BeforeSave; +begin + +end; + +procedure TDelphiAIDevIDENTAEditViewNotifier.BeginPaint(const View: IOTAEditView; var FullRepaint: Boolean); +begin + FullRepaint := True; +end; + +procedure TDelphiAIDevIDENTAEditViewNotifier.EditorIdle(const View: IOTAEditView); +var + LRow: Integer; + LColumn: Integer; +begin + TUtilsOTA.GetCursorPosition(LRow, LColumn); + +// TUtils.AddLog(Format('EditorIdle - %d (%d) - %d (%d) - %s ', +// [TDelphiAIDevCodeCompletionVars.GetInstance.Row, LRow, TDelphiAIDevCodeCompletionVars.GetInstance.Column, LColumn, DateTimeToStr(Now)])); + + if (LRow <> TDelphiAIDevCodeCompletionVars.GetInstance.Row) or (LColumn <> TDelphiAIDevCodeCompletionVars.GetInstance.Column) then + begin + TDelphiAIDevCodeCompletionVars.GetInstance.LineIni := 0; + TDelphiAIDevCodeCompletionVars.GetInstance.Clear; + end; + + //TUtils.AddLog('EditorIdle ' + BoolToStr(TDelphiAIDevCodeCompletionVars.GetInstance.ClearNext, True)); + +// if TDelphiAIDevCodeCompletionVars.GetInstance.ClearNext then +// begin +// TDelphiAIDevCodeCompletionVars.GetInstance.Clear; +// end +// else +// TDelphiAIDevCodeCompletionVars.GetInstance.ClearNext := True; + + //View.AddNotifier() + //View.GetEditWindow.Form.Repaint; +end; + +procedure TDelphiAIDevIDENTAEditViewNotifier.EndPaint(const View: IOTAEditView); +begin + //TUtils.AddLog('EndPaint'); +end; + +procedure TDelphiAIDevIDENTAEditViewNotifier.Modified; +begin + +end; + + +procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; LineNumber: Integer; + const LineText: PAnsiChar; const TextWidth: Word; const LineAttributes: TOTAAttributeArray; + const Canvas: TCanvas; const TextRect: TRect; const LineRect: TRect; const CellSize: TSize); +var + LLineText: string; +begin + if LineNumber < 1 then + Exit; + + LLineText := string(LineText); + + if not LLineText.Trim.IsEmpty then + Exit; + + //if LineNumber <> View.CursorPos.Line then + // Exit; + + if (LineNumber >= TDelphiAIDevCodeCompletionVars.GetInstance.LineIni)and(LineNumber <= TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd) then + begin + Canvas.Brush.Style := bsClear; + Canvas.Font.Color := $777777; //$666666; + + try + LLineText := TDelphiAIDevCodeCompletionVars.GetInstance.Contents[LineNumber - TDelphiAIDevCodeCompletionVars.GetInstance.LineIni]; + Canvas.TextOut(TextRect.Left, TextRect.Top, LLineText.TrimRight); + except on E: Exception do + TUtils.AddLog(E.Message); + end; + end; +end; + +procedure TDelphiAIDevIDENTAEditViewNotifier.RemoveNotifier; +begin + if Assigned(FIOTAEditView) and (FIndex >= 0) then + begin + FIOTAEditView.RemoveNotifier(FIndex); + FIndex := -1; + FIOTAEditView := nil; + end; +end; + +end. diff --git a/Src/IDE/OTAEditorNotifier/DelphiAIDev.IDE.OTAEditorNotifier.pas b/Src/IDE/OTAEditorNotifier/DelphiAIDev.IDE.OTAEditorNotifier.pas new file mode 100644 index 0000000..474ed14 --- /dev/null +++ b/Src/IDE/OTAEditorNotifier/DelphiAIDev.IDE.OTAEditorNotifier.pas @@ -0,0 +1,93 @@ +unit DelphiAIDev.IDE.OTAEditorNotifier; + +interface + +uses + System.SysUtils, + System.Classes, + System.Generics.Collections, + System.Types, + System.SyncObjs, + System.RegularExpressions, + Vcl.Dialogs, + Vcl.Graphics, + Vcl.Imaging.pngimage, + ToolsAPI, + DelphiAIDev.Utils, + DelphiAIDev.Consts, + DelphiAIDev.CodeCompletion.Vars, + DelphiAIDev.IDE.NTAEditViewNotifier; + +type + TDelphiAIDevIDEOTAEditorNotifier = class(TNotifierObject, IOTANotifier, IOTAEditorNotifier) + private + FIOTASourceEditor: IOTASourceEditor; + FINTAEditViewNotifierList: TList; + FIndex: Integer; + procedure RemoveNotifiers; + public + constructor Create(ASourceEditor: IOTASourceEditor); + destructor Destroy; override; + { IOTANotifier } + procedure Destroyed; + { IOTAEditorNotifier } + procedure ViewNotification(const View: IOTAEditView; Operation: TOperation); + procedure ViewActivated(const View: IOTAEditView); + end; + + +implementation + +constructor TDelphiAIDevIDEOTAEditorNotifier.Create(ASourceEditor: IOTASourceEditor); +var + i: Integer; +begin + inherited Create; + FINTAEditViewNotifierList := TList.Create; + FIOTASourceEditor := ASourceEditor; + + FIndex := FIOTASourceEditor.AddNotifier(Self); + for i := 0 to Pred(FIOTASourceEditor.EditViewCount) do + FINTAEditViewNotifierList.Add(TDelphiAIDevIDENTAEditViewNotifier.Create(FIOTASourceEditor.FileName, FIOTASourceEditor.EditViews[i])); +end; + +destructor TDelphiAIDevIDEOTAEditorNotifier.Destroy; +begin + RemoveNotifiers; + FINTAEditViewNotifierList.Free; + inherited; +end; + +procedure TDelphiAIDevIDEOTAEditorNotifier.Destroyed; +begin + RemoveNotifiers; +end; + +procedure TDelphiAIDevIDEOTAEditorNotifier.RemoveNotifiers; +var + i: Integer; +begin + for i := 0 to Pred(FINTAEditViewNotifierList.Count) do + FINTAEditViewNotifierList[i].Destroyed; + FINTAEditViewNotifierList.Clear; + + if Assigned(FIOTASourceEditor) and (FIndex >= 0) then + begin + FIOTASourceEditor.RemoveNotifier(FIndex); + FIndex := -1; + FIOTASourceEditor := nil; + end; +end; + +procedure TDelphiAIDevIDEOTAEditorNotifier.ViewActivated(const View: IOTAEditView); +begin + +end; + +procedure TDelphiAIDevIDEOTAEditorNotifier.ViewNotification(const View: IOTAEditView; Operation: TOperation); +begin + if Operation = opInsert then + FINTAEditViewNotifierList.Add(TDelphiAIDevIDENTAEditViewNotifier.Create(FIOTASourceEditor.FileName, View)); +end; + +end. diff --git a/Src/IDE/OTAIDENotifier/DelphiAIDev.IDE.OTAIDENotifier.pas b/Src/IDE/OTAIDENotifier/DelphiAIDev.IDE.OTAIDENotifier.pas new file mode 100644 index 0000000..f295128 --- /dev/null +++ b/Src/IDE/OTAIDENotifier/DelphiAIDev.IDE.OTAIDENotifier.pas @@ -0,0 +1,137 @@ +unit DelphiAIDev.IDE.OTAIDENotifier; + +interface + +uses + System.SysUtils, + System.Classes, + System.Generics.Collections, + System.Types, + System.SyncObjs, + System.RegularExpressions, + Vcl.Dialogs, + Vcl.Graphics, + Vcl.Imaging.pngimage, + ToolsAPI, + DelphiAIDev.Utils, + DelphiAIDev.Consts, + DelphiAIDev.CodeCompletion.Vars, + DelphiAIDev.IDE.OTAEditorNotifier; + +type + TDelphiAIDevIDEOTAIDENotifier = class(TNotifierObject, IOTANotifier, IOTAIDENotifier) + private + FEditorNotifiers: TList; + protected + procedure FileNotification(NotifyCode: TOTAFileNotification;const FileName: string; var Cancel: Boolean); + procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); overload; + procedure AfterCompile(Succeeded: Boolean); overload; + public + constructor Create; + destructor Destroy; override; + end; + + procedure RegisterSelf; + +implementation + +var + Index: Integer; + +procedure RegisterSelf; +begin + Index := (BorlandIDEServices as IOTAServices).AddNotifier(TDelphiAIDevIDEOTAIDENotifier.Create); +end; + +procedure TDelphiAIDevIDEOTAIDENotifier.AfterCompile(Succeeded: Boolean); +begin + // +end; + +procedure TDelphiAIDevIDEOTAIDENotifier.BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); +begin + Cancel := False; +end; + +constructor TDelphiAIDevIDEOTAIDENotifier.Create; +var + LIOTAModuleServices: IOTAModuleServices; + i: Integer; + j: Integer; + LIOTAModule: IOTAModule; + LIOTASourceEditor: IOTASourceEditor; + LExt: string; +begin + //TUtils.AddLog('#01 - TC4DFileNotification.Create'); + FEditorNotifiers := TList.Create; + LIOTAModuleServices := BorlandIDEServices as IOTAModuleServices; + for i := 0 to Pred(LIOTAModuleServices.ModuleCount) do + begin + LIOTAModule := LIOTAModuleServices.Modules[i]; + + for j := 0 to Pred(LIOTAModule.ModuleFileCount) do + if Supports(LIOTAModule.ModuleFileEditors[j], IOTASourceEditor, LIOTASourceEditor) then + begin + LExt := ExtractFileExt(LIOTASourceEditor.FileName).ToLower; + if LExt.Equals('.pas') then + FEditorNotifiers.Add(TDelphiAIDevIDEOTAEditorNotifier.Create(LIOTASourceEditor)); + end; + end; + + inherited; +end; + +destructor TDelphiAIDevIDEOTAIDENotifier.Destroy; +var + i: Integer; +begin + for i := 0 to Pred(FEditorNotifiers.Count) do + FEditorNotifiers[i].Destroyed; + FEditorNotifiers.Free; + inherited; +end; + +procedure TDelphiAIDevIDEOTAIDENotifier.FileNotification(NotifyCode: TOTAFileNotification; const FileName: string; var Cancel: Boolean); +var + LExtensao: string; + LIOTAModule: IOTAModule; + i: Integer; + LIOTASourceEditor: IOTASourceEditor; +begin + Cancel := False; + + if NotifyCode = ofnFileOpened then + begin + LIOTAModule := (BorlandIDEServices as IOTAModuleServices).FindModule(FileName); + + if not Assigned(LIOTAModule) then + Exit; + + for i := 0 to Pred(LIOTAModule.ModuleFileCount) do + if Supports(LIOTAModule.ModuleFileEditors[i], IOTASourceEditor, LIOTASourceEditor) then + begin + LExtensao := ExtractFileExt(LIOTASourceEditor.FileName).ToLower; + if LExtensao.Equals('.pas') then + FEditorNotifiers.Add(TDelphiAIDevIDEOTAEditorNotifier.Create(LIOTASourceEditor)); + end; + end; + + if (NotifyCode <> ofnFileOpened) and (NotifyCode <> ofnFileClosing) then + Exit; + + LExtensao := ExtractFileExt(FileName).ToLower; + if (LExtensao <> '.dproj') and (LExtensao <> '.groupproj') then + Exit; +end; + +initialization + +finalization + if Index >= 0 then + (BorlandIDEServices as IOTAServices).RemoveNotifier(Index); + + + + + +end. diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 4e3ba1d..57521a8 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -128,6 +128,7 @@ procedure TDelphiAIDevKeyboardBinding.AddBlockText; TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Clear; TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(' TUtils.AddLog(EmptyStr);'); TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(' TUtils.ShowMsg(EmptyStr);'); + TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(' TUtils.ShowMsg(LMsg3);'); end; procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 4fc715f..81f8e6b 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -5,9 +5,32 @@ interface type TDelphiAIDevTest = class private + FNome: string; + FEndereco: string; + FBairro: string; + FNumero: Integer; + FTelefone: string; + FEmail: string; + FDataNascimento: TDateTime; public + property Nome: string read FNome write FNome; + property Endereco: string read FEndereco write FEndereco; + property Bairro: string read FBairro write FBairro; + property Numero: Integer read FNumero write FNumero; + property Telefone: string read FTelefone write FTelefone; + property Email: string read FEmail write FEmail; + property DataNascimento: TDateTime read FDataNascimento write FDataNascimento; + + procedure Clear; end; implementation +{ TDelphiAIDevTest } + +procedure TDelphiAIDevTest.Clear; +begin + +end; + end. diff --git a/Src/Utils/DelphiAIDev.Utils.OTA.pas b/Src/Utils/DelphiAIDev.Utils.OTA.pas index 9b3096a..a1980ab 100644 --- a/Src/Utils/DelphiAIDev.Utils.OTA.pas +++ b/Src/Utils/DelphiAIDev.Utils.OTA.pas @@ -18,6 +18,8 @@ interface TUtilsOTA = class private public + class procedure GetCursorPosition(var ALine, AColumn: Integer); + class procedure GetCursorPositionPixel(var AX, AY: Integer); class function CurrentProjectIsDelphiAIDeveloperDPROJ: Boolean; class function CurrentModuleIsReadOnly: Boolean; class procedure SaveAllModifiedModules; @@ -88,6 +90,95 @@ implementation uses DelphiAIDev.Utils; +class procedure TUtilsOTA.GetCursorPosition(var ALine, AColumn: Integer); +var + LOTAEditorServices: IOTAEditorServices; + LIOTAEditView: IOTAEditView; + LOTAEditPos: TOTAEditPos; + //LIOTAEditPosition: IOTAEditPosition; +begin + ALine := 0; + AColumn := 0; + + LOTAEditorServices := Self.GetIOTAEditorServices; + if not Assigned(LOTAEditorServices) then + Exit; + + LIOTAEditView := LOTAEditorServices.TopView; + if Assigned(LIOTAEditView) then + begin + LOTAEditPos := LIOTAEditView.CursorPos; + ALine := LOTAEditPos.Line; + AColumn := LOTAEditPos.Col; + + {LIOTAEditPosition := LIOTAEditView.Position; + if Assigned(LIOTAEditPosition) then + begin + ALine := LIOTAEditPosition.Row; + AColumn := LIOTAEditPosition.Column; + //TUtils.AddLog(Format('%d : %d', [ALine, AColumn])); + end;} + end; +end; + +class procedure TUtilsOTA.GetCursorPositionPixel(var AX, AY: Integer); +var + LIOTAEditorServices: IOTAEditorServices; + LIOTAEditView: IOTAEditView; + LIOTAEditPosition: IOTAEditPosition; + LLineHeight: Integer; + LCharWidth: Integer; + LEditorWindow: TCustomForm; + LHDC: HDC; + LCanvas: TCanvas; + LTextMetric: TTextMetric; +begin + // Obtém a instância do Editor Services + LIOTAEditorServices := BorlandIDEServices as IOTAEditorServices; + + if Assigned(LIOTAEditorServices) then + begin + // Obtém a visualização de edição ativa + LIOTAEditView := LIOTAEditorServices.TopView; + if Assigned(LIOTAEditView) then + begin + // Obtém a posição do cursor + LIOTAEditPosition := LIOTAEditView.Position; + if Assigned(LIOTAEditPosition) then + begin + // Obtém a janela do editor + LEditorWindow := LIOTAEditView.GetEditWindow.Form; + + // Cria um DC (Device Context) para a janela do editor + LHDC := GetDC(LEditorWindow.Handle); + try + LCanvas := TCanvas.Create; + try + LCanvas.Handle := LHDC; + + // Obtém as métricas do texto (altura da linha e largura do caractere) + GetTextMetrics(LCanvas.Handle, LTextMetric); + LLineHeight := LTextMetric.tmHeight; + LCharWidth := LTextMetric.tmAveCharWidth; + finally + LCanvas.Free; + end; + finally + ReleaseDC(LEditorWindow.Handle, LHDC); + end; + + // Calcula a posição em pixels + AX := (LIOTAEditPosition.Column - 1) * LCharWidth; + AY := (LIOTAEditPosition.Row - 1) * LLineHeight; + + // Agora você tem a posição do cursor em pixels + //ShowMessage(Format('Cursor está em X: %d, Y: %d pixels', [PixelX, PixelY])); + TUtils.AddLog(Format('Cursor está em X: %d, Y: %d pixels', [AX, AY])); + end; + end; + end; +end; + class function TUtilsOTA.CurrentProjectIsDelphiAIDeveloperDPROJ: Boolean; var LIOTAProject: IOTAProject; @@ -268,9 +359,9 @@ class procedure TUtilsOTA.InsertBlockTextIntoEditor(const AText: string); var LOTAEditorServices: IOTAEditorServices; LIOTAEditView: IOTAEditView; + LOTAEditPos: TOTAEditPos; LPosition: Longint; LOTACharPos: TOTACharPos; - LOTAEditPos: TOTAEditPos; LIOTAEditWriter: IOTAEditWriter; begin LOTAEditorServices := Self.GetIOTAEditorServices; diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index dfca055..dc27141 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -210,6 +210,8 @@ class function TUtils.AdjustQuestionToJson(const AValue: string): string; Result := Result.Replace('\\"', '\"', [rfReplaceAll, rfIgnoreCase]); end; + + class procedure TUtils.AddLog(const AMessage: string); const DIRECTORY = 'C:\TempLog\DelphiAIDev\'; From 7b05d294e94ed9c537302eb24bf165335b43e18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Wed, 28 Aug 2024 01:43:50 -0300 Subject: [PATCH 048/109] bk/2024-08-28-0143 --- Package/DelphiAIDeveloper.dpk | 3 +- Package/DelphiAIDeveloper.dproj | 1 + .../DelphiAIDev.CodeCompletion.Search.pas | 113 ++++++++++++++++++ .../DelphiAIDev.KeyboardBinding.pas | 36 +++++- Src/Test/DelphiAIDev.Test.pas | 3 + 5 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 4cead8e..8451ba3 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -110,6 +110,7 @@ contains DelphiAIDev.CodeCompletion.Vars in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Vars.pas', DelphiAIDev.IDE.OTAIDENotifier in '..\Src\IDE\OTAIDENotifier\DelphiAIDev.IDE.OTAIDENotifier.pas', DelphiAIDev.IDE.OTAEditorNotifier in '..\Src\IDE\OTAEditorNotifier\DelphiAIDev.IDE.OTAEditorNotifier.pas', - DelphiAIDev.IDE.NTAEditViewNotifier in '..\Src\IDE\NTAEditViewNotifier\DelphiAIDev.IDE.NTAEditViewNotifier.pas'; + DelphiAIDev.IDE.NTAEditViewNotifier in '..\Src\IDE\NTAEditViewNotifier\DelphiAIDev.IDE.NTAEditViewNotifier.pas', + DelphiAIDev.CodeCompletion.Search in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Search.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 92bed87..1c82031 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -226,6 +226,7 @@ + BITMAP c4d_Logo diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas new file mode 100644 index 0000000..f496d3f --- /dev/null +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -0,0 +1,113 @@ +unit DelphiAIDev.CodeCompletion.Search; + +interface + +uses + System.SysUtils, + System.Classes, + ToolsAPI, + DelphiAIDev.Types, + DelphiAIDev.Consts, + DelphiAIDev.Settings, + DelphiAIDev.Utils, + DelphiAIDev.Utils.OTA, + DelphiAIDev.CodeCompletion.Vars, + DelphiAIDev.Chat; + +type + IDelphiAIDevCodeCompletionSearch = interface + ['{5F8BDEE9-14DC-4C8C-BA7A-681A94844AD8}'] + procedure Process(const AContext: IOTAKeyContext); + end; + + TDelphiAIDevCodeCompletionSearch = class(TInterfacedObject, IDelphiAIDevCodeCompletionSearch) + private + FSettings: TDelphiAIDevSettings; + FQuestions: TStrings; + FChat: TDelphiAIDevChat; + protected + procedure Process(const AContext: IOTAKeyContext); + public + class function New: IDelphiAIDevCodeCompletionSearch; + constructor Create; + destructor Destroy; override; + end; + +implementation + +class function TDelphiAIDevCodeCompletionSearch.New: IDelphiAIDevCodeCompletionSearch; +begin + Result := Self.Create; +end; + +constructor TDelphiAIDevCodeCompletionSearch.Create; +begin + FSettings := TDelphiAIDevSettings.GetInstance; + FChat := TDelphiAIDevChat.Create; + FQuestions := TStringList.Create; +end; + +destructor TDelphiAIDevCodeCompletionSearch.Destroy; +begin + FQuestions.Free; + FChat.Free; + inherited; +end; + +procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContext); +var + LRow: Integer; + LColumn: Integer; + i: Integer; + LText: string; +begin + FSettings.ValidateFillingSelectedAI; + + FQuestions.Clear; + FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); + FQuestions.Add(TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim); + FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeOnly); + + FQuestions.Add('Com base no seguinte código delphi, de uma sugestão ' + + 'de código para ser adicionado onde esta o comentário //Suggestion'); + TUtils.ShowMsg(FQuestions.Text); + try + FChat.ProcessSend(FQuestions.Text); + except + Abort; + end; + //Self.AddBlockText; + + TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Clear; + for i := 0 to Pred(FChat.Response.Count) do + begin + TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(FChat.Response[i]); + end; + + TUtils.ShowMsg(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Text); + + LRow := AContext.EditBuffer.EditPosition.Row; + LColumn := AContext.EditBuffer.EditPosition.Column; + + TDelphiAIDevCodeCompletionVars.GetInstance.LineIni := LRow; // + 1; + TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + (TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count); // + 1 //TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + 1; + + //Context.EditBuffer.EditPosition.InsertText(sLineBreak + sLineBreak); + LText := ''; + for i := 0 to Pred(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count) do + LText := LText + sLineBreak; + + AContext.EditBuffer.EditPosition.InsertText(LText.TrimRight + sLineBreak); + AContext.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineIni, LColumn); + + TDelphiAIDevCodeCompletionVars.GetInstance.Row := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni; + TDelphiAIDevCodeCompletionVars.GetInstance.Column := LColumn; + + //Context.EditBuffer.EditPosition.MoveBOL; + // //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; + // LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView); + // if LTextCurrentLineOrBlock.Trim.IsEmpty then + // Exit; +end; + +end. diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 57521a8..1f72c3e 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -9,7 +9,8 @@ interface Vcl.Menus, ToolsAPI, DelphiAIDev.Utils.CnWizard, - DelphiAIDev.Chat.View; + DelphiAIDev.Chat.View, + DelphiAIDev.CodeCompletion.Search; type TDelphiAIDevKeyboardBinding = class(TNotifierObject, IOTAKeyboardBinding) @@ -141,7 +142,9 @@ procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; if KeyCode <> Shortcut(VK_HOME, [ssAlt]) then Exit; - Self.AddBlockText; + TDelphiAIDevCodeCompletionSearch.New.Process(Context); + + //Self.AddBlockText; LRow := Context.EditBuffer.EditPosition.Row; LColumn := Context.EditBuffer.EditPosition.Column; @@ -167,6 +170,35 @@ procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; // Exit; BindingResult := TKeyBindingResult.krUnhandled; //krNextProc; + + + //** + //Self.AddBlockText; + + {LRow := Context.EditBuffer.EditPosition.Row; + LColumn := Context.EditBuffer.EditPosition.Column; + + TDelphiAIDevCodeCompletionVars.GetInstance.LineIni := LRow; // + 1; + TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + (TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count); // + 1 //TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + 1; + + //Context.EditBuffer.EditPosition.InsertText(sLineBreak + sLineBreak); + LText := ''; + for i := 0 to Pred(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count) do + LText := LText + sLineBreak; + + Context.EditBuffer.EditPosition.InsertText(LText.TrimRight + sLineBreak); + Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineIni, LColumn); + + TDelphiAIDevCodeCompletionVars.GetInstance.Row := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni; + TDelphiAIDevCodeCompletionVars.GetInstance.Column := LColumn; + + //Context.EditBuffer.EditPosition.MoveBOL; + // //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; + // LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView); + // if LTextCurrentLineOrBlock.Trim.IsEmpty then + // Exit; + + BindingResult := TKeyBindingResult.krUnhandled; //krNextProc; } end; procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 81f8e6b..6874a8e 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -30,6 +30,9 @@ implementation procedure TDelphiAIDevTest.Clear; begin + //Suggestion + + end; From dc5e4db5aaa7f2219f7ac7fd106750bd299437f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 29 Aug 2024 14:21:37 -0300 Subject: [PATCH 049/109] feature/auto-completar-parcial --- Package/DelphiAIDeveloper.dpk | 3 +- Package/DelphiAIDeveloper.dproj | 11 +- Src/Chat/DelphiAIDev.Chat.View.pas | 110 ----------------- .../DelphiAIDev.CodeCompletion.Search.pas | 46 ++++--- .../DelphiAIDev.IDE.NTAEditViewNotifier.pas | 29 ++--- .../DelphiAIDev.IDE.OTAEditorNotifier.pas | 1 - .../DelphiAIDev.IDE.OTAIDENotifier.pas | 21 ++-- .../DelphiAIDev.KeyboardBinding.pas | 116 +++--------------- Src/Settings/DelphiAIDev.Settings.View.dfm | 6 +- Src/Settings/DelphiAIDev.Settings.View.pas | 1 - Src/Settings/DelphiAIDev.Settings.pas | 33 +++-- Src/Test/DelphiAIDev.Test.Client.pas | 35 ++++++ Src/Test/DelphiAIDev.Test.pas | 8 +- Src/Types/DelphiAIDev.Types.pas | 41 +++++-- Src/Utils/DelphiAIDev.Utils.pas | 4 +- 15 files changed, 163 insertions(+), 302 deletions(-) create mode 100644 Src/Test/DelphiAIDev.Test.Client.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 8451ba3..53bc54c 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -111,6 +111,7 @@ contains DelphiAIDev.IDE.OTAIDENotifier in '..\Src\IDE\OTAIDENotifier\DelphiAIDev.IDE.OTAIDENotifier.pas', DelphiAIDev.IDE.OTAEditorNotifier in '..\Src\IDE\OTAEditorNotifier\DelphiAIDev.IDE.OTAEditorNotifier.pas', DelphiAIDev.IDE.NTAEditViewNotifier in '..\Src\IDE\NTAEditViewNotifier\DelphiAIDev.IDE.NTAEditViewNotifier.pas', - DelphiAIDev.CodeCompletion.Search in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Search.pas'; + DelphiAIDev.CodeCompletion.Search in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Search.pas', + DelphiAIDev.Test.Client in '..\Src\Test\DelphiAIDev.Test.Client.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 1c82031..cdba060 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -74,26 +74,26 @@ None android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar - rtl;bindengine;bindcomp;RESTComponents;$(DCC_UsePackage) + rtl;bindengine;bindcomp;RESTComponents;FireDAC;FireDACCommonDriver;FireDACCommon;FireDACIBDriver;$(DCC_UsePackage) None android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar - rtl;bindengine;bindcomp;RESTComponents;$(DCC_UsePackage) + rtl;bindengine;bindcomp;RESTComponents;FireDAC;FireDACCommonDriver;FireDACCommon;FireDACIBDriver;$(DCC_UsePackage) - rtl;bindengine;bindcomp;RESTComponents;$(DCC_UsePackage) + rtl;bindengine;bindcomp;RESTComponents;FireDAC;FireDACCommonDriver;FireDACCommon;FireDACIBDriver;FireDACMySQLDriver;$(DCC_UsePackage) Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug true 1033 - rtl;bindengine;bindcomp;RESTComponents;$(DCC_UsePackage) + rtl;bindengine;bindcomp;RESTComponents;vclFireDAC;FireDAC;FireDACCommonDriver;FireDACCommon;FireDACIBDriver;FireDACMySQLDriver;$(DCC_UsePackage) .\dcu\ - rtl;bindengine;bindcomp;RESTComponents;$(DCC_UsePackage) + rtl;bindengine;bindcomp;RESTComponents;vclFireDAC;FireDAC;FireDACCommonDriver;FireDACCommon;FireDACIBDriver;FireDACMySQLDriver;$(DCC_UsePackage) DEBUG;$(DCC_Define) @@ -227,6 +227,7 @@ + BITMAP c4d_Logo diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index 07f9407..186b8e9 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -487,116 +487,6 @@ procedure TDelphiAIDevChatView.AddResponseSimple(const AString: string); Self.Last; end; -////Add line-by-line response to color where Delphi code is -//procedure TDelphiAIDevChatView.AddResponseComplete(const AStrings: TStrings); -//var -// LLineNum: Integer; -// LLineStr: string; -// LCodeStarted: Boolean; -//begin -// mmReturn.Lines.Clear; -// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; -// mmReturn.SelAttributes.Style := []; -// -// LCodeStarted := False; -// for LLineNum := 0 to Pred(AStrings.Count) do -// begin -// LLineStr := AStrings[LLineNum].TrimRight; -// -// if not LCodeStarted then -// begin -// if TUtils.CodeIdMarkBeginCode(LLineStr) then -// begin -// LCodeStarted := True; -// Continue; -// end; -// end; -// -// if LLineStr.Trim = TConsts.MARK_END then -// begin -// LCodeStarted := False; -// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; -// Continue; -// end; -// -// if LCodeStarted then -// begin -// if (FSettings.ColorHighlightCodeDelphiUse) and (FSettings.ColorHighlightCodeDelphi <> clNone) then -// mmReturn.SelAttributes.Color := FSettings.ColorHighlightCodeDelphi -// else -// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeForCode; -// end -// else -// mmReturn.SelAttributes.Color := TUtilsOTA.ActiveThemeColorDefault; -// -// //Optional use of one of the following lines -// //mmReturn.Lines.Add(LLineStr); -// Self.AddResponseLine(LLineStr); //.Replace(TConsts.MARK_BEGIN_PASCAL2, '', [rfReplaceAll, rfIgnoreCase]) -// end; -// Self.Last; -//end; -// -////Bold in words between Backtick -//procedure TDelphiAIDevChatView.AddResponseLine(const ALineStr: string); -//const -// BACKTICK = '`'; -//var -// i: Integer; -// LCurrentLetter: Char; -// LNextLetter: Char; -// LLineStarted: Boolean; -// LCodeStarted: Boolean; -//begin -// if not ALineStr.Contains(BACKTICK) then -// begin -// mmReturn.Lines.Add(IFThen(ALineStr.IsEmpty, ' ', ALineStr)); -// Exit; -// end; -// -// LLineStarted := False; -// LCodeStarted := False; -// for i := 0 to ALineStr.Length do -// begin -// LCurrentLetter := ALineStr[i]; -// LNextLetter := ALineStr[Succ(i)]; -// -// if not LCodeStarted then -// begin -// if (LCurrentLetter = BACKTICK) and (LNextLetter <> BACKTICK) then -// begin -// LCodeStarted := True; -// Continue; -// end; -// end; -// -// if (LCurrentLetter = BACKTICK) and (LNextLetter <> BACKTICK) then -// begin -// LCodeStarted := False; -// mmReturn.SelAttributes.Style := []; -// Continue; -// end; -// -// SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); -// if LCodeStarted then -// mmReturn.SelAttributes.Style := [fsBold] -// else -// mmReturn.SelAttributes.Style := []; -// -// if LLineStarted then -// mmReturn.SelText := LCurrentLetter -// else -// begin -// mmReturn.Lines.Add(''); -// mmReturn.SelText := LCurrentLetter; -// -// LLineStarted := True; -// end; -// SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); -// end; -// mmReturn.SelText := ' '; -// SendMessage(mmReturn.Handle, WM_VSCROLL, SB_BOTTOM, 0); -//end; - procedure TDelphiAIDevChatView.WaitingFormON; begin pnWait.Visible := False; diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index f496d3f..ba4d8a7 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -25,6 +25,7 @@ TDelphiAIDevCodeCompletionSearch = class(TInterfacedObject, IDelphiAIDevCodeCo FSettings: TDelphiAIDevSettings; FQuestions: TStrings; FChat: TDelphiAIDevChat; + FVars: TDelphiAIDevCodeCompletionVars; protected procedure Process(const AContext: IOTAKeyContext); public @@ -45,6 +46,7 @@ constructor TDelphiAIDevCodeCompletionSearch.Create; FSettings := TDelphiAIDevSettings.GetInstance; FChat := TDelphiAIDevChat.Create; FQuestions := TStringList.Create; + FVars := TDelphiAIDevCodeCompletionVars.GetInstance; end; destructor TDelphiAIDevCodeCompletionSearch.Destroy; @@ -58,52 +60,46 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex var LRow: Integer; LColumn: Integer; - i: Integer; LText: string; + i: Integer; + LIOTAEditPosition: IOTAEditPosition; begin - FSettings.ValidateFillingSelectedAI; + FSettings.ValidateFillingSelectedAI(TShowMsg.No); FQuestions.Clear; FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); - FQuestions.Add(TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim); + FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeCompletionSuggestion); FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeOnly); + FQuestions.Add(TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim); - FQuestions.Add('Com base no seguinte código delphi, de uma sugestão ' + - 'de código para ser adicionado onde esta o comentário //Suggestion'); - TUtils.ShowMsg(FQuestions.Text); + //TUtils.ShowMsg('CodeCompletionSearch.Process - FQuestions.Text', FQuestions.Text); try FChat.ProcessSend(FQuestions.Text); except Abort; end; - //Self.AddBlockText; - - TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Clear; - for i := 0 to Pred(FChat.Response.Count) do - begin - TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(FChat.Response[i]); - end; - TUtils.ShowMsg(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Text); + FVars.Contents.Text := TUtils.ConfReturnAI(FChat.Response.Text); + //TUtils.ShowMsg('CodeCompletionSearch.Process - FVars.Contents.Text', FVars.Contents.Text); - LRow := AContext.EditBuffer.EditPosition.Row; - LColumn := AContext.EditBuffer.EditPosition.Column; + LIOTAEditPosition := AContext.EditBuffer.EditPosition; + LRow := LIOTAEditPosition.Row; + LColumn := LIOTAEditPosition.Column; - TDelphiAIDevCodeCompletionVars.GetInstance.LineIni := LRow; // + 1; - TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + (TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count); // + 1 //TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + 1; + FVars.Row := LRow; + FVars.Column := LColumn; + FVars.LineIni := LRow; + FVars.LineEnd := FVars.LineIni + FVars.Contents.Count; - //Context.EditBuffer.EditPosition.InsertText(sLineBreak + sLineBreak); LText := ''; - for i := 0 to Pred(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count) do + for i := 0 to Pred(FVars.Contents.Count) do LText := LText + sLineBreak; - AContext.EditBuffer.EditPosition.InsertText(LText.TrimRight + sLineBreak); - AContext.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineIni, LColumn); + LIOTAEditPosition.InsertText(LText); //.TrimRight + sLineBreak); + LIOTAEditPosition.Move(FVars.LineIni, LColumn); - TDelphiAIDevCodeCompletionVars.GetInstance.Row := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni; - TDelphiAIDevCodeCompletionVars.GetInstance.Column := LColumn; - //Context.EditBuffer.EditPosition.MoveBOL; + //LIOTAEditPositionMoveBOL; // //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; // LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView); // if LTextCurrentLineOrBlock.Trim.IsEmpty then diff --git a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas index cabcd68..cc129d5 100644 --- a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas +++ b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas @@ -20,6 +20,8 @@ interface type TDelphiAIDevIDENTAEditViewNotifier = class(TInterfacedObject, IOTANotifier, INTAEditViewNotifier) + private + LVars: TDelphiAIDevCodeCompletionVars; protected FIOTAEditView: IOTAEditView; FIndex: Integer; @@ -57,17 +59,18 @@ constructor TDelphiAIDevIDENTAEditViewNotifier.Create(FileName: string; AEditVie inherited Create; FIOTAEditView := AEditView; FIndex := FIOTAEditView.AddNotifier(Self); + LVars := TDelphiAIDevCodeCompletionVars.GetInstance; end; destructor TDelphiAIDevIDENTAEditViewNotifier.Destroy; begin - RemoveNotifier; + Self.RemoveNotifier; inherited; end; procedure TDelphiAIDevIDENTAEditViewNotifier.Destroyed; begin - RemoveNotifier; + Self.RemoveNotifier; end; procedure TDelphiAIDevIDENTAEditViewNotifier.AfterSave; @@ -92,23 +95,22 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.EditorIdle(const View: IOTAEditView begin TUtilsOTA.GetCursorPosition(LRow, LColumn); -// TUtils.AddLog(Format('EditorIdle - %d (%d) - %d (%d) - %s ', -// [TDelphiAIDevCodeCompletionVars.GetInstance.Row, LRow, TDelphiAIDevCodeCompletionVars.GetInstance.Column, LColumn, DateTimeToStr(Now)])); + //TUtils.AddLog(Format('EditorIdle - %d (%d) - %d (%d) - %s ', [LVars.Row, LRow, LVars.Column, LColumn, DateTimeToStr(Now)])); - if (LRow <> TDelphiAIDevCodeCompletionVars.GetInstance.Row) or (LColumn <> TDelphiAIDevCodeCompletionVars.GetInstance.Column) then + if (LRow <> LVars.Row) or (LColumn <> LVars.Column) then begin - TDelphiAIDevCodeCompletionVars.GetInstance.LineIni := 0; - TDelphiAIDevCodeCompletionVars.GetInstance.Clear; + LVars.LineIni := 0; + LVars.Clear; end; - //TUtils.AddLog('EditorIdle ' + BoolToStr(TDelphiAIDevCodeCompletionVars.GetInstance.ClearNext, True)); + //TUtils.AddLog('EditorIdle ' + BoolToStr(LVars.ClearNext, True)); -// if TDelphiAIDevCodeCompletionVars.GetInstance.ClearNext then +// if LVars.ClearNext then // begin -// TDelphiAIDevCodeCompletionVars.GetInstance.Clear; +// LVars.Clear; // end // else -// TDelphiAIDevCodeCompletionVars.GetInstance.ClearNext := True; +// LVars.ClearNext := True; //View.AddNotifier() //View.GetEditWindow.Form.Repaint; @@ -124,7 +126,6 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.Modified; end; - procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; LineNumber: Integer; const LineText: PAnsiChar; const TextWidth: Word; const LineAttributes: TOTAAttributeArray; const Canvas: TCanvas; const TextRect: TRect; const LineRect: TRect; const CellSize: TSize); @@ -142,13 +143,13 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; //if LineNumber <> View.CursorPos.Line then // Exit; - if (LineNumber >= TDelphiAIDevCodeCompletionVars.GetInstance.LineIni)and(LineNumber <= TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd) then + if (LineNumber >= LVars.LineIni)and(LineNumber <= LVars.LineEnd) then begin Canvas.Brush.Style := bsClear; Canvas.Font.Color := $777777; //$666666; try - LLineText := TDelphiAIDevCodeCompletionVars.GetInstance.Contents[LineNumber - TDelphiAIDevCodeCompletionVars.GetInstance.LineIni]; + LLineText := LVars.Contents[LineNumber - LVars.LineIni]; Canvas.TextOut(TextRect.Left, TextRect.Top, LLineText.TrimRight); except on E: Exception do TUtils.AddLog(E.Message); diff --git a/Src/IDE/OTAEditorNotifier/DelphiAIDev.IDE.OTAEditorNotifier.pas b/Src/IDE/OTAEditorNotifier/DelphiAIDev.IDE.OTAEditorNotifier.pas index 474ed14..f1a7998 100644 --- a/Src/IDE/OTAEditorNotifier/DelphiAIDev.IDE.OTAEditorNotifier.pas +++ b/Src/IDE/OTAEditorNotifier/DelphiAIDev.IDE.OTAEditorNotifier.pas @@ -35,7 +35,6 @@ TDelphiAIDevIDEOTAEditorNotifier = class(TNotifierObject, IOTANotifier, IOTAEd procedure ViewActivated(const View: IOTAEditView); end; - implementation constructor TDelphiAIDevIDEOTAEditorNotifier.Create(ASourceEditor: IOTASourceEditor); diff --git a/Src/IDE/OTAIDENotifier/DelphiAIDev.IDE.OTAIDENotifier.pas b/Src/IDE/OTAIDENotifier/DelphiAIDev.IDE.OTAIDENotifier.pas index f295128..d31ed98 100644 --- a/Src/IDE/OTAIDENotifier/DelphiAIDev.IDE.OTAIDENotifier.pas +++ b/Src/IDE/OTAIDENotifier/DelphiAIDev.IDE.OTAIDENotifier.pas @@ -15,6 +15,7 @@ interface ToolsAPI, DelphiAIDev.Utils, DelphiAIDev.Consts, + DelphiAIDev.Types, DelphiAIDev.CodeCompletion.Vars, DelphiAIDev.IDE.OTAEditorNotifier; @@ -62,7 +63,6 @@ constructor TDelphiAIDevIDEOTAIDENotifier.Create; LIOTASourceEditor: IOTASourceEditor; LExt: string; begin - //TUtils.AddLog('#01 - TC4DFileNotification.Create'); FEditorNotifiers := TList.Create; LIOTAModuleServices := BorlandIDEServices as IOTAModuleServices; for i := 0 to Pred(LIOTAModuleServices.ModuleCount) do @@ -73,7 +73,7 @@ constructor TDelphiAIDevIDEOTAIDENotifier.Create; if Supports(LIOTAModule.ModuleFileEditors[j], IOTASourceEditor, LIOTASourceEditor) then begin LExt := ExtractFileExt(LIOTASourceEditor.FileName).ToLower; - if LExt.Equals('.pas') then + if LExt.Equals(TC4DExtensionsFiles.PAS.ToStringWithPoint) then FEditorNotifiers.Add(TDelphiAIDevIDEOTAEditorNotifier.Create(LIOTASourceEditor)); end; end; @@ -93,8 +93,8 @@ destructor TDelphiAIDevIDEOTAIDENotifier.Destroy; procedure TDelphiAIDevIDEOTAIDENotifier.FileNotification(NotifyCode: TOTAFileNotification; const FileName: string; var Cancel: Boolean); var - LExtensao: string; LIOTAModule: IOTAModule; + LExtension: string; i: Integer; LIOTASourceEditor: IOTASourceEditor; begin @@ -110,8 +110,8 @@ procedure TDelphiAIDevIDEOTAIDENotifier.FileNotification(NotifyCode: TOTAFileNot for i := 0 to Pred(LIOTAModule.ModuleFileCount) do if Supports(LIOTAModule.ModuleFileEditors[i], IOTASourceEditor, LIOTASourceEditor) then begin - LExtensao := ExtractFileExt(LIOTASourceEditor.FileName).ToLower; - if LExtensao.Equals('.pas') then + LExtension := ExtractFileExt(LIOTASourceEditor.FileName).ToLower; + if LExtension.Equals(TC4DExtensionsFiles.PAS.ToStringWithPoint) then FEditorNotifiers.Add(TDelphiAIDevIDEOTAEditorNotifier.Create(LIOTASourceEditor)); end; end; @@ -119,8 +119,10 @@ procedure TDelphiAIDevIDEOTAIDENotifier.FileNotification(NotifyCode: TOTAFileNot if (NotifyCode <> ofnFileOpened) and (NotifyCode <> ofnFileClosing) then Exit; - LExtensao := ExtractFileExt(FileName).ToLower; - if (LExtensao <> '.dproj') and (LExtensao <> '.groupproj') then + LExtension := ExtractFileExt(FileName).ToLower; + if (LExtension <> TC4DExtensionsFiles.DPROJ.ToStringWithPoint) + and (LExtension <> TC4DExtensionsFiles.GROUPPROJ.ToStringWithPoint) + then Exit; end; @@ -129,9 +131,4 @@ initialization finalization if Index >= 0 then (BorlandIDEServices as IOTAServices).RemoveNotifier(Index); - - - - - end. diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 1f72c3e..924360a 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -19,7 +19,6 @@ TDelphiAIDevKeyboardBinding = class(TNotifierObject, IOTAKeyboardBinding) procedure KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); //procedure KeyProcBlockReturn(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); procedure KeyProcBlockReturnAndAlt(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); - procedure AddBlockText; protected function GetBindingType: TBindingType; function GetDisplayName: string; @@ -87,30 +86,27 @@ procedure TDelphiAIDevKeyboardBinding.BindKeyboard(const BindingServices: IOTAKe // if TUtilsOTA.CurrentProjectIsDelphiAIDeveloperDPROJ then // Exit; - BindingServices.AddKeyBinding([Shortcut(VK_HOME, [ssAlt])], Self.KeyAltHome, nil); - BindingServices.AddKeyBinding([Shortcut(VK_TAB, [])], Self.KeyTab, nil); - - //BindingServices.AddKeyBinding([Shortcut(VK_RETURN, [])], Self.KeyProcBlockReturn, nil); BindingServices.AddKeyBinding([Shortcut(VK_RETURN, [ssAlt])], Self.KeyProcBlockReturnAndAlt, nil); + BindingServices.AddKeyBinding([Shortcut(VK_TAB, [])], Self.KeyTab, nil); + BindingServices.AddKeyBinding([Shortcut(VK_HOME, [ssAlt])], Self.KeyAltHome, nil); end; -//procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturn(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); -//begin -// if KeyCode <> Shortcut(VK_RETURN, []) then -// Exit; -// -// TUtils.AddLog(GetCurrentLineOrBlock(CnOtaGetTopMostEditView)); -// BindingResult := TKeyBindingResult.krNextProc; //krUnhandled; -//end; - procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturnAndAlt(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); +begin + try + TDelphiAIDevCodeCompletionSearch.New.Process(Context); + finally + BindingResult := TKeyBindingResult.krUnhandled; + end; +end; + +procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); var LTextCurrentLineOrBlock: string; begin if KeyCode <> Shortcut(VK_RETURN, [ssAlt]) then Exit; - //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView).Trim; if LTextCurrentLineOrBlock.Trim.IsEmpty then Exit; @@ -121,84 +117,7 @@ procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturnAndAlt(const Context: IO DelphiAIDev.Chat.View.DelphiAIDevChatView.QuestionOnShow := LTextCurrentLineOrBlock; DelphiAIDev.Chat.View.DelphiAIDevChatViewShowDockableForm; - BindingResult := TKeyBindingResult.krUnhandled; //krNextProc; -end; - -procedure TDelphiAIDevKeyboardBinding.AddBlockText; -begin - TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Clear; - TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(' TUtils.AddLog(EmptyStr);'); - TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(' TUtils.ShowMsg(EmptyStr);'); - TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Add(' TUtils.ShowMsg(LMsg3);'); -end; - -procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); -var - LRow: Integer; - LColumn: Integer; - i: Integer; - LText: string; -begin - if KeyCode <> Shortcut(VK_HOME, [ssAlt]) then - Exit; - - TDelphiAIDevCodeCompletionSearch.New.Process(Context); - - //Self.AddBlockText; - - LRow := Context.EditBuffer.EditPosition.Row; - LColumn := Context.EditBuffer.EditPosition.Column; - - TDelphiAIDevCodeCompletionVars.GetInstance.LineIni := LRow; // + 1; - TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + (TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count); // + 1 //TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + 1; - - //Context.EditBuffer.EditPosition.InsertText(sLineBreak + sLineBreak); - LText := ''; - for i := 0 to Pred(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count) do - LText := LText + sLineBreak; - - Context.EditBuffer.EditPosition.InsertText(LText.TrimRight + sLineBreak); - Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineIni, LColumn); - - TDelphiAIDevCodeCompletionVars.GetInstance.Row := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni; - TDelphiAIDevCodeCompletionVars.GetInstance.Column := LColumn; - - //Context.EditBuffer.EditPosition.MoveBOL; - // //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; - // LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView); - // if LTextCurrentLineOrBlock.Trim.IsEmpty then - // Exit; - - BindingResult := TKeyBindingResult.krUnhandled; //krNextProc; - - - //** - //Self.AddBlockText; - - {LRow := Context.EditBuffer.EditPosition.Row; - LColumn := Context.EditBuffer.EditPosition.Column; - - TDelphiAIDevCodeCompletionVars.GetInstance.LineIni := LRow; // + 1; - TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + (TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count); // + 1 //TDelphiAIDevCodeCompletionVars.GetInstance.LineIni + 1; - - //Context.EditBuffer.EditPosition.InsertText(sLineBreak + sLineBreak); - LText := ''; - for i := 0 to Pred(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count) do - LText := LText + sLineBreak; - - Context.EditBuffer.EditPosition.InsertText(LText.TrimRight + sLineBreak); - Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineIni, LColumn); - - TDelphiAIDevCodeCompletionVars.GetInstance.Row := TDelphiAIDevCodeCompletionVars.GetInstance.LineIni; - TDelphiAIDevCodeCompletionVars.GetInstance.Column := LColumn; - - //Context.EditBuffer.EditPosition.MoveBOL; - // //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; - // LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView); - // if LTextCurrentLineOrBlock.Trim.IsEmpty then - // Exit; - - BindingResult := TKeyBindingResult.krUnhandled; //krNextProc; } + BindingResult := TKeyBindingResult.krUnhandled; end; procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); @@ -206,14 +125,11 @@ procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyC LText: string; i: Integer; begin - TUtils.AddLog('KeyTab ' + TDelphiAIDevCodeCompletionVars.GetInstance.LineIni.ToString); - if KeyCode <> Shortcut(VK_TAB, []) then Exit; if TDelphiAIDevCodeCompletionVars.GetInstance.LineIni > 0 then begin - //Context.EditBuffer.EditPosition.InsertText('Minha linha 01' + sLineBreak + 'Linha 2'); LText := ''; for i := 0 to Pred(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count) do LText := LText + TDelphiAIDevCodeCompletionVars.GetInstance.Contents[i].Trim + sLineBreak; @@ -222,10 +138,10 @@ procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyC //Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd, 20); TDelphiAIDevCodeCompletionVars.GetInstance.Clear; - end; - - BindingResult := TKeyBindingResult.krUnhandled; //krNextProc; - TUtils.AddLog('KeyTab krUnhandled'); + BindingResult := TKeyBindingResult.krHandled; + end + else + BindingResult := TKeyBindingResult.krUnhandled; end; initialization diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 7b13457..a7fec97 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -817,7 +817,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 16 Top = 7 Width = 80 - Height = 13 + Height = 21 Cursor = crHandPoint Margins.Left = 16 Margins.Top = 5 @@ -834,13 +834,14 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView ShowHint = True Layout = tlCenter OnClick = lbRestoreDefaultsClick + ExplicitHeight = 13 end object lbOpenDataFolder: TLabel AlignWithMargins = True Left = 115 Top = 7 Width = 85 - Height = 13 + Height = 21 Cursor = crHandPoint Margins.Left = 16 Margins.Top = 5 @@ -857,6 +858,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView ShowHint = True Layout = tlCenter OnClick = lbOpenDataFolderClick + ExplicitHeight = 13 end object btnConfirm: TButton AlignWithMargins = True diff --git a/Src/Settings/DelphiAIDev.Settings.View.pas b/Src/Settings/DelphiAIDev.Settings.View.pas index 55dcac7..94af90b 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.pas +++ b/Src/Settings/DelphiAIDev.Settings.View.pas @@ -136,7 +136,6 @@ procedure TDelphiAIDevSettingsView.FormShow(Sender: TObject); begin FSettings.LoadData; Self.ConfigScreen; - //FSettings.LoadData; Self.LoadSettings; end; diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index 33f9f75..12bef23 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -59,7 +59,7 @@ TDelphiAIDevSettings = class procedure LoadDefaults; procedure SaveData; procedure LoadData; - procedure ValidateFillingSelectedAI; + procedure ValidateFillingSelectedAI(const AShowMsg: TShowMsg = TShowMsg.Yes); property LanguageQuestions: TC4DLanguage read FLanguageQuestions write FLanguageQuestions; property AIDefault: TC4DAIsAvailable read FAIDefault write FAIDefault; @@ -237,52 +237,59 @@ procedure TDelphiAIDevSettings.LoadData; end; end; -procedure TDelphiAIDevSettings.ValidateFillingSelectedAI; +procedure TDelphiAIDevSettings.ValidateFillingSelectedAI(const AShowMsg: TShowMsg = TShowMsg.Yes); const MSG = '"%s" for IA %s not specified in settings.' + sLineBreak + sLineBreak + 'Access menu > AI Developer > Settings'; + + procedure ShowMsgInternal(const AArgs: array of const);//(const AMsg: string); + begin + if AShowMsg = TShowMsg.Yes then + TUtils.ShowMsg(Format(MSG, AArgs)); + Abort; + end; begin case FAIDefault of TC4DAIsAvailable.Gemini: begin if FBaseUrlGemini.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'Gemini'])); + ShowMsgInternal(['Base URL', 'Gemini']); if FModelGemini.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Gemini'])); + ShowMsgInternal(['Model', 'Gemini']); if FApiKeyGemini.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'Gemini'])); + ShowMsgInternal(['API Key', 'Gemini']); end; TC4DAIsAvailable.OpenAI: begin if FBaseUrlOpenAI.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'ChatGPT'])); + ShowMsgInternal(['Base URL', 'ChatGPT']); if FModelOpenAI.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'ChatGPT'])); + ShowMsgInternal(['Model', 'ChatGPT']); if FApiKeyOpenAI.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'ChatGPT'])); + ShowMsgInternal(['API Key', 'ChatGPT']); end; TC4DAIsAvailable.Groq: begin if FBaseUrlGroq.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'Groq'])); + ShowMsgInternal(['Base URL', 'Groq']); if FModelGroq.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Groq'])); + ShowMsgInternal(['Model', 'Groq']); if FApiKeyGroq.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['API Key', 'Groq'])); + ShowMsgInternal(['API Key', 'Groq']); end; TC4DAIsAvailable.Ollama: begin if FBaseUrlOllama.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Base URL', 'Ollama'])); + ShowMsgInternal(['Base URL', 'Ollama']); if FModelOllama.Trim.IsEmpty then - TUtils.ShowMsgAndAbort(Format(MSG, ['Model', 'Ollama'])); + ShowMsgInternal(['Model', 'Ollama']); end; end; end; diff --git a/Src/Test/DelphiAIDev.Test.Client.pas b/Src/Test/DelphiAIDev.Test.Client.pas new file mode 100644 index 0000000..8aa1ba6 --- /dev/null +++ b/Src/Test/DelphiAIDev.Test.Client.pas @@ -0,0 +1,35 @@ +unit DelphiAIDev.Test.Client; + +interface + +type + TDelphiAIDevTestClient = class + private + FNome: string; + FEndereco: string; + FBairro: string; + FNumero: Integer; + FTelefone: string; + FEmail: string; + FDataNascimento: TDateTime; + public + property Nome: string read FNome write FNome; + property Endereco: string read FEndereco write FEndereco; + property Bairro: string read FBairro write FBairro; + property Numero: Integer read FNumero write FNumero; + property Telefone: string read FTelefone write FTelefone; + property Email: string read FEmail write FEmail; + property DataNascimento: TDateTime read FDataNascimento write FDataNascimento; + + procedure Clear; + end; + +implementation + +procedure TDelphiAIDevTestClient.Clear; +begin + //Suggestion + +end; + +end. diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 6874a8e..ab264ef 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -12,6 +12,7 @@ TDelphiAIDevTest = class FTelefone: string; FEmail: string; FDataNascimento: TDateTime; + FApelido: string; public property Nome: string read FNome write FNome; property Endereco: string read FEndereco write FEndereco; @@ -20,19 +21,16 @@ TDelphiAIDevTest = class property Telefone: string read FTelefone write FTelefone; property Email: string read FEmail write FEmail; property DataNascimento: TDateTime read FDataNascimento write FDataNascimento; + //Suggestion + property Apelido: string read FApelido write FApelido; procedure Clear; end; implementation -{ TDelphiAIDevTest } - procedure TDelphiAIDevTest.Clear; begin - //Suggestion - - end; diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index 9f770e6..c6ce841 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -13,7 +13,7 @@ interface {$SCOPEDENUMS ON} TC4DAIsAvailable = (Gemini, OpenAI, Groq, Ollama); TC4DLanguage = (en, ptBR, es); - TC4DExtensionsFiles = (None, PAS, DFM, FMX, DPR, DPK, DPROJ, ZIP, BMP, INI, ALL); + TC4DExtensionsFiles = (None, PAS, DFM, FMX, DPR, DPK, DPROJ, GROUPPROJ, ZIP, BMP, INI, ALL); TC4DExtensionsOfFiles = set of TC4DExtensionsFiles; TC4DExtensionsCommon = (rtf, csv, txt); TC4DIcon = (Information, Question, Warning, Error, Success); @@ -22,6 +22,7 @@ interface TC4DQuestionKind = (None, ItemMenuNormal, MenuMasterOnly, Separators); TC4DDriverID = (None, MySQL, Firebird); TAutoFreeField = (Yes, No); + TShowMsg = (Yes, No); {$SCOPEDENUMS OFF} TC4DAIsAvailableHelper = record helper for TC4DAIsAvailable @@ -36,6 +37,7 @@ TC4DLanguageHelper = record helper for TC4DLanguage function GetMsgSQLOnly: string; function GetMsgJSONIsDatabaseStructure(ASGBDName: string): string; function GetMsgJSONInformedAnswerQuestion: string; + function GetMsgCodeCompletionSuggestion: string; end; TC4DExtensionsFilesHelper = record helper for TC4DExtensionsFiles @@ -119,7 +121,8 @@ function TC4DLanguageHelper.GetLanguageDefinition: string; function TC4DLanguageHelper.GetMsgCodeOnly: string; begin - Result := 'Faça a seguinte ação sem adicionar comentários:'; + //Result := 'Faça a seguinte ação sem adicionar nenhum comentários'; + Result := 'Responda a pergunta sem adicionar nenhum comentários, retorne apenas o código fonte'; case Self of TC4DLanguage.en: Result := 'Perform the following action without adding comments:'; @@ -169,6 +172,20 @@ function TC4DLanguageHelper.GetMsgJSONInformedAnswerQuestion: string; Result := Result + sLineBreak; end; +function TC4DLanguageHelper.GetMsgCodeCompletionSuggestion: string; +begin + Result := 'Com base no seguinte código delphi, de uma sugestão ' + + 'de código para ser adicionado onde esta o comentário //Suggestion'; + case Self of + TC4DLanguage.en: + Result := 'Based on the following Delphi code, give a suggestion of code to be added where the comment //Suggestion is'; + TC4DLanguage.es: + Result := 'Basado en el siguiente código Delphi, se agregará una sugerencia de código donde está el comentario //Sugerencia'; + end; + + Result := Result + sLineBreak; +end; + { TC4DExtensionsFilesHelper } function TC4DExtensionsFilesHelper.ToString: string; begin @@ -187,23 +204,25 @@ function TC4DExtensionsOfFilesHelper.ContainsStr(const AExtension: string): Bool begin Result := False; LExtension := AExtension.Trim.ToLower; - if LExtension = '.pas' then + if LExtension = TC4DExtensionsFiles.PAS.ToStringWithPoint then Result := TC4DExtensionsFiles.PAS in Self - else if LExtension = '.dfm' then + else if LExtension = TC4DExtensionsFiles.DFM.ToStringWithPoint then Result := TC4DExtensionsFiles.DFM in Self - else if LExtension = '.fmx' then + else if LExtension = TC4DExtensionsFiles.FMX.ToStringWithPoint then Result := TC4DExtensionsFiles.FMX in Self - else if LExtension = '.dpr' then + else if LExtension = TC4DExtensionsFiles.DPR.ToStringWithPoint then Result := TC4DExtensionsFiles.DPR in Self - else if LExtension = '.dpk' then + else if LExtension = TC4DExtensionsFiles.DPK.ToStringWithPoint then Result := TC4DExtensionsFiles.DPK in Self - else if LExtension = '.dproj' then + else if LExtension = TC4DExtensionsFiles.DPROJ.ToStringWithPoint then Result := TC4DExtensionsFiles.DPROJ in Self - else if LExtension = '.zip' then + else if LExtension = TC4DExtensionsFiles.GROUPPROJ.ToStringWithPoint then + Result := TC4DExtensionsFiles.GROUPPROJ in Self + else if LExtension =TC4DExtensionsFiles.ZIP.ToStringWithPoint then Result := TC4DExtensionsFiles.ZIP in Self - else if LExtension = '.bmp' then + else if LExtension = TC4DExtensionsFiles.BMP.ToStringWithPoint then Result := TC4DExtensionsFiles.BMP in Self - else if LExtension = '.ini' then + else if LExtension = TC4DExtensionsFiles.INI.ToStringWithPoint then Result := TC4DExtensionsFiles.INI in Self; end; diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index dc27141..d71f5e6 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -214,7 +214,7 @@ class function TUtils.AdjustQuestionToJson(const AValue: string): string; class procedure TUtils.AddLog(const AMessage: string); const - DIRECTORY = 'C:\TempLog\DelphiAIDev\'; + DIRECTORY = 'C:\Temp\DelphiAIDev\'; var LFileName: string; LTextFile: TextFile; @@ -1043,7 +1043,7 @@ class function TUtils.IsDPK(const AFilePath: string): Boolean; class function TUtils.IsProjectGroup(const AFilePath: string): Boolean; begin - Result := ExtractFileExt(AFilePath).ToLower = '.groupproj'; + Result := ExtractFileExt(AFilePath).ToLower = TC4DExtensionsFiles.GROUPPROJ.ToStringWithPoint; end; class function TUtils.IsProject(const AFilePath: string): Boolean; From 18c009b58e64481d3af5607295f3f6324326dc8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 29 Aug 2024 16:54:06 -0300 Subject: [PATCH 050/109] bk/2024-08-29-1654 --- .../DelphiAIDev.CodeCompletion.Search.pas | 11 ++++- Src/Consts/DelphiAIDev.Consts.pas | 1 + .../DelphiAIDev.KeyboardBinding.pas | 40 +++++++++---------- Src/Test/DelphiAIDev.Test.pas | 7 +--- Src/Utils/DelphiAIDev.Utils.OTA.pas | 3 -- 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index ba4d8a7..3157e18 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -66,11 +66,19 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex begin FSettings.ValidateFillingSelectedAI(TShowMsg.No); + FQuestions.Clear; FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeCompletionSuggestion); FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeOnly); - FQuestions.Add(TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim); + + LIOTAEditPosition := AContext.EditBuffer.EditPosition; + LIOTAEditPosition.InsertText(TConsts.TAG_CODE_COMPLETION); + try + FQuestions.Add(TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim); + finally + LIOTAEditPosition.BackspaceDelete(TConsts.TAG_CODE_COMPLETION.Length); + end; //TUtils.ShowMsg('CodeCompletionSearch.Process - FQuestions.Text', FQuestions.Text); try @@ -82,7 +90,6 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex FVars.Contents.Text := TUtils.ConfReturnAI(FChat.Response.Text); //TUtils.ShowMsg('CodeCompletionSearch.Process - FVars.Contents.Text', FVars.Contents.Text); - LIOTAEditPosition := AContext.EditBuffer.EditPosition; LRow := LIOTAEditPosition.Row; LColumn := LIOTAEditPosition.Column; diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index ba55055..c86ad31 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -24,6 +24,7 @@ TConsts = class MARK_BEGIN_SQL2 = '``sql'; MARK_END = '```'; PREFIX_NAME_SEPARATOR = 'DelphiAIDevSeparator'; + TAG_CODE_COMPLETION = '//Suggestion_Code_Delphi'; //SETTINGS KEY_SETTINGS_IN_WINDOWS_REGISTRY = '\SOFTWARE\DelphiAIDeveloper'; diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 924360a..e526c71 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -100,26 +100,6 @@ procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturnAndAlt(const Context: IO end; end; -procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); -var - LTextCurrentLineOrBlock: string; -begin - if KeyCode <> Shortcut(VK_RETURN, [ssAlt]) then - Exit; - - LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView).Trim; - if LTextCurrentLineOrBlock.Trim.IsEmpty then - Exit; - - if copy(LTextCurrentLineOrBlock, 1, 2) = '//' then - LTextCurrentLineOrBlock := copy(LTextCurrentLineOrBlock, 3, LTextCurrentLineOrBlock.Length); - - DelphiAIDev.Chat.View.DelphiAIDevChatView.QuestionOnShow := LTextCurrentLineOrBlock; - DelphiAIDev.Chat.View.DelphiAIDevChatViewShowDockableForm; - - BindingResult := TKeyBindingResult.krUnhandled; -end; - procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); var LText: string; @@ -144,6 +124,26 @@ procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyC BindingResult := TKeyBindingResult.krUnhandled; end; +procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); +var + LTextCurrentLineOrBlock: string; +begin + if KeyCode <> Shortcut(VK_RETURN, [ssAlt]) then + Exit; + + LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView).Trim; + if LTextCurrentLineOrBlock.Trim.IsEmpty then + Exit; + + if copy(LTextCurrentLineOrBlock, 1, 2) = '//' then + LTextCurrentLineOrBlock := copy(LTextCurrentLineOrBlock, 3, LTextCurrentLineOrBlock.Length); + + DelphiAIDev.Chat.View.DelphiAIDevChatView.QuestionOnShow := LTextCurrentLineOrBlock; + DelphiAIDev.Chat.View.DelphiAIDevChatViewShowDockableForm; + + BindingResult := TKeyBindingResult.krUnhandled; +end; + initialization finalization diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index ab264ef..7c948a0 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -13,6 +13,7 @@ TDelphiAIDevTest = class FEmail: string; FDataNascimento: TDateTime; FApelido: string; + FCep: Integer; public property Nome: string read FNome write FNome; property Endereco: string read FEndereco write FEndereco; @@ -21,17 +22,13 @@ TDelphiAIDevTest = class property Telefone: string read FTelefone write FTelefone; property Email: string read FEmail write FEmail; property DataNascimento: TDateTime read FDataNascimento write FDataNascimento; - //Suggestion property Apelido: string read FApelido write FApelido; + property Cep: Integer read FCep write FCep; procedure Clear; end; implementation -procedure TDelphiAIDevTest.Clear; -begin - -end; end. diff --git a/Src/Utils/DelphiAIDev.Utils.OTA.pas b/Src/Utils/DelphiAIDev.Utils.OTA.pas index a1980ab..afa4630 100644 --- a/Src/Utils/DelphiAIDev.Utils.OTA.pas +++ b/Src/Utils/DelphiAIDev.Utils.OTA.pas @@ -309,10 +309,7 @@ class function TUtilsOTA.EditorAsString(AIOTAModule: IOTAModule): string; LOTASourceEditor := Self.GetIOTASourceEditor(AIOTAModule); if LOTASourceEditor = nil then - begin - //TUtils.ShowMsgSynchronize('Unable to get SourceEditor.'); Exit; - end; LIOTAEditReader := LOTASourceEditor.CreateReader; try From e785c91f6ad5e0dce04c5f4a1a46dce90ccfe7a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 29 Aug 2024 17:40:24 -0300 Subject: [PATCH 051/109] refactor/separado-key-tab --- Package/DelphiAIDeveloper.dpk | 3 +- Package/DelphiAIDeveloper.dproj | 1 + .../DelphiAIDev.CodeCompletion.KeyTab.pas | 54 +++++++++++++++++++ .../DelphiAIDev.KeyboardBinding.pas | 15 ++---- Src/Test/DelphiAIDev.Test.pas | 4 ++ 5 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 53bc54c..78d5ca3 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -112,6 +112,7 @@ contains DelphiAIDev.IDE.OTAEditorNotifier in '..\Src\IDE\OTAEditorNotifier\DelphiAIDev.IDE.OTAEditorNotifier.pas', DelphiAIDev.IDE.NTAEditViewNotifier in '..\Src\IDE\NTAEditViewNotifier\DelphiAIDev.IDE.NTAEditViewNotifier.pas', DelphiAIDev.CodeCompletion.Search in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Search.pas', - DelphiAIDev.Test.Client in '..\Src\Test\DelphiAIDev.Test.Client.pas'; + DelphiAIDev.Test.Client in '..\Src\Test\DelphiAIDev.Test.Client.pas', + DelphiAIDev.CodeCompletion.KeyTab in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.KeyTab.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index cdba060..750c39e 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -228,6 +228,7 @@ + BITMAP c4d_Logo diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas new file mode 100644 index 0000000..f3d006c --- /dev/null +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas @@ -0,0 +1,54 @@ +unit DelphiAIDev.CodeCompletion.KeyTab; + +interface + +uses + System.SysUtils, + System.Classes, + ToolsAPI, + DelphiAIDev.CodeCompletion.Vars; + +type + IDelphiAIDevCodeCompletionKeyTab = interface + ['{A032D6DE-E66D-4088-B384-5FEE82F65160}'] + procedure Process(const AContext: IOTAKeyContext); + end; + + TDelphiAIDevCodeCompletionKeyTab = class(TInterfacedObject, IDelphiAIDevCodeCompletionKeyTab) + private + FVars: TDelphiAIDevCodeCompletionVars; + protected + procedure Process(const AContext: IOTAKeyContext); + public + class function New: IDelphiAIDevCodeCompletionKeyTab; + constructor Create; + end; + +implementation + +class function TDelphiAIDevCodeCompletionKeyTab.New: IDelphiAIDevCodeCompletionKeyTab; +begin + Result := Self.Create; +end; + +constructor TDelphiAIDevCodeCompletionKeyTab.Create; +begin + FVars := TDelphiAIDevCodeCompletionVars.GetInstance; +end; + +procedure TDelphiAIDevCodeCompletionKeyTab.Process(const AContext: IOTAKeyContext); +var + LText: string; + i: Integer; +begin + LText := ''; + for i := 0 to Pred(FVars.Contents.Count) do + LText := LText + FVars.Contents[i].Trim + sLineBreak; + + AContext.EditBuffer.EditPosition.InsertText(LText.Trim); + //Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd, 20); + + FVars.GetInstance.Clear; +end; + +end. diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index e526c71..7ffec36 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -10,7 +10,8 @@ interface ToolsAPI, DelphiAIDev.Utils.CnWizard, DelphiAIDev.Chat.View, - DelphiAIDev.CodeCompletion.Search; + DelphiAIDev.CodeCompletion.Search, + DelphiAIDev.CodeCompletion.KeyTab; type TDelphiAIDevKeyboardBinding = class(TNotifierObject, IOTAKeyboardBinding) @@ -101,23 +102,13 @@ procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturnAndAlt(const Context: IO end; procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); -var - LText: string; - i: Integer; begin if KeyCode <> Shortcut(VK_TAB, []) then Exit; if TDelphiAIDevCodeCompletionVars.GetInstance.LineIni > 0 then begin - LText := ''; - for i := 0 to Pred(TDelphiAIDevCodeCompletionVars.GetInstance.Contents.Count) do - LText := LText + TDelphiAIDevCodeCompletionVars.GetInstance.Contents[i].Trim + sLineBreak; - - Context.EditBuffer.EditPosition.InsertText(LText.Trim); - //Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd, 20); - - TDelphiAIDevCodeCompletionVars.GetInstance.Clear; + TDelphiAIDevCodeCompletionKeyTab.New.Process(Context); BindingResult := TKeyBindingResult.krHandled; end else diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 7c948a0..3c79ed5 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -30,5 +30,9 @@ TDelphiAIDevTest = class implementation +procedure TDelphiAIDevTest.Clear; +begin + +end; end. From ad03b7860e9c3504777e9e618c9536168c16182d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 29 Aug 2024 23:38:55 -0300 Subject: [PATCH 052/109] add-settings-code-complet --- Src/Chat/DelphiAIDev.Chat.View.pas | 18 +- Src/Chat/DelphiAIDev.Chat.pas | 8 +- Src/Consts/DelphiAIDev.Consts.pas | 2 + Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 18 +- .../DelphiAIDev.IDE.NTAEditViewNotifier.pas | 19 +- .../DelphiAIDev.KeyboardBinding.pas | 15 +- Src/Settings/DelphiAIDev.Settings.View.dfm | 1827 ++++++++++------- Src/Settings/DelphiAIDev.Settings.View.pas | 193 +- Src/Settings/DelphiAIDev.Settings.pas | 66 +- Src/Types/DelphiAIDev.Types.pas | 20 +- 10 files changed, 1290 insertions(+), 896 deletions(-) diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index 186b8e9..f062c0e 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -607,13 +607,13 @@ procedure TDelphiAIDevChatView.pMenuCurrentAIPopup(Sender: TObject); Groq1.Checked := False; Ollama1.Checked := False; case FSettings.AIDefault of - TC4DAIsAvailable.Gemini: + TC4DAiAvailable.Gemini: Gemini1.Checked := True; - TC4DAIsAvailable.OpenAI: + TC4DAiAvailable.OpenAI: ChatGPT1.Checked := True; - TC4DAIsAvailable.Groq: + TC4DAiAvailable.Groq: Groq1.Checked := True; - TC4DAIsAvailable.Ollama: + TC4DAiAvailable.Ollama: Ollama1.Checked := True; end; end; @@ -623,13 +623,13 @@ procedure TDelphiAIDevChatView.ConfLabelCurrentAI; lbCurrentAI.Caption := FSettings.AIDefault.ToString; case FSettings.AIDefault of - TC4DAIsAvailable.Gemini: + TC4DAiAvailable.Gemini: lbCurrentAI.Hint := FSettings.ModelGemini; - TC4DAIsAvailable.OpenAI: + TC4DAiAvailable.OpenAI: lbCurrentAI.Hint := FSettings.ModelOpenAI; - TC4DAIsAvailable.Groq: + TC4DAiAvailable.Groq: lbCurrentAI.Hint := FSettings.ModelGroq; - TC4DAIsAvailable.Ollama: + TC4DAiAvailable.Ollama: lbCurrentAI.Hint := FSettings.ModelOllama; end; @@ -646,7 +646,7 @@ procedure TDelphiAIDevChatView.Gemini1Click(Sender: TObject); if not(LTag in [0, 1, 2, 3])then Exit; - FSettings.AIDefault := TC4DAIsAvailable(LTag); + FSettings.AIDefault := TC4DAiAvailable(LTag); FSettings.SaveData; Self.ConfLabelCurrentAI; end; diff --git a/Src/Chat/DelphiAIDev.Chat.pas b/Src/Chat/DelphiAIDev.Chat.pas index ec0a21e..04ea374 100644 --- a/Src/Chat/DelphiAIDev.Chat.pas +++ b/Src/Chat/DelphiAIDev.Chat.pas @@ -48,13 +48,13 @@ procedure TDelphiAIDevChat.ProcessSend(const AQuestion: string); FResponse.Clear; case FSettings.AIDefault of - TC4DAIsAvailable.Gemini: + TC4DAiAvailable.Gemini: FResponse.Text := TDelphiAIDevAIGemini.New(FSettings).GetResponse(LQuestion); - TC4DAIsAvailable.OpenAI: + TC4DAiAvailable.OpenAI: FResponse.Text := TDelphiAIDevAIChatGPT.New(FSettings).GetResponse(LQuestion); - TC4DAIsAvailable.Groq: + TC4DAiAvailable.Groq: FResponse.Text := TDelphiAIDevAIGroq.New(FSettings).GetResponse(LQuestion); - TC4DAIsAvailable.Ollama: + TC4DAiAvailable.Ollama: FResponse.Text := TDelphiAIDevAIOllama.New(FSettings).GetResponse(LQuestion); else FResponse.Text := 'Default AI not reported in Delphi AI Developer settings'; diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index c86ad31..b46f3ee 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -16,6 +16,8 @@ TConsts = class GITHUB_Code4Delphi = 'https://github.com/Code4Delphi'; GITHUB_PROJECT = 'https://github.com/Code4Delphi/Delphi-AI-Developer'; APPLICATION_JSON = 'application/json'; + CODE_COMPLETION_SUGGESTION_COLOR = $777777; + CODE_COMPLETION_SHORTCUT_INVOKE = 'Alt+Enter'; MARK_BEGIN_DELPHI = '```delphi'; MARK_BEGIN_PASCAL = '```objectpascal'; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 3b4dc01..9eeb961 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -613,13 +613,13 @@ procedure TDelphiAIDevDBChatView.pMenuCurrentAIPopup(Sender: TObject); Groq1.Checked := False; Ollama1.Checked := False; case FSettings.AIDefault of - TC4DAIsAvailable.Gemini: + TC4DAiAvailable.Gemini: Gemini1.Checked := True; - TC4DAIsAvailable.OpenAI: + TC4DAiAvailable.OpenAI: ChatGPT1.Checked := True; - TC4DAIsAvailable.Groq: + TC4DAiAvailable.Groq: Groq1.Checked := True; - TC4DAIsAvailable.Ollama: + TC4DAiAvailable.Ollama: Ollama1.Checked := True; end; end; @@ -629,13 +629,13 @@ procedure TDelphiAIDevDBChatView.ConfLabelCurrentAI; lbCurrentAI.Caption := FSettings.AIDefault.ToString; case FSettings.AIDefault of - TC4DAIsAvailable.Gemini: + TC4DAiAvailable.Gemini: lbCurrentAI.Hint := FSettings.ModelGemini; - TC4DAIsAvailable.OpenAI: + TC4DAiAvailable.OpenAI: lbCurrentAI.Hint := FSettings.ModelOpenAI; - TC4DAIsAvailable.Groq: + TC4DAiAvailable.Groq: lbCurrentAI.Hint := FSettings.ModelGroq; - TC4DAIsAvailable.Ollama: + TC4DAiAvailable.Ollama: lbCurrentAI.Hint := FSettings.ModelOllama; end; @@ -652,7 +652,7 @@ procedure TDelphiAIDevDBChatView.Gemini1Click(Sender: TObject); if not(LTag in [0, 1, 2, 3])then Exit; - FSettings.AIDefault := TC4DAIsAvailable(LTag); + FSettings.AIDefault := TC4DAiAvailable(LTag); FSettings.SaveData; Self.ConfLabelCurrentAI; end; diff --git a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas index cc129d5..5bbe40e 100644 --- a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas +++ b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas @@ -16,6 +16,7 @@ interface DelphiAIDev.Utils.OTA, DelphiAIDev.Consts, DelphiAIDev.CodeCompletion.Vars, + DelphiAIDev.Settings, ToolsAPI; type @@ -95,30 +96,16 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.EditorIdle(const View: IOTAEditView begin TUtilsOTA.GetCursorPosition(LRow, LColumn); - //TUtils.AddLog(Format('EditorIdle - %d (%d) - %d (%d) - %s ', [LVars.Row, LRow, LVars.Column, LColumn, DateTimeToStr(Now)])); - if (LRow <> LVars.Row) or (LColumn <> LVars.Column) then begin LVars.LineIni := 0; LVars.Clear; end; - - //TUtils.AddLog('EditorIdle ' + BoolToStr(LVars.ClearNext, True)); - -// if LVars.ClearNext then -// begin -// LVars.Clear; -// end -// else -// LVars.ClearNext := True; - - //View.AddNotifier() - //View.GetEditWindow.Form.Repaint; end; procedure TDelphiAIDevIDENTAEditViewNotifier.EndPaint(const View: IOTAEditView); begin - //TUtils.AddLog('EndPaint'); + end; procedure TDelphiAIDevIDENTAEditViewNotifier.Modified; @@ -147,6 +134,8 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; begin Canvas.Brush.Style := bsClear; Canvas.Font.Color := $777777; //$666666; + if TDelphiAIDevSettings.GetInstance.CodeCompletionSuggestionColorUse then + Canvas.Font.Color := TDelphiAIDevSettings.GetInstance.CodeCompletionSuggestionColor; try LLineText := LVars.Contents[LineNumber - LVars.LineIni]; diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 7ffec36..62bb1d9 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -8,10 +8,12 @@ interface Winapi.Windows, Vcl.Menus, ToolsAPI, + DelphiAIDev.Consts, DelphiAIDev.Utils.CnWizard, DelphiAIDev.Chat.View, DelphiAIDev.CodeCompletion.Search, - DelphiAIDev.CodeCompletion.KeyTab; + DelphiAIDev.CodeCompletion.KeyTab, + DelphiAIDev.Settings; type TDelphiAIDevKeyboardBinding = class(TNotifierObject, IOTAKeyboardBinding) @@ -83,11 +85,20 @@ function TDelphiAIDevKeyboardBinding.GetName: string; end; procedure TDelphiAIDevKeyboardBinding.BindKeyboard(const BindingServices: IOTAKeyBindingServices); +var + LShortcut: string; begin // if TUtilsOTA.CurrentProjectIsDelphiAIDeveloperDPROJ then // Exit; - BindingServices.AddKeyBinding([Shortcut(VK_RETURN, [ssAlt])], Self.KeyProcBlockReturnAndAlt, nil); + //BindingServices.AddKeyBinding([Shortcut(VK_RETURN, [ssAlt])], Self.KeyProcBlockReturnAndAlt, nil); + LShortcut := TConsts.CODE_COMPLETION_SHORTCUT_INVOKE; + if not(Trim(TDelphiAIDevSettings.GetInstance.CodeCompletionShortcutInvoke).IsEmpty) then + LShortcut := TDelphiAIDevSettings.GetInstance.CodeCompletionShortcutInvoke; + + TUtils.ShowMsg(LShortcut); + BindingServices.AddKeyBinding([TextToShortCut(LShortcut)], Self.KeyProcBlockReturnAndAlt, nil); + BindingServices.AddKeyBinding([Shortcut(VK_TAB, [])], Self.KeyTab, nil); BindingServices.AddKeyBinding([Shortcut(VK_HOME, [ssAlt])], Self.KeyAltHome, nil); end; diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index a7fec97..222aa2b 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -2,8 +2,8 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Caption = 'Delphi AI Developer - Settings' - ClientHeight = 647 - ClientWidth = 632 + ClientHeight = 601 + ClientWidth = 670 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -21,875 +21,1112 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object pnBackAll: TPanel Left = 0 Top = 0 - Width = 632 - Height = 647 + Width = 670 + Height = 601 Align = alClient BevelOuter = bvNone TabOrder = 0 - object pnBody: TPanel + object pnBottom: TPanel Left = 0 - Top = 0 - Width = 632 - Height = 612 - Align = alClient + Top = 566 + Width = 670 + Height = 35 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alBottom + BevelEdges = [beLeft, beRight, beBottom] BevelOuter = bvNone + Padding.Top = 2 + Padding.Right = 2 + Padding.Bottom = 2 ParentBackground = False TabOrder = 0 - object Bevel1: TBevel + object lbRestoreDefaults: TLabel AlignWithMargins = True - Left = 0 - Top = 608 - Width = 632 - Height = 1 - Margins.Left = 0 - Margins.Top = 0 - Margins.Right = 0 - Align = alBottom - Shape = bsTopLine - ExplicitTop = 158 - ExplicitWidth = 441 + Left = 16 + Top = 7 + Width = 80 + Height = 21 + Cursor = crHandPoint + Margins.Left = 16 + Margins.Top = 5 + Margins.Bottom = 5 + Align = alLeft + Caption = 'Restore defaults' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + Layout = tlCenter + OnClick = lbRestoreDefaultsClick + ExplicitHeight = 13 end - object Bevel2: TBevel + object btnConfirm: TButton AlignWithMargins = True - Left = 0 - Top = 475 - Width = 632 - Height = 1 + Left = 442 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint Margins.Left = 0 Margins.Top = 0 - Margins.Right = 0 - Align = alTop - Shape = bsTopLine + Margins.Bottom = 0 + Align = alRight + Caption = 'Confirm' + TabOrder = 0 + OnClick = btnConfirmClick end - object Bevel3: TBevel + object btnClose: TButton AlignWithMargins = True - Left = 0 - Top = 347 - Width = 632 - Height = 1 + Left = 555 + Top = 2 + Width = 110 + Height = 31 + Cursor = crHandPoint Margins.Left = 0 Margins.Top = 0 - Margins.Right = 0 - Align = alTop - Shape = bsTopLine + Margins.Bottom = 0 + Align = alRight + Caption = 'Close' + TabOrder = 1 + OnClick = btnCloseClick end - object Bevel4: TBevel - AlignWithMargins = True + end + object pnMyControl: TPanel + Left = 0 + Top = 0 + Width = 670 + Height = 566 + Align = alClient + BevelOuter = bvNone + TabOrder = 1 + object pnMyControlButtons: TPanel Left = 0 - Top = 218 - Width = 632 - Height = 1 - Margins.Left = 0 - Margins.Top = 0 - Margins.Right = 0 + Top = 0 + Width = 670 + Height = 30 Align = alTop - Shape = bsTopLine + BevelEdges = [beBottom] + BevelOuter = bvNone + TabOrder = 0 + object Bevel5: TBevel + AlignWithMargins = True + Left = 0 + Top = 26 + Width = 670 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alBottom + Shape = bsTopLine + ExplicitTop = 218 + ExplicitWidth = 632 + end + object btnPreferences: TButton + AlignWithMargins = True + Left = 3 + Top = 2 + Width = 95 + Height = 23 + Cursor = crHandPoint + Margins.Top = 2 + Margins.Right = 0 + Margins.Bottom = 1 + Align = alLeft + Caption = 'Preferences' + TabOrder = 0 + OnClick = btnPreferencesClick + end + object btnIAsOnline: TButton + AlignWithMargins = True + Left = 101 + Top = 2 + Width = 95 + Height = 23 + Cursor = crHandPoint + Margins.Top = 2 + Margins.Right = 0 + Margins.Bottom = 1 + Align = alLeft + Caption = 'IAs on-line' + TabOrder = 1 + OnClick = btnIAsOnlineClick + end + object btnIAsOffline: TButton + AlignWithMargins = True + Left = 199 + Top = 2 + Width = 95 + Height = 23 + Cursor = crHandPoint + Margins.Top = 2 + Margins.Right = 0 + Margins.Bottom = 1 + Align = alLeft + Caption = 'IAs off-Line' + TabOrder = 2 + OnClick = btnIAsOfflineClick + end + object btnCodeCompletion: TButton + AlignWithMargins = True + Left = 297 + Top = 2 + Width = 95 + Height = 23 + Cursor = crHandPoint + Margins.Top = 2 + Margins.Right = 0 + Margins.Bottom = 1 + Align = alLeft + Caption = 'Code Completion' + TabOrder = 3 + OnClick = btnCodeCompletionClick + end end - object Bevel5: TBevel - AlignWithMargins = True + object pnBody: TPanel Left = 0 - Top = 90 - Width = 632 - Height = 1 - Margins.Left = 0 - Margins.Top = 0 - Margins.Right = 0 - Align = alTop - Shape = bsTopLine + Top = 30 + Width = 670 + Height = 536 + Align = alClient + BevelOuter = bvNone + TabOrder = 1 end - object gBoxGemini: TGroupBox + end + end + object PageControl1: TPageControl + Left = 0 + Top = 33 + Width = 667 + Height = 521 + ActivePage = TabSheet4 + TabOrder = 1 + object TabSheet1: TTabSheet + Caption = 'Preferences' + object pnPreferencesBack: TPanel Left = 0 - Top = 94 - Width = 632 - Height = 124 - Align = alTop - Caption = ' Gemini (Google) ' + Top = 0 + Width = 659 + Height = 493 + Align = alClient + BevelOuter = bvNone ParentBackground = False - TabOrder = 1 - object pnGeminiBack: TPanel - AlignWithMargins = True - Left = 5 - Top = 18 - Width = 622 - Height = 101 + TabOrder = 0 + object GroupBox2: TGroupBox + Left = 0 + Top = 0 + Width = 659 + Height = 493 Align = alClient - BevelOuter = bvNone + Caption = ' Preferences ' ParentBackground = False TabOrder = 0 - object Label5: TLabel - Left = 16 - Top = 5 - Width = 45 + object Label11: TLabel + Left = 272 + Top = 23 + Width = 186 Height = 13 - Caption = 'Base URL' + Caption = 'AI default (Chat and Databases Chat) ' end - object Label6: TLabel - Left = 16 - Top = 44 - Width = 37 + object Label4: TLabel + Left = 21 + Top = 23 + Width = 133 Height = 13 - Caption = 'API key' + Caption = 'Language used in questions' end - object Label7: TLabel - Left = 267 - Top = 5 - Width = 28 - Height = 13 - Caption = 'Model' - end - object lbLinkGemini01: TLabel - Left = 16 - Top = 83 - Width = 86 - Height = 13 - Cursor = crHandPoint - Hint = 'https://aistudio.google.com/app/apikey' - Caption = 'Generate API Key' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click - end - object lbLinkGemini02: TLabel - Left = 128 - Top = 83 - Width = 72 - Height = 13 - Cursor = crHandPoint - Hint = 'https://ai.google.dev/gemini-api/docs/api-overview#curl_1' - Caption = 'Documentation' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click + object cBoxAIDefault: TComboBox + Left = 272 + Top = 38 + Width = 333 + Height = 21 + Style = csDropDownList + TabOrder = 1 + Items.Strings = ( + '') end - object btnApiKeyGeminiView: TSpeedButton - Left = 582 - Top = 59 - Width = 23 + object ColorBoxColorHighlightCodeDelphi: TColorBox + Left = 21 + Top = 87 + Width = 194 Height = 22 - Cursor = crHandPoint - Hint = 'Show/Hide API Key' - Flat = True - Glyph.Data = { - 36030000424D3603000000000000360000002800000010000000100000000100 - 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C - BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF - 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF - 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 - B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD - EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF - FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 - C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF - FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF - E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 - C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 - C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 - DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 - 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF - 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} - ParentShowHint = False - ShowHint = True - OnClick = btnApiKeyGeminiViewClick + TabOrder = 3 end - object lbLinkGemini03: TLabel - Left = 232 - Top = 83 - Width = 67 - Height = 13 - Cursor = crHandPoint - Hint = 'https://ai.google.dev/gemini-api/docs/models/gemini?hl=pt-br' - Caption = 'Gemini Models' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click + object ckColorHighlightCodeDelphiUse: TCheckBox + Left = 21 + Top = 67 + Width = 194 + Height = 17 + Caption = 'Color to highlight Delphi/Pascal code' + TabOrder = 2 + OnClick = ckColorHighlightCodeDelphiUseClick end - object edtBaseUrlGemini: TEdit - Left = 16 - Top = 20 + object cBoxLanguageQuestions: TComboBox + Left = 21 + Top = 38 Width = 249 Height = 21 + Hint = 'What is the standard language for questions?' + Style = csDropDownList + ParentShowHint = False + ShowHint = True TabOrder = 0 end - object edtApiKeyGemini: TEdit - Left = 16 - Top = 60 - Width = 563 - Height = 21 - PasswordChar = '*' - TabOrder = 2 - end - object cBoxModelGemini: TComboBox - Left = 267 - Top = 20 - Width = 333 - Height = 21 - TabOrder = 1 - Items.Strings = ( - 'v1/models/gemini-1.5-flash:generateContent' - 'v1beta/models/gemini-pro:generateContent' - 'v1beta/models/gemini-1.5-flash:generateContent') + object gboxData: TGroupBox + Left = 2 + Top = 433 + Width = 655 + Height = 58 + Align = alBottom + Caption = ' Data ' + Padding.Left = 2 + Padding.Top = 5 + Padding.Bottom = 3 + TabOrder = 4 + object btnOpenDataFolder: TButton + Left = 4 + Top = 20 + Width = 122 + Height = 33 + Cursor = crHandPoint + Align = alLeft + Caption = 'Open Data Folder' + TabOrder = 0 + OnClick = btnOpenDataFolderClick + end end end end - object GroupBox2: TGroupBox + end + object TabSheet2: TTabSheet + Caption = 'IAs on-line' + ImageIndex = 1 + object pnIAsOnLineBack: TPanel Left = 0 Top = 0 - Width = 632 - Height = 90 - Align = alTop - Caption = ' Preferences ' + Width = 659 + Height = 493 + Align = alClient + BevelOuter = bvNone ParentBackground = False TabOrder = 0 - object Label11: TLabel - Left = 272 - Top = 23 - Width = 48 - Height = 13 - Caption = 'AI default' - end - object Label4: TLabel - Left = 21 - Top = 23 - Width = 133 - Height = 13 - Caption = 'Language used in questions' - end - object cBoxAIDefault: TComboBox - Left = 272 - Top = 38 - Width = 333 - Height = 21 - Style = csDropDownList - TabOrder = 1 - Items.Strings = ( - '') - end - object ColorBoxColorHighlightCodeDelphi: TColorBox - Left = 218 - Top = 63 - Width = 133 - Height = 22 - TabOrder = 3 + object Bevel1: TBevel + AlignWithMargins = True + Left = 0 + Top = 489 + Width = 659 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alBottom + Shape = bsTopLine + ExplicitTop = 158 + ExplicitWidth = 441 end - object ckColorHighlightCodeDelphiUse: TCheckBox - Left = 21 - Top = 65 - Width = 194 - Height = 17 - Caption = 'Color to highlight Delphi/Pascal code' - TabOrder = 2 - OnClick = ckColorHighlightCodeDelphiUseClick + object Bevel2: TBevel + AlignWithMargins = True + Left = 0 + Top = 381 + Width = 659 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alTop + Shape = bsTopLine + ExplicitTop = 475 + ExplicitWidth = 632 end - object cBoxLanguageQuestions: TComboBox - Left = 21 - Top = 38 - Width = 249 - Height = 21 - Hint = 'What is the standard language for questions?' - Style = csDropDownList - ParentShowHint = False - ShowHint = True - TabOrder = 0 + object Bevel3: TBevel + AlignWithMargins = True + Left = 0 + Top = 253 + Width = 659 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alTop + Shape = bsTopLine + ExplicitTop = 347 + ExplicitWidth = 632 end - end - object gBoxOpenAI: TGroupBox - Left = 0 - Top = 222 - Width = 632 - Height = 125 - Align = alTop - Caption = ' ChatGPT (OpenAI)' - ParentBackground = False - TabOrder = 2 - object pnOpenAIBack: TPanel + object Bevel4: TBevel AlignWithMargins = True - Left = 5 - Top = 18 - Width = 622 - Height = 102 - Align = alClient - BevelOuter = bvNone + Left = 0 + Top = 124 + Width = 659 + Height = 1 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Align = alTop + Shape = bsTopLine + ExplicitTop = 218 + ExplicitWidth = 632 + end + object gBoxGemini: TGroupBox + Left = 0 + Top = 0 + Width = 659 + Height = 124 + Align = alTop + Caption = ' Gemini (Google) ' ParentBackground = False TabOrder = 0 - object Label1: TLabel - Left = 16 - Top = 5 - Width = 45 - Height = 13 - Caption = 'Base URL' - end - object Label3: TLabel - Left = 16 - Top = 44 - Width = 37 - Height = 13 - Caption = 'API key' - end - object Label2: TLabel - Left = 374 - Top = 5 - Width = 28 - Height = 13 - Caption = 'Model' - end - object lbLinkGpt01: TLabel - Left = 16 - Top = 84 - Width = 86 - Height = 13 - Cursor = crHandPoint - Hint = 'https://platform.openai.com/api-keys' - Caption = 'Generate API Key' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click - end - object btnApiKeyOpenAIView: TSpeedButton - Left = 582 - Top = 59 - Width = 23 - Height = 22 - Cursor = crHandPoint - Hint = 'Show/Hide API Key' - Flat = True - Glyph.Data = { - 36030000424D3603000000000000360000002800000010000000100000000100 - 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C - BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF - 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF - 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 - B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD - EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF - FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 - C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF - FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF - E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 - C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 - C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 - DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 - 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF - 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} - ParentShowHint = False - ShowHint = True - OnClick = btnApiKeyOpenAIViewClick - end - object lbLinkGpt02: TLabel - Left = 128 - Top = 84 - Width = 72 - Height = 13 - Cursor = crHandPoint - Hint = 'https://platform.openai.com/docs/api-reference/making-requests' - Caption = 'Documentation' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click - end - object edtBaseUrlOpenAI: TEdit - Left = 16 - Top = 21 - Width = 356 - Height = 21 + object pnGeminiBack: TPanel + AlignWithMargins = True + Left = 5 + Top = 18 + Width = 649 + Height = 101 + Align = alClient + BevelOuter = bvNone + ParentBackground = False TabOrder = 0 + object Label5: TLabel + Left = 16 + Top = 5 + Width = 45 + Height = 13 + Caption = 'Base URL' + end + object Label6: TLabel + Left = 16 + Top = 44 + Width = 37 + Height = 13 + Caption = 'API key' + end + object Label7: TLabel + Left = 267 + Top = 5 + Width = 28 + Height = 13 + Caption = 'Model' + end + object lbLinkGemini01: TLabel + Left = 16 + Top = 83 + Width = 86 + Height = 13 + Cursor = crHandPoint + Hint = 'https://aistudio.google.com/app/apikey' + Caption = 'Generate API Key' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object lbLinkGemini02: TLabel + Left = 128 + Top = 83 + Width = 72 + Height = 13 + Cursor = crHandPoint + Hint = 'https://ai.google.dev/gemini-api/docs/api-overview#curl_1' + Caption = 'Documentation' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object btnApiKeyGeminiView: TSpeedButton + Left = 582 + Top = 59 + Width = 23 + Height = 22 + Cursor = crHandPoint + Hint = 'Show/Hide API Key' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C + BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF + 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF + 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 + B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD + EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF + FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 + C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF + FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF + E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 + C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 + C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 + DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 + 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + OnClick = btnApiKeyGeminiViewClick + end + object lbLinkGemini03: TLabel + Left = 232 + Top = 83 + Width = 67 + Height = 13 + Cursor = crHandPoint + Hint = 'https://ai.google.dev/gemini-api/docs/models/gemini?hl=pt-br' + Caption = 'Gemini Models' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object edtBaseUrlGemini: TEdit + Left = 16 + Top = 20 + Width = 249 + Height = 21 + TabOrder = 0 + end + object edtApiKeyGemini: TEdit + Left = 16 + Top = 60 + Width = 563 + Height = 21 + PasswordChar = '*' + TabOrder = 2 + end + object cBoxModelGemini: TComboBox + Left = 267 + Top = 20 + Width = 333 + Height = 21 + TabOrder = 1 + Items.Strings = ( + 'v1/models/gemini-1.5-flash:generateContent' + 'v1beta/models/gemini-pro:generateContent' + 'v1beta/models/gemini-1.5-flash:generateContent') + end end - object edtApiKeyOpenAI: TEdit - Left = 16 - Top = 60 - Width = 563 - Height = 21 - PasswordChar = '*' - TabOrder = 2 + end + object gBoxOpenAI: TGroupBox + Left = 0 + Top = 128 + Width = 659 + Height = 125 + Align = alTop + Caption = ' ChatGPT (OpenAI)' + ParentBackground = False + TabOrder = 1 + object pnOpenAIBack: TPanel + AlignWithMargins = True + Left = 5 + Top = 18 + Width = 649 + Height = 102 + Align = alClient + BevelOuter = bvNone + ParentBackground = False + TabOrder = 0 + object Label1: TLabel + Left = 16 + Top = 5 + Width = 45 + Height = 13 + Caption = 'Base URL' + end + object Label3: TLabel + Left = 16 + Top = 44 + Width = 37 + Height = 13 + Caption = 'API key' + end + object Label2: TLabel + Left = 374 + Top = 5 + Width = 28 + Height = 13 + Caption = 'Model' + end + object lbLinkGpt01: TLabel + Left = 16 + Top = 84 + Width = 86 + Height = 13 + Cursor = crHandPoint + Hint = 'https://platform.openai.com/api-keys' + Caption = 'Generate API Key' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object btnApiKeyOpenAIView: TSpeedButton + Left = 582 + Top = 59 + Width = 23 + Height = 22 + Cursor = crHandPoint + Hint = 'Show/Hide API Key' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C + BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF + 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF + 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 + B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD + EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF + FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 + C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF + FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF + E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 + C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 + C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 + DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 + 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + OnClick = btnApiKeyOpenAIViewClick + end + object lbLinkGpt02: TLabel + Left = 128 + Top = 84 + Width = 72 + Height = 13 + Cursor = crHandPoint + Hint = 'https://platform.openai.com/docs/api-reference/making-requests' + Caption = 'Documentation' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object edtBaseUrlOpenAI: TEdit + Left = 16 + Top = 21 + Width = 356 + Height = 21 + TabOrder = 0 + end + object edtApiKeyOpenAI: TEdit + Left = 16 + Top = 60 + Width = 563 + Height = 21 + PasswordChar = '*' + TabOrder = 2 + end + object cBoxModelOpenAI: TComboBox + Left = 374 + Top = 21 + Width = 226 + Height = 21 + TabOrder = 1 + Items.Strings = ( + 'gpt-3.5-turbo' + 'gpt-3.5-turbo-16k' + 'gpt-4' + 'gpt-4o-2024-05-13' + 'gpt-4o-2024-08-06') + end end - object cBoxModelOpenAI: TComboBox - Left = 374 - Top = 21 - Width = 226 - Height = 21 - TabOrder = 1 - Items.Strings = ( - 'gpt-3.5-turbo' - 'gpt-3.5-turbo-16k' - 'gpt-4' - 'gpt-4o-2024-05-13' - 'gpt-4o-2024-08-06') + end + object gBoxGroq: TGroupBox + Left = 0 + Top = 257 + Width = 659 + Height = 124 + Align = alTop + Caption = ' Groq ' + ParentBackground = False + TabOrder = 2 + object pnGroqBack: TPanel + AlignWithMargins = True + Left = 5 + Top = 18 + Width = 649 + Height = 101 + Align = alClient + BevelOuter = bvNone + ParentBackground = False + TabOrder = 0 + object Label8: TLabel + Left = 16 + Top = 5 + Width = 45 + Height = 13 + Caption = 'Base URL' + end + object Label9: TLabel + Left = 16 + Top = 44 + Width = 37 + Height = 13 + Caption = 'API key' + end + object Label10: TLabel + Left = 374 + Top = 5 + Width = 28 + Height = 13 + Caption = 'Model' + end + object lbLinkGroq01: TLabel + Left = 16 + Top = 84 + Width = 86 + Height = 13 + Cursor = crHandPoint + Hint = 'https://console.groq.com/keys' + Caption = 'Generate API Key' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object btnApiKeyGroqView: TSpeedButton + Left = 582 + Top = 59 + Width = 23 + Height = 22 + Cursor = crHandPoint + Hint = 'Show/Hide API Key' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C + BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF + 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF + 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 + B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD + EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF + FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 + C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF + FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF + E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 + C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 + C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 + DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 + 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + OnClick = btnApiKeyGroqViewClick + end + object lbLinkGroq02: TLabel + Left = 128 + Top = 84 + Width = 72 + Height = 13 + Cursor = crHandPoint + Hint = 'https://console.groq.com/docs/quickstart' + Caption = 'Documentation' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object lbLinkGroq03: TLabel + Left = 232 + Top = 84 + Width = 59 + Height = 13 + Cursor = crHandPoint + Hint = 'https://console.groq.com/docs/models' + Caption = 'Groq Models' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object edtBaseUrlGroq: TEdit + Left = 16 + Top = 21 + Width = 356 + Height = 21 + TabOrder = 0 + end + object edtApiKeyGroq: TEdit + Left = 16 + Top = 60 + Width = 563 + Height = 21 + PasswordChar = '*' + TabOrder = 2 + end + object cBoxModelGroq: TComboBox + Left = 374 + Top = 21 + Width = 226 + Height = 21 + TabOrder = 1 + Items.Strings = ( + 'llama3-8b-8192' + 'llama3-70b-8192' + 'llama3-groq-8b-8192-tool-use-preview' + 'llama3-groq-70b-8192-tool-use-preview' + 'mixtral-8x7b-32768' + 'gemma-7b-it' + 'gemma2-9b-it' + 'whisper-large-v3') + end end end end - object gBoxGroq: TGroupBox + end + object TabSheet3: TTabSheet + Caption = 'IAs off-Line' + ImageIndex = 2 + object pnIAsOffLineBack: TPanel Left = 0 - Top = 351 - Width = 632 - Height = 124 - Align = alTop - Caption = ' Groq ' + Top = 0 + Width = 659 + Height = 493 + Align = alClient + BevelOuter = bvNone ParentBackground = False - TabOrder = 3 - object pnGroqBack: TPanel - AlignWithMargins = True - Left = 5 - Top = 18 - Width = 622 - Height = 101 - Align = alClient - BevelOuter = bvNone + TabOrder = 0 + object GroupBox1: TGroupBox + Left = 0 + Top = 0 + Width = 659 + Height = 152 + Align = alTop + Caption = ' Ollama (offline) ' ParentBackground = False TabOrder = 0 - object Label8: TLabel - Left = 16 - Top = 5 - Width = 45 - Height = 13 - Caption = 'Base URL' - end - object Label9: TLabel - Left = 16 - Top = 44 - Width = 37 - Height = 13 - Caption = 'API key' - end - object Label10: TLabel - Left = 374 - Top = 5 - Width = 28 - Height = 13 - Caption = 'Model' - end - object lbLinkGroq01: TLabel - Left = 16 - Top = 84 - Width = 86 - Height = 13 - Cursor = crHandPoint - Hint = 'https://console.groq.com/keys' - Caption = 'Generate API Key' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click - end - object btnApiKeyGroqView: TSpeedButton - Left = 582 - Top = 59 - Width = 23 - Height = 22 - Cursor = crHandPoint - Hint = 'Show/Hide API Key' - Flat = True - Glyph.Data = { - 36030000424D3603000000000000360000002800000010000000100000000100 - 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C - BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF - 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF - 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 - B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD - EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF - FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 - C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF - FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF - E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 - C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 - C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 - DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 - 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF - 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} - ParentShowHint = False - ShowHint = True - OnClick = btnApiKeyGroqViewClick - end - object lbLinkGroq02: TLabel - Left = 128 - Top = 84 - Width = 72 - Height = 13 - Cursor = crHandPoint - Hint = 'https://console.groq.com/docs/quickstart' - Caption = 'Documentation' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click - end - object lbLinkGroq03: TLabel - Left = 232 - Top = 84 - Width = 59 - Height = 13 - Cursor = crHandPoint - Hint = 'https://console.groq.com/docs/models' - Caption = 'Groq Models' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click - end - object edtBaseUrlGroq: TEdit - Left = 16 - Top = 21 - Width = 356 - Height = 21 + object Panel1: TPanel + AlignWithMargins = True + Left = 5 + Top = 18 + Width = 649 + Height = 129 + Align = alClient + BevelOuter = bvNone + ParentBackground = False TabOrder = 0 - end - object edtApiKeyGroq: TEdit - Left = 16 - Top = 60 - Width = 563 - Height = 21 - PasswordChar = '*' - TabOrder = 2 - end - object cBoxModelGroq: TComboBox - Left = 374 - Top = 21 - Width = 226 - Height = 21 - TabOrder = 1 - Items.Strings = ( - 'llama3-8b-8192' - 'llama3-70b-8192' - 'llama3-groq-8b-8192-tool-use-preview' - 'llama3-groq-70b-8192-tool-use-preview' - 'mixtral-8x7b-32768' - 'gemma-7b-it' - 'gemma2-9b-it' - 'whisper-large-v3') + object Label12: TLabel + Left = 16 + Top = 5 + Width = 45 + Height = 13 + Caption = 'Base URL' + end + object Label13: TLabel + Left = 16 + Top = 44 + Width = 29 + Height = 13 + Caption = 'Token' + end + object Label14: TLabel + Left = 374 + Top = 5 + Width = 28 + Height = 13 + Caption = 'Model' + end + object btnApiKeyOllamaView: TSpeedButton + Left = 582 + Top = 59 + Width = 23 + Height = 22 + Cursor = crHandPoint + Hint = 'Show/Hide API Key' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C + BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF + 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF + 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 + B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD + EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF + FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 + C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF + FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF + E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 + C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 + C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 + DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 + 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + OnClick = btnApiKeyOllamaViewClick + end + object lbLinkOllama02: TLabel + Left = 128 + Top = 84 + Width = 72 + Height = 13 + Cursor = crHandPoint + Hint = 'https://github.com/ollama/ollama/blob/main/docs/api.md' + Caption = 'Documentation' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object lbLinkOllama03: TLabel + Left = 232 + Top = 84 + Width = 68 + Height = 13 + Cursor = crHandPoint + Hint = 'https://ollama.com/library' + Caption = 'Ollama Models' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object lbLinkOllama01: TLabel + Left = 16 + Top = 84 + Width = 82 + Height = 13 + Cursor = crHandPoint + Hint = 'https://ollama.com/' + Caption = 'Ollama Download' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object edtBaseUrlOllama: TEdit + Left = 16 + Top = 21 + Width = 356 + Height = 21 + TabOrder = 0 + end + object edtApiKeyOllama: TEdit + Left = 16 + Top = 60 + Width = 563 + Height = 21 + PasswordChar = '*' + TabOrder = 2 + end + object cBoxModelOllama: TComboBox + Left = 374 + Top = 21 + Width = 226 + Height = 21 + TabOrder = 1 + Items.Strings = ( + 'llama2' + 'llama3' + 'llama3.1' + 'codellama' + 'tinyllama' + 'mistral') + end end end end - object GroupBox1: TGroupBox + end + object TabSheet4: TTabSheet + Caption = 'Code Completion' + ImageIndex = 3 + object pnCodeCompletionBack: TPanel Left = 0 - Top = 479 - Width = 632 - Height = 129 + Top = 0 + Width = 659 + Height = 493 Align = alClient - Caption = ' Ollama (offline) ' + BevelOuter = bvNone ParentBackground = False - TabOrder = 4 - object Panel1: TPanel - AlignWithMargins = True - Left = 5 - Top = 18 - Width = 622 - Height = 106 + TabOrder = 0 + object GroupBox3: TGroupBox + Left = 0 + Top = 0 + Width = 659 + Height = 493 Align = alClient - BevelOuter = bvNone + Caption = ' Code Completion (BETA) ' ParentBackground = False TabOrder = 0 - object Label12: TLabel - Left = 16 - Top = 5 - Width = 45 - Height = 13 - Caption = 'Base URL' - end - object Label13: TLabel - Left = 16 - Top = 44 - Width = 29 - Height = 13 - Caption = 'Token' - end - object Label14: TLabel - Left = 374 - Top = 5 - Width = 28 - Height = 13 - Caption = 'Model' - end - object btnApiKeyOllamaView: TSpeedButton - Left = 582 - Top = 59 - Width = 23 - Height = 22 - Cursor = crHandPoint - Hint = 'Show/Hide API Key' - Flat = True - Glyph.Data = { - 36030000424D3603000000000000360000002800000010000000100000000100 - 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C - BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF - 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF - 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 - B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD - EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF - FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 - C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF - FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF - E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 - C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 - C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 - DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 - 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF - 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} - ParentShowHint = False - ShowHint = True - OnClick = btnApiKeyOllamaViewClick - end - object lbLinkOllama02: TLabel - Left = 128 - Top = 84 - Width = 72 - Height = 13 - Cursor = crHandPoint - Hint = 'https://github.com/ollama/ollama/blob/main/docs/api.md' - Caption = 'Documentation' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click - end - object lbLinkOllama03: TLabel - Left = 232 - Top = 84 - Width = 68 - Height = 13 - Cursor = crHandPoint - Hint = 'https://ollama.com/library' - Caption = 'Ollama Models' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click - end - object lbLinkOllama01: TLabel - Left = 16 - Top = 84 - Width = 82 - Height = 13 - Cursor = crHandPoint - Hint = 'https://ollama.com/' - Caption = 'Ollama Download' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - OnClick = lbLinkGpt01Click - end - object edtBaseUrlOllama: TEdit - Left = 16 - Top = 21 - Width = 356 - Height = 21 + object Panel2: TPanel + AlignWithMargins = True + Left = 5 + Top = 18 + Width = 649 + Height = 470 + Align = alClient + BevelOuter = bvNone + ParentBackground = False TabOrder = 0 - end - object edtApiKeyOllama: TEdit - Left = 16 - Top = 60 - Width = 563 - Height = 21 - PasswordChar = '*' - TabOrder = 2 - end - object cBoxModelOllama: TComboBox - Left = 374 - Top = 21 - Width = 226 - Height = 21 - TabOrder = 1 - Items.Strings = ( - 'llama2' - 'llama3' - 'llama3.1' - 'codellama' - 'tinyllama' - 'mistral') + ExplicitLeft = 3 + ExplicitTop = 9 + ExplicitWidth = 655 + ExplicitHeight = 476 + object Label15: TLabel + Left = 16 + Top = 29 + Width = 48 + Height = 13 + Caption = 'AI default' + end + object Label16: TLabel + Left = 16 + Top = 138 + Width = 92 + Height = 13 + Caption = 'Shortcut for invoke' + end + object ckCodeCompletionUse: TCheckBox + Left = 16 + Top = 5 + Width = 97 + Height = 17 + Cursor = crHandPoint + Caption = 'Code Completion' + TabOrder = 0 + end + object cBoxCodeCompletionAIDefault: TComboBox + Left = 16 + Top = 48 + Width = 333 + Height = 21 + Style = csDropDownList + TabOrder = 1 + Items.Strings = ( + '') + end + object ColorBoxCodeCompletionSuggestionColor: TColorBox + Left = 16 + Top = 102 + Width = 133 + Height = 22 + TabOrder = 2 + end + object ckCodeCompletionSuggestionColorUse: TCheckBox + Left = 16 + Top = 81 + Width = 131 + Height = 17 + Cursor = crHandPoint + Caption = 'Suggestion Code Color' + TabOrder = 3 + OnClick = ckColorHighlightCodeDelphiUseClick + end + object hotKeyCodeCompletionShortcutInvoke: THotKey + Left = 16 + Top = 154 + Width = 150 + Height = 19 + Cursor = crArrow + Hint = 'Customize Shortcut' + HotKey = 0 + InvalidKeys = [hcNone] + Modifiers = [] + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end end end end end - object pnBottom: TPanel - Left = 0 - Top = 612 - Width = 632 - Height = 35 - Margins.Left = 0 - Margins.Top = 0 - Margins.Right = 0 - Margins.Bottom = 0 - Align = alBottom - BevelEdges = [beLeft, beRight, beBottom] - BevelOuter = bvNone - Padding.Top = 2 - Padding.Right = 2 - Padding.Bottom = 2 - ParentBackground = False - TabOrder = 1 - object lbRestoreDefaults: TLabel - AlignWithMargins = True - Left = 16 - Top = 7 - Width = 80 - Height = 21 - Cursor = crHandPoint - Margins.Left = 16 - Margins.Top = 5 - Margins.Bottom = 5 - Align = alLeft - Caption = 'Restore defaults' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - Layout = tlCenter - OnClick = lbRestoreDefaultsClick - ExplicitHeight = 13 - end - object lbOpenDataFolder: TLabel - AlignWithMargins = True - Left = 115 - Top = 7 - Width = 85 - Height = 21 - Cursor = crHandPoint - Margins.Left = 16 - Margins.Top = 5 - Margins.Bottom = 5 - Align = alLeft - Caption = 'Open Data Folder' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlue - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - Layout = tlCenter - OnClick = lbOpenDataFolderClick - ExplicitHeight = 13 - end - object btnConfirm: TButton - AlignWithMargins = True - Left = 404 - Top = 2 - Width = 110 - Height = 31 - Cursor = crHandPoint - Margins.Left = 0 - Margins.Top = 0 - Margins.Bottom = 0 - Align = alRight - Caption = 'Confirm' - TabOrder = 0 - OnClick = btnConfirmClick - end - object btnClose: TButton - AlignWithMargins = True - Left = 517 - Top = 2 - Width = 110 - Height = 31 - Cursor = crHandPoint - Margins.Left = 0 - Margins.Top = 0 - Margins.Bottom = 0 - Align = alRight - Caption = 'Close' - TabOrder = 1 - OnClick = btnCloseClick - end - end end end diff --git a/Src/Settings/DelphiAIDev.Settings.View.pas b/Src/Settings/DelphiAIDev.Settings.View.pas index 94af90b..995170a 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.pas +++ b/Src/Settings/DelphiAIDev.Settings.View.pas @@ -14,9 +14,11 @@ interface Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, + Vcl.Buttons, + Vcl.ComCtrls, + Vcl.Menus, DelphiAIDev.Settings, - DelphiAIDev.Types, - Vcl.Buttons, Vcl.ComCtrls; + DelphiAIDev.Types; type TDelphiAIDevSettingsView = class(TForm) @@ -24,38 +26,66 @@ TDelphiAIDevSettingsView = class(TForm) btnConfirm: TButton; btnClose: TButton; pnBackAll: TPanel; - pnBody: TPanel; + lbRestoreDefaults: TLabel; + PageControl1: TPageControl; + TabSheet1: TTabSheet; + TabSheet2: TTabSheet; + pnMyControl: TPanel; + pnMyControlButtons: TPanel; + btnPreferences: TButton; + btnIAsOnline: TButton; + pnPreferencesBack: TPanel; + GroupBox2: TGroupBox; + Label11: TLabel; + Label4: TLabel; + cBoxAIDefault: TComboBox; + ColorBoxColorHighlightCodeDelphi: TColorBox; + ckColorHighlightCodeDelphiUse: TCheckBox; + cBoxLanguageQuestions: TComboBox; + TabSheet3: TTabSheet; + pnIAsOffLineBack: TPanel; + GroupBox1: TGroupBox; + Panel1: TPanel; + Label12: TLabel; + Label13: TLabel; + Label14: TLabel; + btnApiKeyOllamaView: TSpeedButton; + lbLinkOllama02: TLabel; + lbLinkOllama03: TLabel; + lbLinkOllama01: TLabel; + edtBaseUrlOllama: TEdit; + edtApiKeyOllama: TEdit; + cBoxModelOllama: TComboBox; + TabSheet4: TTabSheet; + pnCodeCompletionBack: TPanel; + pnIAsOnLineBack: TPanel; + Bevel1: TBevel; + Bevel2: TBevel; + Bevel3: TBevel; + Bevel4: TBevel; gBoxGemini: TGroupBox; pnGeminiBack: TPanel; Label5: TLabel; Label6: TLabel; Label7: TLabel; lbLinkGemini01: TLabel; + lbLinkGemini02: TLabel; + btnApiKeyGeminiView: TSpeedButton; + lbLinkGemini03: TLabel; edtBaseUrlGemini: TEdit; edtApiKeyGemini: TEdit; cBoxModelGemini: TComboBox; - lbLinkGemini02: TLabel; - GroupBox2: TGroupBox; gBoxOpenAI: TGroupBox; pnOpenAIBack: TPanel; Label1: TLabel; Label3: TLabel; Label2: TLabel; lbLinkGpt01: TLabel; + btnApiKeyOpenAIView: TSpeedButton; + lbLinkGpt02: TLabel; edtBaseUrlOpenAI: TEdit; edtApiKeyOpenAI: TEdit; cBoxModelOpenAI: TComboBox; - Label11: TLabel; - cBoxAIDefault: TComboBox; - btnApiKeyGeminiView: TSpeedButton; - btnApiKeyOpenAIView: TSpeedButton; - lbLinkGpt02: TLabel; - lbRestoreDefaults: TLabel; - ColorBoxColorHighlightCodeDelphi: TColorBox; - ckColorHighlightCodeDelphiUse: TCheckBox; - lbLinkGemini03: TLabel; - Label4: TLabel; - cBoxLanguageQuestions: TComboBox; gBoxGroq: TGroupBox; pnGroqBack: TPanel; Label8: TLabel; @@ -64,28 +94,25 @@ TDelphiAIDevSettingsView = class(TForm) lbLinkGroq01: TLabel; btnApiKeyGroqView: TSpeedButton; lbLinkGroq02: TLabel; + lbLinkGroq03: TLabel; edtBaseUrlGroq: TEdit; edtApiKeyGroq: TEdit; cBoxModelGroq: TComboBox; - lbLinkGroq03: TLabel; - lbOpenDataFolder: TLabel; - GroupBox1: TGroupBox; - Panel1: TPanel; - Label12: TLabel; - Label13: TLabel; - Label14: TLabel; - btnApiKeyOllamaView: TSpeedButton; - lbLinkOllama01: TLabel; - lbLinkOllama02: TLabel; - lbLinkOllama03: TLabel; - edtBaseUrlOllama: TEdit; - edtApiKeyOllama: TEdit; - cBoxModelOllama: TComboBox; - Bevel1: TBevel; - Bevel2: TBevel; - Bevel3: TBevel; - Bevel4: TBevel; + pnBody: TPanel; + btnIAsOffline: TButton; + btnCodeCompletion: TButton; Bevel5: TBevel; + GroupBox3: TGroupBox; + Panel2: TPanel; + ckCodeCompletionUse: TCheckBox; + Label15: TLabel; + cBoxCodeCompletionAIDefault: TComboBox; + ColorBoxCodeCompletionSuggestionColor: TColorBox; + ckCodeCompletionSuggestionColorUse: TCheckBox; + hotKeyCodeCompletionShortcutInvoke: THotKey; + Label16: TLabel; + gboxData: TGroupBox; + btnOpenDataFolder: TButton; procedure FormCreate(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure btnCloseClick(Sender: TObject); @@ -98,8 +125,12 @@ TDelphiAIDevSettingsView = class(TForm) procedure lbRestoreDefaultsClick(Sender: TObject); procedure ckColorHighlightCodeDelphiUseClick(Sender: TObject); procedure btnApiKeyGroqViewClick(Sender: TObject); - procedure lbOpenDataFolderClick(Sender: TObject); procedure btnApiKeyOllamaViewClick(Sender: TObject); + procedure btnPreferencesClick(Sender: TObject); + procedure btnIAsOnlineClick(Sender: TObject); + procedure btnIAsOfflineClick(Sender: TObject); + procedure btnCodeCompletionClick(Sender: TObject); + procedure btnOpenDataFolderClick(Sender: TObject); private FSettings: TDelphiAIDevSettings; procedure SaveSettings; @@ -108,6 +139,9 @@ TDelphiAIDevSettingsView = class(TForm) procedure ConfigFieldsColorHighlightDelphi; procedure FillcBoxLanguageQuestions; procedure FillcBoxAIDefault; + procedure FillcBoxCodeCompletionAIDefault; + procedure ShowPanel(const AButton: TButton; const APanel: TPanel); + procedure PanelsSetParent; public end; @@ -128,8 +162,10 @@ procedure TDelphiAIDevSettingsView.FormCreate(Sender: TObject); TUtilsOTA.IDEThemingAll(TDelphiAIDevSettingsView, Self); FSettings := TDelphiAIDevSettings.GetInstance; + Self.PanelsSetParent; Self.FillcBoxLanguageQuestions; Self.FillcBoxAIDefault; + Self.FillcBoxCodeCompletionAIDefault; end; procedure TDelphiAIDevSettingsView.FormShow(Sender: TObject); @@ -155,13 +191,22 @@ procedure TDelphiAIDevSettingsView.FillcBoxLanguageQuestions; procedure TDelphiAIDevSettingsView.FillcBoxAIDefault; var - LItem: TC4DAIsAvailable; + LItem: TC4DAiAvailable; begin cBoxAIDefault.Items.Clear; - for LItem := Low(TC4DAIsAvailable) to High(TC4DAIsAvailable) do + for LItem := Low(TC4DAiAvailable) to High(TC4DAiAvailable) do cBoxAIDefault.Items.Add(LItem.ToString); end; +procedure TDelphiAIDevSettingsView.FillcBoxCodeCompletionAIDefault; +var + LItem: TC4DAiAvailable; +begin + cBoxCodeCompletionAIDefault.Items.Clear; + for LItem := Low(TC4DAiAvailable) to High(TC4DAiAvailable) do + cBoxCodeCompletionAIDefault.Items.Add(LItem.ToString); +end; + procedure TDelphiAIDevSettingsView.ConfigScreen; var LColor: TColor; @@ -176,7 +221,6 @@ procedure TDelphiAIDevSettingsView.ConfigScreen; lbLinkGroq02.Font.Color := LColor; lbLinkGroq03.Font.Color := LColor; lbRestoreDefaults.Font.Color := LColor; - lbOpenDataFolder.Font.Color := LColor; lbLinkOllama01.Font.Color := LColor; lbLinkOllama02.Font.Color := LColor; lbLinkOllama03.Font.Color := LColor; @@ -269,6 +313,12 @@ procedure TDelphiAIDevSettingsView.LoadSettings; ColorBoxColorHighlightCodeDelphi.Selected := FSettings.ColorHighlightCodeDelphi; Self.ConfigFieldsColorHighlightDelphi; + ckCodeCompletionUse.Checked := FSettings.CodeCompletionUse; + cBoxCodeCompletionAIDefault.ItemIndex := Integer(FSettings.CodeCompletionAIDefault); + ckCodeCompletionSuggestionColorUse.Checked := FSettings.CodeCompletionSuggestionColorUse; + ColorBoxCodeCompletionSuggestionColor.Selected := FSettings.CodeCompletionSuggestionColor; + hotKeyCodeCompletionShortcutInvoke.HotKey := TextToShortCut(FSettings.CodeCompletionShortcutInvoke); + edtBaseUrlGemini.Text := FSettings.BaseUrlGemini; cBoxModelGemini.ItemIndex := cBoxModelGemini.Items.IndexOf(FSettings.ModelGemini); if cBoxModelGemini.ItemIndex < 0 then @@ -297,11 +347,17 @@ procedure TDelphiAIDevSettingsView.LoadSettings; procedure TDelphiAIDevSettingsView.SaveSettings; begin FSettings.LanguageQuestions := TC4DLanguage(cBoxLanguageQuestions.ItemIndex); - FSettings.AIDefault := TC4DAIsAvailable(cBoxAIDefault.ItemIndex); + FSettings.AIDefault := TC4DAiAvailable(cBoxAIDefault.ItemIndex); FSettings.ColorHighlightCodeDelphiUse := ckColorHighlightCodeDelphiUse.Checked; FSettings.ColorHighlightCodeDelphi := ColorBoxColorHighlightCodeDelphi.Selected; + FSettings.CodeCompletionUse := ckCodeCompletionUse.Checked; + FSettings.CodeCompletionAIDefault := TC4DAiAvailable(cBoxCodeCompletionAIDefault.ItemIndex); + FSettings.CodeCompletionSuggestionColorUse := ckCodeCompletionSuggestionColorUse.Checked; + FSettings.CodeCompletionSuggestionColor := ColorBoxCodeCompletionSuggestionColor.Selected; + FSettings.CodeCompletionShortcutInvoke := ShortCutToText(hotKeyCodeCompletionShortcutInvoke.HotKey); + FSettings.BaseUrlGemini := edtBaseUrlGemini.Text; FSettings.ModelGemini := cBoxModelGemini.Text; FSettings.ApiKeyGemini := edtApiKeyGemini.Text; @@ -318,10 +374,43 @@ procedure TDelphiAIDevSettingsView.SaveSettings; FSettings.ModelOllama := cBoxModelOllama.Text; FSettings.ApiKeyOllama := edtApiKeyOllama.Text; + + FSettings.SaveData; end; -procedure TDelphiAIDevSettingsView.lbOpenDataFolderClick(Sender: TObject); +procedure TDelphiAIDevSettingsView.btnApiKeyOllamaViewClick(Sender: TObject); +begin + TUtils.TogglePasswordChar(edtApiKeyOllama); +end; + +procedure TDelphiAIDevSettingsView.PanelsSetParent; +begin + pnPreferencesBack.Visible := False; + pnIAsOnLineBack.Visible := False; + pnIAsOffLineBack.Visible := False; + pnCodeCompletionBack.Visible := False; + + pnPreferencesBack.Parent := pnBody; + pnIAsOnLineBack.Parent := pnBody; + pnIAsOffLineBack.Parent := pnBody; + pnCodeCompletionBack.Parent := pnBody; + PageControl1.Visible := False; + + btnPreferences.Click; +end; + +procedure TDelphiAIDevSettingsView.btnPreferencesClick(Sender: TObject); +begin + Self.ShowPanel(TButton(Sender), pnPreferencesBack); +end; + +procedure TDelphiAIDevSettingsView.btnIAsOnlineClick(Sender: TObject); +begin + Self.ShowPanel(TButton(Sender), pnIAsOnLineBack); +end; + +procedure TDelphiAIDevSettingsView.btnOpenDataFolderClick(Sender: TObject); var LPathFolder: string; begin @@ -332,9 +421,29 @@ procedure TDelphiAIDevSettingsView.lbOpenDataFolderClick(Sender: TObject); TUtils.OpenFolder(LPathFolder); end; -procedure TDelphiAIDevSettingsView.btnApiKeyOllamaViewClick(Sender: TObject); +procedure TDelphiAIDevSettingsView.btnIAsOfflineClick(Sender: TObject); begin - TUtils.TogglePasswordChar(edtApiKeyOllama); + Self.ShowPanel(TButton(Sender), pnIAsOffLineBack); +end; + +procedure TDelphiAIDevSettingsView.btnCodeCompletionClick(Sender: TObject); +begin + Self.ShowPanel(TButton(Sender), pnCodeCompletionBack); +end; + +procedure TDelphiAIDevSettingsView.ShowPanel(const AButton: TButton; const APanel: TPanel); +begin + btnPreferences.Default := False; + btnIAsOnline.Default := False; + btnIAsOffline.Default := False; + btnCodeCompletion.Default := False; + AButton.Default := True; + + pnPreferencesBack.Visible := False; + pnIAsOnLineBack.Visible := False; + pnIAsOffLineBack.Visible := False; + pnCodeCompletionBack.Visible := False; + APanel.Visible := True; end; end. diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index 12bef23..feb29b1 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -15,10 +15,15 @@ interface type TDelphiAIDevSettings = class private const - FIELD_LanguageQuestions = 'LanguageQuestions'; + FIELD_LanguageQuestions = 'LanguageQuestions'; FIELD_AIDefault = 'AIDefault'; FIELD_ColorHighlightCodeDelphiUse = 'ColorHighlightCodeDelphiUse'; FIELD_ColorHighlightCodeDelphi = 'ColorHighlightCodeDelphi'; + FIELD_CodeCompletionUse = 'CodeCompletionUse'; + FIELD_CodeCompletionAIDefault = 'CodeCompletionAIDefault'; + FIELD_CodeCompletionSuggestionColorUse = 'CodeCompletionSuggestionColorUse'; + FIELD_CodeCompletionSuggestionColor = 'CodeCompletionSuggestionColor'; + FIELD_CodeCompletionShortcutInvoke = 'CodeCompletionShortcutInvoke'; FIELD_BaseUrlGemini = 'BaseUrlGemini'; FIELD_ModelGemini = 'ModelGemini'; FIELD_ApiKeyGemini = 'ApiKeyGemini'; @@ -33,10 +38,16 @@ TDelphiAIDevSettings = class FIELD_ApiKeyOllama = 'ApiKeyOllama'; private FLanguageQuestions: TC4DLanguage; - FAIDefault: TC4DAIsAvailable; + FAIDefault: TC4DAiAvailable; FColorHighlightCodeDelphiUse: Boolean; FColorHighlightCodeDelphi: TColor; + FCodeCompletionUse: Boolean; + FCodeCompletionAIDefault: TC4DAiAvailable; + FCodeCompletionSuggestionColorUse: Boolean; + FCodeCompletionSuggestionColor: TColor; + FCodeCompletionShortcutInvoke: string; + FBaseUrlGemini: string; FModelGemini: string; FApiKeyGemini: string; @@ -62,10 +73,16 @@ TDelphiAIDevSettings = class procedure ValidateFillingSelectedAI(const AShowMsg: TShowMsg = TShowMsg.Yes); property LanguageQuestions: TC4DLanguage read FLanguageQuestions write FLanguageQuestions; - property AIDefault: TC4DAIsAvailable read FAIDefault write FAIDefault; + property AIDefault: TC4DAiAvailable read FAIDefault write FAIDefault; property ColorHighlightCodeDelphiUse: Boolean read FColorHighlightCodeDelphiUse write FColorHighlightCodeDelphiUse; property ColorHighlightCodeDelphi: TColor read FColorHighlightCodeDelphi write FColorHighlightCodeDelphi; + property CodeCompletionUse: Boolean read FCodeCompletionUse write FCodeCompletionUse; + property CodeCompletionAIDefault: TC4DAiAvailable read FCodeCompletionAIDefault write FCodeCompletionAIDefault; + property CodeCompletionSuggestionColorUse: Boolean read FCodeCompletionSuggestionColorUse write FCodeCompletionSuggestionColorUse; + property CodeCompletionSuggestionColor: TColor read FCodeCompletionSuggestionColor write FCodeCompletionSuggestionColor; + property CodeCompletionShortcutInvoke: string read FCodeCompletionShortcutInvoke write FCodeCompletionShortcutInvoke; + property BaseUrlGemini: string read FBaseUrlGemini write FBaseUrlGemini; property ModelGemini: string read FModelGemini write FModelGemini; property ApiKeyGemini: string read FApiKeyGemini write FApiKeyGemini; @@ -103,11 +120,17 @@ constructor TDelphiAIDevSettings.Create; procedure TDelphiAIDevSettings.LoadDefaults; begin FLanguageQuestions := TC4DLanguage.ptBR; - FAIDefault := TC4DAIsAvailable.Groq; + FAIDefault := TC4DAiAvailable.Groq; FColorHighlightCodeDelphiUse := False; FColorHighlightCodeDelphi := clNone; + FCodeCompletionUse := False; + FCodeCompletionAIDefault := TC4DAiAvailable.Groq; + FCodeCompletionSuggestionColorUse := False; + FCodeCompletionSuggestionColor := TConsts.CODE_COMPLETION_SUGGESTION_COLOR; + FCodeCompletionShortcutInvoke := TConsts.CODE_COMPLETION_SHORTCUT_INVOKE; + FBaseUrlGemini := TConsts.BASE_URL_GEMINI_DEFAULT; FModelGemini := TConsts.MODEL_GEMINI_DEFAULT; FApiKeyGemini := ''; @@ -142,6 +165,12 @@ procedure TDelphiAIDevSettings.SaveData; LReg.WriteBool(FIELD_ColorHighlightCodeDelphiUse, FColorHighlightCodeDelphiUse); LReg.WriteString(FIELD_ColorHighlightCodeDelphi, ColorToString(FColorHighlightCodeDelphi)); + LReg.WriteBool(FIELD_CodeCompletionUse, FCodeCompletionUse); + LReg.WriteInteger(FIELD_CodeCompletionAIDefault, Integer(FCodeCompletionAIDefault)); + LReg.WriteBool(FIELD_CodeCompletionSuggestionColorUse, FCodeCompletionSuggestionColorUse); + LReg.WriteString(FIELD_CodeCompletionSuggestionColor, ColorToString(FCodeCompletionSuggestionColor)); + LReg.WriteString(FIELD_CodeCompletionShortcutInvoke, FCodeCompletionShortcutInvoke); + LReg.WriteString(FIELD_BaseUrlGemini, FBaseUrlGemini); LReg.WriteString(FIELD_ModelGemini, FModelGemini); LReg.WriteString(FIELD_ApiKeyGemini, FApiKeyGemini); @@ -173,14 +202,14 @@ procedure TDelphiAIDevSettings.LoadData; LReg.CloseKey; LReg.RootKey := HKEY_CURRENT_USER; - if not(LReg.OpenKey(TConsts.KEY_SETTINGS_IN_WINDOWS_REGISTRY, False)) then + if not LReg.OpenKey(TConsts.KEY_SETTINGS_IN_WINDOWS_REGISTRY, False) then Exit; if LReg.ValueExists(FIELD_LanguageQuestions) then FLanguageQuestions := TC4DLanguage(LReg.ReadInteger(FIELD_LanguageQuestions)); if LReg.ValueExists(FIELD_AIDefault) then - FAIDefault := TC4DAIsAvailable(LReg.ReadInteger(FIELD_AIDefault)); + FAIDefault := TC4DAiAvailable(LReg.ReadInteger(FIELD_AIDefault)); //COLOR FOR HIGHLIGHT CODE DELPHI/PASCAL if LReg.ValueExists(FIELD_ColorHighlightCodeDelphiUse) then @@ -190,6 +219,23 @@ procedure TDelphiAIDevSettings.LoadData; FColorHighlightCodeDelphi := TUtils.StringToColorDef(LReg.ReadString(FIELD_ColorHighlightCodeDelphi), TUtilsOTA.ActiveThemeForCode); + //Code Completion + if LReg.ValueExists(FIELD_CodeCompletionUse) then + FCodeCompletionUse := LReg.ReadBool(FIELD_CodeCompletionUse); + + if LReg.ValueExists(FIELD_CodeCompletionAIDefault) then + FCodeCompletionAIDefault := TC4DAiAvailable(LReg.ReadInteger(FIELD_CodeCompletionAIDefault)); + + if LReg.ValueExists(FIELD_CodeCompletionSuggestionColorUse) then + FCodeCompletionSuggestionColorUse := LReg.ReadBool(FIELD_CodeCompletionSuggestionColorUse); + + if LReg.ValueExists(FIELD_CodeCompletionSuggestionColor) then + FCodeCompletionSuggestionColor := TUtils.StringToColorDef(LReg.ReadString(FIELD_CodeCompletionSuggestionColor), + TUtilsOTA.ActiveThemeForCode); + + if LReg.ValueExists(FIELD_CodeCompletionShortcutInvoke) then + FCodeCompletionShortcutInvoke := LReg.ReadString(FIELD_CodeCompletionShortcutInvoke); + //GEMINI if LReg.ValueExists(FIELD_BaseUrlGemini) then FBaseUrlGemini := LReg.ReadString(FIELD_BaseUrlGemini); @@ -250,7 +296,7 @@ procedure TDelphiAIDevSettings.ValidateFillingSelectedAI(const AShowMsg: TShowMs end; begin case FAIDefault of - TC4DAIsAvailable.Gemini: + TC4DAiAvailable.Gemini: begin if FBaseUrlGemini.Trim.IsEmpty then ShowMsgInternal(['Base URL', 'Gemini']); @@ -261,7 +307,7 @@ procedure TDelphiAIDevSettings.ValidateFillingSelectedAI(const AShowMsg: TShowMs if FApiKeyGemini.Trim.IsEmpty then ShowMsgInternal(['API Key', 'Gemini']); end; - TC4DAIsAvailable.OpenAI: + TC4DAiAvailable.OpenAI: begin if FBaseUrlOpenAI.Trim.IsEmpty then ShowMsgInternal(['Base URL', 'ChatGPT']); @@ -272,7 +318,7 @@ procedure TDelphiAIDevSettings.ValidateFillingSelectedAI(const AShowMsg: TShowMs if FApiKeyOpenAI.Trim.IsEmpty then ShowMsgInternal(['API Key', 'ChatGPT']); end; - TC4DAIsAvailable.Groq: + TC4DAiAvailable.Groq: begin if FBaseUrlGroq.Trim.IsEmpty then ShowMsgInternal(['Base URL', 'Groq']); @@ -283,7 +329,7 @@ procedure TDelphiAIDevSettings.ValidateFillingSelectedAI(const AShowMsg: TShowMs if FApiKeyGroq.Trim.IsEmpty then ShowMsgInternal(['API Key', 'Groq']); end; - TC4DAIsAvailable.Ollama: + TC4DAiAvailable.Ollama: begin if FBaseUrlOllama.Trim.IsEmpty then ShowMsgInternal(['Base URL', 'Ollama']); diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index c6ce841..64c190c 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -11,7 +11,7 @@ interface TC4DWizardMenuContextList = procedure(const MenuContextList: IInterfaceList) of object; {$SCOPEDENUMS ON} - TC4DAIsAvailable = (Gemini, OpenAI, Groq, Ollama); + TC4DAiAvailable = (Gemini, OpenAI, Groq, Ollama); TC4DLanguage = (en, ptBR, es); TC4DExtensionsFiles = (None, PAS, DFM, FMX, DPR, DPK, DPROJ, GROUPPROJ, ZIP, BMP, INI, ALL); TC4DExtensionsOfFiles = set of TC4DExtensionsFiles; @@ -25,7 +25,7 @@ interface TShowMsg = (Yes, No); {$SCOPEDENUMS OFF} - TC4DAIsAvailableHelper = record helper for TC4DAIsAvailable + TC4DAiAvailableHelper = record helper for TC4DAiAvailable function ToString: string; function ToStringWithCreator: string; end; @@ -69,27 +69,27 @@ implementation DelphiAIDev.Consts; { TAIsAvailableHelper } -function TC4DAIsAvailableHelper.ToString: string; +function TC4DAiAvailableHelper.ToString: string; begin case Self of - TC4DAIsAvailable.Gemini: + TC4DAiAvailable.Gemini: Result := 'Gemini'; - TC4DAIsAvailable.OpenAI: + TC4DAiAvailable.OpenAI: Result := 'ChatGPT'; else - Result := GetEnumName(TypeInfo(TC4DAIsAvailable), Integer(Self)); + Result := GetEnumName(TypeInfo(TC4DAiAvailable), Integer(Self)); end; end; -function TC4DAIsAvailableHelper.ToStringWithCreator: string; +function TC4DAiAvailableHelper.ToStringWithCreator: string; begin case Self of - TC4DAIsAvailable.Gemini: + TC4DAiAvailable.Gemini: Result := 'Gemini (Google)'; - TC4DAIsAvailable.OpenAI: + TC4DAiAvailable.OpenAI: Result := 'ChatGPT (OpenAI)'; else - Result := GetEnumName(TypeInfo(TC4DAIsAvailable), Integer(Self)); + Result := GetEnumName(TypeInfo(TC4DAiAvailable), Integer(Self)); end; end; From 6d328c0f1767d6c8155f6b7a128c612070545c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 30 Aug 2024 00:44:50 -0300 Subject: [PATCH 053/109] add-itens-in-setting --- .../DelphiAIDev.CodeCompletion.Search.pas | 4 -- .../DelphiAIDev.KeyboardBinding.pas | 20 ++++----- Src/Settings/DelphiAIDev.Settings.View.dfm | 43 ++++++++++--------- Src/Settings/DelphiAIDev.Settings.View.pas | 42 +++++++++++++++--- 4 files changed, 69 insertions(+), 40 deletions(-) diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index 3157e18..aca1f38 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -66,7 +66,6 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex begin FSettings.ValidateFillingSelectedAI(TShowMsg.No); - FQuestions.Clear; FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeCompletionSuggestion); @@ -80,7 +79,6 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex LIOTAEditPosition.BackspaceDelete(TConsts.TAG_CODE_COMPLETION.Length); end; - //TUtils.ShowMsg('CodeCompletionSearch.Process - FQuestions.Text', FQuestions.Text); try FChat.ProcessSend(FQuestions.Text); except @@ -88,7 +86,6 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex end; FVars.Contents.Text := TUtils.ConfReturnAI(FChat.Response.Text); - //TUtils.ShowMsg('CodeCompletionSearch.Process - FVars.Contents.Text', FVars.Contents.Text); LRow := LIOTAEditPosition.Row; LColumn := LIOTAEditPosition.Column; @@ -105,7 +102,6 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex LIOTAEditPosition.InsertText(LText); //.TrimRight + sLineBreak); LIOTAEditPosition.Move(FVars.LineIni, LColumn); - //LIOTAEditPositionMoveBOL; // //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; // LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView); diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 62bb1d9..9ac8183 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -21,7 +21,7 @@ TDelphiAIDevKeyboardBinding = class(TNotifierObject, IOTAKeyboardBinding) procedure KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); procedure KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); //procedure KeyProcBlockReturn(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); - procedure KeyProcBlockReturnAndAlt(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); + procedure CodeCompletionSearch(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); protected function GetBindingType: TBindingType; function GetDisplayName: string; @@ -96,17 +96,17 @@ procedure TDelphiAIDevKeyboardBinding.BindKeyboard(const BindingServices: IOTAKe if not(Trim(TDelphiAIDevSettings.GetInstance.CodeCompletionShortcutInvoke).IsEmpty) then LShortcut := TDelphiAIDevSettings.GetInstance.CodeCompletionShortcutInvoke; - TUtils.ShowMsg(LShortcut); - BindingServices.AddKeyBinding([TextToShortCut(LShortcut)], Self.KeyProcBlockReturnAndAlt, nil); + BindingServices.AddKeyBinding([TextToShortCut(LShortcut)], Self.CodeCompletionSearch, nil); BindingServices.AddKeyBinding([Shortcut(VK_TAB, [])], Self.KeyTab, nil); BindingServices.AddKeyBinding([Shortcut(VK_HOME, [ssAlt])], Self.KeyAltHome, nil); end; -procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturnAndAlt(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); +procedure TDelphiAIDevKeyboardBinding.CodeCompletionSearch(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); begin try - TDelphiAIDevCodeCompletionSearch.New.Process(Context); + if TDelphiAIDevSettings.GetInstance.CodeCompletionUse then + TDelphiAIDevCodeCompletionSearch.New.Process(Context); finally BindingResult := TKeyBindingResult.krUnhandled; end; @@ -114,16 +114,16 @@ procedure TDelphiAIDevKeyboardBinding.KeyProcBlockReturnAndAlt(const Context: IO procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); begin - if KeyCode <> Shortcut(VK_TAB, []) then - Exit; +// if KeyCode <> Shortcut(VK_TAB, []) then +// Exit; + + BindingResult := TKeyBindingResult.krUnhandled; if TDelphiAIDevCodeCompletionVars.GetInstance.LineIni > 0 then begin TDelphiAIDevCodeCompletionKeyTab.New.Process(Context); BindingResult := TKeyBindingResult.krHandled; - end - else - BindingResult := TKeyBindingResult.krUnhandled; + end; end; procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 222aa2b..8931302 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -10,6 +10,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] + KeyPreview = True OldCreateOrder = False Position = poScreenCenter OnClose = FormClose @@ -1056,10 +1057,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView BevelOuter = bvNone ParentBackground = False TabOrder = 0 - ExplicitLeft = 3 - ExplicitTop = 9 - ExplicitWidth = 655 - ExplicitHeight = 476 object Label15: TLabel Left = 16 Top = 29 @@ -1070,14 +1067,27 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object Label16: TLabel Left = 16 Top = 138 - Width = 92 + Width = 231 Height = 13 - Caption = 'Shortcut for invoke' + Caption = 'Shortcut for invoke (Delphi IDE restart required)' + end + object Label17: TLabel + Left = 16 + Top = 443 + Width = 316 + Height = 13 + Caption = '* Attention! This feature is in Beta and may be unstable.' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False end object ckCodeCompletionUse: TCheckBox Left = 16 Top = 5 - Width = 97 + Width = 111 Height = 17 Cursor = crHandPoint Caption = 'Code Completion' @@ -1096,7 +1106,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object ColorBoxCodeCompletionSuggestionColor: TColorBox Left = 16 Top = 102 - Width = 133 + Width = 333 Height = 22 TabOrder = 2 end @@ -1108,20 +1118,13 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Cursor = crHandPoint Caption = 'Suggestion Code Color' TabOrder = 3 - OnClick = ckColorHighlightCodeDelphiUseClick + OnClick = ckCodeCompletionSuggestionColorUseClick end - object hotKeyCodeCompletionShortcutInvoke: THotKey + object edtCodeCompletionShortcutInvoke: TEdit Left = 16 - Top = 154 - Width = 150 - Height = 19 - Cursor = crArrow - Hint = 'Customize Shortcut' - HotKey = 0 - InvalidKeys = [hcNone] - Modifiers = [] - ParentShowHint = False - ShowHint = True + Top = 155 + Width = 333 + Height = 21 TabOrder = 4 end end diff --git a/Src/Settings/DelphiAIDev.Settings.View.pas b/Src/Settings/DelphiAIDev.Settings.View.pas index 995170a..23ad7a4 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.pas +++ b/Src/Settings/DelphiAIDev.Settings.View.pas @@ -18,7 +18,8 @@ interface Vcl.ComCtrls, Vcl.Menus, DelphiAIDev.Settings, - DelphiAIDev.Types; + DelphiAIDev.Types, + DelphiAIDev.Consts; type TDelphiAIDevSettingsView = class(TForm) @@ -109,10 +110,11 @@ TDelphiAIDevSettingsView = class(TForm) cBoxCodeCompletionAIDefault: TComboBox; ColorBoxCodeCompletionSuggestionColor: TColorBox; ckCodeCompletionSuggestionColorUse: TCheckBox; - hotKeyCodeCompletionShortcutInvoke: THotKey; Label16: TLabel; gboxData: TGroupBox; btnOpenDataFolder: TButton; + edtCodeCompletionShortcutInvoke: TEdit; + Label17: TLabel; procedure FormCreate(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure btnCloseClick(Sender: TObject); @@ -131,6 +133,7 @@ TDelphiAIDevSettingsView = class(TForm) procedure btnIAsOfflineClick(Sender: TObject); procedure btnCodeCompletionClick(Sender: TObject); procedure btnOpenDataFolderClick(Sender: TObject); + procedure ckCodeCompletionSuggestionColorUseClick(Sender: TObject); private FSettings: TDelphiAIDevSettings; procedure SaveSettings; @@ -142,6 +145,8 @@ TDelphiAIDevSettingsView = class(TForm) procedure FillcBoxCodeCompletionAIDefault; procedure ShowPanel(const AButton: TButton; const APanel: TPanel); procedure PanelsSetParent; + procedure ValidateCodeCompletionShortcutInvoke; + procedure ConfigFieldsCodeCompletionSuggestionColor; public end; @@ -289,11 +294,38 @@ procedure TDelphiAIDevSettingsView.lbRestoreDefaultsClick(Sender: TObject); procedure TDelphiAIDevSettingsView.btnConfirmClick(Sender: TObject); begin + Self.ValidateCodeCompletionShortcutInvoke; + Self.SaveSettings; Self.Close; Self.ModalResult := mrOk; end; +procedure TDelphiAIDevSettingsView.ValidateCodeCompletionShortcutInvoke; +var + LShortcutStr: string; + LShortCut: TShortCut; +begin + LShortcutStr := Trim(edtCodeCompletionShortcutInvoke.Text); + if LShortcutStr.Length = 1 then + raise Exception.Create('Invalid CodeCompletion shortcut'); + + LShortCut := TextToShortCut(LShortcutStr); + + if ShortCutToText(LShortCut).Trim.IsEmpty then + edtCodeCompletionShortcutInvoke.Text := TConsts.CODE_COMPLETION_SHORTCUT_INVOKE; +end; + +procedure TDelphiAIDevSettingsView.ckCodeCompletionSuggestionColorUseClick(Sender: TObject); +begin + Self.ConfigFieldsCodeCompletionSuggestionColor; +end; + +procedure TDelphiAIDevSettingsView.ConfigFieldsCodeCompletionSuggestionColor; +begin + ColorBoxCodeCompletionSuggestionColor.Enabled := ckCodeCompletionSuggestionColorUse.Checked; +end; + procedure TDelphiAIDevSettingsView.ckColorHighlightCodeDelphiUseClick(Sender: TObject); begin Self.ConfigFieldsColorHighlightDelphi; @@ -317,7 +349,7 @@ procedure TDelphiAIDevSettingsView.LoadSettings; cBoxCodeCompletionAIDefault.ItemIndex := Integer(FSettings.CodeCompletionAIDefault); ckCodeCompletionSuggestionColorUse.Checked := FSettings.CodeCompletionSuggestionColorUse; ColorBoxCodeCompletionSuggestionColor.Selected := FSettings.CodeCompletionSuggestionColor; - hotKeyCodeCompletionShortcutInvoke.HotKey := TextToShortCut(FSettings.CodeCompletionShortcutInvoke); + edtCodeCompletionShortcutInvoke.Text := FSettings.CodeCompletionShortcutInvoke; edtBaseUrlGemini.Text := FSettings.BaseUrlGemini; cBoxModelGemini.ItemIndex := cBoxModelGemini.Items.IndexOf(FSettings.ModelGemini); @@ -356,7 +388,7 @@ procedure TDelphiAIDevSettingsView.SaveSettings; FSettings.CodeCompletionAIDefault := TC4DAiAvailable(cBoxCodeCompletionAIDefault.ItemIndex); FSettings.CodeCompletionSuggestionColorUse := ckCodeCompletionSuggestionColorUse.Checked; FSettings.CodeCompletionSuggestionColor := ColorBoxCodeCompletionSuggestionColor.Selected; - FSettings.CodeCompletionShortcutInvoke := ShortCutToText(hotKeyCodeCompletionShortcutInvoke.HotKey); + FSettings.CodeCompletionShortcutInvoke := edtCodeCompletionShortcutInvoke.Text; FSettings.BaseUrlGemini := edtBaseUrlGemini.Text; FSettings.ModelGemini := cBoxModelGemini.Text; @@ -374,8 +406,6 @@ procedure TDelphiAIDevSettingsView.SaveSettings; FSettings.ModelOllama := cBoxModelOllama.Text; FSettings.ApiKeyOllama := edtApiKeyOllama.Text; - - FSettings.SaveData; end; From 26bebbc18c24d44b974bd18523f0f8d695de0edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 30 Aug 2024 01:24:06 -0300 Subject: [PATCH 054/109] refactor/2024-08-30-0124 --- Package/DelphiAIDeveloper.dpk | 2 +- Package/DelphiAIDeveloper.dproj | 2 +- .../DelphiAIDev.AI.pas} | 24 +++++++++++++------ Src/Chat/DelphiAIDev.Chat.View.dfm | 4 +++- Src/Chat/DelphiAIDev.Chat.View.pas | 12 +++++----- .../DelphiAIDev.CodeCompletion.Search.pas | 14 +++++------ Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 7 +++--- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 12 +++++----- Src/Settings/DelphiAIDev.Settings.pas | 16 ++++++++++++- 9 files changed, 59 insertions(+), 34 deletions(-) rename Src/{Chat/DelphiAIDev.Chat.pas => AI/DelphiAIDev.AI.pas} (71%) diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 78d5ca3..d25e7de 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -57,7 +57,7 @@ contains DelphiAIDev.Test in '..\Src\Test\DelphiAIDev.Test.pas', DelphiAIDev.Settings.View in '..\Src\Settings\DelphiAIDev.Settings.View.pas' {DelphiAIDevSettingsView}, DelphiAIDev.Settings in '..\Src\Settings\DelphiAIDev.Settings.pas', - DelphiAIDev.Chat in '..\Src\Chat\DelphiAIDev.Chat.pas', + DelphiAIDev.AI in '..\Src\AI\DelphiAIDev.AI.pas', DelphiAIDev.Chat.View in '..\Src\Chat\DelphiAIDev.Chat.View.pas' {DelphiAIDevChatView}, DelphiAIDev.Chat.ProcessResponse in '..\Src\Chat\DelphiAIDev.Chat.ProcessResponse.pas', DelphiAIDev.AI.Gemini in '..\Src\AI\DelphiAIDev.AI.Gemini.pas', diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 750c39e..5fb7005 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -154,7 +154,7 @@
DelphiAIDevSettingsView
- +
DelphiAIDevChatView
diff --git a/Src/Chat/DelphiAIDev.Chat.pas b/Src/AI/DelphiAIDev.AI.pas similarity index 71% rename from Src/Chat/DelphiAIDev.Chat.pas rename to Src/AI/DelphiAIDev.AI.pas index 04ea374..f32912d 100644 --- a/Src/Chat/DelphiAIDev.Chat.pas +++ b/Src/AI/DelphiAIDev.AI.pas @@ -1,4 +1,4 @@ -unit DelphiAIDev.Chat; +unit DelphiAIDev.AI; interface @@ -14,40 +14,50 @@ interface DelphiAIDev.AI.Ollama; type - TDelphiAIDevChat = class + TDelphiAIDevAI = class private + FAiUse: TC4DAiAvailable; FSettings: TDelphiAIDevSettings; FResponse: TStrings; public constructor Create; destructor Destroy; override; + function AiUse(const Value: TC4DAiAvailable): TDelphiAIDevAI; procedure ProcessSend(const AQuestion: string); function Response: TStrings; end; implementation -constructor TDelphiAIDevChat.Create; +constructor TDelphiAIDevAI.Create; begin FSettings := TDelphiAIDevSettings.GetInstance; FSettings.LoadData; + FAiUse := FSettings.AIDefault; FResponse := TStringList.Create; end; -destructor TDelphiAIDevChat.Destroy; +destructor TDelphiAIDevAI.Destroy; begin FResponse.Free; inherited; end; -procedure TDelphiAIDevChat.ProcessSend(const AQuestion: string); +function TDelphiAIDevAI.AiUse(const Value: TC4DAiAvailable): TDelphiAIDevAI; +begin + Result := Self; + FAiUse := Value; +end; + +procedure TDelphiAIDevAI.ProcessSend(const AQuestion: string); var LQuestion: string; begin LQuestion := TUtils.AdjustQuestionToJson(AQuestion); FResponse.Clear; - case FSettings.AIDefault of + TUtils.ShowMsgSynchronize(FAiUse.ToString); + case FAiUse of TC4DAiAvailable.Gemini: FResponse.Text := TDelphiAIDevAIGemini.New(FSettings).GetResponse(LQuestion); TC4DAiAvailable.OpenAI: @@ -61,7 +71,7 @@ procedure TDelphiAIDevChat.ProcessSend(const AQuestion: string); end; end; -function TDelphiAIDevChat.Response: TStrings; +function TDelphiAIDevAI.Response: TStrings; begin Result := FResponse; end; diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index 11c2036..d797f7b 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -138,7 +138,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Left = 0 Top = 3 Width = 56 - Height = 13 + Height = 22 Cursor = crHandPoint Hint = 'AI being used' Margins.Left = 0 @@ -149,6 +149,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'lbCurrentAI' PopupMenu = pMenuCurrentAI OnClick = lbCurrentAIClick + ExplicitHeight = 13 end object btnSend: TButton AlignWithMargins = True @@ -164,6 +165,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'Send' TabOrder = 0 OnClick = btnSendClick + ExplicitTop = 0 end object pnBackConfigurableButtons: TPanel Left = 395 diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index f062c0e..44b2a3e 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -26,7 +26,7 @@ interface Clipbrd, DelphiAIDev.Types, DelphiAIDev.Consts, - DelphiAIDev.Chat, + DelphiAIDev.AI, DelphiAIDev.Settings, DelphiAIDev.ModuleCreator, DelphiAIDev.DefaultsQuestions.PopupMenu, @@ -103,7 +103,7 @@ TDelphiAIDevChatView = class(TDockableForm) procedure Clear1Click(Sender: TObject); procedure btnCleanAllClick(Sender: TObject); private - FChat: TDelphiAIDevChat; + FAI: TDelphiAIDevAI; FSettings: TDelphiAIDevSettings; FProcessResponse: TDelphiAIDevChatProcessResponse; FPopupMenuQuestions: TDelphiAIDevDefaultsQuestionsPopupMenu; @@ -188,7 +188,7 @@ constructor TDelphiAIDevChatView.Create(AOwner: TComponent); AutoSave := True; SaveStateNecessary := True; - FChat := TDelphiAIDevChat.Create; + FAI := TDelphiAIDevAI.Create; FSettings := TDelphiAIDevSettings.GetInstance; FProcessResponse := TDelphiAIDevChatProcessResponse.Create(mmReturn); FPopupMenuQuestions := TDelphiAIDevDefaultsQuestionsPopupMenu.Create; @@ -203,7 +203,7 @@ destructor TDelphiAIDevChatView.Destroy; Self.SaveMemoReturnInFile; FPopupMenuQuestions.Free; FProcessResponse.Free; - FChat.Free; + FAI.Free; inherited; end; @@ -443,7 +443,7 @@ procedure TDelphiAIDevChatView.ProcessSend; begin try try - FChat.ProcessSend(LQuestion); + FAI.AiUse(FSettings.AIDefault).ProcessSend(LQuestion); except on E: Exception do TThread.Synchronize(nil, @@ -460,7 +460,7 @@ procedure TDelphiAIDevChatView.ProcessSend; mmReturn.Lines.BeginUpdate; try //Optional use of one of the following lines - FProcessResponse.AddResponseComplete(FChat.Response); + FProcessResponse.AddResponseComplete(FAI.Response); Self.Last; //Self.AddResponseSimple(FChat.Response.Text); finally diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index aca1f38..1a8b1f5 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -12,7 +12,7 @@ interface DelphiAIDev.Utils, DelphiAIDev.Utils.OTA, DelphiAIDev.CodeCompletion.Vars, - DelphiAIDev.Chat; + DelphiAIDev.AI; type IDelphiAIDevCodeCompletionSearch = interface @@ -24,7 +24,7 @@ TDelphiAIDevCodeCompletionSearch = class(TInterfacedObject, IDelphiAIDevCodeCo private FSettings: TDelphiAIDevSettings; FQuestions: TStrings; - FChat: TDelphiAIDevChat; + FAI: TDelphiAIDevAI; FVars: TDelphiAIDevCodeCompletionVars; protected procedure Process(const AContext: IOTAKeyContext); @@ -44,7 +44,7 @@ class function TDelphiAIDevCodeCompletionSearch.New: IDelphiAIDevCodeCompletionS constructor TDelphiAIDevCodeCompletionSearch.Create; begin FSettings := TDelphiAIDevSettings.GetInstance; - FChat := TDelphiAIDevChat.Create; + FAI := TDelphiAIDevAI.Create; FQuestions := TStringList.Create; FVars := TDelphiAIDevCodeCompletionVars.GetInstance; end; @@ -52,7 +52,7 @@ constructor TDelphiAIDevCodeCompletionSearch.Create; destructor TDelphiAIDevCodeCompletionSearch.Destroy; begin FQuestions.Free; - FChat.Free; + FAI.Free; inherited; end; @@ -64,7 +64,7 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex i: Integer; LIOTAEditPosition: IOTAEditPosition; begin - FSettings.ValidateFillingSelectedAI(TShowMsg.No); + FSettings.ValidateFillingSelectedAICodeCompletion(TShowMsg.No); FQuestions.Clear; FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); @@ -80,12 +80,12 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex end; try - FChat.ProcessSend(FQuestions.Text); + FAI.AiUse(FSettings.CodeCompletionAIDefault).ProcessSend(FQuestions.Text); except Abort; end; - FVars.Contents.Text := TUtils.ConfReturnAI(FChat.Response.Text); + FVars.Contents.Text := TUtils.ConfReturnAI(FAI.Response.Text); LRow := LIOTAEditPosition.Row; LColumn := LIOTAEditPosition.Column; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index cc3c49d..0e8c461 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -381,7 +381,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView AlignWithMargins = True Left = 508 Top = 0 - Width = 58 + Width = 61 Height = 25 Cursor = crHandPoint Margins.Left = 0 @@ -391,7 +391,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Caption = 'Generate' TabOrder = 2 OnClick = btnGenerateDatabaseReferenceClick - ExplicitLeft = 503 end end end @@ -445,8 +444,8 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end> end object pnCommands: TPanel - Left = 936 - Top = 184 + Left = 947 + Top = 174 Width = 26 Height = 115 Margins.Left = 0 diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 9eeb961..b0a0d85 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -26,7 +26,7 @@ interface Clipbrd, DelphiAIDev.Types, DelphiAIDev.Consts, - DelphiAIDev.Chat, + DelphiAIDev.AI, DelphiAIDev.Settings, DelphiAIDev.ModuleCreator, DelphiAIDev.DefaultsQuestions.PopupMenu, @@ -143,7 +143,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure DBGrid1TitleClick(Column: TColumn); procedure btnGenerateDatabaseReferenceClick(Sender: TObject); private - FChat: TDelphiAIDevChat; + FAI: TDelphiAIDevAI; FSettings: TDelphiAIDevSettings; FProcessResponse: TDelphiAIDevChatProcessResponse; FPopupMenuQuestions: TDelphiAIDevDefaultsQuestionsPopupMenu; @@ -236,7 +236,7 @@ constructor TDelphiAIDevDBChatView.Create(AOwner: TComponent); AutoSave := True; SaveStateNecessary := True; - FChat := TDelphiAIDevChat.Create; + FAI := TDelphiAIDevAI.Create; FSettings := TDelphiAIDevSettings.GetInstance; FProcessResponse := TDelphiAIDevChatProcessResponse.Create(mmReturn); FPopupMenuQuestions := TDelphiAIDevDefaultsQuestionsPopupMenu.Create; @@ -261,7 +261,7 @@ destructor TDelphiAIDevDBChatView.Destroy; Self.SaveMemoReturnInFile; FPopupMenuQuestions.Free; FProcessResponse.Free; - FChat.Free; + FAI.Free; inherited; end; @@ -742,7 +742,7 @@ procedure TDelphiAIDevDBChatView.ProcessSend; begin try try - FChat.ProcessSend(LQuestion); + FAI.AiUse(FSettings.AIDefault).ProcessSend(LQuestion); except on E: Exception do TThread.Synchronize(nil, @@ -759,7 +759,7 @@ procedure TDelphiAIDevDBChatView.ProcessSend; mmReturn.Lines.BeginUpdate; try //Optional use of one of the following lines - FProcessResponse.AddResponseComplete(FChat.Response); + FProcessResponse.AddResponseComplete(FAI.Response); Self.Last; //Self.AddResponseSimple(FChat.Response.Text); finally diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index feb29b1..f97c008 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -65,12 +65,15 @@ TDelphiAIDevSettings = class FApiKeyOllama: string; constructor Create; + procedure ValidateFillingSelectedAIInternal( + const AShowMsg: TShowMsg; const AAiUse: TC4DAiAvailable); public class function GetInstance: TDelphiAIDevSettings; procedure LoadDefaults; procedure SaveData; procedure LoadData; procedure ValidateFillingSelectedAI(const AShowMsg: TShowMsg = TShowMsg.Yes); + procedure ValidateFillingSelectedAICodeCompletion(const AShowMsg: TShowMsg = TShowMsg.Yes); property LanguageQuestions: TC4DLanguage read FLanguageQuestions write FLanguageQuestions; property AIDefault: TC4DAiAvailable read FAIDefault write FAIDefault; @@ -284,6 +287,17 @@ procedure TDelphiAIDevSettings.LoadData; end; procedure TDelphiAIDevSettings.ValidateFillingSelectedAI(const AShowMsg: TShowMsg = TShowMsg.Yes); +begin + Self.ValidateFillingSelectedAIInternal(AShowMsg, FAIDefault); +end; + +procedure TDelphiAIDevSettings.ValidateFillingSelectedAICodeCompletion(const AShowMsg: TShowMsg = TShowMsg.Yes); +begin + Self.ValidateFillingSelectedAIInternal(AShowMsg, FCodeCompletionAIDefault); +end; + +procedure TDelphiAIDevSettings.ValidateFillingSelectedAIInternal( + const AShowMsg: TShowMsg; const AAiUse: TC4DAiAvailable); const MSG = '"%s" for IA %s not specified in settings.' + sLineBreak + sLineBreak + 'Access menu > AI Developer > Settings'; @@ -295,7 +309,7 @@ procedure TDelphiAIDevSettings.ValidateFillingSelectedAI(const AShowMsg: TShowMs Abort; end; begin - case FAIDefault of + case AAiUse of TC4DAiAvailable.Gemini: begin if FBaseUrlGemini.Trim.IsEmpty then From 5a74add6af69438a094d62b299d592c45ad1490e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 30 Aug 2024 01:42:03 -0300 Subject: [PATCH 055/109] bk/2024-08-30-0142 --- Src/AI/DelphiAIDev.AI.pas | 1 - Src/Utils/DelphiAIDev.Utils.pas | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Src/AI/DelphiAIDev.AI.pas b/Src/AI/DelphiAIDev.AI.pas index f32912d..2ac4a30 100644 --- a/Src/AI/DelphiAIDev.AI.pas +++ b/Src/AI/DelphiAIDev.AI.pas @@ -56,7 +56,6 @@ procedure TDelphiAIDevAI.ProcessSend(const AQuestion: string); LQuestion := TUtils.AdjustQuestionToJson(AQuestion); FResponse.Clear; - TUtils.ShowMsgSynchronize(FAiUse.ToString); case FAiUse of TC4DAiAvailable.Gemini: FResponse.Text := TDelphiAIDevAIGemini.New(FSettings).GetResponse(LQuestion); diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index d71f5e6..0740f65 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -228,7 +228,7 @@ class procedure TUtils.AddLog(const AMessage: string); if not FileExists(LFileName)then Rewrite(LTextFile); Append(LTextFile); - Writeln(LTextFile, AMessage); + Writeln(LTextFile, Format('%s: %s', [DateTimeToStr(Now), AMessage])); CloseFile(LTextFile); except // on E: Exception do From c3d1df608832186992a2baeb77747f63c78651ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 30 Aug 2024 02:02:07 -0300 Subject: [PATCH 056/109] bk/2024-08-30-0202 --- Src/Chat/DelphiAIDev.Chat.View.dfm | 1 - .../DelphiAIDev.CodeCompletion.Search.pas | 71 ++++++++++--------- Src/Settings/DelphiAIDev.Settings.pas | 2 +- 3 files changed, 40 insertions(+), 34 deletions(-) diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index d797f7b..2610221 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -165,7 +165,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'Send' TabOrder = 0 OnClick = btnSendClick - ExplicitTop = 0 end object pnBackConfigurableButtons: TPanel Left = 395 diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index 1a8b1f5..27135ee 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -5,6 +5,8 @@ interface uses System.SysUtils, System.Classes, + Vcl.Forms, + Vcl.Controls, ToolsAPI, DelphiAIDev.Types, DelphiAIDev.Consts, @@ -66,42 +68,47 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex begin FSettings.ValidateFillingSelectedAICodeCompletion(TShowMsg.No); - FQuestions.Clear; - FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); - FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeCompletionSuggestion); - FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeOnly); - - LIOTAEditPosition := AContext.EditBuffer.EditPosition; - LIOTAEditPosition.InsertText(TConsts.TAG_CODE_COMPLETION); + Screen.Cursor := crHourGlass; try - FQuestions.Add(TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim); + FQuestions.Clear; + FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); + FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeCompletionSuggestion); + FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeOnly); + + LIOTAEditPosition := AContext.EditBuffer.EditPosition; + LIOTAEditPosition.InsertText(TConsts.TAG_CODE_COMPLETION); + try + FQuestions.Add(TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim); + finally + LIOTAEditPosition.BackspaceDelete(TConsts.TAG_CODE_COMPLETION.Length); + end; + + try + FAI.AiUse(FSettings.CodeCompletionAIDefault).ProcessSend(FQuestions.Text); + except + Abort; + end; + + FVars.Contents.Text := TUtils.ConfReturnAI(FAI.Response.Text); + + LRow := LIOTAEditPosition.Row; + LColumn := LIOTAEditPosition.Column; + + FVars.Row := LRow; + FVars.Column := LColumn; + FVars.LineIni := LRow; + FVars.LineEnd := FVars.LineIni + FVars.Contents.Count; + + LText := ''; + for i := 0 to Pred(FVars.Contents.Count) do + LText := LText + sLineBreak; + + LIOTAEditPosition.InsertText(LText); //.TrimRight + sLineBreak); + LIOTAEditPosition.Move(FVars.LineIni, LColumn); finally - LIOTAEditPosition.BackspaceDelete(TConsts.TAG_CODE_COMPLETION.Length); + Screen.Cursor := crDefault; end; - try - FAI.AiUse(FSettings.CodeCompletionAIDefault).ProcessSend(FQuestions.Text); - except - Abort; - end; - - FVars.Contents.Text := TUtils.ConfReturnAI(FAI.Response.Text); - - LRow := LIOTAEditPosition.Row; - LColumn := LIOTAEditPosition.Column; - - FVars.Row := LRow; - FVars.Column := LColumn; - FVars.LineIni := LRow; - FVars.LineEnd := FVars.LineIni + FVars.Contents.Count; - - LText := ''; - for i := 0 to Pred(FVars.Contents.Count) do - LText := LText + sLineBreak; - - LIOTAEditPosition.InsertText(LText); //.TrimRight + sLineBreak); - LIOTAEditPosition.Move(FVars.LineIni, LColumn); - //LIOTAEditPositionMoveBOL; // //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; // LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView); diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index f97c008..27ee603 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -129,7 +129,7 @@ procedure TDelphiAIDevSettings.LoadDefaults; FColorHighlightCodeDelphi := clNone; FCodeCompletionUse := False; - FCodeCompletionAIDefault := TC4DAiAvailable.Groq; + FCodeCompletionAIDefault := TC4DAiAvailable.Gemini; FCodeCompletionSuggestionColorUse := False; FCodeCompletionSuggestionColor := TConsts.CODE_COMPLETION_SUGGESTION_COLOR; FCodeCompletionShortcutInvoke := TConsts.CODE_COMPLETION_SHORTCUT_INVOKE; From 473555935e2e742eb20891f87dd77d2a0fb37821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 30 Aug 2024 17:17:32 -0300 Subject: [PATCH 057/109] bk/2024-08-30-1717 --- Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas | 9 ++------- Src/Test/DelphiAIDev.Test.Client.pas | 11 ++--------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 9ac8183..ce1bf37 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -20,7 +20,6 @@ TDelphiAIDevKeyboardBinding = class(TNotifierObject, IOTAKeyboardBinding) private procedure KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); procedure KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); - //procedure KeyProcBlockReturn(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); procedure CodeCompletionSearch(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); protected function GetBindingType: TBindingType; @@ -88,10 +87,9 @@ procedure TDelphiAIDevKeyboardBinding.BindKeyboard(const BindingServices: IOTAKe var LShortcut: string; begin -// if TUtilsOTA.CurrentProjectIsDelphiAIDeveloperDPROJ then -// Exit; + //if TUtilsOTA.CurrentProjectIsDelphiAIDeveloperDPROJ then + // Exit; - //BindingServices.AddKeyBinding([Shortcut(VK_RETURN, [ssAlt])], Self.KeyProcBlockReturnAndAlt, nil); LShortcut := TConsts.CODE_COMPLETION_SHORTCUT_INVOKE; if not(Trim(TDelphiAIDevSettings.GetInstance.CodeCompletionShortcutInvoke).IsEmpty) then LShortcut := TDelphiAIDevSettings.GetInstance.CodeCompletionShortcutInvoke; @@ -130,9 +128,6 @@ procedure TDelphiAIDevKeyboardBinding.KeyAltHome(const Context: IOTAKeyContext; var LTextCurrentLineOrBlock: string; begin - if KeyCode <> Shortcut(VK_RETURN, [ssAlt]) then - Exit; - LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView).Trim; if LTextCurrentLineOrBlock.Trim.IsEmpty then Exit; diff --git a/Src/Test/DelphiAIDev.Test.Client.pas b/Src/Test/DelphiAIDev.Test.Client.pas index 8aa1ba6..7097eb8 100644 --- a/Src/Test/DelphiAIDev.Test.Client.pas +++ b/Src/Test/DelphiAIDev.Test.Client.pas @@ -11,7 +11,7 @@ TDelphiAIDevTestClient = class FNumero: Integer; FTelefone: string; FEmail: string; - FDataNascimento: TDateTime; + FSalario: Double; public property Nome: string read FNome write FNome; property Endereco: string read FEndereco write FEndereco; @@ -19,17 +19,10 @@ TDelphiAIDevTestClient = class property Numero: Integer read FNumero write FNumero; property Telefone: string read FTelefone write FTelefone; property Email: string read FEmail write FEmail; - property DataNascimento: TDateTime read FDataNascimento write FDataNascimento; - - procedure Clear; + property Salario: Double read FSalario write FSalario; end; implementation -procedure TDelphiAIDevTestClient.Clear; -begin - //Suggestion - -end; end. From 9b20b25480142aafd779e370eadb5dd8e452ae40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Sat, 31 Aug 2024 01:39:46 -0300 Subject: [PATCH 058/109] bk/2024-08-31-0139 --- Src/Consts/DelphiAIDev.Consts.pas | 1 + Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas | 3 ++- Src/MainMenu/DelphiAIDev.MainMenu.pas | 2 +- Src/Test/DelphiAIDev.Test.Client.pas | 6 ++++++ Src/Test/DelphiAIDev.Test.pas | 3 +-- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index b46f3ee..8ecbd74 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -16,6 +16,7 @@ TConsts = class GITHUB_Code4Delphi = 'https://github.com/Code4Delphi'; GITHUB_PROJECT = 'https://github.com/Code4Delphi/Delphi-AI-Developer'; APPLICATION_JSON = 'application/json'; + SHORTCUT_CHAT_DEFAULT = 'Ctrl+Shift+Alt+A'; CODE_COMPLETION_SUGGESTION_COLOR = $777777; CODE_COMPLETION_SHORTCUT_INVOKE = 'Alt+Enter'; diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index ce1bf37..f1d7d80 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -106,7 +106,8 @@ procedure TDelphiAIDevKeyboardBinding.CodeCompletionSearch(const Context: IOTAKe if TDelphiAIDevSettings.GetInstance.CodeCompletionUse then TDelphiAIDevCodeCompletionSearch.New.Process(Context); finally - BindingResult := TKeyBindingResult.krUnhandled; + //BindingResult := TKeyBindingResult.krUnhandled; + BindingResult := TKeyBindingResult.krHandled; end; end; diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.pas b/Src/MainMenu/DelphiAIDev.MainMenu.pas index 8c914a3..631e702 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.pas @@ -145,7 +145,7 @@ function TDelphiAIDevIDEMainMenu.CreateSubMenu(AName: string; ACaption: string; function TDelphiAIDevIDEMainMenu.GetShortCutStrChat: string; begin - Result := 'Ctrl+Shift+Alt+A'; + Result := TConsts.SHORTCUT_CHAT_DEFAULT; end; initialization diff --git a/Src/Test/DelphiAIDev.Test.Client.pas b/Src/Test/DelphiAIDev.Test.Client.pas index 7097eb8..550547c 100644 --- a/Src/Test/DelphiAIDev.Test.Client.pas +++ b/Src/Test/DelphiAIDev.Test.Client.pas @@ -20,9 +20,15 @@ TDelphiAIDevTestClient = class property Telefone: string read FTelefone write FTelefone; property Email: string read FEmail write FEmail; property Salario: Double read FSalario write FSalario; + + procedure Clear; end; implementation +procedure TDelphiAIDevTestClient.Clear; +begin + +end; end. diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 3c79ed5..0ed2974 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -23,7 +23,7 @@ TDelphiAIDevTest = class property Email: string read FEmail write FEmail; property DataNascimento: TDateTime read FDataNascimento write FDataNascimento; property Apelido: string read FApelido write FApelido; - property Cep: Integer read FCep write FCep; + procedure Clear; end; @@ -32,7 +32,6 @@ implementation procedure TDelphiAIDevTest.Clear; begin - end; end. From 8c5729f6216912004ddea7338a6a0c1c4f5ffda7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 2 Sep 2024 11:48:07 -0300 Subject: [PATCH 059/109] bk/2024-09-02-1148 --- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 13 ++++++------- .../Registers/DelphiAIDev.DB.Registers.Fields.pas | 1 + Src/DelphiAIDev.Register.pas | 4 ++-- Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas | 1 - Src/Settings/DelphiAIDev.Settings.View.dfm | 4 ++-- Src/Test/DelphiAIDev.Test.Client.pas | 11 ++++++----- Src/Test/DelphiAIDev.Test.pas | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index b0a0d85..4fed8d3 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -245,17 +245,10 @@ constructor TDelphiAIDevDBChatView.Create(AOwner: TComponent); FConn := TC4DConn.New; FQueryExecuteSQL := FConn.Query.DataSource(DataSource1); - Self.ConfScreenOnCreate; Self.FillMemoReturnWithFile; end; -procedure TDelphiAIDevDBChatView.DBGrid1DrawColumnCell(Sender: TObject; - const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); -begin - TUtilsDBGrids.DrawColumnCell(TDBGrid(Sender), Rect, DataCol, Column, Vcl.Grids.TGridDrawState(State)); -end; - destructor TDelphiAIDevDBChatView.Destroy; begin Self.SaveMemoReturnInFile; @@ -297,6 +290,12 @@ procedure TDelphiAIDevDBChatView.FormClose(Sender: TObject; var Action: TCloseAc Self.WaitingFormOFF; end; +procedure TDelphiAIDevDBChatView.DBGrid1DrawColumnCell(Sender: TObject; + const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); +begin + TUtilsDBGrids.DrawColumnCell(TDBGrid(Sender), Rect, DataCol, Column, Vcl.Grids.TGridDrawState(State)); +end; + procedure TDelphiAIDevDBChatView.ConfScreenOnCreate; begin mmReturn.Lines.Clear; diff --git a/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas b/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas index ebce1f8..6e2af9c 100644 --- a/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas +++ b/Src/DB/Registers/DelphiAIDev.DB.Registers.Fields.pas @@ -73,4 +73,5 @@ procedure TDelphiAIDevDBRegistersFields.GetDataFromOtherObject(const AOtherObj: FLastReferences := AOtherObj.LastReferences; end; + end. diff --git a/Src/DelphiAIDev.Register.pas b/Src/DelphiAIDev.Register.pas index 671f1e6..6a38c15 100644 --- a/Src/DelphiAIDev.Register.pas +++ b/Src/DelphiAIDev.Register.pas @@ -4,10 +4,10 @@ interface uses DelphiAIDev.Chat.View, + DelphiAIDev.DB.Chat.View, DelphiAIDev.MainMenu.Register, DelphiAIDev.KeyboardBinding, DelphiAIDev.PopupMenuProjects, - DelphiAIDev.DB.Chat.View, DelphiAIDev.IDE.OTAIDENotifier; procedure Register; @@ -17,10 +17,10 @@ implementation procedure Register; begin DelphiAIDev.Chat.View.RegisterSelf; + DelphiAIDev.DB.Chat.View.RegisterSelf; DelphiAIDev.MainMenu.Register.RegisterSelf; DelphiAIDev.KeyboardBinding.RefreshRegister; DelphiAIDev.PopupMenuProjects.RegisterSelf; - DelphiAIDev.DB.Chat.View.RegisterSelf; DelphiAIDev.IDE.OTAIDENotifier.RegisterSelf; end; diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas index b5647c7..5dd7993 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.Clicks.pas @@ -31,7 +31,6 @@ implementation DelphiAIDev.Settings.View, DelphiAIDev.View.About; - class procedure TDelphiAIDevIDEMainMenuClicks.ChatClick(Sender: TObject); begin DelphiAIDev.Chat.View.DelphiAIDevChatViewShowDockableForm; diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 8931302..107542b 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -207,7 +207,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Top = 33 Width = 667 Height = 521 - ActivePage = TabSheet4 + ActivePage = TabSheet3 TabOrder = 1 object TabSheet1: TTabSheet Caption = 'Preferences' @@ -981,7 +981,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Width = 82 Height = 13 Cursor = crHandPoint - Hint = 'https://ollama.com/' + Hint = 'https://ollama.com/download' Caption = 'Ollama Download' Font.Charset = DEFAULT_CHARSET Font.Color = clBlue diff --git a/Src/Test/DelphiAIDev.Test.Client.pas b/Src/Test/DelphiAIDev.Test.Client.pas index 550547c..8d87c0c 100644 --- a/Src/Test/DelphiAIDev.Test.Client.pas +++ b/Src/Test/DelphiAIDev.Test.Client.pas @@ -10,16 +10,13 @@ TDelphiAIDevTestClient = class FBairro: string; FNumero: Integer; FTelefone: string; - FEmail: string; - FSalario: Double; + public property Nome: string read FNome write FNome; property Endereco: string read FEndereco write FEndereco; property Bairro: string read FBairro write FBairro; property Numero: Integer read FNumero write FNumero; property Telefone: string read FTelefone write FTelefone; - property Email: string read FEmail write FEmail; - property Salario: Double read FSalario write FSalario; procedure Clear; end; @@ -28,7 +25,11 @@ implementation procedure TDelphiAIDevTestClient.Clear; begin - + FNome := ''; + FEndereco := ''; + FBairro := ''; + FNumero := 0; + FTelefone := ''; end; end. diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 0ed2974..55203ea 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -23,8 +23,7 @@ TDelphiAIDevTest = class property Email: string read FEmail write FEmail; property DataNascimento: TDateTime read FDataNascimento write FDataNascimento; property Apelido: string read FApelido write FApelido; - - + property Cep: Integer read FCep write FCep; procedure Clear; end; @@ -32,6 +31,7 @@ implementation procedure TDelphiAIDevTest.Clear; begin + end; end. From 9bb504a8549a64244c6316c5baf5b854b3769f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 2 Sep 2024 15:37:32 -0300 Subject: [PATCH 060/109] Create FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..89e42ea --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: ['https://pag.ae/7ZhEY1xKr'] From 209dddee84a21a6e6889d5761c1ca1e010b33118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 2 Sep 2024 15:38:00 -0300 Subject: [PATCH 061/109] Delete FUNDING.yml --- .github/FUNDING.yml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 89e42ea..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -custom: ['https://pag.ae/7ZhEY1xKr'] From 3a37c6eb03e650593670957e38fe36753ccd535d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 2 Sep 2024 15:38:26 -0300 Subject: [PATCH 062/109] Create FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..89e42ea --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: ['https://pag.ae/7ZhEY1xKr'] From 324fd182cc499c4603e3ad1769b160a43eb0be13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 3 Sep 2024 10:43:04 -0300 Subject: [PATCH 063/109] fit/chats-fonts --- Src/Chat/DelphiAIDev.Chat.View.dfm | 4 ++-- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 17 +++++++++++++---- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index 2610221..eea88f7 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -67,7 +67,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Ctl3D = True Font.Charset = ANSI_CHARSET Font.Color = clWindow - Font.Height = -12 + Font.Height = -13 Font.Name = 'Courier New' Font.Style = [] Lines.Strings = ( @@ -109,7 +109,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Align = alClient Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText - Font.Height = -11 + Font.Height = -13 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 0e8c461..1658524 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -79,7 +79,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Ctl3D = True Font.Charset = ANSI_CHARSET Font.Color = clWindow - Font.Height = -12 + Font.Height = -13 Font.Name = 'Courier New' Font.Style = [] Lines.Strings = ( @@ -108,12 +108,21 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Top = 5 ParentBackground = False TabOrder = 0 + object Label2: TLabel + Left = 0 + Top = 5 + Width = 938 + Height = 17 + Align = alTop + AutoSize = False + Caption = 'Question / prompt' + end object mmQuestion: TMemo AlignWithMargins = True Left = 0 - Top = 5 + Top = 22 Width = 938 - Height = 108 + Height = 91 Hint = 'Insert question' Margins.Left = 0 Margins.Top = 0 @@ -122,7 +131,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Align = alClient Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText - Font.Height = -11 + Font.Height = -13 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 4fed8d3..b2db000 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -104,6 +104,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) Label3: TLabel; Ollama1: TMenuItem; btnGenerateDatabaseReference: TButton; + Label2: TLabel; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); procedure Cut1Click(Sender: TObject); From b3919ecad668ec04538d23f662580b2dab1a7e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 3 Sep 2024 15:38:10 -0300 Subject: [PATCH 064/109] bk/2024-09-03-1538 --- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 1658524..e0dc662 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -43,7 +43,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView TabOrder = 0 object Splitter1: TSplitter Left = 18 - Top = 128 + Top = 153 Width = 938 Height = 3 Cursor = crVSplit @@ -54,7 +54,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object Splitter2: TSplitter Left = 18 - Top = 333 + Top = 498 Width = 938 Height = 3 Cursor = crVSplit @@ -65,9 +65,9 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView object mmReturn: TRichEdit AlignWithMargins = True Left = 18 - Top = 158 + Top = 183 Width = 938 - Height = 145 + Height = 285 Hint = 'Response returned' Margins.Left = 0 Margins.Top = 0 @@ -98,7 +98,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Left = 18 Top = 15 Width = 938 - Height = 113 + Height = 138 Margins.Left = 0 Margins.Top = 0 Margins.Right = 0 @@ -122,7 +122,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Left = 0 Top = 22 Width = 938 - Height = 91 + Height = 116 Hint = 'Insert question' Margins.Left = 0 Margins.Top = 0 @@ -145,7 +145,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object pnBackButtonsSearch: TPanel Left = 18 - Top = 131 + Top = 156 Width = 938 Height = 27 Margins.Left = 0 @@ -257,9 +257,9 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object pnGridBack: TPanel Left = 18 - Top = 336 + Top = 501 Width = 938 - Height = 325 + Height = 160 Align = alBottom BevelOuter = bvNone ParentBackground = False @@ -268,7 +268,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Left = 0 Top = 0 Width = 938 - Height = 298 + Height = 133 Align = alClient BorderStyle = bsNone DataSource = DataSource1 @@ -285,7 +285,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object Panel9: TPanel Left = 0 - Top = 298 + Top = 133 Width = 938 Height = 27 Align = alBottom @@ -320,7 +320,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView end object Panel1: TPanel Left = 18 - Top = 306 + Top = 471 Width = 938 Height = 27 Margins.Left = 0 From 2d9549df09c67c9f3a29ae3ffc0d68779f960ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 10:34:10 -0300 Subject: [PATCH 065/109] bk/2024-09-16-1034 --- Src/Chat/DelphiAIDev.Chat.View.pas | 5 ++- .../DelphiAIDev.CodeCompletion.Search.pas | 2 + Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 2 + Src/Settings/DelphiAIDev.Settings.View.dfm | 44 ++++++++++++++++++- Src/Settings/DelphiAIDev.Settings.View.pas | 8 ++++ Src/Settings/DelphiAIDev.Settings.pas | 18 +++++++- 6 files changed, 76 insertions(+), 3 deletions(-) diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index 44b2a3e..b5a5526 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -434,7 +434,10 @@ procedure TDelphiAIDevChatView.ProcessSend; LQuestion := TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim + sLineBreak; if btnCodeOnly.ImageIndex = CodeOnly_ImageIndex_ON then - LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgCodeOnly; + LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgCodeOnly + sLineBreak; + + if not FSettings.DefaultPrompt.Trim.IsEmpty then + LQuestion := LQuestion + FSettings.DefaultPrompt + sLineBreak; LQuestion := LQuestion + mmQuestion.Lines.Text; diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index 27135ee..114f809 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -74,6 +74,8 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeCompletionSuggestion); FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeOnly); + if not FSettings.CodeCompletionDefaultPrompt.Trim.IsEmpty then + FQuestions.Add(FSettings.CodeCompletionDefaultPrompt); LIOTAEditPosition := AContext.EditBuffer.EditPosition; LIOTAEditPosition.InsertText(TConsts.TAG_CODE_COMPLETION); diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index b2db000..baa660c 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -735,6 +735,8 @@ procedure TDelphiAIDevDBChatView.ProcessSend; LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgJSONIsDatabaseStructure(Self.GetFieldDBSelected.DriverID.ToString); LQuestion := LQuestion + Self.GetJsonDatabase + sLineBreak; LQuestion := LQuestion + FSettings.LanguageQuestions.GetMsgJSONInformedAnswerQuestion; + if not FSettings.DefaultPrompt.Trim.IsEmpty then + LQuestion := LQuestion + FSettings.DefaultPrompt + sLineBreak; LQuestion := LQuestion + mmQuestion.Lines.Text; LTask := TTask.Create( diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 107542b..14e7cc2 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -207,10 +207,14 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Top = 33 Width = 667 Height = 521 - ActivePage = TabSheet3 + ActivePage = TabSheet4 TabOrder = 1 object TabSheet1: TTabSheet Caption = 'Preferences' + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 0 + ExplicitHeight = 0 object pnPreferencesBack: TPanel Left = 0 Top = 0 @@ -243,6 +247,13 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Height = 13 Caption = 'Language used in questions' end + object Label19: TLabel + Left = 21 + Top = 122 + Width = 72 + Height = 13 + Caption = 'Default Prompt' + end object cBoxAIDefault: TComboBox Left = 272 Top = 38 @@ -303,12 +314,24 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView OnClick = btnOpenDataFolderClick end end + object mmDefaultPrompt: TMemo + Left = 21 + Top = 139 + Width = 617 + Height = 201 + ScrollBars = ssVertical + TabOrder = 5 + end end end end object TabSheet2: TTabSheet Caption = 'IAs on-line' ImageIndex = 1 + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 0 + ExplicitHeight = 0 object pnIAsOnLineBack: TPanel Left = 0 Top = 0 @@ -851,6 +874,10 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object TabSheet3: TTabSheet Caption = 'IAs off-Line' ImageIndex = 2 + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 0 + ExplicitHeight = 0 object pnIAsOffLineBack: TPanel Left = 0 Top = 0 @@ -1084,6 +1111,13 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Font.Style = [fsBold] ParentFont = False end + object Label18: TLabel + Left = 16 + Top = 187 + Width = 72 + Height = 13 + Caption = 'Default Prompt' + end object ckCodeCompletionUse: TCheckBox Left = 16 Top = 5 @@ -1127,6 +1161,14 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Height = 21 TabOrder = 4 end + object mmCodeCompletionDefaultPrompt: TMemo + Left = 16 + Top = 204 + Width = 617 + Height = 201 + ScrollBars = ssVertical + TabOrder = 5 + end end end end diff --git a/Src/Settings/DelphiAIDev.Settings.View.pas b/Src/Settings/DelphiAIDev.Settings.View.pas index 23ad7a4..0d5c909 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.pas +++ b/Src/Settings/DelphiAIDev.Settings.View.pas @@ -115,6 +115,10 @@ TDelphiAIDevSettingsView = class(TForm) btnOpenDataFolder: TButton; edtCodeCompletionShortcutInvoke: TEdit; Label17: TLabel; + Label18: TLabel; + mmCodeCompletionDefaultPrompt: TMemo; + Label19: TLabel; + mmDefaultPrompt: TMemo; procedure FormCreate(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure btnCloseClick(Sender: TObject); @@ -344,12 +348,14 @@ procedure TDelphiAIDevSettingsView.LoadSettings; ckColorHighlightCodeDelphiUse.Checked := FSettings.ColorHighlightCodeDelphiUse; ColorBoxColorHighlightCodeDelphi.Selected := FSettings.ColorHighlightCodeDelphi; Self.ConfigFieldsColorHighlightDelphi; + mmDefaultPrompt.Lines.Text := FSettings.DefaultPrompt; ckCodeCompletionUse.Checked := FSettings.CodeCompletionUse; cBoxCodeCompletionAIDefault.ItemIndex := Integer(FSettings.CodeCompletionAIDefault); ckCodeCompletionSuggestionColorUse.Checked := FSettings.CodeCompletionSuggestionColorUse; ColorBoxCodeCompletionSuggestionColor.Selected := FSettings.CodeCompletionSuggestionColor; edtCodeCompletionShortcutInvoke.Text := FSettings.CodeCompletionShortcutInvoke; + mmCodeCompletionDefaultPrompt.Lines.Text := FSettings.CodeCompletionDefaultPrompt; edtBaseUrlGemini.Text := FSettings.BaseUrlGemini; cBoxModelGemini.ItemIndex := cBoxModelGemini.Items.IndexOf(FSettings.ModelGemini); @@ -383,12 +389,14 @@ procedure TDelphiAIDevSettingsView.SaveSettings; FSettings.ColorHighlightCodeDelphiUse := ckColorHighlightCodeDelphiUse.Checked; FSettings.ColorHighlightCodeDelphi := ColorBoxColorHighlightCodeDelphi.Selected; + FSettings.DefaultPrompt := mmDefaultPrompt.Lines.Text; FSettings.CodeCompletionUse := ckCodeCompletionUse.Checked; FSettings.CodeCompletionAIDefault := TC4DAiAvailable(cBoxCodeCompletionAIDefault.ItemIndex); FSettings.CodeCompletionSuggestionColorUse := ckCodeCompletionSuggestionColorUse.Checked; FSettings.CodeCompletionSuggestionColor := ColorBoxCodeCompletionSuggestionColor.Selected; FSettings.CodeCompletionShortcutInvoke := edtCodeCompletionShortcutInvoke.Text; + FSettings.CodeCompletionDefaultPrompt := mmCodeCompletionDefaultPrompt.Lines.Text; FSettings.BaseUrlGemini := edtBaseUrlGemini.Text; FSettings.ModelGemini := cBoxModelGemini.Text; diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index 27ee603..ac9d175 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -18,12 +18,14 @@ TDelphiAIDevSettings = class FIELD_LanguageQuestions = 'LanguageQuestions'; FIELD_AIDefault = 'AIDefault'; FIELD_ColorHighlightCodeDelphiUse = 'ColorHighlightCodeDelphiUse'; - FIELD_ColorHighlightCodeDelphi = 'ColorHighlightCodeDelphi'; + FIELD_ColorHighlightCodeDelphi = 'ColorHighlightCodeDelphi'; + FIELD_DefaultPrompt = 'DefaultPrompt'; FIELD_CodeCompletionUse = 'CodeCompletionUse'; FIELD_CodeCompletionAIDefault = 'CodeCompletionAIDefault'; FIELD_CodeCompletionSuggestionColorUse = 'CodeCompletionSuggestionColorUse'; FIELD_CodeCompletionSuggestionColor = 'CodeCompletionSuggestionColor'; FIELD_CodeCompletionShortcutInvoke = 'CodeCompletionShortcutInvoke'; + FIELD_CodeCompletionDefaultPrompt = 'CodeCompletionDefaultPrompt'; FIELD_BaseUrlGemini = 'BaseUrlGemini'; FIELD_ModelGemini = 'ModelGemini'; FIELD_ApiKeyGemini = 'ApiKeyGemini'; @@ -41,12 +43,14 @@ TDelphiAIDevSettings = class FAIDefault: TC4DAiAvailable; FColorHighlightCodeDelphiUse: Boolean; FColorHighlightCodeDelphi: TColor; + FDefaultPrompt: string; FCodeCompletionUse: Boolean; FCodeCompletionAIDefault: TC4DAiAvailable; FCodeCompletionSuggestionColorUse: Boolean; FCodeCompletionSuggestionColor: TColor; FCodeCompletionShortcutInvoke: string; + FCodeCompletionDefaultPrompt: string; FBaseUrlGemini: string; FModelGemini: string; @@ -79,12 +83,14 @@ TDelphiAIDevSettings = class property AIDefault: TC4DAiAvailable read FAIDefault write FAIDefault; property ColorHighlightCodeDelphiUse: Boolean read FColorHighlightCodeDelphiUse write FColorHighlightCodeDelphiUse; property ColorHighlightCodeDelphi: TColor read FColorHighlightCodeDelphi write FColorHighlightCodeDelphi; + property DefaultPrompt: string read FDefaultPrompt write FDefaultPrompt; property CodeCompletionUse: Boolean read FCodeCompletionUse write FCodeCompletionUse; property CodeCompletionAIDefault: TC4DAiAvailable read FCodeCompletionAIDefault write FCodeCompletionAIDefault; property CodeCompletionSuggestionColorUse: Boolean read FCodeCompletionSuggestionColorUse write FCodeCompletionSuggestionColorUse; property CodeCompletionSuggestionColor: TColor read FCodeCompletionSuggestionColor write FCodeCompletionSuggestionColor; property CodeCompletionShortcutInvoke: string read FCodeCompletionShortcutInvoke write FCodeCompletionShortcutInvoke; + property CodeCompletionDefaultPrompt: string read FCodeCompletionDefaultPrompt write FCodeCompletionDefaultPrompt; property BaseUrlGemini: string read FBaseUrlGemini write FBaseUrlGemini; property ModelGemini: string read FModelGemini write FModelGemini; @@ -127,12 +133,14 @@ procedure TDelphiAIDevSettings.LoadDefaults; FColorHighlightCodeDelphiUse := False; FColorHighlightCodeDelphi := clNone; + FDefaultPrompt := ''; FCodeCompletionUse := False; FCodeCompletionAIDefault := TC4DAiAvailable.Gemini; FCodeCompletionSuggestionColorUse := False; FCodeCompletionSuggestionColor := TConsts.CODE_COMPLETION_SUGGESTION_COLOR; FCodeCompletionShortcutInvoke := TConsts.CODE_COMPLETION_SHORTCUT_INVOKE; + FCodeCompletionDefaultPrompt := ''; FBaseUrlGemini := TConsts.BASE_URL_GEMINI_DEFAULT; FModelGemini := TConsts.MODEL_GEMINI_DEFAULT; @@ -167,12 +175,14 @@ procedure TDelphiAIDevSettings.SaveData; LReg.WriteBool(FIELD_ColorHighlightCodeDelphiUse, FColorHighlightCodeDelphiUse); LReg.WriteString(FIELD_ColorHighlightCodeDelphi, ColorToString(FColorHighlightCodeDelphi)); + LReg.WriteString(FIELD_DefaultPrompt, FDefaultPrompt); LReg.WriteBool(FIELD_CodeCompletionUse, FCodeCompletionUse); LReg.WriteInteger(FIELD_CodeCompletionAIDefault, Integer(FCodeCompletionAIDefault)); LReg.WriteBool(FIELD_CodeCompletionSuggestionColorUse, FCodeCompletionSuggestionColorUse); LReg.WriteString(FIELD_CodeCompletionSuggestionColor, ColorToString(FCodeCompletionSuggestionColor)); LReg.WriteString(FIELD_CodeCompletionShortcutInvoke, FCodeCompletionShortcutInvoke); + LReg.WriteString(FIELD_CodeCompletionDefaultPrompt, FCodeCompletionDefaultPrompt); LReg.WriteString(FIELD_BaseUrlGemini, FBaseUrlGemini); LReg.WriteString(FIELD_ModelGemini, FModelGemini); @@ -222,6 +232,9 @@ procedure TDelphiAIDevSettings.LoadData; FColorHighlightCodeDelphi := TUtils.StringToColorDef(LReg.ReadString(FIELD_ColorHighlightCodeDelphi), TUtilsOTA.ActiveThemeForCode); + if LReg.ValueExists(FIELD_DefaultPrompt) then + FDefaultPrompt := LReg.ReadString(FIELD_DefaultPrompt); + //Code Completion if LReg.ValueExists(FIELD_CodeCompletionUse) then FCodeCompletionUse := LReg.ReadBool(FIELD_CodeCompletionUse); @@ -239,6 +252,9 @@ procedure TDelphiAIDevSettings.LoadData; if LReg.ValueExists(FIELD_CodeCompletionShortcutInvoke) then FCodeCompletionShortcutInvoke := LReg.ReadString(FIELD_CodeCompletionShortcutInvoke); + if LReg.ValueExists(FIELD_CodeCompletionDefaultPrompt) then + FCodeCompletionDefaultPrompt := LReg.ReadString(FIELD_CodeCompletionDefaultPrompt); + //GEMINI if LReg.ValueExists(FIELD_BaseUrlGemini) then FBaseUrlGemini := LReg.ReadString(FIELD_BaseUrlGemini); From 67890bca68de0adfbb45800baed3d155825cca56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 14:04:54 -0300 Subject: [PATCH 066/109] bk/2024-09-16-1404 --- Src/AI/DelphiAIDev.AI.pas | 3 +++ Src/Test/DelphiAIDev.Test.Client.pas | 1 - Src/Types/DelphiAIDev.Types.pas | 19 +++++++++++++--- Src/Utils/DelphiAIDev.Utils.pas | 34 ++++++++++++++++++++++++---- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/Src/AI/DelphiAIDev.AI.pas b/Src/AI/DelphiAIDev.AI.pas index 2ac4a30..5daa847 100644 --- a/Src/AI/DelphiAIDev.AI.pas +++ b/Src/AI/DelphiAIDev.AI.pas @@ -56,6 +56,9 @@ procedure TDelphiAIDevAI.ProcessSend(const AQuestion: string); LQuestion := TUtils.AdjustQuestionToJson(AQuestion); FResponse.Clear; + if TUtils.InDebugMy then + TUtils.AddLogDeleteFileFirst(LQuestion, 'DelphiAIDevAI_ProcessSend'); + case FAiUse of TC4DAiAvailable.Gemini: FResponse.Text := TDelphiAIDevAIGemini.New(FSettings).GetResponse(LQuestion); diff --git a/Src/Test/DelphiAIDev.Test.Client.pas b/Src/Test/DelphiAIDev.Test.Client.pas index 8d87c0c..301fcb5 100644 --- a/Src/Test/DelphiAIDev.Test.Client.pas +++ b/Src/Test/DelphiAIDev.Test.Client.pas @@ -10,7 +10,6 @@ TDelphiAIDevTestClient = class FBairro: string; FNumero: Integer; FTelefone: string; - public property Nome: string read FNome write FNome; property Endereco: string read FEndereco write FEndereco; diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index 64c190c..27097b0 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -175,14 +175,27 @@ function TC4DLanguageHelper.GetMsgJSONInformedAnswerQuestion: string; function TC4DLanguageHelper.GetMsgCodeCompletionSuggestion: string; begin Result := 'Com base no seguinte código delphi, de uma sugestão ' + - 'de código para ser adicionado onde esta o comentário //Suggestion'; + 'de código para ser adicionado onde esta o comentário %s ' + sLineBreak + + 'Importante: antes do implementation e dentro dos especificadores '+ + 'private, protected, public, published deve-se adicionar apenas declarações '+ + 'e nunca se deve adicionar implementações de códigos delphi que contenham begin. ' + sLineBreak + + 'Nas sugestões, nunca repita um código que já exista. '; case Self of TC4DLanguage.en: - Result := 'Based on the following Delphi code, give a suggestion of code to be added where the comment //Suggestion is'; + Result := 'Based on the following Delphi code, give a suggestion of code to be added where the comment %s is ' + sLineBreak + + 'Important: before implementation and within the '+ + 'private, protected, public, published specifiers, you should only add declarations '+ + 'and never add Delphi code implementations that contain begin. '+ sLineBreak + + 'In suggestions, never repeat code that already exists. '; TC4DLanguage.es: - Result := 'Basado en el siguiente código Delphi, se agregará una sugerencia de código donde está el comentario //Sugerencia'; + Result := 'Basado en el siguiente código Delphi, se agregará una sugerencia de código donde está el comentario %s ' + sLineBreak + + 'Importante: antes de la implementación y dentro de los especificadores '+ + 'privados, protegidos, públicos y publicados, solo se deben agregar declaraciones '+ + 'y nunca se deben agregar implementaciones de códigos Delphi que contienen begin. ' + sLineBreak + + 'En sugerencias, nunca repita código que ya existe. '; end; + Result := Format(Result, [TConsts.TAG_CODE_COMPLETION]); Result := Result + sLineBreak; end; diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 0740f65..1f979b1 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -36,7 +36,10 @@ TUtils = class class procedure DriverIDFillItemsTStrings(AStrings: TStrings); class procedure DefaultsQuestionsKindFillItemsTStrings(AStrings: TStrings); class function AdjustQuestionToJson(const AValue: string): string; + class function InDebugMy: Boolean; class procedure AddLog(const AMessage: string); + class procedure AddLogDeleteFileFirst(const AMessage: string; const ANameFile: string); + class procedure AddLogInFileTxt(const AMessage: string; const ANameFile: string; ADeleteFileFirst: Boolean = False); class function GetFileName(const AExtension: string): string; class procedure MemoFocusOnTheEnd(const AMemo: TMemo); class function IfThenColor(const Conditional: Boolean; const AColorTrue, AColorFalse: TColor): TColor; @@ -210,11 +213,24 @@ class function TUtils.AdjustQuestionToJson(const AValue: string): string; Result := Result.Replace('\\"', '\"', [rfReplaceAll, rfIgnoreCase]); end; - +class function TUtils.InDebugMy: Boolean; +begin + Result := FileExists('C:\Temp\DelphiAIDev\DebugOn.c4d'); +end; class procedure TUtils.AddLog(const AMessage: string); +begin + Self.AddLogInFileTxt(AMessage, FormatDateTime('yyyy-mm-dd', Now)); +end; + +class procedure TUtils.AddLogDeleteFileFirst(const AMessage: string; const ANameFile: string); +begin + Self.AddLogInFileTxt(AMessage, ANameFile, True); +end; + +class procedure TUtils.AddLogInFileTxt(const AMessage: string; const ANameFile: string; ADeleteFileFirst: Boolean = False); const - DIRECTORY = 'C:\Temp\DelphiAIDev\'; + DIRECTORY = 'C:\Temp\DelphiAIDev\Logs\'; var LFileName: string; LTextFile: TextFile; @@ -223,7 +239,14 @@ class procedure TUtils.AddLog(const AMessage: string); if not(DirectoryExists(DIRECTORY)) then ForceDirectories(DIRECTORY); - LFileName := DIRECTORY + FormatDateTime('yyyy-mm-dd', Now) + '.txt'; + LFileName := DIRECTORY + ANameFile + '.txt'; + + if ADeleteFileFirst then + begin + if FileExists(LFileName)then + DeleteFile(LFileName); + end; + AssignFile(LTextFile, LFileName); if not FileExists(LFileName)then Rewrite(LTextFile); @@ -231,11 +254,12 @@ class procedure TUtils.AddLog(const AMessage: string); Writeln(LTextFile, Format('%s: %s', [DateTimeToStr(Now), AMessage])); CloseFile(LTextFile); except -// on E: Exception do -// ShowMsg('Unable to generate log. Message: ' + E.Message + sLineBreak + 'Filename: ' + LFileName); + //on E: Exception do + // ShowMsg('Unable to generate log. Message: ' + E.Message + sLineBreak + 'Filename: ' + LFileName); end; end; + class function TUtils.GetFileName(const AExtension: string): string; var LFileName: string; From 40a8ba2780ce53a9ca5fd1c24fc5e7fd666dcdd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 14:42:27 -0300 Subject: [PATCH 067/109] hotfix/chamada-tela-db-chat --- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 1 - Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index e0dc662..c7f76c2 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -17,7 +17,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView ShowHint = True OnActivate = FormActivate OnClose = FormClose - OnCreate = FormCreate OnResize = FormResize OnShow = FormShow DesignSize = ( diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index baa660c..5ae6040 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -134,7 +134,6 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure btnCleanAllClick(Sender: TObject); procedure btnExecuteSQLClick(Sender: TObject); procedure cBoxDatabasesClick(Sender: TObject); - procedure FormCreate(Sender: TObject); procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); procedure CopyCurrentColumn1Click(Sender: TObject); procedure CopyCurrentLine1Click(Sender: TObject); @@ -248,6 +247,7 @@ constructor TDelphiAIDevDBChatView.Create(AOwner: TComponent); Self.ConfScreenOnCreate; Self.FillMemoReturnWithFile; + TUtilsDBGrids.ConfDBGrid(DBGrid1); end; destructor TDelphiAIDevDBChatView.Destroy; @@ -281,11 +281,6 @@ procedure TDelphiAIDevDBChatView.FormActivate(Sender: TObject); end; end; -procedure TDelphiAIDevDBChatView.FormCreate(Sender: TObject); -begin - TUtilsDBGrids.ConfDBGrid(DBGrid1); -end; - procedure TDelphiAIDevDBChatView.FormClose(Sender: TObject; var Action: TCloseAction); begin Self.WaitingFormOFF; From f14c080354430eaad8ba3c1f6006b4d9deda9511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 15:01:36 -0300 Subject: [PATCH 068/109] bk/2024-09-16-1501 --- Src/AI/DelphiAIDev.AI.pas | 2 +- .../DelphiAIDev.IDE.NTAEditViewNotifier.pas | 23 ++++++++++++------- Src/Utils/DelphiAIDev.Utils.pas | 4 ++-- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Src/AI/DelphiAIDev.AI.pas b/Src/AI/DelphiAIDev.AI.pas index 5daa847..fc4f0db 100644 --- a/Src/AI/DelphiAIDev.AI.pas +++ b/Src/AI/DelphiAIDev.AI.pas @@ -56,7 +56,7 @@ procedure TDelphiAIDevAI.ProcessSend(const AQuestion: string); LQuestion := TUtils.AdjustQuestionToJson(AQuestion); FResponse.Clear; - if TUtils.InDebugMy then + if TUtils.DebugMyIsOn then TUtils.AddLogDeleteFileFirst(LQuestion, 'DelphiAIDevAI_ProcessSend'); case FAiUse of diff --git a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas index 5bbe40e..b80fd2e 100644 --- a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas +++ b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas @@ -96,11 +96,13 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.EditorIdle(const View: IOTAEditView begin TUtilsOTA.GetCursorPosition(LRow, LColumn); - if (LRow <> LVars.Row) or (LColumn <> LVars.Column) then - begin - LVars.LineIni := 0; - LVars.Clear; - end; + if LVars.LineIni > 0 then + if (LRow <> LVars.Row) or (LColumn <> LVars.Column) then + begin + LVars.LineIni := 0; + LVars.Clear; + TUtils.AddLog('EditorIdle'); + end; end; procedure TDelphiAIDevIDENTAEditViewNotifier.EndPaint(const View: IOTAEditView); @@ -130,10 +132,10 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; //if LineNumber <> View.CursorPos.Line then // Exit; - if (LineNumber >= LVars.LineIni)and(LineNumber <= LVars.LineEnd) then + if (LineNumber >= LVars.LineIni)and(LineNumber < LVars.LineEnd) then begin Canvas.Brush.Style := bsClear; - Canvas.Font.Color := $777777; //$666666; + Canvas.Font.Color := $777777; if TDelphiAIDevSettings.GetInstance.CodeCompletionSuggestionColorUse then Canvas.Font.Color := TDelphiAIDevSettings.GetInstance.CodeCompletionSuggestionColor; @@ -141,7 +143,12 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; LLineText := LVars.Contents[LineNumber - LVars.LineIni]; Canvas.TextOut(TextRect.Left, TextRect.Top, LLineText.TrimRight); except on E: Exception do - TUtils.AddLog(E.Message); + if TUtils.DebugMyIsOn then + TUtils.AddLog('Exception in TDelphiAIDevIDENTAEditViewNotifier.PaintLine: ' + sLineBreak + + 'LineNumber: ' + LineNumber.ToString + sLineBreak + + 'LineIni: ' + LVars.LineIni.ToString + sLineBreak + + 'LineEnd: ' + LVars.LineEnd.ToString + sLineBreak + + E.Message); end; end; end; diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 1f979b1..fa6455e 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -36,7 +36,7 @@ TUtils = class class procedure DriverIDFillItemsTStrings(AStrings: TStrings); class procedure DefaultsQuestionsKindFillItemsTStrings(AStrings: TStrings); class function AdjustQuestionToJson(const AValue: string): string; - class function InDebugMy: Boolean; + class function DebugMyIsOn: Boolean; class procedure AddLog(const AMessage: string); class procedure AddLogDeleteFileFirst(const AMessage: string; const ANameFile: string); class procedure AddLogInFileTxt(const AMessage: string; const ANameFile: string; ADeleteFileFirst: Boolean = False); @@ -213,7 +213,7 @@ class function TUtils.AdjustQuestionToJson(const AValue: string): string; Result := Result.Replace('\\"', '\"', [rfReplaceAll, rfIgnoreCase]); end; -class function TUtils.InDebugMy: Boolean; +class function TUtils.DebugMyIsOn: Boolean; begin Result := FileExists('C:\Temp\DelphiAIDev\DebugOn.c4d'); end; From f8fd7f579a1e4c8bb05216227aa5b55f313674b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 15:37:35 -0300 Subject: [PATCH 069/109] Update DelphiAIDev.CodeCompletion.KeyTab.pas --- Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas | 1 + 1 file changed, 1 insertion(+) diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas index f3d006c..9024396 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas @@ -45,6 +45,7 @@ procedure TDelphiAIDevCodeCompletionKeyTab.Process(const AContext: IOTAKeyContex for i := 0 to Pred(FVars.Contents.Count) do LText := LText + FVars.Contents[i].Trim + sLineBreak; + AContext.EditBuffer.EditPosition.Delete(FVars.Contents.Count); AContext.EditBuffer.EditPosition.InsertText(LText.Trim); //Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd, 20); From 1db586b2c21ea768c5deca0a36d9da84a98f888b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 16:52:18 -0300 Subject: [PATCH 070/109] bk/2024-09-16-1652 --- .../DelphiAIDev.CodeCompletion.KeyTab.pas | 4 ++- .../DelphiAIDev.CodeCompletion.Search.pas | 10 +++---- Src/Utils/DelphiAIDev.Utils.pas | 26 +++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas index 9024396..a1db150 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas @@ -45,7 +45,9 @@ procedure TDelphiAIDevCodeCompletionKeyTab.Process(const AContext: IOTAKeyContex for i := 0 to Pred(FVars.Contents.Count) do LText := LText + FVars.Contents[i].Trim + sLineBreak; - AContext.EditBuffer.EditPosition.Delete(FVars.Contents.Count); + if FVars.Contents.Count > 1 then + AContext.EditBuffer.EditPosition.Delete(Pred(FVars.Contents.Count)); + AContext.EditBuffer.EditPosition.InsertText(LText.Trim); //Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd, 20); diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index 114f809..778777d 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -62,7 +62,7 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex var LRow: Integer; LColumn: Integer; - LText: string; + LBlankTextLines: string; i: Integer; LIOTAEditPosition: IOTAEditPosition; begin @@ -101,11 +101,11 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex FVars.LineIni := LRow; FVars.LineEnd := FVars.LineIni + FVars.Contents.Count; - LText := ''; - for i := 0 to Pred(FVars.Contents.Count) do - LText := LText + sLineBreak; + LBlankTextLines := ''; + for i := 1 to Pred(FVars.Contents.Count) do + LBlankTextLines := LBlankTextLines + sLineBreak; - LIOTAEditPosition.InsertText(LText); //.TrimRight + sLineBreak); + LIOTAEditPosition.InsertText(LBlankTextLines); LIOTAEditPosition.Move(FVars.LineIni, LColumn); finally Screen.Cursor := crDefault; diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index fa6455e..81d7415 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -384,6 +384,10 @@ class function TUtils.CodeIdMarkBeginCode(const AValue: string): Boolean; end; class function TUtils.ConfReturnAI(const AValue: string): string; +var + LStrings: TStrings; + LStrLine: string; + i: Integer; begin Result := AValue.Trim .Replace(TConsts.MARK_BEGIN_DELPHI, '', [rfReplaceAll, rfIgnoreCase]) @@ -392,6 +396,28 @@ class function TUtils.ConfReturnAI(const AValue: string): string; .Replace(TConsts.MARK_BEGIN_SQL, '', [rfReplaceAll, rfIgnoreCase]) .Replace(TConsts.MARK_BEGIN_SQL2, '', [rfReplaceAll, rfIgnoreCase]) .Replace(TConsts.MARK_END, '', [rfReplaceAll, rfIgnoreCase]); + + LStrings := TStringList.Create; + try + LStrings.Text := Result; + + Result := ''; + for i := 0 to Pred(LStrings.Count) do + begin + LStrLine := LStrings[i]; + if (i = 0) and ((LStrLine.Trim.IsEmpty)or(LStrLine = sLineBreak)) then + Continue; + + //if (i = Pred(LStrings.Count)) and ((LStrLine.Trim.IsEmpty) or (LStrLine = sLineBreak)) then + // Continue; + + Result := Result + LStrLine + sLineBreak; + end; + + Result := Result.TrimRight; + finally + LStrings.Free; + end; end; class function TUtils.ProcessTextForEditor(const AText: string): string; From 30e210263f70b506e3d9ca52359648898c5266d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 17:21:52 -0300 Subject: [PATCH 071/109] bk/2024-09-16-1721 --- .../DelphiAIDev.CodeCompletion.KeyTab.pas | 11 +++++------ Src/Test/DelphiAIDev.Test.pas | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas index a1db150..bbf05b8 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas @@ -41,15 +41,14 @@ procedure TDelphiAIDevCodeCompletionKeyTab.Process(const AContext: IOTAKeyContex LText: string; i: Integer; begin - LText := ''; - for i := 0 to Pred(FVars.Contents.Count) do - LText := LText + FVars.Contents[i].Trim + sLineBreak; - if FVars.Contents.Count > 1 then AContext.EditBuffer.EditPosition.Delete(Pred(FVars.Contents.Count)); - AContext.EditBuffer.EditPosition.InsertText(LText.Trim); - //Context.EditBuffer.EditPosition.Move(TDelphiAIDevCodeCompletionVars.GetInstance.LineEnd, 20); + for i := 0 to Pred(FVars.Contents.Count) do + begin + AContext.EditBuffer.EditPosition.MoveEOL; + AContext.EditBuffer.EditPosition.InsertText(FVars.Contents[i] + sLineBreak); + end; FVars.GetInstance.Clear; end; diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 55203ea..ab356fc 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -25,6 +25,7 @@ TDelphiAIDevTest = class property Apelido: string read FApelido write FApelido; property Cep: Integer read FCep write FCep; procedure Clear; + end; implementation From df0c204c409521793e1e2a903e552595a6ce9d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 17:36:08 -0300 Subject: [PATCH 072/109] bk/2024-09-16-1736 --- .../DelphiAIDev.CodeCompletion.KeyTab.pas | 21 ++++++++++--------- Src/MainMenu/DelphiAIDev.MainMenu.pas | 16 ++++++++------ Src/Test/DelphiAIDev.Test.pas | 1 - Src/Utils/DelphiAIDev.Utils.pas | 3 --- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas index bbf05b8..b3a37f7 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas @@ -38,19 +38,20 @@ constructor TDelphiAIDevCodeCompletionKeyTab.Create; procedure TDelphiAIDevCodeCompletionKeyTab.Process(const AContext: IOTAKeyContext); var - LText: string; i: Integer; begin - if FVars.Contents.Count > 1 then - AContext.EditBuffer.EditPosition.Delete(Pred(FVars.Contents.Count)); - - for i := 0 to Pred(FVars.Contents.Count) do - begin - AContext.EditBuffer.EditPosition.MoveEOL; - AContext.EditBuffer.EditPosition.InsertText(FVars.Contents[i] + sLineBreak); + try + if FVars.Contents.Count > 1 then + AContext.EditBuffer.EditPosition.Delete(Pred(FVars.Contents.Count)); + + for i := 0 to Pred(FVars.Contents.Count) do + begin + AContext.EditBuffer.EditPosition.MoveEOL; + AContext.EditBuffer.EditPosition.InsertText(FVars.Contents[i] + sLineBreak); + end; + finally + FVars.Clear; end; - - FVars.GetInstance.Clear; end; end. diff --git a/Src/MainMenu/DelphiAIDev.MainMenu.pas b/Src/MainMenu/DelphiAIDev.MainMenu.pas index 631e702..2c25baf 100644 --- a/Src/MainMenu/DelphiAIDev.MainMenu.pas +++ b/Src/MainMenu/DelphiAIDev.MainMenu.pas @@ -57,13 +57,17 @@ destructor TDelphiAIDevIDEMainMenu.Destroy; end; procedure TDelphiAIDevIDEMainMenu.CreateMenus; +var + LImgList: TDelphiAIDevIDEImageListMain; begin + LImgList := TDelphiAIDevIDEImageListMain.GetInstance; + Self.CreateMenuDelphiAIDeveloperInIDEMenu; Self.CreateSubMenu(TConsts.MENU_IDE_CHAT_NAME, TConsts.MENU_IDE_CHAT_CAPTION, TDelphiAIDevIDEMainMenuClicks.ChatClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgIndexMessage, + LImgList.ImgIndexMessage, Self.GetShortCutStrChat); Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '10', '-', nil); @@ -71,32 +75,32 @@ procedure TDelphiAIDevIDEMainMenu.CreateMenus; Self.CreateSubMenu(TConsts.MENU_IDE_DEFAULTS_QUESTIONS_NAME, TConsts.MENU_IDE_DEFAULTS_QUESTIONS_CAPTION, TDelphiAIDevIDEMainMenuClicks.DefaultsQuestionsClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgQuestion); + LImgList.ImgQuestion); Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '20', '-', nil); Self.CreateSubMenu(TConsts.MENU_IDE_DEFAULTS_DATABASES_ADD_NAME, TConsts.MENU_IDE_DEFAULTS_DATABASES_ADD_Caption, TDelphiAIDevIDEMainMenuClicks.DatabasesAddClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgDatabaseAdd); + LImgList.ImgDatabaseAdd); Self.CreateSubMenu(TConsts.MENU_IDE_DEFAULTS_DATABASES_CHAT_NAME, TConsts.MENU_IDE_DEFAULTS_DATABASES_CHAT_CAPTION, TDelphiAIDevIDEMainMenuClicks.DatabasesChatClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgDatabaseExecute); + LImgList.ImgDatabaseExecute); Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '30', '-', nil); Self.CreateSubMenu(TConsts.MENU_IDE_SETTINGS_NAME, TConsts.MENU_IDE_SETTINGS_CAPTION, TDelphiAIDevIDEMainMenuClicks.SettingsClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgIndexGear); + LImgList.ImgIndexGear); Self.CreateSubMenu(TConsts.PREFIX_NAME_SEPARATOR + '40', '-', nil); Self.CreateSubMenu(TConsts.MENU_IDE_ABOUT_NAME, TConsts.MENU_IDE_ABOUT_CAPTION, TDelphiAIDevIDEMainMenuClicks.AboutClick, - TDelphiAIDevIDEImageListMain.GetInstance.ImgIndexC4D_Logo); + LImgList.ImgIndexC4D_Logo); end; procedure TDelphiAIDevIDEMainMenu.CreateMenuDelphiAIDeveloperInIDEMenu; diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index ab356fc..9e4e1f3 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -32,7 +32,6 @@ implementation procedure TDelphiAIDevTest.Clear; begin - end; end. diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 81d7415..0ae6ffc 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -408,9 +408,6 @@ class function TUtils.ConfReturnAI(const AValue: string): string; if (i = 0) and ((LStrLine.Trim.IsEmpty)or(LStrLine = sLineBreak)) then Continue; - //if (i = Pred(LStrings.Count)) and ((LStrLine.Trim.IsEmpty) or (LStrLine = sLineBreak)) then - // Continue; - Result := Result + LStrLine + sLineBreak; end; From 1393b3314af3c07384ba14f9c46d4981d9abb3f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 17:43:20 -0300 Subject: [PATCH 073/109] bk/2024-09-16-1743 --- .../DelphiAIDev.CodeCompletion.KeyTab.pas | 12 ++++++++++-- Src/Test/DelphiAIDev.Test.pas | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas index b3a37f7..1835795 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.KeyTab.pas @@ -39,6 +39,7 @@ constructor TDelphiAIDevCodeCompletionKeyTab.Create; procedure TDelphiAIDevCodeCompletionKeyTab.Process(const AContext: IOTAKeyContext); var i: Integer; + LTextLine: string; begin try if FVars.Contents.Count > 1 then @@ -46,8 +47,15 @@ procedure TDelphiAIDevCodeCompletionKeyTab.Process(const AContext: IOTAKeyContex for i := 0 to Pred(FVars.Contents.Count) do begin - AContext.EditBuffer.EditPosition.MoveEOL; - AContext.EditBuffer.EditPosition.InsertText(FVars.Contents[i] + sLineBreak); + LTextLine := FVars.Contents[i].Trim; + + if FVars.Contents.Count > 1 then + begin + AContext.EditBuffer.EditPosition.MoveEOL; + LTextLine := FVars.Contents[i]; + end; + + AContext.EditBuffer.EditPosition.InsertText(LTextLine + sLineBreak); end; finally FVars.Clear; diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 9e4e1f3..55203ea 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -25,13 +25,13 @@ TDelphiAIDevTest = class property Apelido: string read FApelido write FApelido; property Cep: Integer read FCep write FCep; procedure Clear; - end; implementation procedure TDelphiAIDevTest.Clear; begin + end; end. From 81c9cc69c2804439327f437dea281301209a6629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 22:37:38 -0300 Subject: [PATCH 074/109] bk/2024-09-16-2237 --- .../DelphiAIDev.CodeCompletion.Search.pas | 2 ++ .../DelphiAIDev.CodeCompletion.Vars.pas | 9 +++++- .../DelphiAIDev.IDE.NTAEditViewNotifier.pas | 30 +++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index 778777d..aca290f 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -91,6 +91,8 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex Abort; end; + //Pegar o nome da tab da unit aberta + FVars.Module := TUtilsOTA.GetCurrentModule; FVars.Contents.Text := TUtils.ConfReturnAI(FAI.Response.Text); LRow := LIOTAEditPosition.Row; diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Vars.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Vars.pas index 790c280..e4f13e6 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Vars.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Vars.pas @@ -4,11 +4,14 @@ interface uses System.SysUtils, - System.Classes; + System.Classes, + ToolsAPI; type TDelphiAIDevCodeCompletionVars = class private + FRelease: Boolean; + FModule: IOTAModule; FLineIni: Integer; FLineEnd: Integer; FRow: Integer; @@ -19,6 +22,8 @@ TDelphiAIDevCodeCompletionVars = class class function GetInstance: TDelphiAIDevCodeCompletionVars; destructor Destroy; override; procedure Clear; + property Release: Boolean read FRelease write FRelease; + property Module: IOTAModule read FModule write FModule; property LineIni: Integer read FLineIni write FLineIni; property LineEnd: Integer read FLineEnd write FLineEnd; property Row: Integer read FRow write FRow; @@ -53,6 +58,8 @@ destructor TDelphiAIDevCodeCompletionVars.Destroy; procedure TDelphiAIDevCodeCompletionVars.Clear; begin + FRelease := False; + FModule := nil; FLineIni := 0; FLineEnd := 0; FRow := 0; diff --git a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas index b80fd2e..866af9f 100644 --- a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas +++ b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas @@ -96,11 +96,13 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.EditorIdle(const View: IOTAEditView begin TUtilsOTA.GetCursorPosition(LRow, LColumn); - if LVars.LineIni > 0 then + //if LVars.LineIni > 0 then + if not LVars.Release then if (LRow <> LVars.Row) or (LColumn <> LVars.Column) then begin - LVars.LineIni := 0; - LVars.Clear; + //LVars.LineIni := 0; + //LVars.Clear; + LVars.Release := True; TUtils.AddLog('EditorIdle'); end; end; @@ -120,6 +122,8 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; const Canvas: TCanvas; const TextRect: TRect; const LineRect: TRect; const CellSize: TSize); var LLineText: string; + LColCurrent: Integer; + LLineCurrent: Integer; begin if LineNumber < 1 then Exit; @@ -132,6 +136,26 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; //if LineNumber <> View.CursorPos.Line then // Exit; + //verificar o nome da tab da unit aberta + if LVars.Release then + begin + LVars.Release := False; + + //** + LColCurrent := View.CursorPos.Col; + LLineCurrent := View.CursorPos.Line; + //** + try + View.Buffer.EditPosition.Move(LVars.LineIni, 2); + View.Buffer.EditPosition.Delete(Pred(LVars.Contents.Count)); + finally + LVars.Clear; + //** + View.Buffer.EditPosition.Move(LLineCurrent, LColCurrent); + //** + end; + end; + if (LineNumber >= LVars.LineIni)and(LineNumber < LVars.LineEnd) then begin Canvas.Brush.Style := bsClear; From c1a97c21d2043cd05b3348cde06eb1dfa8e8bef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 16 Sep 2024 23:50:22 -0300 Subject: [PATCH 075/109] bk/2024-09-16-2350 --- .../DelphiAIDev.CodeCompletion.Search.pas | 1 - .../DelphiAIDev.IDE.NTAEditViewNotifier.pas | 70 ++++++++++++++----- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index aca290f..9cefa1e 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -91,7 +91,6 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex Abort; end; - //Pegar o nome da tab da unit aberta FVars.Module := TUtilsOTA.GetCurrentModule; FVars.Contents.Text := TUtils.ConfReturnAI(FAI.Response.Text); diff --git a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas index 866af9f..9523598 100644 --- a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas +++ b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas @@ -51,6 +51,9 @@ TDelphiAIDevIDENTAEditViewNotifier = class(TInterfacedObject, IOTANotifier, IN procedure BeforeSave; procedure Modified; procedure Destroyed; + + //TDelphiAIDevIDENTAEditViewNotifier + procedure ClearLinesNotUsed; end; implementation @@ -96,8 +99,8 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.EditorIdle(const View: IOTAEditView begin TUtilsOTA.GetCursorPosition(LRow, LColumn); - //if LVars.LineIni > 0 then - if not LVars.Release then + if LVars.LineIni > 0 then + //if LVars.Release then if (LRow <> LVars.Row) or (LColumn <> LVars.Column) then begin //LVars.LineIni := 0; @@ -117,13 +120,38 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.Modified; end; +procedure TDelphiAIDevIDENTAEditViewNotifier.ClearLinesNotUsed; +var + LView: IOTAEditView; + LColCurrent: Integer; + LLineCurrent: Integer; +begin + LVars.Release := False; + + if LVars.Module = nil then + Exit; + + TUtils.AddLog(sLineBreak + LVars.Module.FileName + sLineBreak + TUtilsOTA.GetCurrentModule.FileName); + + //if LVars.Module.FileName <> TUtilsOTA.GetCurrentModule.FileName then + // Exit; + + LView := TUtilsOTA.GetIOTAEditView(LVars.Module); + LColCurrent := LView.CursorPos.Col; + LLineCurrent := LView.CursorPos.Line; + try + LView.Buffer.EditPosition.Move(LVars.LineIni, 2); + LView.Buffer.EditPosition.Delete(Pred(LVars.Contents.Count)); + finally + LView.Buffer.EditPosition.Move(LLineCurrent, LColCurrent); + end; +end; + procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; LineNumber: Integer; const LineText: PAnsiChar; const TextWidth: Word; const LineAttributes: TOTAAttributeArray; const Canvas: TCanvas; const TextRect: TRect; const LineRect: TRect; const CellSize: TSize); var LLineText: string; - LColCurrent: Integer; - LLineCurrent: Integer; begin if LineNumber < 1 then Exit; @@ -133,27 +161,35 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; if not LLineText.Trim.IsEmpty then Exit; - //if LineNumber <> View.CursorPos.Line then - // Exit; - //verificar o nome da tab da unit aberta + //if LineNumber <> View.CursorPos.Line then Exit; + if LVars.Release then begin + try + Self.ClearLinesNotUsed; + finally + LVars.Clear; + end; + + {TUtils.AddLog(sLineBreak + LVars.Module.FileName + sLineBreak + TUtilsOTA.GetCurrentModule.FileName); LVars.Release := False; - //** - LColCurrent := View.CursorPos.Col; - LLineCurrent := View.CursorPos.Line; - //** try - View.Buffer.EditPosition.Move(LVars.LineIni, 2); - View.Buffer.EditPosition.Delete(Pred(LVars.Contents.Count)); + if LVars.Module.FileName = TUtilsOTA.GetCurrentModule.FileName then + begin + LColCurrent := View.CursorPos.Col; + LLineCurrent := View.CursorPos.Line; + try + View.Buffer.EditPosition.Move(LVars.LineIni, 2); + View.Buffer.EditPosition.Delete(Pred(LVars.Contents.Count)); + finally + View.Buffer.EditPosition.Move(LLineCurrent, LColCurrent); + end; + end finally LVars.Clear; - //** - View.Buffer.EditPosition.Move(LLineCurrent, LColCurrent); - //** - end; + end;} end; if (LineNumber >= LVars.LineIni)and(LineNumber < LVars.LineEnd) then From db8d3a0140731672799d0a0f8b9931d44d5dafcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 17 Sep 2024 09:16:19 -0300 Subject: [PATCH 076/109] Update DelphiAIDev.IDE.NTAEditViewNotifier.pas --- .../DelphiAIDev.IDE.NTAEditViewNotifier.pas | 64 +++++++------------ 1 file changed, 22 insertions(+), 42 deletions(-) diff --git a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas index 9523598..133ca5a 100644 --- a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas +++ b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas @@ -97,17 +97,22 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.EditorIdle(const View: IOTAEditView LRow: Integer; LColumn: Integer; begin + if LVars.LineIni <= 0 then + Exit; + TUtilsOTA.GetCursorPosition(LRow, LColumn); - if LVars.LineIni > 0 then - //if LVars.Release then - if (LRow <> LVars.Row) or (LColumn <> LVars.Column) then - begin - //LVars.LineIni := 0; - //LVars.Clear; - LVars.Release := True; - TUtils.AddLog('EditorIdle'); + if (LRow <> LVars.Row) or (LColumn <> LVars.Column) then + begin + TUtils.AddLog('EditorIdle'); + + ////LVars.Release := True; + try + Self.ClearLinesNotUsed; + finally + LVars.Clear; end; + end; end; procedure TDelphiAIDevIDENTAEditViewNotifier.EndPaint(const View: IOTAEditView); @@ -126,16 +131,11 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.ClearLinesNotUsed; LColCurrent: Integer; LLineCurrent: Integer; begin - LVars.Release := False; + ////LVars.Release := False; if LVars.Module = nil then Exit; - TUtils.AddLog(sLineBreak + LVars.Module.FileName + sLineBreak + TUtilsOTA.GetCurrentModule.FileName); - - //if LVars.Module.FileName <> TUtilsOTA.GetCurrentModule.FileName then - // Exit; - LView := TUtilsOTA.GetIOTAEditView(LVars.Module); LColCurrent := LView.CursorPos.Col; LLineCurrent := LView.CursorPos.Line; @@ -161,36 +161,16 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; if not LLineText.Trim.IsEmpty then Exit; - //if LineNumber <> View.CursorPos.Line then Exit; - if LVars.Release then - begin - try - Self.ClearLinesNotUsed; - finally - LVars.Clear; - end; - - {TUtils.AddLog(sLineBreak + LVars.Module.FileName + sLineBreak + TUtilsOTA.GetCurrentModule.FileName); - LVars.Release := False; - - try - if LVars.Module.FileName = TUtilsOTA.GetCurrentModule.FileName then - begin - LColCurrent := View.CursorPos.Col; - LLineCurrent := View.CursorPos.Line; - try - View.Buffer.EditPosition.Move(LVars.LineIni, 2); - View.Buffer.EditPosition.Delete(Pred(LVars.Contents.Count)); - finally - View.Buffer.EditPosition.Move(LLineCurrent, LColCurrent); - end; - end - finally - LVars.Clear; - end;} - end; +// if LVars.Release then +// begin +// try +// Self.ClearLinesNotUsed; +// finally +// LVars.Clear; +// end; +// end; if (LineNumber >= LVars.LineIni)and(LineNumber < LVars.LineEnd) then begin From d34deeba9c25963611d2d6a1cda85b807a7c2c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 24 Sep 2024 22:19:25 -0300 Subject: [PATCH 077/109] bk/2024-09-24-2219 --- .../DelphiAIDev.IDE.NTAEditViewNotifier.pas | 5 +++++ Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas | 4 ++-- Src/Test/DelphiAIDev.Test.pas | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas index 133ca5a..2d328e1 100644 --- a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas +++ b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas @@ -136,6 +136,11 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.ClearLinesNotUsed; if LVars.Module = nil then Exit; + //** + if LVars.Contents.Count <= 1 then + Exit; + //** + LView := TUtilsOTA.GetIOTAEditView(LVars.Module); LColCurrent := LView.CursorPos.Col; LLineCurrent := LView.CursorPos.Line; diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index f1d7d80..3a6bf03 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -107,7 +107,7 @@ procedure TDelphiAIDevKeyboardBinding.CodeCompletionSearch(const Context: IOTAKe TDelphiAIDevCodeCompletionSearch.New.Process(Context); finally //BindingResult := TKeyBindingResult.krUnhandled; - BindingResult := TKeyBindingResult.krHandled; + BindingResult := TKeyBindingResult.krNextProc; //krHandled; end; end; @@ -121,7 +121,7 @@ procedure TDelphiAIDevKeyboardBinding.KeyTab(const Context: IOTAKeyContext; KeyC if TDelphiAIDevCodeCompletionVars.GetInstance.LineIni > 0 then begin TDelphiAIDevCodeCompletionKeyTab.New.Process(Context); - BindingResult := TKeyBindingResult.krHandled; + BindingResult := TKeyBindingResult.krNextProc; //krHandled; end; end; diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 55203ea..6183b20 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -25,7 +25,8 @@ TDelphiAIDevTest = class property Apelido: string read FApelido write FApelido; property Cep: Integer read FCep write FCep; procedure Clear; - end; + + end; implementation From 1f940ca8c451c6abd2a102a972598fa7718fa33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 24 Sep 2024 22:51:32 -0300 Subject: [PATCH 078/109] bk/2024-09-24-2251 --- .../DelphiAIDev.IDE.NTAEditViewNotifier.pas | 59 +++++++++---------- .../DelphiAIDev.KeyboardBinding.pas | 2 +- Src/Test/DelphiAIDev.Test.pas | 1 - 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas index 2d328e1..82bbc5d 100644 --- a/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas +++ b/Src/IDE/NTAEditViewNotifier/DelphiAIDev.IDE.NTAEditViewNotifier.pas @@ -87,6 +87,32 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.BeforeSave; end; +procedure TDelphiAIDevIDENTAEditViewNotifier.ClearLinesNotUsed; +var + LView: IOTAEditView; + LColCurrent: Integer; + LLineCurrent: Integer; +begin + ////LVars.Release := False; + if LVars.Module = nil then + Exit; + + //** + if LVars.Contents.Count <= 1 then + Exit; + //** + + LView := TUtilsOTA.GetIOTAEditView(LVars.Module); + LColCurrent := LView.CursorPos.Col; + LLineCurrent := LView.CursorPos.Line; + try + LView.Buffer.EditPosition.Move(LVars.LineIni, 2); + LView.Buffer.EditPosition.Delete(Pred(LVars.Contents.Count)); + finally + LView.Buffer.EditPosition.Move(LLineCurrent, LColCurrent); + end; +end; + procedure TDelphiAIDevIDENTAEditViewNotifier.BeginPaint(const View: IOTAEditView; var FullRepaint: Boolean); begin FullRepaint := True; @@ -125,33 +151,6 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.Modified; end; -procedure TDelphiAIDevIDENTAEditViewNotifier.ClearLinesNotUsed; -var - LView: IOTAEditView; - LColCurrent: Integer; - LLineCurrent: Integer; -begin - ////LVars.Release := False; - - if LVars.Module = nil then - Exit; - - //** - if LVars.Contents.Count <= 1 then - Exit; - //** - - LView := TUtilsOTA.GetIOTAEditView(LVars.Module); - LColCurrent := LView.CursorPos.Col; - LLineCurrent := LView.CursorPos.Line; - try - LView.Buffer.EditPosition.Move(LVars.LineIni, 2); - LView.Buffer.EditPosition.Delete(Pred(LVars.Contents.Count)); - finally - LView.Buffer.EditPosition.Move(LLineCurrent, LColCurrent); - end; -end; - procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; LineNumber: Integer; const LineText: PAnsiChar; const TextWidth: Word; const LineAttributes: TOTAAttributeArray; const Canvas: TCanvas; const TextRect: TRect; const LineRect: TRect; const CellSize: TSize); @@ -163,8 +162,8 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; LLineText := string(LineText); - if not LLineText.Trim.IsEmpty then - Exit; + //AQUI VERIFICA SE A LINHA NAO FOR VAZIA NAO ADICIONA O TEXTO DA SUGESTAO + //if not LLineText.Trim.IsEmpty then Exit; //if LineNumber <> View.CursorPos.Line then Exit; @@ -177,7 +176,7 @@ procedure TDelphiAIDevIDENTAEditViewNotifier.PaintLine(const View: IOTAEditView; // end; // end; - if (LineNumber >= LVars.LineIni)and(LineNumber < LVars.LineEnd) then + if (LineNumber >= LVars.LineIni) and (LineNumber < LVars.LineEnd) then begin Canvas.Brush.Style := bsClear; Canvas.Font.Color := $777777; diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 3a6bf03..9de2c8e 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -91,7 +91,7 @@ procedure TDelphiAIDevKeyboardBinding.BindKeyboard(const BindingServices: IOTAKe // Exit; LShortcut := TConsts.CODE_COMPLETION_SHORTCUT_INVOKE; - if not(Trim(TDelphiAIDevSettings.GetInstance.CodeCompletionShortcutInvoke).IsEmpty) then + if not Trim(TDelphiAIDevSettings.GetInstance.CodeCompletionShortcutInvoke).IsEmpty then LShortcut := TDelphiAIDevSettings.GetInstance.CodeCompletionShortcutInvoke; BindingServices.AddKeyBinding([TextToShortCut(LShortcut)], Self.CodeCompletionSearch, nil); diff --git a/Src/Test/DelphiAIDev.Test.pas b/Src/Test/DelphiAIDev.Test.pas index 6183b20..16205ab 100644 --- a/Src/Test/DelphiAIDev.Test.pas +++ b/Src/Test/DelphiAIDev.Test.pas @@ -25,7 +25,6 @@ TDelphiAIDevTest = class property Apelido: string read FApelido write FApelido; property Cep: Integer read FCep write FCep; procedure Clear; - end; implementation From d502842603841060df6bd7f6b941fe2ec79405a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Wed, 2 Oct 2024 09:28:35 -0300 Subject: [PATCH 079/109] feature/clear-lines-emptys --- .../DelphiAIDev.KeyboardBinding.pas | 17 +++++++++++ Src/Test/DelphiAIDev.Test.Client.pas | 29 +++++++++++-------- Src/Utils/DelphiAIDev.Utils.pas | 2 +- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas index 9de2c8e..ffa28da 100644 --- a/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas +++ b/Src/KeyboardBinding/DelphiAIDev.KeyboardBinding.pas @@ -21,6 +21,7 @@ TDelphiAIDevKeyboardBinding = class(TNotifierObject, IOTAKeyboardBinding) procedure KeyAltHome(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); procedure KeyTab(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); procedure CodeCompletionSearch(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); + //procedure HandleKeyBinding(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); protected function GetBindingType: TBindingType; function GetDisplayName: string; @@ -98,8 +99,24 @@ procedure TDelphiAIDevKeyboardBinding.BindKeyboard(const BindingServices: IOTAKe BindingServices.AddKeyBinding([Shortcut(VK_TAB, [])], Self.KeyTab, nil); BindingServices.AddKeyBinding([Shortcut(VK_HOME, [ssAlt])], Self.KeyAltHome, nil); + +// //** +// BindingServices.AddKeyBinding([], HandleKeyBinding, nil); +// //** end; +////** +//procedure TDelphiAIDevKeyboardBinding.HandleKeyBinding(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); +//var +// Key: Word; +//begin +// //Key := Word(KeyCode and $FF); // Extrai o código da tecla +// //TUtils.AddLog('Tecla pressionada: ' + IntToStr(Key)); +// TUtils.ShowMsg('Aqui'); +// BindingResult := TKeyBindingResult.krNextProc +//end; +////** + procedure TDelphiAIDevKeyboardBinding.CodeCompletionSearch(const Context: IOTAKeyContext; KeyCode: TShortcut; var BindingResult: TKeyBindingResult); begin try diff --git a/Src/Test/DelphiAIDev.Test.Client.pas b/Src/Test/DelphiAIDev.Test.Client.pas index 301fcb5..5c67f6a 100644 --- a/Src/Test/DelphiAIDev.Test.Client.pas +++ b/Src/Test/DelphiAIDev.Test.Client.pas @@ -6,29 +6,34 @@ interface TDelphiAIDevTestClient = class private FNome: string; + FCPF: string; FEndereco: string; - FBairro: string; - FNumero: Integer; - FTelefone: string; + FIdade: Integer; public + constructor Create(ANome: string; ACpf: string; AEndereco: string); property Nome: string read FNome write FNome; + property CPF: string read FCPF write FCPF; property Endereco: string read FEndereco write FEndereco; - property Bairro: string read FBairro write FBairro; - property Numero: Integer read FNumero write FNumero; - property Telefone: string read FTelefone write FTelefone; - - procedure Clear; + property Idade: Integer read FIdade write FIdade; + procedure LimparVariaveis; end; implementation -procedure TDelphiAIDevTestClient.Clear; + +{ TDelphiAIDevTestClient } + +constructor TDelphiAIDevTestClient.Create(ANome, ACpf, AEndereco: string); +begin + +end; + +procedure TDelphiAIDevTestClient.LimparVariaveis; begin FNome := ''; + FCPF := ''; FEndereco := ''; - FBairro := ''; - FNumero := 0; - FTelefone := ''; + FIdade := 0; end; end. diff --git a/Src/Utils/DelphiAIDev.Utils.pas b/Src/Utils/DelphiAIDev.Utils.pas index 0ae6ffc..dfcf513 100644 --- a/Src/Utils/DelphiAIDev.Utils.pas +++ b/Src/Utils/DelphiAIDev.Utils.pas @@ -236,7 +236,7 @@ class procedure TUtils.AddLogInFileTxt(const AMessage: string; const ANameFile: LTextFile: TextFile; begin try - if not(DirectoryExists(DIRECTORY)) then + if not DirectoryExists(DIRECTORY) then ForceDirectories(DIRECTORY); LFileName := DIRECTORY + ANameFile + '.txt'; From 74b9794b5387731494f64f954ea871c2cd4b887e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Wed, 2 Oct 2024 10:59:28 -0300 Subject: [PATCH 080/109] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index c98fb58..4c14694 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,19 @@ Receive suggestions for creating and improving code directly in the IDE and take ![image](https://github.com/Code4Delphi/Delphi-AI-Developer/assets/33873267/1c0ae468-ec44-4095-b299-65e873e79741) +
+ +# PLUGIN SETTINGS +- Access the menu “AI Developer†> “Settings†> Tab “Preferences†+![image](https://github.com/user-attachments/assets/c89d1145-4178-45ec-bd45-ecb13dfc37cc) + +1. **Language used in questions:** Indicate in which language you will ask questions in chats, so that the prompts generated by the Plugin are generated in the same language. +2. **AI default (Chat and Databases Chat):** Default AI when starting the IDE. +3. **Color to highlight Delphi/Pascal code:** Color to highlight Delphi/Pascal/SQL code in responses displayed on chat screens +4. **Default Prompt:** The Default Prompts that were added in this field will be sent to the AIs, with this you can considerably improve the quality of the responses. (Example of prompt: Always return SQL commands in lowercase) + + +
## â–¶ï¸ Demo Video From 9fcafcd023c08ec5c39b0f342978d3adb56ecebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:00:00 -0300 Subject: [PATCH 081/109] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c14694..675025d 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Receive suggestions for creating and improving code directly in the IDE and take
-# PLUGIN SETTINGS +## PLUGIN SETTINGS - Access the menu “AI Developer†> “Settings†> Tab “Preferences†![image](https://github.com/user-attachments/assets/c89d1145-4178-45ec-bd45-ecb13dfc37cc) From 14339fd7eb4a4995748b479f087de21eb85d7632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:14:38 -0300 Subject: [PATCH 082/109] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 675025d..5d4b980 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,16 @@ Receive suggestions for creating and improving code directly in the IDE and take 4. **Default Prompt:** The Default Prompts that were added in this field will be sent to the AIs, with this you can considerably improve the quality of the responses. (Example of prompt: Always return SQL commands in lowercase) +
+ +## CONFIGURING IAS ONLINE +You can choose between 3 APIs, Gemini (Google), ChatGPT (OpenAI) and Groq. Gemini and Groq APIs are free. +- Access the menu “AI Developer†> “Settings†> Tab “IAs on-line†+![image](https://github.com/user-attachments/assets/2c3a45a2-94c8-4449-8c71-58246f6ca67f) + +1. Inform the desired model. +2. Click on the **"Generate API Key"** link to generate your key. +3. In this field you must enter the API access key.
From 82bb4002536dc3f685a55a1c7d49fe5bdcbd7eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:48:53 -0300 Subject: [PATCH 083/109] Update README.md --- README.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d4b980..6b1c2c4 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Receive suggestions for creating and improving code directly in the IDE and take ## CONFIGURING IAS ONLINE You can choose between 3 APIs, Gemini (Google), ChatGPT (OpenAI) and Groq. Gemini and Groq APIs are free. -- Access the menu “AI Developer†> “Settings†> Tab “IAs on-line†+Access the menu “AI Developer†> “Settings†> Tab “IAs on-line†![image](https://github.com/user-attachments/assets/2c3a45a2-94c8-4449-8c71-58246f6ca67f) 1. Inform the desired model. @@ -74,6 +74,26 @@ You can choose between 3 APIs, Gemini (Google), ChatGPT (OpenAI) and Groq. Gemin
+## AI Chat interacting with Delphi IDE +Access the menu “AI Developer†> “Chat†or Ctrl+Shift+Alt+A +![image](https://github.com/user-attachments/assets/a8e58367-36c3-481f-8583-98d19cee68af) + +1. Select the desired AI to be used in the chat +2. Field where the question/prompt should be added +3. Field where the AI ​​response will be displayed +4. Access the menu with pre-registered questions (to register, access the menu: “AI Developer†> “Defaults Questionsâ€) +5. By checking this option, the AI ​​will only return codes, without inserting comments or explanations. +6. By checking the "Use current unit code in query" option, the source code of the current unit will be used as a reference for the prompt sent to the AIs. +Note: If the current unit has any code selected, only the selected code snippet will be used as a reference, otherwise the entire unit code will be used. +7. Button that makes the request to the AIs +8. **Insert Selected Text at Cursor**: Inserts the selected text into the response, field in the IDE code editor (if there is no selection, use the entire response) +9. Create new unit with selected code (if there is no selection, use the entire response) +10. Copy Selected Text (if there is no selection, use the entire response) +11. Clean all and start a new chat +12. Opens a menu with additional options + +
+ ## â–¶ï¸ Demo Video We have also created a video with details on how to download, install and use the plugin. The video is in Portuguese (ptBR), but we are providing subtitles and possibly a video in English. * [https://www.youtube.com/watch?v=2NAlUFK2FGs](https://www.youtube.com/watch?v=2NAlUFK2FGs) From 33b9a7330d6eb323a4744e1b3f46370a9fed61ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Wed, 2 Oct 2024 12:17:29 -0300 Subject: [PATCH 084/109] Update README.md --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 6b1c2c4..b8badfa 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,43 @@ Note: If the current unit has any code selected, only the selected code snippet
+## Chat for database interaction +- To register Databases, access the menu “AI Developer†> “Databases Registers†+![image](https://github.com/user-attachments/assets/aacd2440-898a-4e7d-96fd-8dfa94c09c76) + +- **Generate reference with database** +- Note: This process must always be performed whenever a new field or table is added to the database. +![image](https://github.com/user-attachments/assets/8649509e-189b-46d2-bc0d-378ead1e8929) + +- Optional Step: Link Default Database to Project or Project Group +![image](https://github.com/user-attachments/assets/92812a6f-fdd6-45e0-b60c-b26669f166dc) + +- Chat for database + +![image](https://github.com/user-attachments/assets/f3aeb00e-cdcb-491d-b360-5c625c5c8f2f) + + +1. Select the desired database +2. Quick access to the reference generation screen for the selected database +3. Select the desired AI to be used in the chat +4. Field where the question/prompt should be added +5. Button that makes the request to the AIs +6. Field where the AI ​​response will be displayed +7. Button to execute the SQL command of the field with the response (field 6) +8. Grid with the response from the execution of the SQl command +9. Options for copying or exporting Grid data +10. Access the menu with pre-registered questions (to register, access the menu: “AI Developer†> “Defaults Questionsâ€) +11. By checking this option, the AI ​​will only return SQL commands, without inserting comments or explanations. +12. By checking the "Use current unit code in query" option, the source code of the current unit will be used as a reference for the prompt sent to the AIs. +Note: If the current unit has any code selected, only the selected code snippet will be used as a reference, otherwise the entire unit code will be used. +13. **Insert Selected Text at Cursor**: Inserts the selected text into the response, field in the IDE code editor (if there is no selection, use the entire response) +14. Create new unit with selected code (if there is no selection, use the entire response) +15. Copy Selected Text (if there is no selection, use the entire response) +16. Clean all and start a new chat +17. Opens a menu with additional options + +
+ ## â–¶ï¸ Demo Video We have also created a video with details on how to download, install and use the plugin. The video is in Portuguese (ptBR), but we are providing subtitles and possibly a video in English. * [https://www.youtube.com/watch?v=2NAlUFK2FGs](https://www.youtube.com/watch?v=2NAlUFK2FGs) From ee4cfca82a3175e1b7c451b82532f85ee4a6fa23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Thu, 3 Oct 2024 00:55:20 -0300 Subject: [PATCH 085/109] Update README.md --- README.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b8badfa..f03786c 100644 --- a/README.md +++ b/README.md @@ -52,19 +52,20 @@ Receive suggestions for creating and improving code directly in the IDE and take
## PLUGIN SETTINGS -- Access the menu “AI Developer†> “Settings†> Tab “Preferences†+Access the menu “AI Developer†> “Settings†> Tab “Preferences†![image](https://github.com/user-attachments/assets/c89d1145-4178-45ec-bd45-ecb13dfc37cc) 1. **Language used in questions:** Indicate in which language you will ask questions in chats, so that the prompts generated by the Plugin are generated in the same language. 2. **AI default (Chat and Databases Chat):** Default AI when starting the IDE. 3. **Color to highlight Delphi/Pascal code:** Color to highlight Delphi/Pascal/SQL code in responses displayed on chat screens -4. **Default Prompt:** The Default Prompts that were added in this field will be sent to the AIs, with this you can considerably improve the quality of the responses. (Example of prompt: Always return SQL commands in lowercase) +4. **Default Prompts:** Prompts added in this field will be sent to the AIs along with the requests. This can significantly improve the quality of the responses. (Example prompt: Always return SQL commands in lowercase letters)
## CONFIGURING IAS ONLINE You can choose between 3 APIs, Gemini (Google), ChatGPT (OpenAI) and Groq. Gemini and Groq APIs are free. + Access the menu “AI Developer†> “Settings†> Tab “IAs on-line†![image](https://github.com/user-attachments/assets/2c3a45a2-94c8-4449-8c71-58246f6ca67f) @@ -72,6 +73,25 @@ Access the menu “AI Developer†> “Settings†> Tab “IAs on-line†2. Click on the **"Generate API Key"** link to generate your key. 3. In this field you must enter the API access key. +
+ +## CODE COMPLETION + +To configure, access the menu “AI Developer†> “Settings†> Tab “Code Completion†+ +![image](https://github.com/user-attachments/assets/fd26a49c-5969-4bbe-8a2e-32e9623bf1d7) + +1. Enables/disables use of Code Completion +2. **AI default:** Default AI that will be used by Code Completion +3. **Suggestion Code Color**: Color code suggested by plugin before being accepted +4. Shortcut to invoke Code Completion usage (requires restart of Delphi IDE) +5. **Default Prompts:** Prompts added in this field will be sent to the AIs along with the requests. This can significantly improve the quality of the responses. (Example prompt: Always return SQL commands in lowercase letters) + +- To use it, simply use the configured shortcut keys (default Alt+Enter) +- To **accept** the suggestion, simply use the Tab key. +![delphi-ai-developer-previa-02](https://github.com/user-attachments/assets/f09fe06a-4471-43e7-b99e-1ac701dad211) + +
## AI Chat interacting with Delphi IDE From c1784a5b97020df4f35cd2ae4d4c2d0c31873a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Thu, 3 Oct 2024 01:02:59 -0300 Subject: [PATCH 086/109] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f03786c..1312879 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Receive suggestions for creating and improving code directly in the IDE and take

-## âš™ï¸ Installation +## 🚀 Installation 1 - Download Delphi AI Developer. You can download the .zip file or clone the project on your PC. ![image](https://github.com/Code4Delphi/Delphi-AI-Developer/assets/33873267/a32c9333-6d5a-4036-9891-b97778bca90a) @@ -51,7 +51,7 @@ Receive suggestions for creating and improving code directly in the IDE and take
-## PLUGIN SETTINGS +## âš™ï¸ PLUGIN SETTINGS Access the menu “AI Developer†> “Settings†> Tab “Preferences†![image](https://github.com/user-attachments/assets/c89d1145-4178-45ec-bd45-ecb13dfc37cc) @@ -63,7 +63,7 @@ Access the menu “AI Developer†> “Settings†> Tab “Preferencesâ€
-## CONFIGURING IAS ONLINE +## âš« CONFIGURING IAS ONLINE You can choose between 3 APIs, Gemini (Google), ChatGPT (OpenAI) and Groq. Gemini and Groq APIs are free. Access the menu “AI Developer†> “Settings†> Tab “IAs on-line†@@ -75,7 +75,7 @@ Access the menu “AI Developer†> “Settings†> Tab “IAs on-lineâ€
-## CODE COMPLETION +## 🟠 CODE COMPLETION To configure, access the menu “AI Developer†> “Settings†> Tab “Code Completion†@@ -94,7 +94,7 @@ To configure, access the menu “AI Developer†> “Settings†> Tab “Code
-## AI Chat interacting with Delphi IDE +## 🔵 AI Chat interacting with Delphi IDE Access the menu “AI Developer†> “Chat†or Ctrl+Shift+Alt+A ![image](https://github.com/user-attachments/assets/a8e58367-36c3-481f-8583-98d19cee68af) @@ -114,7 +114,7 @@ Note: If the current unit has any code selected, only the selected code snippet
-## Chat for database interaction +## 🟣 Chat for database interaction - To register Databases, access the menu “AI Developer†> “Databases Registers†![image](https://github.com/user-attachments/assets/aacd2440-898a-4e7d-96fd-8dfa94c09c76) From 84b5b9ee23783343b620dea1779e159639aef097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Thu, 3 Oct 2024 01:05:34 -0300 Subject: [PATCH 087/109] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1312879..c8d8163 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ With Delphi AI Developer, you will have assistance in generating and refactoring Receive suggestions for creating and improving code directly in the IDE and take advantage of the possibility of creating predefined questions to speed up your searches. -# 📞 Contacts +## 📞 Contacts

@@ -29,7 +29,7 @@ Receive suggestions for creating and improving code directly in the IDE and take

-## 🚀 Installation +## 🚀 INSTALLATION 1 - Download Delphi AI Developer. You can download the .zip file or clone the project on your PC. ![image](https://github.com/Code4Delphi/Delphi-AI-Developer/assets/33873267/a32c9333-6d5a-4036-9891-b97778bca90a) @@ -94,7 +94,7 @@ To configure, access the menu “AI Developer†> “Settings†> Tab “Code
-## 🔵 AI Chat interacting with Delphi IDE +## 🔵 AI CHAT INTERACTING WITH DELPHI IDE Access the menu “AI Developer†> “Chat†or Ctrl+Shift+Alt+A ![image](https://github.com/user-attachments/assets/a8e58367-36c3-481f-8583-98d19cee68af) @@ -114,7 +114,7 @@ Note: If the current unit has any code selected, only the selected code snippet
-## 🟣 Chat for database interaction +## 🟣 CHAT FOR DATABASE INTERACTION - To register Databases, access the menu “AI Developer†> “Databases Registers†![image](https://github.com/user-attachments/assets/aacd2440-898a-4e7d-96fd-8dfa94c09c76) @@ -151,7 +151,7 @@ Note: If the current unit has any code selected, only the selected code snippet
-## â–¶ï¸ Demo Video +## â–¶ï¸ DEMO VIDEO We have also created a video with details on how to download, install and use the plugin. The video is in Portuguese (ptBR), but we are providing subtitles and possibly a video in English. * [https://www.youtube.com/watch?v=2NAlUFK2FGs](https://www.youtube.com/watch?v=2NAlUFK2FGs) From 0774dda83614192e218688496380f78f3917fb1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Thu, 3 Oct 2024 01:18:20 -0300 Subject: [PATCH 088/109] Update README.md --- README.md | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c8d8163..515b297 100644 --- a/README.md +++ b/README.md @@ -157,19 +157,11 @@ We have also created a video with details on how to download, install and use th
-## 📄 Documentation under construction -**We will soon publish the complete documentation for the Plugin.** +## 💬 CONTRIBUTIONS / IDEAS / BUG FIXES +Any suggestions or help are welcome. Send us a pull request or open an [issue](/../../issues/). -# 💬 Contributions / Ideas / Bug Fixes -To submit a pull request, follow these steps: - -1. Fork the project -2. Create a new branch (`git checkout -b minha-nova-funcionalidade`) -3. Make your changes -4. Make the commit (`git commit -am 'Functionality or adjustment message'`) -5. Push the branch (`git push origin Message about functionality or adjustment`) -6. Open a pull request +
+## âš ï¸ LICENSE +`Delphi AI Developer` is free and open-source wizard licensed under the [MIT License](LICENSE). -## âš ï¸ License -`Delphi AI Developer` is free and open-source wizard licensed under the [MIT License](https://github.com/Code4Delphi/Delphi-AI-Developer/blob/master/LICENSE). From 0e4c5ab856a6ab50af042019d8a900e902d7016f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Thu, 3 Oct 2024 01:58:44 -0300 Subject: [PATCH 089/109] Update README.md --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 515b297..75857a7 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Access the menu “AI Developer†> “Settings†> Tab “Preferencesâ€
-## ⚫ CONFIGURING IAS ONLINE +## ⚪ CONFIGURING IAS ONLINE You can choose between 3 APIs, Gemini (Google), ChatGPT (OpenAI) and Groq. Gemini and Groq APIs are free. Access the menu “AI Developer†> “Settings†> Tab “IAs on-line†@@ -149,6 +149,20 @@ Note: If the current unit has any code selected, only the selected code snippet 16. Clean all and start a new chat 17. Opens a menu with additional options +
+ +## 🟤 IAS OFF-LINE + +To use AI offline, follow these steps: +1. Install Ollama, which can be found at the following link: [https://ollama.com/download](https://ollama.com/download) +2. Choose the desired model. This can be done at the following link: [https://ollama.com/library](https://ollama.com/library) +![image](https://github.com/user-attachments/assets/1c259158-8118-421e-84ab-f6931b1438c0) +3. Open command prompt or terminal and run the command “ollama run †and wait for the installation to finish +![image](https://github.com/user-attachments/assets/b5c12854-5ce4-4fe7-aa49-b0396f0d4040) +4. **To configure**, access the menu “AI Developer†> “Settings†> Tab “IAs off-Line“ +![image](https://github.com/user-attachments/assets/f821ab05-743a-480f-a72b-f7ca3809ae6b) + +
## â–¶ï¸ DEMO VIDEO From 9a7c4611b775b00a68b1613812b2c3414012245e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 3 Oct 2024 03:01:52 -0300 Subject: [PATCH 090/109] fit/color-pnWaitCaption --- Src/Chat/DelphiAIDev.Chat.View.pas | 4 ++++ Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index b5a5526..52c53e9 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -241,6 +241,10 @@ procedure TDelphiAIDevChatView.ConfScreenOnCreate; ShapeCommands.Top := 0; ShapeCommands.Width := ShapeCommands.Parent.Width; ShapeCommands.Height := ShapeCommands.Parent.Height; + + {$IF CompilerVersion >= 34} //Sydney + pnWaitCaption.StyleElements := pnWaitCaption.StyleElements - [seFont]; + {$ENDIF} end; procedure TDelphiAIDevChatView.ConfScreenOnShow; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 5ae6040..61c4e36 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -305,6 +305,10 @@ procedure TDelphiAIDevDBChatView.ConfScreenOnCreate; ShapeCommands.Top := 0; ShapeCommands.Width := ShapeCommands.Parent.Width; ShapeCommands.Height := ShapeCommands.Parent.Height; + + {$IF CompilerVersion >= 34} //Sydney + pnWaitCaption.StyleElements := pnWaitCaption.StyleElements - [seFont]; + {$ENDIF} end; procedure TDelphiAIDevDBChatView.ConfScreenOnShow; From 088cb4ddba79d62bf2c855e80c52d61dbc5ecd92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 3 Oct 2024 03:37:42 -0300 Subject: [PATCH 091/109] fits/db-chat --- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 61c4e36..31a6bb2 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -176,6 +176,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) function GetFieldDBSelected: TDelphiAIDevDBRegistersFields; function GetJsonDatabase: string; procedure HandleErrorExecutingSQLCommand(const E: Exception); + procedure ValidateIfDatabaseSelected; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -671,7 +672,7 @@ procedure TDelphiAIDevDBChatView.FillDateLastReferences; begin lbLastGeneration.Caption := ''; - if cBoxDatabases.Items.Count < 0 then + if cBoxDatabases.Items.Count <= 0 then Exit; lbLastGeneration.Caption := TUtils.DateTimeToStrEmpty(Self.GetFieldDBSelected.LastReferences); @@ -682,8 +683,7 @@ procedure TDelphiAIDevDBChatView.btnGenerateDatabaseReferenceClick(Sender: TObje LView: TDelphiAIDevDBReferencesView; LFields: TDelphiAIDevDBRegistersFields; begin - if cBoxDatabases.Items.Count < 0 then - Exit; + Self.ValidateIfDatabaseSelected; LFields := Self.GetFieldDBSelected; if LFields = nil then @@ -699,9 +699,15 @@ procedure TDelphiAIDevDBChatView.btnGenerateDatabaseReferenceClick(Sender: TObje end; end; +procedure TDelphiAIDevDBChatView.ValidateIfDatabaseSelected; +begin + if cBoxDatabases.Items.Count <= 0 then + TUtils.ShowMsgAndAbort('Please select a database to continue', cBoxDatabases); +end; function TDelphiAIDevDBChatView.GetFieldDBSelected: TDelphiAIDevDBRegistersFields; begin + Self.ValidateIfDatabaseSelected; Result := TDelphiAIDevDBRegistersFields(cBoxDatabases.Items.Objects[cBoxDatabases.ItemIndex]); end; @@ -721,7 +727,6 @@ procedure TDelphiAIDevDBChatView.ProcessSend; FSettings.ValidateFillingSelectedAI; mmReturn.Lines.Clear; - Self.WaitingFormON; LQuestion := FSettings.LanguageQuestions.GetLanguageDefinition; @@ -738,6 +743,7 @@ procedure TDelphiAIDevDBChatView.ProcessSend; LQuestion := LQuestion + FSettings.DefaultPrompt + sLineBreak; LQuestion := LQuestion + mmQuestion.Lines.Text; + Self.WaitingFormON; LTask := TTask.Create( procedure begin @@ -802,6 +808,8 @@ procedure TDelphiAIDevDBChatView.btnExecuteSQLClick(Sender: TObject); LCommand: string; LField: TDelphiAIDevDBRegistersFields; begin + Self.ValidateIfDatabaseSelected; + LCommand := Trim(mmReturn.Lines.Text); if LCommand.IsEmpty then TUtils.ShowMsgAndAbort('No SQL command informed'); @@ -887,12 +895,18 @@ procedure TDelphiAIDevDBChatView.CopyAllGridDataClick(Sender: TObject); procedure TDelphiAIDevDBChatView.SaveAllGridDataAsCSVClick(Sender: TObject); begin + if DataSource1.DataSet.IsEmpty then + TUtils.ShowMsgAndAbort('There is no data to be exported'); + TUtilsDBGrids.DBGridToCSV(DBGrid1); TUtils.ShowV('File saved successfully'); end; procedure TDelphiAIDevDBChatView.SaveAllGridDataAsTXTClick(Sender: TObject); begin + if DataSource1.DataSet.IsEmpty then + TUtils.ShowMsgAndAbort('There is no data to be exported'); + TUtilsDBGrids.DBGridToTxt(DBGrid1); TUtils.ShowV('File saved successfully'); end; From 81ae19e3e6ec748adfc6e4ed483234c49302679c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 3 Oct 2024 03:53:24 -0300 Subject: [PATCH 092/109] fit/version --- Src/Consts/DelphiAIDev.Consts.pas | 2 +- Src/View/DelphiAIDev.View.About.dfm | 8 ++++---- Src/View/DelphiAIDev.View.About.pas | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index 8ecbd74..437c642 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -5,7 +5,7 @@ interface type TConsts = class public const - SEMANTIC_VERSION = '1.8.0'; + SEMANTIC_VERSION = '2.2.2'; SEMANTIC_VERSION_LB = 'Version: ' + SEMANTIC_VERSION; WIN_CONTROL_FOCU_NIL = nil; DELPHI_AI_DEVELOPER_DPROJ = 'DelphiAIDeveloper.dproj'; diff --git a/Src/View/DelphiAIDev.View.About.dfm b/Src/View/DelphiAIDev.View.About.dfm index 46d9422..3a7fe14 100644 --- a/Src/View/DelphiAIDev.View.About.dfm +++ b/Src/View/DelphiAIDev.View.About.dfm @@ -29,7 +29,6 @@ object DelphiAIDevViewAbout: TDelphiAIDevViewAbout Color = clWindow ParentBackground = False TabOrder = 0 - ExplicitTop = -4 object Bevel1: TBevel AlignWithMargins = True Left = 0 @@ -2104,15 +2103,16 @@ object DelphiAIDevViewAbout: TDelphiAIDevViewAbout TabOrder = 0 OnClick = btnOKClick end - object btnTeste: TButton + object btnTest: TButton Left = 2 Top = 2 Width = 75 Height = 31 Align = alLeft - Caption = 'Teste' + Caption = 'Test' TabOrder = 1 - OnClick = btnTesteClick + Visible = False + OnClick = btnTestClick end end end diff --git a/Src/View/DelphiAIDev.View.About.pas b/Src/View/DelphiAIDev.View.About.pas index b694cdb..e4f78e0 100644 --- a/Src/View/DelphiAIDev.View.About.pas +++ b/Src/View/DelphiAIDev.View.About.pas @@ -32,7 +32,7 @@ TDelphiAIDevViewAbout = class(TForm) imgGithub: TImage; pnButtons: TPanel; btnOK: TButton; - btnTeste: TButton; + btnTest: TButton; Panel1: TPanel; lbDonateToCode4Delphi: TLabel; imgDonate: TImage; @@ -44,7 +44,7 @@ TDelphiAIDevViewAbout = class(TForm) procedure lbSiteCode4DelphiMouseLeave(Sender: TObject); procedure lbGitHubCode4DelphiClick(Sender: TObject); procedure FormCreate(Sender: TObject); - procedure btnTesteClick(Sender: TObject); + procedure btnTestClick(Sender: TObject); procedure lbDonateToCode4DelphiClick(Sender: TObject); private @@ -121,7 +121,7 @@ procedure TDelphiAIDevViewAbout.lbSiteCode4DelphiMouseMove(Sender: TObject; Shif TLabel(Sender).Font.Style := TLabel(Sender).Font.Style + [fsUnderline]; end; -procedure TDelphiAIDevViewAbout.btnTesteClick(Sender: TObject); +procedure TDelphiAIDevViewAbout.btnTestClick(Sender: TObject); begin // end; From 37bdffd80369e32995b61d69987e31113f2e08dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 4 Oct 2024 17:12:40 -0300 Subject: [PATCH 093/109] refactor/treatments-return-ais --- Package/DelphiAIDeveloper.dpk | 5 +- Package/DelphiAIDeveloper.dproj | 3 +- Src/AI/DelphiAIDev.AI.ChatGPT.pas | 40 ++++--- Src/AI/DelphiAIDev.AI.Facade.pas | 88 +++++++++++++++ Src/AI/DelphiAIDev.AI.Gemini.pas | 40 ++++--- Src/AI/DelphiAIDev.AI.Groq.pas | 35 +++--- Src/AI/DelphiAIDev.AI.Interfaces.pas | 14 ++- Src/AI/DelphiAIDev.AI.Ollama.pas | 61 ++++++---- Src/AI/DelphiAIDev.AI.Response.pas | 75 +++++++++++++ Src/AI/DelphiAIDev.AI.pas | 81 -------------- Src/Chat/DelphiAIDev.Chat.View.dfm | 3 +- Src/Chat/DelphiAIDev.Chat.View.pas | 8 +- .../DelphiAIDev.CodeCompletion.Search.pas | 104 ++++++++++-------- Src/Consts/DelphiAIDev.Consts.pas | 2 +- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 15 +-- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 8 +- 16 files changed, 360 insertions(+), 222 deletions(-) create mode 100644 Src/AI/DelphiAIDev.AI.Facade.pas create mode 100644 Src/AI/DelphiAIDev.AI.Response.pas delete mode 100644 Src/AI/DelphiAIDev.AI.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index d25e7de..576683c 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -57,7 +57,7 @@ contains DelphiAIDev.Test in '..\Src\Test\DelphiAIDev.Test.pas', DelphiAIDev.Settings.View in '..\Src\Settings\DelphiAIDev.Settings.View.pas' {DelphiAIDevSettingsView}, DelphiAIDev.Settings in '..\Src\Settings\DelphiAIDev.Settings.pas', - DelphiAIDev.AI in '..\Src\AI\DelphiAIDev.AI.pas', + DelphiAIDev.AI.Facade in '..\Src\AI\DelphiAIDev.AI.Facade.pas', DelphiAIDev.Chat.View in '..\Src\Chat\DelphiAIDev.Chat.View.pas' {DelphiAIDevChatView}, DelphiAIDev.Chat.ProcessResponse in '..\Src\Chat\DelphiAIDev.Chat.ProcessResponse.pas', DelphiAIDev.AI.Gemini in '..\Src\AI\DelphiAIDev.AI.Gemini.pas', @@ -113,6 +113,7 @@ contains DelphiAIDev.IDE.NTAEditViewNotifier in '..\Src\IDE\NTAEditViewNotifier\DelphiAIDev.IDE.NTAEditViewNotifier.pas', DelphiAIDev.CodeCompletion.Search in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Search.pas', DelphiAIDev.Test.Client in '..\Src\Test\DelphiAIDev.Test.Client.pas', - DelphiAIDev.CodeCompletion.KeyTab in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.KeyTab.pas'; + DelphiAIDev.CodeCompletion.KeyTab in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.KeyTab.pas', + DelphiAIDev.AI.Response in '..\Src\AI\DelphiAIDev.AI.Response.pas'; end. diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 5fb7005..66a3dfc 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -154,7 +154,7 @@
DelphiAIDevSettingsView
- +
DelphiAIDevChatView
@@ -229,6 +229,7 @@ + BITMAP c4d_Logo diff --git a/Src/AI/DelphiAIDev.AI.ChatGPT.pas b/Src/AI/DelphiAIDev.AI.ChatGPT.pas index 76b965d..7409225 100644 --- a/Src/AI/DelphiAIDev.AI.ChatGPT.pas +++ b/Src/AI/DelphiAIDev.AI.ChatGPT.pas @@ -16,11 +16,11 @@ interface TDelphiAIDevAIChatGPT = class(TInterfacedObject, IDelphiAIDevAI) private FSettings: TDelphiAIDevSettings; + FResponse: IDelphiAIDevAIResponse; protected - function GetResponse(const AQuestion: string): string; + function GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; public - class function New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; - constructor Create(const ASettings: TDelphiAIDevSettings); + constructor Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); end; implementation @@ -28,17 +28,13 @@ implementation const API_JSON_BODY_BASE = '{"model": "%s", "messages": [{"role": "user", "content": "%s"}], "stream": false, "max_tokens": 2048}'; -class function TDelphiAIDevAIChatGPT.New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; -begin - Result := Self.Create(ASettings); -end; - -constructor TDelphiAIDevAIChatGPT.Create(const ASettings: TDelphiAIDevSettings); +constructor TDelphiAIDevAIChatGPT.Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); begin FSettings := ASettings; + FResponse := AResponse; end; -function TDelphiAIDevAIChatGPT.GetResponse(const AQuestion: string): string; +function TDelphiAIDevAIChatGPT.GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; var LResponse: IResponse; LJsonValueAll: TJSONValue; @@ -48,8 +44,9 @@ function TDelphiAIDevAIChatGPT.GetResponse(const AQuestion: string): string; LJsonValueMessage: TJSONValue; LJsonObjMessage: TJSONObject; LItemChoices: Integer; + LResult: string; begin - Result := ''; + Result := FResponse; LResponse := TRequest.New .BaseURL(FSettings.BaseUrlOpenAI) @@ -59,18 +56,29 @@ function TDelphiAIDevAIChatGPT.GetResponse(const AQuestion: string): string; .AddBody(Format(API_JSON_BODY_BASE, [FSettings.ModelOpenAI, AQuestion])) .Post; + FResponse.SetStatusCode(LResponse.StatusCode); + if LResponse.StatusCode <> 200 then - Exit('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + begin + FResponse.SetContentText('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonValueAll := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LResponse.Content), 0); if not(LJsonValueAll is TJSONObject) then - Exit('The question cannot be answered, return object not found.' + sLineBreak + + begin + FResponse.SetContentText('The question cannot be answered, return object not found.' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonValueChoices := TJSONObject(LJsonValueAll).GetValue('choices'); if not(LJsonValueChoices is TJSONArray) then - Exit('The question cannot be answered, choices not found.' + sLineBreak + + begin + FResponse.SetContentText('The question cannot be answered, choices not found.' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonArrayChoices := LJsonValueChoices as TJSONArray; for LItemChoices := 0 to Pred(LJsonArrayChoices.Count) do @@ -88,10 +96,10 @@ function TDelphiAIDevAIChatGPT.GetResponse(const AQuestion: string): string; //GET MESSAGE LIKE TJSONObject LJsonObjMessage := LJsonValueMessage as TJSONObject; - Result := Result + TJSONString(LJsonObjMessage.GetValue('content')).Value.Trim + sLineBreak; + LResult := LResult + TJSONString(LJsonObjMessage.GetValue('content')).Value.Trim + sLineBreak; end; - Result := Result.Trim; + FResponse.SetContentText(LResult.Trim); end; end. diff --git a/Src/AI/DelphiAIDev.AI.Facade.pas b/Src/AI/DelphiAIDev.AI.Facade.pas new file mode 100644 index 0000000..ab1e983 --- /dev/null +++ b/Src/AI/DelphiAIDev.AI.Facade.pas @@ -0,0 +1,88 @@ +unit DelphiAIDev.AI.Facade; + +interface + +uses + System.SysUtils, + System.Classes, + DelphiAIDev.Utils, + DelphiAIDev.Types, + DelphiAIDev.Settings, + DelphiAIDev.AI.Interfaces, + DelphiAIDev.AI.Response, + DelphiAIDev.AI.Gemini, + DelphiAIDev.AI.ChatGPT, + DelphiAIDev.AI.Groq, + DelphiAIDev.AI.Ollama; + +type + IDelphiAIDevAIResponse = DelphiAIDev.AI.Interfaces.IDelphiAIDevAIResponse; + + TDelphiAIDevAIFacade = class + private + FAiUse: TC4DAiAvailable; + FSettings: TDelphiAIDevSettings; + FResponse: IDelphiAIDevAIResponse; + public + constructor Create; + destructor Destroy; override; + function AiUse(const Value: TC4DAiAvailable): TDelphiAIDevAIFacade; + function ProcessSend(const AQuestion: string): TDelphiAIDevAIFacade; + function Response: IDelphiAIDevAIResponse; + end; + +implementation + +constructor TDelphiAIDevAIFacade.Create; +begin + FSettings := TDelphiAIDevSettings.GetInstance; + FSettings.LoadData; + FAiUse := FSettings.AIDefault; + FResponse := TDelphiAIDevAIResponse.New; +end; + +destructor TDelphiAIDevAIFacade.Destroy; +begin + inherited; +end; + +function TDelphiAIDevAIFacade.AiUse(const Value: TC4DAiAvailable): TDelphiAIDevAIFacade; +begin + Result := Self; + FAiUse := Value; +end; + +function TDelphiAIDevAIFacade.ProcessSend(const AQuestion: string): TDelphiAIDevAIFacade; +var + LQuestion: string; + LRequest: IDelphiAIDevAI; +begin + Result := Self; + LQuestion := TUtils.AdjustQuestionToJson(AQuestion); + + if TUtils.DebugMyIsOn then + TUtils.AddLogDeleteFileFirst(LQuestion, 'DelphiAIDevAI_ProcessSend'); + + case FAiUse of + TC4DAiAvailable.Gemini: + LRequest := TDelphiAIDevAIGemini.Create(FSettings, FResponse); + TC4DAiAvailable.OpenAI: + LRequest := TDelphiAIDevAIChatGPT.Create(FSettings, FResponse); + TC4DAiAvailable.Groq: + LRequest := TDelphiAIDevAIGroq.Create(FSettings, FResponse); + TC4DAiAvailable.Ollama: + LRequest := TDelphiAIDevAIOllama.Create(FSettings, FResponse); + else + FResponse.SetContentText('Default AI not reported in Delphi AI Developer settings'); + Exit; + end; + + LRequest.GetResponse(LQuestion); +end; + +function TDelphiAIDevAIFacade.Response: IDelphiAIDevAIResponse; +begin + Result := FResponse; +end; + +end. diff --git a/Src/AI/DelphiAIDev.AI.Gemini.pas b/Src/AI/DelphiAIDev.AI.Gemini.pas index 38e9e62..ed284cf 100644 --- a/Src/AI/DelphiAIDev.AI.Gemini.pas +++ b/Src/AI/DelphiAIDev.AI.Gemini.pas @@ -10,17 +10,18 @@ interface DelphiAIDev.Consts, DelphiAIDev.Utils, DelphiAIDev.Settings, - DelphiAIDev.AI.Interfaces; + DelphiAIDev.AI.Interfaces, + DelphiAIDev.AI.Response; type TDelphiAIDevAIGemini = class(TInterfacedObject, IDelphiAIDevAI) private FSettings: TDelphiAIDevSettings; + FResponse: IDelphiAIDevAIResponse; protected - function GetResponse(const AQuestion: string): string; + function GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; public - class function New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; - constructor Create(const ASettings: TDelphiAIDevSettings); + constructor Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); end; implementation @@ -28,17 +29,13 @@ implementation const API_JSON_BODY_BASE = '{"contents": [{"parts": [ {"text": "%s"}]}]}'; -class function TDelphiAIDevAIGemini.New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; -begin - Result := Self.Create(ASettings); -end; - -constructor TDelphiAIDevAIGemini.Create(const ASettings: TDelphiAIDevSettings); +constructor TDelphiAIDevAIGemini.Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); begin FSettings := ASettings; + FResponse := AResponse; end; -function TDelphiAIDevAIGemini.GetResponse(const AQuestion: string): string; +function TDelphiAIDevAIGemini.GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; var LApiUrl: string; LResponse: IResponse; @@ -49,23 +46,32 @@ function TDelphiAIDevAIGemini.GetResponse(const AQuestion: string): string; LJsonObjParts: TJsonObject; LItemCandidates: Integer; LItemParts: Integer; + LResult: string; begin - Result := ''; - LApiUrl := FSettings.BaseUrlGemini + FSettings.ModelGemini + '?key=' + FSettings.ApiKeyGemini; + Result := FResponse; + LApiUrl := FSettings.BaseUrlGemini + FSettings.ModelGemini + '?key=' + FSettings.ApiKeyGemini; LResponse := TRequest.New .BaseURL(LApiUrl) .Accept(TConsts.APPLICATION_JSON) .AddBody(Format(API_JSON_BODY_BASE, [AQuestion])) .Post; + FResponse.SetStatusCode(LResponse.StatusCode); + if LResponse.StatusCode <> 200 then - Exit('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + begin + FResponse.SetContentText('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonValueAll := TJsonObject.ParseJSONValue(LResponse.Content); if not(LJsonValueAll is TJSONObject) then - Exit('The question cannot be answered, return object not found.' + sLineBreak + + begin + FResponse.SetContentText('The question cannot be answered, return object not found.' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonArrayCandidates := (LJsonValueAll as TJsonObject).GetValue('candidates'); for LItemCandidates := 0 to Pred(LJsonArrayCandidates.Count) do @@ -75,11 +81,11 @@ function TDelphiAIDevAIGemini.GetResponse(const AQuestion: string): string; for LItemParts := 0 to Pred(LJsonArrayParts.Count) do begin LJsonObjParts := LJsonArrayParts.Items[LItemParts] as TJsonObject; - Result := Result + LJsonObjParts.GetValue('text').Trim + sLineBreak; + LResult := LResult + LJsonObjParts.GetValue('text').Trim + sLineBreak; end; end; - Result := Result.Trim; + FResponse.SetContentText(LResult.Trim); end; end. diff --git a/Src/AI/DelphiAIDev.AI.Groq.pas b/Src/AI/DelphiAIDev.AI.Groq.pas index 12404a1..f1a843b 100644 --- a/Src/AI/DelphiAIDev.AI.Groq.pas +++ b/Src/AI/DelphiAIDev.AI.Groq.pas @@ -16,11 +16,11 @@ interface TDelphiAIDevAIGroq = class(TInterfacedObject, IDelphiAIDevAI) private FSettings: TDelphiAIDevSettings; + FResponse: IDelphiAIDevAIResponse; protected - function GetResponse(const AQuestion: string): string; + function GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; public - class function New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; - constructor Create(const ASettings: TDelphiAIDevSettings); + constructor Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); end; implementation @@ -28,17 +28,13 @@ implementation const API_JSON_BODY_BASE = '{"messages": [{"role": "user", "content": "%s"}], "model": "%s"}'; -class function TDelphiAIDevAIGroq.New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; -begin - Result := Self.Create(ASettings); -end; - -constructor TDelphiAIDevAIGroq.Create(const ASettings: TDelphiAIDevSettings); +constructor TDelphiAIDevAIGroq.Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); begin FSettings := ASettings; + FResponse := AResponse; end; -function TDelphiAIDevAIGroq.GetResponse(const AQuestion: string): string; +function TDelphiAIDevAIGroq.GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; var LResponse: IResponse; LJsonValueAll: TJSONVALUE; @@ -46,8 +42,9 @@ function TDelphiAIDevAIGroq.GetResponse(const AQuestion: string): string; LJsonObjMessage: TJsonObject; LContent: string; LItemChoices: Integer; + LResult: string; begin - Result := ''; + Result := FResponse; LResponse := TRequest.New .BaseURL(FSettings.BaseUrlGroq) @@ -57,23 +54,31 @@ function TDelphiAIDevAIGroq.GetResponse(const AQuestion: string): string; .AddBody(Format(API_JSON_BODY_BASE, [AQuestion, FSettings.ModelGroq])) .Post; + FResponse.SetStatusCode(LResponse.StatusCode); + if LResponse.StatusCode <> 200 then - Exit('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + begin + FResponse.SetContentText('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonValueAll := TJsonObject.ParseJSONValue(LResponse.Content); if not(LJsonValueAll is TJSONObject) then - Exit('The question cannot be answered, return object not found.' + sLineBreak + + begin + FResponse.SetContentText('The question cannot be answered, return object not found.' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonArrayChoices := (LJsonValueAll as TJsonObject).GetValue('choices'); for LItemChoices := 0 to Pred(LJsonArrayChoices.Count) do begin LJsonObjMessage := LJsonArrayChoices.Items[LItemChoices].GetValue('message'); LContent := LJsonObjMessage.GetValue('content'); - Result := Result + LContent.Trim + sLineBreak; + LResult := LResult + LContent.Trim + sLineBreak; end; - Result := Result.Trim; + FResponse.SetContentText(LResult.Trim); end; end. diff --git a/Src/AI/DelphiAIDev.AI.Interfaces.pas b/Src/AI/DelphiAIDev.AI.Interfaces.pas index a06e489..71317c8 100644 --- a/Src/AI/DelphiAIDev.AI.Interfaces.pas +++ b/Src/AI/DelphiAIDev.AI.Interfaces.pas @@ -2,10 +2,22 @@ interface +uses + System.Classes; + type + IDelphiAIDevAIResponse = interface + ['{F9E7734A-33FA-4448-9F5D-A3680FFFFFB9}'] + function Clear: IDelphiAIDevAIResponse; + function SetStatusCode(const Value: Integer): IDelphiAIDevAIResponse; + function GetStatusCode: Integer; + function SetContentText(const Value: string): IDelphiAIDevAIResponse; + function GetContent: TStrings; + end; + IDelphiAIDevAI = interface ['{B82FACA6-66DA-4DC0-877F-8263B5C172C1}'] - function GetResponse(const AQuestion: string): string; + function GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; end; implementation diff --git a/Src/AI/DelphiAIDev.AI.Ollama.pas b/Src/AI/DelphiAIDev.AI.Ollama.pas index 10239a5..e1496bc 100644 --- a/Src/AI/DelphiAIDev.AI.Ollama.pas +++ b/Src/AI/DelphiAIDev.AI.Ollama.pas @@ -16,11 +16,11 @@ interface TDelphiAIDevAIOllama = class(TInterfacedObject, IDelphiAIDevAI) private FSettings: TDelphiAIDevSettings; + FResponse: IDelphiAIDevAIResponse; protected - function GetResponse(const AQuestion: string): string; + function GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; public - class function New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; - constructor Create(const ASettings: TDelphiAIDevSettings); + constructor Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); end; implementation @@ -32,48 +32,65 @@ implementation '"options": {"seed": 101, "temperature": 0}, '+ '"stream": false}'; -class function TDelphiAIDevAIOllama.New(const ASettings: TDelphiAIDevSettings): IDelphiAIDevAI; -begin - Result := Self.Create(ASettings); -end; - -constructor TDelphiAIDevAIOllama.Create(const ASettings: TDelphiAIDevSettings); +constructor TDelphiAIDevAIOllama.Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); begin FSettings := ASettings; + FResponse := AResponse; end; -function TDelphiAIDevAIOllama.GetResponse(const AQuestion: string): string; +function TDelphiAIDevAIOllama.GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; var LResponse: IResponse; LJsonValueAll: TJSONVALUE; LJsonValueMessage: TJSONValue; LJsonObjMessage: TJsonObject; begin - Result := ''; + Result := FResponse; + + try + LResponse := TRequest.New + .BaseURL(FSettings.BaseUrlOllama) + .ContentType(TConsts.APPLICATION_JSON) + .Accept(TConsts.APPLICATION_JSON) + //.Token('Bearer ' + FSettings.ApiKeyOllama) + .AddBody(Format(API_JSON_BODY_BASE, [FSettings.ModelOllama, AQuestion])) + .Post; + except + on E: Exception do + begin + FResponse.SetStatusCode(LResponse.StatusCode) + .SetContentText('The question cannot be answered, return object not found.' + sLineBreak + + 'Return: ' + LResponse.Content); + Exit; + end; + end; - LResponse := TRequest.New - .BaseURL(FSettings.BaseUrlOllama) - .ContentType(TConsts.APPLICATION_JSON) - .Accept(TConsts.APPLICATION_JSON) - //.Token('Bearer ' + FSettings.ApiKeyOllama) - .AddBody(Format(API_JSON_BODY_BASE, [FSettings.ModelOllama, AQuestion])) - .Post; + FResponse.SetStatusCode(LResponse.StatusCode); if LResponse.StatusCode <> 200 then - Exit('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + begin + FResponse.SetContentText('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonValueAll := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(LResponse.Content), 0); if not(LJsonValueAll is TJSONObject) then - Exit('The question cannot be answered, return object not found.' + sLineBreak + + begin + FResponse.SetContentText('The question cannot be answered, return object not found.' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonValueMessage := (LJsonValueAll as TJSONObject).GetValue('message'); if not(LJsonValueMessage is TJSONObject) then - Exit('The question cannot be answered, return object not found.' + sLineBreak + + begin + FResponse.SetContentText('The question cannot be answered, return object not found.' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; LJsonObjMessage := LJsonValueMessage as TJSONObject; - Result := TJSONString(LJsonObjMessage.GetValue('content')).Value.Trim; + FResponse.SetContentText(TJSONString(LJsonObjMessage.GetValue('content')).Value.Trim); end; end. diff --git a/Src/AI/DelphiAIDev.AI.Response.pas b/Src/AI/DelphiAIDev.AI.Response.pas new file mode 100644 index 0000000..1481f03 --- /dev/null +++ b/Src/AI/DelphiAIDev.AI.Response.pas @@ -0,0 +1,75 @@ +unit DelphiAIDev.AI.Response; + +interface + +uses + System.SysUtils, + System.Classes, + DelphiAIDev.AI.Interfaces; + +type + TDelphiAIDevAIResponse = class(TInterfacedObject, IDelphiAIDevAIResponse) + private + FStatusCode: Integer; + FContent: TStrings; + protected + function Clear: IDelphiAIDevAIResponse; + function SetStatusCode(const Value: Integer): IDelphiAIDevAIResponse; + function GetStatusCode: Integer; + function SetContentText(const Value: string): IDelphiAIDevAIResponse; + function GetContent: TStrings; + public + class function New: IDelphiAIDevAIResponse; + constructor Create; + destructor Destroy; override; + end; + +implementation + +class function TDelphiAIDevAIResponse.New: IDelphiAIDevAIResponse; +begin + Result := Self.Create; +end; + +constructor TDelphiAIDevAIResponse.Create; +begin + FContent := TStringList.Create; + Self.Clear; +end; + +destructor TDelphiAIDevAIResponse.Destroy; +begin + FContent.Free; + inherited; +end; + +function TDelphiAIDevAIResponse.Clear: IDelphiAIDevAIResponse; +begin + Result := Self; + FStatusCode := 0; + FContent.Clear; +end; + +function TDelphiAIDevAIResponse.SetStatusCode(const Value: Integer): IDelphiAIDevAIResponse; +begin + Result := Self; + FStatusCode := Value; +end; + +function TDelphiAIDevAIResponse.GetStatusCode: Integer; +begin + Result := FStatusCode; +end; + +function TDelphiAIDevAIResponse.SetContentText(const Value: string): IDelphiAIDevAIResponse; +begin + Result := Self; + FContent.Text := Value; +end; + +function TDelphiAIDevAIResponse.GetContent: TStrings; +begin + Result := FContent; +end; + +end. diff --git a/Src/AI/DelphiAIDev.AI.pas b/Src/AI/DelphiAIDev.AI.pas deleted file mode 100644 index fc4f0db..0000000 --- a/Src/AI/DelphiAIDev.AI.pas +++ /dev/null @@ -1,81 +0,0 @@ -unit DelphiAIDev.AI; - -interface - -uses - System.SysUtils, - System.Classes, - DelphiAIDev.Utils, - DelphiAIDev.Types, - DelphiAIDev.Settings, - DelphiAIDev.AI.Gemini, - DelphiAIDev.AI.ChatGPT, - DelphiAIDev.AI.Groq, - DelphiAIDev.AI.Ollama; - -type - TDelphiAIDevAI = class - private - FAiUse: TC4DAiAvailable; - FSettings: TDelphiAIDevSettings; - FResponse: TStrings; - public - constructor Create; - destructor Destroy; override; - function AiUse(const Value: TC4DAiAvailable): TDelphiAIDevAI; - procedure ProcessSend(const AQuestion: string); - function Response: TStrings; - end; - -implementation - -constructor TDelphiAIDevAI.Create; -begin - FSettings := TDelphiAIDevSettings.GetInstance; - FSettings.LoadData; - FAiUse := FSettings.AIDefault; - FResponse := TStringList.Create; -end; - -destructor TDelphiAIDevAI.Destroy; -begin - FResponse.Free; - inherited; -end; - -function TDelphiAIDevAI.AiUse(const Value: TC4DAiAvailable): TDelphiAIDevAI; -begin - Result := Self; - FAiUse := Value; -end; - -procedure TDelphiAIDevAI.ProcessSend(const AQuestion: string); -var - LQuestion: string; -begin - LQuestion := TUtils.AdjustQuestionToJson(AQuestion); - FResponse.Clear; - - if TUtils.DebugMyIsOn then - TUtils.AddLogDeleteFileFirst(LQuestion, 'DelphiAIDevAI_ProcessSend'); - - case FAiUse of - TC4DAiAvailable.Gemini: - FResponse.Text := TDelphiAIDevAIGemini.New(FSettings).GetResponse(LQuestion); - TC4DAiAvailable.OpenAI: - FResponse.Text := TDelphiAIDevAIChatGPT.New(FSettings).GetResponse(LQuestion); - TC4DAiAvailable.Groq: - FResponse.Text := TDelphiAIDevAIGroq.New(FSettings).GetResponse(LQuestion); - TC4DAiAvailable.Ollama: - FResponse.Text := TDelphiAIDevAIOllama.New(FSettings).GetResponse(LQuestion); - else - FResponse.Text := 'Default AI not reported in Delphi AI Developer settings'; - end; -end; - -function TDelphiAIDevAI.Response: TStrings; -begin - Result := FResponse; -end; - -end. diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index eea88f7..264b2a0 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -138,7 +138,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Left = 0 Top = 3 Width = 56 - Height = 22 + Height = 13 Cursor = crHandPoint Hint = 'AI being used' Margins.Left = 0 @@ -149,7 +149,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'lbCurrentAI' PopupMenu = pMenuCurrentAI OnClick = lbCurrentAIClick - ExplicitHeight = 13 end object btnSend: TButton AlignWithMargins = True diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index 52c53e9..1c695ba 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -26,7 +26,7 @@ interface Clipbrd, DelphiAIDev.Types, DelphiAIDev.Consts, - DelphiAIDev.AI, + DelphiAIDev.AI.Facade, DelphiAIDev.Settings, DelphiAIDev.ModuleCreator, DelphiAIDev.DefaultsQuestions.PopupMenu, @@ -103,7 +103,7 @@ TDelphiAIDevChatView = class(TDockableForm) procedure Clear1Click(Sender: TObject); procedure btnCleanAllClick(Sender: TObject); private - FAI: TDelphiAIDevAI; + FAI: TDelphiAIDevAIFacade; FSettings: TDelphiAIDevSettings; FProcessResponse: TDelphiAIDevChatProcessResponse; FPopupMenuQuestions: TDelphiAIDevDefaultsQuestionsPopupMenu; @@ -188,7 +188,7 @@ constructor TDelphiAIDevChatView.Create(AOwner: TComponent); AutoSave := True; SaveStateNecessary := True; - FAI := TDelphiAIDevAI.Create; + FAI := TDelphiAIDevAIFacade.Create; FSettings := TDelphiAIDevSettings.GetInstance; FProcessResponse := TDelphiAIDevChatProcessResponse.Create(mmReturn); FPopupMenuQuestions := TDelphiAIDevDefaultsQuestionsPopupMenu.Create; @@ -467,7 +467,7 @@ procedure TDelphiAIDevChatView.ProcessSend; mmReturn.Lines.BeginUpdate; try //Optional use of one of the following lines - FProcessResponse.AddResponseComplete(FAI.Response); + FProcessResponse.AddResponseComplete(FAI.Response.GetContent); Self.Last; //Self.AddResponseSimple(FChat.Response.Text); finally diff --git a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas index 9cefa1e..b7c6daf 100644 --- a/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas +++ b/Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas @@ -14,7 +14,7 @@ interface DelphiAIDev.Utils, DelphiAIDev.Utils.OTA, DelphiAIDev.CodeCompletion.Vars, - DelphiAIDev.AI; + DelphiAIDev.AI.Facade; type IDelphiAIDevCodeCompletionSearch = interface @@ -26,8 +26,11 @@ TDelphiAIDevCodeCompletionSearch = class(TInterfacedObject, IDelphiAIDevCodeCo private FSettings: TDelphiAIDevSettings; FQuestions: TStrings; - FAI: TDelphiAIDevAI; + FAIRequest: TDelphiAIDevAIFacade; FVars: TDelphiAIDevCodeCompletionVars; + FIOTAEditPosition: IOTAEditPosition; + procedure ProcessQuestions(const AContext: IOTAKeyContext); + procedure ProcessResponse; protected procedure Process(const AContext: IOTAKeyContext); public @@ -46,7 +49,7 @@ class function TDelphiAIDevCodeCompletionSearch.New: IDelphiAIDevCodeCompletionS constructor TDelphiAIDevCodeCompletionSearch.Create; begin FSettings := TDelphiAIDevSettings.GetInstance; - FAI := TDelphiAIDevAI.Create; + FAIRequest := TDelphiAIDevAIFacade.Create; FQuestions := TStringList.Create; FVars := TDelphiAIDevCodeCompletionVars.GetInstance; end; @@ -54,69 +57,78 @@ constructor TDelphiAIDevCodeCompletionSearch.Create; destructor TDelphiAIDevCodeCompletionSearch.Destroy; begin FQuestions.Free; - FAI.Free; + FAIRequest.Free; inherited; end; procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContext); -var - LRow: Integer; - LColumn: Integer; - LBlankTextLines: string; - i: Integer; - LIOTAEditPosition: IOTAEditPosition; begin FSettings.ValidateFillingSelectedAICodeCompletion(TShowMsg.No); Screen.Cursor := crHourGlass; try - FQuestions.Clear; - FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); - FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeCompletionSuggestion); - FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeOnly); - if not FSettings.CodeCompletionDefaultPrompt.Trim.IsEmpty then - FQuestions.Add(FSettings.CodeCompletionDefaultPrompt); - - LIOTAEditPosition := AContext.EditBuffer.EditPosition; - LIOTAEditPosition.InsertText(TConsts.TAG_CODE_COMPLETION); - try - FQuestions.Add(TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim); - finally - LIOTAEditPosition.BackspaceDelete(TConsts.TAG_CODE_COMPLETION.Length); - end; + Self.ProcessQuestions(AContext); try - FAI.AiUse(FSettings.CodeCompletionAIDefault).ProcessSend(FQuestions.Text); + FAIRequest.AiUse(FSettings.CodeCompletionAIDefault).ProcessSend(FQuestions.Text); except Abort; end; - FVars.Module := TUtilsOTA.GetCurrentModule; - FVars.Contents.Text := TUtils.ConfReturnAI(FAI.Response.Text); + Self.ProcessResponse; + finally + Screen.Cursor := crDefault; + end; +end; - LRow := LIOTAEditPosition.Row; - LColumn := LIOTAEditPosition.Column; +procedure TDelphiAIDevCodeCompletionSearch.ProcessQuestions(const AContext: IOTAKeyContext); +begin + FQuestions.Clear; + FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition); + FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeCompletionSuggestion); + FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeOnly); + if not FSettings.CodeCompletionDefaultPrompt.Trim.IsEmpty then + FQuestions.Add(FSettings.CodeCompletionDefaultPrompt); + + FIOTAEditPosition := AContext.EditBuffer.EditPosition; + FIOTAEditPosition.InsertText(TConsts.TAG_CODE_COMPLETION); + try + FQuestions.Add(TUtilsOTA.GetSelectedBlockOrAllCodeUnit.Trim); + finally + FIOTAEditPosition.BackspaceDelete(TConsts.TAG_CODE_COMPLETION.Length); + end; +end; - FVars.Row := LRow; - FVars.Column := LColumn; - FVars.LineIni := LRow; - FVars.LineEnd := FVars.LineIni + FVars.Contents.Count; +procedure TDelphiAIDevCodeCompletionSearch.ProcessResponse; +var + LRow: Integer; + LColumn: Integer; + LBlankTextLines: string; + i: Integer; +begin + if FAIRequest.Response.GetStatusCode <> 200 then + begin + TUtils.ShowMsg('Unable to perform AI request.', + Format('Code: %d %s Message: %s', [FAIRequest.Response.GetStatusCode, sLineBreak, FAIRequest.Response.GetContent.Text])); + Exit; + end; - LBlankTextLines := ''; - for i := 1 to Pred(FVars.Contents.Count) do - LBlankTextLines := LBlankTextLines + sLineBreak; + FVars.Module := TUtilsOTA.GetCurrentModule; + FVars.Contents.Text := TUtils.ConfReturnAI(FAIRequest.Response.GetContent.Text); + LRow := FIOTAEditPosition.Row; + LColumn := FIOTAEditPosition.Column; - LIOTAEditPosition.InsertText(LBlankTextLines); - LIOTAEditPosition.Move(FVars.LineIni, LColumn); - finally - Screen.Cursor := crDefault; - end; + FVars.Row := LRow; + FVars.Column := LColumn; + FVars.LineIni := LRow; + FVars.LineEnd := FVars.LineIni + FVars.Contents.Count; + + LBlankTextLines := ''; + for i := 1 to Pred(FVars.Contents.Count) do + LBlankTextLines := LBlankTextLines + sLineBreak; - //LIOTAEditPositionMoveBOL; - // //LTextCurrentLineOrBlock := Context.EditBuffer.EditBlock.Text; - // LTextCurrentLineOrBlock := GetCurrentLineOrBlock(CnOtaGetTopMostEditView); - // if LTextCurrentLineOrBlock.Trim.IsEmpty then - // Exit; + FIOTAEditPosition.InsertText(LBlankTextLines); + FIOTAEditPosition.Move(FVars.LineIni, LColumn); end; end. diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index 437c642..ee03c30 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -5,7 +5,7 @@ interface type TConsts = class public const - SEMANTIC_VERSION = '2.2.2'; + SEMANTIC_VERSION = '2.3.0'; SEMANTIC_VERSION_LB = 'Version: ' + SEMANTIC_VERSION; WIN_CONTROL_FOCU_NIL = nil; DELPHI_AI_DEVELOPER_DPROJ = 'DelphiAIDeveloper.dproj'; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index c7f76c2..ce46b48 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -161,7 +161,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Left = 0 Top = 3 Width = 56 - Height = 22 + Height = 13 Cursor = crHandPoint Hint = 'AI being used' Margins.Left = 0 @@ -172,7 +172,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Caption = 'lbCurrentAI' PopupMenu = pMenuCurrentAI OnClick = lbCurrentAIClick - ExplicitHeight = 13 end object btnSend: TButton AlignWithMargins = True @@ -299,21 +298,19 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Left = 899 Top = 3 Width = 36 - Height = 21 + Height = 13 Align = alRight Caption = '000000' Layout = tlCenter - ExplicitHeight = 13 end object Label3: TLabel Left = 863 Top = 3 Width = 36 - Height = 21 + Height = 13 Align = alRight Caption = 'Count: ' Layout = tlCenter - ExplicitHeight = 13 end end end @@ -335,18 +332,17 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Left = 337 Top = 0 Width = 85 - Height = 25 + Height = 13 Align = alLeft Caption = ' Last generation: ' Layout = tlCenter - ExplicitHeight = 13 end object lbLastGeneration: TLabel AlignWithMargins = True Left = 422 Top = 0 Width = 81 - Height = 25 + Height = 13 Margins.Left = 0 Margins.Top = 0 Margins.Right = 5 @@ -354,7 +350,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Align = alLeft Caption = 'lbLastGeneration' Layout = tlCenter - ExplicitHeight = 13 end object btnExecuteSQL: TButton AlignWithMargins = True diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 31a6bb2..e42fe37 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -26,7 +26,7 @@ interface Clipbrd, DelphiAIDev.Types, DelphiAIDev.Consts, - DelphiAIDev.AI, + DelphiAIDev.AI.Facade, DelphiAIDev.Settings, DelphiAIDev.ModuleCreator, DelphiAIDev.DefaultsQuestions.PopupMenu, @@ -143,7 +143,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) procedure DBGrid1TitleClick(Column: TColumn); procedure btnGenerateDatabaseReferenceClick(Sender: TObject); private - FAI: TDelphiAIDevAI; + FAI: TDelphiAIDevAIFacade; FSettings: TDelphiAIDevSettings; FProcessResponse: TDelphiAIDevChatProcessResponse; FPopupMenuQuestions: TDelphiAIDevDefaultsQuestionsPopupMenu; @@ -237,7 +237,7 @@ constructor TDelphiAIDevDBChatView.Create(AOwner: TComponent); AutoSave := True; SaveStateNecessary := True; - FAI := TDelphiAIDevAI.Create; + FAI := TDelphiAIDevAIFacade.Create; FSettings := TDelphiAIDevSettings.GetInstance; FProcessResponse := TDelphiAIDevChatProcessResponse.Create(mmReturn); FPopupMenuQuestions := TDelphiAIDevDefaultsQuestionsPopupMenu.Create; @@ -766,7 +766,7 @@ procedure TDelphiAIDevDBChatView.ProcessSend; mmReturn.Lines.BeginUpdate; try //Optional use of one of the following lines - FProcessResponse.AddResponseComplete(FAI.Response); + FProcessResponse.AddResponseComplete(FAI.Response.GetContent); Self.Last; //Self.AddResponseSimple(FChat.Response.Text); finally From 2ba9a66edad0c2cbef83d5a8bdc82d72d8a5f087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Mon, 14 Oct 2024 07:23:29 -0300 Subject: [PATCH 094/109] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75857a7..7f672e7 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ To use AI offline, follow these steps:
## â–¶ï¸ DEMO VIDEO -We have also created a video with details on how to download, install and use the plugin. The video is in Portuguese (ptBR), but we are providing subtitles and possibly a video in English. +Para mais detalhes sobre o plugin, assista à nossa palestra, eleita como uma das melhores da Embarcadero Conference 2024. O vídeo está em português (pt-BR), mas estamos fornecendo legendas e, possivelmente, uma versão em inglês. * [https://www.youtube.com/watch?v=2NAlUFK2FGs](https://www.youtube.com/watch?v=2NAlUFK2FGs)
From cfeed40d9cf7d1da5f99ef03c264003a4ce2ea34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Mon, 14 Oct 2024 07:24:15 -0300 Subject: [PATCH 095/109] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f672e7..3afe124 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ To use AI offline, follow these steps:
## â–¶ï¸ DEMO VIDEO -Para mais detalhes sobre o plugin, assista à nossa palestra, eleita como uma das melhores da Embarcadero Conference 2024. O vídeo está em português (pt-BR), mas estamos fornecendo legendas e, possivelmente, uma versão em inglês. +For more details about the plugin, watch our talk, voted one of the best of Embarcadero Conference 2024. The video is in Portuguese (pt-BR), but we are providing subtitles and possibly an English version. * [https://www.youtube.com/watch?v=2NAlUFK2FGs](https://www.youtube.com/watch?v=2NAlUFK2FGs)
From 25bf7cafb37ca92a2fab0abc27b5d2660c0a784c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Mon, 14 Oct 2024 07:26:13 -0300 Subject: [PATCH 096/109] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3afe124..19ea112 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ To use AI offline, follow these steps: ## â–¶ï¸ DEMO VIDEO For more details about the plugin, watch our talk, voted one of the best of Embarcadero Conference 2024. The video is in Portuguese (pt-BR), but we are providing subtitles and possibly an English version. -* [https://www.youtube.com/watch?v=2NAlUFK2FGs](https://www.youtube.com/watch?v=2NAlUFK2FGs) +* [https://www.youtube.com/live/7UcfPyqR2TY?si=bLw27HQP4diF7TCB&t=2822](https://www.youtube.com/live/7UcfPyqR2TY?si=bLw27HQP4diF7TCB&t=2822)
From 187aad1574bf741ea0ec42eccf46276803f0f34c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:27:45 -0300 Subject: [PATCH 097/109] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 19ea112..e8fbede 100644 --- a/README.md +++ b/README.md @@ -63,10 +63,10 @@ Access the menu “AI Developer†> “Settings†> Tab “Preferencesâ€
-## ⚪ CONFIGURING IAS ONLINE +## ⚪ CONFIGURING AI ONLINE You can choose between 3 APIs, Gemini (Google), ChatGPT (OpenAI) and Groq. Gemini and Groq APIs are free. -Access the menu “AI Developer†> “Settings†> Tab “IAs on-line†+Access the menu “AI Developer†> “Settings†> Tab “AI on-line†![image](https://github.com/user-attachments/assets/2c3a45a2-94c8-4449-8c71-58246f6ca67f) 1. Inform the desired model. @@ -151,7 +151,7 @@ Note: If the current unit has any code selected, only the selected code snippet
-## 🟤 IAS OFF-LINE +## 🟤 AI OFF-LINE To use AI offline, follow these steps: 1. Install Ollama, which can be found at the following link: [https://ollama.com/download](https://ollama.com/download) @@ -159,7 +159,7 @@ To use AI offline, follow these steps: ![image](https://github.com/user-attachments/assets/1c259158-8118-421e-84ab-f6931b1438c0) 3. Open command prompt or terminal and run the command “ollama run †and wait for the installation to finish ![image](https://github.com/user-attachments/assets/b5c12854-5ce4-4fe7-aa49-b0396f0d4040) -4. **To configure**, access the menu “AI Developer†> “Settings†> Tab “IAs off-Line“ +4. **To configure**, access the menu “AI Developer†> “Settings†> Tab “AI off-Line“ ![image](https://github.com/user-attachments/assets/f821ab05-743a-480f-a72b-f7ca3809ae6b) From 24b9c855d6cead0bf50ce621059d80db5cab2eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Tue, 15 Oct 2024 17:53:24 -0300 Subject: [PATCH 098/109] bk/2024-10-15-1753 --- Src/Settings/DelphiAIDev.Settings.View.dfm | 22 +++++----------------- Src/Settings/DelphiAIDev.Settings.View.pas | 2 +- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 14e7cc2..05b6dbb 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -156,7 +156,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Margins.Right = 0 Margins.Bottom = 1 Align = alLeft - Caption = 'IAs on-line' + Caption = 'AI on-line' TabOrder = 1 OnClick = btnIAsOnlineClick end @@ -171,7 +171,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Margins.Right = 0 Margins.Bottom = 1 Align = alLeft - Caption = 'IAs off-Line' + Caption = 'AI off-Line' TabOrder = 2 OnClick = btnIAsOfflineClick end @@ -207,14 +207,10 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Top = 33 Width = 667 Height = 521 - ActivePage = TabSheet4 + ActivePage = TabSheet1 TabOrder = 1 object TabSheet1: TTabSheet Caption = 'Preferences' - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object pnPreferencesBack: TPanel Left = 0 Top = 0 @@ -326,12 +322,8 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end end object TabSheet2: TTabSheet - Caption = 'IAs on-line' + Caption = 'AI on-line' ImageIndex = 1 - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object pnIAsOnLineBack: TPanel Left = 0 Top = 0 @@ -872,12 +864,8 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end end object TabSheet3: TTabSheet - Caption = 'IAs off-Line' + Caption = 'AI off-Line' ImageIndex = 2 - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object pnIAsOffLineBack: TPanel Left = 0 Top = 0 diff --git a/Src/Settings/DelphiAIDev.Settings.View.pas b/Src/Settings/DelphiAIDev.Settings.View.pas index 0d5c909..c3271b3 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.pas +++ b/Src/Settings/DelphiAIDev.Settings.View.pas @@ -270,7 +270,7 @@ procedure TDelphiAIDevSettingsView.FormKeyDown(Sender: TObject; var Key: Word; S procedure TDelphiAIDevSettingsView.lbLinkGpt01Click(Sender: TObject); begin - //**Several + //**SEVERAL TUtils.OpenLink(TLabel(Sender).Hint.Trim); end; From d064bd7fed002d082cab42938c06f83d92ee42ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:28:41 -0300 Subject: [PATCH 099/109] Create LGPD.md --- LGPD.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 LGPD.md diff --git a/LGPD.md b/LGPD.md new file mode 100644 index 0000000..44686c9 --- /dev/null +++ b/LGPD.md @@ -0,0 +1,26 @@ +# LGPD Compliance + +The LGPD, or General Law for the Protection of Personal Data (Law No. 13.709/2018), is the Brazilian legislation that regulates the use, collection, storage and sharing of personal data of individuals in Brazil. + +## Introduction +**Delphi AI Developer** was developed for use in Delphi IDE in compliance with the guidelines of the General Law on the Protection of Personal Data (LGPD), ensuring that user data is not used by us. + +## Data Collection and Use +**Delphi AI Developer** uses Artificial Intelligence APIs to enhance the programming experience and facilitate interaction with the database structure. When operating, the plugin: +- **Sends code snippets and database structure to Artificial Intelligence APIs**, aiming to provide suggestions and automation in development. +- **Does not store any user information on external servers**, including code snippets, database structure or other personal data. + +## Database Structure Storage +The plugin **does not access, store or send data from the database** itself. Only the **database structure** is used, including the database name, table names, field names, field data types and field sizes. This structure is **stored locally in a JSON file** on the user's own computer, without being exposed to any server or external source. This local storage aims to optimize the plugin's performance and interaction with the APIs, while maintaining data security and privacy. + +## Data Subject Rights +Although Delphi AI Developer does not collect or store personal data, users can request more information about the functioning and data processing at any time. For questions related to the use of data by the tool, please contact **[contato@code4delphi.com.br](mailto:contato@code4delphi.com.br)**. + +## Segurança e Privacidade +O Delphi AI Developer adota medidas de segurança rigorosas para proteger as interações entre o plugin e as APIs de Inteligência Artificial, além de garantir que o arquivo JSON local seja seguro e acessível apenas ao usuário. Todo o processamento de dados é feito com transparência e alinhado aos princípios da LGPD. + +## Privacy Policy Updates +Any changes in LGPD compliance or data usage practices will be added to this page. + +## Contact +For questions or requests regarding the use of data by **Delphi AI Developer**, please contact **[contato@code4delphi.com.br](mailto:contato@code4delphi.com.br)**. From 1a364166b8fd365e3ed3cf7a7ea1e7dba3075e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:31:45 -0300 Subject: [PATCH 100/109] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index e8fbede..c69208e 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,11 @@ Any suggestions or help are welcome. Send us a pull request or open an [issue](/
+## 📄 LGPD Compliance +[Access information about LGPD](https://github.com/Code4Delphi/Delphi-AI-Developer/blob/master/LGPD.md) + +
+ ## âš ï¸ LICENSE `Delphi AI Developer` is free and open-source wizard licensed under the [MIT License](LICENSE). From 489e95bc163c90678c3890b332806a668db4769f Mon Sep 17 00:00:00 2001 From: Lucas Rubian Schatz Date: Fri, 31 Jan 2025 11:28:13 -0300 Subject: [PATCH 101/109] Add support for Mistral.ai models --- Package/DelphiAIDeveloper.dpk | 3 +- Src/AI/DelphiAIDev.AI.Facade.pas | 3 + Src/AI/DelphiAIDev.AI.Mistral.pas | 84 ++++++++ Src/Consts/DelphiAIDev.Consts.pas | 3 + Src/Settings/DelphiAIDev.Settings.View.dfm | 221 ++++++++++++++++++--- Src/Settings/DelphiAIDev.Settings.View.pas | 34 ++++ Src/Settings/DelphiAIDev.Settings.pas | 40 ++++ Src/Types/DelphiAIDev.Types.pas | 2 +- 8 files changed, 358 insertions(+), 32 deletions(-) create mode 100644 Src/AI/DelphiAIDev.AI.Mistral.pas diff --git a/Package/DelphiAIDeveloper.dpk b/Package/DelphiAIDeveloper.dpk index 576683c..28b6eda 100644 --- a/Package/DelphiAIDeveloper.dpk +++ b/Package/DelphiAIDeveloper.dpk @@ -114,6 +114,7 @@ contains DelphiAIDev.CodeCompletion.Search in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.Search.pas', DelphiAIDev.Test.Client in '..\Src\Test\DelphiAIDev.Test.Client.pas', DelphiAIDev.CodeCompletion.KeyTab in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.KeyTab.pas', - DelphiAIDev.AI.Response in '..\Src\AI\DelphiAIDev.AI.Response.pas'; + DelphiAIDev.AI.Response in '..\Src\AI\DelphiAIDev.AI.Response.pas', + DelphiAIDev.AI.Mistral in '..\Src\AI\DelphiAIDev.AI.Mistral.pas'; end. diff --git a/Src/AI/DelphiAIDev.AI.Facade.pas b/Src/AI/DelphiAIDev.AI.Facade.pas index ab1e983..d7f418d 100644 --- a/Src/AI/DelphiAIDev.AI.Facade.pas +++ b/Src/AI/DelphiAIDev.AI.Facade.pas @@ -13,6 +13,7 @@ interface DelphiAIDev.AI.Gemini, DelphiAIDev.AI.ChatGPT, DelphiAIDev.AI.Groq, + DelphiAIDev.AI.Mistral, DelphiAIDev.AI.Ollama; type @@ -70,6 +71,8 @@ function TDelphiAIDevAIFacade.ProcessSend(const AQuestion: string): TDelphiAIDev LRequest := TDelphiAIDevAIChatGPT.Create(FSettings, FResponse); TC4DAiAvailable.Groq: LRequest := TDelphiAIDevAIGroq.Create(FSettings, FResponse); + TC4DAiAvailable.Mistral: + LRequest := TDelphiAIDevAIMistral.Create(FSettings, FResponse); TC4DAiAvailable.Ollama: LRequest := TDelphiAIDevAIOllama.Create(FSettings, FResponse); else diff --git a/Src/AI/DelphiAIDev.AI.Mistral.pas b/Src/AI/DelphiAIDev.AI.Mistral.pas new file mode 100644 index 0000000..572dcba --- /dev/null +++ b/Src/AI/DelphiAIDev.AI.Mistral.pas @@ -0,0 +1,84 @@ +unit DelphiAIDev.AI.Mistral; + +interface + +uses + System.SysUtils, + System.JSON, + System.Classes, + RESTRequest4D, + DelphiAIDev.Consts, + DelphiAIDev.Utils, + DelphiAIDev.Settings, + DelphiAIDev.AI.Interfaces; + +type + TDelphiAIDevAIMistral = class(TInterfacedObject, IDelphiAIDevAI) + private + FSettings: TDelphiAIDevSettings; + FResponse: IDelphiAIDevAIResponse; + protected + function GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; + public + constructor Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); + end; + +implementation + +const + API_JSON_BODY_BASE = '{"messages": [{"role": "user", "content": "%s"}], "model": "%s"}'; + +constructor TDelphiAIDevAIMistral.Create(const ASettings: TDelphiAIDevSettings; const AResponse: IDelphiAIDevAIResponse); +begin + FSettings := ASettings; + FResponse := AResponse; +end; + +function TDelphiAIDevAIMistral.GetResponse(const AQuestion: string): IDelphiAIDevAIResponse; +var + LResponse: IResponse; + LJsonValueAll: TJSONVALUE; + LJsonArrayChoices: TJsonArray; + LJsonObjMessage: TJsonObject; + LContent: string; + LItemChoices: Integer; + LResult: string; +begin + Result := FResponse; + + LResponse := TRequest.New + .BaseURL(FSettings.BaseUrlMistral) + .ContentType(TConsts.APPLICATION_JSON) + .Accept(TConsts.APPLICATION_JSON) + .Token('Bearer ' + FSettings.ApiKeyMistral) + .AddBody(Format(API_JSON_BODY_BASE, [AQuestion, FSettings.ModelMistral])) + .Post; + + FResponse.SetStatusCode(LResponse.StatusCode); + + if LResponse.StatusCode <> 200 then + begin + FResponse.SetContentText('Question cannot be answered' + sLineBreak + 'Return: ' + LResponse.Content); + Exit; + end; + + LJsonValueAll := TJsonObject.ParseJSONValue(LResponse.Content); + if not(LJsonValueAll is TJSONObject) then + begin + FResponse.SetContentText('The question cannot be answered, return object not found.' + sLineBreak + + 'Return: ' + LResponse.Content); + Exit; + end; + + LJsonArrayChoices := (LJsonValueAll as TJsonObject).GetValue('choices'); + for LItemChoices := 0 to Pred(LJsonArrayChoices.Count) do + begin + LJsonObjMessage := LJsonArrayChoices.Items[LItemChoices].GetValue('message'); + LContent := LJsonObjMessage.GetValue('content'); + LResult := LResult + LContent.Trim + sLineBreak; + end; + + FResponse.SetContentText(LResult.Trim); +end; + +end. diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index ee03c30..f37a1a9 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -38,6 +38,9 @@ TConsts = class BASE_URL_GROQ = 'https://api.groq.com/openai/v1/chat/completions'; MODEL_GROQ_DEFAULT = 'llama3-70b-8192'; //'llama3-8b-8192';; + BASE_URL_Mistral = 'https://api.mistral.ai/v1/chat/completions'; + MODEL_Mistral_DEFAULT = 'mistral-small-latest'; + BASE_URL_OLLAMA = 'http://localhost:11434/api/chat'; MODEL_OLLAMA_DEFAULT = ''; //'tinyllama' 'mistral'; diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 14e7cc2..bb9eb4d 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -2,7 +2,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Caption = 'Delphi AI Developer - Settings' - ClientHeight = 601 + ClientHeight = 676 ClientWidth = 670 Color = clBtnFace Font.Charset = DEFAULT_CHARSET @@ -11,25 +11,25 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Font.Name = 'Tahoma' Font.Style = [] KeyPreview = True - OldCreateOrder = False Position = poScreenCenter OnClose = FormClose OnCreate = FormCreate OnKeyDown = FormKeyDown OnShow = FormShow - PixelsPerInch = 96 TextHeight = 13 object pnBackAll: TPanel Left = 0 Top = 0 Width = 670 - Height = 601 + Height = 676 Align = alClient BevelOuter = bvNone TabOrder = 0 + ExplicitWidth = 664 + ExplicitHeight = 659 object pnBottom: TPanel Left = 0 - Top = 566 + Top = 641 Width = 670 Height = 35 Margins.Left = 0 @@ -44,6 +44,8 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Padding.Bottom = 2 ParentBackground = False TabOrder = 0 + ExplicitTop = 624 + ExplicitWidth = 664 object lbRestoreDefaults: TLabel AlignWithMargins = True Left = 16 @@ -82,6 +84,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Caption = 'Confirm' TabOrder = 0 OnClick = btnConfirmClick + ExplicitLeft = 436 end object btnClose: TButton AlignWithMargins = True @@ -97,16 +100,19 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Caption = 'Close' TabOrder = 1 OnClick = btnCloseClick + ExplicitLeft = 549 end end object pnMyControl: TPanel Left = 0 Top = 0 Width = 670 - Height = 566 + Height = 641 Align = alClient BevelOuter = bvNone TabOrder = 1 + ExplicitWidth = 664 + ExplicitHeight = 624 object pnMyControlButtons: TPanel Left = 0 Top = 0 @@ -116,6 +122,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView BevelEdges = [beBottom] BevelOuter = bvNone TabOrder = 0 + ExplicitWidth = 664 object Bevel5: TBevel AlignWithMargins = True Left = 0 @@ -195,10 +202,12 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 30 Width = 670 - Height = 536 + Height = 611 Align = alClient BevelOuter = bvNone TabOrder = 1 + ExplicitWidth = 664 + ExplicitHeight = 594 end end end @@ -206,20 +215,16 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 33 Width = 667 - Height = 521 + Height = 592 ActivePage = TabSheet4 TabOrder = 1 object TabSheet1: TTabSheet Caption = 'Preferences' - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object pnPreferencesBack: TPanel Left = 0 Top = 0 Width = 659 - Height = 493 + Height = 564 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -228,7 +233,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 659 - Height = 493 + Height = 564 Align = alClient Caption = ' Preferences ' ParentBackground = False @@ -293,7 +298,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object gboxData: TGroupBox Left = 2 - Top = 433 + Top = 504 Width = 655 Height = 58 Align = alBottom @@ -328,15 +333,11 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object TabSheet2: TTabSheet Caption = 'IAs on-line' ImageIndex = 1 - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object pnIAsOnLineBack: TPanel Left = 0 Top = 0 Width = 659 - Height = 493 + Height = 564 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -344,7 +345,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object Bevel1: TBevel AlignWithMargins = True Left = 0 - Top = 489 + Top = 560 Width = 659 Height = 1 Margins.Left = 0 @@ -358,7 +359,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object Bevel2: TBevel AlignWithMargins = True Left = 0 - Top = 381 + Top = 505 Width = 659 Height = 1 Margins.Left = 0 @@ -869,20 +870,180 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end end end + object gBoxMistral: TGroupBox + Left = 0 + Top = 381 + Width = 659 + Height = 124 + Align = alTop + Caption = ' Mistral ' + ParentBackground = False + TabOrder = 3 + object pnMistralBack: TPanel + AlignWithMargins = True + Left = 5 + Top = 18 + Width = 649 + Height = 101 + Align = alClient + BevelOuter = bvNone + ParentBackground = False + TabOrder = 0 + object Label20: TLabel + Left = 16 + Top = 5 + Width = 45 + Height = 13 + Caption = 'Base URL' + end + object Label21: TLabel + Left = 16 + Top = 44 + Width = 37 + Height = 13 + Caption = 'API key' + end + object Label22: TLabel + Left = 374 + Top = 5 + Width = 28 + Height = 13 + Caption = 'Model' + end + object lbLinkMistral01: TLabel + Left = 16 + Top = 84 + Width = 86 + Height = 13 + Cursor = crHandPoint + Hint = 'https://console.mistral.ai/api-keys/' + Caption = 'Generate API Key' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object btnApiKeyMistralView: TSpeedButton + Left = 582 + Top = 59 + Width = 23 + Height = 22 + Cursor = crHandPoint + Hint = 'Show/Hide API Key' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C + BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF + 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF + 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 + B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD + EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF + FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 + C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF + FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF + E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 + C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 + C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 + DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 + 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + OnClick = btnApiKeyMistralViewClick + end + object lbLinkMistral02: TLabel + Left = 128 + Top = 84 + Width = 72 + Height = 13 + Cursor = crHandPoint + Hint = 'https://docs.mistral.ai/getting-started/quickstart/' + Caption = 'Documentation' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object lbLinkMistral03: TLabel + Left = 232 + Top = 84 + Width = 67 + Height = 13 + Cursor = crHandPoint + Hint = 'https://docs.mistral.ai/getting-started/models/models_overview/' + Caption = 'Mistral Models' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = lbLinkGpt01Click + end + object edtBaseUrlMistral: TEdit + Left = 16 + Top = 21 + Width = 356 + Height = 21 + TabOrder = 0 + end + object edtApiKeyMistral: TEdit + Left = 16 + Top = 60 + Width = 563 + Height = 21 + PasswordChar = '*' + TabOrder = 2 + end + object cBoxModelMistral: TComboBox + Left = 374 + Top = 21 + Width = 226 + Height = 21 + TabOrder = 1 + Items.Strings = ( + 'codestral-latest' + 'mistral-large-latest' + 'ministral-3b-latest' + 'ministral-8b-latest' + 'mistral-small-latest' + 'open-codestral-mamba') + end + end + end end end object TabSheet3: TTabSheet Caption = 'IAs off-Line' ImageIndex = 2 - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object pnIAsOffLineBack: TPanel Left = 0 Top = 0 Width = 659 - Height = 493 + Height = 564 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -1060,7 +1221,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 659 - Height = 493 + Height = 564 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -1069,7 +1230,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 659 - Height = 493 + Height = 564 Align = alClient Caption = ' Code Completion (BETA) ' ParentBackground = False @@ -1079,7 +1240,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 5 Top = 18 Width = 649 - Height = 470 + Height = 541 Align = alClient BevelOuter = bvNone ParentBackground = False diff --git a/Src/Settings/DelphiAIDev.Settings.View.pas b/Src/Settings/DelphiAIDev.Settings.View.pas index 0d5c909..fbe7d1e 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.pas +++ b/Src/Settings/DelphiAIDev.Settings.View.pas @@ -119,6 +119,18 @@ TDelphiAIDevSettingsView = class(TForm) mmCodeCompletionDefaultPrompt: TMemo; Label19: TLabel; mmDefaultPrompt: TMemo; + gBoxMistral: TGroupBox; + pnMistralBack: TPanel; + Label20: TLabel; + Label21: TLabel; + Label22: TLabel; + lbLinkMistral01: TLabel; + btnApiKeyMistralView: TSpeedButton; + lbLinkMistral02: TLabel; + lbLinkMistral03: TLabel; + edtBaseUrlMistral: TEdit; + edtApiKeyMistral: TEdit; + cBoxModelMistral: TComboBox; procedure FormCreate(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure btnCloseClick(Sender: TObject); @@ -138,6 +150,7 @@ TDelphiAIDevSettingsView = class(TForm) procedure btnCodeCompletionClick(Sender: TObject); procedure btnOpenDataFolderClick(Sender: TObject); procedure ckCodeCompletionSuggestionColorUseClick(Sender: TObject); + procedure btnApiKeyMistralViewClick(Sender: TObject); private FSettings: TDelphiAIDevSettings; procedure SaveSettings; @@ -229,6 +242,9 @@ procedure TDelphiAIDevSettingsView.ConfigScreen; lbLinkGroq01.Font.Color := LColor; lbLinkGroq02.Font.Color := LColor; lbLinkGroq03.Font.Color := LColor; + lbLinkMistral01.Font.Color := LColor; + lbLinkMistral02.Font.Color := LColor; + lbLinkMistral03.Font.Color := LColor; lbRestoreDefaults.Font.Color := LColor; lbLinkOllama01.Font.Color := LColor; lbLinkOllama02.Font.Color := LColor; @@ -250,6 +266,11 @@ procedure TDelphiAIDevSettingsView.btnApiKeyGroqViewClick(Sender: TObject); TUtils.TogglePasswordChar(edtApiKeyGroq); end; +procedure TDelphiAIDevSettingsView.btnApiKeyMistralViewClick(Sender: TObject); +begin + TUtils.TogglePasswordChar(edtApiKeyMistral); +end; + procedure TDelphiAIDevSettingsView.btnCloseClick(Sender: TObject); begin Self.Close; @@ -279,11 +300,13 @@ procedure TDelphiAIDevSettingsView.lbRestoreDefaultsClick(Sender: TObject); LApiKeyGemini: string; LApiKeyOpenAI: string; LApiKeyGroq: string; + LApiKeyMistral: string; LApiKeyOllama: string; begin LApiKeyGemini := FSettings.ApiKeyGemini; LApiKeyOpenAI := FSettings.ApiKeyOpenAI; LApiKeyGroq := FSettings.ApiKeyGroq; + LApiKeyMistral := FSettings.ApiKeyMistral; LApiKeyOllama := FSettings.ApiKeyOllama; FSettings.LoadDefaults; @@ -291,6 +314,7 @@ procedure TDelphiAIDevSettingsView.lbRestoreDefaultsClick(Sender: TObject); FSettings.ApiKeyGemini := LApiKeyGemini; FSettings.ApiKeyOpenAI := LApiKeyOpenAI; FSettings.ApiKeyGroq := LApiKeyGroq; + FSettings.ApiKeyMistral := LApiKeyMistral; FSettings.ApiKeyOllama := LApiKeyOllama; Self.LoadSettings; @@ -375,6 +399,12 @@ procedure TDelphiAIDevSettingsView.LoadSettings; cBoxModelGroq.Text := FSettings.ModelGroq; edtApiKeyGroq.Text := FSettings.ApiKeyGroq; + edtBaseUrlMistral.Text := FSettings.BaseUrlMistral; + cBoxModelMistral.ItemIndex := cBoxModelMistral.Items.IndexOf(FSettings.ModelMistral); + if cBoxModelMistral.ItemIndex < 0 then + cBoxModelMistral.Text := FSettings.ModelMistral; + edtApiKeyMistral.Text := FSettings.ApiKeyMistral; + edtBaseUrlOllama.Text := FSettings.BaseUrlOllama; cBoxModelOllama.ItemIndex := cBoxModelOllama.Items.IndexOf(FSettings.ModelOllama); if cBoxModelOllama.ItemIndex < 0 then @@ -410,6 +440,10 @@ procedure TDelphiAIDevSettingsView.SaveSettings; FSettings.ModelGroq := cBoxModelGroq.Text; FSettings.ApiKeyGroq := edtApiKeyGroq.Text; + FSettings.BaseUrlMistral := edtBaseUrlMistral.Text; + FSettings.ModelMistral := cBoxModelMistral.Text; + FSettings.ApiKeyMistral := edtApiKeyMistral.Text; + FSettings.BaseUrlOllama := edtBaseUrlOllama.Text; FSettings.ModelOllama := cBoxModelOllama.Text; FSettings.ApiKeyOllama := edtApiKeyOllama.Text; diff --git a/Src/Settings/DelphiAIDev.Settings.pas b/Src/Settings/DelphiAIDev.Settings.pas index ac9d175..7b73466 100644 --- a/Src/Settings/DelphiAIDev.Settings.pas +++ b/Src/Settings/DelphiAIDev.Settings.pas @@ -35,6 +35,9 @@ TDelphiAIDevSettings = class FIELD_BaseUrlGroq = 'BaseUrlGroq'; FIELD_ModelGroq = 'ModelGroq'; FIELD_ApiKeyGroq = 'ApiKeyGroq'; + FIELD_BaseUrlMistral = 'BaseUrlMistral'; + FIELD_ModelMistral = 'ModelMistral'; + FIELD_ApiKeyMistral = 'ApiKeyMistral'; FIELD_BaseUrlOllama = 'BaseUrlOllama'; FIELD_ModelOllama = 'ModelOllama'; FIELD_ApiKeyOllama = 'ApiKeyOllama'; @@ -64,6 +67,10 @@ TDelphiAIDevSettings = class FModelGroq: string; FApiKeyGroq: string; + FBaseUrlMistral: string; + FModelMistral: string; + FApiKeyMistral: string; + FBaseUrlOllama: string; FModelOllama: string; FApiKeyOllama: string; @@ -104,6 +111,10 @@ TDelphiAIDevSettings = class property ModelGroq: string read FModelGroq write FModelGroq; property ApiKeyGroq: string read FApiKeyGroq write FApiKeyGroq; + property BaseUrlMistral: string read FBaseUrlMistral write FBaseUrlMistral; + property ModelMistral: string read FModelMistral write FModelMistral; + property ApiKeyMistral: string read FApiKeyMistral write FApiKeyMistral; + property BaseUrlOllama: string read FBaseUrlOllama write FBaseUrlOllama; property ModelOllama: string read FModelOllama write FModelOllama; property ApiKeyOllama: string read FApiKeyOllama write FApiKeyOllama; @@ -154,6 +165,10 @@ procedure TDelphiAIDevSettings.LoadDefaults; FModelGroq := TConsts.MODEL_GROQ_DEFAULT; FApiKeyGroq := ''; + FBaseUrlMistral := TConsts.BASE_URL_Mistral; + FModelMistral := TConsts.MODEL_Mistral_DEFAULT; + FApiKeyMistral := ''; + FBaseUrlOllama := TConsts.BASE_URL_OLLAMA; FModelOllama := TConsts.MODEL_OLLAMA_DEFAULT; FApiKeyOllama := ''; @@ -196,6 +211,10 @@ procedure TDelphiAIDevSettings.SaveData; LReg.WriteString(FIELD_ModelGroq, FModelGroq); LReg.WriteString(FIELD_ApiKeyGroq, FApiKeyGroq); + LReg.WriteString(FIELD_BaseUrlMistral, FBaseUrlMistral); + LReg.WriteString(FIELD_ModelMistral, FModelMistral); + LReg.WriteString(FIELD_ApiKeyMistral, FApiKeyMistral); + LReg.WriteString(FIELD_BaseUrlOllama, FBaseUrlOllama); LReg.WriteString(FIELD_ModelOllama, FModelOllama); LReg.WriteString(FIELD_ApiKeyOllama, FApiKeyOllama); @@ -285,6 +304,16 @@ procedure TDelphiAIDevSettings.LoadData; if LReg.ValueExists(FIELD_ApiKeyGroq) then fApiKeyGroq := LReg.ReadString(FIELD_ApiKeyGroq); + //MISTRAL + if LReg.ValueExists(FIELD_BaseUrlMistral) then + fBaseUrlMistral := LReg.ReadString(FIELD_BaseUrlMistral); + + if LReg.ValueExists(FIELD_ModelMistral) then + fModelMistral := LReg.ReadString(FIELD_ModelMistral); + + if LReg.ValueExists(FIELD_ApiKeyMistral) then + fApiKeyMistral := LReg.ReadString(FIELD_ApiKeyMistral); + //OLLAMA if LReg.ValueExists(FIELD_BaseUrlOllama) then fBaseUrlOllama := LReg.ReadString(FIELD_BaseUrlOllama); @@ -359,6 +388,17 @@ procedure TDelphiAIDevSettings.ValidateFillingSelectedAIInternal( if FApiKeyGroq.Trim.IsEmpty then ShowMsgInternal(['API Key', 'Groq']); end; + TC4DAiAvailable.Mistral: + begin + if FBaseUrlMistral.Trim.IsEmpty then + ShowMsgInternal(['Base URL', 'Mistral']); + + if FModelMistral.Trim.IsEmpty then + ShowMsgInternal(['Model', 'Mistral']); + + if FApiKeyMistral.Trim.IsEmpty then + ShowMsgInternal(['API Key', 'Mistral']); + end; TC4DAiAvailable.Ollama: begin if FBaseUrlOllama.Trim.IsEmpty then diff --git a/Src/Types/DelphiAIDev.Types.pas b/Src/Types/DelphiAIDev.Types.pas index 27097b0..08a8b70 100644 --- a/Src/Types/DelphiAIDev.Types.pas +++ b/Src/Types/DelphiAIDev.Types.pas @@ -11,7 +11,7 @@ interface TC4DWizardMenuContextList = procedure(const MenuContextList: IInterfaceList) of object; {$SCOPEDENUMS ON} - TC4DAiAvailable = (Gemini, OpenAI, Groq, Ollama); + TC4DAiAvailable = (Gemini, OpenAI, Groq, Mistral, Ollama); TC4DLanguage = (en, ptBR, es); TC4DExtensionsFiles = (None, PAS, DFM, FMX, DPR, DPK, DPROJ, GROUPPROJ, ZIP, BMP, INI, ALL); TC4DExtensionsOfFiles = set of TC4DExtensionsFiles; From 225d80ece6a4077617b3e73ed7a1dbfa3f57e62c Mon Sep 17 00:00:00 2001 From: Lucas Rubian Schatz Date: Fri, 31 Jan 2025 11:44:24 -0300 Subject: [PATCH 102/109] Add missing mistral.ai related code --- Src/Chat/DelphiAIDev.Chat.View.dfm | 24 ++++++++++++-- Src/Chat/DelphiAIDev.Chat.View.pas | 7 ++++- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 40 +++++++++++++++++++----- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 7 ++++- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index 264b2a0..064453f 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -22,7 +22,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView DesignSize = ( 975 661) - PixelsPerInch = 96 TextHeight = 13 object pnBack: TPanel Left = 0 @@ -40,6 +39,8 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Padding.Top = 15 ParentBackground = False TabOrder = 0 + ExplicitWidth = 950 + ExplicitHeight = 644 object Splitter1: TSplitter Left = 18 Top = 518 @@ -80,7 +81,8 @@ object DelphiAIDevChatView: TDelphiAIDevChatView ScrollBars = ssVertical ShowHint = True TabOrder = 1 - Zoom = 100 + ExplicitWidth = 932 + ExplicitHeight = 483 end object pnBackQuestion: TPanel Left = 18 @@ -96,6 +98,8 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Padding.Top = 5 ParentBackground = False TabOrder = 0 + ExplicitTop = 504 + ExplicitWidth = 932 object mmQuestion: TMemo AlignWithMargins = True Left = 0 @@ -117,6 +121,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView OnChange = mmQuestionChange OnKeyDown = mmQuestionKeyDown OnKeyUp = mmQuestionKeyUp + ExplicitWidth = 932 end end object pnBackButtons: TPanel @@ -134,11 +139,13 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Padding.Bottom = 2 ParentBackground = False TabOrder = 2 + ExplicitTop = 617 + ExplicitWidth = 932 object lbCurrentAI: TLabel Left = 0 Top = 3 Width = 56 - Height = 13 + Height = 22 Cursor = crHandPoint Hint = 'AI being used' Margins.Left = 0 @@ -149,6 +156,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'lbCurrentAI' PopupMenu = pMenuCurrentAI OnClick = lbCurrentAIClick + ExplicitHeight = 13 end object btnSend: TButton AlignWithMargins = True @@ -164,6 +172,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'Send' TabOrder = 0 OnClick = btnSendClick + ExplicitLeft = 858 end object pnBackConfigurableButtons: TPanel Left = 395 @@ -173,6 +182,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Align = alRight BevelOuter = bvNone TabOrder = 1 + ExplicitLeft = 389 object btnUseCurrentUnitCode: TButton AlignWithMargins = True Left = 261 @@ -279,6 +289,8 @@ object DelphiAIDevChatView: TDelphiAIDevChatView item Width = 50 end> + ExplicitLeft = 950 + ExplicitHeight = 644 end object pnCommands: TPanel Left = 936 @@ -293,6 +305,7 @@ object DelphiAIDevChatView: TDelphiAIDevChatView BevelOuter = bvNone ParentBackground = False TabOrder = 3 + ExplicitLeft = 930 DesignSize = ( 26 115) @@ -817,6 +830,11 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'Groq' OnClick = Gemini1Click end + object Mistral1: TMenuItem + Tag = 2 + Caption = 'Mistral' + OnClick = Gemini1Click + end object Ollama1: TMenuItem Tag = 3 Caption = 'Ollama (offline)' diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index 1c695ba..8f06147 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -74,6 +74,7 @@ TDelphiAIDevChatView = class(TDockableForm) pMenuQuestions: TPopupMenu; btnCleanAll: TSpeedButton; Groq1: TMenuItem; + Mistral1: TMenuItem; Ollama1: TMenuItem; procedure FormShow(Sender: TObject); procedure cBoxSizeFontKeyPress(Sender: TObject; var Key: Char); @@ -620,6 +621,8 @@ procedure TDelphiAIDevChatView.pMenuCurrentAIPopup(Sender: TObject); ChatGPT1.Checked := True; TC4DAiAvailable.Groq: Groq1.Checked := True; + TC4DAiAvailable.Mistral: + Mistral1.Checked := True; TC4DAiAvailable.Ollama: Ollama1.Checked := True; end; @@ -636,6 +639,8 @@ procedure TDelphiAIDevChatView.ConfLabelCurrentAI; lbCurrentAI.Hint := FSettings.ModelOpenAI; TC4DAiAvailable.Groq: lbCurrentAI.Hint := FSettings.ModelGroq; + TC4DAiAvailable.Mistral: + lbCurrentAI.Hint := FSettings.ModelMistral; TC4DAiAvailable.Ollama: lbCurrentAI.Hint := FSettings.ModelOllama; end; @@ -650,7 +655,7 @@ procedure TDelphiAIDevChatView.Gemini1Click(Sender: TObject); begin //*SEVERAL LTag := TMenuItem(Sender).Tag; - if not(LTag in [0, 1, 2, 3])then + if not(LTag in [0, 1, 2, 3, 4])then Exit; FSettings.AIDefault := TC4DAiAvailable(LTag); diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index ce46b48..7c00112 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -22,7 +22,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView DesignSize = ( 975 661) - PixelsPerInch = 96 TextHeight = 13 object pnBack: TPanel Left = 0 @@ -40,6 +39,8 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Top = 15 ParentBackground = False TabOrder = 0 + ExplicitWidth = 950 + ExplicitHeight = 644 object Splitter1: TSplitter Left = 18 Top = 153 @@ -91,7 +92,8 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView ScrollBars = ssVertical ShowHint = True TabOrder = 1 - Zoom = 100 + ExplicitWidth = 932 + ExplicitHeight = 268 end object pnBackQuestion: TPanel Left = 18 @@ -107,6 +109,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Top = 5 ParentBackground = False TabOrder = 0 + ExplicitWidth = 932 object Label2: TLabel Left = 0 Top = 5 @@ -140,6 +143,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView OnChange = mmQuestionChange OnKeyDown = mmQuestionKeyDown OnKeyUp = mmQuestionKeyUp + ExplicitWidth = 932 end end object pnBackButtonsSearch: TPanel @@ -157,11 +161,12 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Bottom = 2 ParentBackground = False TabOrder = 2 + ExplicitWidth = 932 object lbCurrentAI: TLabel Left = 0 Top = 3 Width = 56 - Height = 13 + Height = 22 Cursor = crHandPoint Hint = 'AI being used' Margins.Left = 0 @@ -172,6 +177,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Caption = 'lbCurrentAI' PopupMenu = pMenuCurrentAI OnClick = lbCurrentAIClick + ExplicitHeight = 13 end object btnSend: TButton AlignWithMargins = True @@ -187,6 +193,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Caption = 'Send' TabOrder = 0 OnClick = btnSendClick + ExplicitLeft = 858 end object pnBackConfigurableButtons: TPanel Left = 395 @@ -196,6 +203,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Align = alRight BevelOuter = bvNone TabOrder = 1 + ExplicitLeft = 389 object btnUseCurrentUnitCode: TButton AlignWithMargins = True Left = 261 @@ -262,6 +270,8 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView BevelOuter = bvNone ParentBackground = False TabOrder = 3 + ExplicitTop = 484 + ExplicitWidth = 932 object DBGrid1: TDBGrid Left = 0 Top = 0 @@ -294,23 +304,26 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Bottom = 3 ParentBackground = False TabOrder = 1 + ExplicitWidth = 932 object lbCount: TLabel Left = 899 Top = 3 Width = 36 - Height = 13 + Height = 21 Align = alRight Caption = '000000' Layout = tlCenter + ExplicitHeight = 13 end object Label3: TLabel Left = 863 Top = 3 Width = 36 - Height = 13 + Height = 21 Align = alRight Caption = 'Count: ' Layout = tlCenter + ExplicitHeight = 13 end end end @@ -328,21 +341,24 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Bottom = 2 ParentBackground = False TabOrder = 4 + ExplicitTop = 454 + ExplicitWidth = 932 object Label1: TLabel Left = 337 Top = 0 Width = 85 - Height = 13 + Height = 25 Align = alLeft Caption = ' Last generation: ' Layout = tlCenter + ExplicitHeight = 13 end object lbLastGeneration: TLabel AlignWithMargins = True Left = 422 Top = 0 Width = 81 - Height = 13 + Height = 25 Margins.Left = 0 Margins.Top = 0 Margins.Right = 5 @@ -350,6 +366,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Align = alLeft Caption = 'lbLastGeneration' Layout = tlCenter + ExplicitHeight = 13 end object btnExecuteSQL: TButton AlignWithMargins = True @@ -368,6 +385,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Images = ImageList1 TabOrder = 0 OnClick = btnExecuteSQLClick + ExplicitLeft = 819 end object cBoxDatabases: TComboBox AlignWithMargins = True @@ -445,6 +463,8 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView item Width = 50 end> + ExplicitLeft = 950 + ExplicitHeight = 644 end object pnCommands: TPanel Left = 947 @@ -459,6 +479,7 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView BevelOuter = bvNone ParentBackground = False TabOrder = 3 + ExplicitLeft = 941 DesignSize = ( 26 115) @@ -983,6 +1004,11 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Caption = 'Groq' OnClick = Gemini1Click end + object Mistral1: TMenuItem + Tag = 2 + Caption = 'Mistral' + OnClick = Gemini1Click + end object Ollama1: TMenuItem Tag = 3 Caption = 'Ollama (offline)' diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index e42fe37..2db29fc 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -83,6 +83,7 @@ TDelphiAIDevDBChatView = class(TDockableForm) pMenuQuestions: TPopupMenu; btnCleanAll: TSpeedButton; Groq1: TMenuItem; + Mistral1: TMenuItem; pnGridBack: TPanel; DBGrid1: TDBGrid; Splitter2: TSplitter; @@ -619,6 +620,8 @@ procedure TDelphiAIDevDBChatView.pMenuCurrentAIPopup(Sender: TObject); ChatGPT1.Checked := True; TC4DAiAvailable.Groq: Groq1.Checked := True; + TC4DAiAvailable.Mistral: + Mistral1.Checked := True; TC4DAiAvailable.Ollama: Ollama1.Checked := True; end; @@ -635,6 +638,8 @@ procedure TDelphiAIDevDBChatView.ConfLabelCurrentAI; lbCurrentAI.Hint := FSettings.ModelOpenAI; TC4DAiAvailable.Groq: lbCurrentAI.Hint := FSettings.ModelGroq; + TC4DAiAvailable.Mistral: + lbCurrentAI.Hint := FSettings.ModelMistral; TC4DAiAvailable.Ollama: lbCurrentAI.Hint := FSettings.ModelOllama; end; @@ -649,7 +654,7 @@ procedure TDelphiAIDevDBChatView.Gemini1Click(Sender: TObject); begin //*SEVERAL LTag := TMenuItem(Sender).Tag; - if not(LTag in [0, 1, 2, 3])then + if not(LTag in [0, 1, 2, 3, 4])then Exit; FSettings.AIDefault := TC4DAiAvailable(LTag); From 8689820b23ec01fa91f76c56a49516517a5f4bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Fri, 28 Feb 2025 15:31:11 -0300 Subject: [PATCH 103/109] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index c69208e..55f3554 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,14 @@ Receive suggestions for creating and improving code directly in the IDE and take ## 📞 Contacts +[![Telegram](https://img.shields.io/badge/Telegram-Join-blue?logo=telegram)](https://t.me/Code4Delphi) +[![YouTube](https://img.shields.io/badge/YouTube-Join-red?logo=youtube&logoColor=red)](https://www.youtube.com/@code4delphi) +[![Instagram](https://img.shields.io/badge/Intagram-Follow-red?logo=instagram&logoColor=pink)](https://www.instagram.com/code4delphi/) +[![LinkedIn](https://img.shields.io/badge/LinkedIn-Connect-blue)](https://www.linkedin.com/in/cesar-cardoso-dev) +[![Blog](https://img.shields.io/badge/Blog-Code4Delphi-F00?logo=delphi)](https://code4delphi.com.br/blog/) +[![Course](https://img.shields.io/badge/Course-Delphi-F00?logo=delphi)](https://go.hotmart.com/U81331747Y?dp=1) +[![E-mail](https://img.shields.io/badge/E--mail-Send-yellowgreen?logo=maildotru&logoColor=yellowgreen)](mailto:contato@code4delphi.com.br) +

From 5a72bf2c66736b9d95dfe6dcd9254bc00c76799f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Baddini?= Date: Thu, 6 Mar 2025 16:53:33 -0300 Subject: [PATCH 104/109] =?UTF-8?q?Adi=C3=A7=C3=A3o=20do=20modelo=20"gpt-4?= =?UTF-8?q?-turbo"=20para=20OpenAI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Src/Settings/DelphiAIDev.Settings.View.dfm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 14e7cc2..35e4717 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -699,7 +699,8 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView 'gpt-3.5-turbo-16k' 'gpt-4' 'gpt-4o-2024-05-13' - 'gpt-4o-2024-08-06') + 'gpt-4o-2024-08-06' + 'gpt-4-turbo') end end end From 7624d1381953376bad8c5d1d03f69292f8ec2a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Wed, 12 Mar 2025 08:34:27 -0300 Subject: [PATCH 105/109] Update README.md --- README.md | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/README.md b/README.md index 55f3554..5d59006 100644 --- a/README.md +++ b/README.md @@ -15,28 +15,6 @@ Receive suggestions for creating and improving code directly in the IDE and take [![Course](https://img.shields.io/badge/Course-Delphi-F00?logo=delphi)](https://go.hotmart.com/U81331747Y?dp=1) [![E-mail](https://img.shields.io/badge/E--mail-Send-yellowgreen?logo=maildotru&logoColor=yellowgreen)](mailto:contato@code4delphi.com.br) -

- - - -   - - - -   - - - -   - - - -   - - - -

- ## 🚀 INSTALLATION 1 - Download Delphi AI Developer. You can download the .zip file or clone the project on your PC. From f04238d8f36320b124672542592328b91bab3b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 7 Apr 2025 17:26:33 -0300 Subject: [PATCH 106/109] refactor/hint-removal --- Package/DelphiAIDeveloper.dproj | 571 +++++++++++++++++------------- Package/DelphiAIDeveloper.res | Bin 688 -> 688 bytes Src/Consts/DelphiAIDev.Consts.pas | 2 +- Src/Utils/DelphiAIDev.Utils.pas | 7 - 4 files changed, 332 insertions(+), 248 deletions(-) diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 66a3dfc..60ee4eb 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -2,13 +2,14 @@ {7EF46619-47CC-4A26-9369-BCDD8C5ECFA8} DelphiAIDeveloper.dpk - 18.8 + 20.2 VCL True Debug Win32 - 1 + 1048577 Package + DelphiAIDeveloper true @@ -38,6 +39,11 @@ Base true + + true + Base + true + true Base @@ -75,11 +81,13 @@ None android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar rtl;bindengine;bindcomp;RESTComponents;FireDAC;FireDACCommonDriver;FireDACCommon;FireDACIBDriver;$(DCC_UsePackage) + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png None android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar rtl;bindengine;bindcomp;RESTComponents;FireDAC;FireDACCommonDriver;FireDACCommon;FireDACIBDriver;$(DCC_UsePackage) + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png rtl;bindengine;bindcomp;RESTComponents;FireDAC;FireDACCommonDriver;FireDACCommon;FireDACIBDriver;FireDACMySQLDriver;$(DCC_UsePackage) @@ -95,6 +103,13 @@ rtl;bindengine;bindcomp;RESTComponents;vclFireDAC;FireDAC;FireDACCommonDriver;FireDACCommon;FireDACIBDriver;FireDACMySQLDriver;$(DCC_UsePackage) + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + 1033 + true + DEBUG;$(DCC_Define) true @@ -262,10 +277,6 @@ BITMAP c4d_database_execute
- - Cfg_2 - Base - Base @@ -273,6 +284,10 @@ Cfg_1 Base
+ + Cfg_2 + Base + Delphi.Personality.12 @@ -290,28 +305,11 @@ Microsoft Office XP Sample Automation Server Wrapper Components - - - - true - - - - - true - - - - - true - - - - - DelphiAIDeveloper.bpl - true - - + + + + + 1 @@ -320,16 +318,6 @@ 0 - - - classes - 1 - - - classes - 1 - - res\xml @@ -340,12 +328,6 @@ 1 - - - library\lib\armeabi-v7a - 1 - - library\lib\armeabi @@ -398,6 +380,16 @@ 1 + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + res\values @@ -418,6 +410,66 @@ 1 + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + res\values @@ -428,6 +480,16 @@ 1 + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + res\drawable @@ -448,6 +510,16 @@ 1 + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + res\drawable-ldpi @@ -588,6 +660,56 @@ 1 + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + 1 @@ -608,6 +730,10 @@ 1 .framework + + 1 + .framework + 0 @@ -621,6 +747,10 @@ 1 .dylib + + 1 + .dylib + 0 .dll;.bpl @@ -635,7 +765,7 @@ 1 .dylib - + 1 .dylib @@ -647,6 +777,10 @@ 1 .dylib + + 1 + .dylib + 0 .bpl @@ -665,7 +799,7 @@ 0 - + 0 @@ -674,394 +808,350 @@ 0 + + 0 + 0 - - - 1 - - + + 1 - + 1 - - + + + + + + Contents\Resources 1 - + + Contents\Resources 1 - + + Contents\Resources 1 - - - 1 - - + + + library\lib\armeabi-v7a 1 - + + library\lib\arm64-v8a 1 - - 1 1 - - 1 - - - - + 1 - + 1 - + 1 - - - + 1 - + 1 - - 1 + + 0 - - - 1 - - - 1 - - + + + library\lib\armeabi-v7a 1 - - + + 1 - + 1 - + 1 - + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - + + + + 1 1 - + 1 - - - 1 - - + + + Assets 1 - + + Assets 1 - - - 1 - - + + + Assets 1 - + + Assets 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - - + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - + - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 - - - - - - + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - - - - Contents\Resources + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - Contents\Resources + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - Assets + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - Assets + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - - Assets + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - Assets + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1 - - + + + + + - - - - + + + + False @@ -1069,6 +1159,7 @@ False True False + True 12 diff --git a/Package/DelphiAIDeveloper.res b/Package/DelphiAIDeveloper.res index 9273b0906bbd637e9fa31e00b2dfb72f35131e39..4a3736958c96db4bf8b7cc4c4b21eaaaee609d94 100644 GIT binary patch delta 16 XcmdnMx`A~=0TUz3(const AJSONObject: TJSONObject; const AKey: string; AResult: T); class function GetExceptionMessage(const E: Exception): string; class function StrToDefaultsQuestionsKind(Value: string): TC4DQuestionKind; class function StrToDriverID(Value: string): TC4DDriverID; @@ -149,12 +148,6 @@ implementation DelphiAIDev.View.Dialog, DelphiAIDev.WaitingScreen; -class procedure TUtils.TryGetValueJson(const AJSONObject: TJSONObject; const AKey: string; AResult: T); -begin - if AJSONObject.GetValue(AKey) <> nil then - AResult := AJSONObject.GetValue(AKey); -end; - class function TUtils.GetExceptionMessage(const E: Exception): string; begin Result := E.Message; From 9836ea631cc51f2ed8254f478345a6790a6af91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 7 Apr 2025 18:01:01 -0300 Subject: [PATCH 107/109] fit/add-mistral --- Package/DelphiAIDeveloper.dproj | 5 +++++ Src/Chat/DelphiAIDev.Chat.View.dfm | 19 ++----------------- Src/Chat/DelphiAIDev.Chat.View.pas | 1 + Src/Consts/DelphiAIDev.Consts.pas | 4 ++-- Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm | 23 ++--------------------- Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas | 1 + Src/Utils/DelphiAIDev.Utils.OTA.pas | 10 +++++----- 7 files changed, 18 insertions(+), 45 deletions(-) diff --git a/Package/DelphiAIDeveloper.dproj b/Package/DelphiAIDeveloper.dproj index 60ee4eb..cd6848e 100644 --- a/Package/DelphiAIDeveloper.dproj +++ b/Package/DelphiAIDeveloper.dproj @@ -245,6 +245,7 @@ + BITMAP c4d_Logo @@ -307,8 +308,12 @@ + + + + diff --git a/Src/Chat/DelphiAIDev.Chat.View.dfm b/Src/Chat/DelphiAIDev.Chat.View.dfm index 064453f..e98bf09 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.dfm +++ b/Src/Chat/DelphiAIDev.Chat.View.dfm @@ -12,7 +12,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Font.Name = 'Tahoma' Font.Style = [] KeyPreview = True - OldCreateOrder = False Position = poScreenCenter ShowHint = True OnActivate = FormActivate @@ -39,8 +38,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Padding.Top = 15 ParentBackground = False TabOrder = 0 - ExplicitWidth = 950 - ExplicitHeight = 644 object Splitter1: TSplitter Left = 18 Top = 518 @@ -81,8 +78,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView ScrollBars = ssVertical ShowHint = True TabOrder = 1 - ExplicitWidth = 932 - ExplicitHeight = 483 end object pnBackQuestion: TPanel Left = 18 @@ -98,8 +93,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Padding.Top = 5 ParentBackground = False TabOrder = 0 - ExplicitTop = 504 - ExplicitWidth = 932 object mmQuestion: TMemo AlignWithMargins = True Left = 0 @@ -121,7 +114,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView OnChange = mmQuestionChange OnKeyDown = mmQuestionKeyDown OnKeyUp = mmQuestionKeyUp - ExplicitWidth = 932 end end object pnBackButtons: TPanel @@ -139,8 +131,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Padding.Bottom = 2 ParentBackground = False TabOrder = 2 - ExplicitTop = 617 - ExplicitWidth = 932 object lbCurrentAI: TLabel Left = 0 Top = 3 @@ -172,7 +162,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Caption = 'Send' TabOrder = 0 OnClick = btnSendClick - ExplicitLeft = 858 end object pnBackConfigurableButtons: TPanel Left = 395 @@ -182,7 +171,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView Align = alRight BevelOuter = bvNone TabOrder = 1 - ExplicitLeft = 389 object btnUseCurrentUnitCode: TButton AlignWithMargins = True Left = 261 @@ -289,8 +277,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView item Width = 50 end> - ExplicitLeft = 950 - ExplicitHeight = 644 end object pnCommands: TPanel Left = 936 @@ -305,7 +291,6 @@ object DelphiAIDevChatView: TDelphiAIDevChatView BevelOuter = bvNone ParentBackground = False TabOrder = 3 - ExplicitLeft = 930 DesignSize = ( 26 115) @@ -831,12 +816,12 @@ object DelphiAIDevChatView: TDelphiAIDevChatView OnClick = Gemini1Click end object Mistral1: TMenuItem - Tag = 2 + Tag = 3 Caption = 'Mistral' OnClick = Gemini1Click end object Ollama1: TMenuItem - Tag = 3 + Tag = 4 Caption = 'Ollama (offline)' OnClick = Gemini1Click end diff --git a/Src/Chat/DelphiAIDev.Chat.View.pas b/Src/Chat/DelphiAIDev.Chat.View.pas index 8f06147..7896092 100644 --- a/Src/Chat/DelphiAIDev.Chat.View.pas +++ b/Src/Chat/DelphiAIDev.Chat.View.pas @@ -613,6 +613,7 @@ procedure TDelphiAIDevChatView.pMenuCurrentAIPopup(Sender: TObject); Gemini1.Checked := False; ChatGPT1.Checked := False; Groq1.Checked := False; + Mistral1.Checked := False; Ollama1.Checked := False; case FSettings.AIDefault of TC4DAiAvailable.Gemini: diff --git a/Src/Consts/DelphiAIDev.Consts.pas b/Src/Consts/DelphiAIDev.Consts.pas index ec10f86..c052748 100644 --- a/Src/Consts/DelphiAIDev.Consts.pas +++ b/Src/Consts/DelphiAIDev.Consts.pas @@ -5,7 +5,7 @@ interface type TConsts = class public const - SEMANTIC_VERSION = '2.3.1'; + SEMANTIC_VERSION = '2.4.0'; SEMANTIC_VERSION_LB = 'Version: ' + SEMANTIC_VERSION; WIN_CONTROL_FOCU_NIL = nil; DELPHI_AI_DEVELOPER_DPROJ = 'DelphiAIDeveloper.dproj'; @@ -58,7 +58,7 @@ TConsts = class //ABOUT AND SPLASH ABOUT_TITLE = 'Delphi AI Developer'; - ABOUT_COPY_RIGHT = 'Copyright 2024 Code4Delphi Team.'; + ABOUT_COPY_RIGHT = 'Copyright 2025 Code4Delphi Team.'; ABOUT_DESCRIPTION = 'Plugin designed to be used in the Delphi IDE.'; PLUGIN_LICENSE = 'MIT license'; IS_UNREGISTERED = False; diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm index 7c00112..2fd2bc6 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.dfm @@ -12,7 +12,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Font.Name = 'Tahoma' Font.Style = [] KeyPreview = True - OldCreateOrder = False Position = poScreenCenter ShowHint = True OnActivate = FormActivate @@ -39,8 +38,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Top = 15 ParentBackground = False TabOrder = 0 - ExplicitWidth = 950 - ExplicitHeight = 644 object Splitter1: TSplitter Left = 18 Top = 153 @@ -92,8 +89,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView ScrollBars = ssVertical ShowHint = True TabOrder = 1 - ExplicitWidth = 932 - ExplicitHeight = 268 end object pnBackQuestion: TPanel Left = 18 @@ -109,7 +104,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Top = 5 ParentBackground = False TabOrder = 0 - ExplicitWidth = 932 object Label2: TLabel Left = 0 Top = 5 @@ -143,7 +137,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView OnChange = mmQuestionChange OnKeyDown = mmQuestionKeyDown OnKeyUp = mmQuestionKeyUp - ExplicitWidth = 932 end end object pnBackButtonsSearch: TPanel @@ -161,7 +154,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Bottom = 2 ParentBackground = False TabOrder = 2 - ExplicitWidth = 932 object lbCurrentAI: TLabel Left = 0 Top = 3 @@ -193,7 +185,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Caption = 'Send' TabOrder = 0 OnClick = btnSendClick - ExplicitLeft = 858 end object pnBackConfigurableButtons: TPanel Left = 395 @@ -203,7 +194,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Align = alRight BevelOuter = bvNone TabOrder = 1 - ExplicitLeft = 389 object btnUseCurrentUnitCode: TButton AlignWithMargins = True Left = 261 @@ -270,8 +260,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView BevelOuter = bvNone ParentBackground = False TabOrder = 3 - ExplicitTop = 484 - ExplicitWidth = 932 object DBGrid1: TDBGrid Left = 0 Top = 0 @@ -304,7 +292,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Bottom = 3 ParentBackground = False TabOrder = 1 - ExplicitWidth = 932 object lbCount: TLabel Left = 899 Top = 3 @@ -341,8 +328,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Padding.Bottom = 2 ParentBackground = False TabOrder = 4 - ExplicitTop = 454 - ExplicitWidth = 932 object Label1: TLabel Left = 337 Top = 0 @@ -385,7 +370,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView Images = ImageList1 TabOrder = 0 OnClick = btnExecuteSQLClick - ExplicitLeft = 819 end object cBoxDatabases: TComboBox AlignWithMargins = True @@ -463,8 +447,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView item Width = 50 end> - ExplicitLeft = 950 - ExplicitHeight = 644 end object pnCommands: TPanel Left = 947 @@ -479,7 +461,6 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView BevelOuter = bvNone ParentBackground = False TabOrder = 3 - ExplicitLeft = 941 DesignSize = ( 26 115) @@ -1005,12 +986,12 @@ object DelphiAIDevDBChatView: TDelphiAIDevDBChatView OnClick = Gemini1Click end object Mistral1: TMenuItem - Tag = 2 + Tag = 3 Caption = 'Mistral' OnClick = Gemini1Click end object Ollama1: TMenuItem - Tag = 3 + Tag = 4 Caption = 'Ollama (offline)' OnClick = Gemini1Click end diff --git a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas index 2db29fc..22f5e27 100644 --- a/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas +++ b/Src/DB/Chat/DelphiAIDev.DB.Chat.View.pas @@ -612,6 +612,7 @@ procedure TDelphiAIDevDBChatView.pMenuCurrentAIPopup(Sender: TObject); Gemini1.Checked := False; ChatGPT1.Checked := False; Groq1.Checked := False; + Mistral1.Checked := False; Ollama1.Checked := False; case FSettings.AIDefault of TC4DAiAvailable.Gemini: diff --git a/Src/Utils/DelphiAIDev.Utils.OTA.pas b/Src/Utils/DelphiAIDev.Utils.OTA.pas index afa4630..68ebe78 100644 --- a/Src/Utils/DelphiAIDev.Utils.OTA.pas +++ b/Src/Utils/DelphiAIDev.Utils.OTA.pas @@ -42,7 +42,7 @@ TUtilsOTA = class class function ActiveThemeForCode: TColor; class function ActiveThemeIsDark: Boolean; class function GetIOTAFormEditor(const AIOTAModule: IOTAModule): IOTAFormEditor; - {$IF CompilerVersion >= 32.0} //Tokyo + {$IF CompilerVersion > 32.0} //Tokyo class function GetIOTAIDEThemingServices: IOTAIDEThemingServices; class function GetIOTAIDEThemingServices250: IOTAIDEThemingServices250; {$ENDIF} @@ -512,7 +512,7 @@ class function TUtilsOTA.CheckIfExistFileInCurrentsProjectGroups(const ANameFile end; class procedure TUtilsOTA.IDEThemingAll(AFormClass: TCustomFormClass; AForm: TForm); -{$IF CompilerVersion >= 32.0} //Tokyo +{$IF CompilerVersion > 32.0} //Tokyo var i: Integer; LIOTAIDEThemingServices250: IOTAIDEThemingServices250; @@ -521,7 +521,7 @@ class procedure TUtilsOTA.IDEThemingAll(AFormClass: TCustomFormClass; AForm: TFo AForm.Constraints.MinHeight := AForm.Height; AForm.Constraints.MinWidth := AForm.Width; - {$IF CompilerVersion >= 32.0} + {$IF CompilerVersion > 32.0} LIOTAIDEThemingServices250 := Self.GetIOTAIDEThemingServices250; LIOTAIDEThemingServices250.RegisterFormClass(AFormClass); LIOTAIDEThemingServices250.ApplyTheme(AForm); @@ -555,7 +555,7 @@ class function TUtilsOTA.ActiveThemeIsDark: Boolean; const THEME_DARK = 'dark'; begin - {$IF CompilerVersion >= 32.0} //Tokyo + {$IF CompilerVersion > 32.0} //Tokyo Result := Self.GetIOTAIDEThemingServices.ActiveTheme.ToLower.Equals(THEME_DARK); {$ELSE} Result := False; @@ -584,7 +584,7 @@ class function TUtilsOTA.GetIOTAFormEditor(const AIOTAModule: IOTAModule): IOTAF end; end; -{$IF CompilerVersion >= 32.0} //Tokyo +{$IF CompilerVersion > 32.0} //Tokyo class function TUtilsOTA.GetIOTAIDEThemingServices: IOTAIDEThemingServices; begin if not Supports(BorlandIDEServices, IOTAIDEThemingServices, Result) then From 4b4df62cdd0523e4b0ceb4b6081c765453096ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Mon, 7 Apr 2025 18:03:38 -0300 Subject: [PATCH 108/109] feature/add-gpt-4-turbo --- Src/Settings/DelphiAIDev.Settings.View.dfm | 34 ++++++++-------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/Src/Settings/DelphiAIDev.Settings.View.dfm b/Src/Settings/DelphiAIDev.Settings.View.dfm index 5b62df9..b023496 100644 --- a/Src/Settings/DelphiAIDev.Settings.View.dfm +++ b/Src/Settings/DelphiAIDev.Settings.View.dfm @@ -25,8 +25,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Align = alClient BevelOuter = bvNone TabOrder = 0 - ExplicitWidth = 664 - ExplicitHeight = 659 object pnBottom: TPanel Left = 0 Top = 641 @@ -44,8 +42,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Padding.Bottom = 2 ParentBackground = False TabOrder = 0 - ExplicitTop = 624 - ExplicitWidth = 664 object lbRestoreDefaults: TLabel AlignWithMargins = True Left = 16 @@ -84,7 +80,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Caption = 'Confirm' TabOrder = 0 OnClick = btnConfirmClick - ExplicitLeft = 436 end object btnClose: TButton AlignWithMargins = True @@ -100,7 +95,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Caption = 'Close' TabOrder = 1 OnClick = btnCloseClick - ExplicitLeft = 549 end end object pnMyControl: TPanel @@ -111,8 +105,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Align = alClient BevelOuter = bvNone TabOrder = 1 - ExplicitWidth = 664 - ExplicitHeight = 624 object pnMyControlButtons: TPanel Left = 0 Top = 0 @@ -122,7 +114,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView BevelEdges = [beBottom] BevelOuter = bvNone TabOrder = 0 - ExplicitWidth = 664 object Bevel5: TBevel AlignWithMargins = True Left = 0 @@ -206,8 +197,6 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Align = alClient BevelOuter = bvNone TabOrder = 1 - ExplicitWidth = 664 - ExplicitHeight = 594 end end end @@ -216,7 +205,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Top = 33 Width = 667 Height = 521 - ActivePage = TabSheet1 + ActivePage = TabSheet2 TabOrder = 1 object TabSheet1: TTabSheet Caption = 'Preferences' @@ -224,7 +213,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 659 - Height = 564 + Height = 493 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -233,7 +222,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 659 - Height = 564 + Height = 493 Align = alClient Caption = ' Preferences ' ParentBackground = False @@ -298,7 +287,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView end object gboxData: TGroupBox Left = 2 - Top = 504 + Top = 433 Width = 655 Height = 58 Align = alBottom @@ -337,7 +326,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 659 - Height = 564 + Height = 493 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -345,7 +334,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView object Bevel1: TBevel AlignWithMargins = True Left = 0 - Top = 560 + Top = 489 Width = 659 Height = 1 Margins.Left = 0 @@ -700,7 +689,8 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView 'gpt-3.5-turbo-16k' 'gpt-4' 'gpt-4o-2024-05-13' - 'gpt-4o-2024-08-06') + 'gpt-4o-2024-08-06' + 'gpt-4-turbo') end end end @@ -1043,7 +1033,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 659 - Height = 564 + Height = 493 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -1221,7 +1211,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 659 - Height = 564 + Height = 493 Align = alClient BevelOuter = bvNone ParentBackground = False @@ -1230,7 +1220,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 0 Top = 0 Width = 659 - Height = 564 + Height = 493 Align = alClient Caption = ' Code Completion (BETA) ' ParentBackground = False @@ -1240,7 +1230,7 @@ object DelphiAIDevSettingsView: TDelphiAIDevSettingsView Left = 5 Top = 18 Width = 649 - Height = 541 + Height = 470 Align = alClient BevelOuter = bvNone ParentBackground = False From 44697fefd8c2eeaebf22df746b12c2b4b9be59de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Sun, 18 May 2025 15:14:14 -0300 Subject: [PATCH 109/109] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d59006..9b37e71 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Delphi AI Developer (Copilot) -Inspired by GitHub Copilot, Delphi AI Developer is a plugin that adds Artificial intelligence (AI) interaction capabilities to the Delphi IDE, using both the OpenAI API, Gemini API and Groq API, as well as offering offline AI support. +Inspired by GitHub Copilot, Delphi AI Developer is a plugin that adds Artificial intelligence (AI) interaction capabilities to the Delphi IDE, using both the OpenAI API, Gemini API, Mistral API and Groq API, as well as offering offline AI support. With Delphi AI Developer, you will have assistance in generating and refactoring code, facilitating and accelerating development.