CUBA : injecting a datasource in a frame dynamically - cuba-platform

Relates to question CUBA : entity inheritance
I have:
- Customer entity (name, email)
- Company extends Customer (industry)
- Person extends Customer (firstName, lastName)
I would like to design following screens:
- CustomerEditFrame, no datasource defined
- CompanyEditScreen embedding CustomerEditFrame
- PersonEditScreen embedding CustomerEditFrame
Then I need to define the datasource of the frame:
- In CompanyEditScreen, a companyDs needs to be defined for the frame
- In PersonEditScreen, a personDs needs to be
Options I see:
1) In all screens embedding the frame, use the same datasource name (e.g customerDs) so that it can be injected in the frame : confusing, if I have a Company Datasource I would like to call it companyDs and not customerDs
2) From the frame, call getDsContext().get(ds_id) : nok, because name of ds changes
3) From the frame, iterate on getDsContext().getAll() and look for a datasource over a Customer class or a subclass and ensure there is only one : not safe, not sure to get the right one
4) From the screen, e.g CompanyEditScreen, assign the companyDs to the frame in the init() method : no method to do so per se
Have looked through all the samples (including sampler code). The case that is closer is the OrderEdit screen of the Sales sample which dynamically open a frame depending on the Operation type. It does not cover inheritance but the solution used is based on datasource name (1st option, which I find confusing when dealing with children classes).
How should I do ?

I would suggest passing an entity instance to the frame instead of passing or referencing the whole datasource, as explained here.
When the screen with two datasources containing the same instance (one in the screen and one in the nested frame) will be committed, there will be no any duplication because screen collects data from all dirty datasources into a single Set.

Related

How to declare two types of layout access one method first one (Post) next( Ads) using one method in adapter class

Is there possibility to have post and ads methods in two class based view?
I tried to do something like this but of course it doesn't work and error it not working (layout ads) Id
enter image description here
In line 55, change HolderProduct to RecyclerView.ViewHolder, and also in your NewpostAdapter class declaration change the ViewHolder type from HolderProduct to RecyclerView.ViewHolder. Then adjust overriden methods accordingly.

Saving Entity does not update class-hierachy labels correctly

