Recent

Author Topic: Nested Property Component problem  (Read 2071 times)

J-23

  • Full Member
  • ***
  • Posts: 108
Nested Property Component problem
« on: March 25, 2018, 01:18:16 am »
Hi,
I am writing a component and I have a problem with nested properties

I have such properties:
DirectoryComposition -> Description

The description property has two more properties, such as:
- XML
- DescriptionField

Why does the XML and DescriptionField property not write to LFM?

Below is the complete unit of the component's properties:
Code: Pascal  [Select][+][-]
  1. unit CompositionDialogProperty;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, DB, PropEdits, DBPropEdits, TypInfo, Controls;
  9.  
  10. type
  11.  
  12.   { TDataSourceProperty }
  13.  
  14.   TDataSourceProperty = class(TPersistent)
  15.   private
  16.     FDataField: string;
  17.     FDataSource: TDataSource;
  18.     procedure SetDataField(AValue: string);
  19.     procedure SetDataSource(AValue: TDataSource);
  20.   published
  21.     property DataSource: TDataSource read FDataSource write SetDataSource;
  22.     property DataField: string read FDataField write SetDataField;
  23.   end;
  24.  
  25. type
  26.  
  27.   { TStatusCompositionFilter }
  28.  
  29.   TStatusCompositionFilter = class(TPersistent)
  30.   private
  31.     FKeyField: string;
  32.     FListField: string;
  33.     FListFieldIndex: integer;
  34.     FListSource: TDataSource;
  35.     procedure SetKeyField(AValue: string);
  36.     procedure SetListField(AValue: string);
  37.     procedure SetListFieldIndex(AValue: integer);
  38.     procedure SetListSource(AValue: TDataSource);
  39.   published
  40.     property ListFieldIndex: integer read FListFieldIndex write SetListFieldIndex;
  41.     property ListSource: TDataSource read FListSource write SetListSource;
  42.     property KeyField: string read FKeyField write SetKeyField;
  43.     property ListField: string read FListField write SetListField;
  44.   end;
  45.  
  46. type
  47.  
  48.   { TStatusComposition }
  49.  
  50.   TStatusComposition = class(TDataSourceProperty)
  51.   private
  52.     FKeyField: string;
  53.     FListField: string;
  54.     FListFieldIndex: integer;
  55.     FListSource: TDataSource;
  56.     procedure SetKeyField(AValue: string);
  57.     procedure SetListField(AValue: string);
  58.     procedure SetListFieldIndex(AValue: integer);
  59.     procedure SetListSource(AValue: TDataSource);
  60.   published
  61.     property ListFieldIndex: integer read FListFieldIndex write SetListFieldIndex;
  62.     property ListSource: TDataSource read FListSource write SetListSource;
  63.     property KeyField: string read FKeyField write SetKeyField;
  64.     property ListField: string read FListField write SetListField;
  65.   end;
  66.  
  67. type
  68.   TDirectoryComposition = class;
  69.  
  70. type
  71.  
  72.   { TDescription }
  73.  
  74.   TDescription = class(TPersistent)
  75.   private
  76.     FDescriptionField: string;
  77.     FXML: boolean;
  78.     FParent: TDirectoryComposition;
  79.     procedure SetDescriptionField(AValue: string);
  80.     procedure SetXML(AValue: boolean);
  81.   protected
  82.     property Parent: TDirectoryComposition read FParent;
  83.   published
  84.     property DescriptionField: string read FDescriptionField write SetDescriptionField;
  85.     property XML: boolean read FXML write SetXML;
  86.   public
  87.     constructor Create(AParent: TDirectoryComposition);
  88.   end;
  89.  
  90. type
  91.  
  92.   { TDirectoryComposition }
  93.  
  94.   TDirectoryComposition = class(TDataSourceProperty)
  95.   private
  96.     FDescription: TDescription;
  97.     FImageIndex: integer;
  98.     FImageList: TimageList;
  99.     FKeyField: string;
  100.     FOnDirectoryCompositionError: TNotifyEvent;
  101.     FParentField: string;
  102.     procedure SetImageIndex(AValue: integer);
  103.     procedure SetImageList(AValue: TimageList);
  104.     procedure SetKeyField(AValue: string);
  105.     procedure SetOnDirectoryCompositionError(AValue: TNotifyEvent);
  106.     procedure SetParentField(AValue: string);
  107.   public
  108.     constructor Create;
  109.     destructor Destroy; override;
  110.   published
  111.     property KeyField: string read FKeyField write SetKeyField;
  112.     property ParentField: string read FParentField write SetParentField;
  113.     property Description: TDescription read FDescription;
  114.     property ImageList: TimageList read FImageList write SetImageList;
  115.     property ImageIndex: integer read FImageIndex write SetImageIndex;
  116.     property OnDirectoryCompositionError: TNotifyEvent
  117.       read FOnDirectoryCompositionError write SetOnDirectoryCompositionError;
  118.   end;
  119.  
  120. type
  121.  
  122.   { TListComposition }
  123.  
  124.   TListComposition = class(TDataSourceProperty)
  125.   private
  126.     FKeyField: string;
  127.     FListField: string;
  128.     FListFieldIndex: integer;
  129.     FListSource: TDataSource;
  130.     FOnListCompositionError: TNotifyEvent;
  131.     FStatusComposition: TStatusComposition;
  132.     procedure SetKeyField(AValue: string);
  133.     procedure SetListField(AValue: string);
  134.     procedure SetListFieldIndex(AValue: integer);
  135.     procedure SetListSource(AValue: TDataSource);
  136.     procedure SetOnListCompositionError(AValue: TNotifyEvent);
  137.     procedure SetStatusComposition(AValue: TStatusComposition);
  138.   public
  139.     constructor Create;
  140.     destructor Destroy; override;
  141.   published
  142.     property ListFieldIndex: integer read FListFieldIndex write SetListFieldIndex;
  143.     property ListSource: TDataSource read FListSource write SetListSource;
  144.     property KeyField: string read FKeyField write SetKeyField;
  145.     property ListField: string read FListField write SetListField;
  146.     property StatusComposition: TStatusComposition
  147.       read FStatusComposition write SetStatusComposition;
  148.     property OnListCompositionError: TNotifyEvent
  149.       read FOnListCompositionError write SetOnListCompositionError;
  150.   end;
  151.  
  152. type
  153.  
  154.   { TSubFieldProperty }
  155.  
  156.   TSubFieldProperty = class(TFieldProperty)
  157.   public
  158.     procedure FillValues(const Values: TStringList); override;
  159.   end;
  160.  
  161.  
  162. implementation
  163.  
  164. { TStatusCompositionFilter }
  165.  
  166. procedure TStatusCompositionFilter.SetKeyField(AValue: string);
  167. begin
  168.   if FKeyField = AValue then
  169.     Exit;
  170.   FKeyField := AValue;
  171. end;
  172.  
  173. procedure TStatusCompositionFilter.SetListField(AValue: string);
  174. begin
  175.   if FListField = AValue then
  176.     Exit;
  177.   FListField := AValue;
  178. end;
  179.  
  180. procedure TStatusCompositionFilter.SetListFieldIndex(AValue: integer);
  181. begin
  182.   if FListFieldIndex = AValue then
  183.     Exit;
  184.   FListFieldIndex := AValue;
  185. end;
  186.  
  187. procedure TStatusCompositionFilter.SetListSource(AValue: TDataSource);
  188. begin
  189.   if FListSource = AValue then
  190.     Exit;
  191.   FListSource := AValue;
  192. end;
  193.  
  194. { TSubFieldProperty }
  195.  
  196. procedure TSubFieldProperty.FillValues(const Values: TStringList);
  197. var
  198.   DataSource: TDataSource;
  199. begin
  200.   DataSource := GetObjectProp((GetComponent(0) as TDescription).Parent, 'DataSource') as
  201.     TDataSource;
  202.   ListDataSourceFields(DataSource, Values);
  203. end;
  204.  
  205. { TDescription }
  206.  
  207. procedure TDescription.SetDescriptionField(AValue: string);
  208. begin
  209.   if FDescriptionField = AValue then
  210.     Exit;
  211.   FDescriptionField := AValue;
  212. end;
  213.  
  214. procedure TDescription.SetXML(AValue: boolean);
  215. begin
  216.   if FXML = AValue then
  217.     Exit;
  218.   FXML := AValue;
  219. end;
  220.  
  221. constructor TDescription.Create(AParent: TDirectoryComposition);
  222. begin
  223.   FParent := AParent;
  224. end;
  225.  
  226. { TListComposition }
  227.  
  228. procedure TListComposition.SetKeyField(AValue: string);
  229. begin
  230.   if FKeyField = AValue then
  231.     Exit;
  232.   FKeyField := AValue;
  233. end;
  234.  
  235. procedure TListComposition.SetListField(AValue: string);
  236. begin
  237.   if FListField = AValue then
  238.     Exit;
  239.   FListField := AValue;
  240. end;
  241.  
  242. procedure TListComposition.SetListFieldIndex(AValue: integer);
  243. begin
  244.   if FListFieldIndex = AValue then
  245.     Exit;
  246.   FListFieldIndex := AValue;
  247. end;
  248.  
  249. procedure TListComposition.SetListSource(AValue: TDataSource);
  250. begin
  251.   if FListSource = AValue then
  252.     Exit;
  253.   FListSource := AValue;
  254. end;
  255.  
  256. procedure TListComposition.SetOnListCompositionError(AValue: TNotifyEvent);
  257. begin
  258.   if FOnListCompositionError = AValue then
  259.     Exit;
  260.   FOnListCompositionError := AValue;
  261. end;
  262.  
  263. procedure TListComposition.SetStatusComposition(AValue: TStatusComposition);
  264. begin
  265.   if FStatusComposition = AValue then
  266.     Exit;
  267.   FStatusComposition := AValue;
  268. end;
  269.  
  270. constructor TListComposition.Create;
  271. begin
  272.   FStatusComposition := TStatusComposition.Create;
  273. end;
  274.  
  275. destructor TListComposition.Destroy;
  276. begin
  277.   FStatusComposition.Free;
  278.   inherited Destroy;
  279. end;
  280.  
  281. { TDirectoryComposition }
  282.  
  283. procedure TDirectoryComposition.SetKeyField(AValue: string);
  284. begin
  285.   if FKeyField = AValue then
  286.     Exit;
  287.   FKeyField := AValue;
  288. end;
  289.  
  290. procedure TDirectoryComposition.SetImageList(AValue: TimageList);
  291. begin
  292.   if FImageList = AValue then
  293.     Exit;
  294.   FImageList := AValue;
  295. end;
  296.  
  297. procedure TDirectoryComposition.SetImageIndex(AValue: integer);
  298. begin
  299.   if FImageIndex = AValue then
  300.     Exit;
  301.   FImageIndex := AValue;
  302. end;
  303.  
  304. procedure TDirectoryComposition.SetOnDirectoryCompositionError(AValue: TNotifyEvent);
  305. begin
  306.   if FOnDirectoryCompositionError = AValue then
  307.     Exit;
  308.   FOnDirectoryCompositionError := AValue;
  309. end;
  310.  
  311. procedure TDirectoryComposition.SetParentField(AValue: string);
  312. begin
  313.   if FParentField = AValue then
  314.     Exit;
  315.   FParentField := AValue;
  316. end;
  317.  
  318. constructor TDirectoryComposition.Create;
  319. begin
  320.   FDescription := TDescription.Create(Self);
  321. end;
  322.  
  323. destructor TDirectoryComposition.Destroy;
  324. begin
  325.   FDescription.Free;
  326.   inherited Destroy;
  327. end;
  328.  
  329. { TStatusComposition }
  330.  
  331. procedure TStatusComposition.SetListFieldIndex(AValue: integer);
  332. begin
  333.   if FListFieldIndex = AValue then
  334.     Exit;
  335.   FListFieldIndex := AValue;
  336. end;
  337.  
  338. procedure TStatusComposition.SetKeyField(AValue: string);
  339. begin
  340.   if FKeyField = AValue then
  341.     Exit;
  342.   FKeyField := AValue;
  343. end;
  344.  
  345. procedure TStatusComposition.SetListField(AValue: string);
  346. begin
  347.   if FListField = AValue then
  348.     Exit;
  349.   FListField := AValue;
  350. end;
  351.  
  352. procedure TStatusComposition.SetListSource(AValue: TDataSource);
  353. begin
  354.   if FListSource = AValue then
  355.     Exit;
  356.   FListSource := AValue;
  357. end;
  358.  
  359. { TDataSourceProperty }
  360.  
  361. procedure TDataSourceProperty.SetDataSource(AValue: TDataSource);
  362. begin
  363.   if FDataSource = AValue then
  364.     Exit;
  365.   FDataSource := AValue;
  366. end;
  367.  
  368. procedure TDataSourceProperty.SetDataField(AValue: string);
  369. begin
  370.   if FDataField = AValue then
  371.     Exit;
  372.   FDataField := AValue;
  373. end;
  374.  
  375. initialization
  376.   RegisterPropertyEditor(TypeInfo(string), TDataSourceProperty,
  377.     'DataField', TFieldProperty);
  378.  
  379.   RegisterPropertyEditor(TypeInfo(string), TDirectoryComposition,
  380.     'KeyField', TFieldProperty);
  381.   RegisterPropertyEditor(TypeInfo(string), TDirectoryComposition,
  382.     'ParentField', TFieldProperty);
  383.   RegisterPropertyEditor(TypeInfo(string), TDescription,
  384.     'DescriptionField', TSubFieldProperty);
  385.  
  386.   RegisterPropertyEditor(TypeInfo(string), TStatusComposition,
  387.     'KeyField', TLookupFieldProperty);
  388.   RegisterPropertyEditor(TypeInfo(string), TStatusComposition, 'ListField',
  389.     TLookupFieldProperty);
  390.  
  391.   RegisterPropertyEditor(TypeInfo(string), TListComposition,
  392.     'KeyField', TLookupFieldProperty);
  393.   RegisterPropertyEditor(TypeInfo(string), TListComposition, 'ListField',
  394.     TLookupFieldProperty);
  395.  
  396. end.
  397.  

