139 lines
5.2 KiB
Java
139 lines
5.2 KiB
Java
package de.marhali.easyi18n.assistance.intention;
|
|
|
|
import com.intellij.codeInsight.intention.BaseElementAtCaretIntentionAction;
|
|
import com.intellij.codeInspection.util.IntentionFamilyName;
|
|
import com.intellij.codeInspection.util.IntentionName;
|
|
import com.intellij.openapi.command.WriteCommandAction;
|
|
import com.intellij.openapi.editor.Caret;
|
|
import com.intellij.openapi.editor.Document;
|
|
import com.intellij.openapi.editor.Editor;
|
|
import com.intellij.openapi.project.Project;
|
|
import com.intellij.openapi.util.TextRange;
|
|
import com.intellij.psi.PsiElement;
|
|
import com.intellij.util.IncorrectOperationException;
|
|
|
|
import de.marhali.easyi18n.InstanceManager;
|
|
import de.marhali.easyi18n.assistance.OptionalAssistance;
|
|
import de.marhali.easyi18n.dialog.AddDialog;
|
|
import de.marhali.easyi18n.dialog.EditDialog;
|
|
import de.marhali.easyi18n.model.KeyPath;
|
|
import de.marhali.easyi18n.model.Translation;
|
|
import de.marhali.easyi18n.model.TranslationData;
|
|
import de.marhali.easyi18n.model.TranslationValue;
|
|
import de.marhali.easyi18n.settings.ProjectSettings;
|
|
import de.marhali.easyi18n.settings.ProjectSettingsService;
|
|
import de.marhali.easyi18n.util.KeyPathConverter;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import java.util.ResourceBundle;
|
|
|
|
/**
|
|
* Intention for translation related use-cases.
|
|
* Can be used to extract (create) translations or to edit existing ones.
|
|
* @author marhali
|
|
*/
|
|
abstract class AbstractTranslationIntention extends BaseElementAtCaretIntentionAction implements OptionalAssistance {
|
|
|
|
protected static final ResourceBundle bundle = ResourceBundle.getBundle("messages");
|
|
|
|
private boolean existingTranslation = false;
|
|
|
|
@Override
|
|
public @IntentionName @NotNull String getText() {
|
|
return existingTranslation
|
|
? bundle.getString("action.edit")
|
|
: bundle.getString("action.extract");
|
|
}
|
|
|
|
@Override
|
|
public @NotNull @IntentionFamilyName String getFamilyName() {
|
|
return "EasyI18n";
|
|
}
|
|
|
|
@Override
|
|
public boolean startInWriteAction() {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* This is the only method a language-specific translation intention needs to implement.
|
|
* The implementation needs to verify element type and extract the relevant key literal or value.
|
|
* @param element Element at caret
|
|
* @return extract translation key (not verified!) or null if intention is not applicable for this element
|
|
*/
|
|
protected abstract @Nullable String extractText(@NotNull PsiElement element);
|
|
|
|
@NotNull TextRange convertRange(@NotNull TextRange input) {
|
|
return new TextRange(input.getStartOffset(), input.getEndOffset());
|
|
}
|
|
|
|
@Override
|
|
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
|
if(!isAssistance(project)) {
|
|
return false;
|
|
}
|
|
|
|
String text = extractText(element);
|
|
|
|
if(text != null) {
|
|
KeyPathConverter converter = new KeyPathConverter(project);
|
|
existingTranslation = InstanceManager.get(project).store().getData()
|
|
.getTranslation(converter.fromString(text)) != null;
|
|
}
|
|
|
|
return text != null;
|
|
}
|
|
|
|
@Override
|
|
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element)
|
|
throws IncorrectOperationException {
|
|
|
|
ProjectSettings settings = ProjectSettingsService.get(project).getState();
|
|
KeyPathConverter converter = new KeyPathConverter(settings);
|
|
|
|
String text = extractText(element);
|
|
|
|
if(text == null) {
|
|
throw new IncorrectOperationException("Cannot extract translation intention at caret");
|
|
}
|
|
|
|
TranslationData data = InstanceManager.get(project).store().getData();
|
|
KeyPath path = converter.fromString(text);
|
|
TranslationValue existingTranslation = data.getTranslation(path);
|
|
|
|
// Existing translation - edit dialog
|
|
if(existingTranslation != null) {
|
|
new EditDialog(project, new Translation(path, existingTranslation)).showAndHandle();
|
|
return;
|
|
}
|
|
|
|
// Extract translation by key
|
|
// We assume that a text is a translation-key if it contains section delimiters and does not end with them
|
|
if(text.contains(settings.getSectionDelimiter()) && !text.endsWith(settings.getSectionDelimiter())) {
|
|
new AddDialog(project, path, null).showAndHandle();
|
|
return;
|
|
}
|
|
|
|
// Extract translation by preview locale value
|
|
AddDialog dialog = new AddDialog(project, new KeyPath(), text);
|
|
|
|
dialog.registerCallback(translationUpdate -> { // Replace text at caret with chosen translation key
|
|
if(editor != null) {
|
|
Document doc = editor.getDocument();
|
|
Caret caret = editor.getCaretModel().getPrimaryCaret();
|
|
TextRange range = convertRange(element.getTextRange());
|
|
|
|
WriteCommandAction.runWriteCommandAction(project, () ->
|
|
doc.replaceString(range.getStartOffset(), range.getEndOffset(),
|
|
converter.toString(translationUpdate.getChange().getKey())));
|
|
|
|
caret.removeSelection();
|
|
}
|
|
});
|
|
|
|
dialog.showAndHandle();
|
|
}
|
|
}
|