I have an abstract superclass Report and two Subclasses SimpleReport and ExtendedReport, which I want to persist in my database.
If a SimpleReport is created, it has the labels "Report" and "SimpleReport" attached to it, as expected.
A user can modify such a SimpleReport, which leads to the SimpleReport becoming an ExtendedReport.
If I now save this ExtendedReport (using the same ID as the SimpleReport, because I just want to update it) it has the labels "Report", "SimpleReport"and "ExtendedReport" attached to it.
IMHO the label "SimpleReport" should be removed on save. I`m currently deleting the wrong label using a cypher query after saving the updated report.
I´m asking if there is a better way to archive this, if may approach is wrong or if this is a bug in ogm?
The rules for labels are as follows:
any plain concrete class in the hierarchy generates a label by default
plain abstract class does not generate a label by default
plain interface does not generate a label by default
any class annotated with #NodeEntity or #NodeEntity(label="something") generates a label
empty or null labels must not be allowed
classes / hierarchies that are not to be persisted must be annotated with #Transient
Therefore if you remove abstract from your base class, or add a #NodeEntity annotation, you will see the results you expect.
Edit:
The OGM does not remove labels when a class is renamed. Any additional labels are left intact.
You can remove these manually using direct database access.
You can declare a field with the #Labels annotation to manage adding/removing additional labels from an entity.

What is the name of described pattern?

From high level perspective, the pattern makes possible to get polymorphic behavior without creating classes hierarchy.
It consists of 3 parts:
Data container classes, which have a certain field to be distinguished (e.g. User class with country field, or any class with tenant field in a multi-tenant saas project).
Context classes: these classes contain the data and logic which varies for different types of data containers (e.g. different logic for different tenants). There's a top-level Context class with all varying props set to default, and multiple derived classes which override defaults.
Data consumers/processors: these are business logic holders. They accept data container(s) and Context as parameters.
The 3rd-group citizen may have a method like:
Price getPrice(Price price, Context context) {
double VAT = context.getVAT()
return new Price(
transform(price.amount + price.amount * VAT, price.currency, context.currency),
context.currency
)
}
...
//and here's the call:
Context ctx = getContext(principal.getCountry())
Price priceInUserCurrency = priceCalculator(priceInUsd, ctx);
Here's a simplified UML diagram:
Basic usage: when we need to introduce a different specific behavior for small groups of objects of the same class,
we add a new method to Context with reasonable default value and implement the actual logic in concrete contexts. Then whereever we need to inject this piece of logic, we just call correspondent context method.
It looks like you are describing the Strategy Design Pattern.
What gives it away is that you can perform process() for both PersonProcessor and PaymentProcessor. Like this example below.
Each object knows how to handle their own case of the functionality.
To me the description of
makes possible to get polymorphic behavior without creating classes hierarchy
is more close to the concept of the State design pattern.
Because it allow an object to alter its behavior when its internal state changes. The object will appear to change its class. Further more also allows you to keep attributes of a former state even when the state changes afterwards.
About the inheritance part you can read more here.

Interactive QSqlTableModel

Please could you give me an advice. I am using QSqlTableModel class to access the database table and QTableView to view it. What signal of what instance should I handle to know about user move the cursor in QTableView?
I want to update the content of TableView B after the cursor moved in QTableView A (Table B have foreign keys to table A in database)
May be somewhat from this http://doc.trolltech.com/latest/qabstractitemmodel.html?
Thanks.
Ivan, if you are talking about table cursor, you can reimplement QAbstractItemView::moveCursor method which is virtual.
If you're talking about mouse cursor, you can use QAbstractItemView::viewportEvent method to detect mouse move event. You need to set QWidget::setMouseTracking(true) to the viewport of your QTableView.
Hope that helps
Another way is using the selection model
Using a selection model
The standard
view classes provide default selection
models that can be used in most
applications. A selection model
belonging to one view can be obtained
using the view's selectionModel()
function, and shared between many
views with setSelectionModel(), so the
construction of new selection models
is generally not required.
If you have an shared selection model the views will be updated not matter which one changes. You can then react to it. The selection flags control if you want a cell, row or multiple selections.
See also working with selections :
//selection changes shall trigger a slot
QItemSelectionModel *selectionModel= treeView->selectionModel();
connect(selectionModel, SIGNAL(selectionChanged (const QItemSelection &, const QItemSelection &)),
this, SLOT(selectionChangedSlot(const QItemSelection &, const QItemSelection &)));
}

How to use GtkTreeView correctly

I am using a TreeView with a ListStore as model. When the user clicks on a row I want to take some action but not using the values in the cells, but using the data I created the row from...
Currently I have the TreeView, the TreeModel (ListStore) and my own data (which I ironically call model)..
So the Questions are:
Is it "right" to have a model - an object representation of the data I want to display and fill a ListStore with that data to display in a TreeView, or would it be better to implement an own version of TreeModel (wrapping my data-model) to display the data?
And also:
If someone double-clicks in a row I can get the RowActivated event (using C#/Gtk#) which provides a Path to the activated row. With that I can get a TreeIter and using that I can get the value of a cell. But what is the best practice to find the data object from which the row was constructed in the first place?\
(Somehow this question got me to the first one - by thinking would getting the data object more easy if I tried to implement my own TreeModel...)
It's quite awkward/difficult to implement TreeModel, so most people simply synch the data from their "real" model into a TreeStore or ListStore.
The columns in the store do not have to match the columns in the view in any way. For example, you can have a column that contains your real managed data objects.
When you add a cellrenderer to a TreeView (visual) column, you can add mappings between its properties and the columns of the store. For example, you could map one store column to the font of a text cellrenderer, and another store column to the text property of the same cellrenderer. Each time the cellrenderer is used to render a particular cell, the mappings will be used to retrieve the values from the store and apply them to the properties of the renderer before it renders.
Here's an example of a mapping:
treeView.AppendColumn ("Title", renderer, "text", 0, "editable", 4);
This maps store column 0 to the renderer's text GTK property and maps store column 4 to the editable property. For GTK property names you can check the GTK docs. Note that the example above uses a convenience method that adds a column, adds a renderer to it and add an arbitrary number of mapping via params. To add mappings directly to a column, for example a column with multiple renderers, pack the renderers into the column then use TreeViewColumn.AddAttribute or TreeViewColumn.SetAttributes.
You can also set up a custom data function that will be used instead of mappings. This allows you to set the properties of the renderer directly, given a TreeIter and the store - so, if all the data you want to display is trivially derived from your real data objects, you could even have your store only contain a single column of these objects, and use data funcs for all the view columns.
Here's an example of a data func that does exactly what the mapping example above does:
treeColumn.SetCellDataFunc (renderer, delegate (TreeViewColumn col,
CellRenderer cell, TreeModel model, TreeIter iter)
{
var textCell = (CellRendererText) cell;
textCell.Text = (string) model.GetValue (iter, 0);
textCell.Editable = (bool) model.GetValue (iter, 4);
});
Obviously data functions are much more powerful because they enable you not only to use properties of more complex GTK objects, but also to implement more complex display logic - for example, lazily processing derived values only when the cell is actually rendered.