Bug 335767 - [ModelTooling] Add support for NLS
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/OSGI-INF/resources.properties b/bundles/org.eclipse.e4.tools.emf.ui/OSGI-INF/resources.properties
index 598a3c1..bf7fc81 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/OSGI-INF/resources.properties
+++ b/bundles/org.eclipse.e4.tools.emf.ui/OSGI-INF/resources.properties
@@ -84,6 +84,7 @@
 IMG_org.eclipse.e4.tools.emf.ui.obj16.application_form=/icons/full/obj16/application_form.png
 IMG_org.eclipse.e4.tools.emf.ui.obj16.chart_organisation=/icons/full/obj16/chart_organisation.png
 IMG_org.eclipse.e4.tools.emf.ui.obj16.error_obj=/icons/full/obj16/error_obj.gif
+IMG_org.eclipse.e4.tools.emf.ui.obj16.world_edit=/icons/full/obj16/world_edit.png
 
 IMG_org.eclipse.e4.tools.emf.ui.wizban.fieldrefact_wiz=/icons/full/wizban/fieldrefact_wiz.png
 IMG_org.eclipse.e4.tools.emf.ui.wizban.import_wiz=/icons/full/wizban/import_wiz.png
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/icons/full/obj16/world_edit.png b/bundles/org.eclipse.e4.tools.emf.ui/icons/full/obj16/world_edit.png
new file mode 100644
index 0000000..00794d4
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.emf.ui/icons/full/obj16/world_edit.png
Binary files differ
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/common/component/AbstractComponentEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/common/component/AbstractComponentEditor.java
index 5786d64..1432201 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/common/component/AbstractComponentEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/common/component/AbstractComponentEditor.java
@@ -13,14 +13,20 @@
 import java.util.Collections;
 import java.util.List;
 import javax.inject.Inject;
+import javax.inject.Named;
 import org.eclipse.core.databinding.observable.list.IObservableList;
 import org.eclipse.core.databinding.observable.value.WritableValue;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.services.translation.TranslationService;
 import org.eclipse.e4.tools.emf.ui.common.Util;
 import org.eclipse.e4.tools.emf.ui.internal.Messages;
 import org.eclipse.e4.tools.emf.ui.internal.common.ModelEditor;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.ControlFactory;
+import org.eclipse.e4.tools.emf.ui.internal.common.properties.ProjectOSGiTranslationProvider;
 import org.eclipse.e4.tools.services.IResourcePool;
 import org.eclipse.e4.tools.services.Translation;
 import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
 import org.eclipse.emf.databinding.FeaturePath;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.edit.domain.EditingDomain;
@@ -46,12 +52,20 @@
 	@Inject
 	private ModelEditor editor;
 	@Inject
-	private IResourcePool resourcePool;
+	protected IResourcePool resourcePool;
 
 	@Inject
 	@Translation
 	protected Messages Messages;
 
+	@Inject
+	@Optional
+	private ProjectOSGiTranslationProvider translationProvider;
+
+	@Inject
+	@Named(TranslationService.LOCALE)
+	private String locale;
+
 	public EditingDomain getEditingDomain() {
 		return editingDomain;
 	}
@@ -100,4 +114,8 @@
 	public List<Action> getActions(Object element) {
 		return Collections.emptyList();
 	}
+
+	protected String getLocalizedLabel(MUILabel element) {
+		return ControlFactory.getLocalizedLabel(translationProvider, element, locale);
+	}
 }
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.java
index 63be298..95ccf71 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.java
@@ -362,10 +362,8 @@
 	public String WindowEditor_AddMainMenu;
 	public String WindowEditor_TreeLabel;
 	public String WindowEditor_TreeLabelDescription;
-	public String WindowEditor_X;
-	public String WindowEditor_Y;
-	public String WindowEditor_Width;
-	public String WindowEditor_Height;
+
+	public String WindowEditor_Bounds;
 	public String WindowEditor_Label;
 	public String WindowEditor_Tooltip;
 	public String WindowEditor_IconURI;
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.properties b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.properties
index 59e04fd..244f4bd 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.properties
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.properties
@@ -362,10 +362,7 @@
 WindowEditor_AddMainMenu=Add Main Menu
 WindowEditor_TreeLabel=Window
 WindowEditor_TreeLabelDescription=Window bla bla bla
