Wednesday, September 23, 2015

Using gettext Library for Translations

GNU gettext is a C library which lets you add translation support to your program with fallbacks to original text if no translation is available.

Here's a list of links to how you use the different utils in the gettext package:

See http://stackoverflow.com/questions/1003360/complete-c-i18n-gettext-hello-world-example for a hello world example using gettext.

See http://www.gnu.org/software/libc/manual/html_node/Locating-gettext-catalog.html for selecting translation file in code.
See http://www.gnu.org/software/libc/manual/html_node/Translation-with-gettext.html for using gettext in code.
See http://www.gnu.org/software/gettext/manual/html_node/lib_002fgettext_002eh.html for using gettext.h instead of libintl.h to get extended capabilities such as pgettext (adds context) and support for replacing gettext commmands with no-op if gettext is not installed on system. See http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html for how PO files work (text files translations).
See http://www.heiner-eichmann.de/autotools/using_gettext.html, http://www.gnu.org/software/gettext/FAQ.html, and http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/xgettext-Invocation.html for some information on using xgettext to extract strings for translation into a POT file.
See http://www.gnu.org/software/gettext/manual/html_node/msginit-Invocation.html on how msginit generates language specific translation files (PO) from POT file.
See http://www.gnu.org/software/gettext/manual/html_node/msgmerge-Invocation.html on how msgmerge generates updated language specific translation files (PO) from a changed POT file.
See http://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html on how msgfmt generates binary translation files (MO) from human readable translation files (PO).


See http://www.gnu.org/software/gettext/FAQ.html#integrating_noop for troubleshooting missing translations


Simple example

  1. Copy gettext.h from /usr/share/gettext/ to your component or project.
  2. Set macro ENABLE_NLS to 1
  3. Include gettext.h in your cpp file.
  4. Example code:
    ::setlocale(LC_ALL, "");
    
    // Set directory to search for translation files in (which contains
    
    // en_US.UTF-8/LC_MESSAGES/hellogt.mo)
    
    bindtextdomain("hellogt", ".");
    
    // Set name of translation file to use (hellogt.mo)
    
    textdomain( "hellogt");
    
    std::cout << gettext("hi") << std::endl;
    
    std::cout << pgettext("bob", "hello, world!") << std::endl;
    

Generate translation files

#Common
find . -name "*.cpp" > files.txt
xgettext --package-name mygt --package-version 1.2 --default-domain mygt --output mygt.pot -f files.txt

#Spanish translations
sudo locale-gen es_MX.UTF-8
msginit --no-translator --locale es_MX --output-file mygt_spanish.po --input mygt.pot
mkdir -p ./es_MX.UTF-8/LC_MESSAGES
msgfmt --check --verbose --output-file ./es_MX.UTF-8/LC_MESSAGES/mygt.mo mygt_spanish.po

#Norwegian translations
sudo locale-gen nb_NO.UTF-8
msginit --no-translator --locale nb_NO --output-file mygt_norwegian.po --input mygt.pot
mkdir -p ./nb_NO.UTF-8/LC_MESSAGES
msgfmt --check --verbose --output-file ./nb_NO.UTF-8/LC_MESSAGES/mygt.mo mygt_norwegian.po

Update translation files

Add changes in code to language specific translation file:
xgettext --package-name mytgt --package-version 1.2 --default-domain mygt --output mygt.pot -f files.txt
msgmerge mygt_norwegian.po_old mygt.pot --output-file=mygt_norwegian.po_new
use msgfmt to generate new mygt.mo file from mygt_norwegian.po_new.

Sunday, June 7, 2015

AirPlay from Windows PC

If you need to play audio or video using Apple AirPlay from a windows machine here's the way:
Don't try AirParrot or TorrenTV as they don't work. And VLC streaming via Iphone/Ipad AirPlay is just silly.
Unfortunately the solution is: Apple has supplied iTunes for Windows with AirPlay functionality, so use that.
Or maybe we should just get a Chromecast. :)

Wednesday, March 11, 2015

AngularJS vs Ionic abstract state


Ionic is a wrapper for AngularJS and one of the changes that they've done is to the abstract state of the ui-router. I tried to follow an AngularJS tutorial for abstract state and added the following code:
.state('myparent', {
    abstract: true,
    url: '/myparent',
    // Note: abstract still needs a ui-view for its children to populate.
    // You can simply add it inline here.
    template: '<ui-view/>',
    controller: 'MyParentController'
})
.state('myparent.mychild', {
    url: '/mychild',
    templateUrl: 'mychild.view.html',
    controller: 'MyChildController'
})


Inside mychild.view.html I had:

<ion-view>
    <ion-content>
    ...
    </ion-content>
</ion-view>


