How to adding new section in INI file using TJvAppIniFileStorage - delphi

I have a database application project written in Delphi XE and connected to MySQL Database using dbExpress. I use JVCL grid Components to show the records from the Dataset. It will be more efficiently if I can use another JVCL Components to do the FormStorage.
I've been suggested to use TJvFormStorage and TJvAppIniFileStorage for form storage. I have many forms on this project so I need to adding new section in my INI file to store the form size values but I don't know how to do that using TJvAppIniFileStorage.
The TJvAppIniFileStorage is just providing the DefaultSection() method which means it's just can modify and write into one section only which declared as the default.
Anyone can describe to me how to adding new section using the JVCL's TJvAppIniFileStorage?
Thanks in advance.

Is the TJvFormStorage instance the one that determines in which path of the abstract storage to put the data about this form, with the value of the AppStoragePath property.
You can use the special value '%FORM_NAME%' to determine that path automatically at run-time. The '%FORM_NAME%' is changed for the real .Name property of the form where the component is located, or if it is a frame, a dot list of the frame chain up to the form containing it. That way you can have different instances of the same class saving the info to different paths.
When you're using a TJvAppIniFileStorage instance as the data storage backed to save the form data to a INI file, that path is equivalent to the INI section where the information is stored.
In other words, if you want to store the info of your form in a section called 'MyForm', set that value to the AppStoragePath property of the TjvFormStorage instance in that form.

Use the Source, Luke! ;)
My guess is: It uses Parent.Name or Parent.ClassName to store parameters.
Another point: take in mind several monitors on user's computer. Almost no app takes in mind this case.

Related

Genexus Extensions SDK - Is there a built in helper to save data locally?

