From 346e25af5bd5970d9ad3d3dad304e4f585a4065d Mon Sep 17 00:00:00 2001 From: Matthias Lettmayer Date: Sat, 5 Jan 2013 15:03:17 +0100 Subject: [397123] Isolate SWT specific classes of babel editor into a separate fragment The babel editor is used in multiple platforms (RCP / RAP). Therefore we are using a single source base for all platforms and specifc implementations for the different platforms. This enhancement contains the SWT specific implementation, which is used by the TapiJI Tools and the TapiJI RCP Translator. --- org.eclipse.babel.editor.swt.compat/.classpath | 7 + org.eclipse.babel.editor.swt.compat/.project | 34 + .../META-INF/MANIFEST.MF | 13 + .../build.properties | 4 + org.eclipse.babel.editor.swt.compat/pom.xml | 13 + .../compat/SwtRapCompatibilityFormToolkit.java | 26 + .../editor/compat/SwtRapCompatibilitySWT.java | 17 + .../eclipse/babel/editor/swt/compat/Activator.java | 45 ++ org.eclipse.babel.editor.swt/.classpath | 7 + org.eclipse.babel.editor.swt/.project | 28 + org.eclipse.babel.editor.swt/META-INF/MANIFEST.MF | 10 + org.eclipse.babel.editor.swt/build.properties | 5 + org.eclipse.babel.editor.swt/fragment.xml | 26 + org.eclipse.babel.editor.swt/pom.xml | 13 + .../org/eclipse/babel/editor/i18n/I18NEntry.java | 88 +++ .../babel/editor/internal/MessagesEditor.java | 53 ++ .../editor/refactoring/RefactoringHandler.java | 99 +++ .../editor/refactoring/RenameKeyArguments.java | 82 ++ .../babel/editor/refactoring/RenameKeyChange.java | 183 +++++ .../editor/refactoring/RenameKeyDescriptor.java | 150 ++++ .../editor/refactoring/RenameKeyProcessor.java | 311 ++++++++ .../babel/editor/refactoring/RenameKeyWizard.java | 189 +++++ .../babel/editor/tree/actions/RenameKeyAction.java | 45 ++ org.eclipse.babel.editor/META-INF/MANIFEST.MF | 35 +- org.eclipse.babel.editor/build.properties | 3 +- org.eclipse.babel.editor/icons/refactoring.png | Bin 783 -> 885 bytes org.eclipse.babel.editor/messages.properties | 1 + .../org/eclipse/babel/editor/IMessagesEditor.java | 8 + .../babel/editor/actions/FilterKeysAction.java | 6 +- .../babel/editor/actions/KeyTreeVisibleAction.java | 6 +- .../babel/editor/actions/NewLocaleAction.java | 6 +- .../org/eclipse/babel/editor/api/EditorUtil.java | 5 +- .../babel/editor/i18n/AbstractI18NEntry.java | 804 ++++++++++++++++++++ .../eclipse/babel/editor/i18n/EntryLeftBanner.java | 2 +- .../babel/editor/i18n/EntryRightBanner.java | 47 +- .../org/eclipse/babel/editor/i18n/I18NEntry.java | 832 --------------------- .../org/eclipse/babel/editor/i18n/I18NPage.java | 73 +- .../babel/editor/i18n/SideNavComposite.java | 14 +- .../babel/editor/i18n/SideNavTextBoxComposite.java | 17 +- .../babel/editor/i18n/actions/FoldingAction.java | 6 +- .../editor/internal/AbstractMessagesEditor.java | 614 +++++++++++++++ .../babel/editor/internal/MessagesEditor.java | 567 -------------- .../editor/internal/MessagesEditorContributor.java | 4 +- .../babel/editor/plugin/MessagesEditorPlugin.java | 10 +- .../editor/preferences/MsgEditorPreferences.java | 6 +- .../editor/refactoring/RenameKeyArguments.java | 82 -- .../babel/editor/refactoring/RenameKeyChange.java | 183 ----- .../editor/refactoring/RenameKeyDescriptor.java | 150 ---- .../editor/refactoring/RenameKeyProcessor.java | 311 -------- .../babel/editor/refactoring/RenameKeyWizard.java | 189 ----- .../tree/actions/AbstractRenameKeyAction.java | 39 + .../editor/tree/actions/AbstractTreeAction.java | 13 +- .../babel/editor/tree/actions/AddKeyAction.java | 4 +- .../editor/tree/actions/CollapseAllAction.java | 5 +- .../babel/editor/tree/actions/DeleteKeyAction.java | 4 +- .../babel/editor/tree/actions/ExpandAllAction.java | 4 +- .../babel/editor/tree/actions/FlatModelAction.java | 4 +- .../editor/tree/actions/RefactorKeyAction.java | 59 ++ .../babel/editor/tree/actions/RenameKeyAction.java | 59 -- .../babel/editor/tree/actions/TreeModelAction.java | 4 +- .../editor/tree/internal/KeyTreeContributor.java | 44 +- .../editor/tree/internal/KeyTreeLabelProvider.java | 6 +- .../src/org/eclipse/babel/editor/util/UIUtils.java | 47 +- .../editor/views/MessagesBundleGroupOutline.java | 6 +- .../nls/internal/ui/editor/LocalizationEditor.java | 3 +- 65 files changed, 3248 insertions(+), 2482 deletions(-) create mode 100644 org.eclipse.babel.editor.swt.compat/.classpath create mode 100644 org.eclipse.babel.editor.swt.compat/.project create mode 100644 org.eclipse.babel.editor.swt.compat/META-INF/MANIFEST.MF create mode 100644 org.eclipse.babel.editor.swt.compat/build.properties create mode 100644 org.eclipse.babel.editor.swt.compat/pom.xml create mode 100644 org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/compat/SwtRapCompatibilityFormToolkit.java create mode 100644 org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/compat/SwtRapCompatibilitySWT.java create mode 100644 org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/swt/compat/Activator.java create mode 100644 org.eclipse.babel.editor.swt/.classpath create mode 100644 org.eclipse.babel.editor.swt/.project create mode 100644 org.eclipse.babel.editor.swt/META-INF/MANIFEST.MF create mode 100644 org.eclipse.babel.editor.swt/build.properties create mode 100644 org.eclipse.babel.editor.swt/fragment.xml create mode 100644 org.eclipse.babel.editor.swt/pom.xml create mode 100644 org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/i18n/I18NEntry.java create mode 100644 org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/internal/MessagesEditor.java create mode 100644 org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RefactoringHandler.java create mode 100644 org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyArguments.java create mode 100644 org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyChange.java create mode 100644 org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyDescriptor.java create mode 100644 org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyProcessor.java create mode 100644 org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyWizard.java create mode 100644 org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/tree/actions/RenameKeyAction.java create mode 100755 org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/AbstractI18NEntry.java delete mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/I18NEntry.java create mode 100755 org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/AbstractMessagesEditor.java delete mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/MessagesEditor.java delete mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyArguments.java delete mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyChange.java delete mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyDescriptor.java delete mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyProcessor.java delete mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyWizard.java create mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AbstractRenameKeyAction.java create mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/RefactorKeyAction.java delete mode 100644 org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/RenameKeyAction.java diff --git a/org.eclipse.babel.editor.swt.compat/.classpath b/org.eclipse.babel.editor.swt.compat/.classpath new file mode 100644 index 0000000..ad32c83 --- /dev/null +++ b/org.eclipse.babel.editor.swt.compat/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.eclipse.babel.editor.swt.compat/.project b/org.eclipse.babel.editor.swt.compat/.project new file mode 100644 index 0000000..5c03016 --- /dev/null +++ b/org.eclipse.babel.editor.swt.compat/.project @@ -0,0 +1,34 @@ + + + org.eclipse.babel.editor.swt.compat + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.eclipse.babel.editor.swt.compat/META-INF/MANIFEST.MF b/org.eclipse.babel.editor.swt.compat/META-INF/MANIFEST.MF new file mode 100644 index 0000000..7700da3 --- /dev/null +++ b/org.eclipse.babel.editor.swt.compat/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: RCP Compatibility for Babel Editor +Bundle-SymbolicName: org.eclipse.babel.editor.swt.compat +Bundle-Version: 0.8.0.qualifier +Bundle-Activator: org.eclipse.babel.editor.swt.compat.Activator +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: org.eclipse.swt, + org.eclipse.swt.widgets, + org.eclipse.ui.forms, + org.eclipse.ui.forms.widgets, + org.osgi.framework;version="1.3.0" +Export-Package: org.eclipse.babel.editor.compat diff --git a/org.eclipse.babel.editor.swt.compat/build.properties b/org.eclipse.babel.editor.swt.compat/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/org.eclipse.babel.editor.swt.compat/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.eclipse.babel.editor.swt.compat/pom.xml b/org.eclipse.babel.editor.swt.compat/pom.xml new file mode 100644 index 0000000..ebb1681 --- /dev/null +++ b/org.eclipse.babel.editor.swt.compat/pom.xml @@ -0,0 +1,13 @@ + + 4.0.0 + org.eclipse.babel.editor + org.eclipse.babel.editor.swt.compat + 0.8.0-SNAPSHOT + eclipse-plugin + + org.eclipse.babel.tapiji.tools + org.eclipse.babel.tapiji.tools.parent + 0.0.2-SNAPSHOT + .. + + \ No newline at end of file diff --git a/org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/compat/SwtRapCompatibilityFormToolkit.java b/org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/compat/SwtRapCompatibilityFormToolkit.java new file mode 100644 index 0000000..e7365ee --- /dev/null +++ b/org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/compat/SwtRapCompatibilityFormToolkit.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2012 Matthias Lettmayer. + * 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: + * Matthias Lettmayer - initial API and implementation + ******************************************************************************/ +package org.eclipse.babel.editor.compat; + +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.forms.FormColors; +import org.eclipse.ui.forms.widgets.FormToolkit; + +public class SwtRapCompatibilityFormToolkit extends FormToolkit { + + public SwtRapCompatibilityFormToolkit(FormColors colors) { + super(colors); + } + + public SwtRapCompatibilityFormToolkit(Display display) { + super(display); + } +} diff --git a/org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/compat/SwtRapCompatibilitySWT.java b/org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/compat/SwtRapCompatibilitySWT.java new file mode 100644 index 0000000..5ae30c0 --- /dev/null +++ b/org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/compat/SwtRapCompatibilitySWT.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2012 Matthias Lettmayer. + * 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: + * Matthias Lettmayer - initial API and implementation + ******************************************************************************/ +package org.eclipse.babel.editor.compat; + +import org.eclipse.swt.SWT; + +public class SwtRapCompatibilitySWT extends SWT { + +} diff --git a/org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/swt/compat/Activator.java b/org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/swt/compat/Activator.java new file mode 100644 index 0000000..c771b3d --- /dev/null +++ b/org.eclipse.babel.editor.swt.compat/src/org/eclipse/babel/editor/swt/compat/Activator.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2012 Matthias Lettmayer. + * 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: + * Matthias Lettmayer - initial API and implementation + ******************************************************************************/ +package org.eclipse.babel.editor.swt.compat; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext + * ) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/org.eclipse.babel.editor.swt/.classpath b/org.eclipse.babel.editor.swt/.classpath new file mode 100644 index 0000000..ad32c83 --- /dev/null +++ b/org.eclipse.babel.editor.swt/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.eclipse.babel.editor.swt/.project b/org.eclipse.babel.editor.swt/.project new file mode 100644 index 0000000..d35cf68 --- /dev/null +++ b/org.eclipse.babel.editor.swt/.project @@ -0,0 +1,28 @@ + + + org.eclipse.babel.editor.swt + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.eclipse.babel.editor.swt/META-INF/MANIFEST.MF b/org.eclipse.babel.editor.swt/META-INF/MANIFEST.MF new file mode 100644 index 0000000..fe12377 --- /dev/null +++ b/org.eclipse.babel.editor.swt/META-INF/MANIFEST.MF @@ -0,0 +1,10 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: RCP fragment for the Babel Editor +Bundle-SymbolicName: org.eclipse.babel.editor.swt;singleton:=true +Bundle-Version: 0.8.0.qualifier +Fragment-Host: org.eclipse.babel.editor;bundle-version="0.8.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Require-Bundle: org.eclipse.ltk.core.refactoring, + org.eclipse.ltk.ui.refactoring +Export-Package: org.eclipse.babel.editor.internal diff --git a/org.eclipse.babel.editor.swt/build.properties b/org.eclipse.babel.editor.swt/build.properties new file mode 100644 index 0000000..e3023e1 --- /dev/null +++ b/org.eclipse.babel.editor.swt/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + fragment.xml diff --git a/org.eclipse.babel.editor.swt/fragment.xml b/org.eclipse.babel.editor.swt/fragment.xml new file mode 100644 index 0000000..c619b03 --- /dev/null +++ b/org.eclipse.babel.editor.swt/fragment.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + diff --git a/org.eclipse.babel.editor.swt/pom.xml b/org.eclipse.babel.editor.swt/pom.xml new file mode 100644 index 0000000..056e492 --- /dev/null +++ b/org.eclipse.babel.editor.swt/pom.xml @@ -0,0 +1,13 @@ + + 4.0.0 + org.eclipse.babel.editor + org.eclipse.babel.editor.swt + 0.8.0-SNAPSHOT + eclipse-plugin + + org.eclipse.babel.tapiji.tools + org.eclipse.babel.tapiji.tools.parent + 0.0.2-SNAPSHOT + .. + + \ No newline at end of file diff --git a/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/i18n/I18NEntry.java b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/i18n/I18NEntry.java new file mode 100644 index 0000000..09a3459 --- /dev/null +++ b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/i18n/I18NEntry.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2007 Pascal Essiembre, Alexej Strelow, Matthias Lettmayer. + * 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: + * Pascal Essiembre - initial API and implementation + * Alexej Strelzow - updateKey + * Matthias Lettmayer - extracted I18NEntry into own class for SWT specific implementation + ******************************************************************************/ +package org.eclipse.babel.editor.i18n; + +import java.util.Locale; + +import org.eclipse.babel.core.message.IMessage; +import org.eclipse.babel.core.message.IMessagesBundleGroup; +import org.eclipse.babel.core.util.BabelUtils; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.widgets.Composite; + +public class I18NEntry extends AbstractI18NEntry { + + public I18NEntry(Composite parent, AbstractMessagesEditor editor, + Locale locale) { + super(parent, editor, locale); + } + + @Override + void updateKey(String key) { + IMessagesBundleGroup messagesBundleGroup = editor.getBundleGroup(); + boolean isKey = key != null && messagesBundleGroup.isMessageKey(key); + textBox.setEnabled(isKey); + if (isKey) { + IMessage entry = messagesBundleGroup.getMessage(key, locale); + if (entry == null || entry.getValue() == null) { + textBox.setText(null); + // commentedCheckbox.setSelection(false); + } else { + // commentedCheckbox.setSelection(bundleEntry.isCommented()); + textBox.setText(entry.getValue()); + } + } else { + textBox.setText(null); + } + } + + @Override + KeyListener getKeyListener() { + return new KeyAdapter() { + public void keyReleased(KeyEvent event) { + // Text field has changed: make editor dirty if not already + if (!BabelUtils.equals(focusGainedText, textBox.getText())) { + // Make the editor dirty if not already. If it is, + // we wait until field focus lost (or save) to + // update it completely. + if (!editor.isDirty()) { + // textEditor.isDirty(); + updateModel(); + // int caretPosition = eventBox.getCaretPosition(); + // updateBundleOnChanges(); + // eventBox.setSelection(caretPosition); + } + // autoDetectRequiredFont(eventBox.getText()); + } + } + }; + // Eric Fettweis : new listener to automatically change the font + // textBox.addModifyListener(new ModifyListener() { + // + // public void modifyText(ModifyEvent e) { + // String text = textBox.getText(); + // Font f = textBox.getFont(); + // String fontName = getBestFont(f.getFontData()[0].getName(), text); + // if(fontName!=null){ + // f = getSWTFont(f, fontName); + // textBox.setFont(f); + // } + // } + // + // }); + // } + } +} diff --git a/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/internal/MessagesEditor.java b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/internal/MessagesEditor.java new file mode 100644 index 0000000..a5203e6 --- /dev/null +++ b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/internal/MessagesEditor.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007 Pascal Essiembre, Alexej Strelzow, Matthias Lettmayer. + * 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: + * Pascal Essiembre - initial API and implementation + * Alexej Strelzow - TapJI integration, bug fixes & enhancements + * - issue 35, 36, 48, 73 + * Matthias Lettmayer - extracted messages editor into own class for SWT specific implementation + ******************************************************************************/ + +package org.eclipse.babel.editor.internal; + +import org.eclipse.babel.core.message.internal.IMessagesBundleGroupListener; +import org.eclipse.babel.core.message.internal.MessagesBundle; +import org.eclipse.babel.core.message.internal.MessagesBundleGroupAdapter; +import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.texteditor.ITextEditor; + +public class MessagesEditor extends AbstractMessagesEditor { + + @Override + protected IMessagesBundleGroupListener getMsgBundleGroupListner() { + return new MessagesBundleGroupAdapter() { + @Override + public void messagesBundleAdded(MessagesBundle messagesBundle) { + addMessagesBundle(messagesBundle); + } + }; + } + + @Override + protected void initRAP() { + // nothing to do + } + + @Override + protected void disposeRAP() { + // nothing to do + } + + @Override + public void setEnabled(boolean enabled) { + i18nPage.setEnabled(enabled); + for (ITextEditor textEditor : textEditorsIndex) { + // TODO disable editors + } + } + +} diff --git a/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RefactoringHandler.java b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RefactoringHandler.java new file mode 100644 index 0000000..81a6048 --- /dev/null +++ b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RefactoringHandler.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2012 Alexej Strelzow. + * 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: + * Alexej Strelzow - initial API and implementation + ******************************************************************************/ +package org.eclipse.babel.editor.refactoring; + +import org.eclipse.babel.core.message.internal.MessagesBundleGroup; +import org.eclipse.babel.core.message.manager.RBManager; +import org.eclipse.babel.core.message.tree.internal.AbstractKeyTreeModel; +import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.ISelectionService; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; + +/** + * Handler for the key binding M1 (= Ctrl) + R. This handler triggers the + * refactoring process. + * + * @author Alexej Strelzow + */ +public class RefactoringHandler extends AbstractHandler { + + /** + * Gets called if triggered + * + * @param event + * The {@link ExecutionEvent} + */ + public Object execute(ExecutionEvent event) throws ExecutionException { + + Event e = ((Event) event.getTrigger()); + Widget widget = e.widget; + + ISelectionService selectionService = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getSelectionService(); + ISelection selection = selectionService.getSelection(); + + if (selection instanceof TextSelection && widget instanceof StyledText) { // Java-File + TextSelection txtSel = (TextSelection) selection; + IEditorPart activeEditor = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage() + .getActiveEditor(); + FileEditorInput input = (FileEditorInput) activeEditor + .getEditorInput(); + IFile file = input.getFile(); + + RBManager.getRefactorService().openRefactorDialog(file, + txtSel.getOffset()); + } + + if (widget != null && widget instanceof Tree) { // Messages-Editor or + // TapiJI-View + Tree tree = (Tree) widget; + TreeItem[] treeItems = tree.getSelection(); + if (treeItems.length == 1) { + TreeItem item = treeItems[0]; + Object data = item.getData(); + String oldKey = item.getText(); + if (data != null && data instanceof KeyTreeNode) { + oldKey = ((KeyTreeNode)data).getMessageKey(); + } + if (tree.getData() instanceof AbstractKeyTreeModel) { + AbstractKeyTreeModel model = (AbstractKeyTreeModel) tree + .getData(); + MessagesBundleGroup messagesBundleGroup = model + .getMessagesBundleGroup(); + String projectName = messagesBundleGroup.getProjectName(); + String resourceBundleId = messagesBundleGroup + .getResourceBundleId(); + + RBManager.getRefactorService().openRefactorDialog( + projectName, resourceBundleId, oldKey, null); + + } + } + } + + return null; + } + +} diff --git a/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyArguments.java b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyArguments.java new file mode 100644 index 0000000..ba64796 --- /dev/null +++ b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyArguments.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2009 Nigel Westbury + * 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: + * Nigel Westbury - initial implementation + ******************************************************************************/ +package org.eclipse.babel.editor.refactoring; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments; + +/** + * This class contains the data that a processor provides to its rename resource + * bundle key participants. + */ +public class RenameKeyArguments extends RefactoringArguments { + + private String fNewName; + + private boolean fRenameChildKeys; + + private boolean fUpdateReferences; + + /** + * Creates new rename arguments. + * + * @param newName + * the new name of the element to be renamed + * @param renameChildKeys + * true if child keys are to be renamed; + * false otherwise + * @param updateReferences + * true if reference updating is requested; + * false otherwise + */ + public RenameKeyArguments(String newName, boolean renameChildKeys, + boolean updateReferences) { + Assert.isNotNull(newName); + fNewName = newName; + fRenameChildKeys = renameChildKeys; + fUpdateReferences = updateReferences; + } + + /** + * Returns the new element name. + * + * @return the new element name + */ + public String getNewName() { + return fNewName; + } + + /** + * Returns whether child keys are to be renamed or not. + * + * @return returns true if child keys are to be renamed; + * false otherwise + */ + public boolean getRenameChildKeys() { + return fRenameChildKeys; + } + + /** + * Returns whether reference updating is requested or not. + * + * @return returns true if reference updating is requested; + * false otherwise + */ + public boolean getUpdateReferences() { + return fUpdateReferences; + } + + public String toString() { + return "rename to " + fNewName //$NON-NLS-1$ + + (fRenameChildKeys ? " (rename child keys)" : " (don't rename child keys)") //$NON-NLS-1$//$NON-NLS-2$ + + (fUpdateReferences ? " (update references)" : " (don't update references)"); //$NON-NLS-1$//$NON-NLS-2$ + } +} diff --git a/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyChange.java b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyChange.java new file mode 100644 index 0000000..f30272e --- /dev/null +++ b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyChange.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2009 Nigel Westbury + * 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: + * Nigel Westbury - initial implementation + ******************************************************************************/ +package org.eclipse.babel.editor.refactoring; + +import java.text.MessageFormat; +import java.util.Collection; + +import org.eclipse.babel.core.message.internal.MessagesBundleGroup; +import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.ChangeDescriptor; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * {@link Change} that renames a resource bundle key. + */ +public class RenameKeyChange extends Change { + + private final MessagesBundleGroup fMessagesBundleGroup; + + private final String fNewName; + + private final boolean fRenameChildKeys; + + private final KeyTreeNode fKeyTreeNode; + + private ChangeDescriptor fDescriptor; + + /** + * Creates the change. + * + * @param keyTreeNode + * the node in the model to rename + * @param newName + * the new name. Must not be empty + * @param renameChildKeys + * true if child keys are also to be renamed, false if just this + * one key is to be renamed + */ + protected RenameKeyChange(MessagesBundleGroup messageBundleGroup, + KeyTreeNode keyTreeNode, String newName, boolean renameChildKeys) { + if (keyTreeNode == null || newName == null || newName.length() == 0) { + throw new IllegalArgumentException(); + } + + fMessagesBundleGroup = messageBundleGroup; + fKeyTreeNode = keyTreeNode; + fNewName = newName; + fRenameChildKeys = renameChildKeys; + fDescriptor = null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.Change#getDescriptor() + */ + public ChangeDescriptor getDescriptor() { + return fDescriptor; + } + + /** + * Sets the change descriptor to be returned by + * {@link Change#getDescriptor()}. + * + * @param descriptor + * the change descriptor + */ + public void setDescriptor(ChangeDescriptor descriptor) { + fDescriptor = descriptor; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.Change#getName() + */ + public String getName() { + return MessageFormat.format("Rename {0} to {1}", new Object[] { + fKeyTreeNode.getMessageKey(), fNewName }); + } + + /** + * Returns the new name. + * + * @return return the new name + */ + public String getNewName() { + return fNewName; + } + + /** + * This implementation of {@link Change#isValid(IProgressMonitor)} tests the + * modified resource using the validation method specified by + * {@link #setValidationMethod(int)}. + */ + public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, + OperationCanceledException { + pm.beginTask("", 2); //$NON-NLS-1$ + try { + RefactoringStatus result = new RefactoringStatus(); + return result; + } finally { + pm.done(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ltk.core.refactoring.Change#initializeValidationData(org. + * eclipse.core.runtime.IProgressMonitor) + */ + public void initializeValidationData(IProgressMonitor pm) { + } + + public Object getModifiedElement() { + return "what is this for?"; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ltk.core.refactoring.Change#perform(org.eclipse.core.runtime + * .IProgressMonitor) + */ + public Change perform(IProgressMonitor pm) throws CoreException { + try { + pm.beginTask("Rename resource bundle key", 1); + + // Find the root - we will need this later + KeyTreeNode root = (KeyTreeNode) fKeyTreeNode.getParent(); + while (root.getName() != null) { + root = (KeyTreeNode) root.getParent(); + } + + if (fRenameChildKeys) { + String key = fKeyTreeNode.getMessageKey(); + String keyPrefix = fKeyTreeNode.getMessageKey() + "."; + Collection branchNodes = fKeyTreeNode.getBranch(); + for (KeyTreeNode branchNode : branchNodes) { + String oldKey = branchNode.getMessageKey(); + if (oldKey.equals(key) || oldKey.startsWith(keyPrefix)) { + String newKey = fNewName + + oldKey.substring(key.length()); + fMessagesBundleGroup.renameMessageKeys(oldKey, newKey); + } + } + } else { + fMessagesBundleGroup.renameMessageKeys( + fKeyTreeNode.getMessageKey(), fNewName); + } + + String oldName = fKeyTreeNode.getMessageKey(); + + // Find the node that was created with the new name + String segments[] = fNewName.split("\\."); + KeyTreeNode renamedKey = root; + for (String segment : segments) { + renamedKey = (KeyTreeNode) renamedKey.getChild(segment); + } + + assert (renamedKey != null); + return new RenameKeyChange(fMessagesBundleGroup, renamedKey, + oldName, fRenameChildKeys); + } finally { + pm.done(); + } + } +} diff --git a/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyDescriptor.java b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyDescriptor.java new file mode 100644 index 0000000..168b618 --- /dev/null +++ b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyDescriptor.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2009 Nigel Westbury + * 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: + * Nigel Westbury - initial implementation + ******************************************************************************/ +package org.eclipse.babel.editor.refactoring; + +import org.eclipse.babel.core.message.internal.MessagesBundleGroup; +import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.core.refactoring.RefactoringContribution; +import org.eclipse.ltk.core.refactoring.RefactoringCore; +import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring; + +/** + * Refactoring descriptor for the rename resource bundle key refactoring. + *