This resultet in a blank page (although the controller was executed since it fetched the model from my backend). Also my navigation, for which I used $ionicHistory, was all messed up.

The trick apparently is to use ion-nav-view instead of ui-view in the abstract state:
.state('myparent', {
    abstract: true,
    url: '/myparent',
    // Note: abstract still needs a ui-view for its children to populate.
    // You can simply add it inline here.
    template: '<ion-nav-view/>',
    controller: 'MyParentController'
})


Lesson learned, use Ionic tutorials. :)

Source:
http://learn.ionicframework.com/formulas/navigation-and-routing-part-2/
https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#abstract-states
http://ionicframework.com/docs/api/service/$ionicHistory/

Friday, March 6, 2015

Android 9-patch image in HTML5 CSS3

One feature that Android has adopted is 9-patch images. The Android Studio contains a Draw 9-patch tool which lets you 'create bitmap images that automatically resize'. Basically you select areas of an image that can be repeated or stretched while others are kept at the same size. Giving you almost SVG functionality for bitmap images, especially great for buttons.


Now this feature would be great for web as well, e.g. responsive design pages. To achieve this we can use the CSS3 feature border-image which combines border-image-source, border-image-width, border-image-slice and border-image-outset.

border-image-source defines which image to use.

border-image-width defines the width of the border image. Stretches or shrinks the image regions to fit the widths.

border-image-slice divides the image into 9 regions, thereby the name (see the image above) deciding which parts can be repeated/stretched. The regions are: four corners, four edges and a middle. The fill property decides if the middle should be filled in or kept transparent.

border-image-outset decides how far out from the border the image will appear. Together with border-width this enables the border to not take up all the space inside the container caused by it having a wide border to fit the image inside (See http://www.norabrowndesign.com/css-experiments/border-image-frame.html#one). This is especially great for select/dropdown boxes as they can't work around this by using line-height (http://stackoverflow.com/questions/18613279/text-over-the-top-of-a-border-image-using-the-border-as-an-expandable-backgroun)

border-image combines the four above properties, but I felt I had more control when splitting them up. However, as of right now browser support for border-image and especially border-image-outset is a bit limited. Most browsers support border-image, but might need browser-specific CSS (e.g. -webkit-border-image).


 Example:
border-style: solid;
border-width: 5px;
border-image-source: url(dropdown.png);
border-image-width: 25% 10% 25% 5%;
border-image-slice: 10 70 20 60 fill;
border-image-outset: 12px;


http://border-image.com lets you generate border-image CSS from an image. but it doesn't put in border-image-outset.

Source:
https://github.com/chrislondon/9-Patch-Image-for-Websites/wiki/What-Are-9-Patch-Images
http://stackoverflow.com/questions/6806559/does-9-patch-png-can-work-somehow-with-css-on-browsers
http://stackoverflow.com/questions/3659457/nine-patch-images-for-web-development
https://teamtreehouse.com/forum/borderimageslice-vs-borderimagewidth 

Friday, February 13, 2015

Mockito for Play 2 Framework

Mocking is great! :)
To use Mockito to mock stuff for your tests in Play 2 Framework do the following:

1. Add mockito as dependency in Build.scala:
val appDependencies = Seq(
    ...,
    "org.mockito" % "mockito-all" % "1.10.19"
)
Find latest version from https://github.com/mockito/mockito/blob/master/doc/release-notes/official.md

2. Add imports to your JUnit java file:
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.mockito.Mockito.*;

Note the static import of Mockito. This lets you call mock and when without "Mockito." prefix, like most of the tutorials do.

3. Create mocks:
Either by putting @RunWith(MockitoJUnitRunner.class) on your test class and using @Mock for class members. E.g.:
@RunWith(MockitoJUnitRunner.class)
public class HomeControllerTest {

    @Mock
    HomeForm mockHome;

or by creating the mocks in your code:
HomeForm mockHome = mock(HomeForm.class);

4. Set up mock behavior:
List mockNames = (List) mock(List.class);
when(mockNames.get(0)).thenReturn("bob");
when(mockCompany.getNames()).thenReturn(mockNames);


5. Run using play test, you might want to run play clean first to make sure mockito is downloaded.

Nice feature:
If you've used googlemock - Google C++ Mocking Framework and miss the "Uninteresting function call encountered" messages, for example for debugging, you can get verbose output from mocks by adding withSettings().verboseLogging() like this:
HomeForm mockHome = mock(HomeForm.class, withSettings().verboseLogging());

Sources:
http://www.javacodegeeks.com/2013/05/junit-and-mockito-cooperation.html
http://stackoverflow.com/questions/11802088/how-do-i-enable-mockito-debug-messages
http://www.baeldung.com/mockito-behavior