Repeater-like qbs item - qbs

I am looking for a way to instantiate several qbs items whose quantity and properties are based on some product properties, something like:
Repeater {
model: ["module1", "module2", "module3"]
delegate: Depends { name: model[index] }
}
Problem I'm trying to solve is creating a product with a weak dependence on every other product in the project: to process outputs of dependees which are built, but to never force a product to be built

There is no such item. The Depends item's productTypes property might do what you need: http://doc-snapshots.qt.io/qbs-1.11/qml-qbslanguageitems-depends.html#productTypes-prop

Related

How do you add data bars to a chart via Java?

On startup, I'm trying to add a varying quantity of values to a barchart. I have an agent type Component. It has a few variables associated with it, one being hopperLevel. I create multiple Component agents based on an Excel sheet that assigns values to these variables. The number of Component agents created depends on the number of rows filled out on the Excel sheet. As the simulation runs, hopperLevel changes and I'd like to chart components(0).hopperLevel, components(1).hopperLevel, components(2).hopperLevel, etc. for all components.
I've tried the addDataItem method in the On startup field like this:
for ( Component comp : components )
{
chartHopperLevels.addDataItem(comp.hopperLevel, comp.componentName, blue);
}
but get the error:
"The method addDataItem(DataItem, String, Color) in the type BarChart is not applicable for the arguments (int, String, Color)"
I understand that an int isn't a DataItem, but I'm not sure what a DataItem is.
How do I use this method? Or is there a better way?
You cannot directly refer to an value in the addDataItem() function. This is because Java cannot monitor a value and do something if it changes.
Instead, AnyLogic has defined the DataItem which contains more or less only an update function which gets triggered and then pulls a new version of your value. The trigger can be automatically (setting Update data automatically in your chart) or manually (DataItem.update()). This update function is custom build for every value that you want to monitor.
You can build such a custom DataItem/update function (here: for variable myVariable) in the Additional class code in main:
public class MyDataItem extends DataItem{
#Override
public void update(){
super.setValue(myVariable);
}
}
You can the initialise your custom version of the DataItem like this:
DataItem di = new MyDataItem();
And finally you can add it (like you already did) to your barchart:
chart.addDataItem(di, "my value", red);
you need to read and understand the API on creating a DataItem first, see the AnyLogic help.
You can create a DataItem as below:
DataItem myItem = new DataItem();
myItem.setValue(12);
chart.addDataItem(myItem, "cool", Color.blue);
So you create a separate DataItem object first and then set its value to something you like. Then, you can add that to your bar chart (which is called "chart" in my example code above).
cheers

What is the best way to wire global data in multiple places using hyperHTML?

I'm working on an application that reuses a lot of constants. I know that I can use wire IDs to use the same data in multiple places, but I'm not sure if I'm supposed to create a new globally unique ID every time I want to use that data.
This is a simplified example of what I'm working with:
const colors = [
{value: 'red', label: 'Red'},
{value: 'blue', label: 'Blue'}
]
class MyElement extends HTMLElement {
constructor() {
super()
this.html = hyperHTML.bind(this)
}
connectedCallback() {
this.html`
Hi, ${this.getAttribute('name')}! What is your favorite color?<br/>
<select>
${colors.map(option => hyperHTML.wire(option)`<option value=${option.value}>${option.label}</option>`)}
</select>
`
}
get name() {
return this.getAttribute('name')
}
}
customElements.define('my-element',MyElement);
hyperHTML.bind(document.body)`
<my-element name="Alice"></my-element>
<my-element name="Bob"></my-element>`
I know that unless I specify a wire ID, the options will only appear in one place. I could use :${this.name} as the wire ID, but I have to figure out what to do if there are two people with the same name, and if I want to have one form for "What is your favorite color?" and another for "What color is your shirt?", I have to make another unique ID for that.
Is there a way to somehow scope wire IDs or do I have to make globally unique ones?
There is a subtle issue in your logic, you'd like to map an array of items to themselves, instead of contextualizing their value.
Example: you are wiring the option object, out of usage, situation, context, instead of wiring the Custom Element instance to some data it's using to render itself.
As you can see in this CodePen example, you can simply wire the Custom Element context, and make the option information unique, in terms of scoped id, simply pointing at its value, through its owner:
hyperHTML.wire(this, `:option:${option.value}`)
At this point you'll have a single option element per each node so that you can easily select anything you want instead of moving the same option node globally all over the place.
Actually, the global ID is an anti-pattern as it is, I believe, in every other keyed framework such React or Vue so ... just use the instance, as your wire context/reference, and create a unique id for it with ease.
I hope this solved your issue.

SAPUI5: How to create a control hierarchy?