Contents of the LFM file (Fragment Problem):
Code: Pascal  [Select][+][-]
  1.   object CompositionDialogRBM1: TCompositionDialogRBM
  2.     Title = 'ooooooooo'
  3.     StatusCompositionFilter.ListFieldIndex = 0
  4.     StatusCompositionFilter.ListSource = DataSourceStatus
  5.     StatusCompositionFilter.KeyField = 'ID_STATUS'
  6.     StatusCompositionFilter.ListField = 'NAZWA'
  7.     DirectoryComposition.DataSource = DataSourceTree
  8.     DirectoryComposition.DataField = 'NAME'
  9.     DirectoryComposition.KeyField = 'ID_TREE'
  10.     DirectoryComposition.ParentField = 'PARENT'
  11.     DirectoryComposition.ImageIndex = 0
  12.     ListComposition.ListFieldIndex = 0
  13.     ListComposition.ListSource = DataSourceComposition
  14.     ListComposition.KeyField = 'ID_COMPOSITION'
  15.     ListComposition.ListField = 'COMPOSITION_NAME'
  16.     ListComposition.StatusComposition.DataSource = DataSource2
  17.     ListComposition.StatusComposition.DataField = 'ID_COMPOSITION_STATUS'
  18.     ListComposition.StatusComposition.ListFieldIndex = 0
  19.     ListComposition.StatusComposition.ListSource = DataSource1
  20.     ListComposition.StatusComposition.KeyField = 'ID_STATUS'
  21.     ListComposition.StatusComposition.ListField = 'NAZWA'
  22.     left = 64
  23.     top = 136
  24.   end          
  25.  

