How to edit an attribute using Xtext? - xtext

I want to use Xtext's editor to edit a String attribute of an EObject instead of editing a text file. How can I achieve this? I found this thread but it only mentions the workaround of creating a temp file. There must be a more elegant solution. I thought of creating a custom EditorInput but I'm not sure where to start. Thanks in advance for any pointers!

Since 2.2, the supported solution is using IEditedResourceProvider with an EmbeddedEditorFactory (since editing an attribute belongs to an embedded editor anyway). Sample code in Xtend (the attribute is updated whenever the editor changes):
val injector = MyDslActivator.instance.getInjector(MyDslActivator.COM_EXAMPLE_MY_DSL)
val resourceSet = injector.getInstance(IResourceSetProvider).get(null)
val fileExtension = injector.getInstance(Key.get(String, Names.named(Constants.FILE_EXTENSIONS)))
val resourceProvider = [|
resourceSet.createResource(createURI('''temp.«fileExtension»''')) as XtextResource
]
injector.getInstance(EmbeddedEditorFactory).newEditor(resourceProvider).withParent(parent) => [
createPartialEditor("", editedAttribute ?: "", "", false)
document.addModelListener[_ | editedAttribute = document.get]
]
Based on: EditTemplateDialog source, StackOverflow, Eclipse Forum.

Related

Migrating from Swagger 1.5 to 2.0 - Annotations alternative

We are migrating from Swagger 1.5 to Swagger 2.0 . I found one link which helped me with process to some extent Link
Though i have few problems :
#ApiModelProperty(value = "Some text", position = 1) and #ApiModel are now
#Schema(description ="Some text")
i did not find the alternative for following attributes of #ApiModelProperty in #Schema annotation
position
notes
dataType
and for #ApiModel(value = "somevalue", parent = Parent.class)
I did not find any method/similar method under Schema Interface for parent as well.
what could be the possible alternative for
position
notes
dataType and
parent
in Schema Interface ?
Could anyone help me with that ?
Thanks

How to dynamically set binding type's "formatOptions" and "constraints" in XML with binding?

I have a list of elements (OData set) and use a binding to show this list.
One field is for a quantity value and this value could sometimes need some decimal places.
The requirement is: only show that amount of decimal numbers that is also available in the OData service.
Annotation techniques can't be used.
I 'hacked' something that is misusing a formatter to update the type of a binding. But this is 'a hack' and it is not possible to convert it to XML views. (The reason is a different handling of the scope the formatter will be called).
So I am searching for a working solution for XML views.
The following code would not work but shows the issue:
new sap.m.Input({ // looking for an XML solution with bindings
value: {
path: "Quantity",
type: new sap.ui.model.type.Float({
// formatOptions
maxFractionDigits: "{QuantityDecimals}",
// ...
}, {
// constraints
minimum: 0
}),
// ...
}
});
The maxFractionDigits : "{QuantityDecimals}" should be "dynamic" and not a constant value.
Setting formatOptions and constraints dynamically in XML (via bindings or a declared function) is unfortunately not (yet) supported. But IMHO this is a valid enhancement request that app developers would greatly benefit from, since it encourages declarative programming.
I already asked for the same feature some years ago but in a comment at https://github.com/SAP/openui5/issues/2449#issuecomment-474304965 (See my answer to Frank's question "If XMLViews would allow a way to specify the dynamic constraints as well (e.g. enhanced syntax), would that fix the problem?").
Please create a new issue via https://github.com/SAP/openui5/issues/new with a clear description of what kind of problems the feature would resolve and possibly other use cases (You can add a link to my comment). I'll add my 👍 to your GitHub issue, and hopefully others too.
I'll update this answer as soon as the feature is available.
Get your dynamic number from your model and store it in a JS variable.
var nQuantityDecimals = this.getModel().getProperty("/QuantityDecimals");
new sap.m.Input({
value : {
path : "Quantity",
type : new sap.ui.model.type.Float({
maxFractionDigits : nQuantityDecimals,
source : {
groupingSeparator: ",",
decimalSeparator: ".",
groupingEnabled: false
}
}, {
minimum:0
})
}
}),

Specific attributes are being excluded from darts Element.setInnerHtml()