I hope you can help me with this. After reading all the documentation several times, googling for days, etc I don't find the way to do what i'm going to explain in a clean way, and in think I'm missing something because it's a really basic scenario.
I'm working with oData models, in this case 2 named models, "Model1", "Model2". Now what I want is to show a "parent" ComboBox based on an oData path, and a table that changes its items depending on the selection, in other words.
Model1 { //JSON representation of the data.
Accounts:[
"account 1": {invoices: ["invoice1", "invoice2", "invoice3"]},
"account 2": {invoices:["invoice4", "invoice5"]}
]
}
Combo Box:
<... items={Model1>/Accounts} /> -- This works and shows Account 1, and Account2.
Table
<Table... items="{Model1>Invoices}">
..
<items>
....
</items>
</Table>
What I want is the table to change it's context to the account selected on the ComboBox. The point is that this works, but the first time it loads the view, as there is no account selected, it calls the wrong odata path MYSERVICE/Invoices, instead of doing nothing, as the Account is not set yet, and the path for the invoices, once selected the account, shoud be MYSERVICE/Account('Account1')/Invoices for example.
I know I can achieve this with code, but I'm sure there must be a clean way to do this.
Seriously, this is driving me crazy.
Thanks for your help.
Are you sure that
items="{Model1>Invoices}"
triggers odata call? Because this is a relative path (without leading slash), normally it should not do the call.
What you can do:
Handle ComboBox selectionChange event;
In this event handler, create a path that you will bound the table to. In your case the path could look like this: "/Account(Account1)" - "/{EntitySetName}({KEY})". You can make use of createKey method of ODataModel2;
Set the table's context using the path:
oTable.bindObject({
path: sPath,
model: "Model1",
parameters: {
$expand: "Invoices"
}
});
Once the context is set, the relative binding will start working automatically and table will get the "Invoices"
I assume that the Account and Invoices are linked via navigation property and one-to-many cardinality, that's why the $expand parameter will load the corresponding invoices.

How to retrieve the rows which are selected in the list report page of smart templates

This is the List Report type of Smart Template application
Here I have selected 2nd and 5th row, I also have a button named Send Requests in the section part which is highlighted. If I click this button it calls a javascript controller function which is defined in the extensions of the application. In this js function how can I retrieve the selected rows that are selected?
I have enabled the checkboxes in this page by mentioning this code
"settings": { "gridTable": false, "multiSelect": true } in the manifest.json
As it was recommended by this link https://sapui5.netweaver.ondemand.com/#docs/guide/116b5d82e8c545e2a56e1b51b8b0a9bd.html
I want to know how can I retrieve the rows which got selected?
There is an API that you can use for your use case. It is described here: https://sapui5.netweaver.ondemand.com/#docs/guide/bd2994b69ef542998becbc69ab093f7e.html
Basically, you just need to call the getSelectedContexts method. Unfortunately you will not be able to really get the items themselves, only the binding contexts (which point to the data entities which are selected). Excerpt from the documentation:
After you have defined a view extension, you can access and modify the
properties of all UI elements defined within these extensions (for
example, change the visibility). However, you cannot access any UI
elements that are not defined within your view extensions.
In this type of table there is way.
var myTable=sap.ui.getCore().byId("your table id");
get all rows:
var myTableRows=myTable.getRows();
now get selected Indices
var selectedIndeices=myTable.getSelectedIndices(); //this will give you array of indeices.
now run loop on indeices array. And get particular row item;
// get binding path
var bindingpath=myTableRows[2].getBindingContext().sPath; // this will return eg:"/ProductCollection/2"
// now get Binding object of that particular row.
var myData=myTableRows[2].getModel().getObject(bindingpath); // this will return binding object at that perticular row.
// once your loop is over in the end you will have all object of selected row. then do whatever you want to do.
If you use smart template create an extension.
This is the standard event befor the table is rebinding:
onBeforeRebindTableExtension: function (oEvent) {
this._table = oEvent.getSource().getTable();
}
In your action function (or where you want) call the table and get the context :
this._table.getSelectedContexts();

enterprise architect api: Add element to a collection

I have few short questions regarding Enterprise architect.
My question is regarding the automation interface. When following the instructions provided on this page: http://www.sparxsystems.com/uml_tool_guide/sdk_for_enterprise_architect/colle... in order to add a new element to the collection ( and the .eap file) it does not add the element. I can get data from the elements, modify and even delete them, but adding a new element does not work?
Instructions provided:
Call AddNew to add a new item.
Modify the item as required.
Call Update on the item to save it to the database.
Call Refresh on the collection to include it in the current set.
my java example:
elements is a collection of all the elements in the model...
org.sparx.Element elementEa = elements.AddNew("Requirement", "non-functional");
elementEa.Update();
elements.Refresh();
With the api is it possible to change the id or guid of an element since there are no methods specified in org.sparx for that?
One last thing... Is it possible to create a custom element in EA, for example a requirement which will not have the standard properties like difficulty, priority etc.. , but will have others? (normal properties, not tagged values)
The arguments to AddNew() are Name and Type, so to create a Requirement element you should specify "SomeRequirementName" and "Requirement".
You can't change the ID or GUID through the API, and your models would crash and burn if you did (connectors would be left dangling, elements would vanish from diagrams, etc, etc).
With an MDG Technology you can create very detailed stereotyped elements if you like, with their own visual representations (shape scripts) etc, but if you're after creating an element type with its own properties dialog the answer is no; there is no hook for a custom dialog in the API.
Collection<Package> packageCollection = myPackage.GetPackages();
Package consolidatedCfsSpecPackage = packageCollection.AddNew("somePackageName", "");
if (!consolidatedCfsSpecPackage.Update()) {
System.err.println("Not Updated: somePackageName");
}
packageCollection.Refresh();
This works for me. I suggest you to check return value of elementEa.Update() method you called. If it returns false, you can get the reason by calling elementEa.GetLastError().