Display all enums from an EMF model in a CheckBoxTable ? - eclipse

I am trying to display a CheckBoxTable in an Eclipse page which enables the user to select any one of a number of items - the items that are available come from an EMF model and are enums.
I've got the content provider and the label provider set up correctly (I think) but I can't figure what to use to set the input in order to display the full list of enums.
So say my model has an enum called MyEnum which has values of ONE, TWO and THREE - I want to be able to display all three of those enums to the user as check boxes.
I need to call setInput(...) on the viewer but what do I pass into it to get those enums?

Although I've never done it for a CheckboxTableViewer, I have set an EEnum as the source of values for other StructuredViewer classes like ComboViewer. What I did was create a custom IStructuredContentProvider that is a subclass of ArrayList and takes the EEnum as a constructor argument (call this class EEnumContentProvider). In the constructor, I iterate over the EEnum's getELiterals() and call add() on each of their getInstance() values. Like this:
public EEnumContentProvider(EEnum source) {
List<EEnumLiteral> literals = source.getELiterals();
for (EEnumLiteral aLiteral : literals) {
add(aLiteral.getInstance());
}
}
You can easily implement IStructuredContentProvider.getElements(Object) by using returning the result of toArray() and you don't care about IContentProvider.setInput() because the contents aren't based on the input, they're static.
Then you can set an instance of EEnumContentProvider as the content provider for the viewer.

Simply you need to get the literals and add them to the control as follows:
/* Populate the Combo Box with the Literals */
EEnum cFEnum = Package.Literals.LITERAL_ENUMERATION;
/*
* Add an EMPTY item value so that the user can disable the specific
* feature
*/
this.cmbNames.add( EMPTY_STRING );
/*
* Add the Enumeration Literals to the
* appropriate SWT Combo widget.
*/
for (int i=0; i<cFEnum.getELiterals().size(); i++){
this.cmbNames.add( cFEnum.getEEnumLiteral( i ).toString() );
}
cFEnum = null;
String[] sortedTypes = this.cmbNames.getItems();
Arrays.sort( sortedTypes );
this.cmbNames.setItems( sortedTypes );

Related

yup - is there any way to set the default value for a string field to be something without defining it for each one

I want that every time I use yup.string(), it will add a specific default value for it
for example:
const schema = yup.object({
text: yup.string()// I want it to also do .default('some string') in the background,
});
or - another option - is there any way to set the default value after creating the scheme? something like setDefault('text', 'some string')
The closest solution I came across to solve your issue is extending your string with a custom method that implements your needs. To do that you need to use addMethod from yup:
import { addMethod, string } from 'yup';
addMethod(string, 'append', function append(appendStr) {
return this.transform((value) => `${value}${appendStr}`);
});
Now, you can use your custom method (append) and apply it to any string you want:
string().append('~~~~').cast('hi'); // 'hi~~~~'
If you want to add the custom method to all your schema types like date, number, etc..., you need to extend the abstract base class Schema:
import { addMethod, Schema } from 'yup';
addMethod(Schema, 'myCustomMethod', ...)
Extra
For Typescript
In your type definition file, you need to declare module yup with your custom method's arguments and return types:
// globals.d.ts
import { StringSchema } from "yup";
declare module 'yup' {
interface StringSchema<TType, TContext, TDefault, TFlags> {
append(appendStr: string): this;
}
}
Unknow behavior for transform method
While I was trying to extend the functionality of the date schema with a custom method that transform the date that user enters from DD-MM-YYY to YYYY-MM-DD, the custom method broke after I used it with other methods like min, max for example.
// `dayMonthYear` should transform "31-12-2022"
// to "2022-12-31" but for some reason it kept
// ignoring the `cast` date and tried to transform
// `1900` instead!
Yup.date().dayMonthYear().min(1900).max(2100).required().cast("31-12-2022") // error
To work around this issue, I appended my custom method at the end of my schema chain:
Yup.date().min(1900).max(2100).required().cast("31-12-2022").dayMonthYear() // works as expected
This issue is mentioned in this GH ticket which I recommend going through it as it's going more in-depth on how to add custom methods with Typescript.
References
addMethod
Extending built-in schema with new methods
Example of addMethod in Typescript (GH ticket)

Retrieve content element field from within a plugin template?

