-
Content Count
931 -
Joined
-
Last visited
-
Days Won
57
Everything posted by pyscripter
-
The code of TReader.ReadCollection is as follows: procedure TReader.ReadCollection(const Collection: TCollection); var Item: TPersistent; begin Collection.BeginUpdate; try if not EndOfList then Collection.Clear; while not EndOfList do begin if NextValue in [vaInt8, vaInt16, vaInt32] then ReadInteger; Item := Collection.Add; ReadListBegin; while not EndOfList do ReadProperty(Item); ReadListEnd; end; ReadListEnd; finally Collection.EndUpdate; end; end; It has been like this forever. My question is about the statement: if not EndOfList then Collection.Clear; It means that if you read an empty collection, the collection you are reading is not cleared or otherwise changed. The practical implication of this is that if you have a component that initializes a collection property with some items, there is no way to really clear it from the collection property inspector. Next time the form is loaded, either at run time or at design time, the collection will revert to the initialized state. Can you think of any reason TReader.ReadCollection does this? I think that if you read an empty collection, the collection property you are loading should be cleared. Should I report this as an issue? Also is there any workaround? I want a collection property to have a default state with some items created by the component constructor, but the users to be able to clear it at design time.
-
Against my better judgement I have submitted an issue report.
-
pyscripter/python4delphi · Discussions · GitHub pyscripter/SynEdit · Discussions · GitHub
-
Use the JAM Software one, The reasons: It is the official Virtual Treeview repo. @joachimd took over the project from the component creator Mike Lischke and he is doing a fantastic job. It is very actively maintained. Bug reports are dealt with and fixed very promptly. The GetIt version is based on the Turbopack repo. This repo was created from an older version of the JAM Software one. Surprisingly, it was not forked, so it is hard to compare the two or merge changes from one to the other. If you look at the Commit history it was created in 2014 and since then there have been around 130 commits, mostly creating packages for new versions of Delphi. In the JAM Software repo there have been as many commits in the last six months. Even if you submit a bug report to the Turbopack repo and it gets fixed (don't bet on it), it will take months before these fixes find their way into GetIt. No.
-
It turns out that the workaround for the second issue is quite simple: procedure TCustomSynEdit.ReadState(Reader: TReader); // If the component is inherited from another form, ReadState will be called // more than once. We only clear the collections if it is the first call // i.e. when reading the base form. begin if not FStateRead then begin FScrollbarAnnotations.Clear; FStateRead := True; end; inherited ReadState(Reader); end; Thanks to @Uwe Raabe for giving me the idea.
-
@Uwe Raabe@Anders MelanderThank you for your feedback. Fully agree. The chances of Embarcadero changing this old code are close, very close, to zero. However let me elaborate on the problems with the current situation. There are two issues: A) Form Inheritance Consider the attached project, There are two forms, one inheriting from the other. The first contains a TCategoryButtons with two categories (Showing just the relevant part) object Form1: TForm1 object CategoryButtons: TCategoryButtons Categories = < item Caption = 'A' Color = 16771839 Collapsed = False Items = <> end item Caption = 'B' Color = 16771818 Collapsed = False Items = <> end> end end If the inherited form does not change the Categories collection then the dfm of the second form does not have any reference to the Categories collection. inherited Form2: TForm2 inherited CategoryButtons: TCategoryButtons Width = 505 end end If you now remove the two categories in Form2, the form is correctly saved as: inherited Form2: TForm2 inherited CategoryButtons: TCategoryButtons Width = 505 Categories = <> end end However, if you run the application though, Form2 still shows the two categories. Also if you view the form as text and then back as form, the Categories revert to the inherited value. The same happens if you close and reopen the form. This is counter intuitive and problematic. I do not see how clearing the selection on reading would result in any undesired behavior. It would work correctly whether the collection is changed or not, Instead, it would solve the above issue. B) Cannot clear a collection created with items at design time Whilst you both focused on inheritance, for me the most important issue is unrelated to form inheritance. If a custom component contains a Collection property that is initialized non-empty at component creation, there is no way to clear it at design time. As an example, Synedit, has a collection property ScrollbarAnnotations. At construction this is initialized with some default annotations. The user may want to remove all annotations, but this cannot be achieved at design time. If you clear all annotations, the form reverts back to the initial state, when you run the project, or just close and open again the form. I cannot think of any backward compatibility issues that result from clearing the collection on reading empty collections. Can you? FormInheritance.zip
-
Could you please explain why not clearing the collection plays better with form inheritance? I would think the opposite. Say you inherit from a form with a component that has a collection property with some items. As it stands, there is no way for the inherited form to clear the inherited collection.
-
Activity view condensed not working
pyscripter replied to Vincent Parrett's topic in Community Management
The Forum selection issue is also fixed. Thanks! -
Activity view condensed not working
pyscripter replied to Vincent Parrett's topic in Community Management
Also the Forum selection under Browse is no longer persisted. -
Don't you get an error when you run your code? Vertaal.PArr[j, taalnr] = translated should be Vertaal.PArr[j][taalnr] = translated Sample code: var VArr: Variant := VarArrayCreate([0, 1, 0, 1], VarVariant); VArr[0, 0] := 'I'; VArr[1, 0] := 'You'; PythonModule1.SetVarFromVariant( 'arr', VArr); After you execute the code: var VArr := PythonModule1.GetVarAsVariant('arr'); ShowMessage(Varr[1][1]); Note that what you get with GetVarAsVariant is not a two-dimensional Variant array, but rather an one-dimensional Variant array containing one-dimensional variant arrays. Before you rush to criticize my French, I know that I is Je in French .
-
module.Events.onExecute or pythoninputoutput.onSendUniData?
pyscripter replied to softtouch's topic in Python4Delphi
Have you watched the video tutorials? Your question is answered at -
How to access/modify underlying records of IList<T>
pyscripter replied to Dave Novo's topic in Delphi Third-Party
Would that work with any TArray as well? -
How to access/modify underlying records of IList<T>
pyscripter replied to Dave Novo's topic in Delphi Third-Party
Spring4d does provide you with access to the array of values using IArrayAccess, but what you ask is not spring4d specific. It applies to any array of records. e.g. type TMyRec = record StrField: string; end; TMyRecArray = TArray<TMyRec>; To modify the values you need iterate using an index var RecArr: TMyRecArray for var I := 0 to Length(RecArr) - 1 do RecArray[I].StrField := ... Unfortunately you cannot do: for var Rec in RecArr do Rec.StrField := ... // <- compiler error: You cannot modify a for loop variable. and in any case what you get in Rec above is a copy of the record not the original one. I agree it would be cool to have an iterator that gives access to the underlying element. -
I don't think this is anything to go by, but Embarcadero is sometimes using a suffix instead of a prefix! e.g. Vcl.CustomizeDialog.dfm object CaptionOptionsGrp: TGroupBox object ApplyToAllChk: TCheckBox object CaptionOptionsCombo: TComboBox This looks to me worse than using a prefix. But anything is better than keeping the default names (Button1, Button2, .. Button105 etc.)
-
ISet<T> in spring4D
pyscripter replied to Dave Novo's topic in Algorithms, Data Structures and Class Design
Inheritance Tree: IEnumerable<T> IReadOnlyCollection<T> ICollection<T> ISet<T> IEnumerable<T> has many functions including Contains: function Contains(const value: T): Boolean; overload; function Contains(const value: T; const comparer: IEqualityComparer<T>): Boolean; overload; function Contains(const value: T; const comparer: TEqualityComparison<T>): Boolean; overload; -
Generic from the RTL for sorted list of objects
pyscripter replied to dummzeuch's topic in RTL and Delphi Object Pascal
If you don't expect to have many duplicates then a dictionary with TArray for values is more time and memory efficient. I am using such a structure in SynEdit: SynEdit/Source/SynEditMiscClasses.pas at master · pyscripter/SynEdit. -
You probably have noticed that when you press the middle mouse button in the Delphi IDE the editor goes into panning mode, that allows you to scroll by moving the mouse. Many of the Vcl.Controls are panning enabled including the Memos, Grids, ContolLists, TabControls, Treeviews and others. For a complete list just search for csPannable in the Delphi Vcl source code folder. They use the exact same code that the IDE uses and behave in exactly the same way. However, what you may not know (I did not), is that to enable panning you need to include in your project the Vcl.IMouse unit. Vcl also makes it easy to add panning to your custom controls. All it takes is to add the csPannable control style. So SynEdit now has the same panning support as the Delphi IDE. However, I have discovered two bugs related to Vcl panning: Memory leak when you use Vcl.IMouse - RAD Studio Service - Jira Service Management The Panning Window is not DPI scaled - RAD Studio Service - Jira Service Management Both are easy to fix, so hopefully Embarcadero will provide fixes soon enough! In the meantime, it is easy to work around the memory leak and hopefully live with the second one, which also affects the Delphi IDE.
-
Unlike DelphiVcl, DelphiFMX does not wrap Canvas. Both DelphiVcl and DelphiFmx are maintained by Embarcadero. There is a reported issue regarding BeginScene, but you may want to submit a broader one about Canvas support.
-
I committed a change trying to fix this. Could you please try once more.
-
python4delphi Add extra components without touch DelphiVCL
pyscripter replied to shineworld's topic in Python4Delphi
This is not correct. When P4D is used in an extension module it uses LoadDllInExtensionModule which just uses the dll loaded in the python process. It does not load or initialize the python dll. The calling process does that. So you can have more than one Delphi generated pyd files without issues. -
In the latest commit, multiple connections are handled in separate threads. So, Multiple Connections on LocalForward · Issue #11 · pyscripter/Ssh-Pascal is fixed. Seems to work fine, but could you please test it?
-
@dummzeuch Please see my latest commit. TSshTunnel.ForwardLocalPort has been refactored and can now handle multiple connections sequentially. So your use case may be working. Could you please test. I will also see whether the connections can be handled in parallel. Is there a use case for that? Can you have multiple connections simultaneously on the same port?
-
@dummzeuchI have updated the build scripts and the binaries which do not need OpenSSL. Could you please try the new binaries and see whether you still get the error you mentioned? These binaries work well with ssh-agent password-less authentication, whilst the Php ones don't. Also would it be possible to post a test project that requires multiple connections, so that I can have a go at fixing the issue?
-
Probably not. When you add commits to the same branch, the commits are added to the PR. If you want to have separate PRs you need different branches for each change. Anyway your changes have been merged and you are listed as a contributor.
-
@dummzeuch I think handling connections sequentially should be quite easy, without resorting to multiple threads. Once one is closed you wait for the next one. Please bear in mind, that there are limitations when using libssh2 from multiple threads: Points 1 and 3 are the same, since the crypto functions are initialized by libssh2_init. Ssh_pascal handles this in a thread safe manner. The second point, I think means that you either have a session per thread or you protect with a lock, access to the same session and its channels,