-WindowEditor_X=X
-WindowEditor_Y=Y
-WindowEditor_Width=Width
-WindowEditor_Height=Height
+WindowEditor_Bounds=Bounds(x,y,w,h)
 WindowEditor_Label=Label
 WindowEditor_Tooltip=Tooltip
 WindowEditor_IconURI=Icon URI
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/ResourceProvider.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/ResourceProvider.java
index 13f4fba..f7b91e9 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/ResourceProvider.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/ResourceProvider.java
@@ -89,6 +89,7 @@
 	public static final String IMG_Obj16_application_form = "IMG_org.eclipse.e4.tools.emf.ui.obj16.application_form"; //$NON-NLS-1$
 	public static final String IMG_Obj16_chart_organisation = "IMG_org.eclipse.e4.tools.emf.ui.obj16.chart_organisation"; //$NON-NLS-1$
 	public static final String IMG_Obj16_error_obj = "IMG_org.eclipse.e4.tools.emf.ui.obj16.error_obj"; //$NON-NLS-1$
+	public static final String IMG_Obj16_world_edit = "IMG_org.eclipse.e4.tools.emf.ui.obj16.world_edit"; //$NON-NLS-1$
 
 	public static final String IMG_Wizban16_fieldrefact_wiz = "IMG_org.eclipse.e4.tools.emf.ui.wizban.fieldrefact_wiz"; //$NON-NLS-1$
 	public static final String IMG_Wizban16_import_wiz = "IMG_org.eclipse.e4.tools.emf.ui.wizban.import_wiz"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/ModelEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/ModelEditor.java
index e6a3823..ff86656 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/ModelEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/ModelEditor.java
@@ -114,6 +114,7 @@
 import org.eclipse.e4.tools.emf.ui.internal.common.component.virtual.VWindowEditor;
 import org.eclipse.e4.tools.emf.ui.internal.common.component.virtual.VWindowSharedElementsEditor;
 import org.eclipse.e4.tools.emf.ui.internal.common.component.virtual.VWindowTrimEditor;
+import org.eclipse.e4.tools.emf.ui.internal.common.properties.ProjectOSGiTranslationProvider;
 import org.eclipse.e4.tools.emf.ui.internal.common.xml.AnnotationAccess;
 import org.eclipse.e4.tools.emf.ui.internal.common.xml.EMFDocumentResourceMediator;
 import org.eclipse.e4.tools.emf.ui.internal.common.xml.XMLConfiguration;
@@ -272,6 +273,21 @@
 		this.context = context;
 		this.context.set(ModelEditor.class, this);
 		this.obsManager = new ObservablesManager();
+		if (project != null) {
+			ProjectOSGiTranslationProvider translationProvider = new ProjectOSGiTranslationProvider(project) {
+				@Override
+				protected void clearCache() {
+					super.clearCache();
+					viewer.getControl().getDisplay().asyncExec(new Runnable() {
+
+						public void run() {
+							viewer.refresh();
+						}
+					});
+				}
+			};
+			context.set(ProjectOSGiTranslationProvider.class, translationProvider);
+		}
 	}
 
 	@PostConstruct
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/AreaEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/AreaEditor.java
index 2f3af7c..43dde29 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/AreaEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/AreaEditor.java
@@ -28,7 +28,6 @@
 import org.eclipse.e4.ui.model.application.ui.MElementContainer;
 import org.eclipse.e4.ui.model.application.ui.MUIElement;
 import org.eclipse.e4.ui.model.application.ui.MUILabel;
-import org.eclipse.e4.ui.model.application.ui.advanced.MArea;
 import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedPackageImpl;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
@@ -402,8 +401,7 @@
 
 	@Override
 	public String getDetailLabel(Object element) {
-		MArea o = (MArea) element;
-		return o.getLabel();
+		return getLocalizedLabel((MUILabel) element);
 	}
 
 	@Override
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ControlFactory.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ControlFactory.java
index c14d9ce..fc15824 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ControlFactory.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ControlFactory.java
@@ -19,11 +19,14 @@
 import org.eclipse.core.databinding.observable.value.IObservableValue;
 import org.eclipse.core.databinding.observable.value.IValueChangeListener;
 import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.core.resources.IProject;
 import org.eclipse.e4.tools.emf.ui.common.Util;
 import org.eclipse.e4.tools.emf.ui.common.component.AbstractComponentEditor;
 import org.eclipse.e4.tools.emf.ui.internal.Messages;
 import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
 import org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs.FindImportElementDialog;
