Recent

Author Topic: Is there a way to get the LFM file to be populated with the default values?  (Read 2801 times)

vfclists

  • Hero Member
  • *****
  • Posts: 1048
    • HowTos Considered Harmful?
When LFM files are created and the property values are not set they are automatically set to the defaults when the form is loaded.

Is there a way to get the LFM to be populated  with the defaults where they are not set by the user?
Lazarus 3.0/FPC 3.2.2

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4517
  • I like bugs.
Is there a way to get the LFM to be populated  with the defaults where they are not set by the user?
Not any easy way. AFAIK you would need to modify the component streaming code.
Why would you want that? I have a feeling you try to solve a problem in a wrong way.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 15555
  • Censorship about opinions does not belong here.
Yes, by using the default modifier  on published properties when writing a component. Actually that is quite easy, Juha...
( I mean the default modifier, not the default() intrinsic)
« Last Edit: January 07, 2024, 11:58:30 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4517
  • I like bugs.
Yes, by using the default modifier  on published properties when writing a component. Actually that is quite easy, Juha...
( I mean the default modifier, not the default() intrinsic)
OK, true, but not practical when using ready made component packages. You would need to modify all of them.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

vfclists

  • Hero Member
  • *****
  • Posts: 1048
    • HowTos Considered Harmful?
Is there a way to get the LFM to be populated  with the defaults where they are not set by the user?
Not any easy way. AFAIK you would need to modify the component streaming code.
Why would you want that? I have a feeling you try to solve a problem in a wrong way.

I am upgrading an old 2016 components to the latest version of Lazarus and many of the properties and property values have been removed or changed.

Opening them in the IDE catches some of them for removal but not all. On some of them the F12 button does not work and brings up the LFM instead.

The solution I want to try now is to use  ReadComponentFromTextStream to repeatedly load the properties from the LFM of the old one to a newly created component in try except blocks.

The LFM code will be stored in a memo, and when try except block shows what properties are invalid, I log them, delete them from the memo with LFM code and try again.

The other option is to parse out the properties in the components source code, compare them with those in the LFM and delete the absent ones in the LFM.

I think I will stick to the former for now, because I have to learn how to debug problems in GUIs and emulating  the users steps in code and trapping the exceptions in try except blocks is the only way forward.

 and delete the invalid properties when they are trapped in the in the try except block
Lazarus 3.0/FPC 3.2.2

avra

  • Hero Member
  • *****
  • Posts: 2525
    • Additional info
The other option is to parse out the properties in the components source code, compare them with those in the LFM and delete the absent ones in the LFM.
You can look at ct2laz which parses PAS, LFM and other CT project files and according to the rules defined in CSV file it does string replacements. With a little adaption you could use it for your case.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

Curt Carpenter

  • Hero Member
  • *****
  • Posts: 505
You probably know more about this than I do, but I used JSONPropStorage to store a full set of default component settings once I settlted on them, and then reload the JSON file settings each time my program starts.  XMLPropStorage and IniPropStorage are alternatives.  None of them alter the LFM file of course, but that may be a plus in a lot of cases.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11732
  • FPC developer.
There is iirc also a defineproperties overridable method. So the RTTI is not entirely complete for a for.

vfclists

  • Hero Member
  • *****
  • Posts: 1048
    • HowTos Considered Harmful?
Yes, by using the default modifier  on published properties when writing a component. Actually that is quite easy, Juha...
( I mean the default modifier, not the default() intrinsic)

By default modifier this do you mean code like this:
Code: Pascal  [Select][+][-]
  1.     property FramesTopMargin: integer read FFramesTopMargin write FFramesTopMargin default 2;
  2.     property FrameHeight: integer read FFrameHeight write FFrameHeight default 40;
  3.     property LeftMargin: integer read FLeftMargin write FLeftMargin default 6;
  4.     property EditWidth: integer read FEditWidth write FEditWidth default 160;
  5.     property LabelTop: integer read FLabelTop write FLabelTop default 0;
  6.  