I Would like to know if the Genexus Extension SDK already implements something to store persistent data locally (KB Independant and per KB), something like PersistentDictionary from ManagedEsent
I know that genexus uses SQL Server to store KB Related information, is there an interface for me to extend that?
I want to save data per genexus instance (locally) and use that data to load my extension config, everytime the users executes Genexus.
We don't use PersistentDictionary. I would advice not to use it, as it's a Windows specific API, and we are trying make everything new cross platform, as part of our journey of making GeneXus BL run on other OS.
There are different options of persistence, depending on the specific details of your scenario.
If you want to store something like configuration settings for your extension, you can use the ConfigurationHelper class located in Artech.Common.Helpers. This class provides read access to the configurations defined in the GeneXus.exe.config file in the GeneXus installation folder, as well as read/write access to the Environment.config file located in %AppData%\GeneXus\GeneXus\<version>\Environment.config. Note this file depends on the current user, and is shared between different GeneXus instances of a same main version.
The ConfigurationHelper class provides operations to read and save settings of basic types string, int and bool.
const string MY_EXTENSION = "MyExtensionSettings";
const string SETTING1 = "Setting1";
const string SETTING1_DEFAULT_VALUE = "This is the default value";
const string SETTING2 = "Setting2";
const int SETTING2_DEFAULT_VALUE = 20;
string setting1Value = ConfigurationHelper.GetUserSetting(MY_EXTENSION, SETTING1, SETTING1_DEFAULT_VALUE);
int setting2Value = ConfigurationHelper.GetUserSetting(MY_EXTENSION, SETTING2, SETTING2_DEFAULT_VALUE);
// Do something and maybe change the setting values
ConfigurationHelper.SetUserSetting(MY_EXTENSION, SETTING1, setting1Value);
ConfigurationHelper.SetUserSetting(MY_EXTENSION, SETTING2, setting2Value);
If you want to store something in a file based on the current opened KB, there's no specific API that'll help you handle the persistence. You can use the properties Location and UserDirectory of the KnowledgeBase class to access the KB location or a directory for the current user under the KB location, but it's up to you the handling of the file. You'll have to decide on the file format (binary or text), file encoding in case of text files, and handle all read and write operations to that file.
We use the kb.UserDirectory path to store non-critical stuff, such as the set of objects that were opened the last time the KB was closed, or the filter values for different dialogs.
In case you'd like to store settings inside the KB, there are plenty of options.
You can add properties to existing objects, KB version or environment. Making it a property doesn't necessary mean you'll have to edit the value in the property grid, although it's usually the way to go.
You can define a new kind of entity. Entities are the basic elements that can be stored in a KB. The entity may be stored depending on the active version of the KB, or may be independent of the current version. Entities can have properties, whose serialization is handled by the property engine, and also can read and store a byte array whose format and content will be handled by you.
You can add a part to an existing object. For instance you may want to add a part to Procedure objects. In order to do this you'll have to extend KBObjectPart, define your part in a BL package, declare that the part composes objects of certain type, and provide an editor for your new part in a UI package. KBObjectPart extends Entity so the serialization of the part is similar as in the previous case. A caveat of this option is that you'll also have to handle how the part content is imported, exported, and compared.
You can add a new kind of object. Objects extend the KBObject class, which extends Entity. Objects are not obliged to have parts (for instance the Folder object doesn't have any). When choosing to provide a new kind of object you have to consider a couple of things, such as:
Do you want to be able to create new instances from the new object dialog?
Will it be shown in the folder view?
Can it be added into modules?
Can it have the same name as other objects of different types?
As a general guideline, if you choose to add a new property, add it to objects, versions, or environments, not parts. Adding properties to parts is not so good for discoverability. Also if you choose to add a new kind of object, even though it inherits from Entity which as mentioned earlier can read and store a byte array, it's preferred to don't use the byte array in KBObject and add a KBObjectPart to it instead. That way the KBObject remains as lightweight as possible, and loading the object definition from the DB remains fast, and the blob content is loaded only when truly needed.
There's no rule of thumb. Depending on the specifics of the scenario, one option may be more suited than others.

TDateEdit cannot LiveBinding with a datasource bidirection

This is a simple question.
Start a multidevice App, place a TDateEdit and DBTable with a field containing TdateTime data. Then use LiveBinding designer link the data source field to TDateEdit.DateTime property. However, this link is unidirectional , The control DateEdit can accept the data from the Datasource, but cannot update the changes to the datasource. How to change the link to bidreiction???
There may be some things that are not clearly understood.
Normally a LiveBindings link will be bidirectional - so if you setup two TDateEdits and bind them together changing one should change the other, irrespective of which one you change.
It seems that what you are hoping is that changing the TField will update the data in the database table.
That's not typically how the Data Access components in Delphi work.
The TField is part of a TDataSet. The TDataSet has a Post method to write changes to the underlying data store, if that's supported.
The Data Access components are extremely powerrful and can cope with lots of different scenarios, and allow you to extended capabilities throguh exposed events as well as subclassing the components.
If you want to update your underlying data store you need to have a writeable TDataSet and you need to call Post on it to write.
I suggest you start off with some of the videos in Enbarcadero's YouTube channel about how to use the data acecss components. It's not difficult to do but beyond the scope of an answer here.
If you use the LiveBindings Wizard to hook the DateEdit with a field, it will hook it up bi-diretionally to a "virtual" SelectedDateTime property of the DateEdit. That property doesn't really exist in the TDateEdit but is used by the LiveBindings to map the separate Date and Time properties of the DateEdit.

Custom form elements for database entities in form builder

We consider Orbeon PE 4.10 for one of our projects. I know that you can add custom form elements as XBL components. Therefore, I read this documentation.
For our project, we need to add datamodel elements to the Form Builder (like the creation of an Microsoft Access form for an existing Access datamodel). Let´s say we have an existing database datamodel with an entity event. This entity has e.g. 15 database attributes like an arrival date, expected number of participants, topic, description etc.
When I create a new form for an event in Form Builder, I want to see all the fields mentioned above in a tree structure so that users can drag and drop those fields into a form (exactly like in Access). In addition, there should be a data binding between the form elements and the database entity.
My question is, of this is possible to realize without changing the source code of orbeon forms PE?
Orbeon Forms doesn't do "relational database mapping", but instead focuses on data capture. So the approach is maybe a little bit different than what you would do in Access. Instead of starting with a database schema, and then designing a form that you map to that schema, you start with the form, and Form Builder automatically creates an XML document for you that holds the data entered by users, and that XML document is typically stored as-is in your database. Then, when you need to access the data, you have Orbeon Forms send the XML to your app, go through the REST API, or access the XML directly in the database.
Now, about the event use case you're describing, if this is something that happens in several forms, you can create a section template for that event, and reuse it whereever you need it. For cases where you need something more custom, like a special date field, map field, or special type of number that requires a custom validation, you can create your own XBL component, which gives you more control, but requires a little more work to put in place compared to section templates.

Can Orbeon controls have multiple values?

I think the answer is no, but the question has been put to me so I'd like to confirm. My understanding is that any custom XBL control that I create for use in Form Builder can have one and only one value. Is this correct?
I have always assumed this because the control name is then used in the data instance as the name of the node which contains the the value.
This question comes from the desire to have reusable components with multiple values, for example, an Address control so that addresses can be recorded consistently and the same set of fields does not need to be added many times. Orbeon does have some support for this in the form of Section Templates but because the control names stay the same in each instance of a Section Template this does not work well with our design.
The best idea I've had is that a custom control which records multiple values could encode all the values into a single text string for example in JSON. Of course, this is not ideal.
Are there any other options?
It is possible for controls to have multiple values. When that happens the values are typically stored in nested elements. I.e. a control could bound to an element <address>, and could create nested elements <street>, <city>,<country>, etc to store the different parts of the address.
In practice, you can look at how this is done in the Image Annotation annotation control (see wpaint.xbl), which creates nested elements <image> and <annotation>, leveraging the xxbl:mirror="true" functionality.

How can I set a TClientDataSet's data in the design view?

I have a TClientDataSet object that I've added to my form.
I've managed to define the fields through the object inspector. However, is there a way to define the data the TClientDataSet contains without doing it in code?
I've managed to do it by adding some AppendRecord statements to the ShowForm event; but I'd rather keep the definition of the TClientDataSet all in one place.
Prior to v10.2 (Seattle, Berlin, etc.), there were no facilities to do this.
You can store and load a file into the ClientDataSet or you can use the Assign Local Data (right click on the ClientDataSet) to load data from an existing source. However, you cannot append or edit the data from inside the IDE directly.
As of v10.2 (Tokyo) has recently added this as a feature.

Resources