+import org.eclipse.e4.tools.emf.ui.internal.common.properties.ProjectOSGiTranslationProvider;
+import org.eclipse.e4.tools.services.IResourcePool;
 import org.eclipse.e4.ui.internal.workbench.E4XMIResource;
 import org.eclipse.e4.ui.model.application.MApplication;
 import org.eclipse.e4.ui.model.application.MApplicationElement;
@@ -270,7 +273,26 @@
 		gd.horizontalSpan = 2;
 		t.setLayoutData(gd);
 		context.bindValue(textProp.observeDelayed(200, t), modelProp.observeDetail(master));
+	}
 
+	public static void createTranslatedTextField(Composite parent, String label, IObservableValue master, EMFDataBindingContext context, IWidgetValueProperty textProp, IEMFEditValueProperty modelProp, IResourcePool resourcePool, IProject project) {
+		Label l = new Label(parent, SWT.NONE);
+		l.setText(label);
+		l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+
+		Text t = new Text(parent, SWT.BORDER);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		if (project == null) {
+			gd.horizontalSpan = 2;
+		}
+
+		t.setLayoutData(gd);
+		context.bindValue(textProp.observeDelayed(200, t), modelProp.observeDetail(master));
+
+		if (project != null) {
+			Button b = new Button(parent, SWT.PUSH | SWT.FLAT);
+			b.setImage(resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_world_edit));
+		}
 	}
 
 	public static void createFindImport(Composite parent, final Messages Messages, final AbstractComponentEditor editor, EMFDataBindingContext context) {
@@ -519,4 +541,27 @@
 		context.bindValue(selectionProp.observe(t), modelProp.observeDetail(master));
 
 	}
