-
Content Count
26 -
Joined
-
Last visited
-
Days Won
7
Everything posted by Ali Dehban
-
A new Delphi plug-in for automatically implementing the client side of a Rest API is now available in beta version. Repository: https://github.com/AliDehbansiahkarbon/OpenAPIClientWizard Demo video: https://www.youtube.com/watch?v=7B7nSHIsV64
-
Hey everyone, this plug-in is currently in beta version, so there may be some bugs or issues. I've already got some valuable advice from the great @Uwe Raabe but any contributions are welcome too, as I may not have much time to work on it until the end of July. I'll be improving it in time, so please be patient and help me make it better and production-ready. Please open an issue on GitHub with a sample specification file so that I can duplicate the error/bug to fix it. Best regards, Ali.
-
Another option where I had a better experience than with OpenAI and Gemini is YouChat
-
Hello, everybuddy. Recently I made a plug-in for Delphi to use ChatGPT inside the IDE. The main service is ChatGPT but it's actually multi-AI support, you can get responses from three different sources, compare and decide. I hope this can be helpful and accelerate your work. Repository: https://github.com/AliDehbansiahkarbon/ChatGPTWizard Key features: - Free text question form. - Dockable question form. - Inline questions(in the editor). - Context menu options to help you to find bugs, write tests, optimize code, add comments, etc... - Class view. - Predefined Questions for class view. - History to save your tokens on OpenAI ! - Fuzzy string match searches in the history. - Animated letters(Like the website). - Proxy server options. - Supports Writesonic AI (https://writesonic.com) - Support YouChat (https://you.com) Short Video 1: Short Video 2 - Inline Questions: Full Video (ver. 2.0):
-
Compile time issue with RTTI, generic interface and type casting...
Ali Dehban posted a topic in RTL and Delphi Object Pascal
Hi mates, I have something on my mind but I couldn't implement it correctly, imagine a generic interface, some classes inherited from that interface, and one method in each class with the same name, now I'm trying to use this interface type every where for different approaches but it doesn't compile correctly. Please have a look at the code if you get a chance and share your thoughts with me, I do appreciate you in advance. The question is how can I implement such an idea properly and safely? I have attached a sample project to save you time too. unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Rtti; type IMyInterface<T> = interface function DoSomething: T; end; TMyClass<T> = class(TInterfacedObject, IMyInterface<T>) function DoSomething: T; end; TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } function UseInterface<T>(obj: IMyInterface<T>): T; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} { TMyClass<T> } function TMyClass<T>.DoSomething: T; var ctx: TRttiContext; typ: TRttiType; begin ctx := TRttiContext.Create; typ := ctx.GetType(TypeInfo(T)); if typ.TypeKind = tkInteger then Result := 20 // E2010 Incompatible types: 'T' and 'Integer' else if typ.TypeKind = tkString then Result := T('Hello') // E2089 Invalid typecast else if typ.AsInstance.MetaclassType.InheritsFrom(TStringList) then Result := (typ.AsInstance.MetaclassType.InitInstance(typ) as TStringList) //E2010 Incompatible types: 'T' and 'TStringList' else Result := Default(T); ctx.Free; end; { TForm1 } function TForm1.UseInterface<T>(obj: IMyInterface<T>): T; begin Result := obj.DoSomething; end; procedure TForm1.FormCreate(Sender: TObject); var obj1: IMyInterface<Integer>; obj2: IMyInterface<String>; obj3: IMyInterface<TStringList>; begin try obj1 := TMyClass<Integer>.Create; obj2 := TMyClass<String>.Create; obj3 := TMyClass<TStringList>.Create; ShowMessage(UseInterface<Integer>(obj1).ToString); ShowMessage(UseInterface<String>(obj2)); ShowMessage(UseInterface<TStringList>(obj3).Text); except on E: Exception do Writeln('Exception: ', E.ClassName, ': ', E.Message); end; end; end. Generic Interface.zip -
Compile time issue with RTTI, generic interface and type casting...
Ali Dehban replied to Ali Dehban's topic in RTL and Delphi Object Pascal
You're absolutely right, this is the normal usage, but at the moment you want to have one function to avoid repeating with the "obj" as input parameter then Delphi forces you to write that function in this way. As I mentioned this is not necessary and what you wrote is ok 99 percent of the time. There is one benefit with such a function that is the possibility to limit the input type to classes.(No primitive types like integer) I'm writing a library and I wanted to force the developers to use it in this way in this case. -
Compile time issue with RTTI, generic interface and type casting...
Ali Dehban replied to Ali Dehban's topic in RTL and Delphi Object Pascal
@pmcgee Hi. In most scenarios your sample would be enough, I agree. But why I used this: function UseInterface<T> ( obj: IMyInterface<T> ) : T; begin Result := obj.DoSomething; end; Because I wanted to call ClassObj.DoSomething from within another class and using one function which is not necessary but I wanted to know how it works in Delphi. When you are calling something like these generic object's generic members/methods from within another object(different class) then Delphi forces you to write like that. For instance, something like this won't be compiled which was my desired call but it's not allowed: function UseInterface(obj: T): T; Besides, I wanted to limit the input type to classes (no primitive types at all) which is possible if I use such a function, so my final function is even more complicated like this: function UseInterface<T: class>(obj: IMyInterface<T>): T; The keyword "class" here can limit the input type only to classes, so Integer or String is no longer allowed here. -
The wrong warning is fixed now. @Die Holländer GitHub and release has been updated. If you prefer to follow it here it's ok but it would be easier for me to follow everything in one place, GitHub. If possible, please open an issue on GitHub in the future.
-
Perfect. Thank you for your reply. It's just a warning and won't be a problem but the warning shouldn't appear. I'm wondering how can I duplicate this. I'll try to fix it.
-
Hi fellows, I wanted to inform you that I have made an improvement to my AI-integration plug-in called ChatGPTWizard. Now it supports Ollama, the offline AI chatbot server. You can download the latest version (v3.0) to try it out here: https://github.com/AliDehbansiahkarbon/ChatGPTWizard To set up your offline GPT-like server read this section: https://github.com/AliDehbansiahkarbon/ChatGPTWizard#:~:text=How to use it in Offline mode I am eagerly looking forward to receiving your valuable feedback. Thank you in advance.
-
Compile time issue with RTTI, generic interface and type casting...
Ali Dehban replied to Ali Dehban's topic in RTL and Delphi Object Pascal
I see. Well, beyond the curiosity, it depends on the nature of the project. As a general sample, it could/might be useful to implement something like an ORM, especially in an Active-Record structure or like that. (More info about the Active-Record: https://guides.rubyonrails.org/active_record_basics.html) In my case, I need it in a multi-purpose data access layer of a project but with complex data types, not Integer and String parameters combined heavily to RTTI functionalities. Thank you for your feedback. -
Compile time issue with RTTI, generic interface and type casting...
Ali Dehban replied to Ali Dehban's topic in RTL and Delphi Object Pascal
First, thank you for your response. Second, I thought so but! It seems using RTTI's TValue it is possible to handle this situation somehow. I'm just not sure if everything goes right with this code or not at the end, I tested with "ReportMemoryLeaksOnShutdown := True;" and there is no memory leak. Please have a look at the final version and share your thoughts with me. Best regards. type IMyInterface<T> = interface ['{D68085A3-6AFB-46D9-A4EE-B46563758127}'] function DoSomething: T; end; TMyClass<T> = class(TInterfacedObject, IMyInterface<T>) function DoSomething: T; end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } function UseInterface<T>(obj: IMyInterface<T>): T; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} { TMyClass<T> } function TMyClass<T>.DoSomething: T; var ctx: TRttiContext; typ: TRttiType; val: TValue; begin ctx := TRttiContext.Create; typ := ctx.GetType(TypeInfo(T)); if typ.TypeKind = tkInteger then val := 20 else if (typ.TypeKind = tkString) or (typ.TypeKind = tkUString) then val := 'Hello' else if typ.AsInstance.MetaclassType.InheritsFrom(TStringList) then begin val := TStringList.Create; val.AsType<TStringList>.Add('Hello from StringList'); end; Result := Val.AsType<T>; ctx.Free; end; { TForm1 } function TForm1.UseInterface<T>(obj: IMyInterface<T>): T; begin Result := obj.DoSomething; end; procedure TForm1.Button1Click(Sender: TObject); var obj1: IMyInterface<Integer>; obj2: IMyInterface<String>; obj3: IMyInterface<TStringList>; lvstr: TStringList; begin try try obj1 := TMyClass<Integer>.Create; obj2 := TMyClass<String>.Create; obj3 := TMyClass<TStringList>.Create; ShowMessage(UseInterface<Integer>(obj1).ToString); ShowMessage(UseInterface<String>(obj2)); lvstr := UseInterface<TStringList>(obj3); ShowMessage(lvstr.Text); except on E: Exception do ShowMessage('Exception: ' + E.ClassName + ': ' + E.Message); end; finally lvstr.Free; obj1 := nil; obj2 := nil; obj3 := nil; end; end; Generic Interface-final.zip -
I'm maintaining an aged legacy application written in Delphi. I'm experiencing something weird in a report made by Fastreport (ver 5.5.6) and Delphi (XE5). There is a situation in which the exe will be triggered with some input parameters to export the expected document to PDF or Image to be used on a website or somewhere. The specific report that I'm talking about has some fields that are formatted by Pascal script to 24-Hour format or AM/PM to meet each customer's needs. (Dynamic report). Everything is perfect in the report preview, the printed report, and export to PDF, image, or Excel in the visible mode of the application(normal usage of the application). but those formats don't apply in invisible mode, those fields come up with the default format of the server. I checked the SQL Server result and the application report preview in visible mode and everything is fine but on the same machine when it executes in invisible mode it doesn't work. I doubted those Pascal scripts (OnAfterData event has been used), so I put some log functions and I realized those Pascal scripts are running, I can verify they are running each time but don't affect the final exported file. Does anybody have the same experience, Any advice?
- 12 replies
-
- fastreport
- export
-
(and 1 more)
Tagged with:
-
DateTime problem in fastreport's PFD export.
Ali Dehban replied to Ali Dehban's topic in General Help
It seems "mm" is defined in the fast report format options for minute, what does it mean "hh:mm" in fast report equals "hh:nn" in Delphi likely.- 12 replies
-
- fastreport
- export
-
(and 1 more)
Tagged with:
-
DateTime problem in fastreport's PFD export.
Ali Dehban replied to Ali Dehban's topic in General Help
You are right, It's designed by the customer itself, and the designer used IIF() to fill the MemoView to select one from two available TdateTime fields by some conditions and the result of IIF is text.- 12 replies
-
- fastreport
- export
-
(and 1 more)
Tagged with:
-
DateTime problem in fastreport's PFD export.
Ali Dehban replied to Ali Dehban's topic in General Help
Sure, I mean the retrieved data field from the database is TDateTime, but when you read from a TfrxMemoView you'll get it as text.- 12 replies
-
- fastreport
- export
-
(and 1 more)
Tagged with:
-
DateTime problem in fastreport's PFD export.
Ali Dehban replied to Ali Dehban's topic in General Help
The value is pure TDateTime. The desired format would be 'hh:nn'. But this 'HH' is a mistake I think (the support team did or myself during tests) and I just copied the current script without more checks, I'm not sure how and when this happened and why it is still working in UI mode. Thank you for the hint, I will investigate more and inform you about it, further.- 12 replies
-
- fastreport
- export
-
(and 1 more)
Tagged with:
-
DateTime problem in fastreport's PFD export.
Ali Dehban replied to Ali Dehban's topic in General Help
1- Invisible means running the exe in the command line with some input parameters to do a certain job and terminate with no UI (Application.ShowMainForm := False) Note: Do not ask me to change it to a Windows service or web service, etc, I wish I could but it's not possible because I'm not the owner of the product and it should work as is by their command; 2- And this is the script: procedure XReportOnAfterData(Sender: TfrxComponent); var LvTimeValue: string; LvLength: Integer; begin if Sender is TfrxMemoView then begin LvTimeValue := Trim(TfrxMemoView(Sender).Text); LvLength := Length(LvTimeValue); if LvLength > 0 then begin try TfrxMemoView(Sender).Text := FormatDateTime('HH:mm', StrToDateTime(LvTimeValue)); except TfrxMemoView(Sender).Text := 'Error: N/A'; end; end; end; end; Thank you for your response by the way.- 12 replies
-
- fastreport
- export
-
(and 1 more)
Tagged with:
-
Strange Benchmark Results; Am I Missing Something?
Ali Dehban replied to Joseph MItzen's topic in I made this
Of course, we don't have the magic parallel=true flag but still, we can use parallelism. Maybe this is not the perfect one but something like this will give you the maximum performance probably. I'm adding this reply just for those who may need something like this, this is not the real answer probably. Anyway, I was able to achieve a 25% improvement in performance by using the code below: Remarks: - NumTasks = 4; ==> Specifies the number of parallel tasks to be used which is limited by the available resources, you can try with more or less chunks. - sw: An instance of TStopwatch to measure the elapsed time. - The code utilizes TParallel.For to parallelize the loop, dividing the range of numbers from 1 to 1000000000 into chunks based on the number of tasks (NumTasks). - Each parallel task calculates the sum of multiples within its assigned chunk using the SumMultiples procedure. - The partial sums from each task are added to the total using TInterlocked.Add for thread-safe operations. uses System.SysUtils, System.Diagnostics, System.Threading, System.SyncObjs, System.Math; const NumTasks = 4; procedure SumMultiples(var partialTotal: Int64; start, finish: Int64); var num: Integer; begin partialTotal := 0; for num := start to finish do if (num mod 3 = 0) or (num mod 5 = 0) then partialTotal := partialTotal + num; end; Var total: Int64; sw: TStopwatch; begin sw := TStopwatch.Create; sw.start; total := 0; TParallel.For(1, NumTasks, procedure(index: Int64) var start, finish, partialTotal: Int64; chunkSize: Int64; begin chunkSize := 1000000000 div NumTasks; start := (index - 1) * chunkSize + 1; finish := Min(index * chunkSize, 1000000000); SumMultiples(partialTotal, start, finish); TInterlocked.Add(total, partialTotal); end); sw.Stop; WriteLn(total); WriteLn('Total time ', sw.ElapsedMilliseconds, ' ms'); Readln; end. -
What? EasyDbMigrator is a database migration library designed for Delphi. It simplifies database evolution and is available in both 32-Bit and 64-Bit versions. Why and how to use it? Please have a look at ReadMe on GitHub(https://github.com/AliDehbansiahkarbon/EasyDBMigrator). Or watch the Introduction Video:
-
Updates: 1- Firebird support has been added. 2- A playlist on youtube is available now to learn about the library here: https://www.youtube.com/playlist?list=PLsToBC7EKBNSkD-mwMN18TQbJ-lzistS7
-
Hello all, If you prefer to use ChatGPT inside the IDE of Lazarus instead of the website, here is a simple plug-in for the Lazarus IDE. https://github.com/AliDehbansiahkarbon/ChatGPTPluginForLazarus
-
I'm making an IDE plug-in and I'm trying to draw something which is not a normal symbol or character. I'm wondering if is it possible to draw something into the editor that can behave like this orange vertical line. This is just highlighting, you can see it but you cannot modify or delete it like characters. I'm aware that I have to catch the Editor and work with canvas probably to draw something like that but I cannot find any interface suitable to get the editor's canvas and draw something.