mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
resource bundle editor: ignore locales for incomplete properties by alt+enter + added fake inspection
This commit is contained in:
+19
-15
@@ -53,7 +53,7 @@ import java.util.*;
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>, SpeedSearchFilter<IntentionActionWithTextCaching> {
|
||||
public class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>, SpeedSearchFilter<IntentionActionWithTextCaching> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.impl.IntentionListStep");
|
||||
|
||||
private final Set<IntentionActionWithTextCaching> myCachedIntentions =
|
||||
@@ -65,6 +65,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
|
||||
private final IntentionManagerSettings mySettings;
|
||||
@Nullable
|
||||
private final IntentionHintComponent myIntentionHintComponent;
|
||||
@Nullable
|
||||
private final Editor myEditor;
|
||||
private final PsiFile myFile;
|
||||
private final Project myProject;
|
||||
@@ -81,9 +82,9 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
|
||||
};
|
||||
private Runnable myFinalRunnable;
|
||||
|
||||
IntentionListStep(@Nullable IntentionHintComponent intentionHintComponent,
|
||||
public IntentionListStep(@Nullable IntentionHintComponent intentionHintComponent,
|
||||
@NotNull ShowIntentionsPass.IntentionsInfo intentions,
|
||||
@NotNull Editor editor,
|
||||
@Nullable Editor editor,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull Project project) {
|
||||
this(intentionHintComponent, editor, file, project);
|
||||
@@ -91,7 +92,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
|
||||
}
|
||||
|
||||
IntentionListStep(@Nullable IntentionHintComponent intentionHintComponent,
|
||||
@NotNull Editor editor,
|
||||
@Nullable Editor editor,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull Project project) {
|
||||
myIntentionHintComponent = intentionHintComponent;
|
||||
@@ -113,7 +114,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
|
||||
private boolean wrapActionsTo(@NotNull List<HighlightInfo.IntentionActionDescriptor> newDescriptors,
|
||||
@NotNull Set<IntentionActionWithTextCaching> cachedActions,
|
||||
boolean callUpdate) {
|
||||
final int caretOffset = myEditor.getCaretModel().getOffset();
|
||||
final int caretOffset = myEditor == null ? 0 : myEditor.getCaretModel().getOffset();
|
||||
final int fileOffset = caretOffset > 0 && caretOffset == myFile.getTextLength() ? caretOffset - 1 : caretOffset;
|
||||
PsiElement element;
|
||||
final PsiElement hostElement;
|
||||
@@ -121,7 +122,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
|
||||
hostElement = element = myFile;
|
||||
|
||||
}
|
||||
else if (PsiDocumentManager.getInstance(myProject).isUncommited(myEditor.getDocument())) {
|
||||
else if (myEditor != null && PsiDocumentManager.getInstance(myProject).isUncommited(myEditor.getDocument())) {
|
||||
//???
|
||||
FileViewProvider viewProvider = myFile.getViewProvider();
|
||||
hostElement = element = viewProvider.findElementAt(fileOffset, viewProvider.getBaseLanguage());
|
||||
@@ -138,14 +139,14 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
|
||||
}
|
||||
else {
|
||||
injectedFile = element.getContainingFile();
|
||||
injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(myEditor, injectedFile);
|
||||
injectedEditor = myEditor == null ? null : InjectedLanguageUtil.getInjectedEditorForInjectedFile(myEditor, injectedFile);
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
for (Iterator<IntentionActionWithTextCaching> iterator = cachedActions.iterator(); iterator.hasNext();) {
|
||||
IntentionActionWithTextCaching cachedAction = iterator.next();
|
||||
IntentionAction action = cachedAction.getAction();
|
||||
if (!ShowIntentionActionsHandler.availableFor(myFile, myEditor, action)
|
||||
if (myEditor != null && !ShowIntentionActionsHandler.availableFor(myFile, myEditor, action)
|
||||
&& (hostElement == element || element != null && !ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) {
|
||||
iterator.remove();
|
||||
changed = true;
|
||||
@@ -155,12 +156,12 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
|
||||
Set<IntentionActionWithTextCaching> wrappedNew = new THashSet<IntentionActionWithTextCaching>(newDescriptors.size(), ACTION_TEXT_AND_CLASS_EQUALS);
|
||||
for (HighlightInfo.IntentionActionDescriptor descriptor : newDescriptors) {
|
||||
final IntentionAction action = descriptor.getAction();
|
||||
if (element != null && element != hostElement && (!callUpdate || ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) {
|
||||
if (element != null && element != hostElement && (!callUpdate || myEditor == null || ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) {
|
||||
IntentionActionWithTextCaching cachedAction = wrapAction(descriptor, element, injectedFile, injectedEditor);
|
||||
wrappedNew.add(cachedAction);
|
||||
changed |= cachedActions.add(cachedAction);
|
||||
}
|
||||
else if (hostElement != null && (!callUpdate || ShowIntentionActionsHandler.availableFor(myFile, myEditor, action))) {
|
||||
else if (hostElement != null && (!callUpdate || myEditor == null || ShowIntentionActionsHandler.availableFor(myFile, myEditor, action))) {
|
||||
IntentionActionWithTextCaching cachedAction = wrapAction(descriptor, hostElement, myFile, myEditor);
|
||||
wrappedNew.add(cachedAction);
|
||||
changed |= cachedActions.add(cachedAction);
|
||||
@@ -181,7 +182,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
|
||||
IntentionActionWithTextCaching wrapAction(@NotNull HighlightInfo.IntentionActionDescriptor descriptor,
|
||||
@NotNull PsiElement element,
|
||||
@NotNull PsiFile containingFile,
|
||||
@NotNull Editor containingEditor) {
|
||||
@Nullable Editor containingEditor) {
|
||||
IntentionActionWithTextCaching cachedAction = new IntentionActionWithTextCaching(descriptor);
|
||||
final List<IntentionAction> options = descriptor.getOptions(element, containingEditor);
|
||||
if (options == null) return cachedAction;
|
||||
@@ -252,12 +253,15 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
|
||||
}
|
||||
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
final PsiFile file = PsiUtilBase.getPsiFileInEditor(myEditor, myProject);
|
||||
if (file == null) {
|
||||
return;
|
||||
PsiFile file = null;
|
||||
if (myEditor != null) {
|
||||
file = PsiUtilBase.getPsiFileInEditor(myEditor, myProject);
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ShowIntentionActionsHandler.chooseActionAndInvoke(file, myEditor, cachedAction.getAction(), cachedAction.getText());
|
||||
ShowIntentionActionsHandler.chooseActionAndInvoke(file, myEditor, cachedAction.getAction(), cachedAction.getText(), myProject);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+15
-7
@@ -166,31 +166,39 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler {
|
||||
@NotNull final Editor hostEditor,
|
||||
@NotNull final IntentionAction action,
|
||||
@NotNull String text) {
|
||||
if (!hostFile.isValid()) return false;
|
||||
final Project project = hostFile.getProject();
|
||||
return chooseActionAndInvoke(hostFile, hostEditor, action, text, project);
|
||||
}
|
||||
|
||||
public static boolean chooseActionAndInvoke(@Nullable PsiFile hostFile,
|
||||
@Nullable final Editor hostEditor,
|
||||
@NotNull final IntentionAction action,
|
||||
@NotNull String text,
|
||||
@NotNull final Project project) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.quickFix");
|
||||
((FeatureUsageTrackerImpl)FeatureUsageTracker.getInstance()).getFixesStats().registerInvocation();
|
||||
|
||||
Pair<PsiFile, Editor> pair = chooseBetweenHostAndInjected(hostFile, hostEditor, new PairProcessor<PsiFile, Editor>() {
|
||||
final Pair<PsiFile, Editor> pair = hostEditor != null && hostFile != null
|
||||
? chooseBetweenHostAndInjected(hostFile, hostEditor, new PairProcessor<PsiFile, Editor>() {
|
||||
@Override
|
||||
public boolean process(PsiFile psiFile, Editor editor) {
|
||||
return availableFor(psiFile, editor, action);
|
||||
}
|
||||
});
|
||||
}) : Pair.<PsiFile, Editor>create(null, null);
|
||||
if (pair == null) return false;
|
||||
final Editor editorToApply = pair.second;
|
||||
final PsiFile fileToApply = pair.first;
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
action.invoke(project, editorToApply, fileToApply);
|
||||
action.invoke(project, pair.second, pair.first);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
DaemonCodeAnalyzer.getInstance(project).updateVisibleHighlighters(hostEditor);
|
||||
if (hostEditor != null) {
|
||||
DaemonCodeAnalyzer.getInstance(project).updateVisibleHighlighters(hostEditor);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+13
-3
@@ -28,6 +28,7 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -67,18 +68,27 @@ public class DisableInspectionToolAction extends IntentionAndQuickFixAction impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, PsiFile file, @Nullable Editor editor) {
|
||||
public void applyFix(@NotNull Project project, final PsiFile file, @Nullable Editor editor) {
|
||||
modifyAndCommitProjectProfile(new Consumer<ModifiableModel>() {
|
||||
@Override
|
||||
public void consume(ModifiableModel modifiableModel) {
|
||||
modifiableModel.disableTool(myToolId, file);
|
||||
}
|
||||
}, project);
|
||||
DaemonCodeAnalyzer.getInstance(project).restart();
|
||||
}
|
||||
|
||||
public static void modifyAndCommitProjectProfile(Consumer<ModifiableModel> action, Project project) {
|
||||
InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(project);
|
||||
InspectionProfile inspectionProfile = profileManager.getInspectionProfile();
|
||||
ModifiableModel model = inspectionProfile.getModifiableModel();
|
||||
model.disableTool(myToolId, file);
|
||||
action.consume(model);
|
||||
try {
|
||||
model.commit();
|
||||
}
|
||||
catch (IOException e) {
|
||||
Messages.showErrorDialog(project, e.getMessage(), CommonBundle.getErrorTitle());
|
||||
}
|
||||
DaemonCodeAnalyzer.getInstance(project).restart();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-1
@@ -78,4 +78,7 @@ create.resource.bundle.dialog.add.locales.validator.title=Add Locales
|
||||
|
||||
add.property.files.to.resource.bundle.dialog.action.title=Add Property Files to Resource Bundle
|
||||
|
||||
resource.bundle.editor.settings.action.title=Resource bundle editor settings
|
||||
resource.bundle.editor.settings.action.title=Resource bundle editor settings
|
||||
incomplete.property.inspection.display.name=Property is incomplete
|
||||
incomplete.property.quick.fix.name=Ignore untranslated locales
|
||||
incomplete.property.inspection.description=Property ''{0}'' is incomplete
|
||||
-160
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor;
|
||||
|
||||
import com.intellij.lang.properties.PropertiesUtil;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.xmlb.annotations.AbstractCollection;
|
||||
import com.intellij.util.xmlb.annotations.Property;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
@State(
|
||||
name = "IgnoredPropertiesFilesSuffixesManager",
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.PROJECT_FILE),
|
||||
@Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/resourceBundles.xml", scheme = StorageScheme.DIRECTORY_BASED)
|
||||
})
|
||||
public class IgnoredPropertiesFilesSuffixesManager implements PersistentStateComponent<IgnoredPropertiesFilesSuffixesManager.IgnoredPropertiesFilesSuffixesState>, Disposable {
|
||||
private IgnoredPropertiesFilesSuffixesState myState = new IgnoredPropertiesFilesSuffixesState();
|
||||
private final List<SuffixesListener> myListeners = new ArrayList<SuffixesListener>();
|
||||
|
||||
public IgnoredPropertiesFilesSuffixesManager(final Project project) {
|
||||
Disposer.register(project, this);
|
||||
}
|
||||
|
||||
public static IgnoredPropertiesFilesSuffixesManager getInstance(final Project project) {
|
||||
return ServiceManager.getService(project, IgnoredPropertiesFilesSuffixesManager.class);
|
||||
}
|
||||
|
||||
public void addListener(final SuffixesListener listener) {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(final SuffixesListener listener) {
|
||||
myListeners.remove(listener);
|
||||
}
|
||||
|
||||
public boolean isPropertyComplete(final ResourceBundle resourceBundle, final String key) {
|
||||
List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
|
||||
for (PropertiesFile propertiesFile : propertiesFiles) {
|
||||
if (propertiesFile.findPropertyByKey(key) == null && !myState.getIgnoredSuffixes().contains(PropertiesUtil.getSuffix(propertiesFile))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Set<String> getIgnoredSuffixes() {
|
||||
return myState.getIgnoredSuffixes();
|
||||
}
|
||||
|
||||
public List<PropertiesFile> getPropertiesFilesWithoutTranslation(final ResourceBundle resourceBundle, final Set<String> keys) {
|
||||
final PropertiesFile defaultPropertiesFile = resourceBundle.getDefaultPropertiesFile();
|
||||
return ContainerUtil.filter(resourceBundle.getPropertiesFiles(), new Condition<PropertiesFile>() {
|
||||
@Override
|
||||
public boolean value(PropertiesFile propertiesFile) {
|
||||
if (defaultPropertiesFile.equals(propertiesFile)) {
|
||||
return false;
|
||||
}
|
||||
for (String key : keys) {
|
||||
if (propertiesFile.findPropertyByKey(key) == null && !myState.getIgnoredSuffixes().contains(PropertiesUtil.getSuffix(propertiesFile))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addSuffixes(Collection<String> suffixes) {
|
||||
final Set<String> oldSuffixes = new HashSet<String>(myState.getIgnoredSuffixes());
|
||||
myState.addSuffixes(suffixes);
|
||||
final Set<String> newSuffixes = myState.getIgnoredSuffixes();
|
||||
if (!oldSuffixes.equals(newSuffixes)) {
|
||||
for (SuffixesListener listener : myListeners) {
|
||||
listener.suffixesChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setSuffixes(Collection<String> suffixes) {
|
||||
final Set<String> oldSuffixes = myState.getIgnoredSuffixes();
|
||||
myState.setSuffixes(suffixes);
|
||||
if (!oldSuffixes.equals(suffixes)) {
|
||||
for (SuffixesListener listener : myListeners) {
|
||||
listener.suffixesChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IgnoredPropertiesFilesSuffixesState getState() {
|
||||
return myState.isEmpty() ? null : myState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(IgnoredPropertiesFilesSuffixesState state) {
|
||||
myState = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (!myListeners.isEmpty()) {
|
||||
myListeners.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static class IgnoredPropertiesFilesSuffixesState {
|
||||
@Property(surroundWithTag = false)
|
||||
@AbstractCollection(elementTag = "ignored-suffix", surroundWithTag = false)
|
||||
public Set<String> myIgnoredSuffixes = new HashSet<String>();
|
||||
|
||||
public void addSuffixes(Collection<String> suffixes) {
|
||||
myIgnoredSuffixes.addAll(suffixes);
|
||||
}
|
||||
|
||||
public void setSuffixes(Collection<String> suffixes) {
|
||||
myIgnoredSuffixes = new HashSet<String>(suffixes);
|
||||
}
|
||||
|
||||
public Set<String> getIgnoredSuffixes() {
|
||||
return myIgnoredSuffixes;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return myIgnoredSuffixes.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public interface SuffixesListener {
|
||||
void suffixesChanged();
|
||||
}
|
||||
}
|
||||
+25
-25
@@ -22,13 +22,15 @@ package com.intellij.lang.properties.editor;
|
||||
import com.intellij.ide.structureView.StructureViewTreeElement;
|
||||
import com.intellij.lang.properties.*;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.navigation.ColoredItemPresentation;
|
||||
import com.intellij.lang.properties.editor.inspections.ResourceBundleEditorInspectionPass;
|
||||
import com.intellij.lang.properties.editor.inspections.ResourceBundleEditorProblemDescriptor;
|
||||
import com.intellij.lang.properties.editor.inspections.ResourceBundleEditorRenderer;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -37,32 +39,23 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class ResourceBundlePropertyStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement {
|
||||
private final ResourceBundle myResourceBundle;
|
||||
@NotNull private final PropertiesAnchorizer.PropertyAnchor myAnchor;
|
||||
private String myPresentableName;
|
||||
|
||||
private static final TextAttributesKey INCOMPLETE_PROPERTY_KEY;
|
||||
private static final TextAttributesKey INCOMPLETE_GROUP_KEY;
|
||||
private static final TextAttributesKey GROUP_KEY;
|
||||
|
||||
public static final String PROPERTY_GROUP_KEY_TEXT = "<property>";
|
||||
|
||||
static {
|
||||
TextAttributes incompleteKeyTextAttributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(PropertiesHighlighter.PROPERTY_KEY).clone();
|
||||
incompleteKeyTextAttributes.setForegroundColor(JBColor.RED);
|
||||
INCOMPLETE_PROPERTY_KEY = TextAttributesKey.createTextAttributesKey("INCOMPLETE_PROPERTY_KEY", incompleteKeyTextAttributes);
|
||||
private final @NotNull PropertiesAnchorizer.PropertyAnchor myAnchor;
|
||||
private String myPresentableName;
|
||||
|
||||
|
||||
static {
|
||||
TextAttributes groupKeyTextAttributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(PropertiesHighlighter.PROPERTY_KEY).clone();
|
||||
groupKeyTextAttributes.setFontType(Font.ITALIC);
|
||||
GROUP_KEY = TextAttributesKey.createTextAttributesKey("GROUP_KEY", groupKeyTextAttributes);
|
||||
|
||||
final TextAttributes incompleteGroupKeyTextAttribute = groupKeyTextAttributes.clone();
|
||||
incompleteGroupKeyTextAttribute.setForegroundColor(JBColor.RED);
|
||||
INCOMPLETE_GROUP_KEY = TextAttributesKey.createTextAttributesKey("INCOMPLETE_GROUP_KEY", incompleteGroupKeyTextAttribute);
|
||||
}
|
||||
|
||||
private ResourceBundleEditorInspectionPass.InspectionPassInfo myInspectionPassInfo;
|
||||
|
||||
public ResourceBundlePropertyStructureViewElement(final ResourceBundle resourceBundle, final @NotNull PropertiesAnchorizer.PropertyAnchor anchor) {
|
||||
myResourceBundle = resourceBundle;
|
||||
myAnchor = anchor;
|
||||
}
|
||||
|
||||
@@ -97,10 +90,16 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ResourceBundleEditorProblemDescriptor[] getProblemDescriptors() {
|
||||
return myInspectionPassInfo.getDescriptors();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ItemPresentation getPresentation() {
|
||||
return new ColoredItemPresentation() {
|
||||
return new ResourceBundleEditorRenderer.TextAttributesPresentation() {
|
||||
|
||||
@Override
|
||||
public String getPresentableText() {
|
||||
return myPresentableName == null ? getProperty().getName() : myPresentableName.isEmpty() ? PROPERTY_GROUP_KEY_TEXT : myPresentableName;
|
||||
@@ -117,14 +116,15 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextAttributesKey getTextAttributesKey() {
|
||||
final IgnoredPropertiesFilesSuffixesManager
|
||||
ignoredPropertiesFilesSuffixesManager = IgnoredPropertiesFilesSuffixesManager.getInstance(myResourceBundle.getProject());
|
||||
final boolean isPropertyComplete = ignoredPropertiesFilesSuffixesManager.isPropertyComplete(myResourceBundle, getProperty().getName());
|
||||
if (myPresentableName != null && myPresentableName.isEmpty()) {
|
||||
return isPropertyComplete ? GROUP_KEY : INCOMPLETE_GROUP_KEY;
|
||||
public TextAttributes getTextAttributes(EditorColorsScheme colorsScheme) {
|
||||
myInspectionPassInfo = ResourceBundleEditorInspectionPass.inspect(getProperty().getKey(), getProperty().getPropertiesFile().getResourceBundle());
|
||||
final TextAttributesKey baseAttrKey = (myPresentableName != null && myPresentableName.isEmpty()) ? GROUP_KEY : PropertiesHighlighter.PROPERTY_KEY;
|
||||
final TextAttributes baseAttrs = colorsScheme.getAttributes(baseAttrKey);
|
||||
TextAttributes highlightingAttributes = myInspectionPassInfo.getTextAttributes(colorsScheme);
|
||||
if (highlightingAttributes != null) {
|
||||
return TextAttributes.merge(baseAttrs, highlightingAttributes);
|
||||
}
|
||||
return isPropertyComplete ? PropertiesHighlighter.PROPERTY_KEY : INCOMPLETE_PROPERTY_KEY;
|
||||
return baseAttrs;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor.inspections;
|
||||
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public abstract class ResourceBundleEditorInspection extends LocalInspectionTool {
|
||||
|
||||
@Nullable
|
||||
public abstract ResourceBundleEditorProblemDescriptor[] checkPropertyGroup(@NotNull List<IProperty> properties,
|
||||
@NotNull ResourceBundle resourceBundle);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public final PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return PsiElementVisitor.EMPTY_VISITOR;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public final PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder,
|
||||
boolean isOnTheFly,
|
||||
@NotNull LocalInspectionToolSession session) {
|
||||
return PsiElementVisitor.EMPTY_VISITOR;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public final ProblemDescriptor[] checkFile(@NotNull PsiFile file,
|
||||
@NotNull InspectionManager manager,
|
||||
boolean isOnTheFly) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor.inspections;
|
||||
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
|
||||
import com.intellij.codeInspection.ProblemDescriptorUtil;
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
import com.intellij.codeInspection.ex.InspectionProfileWrapper;
|
||||
import com.intellij.codeInspection.ex.InspectionToolWrapper;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManagerImpl;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class ResourceBundleEditorInspectionPass {
|
||||
@Nullable
|
||||
public static InspectionPassInfo inspect(@NotNull final String key, ResourceBundle resourceBundle) {
|
||||
final List<IProperty> properties =
|
||||
ContainerUtil.mapNotNull(resourceBundle.getPropertiesFiles(), new Function<PropertiesFile, IProperty>() {
|
||||
@Override
|
||||
public IProperty fun(PropertiesFile propertiesFile) {
|
||||
return propertiesFile.findPropertyByKey(key);
|
||||
}
|
||||
});
|
||||
|
||||
if (properties.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final IProperty property = properties.get(0);
|
||||
final PsiElement representativeElement = property.getPsiElement();
|
||||
final PsiFile representativeFile = representativeElement.getContainingFile();
|
||||
|
||||
final Project project = representativeElement.getProject();
|
||||
|
||||
InspectionProfileWrapper profileToUse = InspectionProjectProfileManagerImpl.getInstanceImpl(project).getProfileWrapper();
|
||||
final PsiFile containingFile = representativeFile.getContainingFile();
|
||||
final InspectionToolWrapper[] propertiesTools = profileToUse.getInspectionTools(containingFile);
|
||||
|
||||
List<ResourceBundleEditorProblemDescriptor> allDescriptors = new SmartList<ResourceBundleEditorProblemDescriptor>();
|
||||
SortedSet<HighlightInfoType> highlightTypes = new TreeSet<HighlightInfoType>(new Comparator<HighlightInfoType>() {
|
||||
@Override
|
||||
public int compare(HighlightInfoType o1, HighlightInfoType o2) {
|
||||
final HighlightSeverity s1 = o1.getSeverity(null);
|
||||
final HighlightSeverity s2 = o2.getSeverity(null);
|
||||
return Comparing.compare(s1, s2);
|
||||
}
|
||||
});
|
||||
|
||||
for (InspectionToolWrapper tool : propertiesTools) {
|
||||
final HighlightDisplayKey toolKey;
|
||||
if (tool.getTool() instanceof ResourceBundleEditorInspection &&
|
||||
profileToUse.isToolEnabled(toolKey = HighlightDisplayKey.find(tool.getShortName()), containingFile)) {
|
||||
final ResourceBundleEditorInspection inspection = (ResourceBundleEditorInspection)tool.getTool();
|
||||
final ResourceBundleEditorProblemDescriptor[] descriptors = inspection.checkPropertyGroup(properties, resourceBundle);
|
||||
if (descriptors != null) {
|
||||
for (ResourceBundleEditorProblemDescriptor descriptor : descriptors) {
|
||||
final QuickFix[] currentFixes = descriptor.getFixes();
|
||||
if (currentFixes != null && currentFixes.length != 0) {
|
||||
Collections.addAll(allDescriptors, descriptor);
|
||||
}
|
||||
HighlightSeverity severity = profileToUse.getInspectionProfile().getErrorLevel(toolKey, containingFile).getSeverity();
|
||||
final HighlightInfoType infoType =
|
||||
ProblemDescriptorUtil.highlightTypeFromDescriptor(descriptor, severity, SeverityRegistrar.getSeverityRegistrar(project));
|
||||
highlightTypes.add(infoType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new InspectionPassInfo(allDescriptors.toArray(new ResourceBundleEditorProblemDescriptor[allDescriptors.size()]), highlightTypes);
|
||||
}
|
||||
|
||||
public static class InspectionPassInfo {
|
||||
private final ResourceBundleEditorProblemDescriptor[] myDescriptors;
|
||||
private final SortedSet<HighlightInfoType> myHighlightTypes;
|
||||
|
||||
public InspectionPassInfo(ResourceBundleEditorProblemDescriptor[] descriptors, SortedSet<HighlightInfoType> types) {
|
||||
myDescriptors = descriptors;
|
||||
myHighlightTypes = types;
|
||||
}
|
||||
|
||||
public ResourceBundleEditorProblemDescriptor[] getDescriptors() {
|
||||
return myDescriptors;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TextAttributes getTextAttributes(EditorColorsScheme scheme) {
|
||||
TextAttributes mixedAttributes = null;
|
||||
for (HighlightInfoType type : myHighlightTypes) {
|
||||
final TextAttributes current = scheme.getAttributes(type.getAttributesKey());
|
||||
if (mixedAttributes == null) {
|
||||
mixedAttributes = current;
|
||||
} else {
|
||||
mixedAttributes = TextAttributes.merge(mixedAttributes, current);
|
||||
}
|
||||
}
|
||||
return mixedAttributes;
|
||||
}
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor.inspections;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
import com.intellij.lang.annotation.ProblemGroup;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class ResourceBundleEditorProblemDescriptor implements ProblemDescriptor {
|
||||
private final ProblemHighlightType myHighlightType;
|
||||
private final String myDescriptionTemplate;
|
||||
private final QuickFix[] myFixes;
|
||||
|
||||
public ResourceBundleEditorProblemDescriptor(final ProblemHighlightType type, String template, QuickFix<ResourceBundleEditorProblemDescriptor>... fixes) {
|
||||
myHighlightType = type;
|
||||
myDescriptionTemplate = template;
|
||||
myFixes = fixes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ProblemHighlightType getHighlightType() {
|
||||
return myHighlightType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDescriptionTemplate() {
|
||||
return myDescriptionTemplate;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public QuickFix[] getFixes() {
|
||||
return myFixes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getPsiElement() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getStartElement() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getEndElement() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getTextRangeInElement() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineNumber() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterEndOfLine() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTextAttributes(TextAttributesKey key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProblemGroup getProblemGroup() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProblemGroup(@Nullable ProblemGroup problemGroup) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showTooltip() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor.inspections;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.ide.util.treeView.NodeRenderer;
|
||||
import com.intellij.ide.util.treeView.smartTree.TreeElement;
|
||||
import com.intellij.ide.util.treeView.smartTree.TreeElementWrapper;
|
||||
import com.intellij.lang.properties.editor.ResourceBundlePropertyStructureViewElement;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class ResourceBundleEditorRenderer extends NodeRenderer {
|
||||
|
||||
@Override
|
||||
public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||
if (customize(value)) {
|
||||
return;
|
||||
}
|
||||
super.customizeCellRenderer(tree, value, selected, expanded, leaf, row, hasFocus);
|
||||
}
|
||||
|
||||
private boolean customize(Object value) {
|
||||
final Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
|
||||
if (!(userObject instanceof TreeElementWrapper)) {
|
||||
return false;
|
||||
}
|
||||
final TreeElement treeElement = ((TreeElementWrapper)userObject).getValue();
|
||||
if (treeElement == null) {
|
||||
return false;
|
||||
}
|
||||
final ItemPresentation presentation = treeElement.getPresentation();
|
||||
if (presentation instanceof TextAttributesPresentation) {
|
||||
final TextAttributesPresentation textAttributesPresentation = (TextAttributesPresentation)presentation;
|
||||
final String text = textAttributesPresentation.getPresentableText();
|
||||
if (text != null) {
|
||||
final SimpleTextAttributes attr =
|
||||
SimpleTextAttributes.fromTextAttributes(textAttributesPresentation.getTextAttributes(getColorsScheme()));
|
||||
append(text, new SimpleTextAttributes(attr.getBgColor(), attr.getFgColor(), attr.getWaveColor(),
|
||||
attr.getStyle() | SimpleTextAttributes.STYLE_OPAQUE));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public interface TextAttributesPresentation extends ItemPresentation {
|
||||
TextAttributes getTextAttributes(EditorColorsScheme colorsScheme);
|
||||
}
|
||||
}
|
||||
@@ -86,6 +86,10 @@
|
||||
key="wrong.property.key.value.delimiter.inspection.display.name" groupKey="properties.files.inspection.group.display.name"
|
||||
enabledByDefault="true" level="WEAK WARNING" cleanupTool="true"
|
||||
implementationClass="com.intellij.codeInspection.WrongPropertyKeyValueDelimiterInspection"/>
|
||||
<localInspection language="Properties" shortName="IncompleteProperty" bundle="messages.PropertiesBundle"
|
||||
key="incomplete.property.inspection.display.name" groupKey="properties.files.inspection.group.display.name"
|
||||
enabledByDefault="true" level="ERROR" cleanupTool="false"
|
||||
implementationClass="com.intellij.lang.properties.editor.inspections.incomplete.IncompletePropertyInspection"/>
|
||||
|
||||
<idIndexer filetype="Properties" implementationClass="com.intellij.psi.impl.cache.impl.idCache.PropertiesIdIndexer"/>
|
||||
<todoIndexer filetype="Properties" implementationClass="com.intellij.psi.impl.cache.impl.idCache.PropertiesTodoIndexer"/>
|
||||
@@ -107,13 +111,6 @@
|
||||
|
||||
<codeStyleSettingsProvider implementation="com.intellij.lang.properties.psi.codeStyle.PropertiesCodeStyleSettingsProvider"/>
|
||||
|
||||
<projectConfigurable groupId="tools"
|
||||
groupWeight="10"
|
||||
provider="com.intellij.lang.properties.ResourceBundleEditorConfigurable$Provider"
|
||||
id="resource.bundle.editor.highlighting.settings"
|
||||
displayName="Resource Bundle Editor"/>
|
||||
<projectService serviceImplementation="com.intellij.lang.properties.editor.IgnoredPropertiesFilesSuffixesManager"/>
|
||||
|
||||
<internalFileTemplate name="XML Properties File.xml"/>
|
||||
<refactoring.copyHandler implementation="com.intellij.lang.properties.editor.PropertiesCopyHandler"/>
|
||||
</extensions>
|
||||
@@ -156,5 +153,9 @@
|
||||
<action id="CreateResourceBundle" class="com.intellij.lang.properties.create.CreateResourceBundleAction">
|
||||
<add-to-group group-id="NewGroup" anchor="after" relative-to-action="NewFromTemplate"/>
|
||||
</action>
|
||||
<action id="ResourceBundleEditorShowIntentions"
|
||||
class="com.intellij.lang.properties.editor.ResourceBundleEditorShowQuickFixesAction"
|
||||
use-shortcut-of="ShowIntentionActions"/>
|
||||
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties;
|
||||
|
||||
import com.intellij.lang.properties.editor.IgnoredPropertiesFilesSuffixesManager;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.options.BaseConfigurable;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurableProvider;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class ResourceBundleEditorConfigurable extends BaseConfigurable {
|
||||
private final JPanel myPanel;
|
||||
private final CollectionListModel<String> mySuffixesModel;
|
||||
private final IgnoredPropertiesFilesSuffixesManager mySuffixesManager;
|
||||
|
||||
public ResourceBundleEditorConfigurable(@NotNull Project project) {
|
||||
mySuffixesManager = IgnoredPropertiesFilesSuffixesManager.getInstance(project);
|
||||
final JBList list = new JBList();
|
||||
final List<String> suffixes = new ArrayList<String>(mySuffixesManager.getIgnoredSuffixes());
|
||||
mySuffixesModel = new CollectionListModel<String>(suffixes);
|
||||
mySuffixesModel.sort(String.CASE_INSENSITIVE_ORDER);
|
||||
list.setModel(mySuffixesModel);
|
||||
myPanel = ToolbarDecorator.createDecorator(list).disableUpDownActions().setAddAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
final String result = Messages.showInputDialog(CommonDataKeys.PROJECT.getData(button.getDataContext()),
|
||||
"Suffixes to ignore (use comma to separate suffixes):",
|
||||
"Add Ignored Suffixes", null);
|
||||
if (result != null) {
|
||||
final List<String> suffixes = StringUtil.split(result, ",");
|
||||
for (String suffix : suffixes) {
|
||||
if (mySuffixesModel.getElementIndex(suffix) == -1) {
|
||||
mySuffixesModel.add(suffix);
|
||||
}
|
||||
}
|
||||
updateModifiedStatus();
|
||||
mySuffixesModel.sort(String.CASE_INSENSITIVE_ORDER);
|
||||
}
|
||||
}
|
||||
}).setRemoveAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
for (Object toDelete : list.getSelectedValues()) {
|
||||
mySuffixesModel.remove((String)toDelete);
|
||||
}
|
||||
updateModifiedStatus();
|
||||
}
|
||||
}).createPanel();
|
||||
list.setCellRenderer(new ColoredListCellRenderer<String>() {
|
||||
@Override
|
||||
protected void customizeCellRenderer(JList list, String suffix, int index, boolean selected, boolean hasFocus) {
|
||||
append(suffix);
|
||||
final Locale locale = PropertiesUtil.getLocale("_" + suffix + ".properties");
|
||||
if (locale != PropertiesUtil.DEFAULT_LOCALE && PropertiesUtil.hasDefaultLanguage(locale)) {
|
||||
append(" ");
|
||||
append(PropertiesUtil.getPresentableLocale(locale), SimpleTextAttributes.GRAY_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
});
|
||||
myPanel.setBorder(IdeBorderFactory.createTitledBorder("Ignored properties file suffixes:"));
|
||||
}
|
||||
|
||||
@Nls
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Resource Bundle Editor";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getHelpTopic() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
mySuffixesManager.setSuffixes(mySuffixesModel.getItems());
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
mySuffixesModel.removeAll();
|
||||
for (String suffix : mySuffixesManager.getIgnoredSuffixes()) {
|
||||
mySuffixesModel.add(suffix);
|
||||
}
|
||||
mySuffixesModel.sort(String.CASE_INSENSITIVE_ORDER);
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
}
|
||||
|
||||
private void updateModifiedStatus() {
|
||||
setModified(!ContainerUtil.newHashSet(mySuffixesModel.getItems()).equals(mySuffixesManager.getIgnoredSuffixes()));
|
||||
}
|
||||
|
||||
public static class Provider extends ConfigurableProvider {
|
||||
private final Project myProject;
|
||||
|
||||
public Provider(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Configurable createConfigurable() {
|
||||
return new ResourceBundleEditorConfigurable(myProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
-179
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor;
|
||||
|
||||
import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.PropertiesUtil;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.lang.properties.psi.Property;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.CollectionListModel;
|
||||
import com.intellij.ui.ToolbarDecorator;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class IgnoreIncompletePropertyPropertiesFilesAction extends AnAction {
|
||||
private final static Logger LOG = Logger.getInstance(IgnoreIncompletePropertyPropertiesFilesAction.class);
|
||||
|
||||
public IgnoreIncompletePropertyPropertiesFilesAction() {
|
||||
super("Ignore Properties Files Without Translation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final ResourceBundleEditor resourceBundleEditor = (ResourceBundleEditor)PlatformDataKeys.FILE_EDITOR.getData(e.getDataContext());
|
||||
LOG.assertTrue(resourceBundleEditor != null);
|
||||
final Project project = getEventProject(e);
|
||||
LOG.assertTrue(project != null);
|
||||
|
||||
final Set<String> properties = new HashSet<String>();
|
||||
processSelectedIncompleteProperties(new Processor<IProperty>() {
|
||||
@Override
|
||||
public boolean process(IProperty property) {
|
||||
properties.add(property.getKey());
|
||||
return true;
|
||||
}
|
||||
}, resourceBundleEditor, project);
|
||||
|
||||
final IgnoredPropertiesFilesSuffixesManager suffixesManager = IgnoredPropertiesFilesSuffixesManager.getInstance(project);
|
||||
final List<PropertiesFile> allFilesWithoutTranslation =
|
||||
suffixesManager.getPropertiesFilesWithoutTranslation(resourceBundleEditor.getResourceBundle(), properties);
|
||||
if (allFilesWithoutTranslation.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Collections.sort(allFilesWithoutTranslation, new Comparator<PropertiesFile>() {
|
||||
@Override
|
||||
public int compare(PropertiesFile p1, PropertiesFile p2) {
|
||||
return p1.getName().compareTo(p2.getName());
|
||||
}
|
||||
});
|
||||
|
||||
final List<PropertiesFile> suffixRepresentatives =
|
||||
new IgnoredSuffixesDialog(allFilesWithoutTranslation, project).showAndGetSuffixesRepresentatives();
|
||||
if (suffixRepresentatives == null) {
|
||||
return;
|
||||
}
|
||||
final List<String> suffixesToIgnore = ContainerUtil.map(suffixRepresentatives, new NotNullFunction<PropertiesFile, String>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String fun(PropertiesFile propertiesFile) {
|
||||
return PropertiesUtil.getSuffix(propertiesFile);
|
||||
}
|
||||
});
|
||||
if (!suffixesToIgnore.isEmpty()) {
|
||||
suffixesManager.addSuffixes(suffixesToIgnore);
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
resourceBundleEditor.queueUpdateTree();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static class IgnoredSuffixesDialog extends DialogWrapper {
|
||||
@NotNull private final List<PropertiesFile> myPropertiesFiles;
|
||||
private CollectionListModel<PropertiesFile> myModel;
|
||||
|
||||
protected IgnoredSuffixesDialog(@NotNull List<PropertiesFile> propertiesFiles, @NotNull Project project) {
|
||||
super(project);
|
||||
myPropertiesFiles = propertiesFiles;
|
||||
setTitle("Suffixes to Ignore:");
|
||||
init();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
final JBList list = new JBList();
|
||||
myModel = new CollectionListModel<PropertiesFile>(myPropertiesFiles);
|
||||
list.setModel(myModel);
|
||||
list.setCellRenderer(new DefaultListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
final JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
label.setText(PropertiesUtil.getSuffix((PropertiesFile)value));
|
||||
return label;
|
||||
}
|
||||
});
|
||||
return ToolbarDecorator.createDecorator(list).disableUpDownActions().disableAddAction().createPanel();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<PropertiesFile> showAndGetSuffixesRepresentatives() {
|
||||
return showAndGet() ? myModel.getItems() : null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
final FileEditor fileEditor = PlatformDataKeys.FILE_EDITOR.getData(e.getDataContext());
|
||||
if (fileEditor instanceof ResourceBundleEditor) {
|
||||
ResourceBundleEditor resourceBundleEditor = (ResourceBundleEditor)fileEditor;
|
||||
final Project project = getEventProject(e);
|
||||
if (project != null) {
|
||||
if (!processSelectedIncompleteProperties(new Processor<IProperty>() {
|
||||
@Override
|
||||
public boolean process(IProperty property) {
|
||||
return false;
|
||||
}
|
||||
}, resourceBundleEditor, project)) {
|
||||
e.getPresentation().setEnabledAndVisible(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
e.getPresentation().setEnabledAndVisible(false);
|
||||
}
|
||||
|
||||
private static boolean processSelectedIncompleteProperties(final @NotNull Processor<IProperty> processor,
|
||||
final @NotNull ResourceBundleEditor resourceBundleEditor,
|
||||
final @NotNull Project project) {
|
||||
final IgnoredPropertiesFilesSuffixesManager suffixesManager = IgnoredPropertiesFilesSuffixesManager.getInstance(project);
|
||||
for (ResourceBundleEditorViewElement element : resourceBundleEditor.getSelectedElements()) {
|
||||
final IProperty[] properties = element.getProperties();
|
||||
if (properties != null) {
|
||||
for (IProperty property : properties) {
|
||||
if (!suffixesManager.isPropertyComplete(resourceBundleEditor.getResourceBundle(), property.getKey()) && !processor.process(property)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+4
-46
@@ -34,6 +34,7 @@ import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.PropertiesImplUtil;
|
||||
import com.intellij.lang.properties.PropertiesUtil;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.editor.inspections.incomplete.IncompletePropertyInspection;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.lang.properties.psi.PropertiesResourceBundleUtil;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
@@ -111,7 +112,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
private final Set<PropertiesFile> myBackSlashPressed = new THashSet<PropertiesFile>();
|
||||
private final Alarm mySelectionChangeAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
private final PropertiesAnchorizer myPropertiesAnchorizer;
|
||||
private final IgnoredPropertiesFilesSuffixesManager.SuffixesListener mySuffixesListener;
|
||||
|
||||
private JPanel myValuesPanel;
|
||||
private JPanel myStructureViewPanel;
|
||||
@@ -201,14 +201,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
onSelectionChanged(event);
|
||||
}
|
||||
});
|
||||
|
||||
mySuffixesListener = new IgnoredPropertiesFilesSuffixesManager.SuffixesListener() {
|
||||
@Override
|
||||
public void suffixesChanged() {
|
||||
recreateEditorsPanel();
|
||||
}
|
||||
};
|
||||
IgnoredPropertiesFilesSuffixesManager.getInstance(myProject).addListener(mySuffixesListener);
|
||||
}
|
||||
|
||||
public ResourceBundle getResourceBundle() {
|
||||
@@ -406,35 +398,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
myValuesPanel.add(myNoPropertySelectedPanel, NO_PROPERTY_SELECTED);
|
||||
|
||||
final List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles();
|
||||
final IgnoredPropertiesFilesSuffixesManager suffixesManager =
|
||||
IgnoredPropertiesFilesSuffixesManager.getInstance(myResourceBundle.getProject());
|
||||
if (!suffixesManager.getIgnoredSuffixes().isEmpty()) {
|
||||
final List<PropertiesFile> initialOrder = new ArrayList<PropertiesFile>(propertiesFiles);
|
||||
final PropertiesFile defaultPropertiesFile = myResourceBundle.getDefaultPropertiesFile();
|
||||
Collections.sort(propertiesFiles, new Comparator<PropertiesFile>() {
|
||||
|
||||
@Override
|
||||
public int compare(PropertiesFile p1, PropertiesFile p2) {
|
||||
if (p1.equals(defaultPropertiesFile)) {
|
||||
return -1;
|
||||
}
|
||||
if (p2.equals(defaultPropertiesFile)) {
|
||||
return 1;
|
||||
}
|
||||
final boolean isIgnored1 = suffixesManager.getIgnoredSuffixes().contains(PropertiesUtil.getSuffix(p1));
|
||||
final boolean isIgnored2 = suffixesManager.getIgnoredSuffixes().contains(PropertiesUtil.getSuffix(p2));
|
||||
if (isIgnored1 != isIgnored2) {
|
||||
if (isIgnored1) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return initialOrder.indexOf(p1) - initialOrder.indexOf(p2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GridBagConstraints gc = new GridBagConstraints(0, 0, 0, 0, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
|
||||
new Insets(5, 5, 5, 5), 0, 0);
|
||||
@@ -733,12 +696,12 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
final String currentKey = selectedProperty.getKey();
|
||||
final int idx = keysOrder.indexOf(currentKey);
|
||||
LOG.assertTrue(idx != -1);
|
||||
final IgnoredPropertiesFilesSuffixesManager
|
||||
ignoredPropertiesFilesSuffixesManager = IgnoredPropertiesFilesSuffixesManager.getInstance(myProject);
|
||||
final IncompletePropertyInspection incompletePropertyInspection =
|
||||
IncompletePropertyInspection.getInstance(myResourceBundle.getDefaultPropertiesFile().getContainingFile());
|
||||
for (int i = 1; i < keysOrder.size(); i++) {
|
||||
int trimmedIndex = (i + idx) % keysOrder.size();
|
||||
final String key = keysOrder.get(trimmedIndex);
|
||||
if (!ignoredPropertiesFilesSuffixesManager.isPropertyComplete(myResourceBundle, key)) {
|
||||
if (!incompletePropertyInspection.isPropertyComplete(key, myResourceBundle)) {
|
||||
selectProperty(key);
|
||||
return;
|
||||
}
|
||||
@@ -894,7 +857,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
}
|
||||
}
|
||||
}
|
||||
IgnoredPropertiesFilesSuffixesManager.getInstance(myProject).removeListener(mySuffixesListener);
|
||||
VirtualFileManager.getInstance().removeVirtualFileListener(myVfsListener);
|
||||
myDisposed = true;
|
||||
Disposer.dispose(myStructureViewComponent);
|
||||
@@ -910,10 +872,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
myEditors.clear();
|
||||
}
|
||||
|
||||
public void queueUpdateTree() {
|
||||
myStructureViewComponent.getTreeBuilder().queueUpdate();
|
||||
}
|
||||
|
||||
public void setKeepEmptyProperties(boolean keepEmptyProperties) {
|
||||
myKeepEmptyProperties = keepEmptyProperties;
|
||||
}
|
||||
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.impl.IntentionListStep;
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.lang.properties.editor.inspections.ResourceBundleEditorProblemDescriptor;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.popup.PopupFactoryImpl;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class ResourceBundleEditorShowQuickFixesAction extends AnAction {
|
||||
private final static Logger LOG = Logger.getInstance(ResourceBundleEditorShowQuickFixesAction.class);
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final ResourceBundleEditor editor = getEditor(e);
|
||||
LOG.assertTrue(editor != null);
|
||||
final ResourceBundlePropertyStructureViewElement element = (ResourceBundlePropertyStructureViewElement)editor.getSelectedElementIfOnlyOne();
|
||||
LOG.assertTrue(element != null);
|
||||
|
||||
final PsiFile file = editor.getResourceBundle().getDefaultPropertiesFile().getContainingFile();
|
||||
final ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
|
||||
|
||||
boolean isQuickFixListEmpty = true;
|
||||
ResourceBundleEditorProblemDescriptor[] descriptors = element.getProblemDescriptors();
|
||||
for (ResourceBundleEditorProblemDescriptor d : descriptors) {
|
||||
QuickFix[] fixes = d.getFixes();
|
||||
if (fixes != null) {
|
||||
for (int i = 0; i < fixes.length; i++) {
|
||||
intentions.inspectionFixesToShow.add(new HighlightInfo.IntentionActionDescriptor(new RBEQuickFixWrapper(d, i),
|
||||
AllIcons.Actions.IntentionBulb));
|
||||
isQuickFixListEmpty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isQuickFixListEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Project project = e.getProject();
|
||||
LOG.assertTrue(project != null);
|
||||
PopupFactoryImpl
|
||||
.getInstance()
|
||||
.createListPopup(new IntentionListStep(null, intentions, null, file, project))
|
||||
.showInBestPositionFor(e.getDataContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
final ResourceBundleEditor editor = getEditor(e);
|
||||
e.getPresentation().setEnabledAndVisible(editor != null &&
|
||||
editor.getSelectedElementIfOnlyOne() instanceof ResourceBundlePropertyStructureViewElement);
|
||||
}
|
||||
|
||||
private ResourceBundleEditor getEditor(AnActionEvent e) {
|
||||
final FileEditor editor = PlatformDataKeys.FILE_EDITOR.getData(e.getDataContext());
|
||||
return editor instanceof ResourceBundleEditor ? (ResourceBundleEditor)editor : null;
|
||||
}
|
||||
|
||||
private static class RBEQuickFixWrapper implements IntentionAction {
|
||||
private final ResourceBundleEditorProblemDescriptor myDescriptor;
|
||||
private final int myIndex;
|
||||
|
||||
private RBEQuickFixWrapper(ResourceBundleEditorProblemDescriptor descriptor, int index) {
|
||||
myDescriptor = descriptor;
|
||||
myIndex = index;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getQuickFix().getFamilyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
getQuickFix().applyFix(project, myDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private QuickFix<ResourceBundleEditorProblemDescriptor> getQuickFix() {
|
||||
return myDescriptor.getFixes()[myIndex];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,9 +21,9 @@ import com.intellij.ide.DeleteProvider;
|
||||
import com.intellij.ide.actions.ContextHelpAction;
|
||||
import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.editor.inspections.ResourceBundleEditorRenderer;
|
||||
import com.intellij.lang.properties.projectView.ResourceBundleDeleteProvider;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.lang.properties.psi.Property;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
@@ -64,6 +64,7 @@ public class ResourceBundleStructureViewComponent extends PropertiesGroupingStru
|
||||
super(resourceBundle.getProject(), editor, new ResourceBundleStructureViewModel(resourceBundle, anchorizer));
|
||||
myResourceBundle = resourceBundle;
|
||||
tunePopupActionGroup();
|
||||
getTree().setCellRenderer(new ResourceBundleEditorRenderer());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,7 +84,6 @@ public class ResourceBundleStructureViewComponent extends PropertiesGroupingStru
|
||||
final DefaultActionGroup propertiesPopupGroup = new DefaultActionGroup();
|
||||
propertiesPopupGroup.copyFromGroup((DefaultActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_STRUCTURE_VIEW_POPUP));
|
||||
propertiesPopupGroup.add(Separator.getInstance(), Constraints.FIRST);
|
||||
propertiesPopupGroup.add(new IgnoreIncompletePropertyPropertiesFilesAction(), Constraints.FIRST);
|
||||
propertiesPopupGroup.add(new NewPropertyAction(true), Constraints.FIRST);
|
||||
PopupHandler.installPopupHandler(getTree(), propertiesPopupGroup, IdeActions.GROUP_STRUCTURE_VIEW_POPUP, ActionManager.getInstance());
|
||||
}
|
||||
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor.inspections.incomplete;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.ModifiableModel;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
import com.intellij.codeInspection.ex.DisableInspectionToolAction;
|
||||
import com.intellij.lang.properties.*;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.editor.inspections.ResourceBundleEditorInspection;
|
||||
import com.intellij.lang.properties.editor.inspections.ResourceBundleEditorProblemDescriptor;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.SmartPointerManager;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.*;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class IncompletePropertyInspection extends ResourceBundleEditorInspection {
|
||||
private static final String SUFFIXES_TAG_NAME = "suffixes";
|
||||
private static final String TOOL_KEY = "IncompleteProperty";
|
||||
|
||||
SortedSet<String> mySuffixes = new TreeSet<String>();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
return new IncompletePropertyInspectionOptionsPanel(mySuffixes).buildPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSettings(@NotNull Element node) throws InvalidDataException {
|
||||
mySuffixes.clear();
|
||||
final Element element = node.getChild(SUFFIXES_TAG_NAME);
|
||||
if (element != null) {
|
||||
mySuffixes.addAll(StringUtil.split(element.getText(), ","));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSettings(@NotNull Element node) throws WriteExternalException {
|
||||
if (!mySuffixes.isEmpty()) {
|
||||
node.addContent(new Element(SUFFIXES_TAG_NAME).setText(StringUtil.join(mySuffixes, ",")));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ResourceBundleEditorProblemDescriptor[] checkPropertyGroup(@NotNull List<IProperty> properties, @NotNull ResourceBundle resourceBundle) {
|
||||
return !isPropertyComplete(properties, resourceBundle)
|
||||
? new ResourceBundleEditorProblemDescriptor[] {new ResourceBundleEditorProblemDescriptor(ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
PropertiesBundle.message("incomplete.property.inspection.description",
|
||||
properties.get(0).getName()),
|
||||
new IgnoreLocalesQuickFix(properties.get(0), resourceBundle))}
|
||||
: null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static IncompletePropertyInspection getInstance(PsiElement element) {
|
||||
final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(element.getProject());
|
||||
InspectionProfile inspectionProfile = profileManager.getInspectionProfile();
|
||||
return (IncompletePropertyInspection) inspectionProfile.getUnwrappedTool(TOOL_KEY, element);
|
||||
}
|
||||
|
||||
private static class IgnoreLocalesQuickFix implements QuickFix<ResourceBundleEditorProblemDescriptor> {
|
||||
private final ResourceBundle myResourceBundle;
|
||||
private final SmartPsiElementPointer<PsiElement> myElementPointer;
|
||||
|
||||
public IgnoreLocalesQuickFix(IProperty property, ResourceBundle bundle) {
|
||||
myElementPointer = SmartPointerManager.getInstance(bundle.getProject()).createSmartPsiElementPointer(property.getPsiElement());
|
||||
myResourceBundle = bundle;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return PropertiesBundle.message("incomplete.property.quick.fix.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ResourceBundleEditorProblemDescriptor descriptor) {
|
||||
final PsiElement element = myElementPointer.getElement();
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
final IProperty property = PropertiesImplUtil.getProperty(element);
|
||||
if (property == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final IncompletePropertyInspection inspection = getInstance(element);
|
||||
final List<PropertiesFile> allFilesWithoutTranslation = inspection.getPropertiesFilesWithoutTranslation(myResourceBundle, property.getKey());
|
||||
|
||||
if (allFilesWithoutTranslation.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final TreeSet<String> suffixesToIgnore = new TreeSet<String>(ContainerUtil.map(allFilesWithoutTranslation,
|
||||
new Function<PropertiesFile, String>() {
|
||||
@Override
|
||||
public String fun(PropertiesFile file) {
|
||||
return PropertiesUtil.getSuffix(file);
|
||||
}
|
||||
}));
|
||||
if (new IncompletePropertyInspectionOptionsPanel(suffixesToIgnore).showDialogAndGet(project)) {
|
||||
DisableInspectionToolAction.modifyAndCommitProjectProfile(new Consumer<ModifiableModel>() {
|
||||
@Override
|
||||
public void consume(ModifiableModel modifiableModel) {
|
||||
((IncompletePropertyInspection)modifiableModel.getInspectionTool(TOOL_KEY, element).getTool()).addSuffixes(suffixesToIgnore);
|
||||
}
|
||||
}, project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPropertyComplete(final String key, final ResourceBundle resourceBundle) {
|
||||
return isPropertyComplete(ContainerUtil.mapNotNull(resourceBundle.getPropertiesFiles(), new Function<PropertiesFile, IProperty>() {
|
||||
@Override
|
||||
public IProperty fun(PropertiesFile file) {
|
||||
return file.findPropertyByKey(key);
|
||||
}
|
||||
}), resourceBundle);
|
||||
}
|
||||
|
||||
private boolean isPropertyComplete(final List<IProperty> properties, final ResourceBundle resourceBundle) {
|
||||
final Set<PropertiesFile> existed = ContainerUtil.map2Set(properties, new Function<IProperty, PropertiesFile>() {
|
||||
|
||||
@Override
|
||||
public PropertiesFile fun(IProperty property) {
|
||||
return property.getPropertiesFile();
|
||||
}
|
||||
});
|
||||
for (PropertiesFile file : resourceBundle.getPropertiesFiles()) {
|
||||
if (!existed.contains(file) && !getIgnoredSuffixes().contains(PropertiesUtil.getSuffix(file))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Set<String> getIgnoredSuffixes() {
|
||||
return mySuffixes;
|
||||
}
|
||||
|
||||
public List<PropertiesFile> getPropertiesFilesWithoutTranslation(final ResourceBundle resourceBundle, final String key) {
|
||||
final PropertiesFile defaultPropertiesFile = resourceBundle.getDefaultPropertiesFile();
|
||||
return ContainerUtil.filter(resourceBundle.getPropertiesFiles(), new Condition<PropertiesFile>() {
|
||||
@Override
|
||||
public boolean value(PropertiesFile propertiesFile) {
|
||||
return !defaultPropertiesFile.equals(propertiesFile) &&
|
||||
propertiesFile.findPropertyByKey(key) == null &&
|
||||
!getIgnoredSuffixes().contains(PropertiesUtil.getSuffix(propertiesFile));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addSuffixes(Collection<String> suffixes) {
|
||||
mySuffixes.addAll(suffixes);
|
||||
}
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor.inspections.incomplete;
|
||||
|
||||
import com.intellij.lang.properties.PropertiesUtil;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Locale;
|
||||
import java.util.SortedSet;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class IncompletePropertyInspectionOptionsPanel {
|
||||
|
||||
private final SortedSet<String> mySuffixes;
|
||||
private final JBList myList;
|
||||
|
||||
public IncompletePropertyInspectionOptionsPanel(SortedSet<String> suffixes) {
|
||||
mySuffixes = suffixes;
|
||||
myList = new JBList(new MyListModel());
|
||||
}
|
||||
|
||||
public JPanel buildPanel() {
|
||||
JPanel panel = ToolbarDecorator
|
||||
.createDecorator(myList)
|
||||
.setPanelBorder(IdeBorderFactory.createTitledBorder("Ignored suffixes"))
|
||||
.disableUpDownActions()
|
||||
.setAddAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
final String result = Messages.showInputDialog(CommonDataKeys.PROJECT.getData(button.getDataContext()),
|
||||
"Suffixes to ignore (use comma to separate suffixes):",
|
||||
"Add Ignored Suffixes", null);
|
||||
if (result != null) {
|
||||
mySuffixes.addAll(StringUtil.split(result, ","));
|
||||
changed();
|
||||
}
|
||||
}
|
||||
}).setRemoveAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
for (Object v : myList.getSelectedValues()) {
|
||||
mySuffixes.remove(v);
|
||||
}
|
||||
changed();
|
||||
}
|
||||
}).createPanel();
|
||||
myList.setCellRenderer(new ColoredListCellRenderer<String>() {
|
||||
@Override
|
||||
protected void customizeCellRenderer(JList list, String suffix, int index, boolean selected, boolean hasFocus) {
|
||||
append(suffix);
|
||||
final Locale locale = PropertiesUtil.getLocale("_" + suffix + ".properties");
|
||||
if (locale != PropertiesUtil.DEFAULT_LOCALE && PropertiesUtil.hasDefaultLanguage(locale)) {
|
||||
append(" ");
|
||||
append(PropertiesUtil.getPresentableLocale(locale), SimpleTextAttributes.GRAY_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
});
|
||||
return panel;
|
||||
}
|
||||
|
||||
public boolean showDialogAndGet(Project project) {
|
||||
return new DialogWrapper(project) {
|
||||
{
|
||||
init();
|
||||
setTitle("Locales to Ignore");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return buildPanel();
|
||||
}
|
||||
}.showAndGet();
|
||||
}
|
||||
|
||||
private void changed() {
|
||||
((MyListModel)myList.getModel()).modified();
|
||||
}
|
||||
|
||||
private class MyListModel extends AbstractListModel {
|
||||
public int getSize() {
|
||||
return mySuffixes.size();
|
||||
}
|
||||
|
||||
public Object getElementAt(int index) {
|
||||
return mySuffixes.toArray(new String[mySuffixes.size()])[index];
|
||||
}
|
||||
|
||||
public void modified() {
|
||||
fireContentsChanged(this, -1, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-18
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.lang.properties;
|
||||
|
||||
import com.intellij.lang.properties.editor.IgnoredPropertiesFilesSuffixesManager;
|
||||
import com.intellij.lang.properties.editor.inspections.incomplete.IncompletePropertyInspection;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
|
||||
@@ -27,6 +27,12 @@ import java.util.Collections;
|
||||
*/
|
||||
public class IgnoredPropertiesFilesSuffixesTest extends LightPlatformCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myFixture.enableInspections(IncompletePropertyInspection.class);
|
||||
}
|
||||
|
||||
public void testPropertyIsComplete() {
|
||||
myFixture.addFileToProject("p.properties", "key=value");
|
||||
myFixture.addFileToProject("p_en.properties", "key=value eng");
|
||||
@@ -35,9 +41,9 @@ public class IgnoredPropertiesFilesSuffixesTest extends LightPlatformCodeInsight
|
||||
assertNotNull(propertiesFile);
|
||||
final ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
|
||||
assertSize(3, resourceBundle.getPropertiesFiles());
|
||||
final IgnoredPropertiesFilesSuffixesManager suffixesManager = IgnoredPropertiesFilesSuffixesManager.getInstance(getProject());
|
||||
suffixesManager.addSuffixes(Collections.singleton("ru"));
|
||||
assertTrue(suffixesManager.isPropertyComplete(resourceBundle, "key"));
|
||||
final IncompletePropertyInspection incompletePropertyInspection = IncompletePropertyInspection.getInstance(propertiesFile.getContainingFile());
|
||||
incompletePropertyInspection.addSuffixes(Collections.singleton("ru"));
|
||||
assertTrue(incompletePropertyInspection.isPropertyComplete("key", resourceBundle));
|
||||
}
|
||||
|
||||
public void testPropertyIsComplete2() {
|
||||
@@ -48,8 +54,8 @@ public class IgnoredPropertiesFilesSuffixesTest extends LightPlatformCodeInsight
|
||||
assertNotNull(propertiesFile);
|
||||
final ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
|
||||
assertSize(3, resourceBundle.getPropertiesFiles());
|
||||
final IgnoredPropertiesFilesSuffixesManager suffixesManager = IgnoredPropertiesFilesSuffixesManager.getInstance(getProject());
|
||||
assertTrue(suffixesManager.isPropertyComplete(resourceBundle, "key"));
|
||||
final IncompletePropertyInspection incompletePropertyInspection = IncompletePropertyInspection.getInstance(propertiesFile.getContainingFile());
|
||||
assertTrue(incompletePropertyInspection.isPropertyComplete("key", resourceBundle));
|
||||
}
|
||||
|
||||
public void testPropertyIsIncomplete() {
|
||||
@@ -61,9 +67,9 @@ public class IgnoredPropertiesFilesSuffixesTest extends LightPlatformCodeInsight
|
||||
assertNotNull(propertiesFile);
|
||||
final ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
|
||||
assertSize(4, resourceBundle.getPropertiesFiles());
|
||||
final IgnoredPropertiesFilesSuffixesManager suffixesManager = IgnoredPropertiesFilesSuffixesManager.getInstance(getProject());
|
||||
suffixesManager.addSuffixes(Collections.singleton("ru"));
|
||||
assertFalse(suffixesManager.isPropertyComplete(resourceBundle, "key"));
|
||||
final IncompletePropertyInspection incompletePropertyInspection = IncompletePropertyInspection.getInstance(propertiesFile.getContainingFile());
|
||||
incompletePropertyInspection.addSuffixes(Collections.singleton("ru"));
|
||||
assertFalse(incompletePropertyInspection.isPropertyComplete("key", resourceBundle));
|
||||
}
|
||||
|
||||
public void testPropertyIsIncomplete2() {
|
||||
@@ -76,14 +82,8 @@ public class IgnoredPropertiesFilesSuffixesTest extends LightPlatformCodeInsight
|
||||
assertNotNull(propertiesFile);
|
||||
final ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
|
||||
assertSize(5, resourceBundle.getPropertiesFiles());
|
||||
final IgnoredPropertiesFilesSuffixesManager suffixesManager = IgnoredPropertiesFilesSuffixesManager.getInstance(getProject());
|
||||
suffixesManager.addSuffixes(Collections.singleton("en"));
|
||||
assertFalse(suffixesManager.isPropertyComplete(resourceBundle, "key"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
IgnoredPropertiesFilesSuffixesManager.getInstance(getProject()).setSuffixes(Collections.<String>emptySet());
|
||||
super.tearDown();
|
||||
final IncompletePropertyInspection incompletePropertyInspection = IncompletePropertyInspection.getInstance(propertiesFile.getContainingFile());
|
||||
incompletePropertyInspection.addSuffixes(Collections.singleton("en"));
|
||||
assertFalse(incompletePropertyInspection.isPropertyComplete("key", resourceBundle));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
~ Copyright 2000-2015 JetBrains s.r.o.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<html>
|
||||
<body>
|
||||
Inspection detects property keys which have no translations in part of resource bundle properties files.
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user