I've encountered the following problem:
Before mods may click 'duplicate', it isn't. I've searched the problem, found 'solutions', applied 'solutions' and they didn't work. So the question could be 'Why is my 'solution' not working?' or the question could be 'What is the actual solution?'
The responsible code for this is
querySelector("#element").setInnerHtml(some_element.outerHtml, treeSanitizer: NodeTreeSanitizer.trusted);
What am I doing wrong?
I found out to apply the sanitizer to the Element.
Element element = new Element.html('<a data-tag="value">thing</a>'), treeSanitizer: NodeTreeSanitizer.trusted)
I haven't gone back recently to double check that is the best way, but we've ended up building a common NodeValidator that we keep up to date with our various custom attributes.
NodeValidator get commonValidator => _commonValidator;
/// Create a NodeValidator which passes common values.
final NodeValidator _commonValidator = new NodeValidatorBuilder.common()
..allowHtml5()
..allowInlineStyles()
..allowNavigation(_policy)
..allowImages()
..allowTextElements()
..allowElement("a", attributes: [
"data-version",
"data-attribute-add"])
..allowElement("div", attributes: [
"data-sec"]);
foo.setInnerHtml(someOddHtml, validator: commonValidator);

Vaadin: How do I add options to a combo box?

I have a combo box that I am trying to add options to. How Do I go about this? This is what I have so far:
ComboBox contactPrefixNametf = new ComboBox("Prefix");
contactPrefixNametf.setItemCaption(contactPrefixNametf, "Mr");
fLayout.addComponent(contactPrefixNametf);
contactPrefixNametf.setImmediate(true);
I guess .setItemCaption() is not the correct method? What is the correct method?
Thank you in advance!
Use addItem() method:
final ComboBox my_combox_box = new ComboBox("My Combo Box");
for (final My_object mo: list_of_my_objects)
{
my_combox_box.addItem(mo);
my_combox_box.setItemCaption(mo, mo.name());
}
This example uses addItem inconjunction with setItemCaption() to store the actual object selected by the user with a display friendly name (if toString() is not appropriate).
myComboBox.addItem("Option 1");
(Especially if you are new to Vaadin), I suggest to try Viritin add-on and its TypedSelect variant of ComboBox. Its well typed API makes many things ridiculously simpler. For instance it has a (typed) setOptions method and its value change listeners provide the value directly instead of through untyped Property interface.
A code example of its usage:
List<Person> options = service.findMyPersons();
TypedSelect<Person> select = new TypedSelect<>(Person.class)
.withSelectType(ComboBox.class);
select.setOptions(options);
// If toString() representation is not good, modify it to something else
select.setCaptionGenerator(person -> person.getFirstName() + person.getLastName());
select.addMValueChangeListener(event -> {
Person person = event.getValue();
});
Disclaimer: I'm the maintainer of Viritin, but also have maintained Vaadin for 8 years and nowadays work as its developer advocate.

Check if entered text is valid in Xtext

lets say we have some grammar like this.
Model:
greeting+=Greeting*;
Greeting:
'Hello' name=ID '!';
I would like to check whether the text written text in name is a valid text.
All the valid words are saved in an array.
Also the array should be filled with words from a given file.
So is it possible to check this at runtime and maybe also use this words as suggestions.
Thanks
For this purpose you can use a validator.
A simple video tutorial about it can be found here
In your case the function in the validator could look like this:
public static val INVALID_NAME = "greeting_InvalidName"
#Check
def nameIsValid(Greeting grt) {
val name = grt.getName() //or just grt.Name
val validNames = NewArrayList
//add all valid names to this list
if (!validNames.contains(name)) {
val errorMsg = "Name is not valid"
error(errorMsg, GreetingsPackage.eINSTANCE.Greeting_name, INVALID_NAME)
}
}
You might have to replace the "GreetingsPackage" if your DSL isn't named Greetings.
The static String passed to the error-method serves for identification of the error. This gets important when you want to implement Quickfixes which is the second thing you have asked for as they provide the possibility to give the programmer a few ideas how to actually fix this particular problem.
Because I don't have any experience with implementing quickfixes myself I can just give you this as a reference.

Resources