+ * An instance of this refactoring descriptor may be obtained by calling + * {@link RefactoringContribution#createDescriptor()} on a refactoring + * contribution requested by invoking + * {@link RefactoringCore#getRefactoringContribution(String)} with the + * refactoring id ({@link #ID}). + */ +public final class RenameKeyDescriptor extends RefactoringDescriptor { + + public static final String ID = "org.eclipse.babel.editor.refactoring.renameKey"; //$NON-NLS-1$ + + /** The name attribute */ + private String fNewName; + + private KeyTreeNode fKeyNode; + + private MessagesBundleGroup fMessagesBundleGroup; + + /** Configures if references will be updated */ + private boolean fRenameChildKeys; + + /** + * Creates a new refactoring descriptor. + *

+ * Clients should not instantiated this class but use + * {@link RefactoringCore#getRefactoringContribution(String)} with + * {@link #ID} to get the contribution that can create the descriptor. + *

+ */ + public RenameKeyDescriptor() { + super(ID, null, "N/A", null, RefactoringDescriptor.STRUCTURAL_CHANGE + | RefactoringDescriptor.MULTI_CHANGE); + fNewName = null; + } + + /** + * Sets the new name to rename the resource to. + * + * @param name + * the non-empty new name to set + */ + public void setNewName(final String name) { + Assert.isNotNull(name); + Assert.isLegal(!"".equals(name), "Name must not be empty"); //$NON-NLS-1$//$NON-NLS-2$ + fNewName = name; + } + + /** + * Returns the new name to rename the resource to. + * + * @return the new name to rename the resource to + */ + public String getNewName() { + return fNewName; + } + + /** + * Sets the project name of this refactoring. + *

+ * Note: If the resource to be renamed is of type {@link IResource#PROJECT}, + * clients are required to to set the project name to null. + *

+ *

+ * The default is to associate the refactoring with the workspace. + *

+ * + * @param project + * the non-empty project name to set, or null for + * the workspace + * + * @see #getProject() + */ + // public void setProject(final String project) { + // super.setProject(project); + // } + + /** + * If set to true, this rename will also rename child keys. The + * default is to rename child keys. + * + * @param renameChildKeys + * true if this rename will rename child keys + */ + public void setRenameChildKeys(boolean renameChildKeys) { + fRenameChildKeys = renameChildKeys; + } + + public void setRenameChildKeys(KeyTreeNode keyNode, + MessagesBundleGroup messagesBundleGroup) { + this.fKeyNode = keyNode; + this.fMessagesBundleGroup = messagesBundleGroup; + } + + /** + * Returns if this rename will also rename child keys + * + * @return returns true if this rename will rename child keys + */ + public boolean isRenameChildKeys() { + return fRenameChildKeys; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ltk.core.refactoring.RefactoringDescriptor#createRefactoring + * (org.eclipse.ltk.core.refactoring.RefactoringStatus) + */ + public Refactoring createRefactoring(RefactoringStatus status) + throws CoreException { + + String newName = getNewName(); + if (newName == null || newName.length() == 0) { + status.addFatalError("The rename resource bundle key refactoring can not be performed as the new name is invalid"); + return null; + } + RenameKeyProcessor processor = new RenameKeyProcessor(fKeyNode, + fMessagesBundleGroup); + processor.setNewResourceName(newName); + processor.setRenameChildKeys(fRenameChildKeys); + + return new RenameRefactoring(processor); + } +} \ No newline at end of file diff --git a/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyProcessor.java b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyProcessor.java new file mode 100644 index 0000000..d477287 --- /dev/null +++ b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyProcessor.java @@ -0,0 +1,311 @@ +/******************************************************************************* + * Copyright (c) 2009 Nigel Westbury + * 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: + * Nigel Westbury - initial implementation + ******************************************************************************/ +package org.eclipse.babel.editor.refactoring; + +import java.text.MessageFormat; + +import org.eclipse.babel.core.message.internal.MessagesBundleGroup; +import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; +import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor; +import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; +import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; +import org.eclipse.ltk.core.refactoring.participants.RenameProcessor; +import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker; +import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; + +/** + * A rename processor for {@link IResource}. The processor will rename the + * resource and load rename participants if references should be renamed as + * well. + * + * @since 3.4 + */ +public class RenameKeyProcessor extends RenameProcessor { + + private KeyTreeNode fKeyNode; + + private MessagesBundleGroup fMessageBundleGroup; + + private String fNewResourceName; + + private boolean fRenameChildKeys; + + private RenameKeyArguments fRenameArguments; // set after + // checkFinalConditions + + /** + * Creates a new rename resource processor. + * + * @param keyNode + * the resource to rename. + * @param messagesBundleGroup + */ + public RenameKeyProcessor(KeyTreeNode keyNode, + MessagesBundleGroup messagesBundleGroup) { + if (keyNode == null) { + throw new IllegalArgumentException("key node must not be null"); //$NON-NLS-1$ + } + + fKeyNode = keyNode; + fMessageBundleGroup = messagesBundleGroup; + fRenameArguments = null; + fRenameChildKeys = true; + setNewResourceName(keyNode.getMessageKey()); // Initialize new name + } + + /** + * Returns the new key node + * + * @return the new key node + */ + public KeyTreeNode getNewKeyTreeNode() { + return fKeyNode; + } + + /** + * Returns the new resource name + * + * @return the new resource name + */ + public String getNewResourceName() { + return fNewResourceName; + } + + /** + * Sets the new resource name + * + * @param newName + * the new resource name + */ + public void setNewResourceName(String newName) { + Assert.isNotNull(newName); + fNewResourceName = newName; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor) + */ + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) + throws CoreException { + /* + * This method allows fatal and non-fatal problems to be shown to the + * user. Currently there are none so we return null to indicate this. + */ + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor, + * org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext) + */ + public RefactoringStatus checkFinalConditions(IProgressMonitor pm, + CheckConditionsContext context) throws CoreException { + pm.beginTask("", 1); //$NON-NLS-1$ + try { + fRenameArguments = new RenameKeyArguments(getNewResourceName(), + fRenameChildKeys, false); + + ResourceChangeChecker checker = (ResourceChangeChecker) context + .getChecker(ResourceChangeChecker.class); + IResourceChangeDescriptionFactory deltaFactory = checker + .getDeltaFactory(); + + // TODO figure out what we want to do here.... + // ResourceModifications.buildMoveDelta(deltaFactory, fKeyNode, + // fRenameArguments); + + return new RefactoringStatus(); + } finally { + pm.done(); + } + } + + /** + * Validates if the a name is valid. This method does not change the name + * settings on the refactoring. It is intended to be used in a wizard to + * validate user input. + * + * @param newName + * the name to validate + * @return returns the resulting status of the validation + */ + public RefactoringStatus validateNewElementName(String newName) { + Assert.isNotNull(newName); + + if (newName.length() == 0) { + return RefactoringStatus + .createFatalErrorStatus("New name for key must be entered"); + } + if (newName.startsWith(".")) { + return RefactoringStatus + .createFatalErrorStatus("Key cannot start with a '.'"); + } + if (newName.endsWith(".")) { + return RefactoringStatus + .createFatalErrorStatus("Key cannot end with a '.'"); + } + + String[] parts = newName.split("\\."); + for (String part : parts) { + if (part.length() == 0) { + return RefactoringStatus + .createFatalErrorStatus("Key cannot contain an empty part between two periods"); + } + if (!part.matches("([A-Z]|[a-z]|[0-9])*")) { + return RefactoringStatus + .createFatalErrorStatus("Key can contain only letters, digits, and periods"); + } + } + + if (fMessageBundleGroup.isMessageKey(newName)) { + return RefactoringStatus + .createFatalErrorStatus(MessagesEditorPlugin + .getString("dialog.error.exists")); + } + + return new RefactoringStatus(); + } + + protected RenameKeyDescriptor createDescriptor() { + RenameKeyDescriptor descriptor = new RenameKeyDescriptor(); + descriptor + .setDescription(MessageFormat.format( + "Rename resource bundle key ''{0}''", + fKeyNode.getMessageKey())); + descriptor.setComment(MessageFormat.format( + "Rename resource ''{0}'' to ''{1}''", + new Object[] { fKeyNode.getMessageKey(), fNewResourceName })); + descriptor.setFlags(RefactoringDescriptor.STRUCTURAL_CHANGE + | RefactoringDescriptor.MULTI_CHANGE + | RefactoringDescriptor.BREAKING_CHANGE); + descriptor.setNewName(getNewResourceName()); + descriptor.setRenameChildKeys(fRenameChildKeys); + return descriptor; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * createChange(org.eclipse.core.runtime.IProgressMonitor) + */ + public Change createChange(IProgressMonitor pm) throws CoreException { + pm.beginTask("", 1); //$NON-NLS-1$ + try { + RenameKeyChange change = new RenameKeyChange(fMessageBundleGroup, + getNewKeyTreeNode(), fNewResourceName, fRenameChildKeys); + change.setDescriptor(new RefactoringChangeDescriptor( + createDescriptor())); + return change; + } finally { + pm.done(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * getElements() + */ + public Object[] getElements() { + return new Object[] { fKeyNode }; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * getIdentifier() + */ + public String getIdentifier() { + return "org.eclipse.babel.editor.refactoring.renameKeyProcessor"; //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * getProcessorName() + */ + public String getProcessorName() { + return "Rename Resource Bundle Key"; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * isApplicable() + */ + public boolean isApplicable() { + if (this.fKeyNode == null) + return false; + return true; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * loadParticipants(org.eclipse.ltk.core.refactoring.RefactoringStatus, + * org.eclipse.ltk.core.refactoring.participants.SharableParticipants) + */ + public RefactoringParticipant[] loadParticipants(RefactoringStatus status, + SharableParticipants shared) throws CoreException { + // TODO: figure out participants to return here + return new RefactoringParticipant[0]; + + // String[] affectedNatures= + // ResourceProcessors.computeAffectedNatures(fResource); + // return ParticipantManager.loadRenameParticipants(status, this, + // fResource, fRenameArguments, null, affectedNatures, shared); + } + + /** + * Returns true if the refactoring processor also renames the + * child keys + * + * @return true if the refactoring processor also renames the + * child keys + */ + public boolean getRenameChildKeys() { + return fRenameChildKeys; + } + + /** + * Specifies if the refactoring processor also updates the child keys. The + * default behaviour is to update the child keys. + * + * @param renameChildKeys + * true if the refactoring processor should also + * rename the child keys + */ + public void setRenameChildKeys(boolean renameChildKeys) { + fRenameChildKeys = renameChildKeys; + } + +} \ No newline at end of file diff --git a/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyWizard.java b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyWizard.java new file mode 100644 index 0000000..8cad851 --- /dev/null +++ b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/refactoring/RenameKeyWizard.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2009 Nigel Westbury + * 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: + * Nigel Westbury - initial implementation + ******************************************************************************/ +package org.eclipse.babel.editor.refactoring; + +import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring; +import org.eclipse.ltk.ui.refactoring.RefactoringWizard; +import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * A wizard for the rename bundle key refactoring. + */ +public class RenameKeyWizard extends RefactoringWizard { + + /** + * Creates a {@link RenameKeyWizard}. + * + * @param resource + * the bundle key to rename + * @param refactoring + */ + public RenameKeyWizard(KeyTreeNode resource, RenameKeyProcessor refactoring) { + super(new RenameRefactoring(refactoring), DIALOG_BASED_USER_INTERFACE); + setDefaultPageTitle("Rename Resource Bundle Key"); + setWindowTitle("Rename Resource Bundle Key"); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.ui.refactoring.RefactoringWizard#addUserInputPages() + */ + protected void addUserInputPages() { + RenameKeyProcessor processor = (RenameKeyProcessor) getRefactoring() + .getAdapter(RenameKeyProcessor.class); + addPage(new RenameResourceRefactoringConfigurationPage(processor)); + } + + private static class RenameResourceRefactoringConfigurationPage extends + UserInputWizardPage { + + private final RenameKeyProcessor fRefactoringProcessor; + private Text fNameField; + + public RenameResourceRefactoringConfigurationPage( + RenameKeyProcessor processor) { + super("RenameResourceRefactoringInputPage"); //$NON-NLS-1$ + fRefactoringProcessor = processor; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt + * .widgets.Composite) + */ + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + composite + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + composite.setFont(parent.getFont()); + + Label label = new Label(composite, SWT.NONE); + label.setText("New name:"); + label.setLayoutData(new GridData()); + + fNameField = new Text(composite, SWT.BORDER); + fNameField.setText(fRefactoringProcessor.getNewResourceName()); + fNameField.setFont(composite.getFont()); + fNameField.setLayoutData(new GridData(GridData.FILL, + GridData.BEGINNING, true, false)); + fNameField.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validatePage(); + } + }); + + final Button includeChildKeysCheckbox = new Button(composite, + SWT.CHECK); + if (fRefactoringProcessor.getNewKeyTreeNode().isUsedAsKey()) { + if (fRefactoringProcessor.getNewKeyTreeNode().getChildren().length == 0) { + // This is an actual key with no child keys. + includeChildKeysCheckbox.setSelection(false); + includeChildKeysCheckbox.setEnabled(false); + } else { + // This is both an actual key and it has child keys, so we + // let the user choose whether to also rename the child + // keys. + includeChildKeysCheckbox.setSelection(fRefactoringProcessor + .getRenameChildKeys()); + includeChildKeysCheckbox.setEnabled(true); + } + } else { + // This is no an actual key, just a containing node, so the + // option + // to rename child keys must be set (otherwise this rename would + // not + // do anything). + includeChildKeysCheckbox.setSelection(true); + includeChildKeysCheckbox.setEnabled(false); + } + + includeChildKeysCheckbox + .setText("Also rename child keys (other keys with this key as a prefix)"); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + includeChildKeysCheckbox.setLayoutData(gd); + includeChildKeysCheckbox + .addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + fRefactoringProcessor + .setRenameChildKeys(includeChildKeysCheckbox + .getSelection()); + } + }); + + fNameField.selectAll(); + setPageComplete(false); + setControl(composite); + } + + public void setVisible(boolean visible) { + if (visible) { + fNameField.setFocus(); + } + super.setVisible(visible); + } + + protected final void validatePage() { + String text = fNameField.getText(); + RefactoringStatus status = fRefactoringProcessor + .validateNewElementName(text); + setPageComplete(status); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ltk.ui.refactoring.UserInputWizardPage#performFinish() + */ + protected boolean performFinish() { + initializeRefactoring(); + storeSettings(); + return super.performFinish(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#getNextPage() + */ + public IWizardPage getNextPage() { + initializeRefactoring(); + storeSettings(); + return super.getNextPage(); + } + + private void storeSettings() { + } + + private void initializeRefactoring() { + fRefactoringProcessor.setNewResourceName(fNameField.getText()); + } + } +} \ No newline at end of file diff --git a/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/tree/actions/RenameKeyAction.java b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/tree/actions/RenameKeyAction.java new file mode 100644 index 0000000..091b4c9 --- /dev/null +++ b/org.eclipse.babel.editor.swt/src/org/eclipse/babel/editor/tree/actions/RenameKeyAction.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2007 Pascal Essiembre, Matthias Lettmayer. + * 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: + * Pascal Essiembre - initial API and implementation + * Matthias Lettmayer - extracted RenameKeyAction into own class for SWT specific implementation + ******************************************************************************/ +package org.eclipse.babel.editor.tree.actions; + +import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; +import org.eclipse.babel.editor.refactoring.RenameKeyProcessor; +import org.eclipse.babel.editor.refactoring.RenameKeyWizard; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.ltk.ui.refactoring.RefactoringWizard; +import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; + +public class RenameKeyAction extends AbstractRenameKeyAction { + + public RenameKeyAction(AbstractMessagesEditor editor, TreeViewer treeViewer) { + super(editor, treeViewer); + } + + @Override + public void run() { + KeyTreeNode node = getNodeSelection(); + + // Rename single item + RenameKeyProcessor refactoring = new RenameKeyProcessor(node, + getBundleGroup()); + + RefactoringWizard wizard = new RenameKeyWizard(node, refactoring); + try { + RefactoringWizardOpenOperation operation = new RefactoringWizardOpenOperation( + wizard); + operation.run(getShell(), "Introduce Indirection"); + } catch (InterruptedException exception) { + // Do nothing + } + } +} diff --git a/org.eclipse.babel.editor/META-INF/MANIFEST.MF b/org.eclipse.babel.editor/META-INF/MANIFEST.MF index 44f856c..faf215e 100644 --- a/org.eclipse.babel.editor/META-INF/MANIFEST.MF +++ b/org.eclipse.babel.editor/META-INF/MANIFEST.MF @@ -4,21 +4,30 @@ Bundle-Name: %plugin.name Bundle-SymbolicName: org.eclipse.babel.editor;singleton:=true Bundle-Version: 0.8.0.qualifier Bundle-Activator: org.eclipse.babel.editor.plugin.MessagesEditorPlugin -Require-Bundle: org.eclipse.ui, +Require-Bundle: org.eclipse.ui;resolution:=optional, + org.eclipse.babel.editor.swt.compat;bundle-version="0.8.0";resolution:=optional, org.eclipse.core.runtime, - org.eclipse.jface.text, - org.eclipse.ui.editors, - org.eclipse.ui.ide, - org.eclipse.ui.workbench.texteditor, - org.eclipse.ui.views, - org.eclipse.ui.forms;bundle-version="3.2.0", + org.eclipse.jface.text;resolution:=optional, + org.eclipse.ui.editors;resolution:=optional, + org.eclipse.babel.editor.rap.compat;bundle-version="0.8.0";resolution:=optional, + org.eclipse.ui.ide;resolution:=optional, + org.eclipse.ui.workbench.texteditor;resolution:=optional, + org.eclipse.ui.views;resolution:=optional, org.eclipse.core.resources;bundle-version="3.2.0", - org.eclipse.jdt.core;bundle-version="3.2.0", - org.eclipse.ltk.core.refactoring, - org.eclipse.ltk.ui.refactoring, + org.eclipse.jdt.core;bundle-version="3.2.0";resolution:=optional, + org.eclipse.ltk.core.refactoring;resolution:=optional, + org.eclipse.ltk.ui.refactoring;resolution:=optional, org.junit;resolution:=optional, - org.eclipse.babel.core;visibility:=reexport, - org.eclipse.pde.core;resolution:=optional + org.eclipse.babel.core, + org.eclipse.pde.core;resolution:=optional, + org.eclipse.rap.ui;bundle-version="1.5.0";resolution:=optional, + org.eclipselabs.tapiji.translator.rap.supplemental;bundle-version="0.0.2";resolution:=optional, + org.eclipse.rap.ui.views;bundle-version="1.5.0";resolution:=optional, + org.eclipse.rap.rwt.supplemental.filedialog;bundle-version="1.5.0";resolution:=optional, + org.eclipse.rap.ui.forms;bundle-version="1.5.0";resolution:=optional, + org.eclipse.ui.forms;bundle-version="3.5.101";resolution:=optional, + org.eclipselabs.tapiji.translator.rap.model;bundle-version="0.0.2";resolution:=optional, + org.eclipselabs.tapiji.translator.rap.helpers;bundle-version="1.0.0";resolution:=optional Bundle-ActivationPolicy: lazy Bundle-Vendor: %plugin.provider Bundle-RequiredExecutionEnvironment: JavaSE-1.6 @@ -26,4 +35,6 @@ Bundle-Localization: plugin Export-Package: org.eclipse.babel.editor, org.eclipse.babel.editor.api, org.eclipse.babel.editor.util, + org.eclipse.babel.editor.widgets, org.eclipse.babel.editor.wizards +Import-Package: org.eclipse.ui.forms.widgets diff --git a/org.eclipse.babel.editor/build.properties b/org.eclipse.babel.editor/build.properties index 232cb4e..fdad6ae 100644 --- a/org.eclipse.babel.editor/build.properties +++ b/org.eclipse.babel.editor/build.properties @@ -9,4 +9,5 @@ bin.includes = META-INF/,\ CHANGES src.includes = icons/,\ messages.properties,\ - CHANGES + plugin.properties,\ + plugin.xml diff --git a/org.eclipse.babel.editor/icons/refactoring.png b/org.eclipse.babel.editor/icons/refactoring.png index 0c435e5..5242fdf 100644 Binary files a/org.eclipse.babel.editor/icons/refactoring.png and b/org.eclipse.babel.editor/icons/refactoring.png differ diff --git a/org.eclipse.babel.editor/messages.properties b/org.eclipse.babel.editor/messages.properties index b2ef016..01f6ed1 100644 --- a/org.eclipse.babel.editor/messages.properties +++ b/org.eclipse.babel.editor/messages.properties @@ -65,6 +65,7 @@ key.expandAll = &Expand All key.layout.flat = Flat key.layout.tree = Tree key.rename = &Rename +key.refactor = Refactor key.uncomment = &Uncomment prefs.alignEquals = Align equal signs diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/IMessagesEditor.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/IMessagesEditor.java index 2286d30..9d397d4 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/IMessagesEditor.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/IMessagesEditor.java @@ -10,8 +10,16 @@ ******************************************************************************/ package org.eclipse.babel.editor; +import org.eclipse.babel.core.message.internal.MessagesBundleGroup; + public interface IMessagesEditor { String getSelectedKey(); void setSelectedKey(String key); + + MessagesBundleGroup getBundleGroup(); + + void setTitleName(String string); + + void setEnabled(boolean enabled); } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/FilterKeysAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/FilterKeysAction.java index 1d1fc41..4c2274d 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/FilterKeysAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/FilterKeysAction.java @@ -11,7 +11,7 @@ package org.eclipse.babel.editor.actions; import org.eclipse.babel.editor.IMessagesEditorChangeListener; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.internal.MessagesEditorChangeAdapter; import org.eclipse.babel.editor.internal.MessagesEditorContributor; import org.eclipse.babel.editor.util.UIUtils; @@ -26,7 +26,7 @@ import org.eclipse.swt.graphics.Image; */ public class FilterKeysAction extends Action { - private MessagesEditor editor; + private AbstractMessagesEditor editor; private final int flagToSet; private ChangeListener listener; @@ -144,7 +144,7 @@ public class FilterKeysAction extends Action { // } } - public void setEditor(MessagesEditor editor) { + public void setEditor(AbstractMessagesEditor editor) { if (editor == this.editor) { return;// no change } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/KeyTreeVisibleAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/KeyTreeVisibleAction.java index ed8eff7..b5740ef 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/KeyTreeVisibleAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/KeyTreeVisibleAction.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.eclipse.babel.editor.actions; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.internal.MessagesEditorChangeAdapter; import org.eclipse.babel.editor.util.UIUtils; import org.eclipse.jface.action.Action; @@ -22,7 +22,7 @@ import org.eclipse.jface.action.IAction; */ public class KeyTreeVisibleAction extends Action { - private MessagesEditor editor; + private AbstractMessagesEditor editor; /** * @@ -36,7 +36,7 @@ public class KeyTreeVisibleAction extends Action { // TODO RBEditor hold such an action registry. Then move this method to // constructor - public void setEditor(MessagesEditor editor) { + public void setEditor(AbstractMessagesEditor editor) { this.editor = editor; editor.addChangeListener(new MessagesEditorChangeAdapter() { public void keyTreeVisibleChanged(boolean visible) { diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/NewLocaleAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/NewLocaleAction.java index bc4ff39..25f76ab 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/NewLocaleAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/actions/NewLocaleAction.java @@ -14,7 +14,7 @@ package org.eclipse.babel.editor.actions; import java.util.Locale; import org.eclipse.babel.core.message.internal.MessagesBundleGroup; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.util.UIUtils; import org.eclipse.babel.editor.widgets.LocaleSelector; import org.eclipse.jface.action.Action; @@ -29,7 +29,7 @@ import org.eclipse.swt.widgets.Shell; */ public class NewLocaleAction extends Action { - private MessagesEditor editor; + private AbstractMessagesEditor editor; /** * @@ -43,7 +43,7 @@ public class NewLocaleAction extends Action { // TODO RBEditor hold such an action registry. Then move this method to // constructor - public void setEditor(MessagesEditor editor) { + public void setEditor(AbstractMessagesEditor editor) { this.editor = editor; } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/api/EditorUtil.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/api/EditorUtil.java index 88ed83f..980b364 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/api/EditorUtil.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/api/EditorUtil.java @@ -2,7 +2,7 @@ package org.eclipse.babel.editor.api; import org.eclipse.babel.core.message.tree.IKeyTreeNode; import org.eclipse.babel.editor.i18n.I18NPage; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IWorkbenchPage; @@ -21,7 +21,8 @@ public class EditorUtil { * @return The selected {@link IKeyTreeNode} of the page. */ public static IKeyTreeNode getSelectedKeyTreeNode(IWorkbenchPage page) { - MessagesEditor editor = (MessagesEditor) page.getActiveEditor(); + AbstractMessagesEditor editor = (AbstractMessagesEditor) page + .getActiveEditor(); if (editor.getSelectedPage() instanceof I18NPage) { I18NPage p = (I18NPage) editor.getSelectedPage(); ISelection selection = p.getSelection(); diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/AbstractI18NEntry.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/AbstractI18NEntry.java new file mode 100755 index 0000000..f05d8b5 --- /dev/null +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/AbstractI18NEntry.java @@ -0,0 +1,804 @@ +/******************************************************************************* + * Copyright (c) 2007 Pascal Essiembre. + * 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: + * Pascal Essiembre - initial API and implementation + * Alexej Strelzow - updateKey + ******************************************************************************/ +package org.eclipse.babel.editor.i18n; + +import java.util.Locale; + +import org.eclipse.babel.core.message.IMessage; +import org.eclipse.babel.core.message.IMessagesBundle; +import org.eclipse.babel.core.message.IMessagesBundleGroup; +import org.eclipse.babel.core.message.internal.Message; +import org.eclipse.babel.core.message.manager.RBManager; +import org.eclipse.babel.core.util.BabelUtils; +import org.eclipse.babel.editor.IMessagesEditorChangeListener; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; +import org.eclipse.babel.editor.internal.MessagesEditorChangeAdapter; +import org.eclipse.babel.editor.util.UIUtils; +import org.eclipse.babel.editor.widgets.NullableText; +import org.eclipse.jface.bindings.keys.IKeyLookup; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CBanner; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.editors.text.TextEditor; + +/** + * Tree for displaying and navigating through resource bundle keys. + * + * @author Pascal Essiembre + */ +public abstract class AbstractI18NEntry extends Composite { + + protected final AbstractMessagesEditor editor; + private final String bundleGroupId; + private final String projectName; + protected final Locale locale; + + private boolean expanded = true; + protected NullableText textBox; + private CBanner banner; + protected String focusGainedText; + + public static final String INSTANCE_CLASS = "org.eclipse.babel.editor.i18n.I18NEntry"; + + private IMessagesEditorChangeListener msgEditorUpdateKey = new MessagesEditorChangeAdapter() { + public void selectedKeyChanged(String oldKey, String newKey) { + updateKey(newKey); + } + }; + + /** + * Constructor. + * + * @param parent + * parent composite + * @param keyTree + * key tree + */ + public AbstractI18NEntry(Composite parent, + final AbstractMessagesEditor editor, final Locale locale) { + super(parent, SWT.NONE); + this.editor = editor; + this.locale = locale; + this.bundleGroupId = editor.getBundleGroup().getResourceBundleId(); + this.projectName = editor.getBundleGroup().getProjectName(); + + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 0; + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + + setLayout(gridLayout); + GridData gd = new GridData(GridData.FILL_BOTH); + // gd.heightHint = 80; + setLayoutData(gd); + + banner = new CBanner(this, SWT.NONE); + + Control bannerLeft = new EntryLeftBanner(banner, this);// createBannerLeft(banner); + Control bannerRight = new EntryRightBanner(banner, this);// createBannerRight(banner); + + GridData gridData = new GridData(); + gridData.horizontalAlignment = GridData.FILL; + gridData.grabExcessHorizontalSpace = true; + + banner.setLeft(bannerLeft); + banner.setRight(bannerRight); + // banner.setRightWidth(300); + banner.setSimple(false); + banner.setLayoutData(gridData); + + createTextbox(); + + } + + public AbstractMessagesEditor getResourceBundleEditor() { + return editor; + } + + public void setExpanded(boolean expanded) { + this.expanded = expanded; + textBox.setVisible(expanded); + + if (expanded) { + GridData gridData = new GridData(); + gridData.verticalAlignment = GridData.FILL; + gridData.grabExcessVerticalSpace = true; + gridData.horizontalAlignment = GridData.FILL; + gridData.grabExcessHorizontalSpace = true; + gridData.heightHint = UIUtils.getHeightInChars(textBox, 3); + textBox.setLayoutData(gridData); + + GridData gd = new GridData(GridData.FILL_BOTH); + // gd.heightHint = 80; + setLayoutData(gd); + getParent().pack(); + getParent().layout(true, true); + + } else { + GridData gridData = ((GridData) textBox.getLayoutData()); + gridData.verticalAlignment = GridData.BEGINNING; + gridData.grabExcessVerticalSpace = false; + textBox.setLayoutData(gridData); + + gridData = (GridData) getLayoutData(); + gridData.heightHint = banner.getSize().y; + gridData.verticalAlignment = GridData.BEGINNING; + gridData.grabExcessVerticalSpace = false; + setLayoutData(gridData); + + getParent().pack(); + getParent().layout(true, true); + } + + } + + public boolean getExpanded() { + return expanded; + } + + public Locale getLocale() { + return locale; + } + + public boolean isEditable() { + IMessagesBundleGroup messagesBundleGroup = editor.getBundleGroup(); + IMessagesBundle bundle = messagesBundleGroup.getMessagesBundle(locale); + return ((TextEditor) bundle.getResource().getSource()).isEditable(); + } + + public String getResourceLocationLabel() { + IMessagesBundleGroup messagesBundleGroup = editor.getBundleGroup(); + IMessagesBundle bundle = messagesBundleGroup.getMessagesBundle(locale); + return bundle.getResource().getResourceLocationLabel(); + } + + // /*default*/ Text getTextBox() { + // return textBox; + // } + + /** + * @param editor + * @param locale + */ + private void createTextbox() { + textBox = new NullableText(this, SWT.MULTI | SWT.WRAP | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.BORDER); + textBox.setEnabled(false); + textBox.setOrientation(UIUtils.getOrientation(locale)); + + textBox.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent event) { + focusGainedText = textBox.getText(); + } + + public void focusLost(FocusEvent event) { + updateModel(); + } + }); + // -- Setup read-only textbox -- + // that is the case if the corresponding editor is itself read-only. + // it happens when the corresponding resource is defined inside the + // target-platform for example + textBox.setEditable(isEditable()); + + // --- Handle tab key --- + // TODO add a preference property listener and add/remove this listener + textBox.addTraverseListener(new TraverseListener() { + public void keyTraversed(TraverseEvent event) { + // if (!MsgEditorPreferences.getFieldTabInserts() + // && event.character == SWT.TAB) { + // event.doit = true; + // } + } + }); + + // Handle dirtyness + textBox.addKeyListener(getKeyListener()); + + editor.addChangeListener(msgEditorUpdateKey); + } + + abstract void updateKey(String key); + + abstract KeyListener getKeyListener(); + + protected void updateModel() { + if (editor.getSelectedKey() != null) { + if (!BabelUtils.equals(focusGainedText, textBox.getText())) { + // IMessagesBundleGroup messagesBundleGroup = + // RBManager.getInstance(projectName).getMessagesBundleGroup(bundleGroupId); + IMessagesBundleGroup messagesBundleGroup = editor + .getBundleGroup(); + String key = editor.getSelectedKey(); + IMessage entry = messagesBundleGroup.getMessage(key, locale); + if (entry == null) { + entry = new Message(key, locale); + IMessagesBundle messagesBundle = messagesBundleGroup + .getMessagesBundle(locale); + if (messagesBundle != null) { + messagesBundle.addMessage(entry); + } + } + entry.setText(textBox.getText()); + } + } + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + textBox.setEnabled(enabled); + } + + @Override + public void dispose() { + editor.removeChangeListener(msgEditorUpdateKey); + super.dispose(); + } + +} + +// TODO Grab and Apply font fix: +// /** +// * Represents a data entry section for a bundle entry. +// * @author Pascal Essiembre (essiembre@users.sourceforge.net) +// * @version $Author: pessiembr $ $Revision: 1.3 $ $Date: 2008/01/11 04:15:15 $ +// */ +// public class BundleEntryComposite extends Composite { +// +// /*default*/ final ResourceManager resourceManager; +// /*default*/ final Locale locale; +// private final Font boldFont; +// private final Font smallFont; +// +// /*default*/ Text textBox; +// private Button commentedCheckbox; +// private Button gotoButton; +// private Button duplButton; +// private Button simButton; +// +// /*default*/ String activeKey; +// /*default*/ String textBeforeUpdate; +// +// /*default*/ DuplicateValuesVisitor duplVisitor; +// /*default*/ SimilarValuesVisitor similarVisitor; +// +// +// /** +// * Constructor. +// * @param parent parent composite +// * @param resourceManager resource manager +// * @param locale locale for this bundle entry +// */ +// public BundleEntryComposite( +// final Composite parent, +// final ResourceManager resourceManager, +// final Locale locale) { +// +// super(parent, SWT.NONE); +// this.resourceManager = resourceManager; +// this.locale = locale; +// +// this.boldFont = UIUtils.createFont(this, SWT.BOLD, 0); +// this.smallFont = UIUtils.createFont(SWT.NONE, -1); +// +// GridLayout gridLayout = new GridLayout(1, false); +// gridLayout.horizontalSpacing = 0; +// gridLayout.verticalSpacing = 2; +// gridLayout.marginWidth = 0; +// gridLayout.marginHeight = 0; +// +// createLabelRow(); +// createTextRow(); +// +// setLayout(gridLayout); +// GridData gd = new GridData(GridData.FILL_BOTH); +// gd.heightHint = 80; +// setLayoutData(gd); +// +// +// } +// +// /** +// * Update bundles if the value of the active key changed. +// */ +// public void updateBundleOnChanges(){ +// if (activeKey != null) { +// MessagesBundleGroup messagesBundleGroup = resourceManager.getBundleGroup(); +// Message entry = messagesBundleGroup.getBundleEntry(locale, activeKey); +// boolean commentedSelected = commentedCheckbox.getSelection(); +// String textBoxValue = textBox.getText(); +// +// if (entry == null || !textBoxValue.equals(entry.getValue()) +// || entry.isCommented() != commentedSelected) { +// String comment = null; +// if (entry != null) { +// comment = entry.getComment(); +// } +// messagesBundleGroup.addBundleEntry(locale, new Message( +// activeKey, +// textBox.getText(), +// comment, +// commentedSelected)); +// } +// } +// } +// +// /** +// * @see org.eclipse.swt.widgets.Widget#dispose() +// */ +// public void dispose() { +// super.dispose(); +// boldFont.dispose(); +// smallFont.dispose(); +// +// //Addition by Eric Fettweis +// for(Iterator it = swtFontCache.values().iterator();it.hasNext();){ +// Font font = (Font) it.next(); +// font.dispose(); +// } +// swtFontCache.clear(); +// } +// +// /** +// * Gets the locale associated with this bundle entry +// * @return a locale +// */ +// public Locale getLocale() { +// return locale; +// } +// +// /** +// * Sets a selection in the text box. +// * @param start starting position to select +// * @param end ending position to select +// */ +// public void setTextSelection(int start, int end) { +// textBox.setSelection(start, end); +// } +// +// /** +// * Refreshes the text field value with value matching given key. +// * @param key key used to grab value +// */ +// public void refresh(String key) { +// activeKey = key; +// MessagesBundleGroup messagesBundleGroup = resourceManager.getBundleGroup(); +// if (key != null && messagesBundleGroup.isKey(key)) { +// Message bundleEntry = messagesBundleGroup.getBundleEntry(locale, key); +// SourceEditor sourceEditor = resourceManager.getSourceEditor(locale); +// if (bundleEntry == null) { +// textBox.setText(""); //$NON-NLS-1$ +// commentedCheckbox.setSelection(false); +// } else { +// commentedCheckbox.setSelection(bundleEntry.isCommented()); +// String value = bundleEntry.getValue(); +// textBox.setText(value); +// } +// commentedCheckbox.setEnabled(!sourceEditor.isReadOnly()); +// textBox.setEnabled(!sourceEditor.isReadOnly()); +// gotoButton.setEnabled(true); +// if (MsgEditorPreferences.getReportDuplicateValues()) { +// findDuplicates(bundleEntry); +// } else { +// duplVisitor = null; +// } +// if (MsgEditorPreferences.getReportSimilarValues()) { +// findSimilar(bundleEntry); +// } else { +// similarVisitor = null; +// } +// } else { +// commentedCheckbox.setSelection(false); +// commentedCheckbox.setEnabled(false); +// textBox.setText(""); //$NON-NLS-1$ +// textBox.setEnabled(false); +// gotoButton.setEnabled(false); +// duplButton.setVisible(false); +// simButton.setVisible(false); +// } +// resetCommented(); +// } +// +// private void findSimilar(Message bundleEntry) { +// ProximityAnalyzer analyzer; +// if (MsgEditorPreferences.getReportSimilarValuesLevensthein()) { +// analyzer = LevenshteinDistanceAnalyzer.getInstance(); +// } else { +// analyzer = WordCountAnalyzer.getInstance(); +// } +// MessagesBundleGroup messagesBundleGroup = resourceManager.getBundleGroup(); +// if (similarVisitor == null) { +// similarVisitor = new SimilarValuesVisitor(); +// } +// similarVisitor.setProximityAnalyzer(analyzer); +// similarVisitor.clear(); +// messagesBundleGroup.getBundle(locale).accept(similarVisitor, bundleEntry); +// if (duplVisitor != null) { +// similarVisitor.getSimilars().removeAll(duplVisitor.getDuplicates()); +// } +// simButton.setVisible(similarVisitor.getSimilars().size() > 0); +// } +// +// private void findDuplicates(Message bundleEntry) { +// MessagesBundleGroup messagesBundleGroup = resourceManager.getBundleGroup(); +// if (duplVisitor == null) { +// duplVisitor = new DuplicateValuesVisitor(); +// } +// duplVisitor.clear(); +// messagesBundleGroup.getBundle(locale).accept(duplVisitor, bundleEntry); +// duplButton.setVisible(duplVisitor.getDuplicates().size() > 0); +// } +// +// +// /** +// * Creates the text field label, icon, and commented check box. +// */ +// private void createLabelRow() { +// Composite labelComposite = new Composite(this, SWT.NONE); +// GridLayout gridLayout = new GridLayout(); +// gridLayout.numColumns = 6; +// gridLayout.horizontalSpacing = 5; +// gridLayout.verticalSpacing = 0; +// gridLayout.marginWidth = 0; +// gridLayout.marginHeight = 0; +// labelComposite.setLayout(gridLayout); +// labelComposite.setLayoutData( +// new GridData(GridData.FILL_HORIZONTAL)); +// +// // Locale text +// Label txtLabel = new Label(labelComposite, SWT.NONE); +// txtLabel.setText(" " + //$NON-NLS-1$ +// UIUtils.getDisplayName(locale) + " "); //$NON-NLS-1$ +// txtLabel.setFont(boldFont); +// GridData gridData = new GridData(); +// +// // Similar button +// gridData = new GridData(); +// gridData.horizontalAlignment = GridData.END; +// gridData.grabExcessHorizontalSpace = true; +// simButton = new Button(labelComposite, SWT.PUSH | SWT.FLAT); +// simButton.setImage(UIUtils.getImage("similar.gif")); //$NON-NLS-1$ +// simButton.setLayoutData(gridData); +// simButton.setVisible(false); +// simButton.setToolTipText( +// RBEPlugin.getString("value.similar.tooltip")); //$NON-NLS-1$ +// simButton.addSelectionListener(new SelectionAdapter() { +// public void widgetSelected(SelectionEvent event) { +// String head = RBEPlugin.getString( +// "dialog.similar.head"); //$NON-NLS-1$ +// String body = RBEPlugin.getString( +// "dialog.similar.body", activeKey, //$NON-NLS-1$ +// UIUtils.getDisplayName(locale)); +// body += "\n\n"; //$NON-NLS-1$ +// for (Iterator iter = similarVisitor.getSimilars().iterator(); +// iter.hasNext();) { +// body += " " //$NON-NLS-1$ +// + ((Message) iter.next()).getKey() +// + "\n"; //$NON-NLS-1$ +// } +// MessageDialog.openInformation(getShell(), head, body); +// } +// }); +// +// // Duplicate button +// gridData = new GridData(); +// gridData.horizontalAlignment = GridData.END; +// duplButton = new Button(labelComposite, SWT.PUSH | SWT.FLAT); +// duplButton.setImage(UIUtils.getImage("duplicate.gif")); //$NON-NLS-1$ +// duplButton.setLayoutData(gridData); +// duplButton.setVisible(false); +// duplButton.setToolTipText( +// RBEPlugin.getString("value.duplicate.tooltip")); //$NON-NLS-1$ +// +// duplButton.addSelectionListener(new SelectionAdapter() { +// public void widgetSelected(SelectionEvent event) { +// String head = RBEPlugin.getString( +// "dialog.identical.head"); //$NON-NLS-1$ +// String body = RBEPlugin.getString( +// "dialog.identical.body", activeKey, //$NON-NLS-1$ +// UIUtils.getDisplayName(locale)); +// body += "\n\n"; //$NON-NLS-1$ +// for (Iterator iter = duplVisitor.getDuplicates().iterator(); +// iter.hasNext();) { +// body += " " //$NON-NLS-1$ +// + ((Message) iter.next()).getKey() +// + "\n"; //$NON-NLS-1$ +// } +// MessageDialog.openInformation(getShell(), head, body); +// } +// }); +// +// // Commented checkbox +// gridData = new GridData(); +// gridData.horizontalAlignment = GridData.END; +// //gridData.grabExcessHorizontalSpace = true; +// commentedCheckbox = new Button( +// labelComposite, SWT.CHECK); +// commentedCheckbox.setText("#"); //$NON-NLS-1$ +// commentedCheckbox.setFont(smallFont); +// commentedCheckbox.setLayoutData(gridData); +// commentedCheckbox.addSelectionListener(new SelectionAdapter() { +// public void widgetSelected(SelectionEvent event) { +// resetCommented(); +// updateBundleOnChanges(); +// } +// }); +// commentedCheckbox.setEnabled(false); +// +// // Country flag +// gridData = new GridData(); +// gridData.horizontalAlignment = GridData.END; +// Label imgLabel = new Label(labelComposite, SWT.NONE); +// imgLabel.setLayoutData(gridData); +// imgLabel.setImage(loadCountryIcon(locale)); +// +// // Goto button +// gridData = new GridData(); +// gridData.horizontalAlignment = GridData.END; +// gotoButton = new Button( +// labelComposite, SWT.ARROW | SWT.RIGHT); +// gotoButton.setToolTipText( +// RBEPlugin.getString("value.goto.tooltip")); //$NON-NLS-1$ +// gotoButton.setEnabled(false); +// gotoButton.addSelectionListener(new SelectionAdapter() { +// public void widgetSelected(SelectionEvent event) { +// ITextEditor editor = resourceManager.getSourceEditor( +// locale).getEditor(); +// Object activeEditor = +// editor.getSite().getPage().getActiveEditor(); +// if (activeEditor instanceof MessagesEditor) { +// ((MessagesEditor) activeEditor).setActivePage(locale); +// } +// } +// }); +// gotoButton.setLayoutData(gridData); +// } +// /** +// * Creates the text row. +// */ +// private void createTextRow() { +// textBox = new Text(this, SWT.MULTI | SWT.WRAP | +// SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); +// textBox.setEnabled(false); +// //Addition by Eric FETTWEIS +// //Note that this does not seem to work... It would however be usefull for +// arabic and some other languages +// textBox.setOrientation(getOrientation(locale)); +// +// GridData gridData = new GridData(); +// gridData.verticalAlignment = GridData.FILL; +// gridData.grabExcessVerticalSpace = true; +// gridData.horizontalAlignment = GridData.FILL; +// gridData.grabExcessHorizontalSpace = true; +// gridData.heightHint = UIUtils.getHeightInChars(textBox, 3); +// textBox.setLayoutData(gridData); +// textBox.addFocusListener(new FocusListener() { +// public void focusGained(FocusEvent event) { +// textBeforeUpdate = textBox.getText(); +// } +// public void focusLost(FocusEvent event) { +// updateBundleOnChanges(); +// } +// }); +// //TODO add a preference property listener and add/remove this listener +// textBox.addTraverseListener(new TraverseListener() { +// public void keyTraversed(TraverseEvent event) { +// if (!MsgEditorPreferences.getFieldTabInserts() +// && event.character == SWT.TAB) { +// event.doit = true; +// } +// } +// }); +// textBox.addKeyListener(new KeyAdapter() { +// public void keyReleased(KeyEvent event) { +// Text eventBox = (Text) event.widget; +// final ITextEditor editor = resourceManager.getSourceEditor( +// locale).getEditor(); +// // Text field has changed: make editor dirty if not already +// if (textBeforeUpdate != null +// && !textBeforeUpdate.equals(eventBox.getText())) { +// // Make the editor dirty if not already. If it is, +// // we wait until field focus lost (or save) to +// // update it completely. +// if (!editor.isDirty()) { +// int caretPosition = eventBox.getCaretPosition(); +// updateBundleOnChanges(); +// eventBox.setSelection(caretPosition); +// } +// //autoDetectRequiredFont(eventBox.getText()); +// } +// } +// }); +// // Eric Fettweis : new listener to automatically change the font +// textBox.addModifyListener(new ModifyListener() { +// +// public void modifyText(ModifyEvent e) { +// String text = textBox.getText(); +// Font f = textBox.getFont(); +// String fontName = getBestFont(f.getFontData()[0].getName(), text); +// if(fontName!=null){ +// f = getSWTFont(f, fontName); +// textBox.setFont(f); +// } +// } +// +// }); +// } +// +// +// +// /*default*/ void resetCommented() { +// if (commentedCheckbox.getSelection()) { +// commentedCheckbox.setToolTipText( +// RBEPlugin.getString("value.uncomment.tooltip"));//$NON-NLS-1$ +// textBox.setForeground( +// getDisplay().getSystemColor(SWT.COLOR_GRAY)); +// } else { +// commentedCheckbox.setToolTipText( +// RBEPlugin.getString("value.comment.tooltip"));//$NON-NLS-1$ +// textBox.setForeground(null); +// } +// } +// +// +// +// /** Additions by Eric FETTWEIS */ +// /*private void autoDetectRequiredFont(String value) { +// Font f = getFont(); +// FontData[] data = f.getFontData(); +// boolean resetFont = true; +// for (int i = 0; i < data.length; i++) { +// java.awt.Font test = new java.awt.Font(data[i].getName(), +// java.awt.Font.PLAIN, 12); +// if(test.canDisplayUpTo(value)==-1){ +// resetFont = false; +// break; +// } +// } +// if(resetFont){ +// String[] fonts = +// GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); +// for (int i = 0; i < fonts.length; i++) { +// java.awt.Font fnt = new java.awt.Font(fonts[i],java.awt.Font.PLAIN,12); +// if(fnt.canDisplayUpTo(value)==-1){ +// textBox.setFont(createFont(fonts[i])); +// break; +// } +// } +// } +// }*/ +// /** +// * Holds swt fonts used for the textBox. +// */ +// private Map swtFontCache = new HashMap(); +// +// /** +// * Gets a font by its name. The resulting font is build based on the baseFont +// parameter. +// * The font is retrieved from the swtFontCache, or created if needed. +// * @param baseFont the current font used to build the new one. +// * Only the name of the new font will differ fromm the original one. +// * @parama baseFont a font +// * @param name the new font name +// * @return a font with the same style and size as the original. +// */ +// private Font getSWTFont(Font baseFont, String name){ +// Font font = (Font) swtFontCache.get(name); +// if(font==null){ +// font = createFont(baseFont, getDisplay(), name); +// swtFontCache.put(name, font); +// } +// return font; +// } +// /** +// * Gets the name of the font which will be the best to display a String. +// * All installed fonts are searched. If a font can display the entire string, +// then it is retuned immediately. +// * Otherwise, the font returned is the one which can display properly the +// longest substring possible from the argument value. +// * @param baseFontName a font to be tested before any other. It will be the +// current font used by a widget. +// * @param value the string to be displayed. +// * @return a font name +// */ +// private static String getBestFont(String baseFontName, String value){ +// if(canFullyDisplay(baseFontName, value)) return baseFontName; +// String[] fonts = +// GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); +// String fontName=null; +// int currentScore = 0; +// for (int i = 0; i < fonts.length; i++) { +// int score = canDisplayUpTo(fonts[i], value); +// if(score==-1){//no need to loop further +// fontName=fonts[i]; +// break; +// } +// if(score>currentScore){ +// fontName=fonts[i]; +// currentScore = score; +// } +// } +// +// return fontName; +// } +// +// /** +// * A cache holding an instance of every AWT font tested. +// */ +// private static Map awtFontCache = new HashMap(); +// +// /** +// * Creates a variation from an original font, by changing the face name. +// * @param baseFont the original font +// * @param display the current display +// * @param name the new font face name +// * @return a new Font +// */ +// private static Font createFont(Font baseFont, Display display, String name){ +// FontData[] fontData = baseFont.getFontData(); +// for (int i = 0; i < fontData.length; i++) { +// fontData[i].setName(name); +// } +// return new Font(display, fontData); +// } +// /** +// * Can a font display correctly an entire string ? +// * @param fontName the font name +// * @param value the string to be displayed +// * @return +// */ +// private static boolean canFullyDisplay(String fontName, String value){ +// return canDisplayUpTo(fontName, value)==-1; +// } +// +// /** +// * Test the number of characters from a given String that a font can display +// correctly. +// * @param fontName the name of the font +// * @param value the value to be displayed +// * @return the number of characters that can be displayed, or -1 if the entire +// string can be displayed successfuly. +// * @see java.aw.Font#canDisplayUpTo(String) +// */ +// private static int canDisplayUpTo(String fontName, String value){ +// java.awt.Font font = getAWTFont(fontName); +// return font.canDisplayUpTo(value); +// } +// /** +// * Returns a cached or new AWT font by its name. +// * If the font needs to be created, its style will be Font.PLAIN and its size +// will be 12. +// * @param name teh font name +// * @return an AWT Font +// */ +// private static java.awt.Font getAWTFont(String name){ +// java.awt.Font font = (java.awt.Font) awtFontCache.get(name); +// if(font==null){ +// font = new java.awt.Font(name, java.awt.Font.PLAIN, 12); +// awtFontCache.put(name, font); +// } +// return font; +// } + +// } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/EntryLeftBanner.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/EntryLeftBanner.java index a32a9c9..c0e17bf 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/EntryLeftBanner.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/EntryLeftBanner.java @@ -41,7 +41,7 @@ public class EntryLeftBanner extends Composite { * @param keyTree * key tree */ - public EntryLeftBanner(Composite parent, final I18NEntry i18NEntry) { + public EntryLeftBanner(Composite parent, final AbstractI18NEntry i18NEntry) { super(parent, SWT.NONE); RowLayout layout = new RowLayout(); diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/EntryRightBanner.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/EntryRightBanner.java index e13feb7..e1981e7 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/EntryRightBanner.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/EntryRightBanner.java @@ -20,15 +20,17 @@ import java.util.Observer; import org.eclipse.babel.core.message.checks.IMessageCheck; import org.eclipse.babel.core.message.checks.internal.DuplicateValueCheck; import org.eclipse.babel.core.message.checks.internal.MissingValueCheck; +import org.eclipse.babel.editor.IMessagesEditorChangeListener; import org.eclipse.babel.editor.i18n.actions.ShowDuplicateAction; import org.eclipse.babel.editor.i18n.actions.ShowMissingAction; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.internal.MessagesEditorChangeAdapter; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; @@ -44,9 +46,19 @@ public class EntryRightBanner extends Composite { private Label warningIcon; private final Map actionByMarkerIds = new HashMap(); private final ToolBarManager toolBarMgr = new ToolBarManager(SWT.FLAT); - private final MessagesEditor editor; - private final I18NEntry i18nEntry; + private final AbstractMessagesEditor editor; + private final AbstractI18NEntry i18nEntry; private final Locale locale; + private final Observer observer = new Observer() { + public void update(Observable o, Object arg) { + updateMarkers(); + } + }; + private final IMessagesEditorChangeListener msgEditorChangeListener = new MessagesEditorChangeAdapter() { + public void selectedKeyChanged(String oldKey, String newKey) { + updateMarkers(); + } + }; /** * Constructor. @@ -56,7 +68,7 @@ public class EntryRightBanner extends Composite { * @param keyTree * key tree */ - public EntryRightBanner(Composite parent, final I18NEntry i18nEntry) { + public EntryRightBanner(Composite parent, final AbstractI18NEntry i18nEntry) { super(parent, SWT.NONE); this.i18nEntry = i18nEntry; this.locale = i18nEntry.getLocale(); @@ -82,17 +94,8 @@ public class EntryRightBanner extends Composite { toolBarMgr.createControl(this); toolBarMgr.update(true); - editor.addChangeListener(new MessagesEditorChangeAdapter() { - public void selectedKeyChanged(String oldKey, String newKey) { - updateMarkers(); - - } - }); - editor.getMarkers().addObserver(new Observer() { - public void update(Observable o, Object arg) { - updateMarkers(); - } - }); + editor.addChangeListener(msgEditorChangeListener); + editor.getMarkers().addObserver(observer); } /** @@ -100,8 +103,13 @@ public class EntryRightBanner extends Composite { * @param colon */ private void updateMarkers() { - PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + Display display = toolBarMgr.getControl().getDisplay(); + // [RAP] only update markers, which belong to this UIThread + if (display.equals(Display.getCurrent()) && !isDisposed()) { + display.asyncExec(new Runnable() { public void run() { + if (isDisposed()) + return; // if (!PlatformUI.getWorkbench().getDisplay().isDisposed() // && !editor.getMarkerManager().isDisposed()) { boolean isMarked = false; @@ -129,6 +137,7 @@ public class EntryRightBanner extends Composite { } // } }); + } } @@ -143,4 +152,10 @@ public class EntryRightBanner extends Composite { return null; } + @Override + public void dispose() { + editor.removeChangeListener(msgEditorChangeListener); + editor.getMarkers().deleteObserver(observer); + super.dispose(); + } } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/I18NEntry.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/I18NEntry.java deleted file mode 100644 index 79e865c..0000000 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/I18NEntry.java +++ /dev/null @@ -1,832 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Pascal Essiembre. - * 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: - * Pascal Essiembre - initial API and implementation - * Alexej Strelzow - updateKey - ******************************************************************************/ -package org.eclipse.babel.editor.i18n; - -import java.util.Locale; - -import org.eclipse.babel.core.message.IMessage; -import org.eclipse.babel.core.message.IMessagesBundle; -import org.eclipse.babel.core.message.IMessagesBundleGroup; -import org.eclipse.babel.core.message.internal.Message; -import org.eclipse.babel.core.message.manager.RBManager; -import org.eclipse.babel.core.util.BabelUtils; -import org.eclipse.babel.editor.internal.MessagesEditor; -import org.eclipse.babel.editor.internal.MessagesEditorChangeAdapter; -import org.eclipse.babel.editor.util.UIUtils; -import org.eclipse.babel.editor.widgets.NullableText; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CBanner; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.editors.text.TextEditor; - -/** - * Tree for displaying and navigating through resource bundle keys. - * - * @author Pascal Essiembre - */ -public class I18NEntry extends Composite { - - private final MessagesEditor editor; - private final String bundleGroupId; - private final String projectName; - private final Locale locale; - - private boolean expanded = true; - private NullableText textBox; - private CBanner banner; - private String focusGainedText; - - /** - * Constructor. - * - * @param parent - * parent composite - * @param keyTree - * key tree - */ - public I18NEntry(Composite parent, final MessagesEditor editor, - final Locale locale) { - super(parent, SWT.NONE); - this.editor = editor; - this.locale = locale; - this.bundleGroupId = editor.getBundleGroup().getResourceBundleId(); - this.projectName = editor.getBundleGroup().getProjectName(); - - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.horizontalSpacing = 0; - gridLayout.verticalSpacing = 0; - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - - setLayout(gridLayout); - GridData gd = new GridData(GridData.FILL_BOTH); - // gd.heightHint = 80; - setLayoutData(gd); - - banner = new CBanner(this, SWT.NONE); - - Control bannerLeft = new EntryLeftBanner(banner, this);// createBannerLeft(banner); - Control bannerRight = new EntryRightBanner(banner, this);// createBannerRight(banner); - - GridData gridData = new GridData(); - gridData.horizontalAlignment = GridData.FILL; - gridData.grabExcessHorizontalSpace = true; - - banner.setLeft(bannerLeft); - banner.setRight(bannerRight); - // banner.setRightWidth(300); - banner.setSimple(false); - banner.setLayoutData(gridData); - - createTextbox(); - - } - - public MessagesEditor getResourceBundleEditor() { - return editor; - } - - public void setExpanded(boolean expanded) { - this.expanded = expanded; - textBox.setVisible(expanded); - - if (expanded) { - GridData gridData = new GridData(); - gridData.verticalAlignment = GridData.FILL; - gridData.grabExcessVerticalSpace = true; - gridData.horizontalAlignment = GridData.FILL; - gridData.grabExcessHorizontalSpace = true; - gridData.heightHint = UIUtils.getHeightInChars(textBox, 3); - textBox.setLayoutData(gridData); - - GridData gd = new GridData(GridData.FILL_BOTH); - // gd.heightHint = 80; - setLayoutData(gd); - getParent().pack(); - getParent().layout(true, true); - - } else { - GridData gridData = ((GridData) textBox.getLayoutData()); - gridData.verticalAlignment = GridData.BEGINNING; - gridData.grabExcessVerticalSpace = false; - textBox.setLayoutData(gridData); - - gridData = (GridData) getLayoutData(); - gridData.heightHint = banner.getSize().y; - gridData.verticalAlignment = GridData.BEGINNING; - gridData.grabExcessVerticalSpace = false; - setLayoutData(gridData); - - getParent().pack(); - getParent().layout(true, true); - } - - } - - public boolean getExpanded() { - return expanded; - } - - public Locale getLocale() { - return locale; - } - - public boolean isEditable() { - IMessagesBundleGroup messagesBundleGroup = RBManager.getInstance( - projectName).getMessagesBundleGroup(bundleGroupId); - IMessagesBundle bundle = messagesBundleGroup.getMessagesBundle(locale); - return ((TextEditor) bundle.getResource().getSource()).isEditable(); - } - - public String getResourceLocationLabel() { - IMessagesBundleGroup messagesBundleGroup = RBManager.getInstance( - projectName).getMessagesBundleGroup(bundleGroupId); - IMessagesBundle bundle = messagesBundleGroup.getMessagesBundle(locale); - return bundle.getResource().getResourceLocationLabel(); - } - - // /*default*/ Text getTextBox() { - // return textBox; - // } - - /** - * @param editor - * @param locale - */ - private void createTextbox() { - textBox = new NullableText(this, SWT.MULTI | SWT.WRAP | SWT.H_SCROLL - | SWT.V_SCROLL | SWT.BORDER); - textBox.setEnabled(false); - textBox.setOrientation(UIUtils.getOrientation(locale)); - - textBox.addFocusListener(new FocusListener() { - public void focusGained(FocusEvent event) { - focusGainedText = textBox.getText(); - } - - public void focusLost(FocusEvent event) { - updateModel(); - } - }); - // -- Setup read-only textbox -- - // that is the case if the corresponding editor is itself read-only. - // it happens when the corresponding resource is defined inside the - // target-platform for example - textBox.setEditable(isEditable()); - - // --- Handle tab key --- - // TODO add a preference property listener and add/remove this listener - textBox.addTraverseListener(new TraverseListener() { - public void keyTraversed(TraverseEvent event) { - // if (!MsgEditorPreferences.getFieldTabInserts() - // && event.character == SWT.TAB) { - // event.doit = true; - // } - } - }); - - // Handle dirtyness - textBox.addKeyListener(new KeyAdapter() { - public void keyReleased(KeyEvent event) { - // Text field has changed: make editor dirty if not already - if (!BabelUtils.equals(focusGainedText, textBox.getText())) { - // Make the editor dirty if not already. If it is, - // we wait until field focus lost (or save) to - // update it completely. - if (!editor.isDirty()) { - // textEditor.isDirty(); - updateModel(); - // int caretPosition = eventBox.getCaretPosition(); - // updateBundleOnChanges(); - // eventBox.setSelection(caretPosition); - } - // autoDetectRequiredFont(eventBox.getText()); - } - } - }); - // // Eric Fettweis : new listener to automatically change the font - // textBox.addModifyListener(new ModifyListener() { - // - // public void modifyText(ModifyEvent e) { - // String text = textBox.getText(); - // Font f = textBox.getFont(); - // String fontName = getBestFont(f.getFontData()[0].getName(), text); - // if(fontName!=null){ - // f = getSWTFont(f, fontName); - // textBox.setFont(f); - // } - // } - // - // }); - - editor.addChangeListener(new MessagesEditorChangeAdapter() { - public void selectedKeyChanged(String oldKey, String newKey) { - updateKey(newKey); - } - }); - - } - - void updateKey(String key) { - IMessagesBundleGroup messagesBundleGroup = RBManager.getInstance( - projectName).getMessagesBundleGroup(bundleGroupId); - boolean isKey = key != null && messagesBundleGroup.isMessageKey(key); - textBox.setEnabled(isKey); - if (isKey) { - IMessage entry = messagesBundleGroup.getMessage(key, locale); - if (entry == null || entry.getValue() == null) { - textBox.setText(null); - // commentedCheckbox.setSelection(false); - } else { - // commentedCheckbox.setSelection(bundleEntry.isCommented()); - textBox.setText(entry.getValue()); - } - } else { - textBox.setText(null); - } - } - - private void updateModel() { - if (editor.getSelectedKey() != null) { - if (!BabelUtils.equals(focusGainedText, textBox.getText())) { - IMessagesBundleGroup messagesBundleGroup = RBManager - .getInstance(projectName).getMessagesBundleGroup( - bundleGroupId); - String key = editor.getSelectedKey(); - IMessage entry = messagesBundleGroup.getMessage(key, locale); - if (entry == null) { - entry = new Message(key, locale); - IMessagesBundle messagesBundle = messagesBundleGroup - .getMessagesBundle(locale); - if (messagesBundle != null) { - messagesBundle.addMessage(entry); - } - } - entry.setText(textBox.getText()); - } - } - } -} - -// TODO Grab and Apply font fix: -// /** -// * Represents a data entry section for a bundle entry. -// * @author Pascal Essiembre (essiembre@users.sourceforge.net) -// * @version $Author: pessiembr $ $Revision: 1.3 $ $Date: 2008/01/11 04:15:15 $ -// */ -// public class BundleEntryComposite extends Composite { -// -// /*default*/ final ResourceManager resourceManager; -// /*default*/ final Locale locale; -// private final Font boldFont; -// private final Font smallFont; -// -// /*default*/ Text textBox; -// private Button commentedCheckbox; -// private Button gotoButton; -// private Button duplButton; -// private Button simButton; -// -// /*default*/ String activeKey; -// /*default*/ String textBeforeUpdate; -// -// /*default*/ DuplicateValuesVisitor duplVisitor; -// /*default*/ SimilarValuesVisitor similarVisitor; -// -// -// /** -// * Constructor. -// * @param parent parent composite -// * @param resourceManager resource manager -// * @param locale locale for this bundle entry -// */ -// public BundleEntryComposite( -// final Composite parent, -// final ResourceManager resourceManager, -// final Locale locale) { -// -// super(parent, SWT.NONE); -// this.resourceManager = resourceManager; -// this.locale = locale; -// -// this.boldFont = UIUtils.createFont(this, SWT.BOLD, 0); -// this.smallFont = UIUtils.createFont(SWT.NONE, -1); -// -// GridLayout gridLayout = new GridLayout(1, false); -// gridLayout.horizontalSpacing = 0; -// gridLayout.verticalSpacing = 2; -// gridLayout.marginWidth = 0; -// gridLayout.marginHeight = 0; -// -// createLabelRow(); -// createTextRow(); -// -// setLayout(gridLayout); -// GridData gd = new GridData(GridData.FILL_BOTH); -// gd.heightHint = 80; -// setLayoutData(gd); -// -// -// } -// -// /** -// * Update bundles if the value of the active key changed. -// */ -// public void updateBundleOnChanges(){ -// if (activeKey != null) { -// MessagesBundleGroup messagesBundleGroup = resourceManager.getBundleGroup(); -// Message entry = messagesBundleGroup.getBundleEntry(locale, activeKey); -// boolean commentedSelected = commentedCheckbox.getSelection(); -// String textBoxValue = textBox.getText(); -// -// if (entry == null || !textBoxValue.equals(entry.getValue()) -// || entry.isCommented() != commentedSelected) { -// String comment = null; -// if (entry != null) { -// comment = entry.getComment(); -// } -// messagesBundleGroup.addBundleEntry(locale, new Message( -// activeKey, -// textBox.getText(), -// comment, -// commentedSelected)); -// } -// } -// } -// -// /** -// * @see org.eclipse.swt.widgets.Widget#dispose() -// */ -// public void dispose() { -// super.dispose(); -// boldFont.dispose(); -// smallFont.dispose(); -// -// //Addition by Eric Fettweis -// for(Iterator it = swtFontCache.values().iterator();it.hasNext();){ -// Font font = (Font) it.next(); -// font.dispose(); -// } -// swtFontCache.clear(); -// } -// -// /** -// * Gets the locale associated with this bundle entry -// * @return a locale -// */ -// public Locale getLocale() { -// return locale; -// } -// -// /** -// * Sets a selection in the text box. -// * @param start starting position to select -// * @param end ending position to select -// */ -// public void setTextSelection(int start, int end) { -// textBox.setSelection(start, end); -// } -// -// /** -// * Refreshes the text field value with value matching given key. -// * @param key key used to grab value -// */ -// public void refresh(String key) { -// activeKey = key; -// MessagesBundleGroup messagesBundleGroup = resourceManager.getBundleGroup(); -// if (key != null && messagesBundleGroup.isKey(key)) { -// Message bundleEntry = messagesBundleGroup.getBundleEntry(locale, key); -// SourceEditor sourceEditor = resourceManager.getSourceEditor(locale); -// if (bundleEntry == null) { -// textBox.setText(""); //$NON-NLS-1$ -// commentedCheckbox.setSelection(false); -// } else { -// commentedCheckbox.setSelection(bundleEntry.isCommented()); -// String value = bundleEntry.getValue(); -// textBox.setText(value); -// } -// commentedCheckbox.setEnabled(!sourceEditor.isReadOnly()); -// textBox.setEnabled(!sourceEditor.isReadOnly()); -// gotoButton.setEnabled(true); -// if (MsgEditorPreferences.getReportDuplicateValues()) { -// findDuplicates(bundleEntry); -// } else { -// duplVisitor = null; -// } -// if (MsgEditorPreferences.getReportSimilarValues()) { -// findSimilar(bundleEntry); -// } else { -// similarVisitor = null; -// } -// } else { -// commentedCheckbox.setSelection(false); -// commentedCheckbox.setEnabled(false); -// textBox.setText(""); //$NON-NLS-1$ -// textBox.setEnabled(false); -// gotoButton.setEnabled(false); -// duplButton.setVisible(false); -// simButton.setVisible(false); -// } -// resetCommented(); -// } -// -// private void findSimilar(Message bundleEntry) { -// ProximityAnalyzer analyzer; -// if (MsgEditorPreferences.getReportSimilarValuesLevensthein()) { -// analyzer = LevenshteinDistanceAnalyzer.getInstance(); -// } else { -// analyzer = WordCountAnalyzer.getInstance(); -// } -// MessagesBundleGroup messagesBundleGroup = resourceManager.getBundleGroup(); -// if (similarVisitor == null) { -// similarVisitor = new SimilarValuesVisitor(); -// } -// similarVisitor.setProximityAnalyzer(analyzer); -// similarVisitor.clear(); -// messagesBundleGroup.getBundle(locale).accept(similarVisitor, bundleEntry); -// if (duplVisitor != null) { -// similarVisitor.getSimilars().removeAll(duplVisitor.getDuplicates()); -// } -// simButton.setVisible(similarVisitor.getSimilars().size() > 0); -// } -// -// private void findDuplicates(Message bundleEntry) { -// MessagesBundleGroup messagesBundleGroup = resourceManager.getBundleGroup(); -// if (duplVisitor == null) { -// duplVisitor = new DuplicateValuesVisitor(); -// } -// duplVisitor.clear(); -// messagesBundleGroup.getBundle(locale).accept(duplVisitor, bundleEntry); -// duplButton.setVisible(duplVisitor.getDuplicates().size() > 0); -// } -// -// -// /** -// * Creates the text field label, icon, and commented check box. -// */ -// private void createLabelRow() { -// Composite labelComposite = new Composite(this, SWT.NONE); -// GridLayout gridLayout = new GridLayout(); -// gridLayout.numColumns = 6; -// gridLayout.horizontalSpacing = 5; -// gridLayout.verticalSpacing = 0; -// gridLayout.marginWidth = 0; -// gridLayout.marginHeight = 0; -// labelComposite.setLayout(gridLayout); -// labelComposite.setLayoutData( -// new GridData(GridData.FILL_HORIZONTAL)); -// -// // Locale text -// Label txtLabel = new Label(labelComposite, SWT.NONE); -// txtLabel.setText(" " + //$NON-NLS-1$ -// UIUtils.getDisplayName(locale) + " "); //$NON-NLS-1$ -// txtLabel.setFont(boldFont); -// GridData gridData = new GridData(); -// -// // Similar button -// gridData = new GridData(); -// gridData.horizontalAlignment = GridData.END; -// gridData.grabExcessHorizontalSpace = true; -// simButton = new Button(labelComposite, SWT.PUSH | SWT.FLAT); -// simButton.setImage(UIUtils.getImage("similar.gif")); //$NON-NLS-1$ -// simButton.setLayoutData(gridData); -// simButton.setVisible(false); -// simButton.setToolTipText( -// RBEPlugin.getString("value.similar.tooltip")); //$NON-NLS-1$ -// simButton.addSelectionListener(new SelectionAdapter() { -// public void widgetSelected(SelectionEvent event) { -// String head = RBEPlugin.getString( -// "dialog.similar.head"); //$NON-NLS-1$ -// String body = RBEPlugin.getString( -// "dialog.similar.body", activeKey, //$NON-NLS-1$ -// UIUtils.getDisplayName(locale)); -// body += "\n\n"; //$NON-NLS-1$ -// for (Iterator iter = similarVisitor.getSimilars().iterator(); -// iter.hasNext();) { -// body += " " //$NON-NLS-1$ -// + ((Message) iter.next()).getKey() -// + "\n"; //$NON-NLS-1$ -// } -// MessageDialog.openInformation(getShell(), head, body); -// } -// }); -// -// // Duplicate button -// gridData = new GridData(); -// gridData.horizontalAlignment = GridData.END; -// duplButton = new Button(labelComposite, SWT.PUSH | SWT.FLAT); -// duplButton.setImage(UIUtils.getImage("duplicate.gif")); //$NON-NLS-1$ -// duplButton.setLayoutData(gridData); -// duplButton.setVisible(false); -// duplButton.setToolTipText( -// RBEPlugin.getString("value.duplicate.tooltip")); //$NON-NLS-1$ -// -// duplButton.addSelectionListener(new SelectionAdapter() { -// public void widgetSelected(SelectionEvent event) { -// String head = RBEPlugin.getString( -// "dialog.identical.head"); //$NON-NLS-1$ -// String body = RBEPlugin.getString( -// "dialog.identical.body", activeKey, //$NON-NLS-1$ -// UIUtils.getDisplayName(locale)); -// body += "\n\n"; //$NON-NLS-1$ -// for (Iterator iter = duplVisitor.getDuplicates().iterator(); -// iter.hasNext();) { -// body += " " //$NON-NLS-1$ -// + ((Message) iter.next()).getKey() -// + "\n"; //$NON-NLS-1$ -// } -// MessageDialog.openInformation(getShell(), head, body); -// } -// }); -// -// // Commented checkbox -// gridData = new GridData(); -// gridData.horizontalAlignment = GridData.END; -// //gridData.grabExcessHorizontalSpace = true; -// commentedCheckbox = new Button( -// labelComposite, SWT.CHECK); -// commentedCheckbox.setText("#"); //$NON-NLS-1$ -// commentedCheckbox.setFont(smallFont); -// commentedCheckbox.setLayoutData(gridData); -// commentedCheckbox.addSelectionListener(new SelectionAdapter() { -// public void widgetSelected(SelectionEvent event) { -// resetCommented(); -// updateBundleOnChanges(); -// } -// }); -// commentedCheckbox.setEnabled(false); -// -// // Country flag -// gridData = new GridData(); -// gridData.horizontalAlignment = GridData.END; -// Label imgLabel = new Label(labelComposite, SWT.NONE); -// imgLabel.setLayoutData(gridData); -// imgLabel.setImage(loadCountryIcon(locale)); -// -// // Goto button -// gridData = new GridData(); -// gridData.horizontalAlignment = GridData.END; -// gotoButton = new Button( -// labelComposite, SWT.ARROW | SWT.RIGHT); -// gotoButton.setToolTipText( -// RBEPlugin.getString("value.goto.tooltip")); //$NON-NLS-1$ -// gotoButton.setEnabled(false); -// gotoButton.addSelectionListener(new SelectionAdapter() { -// public void widgetSelected(SelectionEvent event) { -// ITextEditor editor = resourceManager.getSourceEditor( -// locale).getEditor(); -// Object activeEditor = -// editor.getSite().getPage().getActiveEditor(); -// if (activeEditor instanceof MessagesEditor) { -// ((MessagesEditor) activeEditor).setActivePage(locale); -// } -// } -// }); -// gotoButton.setLayoutData(gridData); -// } -// /** -// * Creates the text row. -// */ -// private void createTextRow() { -// textBox = new Text(this, SWT.MULTI | SWT.WRAP | -// SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); -// textBox.setEnabled(false); -// //Addition by Eric FETTWEIS -// //Note that this does not seem to work... It would however be usefull for -// arabic and some other languages -// textBox.setOrientation(getOrientation(locale)); -// -// GridData gridData = new GridData(); -// gridData.verticalAlignment = GridData.FILL; -// gridData.grabExcessVerticalSpace = true; -// gridData.horizontalAlignment = GridData.FILL; -// gridData.grabExcessHorizontalSpace = true; -// gridData.heightHint = UIUtils.getHeightInChars(textBox, 3); -// textBox.setLayoutData(gridData); -// textBox.addFocusListener(new FocusListener() { -// public void focusGained(FocusEvent event) { -// textBeforeUpdate = textBox.getText(); -// } -// public void focusLost(FocusEvent event) { -// updateBundleOnChanges(); -// } -// }); -// //TODO add a preference property listener and add/remove this listener -// textBox.addTraverseListener(new TraverseListener() { -// public void keyTraversed(TraverseEvent event) { -// if (!MsgEditorPreferences.getFieldTabInserts() -// && event.character == SWT.TAB) { -// event.doit = true; -// } -// } -// }); -// textBox.addKeyListener(new KeyAdapter() { -// public void keyReleased(KeyEvent event) { -// Text eventBox = (Text) event.widget; -// final ITextEditor editor = resourceManager.getSourceEditor( -// locale).getEditor(); -// // Text field has changed: make editor dirty if not already -// if (textBeforeUpdate != null -// && !textBeforeUpdate.equals(eventBox.getText())) { -// // Make the editor dirty if not already. If it is, -// // we wait until field focus lost (or save) to -// // update it completely. -// if (!editor.isDirty()) { -// int caretPosition = eventBox.getCaretPosition(); -// updateBundleOnChanges(); -// eventBox.setSelection(caretPosition); -// } -// //autoDetectRequiredFont(eventBox.getText()); -// } -// } -// }); -// // Eric Fettweis : new listener to automatically change the font -// textBox.addModifyListener(new ModifyListener() { -// -// public void modifyText(ModifyEvent e) { -// String text = textBox.getText(); -// Font f = textBox.getFont(); -// String fontName = getBestFont(f.getFontData()[0].getName(), text); -// if(fontName!=null){ -// f = getSWTFont(f, fontName); -// textBox.setFont(f); -// } -// } -// -// }); -// } -// -// -// -// /*default*/ void resetCommented() { -// if (commentedCheckbox.getSelection()) { -// commentedCheckbox.setToolTipText( -// RBEPlugin.getString("value.uncomment.tooltip"));//$NON-NLS-1$ -// textBox.setForeground( -// getDisplay().getSystemColor(SWT.COLOR_GRAY)); -// } else { -// commentedCheckbox.setToolTipText( -// RBEPlugin.getString("value.comment.tooltip"));//$NON-NLS-1$ -// textBox.setForeground(null); -// } -// } -// -// -// -// /** Additions by Eric FETTWEIS */ -// /*private void autoDetectRequiredFont(String value) { -// Font f = getFont(); -// FontData[] data = f.getFontData(); -// boolean resetFont = true; -// for (int i = 0; i < data.length; i++) { -// java.awt.Font test = new java.awt.Font(data[i].getName(), -// java.awt.Font.PLAIN, 12); -// if(test.canDisplayUpTo(value)==-1){ -// resetFont = false; -// break; -// } -// } -// if(resetFont){ -// String[] fonts = -// GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); -// for (int i = 0; i < fonts.length; i++) { -// java.awt.Font fnt = new java.awt.Font(fonts[i],java.awt.Font.PLAIN,12); -// if(fnt.canDisplayUpTo(value)==-1){ -// textBox.setFont(createFont(fonts[i])); -// break; -// } -// } -// } -// }*/ -// /** -// * Holds swt fonts used for the textBox. -// */ -// private Map swtFontCache = new HashMap(); -// -// /** -// * Gets a font by its name. The resulting font is build based on the baseFont -// parameter. -// * The font is retrieved from the swtFontCache, or created if needed. -// * @param baseFont the current font used to build the new one. -// * Only the name of the new font will differ fromm the original one. -// * @parama baseFont a font -// * @param name the new font name -// * @return a font with the same style and size as the original. -// */ -// private Font getSWTFont(Font baseFont, String name){ -// Font font = (Font) swtFontCache.get(name); -// if(font==null){ -// font = createFont(baseFont, getDisplay(), name); -// swtFontCache.put(name, font); -// } -// return font; -// } -// /** -// * Gets the name of the font which will be the best to display a String. -// * All installed fonts are searched. If a font can display the entire string, -// then it is retuned immediately. -// * Otherwise, the font returned is the one which can display properly the -// longest substring possible from the argument value. -// * @param baseFontName a font to be tested before any other. It will be the -// current font used by a widget. -// * @param value the string to be displayed. -// * @return a font name -// */ -// private static String getBestFont(String baseFontName, String value){ -// if(canFullyDisplay(baseFontName, value)) return baseFontName; -// String[] fonts = -// GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); -// String fontName=null; -// int currentScore = 0; -// for (int i = 0; i < fonts.length; i++) { -// int score = canDisplayUpTo(fonts[i], value); -// if(score==-1){//no need to loop further -// fontName=fonts[i]; -// break; -// } -// if(score>currentScore){ -// fontName=fonts[i]; -// currentScore = score; -// } -// } -// -// return fontName; -// } -// -// /** -// * A cache holding an instance of every AWT font tested. -// */ -// private static Map awtFontCache = new HashMap(); -// -// /** -// * Creates a variation from an original font, by changing the face name. -// * @param baseFont the original font -// * @param display the current display -// * @param name the new font face name -// * @return a new Font -// */ -// private static Font createFont(Font baseFont, Display display, String name){ -// FontData[] fontData = baseFont.getFontData(); -// for (int i = 0; i < fontData.length; i++) { -// fontData[i].setName(name); -// } -// return new Font(display, fontData); -// } -// /** -// * Can a font display correctly an entire string ? -// * @param fontName the font name -// * @param value the string to be displayed -// * @return -// */ -// private static boolean canFullyDisplay(String fontName, String value){ -// return canDisplayUpTo(fontName, value)==-1; -// } -// -// /** -// * Test the number of characters from a given String that a font can display -// correctly. -// * @param fontName the name of the font -// * @param value the value to be displayed -// * @return the number of characters that can be displayed, or -1 if the entire -// string can be displayed successfuly. -// * @see java.aw.Font#canDisplayUpTo(String) -// */ -// private static int canDisplayUpTo(String fontName, String value){ -// java.awt.Font font = getAWTFont(fontName); -// return font.canDisplayUpTo(value); -// } -// /** -// * Returns a cached or new AWT font by its name. -// * If the font needs to be created, its style will be Font.PLAIN and its size -// will be 12. -// * @param name teh font name -// * @return an AWT Font -// */ -// private static java.awt.Font getAWTFont(String name){ -// java.awt.Font font = (java.awt.Font) awtFontCache.get(name); -// if(font==null){ -// font = new java.awt.Font(name, java.awt.Font.PLAIN, 12); -// awtFontCache.put(name, font); -// } -// return font; -// } - -// } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/I18NPage.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/I18NPage.java index c6a8bf1..ae4ab20 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/I18NPage.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/I18NPage.java @@ -11,6 +11,7 @@ ******************************************************************************/ package org.eclipse.babel.editor.i18n; +import java.lang.reflect.Constructor; import java.util.Collection; import java.util.HashMap; import java.util.Locale; @@ -20,8 +21,9 @@ import org.eclipse.babel.core.message.IMessagesBundle; import org.eclipse.babel.core.message.manager.IMessagesEditorListener; import org.eclipse.babel.core.message.manager.RBManager; import org.eclipse.babel.editor.IMessagesEditorChangeListener; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.internal.MessagesEditorChangeAdapter; +import org.eclipse.babel.editor.tree.actions.AbstractRenameKeyAction; import org.eclipse.babel.editor.util.UIUtils; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -31,8 +33,10 @@ import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IWorkbenchPart; @@ -47,10 +51,10 @@ public class I18NPage extends ScrolledComposite implements ISelectionProvider { /** Minimum height of text fields. */ private static final int TEXT_MIN_HEIGHT = 90; - private final MessagesEditor editor; - private final SideNavComposite keysComposite; + protected final AbstractMessagesEditor editor; + protected final SideNavComposite keysComposite; private final Composite valuesComposite; - private final Map entryComposites = new HashMap(); + private final Map entryComposites = new HashMap(); private Composite entriesComposite; // private Composite parent; @@ -69,7 +73,8 @@ public class I18NPage extends ScrolledComposite implements ISelectionProvider { * @param resourceMediator * resource manager */ - public I18NPage(Composite parent, int style, final MessagesEditor editor) { + public I18NPage(Composite parent, int style, + final AbstractMessagesEditor editor) { super(parent, style); this.editor = editor; sashForm = new SashForm(this, SWT.SMOOTH); @@ -127,13 +132,21 @@ public class I18NPage extends ScrolledComposite implements ISelectionProvider { } public void onResourceChanged(IMessagesBundle bundle) { - I18NEntry i18nEntry = entryComposites.get(bundle.getLocale()); + // [RAP] only update tree, which belongs to this UIThread + if (!keysComposite.isDisposed()) { + Display display = keysComposite.getTreeViewer().getTree() + .getDisplay(); + if (display.equals(Display.getCurrent())) { + AbstractI18NEntry i18nEntry = entryComposites.get(bundle + .getLocale()); if (i18nEntry != null && !getSelection().isEmpty()) { i18nEntry.updateKey(String .valueOf(((IStructuredSelection) getSelection()) .getFirstElement())); } } + } + } }); } @@ -181,7 +194,7 @@ public class I18NPage extends ScrolledComposite implements ISelectionProvider { locales = UIUtils.filterLocales(locales); for (int i = 0; i < locales.length; i++) { Locale locale = locales[i]; - addI18NEntry(editor, locale); + addI18NEntry(locale); } editor.addChangeListener(new MessagesEditorChangeAdapter() { @@ -195,17 +208,35 @@ public class I18NPage extends ScrolledComposite implements ISelectionProvider { return scrolledComposite; } - public void addI18NEntry(MessagesEditor editor, Locale locale) { - I18NEntry i18NEntry = new I18NEntry(entriesComposite, editor, locale); + public void addI18NEntry(Locale locale) { + AbstractI18NEntry i18NEntry = null; + try { + Class clazz = Class.forName(AbstractI18NEntry.INSTANCE_CLASS); + Constructor cons = clazz.getConstructor(Composite.class, + AbstractMessagesEditor.class, Locale.class); + i18NEntry = (AbstractI18NEntry) cons.newInstance(entriesComposite, + editor, locale); + } catch (Exception e) { + e.printStackTrace(); + } // entryComposite.addFocusListener(localBehaviour); entryComposites.put(locale, i18NEntry); entriesComposite.layout(); } + public void removeI18NEntry(Locale locale) { + AbstractI18NEntry i18NEntry = entryComposites.get(locale); + if (i18NEntry != null) { + i18NEntry.dispose(); + entryComposites.remove(locale); + entriesComposite.layout(); + } + } + public void selectLocale(Locale locale) { Collection locales = entryComposites.keySet(); for (Locale entryLocale : locales) { - I18NEntry entry = entryComposites.get(entryLocale); + AbstractI18NEntry entry = entryComposites.get(entryLocale); // TODO add equivalent method on entry composite // Text textBox = entry.getTextBox(); @@ -239,4 +270,26 @@ public class I18NPage extends ScrolledComposite implements ISelectionProvider { public TreeViewer getTreeViewer() { return keysComposite.getTreeViewer(); } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + for (AbstractI18NEntry entry : entryComposites.values()) + entry.setEnabled(enabled); + } + + public void setEnabled(boolean enabled, Locale locale) { + // super.setEnabled(enabled); + for (AbstractI18NEntry entry : entryComposites.values()) { + if (locale == entry.getLocale() + || (locale != null && locale.equals(entry.getLocale()))) { + entry.setEnabled(enabled); + break; + } + } + } + + public SideNavTextBoxComposite getSidNavTextBoxComposite() { + return keysComposite.getSidNavTextBoxComposite(); + } } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/SideNavComposite.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/SideNavComposite.java index a71649e..86b9265 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/SideNavComposite.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/SideNavComposite.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.eclipse.babel.editor.i18n; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.tree.actions.CollapseAllAction; import org.eclipse.babel.editor.tree.actions.ExpandAllAction; import org.eclipse.babel.editor.tree.actions.FlatModelAction; @@ -35,7 +35,9 @@ public class SideNavComposite extends Composite { /** Key Tree Viewer. */ private TreeViewer treeViewer; - private MessagesEditor editor; + private AbstractMessagesEditor editor; + + private SideNavTextBoxComposite textBoxComp; /** * Constructor. @@ -45,7 +47,8 @@ public class SideNavComposite extends Composite { * @param keyTree * key tree */ - public SideNavComposite(Composite parent, final MessagesEditor editor) { + public SideNavComposite(Composite parent, + final AbstractMessagesEditor editor) { super(parent, SWT.BORDER); this.editor = editor; @@ -77,7 +80,7 @@ public class SideNavComposite extends Composite { // createTopSection(); createKeyTree(); - new SideNavTextBoxComposite(this, editor); + textBoxComp = new SideNavTextBoxComposite(this, editor); } // private void initListener() { @@ -128,4 +131,7 @@ public class SideNavComposite extends Composite { } + public SideNavTextBoxComposite getSidNavTextBoxComposite() { + return textBoxComp; + } } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/SideNavTextBoxComposite.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/SideNavTextBoxComposite.java index 15b5163..b5cdae1 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/SideNavTextBoxComposite.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/SideNavTextBoxComposite.java @@ -12,7 +12,7 @@ package org.eclipse.babel.editor.i18n; import org.eclipse.babel.core.message.tree.IKeyTreeNode; import org.eclipse.babel.core.message.tree.visitor.NodePathRegexVisitor; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.internal.MessagesEditorChangeAdapter; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.swt.SWT; @@ -40,8 +40,8 @@ public class SideNavTextBoxComposite extends Composite { /** Text box to add a new key. */ private Text addTextBox; - - private MessagesEditor editor; + private Button addButton; + private AbstractMessagesEditor editor; /** * Constructor. @@ -51,7 +51,8 @@ public class SideNavTextBoxComposite extends Composite { * @param keyTree * key tree */ - public SideNavTextBoxComposite(Composite parent, final MessagesEditor editor) { + public SideNavTextBoxComposite(Composite parent, + final AbstractMessagesEditor editor) { super(parent, SWT.NONE); this.editor = editor; @@ -76,7 +77,7 @@ public class SideNavTextBoxComposite extends Composite { addTextBox.setLayoutData(gridData); // Add button - final Button addButton = new Button(this, SWT.PUSH); + addButton = new Button(this, SWT.PUSH); addButton.setText(MessagesEditorPlugin.getString("key.add")); //$NON-NLS-1$ addButton.setEnabled(false); addButton.addSelectionListener(new SelectionAdapter() { @@ -126,4 +127,10 @@ public class SideNavTextBoxComposite extends Composite { private boolean isNewKey(String key) { return !editor.getBundleGroup().isMessageKey(key) && key.length() > 0; } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + addButton.setEnabled(enabled); + } } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/actions/FoldingAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/actions/FoldingAction.java index 00cb990..f32e4db 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/actions/FoldingAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/i18n/actions/FoldingAction.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.eclipse.babel.editor.i18n.actions; -import org.eclipse.babel.editor.i18n.I18NEntry; +import org.eclipse.babel.editor.i18n.AbstractI18NEntry; import org.eclipse.babel.editor.util.UIUtils; import org.eclipse.jface.action.Action; @@ -20,13 +20,13 @@ import org.eclipse.jface.action.Action; */ public class FoldingAction extends Action { - private final I18NEntry i18NEntry; + private final AbstractI18NEntry i18NEntry; private boolean expanded; /** * */ - public FoldingAction(I18NEntry i18NEntry) { + public FoldingAction(AbstractI18NEntry i18NEntry) { super(); this.i18NEntry = i18NEntry; this.expanded = i18NEntry.getExpanded(); diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/AbstractMessagesEditor.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/AbstractMessagesEditor.java new file mode 100755 index 0000000..75a72ea --- /dev/null +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/AbstractMessagesEditor.java @@ -0,0 +1,614 @@ +/******************************************************************************* + * Copyright (c) 2007 Pascal Essiembre. + * 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: + * Pascal Essiembre - initial API and implementation + * Alexej Strelzow - TapJI integration, bug fixes & enhancements + * - issue 35, 36, 48, 73 + ******************************************************************************/ +package org.eclipse.babel.editor.internal; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +import org.eclipse.babel.core.message.IMessagesBundle; +import org.eclipse.babel.core.message.internal.IMessagesBundleGroupListener; +import org.eclipse.babel.core.message.internal.IMessagesBundleListener; +import org.eclipse.babel.core.message.internal.MessageException; +import org.eclipse.babel.core.message.internal.MessagesBundle; +import org.eclipse.babel.core.message.internal.MessagesBundleGroup; +import org.eclipse.babel.core.message.internal.MessagesBundleGroupAdapter; +import org.eclipse.babel.core.message.manager.RBManager; +import org.eclipse.babel.core.message.resource.IMessagesResource; +import org.eclipse.babel.core.message.tree.internal.AbstractKeyTreeModel; +import org.eclipse.babel.editor.IMessagesEditor; +import org.eclipse.babel.editor.IMessagesEditorChangeListener; +import org.eclipse.babel.editor.builder.ToggleNatureAction; +import org.eclipse.babel.editor.bundle.MessagesBundleGroupFactory; +import org.eclipse.babel.editor.i18n.I18NPage; +import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; +import org.eclipse.babel.editor.preferences.MsgEditorPreferences; +import org.eclipse.babel.editor.resource.EclipsePropertiesEditorResource; +import org.eclipse.babel.editor.util.UIUtils; +import org.eclipse.babel.editor.views.MessagesBundleGroupOutline; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.ide.IGotoMarker; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.part.MultiPageEditorPart; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; + +/** + * Multi-page editor for editing resource bundles. + */ +public abstract class AbstractMessagesEditor extends MultiPageEditorPart + implements IGotoMarker, IMessagesEditor { + + /** Editor ID, as defined in plugin.xml. */ + public static final String EDITOR_ID = "org.eclilpse.babel.editor.editor.MessagesEditor"; //$NON-NLS-1$ + + protected String selectedKey; + protected List changeListeners = new ArrayList( + 2); + + /** MessagesBundle group. */ + protected MessagesBundleGroup messagesBundleGroup; + + /** Page with key tree and text fields for all locales. */ + protected I18NPage i18nPage; + protected final List localesIndex = new ArrayList(); + protected final List textEditorsIndex = new ArrayList(); + + protected MessagesBundleGroupOutline outline; + + protected MessagesEditorMarkers markers; + + protected AbstractKeyTreeModel keyTreeModel; + + protected IFile file; // init + + protected boolean updateSelectedKey; + + /** + * Creates a multi-page editor example. + */ + public AbstractMessagesEditor() { + super(); + outline = new MessagesBundleGroupOutline(this); + } + + public MessagesEditorMarkers getMarkers() { + return markers; + } + + private IPropertyChangeListener preferenceListener; + + /** + * The MultiPageEditorExample implementation of this method + * checks that the input is an instance of IFileEditorInput. + */ + @Override + public void init(IEditorSite site, IEditorInput editorInput) + throws PartInitException { + + if (editorInput instanceof IFileEditorInput) { + file = ((IFileEditorInput) editorInput).getFile(); + if (MsgEditorPreferences.getInstance() + .isBuilderSetupAutomatically()) { + IProject p = file.getProject(); + if (p != null && p.isAccessible()) { + ToggleNatureAction + .addOrRemoveNatureOnProject(p, true, true); + } + } + try { + messagesBundleGroup = MessagesBundleGroupFactory + .createBundleGroup(site, file); + } catch (MessageException e) { + throw new PartInitException("Cannot create bundle group.", e); //$NON-NLS-1$ + } + messagesBundleGroup + .addMessagesBundleGroupListener(getMsgBundleGroupListner()); + markers = new MessagesEditorMarkers(messagesBundleGroup); + setPartName(messagesBundleGroup.getName()); + setTitleImage(UIUtils.getImage(UIUtils.IMAGE_RESOURCE_BUNDLE)); + closeIfAreadyOpen(site, file); + super.init(site, editorInput); + // TODO figure out model to use based on preferences + keyTreeModel = new AbstractKeyTreeModel(messagesBundleGroup); + // markerManager = new RBEMarkerManager(this); + } else { + throw new PartInitException( + "Invalid Input: Must be IFileEditorInput"); //$NON-NLS-1$ + } + initRAP(); + } + + // public RBEMarkerManager getMarkerManager() { + // return markerManager; + // } + + /** + * Creates the pages of the multi-page editor. + */ + @Override + protected void createPages() { + // Create I18N page + i18nPage = new I18NPage(getContainer(), SWT.NONE, this); + int index = addPage(i18nPage); + setPageText(index, MessagesEditorPlugin.getString("editor.properties")); //$NON-NLS-1$ + setPageImage(index, UIUtils.getImage(UIUtils.IMAGE_RESOURCE_BUNDLE)); + + // Create text editor pages for each locales + Locale[] locales = messagesBundleGroup.getLocales(); + // first: sort the locales. + UIUtils.sortLocales(locales); + // second: filter+sort them according to the filter preferences. + locales = UIUtils.filterLocales(locales); + for (int i = 0; i < locales.length; i++) { + Locale locale = locales[i]; + MessagesBundle messagesBundle = (MessagesBundle) messagesBundleGroup + .getMessagesBundle(locale); + createMessagesBundlePage(messagesBundle); + } + } + + /** + * Creates a new text editor for the messages bundle, which gets added to a new page + */ + protected void createMessagesBundlePage(MessagesBundle messagesBundle) { + try { + IMessagesResource resource = messagesBundle.getResource(); + final TextEditor textEditor = (TextEditor) resource.getSource(); + int index = addPage(textEditor, textEditor.getEditorInput()); + setPageText(index, + UIUtils.getDisplayName(messagesBundle.getLocale())); + setPageImage(index, UIUtils.getImage(UIUtils.IMAGE_PROPERTIES_FILE)); + localesIndex.add(messagesBundle.getLocale()); + textEditorsIndex.add(textEditor); + } catch (PartInitException e) { + ErrorDialog.openError(getSite().getShell(), + "Error creating text editor page.", //$NON-NLS-1$ + null, e.getStatus()); + } + } + + /** + * Adds a new messages bundle to an opened messages editor. Creates a new text edtor page + * and a new entry in the i18n page for the given locale and messages bundle. + */ + protected void addMessagesBundle(MessagesBundle messagesBundle) { + createMessagesBundlePage(messagesBundle); + i18nPage.addI18NEntry(messagesBundle.getLocale()); + } + + /** + * Removes the text editor page + the entry from the i18n page of the given locale and messages bundle. + */ + protected void removeMessagesBundle(MessagesBundle messagesBundle) { + IMessagesResource resource = messagesBundle.getResource(); + final TextEditor textEditor = (TextEditor) resource.getSource(); + // index + 1 because of i18n page + int pageIndex = textEditorsIndex.indexOf(textEditor) + 1; + removePage(pageIndex); + + textEditorsIndex.remove(textEditor); + localesIndex.remove(messagesBundle.getLocale()); + + textEditor.dispose(); + + // remove entry from i18n page + i18nPage.removeI18NEntry(messagesBundle.getLocale()); + } + + /** + * Called when the editor's pages need to be reloaded. For example when the + * filters of locale is changed. + *

+ * Currently this only reloads the index page. TODO: remove and add the new + * locales? it actually looks quite hard to do. + *

+ */ + public void reloadDisplayedContents() { + super.removePage(0); + int currentlyActivePage = super.getActivePage(); + i18nPage.dispose(); + i18nPage = new I18NPage(getContainer(), SWT.NONE, this); + super.addPage(0, i18nPage); + if (currentlyActivePage == 0) { + super.setActivePage(currentlyActivePage); + } + } + + /** + * Saves the multi-page editor's document. + */ + @Override + public void doSave(IProgressMonitor monitor) { + for (ITextEditor textEditor : textEditorsIndex) { + textEditor.doSave(monitor); + } + + try { // [alst] remove in near future + Thread.sleep(200); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + updateSelectedKey = true; + + RBManager instance = RBManager.getInstance(messagesBundleGroup + .getProjectName()); + + refreshKeyTreeModel(); // keeps editor and I18NPage in sync + + instance.fireEditorSaved(); + + // // maybe new init? + } + + protected void refreshKeyTreeModel() { + String selectedKey = getSelectedKey(); // memorize + + if (messagesBundleGroup == null) { + messagesBundleGroup = MessagesBundleGroupFactory.createBundleGroup( + (IEditorSite) getSite(), file); + } + + AbstractKeyTreeModel oldModel = this.keyTreeModel; + this.keyTreeModel = new AbstractKeyTreeModel(messagesBundleGroup); + + for (IMessagesEditorChangeListener listener : changeListeners) { + listener.keyTreeModelChanged(oldModel, this.keyTreeModel); + } + + i18nPage.getTreeViewer().expandAll(); + + if (selectedKey != null) { + setSelectedKey(selectedKey); + } + } + + /** + * @see org.eclipse.ui.ISaveablePart#doSaveAs() + */ + @Override + public void doSaveAs() { + // Save As not allowed. + } + + /** + * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed() + */ + @Override + public boolean isSaveAsAllowed() { + return false; + } + + /** + * Change current page based on locale. If there is no editors associated + * with current locale, do nothing. + * + * @param locale + * locale used to identify the page to change to + */ + public void setActivePage(Locale locale) { + int index = localesIndex.indexOf(locale); + if (index > -1) { + setActivePage(index + 1); + } + } + + /** + * @see org.eclipse.ui.ide.IGotoMarker#gotoMarker(org.eclipse.core.resources.IMarker) + */ + public void gotoMarker(IMarker marker) { + // String key = marker.getAttribute(RBEMarker.KEY, ""); + // if (key != null && key.length() > 0) { + // setActivePage(0); + // setSelectedKey(key); + // getI18NPage().selectLocale(BabelUtils.parseLocale( + // marker.getAttribute(RBEMarker.LOCALE, ""))); + // } else { + IResource resource = marker.getResource(); + Locale[] locales = messagesBundleGroup.getLocales(); + for (int i = 0; i < locales.length; i++) { + IMessagesResource messagesResource = ((MessagesBundle) messagesBundleGroup + .getMessagesBundle(locales[i])).getResource(); + if (messagesResource instanceof EclipsePropertiesEditorResource) { + EclipsePropertiesEditorResource propFile = (EclipsePropertiesEditorResource) messagesResource; + if (resource.equals(propFile.getResource())) { + // ok we got the locale. + // try to open the master i18n page and select the + // corresponding key. + try { + String key = (String) marker + .getAttribute(IMarker.LOCATION); + if (key != null && key.length() > 0) { + getI18NPage().selectLocale(locales[i]); + setActivePage(0); + setSelectedKey(key); + return; + } + } catch (Exception e) { + e.printStackTrace();// something better.s + } + // it did not work... fall back to the text editor. + setActivePage(locales[i]); + IDE.gotoMarker((IEditorPart) propFile.getSource(), marker); + break; + } + } + } + // } + } + + /** + * Calculates the contents of page GUI page when it is activated. + */ + @Override + protected void pageChange(int newPageIndex) { + super.pageChange(newPageIndex); + if (newPageIndex != 0) { // if we just want the default page -> == 1 + setSelection(newPageIndex); + } else if (newPageIndex == 0 && updateSelectedKey) { + // TODO: find better way + for (IMessagesBundle bundle : messagesBundleGroup + .getMessagesBundles()) { + RBManager.getInstance(messagesBundleGroup.getProjectName()) + .fireResourceChanged(bundle); + } + updateSelectedKey = false; + } + + // if (newPageIndex == 0) { + // resourceMediator.reloadProperties(); + // i18nPage.refreshTextBoxes(); + // } + } + + private void setSelection(int newPageIndex) { + ITextEditor editor = textEditorsIndex.get(--newPageIndex); + String selectedKey = getSelectedKey(); + if (selectedKey != null) { + if (editor.getEditorInput() instanceof FileEditorInput) { + FileEditorInput input = (FileEditorInput) editor + .getEditorInput(); + try { + IFile file = input.getFile(); + file.refreshLocal(IResource.DEPTH_ZERO, null); + BufferedReader reader = new BufferedReader( + new InputStreamReader(file.getContents())); + String line = ""; + int selectionIndex = 0; + boolean found = false; + + while ((line = reader.readLine()) != null) { + int index = line.indexOf('='); + if (index != -1) { + if (selectedKey.equals(line.substring(0, index) + .trim())) { + found = true; + break; + } + } + selectionIndex += line.length() + 2; // + \r\n + } + + if (found) { + editor.selectAndReveal(selectionIndex, 0); + } + } catch (CoreException e) { + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + } + + /** + * Is the given file a member of this resource bundle. + * + * @param file + * file to test + * @return true if file is part of bundle + */ + public boolean isBundleMember(IFile file) { + // return resourceMediator.isResource(file); + return false; + } + + protected void closeIfAreadyOpen(IEditorSite site, IFile file) { + IWorkbenchPage[] pages = site.getWorkbenchWindow().getPages(); + for (int i = 0; i < pages.length; i++) { + IWorkbenchPage page = pages[i]; + IEditorReference[] editors = page.getEditorReferences(); + for (int j = 0; j < editors.length; j++) { + IEditorPart editor = editors[j].getEditor(false); + if (editor instanceof AbstractMessagesEditor) { + AbstractMessagesEditor rbe = (AbstractMessagesEditor) editor; + if (rbe.isBundleMember(file)) { + page.closeEditor(editor, true); + } + } + } + } + } + + /** + * @see org.eclipse.ui.IWorkbenchPart#dispose() + */ + @Override + public void dispose() { + for (IMessagesEditorChangeListener listener : changeListeners) { + listener.editorDisposed(); + } + i18nPage.dispose(); + for (ITextEditor textEditor : textEditorsIndex) { + textEditor.dispose(); + } + + disposeRAP(); + } + + /** + * @return Returns the selectedKey. + */ + public String getSelectedKey() { + return selectedKey; + } + + /** + * @param selectedKey + * The selectedKey to set. + */ + public void setSelectedKey(String activeKey) { + if ((selectedKey == null && activeKey != null) + || (selectedKey != null && activeKey == null) + || (selectedKey != null && !selectedKey.equals(activeKey))) { + String oldKey = this.selectedKey; + this.selectedKey = activeKey; + for (IMessagesEditorChangeListener listener : changeListeners) { + listener.selectedKeyChanged(oldKey, activeKey); + } + } + } + + public void addChangeListener(IMessagesEditorChangeListener listener) { + changeListeners.add(0, listener); + } + + public void removeChangeListener(IMessagesEditorChangeListener listener) { + changeListeners.remove(listener); + } + + public Collection getChangeListeners() { + return changeListeners; + } + + /** + * @return Returns the messagesBundleGroup. + */ + public MessagesBundleGroup getBundleGroup() { + return messagesBundleGroup; + } + + /** + * @return Returns the keyTreeModel. + */ + public AbstractKeyTreeModel getKeyTreeModel() { + return keyTreeModel; + } + + /** + * @param keyTreeModel + * The keyTreeModel to set. + */ + public void setKeyTreeModel(AbstractKeyTreeModel newKeyTreeModel) { + if ((this.keyTreeModel == null && newKeyTreeModel != null) + || (keyTreeModel != null && newKeyTreeModel == null) + || (!keyTreeModel.equals(newKeyTreeModel))) { + AbstractKeyTreeModel oldModel = this.keyTreeModel; + this.keyTreeModel = newKeyTreeModel; + for (IMessagesEditorChangeListener listener : changeListeners) { + listener.keyTreeModelChanged(oldModel, newKeyTreeModel); + } + } + } + + public I18NPage getI18NPage() { + return i18nPage; + } + + /** + * one of the SHOW_* constants defined in the + * {@link IMessagesEditorChangeListener} + */ + private int showOnlyMissingAndUnusedKeys = IMessagesEditorChangeListener.SHOW_ALL; + + /** + * @return true when only unused and missing keys should be displayed. flase + * by default. + */ + public int isShowOnlyUnusedAndMissingKeys() { + return showOnlyMissingAndUnusedKeys; + } + + public void setShowOnlyUnusedMissingKeys(int showFlag) { + showOnlyMissingAndUnusedKeys = showFlag; + for (IMessagesEditorChangeListener listener : getChangeListeners()) { + listener.showOnlyUnusedAndMissingChanged(showFlag); + } + } + + @Override + public Object getAdapter(Class adapter) { + Object obj = super.getAdapter(adapter); + if (obj == null) { + if (IContentOutlinePage.class.equals(adapter)) { + return (outline); + } + } + return (obj); + } + + public ITextEditor getTextEditor(Locale locale) { + int index = localesIndex.indexOf(locale); + return textEditorsIndex.get(index); + } + + // Needed for RAP, otherwise super implementation of getTitleImage always + // returns + // same image with same device and same session context, and when this + // session ends + // -> NPE at org.eclipse.swt.graphics.Image.getImageData(Image.java:348) + @Override + public Image getTitleImage() { + // create new image with current display + return UIUtils.getImageDescriptor(UIUtils.IMAGE_RESOURCE_BUNDLE) + .createImage(); + } + + public void setTitleName(String name) { + setPartName(name); + } + + abstract public void setEnabled(boolean enabled); + + abstract protected void initRAP(); + + abstract protected void disposeRAP(); + + abstract protected IMessagesBundleGroupListener getMsgBundleGroupListner(); +} diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/MessagesEditor.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/MessagesEditor.java deleted file mode 100644 index 59bdf5b..0000000 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/MessagesEditor.java +++ /dev/null @@ -1,567 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Pascal Essiembre. - * 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: - * Pascal Essiembre - initial API and implementation - * Alexej Strelzow - TapJI integration, bug fixes & enhancements - * - issue 35, 36, 48, 73 - ******************************************************************************/ -package org.eclipse.babel.editor.internal; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Locale; - -import org.eclipse.babel.core.message.IMessagesBundle; -import org.eclipse.babel.core.message.internal.MessageException; -import org.eclipse.babel.core.message.internal.MessagesBundle; -import org.eclipse.babel.core.message.internal.MessagesBundleGroup; -import org.eclipse.babel.core.message.internal.MessagesBundleGroupAdapter; -import org.eclipse.babel.core.message.manager.RBManager; -import org.eclipse.babel.core.message.resource.IMessagesResource; -import org.eclipse.babel.core.message.tree.internal.AbstractKeyTreeModel; -import org.eclipse.babel.editor.IMessagesEditor; -import org.eclipse.babel.editor.IMessagesEditorChangeListener; -import org.eclipse.babel.editor.builder.ToggleNatureAction; -import org.eclipse.babel.editor.bundle.MessagesBundleGroupFactory; -import org.eclipse.babel.editor.i18n.I18NPage; -import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; -import org.eclipse.babel.editor.preferences.MsgEditorPreferences; -import org.eclipse.babel.editor.resource.EclipsePropertiesEditorResource; -import org.eclipse.babel.editor.util.UIUtils; -import org.eclipse.babel.editor.views.MessagesBundleGroupOutline; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.swt.SWT; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.IFileEditorInput; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.editors.text.TextEditor; -import org.eclipse.ui.ide.IDE; -import org.eclipse.ui.ide.IGotoMarker; -import org.eclipse.ui.part.FileEditorInput; -import org.eclipse.ui.part.MultiPageEditorPart; -import org.eclipse.ui.texteditor.ITextEditor; -import org.eclipse.ui.views.contentoutline.IContentOutlinePage; - -/** - * Multi-page editor for editing resource bundles. - */ -public class MessagesEditor extends MultiPageEditorPart implements IGotoMarker, - IMessagesEditor { - - /** Editor ID, as defined in plugin.xml. */ - public static final String EDITOR_ID = "org.eclilpse.babel.editor.editor.MessagesEditor"; //$NON-NLS-1$ - - private String selectedKey; - private List changeListeners = new ArrayList( - 2); - - /** MessagesBundle group. */ - private MessagesBundleGroup messagesBundleGroup; - - /** Page with key tree and text fields for all locales. */ - private I18NPage i18nPage; - private final List localesIndex = new ArrayList(); - private final List textEditorsIndex = new ArrayList(); - - private MessagesBundleGroupOutline outline; - - private MessagesEditorMarkers markers; - - private AbstractKeyTreeModel keyTreeModel; - - private IFile file; // init - - private boolean updateSelectedKey; - - /** - * Creates a multi-page editor example. - */ - public MessagesEditor() { - super(); - outline = new MessagesBundleGroupOutline(this); - } - - public MessagesEditorMarkers getMarkers() { - return markers; - } - - private IPropertyChangeListener preferenceListener; - - /** - * The MultiPageEditorExample implementation of this method - * checks that the input is an instance of IFileEditorInput. - */ - @Override - public void init(IEditorSite site, IEditorInput editorInput) - throws PartInitException { - - if (editorInput instanceof IFileEditorInput) { - file = ((IFileEditorInput) editorInput).getFile(); - if (MsgEditorPreferences.getInstance() - .isBuilderSetupAutomatically()) { - IProject p = file.getProject(); - if (p != null && p.isAccessible()) { - ToggleNatureAction - .addOrRemoveNatureOnProject(p, true, true); - } - } - try { - messagesBundleGroup = MessagesBundleGroupFactory - .createBundleGroup(site, file); - } catch (MessageException e) { - throw new PartInitException("Cannot create bundle group.", e); //$NON-NLS-1$ - } - // register bundle group listener to refresh editor when new a - // bundle is added - messagesBundleGroup - .addMessagesBundleGroupListener(new MessagesBundleGroupAdapter() { - @Override - public void messagesBundleAdded( - MessagesBundle messagesBundle) { - addMessagesBundle(messagesBundle, - messagesBundle.getLocale()); - // refresh i18n page - i18nPage.addI18NEntry(MessagesEditor.this, - messagesBundle.getLocale()); - } - }); - markers = new MessagesEditorMarkers(messagesBundleGroup); - setPartName(messagesBundleGroup.getName()); - setTitleImage(UIUtils.getImage(UIUtils.IMAGE_RESOURCE_BUNDLE)); - closeIfAreadyOpen(site, file); - super.init(site, editorInput); - // TODO figure out model to use based on preferences - keyTreeModel = new AbstractKeyTreeModel(messagesBundleGroup); - // markerManager = new RBEMarkerManager(this); - } else { - throw new PartInitException( - "Invalid Input: Must be IFileEditorInput"); //$NON-NLS-1$ - } - } - - // public RBEMarkerManager getMarkerManager() { - // return markerManager; - // } - - /** - * Creates the pages of the multi-page editor. - */ - @Override - protected void createPages() { - // Create I18N page - i18nPage = new I18NPage(getContainer(), SWT.NONE, this); - int index = addPage(i18nPage); - setPageText(index, MessagesEditorPlugin.getString("editor.properties")); //$NON-NLS-1$ - setPageImage(index, UIUtils.getImage(UIUtils.IMAGE_RESOURCE_BUNDLE)); - - // Create text editor pages for each locales - Locale[] locales = messagesBundleGroup.getLocales(); - // first: sort the locales. - UIUtils.sortLocales(locales); - // second: filter+sort them according to the filter preferences. - locales = UIUtils.filterLocales(locales); - for (int i = 0; i < locales.length; i++) { - Locale locale = locales[i]; - MessagesBundle messagesBundle = (MessagesBundle) messagesBundleGroup - .getMessagesBundle(locale); - addMessagesBundle(messagesBundle, locale); - } - } - - /** - * Creates a new text editor for the messages bundle and locale, which gets - * added to a new page - */ - private void addMessagesBundle(MessagesBundle messagesBundle, Locale locale) { - try { - IMessagesResource resource = messagesBundle.getResource(); - TextEditor textEditor = (TextEditor) resource.getSource(); - int index = addPage(textEditor, textEditor.getEditorInput()); - setPageText(index, - UIUtils.getDisplayName(messagesBundle.getLocale())); - setPageImage(index, UIUtils.getImage(UIUtils.IMAGE_PROPERTIES_FILE)); - localesIndex.add(locale); - textEditorsIndex.add(textEditor); - } catch (PartInitException e) { - ErrorDialog.openError(getSite().getShell(), - "Error creating text editor page.", //$NON-NLS-1$ - null, e.getStatus()); - } - } - - /** - * Called when the editor's pages need to be reloaded. For example when the - * filters of locale is changed. - *

- * Currently this only reloads the index page. TODO: remove and add the new - * locales? it actually looks quite hard to do. - *

- */ - public void reloadDisplayedContents() { - super.removePage(0); - int currentlyActivePage = super.getActivePage(); - i18nPage.dispose(); - i18nPage = new I18NPage(getContainer(), SWT.NONE, this); - super.addPage(0, i18nPage); - if (currentlyActivePage == 0) { - super.setActivePage(currentlyActivePage); - } - } - - /** - * Saves the multi-page editor's document. - */ - @Override - public void doSave(IProgressMonitor monitor) { - for (ITextEditor textEditor : textEditorsIndex) { - textEditor.doSave(monitor); - } - - try { // [alst] remove in near future - Thread.sleep(200); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - updateSelectedKey = true; - - RBManager instance = RBManager.getInstance(messagesBundleGroup - .getProjectName()); - - refreshKeyTreeModel(); // keeps editor and I18NPage in sync - - instance.fireEditorSaved(); - - // // maybe new init? - } - - private void refreshKeyTreeModel() { - String selectedKey = getSelectedKey(); // memorize - - if (messagesBundleGroup == null) { - messagesBundleGroup = MessagesBundleGroupFactory.createBundleGroup( - (IEditorSite) getSite(), file); - } - - AbstractKeyTreeModel oldModel = this.keyTreeModel; - this.keyTreeModel = new AbstractKeyTreeModel(messagesBundleGroup); - - for (IMessagesEditorChangeListener listener : changeListeners) { - listener.keyTreeModelChanged(oldModel, this.keyTreeModel); - } - - i18nPage.getTreeViewer().expandAll(); - - if (selectedKey != null) { - setSelectedKey(selectedKey); - } - } - - /** - * @see org.eclipse.ui.ISaveablePart#doSaveAs() - */ - @Override - public void doSaveAs() { - // Save As not allowed. - } - - /** - * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed() - */ - @Override - public boolean isSaveAsAllowed() { - return false; - } - - /** - * Change current page based on locale. If there is no editors associated - * with current locale, do nothing. - * - * @param locale - * locale used to identify the page to change to - */ - public void setActivePage(Locale locale) { - int index = localesIndex.indexOf(locale); - if (index > -1) { - setActivePage(index + 1); - } - } - - /** - * @see org.eclipse.ui.ide.IGotoMarker#gotoMarker(org.eclipse.core.resources.IMarker) - */ - public void gotoMarker(IMarker marker) { - // String key = marker.getAttribute(RBEMarker.KEY, ""); - // if (key != null && key.length() > 0) { - // setActivePage(0); - // setSelectedKey(key); - // getI18NPage().selectLocale(BabelUtils.parseLocale( - // marker.getAttribute(RBEMarker.LOCALE, ""))); - // } else { - IResource resource = marker.getResource(); - Locale[] locales = messagesBundleGroup.getLocales(); - for (int i = 0; i < locales.length; i++) { - IMessagesResource messagesResource = ((MessagesBundle) messagesBundleGroup - .getMessagesBundle(locales[i])).getResource(); - if (messagesResource instanceof EclipsePropertiesEditorResource) { - EclipsePropertiesEditorResource propFile = (EclipsePropertiesEditorResource) messagesResource; - if (resource.equals(propFile.getResource())) { - // ok we got the locale. - // try to open the master i18n page and select the - // corresponding key. - try { - String key = (String) marker - .getAttribute(IMarker.LOCATION); - if (key != null && key.length() > 0) { - getI18NPage().selectLocale(locales[i]); - setActivePage(0); - setSelectedKey(key); - return; - } - } catch (Exception e) { - e.printStackTrace();// something better.s - } - // it did not work... fall back to the text editor. - setActivePage(locales[i]); - IDE.gotoMarker((IEditorPart) propFile.getSource(), marker); - break; - } - } - } - // } - } - - /** - * Calculates the contents of page GUI page when it is activated. - */ - @Override - protected void pageChange(int newPageIndex) { - super.pageChange(newPageIndex); - if (newPageIndex != 0) { // if we just want the default page -> == 1 - setSelection(newPageIndex); - } else if (newPageIndex == 0 && updateSelectedKey) { - // TODO: find better way - for (IMessagesBundle bundle : messagesBundleGroup - .getMessagesBundles()) { - RBManager.getInstance(messagesBundleGroup.getProjectName()) - .fireResourceChanged(bundle); - } - updateSelectedKey = false; - } - - // if (newPageIndex == 0) { - // resourceMediator.reloadProperties(); - // i18nPage.refreshTextBoxes(); - // } - } - - private void setSelection(int newPageIndex) { - ITextEditor editor = textEditorsIndex.get(--newPageIndex); - String selectedKey = getSelectedKey(); - if (selectedKey != null) { - if (editor.getEditorInput() instanceof FileEditorInput) { - FileEditorInput input = (FileEditorInput) editor - .getEditorInput(); - try { - BufferedReader reader = new BufferedReader( - new InputStreamReader(input.getFile().getContents())); - String line = ""; - int selectionIndex = 0; - boolean found = false; - - while ((line = reader.readLine()) != null) { - int index = line.indexOf('='); - if (index != -1) { - if (selectedKey.equals(line.substring(0, index) - .trim())) { - found = true; - break; - } - } - selectionIndex += line.length() + 2; // + \r\n - } - - if (found) { - editor.selectAndReveal(selectionIndex, 0); - } - } catch (CoreException e) { - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - - } - - /** - * Is the given file a member of this resource bundle. - * - * @param file - * file to test - * @return true if file is part of bundle - */ - public boolean isBundleMember(IFile file) { - // return resourceMediator.isResource(file); - return false; - } - - private void closeIfAreadyOpen(IEditorSite site, IFile file) { - IWorkbenchPage[] pages = site.getWorkbenchWindow().getPages(); - for (int i = 0; i < pages.length; i++) { - IWorkbenchPage page = pages[i]; - IEditorReference[] editors = page.getEditorReferences(); - for (int j = 0; j < editors.length; j++) { - IEditorPart editor = editors[j].getEditor(false); - if (editor instanceof MessagesEditor) { - MessagesEditor rbe = (MessagesEditor) editor; - if (rbe.isBundleMember(file)) { - page.closeEditor(editor, true); - } - } - } - } - } - - /** - * @see org.eclipse.ui.IWorkbenchPart#dispose() - */ - @Override - public void dispose() { - for (IMessagesEditorChangeListener listener : changeListeners) { - listener.editorDisposed(); - } - i18nPage.dispose(); - for (ITextEditor textEditor : textEditorsIndex) { - textEditor.dispose(); - } - } - - /** - * @return Returns the selectedKey. - */ - public String getSelectedKey() { - return selectedKey; - } - - /** - * @param selectedKey - * The selectedKey to set. - */ - public void setSelectedKey(String activeKey) { - if ((selectedKey == null && activeKey != null) - || (selectedKey != null && activeKey == null) - || (selectedKey != null && !selectedKey.equals(activeKey))) { - String oldKey = this.selectedKey; - this.selectedKey = activeKey; - for (IMessagesEditorChangeListener listener : changeListeners) { - listener.selectedKeyChanged(oldKey, activeKey); - } - } - } - - public void addChangeListener(IMessagesEditorChangeListener listener) { - changeListeners.add(0, listener); - } - - public void removeChangeListener(IMessagesEditorChangeListener listener) { - changeListeners.remove(listener); - } - - public Collection getChangeListeners() { - return changeListeners; - } - - /** - * @return Returns the messagesBundleGroup. - */ - public MessagesBundleGroup getBundleGroup() { - return messagesBundleGroup; - } - - /** - * @return Returns the keyTreeModel. - */ - public AbstractKeyTreeModel getKeyTreeModel() { - return keyTreeModel; - } - - /** - * @param keyTreeModel - * The keyTreeModel to set. - */ - public void setKeyTreeModel(AbstractKeyTreeModel newKeyTreeModel) { - if ((this.keyTreeModel == null && newKeyTreeModel != null) - || (keyTreeModel != null && newKeyTreeModel == null) - || (!keyTreeModel.equals(newKeyTreeModel))) { - AbstractKeyTreeModel oldModel = this.keyTreeModel; - this.keyTreeModel = newKeyTreeModel; - for (IMessagesEditorChangeListener listener : changeListeners) { - listener.keyTreeModelChanged(oldModel, newKeyTreeModel); - } - } - } - - public I18NPage getI18NPage() { - return i18nPage; - } - - /** - * one of the SHOW_* constants defined in the - * {@link IMessagesEditorChangeListener} - */ - private int showOnlyMissingAndUnusedKeys = IMessagesEditorChangeListener.SHOW_ALL; - - /** - * @return true when only unused and missing keys should be displayed. flase - * by default. - */ - public int isShowOnlyUnusedAndMissingKeys() { - return showOnlyMissingAndUnusedKeys; - } - - public void setShowOnlyUnusedMissingKeys(int showFlag) { - showOnlyMissingAndUnusedKeys = showFlag; - for (IMessagesEditorChangeListener listener : getChangeListeners()) { - listener.showOnlyUnusedAndMissingChanged(showFlag); - } - } - - @Override - public Object getAdapter(Class adapter) { - Object obj = super.getAdapter(adapter); - if (obj == null) { - if (IContentOutlinePage.class.equals(adapter)) { - return (outline); - } - } - return (obj); - } - - public ITextEditor getTextEditor(Locale locale) { - int index = localesIndex.indexOf(locale); - return textEditorsIndex.get(index); - } -} diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/MessagesEditorContributor.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/MessagesEditorContributor.java index c0c2135..cd47369 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/MessagesEditorContributor.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/internal/MessagesEditorContributor.java @@ -172,7 +172,7 @@ public class MessagesEditorContributor extends */ public void setActiveEditor(IEditorPart part) { super.setActiveEditor(part); - MessagesEditor me = part instanceof MessagesEditor ? (MessagesEditor) part + AbstractMessagesEditor me = part instanceof AbstractMessagesEditor ? (AbstractMessagesEditor) part : null; toggleKeyTreeAction.setEditor(me); ((FilterKeysActionGroup) FILTERS).setActiveEditor(part); @@ -217,7 +217,7 @@ public class MessagesEditorContributor extends } public void setActiveEditor(IEditorPart part) { - MessagesEditor me = part instanceof MessagesEditor ? (MessagesEditor) part + AbstractMessagesEditor me = part instanceof AbstractMessagesEditor ? (AbstractMessagesEditor) part : null; for (int i = 0; i < filtersAction.length; i++) { filtersAction[i].setEditor(me); diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/plugin/MessagesEditorPlugin.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/plugin/MessagesEditorPlugin.java index 3619a1e..89b1c0e 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/plugin/MessagesEditorPlugin.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/plugin/MessagesEditorPlugin.java @@ -182,15 +182,19 @@ public class MessagesEditorPlugin extends AbstractUIPlugin implements }; ResourcesPlugin.getWorkspace().addResourceChangeListener( resourceChangeListener); - + try { Display.getDefault().asyncExec(new Runnable() { public void run() { - Display.getDefault() - .addFilter(SWT.KeyUp, new UndoKeyListener()); + Display.getDefault().addFilter(SWT.KeyUp, + new UndoKeyListener()); } }); + } catch (NullPointerException e) { + // TODO [RAP] Non UI-Thread, no default display available, in RAP + // multiple clients and displays + } } /** diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/preferences/MsgEditorPreferences.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/preferences/MsgEditorPreferences.java index 5576eed..6c40a50 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/preferences/MsgEditorPreferences.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/preferences/MsgEditorPreferences.java @@ -19,7 +19,7 @@ import org.eclipse.babel.core.message.resource.ser.IPropertiesSerializerConfig; import org.eclipse.babel.editor.IMessagesEditorChangeListener; import org.eclipse.babel.editor.builder.Builder; import org.eclipse.babel.editor.builder.ToggleNatureAction; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IProject; @@ -527,9 +527,9 @@ public final class MsgEditorPreferences implements /* for (int j = 0; j < edRefs.length; j++) { IEditorReference ref = edRefs[j]; IEditorPart edPart = ref.getEditor(false); - if (edPart != null && edPart instanceof MessagesEditor) { + if (edPart != null && edPart instanceof AbstractMessagesEditor) { // the editor was loaded. reload it: - MessagesEditor meToReload = (MessagesEditor) edPart; + AbstractMessagesEditor meToReload = (AbstractMessagesEditor) edPart; meToReload.reloadDisplayedContents(); } } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyArguments.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyArguments.java deleted file mode 100644 index ba64796..0000000 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyArguments.java +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Nigel Westbury - * 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: - * Nigel Westbury - initial implementation - ******************************************************************************/ -package org.eclipse.babel.editor.refactoring; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments; - -/** - * This class contains the data that a processor provides to its rename resource - * bundle key participants. - */ -public class RenameKeyArguments extends RefactoringArguments { - - private String fNewName; - - private boolean fRenameChildKeys; - - private boolean fUpdateReferences; - - /** - * Creates new rename arguments. - * - * @param newName - * the new name of the element to be renamed - * @param renameChildKeys - * true if child keys are to be renamed; - * false otherwise - * @param updateReferences - * true if reference updating is requested; - * false otherwise - */ - public RenameKeyArguments(String newName, boolean renameChildKeys, - boolean updateReferences) { - Assert.isNotNull(newName); - fNewName = newName; - fRenameChildKeys = renameChildKeys; - fUpdateReferences = updateReferences; - } - - /** - * Returns the new element name. - * - * @return the new element name - */ - public String getNewName() { - return fNewName; - } - - /** - * Returns whether child keys are to be renamed or not. - * - * @return returns true if child keys are to be renamed; - * false otherwise - */ - public boolean getRenameChildKeys() { - return fRenameChildKeys; - } - - /** - * Returns whether reference updating is requested or not. - * - * @return returns true if reference updating is requested; - * false otherwise - */ - public boolean getUpdateReferences() { - return fUpdateReferences; - } - - public String toString() { - return "rename to " + fNewName //$NON-NLS-1$ - + (fRenameChildKeys ? " (rename child keys)" : " (don't rename child keys)") //$NON-NLS-1$//$NON-NLS-2$ - + (fUpdateReferences ? " (update references)" : " (don't update references)"); //$NON-NLS-1$//$NON-NLS-2$ - } -} diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyChange.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyChange.java deleted file mode 100644 index f30272e..0000000 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyChange.java +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Nigel Westbury - * 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: - * Nigel Westbury - initial implementation - ******************************************************************************/ -package org.eclipse.babel.editor.refactoring; - -import java.text.MessageFormat; -import java.util.Collection; - -import org.eclipse.babel.core.message.internal.MessagesBundleGroup; -import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.ChangeDescriptor; -import org.eclipse.ltk.core.refactoring.RefactoringStatus; - -/** - * {@link Change} that renames a resource bundle key. - */ -public class RenameKeyChange extends Change { - - private final MessagesBundleGroup fMessagesBundleGroup; - - private final String fNewName; - - private final boolean fRenameChildKeys; - - private final KeyTreeNode fKeyTreeNode; - - private ChangeDescriptor fDescriptor; - - /** - * Creates the change. - * - * @param keyTreeNode - * the node in the model to rename - * @param newName - * the new name. Must not be empty - * @param renameChildKeys - * true if child keys are also to be renamed, false if just this - * one key is to be renamed - */ - protected RenameKeyChange(MessagesBundleGroup messageBundleGroup, - KeyTreeNode keyTreeNode, String newName, boolean renameChildKeys) { - if (keyTreeNode == null || newName == null || newName.length() == 0) { - throw new IllegalArgumentException(); - } - - fMessagesBundleGroup = messageBundleGroup; - fKeyTreeNode = keyTreeNode; - fNewName = newName; - fRenameChildKeys = renameChildKeys; - fDescriptor = null; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.Change#getDescriptor() - */ - public ChangeDescriptor getDescriptor() { - return fDescriptor; - } - - /** - * Sets the change descriptor to be returned by - * {@link Change#getDescriptor()}. - * - * @param descriptor - * the change descriptor - */ - public void setDescriptor(ChangeDescriptor descriptor) { - fDescriptor = descriptor; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.Change#getName() - */ - public String getName() { - return MessageFormat.format("Rename {0} to {1}", new Object[] { - fKeyTreeNode.getMessageKey(), fNewName }); - } - - /** - * Returns the new name. - * - * @return return the new name - */ - public String getNewName() { - return fNewName; - } - - /** - * This implementation of {@link Change#isValid(IProgressMonitor)} tests the - * modified resource using the validation method specified by - * {@link #setValidationMethod(int)}. - */ - public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, - OperationCanceledException { - pm.beginTask("", 2); //$NON-NLS-1$ - try { - RefactoringStatus result = new RefactoringStatus(); - return result; - } finally { - pm.done(); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ltk.core.refactoring.Change#initializeValidationData(org. - * eclipse.core.runtime.IProgressMonitor) - */ - public void initializeValidationData(IProgressMonitor pm) { - } - - public Object getModifiedElement() { - return "what is this for?"; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ltk.core.refactoring.Change#perform(org.eclipse.core.runtime - * .IProgressMonitor) - */ - public Change perform(IProgressMonitor pm) throws CoreException { - try { - pm.beginTask("Rename resource bundle key", 1); - - // Find the root - we will need this later - KeyTreeNode root = (KeyTreeNode) fKeyTreeNode.getParent(); - while (root.getName() != null) { - root = (KeyTreeNode) root.getParent(); - } - - if (fRenameChildKeys) { - String key = fKeyTreeNode.getMessageKey(); - String keyPrefix = fKeyTreeNode.getMessageKey() + "."; - Collection branchNodes = fKeyTreeNode.getBranch(); - for (KeyTreeNode branchNode : branchNodes) { - String oldKey = branchNode.getMessageKey(); - if (oldKey.equals(key) || oldKey.startsWith(keyPrefix)) { - String newKey = fNewName - + oldKey.substring(key.length()); - fMessagesBundleGroup.renameMessageKeys(oldKey, newKey); - } - } - } else { - fMessagesBundleGroup.renameMessageKeys( - fKeyTreeNode.getMessageKey(), fNewName); - } - - String oldName = fKeyTreeNode.getMessageKey(); - - // Find the node that was created with the new name - String segments[] = fNewName.split("\\."); - KeyTreeNode renamedKey = root; - for (String segment : segments) { - renamedKey = (KeyTreeNode) renamedKey.getChild(segment); - } - - assert (renamedKey != null); - return new RenameKeyChange(fMessagesBundleGroup, renamedKey, - oldName, fRenameChildKeys); - } finally { - pm.done(); - } - } -} diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyDescriptor.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyDescriptor.java deleted file mode 100644 index 168b618..0000000 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyDescriptor.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Nigel Westbury - * 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: - * Nigel Westbury - initial implementation - ******************************************************************************/ -package org.eclipse.babel.editor.refactoring; - -import org.eclipse.babel.core.message.internal.MessagesBundleGroup; -import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.ltk.core.refactoring.Refactoring; -import org.eclipse.ltk.core.refactoring.RefactoringContribution; -import org.eclipse.ltk.core.refactoring.RefactoringCore; -import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; -import org.eclipse.ltk.core.refactoring.RefactoringStatus; -import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring; - -/** - * Refactoring descriptor for the rename resource bundle key refactoring. - *

- * An instance of this refactoring descriptor may be obtained by calling - * {@link RefactoringContribution#createDescriptor()} on a refactoring - * contribution requested by invoking - * {@link RefactoringCore#getRefactoringContribution(String)} with the - * refactoring id ({@link #ID}). - */ -public final class RenameKeyDescriptor extends RefactoringDescriptor { - - public static final String ID = "org.eclipse.babel.editor.refactoring.renameKey"; //$NON-NLS-1$ - - /** The name attribute */ - private String fNewName; - - private KeyTreeNode fKeyNode; - - private MessagesBundleGroup fMessagesBundleGroup; - - /** Configures if references will be updated */ - private boolean fRenameChildKeys; - - /** - * Creates a new refactoring descriptor. - *

- * Clients should not instantiated this class but use - * {@link RefactoringCore#getRefactoringContribution(String)} with - * {@link #ID} to get the contribution that can create the descriptor. - *

- */ - public RenameKeyDescriptor() { - super(ID, null, "N/A", null, RefactoringDescriptor.STRUCTURAL_CHANGE - | RefactoringDescriptor.MULTI_CHANGE); - fNewName = null; - } - - /** - * Sets the new name to rename the resource to. - * - * @param name - * the non-empty new name to set - */ - public void setNewName(final String name) { - Assert.isNotNull(name); - Assert.isLegal(!"".equals(name), "Name must not be empty"); //$NON-NLS-1$//$NON-NLS-2$ - fNewName = name; - } - - /** - * Returns the new name to rename the resource to. - * - * @return the new name to rename the resource to - */ - public String getNewName() { - return fNewName; - } - - /** - * Sets the project name of this refactoring. - *

- * Note: If the resource to be renamed is of type {@link IResource#PROJECT}, - * clients are required to to set the project name to null. - *

- *

- * The default is to associate the refactoring with the workspace. - *

- * - * @param project - * the non-empty project name to set, or null for - * the workspace - * - * @see #getProject() - */ - // public void setProject(final String project) { - // super.setProject(project); - // } - - /** - * If set to true, this rename will also rename child keys. The - * default is to rename child keys. - * - * @param renameChildKeys - * true if this rename will rename child keys - */ - public void setRenameChildKeys(boolean renameChildKeys) { - fRenameChildKeys = renameChildKeys; - } - - public void setRenameChildKeys(KeyTreeNode keyNode, - MessagesBundleGroup messagesBundleGroup) { - this.fKeyNode = keyNode; - this.fMessagesBundleGroup = messagesBundleGroup; - } - - /** - * Returns if this rename will also rename child keys - * - * @return returns true if this rename will rename child keys - */ - public boolean isRenameChildKeys() { - return fRenameChildKeys; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ltk.core.refactoring.RefactoringDescriptor#createRefactoring - * (org.eclipse.ltk.core.refactoring.RefactoringStatus) - */ - public Refactoring createRefactoring(RefactoringStatus status) - throws CoreException { - - String newName = getNewName(); - if (newName == null || newName.length() == 0) { - status.addFatalError("The rename resource bundle key refactoring can not be performed as the new name is invalid"); - return null; - } - RenameKeyProcessor processor = new RenameKeyProcessor(fKeyNode, - fMessagesBundleGroup); - processor.setNewResourceName(newName); - processor.setRenameChildKeys(fRenameChildKeys); - - return new RenameRefactoring(processor); - } -} \ No newline at end of file diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyProcessor.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyProcessor.java deleted file mode 100644 index d477287..0000000 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyProcessor.java +++ /dev/null @@ -1,311 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Nigel Westbury - * 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: - * Nigel Westbury - initial implementation - ******************************************************************************/ -package org.eclipse.babel.editor.refactoring; - -import java.text.MessageFormat; - -import org.eclipse.babel.core.message.internal.MessagesBundleGroup; -import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; -import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor; -import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; -import org.eclipse.ltk.core.refactoring.RefactoringStatus; -import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; -import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; -import org.eclipse.ltk.core.refactoring.participants.RenameProcessor; -import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker; -import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; - -/** - * A rename processor for {@link IResource}. The processor will rename the - * resource and load rename participants if references should be renamed as - * well. - * - * @since 3.4 - */ -public class RenameKeyProcessor extends RenameProcessor { - - private KeyTreeNode fKeyNode; - - private MessagesBundleGroup fMessageBundleGroup; - - private String fNewResourceName; - - private boolean fRenameChildKeys; - - private RenameKeyArguments fRenameArguments; // set after - // checkFinalConditions - - /** - * Creates a new rename resource processor. - * - * @param keyNode - * the resource to rename. - * @param messagesBundleGroup - */ - public RenameKeyProcessor(KeyTreeNode keyNode, - MessagesBundleGroup messagesBundleGroup) { - if (keyNode == null) { - throw new IllegalArgumentException("key node must not be null"); //$NON-NLS-1$ - } - - fKeyNode = keyNode; - fMessageBundleGroup = messagesBundleGroup; - fRenameArguments = null; - fRenameChildKeys = true; - setNewResourceName(keyNode.getMessageKey()); // Initialize new name - } - - /** - * Returns the new key node - * - * @return the new key node - */ - public KeyTreeNode getNewKeyTreeNode() { - return fKeyNode; - } - - /** - * Returns the new resource name - * - * @return the new resource name - */ - public String getNewResourceName() { - return fNewResourceName; - } - - /** - * Sets the new resource name - * - * @param newName - * the new resource name - */ - public void setNewResourceName(String newName) { - Assert.isNotNull(newName); - fNewResourceName = newName; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# - * checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor) - */ - public RefactoringStatus checkInitialConditions(IProgressMonitor pm) - throws CoreException { - /* - * This method allows fatal and non-fatal problems to be shown to the - * user. Currently there are none so we return null to indicate this. - */ - return null; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# - * checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor, - * org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext) - */ - public RefactoringStatus checkFinalConditions(IProgressMonitor pm, - CheckConditionsContext context) throws CoreException { - pm.beginTask("", 1); //$NON-NLS-1$ - try { - fRenameArguments = new RenameKeyArguments(getNewResourceName(), - fRenameChildKeys, false); - - ResourceChangeChecker checker = (ResourceChangeChecker) context - .getChecker(ResourceChangeChecker.class); - IResourceChangeDescriptionFactory deltaFactory = checker - .getDeltaFactory(); - - // TODO figure out what we want to do here.... - // ResourceModifications.buildMoveDelta(deltaFactory, fKeyNode, - // fRenameArguments); - - return new RefactoringStatus(); - } finally { - pm.done(); - } - } - - /** - * Validates if the a name is valid. This method does not change the name - * settings on the refactoring. It is intended to be used in a wizard to - * validate user input. - * - * @param newName - * the name to validate - * @return returns the resulting status of the validation - */ - public RefactoringStatus validateNewElementName(String newName) { - Assert.isNotNull(newName); - - if (newName.length() == 0) { - return RefactoringStatus - .createFatalErrorStatus("New name for key must be entered"); - } - if (newName.startsWith(".")) { - return RefactoringStatus - .createFatalErrorStatus("Key cannot start with a '.'"); - } - if (newName.endsWith(".")) { - return RefactoringStatus - .createFatalErrorStatus("Key cannot end with a '.'"); - } - - String[] parts = newName.split("\\."); - for (String part : parts) { - if (part.length() == 0) { - return RefactoringStatus - .createFatalErrorStatus("Key cannot contain an empty part between two periods"); - } - if (!part.matches("([A-Z]|[a-z]|[0-9])*")) { - return RefactoringStatus - .createFatalErrorStatus("Key can contain only letters, digits, and periods"); - } - } - - if (fMessageBundleGroup.isMessageKey(newName)) { - return RefactoringStatus - .createFatalErrorStatus(MessagesEditorPlugin - .getString("dialog.error.exists")); - } - - return new RefactoringStatus(); - } - - protected RenameKeyDescriptor createDescriptor() { - RenameKeyDescriptor descriptor = new RenameKeyDescriptor(); - descriptor - .setDescription(MessageFormat.format( - "Rename resource bundle key ''{0}''", - fKeyNode.getMessageKey())); - descriptor.setComment(MessageFormat.format( - "Rename resource ''{0}'' to ''{1}''", - new Object[] { fKeyNode.getMessageKey(), fNewResourceName })); - descriptor.setFlags(RefactoringDescriptor.STRUCTURAL_CHANGE - | RefactoringDescriptor.MULTI_CHANGE - | RefactoringDescriptor.BREAKING_CHANGE); - descriptor.setNewName(getNewResourceName()); - descriptor.setRenameChildKeys(fRenameChildKeys); - return descriptor; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# - * createChange(org.eclipse.core.runtime.IProgressMonitor) - */ - public Change createChange(IProgressMonitor pm) throws CoreException { - pm.beginTask("", 1); //$NON-NLS-1$ - try { - RenameKeyChange change = new RenameKeyChange(fMessageBundleGroup, - getNewKeyTreeNode(), fNewResourceName, fRenameChildKeys); - change.setDescriptor(new RefactoringChangeDescriptor( - createDescriptor())); - return change; - } finally { - pm.done(); - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# - * getElements() - */ - public Object[] getElements() { - return new Object[] { fKeyNode }; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# - * getIdentifier() - */ - public String getIdentifier() { - return "org.eclipse.babel.editor.refactoring.renameKeyProcessor"; //$NON-NLS-1$ - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# - * getProcessorName() - */ - public String getProcessorName() { - return "Rename Resource Bundle Key"; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# - * isApplicable() - */ - public boolean isApplicable() { - if (this.fKeyNode == null) - return false; - return true; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# - * loadParticipants(org.eclipse.ltk.core.refactoring.RefactoringStatus, - * org.eclipse.ltk.core.refactoring.participants.SharableParticipants) - */ - public RefactoringParticipant[] loadParticipants(RefactoringStatus status, - SharableParticipants shared) throws CoreException { - // TODO: figure out participants to return here - return new RefactoringParticipant[0]; - - // String[] affectedNatures= - // ResourceProcessors.computeAffectedNatures(fResource); - // return ParticipantManager.loadRenameParticipants(status, this, - // fResource, fRenameArguments, null, affectedNatures, shared); - } - - /** - * Returns true if the refactoring processor also renames the - * child keys - * - * @return true if the refactoring processor also renames the - * child keys - */ - public boolean getRenameChildKeys() { - return fRenameChildKeys; - } - - /** - * Specifies if the refactoring processor also updates the child keys. The - * default behaviour is to update the child keys. - * - * @param renameChildKeys - * true if the refactoring processor should also - * rename the child keys - */ - public void setRenameChildKeys(boolean renameChildKeys) { - fRenameChildKeys = renameChildKeys; - } - -} \ No newline at end of file diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyWizard.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyWizard.java deleted file mode 100644 index 8cad851..0000000 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/refactoring/RenameKeyWizard.java +++ /dev/null @@ -1,189 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Nigel Westbury - * 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: - * Nigel Westbury - initial implementation - ******************************************************************************/ -package org.eclipse.babel.editor.refactoring; - -import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.ltk.core.refactoring.RefactoringStatus; -import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring; -import org.eclipse.ltk.ui.refactoring.RefactoringWizard; -import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; - -/** - * A wizard for the rename bundle key refactoring. - */ -public class RenameKeyWizard extends RefactoringWizard { - - /** - * Creates a {@link RenameKeyWizard}. - * - * @param resource - * the bundle key to rename - * @param refactoring - */ - public RenameKeyWizard(KeyTreeNode resource, RenameKeyProcessor refactoring) { - super(new RenameRefactoring(refactoring), DIALOG_BASED_USER_INTERFACE); - setDefaultPageTitle("Rename Resource Bundle Key"); - setWindowTitle("Rename Resource Bundle Key"); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.ui.refactoring.RefactoringWizard#addUserInputPages() - */ - protected void addUserInputPages() { - RenameKeyProcessor processor = (RenameKeyProcessor) getRefactoring() - .getAdapter(RenameKeyProcessor.class); - addPage(new RenameResourceRefactoringConfigurationPage(processor)); - } - - private static class RenameResourceRefactoringConfigurationPage extends - UserInputWizardPage { - - private final RenameKeyProcessor fRefactoringProcessor; - private Text fNameField; - - public RenameResourceRefactoringConfigurationPage( - RenameKeyProcessor processor) { - super("RenameResourceRefactoringInputPage"); //$NON-NLS-1$ - fRefactoringProcessor = processor; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt - * .widgets.Composite) - */ - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout(2, false)); - composite - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - composite.setFont(parent.getFont()); - - Label label = new Label(composite, SWT.NONE); - label.setText("New name:"); - label.setLayoutData(new GridData()); - - fNameField = new Text(composite, SWT.BORDER); - fNameField.setText(fRefactoringProcessor.getNewResourceName()); - fNameField.setFont(composite.getFont()); - fNameField.setLayoutData(new GridData(GridData.FILL, - GridData.BEGINNING, true, false)); - fNameField.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - validatePage(); - } - }); - - final Button includeChildKeysCheckbox = new Button(composite, - SWT.CHECK); - if (fRefactoringProcessor.getNewKeyTreeNode().isUsedAsKey()) { - if (fRefactoringProcessor.getNewKeyTreeNode().getChildren().length == 0) { - // This is an actual key with no child keys. - includeChildKeysCheckbox.setSelection(false); - includeChildKeysCheckbox.setEnabled(false); - } else { - // This is both an actual key and it has child keys, so we - // let the user choose whether to also rename the child - // keys. - includeChildKeysCheckbox.setSelection(fRefactoringProcessor - .getRenameChildKeys()); - includeChildKeysCheckbox.setEnabled(true); - } - } else { - // This is no an actual key, just a containing node, so the - // option - // to rename child keys must be set (otherwise this rename would - // not - // do anything). - includeChildKeysCheckbox.setSelection(true); - includeChildKeysCheckbox.setEnabled(false); - } - - includeChildKeysCheckbox - .setText("Also rename child keys (other keys with this key as a prefix)"); - GridData gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 2; - includeChildKeysCheckbox.setLayoutData(gd); - includeChildKeysCheckbox - .addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - fRefactoringProcessor - .setRenameChildKeys(includeChildKeysCheckbox - .getSelection()); - } - }); - - fNameField.selectAll(); - setPageComplete(false); - setControl(composite); - } - - public void setVisible(boolean visible) { - if (visible) { - fNameField.setFocus(); - } - super.setVisible(visible); - } - - protected final void validatePage() { - String text = fNameField.getText(); - RefactoringStatus status = fRefactoringProcessor - .validateNewElementName(text); - setPageComplete(status); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ltk.ui.refactoring.UserInputWizardPage#performFinish() - */ - protected boolean performFinish() { - initializeRefactoring(); - storeSettings(); - return super.performFinish(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#getNextPage() - */ - public IWizardPage getNextPage() { - initializeRefactoring(); - storeSettings(); - return super.getNextPage(); - } - - private void storeSettings() { - } - - private void initializeRefactoring() { - fRefactoringProcessor.setNewResourceName(fNameField.getText()); - } - } -} \ No newline at end of file diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AbstractRenameKeyAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AbstractRenameKeyAction.java new file mode 100644 index 0000000..f57faa1 --- /dev/null +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AbstractRenameKeyAction.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2007 Pascal Essiembre. + * 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: + * Pascal Essiembre - initial API and implementation + ******************************************************************************/ +package org.eclipse.babel.editor.tree.actions; + +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; +import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; +import org.eclipse.babel.editor.util.UIUtils; +import org.eclipse.jface.viewers.TreeViewer; + +/** + * @author Pascal Essiembre + * + */ +public abstract class AbstractRenameKeyAction extends AbstractTreeAction { + + public static final String INSTANCE_CLASS = "org.eclipse.babel.editor.tree.actions.RenameKeyAction"; + + public AbstractRenameKeyAction(AbstractMessagesEditor editor, + TreeViewer treeViewer) { + super(editor, treeViewer); + setText(MessagesEditorPlugin.getString("key.rename") + " ..."); //$NON-NLS-1$ + setImageDescriptor(UIUtils.getImageDescriptor(UIUtils.IMAGE_RENAME)); + setToolTipText("TODO put something here"); // TODO put tooltip + } + + /** + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public abstract void run(); +} diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AbstractTreeAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AbstractTreeAction.java index 46e71a5..d537d78 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AbstractTreeAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AbstractTreeAction.java @@ -13,7 +13,7 @@ package org.eclipse.babel.editor.tree.actions; import org.eclipse.babel.core.message.internal.MessagesBundleGroup; import org.eclipse.babel.core.message.tree.internal.AbstractKeyTreeModel; import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.jface.action.Action; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; @@ -30,12 +30,13 @@ public abstract class AbstractTreeAction extends Action { // KeyTreeNode[]{}; protected final TreeViewer treeViewer; - protected final MessagesEditor editor; + protected final AbstractMessagesEditor editor; /** * */ - public AbstractTreeAction(MessagesEditor editor, TreeViewer treeViewer) { + public AbstractTreeAction(AbstractMessagesEditor editor, + TreeViewer treeViewer) { super(); this.treeViewer = treeViewer; this.editor = editor; @@ -44,8 +45,8 @@ public abstract class AbstractTreeAction extends Action { /** * */ - public AbstractTreeAction(MessagesEditor editor, TreeViewer treeViewer, - int style) { + public AbstractTreeAction(AbstractMessagesEditor editor, + TreeViewer treeViewer, int style) { super("", style); this.treeViewer = treeViewer; this.editor = editor; @@ -82,7 +83,7 @@ public abstract class AbstractTreeAction extends Action { return treeViewer; } - protected MessagesEditor getEditor() { + protected AbstractMessagesEditor getEditor() { return editor; } diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AddKeyAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AddKeyAction.java index d55bf21..2d0273e 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AddKeyAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/AddKeyAction.java @@ -12,7 +12,7 @@ package org.eclipse.babel.editor.tree.actions; import org.eclipse.babel.core.message.internal.MessagesBundleGroup; import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.babel.editor.util.UIUtils; import org.eclipse.jface.dialogs.IInputValidator; @@ -29,7 +29,7 @@ public class AddKeyAction extends AbstractTreeAction { /** * */ - public AddKeyAction(MessagesEditor editor, TreeViewer treeViewer) { + public AddKeyAction(AbstractMessagesEditor editor, TreeViewer treeViewer) { super(editor, treeViewer); setText(MessagesEditorPlugin.getString("key.add") + " ..."); //$NON-NLS-1$ setImageDescriptor(UIUtils.getImageDescriptor(UIUtils.IMAGE_ADD)); diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/CollapseAllAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/CollapseAllAction.java index 7707356..a4f5018 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/CollapseAllAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/CollapseAllAction.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.eclipse.babel.editor.tree.actions; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.babel.editor.util.UIUtils; import org.eclipse.jface.viewers.TreeViewer; @@ -25,7 +25,8 @@ public class CollapseAllAction extends AbstractTreeAction { * @param editor * @param treeViewer */ - public CollapseAllAction(MessagesEditor editor, TreeViewer treeViewer) { + public CollapseAllAction(AbstractMessagesEditor editor, + TreeViewer treeViewer) { super(editor, treeViewer); setText(MessagesEditorPlugin.getString("key.collapseAll")); //$NON-NLS-1$ setImageDescriptor(UIUtils diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/DeleteKeyAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/DeleteKeyAction.java index d28cb5c..6135d93 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/DeleteKeyAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/DeleteKeyAction.java @@ -12,7 +12,7 @@ package org.eclipse.babel.editor.tree.actions; import org.eclipse.babel.core.message.internal.MessagesBundleGroup; import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; @@ -29,7 +29,7 @@ public class DeleteKeyAction extends AbstractTreeAction { /** * */ - public DeleteKeyAction(MessagesEditor editor, TreeViewer treeViewer) { + public DeleteKeyAction(AbstractMessagesEditor editor, TreeViewer treeViewer) { super(editor, treeViewer); setText(MessagesEditorPlugin.getString("key.delete")); //$NON-NLS-1$ setImageDescriptor(PlatformUI.getWorkbench().getSharedImages() diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/ExpandAllAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/ExpandAllAction.java index 1a87db8..61d1ad2 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/ExpandAllAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/ExpandAllAction.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.eclipse.babel.editor.tree.actions; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.babel.editor.util.UIUtils; import org.eclipse.jface.viewers.TreeViewer; @@ -25,7 +25,7 @@ public class ExpandAllAction extends AbstractTreeAction { * @param editor * @param treeViewer */ - public ExpandAllAction(MessagesEditor editor, TreeViewer treeViewer) { + public ExpandAllAction(AbstractMessagesEditor editor, TreeViewer treeViewer) { super(editor, treeViewer); setText(MessagesEditorPlugin.getString("key.expandAll")); //$NON-NLS-1$ setImageDescriptor(UIUtils.getImageDescriptor(UIUtils.IMAGE_EXPAND_ALL)); diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/FlatModelAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/FlatModelAction.java index 09070a6..9d5b3d9 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/FlatModelAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/FlatModelAction.java @@ -11,7 +11,7 @@ package org.eclipse.babel.editor.tree.actions; import org.eclipse.babel.core.message.tree.TreeType; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.babel.editor.tree.internal.KeyTreeContentProvider; import org.eclipse.babel.editor.util.UIUtils; @@ -28,7 +28,7 @@ public class FlatModelAction extends AbstractTreeAction { * @param editor * @param treeViewer */ - public FlatModelAction(MessagesEditor editor, TreeViewer treeViewer) { + public FlatModelAction(AbstractMessagesEditor editor, TreeViewer treeViewer) { super(editor, treeViewer, IAction.AS_RADIO_BUTTON); setText(MessagesEditorPlugin.getString("key.layout.flat")); //$NON-NLS-1$ setImageDescriptor(UIUtils diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/RefactorKeyAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/RefactorKeyAction.java new file mode 100644 index 0000000..062ef06 --- /dev/null +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/RefactorKeyAction.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2012 Alexej Strelzow. + * 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: + * Alexej Strelzow - initial API and implementation + ******************************************************************************/ +package org.eclipse.babel.editor.tree.actions; + +import org.eclipse.babel.core.message.manager.RBManager; +import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; +import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; +import org.eclipse.babel.editor.util.UIUtils; +import org.eclipse.jface.viewers.TreeViewer; + +/** + * An action, which triggers the refactoring of message keys. + * + * @author Alexej Strelzow + */ +public class RefactorKeyAction extends AbstractTreeAction { + + /** + * Constructor. + * + * @param editor + * The {@link MessagesEditor} + * @param treeViewer + * The {@link TreeViewer} + */ + public RefactorKeyAction(AbstractMessagesEditor editor, + TreeViewer treeViewer) { + super(editor, treeViewer); + setText(MessagesEditorPlugin.getString("key.refactor") + " ..."); //$NON-NLS-1$ + setImageDescriptor(UIUtils + .getImageDescriptor(UIUtils.IMAGE_REFACTORING)); + setToolTipText("Refactor the name of the key"); + } + + /** + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + KeyTreeNode node = getNodeSelection(); + + String key = node.getMessageKey(); + String bundleId = node.getMessagesBundleGroup().getResourceBundleId(); + String projectName = node.getMessagesBundleGroup().getProjectName(); + + RBManager.getRefactorService().openRefactorDialog(projectName, + bundleId, key, null); + + } +} diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/RenameKeyAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/RenameKeyAction.java deleted file mode 100644 index add1ff9..0000000 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/RenameKeyAction.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Pascal Essiembre. - * 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: - * Pascal Essiembre - initial API and implementation - ******************************************************************************/ -package org.eclipse.babel.editor.tree.actions; - -import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; -import org.eclipse.babel.editor.internal.MessagesEditor; -import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; -import org.eclipse.babel.editor.refactoring.RenameKeyProcessor; -import org.eclipse.babel.editor.refactoring.RenameKeyWizard; -import org.eclipse.babel.editor.util.UIUtils; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.ltk.ui.refactoring.RefactoringWizard; -import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; - -/** - * @author Pascal Essiembre - * - */ -public class RenameKeyAction extends AbstractTreeAction { - - /** - * - */ - public RenameKeyAction(MessagesEditor editor, TreeViewer treeViewer) { - super(editor, treeViewer); - setText(MessagesEditorPlugin.getString("key.rename") + " ..."); //$NON-NLS-1$ - setImageDescriptor(UIUtils.getImageDescriptor(UIUtils.IMAGE_RENAME)); - setToolTipText("TODO put something here"); // TODO put tooltip - } - - /** - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - KeyTreeNode node = getNodeSelection(); - - // Rename single item - RenameKeyProcessor refactoring = new RenameKeyProcessor(node, - getBundleGroup()); - - RefactoringWizard wizard = new RenameKeyWizard(node, refactoring); - try { - RefactoringWizardOpenOperation operation = new RefactoringWizardOpenOperation( - wizard); - operation.run(getShell(), "Introduce Indirection"); - } catch (InterruptedException exception) { - // Do nothing - } - } -} diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/TreeModelAction.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/TreeModelAction.java index 756b2ae..4f5ed4d 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/TreeModelAction.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/actions/TreeModelAction.java @@ -11,7 +11,7 @@ package org.eclipse.babel.editor.tree.actions; import org.eclipse.babel.core.message.tree.TreeType; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.babel.editor.tree.internal.KeyTreeContentProvider; import org.eclipse.babel.editor.util.UIUtils; @@ -28,7 +28,7 @@ public class TreeModelAction extends AbstractTreeAction { * @param editor * @param treeViewer */ - public TreeModelAction(MessagesEditor editor, TreeViewer treeViewer) { + public TreeModelAction(AbstractMessagesEditor editor, TreeViewer treeViewer) { super(editor, treeViewer, IAction.AS_RADIO_BUTTON); setText(MessagesEditorPlugin.getString("key.layout.tree")); //$NON-NLS-1$ setImageDescriptor(UIUtils diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/internal/KeyTreeContributor.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/internal/KeyTreeContributor.java index ace9d7b..162b47f 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/internal/KeyTreeContributor.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/internal/KeyTreeContributor.java @@ -10,6 +10,7 @@ ******************************************************************************/ package org.eclipse.babel.editor.tree.internal; +import java.lang.reflect.Constructor; import java.util.Observable; import java.util.Observer; @@ -19,19 +20,22 @@ import org.eclipse.babel.core.message.tree.internal.AbstractKeyTreeModel; import org.eclipse.babel.core.message.tree.internal.IKeyTreeModelListener; import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; import org.eclipse.babel.editor.IMessagesEditorChangeListener; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.internal.MessagesEditorChangeAdapter; import org.eclipse.babel.editor.internal.MessagesEditorMarkers; import org.eclipse.babel.editor.tree.IKeyTreeContributor; +import org.eclipse.babel.editor.tree.actions.AbstractRenameKeyAction; import org.eclipse.babel.editor.tree.actions.AddKeyAction; import org.eclipse.babel.editor.tree.actions.DeleteKeyAction; -import org.eclipse.babel.editor.tree.actions.RenameKeyAction; +import org.eclipse.babel.editor.tree.actions.RefactorKeyAction; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; @@ -52,14 +56,14 @@ import org.eclipse.swt.widgets.Tree; */ public class KeyTreeContributor implements IKeyTreeContributor { - private MessagesEditor editor; + private AbstractMessagesEditor editor; private AbstractKeyTreeModel treeModel; private TreeType treeType; /** * */ - public KeyTreeContributor(final MessagesEditor editor) { + public KeyTreeContributor(final AbstractMessagesEditor editor) { super(); this.editor = editor; this.treeModel = new AbstractKeyTreeModel(editor.getBundleGroup()); @@ -101,6 +105,10 @@ public class KeyTreeContributor implements IKeyTreeContributor { // Set input model treeViewer.setInput(treeModel); treeViewer.expandAll(); + + treeViewer.setColumnProperties(new String[] { "column1" }); + treeViewer.setCellEditors(new CellEditor[] { new TextCellEditor( + treeViewer.getTree()) }); } private class OnlyUnsuedAndMissingKey extends ViewerFilter implements @@ -166,12 +174,16 @@ public class KeyTreeContributor implements IKeyTreeContributor { private void contributeMarkers(final TreeViewer treeViewer) { editor.getMarkers().addObserver(new Observer() { public void update(Observable o, Object arg) { - Display.getDefault().asyncExec(new Runnable() { + Display display = treeViewer.getTree().getDisplay(); + // [RAP] only refresh tree viewer in this UIThread + if (display.equals(Display.getCurrent())) { + display.asyncExec(new Runnable() { public void run() { treeViewer.refresh(); } }); } + } }); // editor.addChangeListener(new MessagesEditorChangeAdapter() { // public void editorDisposed() { @@ -242,8 +254,10 @@ public class KeyTreeContributor implements IKeyTreeContributor { public void nodeAdded(KeyTreeNode node) { Display.getDefault().asyncExec(new Runnable() { public void run() { + if (!editor.getI18NPage().isDisposed()) { treeViewer.refresh(true); } + } }); }; @@ -253,8 +267,10 @@ public class KeyTreeContributor implements IKeyTreeContributor { public void nodeRemoved(KeyTreeNode node) { Display.getDefault().asyncExec(new Runnable() { public void run() { + if (!editor.getI18NPage().isDisposed()) { treeViewer.refresh(true); } + } }); }; }; @@ -340,9 +356,25 @@ public class KeyTreeContributor implements IKeyTreeContributor { final IAction deleteAction = new DeleteKeyAction(editor, treeViewer); menuManager.add(deleteAction); // Rename - final IAction renameAction = new RenameKeyAction(editor, treeViewer); + // final IAction renameAction = new RenameKeyAction(editor, treeViewer); + AbstractRenameKeyAction renameKeyAction = null; + try { + Class clazz = Class + .forName(AbstractRenameKeyAction.INSTANCE_CLASS); + Constructor cons = clazz.getConstructor( + AbstractMessagesEditor.class, TreeViewer.class); + renameKeyAction = (AbstractRenameKeyAction) cons.newInstance( + editor, treeViewer); + } catch (Exception e) { + e.printStackTrace(); + } + final IAction renameAction = renameKeyAction; menuManager.add(renameAction); + // Refactor + final IAction refactorAction = new RefactorKeyAction(editor, treeViewer); + menuManager.add(refactorAction); + menuManager.update(true); tree.setMenu(menu); diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/internal/KeyTreeLabelProvider.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/internal/KeyTreeLabelProvider.java index 1a9b6ce..4ecef0b 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/internal/KeyTreeLabelProvider.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/tree/internal/KeyTreeLabelProvider.java @@ -17,7 +17,7 @@ import org.eclipse.babel.core.message.internal.MessagesBundleGroup; import org.eclipse.babel.core.message.tree.IKeyTreeNode; import org.eclipse.babel.core.message.tree.internal.AbstractKeyTreeModel; import org.eclipse.babel.core.message.tree.internal.KeyTreeNode; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.internal.MessagesEditorMarkers; import org.eclipse.babel.editor.util.OverlayImageIcon; import org.eclipse.babel.editor.util.UIUtils; @@ -50,7 +50,7 @@ public class KeyTreeLabelProvider extends ColumnLabelProvider implements /** Registry instead of UIUtils one for image not keyed by file name. */ private static ImageRegistry imageRegistry = new ImageRegistry(); - private MessagesEditor editor; + private AbstractMessagesEditor editor; private MessagesBundleGroup messagesBundleGroup; /** @@ -67,7 +67,7 @@ public class KeyTreeLabelProvider extends ColumnLabelProvider implements /** * */ - public KeyTreeLabelProvider(MessagesEditor editor, + public KeyTreeLabelProvider(AbstractMessagesEditor editor, AbstractKeyTreeModel treeModel, KeyTreeContentProvider contentProvider) { super(); diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/util/UIUtils.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/util/UIUtils.java index 0e915e8..7153cad 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/util/UIUtils.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/util/UIUtils.java @@ -16,6 +16,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.Reader; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -27,12 +29,15 @@ import java.util.List; import java.util.Locale; import java.util.Set; +import org.eclipse.babel.editor.compat.SwtRapCompatibilitySWT; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.babel.editor.preferences.MsgEditorPreferences; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.resource.ImageDescriptor; @@ -75,9 +80,9 @@ public final class UIUtils { public static final String IMAGE_ADD = "add.png"; //$NON-NLS-1$ /** Name of edit icon. */ public static final String IMAGE_RENAME = "rename.gif"; //$NON-NLS-1$ + /** Name of "view left" icon. */ /** Name of refactoring icon. */ public static final String IMAGE_REFACTORING = "refactoring.png"; //$NON-NLS-1$ - /** Name of "view left" icon. */ public static final String IMAGE_VIEW_LEFT = "viewLeft.gif"; //$NON-NLS-1$ /** Name of locale icon. */ public static final String IMAGE_LOCALE = "locale.gif"; //$NON-NLS-1$ @@ -101,13 +106,13 @@ public final class UIUtils { public static final String IMAGE_ERROR = "error_co.gif"; //$NON-NLS-1$ /** Image registry. */ - private static final ImageRegistry imageRegistry = + private static ImageRegistry imageRegistry; // TODO: REMOVE this comment eventually: // necessary to specify the display otherwise Display.getCurrent() // is called and will return null if this is not the UI-thread. // this happens if the builder is called and initialize this class: // the thread will not be the UI-thread. - new ImageRegistry(PlatformUI.getWorkbench().getDisplay()); + // new ImageRegistry(PlatformUI.getWorkbench().getDisplay()); public static final String PDE_NATURE = "org.eclipse.pde.PluginNature"; //$NON-NLS-1$ public static final String JDT_JAVA_NATURE = "org.eclipse.jdt.core.javanature"; //$NON-NLS-1$ @@ -126,7 +131,6 @@ public final class UIUtils { public static final void sortLocales(Locale[] locales) { List localesList = new ArrayList(Arrays.asList(locales)); Comparator comp = new Comparator() { - @Override public int compare(Locale l1, Locale l2) { if (ROOT_LOCALE.equals(l1)) { return -1; @@ -443,6 +447,35 @@ public final class UIUtils { * @return image */ public static Image getImage(String imageName) { + Image image = null; + try { + // [RAP] In RAP multiple displays could exist (multiple user), + // therefore image needs to be created every time with the current + // display + Method getImageRAP = Class.forName( + "org.eclipse.babel.editor.util.UIUtilsRAP").getMethod( + "getImage", String.class); + image = (Image) getImageRAP.invoke(null, imageName); + } catch (Exception e) { + // RAP fragment not running --> invoke rcp version + image = getImageRCP(imageName); + } + + return image; + } + + /** + * Gets an image from image registry or creates a new one if it the first + * time. + * + * @param imageName + * image name + * @return image + */ + private static Image getImageRCP(String imageName) { + if (imageRegistry == null) + imageRegistry = new ImageRegistry(PlatformUI.getWorkbench() + .getDisplay()); Image image = imageRegistry.get(imageName); if (image == null) { image = getImageDescriptor(imageName).createImage(); @@ -535,7 +568,7 @@ public final class UIUtils { ComponentOrientation orientation = ComponentOrientation .getOrientation(locale); if (orientation == ComponentOrientation.RIGHT_TO_LEFT) { - return SWT.RIGHT_TO_LEFT; + return SwtRapCompatibilitySWT.RIGHT_TO_LEFT; } } return SWT.LEFT_TO_RIGHT; @@ -563,11 +596,11 @@ public final class UIUtils { if (!projDescr.exists()) { return false;// a corrupted project } - // InputStream in = null; try { - in = ((IFile) projDescr).getContents(); + projDescr.refreshLocal(IResource.DEPTH_ZERO, null); + in = projDescr.getContents(); // supposedly in utf-8. should not really matter for us Reader r = new InputStreamReader(in, "UTF-8"); LineNumberReader lnr = new LineNumberReader(r); diff --git a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/views/MessagesBundleGroupOutline.java b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/views/MessagesBundleGroupOutline.java index f9a5dee..fc5242d 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/babel/editor/views/MessagesBundleGroupOutline.java +++ b/org.eclipse.babel.editor/src/org/eclipse/babel/editor/views/MessagesBundleGroupOutline.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.eclipse.babel.editor.views; -import org.eclipse.babel.editor.internal.MessagesEditor; +import org.eclipse.babel.editor.internal.AbstractMessagesEditor; import org.eclipse.babel.editor.tree.actions.CollapseAllAction; import org.eclipse.babel.editor.tree.actions.ExpandAllAction; import org.eclipse.babel.editor.tree.actions.FlatModelAction; @@ -28,9 +28,9 @@ import org.eclipse.ui.views.contentoutline.ContentOutlinePage; */ public class MessagesBundleGroupOutline extends ContentOutlinePage { - private final MessagesEditor editor; + private final AbstractMessagesEditor editor; - public MessagesBundleGroupOutline(MessagesEditor editor) { + public MessagesBundleGroupOutline(AbstractMessagesEditor editor) { super(); this.editor = editor; } diff --git a/org.eclipse.babel.editor/src/org/eclipse/pde/nls/internal/ui/editor/LocalizationEditor.java b/org.eclipse.babel.editor/src/org/eclipse/pde/nls/internal/ui/editor/LocalizationEditor.java index fa1a606..b1b4bef 100644 --- a/org.eclipse.babel.editor/src/org/eclipse/pde/nls/internal/ui/editor/LocalizationEditor.java +++ b/org.eclipse.babel.editor/src/org/eclipse/pde/nls/internal/ui/editor/LocalizationEditor.java @@ -22,6 +22,7 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; +import org.eclipse.babel.editor.compat.SwtRapCompatibilityFormToolkit; import org.eclipse.babel.editor.plugin.MessagesEditorPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -415,7 +416,7 @@ public class LocalizationEditor extends EditorPart { private ExportAction exportAction; // Form - protected FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + protected SwtRapCompatibilityFormToolkit toolkit = new SwtRapCompatibilityFormToolkit(Display.getCurrent()); private Form form; private Image formImage; -- cgit v1.2.3