I would like the contents of the LFM file to look like this:

Code: Pascal  [Select][+][-]
  1.   object CompositionDialogRBM1: TCompositionDialogRBM
  2.     Title = 'ooooooooo'
  3.     StatusCompositionFilter.ListFieldIndex = 0
  4.     StatusCompositionFilter.ListSource = DataSourceStatus
  5.     StatusCompositionFilter.KeyField = 'ID_STATUS'
  6.     StatusCompositionFilter.ListField = 'NAZWA'
  7.     DirectoryComposition.DataSource = DataSourceTree
  8.     DirectoryComposition.DataField = 'NAME'
  9.     DirectoryComposition.KeyField = 'ID_TREE'
  10.     DirectoryComposition.ParentField = 'PARENT'
  11.     DirectoryComposition.Description.DescriptionField ='DESCRIPTION'
  12.     DirectoryComposition.Description.XML = True;
  13.     DirectoryComposition.ImageIndex = 0
  14.     ListComposition.ListFieldIndex = 0
  15.     ListComposition.ListSource = DataSourceComposition
  16.     ListComposition.KeyField = 'ID_COMPOSITION'
  17.     ListComposition.ListField = 'COMPOSITION_NAME'
  18.     ListComposition.StatusComposition.DataSource = DataSource2
  19.     ListComposition.StatusComposition.DataField = 'ID_COMPOSITION_STATUS'
  20.     ListComposition.StatusComposition.ListFieldIndex = 0
  21.     ListComposition.StatusComposition.ListSource = DataSource1
  22.     ListComposition.StatusComposition.KeyField = 'ID_STATUS'
  23.     ListComposition.StatusComposition.ListField = 'NAZWA'
  24.     left = 64
  25.     top = 136
  26.   end          
  27.  

