GWT Internationalization to Arabic (RTL language)? - gwt

I have a problem (supposed to be a GWT feature) when i internationalize my Webapp to a RTL language. Basically, the GWT feature mirrors the interface to RTL and I don't want that to happen.
How can I prevent GWT from automatically mirror my interface and just keep translated strings?
Here is my *.gwt.xml code:
<!DOCTYPE ... >
<module rename-to='blah'>
<inherits name='com.google.gwt.user.User' />
<inherits name='com.google.gwt.user.theme.clean.Clean'/>
<inherits name="com.google.gwt.i18n.I18N"/>
<inherits name="com.google.gwt.json.JSON" />
<inherits name="com.google.gwt.user.Debug"/>
<extend-property name="locale" values="pt"/>
<extend-property name="locale" values="es"/>
<extend-property name="locale" values="ar"/>
<source path="client"/>
<source path="shared"/>
<entry-point
class="EntryPoint"/>
<!-- Remote services -->
</module>
Regards

GWT Support Both RTL & LTR Langauages
If you want to have LTR(Left to Right) theme then use <inherits name="com.google.gwt.user.theme.chrome.Chrome"/> (default theme) in *.gwt.xml
If you want to have RTL(Right to Left) theme then use <inherits name="com.google.gwt.user.theme.chrome.ChromeRTL"/>in *.gwt.xml
In your case If you dont want GWT feature mirrors the interface to RTL then use <inherits name="com.google.gwt.user.theme.chrome.Chrome"/>

You can create a class called "CldrImpl_ar" in your project under the "com.google.gwt.i18n.client.impl.cldr" package (you will have to create this package yourself). The class would contain the following code:
package com.google.gwt.i18n.client.impl.cldr;
import com.google.gwt.i18n.client.impl.CldrImpl;
public class CldrImpl_ar extends CldrImpl {
#Override
public boolean isRTL() {
return false;
}
}
This class already exists in the GWT library code but the return value is true there. Once this standalone class is created, it takes precedence over the one in the GWT library, thus achieving the "overwriting" effect.
This does exactly what you are looking for:
No automatic mirror effect when using Arabic
Just use the translated strings
The end result is probably not the best experience for the Arabic user, but it does save significant development time if supporting right-to-left is not a high priority for your project..

Unfortunally this is a feature of a number of the GWT widgets. These widgets call LocaleInfo.getCurrentLocale().isRTL() internally and even if you would somehow change the return value of this call it would then disable the rtl for text also. So that's not an option.
I guess you have 2 options. Firstly, not use widgets that use the RTL check or secondly, when adding a widget check for isRTL yourself and add it in the opposite direction. For example if you add a widget to the WEST, add it to the EAST when isRTL() is true. Both options are not optimal, but I see no other solution.

We had the same issue. With GWT 2.6.x, you can accomplish this by using deferred binding to force the value of LocaleInfo.isRTL() to false:
<replace-with class="org.activityinfo.i18n.shared.CldrImplLtr">
<when-type-is class="com.google.gwt.i18n.client.impl.CldrImpl"/>
<when-property-is name="locale" value="ar" />
</replace-with>
You can leave out the <when-property-is tag if you want to force this
for all locales.
And then provide a simple CldrImplLtr class:
public class CldrImplLtr extends CldrImpl {
#Override
public boolean isRTL() { return false; }
}
There seem to a few funny things, but it seems to be more manageable than supporting a full Right-to-left mirroring of the interface.

Related

Uno Platform ViewModelLocator