I am modifying the template of a plugin, and I want to retrieve a field from the content element.
Using f:debug I see the only data available is from the plugin itself, and none from the content element.
Is there any way I can perhaps insert the field I need in the plugin settings?
eg. something like:
plugin.tx_plugin.settings {
contentUid = TEXT
contentUid.field = uid
}
The best way I can think of to do this is with a custom ViewHelper. Something like:
namespace MyVendor\MyExtension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
class ContentUidViewHelper extends AbstractViewHelper
{
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
return $configurationManager->getContentObject()->data['uid'];
}
}
In your Fluid template:
<mynamespace:contentUid />
This will get the uid of the content element, but you can get any field this way. Just change the key of the data array to the field you need.
In the corresponding method (like the listAction or showAction) of the controller you can get the data of the content element in the following way:
$contentObject = $this->configurationManager->getContentObject();
$this->view->assign('contentObjectData', $contentObject->data);
As far as I know, you can't get to that data using typoscript, but I've never needed it anyway since I've been using the above code in the controller.
settings do not have stdWrap-type per default, but only string. So you can not use cObjects as values.
For one (or a few) settings, you could do the stdWrap-processing in your method/class yourself:
$settingsAsTypoScriptArray = $this->objectManager->get(TypoScriptService::class)->convertPlainArrayToTypoScriptArray($this->settings);
$contentObj = $this->configurationManager->getContentObject();
if ($contentObj === null) {
$contentObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
}
// now override the values in the settings array with the processed value
$contentUid = (int)$contentObj->stdWrap($settingsAsTypoScriptArray['contentUid'], $settingsAsTypoScriptArray['contentUid.']);
If you wanna have many settings to be stdWraped, have a look into EXT:news. Georg implemented an interesting concept via useStdWrap configuration.

Symfony 4: Where is the logic of the CollectionType's "allow_delete" option?

So, I'm trying to understand Symfony forms. I'm searching the core code for "allow_delete" option to see how it works under the hood, but the only place where it can be found is in the CollectionType class and I cannot find any logic there.
Documentation states:
If set to true, then if an existing item is not contained in the
submitted data, it will be correctly absent from the final array of
items.
Where in the code exactly it influences the submitted data?
You can find the function in MergeCollectionListener.php beginning on line 91:
// Remove deleted items before adding to free keys that are to be
// replaced
if ($this->allowDelete) {
foreach ($itemsToDelete as $key) {
unset($dataToMergeInto[$key]);
}
}
$dataToMergeInto is set as $dataToMergeInto = $event->getForm()->getNormData();
which refers to a function in which is explained in FormInterface.php:
/**
* Returns the normalized data of the field.
*
* #return mixed When the field is not submitted, the default data is returned.
* When the field is submitted, the normalized submitted data is
* returned if the field is valid, null otherwise.
*/
public function getNormData();

Custom winid definition with EVT_MENU

I am a beginner in wxWidgets and so this is a very basic thing I'm having trouble with. I want to know how to define a custom winid like "ID_MENU_CIRCLE" with EVT_MENU which already has defined winid's.
BEGIN_EVENT_TABLE(ShapeFrame,wxFrame)
EVT_MENU(ID_MENU_CIRCLE, ShapeFrame::OnModelCircle)
END_EVENT_TABLE()
You're probably mixing up event IDs and event types. All menu items generate events of wxEVT_MENU type, but each event carries its own unique ID, corresponding to the ID of the menu item that generated it. And menu item IDs are just unique integers allowing you to uniquely identify the items.
So your ID_MENU_CIRCLE can be just any integer and could be just
const int ID_MENU_CIRCLE = 100;
but it's common to use an enum to define these constants because you'd typically have many of them:
enum {
ID_MENU_CIRCLE = 100,
ID_MENU_SQUARE,
...
};

Richfaces 4 dynamic select options when user type

I am using rich faces select component.
I want dynamic values when user manually type some thing in the select component.
<rich:select enableManualInput="true" defaultLabel="start typing for select" value="#{supplierSearchBean.userInput}">
<a4j:ajax event="keyup" execute="#this" listener="#{supplierSearchBean.userInputChange}"/>
<f:selectItems value="#{supplierSearchBean.selectOptions}" />
</rich:select>
Java code as follows
public void userInputChange(ActionEvent ae){
Map map = ae.getComponent().getAttributes();
System.out.println(map.toString());
}
public void setUserInput(String userInput) {
System.out.println("userINput = " + userInput);
this.userInput = userInput;
}
Here i found 2 issues
1st: setUserINput always print empty string when user type value
2nd: listener method never get call.
any help ?
The problem is most probably that there is no selected value while the user types, and this component restricts the allowed values to the specified select items. A partial input is thus not valid and cannot be bound to your bean.
I think you could get the expected behavior if you use a rich:autocomplete instead. However, if you want to restrict the allowed values, maybe you can keep your rich:select and listen for the selectitem event.
Override getItems function in richfaces-utils.js file in richfaces-core-impl-4.0.0.Final.jar under richfaces-core-impl-4.0.0.Final\META-INF\resources folder.
Change the condition of pushing items to be
if(p != -1)
instead of
if(p == 0)
This should fix the issue.