Lazarus 1.8.2

Regards

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9869
  • Debugger - SynEdit - and more
    • wiki
Re: Nested Property Component problem
« Reply #1 on: March 25, 2018, 01:34:11 am »
Not sure (long time since...)

You might want to try (in the owner's Create)
Code: Pascal  [Select][+][-]
  1.   SetInline(True);
  2.   ControlStyle:=ControlStyle+[csOwnedChildrenNotSelectable]; // optional
  3.  

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Nested Property Component problem
« Reply #2 on: March 25, 2018, 01:43:37 am »
Try
Code: Pascal  [Select][+][-]
  1. property Description: TDescription read FDescription write FDescription;
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

J-23

  • Full Member
  • ***
  • Posts: 108
Re: Nested Property Component problem
« Reply #3 on: March 25, 2018, 03:07:29 am »
Not sure (long time since...)

You might want to try (in the owner's Create)
Code: Pascal  [Select][+][-]
  1.   SetInline(True);
  2.   ControlStyle:=ControlStyle+[csOwnedChildrenNotSelectable]; // optional
  3.  

Where exactly? give an example, because I do not know what exactly you mean

J-23

  • Full Member
  • ***
  • Posts: 108
Re: Nested Property Component problem
« Reply #4 on: March 25, 2018, 03:11:44 am »
Try
Code: Pascal  [Select][+][-]
  1. property Description: TDescription read FDescription write FDescription;

That's how it is done.

With a single nest, everything is ok
It does not save with double nesting.

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Nested Property Component problem
« Reply #5 on: March 25, 2018, 03:16:55 am »
Quote
That's how it is done.

Line 113 of your first post, there it's declared as a read-only property.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

J-23

  • Full Member
  • ***
  • Posts: 108
Re: Nested Property Component problem
« Reply #6 on: March 25, 2018, 02:16:19 pm »
Quote
That's how it is done.

Line 113 of your first post, there it's declared as a read-only property.

You're right, I'm forgetful :)

Regards

 

TinyPortal © 2005-2018