I tried it and it doesn't seem to work.

When I drop a new component on the form aren't the properties supposed to be automatically set to these?
Lazarus 3.0/FPC 3.2.2

Bart

  • Hero Member
  • *****
  • Posts: 5349
    • Bart en Mariska's Webstek
When I drop a new component on the form aren't the properties supposed to be automatically set to these?

No, if a property has the default value, it will not be streamed to the lfm.
It is however the responsibility of the component's author/writer to actually set the value of the property to the designated default value.
Usually this is done in the components constructor.


Bart

vfclists

  • Hero Member
  • *****
  • Posts: 1048
    • HowTos Considered Harmful?
When I drop a new component on the form aren't the properties supposed to be automatically set to these?

No, if a property has the default value, it will not be streamed to the lfm.
It is however the responsibility of the component's author/writer to actually set the value of the property to the designated default value.
Usually this is done in the components constructor.


Bart

Does that mean that in the constructor I should do something like this:
Code: Pascal  [Select][+][-]
  1.     FFramesTopMargin := 2;
  2.     FFrameHeight := 40;
  3.     FLeftMargin := 6;
  4.     FEditWidth := 160;
  5.     FLabelTop := 0;
  6.  

meaning these values will be retained and be shown in the inspector unless the LFM contains different values?
Lazarus 3.0/FPC 3.2.2

BildatBoffin

  • New Member
  • *
  • Posts: 27
I see the issue since I had the issue a few years back, in dexed: config of a widget is stored using component streaming. One file A defines a non-default value for property X. Load it. Nice. Then you load a different setting file, filr B, with X not written because X value was the default, so after the load, X is not modified and keep the value from the previous file (A).

Hence I'd advice to try stored (https://www.freepascal.org/docs-html/ref/refsu38.html).

Syntax must something like

Code: Pascal  [Select][+][-]
  1. property FramesTopMargin: integer read FFramesTopMargin write FFramesTopMargin default 2; stored true;
« Last Edit: August 25, 2024, 11:50:38 pm by BildatBoffin »

wp

  • Hero Member
  • *****
  • Posts: 12305
I am upgrading an old 2016 components to the latest version of Lazarus and many of the properties and property values have been removed or changed.

Opening them in the IDE catches some of them for removal but not all.
This does not have to do with the default value. When properties having default values are removed in a later Laz version you still can load that lfm without error and without changes because these properties simply are not listed in the lfm - that's one of the big advantages of assigning default values to properties.

But when there are renamed/removed properties which do not have a default value of have a value different from default they cannot be loaded by a newer Laz version because the lfm parser during streaming cannot find these names any more. In this case I close the IDE, open the lfm in an external editor (*), manually remove the unknown properties and then load the form into the IDE again; I usually have to repeat these steps several times until the form loads without error. Before doing this you should have a look at the Release Notes (e.g. https://wiki.freepascal.org/Lazarus_3.0_release_notes for Laz 3.0, see others at the bottom of the page); they contain a section about incompatible changes.

If you need to know a default value take a look at the constructor of the component.

Working with different versions is greatly simplified when you have both old and new Laz versions available; in Windows use the "secondary installation" feature to get independent versions, in Linux/mac install into the home directory and use different config directories for each version (--primary-config-path=<path-to-config-dir>) in a lazarus.cfg file next to the Laz binary.

When you want to load the same form into both old and new Laz versions use {$IF LCL_FullVersion<aabbccdd} directives (where "a".."c" are the different levels of version numbers; e.g. LCL_FullVersion = 3040000 for Laz 3.4.0.0). In this case it may be advantageous to create the changing components at runtime and to delete them from the lfm at all. You may have to set non-default property values within {$IF LCL_FullVersions...} blocks again.

(*) Do not do this in the IDE because of heavy caching and because you can crash the IDE easily here.

 

TinyPortal © 2005-2018