From 50eefc612119c8b7ce3ded9b234dca44cf2376c9 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 27 May 2015 14:57:25 +0300 Subject: [PATCH] ResourceBundleEditor: added context menu for translation editors + action to propagate value across all of translations --- .../editor/ResourceBundleEditor.java | 66 +++++++++++++------ ...esourceBundlePropertiesUpdateManager.java} | 11 ++-- ...rceBundlePropertiesUpdateManagerImpl.java} | 25 ++++--- .../ResourceBundleStructureViewComponent.java | 6 +- ...ResourceBundleEditorInsertManagerTest.java | 49 +++++++------- 5 files changed, 96 insertions(+), 61 deletions(-) rename plugins/properties/src/com/intellij/lang/properties/editor/{ResourceBundlePropertiesInsertManager.java => ResourceBundlePropertiesUpdateManager.java} (68%) rename plugins/properties/src/com/intellij/lang/properties/editor/{ResourceBundlePropertiesInsertManagerImpl.java => ResourceBundlePropertiesUpdateManagerImpl.java} (88%) diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java index 8c78dc1a0171..c50195354365 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java @@ -38,7 +38,6 @@ import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.lang.properties.psi.PropertiesResourceBundleUtil; import com.intellij.lang.properties.psi.impl.PropertyKeyImpl; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.WriteCommandAction; @@ -50,7 +49,6 @@ import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.actions.EditorActionUtil; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; -import com.intellij.openapi.editor.event.EditorMouseAdapter; import com.intellij.openapi.editor.event.EditorMouseEvent; import com.intellij.openapi.editor.event.EditorMouseEventArea; import com.intellij.openapi.editor.ex.EditorEx; @@ -85,7 +83,6 @@ import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import java.awt.*; -import java.awt.event.MouseEvent; import java.beans.PropertyChangeListener; import java.util.*; import java.util.List; @@ -100,7 +97,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit private final StructureViewComponent myStructureViewComponent; private final Map myEditors; private final ResourceBundle myResourceBundle; - private final ResourceBundlePropertiesInsertManager myPropertiesInsertDeleteManager; + private final ResourceBundlePropertiesUpdateManager myPropertiesInsertDeleteManager; private final Map myTitledPanels; private final JComponent myNoPropertySelectedPanel = new NoPropertySelectedPanel().getComponent(); private final Project myProject; @@ -134,7 +131,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit splitPanel.add(splitter, BorderLayout.CENTER); myResourceBundle = resourceBundle; - myPropertiesInsertDeleteManager = ResourceBundlePropertiesInsertManagerImpl.create(resourceBundle); + myPropertiesInsertDeleteManager = ResourceBundlePropertiesUpdateManagerImpl.create(resourceBundle); myPropertiesAnchorizer = new PropertiesAnchorizer(myResourceBundle.getProject()); myStructureViewComponent = new ResourceBundleStructureViewComponent(myResourceBundle, this, myPropertiesAnchorizer); @@ -155,7 +152,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit if (e.getOldLeadSelectionPath() != null) { for (Map.Entry entry : myEditors.entrySet()) { if (entry.getValue() == mySelectedEditor) { - writeEditorPropertyValue(mySelectedEditor, entry.getKey(), selectedProperty.getName()); + writeEditorPropertyValue(selectedProperty.getName(), mySelectedEditor, entry.getKey()); break; } } @@ -211,7 +208,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit } @NotNull - public ResourceBundlePropertiesInsertManager getPropertiesInsertDeleteManager() { + public ResourceBundlePropertiesUpdateManager getPropertiesInsertDeleteManager() { return myPropertiesInsertDeleteManager; } @@ -341,7 +338,9 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit return value instanceof ResourceBundleEditorViewElement ? (ResourceBundleEditorViewElement) value : null; } - private void writeEditorPropertyValue(final Editor editor, final PropertiesFile propertiesFile, final @Nullable String propertyName) { + private void writeEditorPropertyValue(final @Nullable String propertyName, + final @NotNull Editor editor, + final @NotNull PropertiesFile propertiesFile) { final String currentValue = editor.getDocument().getText(); final String currentSelectedProperty = propertyName == null ? getSelectedPropertyName() : propertyName; if (currentSelectedProperty == null) { @@ -354,14 +353,8 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit WriteCommandAction.runWriteCommandAction(myProject, new Runnable() { @Override public void run() { - final IProperty property = propertiesFile.findPropertyByKey(currentSelectedProperty); try { - if (property == null) { - myPropertiesInsertDeleteManager.insertTranslation(currentSelectedProperty, currentValue, propertiesFile); - } - else { - property.setValue(currentValue); - } + myPropertiesInsertDeleteManager.insertOrUpdateTranslation(currentSelectedProperty, currentValue, propertiesFile); } catch (final IncorrectOperationException e) { LOG.error(e); @@ -418,7 +411,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit @Override public void focusLost(final Editor eventEditor) { - writeEditorPropertyValue(editor, propertiesFile, null); + writeEditorPropertyValue(null, editor, propertiesFile); } }); gc.gridx = 0; @@ -847,7 +840,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit if (mySelectedEditor != null) { for (final Map.Entry entry : myEditors.entrySet()) { if (mySelectedEditor.equals(entry.getValue())) { - writeEditorPropertyValue(mySelectedEditor, entry.getKey(), null); + writeEditorPropertyValue(null, mySelectedEditor, entry.getKey()); } } } @@ -893,7 +886,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit return editor; } - private static void reinitSettings(final EditorEx editor) { + private void reinitSettings(final EditorEx editor) { EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); editor.setColorsScheme(scheme); EditorSettings settings = editor.getSettings(); @@ -914,7 +907,42 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit @Override public void invokePopup(EditorMouseEvent event) { if (!event.isConsumed() && event.getArea() == EditorMouseEventArea.EDITING_AREA) { - ActionGroup group = (ActionGroup)CustomActionsSchema.getInstance().getCorrectedAction(IdeActions.GROUP_CUT_COPY_PASTE); + DefaultActionGroup group = new DefaultActionGroup(); + group.copyFromGroup((DefaultActionGroup)CustomActionsSchema.getInstance().getCorrectedAction(IdeActions.GROUP_CUT_COPY_PASTE)); + group.addSeparator(); + group.add(new AnAction("Propagate Value Across of Resource Bundle") { + @Override + public void actionPerformed(AnActionEvent e) { + final String valueToPropagate = editor.getDocument().getText(); + final String currentSelectedProperty = getSelectedPropertyName(); + if (currentSelectedProperty == null) { + return; + } + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + WriteCommandAction.runWriteCommandAction(myProject, new Runnable() { + @Override + public void run() { + try { + for (Map.Entry entry : myEditors.entrySet()) { + final Editor translationEditor = entry.getValue(); + if (translationEditor != editor) { + final PropertiesFile propertiesFile = entry.getKey(); + myPropertiesInsertDeleteManager.insertOrUpdateTranslation(currentSelectedProperty, valueToPropagate, propertiesFile); + translationEditor.getDocument().setText(valueToPropagate); + } + } + } + catch (final IncorrectOperationException e) { + LOG.error(e); + } + } + }); + } + }); + } + }); EditorPopupHandler handler = EditorActionUtil.createEditorPopupHandler(group); handler.invokePopup(event); event.consume(); diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManager.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesUpdateManager.java similarity index 68% rename from plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManager.java rename to plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesUpdateManager.java index f7cf28761864..e6fb9191c8f9 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManager.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesUpdateManager.java @@ -16,26 +16,27 @@ package com.intellij.lang.properties.editor; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.util.IncorrectOperationException; /** * @author Dmitry Batkovich */ -public interface ResourceBundlePropertiesInsertManager { +public interface ResourceBundlePropertiesUpdateManager { void insertNewProperty(String key, String value); - void insertTranslation(String key, String value, PropertiesFile propertiesFile); + void insertOrUpdateTranslation(String key, String value, PropertiesFile propertiesFile) throws IncorrectOperationException; void reload(); - class Stub implements ResourceBundlePropertiesInsertManager { - public static final ResourceBundlePropertiesInsertManager INSTANCE = new Stub(); + class Stub implements ResourceBundlePropertiesUpdateManager { + public static final ResourceBundlePropertiesUpdateManager INSTANCE = new Stub(); @Override public void insertNewProperty(String key, String value) { } @Override - public void insertTranslation(String key, String value, PropertiesFile propertiesFile) { + public void insertOrUpdateTranslation(String key, String value, PropertiesFile propertiesFile) { } @Override diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManagerImpl.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesUpdateManagerImpl.java similarity index 88% rename from plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManagerImpl.java rename to plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesUpdateManagerImpl.java index 9e9a05e4c2b7..45281074d637 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManagerImpl.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesUpdateManagerImpl.java @@ -26,6 +26,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiWhiteSpace; +import com.intellij.util.IncorrectOperationException; import com.intellij.util.graph.CachingSemiGraph; import com.intellij.util.graph.DFSTBuilder; import com.intellij.util.graph.GraphGenerator; @@ -37,26 +38,26 @@ import java.util.*; /** * @author Dmitry Batkovich */ -public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundlePropertiesInsertManager { - private final static Logger LOG = Logger.getInstance(ResourceBundlePropertiesInsertManagerImpl.class); +public class ResourceBundlePropertiesUpdateManagerImpl implements ResourceBundlePropertiesUpdateManager { + private final static Logger LOG = Logger.getInstance(ResourceBundlePropertiesUpdateManagerImpl.class); private final ResourceBundle myResourceBundle; private boolean myOrdered; private boolean myAlphaSorted; private List myKeysOrder; - private ResourceBundlePropertiesInsertManagerImpl(ResourceBundle bundle) { + private ResourceBundlePropertiesUpdateManagerImpl(ResourceBundle bundle) { myResourceBundle = bundle; reload(); } - public static ResourceBundlePropertiesInsertManager create(ResourceBundle bundle) { + public static ResourceBundlePropertiesUpdateManager create(ResourceBundle bundle) { for (PropertiesFile file : bundle.getPropertiesFiles()) { if (!(file instanceof PropertiesFileImpl)) { - return ResourceBundlePropertiesInsertManager.Stub.INSTANCE; + return ResourceBundlePropertiesUpdateManager.Stub.INSTANCE; } } - return new ResourceBundlePropertiesInsertManagerImpl(bundle); + return new ResourceBundlePropertiesUpdateManagerImpl(bundle); } @Override @@ -76,15 +77,21 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle } @Override - public void insertTranslation(String key, String value, final PropertiesFile propertiesFile) { + public void insertOrUpdateTranslation(String key, String value, final PropertiesFile propertiesFile) throws IncorrectOperationException { + final IProperty property = propertiesFile.findPropertyByKey(key); + if (property != null) { + property.setValue(value); + } + if (myOrdered) { if (myAlphaSorted) { propertiesFile.addProperty(key, value); return; } final Pair propertyAndPosition = findExistedPrevSiblingProperty(key, propertiesFile); - propertiesFile.addPropertyAfter(key, value, propertyAndPosition == null ? null :(Property)propertyAndPosition.getFirst()); - } else { + propertiesFile.addPropertyAfter(key, value, propertyAndPosition == null ? null : (Property)propertyAndPosition.getFirst()); + } + else { insertPropertyLast(key, value, propertiesFile); } } diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java index e6e8fa495a5c..88eefa471644 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java @@ -26,11 +26,9 @@ import com.intellij.lang.properties.psi.Property; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ide.CopyPasteManager; -import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; -import com.intellij.psi.impl.FakePsiElement; import com.intellij.psi.util.PsiUtilCore; import com.intellij.refactoring.safeDelete.SafeDeleteHandler; import com.intellij.ui.PopupHandler; @@ -149,10 +147,10 @@ public class ResourceBundleStructureViewComponent extends PropertiesGroupingStru } private class PsiElementsDeleteProvider implements DeleteProvider { - private final ResourceBundlePropertiesInsertManager myInsertDeleteManager; + private final ResourceBundlePropertiesUpdateManager myInsertDeleteManager; private final PsiElement[] myElements; - private PsiElementsDeleteProvider(ResourceBundlePropertiesInsertManager insertDeleteManager, final PsiElement[] elements) { + private PsiElementsDeleteProvider(ResourceBundlePropertiesUpdateManager insertDeleteManager, final PsiElement[] elements) { myInsertDeleteManager = insertDeleteManager; myElements = elements; } diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleEditorInsertManagerTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleEditorInsertManagerTest.java index c4aa56d1d458..a39b092466ff 100644 --- a/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleEditorInsertManagerTest.java +++ b/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleEditorInsertManagerTest.java @@ -15,8 +15,8 @@ */ package com.intellij.lang.properties; -import com.intellij.lang.properties.editor.ResourceBundlePropertiesInsertManager; -import com.intellij.lang.properties.editor.ResourceBundlePropertiesInsertManagerImpl; +import com.intellij.lang.properties.editor.ResourceBundlePropertiesUpdateManager; +import com.intellij.lang.properties.editor.ResourceBundlePropertiesUpdateManagerImpl; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.openapi.application.PluginPathManager; import com.intellij.psi.PsiFile; @@ -39,26 +39,27 @@ public class ResourceBundleEditorInsertManagerTest extends LightPlatformCodeInsi myFixture.configureByFile(getTestName(true) + "/p_fr.properties"); final PsiFile file = myFixture.configureByFile(getTestName(true) + "/p_ru.properties"); final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file); - final ResourceBundlePropertiesInsertManager manager = ResourceBundlePropertiesInsertManagerImpl.create(propertiesFile.getResourceBundle()); + final ResourceBundlePropertiesUpdateManager + manager = ResourceBundlePropertiesUpdateManagerImpl.create(propertiesFile.getResourceBundle()); manager.reload(); - assertTrue(((ResourceBundlePropertiesInsertManagerImpl)manager).isAlphaSorted()); + assertTrue(((ResourceBundlePropertiesUpdateManagerImpl)manager).isAlphaSorted()); } public void testAddToAlphaOrdered() { doTest(new TestAction() { @Override - public void doTestAction(PropertiesFile baseFile, PropertiesFile translationFile, ResourceBundlePropertiesInsertManagerImpl manager) { + public void doTestAction(PropertiesFile baseFile, PropertiesFile translationFile, ResourceBundlePropertiesUpdateManagerImpl manager) { assertTrue(manager.isAlphaSorted()); manager.insertNewProperty("l", "v"); - manager.insertTranslation("d", "v", baseFile); - manager.insertTranslation("r", "v", translationFile); + manager.insertOrUpdateTranslation("d", "v", baseFile); + manager.insertOrUpdateTranslation("r", "v", translationFile); manager.insertNewProperty("a", "v"); - manager.insertTranslation("a", "v", translationFile); + manager.insertOrUpdateTranslation("a", "v", translationFile); manager.insertNewProperty("z", "v"); - manager.insertTranslation("z", "v", translationFile); - manager.insertTranslation("l", "v", translationFile); - manager.insertTranslation("e", "v", translationFile); - manager.insertTranslation("t", "v", baseFile); + manager.insertOrUpdateTranslation("z", "v", translationFile); + manager.insertOrUpdateTranslation("l", "v", translationFile); + manager.insertOrUpdateTranslation("e", "v", translationFile); + manager.insertOrUpdateTranslation("t", "v", baseFile); } }); } @@ -66,13 +67,13 @@ public class ResourceBundleEditorInsertManagerTest extends LightPlatformCodeInsi public void testAddToOrdered() { doTest(new TestAction() { @Override - public void doTestAction(PropertiesFile baseFile, PropertiesFile translationFile, ResourceBundlePropertiesInsertManagerImpl manager) { + public void doTestAction(PropertiesFile baseFile, PropertiesFile translationFile, ResourceBundlePropertiesUpdateManagerImpl manager) { assertFalse(manager.isAlphaSorted()); manager.insertNewProperty("bnm", "v"); manager.insertNewProperty("uio", "v"); - manager.insertTranslation("uio", "v", translationFile); - manager.insertTranslation("qwe", "v", translationFile); - manager.insertTranslation("zxc", "v", baseFile); + manager.insertOrUpdateTranslation("uio", "v", translationFile); + manager.insertOrUpdateTranslation("qwe", "v", translationFile); + manager.insertOrUpdateTranslation("zxc", "v", baseFile); } }); } @@ -80,13 +81,13 @@ public class ResourceBundleEditorInsertManagerTest extends LightPlatformCodeInsi public void testAddToUnordered() { doTest(new TestAction() { @Override - public void doTestAction(PropertiesFile baseFile, PropertiesFile translationFile, ResourceBundlePropertiesInsertManagerImpl manager) { + public void doTestAction(PropertiesFile baseFile, PropertiesFile translationFile, ResourceBundlePropertiesUpdateManagerImpl manager) { assertFalse(manager.isAlphaSorted()); - manager.insertTranslation("bnm", "v", translationFile); + manager.insertOrUpdateTranslation("bnm", "v", translationFile); manager.insertNewProperty("ghj", "v"); - manager.insertTranslation("ghj", "v", translationFile); + manager.insertOrUpdateTranslation("ghj", "v", translationFile); manager.insertNewProperty("uio", "v"); - manager.insertTranslation("uio", "v", translationFile); + manager.insertOrUpdateTranslation("uio", "v", translationFile); } }); } @@ -97,15 +98,15 @@ public class ResourceBundleEditorInsertManagerTest extends LightPlatformCodeInsi final PropertiesFile basePropertiesFile = PropertiesImplUtil.getPropertiesFile(baseFile); assertNotNull(basePropertiesFile); final ResourceBundle bundle = basePropertiesFile.getResourceBundle(); - final ResourceBundlePropertiesInsertManager manager = ResourceBundlePropertiesInsertManagerImpl.create(bundle); - assertInstanceOf(manager, ResourceBundlePropertiesInsertManagerImpl.class); + final ResourceBundlePropertiesUpdateManager manager = ResourceBundlePropertiesUpdateManagerImpl.create(bundle); + assertInstanceOf(manager, ResourceBundlePropertiesUpdateManagerImpl.class); testAction.doTestAction(basePropertiesFile, PropertiesImplUtil.getPropertiesFile(translationFile), - (ResourceBundlePropertiesInsertManagerImpl)manager); + (ResourceBundlePropertiesUpdateManagerImpl)manager); myFixture.checkResultByFile(getTestName(true) + "/p.properties", getTestName(true) + "/p-after.properties", true); myFixture.checkResultByFile(getTestName(true) + "/p_en.properties", getTestName(true) + "/p-after_en.properties",true); } private interface TestAction { - void doTestAction(PropertiesFile baseFile, PropertiesFile translationFile, ResourceBundlePropertiesInsertManagerImpl manager); + void doTestAction(PropertiesFile baseFile, PropertiesFile translationFile, ResourceBundlePropertiesUpdateManagerImpl manager); } }