+
+	public static String getLocalizedLabel(ProjectOSGiTranslationProvider translationProvider, MUILabel element, String locale) {
+		if (translationProvider == null) {
+			if (element.getLocalizedLabel() != null && element.getLocalizedLabel().trim().length() > 0) {
+				return element.getLocalizedLabel();
+			}
+		}
+
+		if (element.getLabel() != null && element.getLabel().trim().length() > 0) {
+			String label = element.getLabel();
+			return tr(translationProvider, locale, label);
+		}
+		return null;
+	}
+
+	public static String tr(ProjectOSGiTranslationProvider translationProvider, String locale, String label) {
+		if (label.startsWith("%") && translationProvider != null) { //$NON-NLS-1$
+			String key = label.substring(1);
+			String translation = translationProvider.translate(locale, key);
+			return translation == key ? label : translation;
+		}
+		return label;
+	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuEditor.java
index 90e6eda..9818264 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuEditor.java
@@ -523,12 +523,7 @@
 
 	@Override
 	public String getDetailLabel(Object element) {
-		MMenu menu = (MMenu) element;
-
-		if (menu.getLabel() != null && menu.getLabel().trim().length() > 0) {
-			return menu.getLabel();
-		}
-		return null;
+		return getLocalizedLabel((MUILabel) element);
 	}
 
 	@Override
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuItemEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuItemEditor.java
index 251fda8..d1698a3 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuItemEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuItemEditor.java
@@ -332,11 +332,7 @@
 
 	@Override
 	public String getDetailLabel(Object element) {
-		MUILabel label = (MUILabel) element;
-		if (label.getLabel() != null && label.getLabel().trim().length() > 0) {
-			return label.getLabel();
-		}
-		return null;
+		return getLocalizedLabel((MUILabel) element);
 	}
 
 	@Override
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PartDescriptorEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PartDescriptorEditor.java
index d786110..ac6200f 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PartDescriptorEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PartDescriptorEditor.java
@@ -412,8 +412,7 @@
 
 	@Override
 	public String getDetailLabel(Object element) {
-		MPartDescriptor o = (MPartDescriptor) element;
-		return o.getLabel();
+		return getLocalizedLabel((MUILabel) element);
 	}
 
 	@Override
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PartEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PartEditor.java
index af1321b..c730592 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PartEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PartEditor.java
@@ -360,8 +360,7 @@
 
 	@Override
 	public String getDetailLabel(Object element) {
-		MPart o = (MPart) element;
-		return o.getLabel();
+		return getLocalizedLabel((MUILabel) element);
 	}
 
 	@Override
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PerspectiveEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PerspectiveEditor.java
index fe375de..ef4351d 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PerspectiveEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PerspectiveEditor.java
@@ -147,12 +147,7 @@
 
 	@Override
 	public String getDetailLabel(Object element) {
-		MPerspective perspective = (MPerspective) element;
-		if (perspective.getLabel() != null && perspective.getLabel().trim().length() > 0) {
-			return perspective.getLabel();
-		}
-
-		return null;
+		return getLocalizedLabel((MUILabel) element);
 	}
 
 	@Override
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PlaceholderEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PlaceholderEditor.java
index ab49f99..e1051d6 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PlaceholderEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/PlaceholderEditor.java
@@ -77,8 +77,10 @@
 			b.append(((EObject) pl.getRef()).eClass().getName());
 			if (pl.getRef() instanceof MUILabel) {
 				MUILabel label = (MUILabel) pl.getRef();
-				if (label.getLabel() != null && label.getLabel().trim().length() > 0) {
-					b.append(" (" + label.getLabel() + ")"); //$NON-NLS-1$//$NON-NLS-2$
+				String l = getLocalizedLabel(label);
+
+				if (l != null && l.trim().length() > 0) {
+					b.append(" (" + l + ")"); //$NON-NLS-1$//$NON-NLS-2$
 				} else if (label.getTooltip() != null && label.getTooltip().trim().length() > 0) {
 					b.append(" (" + label.getTooltip() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
 				} else {
@@ -194,8 +196,9 @@
 						EObject o = (EObject) fromObject;
 						if (o instanceof MUILabel) {
 							MUILabel label = (MUILabel) o;
-							if (!Util.isNullOrEmpty(label.getLabel())) {
-								return o.eClass().getName() + " - " + label.getLabel(); //$NON-NLS-1$
+							String l = getLocalizedLabel(label);
+							if (!Util.isNullOrEmpty(l)) {
+								return o.eClass().getName() + " - " + l; //$NON-NLS-1$
 							}
 						}
 
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ToolItemEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ToolItemEditor.java
index 43e56a9..e80b357 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ToolItemEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ToolItemEditor.java
@@ -299,8 +299,10 @@
 	@Override
 	public String getDetailLabel(Object element) {
 		MToolItem item = (MToolItem) element;
-		if (item.getLabel() != null && item.getLabel().trim().length() > 0) {
-			return item.getLabel();
+		String l = getLocalizedLabel(item);
+
+		if (l != null && l.trim().length() > 0) {
+			return l;
 		} else if (item.getTooltip() != null && item.getTooltip().trim().length() > 0) {
 			return item.getTooltip();
 		}
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/WindowEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/WindowEditor.java
index 31ee67b..17dbc2f 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/WindowEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/WindowEditor.java
@@ -177,98 +177,43 @@
 			return parent;
 		}
 
-		// ------------------------------------------------------------
-		{
-			Label l = new Label(parent, SWT.NONE);
-			l.setText(Messages.ModelTooling_Common_Id);
-			l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-
-			Text t = new Text(parent, SWT.BORDER);
-			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-			gd.horizontalSpan = 2;
-			t.setLayoutData(gd);
-			context.bindValue(textProp.observeDelayed(200, t), EMFEditProperties.value(getEditingDomain(), ApplicationPackageImpl.Literals.APPLICATION_ELEMENT__ELEMENT_ID).observeDetail(getMaster()));
-		}
+		ControlFactory.createTextField(parent, Messages.ModelTooling_Common_Id, getMaster(), context, textProp, EMFEditProperties.value(getEditingDomain(), ApplicationPackageImpl.Literals.APPLICATION_ELEMENT__ELEMENT_ID));
 
 		// ------------------------------------------------------------
 		{
 			Label l = new Label(parent, SWT.NONE);
-			l.setText(Messages.WindowEditor_X);
+			l.setText(Messages.WindowEditor_Bounds);
 			l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
 
-			Text t = new Text(parent, SWT.BORDER);
+			Composite comp = new Composite(parent, SWT.NONE);
+			GridLayout layout = new GridLayout(4, true);
+			layout.marginWidth = 0;
+			layout.marginHeight = 0;
+			comp.setLayout(layout);
 			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
 			gd.horizontalSpan = 2;
-			t.setLayoutData(gd);
+			comp.setLayoutData(gd);
+
+			Text t = new Text(comp, SWT.BORDER | SWT.TRAIL);
+			t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 			context.bindValue(textProp.observeDelayed(200, t), EMFEditProperties.value(getEditingDomain(), BasicPackageImpl.Literals.WINDOW__X).observeDetail(getMaster()));
-		}
 
-		// ------------------------------------------------------------
-		{
-			Label l = new Label(parent, SWT.NONE);
-			l.setText(Messages.WindowEditor_Y);
-			l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-
-			Text t = new Text(parent, SWT.BORDER);
-			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-			gd.horizontalSpan = 2;
-			t.setLayoutData(gd);
+			t = new Text(comp, SWT.BORDER | SWT.TRAIL);
+			t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 			context.bindValue(textProp.observeDelayed(200, t), EMFEditProperties.value(getEditingDomain(), BasicPackageImpl.Literals.WINDOW__Y).observeDetail(getMaster()));
-		}
 
-		// ------------------------------------------------------------
-		{
-			Label l = new Label(parent, SWT.NONE);
-			l.setText(Messages.WindowEditor_Width);
-			l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-
-			Text t = new Text(parent, SWT.BORDER);
-			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-			gd.horizontalSpan = 2;
-			t.setLayoutData(gd);
+			t = new Text(comp, SWT.BORDER | SWT.TRAIL);
+			t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 			context.bindValue(textProp.observeDelayed(200, t), EMFEditProperties.value(getEditingDomain(), BasicPackageImpl.Literals.WINDOW__WIDTH).observeDetail(getMaster()));
-		}
 
-		// ------------------------------------------------------------
-		{
-			Label l = new Label(parent, SWT.NONE);
-			l.setText(Messages.WindowEditor_Height);
-			l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-
-			Text t = new Text(parent, SWT.BORDER);
-			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-			gd.horizontalSpan = 2;
-			t.setLayoutData(gd);
+			t = new Text(comp, SWT.BORDER | SWT.TRAIL);
+			t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 			context.bindValue(textProp.observeDelayed(200, t), EMFEditProperties.value(getEditingDomain(), BasicPackageImpl.Literals.WINDOW__HEIGHT).observeDetail(getMaster()));
 		}
 
-		// ------------------------------------------------------------
-		{
-			Label l = new Label(parent, SWT.NONE);
-			l.setText(Messages.WindowEditor_Label);
-			l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-
-			Text t = new Text(parent, SWT.BORDER);
-			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-			gd.horizontalSpan = 2;
-			t.setLayoutData(gd);
-			context.bindValue(textProp.observeDelayed(200, t), EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__LABEL).observeDetail(master));
-		}
-
-		ControlFactory.createTextField(parent, Messages.ModelTooling_UIElement_AccessibilityPhrase, getMaster(), context, textProp, EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_ELEMENT__ACCESSIBILITY_PHRASE));
-
-		// ------------------------------------------------------------
-		{
-			Label l = new Label(parent, SWT.NONE);
-			l.setText(Messages.WindowEditor_Tooltip);
-			l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-
-			Text t = new Text(parent, SWT.BORDER);
-			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-			gd.horizontalSpan = 2;
-			t.setLayoutData(gd);
-			context.bindValue(textProp.observeDelayed(200, t), EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__TOOLTIP).observeDetail(master));
-		}
+		ControlFactory.createTranslatedTextField(parent, Messages.WindowEditor_Label, getMaster(), context, textProp, EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__LABEL), resourcePool, project);
+		ControlFactory.createTranslatedTextField(parent, Messages.WindowEditor_Tooltip, getMaster(), context, textProp, EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__TOOLTIP), resourcePool, project);
+		ControlFactory.createTranslatedTextField(parent, Messages.ModelTooling_UIElement_AccessibilityPhrase, getMaster(), context, textProp, EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_ELEMENT__ACCESSIBILITY_PHRASE), resourcePool, project);
 
 		// ------------------------------------------------------------
 		{
@@ -424,11 +369,7 @@
 
 	@Override
 	public String getDetailLabel(Object element) {
-		MWindow window = (MWindow) element;
-		if (window.getLabel() != null && window.getLabel().trim().length() > 0) {
-			return window.getLabel();
-		}
-		return null;
+		return getLocalizedLabel((MUILabel) element);
 	}
 
 	@Override
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/properties/ProjectOSGiTranslationProvider.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/properties/ProjectOSGiTranslationProvider.java
new file mode 100644
index 0000000..112b60e
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/properties/ProjectOSGiTranslationProvider.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.tools.emf.ui.internal.common.properties;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.e4.tools.services.impl.AbstractTranslationProvider;
+
+public abstract class ProjectOSGiTranslationProvider extends AbstractTranslationProvider {
+	private IProject project;
+	private List<String> observedFiles = new ArrayList<String>();
+	private IResourceChangeListener listener;
+	private String basename;
+
+	public ProjectOSGiTranslationProvider(IProject project) {
+		super();
+		this.project = project;
+		this.listener = new IResourceChangeListener() {
+
+			public void resourceChanged(IResourceChangeEvent event) {
+				if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
+					try {
+						event.getDelta().accept(new IResourceDeltaVisitor() {
+
+							public boolean visit(IResourceDelta delta) throws CoreException {
+								return ProjectOSGiTranslationProvider.this.visit(delta);
+							}
+						});
+					} catch (CoreException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				}
+			}
+		};
+		this.project.getWorkspace().addResourceChangeListener(listener);
+		IFile f = this.project.getFile("META-INF/MANIFEST.MF"); //$NON-NLS-1$
+		if (f.exists()) {
+			handleManifestChange(f);
+		} else {
+			basename = "OSGI-INF/l10n/bundle"; //$NON-NLS-1$
+		}
+	}
+
+	boolean visit(IResourceDelta delta) throws CoreException {
+		if (delta.getResource() instanceof IWorkspaceRoot) {
+			return true;
+		} else if (delta.getResource().equals(project)) {
+			return true;
+		} else if (delta.getResource().getProjectRelativePath().toString().equals("META-INF")) { //$NON-NLS-1$
+			return true;
+		} else if (delta.getResource().getProjectRelativePath().toString().equals("META-INF/MANIFEST.MF")) { //$NON-NLS-1$
+			handleManifestChange((IFile) delta.getResource());
+			return false;
+		}
+
+		for (String o : observedFiles) {
+			if (delta.getResource().getProjectRelativePath().toString().equals(o)) {
+				clearCache();
+				return false;
+			}
+
+			String[] p = o.split("/"); //$NON-NLS-1$
+			int i = 0;
+			String path = ""; //$NON-NLS-1$
+			do {
+				path += p[i];
+				if (delta.getResource().getProjectRelativePath().toString().equals(path)) {
+					return true;
+				}
+				path += "/"; //$NON-NLS-1$
+			} while (++i < p.length);
+		}
+
+		return false;
+	}
+
+	private void handleManifestChange(IFile file) {
+		try {
+			InputStream in = file.getContents();
+			BufferedReader r = new BufferedReader(new InputStreamReader(in));
+			String line;
+			String newValue = "OSGI-INF/l10n/bundle"; //$NON-NLS-1$
+			while ((line = r.readLine()) != null) {
+				if (line.startsWith("Bundle-Localization:")) { //$NON-NLS-1$
+					newValue = line.substring("Bundle-Localization:".length()).trim(); //$NON-NLS-1$
+					break;
+				}
+			}
+
+			r.close();
+
+			if (!newValue.equals(basename)) {
+				if (basename != null) {
+					basename = newValue;
+					clearCache();
+				} else {
+					basename = newValue;
+				}
+			}
+
+		} catch (CoreException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	protected InputStream getResourceAsStream(String name) {
+		IFile f = project.getFile(name);
+		observedFiles.add(name);
+		try {
+			if (f.exists()) {
+				return f.getContents();
+			} else {
+				return null;
+			}
+		} catch (CoreException e) {
+			return null;
+		}
+	}
+
+	@Override
+	protected void clearCache() {
+		super.clearCache();
+		observedFiles.clear();
+	}
+
+	@Override
+	protected String getBasename() {
+		return basename;
+	}
+
+	public void dispose() {
+
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/properties/ResourceBundleEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/properties/ResourceBundleEditor.java
new file mode 100644
index 0000000..4c8495a
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/properties/ResourceBundleEditor.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.tools.emf.ui.internal.common.properties;
+
+public class ResourceBundleEditor {
+
+}
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/properties/ResourceBundleEntry.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/properties/ResourceBundleEntry.java
new file mode 100644
index 0000000..63b9f41
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/properties/ResourceBundleEntry.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.tools.emf.ui.internal.common.properties;
+
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+public class ResourceBundleEntry {
+	public String key;
+	public SortedMap<String, String> translations = new TreeMap<String, String>();
+}