I'm testing uno platform solution to see if it's flexible enough and can integrate pre existing autofac (6.2.0) and Autofac.Extras.CommonServiceLocator(6.0.1) stuff in it.
I want to add the ViewModelLocator to auto resolve view models. it's working with UWP and wpf project, but not with droid or WASM.
I added in shared app.xaml the resource
<Application
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- #Region MVM light view model locator -->
<ResourceDictionary>
<local:ViewModelLocator x:Key="ViewModelLocator" d:IsDataSource="True" />
</ResourceDictionary>
<!-- #Endregion -->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
In the mainpage.xaml
DataContext="{Binding [TestViewModel], Source={StaticResource ViewModelLocator}}"
whit this configuration the constructor is called at startup where I also want to set up Inversion of control stuff
public ViewModelLocator()
{
this._container = IOCContainerConfig.Configure();
var serviceLocator = new AutofacServiceLocator(this._container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
//this._dbContext = serviceLocator.GetInstance<IContext>();
//TestDbConnection(this._dbContext);
}
As said this is not working with other kind of projects like droid or wasm the constructor of the locator is never called but I don-t have errors, just page is loaded without the viewmodel behind.
Any ideas or tips to make it working for all projects?
Depending on the type of resource, Uno Platform is initializing some resources in a ResourceDictionary lazily only when they are accessed. This is done as a performance optimization.
To guarantee that the ViewModelLocator constructor is always called on all platforms, it may be better to call it from code, eg from the App constructor in App.xaml.cs.

Add custom properties to eclipse's project class

I have a custom project nature and created a new project that has this new custom nature.
What I am trying to do now, is extend the properties of that project, so when it is selected e.g. in package explorer view, not only the standard project properties are shown in the (standard) property-view but also customized ones (like the nature of the selected project - but only for a project that has my custom nature)
Is this possible with standard eclipse extension points?
I have doubts since I don't have my own class where I could register a property-descriptor, just a new nature.
You should be able to define a project properties page without a project class, as I've done in the Haskell plugin:
<page
name="%projectFlagsPP_name"
class="net.sf.eclipsefp.haskell.ui.properties.UserFlagsPP"
id="net.sf.eclipsefp.haskell.ui.properties.UserFlagsPP">
<filter
name="nature"
value="net.sf.eclipsefp.haskell.core.project.HaskellNature">
</filter>
<filter
name="open"
value="true">
</filter>
<enabledWhen>
<adapt type="org.eclipse.core.resources.IProject" />
</enabledWhen>
</page>
And then the java code starts like:
public class UserFlagsPP extends PropertyPage implements
IWorkbenchPreferencePage {
This says that the property page will appear for a IProject that has the Haskell Nature...

Using mgwt for desktop and mobile applications

I have an application written in GWT. I want to be able to provide a subset of the same application for use when the site is opened in mobile browsers, and have been looking at mgwt as a way of achieving this.
The way I am expecting it to work is that I will augment my existing GWT application project with mgwt code (with some logic sharing) resulting in two entry points. My question is how to manage this given a single html page? I have seen the approach described in this article and was wondering whether that will work well with mgwt or whether there should be another pattern I should be considering?
I don't think you need 2 entry points. As kiran said above, you should reuse all the code except the view components. In case you used the GWT Activities and Places module, the view components should be completely decoupled from the rest of the code.
In this case you can use the the GWT.create method associated with the correct definitions in the module xml definition:
//in your entry point:
private IClientFactory clientFactory = GWT.create(IClientFactory.class);
//in your module xml definition:
<replace-with class="com.vv.xui.client.DesktopClientFactory">
<when-type-is class="com.vv.xui.client.IClientFactory" />
<when-property-is name="formfactor" value="desktop"/>
</replace-with>
<replace-with class="com.vv.xui.client.MobileClientFactory">
<when-type-is class="com.vv.xui.client.IClientFactory" />
<when-property-is name="formfactor" value="mobile"/>
</replace-with>
The form formfactor property can be defined as in this example:
https://code.google.com/p/gwt-cx/source/browse/trunk/gwtcx/gwtcx-core/gwtcx-core-client/src/main/resources/com/gwtcx/FormFactor.gwt.xml
In your IClientFactory you will have something like this:
public interface IClientFactory {
IHomeView getHomeView();
ISearchView getSearchView();
...
}
Where IHomeView and ISearchView are the view interfaces implemented by the desktop and the mobile versions. In my case the View implementations are UiBinder components that implement the associated view interface.
In your DesktopClientFactory you will have something like this:
public class DesktopClientFactory implements IClientFactory {
private static final ISearchView searchView = new com.vv.xui.client.view.desktop.SearchView.SearchView();
#Override
public ISearchView getSearchView() {
return searchView;
}
...
}
In this way you don't need different entry points for mobile and desktop and can share all the code except the view components.
That pattern in the link pointing to MobileWebApp on googlecode is correct. Basically you have UI view interfaces in GWT which stick to MVP pattern recommended on GWT. Then you can do different implementations of the UI Views based on the screen resolutions available. Obviously you don't want the same screen lay outs on desktop and mobile. So you will need to redesign your views for different form factors and then call the correct implementations based on the form factor the device. Since you already have a gwt application, you can create views for mobile using mgwt and reuse the code that you already created. But still you will have to create new views for mobile using mgwt, it wont be a straight forward replace.

How to write completely custom widgets recognizable by GWT Designer?

When I add let's say, a standard GWT VerticalPanel, with GWT Designer I can add widgets to this panel by drag and dropping them. GWT Designer provides a red line indicating I am adding a widget to my VerticalPanel.
Suppose that I want to create my own panel from scratch, and I don't want to extend standard GWT panels. I want GWT Designer to recognize my panel and provide the same functionality it provides when I use standard gwt panels.
As far as I know frameworks such as Ext-GWT wrote their widget libraries from scratch and yet they work in unison with GWT Designer. Do I need to implement certain methods in my custom panel to achieve this functionality? Any guidance or ideas are well appreciated.
Thank you
To summarize, support for a new component requires adding special support for this component into GWT Designer. Assume I have a custom component which I want it to act like a VerticalPanel but which infact is type composite :
public class CustomPanel extends Composite implements HasWidgets{
private VerticalPanel panel = new VerticalPanel();
public CustomPanel() {
initWidget(panel);
}
#Override
public void add(Widget w) {panel.add(w);}
#Override
public void clear() {panel.clear();}
#Override
public Iterator<Widget> iterator() {return panel.iterator();}
#Override
public boolean remove(Widget w) {return panel.remove(w);}
}
This will work as a VerticalPanel, but when you are looking from the Designers perspective this still is a Composite. As a result you can not drop widgets inside it. In the simplest case, what you should do to make it designer friendly is to create a CustomPanel.wbp-component.xml in the same package of CustomPanel following given name convention. A simple one to give flow like widget adding behaviour would be,
<?xml version="1.0" encoding="UTF-8"?>
<component xmlns="http://www.eclipse.org/wb/WBPComponent">
<description>This is a simple Composite acting like VerticalPanel</description>
<!-- CREATION -->
<creation>
<source><![CDATA[new org.test.client.CustomPanel()]]></source>
</creation>
<parameters>
<parameter name="flowContainer">true</parameter>
<parameter name="flowContainer.horizontal">false</parameter>
<parameter name="flowContainer.association">%parent%.add(%child%)</parameter>
</parameters>
</component>
After adding this step your composite should be treated like a vertical panel (dropping widgets inside support) by the gwt designer as well. When this XML alone is not enough, meaning you need some behavior more of a complex nature, you need to start writing java model classes that defines custom behaviour of your component to Designer and reference it in your component xml using <model> tag. In this case you need to write a plugin to host your models and policies.
Here are the references for this summary and useful links:
Google groups question answered by WindowBuilder team
http://code.google.com/intl/tr-TR/javadevtools/wbpro/DesignerCustomizationAPI.pdf
http://code.google.com/intl/tr-TR/javadevtools/wbpro/NewComponentsTutorial.pdf
http://en.wikipedia.org/wiki/MVEL
GWT Designer documentation have a page about custom composites and panels but these pertain to Swing and SWT components. As for GWT, the documentation recommends using GWT's layout managers for maximum portability.

How to get Google Fonts to apply to GWT widgets?

I am writing a GWT application in which everything on the screen is in some widget or other, i.e. there's nothing there from the HTML file in ordinary HTML.
I would like all the text to appear in a certain Google web font. My question is, how to apply the font to the widgets in some kind of automatic way? If I put the font-family CSS in the body{}, none of the widgets picks up the font, but ordinary HTML does (and, like I say, there isn't any of that).
On the other hand, I want to avoid this kind of thing, which is what I've got at the moment, in my stylesheet:
.gwt-Label, .gwt-TextBox, .gwt-Button, .gwt-DialogBox .Caption, .gwt-EveryOtherKindOfWidget....
{
font-family: Quattrocento, serif;
}
So my question is, how can I get everything to inherit this font? I feel I must be missing something fairly fundamental here. Can anyone help?
Thanks
Neil
So there are a couple of issues here:
The default GWT theme (standard) includes the standard.css file. This file contains style definitions for all widgets. The theme is defined in your module's xml file:
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
There are different ways on how to override widget styles:
copy the standard.css file, include it as a CSSResource in a ClientBundle in your app and remove the inherit line from your module's xml file.
add your stylesheet which overrides the widget styles defined in the standard.css after the inherit line in your module's xml file (see here for more details)
i.e:
<inherits name='com.google.gwt.user.theme.standard.Standard' />
<stylesheet src="CustomStylesheet.css" />
Looking at the standard.css stylesheet you will see that the widgets don't define any fonts. It is actually inherited from the body style.
excerpt from the standard.css:
body, table td, select {
font-family: Arial Unicode MS,Arial,sans-serif;
font-size: small;
}
So you probably only have to override the body part in your custom stylesheet with the google fonts and all widgets will inherit it.
Here comes the second issue: Loading the google fonts isn't that easy because of stylesheet precedence/inheritance.
This wiki describes how to load the google fonts into your GWT app.